15 First Bad Version

109 阅读1分钟

暴力解题思路

暴力解法,逐个递减值,直到达到了下限返回上一个值即可

代码

/**
 * Definition for isBadVersion()
 * 
 * @param {integer} version number
 * @return {boolean} whether the version is bad
 * isBadVersion = function(version) {
 *     ...
 * };
 */

/**
 * @param {function} isBadVersion()
 * @return {function}
 */
var solution = function (isBadVersion) {
    /**
     * @param {integer} n Total versions
     * @return {integer} The first bad version
     */
    let iter = (n) => {
        if(n === 1) return 1
        let i = n
        for (i = n; i > 1; i--) {
            var bad = isBadVersion(i)
            if(!bad) {
                break
            }
        }
        return i + 1
    }
    return function (n) {
        return iter(n)
    };
};

二分法解题思路

  1. 二分求解关键左右标点 left = 1 right = n, 目标值肯定在 [1, n]之间
  2. 初始条件 right 必须大于 left 否则 [1,1]说明找到了目标值
  3. 求解 mid 中间值时,为了防止溢出 采用 left + (right - left)/ 2 等效于 (left + right) / 2
  4. 如果 mid 符合即isBadVersion(mid)为真, 那么说明目标值在 [left, mid] 之间
  5. 如果 mid 不符合即isBadVersion(mid)为假, 那么说明mid不符合排除掉 left = mid + 1,目标值在 [left + 1, right] 之间

代码

/**
 * Definition for isBadVersion()
 * 
 * @param {integer} version number
 * @return {boolean} whether the version is bad
 * isBadVersion = function(version) {
 *     ...
 * };
 */

/**
 * @param {function} isBadVersion()
 * @return {function}
 */
var solution = function (isBadVersion) {
    /**
     * @param {integer} n Total versions
     * @return {integer} The first bad version
     */
    return (n) => {
        let left = 1
        let right = n
        while(right > left) {
            let mid = Math.floor((left + (right - left) / 2 ))
            if(isBadVersion(mid)) { // 说明在 [left,mid] 之间存在
                right = mid
            } else {
                left = mid + 1 // mid 不满足说明中间值取小了同时需要排除mid值即 [left + 1,right]之间存在最小bad version 
            }
        }
        return left
    }
};