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;
};

结语

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

目录
相关文章
|
4月前
|
JavaScript 算法 前端开发
JS算法必备之String常用操作方法
这篇文章详细介绍了JavaScript中字符串的基本操作,包括创建字符串、访问特定字符、字符串的拼接、位置查找、大小写转换、模式匹配、以及字符串的迭代和格式化等方法。
JS算法必备之String常用操作方法
|
4月前
|
JavaScript 算法 前端开发
JS算法必备之Array常用操作方法
这篇文章详细介绍了JavaScript中数组的创建、检测、转换、排序、操作方法以及迭代方法等,提供了数组操作的全面指南。
JS算法必备之Array常用操作方法
|
4月前
|
JavaScript 算法 前端开发
"揭秘Vue.js的高效渲染秘诀:深度解析Diff算法如何让前端开发快人一步"
【8月更文挑战第20天】Vue.js是一款备受欢迎的前端框架,以其声明式的响应式数据绑定和组件化开发著称。在Vue中,Diff算法是核心之一,它高效计算虚拟DOM更新时所需的最小实际DOM变更,确保界面快速准确更新。算法通过比较新旧虚拟DOM树的同层级节点,递归检查子节点,并利用`key`属性优化列表更新。虽然存在局限性,如难以处理跨层级节点移动,但Diff算法仍是Vue高效更新机制的关键,帮助开发者构建高性能Web应用。
82 1
|
5月前
|
数据采集 算法 JavaScript
揭开JavaScript字符串搜索的秘密:indexOf、includes与KMP算法
JavaScript字符串搜索涵盖`indexOf`、`includes`及KMP算法。`indexOf`返回子字符串位置,`includes`检查是否包含子字符串。KMP是高效的搜索算法,尤其适合长模式匹配。示例展示了如何在数据采集(如网页爬虫)中使用这些方法,结合代理IP进行安全搜索。代码示例中,搜索百度新闻结果并检测是否含有特定字符串。学习这些技术能提升编程效率和性能。
141 1
揭开JavaScript字符串搜索的秘密:indexOf、includes与KMP算法
|
5月前
|
算法 JavaScript
JS 【详解】树的遍历(含深度优先遍历和广度优先遍历的算法实现)
JS 【详解】树的遍历(含深度优先遍历和广度优先遍历的算法实现)
83 0
JS 【详解】树的遍历(含深度优先遍历和广度优先遍历的算法实现)
|
5月前
|
算法 JavaScript
JS 【详解】二叉树(含二叉树的前、中、后序遍历技巧和算法实现)
JS 【详解】二叉树(含二叉树的前、中、后序遍历技巧和算法实现)
53 0
|
5月前
|
算法 JavaScript
JS 【算法】二分查找
JS 【算法】二分查找
40 0
|
5月前
|
缓存 算法 前端开发
前端 JS 经典:LRU 缓存算法
前端 JS 经典:LRU 缓存算法
103 0
|
5月前
|
存储 JavaScript 搜索推荐
js【详解】arr.sort()数组排序(内含十大经典排序算法的js实现)
js【详解】arr.sort()数组排序(内含十大经典排序算法的js实现)
38 0
|
6月前
|
算法 JavaScript 安全
一篇文章讲明白JavaScript_提交表单和MD5算法密码加密
一篇文章讲明白JavaScript_提交表单和MD5算法密码加密
62 0