LeetCode 算法:两数相加 c++

原题链接🔗两数相加
难度:中等⭐️

题目

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

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

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

示例 1
在这里插入图片描述

输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.
示例 2
输入:l1 = [0], l2 = [0]
输出:[0]

示例 3

输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]

提示

  • 每个链表中的节点数在范围 [1, 100] 内
  • 0 <= Node.val <= 9
  • 题目数据保证列表表示的数字不含前导零

题解

迭代法

  1. 题解

LeetCode 上的 "两数相加"问题要求你设计一个算法,将两个非负整数的链表表示相加,并返回一个表示和的链表。这里的解题思路主要包括以下几个步骤:

  1. 理解问题:首先,要清楚题目要求的是两个非负整数的链表表示,即每个链表节点存储的是一个数字的某一位,链表的头节点存储的是最低位。

  2. 初始化:创建一个哑节点(dummy node),这个节点不存储有效数字,但是可以简化链表操作,因为链表的头节点可能在相加后被删除。

  3. 迭代处理:遍历两个链表,直到两个链表都到达末尾。在每一步中,取出当前两个节点的值,加上之前的进位(carry),计算出当前位的和以及新的进位。

  4. 处理进位:将当前位的和的个位数存储到新链表的下一个节点中,进位则保留下来,用于下一次迭代。

  5. 链表连接:在每次迭代中,将新计算出的节点连接到结果链表上。

  6. 处理剩余的链表:如果其中一个链表先遍历完,但另一个链表还有剩余,继续迭代直到另一个链表也遍历完。

  7. 处理最后的进位:如果最后一个节点相加后还有进位,需要在结果链表的末尾添加一个新的节点来存储这个进位。

  8. 返回结果:返回哑节点的下一个节点,即实际的结果链表的头节点。

  9. 代码实现:使用上述思路,用 C++ 或其他语言编写代码实现算法。

  10. 测试:编写测试用例,验证算法的正确性,包括但不限于两个链表长度相等、不等、含有前导零等情况。

通过这种方法,你可以有效地解决 “两数相加” 的问题,同时确保算法的鲁棒性和正确性。

  1. 复杂度:时间复杂度O(max(m,n)),要遍历两个链表的全部位置,而处理每个位置只需要 O(1) 的时间;空间复杂度O(1)。
  2. 代码过程:如demo所示。
  3. c++ demo
#include <iostream>

// 定义链表节点结构体
struct ListNode {
    int val;
    ListNode* next;
    ListNode(int x) : val(x), next(nullptr) {}
};

// 函数用于将两个链表相加
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
    ListNode* dummyHead = new ListNode(0); // 创建一个哑节点,方便操作
    ListNode* current = dummyHead; // 当前节点
    int carry = 0; // 进位

    while (l1 != nullptr || l2 != nullptr) {
        int x = (l1 != nullptr) ? l1->val : 0;
        int y = (l2 != nullptr) ? l2->val : 0;
        int sum = carry + x + y;
        carry = sum / 10; // 更新进位值
        current->next = new ListNode(sum % 10); // 创建新节点,存储当前位的值
        current = current->next; // 移动指针

        if (l1 != nullptr) l1 = l1->next; // 移动链表指针
        if (l2 != nullptr) l2 = l2->next;
    }

    if (carry > 0) {
        current->next = new ListNode(carry); // 如果还有进位,添加新节点
    }

    ListNode* result = dummyHead->next; // 返回结果链表,跳过哑节点
    delete dummyHead; // 删除哑节点
    return result;
}

// 辅助函数,用于打印链表
void printList(ListNode* node) {
    while (node != nullptr) {
        std::cout << node->val << " -> ";
        node = node->next;
    }
    std::cout << "null" << std::endl;
}

// 测试代码
int main() {
    // 创建两个链表
    ListNode* l1 = new ListNode(2);
    l1->next = new ListNode(4);
    l1->next->next = new ListNode(3);

    ListNode* l2 = new ListNode(5);
    l2->next = new ListNode(6);
    l2->next->next = new ListNode(4);

    std::cout << "List 1: ";
    printList(l1);
    std::cout << "List 2: ";
    printList(l2);

    // 相加链表
    ListNode* result = addTwoNumbers(l1, l2);

    std::cout << "Result: ";
    printList(result);

    // 释放链表内存
    delete l1;
    delete l2;
    delete result;

    return 0;
}
  • 16
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
根据提供的引用内容,Leetcode 2 "两数相加"是一个涉及链表的问题。该问题给定了两个非负整数,每个整数的每一位都是按照逆序的方式存储在链表中。我们需要将这两个链表相加,并返回一个新的链表作为结果。 具体解题思路可以使用迭代法或递归法来解决。迭代法的伪代码如下所示: ``` 初始化一个哑节点 dummy 和一个进位 carry,同时把两个链表的头节点分别赋值给 p 和 q 遍历链表,直到 p 和 q 都为 None 计算当前的和 sum 为 p.val + q.val + carry 计算当前的进位 carry 为 sum // 10 创建一个新节点 node,节点的值为 sum % 10 把新节点连接到结果链表的尾部 更新 p 和 q 分别为 p.next 和 q.next 如果最后还有进位 carry,则创建一个新节点 node,节点的值为 carry,并连接到结果链表的尾部 返回结果链表的头节点 dummy.next ``` 递归法的伪代码如下所示: ``` 定义一个辅助函数 addTwoNumbersHelper,输入为两个链表的头节点 p 和 q,以及进位 carry 如果 p 和 q 都为 None 且 进位 carry 为 0,则返回 None 计算当前的和 sum 为 p.val + q.val + carry 计算当前的进位 carry 为 sum // 10 创建一个新节点 node,节点的值为 sum % 10 设置新节点的下一个节点为递归调用 addTwoNumbersHelper(p.next, q.next, carry) 返回新节点 返回 addTwoNumbersHelper(p, q, 0) 的结果 以上是解决 Leetcode 2 "两数相加"问题的两种方法。如果你还有其他相关问题,请

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Codec Conductor

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值