LeetCode 热题 100-----28. 两数相加

一、题目完整详情

1. 原题描述

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

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

2. 核心题意拆解(必看)

  • 存储规则 :链表逆序存储数字,即链表第一个节点是数字的个位 ,第二个节点是十位 ,依次往后。例如:数字342 → 链表 2→4→3

  • 节点规则:单个节点仅存储 0-9 的一位数字,无多位数

  • 输入规则:两个链表均非空,数字无前置零(仅数字0本身允许单个0节点)

  • 输出规则 :相加结果同样以逆序链表返回

3. 经典示例深度解析

  • 示例1:输入 l1=[2,4,3]、l2=[5,6,4],对应数字 342+465=807,输出逆序链表 [7,0,8]

  • 示例2:输入 l1=[0]、l2=[0],对应数字 0+0=0,输出 [0]

  • 示例3:输入 l1=[9,9,9,9,9,9,9]、l2=[9,9,9,9],对应数字 9999999+9999=10009998,输出逆序链表 [8,9,9,9,0,0,0,1]

4. 题目难点

  • 链表长度不统一,需要兼容长短链表相加

  • 加法进位处理,尤其是最后一位产生进位的边界情况

  • 链表无法直接随机访问,只能从头遍历

  • 大数场景下,直接转换数字会溢出失效

二、零基础必备前置知识

本节包含本题用到的所有基础知识点,从未接触过编程、算法、链表的,看完即可完全掌握解题基础。

1. 单链表数据结构(本题核心)

1.1 什么是单链表?

单链表是一种线性链式存储的数据结构,由多个「节点」串联组成,类比现实中的糖葫芦:每一颗山楂是节点,串联的绳子是指针。

与数组不同,链表的内存地址不连续,只能通过指针依次访问,不能直接跳转到指定位置。

1.2 链表节点的组成

本题的标准节点固定包含两个核心属性:

  • 数据域 val:存储当前节点的数值,本题固定为 0-9 的整数

  • 指针域 next :存储下一个节点的地址,用于串联链表

链表末尾节点的 next 指向 空值(Python:None / C++:nullptr),代表链表结束。

1.3 链表核心特性
  • 必须从头节点开始遍历,无法直接访问中间、末尾节点

  • 支持动态新增节点,长度不固定

  • 逆序存储适配加法:个位在前,刚好对应数学加法从低位开始计算的规则

2. 十进制加法进位规则(算法核心逻辑)

本题算法完全模拟小学竖式加法,所有计算逻辑基于以下规则:

  • 加法顺序:从**最低位(个位)**向高位依次相加

  • 计算公式:当前位总和 = 第一个数当前位 + 第二个数当前位 + 上一位的进位值

  • 进位规则:总和 ≥10 则产生进位,进位值固定为1;总和<10 进位值为0

  • 当前位结果:总和对10取余(保留个位数字)

  • 收尾规则:所有位数相加完成后,若仍有进位,需要单独新增一位存储进位

示例:9+9=18 → 当前位存8,进位1;最后剩余进位1,需新增节点存储1

3. 代码基础运算知识

  • 取余运算 %a % 10,获取数字的个位(例:18%10=8、7%10=7)

  • 整除运算 // / :Python用//、C++用/,获取数字的十位及以上(例:18//10=1、7//10=0)

  • 空值判断:链表节点遍历结束后为空,空节点数值统一取0参与计算

4. 算法常用技巧:哑节点(哨兵节点)

4.1 定义

哑节点是一个无实际业务意义的虚拟头节点,数值固定为0,不参与计算,仅用于拼接结果链表。

4.2 作用(解题关键)

如果不使用哑节点,需要单独判断结果链表的第一个节点,代码冗余、逻辑复杂;使用哑节点后,所有节点统一拼接在哑节点后方,无需处理头节点特殊情况,代码逻辑统一、简洁。

4.3 使用方式

最终结果为:哑节点的下一个节点(dummy.next)

5. 链表遍历规则

  • 定义指针变量,初始指向链表头节点

  • 每完成一次当前节点计算,指针向后移动:指针 = 指针.next

  • 循环终止条件:指针为空,代表链表遍历完成

三、解题思路(由易到难:暴力法→最优优化法)

解法一:暴力转换数字法(入门简单,适合理解)

1. 核心思路

跳过链表逐位计算,直接将两个逆序链表转换为完整整数 ,整数相加后,再将结果整数逆序转换为链表。逻辑直观,完全贴合题目字面意思。

2. 执行步骤
  1. 遍历第一个链表,逆序拼接为完整整数 num1

  2. 遍历第二个链表,逆序拼接为完整整数 num2

  3. 计算总和 sum_num = num1 + num2

  4. 将 sum_num 逐位拆分,逆序构建结果链表

3. 优缺点分析
  • 优点:逻辑极简,零基础极易理解,代码可读性高

  • 缺点:存在大数溢出问题,题目支持链表长度最大100位,远超普通整数、长整数存储范围,无法通过超长用例,仅适合入门学习

解法二:逐位模拟进位法(最优解法、面试标准、AC满分)

1. 核心思路

完全模拟小学竖式加法,不转换完整数字,直接遍历两个链表,逐位相加、更新进位、构建结果链表,规避大数溢出问题,是本题唯一通用解法。

2. 执行步骤
  1. 初始化哑节点、遍历指针、进位变量(初始进位为0)

  2. 循环遍历:只要任意链表未遍历完 或 存在进位,持续循环

  3. 取出两个链表当前位数值(空节点补0)

  4. 计算当前位总和、更新进位、生成当前结果位

  5. 新建节点拼接至结果链表,移动所有遍历指针

  6. 循环结束,返回哑节点下的结果链表

3. 优缺点分析
  • 优点:无溢出问题,兼容所有边界用例,时间空间最优,可直接提交AC

  • 缺点:需要理解进位循环逻辑,比暴力法稍抽象

四、Python 完整代码实现(双解法+逐行注释+全测试用例+自定义输入)

1. 暴力转换数字法(入门版)

python 复制代码
# 定义链表节点类(题目标准模板,不可修改)
class ListNode:
    # 节点构造方法:默认值0,默认无下一个节点
    def __init__(self, val=0, next=None):
        self.val = val      # 节点存储的数值
        self.next = next    # 指向后继节点的指针

from typing import Optional

class Solution:
    # 暴力解法:链表转数字相加
    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
        # 1. 初始化两个数字的基数和结果值
        num1 = 0
        num2 = 0
        base = 1  # 基数:个位1、十位10、百位100...对应逆序链表
        
        # 2. 遍历l1链表,转换为完整整数
        while l1:
            num1 += l1.val * base  # 当前位数值*基数,累加得到完整数
            base *= 10             # 基数升级(个位→十位→百位)
            l1 = l1.next          # 指针后移
        
        # 重置基数,遍历l2链表
        base = 1
        while l2:
            num2 += l2.val * base
            base *= 10
            l2 = l2.next
        
        # 3. 两数直接相加
        sum_num = num1 + num2
        
        # 4. 将总和逆序转为链表
        # 处理特殊情况:和为0
        if sum_num == 0:
            return ListNode(0)
        
        # 创建哑节点用于拼接结果
        dummy = ListNode(0)
        cur = dummy
        # 逐位拆分总和,构建逆序链表
        while sum_num > 0:
            cur.next = ListNode(sum_num % 10)  # 取个位作为当前节点值
            sum_num = sum_num // 10            # 去掉个位,剩余高位继续拆分
            cur = cur.next                     # 指针后移
        
        # 返回结果链表头节点
        return dummy.next

# ====================== 工具函数:测试专用 ======================
def create_linked_list(nums):
    """根据数字列表快速创建链表"""
    dummy = ListNode(0)
    cur = dummy
    for num in nums:
        cur.next = ListNode(num)
        cur = cur.next
    return dummy.next

def print_linked_list(head):
    """格式化打印链表,输出样式:7→0→8"""
    res = []
    cur = head
    while cur:
        res.append(str(cur.val))
        cur = cur.next
    print("→".join(res))

def custom_input():
    """自定义用户输入,手动输入两个链表"""
    print("\n===== 自定义输入测试 =====")
    print("提示:输入逆序数字,例如342输入 2 4 3,空格分隔,回车结束")
    nums1 = list(map(int, input("请输入第一个链表数字:").split()))
    nums2 = list(map(int, input("请输入第二个链表数字:").split()))
    return create_linked_list(nums1), create_linked_list(nums2)

# ====================== 主函数:全用例测试 ======================
if __name__ == "__main__":
    sol = Solution()
    
    # 测试用例1:官方示例1
    print("【测试用例1 官方示例】")
    l1 = create_linked_list([2,4,3])
    l2 = create_linked_list([5,6,4])
    print("输入链表1:", end="")
    print_linked_list(l1)
    print("输入链表2:", end="")
    print_linked_list(l2)
    print("运算结果:", end="")
    print_linked_list(sol.addTwoNumbers(l1, l2))

    # 测试用例2:官方示例2
    print("\n【测试用例2 官方示例】")
    l1 = create_linked_list([0])
    l2 = create_linked_list([0])
    print("输入链表1:", end="")
    print_linked_list(l1)
    print("输入链表2:", end="")
    print_linked_list(l2)
    print("运算结果:", end="")
    print_linked_list(sol.addTwoNumbers(l1, l2))

    # 测试用例3:官方示例3
    print("\n【测试用例3 官方示例】")
    l1 = create_linked_list([9,9,9,9,9,9,9])
    l2 = create_linked_list([9,9,9,9])
    print("输入链表1:", end="")
    print_linked_list(l1)
    print("输入链表2:", end="")
    print_linked_list(l2)
    print("运算结果:", end="")
    print_linked_list(sol.addTwoNumbers(l1, l2))

    # 自定义输入测试
    l1_custom, l2_custom = custom_input()
    print("自定义运算结果:", end="")
    print_linked_list(sol.addTwoNumbers(l1_custom, l2_custom))

2. 最优模拟进位法(满分AC版,逐行超详细注释)

python 复制代码
# 定义链表节点类(LeetCode官方标准模板)
class ListNode:
    # 构造函数:初始化节点值和后继节点
    def __init__(self, val=0, next=None):
        self.val = val      # 节点存储的单个数字
        self.next = next    # 指向后续节点的指针

# 导入类型注解,适配LeetCode编译规范
from typing import Optional

class Solution:
    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
        """
        最优解法:逐位模拟竖式加法
        :param l1: 第一个逆序数字链表
        :param l2: 第二个逆序数字链表
        :return: 相加结果的逆序链表
        """
        # 1. 初始化哑节点:虚拟头节点,统一拼接逻辑,无需处理首节点特殊情况
        dummy_node = ListNode(0)
        # 2. 遍历指针:专门用于构建、移动结果链表
        current = dummy_node
        # 3. 进位变量:存储每一位相加的进位,初始无进位为0
        carry = 0

        # 4. 核心循环:满足任意条件则继续遍历
        # 条件1:l1未遍历完  条件2:l2未遍历完  条件3:存在剩余进位
        while l1 is not None or l2 is not None or carry != 0:
            # 空节点补0:如果当前链表遍历完毕,当前位数值取0
            val1 = l1.val if l1 else 0
            val2 = l2.val if l2 else 0

            # 5. 计算当前位总和:两个当前位数值 + 上一轮进位
            total = val1 + val2 + carry

            # 6. 更新进位:总和十位为新进位(0或1)
            carry = total // 10

            # 7. 计算当前位最终结果:总和个位为当前节点值
            cur_val = total % 10

            # 8. 新建结果节点,拼接至结果链表尾部
            current.next = ListNode(cur_val)

            # 9. 结果指针后移,等待拼接下一个节点
            current = current.next

            # 10. 原链表指针后移,遍历下一位,空则保持空
            if l1:
                l1 = l1.next
            if l2:
                l2 = l2.next

        # 11. 返回哑节点的下一个节点(结果链表真正的头节点)
        return dummy_node.next

# ====================== 通用工具函数 ======================
def create_linked_list(nums):
    """数字列表转逆序链表"""
    dummy = ListNode(0)
    cur = dummy
    for num in nums:
        cur.next = ListNode(num)
        cur = cur.next
    return dummy.next

def print_linked_list(head):
    """格式化打印链表"""
    res = []
    cur = head
    while cur:
        res.append(str(cur.val))
        cur = cur.next
    print("→".join(res))

def custom_input():
    """自定义用户手动输入"""
    print("\n===== 自定义输入测试 =====")
    nums1 = list(map(int, input("请输入第一个链表逆序数字:").split()))
    nums2 = list(map(int, input("请输入第二个链表逆序数字:").split()))
    return create_linked_list(nums1), create_linked_list(nums2)

# ====================== 主函数:全覆盖测试 ======================
if __name__ == "__main__":
    sol = Solution()

    # 官方测试用例1
    print("【官方测试用例1】")
    l1, l2 = create_linked_list([2,4,3]), create_linked_list([5,6,4])
    print("输入1:", end=""); print_linked_list(l1)
    print("输入2:", end=""); print_linked_list(l2)
    print("结果:", end=""); print_linked_list(sol.addTwoNumbers(l1, l2))

    # 官方测试用例2
    print("\n【官方测试用例2】")
    l1, l2 = create_linked_list([0]), create_linked_list([0])
    print("输入1:", end=""); print_linked_list(l1)
    print("输入2:", end=""); print_linked_list(l2)
    print("结果:", end=""); print_linked_list(sol.addTwoNumbers(l1, l2))

    # 官方测试用例3
    print("\n【官方测试用例3】")
    l1, l2 = create_linked_list([9,9,9,9,9,9,9]), create_linked_list([9,9,9,9])
    print("输入1:", end=""); print_linked_list(l1)
    print("输入2:", end=""); print_linked_list(l2)
    print("结果:", end=""); print_linked_list(sol.addTwoNumbers(l1, l2))

    # 自定义输入测试
    l1_c, l2_c = custom_input()
    print("自定义运算结果:", end=""); print_linked_list(sol.addTwoNumbers(l1_c, l2_c))

3. 最优解法详细运行流程(以示例1为例)

测试用例:l1=[2,4,3]、l2=[5,6,4],目标:342+465=807,输出[7,0,8]

  1. 初始化:dummy=0,current=dummy,carry=0

  2. 第一轮循环(个位相加):val1=2、val2=5,total=7,carry=0,当前值7,结果链表:0→7,指针后移

  3. 第二轮循环(十位相加):val1=4、val2=6,total=10,carry=1,当前值0,结果链表:0→7→0,指针后移

  4. 第三轮循环(百位相加):val1=3、val2=4,total=3+4+1=8,carry=0,当前值8,结果链表:0→7→0→8,指针后移

  5. 循环终止:两个链表遍历完成,无剩余进位

  6. 返回结果:dummy.next → 7→0→8,运算正确

五、C++ 完整代码实现(双解法+逐行注释+内存释放+全测试)

1. 暴力转换数字法(入门版)

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;

// LeetCode官方标准链表节点结构体
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 {
public:
    // 暴力解法:链表转数字相加
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        long long num1 = 0, num2 = 0;
        long long base = 1;

        // 遍历l1,转换为完整数字
        while(l1 != nullptr){
            num1 += l1->val * base;
            base *= 10;
            l1 = l1->next;
        }

        // 遍历l2,转换为完整数字
        base = 1;
        while(l2 != nullptr){
            num2 += l2->val * base;
            base *= 10;
            l2 = l2->next;
        }

        // 数字相加
        long long sum = num1 + num2;

        // 处理和为0的特殊情况
        if(sum == 0) return new ListNode(0);

        // 构建结果链表
        ListNode* dummy = new ListNode(0);
        ListNode* cur = dummy;
        while(sum > 0){
            cur->next = new ListNode(sum % 10);
            sum = sum / 10;
            cur = cur->next;
        }
        return dummy->next;
    }
};

// ====================== 工具函数 ======================
// 数组创建链表
ListNode* createList(vector<int> nums){
    ListNode* dummy = new ListNode(0);
    ListNode* cur = dummy;
    for(int num : nums){
        cur->next = new ListNode(num);
        cur = cur->next;
    }
    return dummy->next;
}

// 打印链表
void printList(ListNode* head){
    ListNode* cur = head;
    while(cur){
        cout << cur->val;
        if(cur->next) cout << "→";
        cur = cur->next;
    }
    cout << endl;
}

// 释放链表内存(C++必备,防止内存泄漏)
void freeList(ListNode* head){
    ListNode* temp;
    while(head){
        temp = head;
        head = head->next;
        delete temp;
    }
}

// 自定义输入链表
ListNode* inputList(){
    vector<int> nums;
    int num;
    cout << "请输入逆序链表数字,输入-1结束:";
    while(cin >> num && num != -1){
        nums.push_back(num);
    }
    return createList(nums);
}

// ====================== 主函数测试 ======================
int main(){
    Solution sol;

    // 测试用例1
    cout << "【官方测试用例1】" << endl;
    ListNode* l1 = createList({2,4,3});
    ListNode* l2 = createList({5,6,4});
    cout << "输入1:"; printList(l1);
    cout << "输入2:"; printList(l2);
    ListNode* res1 = sol.addTwoNumbers(l1, l2);
    cout << "结果:"; printList(res1);
    freeList(l1); freeList(l2); freeList(res1);

    // 测试用例2
    cout << "\n【官方测试用例2】" << endl;
    l1 = createList({0});
    l2 = createList({0});
    cout << "输入1:"; printList(l1);
    cout << "输入2:"; printList(l2);
    ListNode* res2 = sol.addTwoNumbers(l1, l2);
    cout << "结果:"; printList(res2);
    freeList(l1); freeList(l2); freeList(res2);

    // 测试用例3
    cout << "\n【官方测试用例3】" << endl;
    l1 = createList({9,9,9,9,9,9,9});
    l2 = createList({9,9,9,9});
    cout << "输入1:"; printList(l1);
    cout << "输入2:"; printList(l2);
    ListNode* res3 = sol.addTwoNumbers(l1, l2);
    cout << "结果:"; printList(res3);
    freeList(l1); freeList(l2); freeList(res3);

    // 自定义输入
    cout << "\n【自定义输入测试】" << endl;
    ListNode* l1_c = inputList();
    ListNode* l2_c = inputList();
    ListNode* res_c = sol.addTwoNumbers(l1_c, l2_c);
    cout << "自定义结果:"; printList(res_c);
    freeList(l1_c); freeList(l2_c); freeList(res_c);

    return 0;
}

2. 最优模拟进位法(满分AC版,逐行超详细注释)

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;

// LeetCode 标准链表节点结构体
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 {
public:
    // 最优解法:逐位模拟竖式加法,无溢出、全覆盖边界
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        // 1. 创建虚拟哑节点,规避头节点特殊处理
        ListNode* dummy = new ListNode(0);
        // 2. 结果链表遍历指针,用于拼接新节点
        ListNode* cur = dummy;
        // 3. 进位变量,初始无进位
        int carry = 0;

        // 4. 核心循环:任意链表未遍历完 或 存在进位,持续执行
        while(l1 != nullptr || l2 != nullptr || carry != 0){
            // 空节点补0,保证长短链表统一计算逻辑
            int val1 = l1 ? l1->val : 0;
            int val2 = l2 ? l2->val : 0;

            // 5. 计算当前位总和(含上一轮进位)
            int total = val1 + val2 + carry;

            // 6. 更新进位值(取十位)
            carry = total / 10;

            // 7. 计算当前位结果(取个位)
            int curVal = total % 10;

            // 8. 新建节点,拼接至结果链表
            cur->next = new ListNode(curVal);

            // 9. 结果指针后移
            cur = cur->next;

            // 10. 原链表指针后移,遍历下一位
            if(l1 != nullptr) l1 = l1->next;
            if(l2 != nullptr) l2 = l2->next;
        }

        // 11. 返回结果链表头节点(跳过虚拟哑节点)
        return dummy->next;
    }
};

// ====================== 工具函数 ======================
// 数组快速创建链表
ListNode* createList(vector<int> nums){
    ListNode* dummy = new ListNode(0);
    ListNode* cur = dummy;
    for(int num : nums){
        cur->next = new ListNode(num);
        cur = cur->next;
    }
    return dummy->next;
}

// 格式化打印链表
void printList(ListNode* head){
    ListNode* cur = head;
    while(cur){
        cout << cur->val;
        if(cur->next) cout << "→";
        cur = cur->next;
    }
    cout << endl;
}

// 手动输入创建链表
ListNode* inputList(){
    vector<int> nums;
    int num;
    cout << "输入链表数字(空格分隔,-1结束):";
    while(cin >> num && num != -1){
        nums.push_back(num);
    }
    return createList(nums);
}

// 释放链表所有内存,杜绝内存泄漏
void freeList(ListNode* head){
    ListNode* temp;
    while(head != nullptr){
        temp = head;
        head = head->next;
        delete temp;
    }
}

// ====================== 主函数:全量测试 ======================
int main(){
    Solution sol;

    // 官方测试用例1
    cout << "===== 官方测试用例1 =====" << endl;
    ListNode* l1 = createList({2,4,3});
    ListNode* l2 = createList({5,6,4});
    cout << "输入链表1:"; printList(l1);
    cout << "输入链表2:"; printList(l2);
    ListNode* res1 = sol.addTwoNumbers(l1, l2);
    cout << "运算结果:"; printList(res1);
    freeList(l1); freeList(l2); freeList(res1);

    // 官方测试用例2
    cout << "\n===== 官方测试用例2 =====" << endl;
    l1 = createList({0});
    l2 = createList({0});
    cout << "输入链表1:"; printList(l1);
    cout << "输入链表2:"; printList(l2);
    ListNode* res2 = sol.addTwoNumbers(l1, l2);
    cout << "运算结果:"; printList(res2);
    freeList(l1); freeList(l2); freeList(res2);

    // 官方测试用例3
    cout << "\n===== 官方测试用例3 =====" << endl;
    l1 = createList({9,9,9,9,9,9,9});
    l2 = createList({9,9,9,9});
    cout << "输入链表1:"; printList(l1);
    cout << "输入链表2:"; printList(l2);
    ListNode* res3 = sol.addTwoNumbers(l1, l2);
    cout << "运算结果:"; printList(res3);
    freeList(l1); freeList(l2); freeList(res3);

    // 自定义输入测试
    cout << "\n===== 自定义输入测试 =====" << endl;
    ListNode* l1_c = inputList();
    ListNode* l2_c = inputList();
    ListNode* res_c = sol.addTwoNumbers(l1_c, l2_c);
    cout << "自定义运算结果:"; printList(res_c);
    freeList(l1_c); freeList(l2_c); freeList(res_c);

    return 0;
}

六、两种解法全面对比

对比维度 暴力数字转换法 逐位模拟进位法(最优)
逻辑难度 极低,零基础秒懂 中等,需理解进位循环
数据范围 有限,超长链表数字溢出失效 无限,兼容题目所有用例
算法效率 两轮遍历,效率较低 单次遍历,时间最优
面试适用性 仅入门学习,面试不推荐 面试标准答案,满分AC

七、算法复杂度分析

1. 时间复杂度

  • 暴力法:O(max(n,m)),两次遍历链表,n、m为两个链表长度

  • 最优法:O(max(n,m)),仅遍历最长链表一次,无冗余操作

2. 空间复杂度

两种解法均为 O(max(n,m)),结果链表长度最大为 最长链表长度+1(最终进位),无额外空间消耗。

八、全覆盖边界条件验证

  • 边界1:两个单节点0链表相加 → 结果0

  • 边界2:链表长度不一致(如[1,2]和[3,4,5])

  • 边界3:全程连续进位(999+999)

  • 边界4:最后一位产生进位(9999+1)

九、总结

  1. 本题核心:模拟小学竖式加法,逆序链表天然适配低位优先计算

  2. 核心技巧:哑节点简化链表拼接逻辑,是链表算法通用神器

  3. 核心关键点:循环必须包含进位判断,否则会丢失最后一位进位

  4. 避坑要点:禁止暴力转数字,超长链表必然溢出,面试只写模拟进位法

  5. 空值处理:长短链表相加,空节点统一补0,保证逻辑统一

相关推荐
菜菜的顾清寒8 小时前
力扣HOT100(25)环形链表
算法·leetcode·链表
学不懂飞行器8 小时前
【2024电赛H题硬核解析】自动行驶小车满分对策:多路灰度循迹与陀螺仪“交替盲走”融合算法(附源码)
stm32·单片机·嵌入式硬件·算法·电赛
机器学习之心8 小时前
大跨度拱桥施工智能优化:基于改进RBF神经网络与多目标算法的工程实践
人工智能·神经网络·算法·大跨度拱桥施工智能优化
Deep-w8 小时前
【MATLAB】基于 MATLAB/Simulink 的无刷直流电机(BLDC)转速控制模糊 PID 算法
开发语言·算法·matlab
皮卡祺q8 小时前
【算法-0】背包问题(三维+二维)
java·javascript·算法
葫三生8 小时前
《论三生原理》对《周易》《道德经》的一次根本性重写?
人工智能·算法·计算机视觉·区块链·量子计算
一路往蓝-Anbo8 小时前
第五章:如何对 HAL 库本身进行单元测试?
网络·数据结构·stm32·单片机·嵌入式硬件·单元测试·tdd
心中有国也有家8 小时前
ascend-boost-comm:一次写完,到处复用——算子公共平台的 M×N 哲学
人工智能·经验分享·笔记·分布式·算法
AI科技星8 小时前
空间圆柱螺旋运动第一性原理终极推导·证明·核验·全量纲闭环
开发语言·人工智能·算法·计算机视觉·量子计算