LeetCode题目笔记——面试题 02.05. 链表求和

2023-10-26

题目描述

给定两个用链表表示的整数,每个节点包含一个数位。

这些数位是反向存放的,也就是个位排在链表首部。

编写函数对这两个整数求和,并用链表形式返回结果。

示例:

输入:(7 -> 1 -> 6) + (5 -> 9 -> 2),即617 + 295
输出:2 -> 1 -> 9,即912

进阶:思考一下,假设这些数位是正向存放的,又该如何解决呢?

示例:

输入:(6 -> 1 -> 7) + (2 -> 9 -> 5),即617 + 295
输出:9 -> 1 -> 2,即912

题目链接

题目难度——中等

方法一:模拟

  按照题目的意思,如果链表是从地位开始走的话,那就好办了,我们只需要模拟一下做加法就行,需要注意的是进位的跟踪。

代码/C++

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode *res = new ListNode, *cur = res;
        int carry = 0, tmp;
        ListNode *p1 = l1, *p2 = l2;
        while(p1 != NULL && p2 != NULL){
            tmp = p1->val + p2->val + carry;
            cur->next = new ListNode(tmp % 10);
            carry = tmp > 9 ? 1 : 0;
            cur = cur->next;
            p1 = p1->next;
            p2 = p2->next;
        }
        while(p1 != NULL){
            cur->next = new ListNode((p1->val + carry) % 10);
            cur = cur->next;
            carry = p1->val + carry > 9 ? 1 : 0;
            p1 = p1->next;
        }
        while(p2 != NULL){
            cur->next = new ListNode((p2->val + carry) % 10);
            cur = cur->next;
            carry = p2->val + carry > 9 ? 1 : 0;
            p2 = p2->next;
        }
        if(carry){
            cur->next = new ListNode(1);
        }
        return res->next;
    }
};

在这里插入图片描述
  代码有点长,还可以精简一下,比如把后面两个循环和最后的判断carry都放到以第一个循环里去,这里用python再写一次。

代码/Python

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        # 模拟
        res = ListNode(-1)
        head = res
        carry = 0
        while l1 != None or l2 != None or carry:
            tmp = 0
            tmp += l1.val if l1 else 0
            tmp += l2.val if l2 else 0
            tmp += carry
            res.next = ListNode(tmp % 10)
            carry = 1 if tmp > 9 else 0
            res = res.next
            l1 = l1.next if l1 else None
            l2 = l2.next if l2 else None
        
        return head.next

方法二——递归

  还可以用递归来解决,递归函数接收4个参数,分别是两个链表和结果链表以及进位,在递归体内当进位和两个链表指针都为空的时候就开始“归”,只要还有一个不为空,就继续往下递,在递的过程中进行加法。

代码/C++

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode *res = new ListNode(-1);
        int carry = 0;
        sum(l1, l2, carry, res);
        return res->next;
    }

    void sum(ListNode *l1, ListNode *l2, int carry, ListNode *res){
        if (l1 == NULL && l2 == NULL && carry == 0){
            return ;
        }
        int tmp = 0;
        tmp += l1 == NULL ? 0 : l1->val;
        tmp += l2 == NULL ? 0 : l2->val;
        tmp += carry;
        res->next = new ListNode(tmp % 10);
        carry = tmp > 9 ? 1 : 0;
        sum(l1 == NULL ? NULL : l1->next, l2 == NULL ? NULL : l2->next, carry, res->next);
    }
};

进阶——借用栈或者先反转原链表

  进阶思考的链表按照我们人更易读的数位顺序存储数据,但处理起来更麻烦了,我们可以借用一个栈来表示这个先用低位的关系,将两个链表元素都入栈之后,就可以用前面两种方法来做了。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        // 进阶问题,用栈解决,或者先翻转一下链表,再用之前的方法
        stack<int> stack1, stack2, stackres;
        ListNode *p1 = l1, *p2 = l2, *res = new ListNode(-1), *p = res;
        while(p1){
            stack1.push(p1->val);
            p1 = p1->next;
        }
        while(p2){
            stack2.push(p2->val);
            p2 = p2->next;
        }
        int carry = 0, tmp;
        while(!stack1.empty() || !stack2.empty() || carry){
            tmp = 0;
            tmp += stack1.empty() ? 0 : stack1.top();
            tmp += stack2.empty() ? 0 : stack2.top();
            if(!stack1.empty()) stack1.pop();
            if(!stack2.empty()) stack2.pop();
            tmp += carry;
            stackres.push(tmp % 10);
            carry = tmp > 9 ? 1 : 0;
        }
        while(!stackres.empty()){
            p->next = new ListNode(stackres.top());
            stackres.pop();
            p = p->next;
        }
        return res->next;
    }

};

总结

  几种方法都要遍历一遍链表,所以时间是O(N),用到了栈的话空间就是O(N)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

LeetCode题目笔记——面试题 02.05. 链表求和 的相关文章

  • 算法(C)(两数之和)

    题目 两数之和 题目描述 给定一个整数数组 nums 和一个整数目标值 target 请你在该数组中找出 和为目标值 target 的那 两个 整数 并返回它们的数组下标 你可以假设每种输入只会对应一个答案 但是 数组中同一个元素在答案里不
  • JSON使用的一些总结

    http sx666 blogspot com 2007 11 json html JSON JavaScript Object Notation 是一种轻量级的数据交换格式 它采用完全独立于语言的文本格式 可以用来在客户端和服务器端传输数
  • innerText和innerHTML区别

    innerText和innerHTML区别 尽管DOM带来了动态修改文档的能力 但对开发人员来说 这还不够 IE4 0为所有的元素引入了两个特性 以更方便的进行文档操作 这两个特性是innerText和innerHTML 其中innerTe
  • Oracle:重复数据去重,只取其中一条(最新时间/其他字段排序规则)数据

    一 问题 一个会话id代表一个聊天室 返回该聊天室最新的一条数据显示在会话列表 二 解决思路 使用row number over 分组排序功能 来解决该问题 1 语法格式 row number over partition by 分组列 o

随机推荐

  • TMOD、SCON、PCON寄存器的配置

    TMOD控制寄存器 TMOD是定时器 计数器模式控制寄存器 它是一个逐位定义的8为寄存器 但只能使用字节寻址 其各位是 由上图我们就可以看出 这个寄存器控制了两个定时器 计数器 寄存器的高四位控制定时器1 低四位控制定时器0 GATE 门控
  • 数据分析毕业设计 二手房数据爬取与分析可视化系统 -python

    1 前言 这两年开始毕业设计和毕业答辩的要求和难度不断提升 传统的毕设题目缺少创新和亮点 往往达不到毕业答辩的要求 这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求 为了大家能够顺利以及最少的精力通过毕设 学长分享优质毕业设计项
  • Air700E开发板

    文章目录 基础资料 概述 主要功能 外设分布 PinOut 管脚定义 管脚功能说明 固件升级 正常开机模式 下载模式 IO 电平选择 基础资料 Air700E文档中心 概述 EVB Air700E 开发板是合宙通信推出的基于 Air700E
  • 去除VsCode代码前面的小点点

    去除VsCode代码前面的小点点 去除图片中的点 步骤 File gt Preferences gt Setting 搜索RenderWhitespace 将Text Editor下的Editor Render Whitespace改为no
  • peewee-async使用描述

    1 peewee async是一个为peewee ORM 提供由asyncio支持的异步io库 在单独使用peewee连接池连接时 同时使用到了async和await协程 这样操作会阻塞整个进程 因为tornado是单进程 必须数据库也使用
  • 数据库的简介与类型 #CSDN博文精选# #IT技术# #数据库#

    大家好 小C将继续与你们见面 带来精选的CSDN博文 又到周一啦 上周的系统化学习专栏已经结束 我们总共一起学习了20篇文章 这周将开启全新专栏 放假不停学 全栈工程师养成记 在这里 你将收获 将系统化学习理论运用于实践 系统学习IT技术
  • 高通 AR Unity 虚拟按钮

    1 虚拟按钮是图像上的目标 用户可以在现实世界中触摸 以触发一个动作的 热点 现有的图像目标的一个实例的VirtualButton预制拖动到场景中添加虚拟按键 平移和缩放按钮 以匹配所需的位置 并给它一个名字 虚拟的按钮添加这样写入到con
  • 计算机视觉概述

    关注公众号 CV算法恩仇录 本文介绍了计算机视觉的主要任务及应用 全文大约 3500 字 阅读时间 10 分钟 人们或许没有意识到自己的视觉系统是如此的强大 婴儿在出生几个小时后能识别出母亲的容貌 在大雾的天气 学生看见朦胧的身体形态 能辨
  • v-viewer 插件图片点击放大预览的几种使用方法

    官网git地址 https github com mirari v viewer 最终效果如下 ps 按钮样式都是可以根据自己需求调整的 第一种使用方法 支持UMD用法 建议把v viewer相关的js和css文件下载到本地引用 可以到上面
  • set容器、map容器

    set multiset 容器 set基本概念 简介 所有元素都会在插入时自动被排序 本质 set multiset属于关联式容器 底层结构是用二叉树实现 set和multiset区别 set不允许容器中有重复的元素 multiset允许容
  • elk笔记23--定期清理索引

    elk笔记23 定期清理索引 1 介绍 2 方案 代码 2 1 方案介绍 2 2 代码 2 3 测试 3 注意事项 4 说明 1 介绍 在生产环境中 如果日志量过大 就会导致集群持续产生很多索引 占用很多存储空间 因此需要定期清理索引 确保
  • 套圈·分治

    套圈 题目信息 输入 测试样例 解答 想法 题目信息 Have you ever played quoit in a playground Quoit is a game in which flat rings are pitched at
  • 闭环步进与伺服电机差异

    当给步进电机配备编码器闭环控制后 从广义上来看 闭环步进电机和伺服电机两者是没有什么大的区别 但是 要详细区分闭环步进电机和伺服电机的不同之处 你需要先了解一下伺服电机和步进电机的差异 闭环步进电机是在步进电机上加装了高精度的编码器 用伺服
  • 理解扩散模型:Diffusion Models & DDPM

    引言 在前面的博客中 我们讨论了生成模型VAE和GAN 近年来 新的生成模型 扩散模型受到越来越多的关注 因此值得好好去研究一番 扩散模型 Diffusion Models 最早由 2 于2015年提出 但直到2020年论文 3 发表之后才
  • 不断发展中的自然语言处理技术,会在未来消灭“笔”和“键盘”吗?

    花满楼 发布于2014 07 20 23 11 00 目前 Siri 和 Google Now 的语音识别技术虽然还不完善 但在未来却很可能威胁到文字的地位 我们手写或者打字 在当下已经成为了无比繁重的劳动 不断的输入各种文字信息 在网页上
  • 快手20230807提前批一面

    Q and A 面试官 你是专硕还是学硕 能不能让实习 研究方向 面试官 项目基于什么背景做的 xxx 面试官 介绍一下框架 xxxx 面试官 里面中用了什么技术 首先的话 服务层使用了springboot 并且使用了mp 持久化使用了my
  • angular7主题样式在线切换

    参考ng alain和delon 思路就是动态加载css文件 代码实现 写两套less文件 分别为light less和dark less 用相关插件将less文件转为一个js对象 less vars to js 插件 function g
  • Road Construction 【POJ - 3352】【Tarjan边双连通】

    题目链接 题意 给一个无向连通图 至少添加几条边使得去掉图中任意一条边不改变图的连通性 即使得它变为边双连通图 思路 就是去求一个缩点之后求度为1的点的个数 然后用 ans 1 2就可以得到最后的答案了 include
  • 计算机图像显示原理与BMP图像文件格式

    本篇文章详细讲述图像文件 里面有一些阐述为个人理解 如有不对的地方欢迎指正 后续会修正补全 计算机图像显示原理与BMP图像的文件格式 一 计算机图像显示原理简述 1 计算机图像分类 2 显示 3 彩色图转灰白图原理 二 BMP图像 1 BM
  • LeetCode题目笔记——面试题 02.05. 链表求和

    文章目录 题目描述 题目难度 中等 方法一 模拟 代码 C 代码 Python 方法二 递归 代码 C 进阶 借用栈或者先反转原链表 总结 题目描述 给定两个用链表表示的整数 每个节点包含一个数位 这些数位是反向存放的 也就是个位排在链表首