一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情。
1 两数之和
有人相爱,有人夜里开车看海,有人LeetCode第一题都做不出来。——LeetCode讨论区
题目描述:
给定一个整数数组 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]
题解
方法一
根据题目可知,目的是在一个数组 nums 中找到和为 target 的两个整数,要求是同一个元素不能重复出现,通常类似的题目首先都可以使用暴力解法通过遍历数组找到两个整数。
使用双重遍历方法,外层遍历枚举 nums 中的每一个元素,内层再次从元素 nums[i]的后一个元素开始遍历,直到nums[i] + nums[j] == target,则表示找到两个整数,返回 i 和 j 即可。
public int[] twoSum(int[] nums, int target) {
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
// 当nums[i] + nums[j] == target时返回答案
if (nums[i] + nums[j] == target) {
return new int[]{i, j};
}
}
}
// 遍历完之后仍然没有返回则表示没有答案,则返回空数组
return new int[0];
}
时间复杂度:O(N^2)
方法二
由于方法一是对数组进行了两次循环,所以在最坏的情况下每两个元素之间都需要进行一次匹配,这样的话时间复杂度就会很高,所以还有一个办法就是使用HashMap,借助HashMap键唯一的特性来完成。
同样是循环遍历数组,但是使用HashMap的话就只需要遍历一次数组,在此之前首先需要明白一个点的是:如果nums[i]是两个整数答案之一,那么 target - nums[i] 得到的值就是另外一个整数。
这样的话每次遍历到一个元素时,就去HashMap中查找是否存在 target 减去当前元素的key,如果存在则当前元素和HashMap中存在的元素就是最终答案,如果不存在则将当前元素的值作为key,下标作为value存入到HashMap中
public int[] twoSum(int[] nums, int target) {
HashMap<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
// 判断 map 是否存在 target - nums[i] 的 key
if (map.containsKey(target - nums[i])) {
// 如果存在则返回 key 对应的下标 value 和 i
return new int[]{map.get(target - nums[i]), i};
}
// 如果不存在则将 num[i] 作为 key,下标 i 作为 value 放入 map 中
map.put(nums[i], i);
}
return new int[0];
}
时间复杂度:O(N)