力扣HOT100-1 两数之和(Java实现)
题目

题目解读
1.只存在一个有效答案
2.给一列数字数组nums,和一个目标值target,找到和为target的两数下标
开始解题
一、暴力枚举(双重循环)
思路:
尝试所有可能的两个下标组合,看哪一对元素之和等于 target。
核心流程:
1.外层循环固定第一个数的下标 i,从 0 到 n-2。
2.内层循环固定第二个数的下标 j,从 i+1 到 n-1(因为不能重复使用同一个元素,且 (i,j) 和 (j,i) 是一回事)。
3.一旦发现 nums[i] + nums[j] == target,直接返回 new int[]{i, j}。
代码
public int[] twoSum(int[] nums, int target) {
int n = nums.length;
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
if (nums[i] + nums[j] == target) {
return new int[]{i, j};
}
}
}
// 题目保证有解,此行不会执行
return new int[]{0, 0};
}
二、基于列表查找(一次循环 + indexOf)
思路:
暴力法在内层循环做了太多重复的扫描。我们可以反过来思考:
对于每个元素 nums[i],我们需要的另一个数 temp = target - nums[i] 是否在数组中出现过?如果我们把数组转成一个列表,就可以用 indexOf 直接查找 temp 的下标。
核心流程:
1.需要正确地将 int[] 转换成 List<Integer>
2.查找 temp 时,不仅要判断它是否存在(indexOf 返回 -1 表示不存在),还要保证找到的下标不是 i 本身(避免同一个元素用两次)。
代码
public int[] twoSum(int[] nums, int target) {
// 正确转换:将 int[] 变为 List<Integer>
List<Integer> numList = Arrays.stream(nums)
.boxed()
.collect(Collectors.toList());
for (int i = 0; i < nums.length; i++) {
int temp = target - nums[i];
int tempIndex = numList.indexOf(temp);
// indexOf 返回 -1 表示没找到,同时必须不是当前下标
if (tempIndex != -1 && tempIndex != i) {
return new int[]{i, tempIndex};
}
}
// 题目保证有解
return new int[]{0, 0};
}
三、哈希表(HashMap)
思路:
我们需要一种“记住之前看到的元素及其下标”的数据结构,并能快速检查 temp 是否存在 ,所以可以采用HashMap。即每拿到一个新数字,就看过去存的值是否已经包含差值了,没包含就把数字和位置存入。
核心流程:
1.创建一个空的 HashMap<Integer, Integer>,键是元素值,值是该元素值对应的下标
2.从左到右遍历数组。对于当前元素 nums[i]:
计算 complement = target - nums[i]。
检查 complement 是否已经在 map 的键集合中(说明之前某个下标的元素正好是需要配对的数)。
如果在,直接返回 [map.get(complement), i]。
如果不在,把 (nums[i], i) 存入 map,继续下一次循环。
问题点
为什么不会重复使用同一个元素?
因为我们总是先查找,后存入。当检查 i 时,map 里只有下标小于 i 的元素,所以找到的 complement 一定不是 nums[i] 自己。
代码
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int complement = target - nums[i];
if (map.containsKey(complement)) {
return new int[]{ map.get(complement), i };
}
map.put(nums[i], i);
}
// 根据题意,永远会提前返回
return new int[]{0, 0};
}
感谢您能够看到这里,一起见证小何同学的算法学习,如果您有不同的见解,希望能得到您的指点和点悟;如果您是和我一样的同学,也希望这篇文章能对您有所帮助。
更多推荐
所有评论(0)