微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

给定排序列表如何创建在OlogN时间内不会落入一定范围的整数列表?

如何解决给定排序列表如何创建在OlogN时间内不会落入一定范围的整数列表?

我有一个排序的arrayList of integers(没有重复项):

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

假设给定范围为[21-38](含),必须将其排除在整数输出列表之外。

然后输出应包含不包含上述范围的整数列表。

{1,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,from);
            result.addAll(sorted.subList(0,from));
        }
        if (to < size - 1) {
            System.out.printf("Keeping tail: [%d,to,size);
            result.addAll(sorted.subList(to + 1,size));
        }
        return result;
    }
}

测试:

int[][] tests = {
    {1,3},{7,10},{3,6},{2,{1,9},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,6]
====

Removing values 3..6
Removing range: [2,5]
result: [1,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为剩余部分的大小。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。