< 算法基础 之 二分查找 >

news2024/10/2 3:31:41

在这里插入图片描述

算法基础 之 二分查找

  • 前言
  • 👉 “ 二分查找 ” 原理及实现
  • 👉 实际案例:
    • > 基础案例 - 搜索下标
      • 示例 1
      • 示例 2
    • 解决方案
    • > 进阶案例 - 搜索二维矩阵
      • 示例 1
      • 示例 2
    • 解决方案
  • 往期内容 💨

前言

在开发中,我们常常会需要查找某个顺序存储结构中的内容时,我们常常会直接使用Javascript中已经封装好的函数去查找或者辅助查找。

但是也由于封装的特性,我们对这种封装好的函数,比较难以控制其复杂度,包括其内部执行语句的庸余部分难以把控。所以,在算法中,诞生了二分查找这个算法概念。

二分查找(Binary Search)也叫作折半查找。二分查找有两个要求,一个是数列有序,另一个是数列使用顺序存储结构(比如数组)。

👉 “ 二分查找 ” 原理及实现

二分查找的实现原理非常简单,首要条件是要有一个有序的列表或者是一个顺序存储结构,如:数组,有序树状结构等。

但是如果没有,则该怎么办?可以使用排序算法进行排序,给二分查找创建先要条件。

升序数列为例,在数组 nums 中寻找目标值 target,对于特定下标 i,比较 nums[i]target 的大小:

  • 如果 nums[i] = target,则下标 i 即为要寻找的下标;

  • 如果 nums[i] > target,则 target 只可能在下标 i 的左侧,则需要将下次查找的结束下标 - 1;

  • 如果 nums[i] > target,则 target 只可能在下标 i 的右侧,则需要将下次查找的开始下标 + 1;

根据上面描述的理论,不难理解。

二分查找的做法是,定义查找的范围 [left,right],初始查找范围是整个数组。每次取查找范围的中点 mid,比较 nums[mid]target 的大小,如果相等则 mid 即为要寻找的下标,如果不相等则根据 nums[mid]target 的大小关系将查找范围缩小一半。

图解如下:

在这里插入图片描述

👉 实际案例:

> 基础案例 - 搜索下标

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

本题取自 leetcode 算法基础

示例 1

输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4

示例 2

输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1

解决方案

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var search = function(nums, target) {
    // 方法一:循环比对, 代码简洁明了,但在数据量大且需要自定义排查逻辑时,不太合适。 适用于简单数组筛查或非顺序数据结构筛查
    return nums.indexOf(target)
	return nums.findIndex(target)
	
    // 方法二: 二分查找,代码
    let left = 0, right = nums.length - 1

    while(left <= right) {
        const mid = Math.floor((right + left) / 2) | Math.floor((right - left) / 2) + left
        const curVal = nums[mid]
        if(curVal === target) return mid
        if(curVal > target) right = mid - 1
        else left = mid + 1
    }

    return -1
};

注意事项: 这里我们可能会有疑惑的地方,就是中间值的取值了。由于left和right都代表的是元素的下标,所以在取中间值的时候,按道理只需right/2 | (right - left) / 2就行,但是这求的是 right下标值的中间值,并非要求的数组中间值下标。 所以需要再加上left的原本的下标值。即: ( left + right ) / 2 或 ( right - left ) / 2 + left

> 进阶案例 - 搜索二维矩阵

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:

  • 每行的元素从左到右升序排列。
  • 每列的元素从上到下升序排列。

本题取自 leetcode 算法

示例 1

在这里插入图片描述

输入:matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 5
输出:true
示例 2:

示例 2

在这里插入图片描述

输入:matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 20
输出:false

解决方案

/**
 * @param {number[][]} matrix
 * @param {number} target
 * @return {boolean}
 */
var searchMatrix = function(matrix, target) {
    // 常规循环比对
    return matrix.some((item, i) => {
        if(item[0] > target) return false
        if(item[item.length - 1] < target) return false
        return item.indexOf(target) != -1
    })

    // 二分查找
    const getIndex = (nums = [], target = '') => {
        let left = 0, right = nums.length - 1
        while(left <= right) {
            let mid = Math.floor((left + right)/2)
            const val = nums[mid]
            if(val == target) return mid
            if(val > target) right = mid - 1
            else left = mid + 1
        }
        return -1
    }

    for(let cur of matrix) {
        if(cur.length == 0 ) continue
        let start = cur[0], end = cur[cur.length - 1]
        if(start <= target && end >= target && getIndex(cur, target) != -1) return true
    }
    return false
};

通过上述案例,相信各位卷王对 “ 二分查找 ”的概念也理解的七七八八了。 可以尝试去刷刷二分查找类型的算法题,巩固记忆吧!

点击跳转 LeetCode “ 二分查找 ” 类型题目

往期内容 💨

🔥 < CSS小技巧:filter滤镜妙用>

🔥 < JavaScript技术分享: 大文件切片上传 及 断点续传思路 >

🔥 < 每日技巧: JavaScript代码优化 >

🔥 < 每日知识点:关于Javascript 精进小妙招 ( Js技巧 ) >

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/348143.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java无重复字符的最长子串

给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”&#xff0c;所以其长度为 3。 示例 2: 输入: s “bbbbb” 输出: 1 解释: 因为无重复字符的最长子串是 “…

GEE学习笔记九十二:Sentinel-2 最新去云方法总结

下面使用例子的原始影像截图如下&#xff1a; 第一种方法&#xff1a;使用QA波段去云 这是我们最常用的方法&#xff0c;具体原理就是利用QA60波段标记实现去云&#xff0c;具体代码如下&#xff1a; var s2 ee.ImageCollection("COPERNICUS/S2"), point /* …

B树与B+树

B树 B树的定义 1970年&#xff0c;R.Bayer和E.mccreight提出了一种适用于外查找的树&#xff0c;它是一种平衡的多叉树&#xff0c;称为B树&#xff08;或B-树、B_树&#xff09;。我们描述一颗B树时需要指定它的阶数&#xff0c;阶数表示了一个结点最多有多少个孩子结点&…

[Android Studio]Android 数据存储--SQLite数据库存储

&#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea; Android Debug&#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea; Topic 发布安卓学习过程中遇到问题解决过程&#xff0c;希望我的解决方案可以对小伙伴们有帮助。 &#x1f4cb;笔记目…

Leetcode_part2

文章目录[406. 根据身高重建队列](https://leetcode.com/problems/queue-reconstruction-by-height/)Solution1 先排序 再插队[409. 最长回文串](https://leetcode.com/problems/longest-palindrome/)Solution1[415. 字符串相加](https://leetcode.com/problems/add-strings/)S…

上采样学习

最近邻 简单来说就是x方向和y方向分别复制 #!/usr/bin/env python # _*_ coding:utf-8 _*_ import numpy as np import torch from cv2 import cv2 from torch import nndef numpy2tensor(x: np.ndarray) -> torch.Tensor:"""(H,W) -> (1, 1, H, W)(H,W…

ShardingSphere-Proxy5按月分表

0、软件版本 ShardingSphere-Proxy&#xff1a; 5.2.0 MySQL&#xff1a; 8.0.30 系统&#xff1a; win10 1、ShardingSphere-Proxy下载 我们可以在 官网 找到最新版ShardingSphere-Proxy下载&#xff0c;也可以在ShardingSphere仓库中下载 2、ShardingSphere-Proxy配置 …

shell编程经典案例,建议收藏

1、编写hello world脚本 #!/bin/bash# 编写hello world脚本echo "Hello World!"2、通过位置变量创建 Linux 系统账户及密码 #!/bin/bash# 通过位置变量创建 Linux 系统账户及密码#$1 是执行脚本的第一个参数,$2 是执行脚本的第二个参数 useradd "$1" …

Linux C++ 200行完成线程池类

文章目录1、atomic使用2、volatile关键字3、条件变量4、成员函数指针使用5、线程池6、主线程先退出对子线程影响7、return、exit、pthread_exit区别8、进程和线程的区别1、atomic使用 原子操作&#xff0c;不可分割的操作&#xff0c;要么完整&#xff0c;要么不完整。 #includ…

vscode开发基于Vue的健身房管理系统node.js

该系统的基本功能包括管理员、会员、教练三个角色功能模块。 对于管理员可以使用的功能模块主要有首页、个人中心&#xff0c;系统公告管理、健身常识管理&#xff0c;会员管理、教练管理、教练考勤管理、会员咨询管理、商品信息管理、团课管理、团课预约管理、论坛管理、系统管…

十三、二叉排序树

1、先看一个需求 给你一个数列 {7, 3, 10, 12, 5, 1, 9} &#xff0c;要求能够高效的完成对数据的查询和添加 2、解决方案分析 使用数组 数组未排序&#xff0c;优点&#xff1a;直接在数组尾添加&#xff0c;速度快。缺点&#xff1a;查找速度慢 数组排序&#xff0c;优点&…

如何推出 NFT 游戏并获得收益?- 综合指南

NFT Gaming - 简介 - NFT 是代表独特内容所有权的数字资产&#xff0c;例如游戏中的一件艺术品或收藏品。它们建立在区块链解决方案之上&#xff0c;允许这些数字资产的真正所有权和稀缺性。 在游戏行业&#xff0c;NFT 用于创建玩家可以拥有和交易的独一无二的游戏内物品。这允…

政企服务机构如何进行数字化转型?

对于服务于政府和企业的产业机构来说&#xff0c;将政府政策和企业发展做完美匹配结合是其根本。在这个过程中&#xff0c;政策信息的准确性、前瞻性、核心价值是服务的基础&#xff0c;只有在政策下可行性高的解决方案才能为政府吸引更多的企业入驻。 那么该类产业机构该如何…

如何理解​session、cookie、token的区别与联系?

session、cookie、token。 相信学过接口的朋友都特别熟悉了。 但是对我一个刚接触接口测试的小白来说&#xff0c;属实有点分不清楚。 下文就是我通过查阅各种资料总结出来的一点理解&#xff0c;不准确的地方还请各位指正。 &#xff08;文末送洗浴中心流程指南&#xff09…

C语言(函数和递归)

函数是完成特定任务的独立程序代码单元。 目录 一.函数 1.创建一个简单的函数 2.定义带形式参数的函数 3.使用return从函数中返回值 二.递归 一.函数 1.创建一个简单的函数 #include <stdio.h> void print(void); //函数原型 int main(){ print(); //函…

Weblogic CVE之旅之T3协议浅学习

前言 这篇文章主要是学习Weblogic CVE漏洞中的过程中&#xff0c;对其中的一种利用方式T3协议反序列化漏洞进行分析。 前置 什么是T3协议&#xff1f; T3协议是一种Weblogic RMI 调用时的通信协议, 对于JAVA RMI(Remote Method Invocation) 来说&#xff0c;基础的通信协议…

Web前端:使用Angular CLI时的最佳实践和专业技巧

在web开发业务中&#xff0c;构建高性能的应用程序是首要因素。此外&#xff0c;用开发人员最流行的语言开发一个健壮的网站将始终为构建高功能的网站提供适当的基础网站。相比之下&#xff0c;不可否认&#xff0c;Angular CLI是建立得最好且正在成长的框架之一。Angular CLI简…

【蓝桥杯嵌入式】第十三届蓝桥杯嵌入式 国赛 程序设计试题以及详细题解

文章目录原题展示原题分析详细题解LED模块按键模块串口LCD模块模拟电压读取(ADC)脉冲输入输出文章福利原题展示 原题分析 本届国赛试题主要包含LCD、LED、按键、EEPROM、串口、模拟电压输入、脉冲输入输出七大部分&#xff0c;其中前面三个部分是蓝桥杯嵌入式的“亲儿子”(必考…

2023年妇女节是哪一天 妇女节是2023年几月几日?

2023年妇女节是哪一天是2023年几月几日&#xff1f; 2023年妇女节是2023年3月8日 三八妇女节是国家法定节假日吗&#xff1f; 妇女节不是国家法定节假日&#xff0c;而国家法定节假日包括&#xff1a;元旦、春节、清明节、劳动节、端午节、中秋节、国庆节&#xff1b; 关于三…

操作系统(day09) -- 连续分配管理方式

连续分配管理方式 单元连续分配 动态分区分配 1.系统要用什么样的数据结构记录内存的使用情况&#xff1f; 两种常用的数据结构 空闲分区表 每个空闲分区对应一个表项。表项中包含分区号、分区大小、分区起始地址等信息空闲分区链 每个分区的起始部分和末尾部分分别设置前向…