第一个错误的版本
作者:互联网
最初版本代码:
/* 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;
}
}
}
}
改进点:
- 对mid的赋值从mid=(left+right)/2 改成了mid=left+(right-left)/2;
- 将对mid的赋值从 else里移到了while循环的开头;
- 取消了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得到所以测试样例呢?
标签:right,第一个,错误,int,isBadVersion,mid,版本,public,left 来源: https://www.cnblogs.com/xukd/p/15262648.html