【LeetCode】2. 两数相加(Add Two Numbers,28.6%,中等)

一、题目描述

给定两个非空链表来表示两个非负整数。位数按照逆序方式存储,它们的每个节点只存储单个数字。将两数相加返回一个新的链表。

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

示例:

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

二、思路分析

每位逐一运算,有点类似「大数运算」,不过大数运算一般都是用数组操作,这里是逆序链表操作,其实逆序链表还简单些,因为直接从个位往上加就行了,相当于两个数字尾部对齐了,若是正序链表,那还得先找到个位或者把链表反转才行。

本题的解题思路有两种:递归与非递归。下面逐一分析。

需要注意的重点有:

  • 进位问题
  • 两数长度错位问题
  • 两数指针末尾判断

三、解决方案

方法一:递归法

从个位开始,两数相加当前位,然后除10余数即为新链表的值,进位交给下一层递归。直到没有进位并且两数都没有下一级指针为止。

/**
 * 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) {
        return addNumbers(l1, l2, 0);
    }

    //carry 为进位
    public ListNode addNumbers(ListNode l1, ListNode l2, int carry) {
        if(l1 != null){
            carry += l1.val;
            l1 = l1.next;
        }
        if(l2 != null){
            carry += l2.val;
            l2 = l2.next;
        }

        ListNode res = new ListNode(carry % 10);;
        if(l1 != null || l2 != null || carry >=10){
            res.next = addNumbers(l1, l2, carry/10);
        }

        return res;
    }
}
  • 时间复杂度: O ( m a x ( m , n ) ) ,m和n分别代表l1和l2的长度,递归层级最深为 m a x ( m , n )
  • 空间复杂度: O ( m a x ( m , n ) ) ,由于每层递归没有开辟新的空间,而是用的l1和l2的引用,所以辅助空间可以看做常数。
    递归算法的空间复杂度:递归深度n*每次递归所需的辅助空间,如果每次递归所需的辅助空间为常数,则递归空间复杂度为 O ( n )

方法二:非递归法

用while循环,注意进位、长度错位、空指针等问题即可。

class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode res = new ListNode(0);
        ListNode point = res;
        int sum = 0;
        while(l1 != null || l2 != null || sum > 0){
            sum += (l1==null?0:l1.val) + (l2==null?0:l2.val);
            point.next = new ListNode(sum % 10);
            point = point.next;
            if(l1!=null){
                l1 = l1.next;
            }
            if(l2!=null){
                l2 = l2.next;
            }
            sum /= 10;
        }
        return res.next;
    }
}
  • 时间复杂度: O ( n )
  • 空间复杂度: O ( n )

猜你喜欢

转载自blog.csdn.net/zhichaosong/article/details/80761951