今日心情:stop wasting life
题目描述:
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
解题代码:
class Solution {
public List<List<Integer>> threeSum(int[] nums){
List<List<Integer>> totalList = new ArrayList<>();
// empty array
int len = nums.length;
if(len <= 2 || nums == null){return totalList;}
// sort the array
Arrays.sort(nums);
// target sum value : 0
int target = 0;
// Notice: the array already been sorted
for(int i = 0 ; i < len-2; i++){
// current number
int cur = nums[i];
// if current number(first) is bigger than zero, then it's impossible to get the 0
if(cur > 0 ){break;}
// avoid the duplicate situation
if(i > 0 && nums[i] == nums[i-1]){continue;}
// double indicators
int left = i+1;
int right = len - 1;
//search 3 numbers that sum equals 0
while(left < right){
// found the 3 numbers that meet the request
if(nums[left]+nums[right]+nums[i] == target){
ArrayList<Integer> solution = new ArrayList<>();
solution.add(nums[left]);
solution.add(nums[right]);
solution.add(nums[i]);
totalList.add(solution);
left++; right--;
//jump the duplicate situations
while(left < right && nums[left] == nums[left-1]) left++;
while(left < right && nums[right] == nums[right+1]) right--;
}else if(nums[left]+nums[right]+nums[i] < target){
left++; // need to get a bigger number
}else{
right--; // need to get a smaller number
}
}
}
return totalList;
}
}
解题思路:
终于一开始拿到题的时候想到了排序+双指针,大致的解题方向基本一致,就是不知道该怎么实现🤷♀️🤷♀️,然后死抠了好久还是没有AC,不管了就直接看题解了,然后按照题解自己实现了一遍。
思路:
(1)First thing first , 空数组判断以及数组长度是否大于3(满足3个数相加的条件)
(2)内置函数对数组进行排序:Arrays.sort(nums);
(3)遍历数组,先确定一个数nums[i]。
(4)然后双指针遍历,找剩下的两个数 nums[left] 和 nums[right]。
如果nums[left]+nums[right]+nums[i] 等于目标值,则将nums[left],nums[right],nums[i] 添加到一个ArrayList 中作为一个solution,然后再添加到总的 totalList 集合中。然后更新 left,right 左右指针:left++; right--;
去除数重复的情况,防止重复和方案添加,所以while 遍历,只要当前 left 和 right 指向的数 和 它们之前指向的数相同,即 left-1指向的数, right +1 指向的数,则更新 left ,right 跳过重复的数:left++; right--。这里需要注意的遍历nums[i] 边界条件就是 i 的限制是 小于 len-2 而不是 len-1 或者 len,因为三个数相加除去 num[i] 本身,还需要两个数的空余。
如果三个数相加小于目标值,nums[left]+nums[right]+nums[i] < target ,则说明需要一个大一点值,则 left++,获取一个更大的数以满足nums[left]+nums[right]+nums[i] 等于 target;如果三个数相加大于目标值,nums[left]+nums[right]+nums[i] > target ,则说明需要一个小一点值,则 right--,获取一个更大的数以满足nums[left]+nums[right]+nums[i] 等于 target。
(5)遍历结束,返回总集合totalList。