JavaScript:数组---二分法

文章目录

  • 二分法
    • 704 二分查找
      • 思路
    • 35.搜索插入位置
      • 四种情况
      • 思路一
      • 思路二
    • 34. 在排序数组中查找元素的第一个和最后一个位置✨
      • 关键在于分析一些细节
      • 解析看代码注释
    • 总结二分法

二分法

来自leetcode

704 二分查找

思路

  1. 利用在右指针:设置target可选范围
  2. 比较目标值 和 中间值 来缩小可选范围
  3. 找到目标值 返回下标 没找到 返回 -1

本体较为简单,主要是二分的方法要知道,以及 可选区间的开闭

/*
 * @lc app=leetcode.cn id=704 lang=javascript
 *
 * [704] 二分查找
 */

// @lc code=start
/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var search = function(nums, target) {
    let left = 0, right = nums.length - 1
    while(left <= right) {
        let mid = left + Math.floor((right - left)/2)
        if(target > nums[mid]) {
            left = mid + 1
        } else if(target < nums[mid]) {
            right = mid - 1
        } else {
            return mid
        }
    }
    return -1
};
// @lc code=end


35.搜索插入位置

四种情况

  1. 目标值在数组所有元素之前
  2. 目标值等于数组中某一个元素
  3. 目标值插入数组中的位置
  4. 目标值在数组所有元素之后

思路一

二分法 找目标值

  • 找到就是按照二分查找的方法
  • 没找到:插入元素
    • 在可选范围里面: 举例分析插在mid后面即可
    • 如果不在范围内 就两端位置
/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var searchInsert = function(nums, target) {

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

思路二

重点代码注释

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var searchInsert = function(nums, target) {
    // 开始还是二分查找 缩小区间
    // 找得到目标就是索引
    // 找不到目标值 插入地方:与mid比较,最后位置肯定会取代mid
    // 当正好到< mid1 > mid2时,位置就确定好了  mid1
    // 注意ant初始值
    // 为什么初始值是nums.length:因为当target>nums[mid]一致都大于的时候,我们这里就直接放在末尾,也就是ant初始值
    let left = 0, right = nums.length - 1
    let ant = nums.length
    while(left <= right) {
        const mid = left + Math.floor((right - left) / 2)
        if(target > nums[mid]) left = mid + 1
        else if (target < nums[mid]) {
            ant = mid
            right = mid - 1
        }
        else return mid
    }
    return ant
};

34. 在排序数组中查找元素的第一个和最后一个位置✨

关键在于分析一些细节

  1. 左右边界分开查找使用二分
  2. target的三种情况划分
  3. 临界值的设置也很关键,为什么不是-1,而是-2
  4. 我们这里的设置的边界值不包括target,为什么不包括

解析看代码注释

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
 // -1 -2 0 0 0 4 5 8
var searchRange = function(nums, target) {
    // 左右边界分开找 
    /**
    三种情况:1 target范围在最左边最右边 不存在目标值 返回[-1,-1] 
             2 target范围在中间    但不存在目标值 返回[-1,-1]
             3 target在范围里面且存在  返回 位置下标
     */
    /**
     我们这里的设置的边界值不包括target,为什么不包括?
     如果只有一个符合条件的时候,我们此时lB,rB也不会重合相等
     如果重合相等说明了没有目标值,也就是我们的情况二
     边界值初始值为什么不是-1?
     因为如果-1,在最左边是可能存在target的([3,3,4,5] target = 3,此时lB = -1),所以我们设为-2
     */

    // 左边界: mid 位置 一直 >= target 最终,到临界值是就是左边界

    // (左边界)target ... target mid
    const getLeftBorder = function(nums, target) {
        let left = 0, right = nums.length -1, lB = -2
        while(left <= right) {
            let mid = left + Math.floor((right - left)/2)
            if(nums[mid] >= target) {
                right = mid - 1
                lB = right
            } else left = mid + 1
        }
        return lB
    }
    // 右边界: mid 位置 一直 <= target 最终,到临界值是就是右边界 
    // mid target ... target(右边界) 
    const getRightBorder = function(nums, target) {
        let left = 0, right = nums.length - 1, rB = -2
        while(left <= right) {
            let mid = left + Math.floor((right - left)/2)
            if(nums[mid] <= target) {
                left = mid + 1
                rB = left
            } else right = mid - 1
        }
        return rB
    }

    // 调用函数
    let lB = getLeftBorder(nums,target)
    let rB = getRightBorder(nums,target)
    // 情况一 目标值无 且在数组范围外
    if(lB ==  -2 || rB == -2) return [-1,-1]
    // 情况三 目标值右,且个数大于等于1   lB target ... target rB
    if(rB - lB > 1) return [lB + 1, rB - 1]
    // 情况二  目标值无,在数组范围内
    return [-1,-1]
};

总结二分法

  1. 二分法的基本使用看706:二分查找即可
  2. 使用条件:有序数组,无重复元素
  3. 要在二分查找的过程中,保持不变量,就是在while寻找中每一次边界的处理都要坚持根据区间的定义来操作,这就是循环不变量规则。
  4. 区间:左闭右闭即[left, right],或者左闭右开即[left, right)
    • while (left <= right) 要使用 <= ,因为left == right是有意义的,所以使用 <=
    • while (left < right),这里使用 < ,因为left == right在区间[left, right)是没有意义的
  5. 操作: 设置一个中间值,与目标值对比,改变区间的边界,选择新的区间,循环

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java 基础入门篇(二)—— Java 基础语法

文章目录 一、注释二、字面量三、变量3.1 变量概述3.2 变量在计算机中的底层原理 四、数据类型五、关键字、标志符六、类型转换6.1 自动类型转换6.2 表达式的自动类型转换6.3 强制类型转换 七、运算符7.1 基本算数运算符7.2 符号做连接符7.3 自增自减运算符7.4 赋值运算符7.5 …

基于simulink采用 QSHB 和 HBPS 算法的混合 MIMO 波束成形仿真

一、前言 本例展示了多输入多输出 &#xff08;MIMO&#xff09; 无线通信系统的 Simulink 模型。无线系统使用混合波束成形技术来提高系统吞吐量。 二、介绍 5G和其他现代无线通信系统广泛使用MIMO波束成形技术进行信噪比&#xff08;SNR&#xff09;增强和空间复用&#xff0…

Netty(2)

Netty 文章目录 Netty4 Netty 模型4.1 Netty 模型介绍4.2 Netty demo4.3 Netty 异步模型4.3.1 基本介绍4.3.2 异步模型4.3.3 Future-Listener 机制4.4 Netty 任务队列 task 4 Netty 模型 4.1 Netty 模型介绍 Netty 线程模式&#xff1a;Netty 主要基于主从 Reactor 多线程模型…

开放式基金净值估算数据 API 数据接口

开放式基金净值估算数据 API 数据接口 全量基金数据&#xff0c;实时数据&#xff0c;所有基金数据。 1. 产品功能 返回实时开放式基金净值估值可定义所有基金估值数据&#xff1b;多个基金属性值返回&#xff1b;多维指标&#xff0c;一次查询毫秒级返回&#xff1b;数据持续…

全球5G市场最新进展及未来展望

从智慧医疗到万物互联&#xff0c;从无人驾驶到关乎我国未来发展的“新基建”&#xff0c;自2019年全球5G商用启动后&#xff0c;5G就步入了发展“快车道”;2022年继续保持快速稳定的增长态势&#xff0c;在网络建设、人口覆盖、终端形态等方面发展势头强劲&#xff0c;在技术标…

【致敬未来的攻城狮计划】— 连续打卡第二十三天:RA2E1的存储器基础知识

系列文章目录 1.连续打卡第一天&#xff1a;提前对CPK_RA2E1是瑞萨RA系列开发板的初体验&#xff0c;了解一下 2.开发环境的选择和调试&#xff08;从零开始&#xff0c;加油&#xff09; 3.欲速则不达&#xff0c;今天是对RA2E1 基础知识的补充学习。 4.e2 studio 使用教程 5.…

每天一道算法练习题--Day18 第一章 --算法专题 --- ----------前缀树

前缀树 字典树也叫前缀树、Trie。它本身就是一个树型结构&#xff0c;也就是一颗多叉树&#xff0c;学过树的朋友应该非常容易理解&#xff0c;它的核心操作是插入&#xff0c;查找。删除很少使用&#xff0c;因此这个讲义不包含删除操作。 截止目前&#xff08;2020-02-04&a…

基于R语言APSIM模型应用

随着数字农业和智慧农业的发展&#xff0c;基于过程的农业生产系统模型在模拟作物对气候变化的响应与适应、农田管理优化、作物品种和株型筛选、农田固碳和温室气体排放等领域扮演着越来越重要的作用。APSIM (Agricultural Production Systems sIMulator)模型是世界知名的作物生…

净利润下滑13%,帅丰电器已掉队?

近年来&#xff0c;随着市场竞争加剧&#xff0c;厨电行业加速洗牌&#xff0c;超60%杂牌或被淘汰出局&#xff0c;三类品牌全部被清退。而作为毛利最高的厨电细分市场&#xff0c;集成灶行业吸引了大批企业涌入&#xff0c;市场渗透率快速提升&#xff0c;已经超过30%&#xf…

华为MPLS跨域——后门链路实验配置

目录 配置PE与CE设备对接命令&#xff08;通过OSPF对接&#xff09; 配置后门链路 可以使用任意方式来跑跨域MPLS&#xff08;A、B、C1、C2都可以&#xff09;&#xff0c;不过关于传递Vpnv4路由的配置此处不做介绍&#xff1b;此处只介绍关于PE和CE对接的配置和关于后门链路…

数据存储系统概要

可靠、可扩展与可维护性 现在有很多都属于数据密集型&#xff0c;而不是计算密集型。对于这些类型应用&#xff0c;CPU的处理能力往往不是第一限制性因素&#xff0c;关键在于数据量、数据的复杂度及数据的快速多边形。 数据密集型应用模块&#xff1a; 数据库&#xff1a;存…

对标世界一流|从Just in time到Just in case ——汽车行业供应链管理经验借鉴

01 丰田汽车精益生产 作为最复杂和最成熟的供应链之一&#xff0c;汽车行业供应链无疑是供应链领域集大成者&#xff0c;而提起汽车行业供应链&#xff0c;就不得不提到丰田汽车&#xff1b;提到丰田汽车&#xff0c;就肯定离不开大名鼎鼎的精益生产以及JIT模式。 JIT模式由丰…

云服务器部署python项目

前言&#xff1a;相信看到这篇文章的小伙伴都或多或少有一些编程基础&#xff0c;懂得一些linux的基本命令了吧&#xff0c;本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python&#xff1a;一种编程语言&…

SpringBoot+Shiro+Jwt+Vue+elementUI实现前后端分离单体系统Demo

记录一下使用SpringBoot集成Shiro框架和Jwt框架实现前后端分离Web项目的过程&#xff0c;后端使用SpringBoot整合ShiroJwt(auth0)&#xff0c;前端使用vueelementUI框架&#xff0c;前后端的交互使用的是jwt的token&#xff0c;shiro的会话关闭&#xff0c;后端只需要使用Shiro…

在Linux上搭建gitlab以及自动化编译部署的完整流程

一、安装gitlab 首先下载gitlab的安装包&#xff0c;地址如下&#xff1a; https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/ubuntu/pool/bionic/main/g/gitlab-ce/ 然后安装下载的包即可&#xff0c;一般还需要安装openssh-server等依赖包&#xff0c;在安装gitlab包之前可以…

睡眠经济2.0时代来了,老巨头们有护城河吗?

在第23个世界睡眠日&#xff0c;中国睡眠研究会等机构发布了《中国睡眠研究报告2023》&#xff0c;近半数人每晚平均睡眠时长不足8小时&#xff0c;“失眠”已成为了当代人的生活常态。 越是睡不好&#xff0c;越要想办法。年轻人纷纷求助于好的寝具、好的助眠产品乃至保健品&…

【Halcon】找到设备上的 标识牌

如图&#xff0c;找到设备上的 标识牌 。 标识牌最明显的特征是比其他区域亮&#xff0c; 二值化选择出亮区域&#xff0c;再通过面积选择出目标区域。 先显示图片 *获取图片的大小 get_image_size(Image,Width,Height)*关闭窗口 dev_close_window()*打开窗口 dev_open_win…

java错题总结(19-21页)

链接&#xff1a;关于Java中的ClassLoader下面的哪些描述是错误的_用友笔试题_牛客网 来源&#xff1a;牛客网 B&#xff1a;先讲一下双亲委派机制&#xff0c;简单来说&#xff0c;就是加载一个类的时候&#xff0c;会往上找他的父类加载器&#xff0c;父类加载器找它的父类加…

Centos系统安装RabbitMQ消息中间件

记录一下在centos7.x下面安装RabbitMQ消息中间件 RabbitMQ是一个开源而且遵循 AMQP协议实现的基于 Erlang语言编写&#xff0c;因此安装RabbitMQ之前是需要部署安装Erlang环境的 先安装Erlang https://packagecloud.io/rabbitmq/ 点进去可以看到 因为使用的centos是7.x版本的…

架构设计-数据库篇

大家好&#xff0c;我是易安&#xff01; 之前我们讲过架构设计的一些原则&#xff0c;和架构设计的方法论&#xff0c;今天我们谈谈高性能数据库集群的设计与应用。 读写分离原理 读写分离的基本原理是将数据库读写操作分散到不同的节点上&#xff0c;下面是其基本架构图。 读…