[JavaScript 刷题] 二分搜索 - 第一个错误的版本,Leetcode 278

Posted GoldenaArcher

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[JavaScript 刷题] 二分搜索 - 第一个错误的版本,Leetcode 278相关的知识,希望对你有一定的参考价值。

[javascript 刷题] 二分搜索 - 第一个错误的版本,Leetcode 278

题目地址:278. First Bad Version (Easy)

题目

如下:

You are a product manager and currently leading a team to develop a new product. Unfortunately, the latest version of your product fails the quality check. Since each version is developed based on the previous version, all the versions after a bad version are also bad.

Suppose you have n versions [1, 2, ..., n] and you want to find out the first bad one, which causes all the following ones to be bad.

You are given an API bool isBadVersion(version) which returns whether version is bad. Implement a function to find the first bad version. You should minimize the number of calls to the API.

解题思路

题目说的挺花里胡哨的,总结下来就是寻找第一个出现的值,这个意思。

  1. 这题看起来是个简单的二分搜索,其实稍微细究一下还是二分算法的变种,毕竟要找的是第一个出现的值

  2. 从给定的值来说,这道题给的值只有 truefalse,所以相对而言会比较好排查,在刚开始写案例做测试的时候,不用编写很多的值,也不用担心数组长度区间等问题,盲写 truefalse 的值就好了:

    truetruetruetruetruefalsefalsefalsefalse

    要搜索的就是第一个出现的 false

  3. 从 JavaScript 的解法来说,可能看起来会比较有点困惑,因为最初的给的解题模板是这样的:

    /**
     * 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 function (n) {};
    };
    

    这是个 闭包(closure),可能第一眼看上去会比较绕,但是实际上要实现的部分只有 function (n) {};,这个匿名函数中的内容就行了。如果要进行本地的测试,大概的逻辑是这样的:

    // 实现 isBadVersion 函数
    const isBadVersion = function (version) {
      // 这里会判断当前版本是 好 还是 坏
      // ...
    };
    
    // 实现 solution 函数
    var solution = function (isBadVersion) {
      // 这里的 n 是二次调用 solution 后传进去的值
      return function (n) {};
    };
    
    // 调用 solution 的方法
    
    // 1. 详解版
    // 这里返回的是匿名函数,所以此时的 solutionFunc 的值是 function (n) {};
    // 相当于 solutionFunc = function (n) {};
    const solutionFunc = solution(isBadVersion);
    // 这一步才会正式调用 solution 中的匿名函数
    // 这里的 10 就是匿名函数中接收的 n
    solutionFunc(10);
    
    // 2. 直接调用
    solution(isBadVersion)(10);
    

使用 JavaScript 解题

因为一般都是先本地实现,使用提供的案例进行测试,最后才提交,所以这里会实现 isBadVersion() 这个函数,并且进行本地调用。

/**
 * Definition for isBadVersion()
 *
 * @param {integer} version number
 * @return {boolean} whether the version is bad
 */
// 实现 isBadVersion 让下面的函数去调用
const isBadVersion = function (version) {
  return version >= 4;
};

/**
 * @param {function} isBadVersion()
 * @return {function}
 */
var solution = function (isBadVersion) {
  /**
   * @param {integer} n Total versions
   * @return {integer} The first bad version
   */
  return function (n) {
    let lo = 0,
      hi = n,
      mid;

    // lo 在这里不会 等于 hi,因为 当 lo = hi 也就代表着 isBadVersion(mid) 永远都是 false,那么就会在死循环里出不来
    while (lo < hi) {
      mid = Math.floor((lo + hi) / 2);
      // 注意作用域的问题,这里调用的 isBadVersion 是通过参数传进来的变量
      if (isBadVersion(mid)) {
        hi = mid;
      } else {
        lo = mid + 1;
      }
    }
    return lo;
  };
};

// 将 isBadVersion 这个函数作为参数传进 solution
console.log(solution(isBadVersion)(5));

以上是关于[JavaScript 刷题] 二分搜索 - 第一个错误的版本,Leetcode 278的主要内容,如果未能解决你的问题,请参考以下文章

[JavaScript 刷题] 二分搜索 - 求开方,Leetcode 69

[JavaScript 刷题] 二分搜索 - 第一个错误的版本,Leetcode 278

[JavaScript 刷题] 二分搜索 - 大于给定元素的最小元素,Leetcode 744

[JavaScript 刷题] 二分搜索 - 有序数组的 Single Element,Leetcode 540

LeetCode刷题第一周

leetcode刷题记录——二分简单题