Add two numbers on Day1

learning target:

I will continue to update my unique algorithm ideas, hoping to bring you different thinking expansion!
If you find it helpful, please like, follow and support!
Your encouragement is what keeps me going!
! ! !

Likou Question Bank Question 2 Official Address


Learning Content:

Add two numbers

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

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

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

Example 1:

Input: l1 = [2,4,3], l2 = [5,6,4]
Output: [7,0,8]
Explanation: 342 + 465 = 807.
Example 2:

Input: l1 = [0], l2 = [0]
Output: [0]
Example 3:

Input: l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
Output: [8,9,9,9,0,0,0,1]

提示:

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

study-time:

2022.1.7


Learning output:

#before optimization

The results of the two submissions are different.
insert image description here
insert image description here
Why is there a situation where the results of the two submissions are different?
After careful analysis, it is found that the second time will take more time. This method may take some time to calculate when the length of the parent chain is greater than that of the child chain. Because the rest of the parent chain is to be cycled, and then a judgment must be made every time.

Problem solving ideas

1 First calculate the length of the two linked lists (although classes are used to implement the structure, but the idea is similar to the linked list in C language)
2 Then find the longer linked list and use it as the main chain
3 Add the value of another chain to On it, and then judge the main chain. If the current element value is greater than or equal to ten, add one to the next digit and then subtract ten by itself (let's call this process overflow detection) (here is a small Tips, that is, the main chain, we default First add one to its length to prevent cross-border, because 999+999=1998, that is, there will be more than one digit at most)
4 Then we have to judge at the end, if its last digit is 0, it must be discarded (this process is called judgment last position).
5 Remember when traversing the main chain, if the next bit of the sub-chain is empty, that is, the length of the main chain is longer than that of the sub-chain, then a new loop is entered, and the main chain is traversed to detect overflow, and then Make an end judgment, because the main chain behind the current node has no sub-chains to add, so let it go through the overflow detection by itself and then finally make an end judgment.

source code

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

        
        


    }
}

#Optimized

insert image description here

The idea here is basically the same as the above, except that the incoming linked list is replaced by the linked list defined by yourself, so that the code is more concise and easy to understand

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

Author: guinea pig Xiaohuihui
The copyright belongs to the author. For commercial reprints, please contact the author for authorization, and for non-commercial reprints, please indicate the source.

Guess you like

Origin blog.csdn.net/m0_48781656/article/details/122378691