leetcode:第二题: 两数相加

题目:

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

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

你可以假设除了数字 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
题目数据保证列表表示的数字不含前导零

误区:

默认两个数是整数,可以随意相加,没有想到精度丢失

解决思路

在这里插入图片描述

正确解法

public class Solution {

    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);

        System.out.println("请输入一个数组numbersStr,以空格分隔");
        String[] numbersStr = sc.nextLine().split(" ");
        ListNode node=linknode(numbersStr);

        System.out.println("请输入一个数组M,以空格分隔");
        String[] m = sc.nextLine().split(" ");
        ListNode node1=linknode(m);

        sc.close();

        System.out.println(addTwoNumbers1(node,node1));

    }


    //数组转链表
    private static ListNode linknode(String[] numbersStr) {
        int[] numbersArray = new int[numbersStr.length];

        //头插法
       /* ListNode head=null;
        for (int i = 0; i < numbersArray.length; i++) {
            numbersArray[i] = Integer.parseInt(numbersStr[i]);
            ListNode newNode=new ListNode(numbersArray[i]);
            if(head==null){
                head=newNode;
            }else {
                newNode.next=head;
                head=newNode;
            }
        }*/

        //尾插法
        ListNode head=null;
        ListNode temo=null;
        for (int i = 0; i < numbersArray.length; i++) {
            numbersArray[i] = Integer.parseInt(numbersStr[i]);
            ListNode newNode=new ListNode(numbersArray[i]);
            if(head==null){
                head=newNode;
                temo=head;
            }else {
                while (temo.next!=null){
                    temo=temo.next;
                }
                temo.next=newNode;
            }
        }

        return head;

    }

    public static ListNode addTwoNumbers1(ListNode l1, ListNode l2) {
        ListNode node=null;

        ListNode tail=null;

        //因为链表数据存储是逆位存储,因此,刚好为 个位 十位 百位 ,因此从个位开始直接相加即可
        //进位
        int carry=0;

        while(l1!=null||l2!=null){
            int a=l1==null?0:l1.val;
            int b=l2==null?0:l2.val;
            //例如:l1个位+l2个位+进位(个位进位肯定为0)
            //     l1十位+l2十位+上一轮进位
            int sum=a+b+carry;

            //使用尾插法
            if(node==null){
                node=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;
            }
            
        }
        
        //若链表遍历结束carry值还大于1,链表加节点加一
        if(carry>0){
            tail.next=new ListNode(carry);
        }

        return node;
    }


}

错误思路示例

 public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        int a=0;int b=0;int c=1;int d=1;
        //这道题并不是简单的int类型的数相加,如果int类型数相加的话,数据会因为过大而丢失精度
        while (l1!=null){
            a=a+l1.val*c;
            c=c*10;
            l1=l1.next;
        }
        while (l2!=null){
            b= b+l2.val*d;
            d=d*10;
            l2= l2.next;
        }
        int sum=a+b;

        ListNode head=null;
        ListNode tail=null;


        while(sum>0){
            if(head==null){
                head=tail=new ListNode(sum%10);
            }else {
                tail.next=new ListNode(sum%10);
                tail=tail.next;
            }
            sum=sum/10;
        }

        while (head!=null){
            System.out.print(head.val+" ");
            head=head.next;
        }
        return head;
    }
  • 14
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值