2.两数相加(双指针)

137 阅读2分钟

2. 两数相加 - 力扣(Leetcode)

题目描述:

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

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

示例:

输入: l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出: [8,9,9,9,0,0,0,1]

解题:

解释,该题即正常将链表中的值相应的加起来,例如

  • l1:9 9 9 9 9 9 9
  • l2:9 9 9 9
  • rs:8 9 9 9 0 0 0 1

不要和正常的加法联想后干扰思路

  • 9 9 9 9 9 9 9
  • 0 0 0 9 9 9 9
  • 1 0 0 0 9 9 8

关键:8->9->9->9->0->0->0->1,将它想象成链表结构,最后返回的时候也是从头开始返回即可。

所以这里我们适合用双指针的思路:

  1. 一个指针currL1指向l1。
  2. 一个指针currL2指向l2。
  3. 一个新的链表res保存这两个指针值相加的结果。
  4. 为了方便后续按顺序输出这个res,我们需要一个新的指针curr来做累加时改变res的指针指向。
  5. (重点)因为涉及到进位
    • 两个数是(0~9)范围,取他们的和余数放在结果中(sum % 10
    • 得到进位sum / 10,让下一次的两个指针相加时带上这个进位,为了通用性,就需要初始时让进位数等于0,这样每次的操作都是相同的了。
  6. 如果最后还进位了,也就是l1和l2的指针都为null了,此时还有进位数存在,这时候需要让curr在某位时在开辟一块空间直接存储这个进位就可。
/**
 * 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) {
        // 双指针的思路
        ListNode currL1 = l1;
        ListNode currL2 = l2;
        // 保存结果
        ListNode res = new ListNode(0);
        // 做每一位的累加,并放在res中
        ListNode curr = res;

        // 进位
        int up = 0;
        while(currL1 != null || currL2 != null){
            int l1Value = currL1 != null ? currL1.val:0;
            int l2Value = currL2 != null ? currL2.val:0;

            int sum = l1Value + l2Value + up;
            // 进位
            up = sum / 10;
            // 余数留下
            curr.next = new ListNode(sum % 10);
            curr = curr.next;

            if(currL1 != null)currL1 = currL1.next;
            if(currL2 != null)currL2 = currL2.next;
        }
        // 如果余数还存在,直接将其值放在尾部
        if(up != 0){
            curr.next = new ListNode(up);
        }
        return res.next;
    }
}