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
(链表专题) 445. 两数相加 II ——Leetcode每日一题
LeetCode 445. 两数相加 II Add Two Numbers II (Medium)