【Java】 劍指offer(53-1) 數字在排序數組中出現的次數

正文html

本文參考自《劍指offer》一書,代碼採用Java語言。java

更多:《劍指Offer》Java實現合集  算法

題目

  統計一個數字在排序數組中出現的次數。例如輸入排序數組{1, 2, 3, 3,3, 3, 4, 5}和數字3,因爲3在這個數組中出現了4次,所以輸出4。數組

思路

  分析:對於例子來講,若是採用二分法找到某一個3後,再往前遍歷和日後遍歷到第一個和最後一個3,在長度爲n的數組中有可能出現O(n)個3,所以這樣的掃描方法時間複雜度爲O(n),效率與從頭至尾掃描同樣,速度太慢。post

  這題關鍵是找到第一個和最後一個3,所以咱們嘗試改進二分法:中間數字比3大或者小的狀況與以前相似,關鍵是中間數字等於3的狀況,這時能夠分類討論以下:測試

  1)若是中間數字的前一個數字也等於3,說明第一個3在前面,繼續在前半段查找第一個3;url

  2)若是中間數字的前一個數字不等於3,說明該位置是第一個3;htm

  3)若是中間數字的後一個數字也等於3,說明最後一個3在後面,繼續在後半段查找最後一個3;blog

  2)若是中間數字的後一個數字不等於3,說明該位置是最後一個3;排序

 

附加:牛客網上還有一種算法:若是找數字k的次數,因爲數組是整數,能夠直接找k-0.5和k+0.5應該在數組中哪一個位置,這種方法就不用討論這麼多狀況了。(不過double類型的大小比較不知道是否會增長太多時間消耗)。

 

測試算例 

  1.功能測試(數字出現次數爲0、一、2等)

  2.邊界值測試(數組只有一個數字,查找數字爲第一個或者最後一個)

  2.特殊測試(null)

Java代碼

//題目:統計一個數字在排序數組中出現的次數。例如輸入排序數組{1, 2, 3, 3,
//3, 3, 4, 5}和數字3,因爲3在這個數組中出現了4次,所以輸出4。

public class NumberOfK {
    public int GetNumberOfK(int [] array , int k) {
        if(array==null || array.length<=0)
            return 0;
         int firstK = getFirstK(array,0,array.length-1,k);
         if(firstK == -1)
             return 0;
         int lastK = getLastK(array,firstK,array.length-1,k);
         return lastK-firstK+1;
     }
      
     private int getFirstK(int[] arr, int start, int end,int k){
         if(start>end)
             return -1;
         int mid = (start+end)>>1;
         if(arr[mid]==k){
             if( mid == 0 ||arr[mid-1]!=k )
                 return mid;
             else
                 end = mid-1;
         }else if(arr[mid]<k){
             start = mid+1;
         }else{
             end = mid-1;
         }
         return getFirstK(arr,start,end,k);
     }
      
     private int getLastK(int[] arr, int start, int end,int k){
         if(start>end)
             return -1;
         int mid = (start+end)>>1;
         if(arr[mid]==k){
             if(mid==arr.length-1 || arr[mid+1]!=k )
                 return mid;
             else
                 start = mid+1;
         }else if(arr[mid]<k){
             start = mid+1;
         }else{
             end = mid-1;
         }
         return getLastK(arr,start,end,k);
     }
}

  

解法二:尋找k+0.5和k-0.5的方法:

    public int GetNumberOfK(int [] arr , int k) {
       if(arr==null || arr.length<=0)
           return 0;
        int first = getLoc(arr, k , k-0.5);
        int last = getLoc(arr,k,k+0.5);
        return last-first;
    }
    
    private int getLoc(int[]arr, int k, double m){ //一樣是二分查找
        int start=0,end=arr.length-1;
        while(start<=end){
            int mid=(start+end)>>1;
            if(arr[mid]>m){
                end=mid-1;
            }else{
                start=mid+1;
            }
        }
        return start;
    }

  

收穫

  1.同53-3

  

更多:《劍指Offer》Java實現合集 

相關文章
相關標籤/搜索