Algorithm 为什么空间复杂度为O(n)的算法比复杂度为O(1)的算法使用更少的内存?
问题涉及: 给您两个非空链表,表示两个非负整数。这些数字以相反的顺序存储,它们的每个节点都包含一个数字。将两个数字相加,并以链表形式返回总和Algorithm 为什么空间复杂度为O(n)的算法比复杂度为O(1)的算法使用更少的内存?,algorithm,space-complexity,Algorithm,Space Complexity,问题涉及: 给您两个非空链表,表示两个非负整数。这些数字以相反的顺序存储,它们的每个节点都包含一个数字。将两个数字相加,并以链表形式返回总和 Input: l1 = [2,4,3], l2 = [5,6,4] Output: [7,0,8] Explanation: 342 + 465 = 807. 我比较了以下两种解决方案: 空间复杂度为O(1)的算法 它使用了超过39000kb的内存: 空间复杂度为O(n)的算法 而且它使用的内存小于39000kb: 我很困惑。我在计算
Input: l1 = [2,4,3], l2 = [5,6,4]
Output: [7,0,8]
Explanation: 342 + 465 = 807.
我比较了以下两种解决方案:
空间复杂度为O(1)的算法
它使用了超过39000kb的内存:
空间复杂度为O(n)的算法
而且它使用的内存小于39000kb:
我很困惑。我在计算空间复杂度时出错了吗?您不应该太依赖这些内存使用情况报告。对于Java,有些方面不在您的控制之下,它们仍然会影响内存使用。例如,垃圾收集器自行决定何时将内存回收为空闲内存。此外,解析代码需要内存,并且不确定代码是否能够在专门用于运行程序的环境中运行。当然,测试代码也在相同的环境中运行。如果一些测试是随机的,以至于内存占用也依赖于它,那么这是另一个起作用的因素 您可能会发现,多次提交相同的代码会导致内存报告略有不同 在这些报告中,重要的是您的解决方案是否与其他高效解决方案的得分相对接近,并且不会占用50%以上的内存。在您的示例中,我们看到这些报告比较接近,差异不到1%。如果你把它们打印在一个X轴从0开始的图形上,你会注意到它们是多么的接近。该裕度可以忽略不计,并且在不同的运行中也会发生变化 至于算法:
一个使用O(1)辅助存储器,另一个使用O(1)辅助存储器,这是事实(你能同时提到这两种算法吗?这有助于分析。列表大小是多少?每个节点将占用大约12个字节,而你报告的是39MB,仅仅添加100个节点不会有任何区别。我会对leetcode的内存使用情况报告持保留态度。垃圾收集等方面可能会影响se统计数据,即使是相同的代码有时也会以不同的方式报告其内存使用情况。@trincot是的,我提交了这两个数据,得到了相反的结果。在问“为什么”之前首先确定它是真的…谢谢你这么多,你让我学到很多。我很抱歉这么晚才回复你。再次感谢。欢迎你。请考虑将这个解决方案标记为接受。
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode l1Pointer = l1;
ListNode l2Pointer = l2;
while(l1Pointer != null){
if(l2Pointer != null)
l1Pointer.val += l2Pointer.val;
if(l1Pointer.val >= 10){
l1Pointer.val -= 10;
if(l1Pointer.next != null) l1Pointer.next.val++;
else if(l2Pointer != null && l2Pointer.next != null) l2Pointer.next.val++;
else l1Pointer.next = new ListNode(1);
}
if(l1Pointer.next == null && l2Pointer != null && l2Pointer.next != null){
l1Pointer.next = l2Pointer.next;
l2Pointer.next = null;
}
l1Pointer = l1Pointer.next;
if(l2Pointer != null)
l2Pointer = l2Pointer.next;
}
return l1;
}
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode c1 = l1;
ListNode c2 = l2;
ListNode sentinel = new ListNode(0);
ListNode d = sentinel;
int sum = 0;
while (c1 != null || c2 != null) {
sum /= 10;
if (c1 != null) {
sum += c1.val;
c1 = c1.next;
}
if (c2 != null) {
sum += c2.val;
c2 = c2.next;
}
d.next = new ListNode(sum % 10);
d = d.next;
}
if (sum / 10 == 1)
d.next = new ListNode(1);
return sentinel.next;
}