LeetCode 445 两数相加 II

Posted wtzhang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 445 两数相加 II相关的知识,希望对你有一定的参考价值。

链接:https://leetcode-cn.com/problems/add-two-numbers-ii

给定两个非空链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储单个数字。将这两数相加会返回一个新的链表。

你可以假设除了数字 0 之外,这两个数字都不会以零开头。

进阶:

如果输入链表不能修改该如何处理?换句话说,你不能对列表中的节点进行翻转。

示例:

输入: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
输出: 7 -> 8 -> 0 -> 7

 

这道题呢,也有两种解法,一种是用栈来做,另一种是用递归来做。栈解法比较简单直观,所以先来看看用栈怎么做的吧~

首先,我们把这两个链表分别用两个栈存储,那么因为栈是先进后出的结构嘛,所以呢,每次取栈的top元素,相当于就是取链表的尾结点啦。得到两个尾结点,那当然就要把它们求和咯。到这里,就像前一道倒序链表求和题了。。进位的处理啊,链表长度不一啊。

重点有三:sum = p + q + carry、新结点的值是sum%10、进位carry的值是sum/10.

当一个栈为空时,此时令其对应的值为0就好啦。

但是,这道题的答案链表是正序的,所以要用头插法,也就是,每次new出来的求和结点应当放在链表的头部。这个实现也不难,一开始我们令答案链表res为nullptr,然后每次都让new出来的结点tmp指向res,再让res=tmp就可以了。

 

c++代码如下:

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
12         stack<int> p, q;
13         while(l1) p.push(l1->val), l1 = l1->next;
14         while(l2) q.push(l2->val), l2 = l2->next;
15         
16         int carry = 0;
17         ListNode* res = nullptr;
18         while(p.size() || q.size() || carry){
19             int m = 0, n = 0;
20             if(p.size()) {
21                 m = p.top();
22                 p.pop();
23             }
24             if(q.size()) {
25                 n = q.top();
26                 q.pop();
27             }
28             int sum = m + n + carry;
29             carry = sum / 10;
30             ListNode* tmp = new ListNode(sum % 10);
31             tmp->next = res;
32             res = tmp;
33         }
34         return res;
35     }
36 };

 

用递归来解的话,我们第一步要将两个链表补齐,为什么要补齐,因为之后的递归函数的需要。。那怎么补齐嘞,就是让短的那个链表前面补上0。既然是前面补0,那还是用上面所说的头插法,很简单吧~当然首先要遍历两个链表,来判断哪个长,哪个短哈哈,这个就不用说啦。

然后就是最重要的递归函数了,我们这个递归函数呢,返回的是当前位置产生的进位噢!知道了函数的目的,就很好写这个函数了。当前位置的进位,要看当前位置结点的和,还有低位来的进位,对吧~低位来的进位,没错,就是在这里递归~边界条件是当链表为空时,最低位肯定是没有进位的,直接返回0即可。因为在计算进位的时候,是需要求和的,在这个过程中,答案链表res就可以得到了。

如果最后carry不为0,那么肯定为1,再new一个值为1的结点,放到链表头部就好了~

 

c++代码如下:

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     int addTwoNumbersHelper(ListNode* l1, ListNode* l2, ListNode* &res) {
12         if(!l1) return 0;
13         int carry = addTwoNumbersHelper(l1->next, l2->next, res);
14         int sum = l1->val + l2->val + carry;
15         ListNode* s = new ListNode(sum % 10);
16         s->next = res;
17         res = s;
18         return sum / 10;
19     }
20     
21     ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
22         ListNode* dummy = new ListNode(-1);
23         ListNode* res = nullptr;
24         auto p = l1, q = l2;
25         int carry = 0, m = 0, n = 0;
26         while(l1) l1 = l1->next, m++;
27         while(l2) l2 = l2->next, n++;
28         
29         if(m > n){
30             int k = m - n;
31             dummy->next = q;
32             while(k--){
33                 auto tmp = new ListNode(0);
34                 tmp->next = q;
35                 q = tmp;
36             }
37         }
38         else if(m < n){
39             int k = n - m;
40             dummy->next = p;
41             while(k--){
42                 auto tmp = new ListNode(0);
43                 tmp->next = p;
44                 p = tmp;
45             }
46             
47         }
48         carry = addTwoNumbersHelper(p, q, res);
49         if(carry){
50                 auto tmp = new ListNode(1);
51                 tmp->next = res;
52                 res = tmp;
53         }
54         return res;
55     }
56 };

 

以上是关于LeetCode 445 两数相加 II的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode Java刷题笔记—445. 两数相加 II

LeetCode 445 两数相加 II

(链表专题) 445. 两数相加 II ——Leetcode每日一题

LeetCode 445. 两数相加 II Add Two Numbers II (Medium)

LeetCode 445. 两数相加 II Add Two Numbers II (Medium)

LeetCode 0445. 两数相加 II