8.1 链表专题:LeetCode 2. 两数相加

如何高效求解逆序链表表示的两数之和?详解LeetCode算法实现

本文针对LeetCode经典题目「两数相加」展开分析,详细讲解基于单向链表的数字求和技巧。通过虚拟头节点和进位优化策略,实现时间复杂度O(n)的高效解法。


1. 题目链接

LeetCode 2. 两数相加


2. 题目描述

给定两个非空链表,分别表示两个非负整数。每个节点存储一位数字,且按逆序方式存储(例如:数字123存储为3→2→1)。要求将这两个数相加,并以相同形式的链表返回结果。

示例说明
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807,逆序存储为708 → 输出链表7→0→8


3. 示例分析

示例1:等长链表且有进位

输入:
l1: 9→9→9(对应数字999)
l2: 1→0→0→1(对应数字1001)
输出:0→0→0→2
计算过程:999 + 1001 = 2000 → 逆序链表0→0→0→2

关键点

  • 链表长度不一致时的处理
  • 最终进位生成新节点

示例2:长度不同且末位进位

输入:
l1: 9→9(99)
l2: 9→9→9→9(9999)
输出:8→9→0→0→1
计算过程:99 + 9999 = 10098 → 逆序存储为89001


4. 算法思路

核心思想:模拟竖式加法

  1. 同步遍历:同时遍历两个链表的当前节点。
  2. 进位处理:计算当前位之和时累加前一位的进位。
  3. 虚拟头节点:简化链表构造,避免头节点特殊处理。
  4. 循环终止条件:两链表均遍历完且无剩余进位。

步骤拆解:

  1. 初始化虚拟头节点newhead和尾指针prev
  2. 使用变量t累计当前位的总和(包括进位)。
  3. 循环处理每个节点:
    • 累加当前节点值到t(若存在)
    • 计算当前位的值t % 10
    • 更新进位t = t / 10
  4. 最终返回虚拟头节点的下一个节点。

5. 边界条件与注意事项

关键边界条件

  1. 链表长度不同:当其中一个链表遍历完时,继续处理另一个链表剩余节点。
  2. 最高位进位:循环结束后若t > 0,需创建新节点存储进位值。
  3. 全零情况:输入为0+0时,需保证输出正确(单个节点0)。

注意事项

  • 内存管理:创建的虚拟头节点需手动释放,避免内存泄漏。
  • 指针操作:移动cur1cur2时需先取值再后移,防止空指针异常。
  • 进位更新顺序:必须先计算当前位值再更新进位,否则逻辑错误。

6. 代码实现

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode* cur1 = l1, *cur2 = l2;
        ListNode* newhead = new ListNode(0); // 虚拟头节点简化操作
        ListNode* prev = newhead;            // 尾插法构建结果链表
        int t = 0; // 同时记录当前位和及进位

        while (cur1 || cur2 || t) { // 任一链表未结束或存在进位时继续
            // 处理当前节点值
            if (cur1) { 
                t += cur1->val;
                cur1 = cur1->next;
            }
            if (cur2) {
                t += cur2->val;
                cur2 = cur2->next;
            }
            
            // 创建新节点并更新指针
            prev->next = new ListNode(t % 10);
            prev = prev->next;
            t /= 10; // 计算进位
        }
        
        // 释放虚拟头节点内存
        ListNode* res = newhead->next;
        delete newhead;
        return res;
    }
};

代码解析

  • 虚拟头节点newhead作为占位节点,其next指向结果链表的真实头节点。
  • 循环条件cur1 || cur2 || t确保处理所有可能情况。
  • 进位复用:变量t先累加节点值,再计算当前位和进位,优化空间复杂度至O(1)。

总结

本算法通过逐位相加和进位处理,高效解决了逆序链表求和问题。重点在于正确处理链表长度差异及进位生成新节点的情况。掌握虚拟头节点技巧可显著简化链表操作,提升代码可读性和健壮性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值