leetcode算法之两数相加

题目描述:

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

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

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

示例:

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

题目解析:

这里leetcode给我们限定的数据结构如下:

class ListNode{
    int val;
    ListNode next;
    ListNode(int x) {
        val = x;
    }
}

2 -> 4 -> 3 + 5 -> 6 -> 4 两个链表长度都一样,计算也比较简单,从左向右依次计算,即l1、l2的第一位相加,l1、l2第二位相加,如果计算结果大于10,则当前位取模(sum%10),计算下一位时需在两数相加结果的前提下+1。这里需考虑如下三种情况:

  1. l1长度等于l2
  2. l1长度大于l2
  3. l1长度小于l2

有了前面的逻辑,下面是我实现的代码,该代码还有很多可以改进的地方,但是不影响整体逻辑:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode nodeList1 = l1;
        ListNode nodeList2 = l2;
        ListNode firstNode = nodeList1;
        boolean first = true;
        // 判断前面一个数是否>10,否则近一
        boolean flag = false;
        // 相加后的值对10取余
        int digit = 0;
        while (nodeList1.next != null && nodeList2.next != null) {
            if (flag) {
                digit = nodeList1.val + nodeList2.val + 1;
                flag = false;
            } else {
                digit = nodeList1.val + nodeList2.val;
            }
            if (digit >= 10) {
                flag = true;
            }
            digit = digit % 10;
            // 将计算后的值放入nodeList1中
            nodeList1.val = digit;
            if (first) {
                first = false;
            }
            // 迭代
            nodeList1 = nodeList1.next;
            nodeList2 = nodeList2.next;
        }


        // 确定链表最后一个元素不被忽略
        if (flag) {
            digit = nodeList1.val + nodeList2.val + 1;
            flag = false;
        } else {
            digit = nodeList1.val + nodeList2.val;
        }
        if (digit >= 10) {
            flag = true;
        }
        digit = digit % 10;
        // 将计算后的值放入nodeList1中
        nodeList1.val = digit;



        if (nodeList1.next != null) { // l1 > l2
            nodeList1 = nodeList1.next;
            // 如果l1、l2对齐的最后一位之和大于10,这里人要对l1下一位近一
            // 如果输入为l1[9,9], l2[9]时,该逻辑会出错
            while (nodeList1.next != null) {
                if (flag) {
                    nodeList1.val = nodeList1.val + 1;
                    flag = false;
                }
                if (nodeList1.val >= 10) {
                    nodeList1.val = nodeList1.val % 10;
                    flag = true;
                }
                nodeList1 = nodeList1.next;
            }
            if (flag) {
                nodeList1.val = nodeList1.val + 1;
                if (nodeList1.val >= 10) {
                    nodeList1.val = nodeList1.val % 10;
                    nodeList1.next = new ListNode(1);
                }
            }

        } else if (nodeList2.next != null) { // l1 < l2,将l2链表追加到l1上
            nodeList2 = nodeList2.next;
            nodeList1.next = nodeList2;
            while (nodeList2.next != null) {
                if (flag) {
                    nodeList2.val = nodeList2.val + 1;
                    flag = false;
                }
                if (nodeList2.val >= 10) {
                    nodeList2.val = nodeList2.val % 10;
                    flag = true;
                }
                nodeList2 = nodeList2.next;
            }
            if (flag) {
                nodeList2.val = nodeList2.val + 1;
                // l1[1],l2[9, 9] ==> 0-0-1
                if (nodeList2.val >= 10) {
                    nodeList2.val = nodeList2.val % 10;
                    nodeList2.next = new ListNode(1);
                }
            }
        } else { // l1 == l2,如果l1、l2两个元素均为5,则还需计算下一位,否则直接返回firstNode即可
            if (flag) {
                // 此时nodeList1下一位肯定是null,这里需要重新构建一个新的ListNode以重新构建链表
                nodeList1.next = new ListNode(0);
                nodeList1 = nodeList1.next;
                nodeList1.val = nodeList1.val + 1;
            }
        }
        // l1 == l2 则直接返回firstNode即可
        return firstNode;
    }
}

该开始提交上去一直报错,原因是由于很多极值情况未考虑到,如[0],[0]、[5],[5]、[9],[9,9]等,不过补充完后也能正常运行,后来发现打败了全国14%的用户,真的好忏愧,不过上面代码还是有很多改进的地方,不过整体逻辑蛮清楚,可以提供很多参考。

这里是正确答案。

你可能感兴趣的:(D&A)