当前位置: 首页 > article >正文

LeetCode两数相加

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

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

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

这个问题是经典的“链表相加”问题。两个链表中的每个节点都存储一个数字,它们按照逆序存储,也就是说最低位数字存储在链表的头部。我们需要对链表中的数字进行逐位相加,并将结果也以链表的形式返回。

解题思路

我们可以使用逐位相加的方式来解决问题,并且需要考虑进位

具体步骤

  1. 遍历两个链表

    • 我们从两个链表的头部开始,逐位相加两个数,同时考虑前一位的进位情况。
    • 如果当前位的和大于或等于10,则产生进位。
  2. 进位处理

    • 当两个链表都遍历完后,如果还有进位,需要在结果链表的最后再加上一个节点来存储该进位。
  3. 特殊情况处理

    • 如果某个链表比另一个链表长,则在较短链表遍历完后,只需继续将长链表的剩余部分与进位相加。
  4. 返回结果链表

    • 结果链表也是按照逆序存储的形式输出。

Java代码实现

// 定义链表节点
class ListNode {
    int val;  // 节点的值
    ListNode next;  // 指向下一个节点的指针
    
    // 构造函数
    ListNode(int val) {
        this.val = val;
    }
}

public class AddTwoNumbers {
    
    /**
     * 将两个链表表示的数字相加,并返回结果链表
     *
     * @param l1 链表1
     * @param l2 链表2
     * @return 结果链表
     */
    public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode dummyHead = new ListNode(0); // 虚拟头节点
        ListNode curr = dummyHead;
        int carry = 0;  // 进位

        // 遍历两个链表
        while (l1 != null || l2 != null) {
            int x = (l1 != null) ? l1.val : 0;
            int y = (l2 != null) ? l2.val : 0;
            int sum = carry + x + y; // 当前位的和
            carry = sum / 10; // 更新进位
            curr.next = new ListNode(sum % 10); // 创建新节点存储当前位的值
            curr = curr.next; // 移动到下一个节点

            // 移动链表指针
            if (l1 != null) l1 = l1.next;
            if (l2 != null) l2 = l2.next;
        }

        // 如果最后有进位,创建新节点存储进位
        if (carry > 0) {
            curr.next = new ListNode(carry);
        }

        return dummyHead.next; // 返回结果链表的头节点
    }

    public static void main(String[] args) {
        // 创建链表1: 2 -> 4 -> 3 表示数字342
        ListNode l1 = new ListNode(2);
        l1.next = new ListNode(4);
        l1.next.next = new ListNode(3);

        // 创建链表2: 5 -> 6 -> 4 表示数字465
        ListNode l2 = new ListNode(5);
        l2.next = new ListNode(6);
        l2.next.next = new ListNode(4);

        // 调用addTwoNumbers方法
        ListNode result = addTwoNumbers(l1, l2);
    }
}

代码解释

  1. ListNode 类

    • ListNode 是一个简单的链表节点类,每个节点包含一个整数 val 和一个指向下一个节点的指针 next
  2. addTwoNumbers 方法

    • 该方法接收两个链表 l1l2,表示两个逆序存储的数字。
    • dummyHead 是一个虚拟头节点,它的目的是简化链表操作(比如插入新节点),最后返回 dummyHead.next 即为结果链表的头节点。
    • carry 用于存储相加时的进位。
    • 使用 while 循环逐位相加 l1l2,直到遍历完所有节点。
  3. 进位处理

    • 如果 carry > 0,意味着最后还有进位,需要在结果链表的尾部再加上一个节点。
  4. 示例

    • main 方法中,创建了两个链表 l1l2,分别表示数字 342 和 465。相加的结果为 807,对应的链表形式为 7 -> 0 -> 8

时间复杂度和空间复杂度

  • 时间复杂度O(max(m, n)),其中 mn 分别是两个链表的长度。我们需要遍历两个链表的所有节点。
  • 空间复杂度O(max(m, n)),用于存储结果链表的节点。

总结

这道题的关键在于链表的逐位相加和进位处理。通过使用虚拟头节点来简化链表操作,并且在遍历时考虑进位问题,我们可以高效地解决这个问题。


http://www.kler.cn/news/361913.html

相关文章:

  • Android OpenGL天空盒
  • 【Qt】Windows下Qt连接DM数据库
  • vuex的store应用
  • 将java项目jar包打包成exe服务
  • 计算机网络—vlan(虚拟局域网)
  • 极狐GitLab 发布安全补丁版本 17.4.2, 17.3.5, 17.2.9
  • ECharts饼图-饼图标签对齐,附视频讲解与代码下载
  • 情怀程序员,没有套路的坐下和大家掏心窝聊聊今年的1024 | 程序员节
  • 通过DevTools逃离Chrome沙盒(CVE-2024-6778和CVE-2024-5836)
  • 删除本地文件不影响Github
  • Centos7 安装部署Zookeeper
  • AMR机器人助力废料管理,实现生产空间最大化利用
  • 五年以上倾斜摄影osgb模型转3dtiles如何在mars3d加载
  • CSS 设置网页的背景图片
  • Spearman、Pearson、Euclidean、Cosine、Jaccard,用来衡量不同数据之间的相似性或差异性
  • 【Linux】从 fork() 到 exec():理解 Linux 进程程序替换的魔法
  • gbn,sr和tcp的区别
  • Oracle VM的网络中桥接网卡找不到网络
  • UEFI EDK2框架学习 (四)——UEFI图形化
  • 设计模式05-创建型模式(建造者/原型/单例模式/Java)
  • 使用js和canvas实现绘制一只丑萌的小猫,一步步绘制
  • 电感的学习
  • Tomcat怎么调整参数以优化性能
  • 【MySQL备份】Percona XtraBackup
  • 中医大模型开源!数据集开源!自己训练一个中医大模型吧!
  • 简单介绍冯诺依曼体系