2. Add Two Numbers 两数相加

题目:Add Two Numbers 两数相加

难度:中等

You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.

You may assume the two numbers do not contain any leading zero, except the number 0 itself.

Example:

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
Explanation: 342 + 465 = 807.

题意解析:

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

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

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

解题思路一:

从第一位开始依次相加,第一位相加的结果为个位数,第二位相加的结果为十位数,第三位相加的结果为百位数,以此类推,在从第二次相加的时候必须判断前面是否进1,若有进位则将其也加上即可。

如对例子中的数字来说,2+5=7,个位为7,4+6=10,十位为0并进1,3+4=7,有进位1加上百位则为8。以此思路不难写出代码。

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode listNode = new ListNode(0);
        ListNode root = listNode;
        int decade = 0;//是否进位
        while (l1 != null && l2 != null){
            listNode.next = new ListNode((l1.val+l2.val+decade)>9?(l1.val+l2.val-10+decade):(l1.val+l2.val+decade));
            decade = (l1.val+l2.val+decade)>9?1:0;
            l1 = l1.next;
            l2 = l2.next;
            listNode = listNode.next;
        }
        while (l1 != null){// l1还有剩余
            listNode.next = new ListNode(l1.val+decade>9?0:l1.val+decade);
            decade = l1.val+decade>9?1:0;
            l1 = l1.next;
            listNode = listNode.next;
        }
        while (l2 != null){// l2还有剩余
            listNode.next = new ListNode(l2.val+decade>9?0:l2.val+decade);
            decade = (l2.val+decade)>9?1:0;
            l2 = l2.next;
            listNode = listNode.next;
        }
        if (decade == 1){//l1 l2都完了还有一个进位
            listNode.next = new ListNode(1);
        }
        return root.next;
    }

此算法只进行了一次的遍历操作,时间复杂度为O(n),引用了额外的存储空间空间复杂度为O(n)。

提交代码之后:

Runtime: 20 ms, faster than 83.18% of Java online submissions for Add Two Numbers.

Memory Usage: 48.7 MB, less than 5.08% of Java online submissions for Add Two Numbers.

解题思路二:

跟法一类似,上述方法中是将两个链表相同的长度先进行了相加操作,然后最对有多余长度的链表进行相加的操作,其实我们完全可以在一个循环中进行。每次先对l1和l2进行非空判断,如果不为空则将其数值加上,节点后移,然后将最后得到的值对其进行是否进位操作就可以了。下面请看源代码。

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode listNode = new ListNode(0);
        ListNode root = listNode;
        int decade = 0;
        while (l1 != null || l2 != null || decade == 1){
            int sum = (l1 == null ? 0 : l1.val) + (l2 == null ? 0 : l2.val) + decade;
            listNode.next = new ListNode(sum % 10);
            listNode = listNode.next;
            decade = sum / 10;
            l1 = l1 == null ? l1 : l1.next;
            l2 = l2 == null ? l2 : l2.next;
        }
        return root.next;
    }

此算法只进行了一次的遍历操作,时间复杂度为O(n),引用了额外的存储空间空间复杂度为O(n)。

提交代码之后:

Runtime: 19 ms, faster than 99.13% of Java online submissions for Add Two Numbers.

Memory Usage: 47.8 MB, less than 40.24% of Java online submissions for Add Two Numbers.

可以看到算法的效率提升了一小节。

猜你喜欢

转载自blog.csdn.net/qq_21963133/article/details/88655212