簡體   English   中英

給定排序列表如何創建在 O(log(N)) 時間內不會落在某個范圍內的整數列表?

[英]Given sorted list how to create list of integers that wont fall in certain range in O(log(N)) time?

我有一個排序的整數數組列表(沒有重復項):

{1,2,4,5,8,12,15, 21,23,26,30,32,35,37,40,42,45,48,51,54}

假設給定的范圍是 [21-38](包括),它必須從整數輸出列表中排除。

然后輸出應包含不包含上述范圍的整數列表。

{1,2,4,5,8,12,15,40,42,45,48,51,54}

我需要在O(log(N) ) 時間內完成此操作。

我現在能想到的方法是:

Approach1:
1) Find lower bound index using binary search in O(logN)
2) Find higher bound index using binary search in O(logN)
3) Then loop over the input list and add the integers to new list by 
considering above lower and higher bound index. But this third step takes O(n).

Approach2:

I also feel that the above approach of using binary search is not 
 great as we can directly iterate over original list to remove the 
  integers falling under the range without using binary search.

我們有什么更好的方法嗎?

通過根據余數和移除的大小估計更好的選項,可以針對更好的情況優化移除元素:

static List<Integer> removeFrom(List<Integer> sorted, int sv, int ev) {
    int i1 = Collections.binarySearch(sorted, sv);
    int i2 = Collections.binarySearch(sorted, ev);
    int from, to;
    if (i1 < i2) {
        from = i1;
        to = i2;
    } else {
        from = i2;
        to = i1;
    }
    System.out.printf("Removing values %d..%d%n", sv, ev);
    int size = sorted.size();
    int removeLength = to - from + 1;
    int remainLength = size - removeLength;
    if (removeLength < remainLength) {
        System.out.printf("Removing range: [%d, %d]%n", from, to);
        sorted.removeAll(sorted.subList(from, to + 1));
        return sorted;
    } else {
        List<Integer> result = new ArrayList<>();
        if (from > 0) {
            System.out.printf("Keeping head: [%d, %d]%n", 0, from);
            result.addAll(sorted.subList(0, from));
        }
        if (to < size - 1) {
            System.out.printf("Keeping tail: [%d, %d]%n", to, size);
            result.addAll(sorted.subList(to + 1, size));
        }
        return result;
    }
}

測試:

int[][] tests = {
    {1, 3},
    {7, 10},
    {3, 6},
    {2, 10},
    {1, 9},
    {2, 9}
};
for (int[] test : tests) {
    List<Integer> sorted = IntStream.rangeClosed(1, 10).boxed().collect(Collectors.toList());
    System.out.println("result: " + removeFrom(sorted, test[0], test[1]) + "\n====\n");
}

輸出

Removing values 1..3
Removing range: [0, 2]
result: [4, 5, 6, 7, 8, 9, 10]
====

Removing values 7..10
Removing range: [6, 9]
result: [1, 2, 3, 4, 5, 6]
====

Removing values 3..6
Removing range: [2, 5]
result: [1, 2, 7, 8, 9, 10]
====

Removing values 2..10
Keeping head: [0, 1]
result: [1]
====

Removing values 1..9
Keeping tail: [8, 10]
result: [10]
====

Removing values 2..9
Keeping head: [0, 1]
Keeping tail: [8, 10]
result: [1, 10]
====

所以,在最好的情況下,復雜度是 O(M),其中 M 是剩余部分的大小。

暫無
暫無

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

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