Skip to content

Commit e8d3f21

Browse files
committed
Add binarySearch and binarySearchTemplated README
1 parent a9326b2 commit e8d3f21

File tree

3 files changed

+148
-2
lines changed

3 files changed

+148
-2
lines changed

src/main/java/algorithms/binarySearch/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ At the end of each iteration, the target value is either within the search range
1515
We will discuss more implementation-specific details and complexity analysis in the respective folders. In short,
1616
1. The [binarySearch](binarySearch) method is a more straightforward and intuitive version of the binary search
1717
algorithm.
18-
2. The [binarySearchTemplate](binarySearchTemplated) method provides a template that can be used for most binary search
19-
problems by introducing a condition method that can be modified based on the requirements of the implementation.
18+
2. The [binarySearchTemplate](binarySearchTemplated) method provides a more generalised template that can be used for
19+
most binary search problems by introducing a condition method that can be modified based on the requirements of the
20+
implementation.
2021

2122

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# BinarySearch
2+
3+
## Background
4+
5+
BinarySearch is a more straightforward and intuitive version of the binary search algorithm. In this approach, after the
6+
mid-value is calculated, the high or low pointer is adjusted by just one unit.
7+
8+
### Illustration
9+
10+
![binary search img](../../../../../../docs/assets/images/BinarySearch.png)
11+
12+
Image Source: GeeksforGeeks
13+
14+
From the above example, after mid points to index 4 in the first search, the low pointer moves to index 5 (+1 from 4)
15+
when narrowing the search. Similarly, when mid points to index 7 in the second search, the high pointer shifts to index
16+
6 (-1 from 7) when narrowing the search. This prevents any possibility of infinite loops. During the search, the moment
17+
mid-value is equal to the target value, the search ends prematurely.
18+
19+
## Complexity Analysis
20+
**Time**:
21+
- Worst case: O(log n)
22+
- Average case: O(log n)
23+
- Best case: O(1)
24+
25+
In the worst case, the target is either in the first or last index or does not exist in the array at all.
26+
In the best case, the target is the middle (odd number of element) or the first middle element (even number of elements)
27+
if floor division is used to determine the middle.
28+
29+
**Space**: O(1)
30+
31+
Since no new data structures are used and searching is only done within the array given.
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# BinarySearchTemplated
2+
3+
## Background
4+
5+
BinarySearchTemplated is a more generalised algorithm of [BinarySearch](../binarySearch) that removes the condition that
6+
checks if the current mid-value is equal to the target (which helps to end the search the moment the target is found).
7+
The template adds a "condition" method which will be modified based on the requirements of the implementation.
8+
9+
The narrowing of the search space differs from BinarySearch - only the high pointer will be adjusted by one unit.
10+
11+
This template will work for most binary search problems and will require the following changes when used for different
12+
problems:
13+
- Search space (high and low pointers)
14+
- Condition method
15+
- Returned value (low or low - 1)
16+
17+
### Search Space (Requires change)
18+
Initialise the boundary values of the high and low pointers to include all possible elements in the search space.
19+
20+
### Condition (Requires change)
21+
We assume that when the condition returns true, the current value "passes" and when the condition returns false, the
22+
current value "fails".
23+
24+
Note that in this template, the conditional blocks
25+
```
26+
if (condition(x)) {
27+
high = mid;
28+
} else {
29+
low = mid + 1;
30+
}
31+
```
32+
requires elements that "fail" the condition to be on the left of the elements that "pass" the condition, see below, in a
33+
sorted array due to the way the high and low pointers are reassigned.
34+
35+
![binary search templated 1 img](../../../../../../docs/assets/images/BinarySearchTemplated1.jpeg)
36+
37+
Hence, we will need to implement a condition method that is able to discern between arrays that "pass" and "fail"
38+
accurately and also place them in the correct relative positions i.e. "fail" on the left of "pass". Suppose we change
39+
the condition method implementation in BinarySearchTemplated from `value >= target` to `value <= target`, what will
40+
happen?
41+
<details>
42+
<summary> <b>what will happen?</b> </summary>
43+
The array becomes "P P F F F F" and the low and high pointers are now reassigned wrongly. We are now looking for the
44+
first "fail" instead of the first "pass".
45+
46+
To resolve this issue, multiple changes are required: the pointer assignment bodies have to be swapped, low = mid + 1
47+
needs to be changed to low = mid, high = mid changed to high = mid - 1 AND ceiling division has to be used to calculate
48+
the mid-value. The arrangement of the "pass" elements on the left of the "fail" elements is discouraged as it breaks
49+
away from the convention used in the template.
50+
</details>
51+
52+
### Returned Value (Requires change)
53+
In this implementation of BinarySearchTemplated, we return the first "pass" in the array with `return low`. This is
54+
because our condition method implementation encompasses the target value that we are finding i.e. when
55+
`value == target`.
56+
57+
```java
58+
public static boolean condition(int value, int target) {
59+
return value >= target;
60+
}
61+
```
62+
![binary search templated 2 img](../../../../../../docs/assets/images/BinarySearchTemplated2.jpeg)
63+
64+
However, if we want to return the last "fail" in the array, we will `return low - 1`.
65+
66+
Suppose now we modify the condition to be `value > target`, how can we modify our BinarySearchTemplated to still work as
67+
expected?
68+
<details>
69+
<summary> <b>value > target?</b> </summary>
70+
Replace `return low` with `return low - 1` and replace arr[low] with arr[low - 1] as now the target value is the last
71+
"fail".
72+
</details>
73+
74+
75+
### Search Space Adjustment
76+
What should be the search space adjustment? Why is only low reassigned with an increment and not high?
77+
78+
Due to the nature of floor division in Java's \ operator, if there are two mid-values within the search range, which is
79+
when the number of elements is even, the first mid-value will be selected. Suppose we do not increment the low pointer
80+
during reassignment, `low = mid`, let us take a look at the following example:
81+
82+
![binary search templated 1 img](../../../../../docs/assets/images/BinarySearchTemplated3.jpeg)
83+
84+
The search space has been narrowed down to the range of index 1 (low) to 2 (high). The mid-value is calculated,
85+
`mid = (1 + 2) / 2`, to be 1 due to floor division. Since `2 < 5`, we enter the else block where there is reassignment
86+
of `low = mid`. This means that the low pointer is still pointing to index 1 and the high pointer remains unchanged at
87+
index 2. This results in an infinite loop as the search range is not narrowed down.
88+
89+
To resolve this issue, we need `low = mid + 1`, which will result in the low pointer pointing to index 2 in this
90+
scenario. We still ensure correctness because the mid-value is not the target value, as the mid-value < target, and we
91+
can safely exclude it from the search range.
92+
93+
Why should we not decrement the high pointer during reassignment? This is because the mid-value could be the target
94+
as the condition implemented is `value >= target`, hence, we cannot exclude it from the search range.
95+
96+
Note that if ceiling division is used instead, `high = mid - 1` will be required to prevent an infinite loop. Both
97+
`low = mid + 1` and `low = mid` will work in this case.
98+
99+
See [here](binarySearchTemplatedExamples/README.md) to use the template for other problems.
100+
101+
Credits: [Powerful Ultimate Binary Search Template](https://leetcode.com/discuss/general-discussion/786126/python-powerful-ultimate-binary-search-template-solved-many-problems)
102+
103+
104+
## Complexity Analysis
105+
**Time**:
106+
- Worst case: O(log n)
107+
- Average case: O(log n)
108+
- Best case: O(log n)
109+
110+
In all cases, O(log n) iterations will be required as there is no condition to exit the loop prematurely.
111+
112+
**Space**: O(1)
113+
114+
Since no new data structures are used and searching is only done within the array given.

0 commit comments

Comments
 (0)