JavaScript的二分算法解析

113 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情

思想

简单来说,是把一个大得问题,分解成多个小模块,每次都二分问题,然后把一个长度为N得问题,拆分为二,拆分后变成了log2N,这就算法得复杂度上得到了一个非常好进步

思路

比如说给定一个数组长度为10W个,如果以循环得方式从这里查找,可能会导致电脑崩溃。

sequenceDiagram
5W个->5W个:总长度10W个

那可以把它从中间分为两块,如果查询得小于中间点,则把另一块排除掉这相当于省了一半得性能。

二分

现在取得一个块有想得到得结果,则再次把这一块分为两块,以此类推,直到查到最接近得那一块

graph TB 
A[5W]
A --> B[2.5W] 
A --> C[2.5W]
B --> E[1.25W]
B --> F[1.25W]
C --> P[1.25W]
C --> L[1.25W]

之前有非常火的前端概念,leftpad,它的意思是在一个字符串的左边拼接一些其他的字符串,在一个字符串中的左边加很多字符串,虽然把它提取为数组进行遍历,直到找到符合这个字符串的位置即可

// 这里分别是传字符串、总长度、补齐的字符
function leftpad(temp,len,num){
  if(!num && num!==0){
    num = '0'
  }
  return num+Array(len-temp.length).join(num)+temp
}

如果有需要补齐的字符串不存,并且它的长度等于零,那字符串修正为0。如果没有的话则需要计算补齐的长度创建一个长度为N的数组(总长度-当前字符串的长度),并把它由数组转换为字符串并进行拼接.join(ch)+str结束。

最后

二分法应用场景非常广泛,比如斐波那契数列,写完它带缓存或者是动态递归做法之后,代码实际上是最优的状态,但是它是自己的动态公式的(N次方计算)