class Solution { public: bool search(int A[], int n, int target) { if (n < 1) return false; int pre = A[0]; int wpos = 1, rpos = 1; while (rpos < n) { if (A[rpos] == pre) { rpos++; } else { pre = A[wpos++] = A[rpos++]; } } n = wpos; int sep = A[n-1]; int left = -1, right = n; while (left + 1 < right) { int mid = (left + right) / 2; if (sep > A[mid]) { right = mid; sep = A[mid]; } else if (sep < A[mid]) { left = mid; } else { right = mid; break; } } return binary_search(A, right, target) || binary_search(A + right, n - right, target); } bool binary_search(int *a, int n, int target) { int left = -1, right = n; while (left + 1 < right) { int mid = (left + right) / 2; if (a[mid] > target) { right = mid; } else if (a[mid] < target) { left = mid; } else { return true; } } return false; } };
多了一步去重的步骤,复杂度没什么变化,只是这样做修改了输入数据
第二轮:
去重已经用了O(n)了,可以像无重复的时候一样先找到最小值,然后在非递减区间内二分搜索:
class Solution { public: bool search(vector<int>& nums, int target) { int len = nums.size(); int lo = 0; int hi = len - 1; while (lo < hi) { int mid = (lo + hi) / 2; if (nums[mid] > nums[hi]) { lo = mid + 1; } else if (nums[mid] < nums[hi]) { hi = mid; } else { if (lo != 0 && nums[lo] < nums[lo - 1]) { break; } lo++; } } return binary_search(nums, 0, lo, target) != -1 || binary_search(nums, lo, len, target) != -1; } int binary_search(vector<int>& nums, int start, int end, int target) { int lo = start; int hi = end; while (lo < hi) { int mid = (lo + hi) / 2; if (nums[mid] < target) { lo = mid + 1; } else if (nums[mid] > target) { hi = mid; } else { return mid; } } return -1; } };