版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hang404/article/details/84781505
题目描述:
给出两个非空的链表用来表示两个非负的整数。其中,它们各自的位数是按照逆序的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
题目解答:
方法1:正向遍历+标志位
将对应位置值相加,并加上上一次的标志位的值,判断和是否大于10,更新标志位,大于10的情况下,和减去10就是当前位置的新值。
最开始考虑在原链表上直接操作,但由于两个链表长度可能不一样,这时候就需要将长链表剩余的节点添加在已操作链表的尾部,重新连起来,意味着每次都需要更新存储一下前一个节点,这样方便连接剩余节点,感觉逻辑会比较复杂,而且会破坏原链表,所以放弃这种方式(也可以解,大致思路一样)。采用每个节点都重新申请空间的方式。
申请头结点,方便插入新节点,后边遍历的逻辑更清晰。一个标志记录当前两个数字相加之后是否会产生进位,循环的条件为链表1节点、链表2节点、flag
三者之一存在一个,在内部维持一个指针,记录此时最后一个节点,用于追加新节点。运行时间20ms,代码如下。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
int flag = 0, t = 0;
struct ListNode* result = (struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode* head = result;
while(l1 || l2 || flag) {
struct ListNode* add = (struct ListNode*)malloc(sizeof(struct ListNode));
t = l1 ? l1->val : 0;
t += l2 ? l2->val : 0;
t += flag;
add->val = (t > 9 ? t - 10 : t);
add->next = NULL;
flag = (t > 9 ? 1 : 0);
if(l1)
l1 = l1->next;
if(l2)
l2 = l2->next;
result->next = add;
result = add;
}
result = head->next;
free(head);
return result;
}