返回顶部
首页 > 资讯 > 前端开发 > JavaScript >JavaScript中二分查找的例题详解
  • 492
分享到

JavaScript中二分查找的例题详解

JavaScript二分查找算法JavaScript二分查找 2023-03-09 17:03:33 492人浏览 独家记忆
摘要

目录二分查找公式寻找一个数缺陷寻找最左边满足条件的值方式一方式二寻找最右侧满足条件的值方式一方式二你有没有碰到过这样的情况,当刷题的时候,刚开始满头雾水不知道从何下手,然后匆匆忙忙的

你有没有碰到过这样的情况,当刷题的时候,刚开始满头雾水不知道从何下手,然后匆匆忙忙的看了题解。哦~是这样啊,然后开始按照题解的思路答题。答到了一半发现不会了,又看了看题解,最后终于答出来了。看看了实现的代码,一步、两步、三步、四步···这也不难啊。

突然有一天面试了,问到了你曾刷到的题目,此时你只记得你曾经刷过了~。思路全忘了。

我也经常碰到这种境况,我也承认我是个算法小菜鸡。所以我打算用文章的形式记录我学习算法的过程。也算是一种输出吧。有大佬说啊“学习算法就像是做数学题,记住公式,碰到题目想想是属于哪一种,开始套公式。”那咱们就试试吧!

二分查找在我们学习算法中是很重要的一部分,而且面试的时候会经常的让我们手写一些算法。

探究几个最常用的二分查找场景:寻找一个数、寻找左侧边界、寻找右侧边界

二分查找公式

function binarySearch(nums, target) {
	let left = 0
	let right = ...
	while(...) {
		const mid = Math.floor(left + (right - left) / 2)
		if(nums[mid] === target) {
			...
		} else if(nums[mid] < target) {
			left = ...
		} else if(nums[mid] > target) {
			right = ...
		}
	} 

	return ...
}

分析二分查找技巧 不要出现else,而是把所有情况用else if 写清楚,这样可以清楚的展示所有细节。

Math.floor(left + (right - left) / 2)其实和Math.floor((left +right)/2)的结果是一样的。如果leftright很大的时候,相加会导致移除。Math.floor(left + (right - left) / 2)可以有效的防止溢出。

寻找一个数

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

力扣第704题二分查找 这题是二分查找最简单的题型,几乎所有的二分查找的题型都是根据这个拓展的。

我们首先考虑的是搜索区间。因为定义的rightnums.length - 1,所以搜索区间为[left, right]两端都闭。当查找到了目标元素,则停止搜索退出循环,然后返回目标值对应的索引

当没有找到目标元素,循环的终止条件为left === right + 1的时候,直接返回-1即可。

缺陷

如果给你个有序数组nums = [1,2,2,2,3],target为2,此时用上面的方法返回的索引是2。如果我们想得到的target的在nums中最左边满足条件的值,或者最右边满足条件的值,这种方法就有问题了。

可能会想到,当找到了target的值,然后向左,向右做线性搜索。但是这样就很难保证二分查找对数级的复杂度了。

寻找最左边满足条件的值

方式一

function leftBound(nums, target) {
  let left = 0;
  let right = nums.length;

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

  if (left === num.length) return -1;
  return nums[left] === target ? left : -1;
}

上面是一种比较常见的代码形式。但是和我们刚开始的框架是可以匹配的。在这里while中使用的<,而不是<=。因为我们在定义right的时候,是nums.length而不是nums.length-1。那就说明我们的搜索区间是在[left,right)左闭右开。所以终止条件就是当left == right的时候。

还会发现一个不一样的地方,right = mid而不是right = mid - 1,这个还是受上面的搜索区间的影响。因为搜索区间为[left,right)左闭右开,所以当nums[mid]被检测到的时候,下一步应该缩小搜索区间。当nums[mid] === target的时候,虽然已经找到了target的值,但是不要立即返回,而是缩小搜索区间为[left, mid)。然后不断的向左边收缩,直到定左侧边界,也就是当left == right的时候。

最后,考虑下越界情况,当left的值为nums.length的时候说明查找左侧边界已经超出了搜索区间,说明target的值比所有数都大。当left的值为target的时候,说明找到了直接返回即可。然后其实返回left和返回right都一样,因为我们的终止条件是left == right

方式二

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

  if (left >= nums.length || nums[left] != target) {
    return -1;
  }

  return left;
}

方式一的搜索区间为[left, right)。我们方式二的搜索区间改为[left, right]左闭右闭。因为right的取值为nums.length - 1nums的最后一个值。while的终止条件则为left == right + 1,也就是代码中用的<=

此时right = mid - 1而不是right = mid, 因为搜索区间变了,[left,right]两边都闭。

最后判断一下边界条件,如果left >= nums.length说明已经超出了搜索区间,或者呢left的值和target不一样说明没找到。

这样就和第⼀种⼆分搜索算法统⼀了,都是两端都闭的搜索区间,⽽且最后返回的也是left 变量的值。不过我还是比较倾向于这种。哈哈。

寻找最右侧满足条件的值

方式一

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

这种方式和寻找左侧边界类似,还是使用搜索区间为[left, right)左闭右开的方式。关键的点在于当nums[mid]=== target的时候,设置的是left=mid+1。这样就可以把搜索区间变为[mid+1, right)。利用这种方式不断的增大左边界left的值,是的区间不断的向右靠拢,最后到达右边界。

但是这种方式最后返回的是left - 1。因为while的终止条件是left === right ,此时循环已经退出,如果已经找到了,那么left的则比要锁定的目标索引多1。因为下面这段代码

if(nums[mid] === target) {
	left = mid + 1
}

所以最后的目标值要left - 1

方式二

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

  if (right < 0 || nums[right] !== target) {
    return -1;
  }
  return right;
}

这里和类似左侧边界的搜索区间[left, right]左闭右闭。

其实二分查找差不多也就是这三种情况,你也可以理解为就是一种情况,然后不断的延伸。那我们记住套路了就开始去刷题巩固一下吧!

以上就是javascript中二分查找的例题详解的详细内容,更多关于JavaScript二分查找的资料请关注编程网其它相关文章!

--结束END--

本文标题: JavaScript中二分查找的例题详解

本文链接: https://lsjlt.com/news/199058.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • JavaScript中二分查找的例题详解
    目录二分查找公式寻找一个数缺陷寻找最左边满足条件的值方式一方式二寻找最右侧满足条件的值方式一方式二你有没有碰到过这样的情况,当刷题的时候,刚开始满头雾水不知道从何下手,然后匆匆忙忙的...
    99+
    2023-03-09
    JavaScript二分查找算法 JavaScript二分查找
  • Python真题案例之二分法查找详解
    目录写在前面的话问题描述原理分析1.实现步骤2.图解参考代码写在前面的话 学了Python一些基础知识之后,相信大家对Python使用方法有了一定的感悟,想要追求深层次的东西还要细细...
    99+
    2024-04-02
  • Java二分查找算法实例详解
    在本文中,我们将介绍二进制搜索相对于简单线性搜索的优势,并介绍它在 Java 中的实现。 1. 需要有效的搜索 假设我们在wine-selling业务和数以百万计的买家每天都访问我们...
    99+
    2022-11-13
    Java 二分查找算法
  • java算法之二分查找法的实例详解
    java算法之二分查找法的实例详解原理假定查找范围为一个有序数组(如升序排列),要从中查找某一元素,如果该元素在此数组中,则返回其索引,否则返回-1。通过数组长度可取出中间位置元素的索引,将其值与目标值比较,如果中间位置元素值大于目标值,则...
    99+
    2023-05-31
    java 算法 二分查找法
  • JavaScript中的二分查找法怎么使用
    这篇文章主要介绍“JavaScript中的二分查找法怎么使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“JavaScript中的二分查找法怎么使用”文章能帮助大家解决问题。二分查找公式functi...
    99+
    2023-07-05
  • Python实现二分法查找及优化的示例详解
    目录1.二分查找的原理2.二分查找的实现3.二分查找的优化4.总结二分查找法(Binary Search)是一种在有序数组中查找某一特定元素的算法,它的思想是将数组从中间分成两部分,...
    99+
    2023-05-16
    Python实现二分法查找 Python二分法查找 Python查找
  • JS中二分查找算法的示例分析
    这篇文章将为大家详细讲解有关JS中二分查找算法的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。二分法查找,也称折半查找,是一种在有序数组中查找特定元素的搜索算法。...
    99+
    2024-04-02
  • JavaScript中二分查找法和计算重复次数的示例分析
    这篇文章主要介绍JavaScript中二分查找法和计算重复次数的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!具体如下:javascript数据结构与算法---检索算法(二分...
    99+
    2024-04-02
  • java 中二分法查找的应用实例
    java 中二分法查找的应用实例二分查找的前提是:数组有序 注意:mid的动态变化,否则出错!!!  实例代码:public class BiSearch { public static void main(St...
    99+
    2023-05-31
    java 二分法 ava
  • C语言二分查找图文详解
    目录一、二分查找算法1.假定给定的数组中元素个数为奇数个2.假定给定的数组为偶数个3.假定给定的数不在此数列中二、分支语句中应注意的小点1.悬空else语句2.switch语句中的b...
    99+
    2023-05-18
    c语言二分查找 c语言二分查找代码 c语言二分查找法
  • 详解C语言中二分查找的运用技巧
    目录基础的二分查查找左侧边界查找右侧边界二分查找问题分析实例1: 爱吃香蕉的珂珂实例2:运送包裹前篇文章聊到了二分查找的基础以及细节的处理问题,主要介绍了 查找和目标值相等的元素、查...
    99+
    2024-04-02
  • sort 包中的二分查找
    php小编草莓在这篇文章中将向大家介绍sort包中的二分查找算法。二分查找是一种高效的查找算法,它适用于有序数组中查找特定元素的场景。通过将数组不断分成两部分,并与目标元素进行比较,我...
    99+
    2024-02-09
  • Python 二分查找之bisect库的使用详解
    目录简介bisect 库的使用bisect_leftbisect_rightinsort_leftinsort_right二分查找基础实现简介 bisect 库是 Python 标准...
    99+
    2023-03-11
    Python bisect库使用 Python bisect
  • python中的bisect模块与二分查找详情
    目录1.bisect模块概述2.bisect模块的函数详解2.1 bisect.bisect*()方法2.2 bisect.insort*()方法3.python中的二分查找3.1 ...
    99+
    2024-04-02
  • Python详细解析之二分查找算法
    本篇文章给大家带来了关于python的相关知识,其中主要整理了二分查找算法的相关问题,包括了算法描述、算法分析、算法思路等等内容,下面一起来看一下,希望对大家有帮助。二分法是一种效率比较高的搜索方法回忆之前做过的猜数字的小游戏,预先给定一个...
    99+
    2022-06-28
    python
  • JavaScript二分查找算法的应用方法
    这篇文章主要介绍“JavaScript二分查找算法的应用方法”,在日常操作中,相信很多人在JavaScript二分查找算法的应用方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”JavaScript二分查找算...
    99+
    2023-06-20
  • python二分法查找实例代码
    对于要搜索的元素越多,二分查找速度比简单查找快的更多 这是二分查找算法的优点,但二分算法也有缺点,二分算法只针对有序的列表,这样插入和删除就会很困难,因此,折半查找方法只适合不经常变...
    99+
    2024-04-02
  • Python实现二分查找与bisect模块详解
    前言 其实Python 的列表(list)内部实现是一个数组,也就是一个线性表。在列表中查找元素可以使用 list.index() 方法,其时间复杂度为O(n) 。对于大数据量,则可以用二分查找进行优化。 ...
    99+
    2022-06-04
    详解 模块 Python
  • C语言详细讲解二分查找用法
    目录【力扣题号】704.二分查找 力扣题目链接 示例 1: 输入: nums = [-1,0,3,5,9,12], target = 9     输出:...
    99+
    2024-04-02
  • Java实现查找算法的示例代码(二分查找、插值查找、斐波那契查找)
    目录1.查找概述2.顺序查找3.二分查找3.1 二分查找概述3.2 二分查找实现4.插值查找4.1 插值查找概述4.2 插值查找实现5.斐波那契查找5.1 斐波那契查找概述5.2 斐...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作