LeetCode 2题:两数相加(原创)

【题目描述】

       给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例 1:

输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.
示例 2:
输入:l1 = [0], l2 = [0]
输出:[0]
示例 3:
输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]

【解题代码】

        

package list;

import list.base.ListNode;


public class AddTwoNumbers {

    public static void main(String[] args) {
        ListNode head1 = ListNode.makeList(9);
        ListNode head2 = ListNode.makeList(99999999);
        head1.printList();
        head2.printList();

        new AddTwoNumbers().addTwoNumbers(head1, head2).printList();
    }

    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        int carry = 0;
        ListNode head = l1;
        while (l1 != null && (l2 != null || carry != 0)){
            int n = l1.val + carry;
            if (l2 != null) {
                n += l2.val;
                l2 = l2.next;
            }
            carry = n / 10;
            l1.val = n - carry *10;
            if (l1.next == null) {
                if (l2 != null) {
                    l1.next = l2;
                    l2 = null;
                } else {
                    if (carry > 0) {
                        l1.next = new ListNode(carry);
                    }
                    break;
                }
            }
            l1 = l1.next;
        }
        return head;
    }
}

【解题思路】

        根据题目描述,解决方案的大体思路应该是同时从头遍历两个链表,将当前两个节点以及上一次进位数值进行求和,模时之后将余数设置为当前节点的数值,并新的进位数带到下一个节点,根据上述思路完成代码开发,并提交LeetCode成功

【解题步骤】

  1. 定义进位值和保存头结点的变量
     int carry = 0;
     ListNode head = l1;
  2. 同从遍历变量两个链表,注意循环中止条件是节点L1不为空,并且节点2不为空或者进位值不为0
    while (l1 != null && (l2 != null || carry != 0)){
  3. 根据节点1,2和进位的值计算当前节点值,和下一位的进位值,这里将结果直接存在L1里,而没有新建一个链表了
    int n = l1.val + carry;
    if (l2 != null) {
        n += l2.val;
        l2 = l2.next;
    }
    carry = n / 10;
    l1.val = n - carry *10;            
  4. 如果节点l1下个节点为空,如果节点l2不为空,直接将l1的下一个节点指向l2,将l2设置为空,否则。如果carry大于0,那么在l1后面新建一个值为carry的节点。然后跳出循环
    if (l1.next == null) {
        if (l2 != null) {
            l1.next = l2;
            l2 = null;
        } else {
            if (carry > 0) {
                l1.next = new ListNode(carry);
            }
            break;
        }
    }
  5. 将节点l1设置为下一个节点
        l1 = l1.next;
    }
  6. 循环结束后,返回之前保存的首节点
    return head;

【思考总结】

  1. 这道题解法的关键流程在于:1)当前两个节点以及上一次进位数值进行求和,模时之后将余数设置为当前节点的数值,并新的进位数带到下一个节点;2)L1或者L2节点为空的情况特殊处理 3)最后一个节点只剩进位值carry的特殊情况处理
  2. 算法中的小技巧:将L1作为返回值,节省了申请新链表的空间,另外l1下个节点为空L2不为空时将,l1的下个节点指向l2,并将l2置空
  3. LeetCode解题之前,一定不要看题解,看了就“破功”了!
  • 22
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值