题目及测试
package pid278;
/*第一个错误的版本
你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。
假设你有 n 个版本 [1, 2, ..., n],你想找出导致之后所有版本出错的第一个错误的版本。
你可以通过调用 bool isBadVersion(version) 接口来判断版本号 version 是否在单元测试中出错。实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。
示例:
给定 n = 5,并且 version = 4 是第一个错误的版本。
调用 isBadVersion(3) -> false
调用 isBadVersion(5) -> true
调用 isBadVersion(4) -> true
所以,4 是第一个错误的版本。
*/
public class main {
public static void main(String[] args) {
int[] testTable = {5,6,10,2126753390};
for(int i=0;i<testTable.length;i++){
test(testTable[i]);
}
}
private static void test(int ito) {
Solution solution = new Solution();
long begin = System.currentTimeMillis();
System.out.println("ito= ");
System.out.print(ito+" ");
int rtn;
rtn=solution.firstBadVersion(ito);//执行程序
long end = System.currentTimeMillis();
System.out.println("rtn="+rtn);
System.out.println();
System.out.println("耗时:" + (end - begin) + "ms");
System.out.println("-------------------");
}
}
方法1(不成功,超时,但应该是对的)
二分法,让begin为false,last为true,直到begin+1=last
package pid278;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/* The isBadVersion API is defined in the parent class VersionControl.
boolean isBadVersion(int version); */
public class Solution /*extends VersionControl*/ {
public int firstBadVersion(int n) {
if(n<=1||isBadVersion(1)){
return 1;
}
//此处必有第一个为false,最后一个为true
int begin=1;
int last=n;
int mid=(begin+last)/2;
while(last!=begin+1){
boolean now=isBadVersion(mid);
if(now==true){
last=mid;
}
else{
begin=mid;
}//此处必有begin为false,last为true
mid=(begin+last)/2;
}
return last;
}
boolean isBadVersion(int version){
if(version>3){
return true;
}
else{
return false;
}
}
}
方法2(成功,16ms,挺快)
与前面方法基本一样就是把mid=begin+(last-begin)/2;
因为如何是begin+last 可能会超出int范围导致mid出错,进而导致程序出错
public int firstBadVersion(int n) {
if(n<=1||isBadVersion(1)){
return 1;
}
//此处必有第一个为false,最后一个为true
int begin=1;
int last=n;
int mid=begin+(last-begin)/2;
while(last!=begin+1){
boolean now=isBadVersion(mid);
if(now==true){
last=mid;
}
else{
begin=mid;
}//此处必有begin为false,last为true
mid=begin+(last-begin)/2;
}
return last;
}
方法3(成功,22ms,较慢)
public int firstBadVersion(int n) {
int begin=1;
int end=n;
while(begin<=end){
int mid=(begin+end)>>>1;
if(isBadVersion(mid)){
//mid是坏版本,检验mid-1是不是
if(!isBadVersion(mid-1)){
//mid-1不是坏版本,mid是
return mid;
}
else{
end=mid-1;
}
}
else{
//mid不是坏版本
begin=mid+1;
}
}
return 0;
}