这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战
打工人最喜欢应该就是周五了吧,但是手上的事情没有取得更多突破,还出现了各种小状况,今天也并不是很顺利。
天气挺热的,周末打算在家补看一些奥运会的比赛,放松一下大脑,新的一周可能就会有一些新思路吧。
不过周末还有很多被日常工作耽搁而没有去做的事情,比如看看沟通的书,比如看看各个基金的季报。虽然投资不多,但是之前2周发现基金经理的季报也是挺有意思的,很多人从头开始看会觉得索然无味,那也很正常,因为你还没找到基金经理说人话的地方,其实在季报或者年报中,也就一小段,隐藏在茫茫多的格式内容中,不过就是这一小段,让你知道,基金经理也是一个活生生的人,而不是什么AI。下次找机会跟大家分享一下我是怎么读基金报告的
扯远了,今天继续刷leetcode第15题,虽然也有些水,不过比前两天好多了。
题目
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
示例 2:
输入:nums = []
输出:[]
示例 3:
输入:nums = [0]
输出:[]
思路
首先还是想到暴力的方法,3层for循环全遍历一遍完事儿。
算法题都是在通过暴力解理解题意基础上去优化,起始抓住和等于0这个特征,可以肯定要么是3个0,要么存在正负不一样的数,因为3个正数的和和3个负数的和都不可能为0。
想到这一点之后,自然而然可以想到先对数组做排序,例如做从小到大的排序。这时候先假定一个最小值a,然后从a右边的数里面找出2个b和c,使得a+b+c=0。因为a右边的数组也是有序的,这时候找b和c其实也不需要2层for循环来遍历,可以使用双指针,分别指向剩余数组的最小和最大,如果和小于0,就让最小值往右边走一个,如果和大于0,就让最大值往左边走一个。
Java版本代码
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> ans = new ArrayList<>();
int len = nums.length;
if (len < 3) {
return ans;
}
Arrays.sort(nums);
for (int i = 0; i < len -2; i++) {
if (nums[i] > 0) {
return ans;
}
if (i > 0 && nums[i] == nums[i-1]) {
continue;
}
int start = i + 1;
int end = len - 1;
while (start < end) {
if (nums[start] + nums[end] == -nums[i]) {
ans.add(Arrays.asList(nums[i], nums[start], nums[end]));
start++;
end--;
while (start < end && nums[start] == nums[start - 1]) {
start++;
}
while (start < end && nums[end] == nums[end + 1]) {
end--;
}
} else if (nums[start] + nums[end] > -nums[i]) {
end--;
} else if (nums[start] + nums[end] < -nums[i]) {
start++;
}
}
}
return ans;
}
}