如何在O(N)时间和O(C)空间复杂度下使用Java8流API仅从列表中删除一个max(min)
下面是一段代码,用于从列表中仅删除一个最大值(在本例中为第一个,但这与此无关)。它在时间上是如何在O(N)时间和O(C)空间复杂度下使用Java8流API仅从列表中删除一个max(min),java,java-8,max,java-stream,Java,Java 8,Max,Java Stream,下面是一段代码,用于从列表中仅删除一个最大值(在本例中为第一个,但这与此无关)。它在时间上是O(n),在空间上是O(n)(输入之外) public List removeoneofmax(List nums){ int max=整数的最小值; int maxIndex=-1; 迭代器it=nums.Iterator(); for(int i=0;it.hasNext();i++){ 整数temp=it.next(); 如果(最大值nums.get(i)>=nums.get(j)?i:j。这个+答
O(n)
,在空间上是O(n)
(输入之外)
public List removeoneofmax(List nums){
int max=整数的最小值;
int maxIndex=-1;
迭代器it=nums.Iterator();
for(int i=0;it.hasNext();i++){
整数temp=it.next();
如果(最大值<温度){
maxIndex=i;
最大值=温度;
}
}
nums.remove(maxIndex);
返回nums;
}
1.使用Java8流API的方法的等效性是什么?我想保留时间和空间的复杂性,因此不允许排序
2.实际上,如果将LinkedList
传递到上述代码中,那么空间复杂度将是O(C)
(同样,超出了输入),但据我所知,.stream()
创建了一个额外的数据结构,因此流API在空间中必须至少是O(N)
。如果我错了,请纠正我。流解决方案可能如下所示:
int maxIndex = IntStream.range(1, nums.size()).reduce(0, (i, j) -> {
int left = nums.get(i);
int right = nums.get(j);
return Integer.max(left, right) == left ? i : j;
});
nums.remove(maxIndex);
下面将有一个拆分器
流操作本身不会创建额外的数据结构。为什么您认为这是空间中的“
O(n)
”?由于已经存在的列表
不计算在内,因此没有随列表大小扩展的内存需求。这是空间中的O(1)
,无论您是使用ArrayList
还是LinkedList
。使用CopyOnWriteArrayList
时会有所不同,但这不是算法的责任。ArrayList.remove(int)
。也许你把它和添加混淆了。然而,即使它是如此昂贵,它也不是您的算法的属性。事实上。除非调用trimToSize()
,否则它永远不会收缩其数组。但是,对于这种行为没有明确的规范。规范所说的是,容量将根据需要增长(非线性,以保证“固定摊销时间成本”)。@GA1 Holger的最后一点不仅适用于ArrayList,也适用于几乎所有其他类型。HashMap内部数组在删除元素时也不会收缩。@Holger您在这里的评论回答了OP提出的更多问题,然后是我发布的实际答案。请您添加这些作为答案,我将非常乐意投票。通常,建议使用现有的方法,但在这里,这只会使代码更加复杂。整个lambda表达式可以简化为(i,j)->nums.get(i)>=nums.get(j)?i:j
。这个+答案正是我想要的
int maxIndex = IntStream.range(1, nums.size()).reduce(0, (i, j) -> {
int left = nums.get(i);
int right = nums.get(j);
return Integer.max(left, right) == left ? i : j;
});
nums.remove(maxIndex);