Skip to content

二分查找

二分查找(Binary Search)简单来说就是折半,步骤就是,找到中间值,然后查找左右区间,一直递归下去。 二分查找的时间复杂度是O(logn)

基本框架

js
const binary = (arr) => {
  const left = 0, right = arr.length - 1
  where(left < right) {
    const mid = left + (right - left) >> 1
    if (arr[mid] < arr[left]) {
      // condition1 
    } else if(arr[right] < arr[mid]) {
      // condition2
    } else {
      // condition3
    }
  }
  // 结束
}

局限性

  • 二分查找依赖顺序表结构,二分查找针对的是有序数据
  • 数据量太小不适合二分查找:直接顺序遍历即可,没有太大优势
  • 数据量太大也不适合二分查找:如果查找1GB的数据,数组为了支持随机访问的特性,要求内存空间连续,对内存的要求比较苛刻。

实现indexOf

js
// 非递归实现,利用指针
var search = function(nums, target) {
 let left = 0
 let right = nums.length - 1
 while(left <= right) {
  const mid =  left + (right - left >> 1)
  if(nums[mid] == target) {
   return mid
  }
  if(nums[mid] < target) {
   left = mid + 1
  } else {
   right = mid - 1
  }
 }
 return -1
};

// 递归实现
var search = function(nums, target, l = 0, r = l.length - 1) {
  if(l > r) {
    return - 1
  }
  const mid = l + (l - r >> 1)
  if(nums[mid] = target) {
    return mid
  } else if(target[mid] < target) {
    search(nums, target, l, mid)
  } else {
    search(nums, target, mid+1, r)
  }
}

二分搜索

javascript
// 递归
function binarySearch(nums, target) {
    return executiveFn(nums, 0, nums.length - 1, target)
}

function executiveFn(nums, l, r, target) {
    // 找到中间点
    const m = parseInt(l + (r - l) / 2)
    // 判断返回条件
    if (nums[m] == target) {
        return m
    }
    // 递归左边或者右边
    if (nums[m] < target) {
        return executiveFn(nums, m + 1, l, target)
    }
    if (nums[m] > target) {
        return executiveFn(nums, r, m - 1, target)
    }
}

// 双指针
var search = function(nums, target) {
    let left = 0
    let right = nums.length - 1
    let mid
    if(nums.length == 1) {
        return nums[0] == target ? 0 : -1
    }
    while(left <= right) {
        mid =  left + parseInt((right - left)/2)
        if(nums[mid] == target) {
            return mid
        }
        if(nums[mid] < target) {
            left = mid + 1
        } else {
            right = mid - 1
        }
    }
    return -1
};

搜索插入位置

js
function searchInsert(nums, target) {
  const len = nums.length
  if (!len || target < nums[0]) {
    return 0
  } else if (target > nums[len - 1]) {
    return len
  }
  let start = 0, end = len - 1
  while (start < end) {
    const mid = (start + end) >> 1
    if (target > nums[mid]) {
      start = mid + 1
    } else {
      end = mid
    }
  }
  return start
}

搜索二维矩阵

TODO

寻找峰值

TODO

搜索旋转排序数组

TODO

寻找旋转排序数组中的最小值

TODO

Released under the MIT License.