两数相加

163 阅读2分钟

这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战

1.LeetCode两数相加

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

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

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

示例 1:

输入: l1 = [2,4,3], l2 = [5,6,4]
输出: [7,0,8]
解释: 342 + 465 = 807.

根据题目可得,每个节点都只能存储一位数,但是当两个节点值相加时有可能变为2位数的值,比如5->4->3和5->1,这个时候5和5相加等于10,一个节点不能存两位数,所以这个时候需要往下个节点进1,为什么是1,因为10/10=1。两个链表还有可能长度不一致,那我们可以把短链表后面的节点看成0,这样就可以和长链表相加了。

方法1

同时遍历两个链表,将两个节点值相加,顺便创建结果链表的节点,把和赋值到该节点上直到两个链表都没有下一个节点,链表长度有可能不一样,会造成长链表还在遍历,而短链表后面已经没节点了,此时可以把短链表后面节点值当做0来于长链表节点相加,当两个链表的节点值相加超过个位数时可以往后的节点进位,就需要维护一个进位变量carry,carry默认为0,节点值相加时也得加上进位变量。进位变量的值为两个节点值/10。最后如果进位值不为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) {
        ListNode sumListNode = new ListNode();
        ListNode nodeTemp = sumListNode;
        int carry = 0;
        while (l1 != null || l2 != null) {
            int sum = 0;
            if (l1 != null) {
                sum += l1.val;
                l1 = l1.next;
            }
            if (l2 != null) {
                sum += l2.val;
                l2 = l2.next;
            }
            sum += carry;
            carry = sum / 10;

            nodeTemp.next = new ListNode(sum % 10);
            nodeTemp = nodeTemp.next;
        }
        if (carry > 0) {
            nodeTemp.next = new ListNode(carry);
        }
        return sumListNode.next;
    }
}

方法2

递归的写法其实也是同时循环两个链表,节点值相加后再赋给新链表的节点。节点相加时注意也加上进位值,两个链表都是空的时候就得结束递归了,同时还需判断进位值大于0的情况需要多加一个节点。

class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        return recursion(l1, l2, 0);
    }

    public ListNode recursion(ListNode node1, ListNode node2, int carry) {
        if (node1 == null && node2 == null) {
            // 两个链表都是空了
            return carry > 0 ? new ListNode(carry) : null;
        }
        if (node1 != null) {
            carry += node1.val;
            node1 = node1.next;
        }
        if (node2 != null) {
            carry += node2.val;
            node2 = node2.next;
        }
        return new ListNode(carry % 10, recursion(node1, node2, carry / 10));
    }
}