第一个错误的版本

时间:2021-09-13
本文章向大家介绍第一个错误的版本,主要包括第一个错误的版本使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

最初版本代码:

/* The isBadVersion API is defined in the parent class VersionControl.
      boolean isBadVersion(int version); */

public class Solution extends VersionControl {
    public int firstBadVersion(int n) {
        int left=1,right=n,mid=(left+right)/2;
        int result=0;
        while(true){
            if(isBadVersion(mid)){
                if(!isBadVersion(mid-1)){
                    result=mid;
                    return result;
                   
                }
                else{
                    right=mid-1;
                    mid=(left+right)/2;
                }
            }
            else{
                left=mid+1;
                mid=(left+right)/2;
            }
            
        }
    }
}

运行结果:未通过,原因,超时。
一次改进:

/* The isBadVersion API is defined in the parent class VersionControl.
      boolean isBadVersion(int version); */

public class Solution extends VersionControl {
    public int firstBadVersion(int n) {
        int left=1,right=n;
        while(true){
            mid=left+(right-left)/2;
            if(isBadVersion(mid)){
                if(!isBadVersion(mid-1)){
                    return mid;
                   
                }
                else{
                    right=mid-1;
                    
                }
            }
            else{
                left=mid+1;
            }
            
        }
      
    }
}

改进点:

  1. 对mid的赋值从mid=(left+right)/2 改成了mid=left+(right-left)/2;
  2. 将对mid的赋值从 else里移到了while循环的开头;
  3. 取消了result变量的设置,取消了将mid复制给result的语句,直接返回mid。
    其中2,3对代码的运行时间没有多少减少,改进后能够通过的关键点在于1,1能够防止计算时溢出

官方答案:

public class Solution extends VersionControl {
    public int firstBadVersion(int n) {
        int left = 1, right = n;
        while (left < right) { // 循环直至区间左右端点相同
            int mid = left + (right - left) / 2; // 防止计算时溢出
            if (isBadVersion(mid)) {
                right = mid; // 答案在区间 [left, mid] 中
            } else {
                left = mid + 1; // 答案在区间 [mid+1, right] 中
            }
        }
        // 此时有 left == right,区间缩为一个点,即为答案
        return left;
    }
}

它与我的不同点在于在判断isBadVersion后,他是直接令right=mid,把区间定在了[left,mid],而我,则是再进一步判断mid是不是就是badVersion,此时在此调用了API,所以时间会比较长。while循环的条件是left<right是循环下去,当left=right时。这个就是答案,它的思想是一直缩区间,知道缩到最小区间即最终答案,而我是一遍缩区间,一边判断是不是答案。
什么是计算溢出呢。
https://blog.csdn.net/malimingwq/article/details/97418866?utm_medium=distribute.pc_relevant_t0.none-task-blog-2~default~CTRLIST~default-1.no_search_link&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2~default~CTRLIST~default-1.no_search_link
这种操作常用于java二分法中

怎么用java得到所以测试样例呢?

本文来自博客园,作者:北征愚人,转载请注明原文链接:https://www.cnblogs.com/xukd/p/15262648.html

原文地址:https://www.cnblogs.com/xukd/p/15262648.html