简体   繁体   English

给定排序列表如何创建在 O(log(N)) 时间内不会落在某个范围内的整数列表?

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

I have a sorted arrayList of integers (no duplicates):我有一个排序的整数数组列表(没有重复项):

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

Lets say given range is [21-38] (inclusive) which has to be excluded from the output list of integers.假设给定的范围是 [21-38](包括),它必须从整数输出列表中排除。

Then the output should contain the list of integers that does not contain the above range.然后输出应包含不包含上述范围的整数列表。

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

I need to do this in O(log(N) ) time.我需要在O(log(N) ) 时间内完成此操作。

The approaches that i could think of at this moment is:我现在能想到的方法是:

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.

Do we have any better approach?我们有什么更好的方法吗?

Removing of elements may be optimized for better cases by estimating a better option by the size of the remainder and removal:通过根据余数和移除的大小估计更好的选项,可以针对更好的情况优化移除元素:

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;
    }
}

Tests:测试:

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");
}

Output输出

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]
====

So, in the best case the complexity is O(M), where M is the size of remaining part.所以,在最好的情况下,复杂度是 O(M),其中 M 是剩余部分的大小。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在O(log(N))时间内找到排序数组中在一定范围内的整数数? - How to find number of integers in a sorted array that are within a certain range in O(log(N)) time? 高效算法在O(log(N))时间内找到排序数组中在一定范围内的整数数量? - Efficient algo to find number of integers in a sorted array that are within a certain range in O(log(N)) time? 获取排序数组中属于log(n)时间的特定范围内的元素数 - Get number of elements in a sorted array that fall within a certain range in log(n) time 在小于 O(n^2) 的范围内对给定的整数列表进行排名 - Ranking a given list of integers in less than O(n^2) 列为O(log(n)) - List as O(log(n)) 鉴于0 &lt; k &lt; n,并且在java中的O(k log n)时间,如何在大小为n的排序数组中获得超过n / k次的任何integer? - how to get any integer in a sorted array of size n that appear more than n/k times, given that 0 < k < n, and in O(k log n) time in java? 如何在O(n)时间内以某个给定大小的块反转单链表? - How to reverse a singly-linked list in blocks of some given size in O(n) time in place? 如何添加,将n个数字乘以数组中的给定范围,并在O(n)时间内反转数组中的范围? - How to add, multiply n numbers to a given range in array and also reverse the range in the array in O(n) time? 如何用O(1)空间和O(n)时间反转列表? - how to reverse a list with O(1) space and O(n) time? 以O(1)空间复杂度对O(n log n)中的链表进行排序 - Sort a linked list in O(n log n) with O(1) space complexity
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM