作者 : XiaXinyu
日期 :2021-10-07
题目
理解
在给定数组中找出所有相加为0的三元组
题解1(朴素做法)
首先对数组进行排序,然后使用三层for循环来枚举出所有三元组并判断是否等于0即可
虽然这种做法的时间复杂度很高,显然是不能通过测试样例的,但是实现代码中还是有很多细节是值得注意的
代码
class Solution{
public List<List<Integer>> threeSum(int[] nums){
List<List<Integer>> ans = new ArrayList<>();
Arrays.sort(nums); //对数组进行从小到大排序
int len = nums.length;
for(int i = 0;i < len - 2;i ++){
//如果三元组中的第一个元素小于0,
//那么这个三元组一定小于0,
//因为数组有序,所以直接break
if(nums[i] > 0) break;
if(i > 0 && nums[i] == nums[i - 1]) continue; // 如果当前枚举到的三元组中第一个元素与上一次枚举到的第一个
// 元素相等则不用进行多次枚举
for(int j = i + 1;j < len - 1;j ++){
if(j > i + 1 && nums[j] == nums[j - 1]) continue; // 如果当前枚举到的三元组中第二个元素与上一次枚举到的
// 第二个元素相等则不用进行多次枚举
for(int k = j + 1;k < len;k ++){ //同理
if(k > j + 1 && nums[k] == nums[k - 1]) continue;
if(nums[i] + nums[j] + nums[k] == 0){
ArrayList<Integer> temp = new ArrayList<>();
temp.add(nums[i]);
temp.add(nums[j]);
temp.add(nums[k]);
ans.add(temp);
}
}
}
}
return ans;
}
}
时间复杂度
:O(n^3) 使用3层循环
空间复杂度
:O(1)
题解2(双指针算法)
三元组中第一个元素使用for循环遍历,剩下两个元素采用双指针算法
代码
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> ans = new ArrayList<>();
if(nums.length < 3) return ans;
int len = nums.length;
Arrays.sort(nums);
for(int i = 0;i < len - 2;i ++){
if(nums[i] > 0) break;
if(i > 0 && nums[i] == nums[i - 1]) continue;
for(int l = i + 1,r = len - 1;l < r; ){
int sum = nums[i] + nums[l] + nums[r];
if(sum < 0){
l ++;
while(l < r && nums[l] == nums[l - 1]) l ++;
}else if(sum > 0){
r --;
while(l < r && nums[r] == nums[r + 1]) r --;
}else{
ArrayList<Integer> temp = new ArrayList<>();
temp.add(nums[i]);
temp.add(nums[l]);
temp.add(nums[r]);
ans.add(temp);
l ++;
r --;
while(l < r && nums[l] == nums[l - 1]) l ++;
while(l < r && nums[r] == nums[r + 1]) r --;
}
}
}
return ans;
}
}
时间复杂度
:O(n^2) 一层for循环结合双指针算法
空间复杂度
:O(1)