【力扣 445】两数相加 II C++题解(链表+模拟+数学+头插法)

给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。

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

示例1:

输入:l1 = [7,2,4,3], l2 = [5,6,4]

输出:[7,8,0,7]

示例2:

输入:l1 = [2,4,3], l2 = [5,6,4]

输出:[8,0,7]

示例3:

输入:l1 = [0], l2 = [0]

输出:[0]

提示:

链表的长度范围为 [1, 100]

0 <= node.val <= 9

输入数据保证链表代表的数字无前导 0

进阶:如果输入链表不能翻转该如何解决?


思路

先将两个输入的链表反转,然后进行逐位相加,最后将结果再反转回来。让最低位在前,在相加过程中可以方便地处理进位问题。最后再将结果反转,使得最高位在前,满足题目要求。

在进行逐位相加的过程中,代码中定义了一个新的链表,用来存储相加的结果。在遍历输入的两个链表的过程中,每次取出两个链表当前节点的值相加,并加上新链表当前节点的值(用于接收上一位的进位),然后将相加的结果对10取余,得到的值赋给新链表的当前节点,将相加的结果除以10得到的值作为进位,如果进位不为0,则在新链表中添加一个新的节点,用于存储这个进位。

在处理完两个链表共有的部分后,如果两个链表的长度不等,还需要将较长的链表剩余的部分也加到新链表中。这部分的处理逻辑和前面相同,只是不再需要加两个链表的节点值,只需要加上新链表当前节点的值(接收上一位的进位)。

最后,将存储结果的新链表反转,并返回。


AC代码

cpp 复制代码
/*
 * @lc app=leetcode.cn id=445 lang=cpp
 *
 * [445] 两数相加 II
 */

// @lc code=start
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
	ListNode* l3 = new ListNode();
	ListNode* p3 = l3;

   public:
	ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
		ListNode* rl1 = reverse(l1);
		ListNode* rl2 = reverse(l2);
		ListNode* p1 = rl1;
		ListNode* p2 = rl2;
		while (p1 != nullptr && p2 != nullptr) {
			if (p3->next == nullptr) {
				p3->next = new ListNode();
			}
			p3 = p3->next;
			int sum = p1->val + p2->val + p3->val;
			int s = sum % 10;
			int c = sum / 10;
			p3->val = s;
			if (c) {
				p3->next = new ListNode(c);
			}
			p1 = p1->next;
			p2 = p2->next;
		}
		move(p1);
		move(p2);
		l3 = l3->next;
		ListNode* rl3 = reverse(l3);
		return rl3;
	}

	ListNode* reverse(ListNode* l) {
		ListNode* rl = new ListNode();
		ListNode* p = l;
		ListNode* rp;
		while (p != nullptr) {
			rp = new ListNode(p->val);
			rp->next = rl->next;
			rl->next = rp;
			p = p->next;
		}
		rl = rl->next;
		return rl;
	}

	void move(ListNode* p) {
		while (p != nullptr) {
			if (p3->next == nullptr) {
				p3->next = new ListNode();
			}
			p3 = p3->next;
			int sum = p->val + p3->val;
			int s = sum % 10;
			int c = sum / 10;
			p3->val = s;
			if (c) {
				p3->next = new ListNode(c);
			}
			p = p->next;
		}
	}
};
// @lc code=end
相关推荐
W23035765736 小时前
经典算法:最长上升子序列(LIS)深度解析 C++ 实现
开发语言·c++·算法
.Ashy.6 小时前
2026.4.11 蓝桥杯软件类C/C++ G组山东省赛 小记
c语言·c++·蓝桥杯
minji...7 小时前
Linux 线程同步与互斥(三) 生产者消费者模型,基于阻塞队列的生产者消费者模型的代码实现
linux·运维·服务器·开发语言·网络·c++·算法
语戚8 小时前
力扣 968. 监控二叉树 —— 贪心 & 树形 DP 双解法递归 + 非递归全解(Java 实现)
java·算法·leetcode·贪心算法·动态规划·力扣·
skywalker_118 小时前
力扣hot100-7(接雨水),8(无重复字符的最长子串)
算法·leetcode·职场和发展
CoderCodingNo9 小时前
【GESP】C++三级真题 luogu-B4499, [GESP202603 三级] 二进制回文串
数据结构·c++·算法
田梓燊10 小时前
leetcode 160
算法·leetcode·职场和发展
_深海凉_10 小时前
LeetCode热题100-颜色分类
python·算法·leetcode
hetao173383710 小时前
2026-04-09~12 hetao1733837 的刷题记录
c++·算法
6Hzlia10 小时前
【Hot 100 刷题计划】 LeetCode 136. 只出现一次的数字 | C++ 哈希表&异或基础解法
c++·算法·leetcode