法算day1

两数之和

问题描述

给定一个整数数组 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]

java版

方法一:使用了哈希表(HashMap)来高效地查找两个数的和是否等于目标值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import java.util.HashMap;

public class TwoSum {


public int[] twoSum(int[] nums, int target) {
// 1. 先准备一本“字典”,名字叫 map
// 左边 key 存“数值”,右边 value 存“这个数值的下标”
Map<Integer, Integer> map = new HashMap<>();

// 2. 从头到尾扫一遍数组
for (int i = 0; i < nums.length; i++) {

// 3. 我想找的“另一半”是多少?
// 如果 target 是 9,当前数是 2,那我就要找 7
int need = target - nums[i];

// 4. 翻字典看看:之前有没有出现过 7?
// 如果出现过,它就记录在 map 里,直接拿到它的下标
if (map.containsKey(need)) {
// 5. 找到了!把“之前那个数的下标”和“现在这个数字的下标”一起返回
return new int[]{map.get(need), i};
}

// 6. 如果字典里没有 7,就把当前的“数-下标”写进字典
// 这样后面遇到 7 时就能查到今天的 2 了
map.put(nums[i], i);//将这对'值-下标'存入字典中,数组里的元素被逐步存入了 map。
}

// 题目保证有解,这里只是为了代码能通过编译
throw new IllegalArgumentException("No two sum solution");
}

// 简单测试
public static void main(String[] args) {
TwoSum solution = new TwoSum();
int[] nums = {2, 7, 11, 15};
int target = 9;
int[] result = solution.twoSum(nums, target);
System.out.println("[" + result[0] + ", " + result[1] + "]"); // 预期输出 [0, 1]
}
}

✅ 说明:
时间复杂度:O(n),只需要遍历一次数组。
空间复杂度:O(n),最坏情况下需要存储所有元素。
不能重复使用同一个元素:通过 map 存储的是已经遍历过的元素,确保不会重复使用。
如果你需要处理多个解或者有其他限制条件,也可以进一步扩展这个逻辑。

方法二:暴力枚举—— 数据量极小(n ≤ 200)时图省事

1
2
3
4
5
6
7
public int[] twoSum_brute(int[] nums, int target) {
for (int i = 0; i < nums.length - 1; i++)
for (int j = i + 1; j < nums.length; j++)
if (nums[i] + nums[j] == target)
return new int[]{i, j};
throw new IllegalArgumentException("No solution");
}

✅ 说明:
时间 O(n²) 空间 O(1)

python版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from typing import List

# 解法 1:暴力枚举
def two_sum_bruteforce(nums: List[int], target: int) -> List[int]:
n = len(nums)
for i in range(n):
for j in range(i + 1, n):
if nums[i] + nums[j] == target:
return [i, j]
return [] # 题目保证有解,这里不会执行

# 解法 2:哈希表一次遍历
def two_sum(nums: List[int], target: int) -> List[int]:
seen = {} # 值 -> 下标
for j, num in enumerate(nums): # 当前下标 j
need = target - num
if need in seen: # 之前已经遇到过符合条件的另一半
return [seen[need], j]
seen[num] = j # 记录值和下标
return [] # 题目保证有解,这里不会执行

# 简单测试
if __name__ == "__main__":
nums = [2, 7, 11, 15]
target = 9
print(two_sum(nums, target)) # 输出: [0, 1]
print(two_sum_bruteforce(nums, target)) # 输出: [0, 1]