牛客 - 链表相加(二)
描述
假设链表中每一个节点的值都在 0 - 9 之间,那么链表整体就可以代表一个整数。
给定两个这种链表,请生成代表两个整数相加值的结果链表。
数据范围:0≤n,m≤1000000,链表任意值 0≤val≤9
要求:空间复杂度 O(n),时间复杂度 O(n)
例如:链表 1 为 9->3->7,链表 2 为 6->3,最后生成新的结果链表为 1->0->0->0。
示例1
输入:
[9,3,7],[6,3]
返回值:{1,0,0,0}
示例2
输入:[0],[6,3]
返回值:{6,3}
备注:
1 ≤ n , m ≤ 1 0 6 1≤n,m≤10^6 1≤n,m≤106
0 ≤ a i , b i ≤ 9 0≤a_i ,b_ i ≤9 0≤ai,bi≤9
思路一:
- 把两个链表的元素都添加到两个容器中,并反转这两个链表,根据两个链表的长度的最大值,对长度较小的那个进行补齐。
- 补齐之后对进行运算,创建一个结果容器,如果两个容器的元素的值加起来大于等于10,就让当前值减去10,并加上进制位,插入结果容器,最后如果进制位不等于默认值,就说明还需要把这个进制位也加入结果容器中。
- 结果容器运算结束反转结果容器,并创建虚拟节点,将元素一个一个插入虚拟节点中,最后返回虚拟节点的下一个节点。
/*** struct ListNode {* int val;* struct ListNode *next;* ListNode(int x) : val(x), next(nullptr) {}* };*/
#include <list>
#include <vector>
class Solution {
public:/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** * @param head1 ListNode类 * @param head2 ListNode类 * @return ListNode类*/ListNode* addInList(ListNode* head1, ListNode* head2) {// 特殊情况处理:如果两个链表都为空,返回nullptrif(head1 == nullptr && head2 == nullptr) return nullptr;// 如果其中一个链表为空,直接返回另一个链表if(head1 == nullptr) return head2;if(head2 == nullptr) return head1;// 将链表数据存到两个容器中std::vector<int> data1; // 存储链表1的值std::vector<int> data2; // 存储链表2的值ListNode* currNode1 = head1; // 遍历链表1的指针ListNode* currNode2 = head2; // 遍历链表2的指针// 遍历链表1,将每个节点的值存入data1while(currNode1 != nullptr){data1.push_back(currNode1->val);currNode1 = currNode1->next;}// 遍历链表2,将每个节点的值存入data2while(currNode2 != nullptr){data2.push_back(currNode2->val);currNode2 = currNode2->next;}// 反转两个容器,因为链表是从低位到高位存储的,反转后便于从高位开始相加std::reverse(data1.begin(), data1.end());std::reverse(data2.begin(), data2.end());// 确定两个容器的长度,并将较短的容器用0填充到与较长容器相同的长度int len = 0;if(data1.size() > data2.size()) {len = data1.size();data2.resize(len, 0); // 用0填充data2}else {len = data2.size();data1.resize(len, 0); // 用0填充data1}// 创建结果容器,用于存储相加后的每一位数字std::vector<int> res;int flag = 0; // 进位标志// 从高位到低位逐位相加for(int i = 0; i < len; i++){int new_val = data1[i] + data2[i] + flag; // 当前位的和加上进位if(new_val >= 10) // 如果当前位的和大于等于10,需要进位{new_val = new_val - 10; // 当前位的值减去10flag = 1; // 设置进位标志为1}else {flag = 0; // 如果不需要进位,重置进位标志}res.push_back(new_val); // 将当前位的结果存入结果容器}// 如果最后还有进位,将进位添加到结果中if(flag != 0){res.push_back(flag);}// 反转结果容器,使其从低位到高位存储std::reverse(res.begin(), res.end());// 创建新的链表来存储结果ListNode* dummy = new ListNode(0); // 创建一个虚拟头节点ListNode* currNode = dummy; // 当前节点指针// 遍历结果容器,创建链表节点for(int i = 0; i < res.size(); i++){ListNode* newNode = new ListNode(res[i]); // 创建新节点currNode->next = newNode; // 将新节点连接到当前节点currNode = currNode->next; // 移动当前节点指针}ListNode* resNode = dummy->next; // 获取结果链表的头节点delete dummy; // 删除虚拟头节点return resNode; // 返回结果链表的头节点}
};
思路二:
直接反转两个链表,反转之后进行运算
/*** struct ListNode {* int val;* struct ListNode *next;* ListNode(int x) : val(x), next(nullptr) {}* };*/
#include <list>
#include <vector>
class Solution {
public:/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** * @param head1 ListNode类 * @param head2 ListNode类 * @return ListNode类*/ListNode* reverseList(ListNode* head){// 创建一个前指针ListNode* prevNode = nullptr;ListNode* currNode = head;while(currNode != nullptr){// 暂存下一个节点ListNode* nextNode = currNode->next;// 反转当前节点的指针currNode->next = prevNode;// 移动prev到当前节点prevNode = currNode;// 继续处理下一个节点currNode = nextNode;}// prev最终指向新的头结点return prevNode;}ListNode* addInList(ListNode* head1, ListNode* head2) {// 特殊情况处理:如果两个链表都为空,返回nullptrif(head1 == nullptr && head2 == nullptr) return nullptr;// 如果其中一个链表为空,直接返回另一个链表if(head1 == nullptr) return head2;if(head2 == nullptr) return head1;// 反转两个链表,使其从低位到高位存储head1 = reverseList(head1);head2 = reverseList(head2);// 创建一个虚拟头节点,方便操作ListNode* dummy = new ListNode(0);// 当前节点指针,用于构建结果链表ListNode* currNode = dummy;// 分别指向两个链表的当前节点ListNode* currNode1 = head1;ListNode* currNode2 = head2;// 进位标志int flag = 0;// 遍历两个链表,直到两个链表都为空while(currNode1 != nullptr || currNode2 != nullptr) {// 获取当前节点的值,如果链表为空则取0int val1 = currNode1 != nullptr ? currNode1->val : 0;int val2 = currNode2 != nullptr ? currNode2->val : 0;// 计算当前位的和,加上进位int new_val = val1 + val2 + flag;// 如果当前位的和大于等于10,需要进位if(new_val >= 10) {new_val -= 10; // 当前位的值减去10flag = 1; // 设置进位标志为1} else {flag = 0; // 如果不需要进位,重置进位标志}// 创建新节点,存储当前位的值ListNode* newNode = new ListNode(new_val);// 将新节点连接到结果链表currNode->next = newNode;// 移动当前节点指针currNode = currNode->next;// 如果链表1不为空,移动到下一个节点if (currNode1 != nullptr) currNode1 = currNode1->next;// 如果链表2不为空,移动到下一个节点if (currNode2 != nullptr) currNode2 = currNode2->next;}// 如果最后还有进位,添加一个新节点if(flag != 0) {ListNode* newNode = new ListNode(flag);currNode->next = newNode;}// 获取结果链表的头节点ListNode* resNode = dummy->next;// 删除虚拟头节点delete dummy;// 反转结果链表,使其从高位到低位存储resNode = reverseList(resNode);return resNode;}
};
相关文章:

牛客 - 链表相加(二)
描述 假设链表中每一个节点的值都在 0 - 9 之间,那么链表整体就可以代表一个整数。 给定两个这种链表,请生成代表两个整数相加值的结果链表。 数据范围:0≤n,m≤1000000,链表任意值 0≤val≤9 要求:空间复杂度 O(n)&am…...

GPU 硬件原理架构(一)
这张费米管线架构图能看懂了,整个GPU的架构基本就熟了。市面上有很多GPU厂家,他们产品的架构各不相同,但是核心往往差不多,整明白一了个基本上就可以触类旁通了。下面这张图信息量很大,可以结合博客GPU 英伟达GPU架构回…...
C/C++编译器
C/C 代码是不可跨平台的,Windows 和 Unix-like 有着不同的 API,C/C 在不同平台有着不同编译器。 MSVC Windows 平台,MSVC 是 Visual Studio 中自带的 C/C 编译器。 GCC Unix-like 平台,GCC 原名 GNU C Compiler,后…...

Immutable设计 SimpleDateFormat DateTimeFormatter
专栏系列文章地址:https://blog.csdn.net/qq_26437925/article/details/145290162 本文目标: 理解不可变设计模式,时间format有线程安全要求的注意使用DateTimeFormatter 目录 ImmutableSimpleDateFormat 非线程安全可以synchronized解决&a…...

最新EFK(Elasticsearch+FileBeat+Kibana)日志收集
文章目录 1.EFK介绍2.操作前提3.FileBeat8.15下载&安装4.编写FileBeat配置文件5.启动FileBeat6.模拟实时日志数据生成7.查看索引(数据流)是否创建成功8.创建数据视图:9.查看数据视图10.使用KQL对采集的日志内容进行过滤11.给日志数据配置保留天数(扩展知识) 1.E…...
Vue 3 30天精进之旅:Day 15 - 插件和指令
欢迎来到“Vue 3 30天精进之旅”的第15天!今天我们将深入探讨Vue 3中的插件和自定义指令。这两个主题能够帮助我们扩展Vue的功能,使我们的应用更加灵活和强大。 一、插件概述 1. 什么是插件? 在Vue中,插件是一种功能扩展机制。…...
【实战篇】Android安卓本地离线实现视频检测人脸
实战篇Android安卓本地离线实现视频检测人脸 引言项目概述核心代码类介绍人脸检测流程项目地址总结 引言 在当今数字化时代,人脸识别技术已经广泛应用于各个领域,如安防监控、门禁系统、移动支付等。本文将以第三视角详细讲解如何基于bifan-wei-Face/De…...
【JavaScript】《JavaScript高级程序设计 (第4版) 》笔记-Chapter3-语言基础
三、语言基础 ECMAScript 的语法很大程度上借鉴了 C 语言和其他类 C 语言,如 Java 和 Perl。ECMAScript 中一切都区分大小写。无论是变量、函数名还是操作符,都区分大小写。 所谓标识符,就是变量、函数、属性或函数参数的名称。标识符可以由…...
(dpdk f-stack)-堆栈溢出-野指针-内存泄露(问题定位)
目的:解决堆栈溢出,野指针,内存泄露。 解决方法 [root@ test]# yum install libasan [root@ test]# cat test.c int main() { int array[10]; array[11] = 11; return 0; } [root@ test]# gcc -fsanitize=address -O1 -fno-omit-frame-pointer -g -O0 test.c -o test ./te…...

HTML5 教程之标签(3)
HTML5 <center> 标签 (已废弃) 定义和用法 <center> 标签对其包围的文本进行水平居中处理。HTML5不支持使用<center>标签,因此有关该标签的更多信息,请参考“HTML <center>标签”部分! 示例: <center>这个…...

【蓝桥】动态规划-简单-破损的楼梯
题目 解题思路 完整代码 #include <bits/stdc.h> using namespace std; const int N1e59; const long long p1e97; long long dp[N];//dp[i]表示走到第i级台阶的方案数 bool broken[N];//broken代表破损台阶的数组 int main() {int n,m;cin>>n>>m;for(int …...

如何自定义软件安装路径及Scoop包管理器使用全攻略
如何自定义软件安装路径及Scoop包管理器使用全攻略 一、为什么无法通过WingetUI自定义安装路径? 问题背景: WingetUI是Windows包管理器Winget的图形化工具,但无法直接修改软件的默认安装路径。原因如下: Winget设计限制…...

107,【7】buuctf web [CISCN2019 华北赛区 Day2 Web1]Hack World
这次先不进入靶场 看到红框里面的话就想先看看uuid是啥 定义与概念 UUID 是 Universally Unique Identifier 的缩写,即通用唯一识别码。它是一种由数字和字母组成的 128 位标识符,在理论上可以保证在全球范围内的唯一性。UUID 的设计目的是让分布式系…...

STM32 ADC单通道配置
硬件电路 接线图: ADC基本结构图 代码配置 根据基本结构框图 1.定义结构体变量 //定义结构体变量 GPIO_InitTypeDef GPIO_InitStructure;//定义GPIO结构体变量 ADC_InitTypeDef ADC_InitStructure; //定义ADC结构体变量 2.开启RCC时钟 ADC、GPIO的时钟&#x…...

【技海登峰】Kafka漫谈系列(二)Kafka高可用副本的数据同步与选主机制
【技海登峰】Kafka漫谈系列(二)Kafka高可用副本的数据同步与选主机制 一. 数据同步 在之前的学习中有了副本Replica的概念,解决了数据备份的问题。我们还需要面临一个设计难题即:如何处理分区中Leader与Follwer节点数据同步不匹配问题所带来的风险,这也是保证数据高可用的…...
Spring的三级缓存如何解决循环依赖问题
循环依赖问题是在对象之间存在相互依赖关系,形成一个闭环,导致无法准确的完成对象的创建和初始化,当两个或多个对象彼此之间相互引用,这种相互引用形成一个循环时,就可能出现循环依赖问题。 在 Spring 框架中…...

Ext文件系统
文件内容属性 被打开的文件在内存中,没有被打开的文件在磁盘里文件系统的工作就是根据路径帮我们找到在磁盘上的文件 磁盘(硬件) 磁盘的存储结构 磁头在传动臂的运动下共同进退,向磁盘写入的时候是向柱面批量写入的 OS文件系统访…...

回溯算法---数独问题
回溯算法理论基础 回溯和递归密不可分,有回溯就有递归,所谓回溯就是基于一个叉树,可能是二叉树或者是三叉树,从root节点开始深度优先搜索遍历节点,当遍历到一个子节点时,回溯到上一个根节点选择另外一个子…...

蓝桥杯python基础算法(2-1)——排序
目录 一、排序 二、例题 P3225——宝藏排序Ⅰ 三、各种排序比较 四、例题 P3226——宝藏排序Ⅱ 一、排序 (一)冒泡排序 基本思想:比较相邻的元素,如果顺序错误就把它们交换过来。 (二)选择排序 基本思想…...
【课程笔记】信息隐藏与数字水印
文章总览:YuanDaiMa2048博客文章总览 【课程笔记】信息隐藏与数字水印 信号处理基础知识隐写系统隐写算法性能指标音频信号处理基础数字音频概念人类听觉系统与语音质量评价信息隐藏的原理数字指纹与版权保护盲水印与非盲水印私钥水印与公钥水印信息隐藏的研究层次信息隐藏与数…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...

简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...

手机平板能效生态设计指令EU 2023/1670标准解读
手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读,综合法规核心要求、最新修正及企业合规要点: 一、法规背景与目标 生效与强制时间 发布于2023年8月31日(OJ公报&…...
【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权
摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题:安全。文章将详细阐述认证(Authentication) 与授权(Authorization的核心概念,对比传统 Session-Cookie 与现代 JWT(JS…...