簡體   English   中英

使用二分搜索有效地獲取排序數組中小於給定數字的數字計數

[英]Efficiently, get the count of numbers in a sorted array that is less than a given number using binary search

我的問題陳述是這樣的 - 在排序數組中查找小於給定數字的數字計數,這應該在時間方面有效地完成。 我使用二進制搜索編寫了一個程序,該程序可以獲取計數,但時間復雜度卻失敗了。 需要幫助來實現這一目標。

import java.util.Arrays;

public class SortedSearch {
    public static int countNumbers(int[] sortedArray, int lessThan) {
        if(sortedArray.length ==1 || sortedArray.length == 0) {
            return singleElement(sortedArray, lessThan);
        }
        else {
            return binarySearch(sortedArray, lessThan);
        }
    }

    public static int singleElement(int[] sortedArray, int searchVal) {
        if(sortedArray.length == 0) {
            return 0;
        }
        if(sortedArray[0] < searchVal) {
            return 1;
        }
        return 0;
    }

    private static int binarySearch(int[] sortedArray, int searchVal) {
        int low = 0;
        int high = (sortedArray.length)-1;
        int mid = (low + high)/2;
        if((sortedArray.length == 0) || (sortedArray[0] > searchVal)) {
            return 0;
        }
        if(sortedArray[high] < searchVal) {
            return sortedArray.length;
        }
        if(sortedArray[high] == searchVal) {
            return sortedArray.length-1;
        }
        if(sortedArray[mid] < searchVal) {
            int newLow = low;
            int newHigh = calculateNewHigh(sortedArray, newLow, 0, searchVal);
            int[] newArray = Arrays.copyOfRange(sortedArray, newLow, newHigh+1);
            return newArray.length;
        }
        else {
            int newLow = low;
            int newHigh = mid;
            int[] newArray = Arrays.copyOfRange(sortedArray, newLow, newHigh+1);
            return binarySearch(newArray, searchVal);
        }
    }

    private static int calculateNewHigh(int[] sortedArray, int low, int previousHigh, int searchVal) {
        int newHigh =  previousHigh + (sortedArray.length-low)/2;
        if(sortedArray[newHigh] < searchVal) {
            newHigh = calculateNewHigh(sortedArray, newHigh, newHigh, searchVal);
        }
        if(sortedArray[newHigh] == searchVal) {
            newHigh--;
        }
        if(sortedArray[newHigh] > searchVal) {
            newHigh--;
        }
        return newHigh;
    }

    public static void main(String[] args) {
        System.out.println(SortedSearch.countNumbers(new int[] { 1, 3, 5, 7 }, 4));
    }
}

由於您無論如何都在使用Arrays ,所以不使用Arrays.binarySearch(int[] a, int key)方法,而不是嘗試編寫自己的方法?

public static int countNumbers(int[] sortedArray, int lessThan) {
    int idx = Arrays.binarySearch(sortedArray, lessThan);
    if (idx < 0)
        return -idx - 1; // insertion point
    while (idx > 0 && sortedArray[idx - 1] == lessThan)
        idx--;
    return idx; // index of first element with given value
}

while循環1是必要的,因為 javadoc 說:

如果數組包含多個具有指定值的元素,則無法保證會找到哪一個。

1)如果例如所有值都相同,則此循環不是最佳的,請參閱例如使用二分搜索查找多個條目

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM