我正在解决这个问题,实际上我已经完成了。但是,我仍然希望改进我的解决方案。是否有其他方法可以解决此问题,从而降低时间复杂度?我的解的时间complextiy是o(n^2)。此外,我想了一种递归求解的方法,但最后我把两者混合了起来;正如我将“迭代地”遍历以获得 numOfNodes
然后“递归地”遍历以计数最后的节点。我还没有实现它,但我对这个解决方案感到困惑,我不知道它是否正确!
**请先看一看代码,,,,,,,,,,,,,,,,,,,,,,关于它的想法是计数 numOfNodes
在列表中,然后再次遍历,但对于每个节点,我将减少 numOfNodes
. 什么时候 numOfNodes == k
,然后使用for循环计算总和。
代码如下:
public int sum(Node head, int k){
int sum = 0;
int numOfNodes = 0;
Node temp = new Node(0);
temp = head;
while(temp != null){
numOfNodes++;
temp = temp.next;
}
temp = head;
while(temp != null){
if(numOfNodes == k){
for(int i = 0; i<k; i++){
sum += temp.data;
temp = temp.next;
}
}else{
numOfNodes--;
temp = temp.next;
}
}
return sum;
}
提前谢谢你!
4条答案
按热度按时间weylhg0b1#
您的代码对列表中的节点数表示乐观。当列表少于时,它将返回0
k
节点。我认为在这种情况下,应该返回所有节点的总和。至于算法的其余部分:它很好。它使用恒定的辅助内存,并以线性时间运行。它并不像您所想的那样是二次的:尽管您在列表中循环了第二次,但这只会使迭代次数o(2n),仍然是o(n)。
您还可以通过跟踪滞后的第二个节点引用,将两个迭代合并为一个迭代
k
前导节点引用后面的节点。下面是它的外观:
递归解决方案的缺点是需要o(k)堆栈空间。
9q78igpj2#
假设您希望保持空间复杂度为常数o(1),那么您的解决方案看起来是最优的。我还假设它是一个单链表。
顺便说一下,解决方案的时间复杂度不是o(n^2)。它是o(n)。您正在进行一次遍历以获得总计数。这就是o(n)。您正在进行另一次遍历以获得k个节点的计数。这是两个独立的遍历。所以时间复杂度是n+n=2n或o(n)。没有内部循环,因此您的解决方案在o(n)时间复杂度下工作。
cqoc49vn3#
您的迭代解决方案看起来不错,但我建议您将实际计数代码简化为以下内容:
您提到的递归解决方案的优点是只需遍历列表一次,计算顶部
k
返回途中的节点。请注意,我们必须使用一个参考值(我使用的是一个简单的单元素数组),以保持计算出的限制,超过该限制,我们应该对节点进行计数。致电:
a0zr77ik4#
它可以很容易地在计算机中完成
O(N)
时间和O(1)
空间复杂性。其思想是迭代列表一次,并计算列表中的节点数。让列表的大小为
size
.现在再次迭代列表并跟踪访问的节点。如果
i
在所需范围内(最后k
节点),然后将这些节点的值添加到结果中sum
.