力扣刷题百天计划 Day1 两数相加

学习目标:

我会持续更新我独特的算法思路,希望能给大家带来不一样的思维拓展!
如果大家感觉有帮助的话,欢迎点赞关注支持哦!
你们的鼓励是我坚持下去的动力!
!!!

力扣题库第二题 官方地址


学习内容:

两数相加

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

你可以假设除了数字 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]

提示:

每个链表中的节点数在范围 [1, 100]0 <= Node.val <= 9
题目数据保证列表表示的数字不含前导零

学习时间:

2022.1.7


学习产出:

#优化前

两次提交的结果不一样
在这里插入图片描述
在这里插入图片描述
为什么会出现两次提交结果不一样的情况呢?
仔细分析,发现第二次用时会多一些,这种方法可能在父链长度大于子链的时候,可能计算会费时一些。因为要将剩下的父链循环,然后每一次都要进行判断。

解题思路

1 首先计算出两个链表的长度(这里虽然是类去实现结构体,但是思想和C语言的链表差不多)
2 然后找到比较长的链表,让它作为主链
3 让另外一个链的值加到它上面,然后对主链进行判断,当前元素值大于等于十就让它下一位加一然后自身减十(我们把这个过程叫做检测溢出吧)(这里有个小Tips,就是主链我们默认先让它长度加一,防止越界,因为999+999=1998,就是最多会超过一位)
4 然后我们结束的时候得判断,如果它的最后一位是0,那肯定舍弃(这个过程叫做判断末位吧)。
5 记得在遍历主链的时候,如果子链的下一位为空,就是主链长度比子链长,那么这时,就进入一个新的循环,对主链进行遍历检测溢出就行了,然后进行一个末尾判断,因为当前节点后面主链已经没有子链去加了,所以让它自己走一遍溢出检测然后最后来个末尾判断就行。

源码

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     public int val;
 *     public ListNode next;
 *     public ListNode(int val=0, ListNode next=null) {
 *         this.val = val;
 *         this.next = next;
 *     }
 * }
 */
public class Solution {
    
    
    public ListNode AddTwoNumbers(ListNode l1, ListNode l2) {
    
    
        //这里是拿到L1的长度
        int length1=1;
        ListNode ll1=l1;
        while(ll1.next!=null){
    
    
            length1++;
            ll1=ll1.next;
        }
        
        //这里是拿到L1的长度
        int length2=1;
        ListNode ll2=l2;
        while(ll2.next!=null){
    
    
            length2++;
            ll2=ll2.next;
        }

        //做判断,让长的作为主链
        if(length1>=length2){
    
    

            ll1.next=new ListNode(0,null);   //延长主链
            ll1=l1; //置为初始元素
            ll2=l2;
            for(int i=1;i<=length1;i++){
    
      //开始遍历
                ll1.val+=ll2.val;   //自加
                if(ll1.val>=10){
    
       //溢出判断
                    ll1.next.val+=1;
                    ll1.val-=10;
                }
               
                if(ll2.next==null){
    
      
                //如果子链下一个为空 那就没必要再进行下去了,开启一个循环,让剩下的主链进行溢出判断
                    for(int j=i;j<=length1;j++){
    
    
                        if(ll1.val>=10){
    
    
                        ll1.next.val+=1;
                        ll1.val-=10;
                        }
                        //末尾判断
                        if(j==length1){
    
    
                            if(ll1.next.val==0){
    
    
                                ll1.next=null;
                                return l1;
                            }
                        }
                        ll1=ll1.next;                      
                    }
                    //直接返回,不再进行计算
                    //这里返回的情况是主链长于子链
                    return l1;
                }
                ll1=ll1.next;               
                ll2=ll2.next;
            }
            
            //这里返回的情况,肯定是主链和子链长度相同
            return l1;
        }
        else{
    
    
           //下面逻辑相同
            ll2.next=new ListNode(0,null);

            ll1=l1;
            ll2=l2;
            for(int i=1;i<=length2;i++){
    
    
                ll2.val+=ll1.val;
                if(ll2.val>=10){
    
    
                    ll2.next.val+=1;
                    ll2.val-=10;
                }



                if(ll1.next==null){
    
    
                    for(int j=i;j<=length2;j++){
    
    
                        if(ll2.val>=10){
    
    
                        ll2.next.val+=1;
                        ll2.val-=10;
                        }

                        if(j==length2){
    
    
                            if(ll2.next.val==0){
    
    
                                ll2.next=null;
                                return l2;
                            }
                        }
                        ll2=ll2.next;                      
                    }
                    return l2;
                }
                ll2=ll2.next;
                ll1=ll1.next;
            }
            return l2;
        }

        
        


    }
}

#优化后

在这里插入图片描述

这里和上面思路基本一致,只不过用自己定义的链表去替代传入的链表,这样代码更简洁易懂

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     public int val;
 *     public ListNode next;
 *     public ListNode(int val=0, ListNode next=null) {
 *         this.val = val;
 *         this.next = next;
 *     }
 * }
 */
public class Solution {
    
    
    public ListNode AddTwoNumbers(ListNode l1, ListNode l2) {
    
    
        int length1=1;
        ListNode ll1=l1;
        while(ll1.next!=null){
    
    
            length1++;
            ll1=ll1.next;
        }

        int length2=1;
        ListNode ll2=l2;
        while(ll2.next!=null){
    
    
            length2++;
            ll2=ll2.next;
        }
        
        //定义三个链表元素
        ListNode longNode=new ListNode(0,null);
        ListNode shortNode=new ListNode(0,null);
        ListNode BackNode=new ListNode(0,null);  //用于返回的Node
        int longlength;
         
        //这里做逻辑判断是为了选出主链和子链
        if(length1>=length2){
    
    
            longNode=l1;
            shortNode=l2;
            longlength=length1;
            BackNode=l1;
            ll1.next=new ListNode(0,null); //因为ll1还是在l1链表的最后一位上,可以用ll1做链表延长
        }else{
    
    
            longNode=l2;
            shortNode=l1;
            longlength=length2;
            BackNode=l2;
            ll2.next=new ListNode(0,null);
        }
       
       
       for(int i=1;i<=longlength;i++){
    
    
                longNode.val+=shortNode.val;
                if(longNode.val>=10){
    
    
                    longNode.next.val+=1;
                    longNode.val-=10;
                }
                //如果子链比主链短
                if(shortNode.next==null){
    
    
                    //溢出检测
                    for(int j=i;j<=longlength;j++){
    
    
                        if(longNode.val>=10){
    
    
                        longNode.next.val+=1;
                        longNode.val-=10;
                        }
                        //末尾判断
                        if(j==longlength){
    
    
                            if(longNode.next.val==0){
    
    
                                longNode.next=null;
                                return BackNode;
                            }
                        }
                        longNode=longNode.next;                      
                    }
                    return BackNode;
                }
                longNode=longNode.next;               
                shortNode=shortNode.next;
        }
            return BackNode;
   }
}

作者:荷兰猪小灰灰
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

猜你喜欢

转载自blog.csdn.net/m0_48781656/article/details/122378691