Leetcode2. 两数相加(C++思路与代码)

博客介绍了将两个非空链表表示的非负整数相加的算法。链表每位数字逆序存储,每个节点存一位数字。给出输入输出示例,如l1 = [2,4,3],l2 = [5,6,4],输出[7,0,8]。思路是创建新链表,用工作指针处理,考虑进位并保存每位和。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

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

思路:
创建一个新的链表,cur为工作指针。考虑进位,每位上的和用sum保存,注意一些细节问题。

/**
 * 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* l3=new ListNode(0);
        ListNode* cur=l3;
        int sum=0; //每个位的加和结果
        bool count=false;
        while(l1!=nullptr||l2!=nullptr){  //终止条件当一个链表为空退出
            sum=0; //初始化为0
            if(l1!=nullptr){
                sum+=l1->val;
                l1=l1->next;
            }
            if(l2!=nullptr){
                sum+=l2->val;
                l2=l2->next;
            }
            if(count){
                sum++;
            }
            cur->next=new ListNode(sum%10);
            cur=cur->next;
            count=sum>=10?true:false;
        }
        if(count){
            cur->next=new ListNode(1);
        }
        auto res=l3->next;
        delete l3;
        return res;
    }
};
### LeetCode 'Two Sum' 问题的 C++ 解决方案 #### 暴力解法 (Brute Force Approach) 暴力方法通过双重循环遍历数组中的每一对元素,检查它们之和是否等于目标值 `target`。这种方法的时间复杂度为 \(O(n^2)\),空间复杂度为 \(O(1)\)[^1]。 ```cpp class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { for(int i = 0; i < nums.size(); i++) { for(int j = i + 1; j < nums.size(); j++) { if(nums[j] == target - nums[i]) { return {i, j}; } } } return {-1, -1}; } }; ``` --- #### 哈希表优化解法 (Hash Table Optimization) 为了提高效率,可以使用哈希表存储已经访问过的数值及其索引位置。这样可以在一次遍历中完成查找操作,时间复杂度降低到 \(O(n)\),而空间复杂度增加至 \(O(n)\)[^3]。 ```cpp #include <unordered_map> using namespace std; class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { unordered_map<int, int> hashTable; for(int i = 0; i < nums.size(); ++i){ int complement = target - nums[i]; if(hashTable.find(complement) != hashTable.end()){ return {hashTable[complement], i}; } hashTable[nums[i]] = i; } return {}; } }; ``` 此代码利用了一个无序映射 (`unordered_map`) 来记录已扫描的数字以及其对应的下标。每次迭代都会计算当前数字所需的补数,并检查该补数是否已经在哈希表中存在。 --- #### 排序数组上的双指针技术 (Two Pointers Technique on Sorted Array) 如果输入数组已经是有序的,则可以通过双指针的方法进一步减少内存消耗并提升性能。初始时设置左指针指向第一个元素,右指针指向最后一个元素;随后逐步调整两个指针的位置直到找到满足条件的一对数字或者确认不存在这样的组合[^2]。 ```cpp class Solution { public: vector<int> twoSum(vector<int>& numbers, int target) { int l = 0, r = numbers.size() - 1; while(l < r){ if(numbers[l] + numbers[r] > target) r--; else if(numbers[l] + numbers[r] < target) l++; else return {l+1, r+1}; } return {}; } }; ``` 注意这里返回的结果是从 1 开始计数的索引值而不是默认从零开始的标准 C++ 数组索引。 --- #### 总结 上述三种算法分别代表了不同的思路和技术应用方向: - **暴力枚举**适合理解基础逻辑但不适用于大规模数据集; - **哈希表辅助**提供了更高效的解决方案,在实际开发场景中最常用; - **双指针策略**则针对特定情况(即预排序列表)进行了特殊优化处理。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值