-
Notifications
You must be signed in to change notification settings - Fork 0
/
704BinarySearch.php
105 lines (87 loc) · 2.3 KB
/
704BinarySearch.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<?php declare(strict_types = 1);
final class Solution
{
private int $leftBoundary;
private int $rightBoundary;
/** @param int[] $nums */
public function search(array $nums, int $target): int
{
$this->leftBoundary = 0;
$this->rightBoundary = count($nums) - 1;
if ($this->compare($nums, $target, $this->leftBoundary)) {
return $this->leftBoundary;
}
do {
$index = $this->calculateNextIndex();
if ($this->compare($nums, $target, $index)) {
return $index;
}
} while ($this->rightBoundary - $this->leftBoundary > 1);
if ($this->compare($nums, $target, $this->rightBoundary)) {
return $this->rightBoundary;
}
return -1;
}
private function calculateNextIndex(): int
{
return $this->leftBoundary + ((int) round(($this->rightBoundary - $this->leftBoundary) / 2));
}
private function compare(array $nums, int $target, int $index): bool
{
$num = $nums[$index];
if ($target > $num) {
$this->leftBoundary = $index;
} elseif ($target === $num) {
return true;
} elseif ($target < $num) {
$this->rightBoundary = $index;
}
return false;
}
}
/* Client code below */
$solution = new Solution();
$nums = [-1,0,3,5,9,12,13,123,3246,89235,253452];
$testCases = [
[
'nums' => $nums,
'target' => 9,
'expectedIndex' => 4,
],
[
'nums' => $nums,
'target' => 3,
'expectedIndex' => 2,
],
[
'nums' => [2,5],
'target' => 2,
'expectedIndex' => 0,
],
[
'nums' => [2,5],
'target' => 5,
'expectedIndex' => 1,
],
[
'nums' => [-1,0,5],
'target' => 5,
'expectedIndex' => 2,
],
[
'nums' => [-1,0,5],
'target' => -1,
'expectedIndex' => 0,
],
[
'nums' => [-1,0,5],
'target' => 0,
'expectedIndex' => 1,
],
];
foreach ($testCases as $t) {
$expectedIndex = $t['expectedIndex'];
$index = $solution->search($t['nums'], $t['target']);
assert($expectedIndex === $index, "$expectedIndex !== $index" . PHP_EOL);
echo "$expectedIndex === $index" . PHP_EOL;
}