Iwen's blog Iwen's blog
首页
  • 前端文章

    • JavaScript
    • Vue
  • 学习笔记

    • 《JavaScript教程》笔记
    • 《JavaScript高级程序设计》笔记
    • 《ES6 教程》笔记
    • 《Vue》笔记
    • 《TypeScript 从零实现 axios》
    • 小程序笔记
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • Linux
  • 学习
  • 面试
  • 心情杂货
  • 友情链接
  • 网站
  • 资源
  • Vue资源
  • 分类
  • 标签
  • 归档
复盘
关于

Iwen

不摸鱼的哥哥
首页
  • 前端文章

    • JavaScript
    • Vue
  • 学习笔记

    • 《JavaScript教程》笔记
    • 《JavaScript高级程序设计》笔记
    • 《ES6 教程》笔记
    • 《Vue》笔记
    • 《TypeScript 从零实现 axios》
    • 小程序笔记
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • Linux
  • 学习
  • 面试
  • 心情杂货
  • 友情链接
  • 网站
  • 资源
  • Vue资源
  • 分类
  • 标签
  • 归档
复盘
关于
  • Vue

  • Vue进阶

  • CSS

  • ES6

  • Base

  • Core

  • Array

  • Object

  • String

  • Async

  • Browser

  • Http

  • 性能优化

  • 正则

  • 经典总结

  • 设计模式

  • 数据结构

  • 算法

    • 复杂度
    • 排序算法
    • 二分搜索
      • 搜索实现
      • 寻找左侧边界的二分搜索
      • 剑指 Offer 53 - II. 0~n-1中缺失的数字
    • 链表
  • 手写

  • TypeScript

  • 复盘
  • 算法
Mr.w
2020-11-29

二分搜索

# 二分搜索

# 搜索实现

function binarySearch(nums, target){
    var left = 0,
        right = nums.length - 1;

    while(left <= right){  
        var mid = Math.floor((left+right)/2);
        if(nums[mid] == target){
            return mid
        }else if(nums[mid] < target){
            left = mid + 1
        }else if(nums[mid] > target){
            right = mid - 1
        }
    }
    return -1
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  1. 循环退出条件是left <= right,注意是<=

因为初始化 right 的赋值是 nums.length - 1,即最后一个元素的索引,而不是 nums.length。

我们这个算法中使用的是前者 [left, right] 两端都闭的区间。这个区间其实就是每次进行搜索的区间。

  1. mid 的取值 Math.floor((low+high)/2) ?

二分法最大的特征, 就是一分为二, 再以中位数为坐标, 来确定选择左边还是右边

  1. 为什么 left = mid + 1,right = mid - 1?

刚才明确了「搜索区间」这个概念,而且本算法的搜索区间是两端都闭的,即 [left, right]。那么当我们发现索引 mid 不是要找的 target 时,下一步应该去搜索哪里呢?

当然是去搜索 [left, mid-1] 或者 [mid+1, right] 对不对?因为 mid 已经搜索过,应该从搜索区间中去除。

  1. 此算法的缺陷

比如说给你有序数组 nums = [1,2,2,2,3],target 为 2,此算法返回的索引是 2,没错。但是如果我想得到 target 的左侧边界,即索引 1,或者我想得到 target 的右侧边界,即索引 3,这样的话此算法是无法处理的。

我们后续的算法就来讨论这两种二分查找的算法。

# 寻找左侧边界的二分搜索

function left_bound(nums, target){
    if(nums.length == 0){
        return -1
    }
    var left = 0,
        right = nums.length;
    
    while(left < right){
        var mid = Math.floor((left+right)/2);
        if(nums[mid] == target){
            
        }
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 剑指 Offer 53 - II. 0~n-1中缺失的数字

一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。

function missingNumber(nums) {
    var left = 0,
        right = nums.length - 1;
    
    while(left <= right){
        var mid = Math.floor((left + right) / 2)
        if(mid == nums[mid]){
            left = mid + 1
        }else if(mid < nums[mid]){
            right = mid - 1
        }
    }
    return left
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  • left 指向 0,right 指向最后一个元素
  • 计算中间坐标 mid:
    • 如果mid = nums[mid],说明[0, mid]范围内不缺失数字,left 更新为 mid + 1
    • 如果mid < nums[mid],说明[mid, right]范围内不缺失数字,right 更新为 mid - 1
  • 检查 left 是否小于等于 mid,若成立,返回第 2 步;否则,向下执行
  • 返回 left 即可

注意,根据题意,可以知道mid > nums[mid]这种情况不存在。

排序算法
链表

← 排序算法 链表→

最近更新
01
flex布局页面自适应滚动条问题
12-28
02
前后端分离开发请求接口跨域如何携带cookie的问题
12-28
03
怎么实现div长宽比固定width-height4比3
12-28
更多文章>
Theme by Vdoing | Copyright © 2017-2022 Iwen | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式