劍指Offer-在排序數組中查找數字 I

46.在排序數組中查找數字 I

統計一個數字在排序數組中出現的次數。

示例 1:

輸入: nums = [5,7,7,8,8,10], target = 8
輸出: 2
示例 2:

輸入: nums = [5,7,7,8,8,10], target = 6
輸出: 0

思路一

雙指針。首尾各放一個指針,由於數組是排好序的,所以找到與target相等的那個範圍即可。注意返回值,如果i和j相遇也沒有找到target,那麼就返回0,否則返回j-i+1。

class Solution {
    public int search(int[] nums, int target) {

        if(nums==null || nums.length==0 )
        {
            return 0;
        }
        int i=0;
        int j=nums.length-1;

        while(i<j)
        {
            if(nums[i]<target) i++;
            if(nums[j]>target) j--;
            if(nums[i]==target && nums[j]==target)
            {
                break;
            }
        }
        return nums[i]==target?(j-i+1):0;
    }
}

這種方法時間複雜度是O(N)。

思路二——二分

二分的精髓就是在已經排好序的數據中發現與尋找目標的聯繫。

數組已經排好序,如果找一個元素出現的次數,那麼他們必然是相連的。當考慮相連的這段的端點時我們發現,左端點的左邊都小於它,右邊都大於等於它。右端點左邊都小於等於它,右邊都大於它。

利用這兩個性質,我們可以使用兩次二分,分別確定兩個端點。端點找到了,用下標一減,就是次數。

class Solution {
    public int search(int[] nums, int target) {
        if(nums==null || nums.length==0)
        {
            return 0;
        }
        int l=0,r=nums.length-1;
        while(l<r)
        {
            int mid=(l+r)>>1;
            if(nums[mid]<target)
            {
                l=mid+1;
            }else
            {
                r=mid;
            }
        }
        if(nums[l]!=target) return 0;
        int left=l;
        l=0;
        r=nums.length-1;
        while(l<r)
        {
            int mid=(l+r+1)>>1;
            if(nums[mid]<=target)
            {
                l=mid;
            }else
            {
                r=mid-1;
            }
        }
        return r-left+1;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章