我正在尝试为上面提到的问题编写一个程序,数字(即列表)可能长度不等,除了最常见的方法之外,我无法找到一种方法来做到这一点即
这应该是O(n + m)的复杂性。无论如何要减少它,还是做得更好?
答案 0 :(得分:3)
理想情况下,我要做的第一件事就是将数字存储在反向数字顺序中,因此将43,412存储为:
2 -> 1 -> 7 -> 3 -> 4
它使算术运算更多更容易。
显示数字可以迭代地完成,也可以使用递归算法更简单地完成。 注意:所有这些都假定单链接列表。
编辑但您已经声明您无法选择存储格式。因此,最好的办法是反转两个列表,进行添加,然后反转结果。
答案 1 :(得分:3)
没有列表反转,您可以做得更好。 WLOG我假设两个列表的长度相等(如果需要,前缀为0)。
从左到右开始添加(从最重要的数字到最不重要的数字)。您有三种情况,取决于两位数的总和:
counter
counter
x九,写入总和,重置counter
9:增加最后一位数,写
counter
x零,写入总和(模10),重置计数器
我将处理以下示例:
2 568 794 +
1 438 204
--------- =
4 006 998
2 + 1 = 3
:案例3。
list = (3)
,counter = 0
5 + 4 = 9
:案例1
list = (3)
,counter = 1
6 + 4 = 9
:案例1
list = (3)
,counter = 2
8 + 8 = 16
:案例3
list = (4, 0, 0, 6)
,counter = 0
7 + 2 = 9
:案例1
list = (4, 0, 0, 6)
,counter = 1
9 + 0 = 9
:案例1
list = (4, 0, 0, 6)
,counter = 2
4 + 4 = 8
:案例2
list = (4, 0, 0, 6, 9, 9, 8)
,counter = 0
答案 2 :(得分:1)
如果您可以使用双向链表,那么您可以快速遍历每个列表的末尾,然后继续前进,在每个点添加数字并将其添加到新列表中。
您需要确定哪个列表更长,并根据较短列表的长度加起来,然后只需完成求和并添加更长的列表。
但是,你会遇到一些问题,即总和可能超过一位数,所以如果发生这种情况,你需要跟踪溢出并将其添加到下一个节点。
答案 3 :(得分:1)
我认为没有更好的解决问题的方法。根本问题是您必须以相反的顺序处理列表元素。从理论上讲,您可以递归地实现算法,从而避免使用显式的反转步骤。但这需要O(max(m,n))
堆栈空间,并且很可能会更慢。
但我认为这确实是说你选择了一个糟糕的代表。如果您将数字表示为int
或int
数组(具有明确大小)的双向链接列表,则复杂度将为O(max(m,n))
,并且具有较小的比例常数。
注意:O(max(m,n))
和O(m+n)
都是O
符号的滥用。严格地说,O
是根据限制定义的,因为单个变量变为无穷大。以这种方式查看,O(max(m,n))
和O(m+n)
都缩减为O(m)
或O(n)
。但是,我明白你要说的是: - )。
答案 4 :(得分:0)
唯一可能以代码清晰度为代价的潜在优化是将初始反转组合成单个循环。然后从O(n + m + m)到O(m + m),尽管循环内的步骤更昂贵。