簡體   English   中英

如何有效地計算排序數組中小於某個值的元素?

[英]How do I efficiently count elements less than a certain value in a sorted array?

例如說我有一個排序數組:

[21, 32, 58, 70, 100, 4342]

和一個鍵值80

如何在不使用 if 條件遍歷整個數組的情況下有效地計算 80 以下的所有值? 我在考慮二進制搜索,但我又不是在搜索任何鍵,我只需要最快的方法返回小於或等於鍵值的值的計數。

您可以使用Arrays.binarySearch 根據文檔,它返回搜索鍵的索引,如果它包含在數組中; 否則, (-(insertion point) - 1) 使用您的示例:

import java.util.Arrays;

class Main {
    public static void main(String args[]) {
        int[] arr = {21, 32, 58, 70, 100, 4342};

        int res70 = Arrays.binarySearch(arr, 70);// returns 3
        int res80 = Arrays.binarySearch(arr, 80);// returns -5
    }
}

考慮到這一點,您可以使用該信息來獲得有效的計數:如果結果為正,則計數為result ,如果結果為負,則計數為(-result)-1-(result+1) (根據您的喜好):

import java.util.Arrays;

class Main {
    public static void main(String args[]) {
        int[] arr = {21, 32, 58, 70, 100, 4342};

        System.out.println("Count is:" + count(arr, 70));// returns 3
        System.out.println("Count is:" + count(arr, 80));// returns 4
    }

    private static int count(int[] sortedArray, int n) {
        int result = Arrays.binarySearch(sortedArray, n);
        if (result > -1) {
            return result;
        }
        return (-result) - 1;
    }
}

對於可能重復,且數組中存在多個80的情況,有兩種可能的解決方案:

  1. 從二分搜索的結果進行線性搜索。 不過,這將使最壞的情況為O(n) ,而平均仍為O(lg n)

  2. 手動實現(或找到具有)二進制搜索的庫以查找等於值的最后一個元素(同時保留對未找到元素的考慮,如 Java 庫所做的那樣)。 此答案中存在查找最后一個元素的示例: Last index of multiple keys using binary-search? 這將使最壞的情況保持在O(lg n)

Java 9開始,如果源數組是有序的,您可以使用takeWhiledropWhile方法:

int key = 80, arr[] = {21, 32, 58, 70, 100, 4342};

System.out.println("Count: " + Arrays.stream(arr)
        .takeWhile(i -> i < key)
        .peek(i -> System.out.print(i + " "))
        .count()); // 21 32 58 70 Count: 4

System.out.println("Count: " + Arrays.stream(arr)
        .dropWhile(i -> i < key)
        .peek(i -> System.out.print(i + " "))
        .count()); // 100 4342 Count: 2

暫無
暫無

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

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