leetcode 15. 3Sum


  1. 3Sum:题目链接

基本思想: 先对数组排序 ,用一个for循环寻找第一个元素(索引为i),在用双指针在[i+1,nums.length-1]寻找第二个元素(索引left),第三个元素(索引right) .
如果nums[i] + nums[left] + nums[right] == 0 说明找到了
如果nums[i] + nums[left] + nums[right] < 0 left++
如果nums[i] + nums[left] + nums[right] > 0 right–

方法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
35
36
37
38
39
import java.util.*;

public class Solution1 {
// 时间复杂度O(Nlog2^N) + O(N^2) 排序 + 双指针
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(nums);

for (int i = 0; i < nums.length - 2; ++i) {
int left = i + 1;
int right = nums.length - 1;
// 在[i+1,nums.length-1] 用双指针搜索另外两个元素
while (left < right) {
int sum = nums[i] + nums[left] + nums[right];
if (sum == 0) {
List<Integer> list = new ArrayList<>();
list.add(nums[i]);
list.add(nums[left++]);
list.add(nums[right--]);
res.add(list);
} else if (sum < 0) {
left++;
} else {
right--;
}
}
}

Set<List<Integer>> set = new HashSet<>(res); // set用来给结果 去重
List<List<Integer>> ans = new ArrayList<>(set); // 将set转list
return res;
}

public static void main(String[] args) {
int[] nums = {-1, 0, 1, 2, -1, -4};
List<List<Integer>> res = new Solution1().threeSum(nums);
System.out.println(res);
}
}

方法2:sorting + twoPoint(推荐)

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
44
45
46
47
48
49
50
51
52
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Solution2 {
// 时间复杂度O(Nlog2^N) + O(N^2) 排序 + 双指针
// 优化Solution1 不需要set去重 直接在找的时候重复元素不添加到res中
// 选取的三个元素 索引从左到右 分别为 i 、left 、right(nums[i] <= nums[left] <= nums[rigt])
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(nums); // 先将数组按从小到大排序
for (int i = 0; i < nums.length - 2; ++i) {
if (nums[i] > 0) { // 最小的元素都大于0 结束
break;
}
if (nums[i] + nums[nums.length-1] + nums[nums.length-2] < 0) { // 说明第一个元素nums[i]太小了
continue;
}
if (i == 0 || (i > 0 && nums[i] != nums[i - 1])) { // 防止res中有重复的结果
int left = i + 1;
int right = nums.length - 1;
while (left < right) {
int sum = nums[i] + nums[left] + nums[right];
if (sum == 0) {
List<Integer> list = new ArrayList<>();
while (left < right && nums[left] == nums[left + 1]) { // 防止res中有重复的结果
left++;
}
while (left < right && nums[right] == nums[right - 1]) { // 防止res中有重复的结果
right--;
}
list.add(nums[i]);
list.add(nums[left++]);
list.add(nums[right--]);
res.add(list);
} else if (sum < 0) {
left++;
} else {
right--;
}
}
}
}
return res;
}

public static void main(String[] args) {
int[] nums = {-1, 0, 1, 2, -1, -4};
List<List<Integer>> res = new Solution2().threeSum(nums);
System.out.println(res);
}
}

pS: 源代码链接

文章目录
  1. 1. 方法1:
  2. 2. 方法2:sorting + twoPoint(推荐)
|