56 lines
1.6 KiB
Markdown
56 lines
1.6 KiB
Markdown
# 10.3. Search in rotated array
|
|
|
|
> Given a sorted array of n integers that has been rotated an unknown number of times, find an element in the array. The array was originally sorted in increasing order.
|
|
|
|
* Input: find 5 in {15, 16, 19, 20, 25, 1, 3, 4, 5, 7, 10, 14}
|
|
* Output: 8 (the index of 5 in the array)
|
|
|
|
If the first element is larger than our number, start search from the end. If not, start from the beginning.
|
|
|
|
```python
|
|
def find_in_rotated(ar: list, el: int) -> int:
|
|
ar = ar[::-1] if el < ar[0] else ar
|
|
for i, num in enumerate(ar):
|
|
if el == num:
|
|
return i
|
|
return None
|
|
```
|
|
|
|
In the worst case scenario it takes O(n/2), O(1) space.
|
|
|
|
## Hints
|
|
|
|
> Modify binary search for this purpose
|
|
|
|
My implementation was brute force. This one uses binary search and has runtime of O(n)
|
|
|
|
```python
|
|
def rotated_binary_search(arr, key):
|
|
N = len(arr)
|
|
L = 0
|
|
R = N - 1
|
|
while L <= R:
|
|
M = L + ((R - L) / 2)
|
|
if (arr[M] == key):
|
|
return M
|
|
# the bottom half is sorted
|
|
if (arr[L] <= arr[M]):
|
|
if (arr[L] <= key and key < arr[M]):
|
|
R = M - 1
|
|
else:
|
|
L = M + 1
|
|
# the upper half is sorted
|
|
else:
|
|
if (arr[M] < key and key <= arr[R]):
|
|
L = M + 1
|
|
else:
|
|
R = M - 1
|
|
return -1
|
|
|
|
arr = [15, 16, 19, 20, 25, 1, 3, 4, 5, 7, 10, 14]
|
|
x = 10
|
|
result = rotated_binary_search(arr, x)
|
|
```
|
|
|
|
If there are duplicates, the runtime might be O(n) because we will have to search both the left and right sides of the array.
|