我有两个链表,按照从最重要到最不重要的顺序表示十进制数字的数字。例如4->7->9->6
和5->7
答案应该是4->8->5->3
而不会颠倒列表,因为撤消列表会导致效率下降。
我正在考虑使用stack解决问题。我将遍历两个列表并将数据元素推送到两个单独的堆栈中。每个链接列表。然后我将两个堆栈一起弹出并添加两个元素,如果结果是两位数,没有I 10模数并将进位存储在临时变量中。余数存储在节点中,进位被加到下一个总和,依此类推。 如果两个堆栈是s1和s2,结果链接列表是res。
temp = 0;
res = (node*)(malloc(sizeof(node*));
while(s1->top!=-1 || s2->top!=-1)
{
temp = 0;
sum = pop(s1) + pop(s2);
n1 = (node*)(malloc(sizeof(node*));
temp = sum/10;
sum = sum%10;
sum = sum+temp;
n1->data = sum;
n1->next = res;
res = n1;
free n1;
//temp=0;
}
if((s1->top==-1)&&(s2->top==-1))
{
return res;
}
else if(s1->top==-1)
{
while(s2->top!=-1)
{
temp = 0;
sum = pop(s2);
sum = sum + temp;
temp = sum/10;
sum = sum%10;
n1 = (node*)(malloc(sizeof(node*));
n1->data = sum;
n1->next = res;
res = n1;
free n1;
}
}
else
{
while(s2->top!=-1)
{
temp = 0;
sum = pop(s2);
sum = sum+temp;
temp = sum/10;
sum = sum%10;
n1=(node*)(malloc(sizeof(node*));
n1->data = sum;
n1->next = res;
res = n1;
free n1;
}
}
return res;
我在面试问题中多次遇到过这个问题,但这是我能想到的最好的解决方案。 如果有人能在c中找到更高效的东西,我将非常高兴。
答案 0 :(得分:11)
两次传球,没有筹码:
获取两个列表的长度。
使用一个节点创建解决方案列表。将此节点的值初始化为零。这将保持进位数。将列表指针(称为进位指针)设置为此节点的位置。将列表指针(称为结束指针)设置为该节点的位置。
从较长的列表开始,对于每个多余的节点,将新节点链接到结束指针并为其分配多余节点的值。将结束指针设置为此新节点。如果 value小于9,将进位指针设置为新节点。
现在我们留下两个列表指针,每个列表指针的节点数相同。
虽然列表不是空的......
将新节点链接到结束指针并将结束指针前进到此节点。
从每个列表中获取值并将每个列表指针前进到下一个节点。
将两个值加在一起。
如果value大于9,则将值设置为value mod 10
,递增进位指针节点中保存的值,将进位指针移动到下一个节点。如果进位指针的值为9,则设置为零并转到下一个节点。
如果值为9。设置它。别无其他。
如果值小于9。设置它。将进位指针设置为当前节点。
完成两个列表后,检查解决方案指针的节点值是否为零。如果是,则将解决方案指针设置为下一个节点,删除不需要的额外数字。
答案 1 :(得分:5)
这就是我要解决的问题:
第1步:在两个链接列表上传递,找到长度
说len(L1) = m and len(L2) = n
第2步:查找长度差异
if ( m > n )
d = m - n
else if ( n > m )
d = n - m
else
d = 0
第3步:将临时指针d移到较大列表前面
第4步:现在我们有两个链接列表要添加其长度相同,所以递归添加它们,保持进位。
第5步: (注意:如果(d == 0)不执行此步骤)
在第4步之后,我们有了部分输出列表,现在我们必须将更大的列表的剩余部分放在输出列表的开头。
if ( d > 0 )
-Travel larger list till d positions recursively
-Append sum = value_at_end + carry (update carry if sum >= 10) to output list at beginning
-Repeat until difference is consumed
注意:我正在解决问题,因为它摆在我面前,而不是建议更改基础数据结构。
时间复杂度:
O(m+n)
O(n)
,假设m > n
O(d)
总计:O( (m+n) + (n) + (d) )
或O(m+n)
空间复杂性:
O(n)
,运行时堆栈空间O(d)
,运行时堆栈空间总计:O(n + d)
或O(n)
答案 2 :(得分:4)
我只是分别找到每个链表的总价值,将它们加在一起,然后将该数字转换为新的链表。因此,将4-> 7-> 9-> 6和5-> 7转换为分别具有值4796和57的整数。将它们加在一起得到4853,然后将其转换成包含4-> 8-> 5-> 3的链表。您可以使用简单的数学运算进行转换。
如果您改变了首先表示数字的方式,那么按照自己的方式进行操作将会轻松得多。这样,数字总是第一位,然后是十位数,接着是数百位,等等。
编辑:因为你显然使用了大量的数字:你有没有考虑过制作双链表?那么你本身就不需要扭转它。只是向后移动它。答案 3 :(得分:3)
使用堆栈并不比撤消列表更有效(实际上 正在反转列表)。如果您的堆栈对象是动态分配的,这没什么大不了的,但如果您使用调用递归创建它,您将很容易得到错误排序的堆栈溢出。 : - )
答案 4 :(得分:3)
如果您对列表进行双重链接,则可以添加数字并使用向后链接查找放置值的位置。 http://en.wikipedia.org/wiki/Doubly_linked_list