力扣-2. 两数相加

╄→尐↘猪︶ㄣ 提交于 2020-09-29 15:44:37

1.题目

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

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

示例:

输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

2.我的解题思路

  第一次拿到这个题目个人认为是写起来别扭的链表应用题,由于没有说链表有多长,我很早就放弃了转成int的思路。我解题的时候,就是简单的思路:以长的链表为基础加短的链表,然后处理长的链表和进位,最后如果还有进位处理进位。我承认办法很土,没啥巧妙,以下贴出勉强能AC的代码:

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode resultListNodeHead = null;
        ListNode l1Pointer = l1;
        ListNode l2Pointer = l2;
        while (l1Pointer != null && l2Pointer != null) {
            l1Pointer = l1Pointer.next;
            l2Pointer = l2Pointer.next;
        }
        ListNode longerListPointer = l1;
        ListNode shorterListPointer = l2;
        if (l2Pointer != null) {
            // l2 longer
            longerListPointer = l2;
            shorterListPointer = l1;
        }
        resultListNodeHead = longerListPointer;
        ListNode resultListNodeHeadForCreate = longerListPointer;
        // 遍历长链表,加短链表
        int carry = 0;
        while (shorterListPointer != null) {
            int shortVal = shorterListPointer.val;
            int longerVal = longerListPointer.val;
            int resultVal = shortVal + longerVal + carry;
            if (carry == 1) {
                carry = 0;
            }
            if (resultVal >= 10) {
                resultVal -= 10;
                carry = 1;
            }
            longerListPointer.val = resultVal;
            longerListPointer = longerListPointer.next;
            shorterListPointer = shorterListPointer.next;
        }
        // 处理长链表和进位
        while (longerListPointer != null) {
            int longerVal = longerListPointer.val;
            int resultVal = longerVal + carry;
            if (carry == 1) {
                carry = 0;
            }
            if (resultVal >= 10) {
                resultVal -= 10;
                carry = 1;
            }
            longerListPointer.val = resultVal;
            longerListPointer = longerListPointer.next;
        }
        // 若还有进位没有处理,添加
        if (carry == 1) {
            if (longerListPointer == null) {
                while (resultListNodeHeadForCreate != null) {
                    if (resultListNodeHeadForCreate.next == null) {
                        resultListNodeHeadForCreate.next = new ListNode(1);
                        break;
                    } else {
                        resultListNodeHeadForCreate = resultListNodeHeadForCreate.next;
                    }
                }
            } else {
                int resultVal = longerListPointer.val + 1;
                if (resultVal == 10) {
                    longerListPointer.val = 0;
                    longerListPointer.next = new ListNode(1);
                } else {
                    longerListPointer.val = resultVal;
                }
            }
        }
        return resultListNodeHead;
    }

3. 官方解答

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
    ListNode dummyHead = new ListNode(0);
    ListNode p = l1, q = l2, curr = dummyHead;
    int carry = 0;
    while (p != null || q != null) {
        int x = (p != null) ? p.val : 0;
        int y = (q != null) ? q.val : 0;
        int sum = carry + x + y;
        carry = sum / 10;
        curr.next = new ListNode(sum % 10);
        curr = curr.next;
        if (p != null) p = p.next;
        if (q != null) q = q.next;
    }
    if (carry > 0) {
        curr.next = new ListNode(carry);
    }
    return dummyHead.next;
}

4. 感想

4.1.不考虑哪个更长,不够长的补为0

链表相加的问题,必然会有长链短链,但我们只需要处理到链表末尾,给出最终结果即可,不需要过程,所以不需要得知哪个链更长。那不够长的链表如何变得和长链表一样长呢?补充0!对应答案中的代码:

while (p != null || q != null) {
        int x = (p != null) ? p.val : 0;
        int y = (q != null) ? q.val : 0;

4.2.多申请一个无用的头节点

本题中的链表很别扭,构造函数必须给一个值,让我下意识跟随题目的引导去编程。其实应当声明一个无用的头节点,然后.next的方式返回答案即可。对应答案中的代码:

ListNode dummyHead = new ListNode(0);
...
return dummyHead.next;
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!