LeetCode 刷題 [C++] 第33題. 搜尋旋轉排序陣列 (二分法+簡潔易懂)
題目描述
給你一個整數陣列 nums ,和一個整數 target 。
該整數陣列原本是按升序排列,但輸入時在預先未知的某個點上進行了旋轉。(例如,陣列 [0,1,2,4,5,6,7] 可能變為 [4,5,6,7,0,1,2] )。
請你在陣列中搜尋 target ,如果陣列中存在這個目標值,則返回它的索引,否則返回 -1 。
示例 1:
輸入:nums = [4,5,6,7,0,1,2], target = 0
輸出:4
示例 2:
輸入:nums = [4,5,6,7,0,1,2], target = 3
輸出:-1
示例 3:
輸入:nums = [1], target = 0
輸出:-1
提示:
1 <= nums.length <= 5000
-10^4 <= nums[i] <= 10^4
nums 中的每個值都 獨一無二
nums 肯定會在某個點上旋轉
-10^4 <= target <= 10^4
解題思路
首先就是暴力求解法:順序遍歷陣列,比較每個元素,時間複雜度為O(N)。
如果要在時間複雜度為O(logN)的條件下解決該題,則需要用到二分法查詢,首先給出二分法程式碼模板:
int binarySearch(const 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;
else if(nums[mid] < target) left = ++mid;
else right = --mid;
}
return -1;
}
解題步驟:
一般情況下,二分法存在left,right,mid位,來輔助判斷。因此,二分法解決該題的步驟如下:
- 如果target 在[mid+1,right]序列中,則left = mid+1,否則 right = mid;
- 關鍵是如何判斷 target在[mid+1,right]序列中,具體判斷如下:
當[0, mid] 序列是升序: nums[0] <= nums[mid], 當target > nums[mid] || target < nums[0] ,則向後規約;
當[0, mid] 序列存在旋轉位: nums[0] > nums[mid],當target < nums[0] && target > nums[mid],則向後規約;
當然其它情況就是向前規約了; - 迴圈判斷,直到排除到只剩最後一個元素時,退出迴圈,如果該元素和 target 相同,直接返回下標,否則返回 -1。
根據解題思路套用二分法模板,具體程式碼實現如下:
class Solution {
public:
int search(vector<int>& nums, int target) {
int L=0,R=nums.size()-1;
while(L<R) {
int mid = L + (R-L)/2;
if( nums[0] <= nums[mid] && ( target > nums[mid] || target < nums[0]))
L = ++mid;
else if( target > nums[mid] && target < nums[0])
L = ++mid;
else
R = mid;
}
return L==R && nums[L]==target ? L : -1;
}
};
AC結果:
利用異或對判斷條件語句進行簡化,簡化後的寫法如下:
class Solution {
public:
int search(vector<int>& nums, int target) {
int L=0,R=nums.size()-1;
while(L<R) {
int mid = L + (R-L)/2;
if((nums[0] > target) ^ (nums[0] > nums[mid]) ^ (target > nums[mid]))
L = ++mid;
else
R = mid;
}
return L==R && nums[L]==target ? L : -1;
}
};
AC結果:
複雜度分析:
- 時間複雜度:二分查詢,時間複雜度為O(logN);
- 空間複雜度:空間複雜度為O(1)。
相關文章
- LeetCode 33——搜尋旋轉排序陣列LeetCode排序陣列
- LeetCode33. 搜尋旋轉排序陣列LeetCode排序陣列
- LeetCode#33搜尋旋轉排序陣列LeetCode排序陣列
- LeetCode33 搜尋旋轉排序陣列LeetCode排序陣列
- 【LeetCode(Java) - 33】搜尋旋轉排序陣列LeetCodeJava排序陣列
- leetCode33搜尋旋轉排序陣列LeetCode排序陣列
- LeetCode 熱題 HOT 100 Java題解——33. 搜尋旋轉排序陣列LeetCodeJava排序陣列
- 力扣·33. 搜尋旋轉排序陣列力扣排序陣列
- LeetCode 81——搜尋旋轉排序陣列 IILeetCode排序陣列
- leetcode, LC68:旋轉排序陣列搜尋LeetCode排序陣列
- 33、搜尋旋轉排序陣列 | 演算法(leetode,附思維導圖 + 全部解法)300題排序陣列演算法
- 力扣-81. 搜尋旋轉排序陣列 II力扣排序陣列
- LeetCode刷題—陣列LeetCode陣列
- LeetCode每日一題: 旋轉陣列(No.189)LeetCode每日一題陣列
- LeetCode-153-尋找旋轉排序陣列中的最小值LeetCode排序陣列
- 【LeetCode】153. 尋找旋轉排序陣列中的最小值LeetCode排序陣列
- LeetCodeHot100 二分查詢 35. 搜尋插入位置 74. 搜尋二維矩陣 34. 在排序陣列中查詢元素的第一個和最後一個位置 33. 搜尋旋轉排序陣列 153. 尋找旋轉排序陣列中的最小值LeetCode矩陣排序陣列
- LeetCode 189 旋轉陣列LeetCode陣列
- leetcode 刷題之深度優先搜尋LeetCode
- 我請大家來刷題:旋轉陣列的最小數字陣列
- 【LeetCode】189. 旋轉陣列LeetCode陣列
- LeetCode-189-旋轉陣列LeetCode陣列
- 153. 尋找旋轉排序陣列中的最小值排序陣列
- LeetCode刷題之第701題LeetCode
- 【Leetcode刷題篇】leetcode152 乘積最大陣列LeetCode陣列
- 153. 尋找旋轉排序陣列中的最小值(中)排序陣列
- LeetCode第4題:尋找兩個有序陣列的中位數LeetCode陣列
- [LeetCode 刷題] 4. 尋找兩個有序陣列的中位數 (Hard)LeetCode陣列
- leetcode排序專題演算法刷題LeetCode排序演算法
- 第二章 :查詢與排序-------2.17解題實戰_旋轉陣列的最小數字(改造二分法)排序陣列
- LeetCode每日一題: 按奇偶排序陣列(No.905)LeetCode每日一題排序陣列
- 【刷題筆記】LeetCode-53 最大子陣列和筆記LeetCode陣列
- leetcode題解(陣列問題)LeetCode陣列
- LeetCode將有序陣列轉化為二叉搜尋樹--JavaLeetCode陣列Java
- LeetCode每日一題: 按奇偶排序陣列 II(No.27)LeetCode每日一題排序陣列
- LeetCode解題(C++)-4. 尋找兩個有序陣列的中位數LeetCodeC++陣列
- LeetCode C++ 56. Merge Intervals【排序/陣列】中等LeetCodeC++排序陣列
- LeetCode刷題記錄與題解(C++版本)LeetCodeC++