Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 给定排序列表如何创建在O(log(N))时间内不在某个范围内的整数列表?_Java_Algorithm_Data Structures_Binary Search - Fatal编程技术网

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

Java 给定排序列表如何创建在O(log(N))时间内不在某个范围内的整数列表?,java,algorithm,data-structures,binary-search,Java,Algorithm,Data Structures,Binary Search,我有一个整数的排序数组列表(没有重复项): 假设给定范围为[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 b

我有一个整数的排序数组列表(没有重复项):

假设给定范围为[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.

我们有更好的方法吗?

根据剩余物的大小和移除情况估计更好的选项,可以优化元素移除以获得更好的情况:

静态列表移除(列表排序、int sv、int ev){
inti1=Collections.binarySearch(排序,sv);
int i2=Collections.binarySearch(排序,ev);
int from,to;
如果(i10){
System.out.printf(“保持头部:[%d,%d]%n”,0,从);
result.addAll(sorted.subList(0,from));
}
如果(尺寸小于-1){
System.out.printf(“保留尾部:[%d,%d]%n”,到,大小);
addAll(排序的子列表(到+1,大小));
}
返回结果;
}
}
测试:

int[][]测试={
{1, 3},
{7, 10},
{3, 6},
{2, 10},
{1, 9},
{2, 9}
};
for(int[]测试:测试){
List sorted=IntStream.rangeClosed(1,10).boxed().collect(Collectors.toList());
System.out.println(“结果:+removfrom(已排序,测试[0],测试[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是剩余部分的大小。

没有办法使新列表比O(N)快。不确定是否对输出列表本身进行任何数据操作,但如果不是,您可以将此列表设置为链表,只需将第一个集合的尾部节点的
next
指针更新为第二个列表的head指针。所以,这可以在对数时间内完成。但是,这实际上取决于您在返回输出列表之前尝试执行的操作的未来用例。感谢Mbo和nice_dev。看来使用arraylist无法实现这一点。@SSK在cose O(N)上使用arraylist,使用linkedList可以使用O(log(N)),但代码会很复杂,所以我认为O(N)很好。@TongChen感谢您的输入,我将使用O(N)方法2,
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]
====