力扣LeetCode算法题第2题-两数之和(二)

力扣算法题第二题,两数相加算法题:

要求:

//给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
//如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
//您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
//示例:
//输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
//输出:7 -> 0 -> 8
//原因:342 + 465 = 807

很多时候不是做不出题目,而是题意没有审清。

我们再来看下题目要求:

我们所指的的个位是在链头,百位是在链尾,所以思路是要转过来。

使用了最简单的一种,不考虑0和超过百位的算法。

public static ListNode addTwoNumbers1(ListNode l1, ListNode l2) {
        //创建一个和值
        ListNode sun_end = new ListNode(-1,new ListNode(-1,new ListNode(-1)));
        //测试数据:[1,2,3] [1,9,9]
        if((l1.val+l2.val)>=10 ){
            //1.判断个位,个位相加>10,个位进位,十位+1。
            sun_end.val=l1.val+l2.val-10;
            //2.十位相加
            if((l1.next.val+l2.next.val+1)>=10){
                //十位进位
                sun_end.next.val =l1.next.val+l2.next.val+1-10;
                //3.百位相加,默认百位不进位
                sun_end.next.next.val =l1.next.next.val+l2.next.next.val+1;
            }else{
                //个位进位,十位不进位,默认百位不进位
                sun_end.next.next.val =l1.next.next.val+l2.next.next.val+1;
                //十位不进位,默认百位不进位
                sun_end.next.next.val =l1.next.next.val+l2.next.next.val;
            }
        }else {
            //判断个位,个位相加<10,个位不进位,十位不加1。
            //1.1 否则个位相加不进位,只考虑相加在3位数以内
            sun_end.val=l1.val+l2.val;
            //2.十位相加
            if((l1.next.val+l2.next.val+1)>=10){
                //个位相加不进位,十位进百位
                sun_end.next.val =l1.next.val+l2.next.val-10;
                //3.百位相加,默认百位不进位
                sun_end.next.next.val =l1.next.next.val+l2.next.next.val+1;
            }else{
                //个位不进位,十位不进位,默认百位不进位
                sun_end.next.val =l1.next.val+l2.next.val;
                //十位不进位,默认百位不进位
                sun_end.next.next.val =l1.next.next.val+l2.next.next.val;
            }
        }
        System.out.println("sun1="+sun_end.val);
        System.out.println("sun2="+sun_end.next.val);
        System.out.println("sun3="+sun_end.next.next.val);
        return sun_end;
    }

以上这种办法只适用于两个都是百位数相加,且和不超过千位,无法通过leatcode算法考验。

所以整合出第三种办法:

循环进制计算法

public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        //创建一个和值
        ListNode sun_header = new ListNode(-1);
        ListNode sun_end = sun_header;//用来调整链接指针下标的next指向
        int carry =0;//用来标识进位
        //用一个while循环去判断“个十百”位相加是否大于10,
        while (l1!=null || l2!=null || carry !=0){
            if(l1!=null){
                carry+=l1.val;
                l1=l1.next;
            }
            if(l2!=null){
                carry+= l2.val;
                l2=l2.next;
            }
            sun_end.next=new ListNode(carry%10);//取余: 比如个位6+6=12%=2,个位=2,十位=1.
            sun_end=sun_end.next;//移动下一个节点sun_end有三个链结构
            carry/=10;//超过1则进位器+1。=0则不进位
            //sun_end.val=carry%10;
        }
        System.out.println("sun1="+sun_header.next.val);
        System.out.println("sun2="+sun_header.next.next.val);
        System.out.println("sun3="+sun_header.next.next.next.val);
        return sun_header.next;//sun_header有四个链结构
    }

这段代码如果要在leatcode上运行,需要去掉static静态方法。因为这是我在idea上测试写的方法。

大家理解起来很抽象。我画图给大家解释下。

每一个listNode就相当于一个回形针(ListNode sun_header = new ListNode(-1)),每个回形针是 listNode。

第一个回形针取值直接用var取值,如:l1.var = 2;

第二个回形针取值直接用l1.next.var,需要next移动到下一个回形针上,如:l2.next.var=6

第四个回形针取值则用3个next。如: sun_header.next.next.next.var=8.

就这么简单,低位相加>10,就进位。

附上所有代码,可以在任何编译器中运行。

package com.zhm.test;

import org.junit.Test;

import java.util.Arrays;

/**
 * @Author bige
 * @Date: 2022/11/16 18:11
 * @ApiNote:两数相加
 */
public class Leatcode_test2 {
    //给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
    //如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
    //您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
    //示例:
    //输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
    //输出:7 -> 0 -> 8
    //原因:342 + 465 = 807
    public static int[] addTwoNumbers(int[] l1, int[] l2) {
        //测试数据:[1,2,3] [1,9,9]
        //int[] sun =new int[5];
        int[] sun =new int[l1.length];
        //想法和思路
        //1.个位相加>10则向10位
        if((l1[l1.length-1]+l2[l2.length-1])>10){
            sun[l1.length-1] =l1[l1.length-1]+l2[l2.length-1]-10;
            //2.十位相加+1
            if((l1[l1.length-2]+l2[l2.length-2]+1)>10){
                //十位进位
                sun[l1.length-2] =l1[l1.length-2]+l2[l2.length-2]+1-10;
                //3.百位相加,默认百位不进位
                sun[l1.length-3] =l1[l1.length-3]+l2[l2.length-3]+1;
            }else{
                //个位进位,十位不进位,默认百位不进位
                sun[l1.length-2] =l1[l1.length-2]+l2[l2.length-2]+1;
                //十位不进位,默认百位不进位
                sun[l1.length-3] =l1[l1.length-3]+l2[l2.length-3];
            }

        }else {
            //1.1 否则个位相加不进位,只考虑相加在3位数以内
            sun[l1.length] =l1[l1.length]+l2[l2.length];
            //2.十位相加
            if((l1[l1.length-2]+l2[l2.length-2]+1)>10){
                //个位不进位,十位进位
                sun[l1.length-2] =l1[l1.length-2]+l2[l2.length-2]-10;
                //3.百位相加,默认百位不进位
                sun[l1.length-3] =l1[l1.length-3]+l2[l2.length-3]+1;
            }else{
                //个位不进位,十位不进位,默认百位不进位
                sun[l1.length-1] =l1[l1.length-1]+l2[l2.length-1];
                //十位不进位,默认百位不进位
                sun[l1.length-2] =l1[l1.length-2]+l2[l2.length-2];
            }
        }

        //2.十位相加>10则向百位+1
        return sun;
    }


    //采用了符合leatcode题意的格式ListNode
     public static class ListNode {
         int val;
         ListNode next;
         ListNode() {}
         ListNode(int val) { this.val = val; }
         ListNode(int val, ListNode next) { this.val = val; this.next = next; }

    }

    public static ListNode addTwoNumbers1(ListNode l1, ListNode l2) {
        //创建一个和值
        ListNode sun_end = new ListNode(-1,new ListNode(-1,new ListNode(-1)));
        //测试数据:[1,2,3] [1,9,9]
        if((l1.val+l2.val)>=10 ){
            //1.判断个位,个位相加>10,个位进位,十位+1。
            sun_end.val=l1.val+l2.val-10;
            //2.十位相加
            if((l1.next.val+l2.next.val+1)>=10){
                //十位进位
                sun_end.next.val =l1.next.val+l2.next.val+1-10;
                //3.百位相加,默认百位不进位
                sun_end.next.next.val =l1.next.next.val+l2.next.next.val+1;
            }else{
                //个位进位,十位不进位,默认百位不进位
                sun_end.next.next.val =l1.next.next.val+l2.next.next.val+1;
                //十位不进位,默认百位不进位
                sun_end.next.next.val =l1.next.next.val+l2.next.next.val;
            }
        }else {
            //判断个位,个位相加<10,个位不进位,十位不加1。
            //1.1 否则个位相加不进位,只考虑相加在3位数以内
            sun_end.val=l1.val+l2.val;
            //2.十位相加
            if((l1.next.val+l2.next.val+1)>=10){
                //个位相加不进位,十位进百位
                sun_end.next.val =l1.next.val+l2.next.val-10;
                //3.百位相加,默认百位不进位
                sun_end.next.next.val =l1.next.next.val+l2.next.next.val+1;
            }else{
                //个位不进位,十位不进位,默认百位不进位
                sun_end.next.val =l1.next.val+l2.next.val;
                //十位不进位,默认百位不进位
                sun_end.next.next.val =l1.next.next.val+l2.next.next.val;
            }
        }
        System.out.println("sun1="+sun_end.val);
        System.out.println("sun2="+sun_end.next.val);
        System.out.println("sun3="+sun_end.next.next.val);
        return sun_end;
    }

    public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        //创建一个和值
        ListNode sun_header = new ListNode(-1);
        ListNode sun_end = sun_header;//用来调整链接指针下标的next指向
        int carry =0;//用来标识进位
        //用一个while循环去判断“个十百”位相加是否大于10,
        while (l1!=null || l2!=null || carry !=0){
            if(l1!=null){
                carry+=l1.val;
                l1=l1.next;
            }
            if(l2!=null){
                carry+= l2.val;
                l2=l2.next;
            }
            sun_end.next=new ListNode(carry%10);//取余: 比如个位6+6=12%=2,个位=2,十位=1.
            sun_end=sun_end.next;//移动下一个节点sun_end有三个链结构
            carry/=10;//超过1则进位器+1。=0则不进位
            //sun_end.val=carry%10;
        }
        System.out.println("sun1="+sun_header.next.val);
        System.out.println("sun2="+sun_header.next.next.val);
        System.out.println("sun3="+sun_header.next.next.next.val);
        return sun_header.next;//sun_header有四个链结构
    }

    public static void main(String[] args) {
        //采用数组格式去测试
        int[] l1={1,2,3};
        int[] l2={1,2,9};
        //int[] result = addTwoNumbers(l1,l2);
        //System.out.println(Arrays.toString(result));

        
        //采用单链表格式去测试数据
        //ListNode newHead = new ListNode(-1);
        ListNode list1 = new ListNode(2,new ListNode(4,new ListNode(3)));
        ListNode list2 = new ListNode(5,new ListNode(6,new ListNode(4)));
        //System.out.println(list1.toString());
        //addTwoNumbers1(list1,list2);
        addTwoNumbers(list1,list2);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

逼哥很疯狂

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

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

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

打赏作者

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

抵扣说明:

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

余额充值