代码随想录算法训练营第一天|704、27

100 阅读1分钟

二分查找

本质就是每次取半查找。通过比较中间值和目标值来确定查找范围。当比较的范围为空时停止。

局限性:得是有序数组

简单的二分查找

  • 数组中没有重复元素
  • 注意边界判断 --- 左闭右闭 左闭右开

leetcode 704

// 左闭右闭
/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var search = function(nums, target) {
    let left = 0
    let right = nums.length - 1
    while(left <= right){
        let mid = left + ((right - left) >> 1);
        if(nums[mid] < target){
            left = mid +1
        }else if(nums[mid] > target){
            right = mid -1
        }else{
            return mid
        }
    }
    return -1
};
//左闭右开
var search = function(nums, target) {
    let left = 0
    let right = nums.length
    while(left < right){
        let mid = left + ((right - left) >> 1);
        if(nums[mid] < target){
            left = mid +1
        }else if(nums[mid] > target){
            right = mid
        }else{
            return mid
        }
    }
    return -1
};

tips:

  • 为什么取中值要这样写 let mid = left + ((right - left) >> 1)?

    越界问题,计算机的整数型也有max值,如果right+left超过(虽然不太可能),结果可能会不准确。

  • 左闭右闭和左闭右开有啥区别?

    左闭右闭的时候,是合法区间,里面还是有元素的,所以还是要进行循环。

    左闭右开的时候,left和right相等的话,是不合法区间。

leetcode 27

// 快慢指针
/**
 * @param {number[]} nums
 * @param {number} val
 * @return {number}
 */
var removeElement = function(nums, val) {
  let k =0;
  for(let i =0;i<nums.length;i++){
      if(nums[i] !== val){
          nums[k] = nums[i]
          k++
      }
  }
  return k
};

好吧...自己写的时候也并没有意识到这是双指针。 将不是目标的元素移到最前面。