數字在排序數組中出現的次數


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

暴力解法的時間復雜度為O(n),還有更優的解法,運用二分查找,時間復雜度為O(logn):

1.先找出第一次出現的下標值,設left,mid,right分別代表數組的起始,中間,結束的下標。

若數組中間的數a[mid]大於k,則right = mid -1;

若數組中間的數a[mid]小於k,則left = mid+1;

若數組中間的數a[mid]等於k,判斷a[mid-1] 是否等於k,若不等於,說明是第一次出現的下標,返回mid下標;若等於,則說明第一次出現的下標還在mid的左邊,right = mid -1;

遞歸重復以上過程。

2.再找出最后出現的下標,原理同上。

參考代碼:

package test;

import org.junit.Test;

public class Solution {
    public int getNumOfK(int[] a, int k) {
        if (a == null || a.length == 0)
            return 0;
        int first = getFirstK(a, 0, a.length - 1, k);
        int last = getLastK(a, 0, a.length - 1, k);
        if (first > -1 && last > -1)
            return last - first + 1;
        return 0;
    }

    private int getFirstK(int[] a, int left, int right, int k) {
        if (left > right)
            return -1;
        int mid = (left + right) / 2;
        int midData = a[mid];
        // 中間的數等於k
        if (midData == k) {
            //mid的前一個數不是k,說明是第一個出現的數
            if (mid > 0 && a[mid - 1] != k || mid == 0)
                return mid;
            else
                //不是第一個出現的數,第一個出現的數再數組的左邊
                right = mid - 1;
            // 中間的數大於k,說明在數組的左邊
        } else if (midData > k)
            right = mid - 1;
        else
            // 中間的數小於k,說明在數組的右邊
            left = mid + 1;
        return getFirstK(a, left, right, k);
    }

    private int getLastK(int[] a, int left, int right, int k) {
        if (left > right)
            return -1;
        int mid = (left + right) / 2;
        int midData = a[mid];
        if (midData == k) {
            if (mid < a.length - 1 && a[mid + 1] != k || mid == a.length - 1)
                return mid;
            else
                left = mid + 1;
        } else if (midData > k)
            right = mid - 1;
        else
            left = mid + 1;
        return getLastK(a, left, right, k);
    }

    @Test
    public void testSolution() {
        int[] a = { 1, 2, 3, 3, 3, 3, 4, 5 };
        int k = 3;
        System.out.println(getNumOfK(a, k));//4
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM