[LeetCode] Add Two Numbers II 两个数字相加之二 【Leetcode 题解 - 链表-(7)-链表求和】
You are given two linked lists representing two non-negative numbers. The most significant digit comes first and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
You may assume the two numbers do not contain any leading zero, except the number 0 itself.
Follow up:
What if you cannot modify the input lists? In other words, reversing the lists is not allowed.
Example:
Input: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 8 -> 0 -> 7
翻转链表的话想到能有栈和递归两种
这道题是之前那道Add Two Numbers的拓展,我们可以看到这道题的最高位在链表首位置,如果我们给链表翻转一下的话就跟之前的题目一样了,这里我们来看一些不修改链表顺序的方法。由于加法需要从最低位开始运算,而最低位在链表末尾,链表只能从前往后遍历,没法取到前面的元素,那怎么办呢?我们可以利用栈来保存所有的元素,然后利用栈的后进先出的特点就可以从后往前取数字了,我们首先遍历两个链表,将所有数字分别压入两个栈s1和s2中,我们建立一个值为0的res节点,然后开始循环,如果栈不为空,则将栈顶数字加入sum中,然后将res节点值赋为sum%10,然后新建一个进位节点head,赋值为sum/10,如果没有进位,那么就是0,然后我们head后面连上res,将res指向head,这样循环退出后,我们只要看res的值是否为0,为0返回res->next,不为0则返回res即可,参见代码如下:
/**
* Definition for singly-linked list.
* public class ListNode {
*int val;
*ListNode next;
*ListNode(int x) { val = x;
}
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
//栈来反转链表
Stack s1= new Stack<>();
Stack s2 = new Stack<>();
while(l1 != null){
s1.push(l1.val);
l1 = l1.next;
}
while(l2 != null){
s2.push(l2.val);
l2 = l2.next;
}int sum = 0;
ListNode p1 = new ListNode(0);
while(!(s1.isEmpty() && s2.isEmpty())){
if(!s1.isEmpty()){
sum += s1.pop();
}
if(!s2.isEmpty()){
sum += s2.pop();
}p1.val = sum % 10;
ListNode p2 = new ListNode(sum / 10);
p2.next = p1;
p1 = p2;
sum /=10;
}
return sum == 0 ? p1.next : p1;
//注意返回值考虑进不进位
}
}
下面这种方法使用递归来实现的,我们知道递归其实也是用栈来保存每一个状态,那么也就可以实现从后往前取数字,我们首先统计出两个链表长度,然后根据长度来调用递归函数,需要传一个参数差值,递归函数参数中的l1链表长度长于l2,在递归函数中,我们建立一个节点res,如果差值不为0,节点值为l1的值,如果为0,那么就是l1和l2的和,然后在根据差值分别调用递归函数求出节点post,然后要处理进位,如果post的值大于9,那么对10取余,且res的值自增1,然后把pos连到res后面,返回res,最后回到原函数中,我们仍要处理进位情况,参见代码如下:
这里明确几点:
1. addTwoNumbers里面也需要考虑进位的情况 比如[5],[5] 这种 在help函数里面是不存在post的 无法考虑到进位 或者说[9,2][9]这中情况也是
2.help函数处理直接相加的节点 res 和 其next节点 post 根据post的值考虑进位的情况
/**
* Definition for singly-linked list.
* public class ListNode {
*int val;
*ListNode next;
*ListNode(int x) { val = x;
}
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
int length1= sumLength(l1), length2 = sumLength(l2);
int diff = length1 - length2;
ListNode head = new ListNode(1);
head.next = diff > 0 ? help(l1, l2, diff) : help(l2,l1, -diff);
if(head.next.val > 9){
head.next.val %= 10;
return head;
}
return head.next;
}
private int sumLength(ListNode node){
int sum = 0;
while(node.next != null){
node = node.next;
sum++;
}
return sum;
}
private ListNode help(ListNode l1, ListNode l2, int diff){
if(l1 == null)
return null;
ListNode res = diff == 0 ? new ListNode(l1.val + l2.val) : new ListNode(l1.val);
ListNode post = diff == 0 ? help(l1.next, l2.next, 0) : help(l1.next, l2, diff - 1);
if(post != null && post.val > 9){
post.val %= 10;
res.val++;
}
res.next = post;
return res;
}
}
推荐阅读
- 数据结构与算法|【算法】力扣第 266场周赛
- leetcode|今天开始记录自己的力扣之路
- Python|Python 每日一练 二分查找 搜索旋转排序数组 详解
- 【LeetCode】28.实现strstr() (KMP超详细讲解,sunday解法等五种方法,java实现)
- LeetCode-35-搜索插入位置-C语言
- leetcode python28.实现strStr()35. 搜索插入位置
- Leetcode Permutation I & II
- python|leetcode Longest Substring with At Most Two Distinct Characters 滑动窗口法
- LeetCode 28 Implement strStr() (C,C++,Java,Python)
- Python|Python Leetcode(665.非递减数列)