声明:此类题为力扣链表编号为 2,445,以及剑指offer的第25题
文章前言
相同点:我们仔细阅读过上面的题后,发现他们其实都是一道题,就是两个链表的每个结点数值相加后组成的一个新的链表
不同点:第一道题,新链表的每个结点的数值和两个链表加和的结果顺序是一致的
不同点:第二题和剑指offer的题目,新链表的每个结点的数值和两个链表逆置后加和的结果顺序是一致的
图解区别:
剑指offer和编号445题:
总的来说:二者差的就是一步逆序的过程
题目大体思路:
步骤一、分别遍历两个链表,加和他们的数值
处理特殊情况:如果哪个链表为空,再次加和就是另一个没有空的链表的结点数值 + 0 + 前面数值加和的进位
图解:
代码表述:
步骤二、处理进位问题
如果两个数值加和后 ≥ 10,我们注意到两个链表的数值都是 0~9 的数值,所以 sum 的范围是[0,18],所以进位最多也就是 1 ,所以记录进位的 carry 只能是在 0 ,1 两个数字间徘徊
所以,当加和后大于等于 10 的时候就存在进位的问题,进位的 1 是加在下一位的加和结果中,当前位置的加和结果是 sum % 10 的结果,利用此 sum 去实例化一个新的结点
代码表述:
处理特殊的进位情况,如果最高位存在进位,假设 3 位数 999 + 1 进一位要变成 4 位数 1000,这样就还需要new一个结点
全部代码:
/**
* 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) {
int carry = 0;
ListNode newHead = new ListNode(0);
ListNode tmp = newHead;
while(l1 != null || l2 != null){
int num1 = l1 != null ? l1.val : 0;
int num2 = l2 != null ? l2.val : 0;
int sum = num1 + num2 + carry;
carry = sum / 10;
ListNode node = new ListNode(sum % 10);
tmp.next = node;
l1 = l1 != null ? l1.next : l1;
l2 = l2 != null ? l2.next : l2;
tmp = tmp.next;
}
if (carry == 1){
ListNode node = new ListNode(carry);
tmp.next = node;
}
return newHead.next;
}
}
成果展示:
剑指offer 25、编号445这两道题就是多一步,逆置操作
全部代码
/**
* 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 = reserve(l1);
l2 = reserve(l2);
// 进位
int carry = 0;
ListNode newHead = new ListNode(0);
ListNode tmp = newHead;
while(l1 != null || l2 != null){
int num1 = l1 != null ? l1.val : 0;
int num2 = l2 != null ? l2.val : 0;
int sum = num1 + num2 + carry;
carry = sum / 10;
tmp.next = new ListNode(sum % 10);
l1 = l1 != null ? l1.next : l1;
l2 = l2 != null ? l2.next : l2;
tmp = tmp.next;
}
if (carry != 0){
tmp.next = new ListNode(carry);
}
return reserve(newHead.next);
}
public ListNode reserve(ListNode node) {
ListNode prev = null;
while(node != null) {
ListNode next = node.next;
node.next = prev;
prev = node;
node = next;
}
return prev;
}
}