1题目分析
本题是上面的升级版,即搜索含有重复字符的循环数组
2.解题思路
先看version1的题目吧,不含重复字符的循环数组搜索。
思路1.
暴力for循环 AC
思路2.
既然Rotate了,找到突变位置,将所有下标进行平移,再二分查找。
思路3.
其实可以不用平移的,我们看图就明白了(此题升序是隐藏条件,真坑)
就这两种情况。
对着图直接上代码
int search(vector<int>& nums, int target) { int l, r, mid; l = 0; r = nums.size() - 1; while(l <= r){ mid = (r + l) / 2; if(nums[mid] == target){ return mid; } if(target > nums[mid]){ if(nums[r] => target || nums[r] < nums[mid]){ l = mid + 1; } else{ r = mid - 1; } } if(target < nums[mid]){ if(nums[l] <= target || nums[l] > nums[mid]){ r = mid - 1; } else{ l = mid + 1; } } } return -1; }
好,有了version1的思路后,再看看version2。
version2是重复字符的,想象之前的示意图,就是线上多了几个“平台”(平行X轴的线)。而假若平台在中间,不影响判定。假若平台在两边,只需将下标跳过平台,一切就转换为version1了。直接上AC代码。
bool search(vector<int>& nums, int target) { int l, r, mid; l = 0; r = nums.size() - 1; while(l <= r){ mid = (r + l) / 2; if(nums[mid] == target){ return true; } while(nums[l] == nums[l + 1] && l <= mid){ l++; } if(l == mid + 1){ continue; } while(nums[r] == nums[r - 1] && r >= mid){ r--; } if(r == mid - 1){ continue; } mid = (l + r) / 2; if(target > nums[mid]){ if(nums[r] >= target || nums[r] < nums[mid]){ l = mid + 1; } else{ r = mid - 1; } } if(target < nums[mid]){ if(nums[l] <= target || nums[l] > nums[mid]){ r = mid - 1; } else{ l = mid + 1; } } } return false; }
时间: 2024-10-11 23:03:31