每日演算法——leetcode系列
問題 Search in Rotated Sorted Array
Difficulty: Hard
Suppose a sorted array is rotated at some pivot unknown to you beforehand.
(i.e.,
0 1 2 4 5 6 7
might become4 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.
class Solution {
public:
int search(vector<int>& nums, int target) {
}
};
翻譯
在旋轉排序陣列中搜尋(指定的目標)
難度係數:困難
假定一個有序陣列在一個預先不知道的軸點地方被旋轉。
例如,0 1 2 4 5 6 7
可能會變為4 5 6 7 0 1 2
。
給你一個目標值去搜尋,如果在陣列中找到了則返回它的索引,否則返回-1。
你可以假定陣列中沒有重複的元素。
思路
對於有序陣列, 查詢可以用二分查詢,但由於是事先不知道在什麼地方旋轉過的,一開始想法簡單粗暴, 找出旋轉的軸點位置, 再把他旋轉回有序狀態, 再二分查詢,最後再用旋轉後跟旋轉前的索引對應關係找到index。這個時間複雜度有點高。
直接分析旋轉後的陣列:
假定start, end, mid分別代表起始、末尾、中間索引
二分法思想:
-
如果 nums[mid] == target, 找到, 如果沒找到則確定target所在的索引範圍
-
如果 nums[start] <= num[mid]
-
可以證明start到mid是有序的且不存在滿足nums[start] <= x <= num[mid]的x在start和mid的外邊(反證法)
如果是target也滿足nums[start] <= target <= num[mid], 那麼target的索引在start和mid間 -
同理可以證明如果target不滿足上面的不等式, 那麼target的索引在mid+1和end之間
-
如果 nums[start] > num[mid]
-
可以證明mid+1到end是有序的且不存在滿足nums[mid+1] <= x <= num[end]的x在mid和end的外邊(反證法)
如果是target也滿足nums[mid+1] <= target <= num[end], 那麼target的索引在mid+1和end之間
-
-
同理可以證明如果target不滿足上面的不等式, 那麼target的索引在start和mid之間
程式碼
class Solution {
public:
int search(vector<int>& nums, int target) {
int start = 0;
int end = static_cast<int>(nums.size());
while (start != end) {
int mid = (start + end) / 2;
if (nums[mid] == target){
return mid;
}
if (nums[start] <= nums[mid]){
if (nums[start] <= target && target < nums[mid]){
end = mid;
} else {
start = mid + 1;
}
} else {
if (nums[mid] < target && target <= nums[end - 1]){
start = mid + 1;
} else {
end = mid;
}
}
}
return -1;
}
};