力扣算法题

前言
  🎄:CSDN的小伙伴们大家好,今天跟大家分享一道经典的力扣启蒙题。如果这篇文章对你有用,麻烦给我点个小赞以示鼓励吧🎄
  🏡:博客主页:空山新雨后的java知识图书馆
  ☔️:昨晚重庆挂大风,不知道各位小伙伴感受到了没有。
  📝:不耻最后”。即使慢,弛而不息,纵会落后,纵会失败,但一定可以达到他所向的目标。——鲁迅📝
  📖上一篇文章:Maven工具的使用📖
  👏欢迎大家一起学习,进步。加油👊



力扣题的总结

题目描述,力扣第二题,算法启蒙

  给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
  请你将两个数相加,并以相同形式返回一个表示和的链表。
  你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
  来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/add-two-numbers/

实例

输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.

解题思路

  1、首先先要弄懂题目的意思,题目是告诉我们两个链表,反序存储,也就是说,如果123+456,存进链表里面就是321+456,但是结果得是123+456=975;

  2、首先我们解题的方法叫做迭代法

​    2.1、什么是迭代法?

  迭代法也称辗转法,是一种不断用变量的旧值递推新值的过程,跟迭代法相对应的是直接法(或者称为一次解法),即一次性解决问题。迭代算法是用计算机解决问题的一种基本方法,它利用计算机运算速度快、适合做重复性操作的特点,让计算机对一组指令(或一定步骤)进行重复执行,在每次执行这组指令(或这些步骤)时,都从变量的原值推出它的一个新值,迭代法又分为精确迭代和近似迭代。比较典型的迭代法如“二分法”和"牛顿迭代法”属于近似迭代法。

  3、那么我们可以采用迭代的方式,来完成这个题目,首先我们要明白,两数(均是个位数)相加,有两种结果,一种是小于10,不用进一,另一种结果是大于10.那么这种情况就要进一了。那么在本题中,由于是在链表中进行,因此我们需要一个变量来决定是否进一,我们定义为next1,还得有一个变量total来接收总数,因为我们的变量和实际存入链表中的值都是由这个total来决定的。

   4、total = L1 + l2 和 可能存在的进一next1

​     next1 = total/10;

​     实际存入链表的值 = total%10

    result结点和cur结点的关系,以及为啥要这么定义↓

在这里插入图片描述

  5、定义好变量之后,我们要做的就是将两个链表分别进行遍历,直到有一方链表为空,就会去执行下面的代码,主要是检查两个链表单独的是否还存在没有被遍历完的情况, 以及最后相加的两个数可能大于10,那么就要进位,也得加上。

  6、循环里面就应该算上total的值,以及他是否进位的值,以及实际存入链表的值,并将其存入链表,然后将所有的需要参与遍历的变量向后移动,保证循环继续,特别注意防止空指针的异常。

  7、当其中有一条链表走完之后,就需要将剩余的一条链表进行遍历,注意的是,这时候的total值只剩下了其中一条链表的值和可能存在的进位值,因此不要加错了。

  8、当所有的链表都遍历完之后,可能会存在一个进位值,切记要将这个进位值给加上。

  9、最后返回链表即可。

图示

在这里插入图片描述

代码演示java

/**
 * 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) {
        //定义一个total,算的是l1,l2两个结点的和以及可能存在的进一
        int total= 0;
        //定义一个next,由total/10得到十位数,决定是否进一
        int next1 = 0;
        //定义一个新节点,作为首结点,首结点为空
        ListNode result = new ListNode(0);
        //定义一个current结点,用于存储最后的返回结果,返回result.next也就是最后的结果
        ListNode cur = result;
        //遍历两个链表,直到有一方为空截止
        while(l1 != null || l2 != null) {
            //考虑可能为空的情况存在,需要给赋值,防止空指针异常
             int x = l1 == null ? 0 : l1.val;
             int y = l2 == null ? 0 : l2.val;
            //计算total
            total = x + y + next1;
            //current结点存的值应该是total的个位数的值
            cur.next = new ListNode(total%10); 
            //那么next决定这进一,next的值就应该是十位数
            next1 = total / 10;
            //将l1,l2,cur依次向后移动
            //注意为空的情况
            if(l1 != null) {
                l1 = l1.next;
            }
               
            if(l2!= null) {
                l2 = l2.next;
            }
                
            cur = cur.next;

        }

        //当l2走完L1没走完的情况
        while(l1 != null) {
            total = l1.val + next1;
            cur.next = new ListNode(total%10);
            next1 = total / 10;
            if(l1.next != null) {
                l1 = l1.next;
            }
           
            cur = cur.next;
        }

        //当L1走完l2没走完的情况
        while(l2 != null) {
            total = l2.val + next1;
            cur.next = new ListNode(total%10);
            next1 = total / 10;
            if(l2.next != null) {
                l2 = l2.next;
            }
            
            cur = cur.next;
        }

        //当所有的结点都已经走完以后,需要判断一下是否还存在进一的数没有加进去
        if(next1 != 0) {
            cur.next = new ListNode(next1);
            cur = cur.next;
        }
        return result.next;
    }
}

结果

在这里插入图片描述

第二种解题方法:递归调用法

解题思路:

  1、首先将l1.l2相加,得到了total值,这个total值我们取出他的个位数存入链表,将十位数作为进一的值,而且将它加到下一次递归调用的随便一个值的上面,参加下一次递归调用的运算,得到一个新的total,直到三个值都为空,为0,递归结束。那么这里面就只需要考虑到值为空的情况,如果链表为空,一定要赋值为0,否则他无法参加运算。

思路图示

在这里插入图片描述

代码java

/**
 * 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) {
        //定义total,首先就是两个值相加
       int total = l1.val + l2.val;
       //是否向下进一
       int next1 = total/10;
       //实际存入链表的值
       ListNode res = new ListNode(total%10);

        //当链表的值有一个不为空,或者向下进一不为0,都可以进入这个条件  
       if(l1.next != null || l2.next != null || next1 != 0) {
           //这个判断是为了判断链表的下一个结点是否有值
           
           if(l1.next != null) {
               //如果有值,则向后移动
                l1 = l1.next;
            }else{
                //如果没有值,则给他赋值为0
                l1 = new ListNode(0);
            }
            if(l2.next != null) {
                l2 = l2.next;
            }else{
                l2 = new ListNode(0);
            }

            //这里这样做的目的是为了将进一的值加到链表中去,
            //具体加哪个链表,都可以
            l1.val = l1.val + next1;
            //递归调用该方法,这时候进去的l1,l2就是链表的下一位了,注意,next的值是被加进去了
            res.next = addTwoNumbers(l1,l2);
            }
            //返回链表,直到递归结束,就得到了我们想要的结果。也就是l1,l2,next1的值都为0,就是我们最终想要的值了。
            return res;
        }
    
    }

在这里插入图片描述

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

空山新雨后~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值