题目描述:给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出和为目标值 target 的那两个整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。你可以按任意顺序返回答案。
实例1:
输入:nums = [2, 7, 11, 15],target = 9
输出:[0, 1]
解释:因为 nums[0] + nums[1] == 9,返回 [0, 1] 。
这个题目还是比较简单的,一般的我们都能想到使用两层 for 循环来进行处理。
思路:
当我们使用遍历整个数组的方式寻找 target - x 时,需要注意到每一个位于 x 之前的数组都已经和 x 匹配过,因此不需要再进行匹配。而每个元素不能被使用两次,所以我们只需要在 x 后面的元素中寻找 target - x 即可。
public int[] twoSum(int[] nums, int target) {
int[] result = new int[];
for (int i = 0; i < nums.length-1; i++) {
for (int j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] == target) {
result[0] = i;
result[1] = j;
}
}
}
return result;
}
代码还是很简单的,我不需要作解释相信大家也都看得懂。在提交之后,发现结果是通过,执行耗时大约在 40多ms,内存消耗是在38 MB多。
分析一下,因为是两层 for 循环,所以时间复杂度是 O(N²) N是数组的长度;空间复杂度是 O(1),只需要创建结果数组 result 的时候消耗一些内存。
我的认知基本也就到此为止了,但是我们做算法题的时候在作出一种解时需要考虑一下是否还有更优的解决方案。
思路:
我们注意一下,上述双层for循环时间复杂度较高的原因是寻找 target -x 的时间耗费较多。最坏的情况是数组中的任意两个数都要被匹配一次。因此,我们需要一种更优秀的方法,能够快速寻找数组中是否存在目标元素。如果存在,我们需要找出它的索引即可。
使用哈希表,可以将寻找 target -x 的时间复杂度从 O(N) 降低到 O(1)。这样我们创建一个哈希表,对于每一个 x ,我们首先查询哈希表中是否存在 target - x,然后将 x 插入到哈希表中,即可保证不会让 x 和自己匹配。
代码如下:
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> hashTable = new HashMap<>(nums.length -1);
for(int i = 0; i < nums.length; i++) {
// 只需要判断一下当前哈希表中是否含有 target - x 的值
if (hashTable.containsKey(target - nums[i])) {
return new int[]{hashTable.get(target - nums[i]), i};
}
hashTable.put(nums[i], i);
}
return new int[0];
}
分析:
时间复杂度:O(N),其中 N 是数组中的元素数量。对于每一个元素 x ,我们可以 O(1) 的寻找 target - x。
空间复杂度:O(N),其中 N 是数组中元素的数量。主要为哈希表的开销。
这是一种空间换时间的策略。果然,提交之后结果是执行用时 1 ms,内存消耗还是 38 MB多。
其实从这一题目中我们不难发现。想要找出更优解,我们需要对相应的数据结构做出更深一些的了解,这样我们才能明白,在什么时候该用什么数据结构。之所以我只能想到用双层循环处理,就是因为对哈希表这一数据结构不够熟悉。这也难怪多数人在说算法的时候都会带上数据结构。
好了,本题就到这了,LeetCode 与大家共勉。
本文探讨了如何通过使用哈希表优化LeetCode的两数之和问题,将时间复杂度从O(N²)降低到O(N),并分析了空间复杂度。作者分享了两种解法,重点在于理解数据结构哈希表的应用,以提高搜索效率。
695

被折叠的 条评论
为什么被折叠?



