链表中的两数相加:算法深度剖析与实现
在算法的领域中,链表相关的问题一直是重要的考察点。其中,“两数相加”这一经典问题,不仅考验我们对链表结构的操作能力,还涉及到基础的数学运算逻辑。今天,我们就来深入探讨这个问题,通过详细的讲解和丰富的示例代码,带你掌握其解题精髓。
一、问题概述
给定两个非空的链表,它们分别表示两个非负整数。这些整数的每位数字按照逆序的方式存储在链表中,并且每个节点只能存储一位数字。我们的任务是将这两个数相加,并以相同的链表形式返回表示和的链表 。同时,除了数字 0 之外,这两个数都不会以 0 开头。
例如,有如下两个链表:
链表 l1
表示数字 342
(逆序存储为 [2, 4, 3]
),链表 l2
表示数字 465
(逆序存储为 [5, 6, 4]
) 。我们需要计算它们的和 342 + 465 = 807
,并以链表形式 [7, 0, 8]
返回。
二、解题思路
模拟竖式加法
我们可以类比小学时学过的竖式加法运算。从两个链表的头节点开始,逐位相加,并考虑进位情况。
- 初始化一个虚拟头节点
dummyHead
,用于简化链表操作,同时设置一个指针p
指向虚拟头节点,以及一个进位变量carry
初始化为 0 。 - 分别设置指针
p1
和p2
指向链表l1
和l2
的头节点。 - 进入循环,只要
p1
、p2
不为空或者进位carry
不为 0 ,就执行以下操作:- 取出
p1
和p2
当前指向节点的值,如果指针为空则视为 0 。 - 将这两个值与进位
carry
相加,得到当前位的和sum
。 - 计算新的进位
carry = sum / 10
。 - 创建一个新节点存储当前位的和的个位数字
sum % 10
,并将指针p
的next
指向新节点,然后将p
移动到新节点。 - 将
p1
和p2
分别向后移动一位。
- 取出
- 循环结束后,返回虚拟头节点
dummyHead
的next
节点,即为表示和的链表的头节点。
三、示例代码(Java)
// 定义链表节点类
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
public class AddTwoNumbers {
public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {