Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
leetcode刷题15三数之和
前文
本文为leetcode双指针类题目,题目序号为15,主要考察内容为在遍历过程中对于遍历方式的优化。
题目信息
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
解题思路
根据题目信息可知,该题的目标为在数组中获取到若干数值,使他们的加和为0。面对这种问题,很容易的会想到直接通过遍历进行实现。而改题目中,由于有三个元素,直接进行遍历会具有极高的时间复杂度,显然这不是一种优秀的思路。本题解题方案采取了一个双指针的方式。首先对于数组进行排序,这是为了后续去重校验比较方便,因题目要求不可重复出现结果。然后对数组进行循环,在循环中设置两个指针p和q,用来指示第二及第三个元素的位置。通过第二、三个元素位置的调整,即可得到去重的加和为0的元素。在操作移动的过程中,还要注意当元素前后移动,可能出现完全相同的两个元素,这种情况要继续向前移动。另外,为了方便指针移动,在加和大时移动后一元素,加和小时移动前一元素。这也是排序所带来的后续便利。以上方式即可实现对于该题目的解答。
解题代码
public List<List<Integer>> threeSum(int[] nums) {
nums = Arrays.stream(nums).sorted().toArray();
List<List<Integer>> list = new ArrayList<>();
if(nums.length < 3){
return list;
}
int temp = Integer.MAX_VALUE;
for (int i = 0; i < nums.length - 2; i++) {
int p = i + 1;
int q = nums.length - 1;
if(nums[i] == temp){
continue;
}
while (true){
if(p >= q){
break;
}
if(nums[i] + nums[p] + nums[q] == 0){
List<Integer> item = new ArrayList<>();
item.add(nums[i]);
item.add(nums[p]);
item.add(nums[q]);
list.add(item);
int oldQ = q;
boolean needBreak = true;
while (p < q){
if(nums[q] == nums[oldQ]){
oldQ = q;
q -= 1;
}else{
needBreak = false;
break;
}
}
if(needBreak){
break;
}
}else if(nums[i] + nums[p] + nums[q] < 0){
int oldP = p;
boolean needBreak = true;
while (p < q){
if(nums[p] == nums[oldP]){
oldP = p;
p += 1;
}else{
needBreak = false;
break;
}
}
if(needBreak){
break;
}
}else{
int oldQ = q;
boolean needBreak = true;
while (p < q){
if(nums[q] == nums[oldQ]){
oldQ = q;
q -= 1;
}else{
needBreak = false;
break;
}
}
if(needBreak){
break;
}
}
}
temp = nums[i];
}
return list;
}
后记
- 千古兴亡多少事?悠悠。不尽长江滚滚流。