LeetCode-33 search-in-rotated-sorted-array 搜尋旋轉排序陣列
題目連結
https://leetcode-cn.com/problems/search-in-rotated-sorted-array/
題意
對於一個升序排序的陣列,從某個位置截斷,然後直接拼在後面。看題目給的例子,還是比較直白的。
題解
其實題本身不難,做了一些中等難度的題,其實大部分都沒啥難度,簡單題反而有一些比較騷的。中等題很多都坑在略考驗碼速,有一個大數乘法、螺旋陣列的模擬等等,這個題也一樣,擼一堆程式碼,出一點錯就很蛋疼。
看評論有人吐槽直接遍歷也能搜出來答案= =因為要求時間複雜度是O(logn),並且是已經升序排序的陣列了,只是中間截斷了而已。那麼反過來,如果從截斷點開始分成兩個陣列,那麼對於單個數組就可以使用二分搜尋了,而二分搜尋恰是O(logn)的時間複雜度。
問題就是如何找到截斷點。很明顯,如果沒有截斷點的話,直接升序,對於i而言:arr[i-1] < arr[i] < arr[i+1]這個等式是恆成立的,題也說了不存在重複。如果存在i:arr[i - 1] > arr[i] || arr[i] > arr[i+1],那麼i就是截斷點,並且屬於後半陣列。所以,找到截斷點就是比較重要了。for迴圈遍歷就有點蛋疼了,仍然使用二分,可以先找截斷點。找到以後就將陣列分成左右兩部分,分別使用二分搜尋即可。
這個題情況非常多,所以剪枝能寫很多。例如分開二分搜尋的時候,如果第一個陣列就搜到答案了,那麼第二組就可以不搜尋了。如果在搜截斷點的時候就找到答案,那麼就可以直接結束了。等等。
另外我的程式碼是忽略了陣列元素小於3的資料,這些單獨拿出來計算了。主要是交的時候發現WA了,所以就拿出來單獨算。可能是搜截斷點的時候,陣列元素是2的時候各種越界吧,懶得寫了,所以就直接判斷了特殊情況= =。
Java 程式碼
class Solution { public static int flag; public static int len; public static int ans; public static void search(int left,int right,int[] nums){ if(left == right) return; int mid = (left+right)/2; if(mid == 0){ if(nums[mid] > nums[mid+1]){ flag = mid; return; } }else{ if(mid == len-1){ if(nums[mid] < nums[mid-1]){ flag = mid; return; } }else{ if(nums[mid] > nums[mid+1] || nums[mid] < nums[mid-1]){ flag = mid; return; } } } search(left,mid,nums); if(flag != -1) return; search(mid+1,right,nums); } public static void brain(int left,int right,int[] nums,int target){ if(left == right){ if(target == nums[left]){ ans = left; } return; } int mid = (left+right)/2; if(target == nums[mid]){ ans = mid; return; } if(target > nums[mid]){ brain(mid+1,right,nums,target); }else{ brain(left,mid,nums,target); } } public int search(int[] nums, int target) { flag = -1; ans = -1; len = nums.length; if(len == 0) return -1; if(len == 1){ if(target == nums[0]) return 0; return -1; } if(len == 2){ for(int i = 0;i < 2;i++){ if(target == nums[i]) return i; } return -1; } search(0,len-1,nums); if(flag == -1){ brain(0,len-1,nums,target); return ans; } if(nums[flag] == target) return flag; brain(0,flag,nums,target); if(ans != -1) return ans; brain(flag+1,len-1,nums,target); return ans; } }