Leetcode2 —— 链表两数相加

目录

题目:

题解思路:

代码:

题目:

题解思路:

  • 输入:两个逆序存储数字的链表(头节点 = 个位,尾节点 = 最高位),比如 l1=[2,4,3] 代表 342,l2=[5,6,4] 代表 465。
  • 输出:逆序存储两数之和的链表(342+465=807 → 7,0,8)。
  • 需求:模拟手工加法(从个位加起,处理进位),用链表存储结果。

用两个链表指针分别遍历两个链表,取出节点的值,计算结果链表当前的值。

注意需要设置一个进位值并且在最后需要判断如果最后一位有进位需添加上进位值。

结果链表需要两个指针:

  • head:结果链表的头指针,始终指向链表第一个节点(最终要返回它,作为结果);
  • tail:结果链表的尾指针,始终指向链表最后一个节点(用来快速新增节点);

代码:

C++无注释版代码:

复制代码
/**
 * 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 {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode* head = nullptr;
        ListNode* tail = nullptr;
        int carry = 0;
        while(l1 || l2){
            int n1 = l1 ? l1->val : 0 ;
            int n2 = l2 ? l2->val : 0 ;
            int sum = n1+n2+carry;
            if(!head){
                head = tail = new ListNode(sum%10);
            }
            else{
                tail->next = new ListNode(sum%10);
                tail = tail->next;
            }
            carry = sum/10;
        if(l1){
            l1 = l1->next;
        }
        if(l2){
            l2 = l2->next;
        }
        }
        
        if(carry){
            tail->next = new ListNode(carry);
        }
        return head;
    }
};

C++注释版代码:

复制代码
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        // 1. 初始化指针和进位
        ListNode* head = nullptr, 
        ListNode* tail = nullptr; // head=结果头,tail=结果尾,初始都为空
        int carry = 0; // 进位,初始为0(加法从个位开始,初始无进位)

        // 2. 核心循环:只要l1或l2还有节点,就继续相加
        while (l1 || l2) { 
            // 2.1 取当前位的值:节点为空则补0(处理链表长度不一致)
            int n1 = l1 ? l1->val : 0; // l1有节点取val,否则取0
            int n2 = l2 ? l2->val : 0; // l2有节点取val,否则取0

            // 2.2 计算当前位总和 = l1位 + l2位 + 上一位的进位
            int sum = n1 + n2 + carry;

            // 2.3 构建结果节点,挂到tail后面
            if (!head) { // 第一次循环:结果链表为空(head是null)
                head = tail = new ListNode(sum % 10); // 新建第一个节点,head和tail都指向它
                // sum%10:取个位(比如sum=15,个位是5,进位是1)
            } else { // 非第一次循环:结果链表已有节点
                tail->next = new ListNode(sum % 10); // 新建节点挂到tail后面
                tail = tail->next; // tail后移,始终指向结果链表最后一个节点
            }

            // 2.4 更新进位:sum//10(比如sum=15,进位=1;sum=7,进位=0)
            carry = sum / 10;

            // 2.5 移动l1/l2指针:如果节点不为空,就指向下一个
            if (l1) {
                l1 = l1->next;
            }
            if (l2) {
                l2 = l2->next;
            }
        }

        // 3. 收尾:循环结束后如果还有进位,新增节点存进位
        if (carry > 0) { 
            tail->next = new ListNode(carry);
            // 比如l1=[9,9], l2=[9,9]:循环结束后carry=1,新增节点存1,结果为[8,9,1]
        }

        // 4. 返回结果链表的头节点
        return head;
    }
};

代码细节补充:

1、l1->val 是当前指针指向节点的数值,tail->next 是当前指针指向节点的下一个节点的指针。

2、int n1 = l1 ? l1->val : 0; 是 C++ 里的三元条件运算符(也叫三目运算符)

复制代码
条件表达式 ? 表达式1 : 表达式2;
  • 如果 l1 这个指针指向有效节点 (不是空),就取这个节点的 val 值;
  • 如果 l1nullptr(空指针,比如其中一个链表已经遍历完了),就用 0 来补齐。

等价于下面这种写法:

复制代码
int n1; // 先声明变量
if (l1 != nullptr) { // 等价于 if(l1),判断l1非空
    n1 = l1->val;    // 取节点值
} else {
    n1 = 0;          // 补0
}
相关推荐
Zenova EdgeOS12 分钟前
C++ 工业边缘 Qt 桌面应用实战:从 QWidget 到模型视图、网络与多线程
网络·c++·qt
老洋葱Mr_Onion26 分钟前
【C++】CSP-J复赛dp问题(含模板题)
开发语言·c++
青 春 记 忆7 小时前
LeetCode 21. 合并两个有序链表|Python 解法详解
python·算法·leetcode·链表
c238568 小时前
MySQL 基础用法(上):库表管理与数据增删改
c语言·数据库·c++·mysql
光源【时光寸寸又逢君】9 小时前
第三方平台预览我方级联监控点串流问题排查
c++·iot
键盘会跳舞10 小时前
C++:容器适配器 queue 的源码级拆解
开发语言·c++·queue
YuforiaCode10 小时前
第十六届蓝桥杯 2025 C/C++组 数列差分
c语言·c++·蓝桥杯
QAQo7T11 小时前
Python组蓝桥杯备赛超详细知识点总结笔记_排序算法篇
笔记·python·算法·蓝桥杯·排序算法
普通网友11 小时前
蓝桥杯 DP 优化:从 O (n²) 到 O (n) 的滚动数组实战
职场和发展·蓝桥杯
醉颜凉11 小时前
蓝桥杯2025年第十六届省赛真题-好串的数目
职场和发展·蓝桥杯