【LeetCode热题100 第一题详解】两数之和(C语言)新手细节解析

128 阅读4分钟

LeetCode 第一题:两数之和(C 语言详解)

🌟 前言:为什么第一题也值得深挖?

LeetCode 的第 1 题「两数之和」看似简单,却是很多初学者在 C 语言环境下踩坑的“第一道坎”。尤其是当你看到 mallocint**returnSize 这些关键词时,可能会一头雾水:

  • 为什么必须用 malloc
  • 为什么 ret 是 int* 类型?
  • 为什么要写 *returnSize = 2?不写会怎样?

本文来搞懂这道题背后的内存机制LeetCode 判题规则,让你不仅会做题的同时理解为什么这样写。

题目描述
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。
你可以按任意顺序返回答案。


📌 本题默认函数参数说明

LeetCode 提供的 C 语言默认代码模板如下:

int* twoSum(int* nums, int numsSize, int target, int* returnSize)
  • *nums:用于求和的整数数组
  • numsSize:传入数组的长度
  • target:目标值
  • *returnSize:用于返回结果数组的长度(若有解则为 2,无解则为 0

✅ 参考代码实现

int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
    for (int i = 0; i < numsSize; ++i) {
        // 固定 i,遍历 j,找到两个数相加等于 target
        for (int j = i + 1; j < numsSize; ++j) {
            if (nums[i] + nums[j] == target) {
                // 找到两个相加等于 target 的数,分配内存,存储下标,返回
                // sizeof(int):单个整数的字节大小  
                // * 2:分配 2 个整数的空间
                int* ret = malloc(sizeof(int) * 2);
                ret[0] = i;
                ret[1] = j;
                // 成功找到两个数之和为 target
                *returnSize = 2;
                // 返回找到的相应整数的下标
                return ret;
            }
        }
    }
    // 遍历完数组,没有找到两个数之和为 target
    *returnSize = 0;
    // 没有找到,返回 NULL
    return NULL;
}

❓ 新手常见疑问解析

🔹 为什么必须用 malloc

栈内存 vs 堆内存
  • 如果你写成:

    int ret[2] = {i, j}; // 栈内存
    

    → 函数返回后,ret 所在的栈帧被销毁,内存自动释放。
    → LeetCode 读取到的是野指针/随机值,程序可能崩溃或结果错误。

  • malloc堆内存分配空间:

    int* ret = malloc(sizeof(int) * 2);
    

    → 堆内存生命周期独立于函数调用,LeetCode 能安全读取返回的地址内容。

结论:必须用 malloc 保证返回的指针在函数结束后依然有效。


🔹 为什么 ret 是 int* 类型?

  • malloc 返回的是 void*(通用指针),在 C 语言中可隐式转换为其他指针类型。
  • 但为了代码清晰、类型安全,我们将其视为 int*,以便后续通过 ret[0]ret[1] 存储整数下标。

💡 实际上在 C语言中不需要显式强制转换 (int*)malloc(...),但明确类型有助于理解。


🔹 *returnSize 有什么用?少了它会怎样?

作用

告诉调用者(LeetCode 判题系统)返回数组的长度

为什么需要它?
  • C 语言限制:函数无法直接返回数组长度(C 语言不支持返回数组)。
  • 标准设计:通过 returnSize 指针间接传递长度,是 LeetCode 题目框架的强制要求。LeetCode 通过 returnSize 这个输出参数来“知道”你返回了几个元素。
如果忘记设置?
  • LeetCode 会报错,例如:

    returnSize not set
    
  • 即使你正确返回了下标,系统也无法知道结果数组长度,判题失败

总结
*returnSize = 2*returnSize = 0 是 LeetCode 判题系统的“通信协议”。
这是代码中唯一不可省略的关键行——逻辑可以优化,但这一行必须保留!


🧠 小结

虽然「两数之和」是 LeetCode 第一题,逻辑简单,但在 C 语言中涉及多个底层细节:

  • 堆内存分配(malloc)确保返回数据有效
  • 指针类型与内存管理的理解
  • LeetCode 特有的输出参数 returnSize 的作用

掌握这些细节,不仅能 AC 本题,更能为后续更复杂的 C 语言算法题打下坚实基础!

💬 提示:在实际工程中,调用方需负责 free() 释放 malloc 分配的内存,但在 LeetCode 环境中无需手动释放。