两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。

你可以按任意顺序返回答案。

https://leetcode.cn/problems/two-sum/description/

HashMap

  1. 遍历数组,用 HashMap:key = 数组值,value = 下标
  2. 对当前元素 nums[i],需要找 c = target - nums[i]
  3. 如果 c在 map 里:找到答案,返回 [map.get(c), i]
  4. 不在 map:把 nums[i],i 放入 map,继续遍历
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.util.HashMap;
import java.util.Map;

class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
for(int i = 0; i < nums.length; i++){
int need = target - nums[i];
if(map.containsKey(need)){
return new int[]{map.get(need), i};
}
map.put(nums[i], i);
}
return new int[]{};
}
}

三数之和

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。

**注意:**答案中不可以包含重复的三元组。

https://leetcode.cn/problems/3sum/

排序+双指针

  1. 数组排序 O (nlogn)

  2. 固定第一个数 nums[i],i 去重(相同 i 跳过,避免重复答案)

  3. j = i+1(左指针),k = n-1(右指针),

    1
    while(j < k)
    • sum = nums[i]+nums[j]+nums[k]
    • sum < 0:总和太小,j++
    • sum > 0:总和太大,k--
    • sum == 0:记录答案;j、k 去重;j++,k–
  4. 外层循环 i 从 0~n-1

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
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(nums);
int n = nums.length;
for(int i = 0; i < n; i++){
// i去重
if(i > 0 && nums[i] == nums[i-1]) continue;
int j = i + 1;
int k = n - 1;
while(j < k){
int sum = nums[i] + nums[j] + nums[k];
if(sum < 0){
j++;
}else if(sum > 0){
k--;
}else{
res.add(Arrays.asList(nums[i], nums[j], nums[k]));
// j去重
while(j < k && nums[j] == nums[j+1]) j++;
// k去重
while(j < k && nums[k] == nums[k-1]) k--;
j++;
k--;
}
}
}
return res;
}
}