前端算法刷题之路—二分查找

一、基本概念

二分查找是基于有序数组的查找。首先有左中右三个指针,当中间指针指向的数大于目标值,将右指针移到中间指针前一位,如果小于则移动左指针到中间指针后一位,通过不断缩小范围,直到找到目标值。

代码实现

function finIndex(list, target) {
    
    
  let left = 0,right = list.length - 1,mid;

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

  return -1;
}

二分查找还能解决一类抽象问题,如查找数组[0,0,0,0,0,1,1,1,1,]中第一个1的位置,或者最后一个0的位置。代码相较原来变化不大,只是左右指针的移动是否移到中间指针前后的差异而已。

二、题目

1.x 的平方根

x 的平方根

思路

此题就是寻找最后一个0的抽象问题。即前面小于等于x的记为0,大于x的记为1,最后一个0就是本题的答案。

代码

/**
 * @param {number} x
 * @return {number}
 */
var mySqrt = function(x) {
    
    
    let left = 0,right = x,mid = Math.floor((left+right)/2);
     // 避免计算超界 mid  = head + ((tail - head) / 2.0);
     
    while(right-left>2){
    
    	//防止死循环
    	mid*mid > x ? right = mid-1 : left = mid
        mid = Math.floor((left+right)/2)
    }

    for(let i=left;i<=right;i++){
    
    	//少于3项用for循环遍历
        if(i*i>x){
    
    
            mid = i-1
            break
        }else{
    
    
            mid = i
        }
    }

    return mid
};

由于原题可以看做函数f(x)=√x,我们可以调整固定100次来找到目标数。因为每二分调整一次,就会把待查找的区间缩少一半,二分调整100次,待调整区间就是2的100次方分之一,此时左右指针相差仅有2的100次方分之一,然后取左指针整数部分即可。

var mySqrt = function(x) {
    
    
    let left = 0,right = x,mid;
    right += 1;
    for(let i = 0; i < 100;i++){
    
    
        // 避免计算超界
        mid  = left + ((right - left) /2.0);
        if(mid * mid <= x) left = mid;
        else right = mid;
    }
    return Math.floor(left);
};

猜你喜欢

转载自blog.csdn.net/m0_49343686/article/details/119542872