题目
思路
- 此题的关键在于,需要清楚,左边的和右边的,哪边是可以放弃的。
 - 如果
nums[mid] < nums[right],说明[mid, right]必然有序 - 如果
nums[mid] > nums[right],说明[left, mid - 1]必然有序 - 利用有序区间的端点值,判断是不是在序列当中,如果在,那么放弃掉无序的一边,如果不在,放弃掉有序的一边。
 此题的二段性,体现在,一段里面包含target,另外一段不包含target
代码
class Solution {public:int search(vector<int>& nums, int target) {// 如果 nums[mid] < nums[right],说明[mid, right]必然有序// 如果 nums[mid] > nums[right],说明[left, mid - 1]必然有序// 利用有序区间的端点值,判断是不是在序列当中,如果在,那么放弃掉无序的一边,如果不在,放弃掉有序的一边// 此题的二段性,体现在,一段里面包含target,另外一段不包含targetint n = nums.size();int left = 0, right = n - 1;while (left < right) {int mid = (left + right + 1) / 2;// 如果右边有序if (nums[mid] < nums[right]) {// 如果右边符合要求,选择右边if (nums[mid] <= target && target <= nums[right]) {left = mid;// 如果右边不符合要求,选择左边} else {right = mid - 1;}// 如果左边有序} else {// 如果左边符合条件if (nums[left] <= target && target <= nums[mid - 1]) {right = mid - 1;// 如果左边不符合条件} else {left = mid;}}}if (nums[left] == target) {return left;} else {return -1;}}};
mid向上取整图示(mid在右区间)

class Solution {public:int search(vector<int>& nums, int target) {// 如果 nums[mid] < nums[right],说明[mid, right]必然有序// 如果 nums[mid] > nums[right],说明[left, mid - 1]必然有序// 利用有序区间的端点值,判断是不是在序列当中,如果在,那么放弃掉无序的一边,如果不在,放弃掉有序的一边// 此题的二段性,体现在,一段里面包含target,另外一段不包含targetint n = nums.size();int left = 0, right = n - 1;while (left < right) {int mid = (left + right) / 2;// 如果右边有序if (nums[mid] < nums[right]) {// 如果右边符合要求,选择右边if (nums[mid + 1] <= target && target <= nums[right]) {left = mid + 1;// 如果右边不符合要求,选择左边} else {right = mid;}// 如果左边有序} else {// 如果左边符合条件if (nums[left] <= target && target <= nums[mid]) {right = mid;// 如果左边不符合条件} else {left = mid + 1;}}}if (nums[left] == target) {return left;} else {return -1;}}};
mid向下取整图示(mid在左区间)
556
