继续打卡算法题,今天学习的是LeetCode的第15题三数之和,这道题目是道中等题。算法题的一些解题思路和技巧真的非常巧妙,每天看一看算法题和解题思路,我相信对我们的编码思维和编码能力有一些帮助。
分析一波题目
这个题目,我们可以先把数组从小到大排序,这样可以方便对相同的数去重。 死办法是需要3层循环,但是我们如果想到使用双指针就可以减少到2层循环,记得双指针可以用于减少循环层数
。
只有2层循环了,我们依次取一个元素作为第一个元素,通过双指针法,第二个元素从第一元素后1个元素开始取,第三个元素从最后一个元素开始找符合条件的三元组,直到第二个元素指针>=第三个元素指针。
比如
[1,0,1,2,-1]
, 排序后变成,[-1,0,1,1,2]
第一遍
第一个元素是-1
第2个元素 依次找 0
第3个元素 依次找 2,这个时候-1+0+2>0,所以继续找1,此时-1+0+1满足=0,记录下来。接着看1和上一个1重复了,去重,这个时候起始下标已经重合,因此以-1
开始的三元组查找就结束了。
接着在找第2个,第3个开始的三元组。
编码实现
class Solution {
//思路 定义一个固定节点 两个起始节点 移动起始节点确定有没有等于0的情况
public List<List<Integer>> threeSum(int[] nums) {
int size = nums.length;
Arrays.sort(nums);
List<List<Integer>> result = new ArrayList<>();
for(int i =0; i<size; i++) {
int start = i+1;
int end = size-1;
if(nums[i] >0) {
return result;
}
//去重
if(i>0 && nums[i] == nums[i-1]) {
continue;
}
while(start < end) {
int r = (nums[start] + nums[end] + nums[i]);
if(r == 0) {
//找到了符合和等于0的,记录下来
List<Integer> subResult = new ArrayList<>();
subResult.add(nums[i]);
subResult.add(nums[start]);
subResult.add(nums[end]);
result.add(subResult);
//去重复
while( start< end && nums[start] == nums[start+1]) {
start = start +1;
}
//去除重复
while( start < end && nums[end] == nums[end-1]) {
end = end-1;
}
start++;
end--;
continue;
}
//和大于0,右边的数太大,因此右边的索引要往左移
if( r > 0) {
end--;
continue;
}
//和小于0,左边的数太小,因此左边的索引往右移
if(r < 0) {
start++;
}
}
}
return result;
}
}
总结
2数之和我们可以想到使用hash表解决,超过2数之和的情况循环次数就多了,双指针可以用来减少循环次数。