C++實現(xiàn)LeetCode(33.在旋轉(zhuǎn)有序數(shù)組中搜索)
[LeetCode] 33. Search in Rotated Sorted Array 在旋轉(zhuǎn)有序數(shù)組中搜索
Suppose an array sorted in ascending order 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.
Your algorithm's runtime complexity must be in the order of O(log n).
Example 1:
Input: nums = [4,5,6,7,0,1,2], target = 0
Output: 4
Example 2:
Input: nums = [4,5,6,7,0,1,2], target = 3
Output: -1
這道題讓在旋轉(zhuǎn)數(shù)組中搜索一個給定值,若存在返回坐標(biāo),若不存在返回 -1。我們還是考慮二分搜索法,但是這道題的難點在于不知道原數(shù)組在哪旋轉(zhuǎn)了,還是用題目中給的例子來分析,對于數(shù)組 [0 1 2 4 5 6 7] 共有下列七種旋轉(zhuǎn)方法(紅色表示中點之前或者之后一定為有序的):
0 1 2 4 5 6 7
7 0 1 2 4 5 6
6 7 0 1 2 4 5
5 6 7 0 1 2 4
4 5 6 7 0 1 2
2 4 5 6 7 0 1
1 2 4 5 6 7 0
二分搜索法的關(guān)鍵在于獲得了中間數(shù)后,判斷下面要搜索左半段還是右半段,觀察上面紅色的數(shù)字都是升序的,可以得出出規(guī)律,如果中間的數(shù)小于最右邊的數(shù),則右半段是有序的,若中間數(shù)大于最右邊數(shù),則左半段是有序的,我們只要在有序的半段里用首尾兩個數(shù)組來判斷目標(biāo)值是否在這一區(qū)域內(nèi),這樣就可以確定保留哪半邊了,代碼如下:
解法一:
class Solution { public: int search(vector<int>& nums, int target) { int left = 0, right = nums.size() - 1; while (left <= right) { int mid = left + (right - left) / 2; if (nums[mid] == target) return mid; if (nums[mid] < nums[right]) { if (nums[mid] < target && nums[right] >= target) left = mid + 1; else right = mid - 1; } else { if (nums[left] <= target && nums[mid] > target) right = mid - 1; else left = mid + 1; } } return -1; } };
看了上面的解法,你可能會產(chǎn)生個疑問,為啥非得用中間的數(shù)字跟最右邊的比較呢?難道跟最左邊的數(shù)字比較不行嗎,當(dāng)中間的數(shù)字大于最左邊的數(shù)字時,左半段也是有序的啊,如下所示(藍(lán)色表示中點之前一定為有序的):
0 1 2 4 5 6 7
7 0 1 2 4 5 6
6 7 0 1 2 4 5
5 6 7 0 1 2 4
4 5 6 7 0 1 2
2 4 5 6 7 0 1
1 2 4 5 6 7 0
貌似也可以做,但是有一個問題,那就是在二分搜索中,nums[mid] 和 nums[left] 還有可能相等的,當(dāng)數(shù)組中只有兩個數(shù)字的時候,比如 [3, 1],那該去取那一邊呢?由于只有兩個數(shù)字且 nums[mid] 不等于 target,target 只有可能在右半邊出現(xiàn)。最好的方法就是讓其無法進(jìn)入左半段,就需要左半段是有序的,而且由于一定無法同時滿足 nums[left] <= target && nums[mid] > target,因為 nums[left] 和 nums[mid] 相等,同一個數(shù)怎么可能同時大于等于 target,又小于 target。由于這個條件不滿足,則直接進(jìn)入右半段繼續(xù)搜索即可,所以等于的情況要加到 nums[mid] > nums[left] 的情況中,變成大于等于,參見代碼如下:
解法二:
class Solution { public: int search(vector<int>& nums, int target) { int left = 0, right = nums.size() - 1; while (left <= right) { int mid = left + (right - left) / 2; if (nums[mid] == target) return mid; if (nums[mid] >= nums[left]) { if (nums[left] <= target && nums[mid] > target) right = mid - 1; else left = mid + 1; } else { if (nums[mid] < target && nums[right] >= target) left = mid + 1; else right = mid - 1; } } return -1; } };
到此這篇關(guān)于C++實現(xiàn)LeetCode(33.在旋轉(zhuǎn)有序數(shù)組中搜索)的文章就介紹到這了,更多相關(guān)C++實現(xiàn)在旋轉(zhuǎn)有序數(shù)組中搜索內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C++實現(xiàn)LeetCode(38.計數(shù)和讀法)
- C++實現(xiàn)LeetCode(51.N皇后問題)
- C++實現(xiàn)LeetCode(77.Combinations 組合項)
- C++實現(xiàn)LeetCode(46.全排列)
- C++實現(xiàn)LeetCode(37.求解數(shù)獨)
- C++實現(xiàn)LeetCode(36.驗證數(shù)獨)
- C++實現(xiàn)LeetCode(35.搜索插入位置)
- C++實現(xiàn)LeetCode(34.在有序數(shù)組中查找元素的第一個和最后一個位置)
- C++實現(xiàn)LeetCode(39.組合之和)
相關(guān)文章
Qt如何實現(xiàn)輸入框@聯(lián)系人的@檢測的示例
本文主要介紹了Qt如何實現(xiàn)輸入框@聯(lián)系人的@檢測的示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08詳解如何實現(xiàn)C++虛函數(shù)調(diào)用匯編代碼
多態(tài)是C++中最重要的特性之一,對虛函數(shù)的調(diào)用在C++代碼中是隨處可見的,本篇文章我們詳細(xì)探討一下,感興趣的朋友快來看看吧2021-11-11