在 C++ 中解决“两数之和”问题,主要有暴力枚举和哈希表两种主流方法。下面我将详细解释这两种方法的实现,并提供代码示例。以下是两种解法的对比表格,帮助你快速了解它们的特点:| 方法 | 时间复杂度 | 空间复杂度 | 核心思路 | 适用场景 || :— | :— | :— | :— | :— || 暴力枚举法 | O(n²) | O(1) | 双重循环遍历所有可能的组合 | 数据量小,对空间复杂度要求高 || 哈希表法 | O(n) | O(n) | 用哈希表存储遍历过的值及其索引,实现快速查找 | 数据量大,追求时间复杂度 |💡 方法一:暴力枚举法这是最直观的解法。我们使用两层循环来检查数组中每一对不同的元素,看它们的和是否等于目标值。代码实现#include <vector>using namespace std;class Solution {public: vector<int> twoSum(vector<int>& nums, int target) { int n = nums.size(); // 外层循环,从第一个元素遍历到倒数第二个元素 for (int i = 0; i < n – 1; ++i) { // 内层循环,从 i 之后的一个元素开始遍历 for (int j = i + 1; j < n; ++j) { // 检查两数之和是否等于 target if (nums[i] + nums[j] == target) { return {i, j}; // 找到后立即返回下标 } } } return {}; // 根据题意,必然存在解,此返回用于保证函数完整性 }};算法分析- 时间复杂度:O(n²)。需要遍历 “n(n-1)/2” 对元素。- 空间复杂度:O(1)。只使用了常数级别的额外空间。🚀 方法二:哈希表法(推荐)为了优化查找速度,我们可以使用哈希表(在 C++ 中通常用 “std::unordered_map”)。核心思想是空间换时间:在遍历数组时,将每个元素的值和其索引记录在哈希表中。对于每个元素 “nums[i]”,我们计算其补数 “complement = target – nums[i]”,然后检查这个补数是否已经存在于哈希表中。如果存在,说明我们找到了答案。代码实现
#include <vector>
#include <unordered_map>
using namespace std;
class Solution
{
public:
vector<int> twoSum(vector<int>& nums, int target)
{
unordered_map<int, int> numMap; // 键:数组元素的值,值:对应的索引
for (int i = 0; i < nums.size(); ++i) {
int complement = target – nums[i]; // 检查补数是否已经在哈希表中
if (numMap.find(complement) != numMap.end()) {
// 找到目标,返回补数的索引和当前索引 return {numMap[complement], i};
}
// 将当前元素的值和索引存入哈希表,供后续查找 numMap[nums[i]] = i;
}
return {}; // 保证函数有返回值
}};
算法分析- 时间复杂度:O(n)。只需遍历数组一次,哈希表的每次查找和插入操作平均时间复杂度为 O(1)。- 空间复杂度:O(n)。哈希表最多需要存储 n 个元素。
💎 总结与选择- 暴力枚举法的思路简单,代码易于编写,在输入规模较小时是可以接受的。- 哈希表法是更高效的通用解法,通过牺牲一部分空间来大幅降低时间复杂度,尤其适用于处理大规模数据。在实际面试或解决问题时,如果对时间复杂度有要求,推荐优先实现哈希表解法。希望这些详细的解释和代码示例能帮助你彻底理解“两数之和”问题。如果还有任何疑问,欢迎继续提问!
评论(0)
暂无评论