1. 程式人生 > >278. 第一個錯誤的版本 領釦

278. 第一個錯誤的版本 領釦

你是產品經理,目前正在帶領一個團隊開發新的產品。不幸的是,你的產品的最新版本沒有通過質量檢測。由於每個版本都是基於之前的版本開發的,所以錯誤的版本之後的所有版本都是錯的。

假設你有 n 個版本 [1, 2, ..., n],你想找出導致之後所有版本出錯的第一個錯誤的版本。

你可以通過呼叫 bool isBadVersion(version) 介面來判斷版本號 version 是否在單元測試中出錯。實現一個函式來查詢第一個錯誤的版本。你應該儘量減少對呼叫 API 的次數。

示例:

給定 n = 5,並且 version = 4 是第一個錯誤的版本。

呼叫 isBadVersion(3) -> false
呼叫 isBadVersion(5) -> true
呼叫 isBadVersion(4) -> true

所以,4 是第一個錯誤的版本。 





在做該題的時候通常都會想到二分法,但是往往會因為判定條件的不對而報錯

程式碼一:
      public int firstBadVersion(int n) {
          if(n==1){
                return 1;
            }
         
              int result = 0;
              int low = 1;
              int high = n;
             
               while(low<=high) {
                   
int mid = (low+high)/2; if(isBadVersion(mid)==false) { if(isBadVersion(mid+1)==true){ low = mid+1; break; }else { low = mid+1; } }
else { high = mid-1; } } return low; }

 

程式碼二:

 public int firstBadVersion(int n) {
       if(n==1){
                return 1;
            }
            
              int result = 0;
              int low = 1;
              int high = n;
             
               while(low<=high) {
                   int mid = low+(high-low)/2;
                   if(isBadVersion(mid)==false) {
                      if(isBadVersion(mid+1)==true){
                          low = mid+1;
                          break;
                      }else {
                          low = mid+1;
                      }
                        
                     
                   } else {
                       
                           high = mid-1;
                       
                   } 
               }
              return low;  

    }
}

這兩段程式碼基本上是一致的,但是程式碼一在提交時總會出現超時,程式碼二則不會,原因在於  中間值  mid的表示式

mid=(low+high)/2      可能會在成記憶體溢位,導致出錯,所以最好採用程式碼二中的表示式 mid=low+(high-low)/2

雖然二者理論上也是一致的,在high很小時,二者都可以使用,在high很大時,建議採用後者,執行效率會更高些!!!