[[Lintcode problems]]
Algorithm: #binarysearch
Level: #medium
Time Complexity: #Ologn
Tags: #rotated
URL:62 · Search in Rotated Sorted Array - LintCode
# Description
Suppose a sorted array is rotated at some pivot unknown to you beforehand.
(i.e., 0 1 2 4 5 6 7
might become 4 5 6 7 0 1 2
).
You are given a target value to search. If found in the array return its index, otherwise return -1
.
You may assume no duplicate exists in the array.
Example 1:
Input:
array = [4, 5, 1, 2, 3]
target = 1
Output:
2
Explanation:
1 is indexed at 2 in the array.
Example 2:
Input:
array = [4, 5, 1, 2, 3]
target = 0
Output:
-1
Explanation:
0 is not in the array. Returns -1.
Challenge:
O(logN) time
# Note
甚麼條件想到此算法的?
- 因為 challenge 是 Ologn, 比 O (n) 快的算法就往二分法想。
甚麼是 rotated sorted array?**
- 循環向左移
# 思路
- [1,2,3,4,5,6,7] -> [5,6,7,1,2,3] 這樣的 array
這樣就很明顯看出 5,6,7 是一段, 1,2,3 又是另一段
假設我要找 target=2 的數
我知道我肯定得在 [1,2,3] 找,肉眼所看到,右邊的 [123] 比左邊的數都要少
那問題來了,我怎麼確認 1,2,3 的位置?
- 我只需要知道左段的數比右邊的大 (並且知道是有序的)
在下面的代碼可以看到怎麼分這個情況(分出兩段)
1. 前段是有序的 (A [start] < A [mid]) e.g. [1,2,3,4,5,6]
那麼我就開始在這有序的 array 裡找 target,比如說 target = 5if A[start] <= target && target <= A[mid]
這樣基本上確認了 target 就在 這一段有序的 array 裡面,
把 end = midelse
那就代表不一定在這個範圍了,我們從 mid 後找
-> start = mid
2. else! 後一段的有序
同樣啦~找後面那段 [1,2,3]java if A[mid] <= target && target <= A[end] start = mid! (從此段開始找) else end = mid
# Solution
public class Solution { | |
/** | |
* @param A: an integer rotated sorted array | |
* @param target: an integer to be searched | |
* @return: an integer | |
*/ | |
public int search(int[] A, int target) { | |
if(A.length == 0 || A == null) { | |
return -1; | |
} | |
int start = 0; | |
int end = A.length - 1; | |
int mid; | |
while (start + 1 < end) { | |
mid = start + (end - start) / 2; | |
if (A[mid] == target) { | |
return mid; | |
} | |
// 最開始的數 < mid : e.g [5,7,0] 這一段 | |
// mid = 7 , start = 5 | |
if (A[start] < A[mid]) { | |
if (A[start] <= target && target <= A[mid]){ | |
end = mid; // 在 mid=7 之後的不需要再看, | |
} else { | |
start = mid; | |
} | |
} else { | |
if (A[mid] <= target && target <= A[end]) { | |
start = mid; | |
} else { | |
end = mid; | |
} | |
} | |
} // end while loop | |
if (A[start] == target){ | |
return start; | |
} | |
if (A[end] == target) { | |
return end; | |
} | |
return -1; | |
} | |
} |
# Related
[[63 Search in Rotated Sorted Array II]] 通常都是問完 正常版沒重覆的 rotated sorted array 後 再問這題的。 63 不能用二分
# Description
Follow up for Search in Rotated Sorted Array:
What if duplicates are allowed?
Would this affect the run-time complexity? How and why?
Write a function to determine if a given target is in the array.
# Solution
// 这个问题在面试中不会让实现完整程序
// 只需要举出能够最坏情况的数据是 [1,1,1,1... 1] 里有一个0即可。
// 在这种情况下是无法使用二分法的,复杂度是O(n)
// 因此写个for循环最坏也是O(n),那就写个for循环就好了
// 如果你觉得,不是每个情况都是最坏情况,你想用二分法解决不是最坏情况的情况,那你就写一个二分吧。
// 反正面试考的不是你在这个题上会不会用二分法。这个题的考点是你想不想得到最坏情况。
public class Solution { | |
/** | |
* @param A: an integer ratated sorted array and duplicates are allowed | |
* @param target: An integer | |
* @return: a boolean | |
*/ | |
public boolean search(int[] A, int target) { | |
for (int i : A){ | |
if (i == target){ | |
return true; | |
} | |
} | |
return false; | |
} | |
} |