Leetcode_两数之和_0001
两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回答案。
示例 1: 输入:nums = [2,7,11,15], target = 9 输出:[0,1] 解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2: 输入:nums = [3,2,4], target = 6 输出:[1,2]
示例 3: 输入:nums = [3,3], target = 6 输出:[0,1]
解题方法
方法一:暴力法
- 描述:
- 使用两层循环遍历所有元素对,检查它们的和是否等于 target。
- 时间复杂度:O(n^2),其中 n 是数组的长度。
- 空间复杂度:O(1)。
方法二:哈希表法(推荐方法)
- 描述:
- 使用单个循环遍历数组。
- 对于每个元素,计算其补数(target - nums[i]),并检查该补数是否已存在于哈希表中。
- 如果存在,立即返回两个数的索引。
- 如果不存在,将当前元素及其索引添加到哈希表中。
- 时间复杂度:O(n),因为哈希表的平均查找和插入时间都是 O(1)。
- 空间复杂度:O(n),因为最坏情况下需要存储所有元素及其索引。
c++代码实现
头文件
暴力法
哈希表法
哈希表法详细说明:
- 哈希表初始化:std::unordered_map<int, int> index_map; 初始化一个空的哈希表,键是数组元素的值,值是对应的索引。
- 循环遍历数组:使用一个循环遍历数组中的每一个元素。
- 计算补数:对于每个元素,计算它需要的补数,以使得它和另一个元素的和等于 target。
- 检查补数:使用 index_map.find(complement) 检查这个补数是否已经存在于哈希表中。
- find() 方法会查找给定键(这里是 complement)是否存在于哈希表中。如果存在,返回一个指向相应元素的迭代器;如果不存在,返回一个指向 unordered_map::end 的迭代器。
- 返回结果:如果找到了补数,即 find() 方法的结果不是 end(),则返回两个元素的索引。这两个索引分别对应于之前存入哈希表的元素和当前元素。
main函数调用
补数的定义
补数是指,在给定一个目标值 target 和当前数 nums[i] 的情况下,另一个需要找到的数,使得这两个数的和等于 target。数学上可以表示为:
complement = target − nums[i]
为什么需要补数
在“两数之和”的问题中,我们的目标是找到两个数,它们相加的结果等于一个指定的 target 值。对于数组中的每一个元素 nums[i],我们都需要检查是否存在另一个元素 nums[j],使得:
nums[i] + nums[j] = target
将上面的等式重新组织,我们可以得到:
nums[j] = target − nums[i]
这里的 nums[j] 就是我们所说的补数。
计算补数的过程
- 假设我们有数组 nums = [2, 7, 11, 15] 和 target = 9。现在我们需要找出哪两个数字的和为 9。我们来逐个检查:
- 当 i = 0,nums[i] = 2:
- 计算补数:complement = 9 - 2 = 7
- 检查数组中是否存在数字7。
- 如果存在数字7,它的索引 j(假设 j != i)与 i 就是我们要找的答案。