算法专题(01)二分查找(03) 简单LeetCode 278

Posted 英雄哪里出来

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法专题(01)二分查找(03) 简单LeetCode 278相关的知识,希望对你有一定的参考价值。


一、题目

1、题目描述

  软件开发的时候,会有版本的概念。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。假设你有 n n n 个版本 [ 1 , 2 , . . . , n ] [1, 2, ..., n] [1,2,...,n],你想找出导致之后所有版本出错的第一个错误的版本。可以通过调用bool isBadVersion(version)接口来判断版本号version是否在单元测试中出错。实现一个函数来查找第一个错误的版本。应该尽量减少对调用 API 的次数。
  样例: 5 5 5 b a d = 4 bad = 4 bad=4,输出 4 4 4

2、基础框架

  • c++ 版本给出的基础框架代码如下,其中bool isBadVersion(int version)是供你调用的 API,也就是当你调用这个 API 时,如果version是错误的,则返回true;否则,返回false
// The API isBadVersion is defined for you.
// bool isBadVersion(int version);

class Solution {
public:
    int firstBadVersion(int n) {
    }
};

3、原题链接

LeetCode 278. 第一个错误的版本

二、解题报告

1、思路分析

  • 由题意可得,我们调用它提供的 API 时,返回值分布如下:
  • 000...000111...111 000...000111...111 000...000111...111
  • 其中 0 代表false,1 代表true;也就是一旦出现 1,就再也不会出现 0 了。
  • 所以基于这思路,我们可以二分位置;

归纳总结为 2 种情况,如下:
  1)当前二分到的位置 m i d mid mid,给出的版本是错误,那么从当前位置以后的版本不需要再检测了(因为一定也是错误的),并且我们可以肯定,出错的位置一定在 [ l , m i d ] [l, mid] [l,mid];并且 m i d mid mid 是一个可行解,记录下来;
  2)当前二分到的位置 m i d mid mid,给出的版本是正确,则出错位置可能在 [ m i d + 1 , r ] [mid+1, r] [mid+1,r]

2、时间复杂度

  • 由于每次都是将区间折半,所以时间复杂度为 O ( l o g 2 n ) O(log_2n) O(log2n)

3、代码详解

// The API isBadVersion is defined for you.
// bool isBadVersion(int version);

class Solution {
public:
    int firstBadVersion(int n) {
        long long l = 1, r = n;             // (1)
        long long ans = (long long)n + 1;
        while(l <= r) {
            long long mid = (l + r) / 2;
            if( isBadVersion(mid) ) {       
                ans = mid;                  // (2)
                r = mid - 1;
            }else {
                l = mid + 1;                // (3)
            }
        }
        return ans;
    }
};
  • ( 1 ) (1) (1) 需要这里,这里两个区间相加可能超过 int,所以需要采用 64 位整型long long
  • ( 2 ) (2) (2) 找到错误版本的嫌疑区间 [ l , m i d ] [l, mid] [l,mid],并且 m i d mid mid 是确定的候选嫌疑位置;
  • ( 3 ) (3) (3) 错误版本不可能落在 [ l , m i d ] [l, mid] [l,mid],所以可能在 [ m i d + 1 , r ] [mid+1, r] [mid+1,r],需要继续二分迭代;

三、本题小知识

二分时,如果区间范围过大,int难以招架时,需要动用long long


以上是关于算法专题(01)二分查找(03) 简单LeetCode 278的主要内容,如果未能解决你的问题,请参考以下文章

算法专题(01)二分查找(02) 简单LeetCode 35

必学!二分查找(微课+PPT)|获奖微课算法专题13-6(公益交流)

二分查找专题总结 - 基础篇

专题总结—二分查找与旋转排序数组

聊聊算法——二分查找算法深度分析

LeetCode刷题704-简单-二分查找