题目:和上题一样,只是放宽了条件,旋转数组中数字可以重复出现。
思路:由于上题中在判断有序时是根据mid元素值与首尾元素比较得到的,考虑这种情况,10111和11101都是01111的旋转数组,当首尾和中间元素都相等时,无法判断是mid前面的序列有序还是mid后面的序列有序,所以只好用顺序查找。
class Solution { public: bool search(vector<int>& nums, int target) { int first=0; int last=nums.size(); while(first<last) { int mid=first+(last-first)/2; if(nums[mid]==target) return true; if(nums[first]==nums[mid] && nums[mid]==nums[last-1])//当出现这种情况时,无法判断哪个序列有序,只好用顺序查找 注意这里还是last-1啊 return searchInOrder(nums,target); if(nums[first]<=nums[mid]) {//左边有序 if(nums[first]<=target && target<=nums[mid]) last=mid; else first=mid+1; } else {//右边有序 if(nums[mid]<=target && target<=nums[last-1]) first=mid+1; else last=mid; } } return false; } private: bool searchInOrder(const vector<int>& nums,int target) { for(int i=0;i<nums.size();++i) if(nums[i]==target) return true; return false; } };
另一思路也可借鉴:
分析 允许重复元素,则上一题中如果 A[m]>=A[l], 那么 [l,m] 为递增序列的假设就不能成立了,比 如 [1,3,1,1,1]。 如果 A[m]>=A[l] 不能确定递增,那就把它拆分成两个条件: • 若 A[m]>A[l],则区间 [l,m] 一定递增 • 若 A[m]==A[l] 确定不了,那就 l++,往下看一步即可。 代码 // LeetCode, Search in Rotated Sorted Array II // 时间复杂度 O(n),空间复杂度 O(1) class Solution { public: bool search(int A[], int n, int target) { int first = 0, last = n; while (first != last) { const int mid = first + (last - first) / 2; if (A[mid] == target) return true; if (A[first] < A[mid]) { if (A[first] <= target && target < A[mid]) last = mid; else first = mid + 1; } else if (A[first] > A[mid]) { if (A[mid] < target && target <= A[last-1]) first = mid + 1; else last = mid; } else //skip duplicate one first++; } return false; } };