Java LeetCode每日一题-从易到难带你领略算法的魅力(三):两数相加

1.题目要求

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

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

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

2.题目示例

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

3.解题

3.1 解题思路

  1. 读完题发现,两个链表都表示的是非空逆序非负的整数,可得,两表对应位置数字可直接相加
  2. 由于涉及到进位的问题,所以我们需要这是一个进位值
  3. 结果链表对应位置数据的和为 n1+n2+进位值
  4. 链表对应位置的数据为(n1+n2+进位值)%10(求余)
  5. 新的进位值为(n1+n2+进位值)/10
  6. 并且考虑到两个链表的长度不一定相同,就假设短链表后面有对应位数的0
  7. 考虑到最后一个节点计算完成后可能有进位的问题,如果在最后的节点计算完毕后进位值>0,就需要在最后新增一个节点,放入进位值

3.2 业务代码

class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode head = null, tail = null;
        int carry = 0;
        while (l1 != null || l2 != null) {
            int n1 = l1 != null ? l1.val : 0;
            int n2 = l2 != null ? l2.val : 0;
            int sum = n1 + n2 + carry;
            if (head == null) {
                head = tail = new ListNode(sum % 10);
            } else {
                tail.next = new ListNode(sum % 10);
                tail = tail.next;
            }
            carry = sum / 10;
            if (l1 != null) {
                l1 = l1.next;
            }
            if (l2 != null) {
                l2 = l2.next;
            }
        }
        if (carry > 0) {
            tail.next = new ListNode(carry);
        }
        return head;
    }
}

3.3 运行结果

结果

4.优化

4.1 优化思路

  1. 大体思路和第一种解决方案差不多,有一点小差距就是用递归的话需要通过传入值的方式来保存进位。
  2. 最后建立新node,然后将进位传入下一层。

4.2 优化业务代码

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

    ListNode dfs(ListNode l, ListNode r, int i) {
        if (l == null && r == null && i == 0) return null;
        int sum = (l != null ? l.val : 0) + (r != null ? r.val : 0) + i;
        var node = new ListNode(sum % 10);
        node.next = dfs(l != null ? l.next : null, r != null ? r.next : null, sum / 10);
        return node;
    }
}

4.3 优化结果

设置

5.总结

  • 刚刚看完题后思路应该是比较清晰的知道要去干什么,在实现了过后,优化真的是不好处理,在最后还是选择使用递归来处理优化部分,但是实际的结果上来说0.1MB没什么区别。所以大家有更好的解决方案的话可以直接在下面留言。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

地球村公民

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值