[英]Efficiently, get the count of numbers in a sorted array that is less than a given number using binary search
[英]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的情況,有兩種可能的解決方案:
從二分搜索的結果進行線性搜索。 不過,這將使最壞的情況為O(n)
,而平均仍為O(lg n)
。
手動實現(或找到具有)二進制搜索的庫以查找等於值的最后一個元素(同時保留對未找到元素的考慮,如 Java 庫所做的那樣)。 此答案中存在查找最后一個元素的示例: Last index of multiple keys using binary-search? 這將使最壞的情況保持在O(lg n)
。
從Java 9開始,如果源數組是有序的,您可以使用takeWhile
和dropWhile
方法:
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.