[array] leetcode - 33. Search in Rotated Sorted Array - Medium
2017-11-15 23:13
676 查看
leetcode - 33. Search in Rotated Sorted Array - Medium
descrition
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.
解析
两种方法的时间复杂度和空间复杂度都是一样的,不过思考的思路有所不同,不过根本都是对二分查找的改进。方法 1 对应代码 int searchDirectly(vector注意点:
当 target 找不到的时候返回 -1
可以假设数组中的元素都是唯一的 (这是代码优化的关键!)
一般的:
直接在原数组上进行二分查找。对于数组 arry[0,...,n-1] 可以将其分成两个部分 left_part = arry[0,...,imax], right_part=arry[imax+1, ..., n-1],其中 imax 指向数组中最大的元素,那么 left_part 和 right_part 都是递增的,并且 left_part 中所有的值都大于 right_part 中的值。
对于 binary search,假设 [ileft, ... , irigt] 确定 arry 中的一个子数组。下面就讨论,我们如何在每次查找中将查找空间减少一半的思路。
每次而分查找我们需要计算 imid = (ileft + iright) / 2,即中间元素的位置,将数组均分成两半。这时我们可以根据 imid 的位置来确定下一次的查找范围。
condition1: 如果 arry[ileft] < arry[imid] : 说明 imid 在 left_part 的 ascending 子数组中
condition2: 如果 arry[imid] < arry[irigh] : 说明 imid 在 rigt_part 的 ascending 子数组中
注意:因为 left_part < right_part ,因此以上两种情况是对立的。如果 ileft, imid, iright 指向的 3 个数相等,我们将无法判断 imid 处在数组的那个部分,也就无法达到划分的目的,这是题意的关键优化点。
方法 1
如果 condition1 成立,那么 [ileft, ..., imid] 是递增有序的如果 target 在 [ileft, ..., imid] 区间内,则 ileft = imid-1
否则 ileft = imid + 1
如果 condition2 成立,那么 [imid, ..., iright] 是递增有序的
如果 target 在 [imid, ..., iright] 区间内,则 ileft = imid + 1
否则 iright = imid - 1
每一次查找都能使搜索空间减半。具体实现看代码,注意细节和边界条件。
方法 2
我们可以先找到数组中最小值的位置 imin,那么相对于原来递增有序的数,新的 rotated 数组中元素的位置 i' = (i + imin)%n。比如 4 5 6 7 0 1 2, imin = 4,相当于原数组 0 1 2 4 5 6 7 循环右移了 imin 步。找最小值的位置也是使用折半查找的思想,时间复杂度 O(log(n))。针对原数组 0 1 2 4 5 6 7 使用而分查找,每次而分查找比较时,使用 i' = (i + imin)%n 计算真是的 middle 位置。这样可以达到减办的效果。时间复杂度 O(log(n)) 。
具体实现查看代码。虽然这样的方法比钱前一种方法来说代码量大,实际上做了两次而分查找,但这里新地址的映射方式是个很好的思考思路。
code
#include <iostream> #include <vector> #include <algorithm> using namespace std; class Solution{ public: int search(vector<int>& nums, int target){ // You may assume no duplicate exists in the array. //return searchDirectly(nums, target); return searchAssist(nums, target); } // time-O(log(n)), space-O(1) int searchDirectly(vector<int>& nums, int target){ int ileft = 0; int iright = nums.size()-1; while(ileft <= iright){ int imid = (ileft+iright)/2; if(nums[imid] == target){ return imid; } // nums[imid] != target if(nums[ileft] <= nums[imid]){ // nums[ileft,...,imid] is ascending // Note: don't forget to check nums[ileft] == target if(nums[ileft] <= target && target < nums[imid]){ iright = imid - 1; }else{ ileft = imid + 1; } }else{ // nums[imid] < nums[iright] // nums[imid,...,iright] is ascending // Note: don't forget to check target == nums[iright] if(nums[imid] < target && target <= nums[iright]){ ileft = imid + 1; }else{ iright = imid - 1; } } } return -1; } // time-O(log(n)), space-O(1) int searchAssist(vector<int>& nums, int target){ if(nums.empty()) return -1; // the number of rotated of each element in nums int irotated = findMinInRotatedArray(nums); int n = nums.size(); int ileft = 0; int iright = nums.size() - 1; while(ileft <= iright){ int imid = (ileft + iright) / 2; int imidReal = (imid + irotated) % n; // calculate the real index of middle value if(nums[imidReal] == target){ return imidReal; }else if (nums[imidReal] < target){ ileft = imid + 1; }else{ // nums[imidReal] > target iright = imid - 1; } } return -1; } int findMinInRotatedArray(vector<int>& nums){ if(nums.empty()) return -1; if(nums[0] < nums[nums.size()-1]) // nums in ascending return 0; // binary search int ileft = 0; int iright = nums.size() - 1; while(ileft+1 < iright){ int imid = (ileft + iright) / 2; if(nums[ileft] < nums[imid]){ ileft = imid; }else{ // nums[imid] < nums[iright] iright = imid; } } // ileft point to the maximum // iright point to the minimum return iright; } }; int main() { return 0; }
相关文章推荐
- leetcode 33[medium]---Search in Rotated Sorted Array
- LeetCode - 33. Search in Rotated Sorted Array
- leetcode33~Search in Rotated Sorted Array
- 【LeetCode】33. Search in Rotated Sorted Array (4 solutions)
- Leetcode 81. Search in Rotated Sorted Array II (Medium) (cpp)
- LeetCode 33.Search in Rotated Sorted Array
- LeetCode 33 Search in Rotated Sorted Array(循环有序数组中进行查找操作)
- Leetcode-33.Search in Rotated Sorted Array.
- LeetCode - 33. Search in Rotated Sorted Array
- [LeetCode] 33. Search in Rotated Sorted Array
- LeetCode33——Search in Rotated Sorted Array
- 【Leetcode】33. Search in Rotated Sorted Array
- [leetcode]33. Search in Rotated Sorted Array
- Leetcode[33]-Search in Rotated Sorted Array
- leetcode题解-33 Search in Rotated Sorted Array
- leetcode 33. Search in Rotated Sorted Array __java
- Leetcode||33. Search in Rotated Sorted Array
- LeetCode --- 33. Search in Rotated Sorted Array
- LeetCode 33. Search in Rotated Sorted Array
- [leetcode] 33. Search in Rotated Sorted Array 解题报告