javascript算法之从会用到理解 - 二分法

简介: javascript算法之从会用到理解 - 二分法

前言

某种算法的实际应用,核心就是要找到当前算法的使用前提,基于其算法核心,对数据进行重组、改造,最终输出;

二分法

二分法顾名思义,通过每次取中间数进行对比,从而得到想要的数据,这就不必赘述了吧!

下面来讲一下二分法的算法核心:

  1. 确定为有序数组,
  2. 利用三个数进行查找,所以先确定三个值,开始值、末尾值、中间值;中间值需要进行计算得来;
  3. 将中间值与目标值进行比较;
  • 中间值 < 末尾值/目标值,以中间值的下一位作为末尾值,开始值不变;
  • 中间值 > 末尾值/目标值,以开始值的前一位作为开始值,末尾值不变;
  • 目标值 = 中间值,则为想要的结果;

注意⚠️

  • 数组必须为有序数组;
  • 确定数组中是否有相同元素,若有,则需要自己处理掉,即无重复元素;

🐲第一个错误的版本

你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。

假设你有 n 个版本 [1, 2, ..., n],你想找出导致之后所有版本出错的第一个错误的版本。

你可以通过调用 bool isBadVersion(version) 接口来判断版本号 version 是否在单元测试中出错。实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。

示例 1:
输入:n = 5, bad = 4
输出:4

解释:
调用 isBadVersion(3) -> false
调用 isBadVersion(5) -> true
调用 isBadVersion(4) -> true
所以,4 是第一个错误的版本。

题目来源:https://leetcode.cn/problems/first-bad-version

分析:
由于此数组本身就是数字,且自增,所以,可以设置开始值为left = 1,末尾值right=n,中间值mid为向下取整的中间数;然后,就利用中间值,判断是否为正确版本,是正确版本,则正确区间为[mid+1, right],不是正确版本,则
正确区间为 [left, mid];当left=right,则输出正确值;

var solution = function(isBadVersion) {
   
  return function(n) {
   
        let left = 1, right = n;
        while (left < right) {
    // 循环直至区间左右端点相同
            const mid = Math.floor(left + (right - left) / 2); // 防止计算时溢出
            if (isBadVersion(mid)) {
   
                right = mid; // 错误版本,答案在区间 [left, mid] 中
            } else {
   
                left = mid + 1; //正确版本 答案在区间 [mid+1, right] 中
            }
        }
        // 此时有 left == right,区间缩为一个点,即为答案
        return left;
    };
};

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

已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到:
若旋转 4 次,则可以得到 [4,5,6,7,0,1,2]
若旋转 7 次,则可以得到 [0,1,2,4,5,6,7]
注意,数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]] 。

给你一个元素值 互不相同 的数组 nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。

你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。

示例 1:
输入:nums = [3,4,5,1,2]

输出:1
解释:原数组为 [1,2,3,4,5] ,旋转 3 次得到输入数组。

题目来源:https://leetcode.cn/problems/find-minimum-in-rotated-sorted-array

分析:
由于目标值可能大于最大的数组元素,所以right值为数组长度,而不是数组的长度-1;

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

结语

二分法,主要逻辑就是通过中间值和目标值的比较,然后缩小数组范围,最终得到答案,从问题中提炼出这个含义,就可以进行二分法的使用了,当然,在某些情况下,二分法也并不算得上最优解,按需取用即可!

目录
相关文章
|
2天前
|
算法 JavaScript 前端开发
LZH 算法的模拟实现,JavaScript 版本
LZH 算法的模拟实现,JavaScript 版本
15 0
|
2天前
|
算法 JavaScript 前端开发
彩票中奖率的真相:用 JavaScript 看透彩票背后的随机算法(下)
至于分发?我们可以参考一下市面上已有的一些概念做一下对比,下面是笼统的一个网络服务器的TPS预估值,也就是说彩票服务器在1秒内可以处理的最大请求数:
|
2天前
|
数据采集 算法 JavaScript
彩票中奖率的真相:用 JavaScript 看透彩票背后的随机算法(上)
原本这篇文章是打算叫「假如我是彩票系统开发者」,但细想一下,如果在文章中引用太多的 JavaScript 的话,反而不是那么纯粹,毕竟也只是我的一厢情愿,彩票开发也不全如本文所讲,有所误导的话便也是得不偿失了。
|
2天前
|
JavaScript 前端开发 算法
JavaScript的垃圾回收机制通过标记-清除算法自动管理内存
【5月更文挑战第11天】JavaScript的垃圾回收机制通过标记-清除算法自动管理内存,免除开发者处理内存泄漏问题。它从根对象开始遍历,标记活动对象,未标记的对象被视为垃圾并释放内存。优化技术包括分代收集和增量收集,以提升性能。然而,开发者仍需谨慎处理全局变量、闭包、定时器和DOM引用,防止内存泄漏,保证程序稳定性和性能。
17 0
|
2天前
|
算法 JavaScript 前端开发
三个js算法
三个js算法
8 2
|
2天前
|
算法 JavaScript
js的两个常用算法
js的两个常用算法
5 1
|
2天前
|
JavaScript 前端开发 算法
【JavaScript技术专栏】使用JavaScript实现常见算法
【4月更文挑战第30天】本文介绍了如何使用JavaScript实现常见算法,包括排序、搜索和图算法。首先,通过JavaScript的`sort`方法讨论了排序算法,以快速排序为例展示了自定义排序的实现。接着,探讨了二分查找这一高效的搜索算法,并提供了实现代码。最后,解释了深度优先搜索(DFS)图算法,并给出了在JavaScript中的实现。理解并运用这些算法能有效提升编程能力。
|
2天前
|
算法 JavaScript 前端开发
游戏物理系统 - 如何在JavaScript中实现基本的碰撞检测算法?
在JavaScript中实现2D矩形碰撞检测,常用AABB方法,适合简单游戏。创建Rectangle类,包含位置和尺寸属性,并定义`collidesWith`方法检查两矩形是否相交。通过比较边界位置判断碰撞,当四条边界条件均满足时,认定发生碰撞。基础算法适用于初级需求,复杂场景可采用更高级的碰撞检测库。
14 1
|
2天前
|
缓存 JavaScript 算法
Vue.js中的diff算法:让虚拟DOM更高效
Vue.js中的diff算法:让虚拟DOM更高效
|
2天前
|
算法 JavaScript 前端开发
JavaScript算法和数据结构:写一个二分查找的函数。
JavaScript算法和数据结构:写一个二分查找的函数。
33 0