两数相加

leetcode每天一题2

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。您可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例:

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

1. 自己的思路

这个题的时候,第一时间想到的是学习数据结构时,课本上讲的有序表的归并算法。所以我是采用这个思路来写的,可能当出学数据结构的时候用的是c语言,所以即便用的时Java也还是没用转变过来。
主要需要做的就是将所有可能出现出现的情况考虑

在这里插入图片描述

a. 第一种情况就是两个链表的长度是相等的,所以只需要将对应位置的数进行加减,当出现进位的时候将其中一个链表的下一个位置的数值+1,最后在判断一下,在临界位置(最后一个节点)的加法会不会出现需要进位的情况,如果需要则创建新节点并将新结点的数值置为1.

在这里插入图片描述
b.当出先其中一方比另一方的位数多时:就需要将链表分解为两段,最开始的一段为a情况,当其中一个链表走到结尾时,将需要对还有数值的链表进行操作,这时需要判断是否有进位情况,当接受到低位来的进位时,就需要+1,同时判断自身是否已经大于10。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        int number=0;//用来存储同位置的两个数的和
        ListNode l3;//创造新的链表用于存放和
        ListNode l4=new ListNode(0);
        l3=l4;
        while(l1.next!=null && l2.next!=null){ //说明到目前位置为止这两链表都还没断,可以正常相加减
            number=l1.val+l2.val;
            if(number>=10){ //当同位置的数相加超过10,是需要进位
                number=number%10;
                l1.next.val++;//随便找一个链表的节点+1即可
            }            
            l4.val=number;
            //找下一个节点
            l1=l1.next;
            l2=l2.next;
            //因为两个链表后续都还有值,所以l4将链接一个节点
            l4.next=new ListNode(0);
            //将l4也移到下一个节点
            l4=l4.next;
        }
        //如果l1还有后续节点的话
        if(l1.next!=null){
            //将l1上该结点的值与剩下的一下l2的节点值进行加法运算
            number=l1.val+l2.val;
            if(number>=10){ //当同位置的数相加超过10,是需要进位
                number=number%10;
                l1.next.val++; //只能找剩余还有节点的链表的下一个节点+1
            }  
            l4.val=number;
            //l1移到下一个节点
            l1=l1.next;
            l2=l2.next;
            //因为l1链表后续都还有值,所以l4将链接一个节点
            l4.next=new ListNode(0);
            //将l4也移到下一个节点
            l4=l4.next;

            //将剩余节点(除最后一个节点外)加到新的链表中,如果有进位的进行进位
            while(l1.next!=null){
                if(l1.val>=10){
                    l1.val=l1.val%10;
                    l1.next.val++;
                }
                l4.val=l1.val;
                l4.next=new ListNode(0);
                l1=l1.next;
                l4=l4.next;
            }

            //将最后一个节点加到新链表 --需要判断最后一个节点是否为10
            if(l1.val>=10){
                l4.val=l1.val%10;
                l4.next=new ListNode(1);
                l4.next.next=null;
            }else{
                l4.val=l1.val;
                l4.next=null;
            }
        }
        
        else if(l2.next!=null){//如果l2还有后续节点的话
            //将l2上该结点的值与剩下的一下l1的节点值进行加法运算
            number=l1.val+l2.val;
            if(number>=10){ //当同位置的数相加超过10,是需要进位
                number=number%10;
                l2.next.val++; //只能找剩余还有节点的链表的下一个节点+1
            }  
            l4.val=number;
            //l2移到下一个节点
            l1=l1.next;
            l2=l2.next;
            //因为l2链表后续都还有值,所以l4将链接一个节点
            l4.next=new ListNode(0);
            //将l4也移到下一个节点
            l4=l4.next;

            //将剩余节点(除最后一个节点外)加到新的链表中,如果有进位的进行进位
            while(l2.next!=null){
                if(l2.val>=10){
                    l2.val=l2.val%10;
                    l2.next.val++;
                }
                l4.val=l2.val;
                l4.next=new ListNode(0);
                l2=l2.next;
                l4=l4.next;
            }

            //将最后一个节点加到新链表 --需要判断最后一个节点是否为10
            if(l2.val>=10){
                l2.val=l2.val%10;
                l4.val=l2.val;
                l4.next=new ListNode(1);
                l4.next.next=null;
            }else{
                l4.val=l2.val;
                l4.next=null;
            }
        }
        
        else if(l1.next==null&&l2.next==null){//两个链表都没有下一个节点时
            number=l1.val+l2.val;
            if(number>=10){
                number=number%10;
                l4.next=new ListNode(1);
                l4.next.next=null;
            }
            l4.val=number;
        }
        return l3;
        //throw new IllegalArgumentException("No two sum solution");
    }
}

出现的错误:
a.忘记给新的链表,创建第二个指向他的对象,而是直接对其进行操作,导致最后只能输出末尾数值而是最前的数值全部丢失。
b.在考虑第二种情况时,最后阶段忘记处理,已走到头的对象,导致最后在单独处理剩余链表的剩余部分时,影响结果

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;
    }
}

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/add-two-numbers/solution/liang-shu-xiang-jia-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值