给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。
示例1:
输入:l1 = [7,2,4,3], l2 = [5,6,4] 输出:[7,8,0,7]示例2:
输入:l1 = [2,4,3], l2 = [5,6,4] 输出:[8,0,7]示例3:
输入:l1 = [0], l2 = [0] 输出:[0]提示:
- 链表的长度范围为
[1, 100]
0 <= node.val <= 9
- 输入数据保证链表代表的数字无前导 0
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
l1 = reverse(l1);
l2 = reverse(l2);
int flag = 0;
ListNode tmp = l1;
ListNode pre = l1;
while(l1!=null || l2!=null) {
int add1 = l1 == null ? 0 : l1.val;
int add2 = l2 == null ? 0 : l2.val;
int sum = flag+add1+add2;
flag = sum/10;
sum = sum%10;
if(l1 != null) {
if(l1 != tmp) pre = pre.next;
l1.val = sum;
l1 = l1.next;
} else {
ListNode x = new ListNode(sum);
pre.next = x;
pre = x;
}
if(l2 != null) l2 = l2.next;
}
if(flag != 0) {
ListNode x = new ListNode(flag);
pre.next = x;
pre = x;
}
l1 = reverse(tmp);
return l1;
}
public ListNode reverse(ListNode l1) {
ListNode pre = l1;
ListNode now = l1.next;
ListNode tmp;
while(now != null) {
tmp = now.next;
now.next = pre;
pre = now;
now = tmp;
if(tmp == null) break;
}
l1.next = null;
l1 = pre;
return l1;
}
}
今天是一道中等题。还是链表相关的。实际上和昨天的题目差不多。
今天这道题仍然是链表相关的加法题。但今天这道题就没昨天那么顺了。最快想到的思路应该就是反转链表了。反转链表,之后再使用昨天的方法进行相加。博主这里直接使用l1链表来存储结果。由于是链表,要注意null的情况。所以需要一个pre的指针来指向l1的前一个,这里是由于用l1来存储结果,如果l1是位数较小的数,那么就需要新建链表结点。所以需要一个pre来存住链表的最后一个位置,而l1则可以继续作为判断的标准。这样全加完之后,有可能有进位,就需要再对flag最后处理一次。处理完反转链表即可。
这是通过的情况:
那么,问题来了?不能反转链表的话,应该怎么做?首先,我们注意到这里是从头部开始。加法运算是从尾部加上来。那反转顺序会想到什么?栈!,先进后出的数据结构。我们可以创建两个栈,把所有数字都放入这两个栈, 再逐个取出,相加,计算进位。并使用头插的方法创建链表(不要思维定式了,觉得链表next就只能往后加。)这样就可以实现不反转的解题啦。
其他的解法,大家可以去力扣看看原题的题解。有更多解法也可以发在评论区,大家一起讨论。