📉

二分

前提:数组有序,无重复元素。
在循环中需要始终坚持根据查找区间的定义来做边界处理
循环不变量原则:区间的定义就是不变量,在循环中坚持根据查找区间的定义来做边界处理
 
右移一位和除2的区别
  • n为非负数时,结果一样
  • n为负数且还是偶数时,结果一样
  • n为负数且还是奇数时,结果不一样
使用位运算是为了防止两个int相加时溢出。
 
  • 左闭右闭即[left, right]
class Solution { public:    int search(vector<int>& nums, int target) {        int left = 0;        int right = nums.size() - 1; // 定义target在左闭右闭的区间里,[left, right]        while (left <= right) { // 当left==right,区间[left, right]依然有效,所以用 <=            int middle = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2            if (nums[middle] > target) {                right = middle - 1; // target 在左区间,所以[left, middle - 1]           } else if (nums[middle] < target) {                left = middle + 1; // target 在右区间,所以[middle + 1, right]           } else { // nums[middle] == target                return middle; // 数组中找到目标值,直接返回下标           }       }        // 未找到目标值        return -1;   } };
  • 左闭右开[left, right)
class Solution { public:    int search(vector<int>& nums, int target) {        int left = 0;        int right = nums.size(); // 定义target在左闭右开的区间里,即:[left, right)        while (left < right) { // 因为left == right的时候,在[left, right)是无效的空间,所以使用 <            int middle = left + ((right - left) >> 1);            if (nums[middle] > target) {                right = middle; // target 在左区间,在[left, middle)中           } else if (nums[middle] < target) {                left = middle + 1; // target 在右区间,在[middle + 1, right)中           } else { // nums[middle] == target                return middle; // 数组中找到目标值,直接返回下标           }       }        // 未找到目标值        return -1;   } };