IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> LeetCode第二题:两数相加 -> 正文阅读

[数据结构与算法]LeetCode第二题:两数相加

题目:

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

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

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

?

上面就是力扣的原题,想必进过力扣的都应该遇到过了吧

这里共有两种解法

咋们先说第一种解法,迭代法

迭代法

迭代法,顾名思义就是利用循环遍历来进行解题

我大概说一下我的思路:

每个节点相加后,只会在新的节点中加入相加总数的个位,如果相加的总数大于等于了10的话,就会向前进一,给新节点的下一个节点加一,那么我们可以定一个新的变量next1来存储相加总和大于了10的十位,也就是需要进的位,然后每次相加时都把这个需要进的位加上,如果没有需要进的位,那么next1也就为0。

定义行链表的时候,我们可以把第一个节点设置为‘哨兵节点’,也就是不使用它,好进行操作,最后返回它的下一个节点就行,这个方法在解好多算法题都有效,下面我来图示一下(这个与题给的数字有差别,但不影响,这个更好):

第一次 2 + 5 = 7,那么存入链表的就是 总数%10 的数,在加上需要进位的数,即 7%10+next1=7

进行完一次后指针要后移

??????

?

?第二次4+6=10,大于等于10,只要往链表中加入个位,也就是取余10得到0,且next1,需要进的位也变成了1

此时,第三次加入的时候,总数为9,但需要加上上一次进的位,所有总数又大于等于了10,又需要往后进一位

?但此时,链表都遍历完毕,但需要进的位中还有一个,这时就直接把需要进的位直接加入链表即可

?

最后就这直接返回res.next即可

Java代码如下:

这里ListNode力扣中已经给出,这里就不再解释了

/**
 * 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) {
        int total = 0;//定义总和
        int next1 = 0;//是否向下一位进1
        ListNode res = new ListNode(); //定义返回的结果
        ListNode cur = res; //定义当前指针的位置,初始指向开头

        while(l1 != null && l2 != null){ //两个链表都不是空时
            total = l1.val + l2.val + next1;
            cur.next = new ListNode(total % 10);//存入个位
            next1 = total / 10;//计算出下一位要进的数
            l1 = l1.next; //链表的下一个
            l2 = l2.next; //链表的下一个
            cur = cur.next; //当前指针下移
        }

        while(l1 != null){
            total = l1.val + next1;
             cur.next = new ListNode(total % 10);//存入个位
             next1 = total / 10;//计算出下一位要进的数
             l1 = l1.next;
             cur = cur.next; //当前指针下移
        }

        while(l2 != null){
            total = l2.val + next1;
             cur.next = new ListNode(total % 10);//存入个位
             next1 = total / 10;//计算出下一位要进的数
             l2 = l2.next;
             cur = cur.next; //当前指针下移
        }
        if(next1 != 0){
            cur.next = new ListNode(next1);//存入个位
        }

        return res.next;

    }
}

?递归调用法

递归调用法,就是每次加完后就把需要加的位,加入到原链表下一次需要加的数据身上,方便下一次递归调用可以取到数据,如果当一个链表走完之后就创建一个0数据的放入原链表,好进行下一次递归,每次数据处理完毕后,就再一次调用此方法,在调用之前一定要记住把两个链表进行指针后移。

下面我图示说明一下

这里total,next1我就不再解释他的用法,和怎么加入算出next1的

方法执行完毕之后,指针下移,并进行递归调用

?下一次递归时,L1的下一个节点数据已经变为了4,

?当后面没数据,且需要进的位也为0是,就结束递归

下面,我按照上面的步骤,演示一下,当链表结束后,需要进的位还有数据怎么办

?若此时,链表已经结束,但需要进的位中还有数据,就把给链表创建一个新的节点,然后把需要进的位加入到链表中

下一次递归直接进行相加即可,这里有人可能要问了,为什么刚才不直接把next1加入到链表呢?

因为next1这里是临时变量,当进行下一次递归调用时,就无法获取到,上一次递归调用的数据,如果直接加入的话,会导致每次都会把next1加入到链表中。

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) {
        int total = 0;//定义总和
        int next1 = 0;//是否向下一位进1
        ListNode res = new ListNode(); //定义返回的结果
        total = l1.val + l2.val; //加总数
        next1 = total / 10; //获取要进的数
        res = new ListNode(total % 10);//把总数的个位存入链表
        if(l1.next != null || l2.next != null || next1 != 0 ){
            if(l1.next != null){ //如果l1 不为null
                l1 = l1.next; //指针后移
            }else{
                l1 = new ListNode(0); //创建一个新的为0的节点
            }
            if(l2.next != null){ //如果l2 不为null
                l2 = l2.next; //指针后移
            }else{
                l2 = new ListNode(0); //创建一个新的为0的节点
            }
            l1.val = l1.val + next1; //把需要进的位随意加到 l1/l2 上,方便下次递归能找到
            res.next = addTwoNumbers(l1,l2); //进行递归,此时l1 l2已经变换
        }
        return res;
    }
}

制作不易,记得点赞!!!?

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-09-21 00:52:38  更:2022-09-21 00:55:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 16:49:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码