C++實(shí)現(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ù)組中搜索一個(gè)給定值,若存在返回坐標(biāo),若不存在返回 -1。我們還是考慮二分搜索法,但是這道題的難點(diǎn)在于不知道原數(shù)組在哪旋轉(zhuǎn)了,還是用題目中給的例子來(lái)分析,對(duì)于數(shù)組 [0 1 2 4 5 6 7] 共有下列七種旋轉(zhuǎn)方法(紅色表示中點(diǎ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ù),則左半段是有序的,我們只要在有序的半段里用首尾兩個(gè)數(shù)組來(lái)判斷目標(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;
}
};
看了上面的解法,你可能會(huì)產(chǎn)生個(gè)疑問(wèn),為啥非得用中間的數(shù)字跟最右邊的比較呢?難道跟最左邊的數(shù)字比較不行嗎,當(dāng)中間的數(shù)字大于最左邊的數(shù)字時(shí),左半段也是有序的啊,如下所示(藍(lán)色表示中點(diǎ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
貌似也可以做,但是有一個(gè)問(wèn)題,那就是在二分搜索中,nums[mid] 和 nums[left] 還有可能相等的,當(dāng)數(shù)組中只有兩個(gè)數(shù)字的時(shí)候,比如 [3, 1],那該去取那一邊呢?由于只有兩個(gè)數(shù)字且 nums[mid] 不等于 target,target 只有可能在右半邊出現(xiàn)。最好的方法就是讓其無(wú)法進(jìn)入左半段,就需要左半段是有序的,而且由于一定無(wú)法同時(shí)滿足 nums[left] <= target && nums[mid] > target,因?yàn)?nums[left] 和 nums[mid] 相等,同一個(gè)數(shù)怎么可能同時(shí)大于等于 target,又小于 target。由于這個(gè)條件不滿足,則直接進(jìn)入右半段繼續(xù)搜索即可,所以等于的情況要加到 nums[mid] > nums[left] 的情況中,變成大于等于,參見(jiàn)代碼如下:
解法二:
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++實(shí)現(xiàn)LeetCode(33.在旋轉(zhuǎn)有序數(shù)組中搜索)的文章就介紹到這了,更多相關(guān)C++實(shí)現(xiàn)在旋轉(zhuǎn)有序數(shù)組中搜索內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C++實(shí)現(xiàn)LeetCode(38.計(jì)數(shù)和讀法)
- C++實(shí)現(xiàn)LeetCode(51.N皇后問(wèn)題)
- C++實(shí)現(xiàn)LeetCode(77.Combinations 組合項(xiàng))
- C++實(shí)現(xiàn)LeetCode(46.全排列)
- C++實(shí)現(xiàn)LeetCode(37.求解數(shù)獨(dú))
- C++實(shí)現(xiàn)LeetCode(36.驗(yàn)證數(shù)獨(dú))
- C++實(shí)現(xiàn)LeetCode(35.搜索插入位置)
- C++實(shí)現(xiàn)LeetCode(34.在有序數(shù)組中查找元素的第一個(gè)和最后一個(gè)位置)
- C++實(shí)現(xiàn)LeetCode(39.組合之和)
相關(guān)文章
C/C++實(shí)現(xiàn)FTP文件上傳下載的示例詳解
FTP(文件傳輸協(xié)議)是一種用于在網(wǎng)絡(luò)上傳輸文件的標(biāo)準(zhǔn)協(xié)議,這篇文章主要為大家詳細(xì)介紹了C++如何實(shí)現(xiàn)FTP文件上傳下載功能,需要的小伙伴可以參考下2023-12-12
C語(yǔ)言中判斷int,long型等變量是否賦值的方法詳解
聲明了int ,long型等局部變量,在利用一些方法給這些變量賦值之后,想判斷這些變量是不是真的被賦初值了,怎么辦2013-07-07
Visual Studio 2022中創(chuàng)建的C++項(xiàng)目無(wú)法使用萬(wàn)能頭<bits/stdc++.h>的
如果大家也遇到下面這種問(wèn)題,可能是沒(méi)有include文件夾中沒(méi)有bits/stdc++.h,這篇文章主要介紹了Visual Studio 2022中創(chuàng)建的C++項(xiàng)目無(wú)法使用萬(wàn)能頭<bits/stdc++.h>的解決方案,感興趣的朋友跟隨小編一起看看吧2024-02-02
C語(yǔ)言實(shí)現(xiàn)運(yùn)籌學(xué)中的馬氏決策算法實(shí)例
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)運(yùn)籌學(xué)中的馬氏決策算法,簡(jiǎn)單介紹了馬氏決策的概念,并結(jié)合實(shí)例形式分析了C語(yǔ)言實(shí)現(xiàn)馬氏決策算法的具體實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-09-09
C語(yǔ)言實(shí)現(xiàn)用戶態(tài)線程庫(kù)案例
下面小編就為大家?guī)?lái)一篇C語(yǔ)言實(shí)現(xiàn)用戶態(tài)線程庫(kù)案例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-05-05

