标签:tco result class 顺序 题目 复杂 一个 arrays 超级
描述:
给定一个整形无序数组a,其中元素可重复,在a中找出所有的{a, b, c}满足条件a+b+c=0,且结果不可以重复
例如,给定数组S = [-1,0,1,2,-1,-4], 答案: [ [-1,0,1], [-1,-1,2] ]
思考过程:
在解决这个题时,我一直考虑怎么才能避免重复,因为这是个无序数组,我最先想到的是匹配已有结果,但是这样会超级复杂,解决方法一定不是这样的。那么既然无序的不好办,把它变成有序的如何?ok就是这样。用Arrays.sort(a),就可以让数组有序化。
本着先做出来再注意时间复杂度的想法,下面是我的方法,逻辑正确,时间超限制了:
public static List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> results = new ArrayList();
int a,b,c,l=nums.length;
for(int i=0; i<l-2; i++){
a=nums[i];
for(int j=i+1; j<l-1; j++){
b=nums[j];
for(int n=j+1; n<l; n++){
c=nums[n];
//由于nums是顺序的,所以当c>(0-a-b)条件满足时且还未匹配到结果时,此次第三层循环就不会有结果了,直接break
if(c>(0-a-b))
break;
if(a+b+c == 0){
List<Integer> result = new ArrayList();
result.add(a);
result.add(b);
result.add(c);
results.add(result);
break;
}
}
//避免第二个数重复出现
while((j+1<l-1) && (b == nums[j+1])){
j++;
}
}
//避免第一个数重复出现
while((i+1<l-2) && (a == nums[i+1])){
i++;
}
}
return results;
}
下面是leetcode大神的方法:
public List<List<Integer>> threeSum1(int[] num) {
Arrays.sort(num);
List<List<Integer>> res = new LinkedList<>();
//这里计算的是第一个数,第一个数是从第0位到第length-2位
for (int i = 0; i < num.length-2; i++) {
//当i++时要避免num[i]=num[i++],否则会出现重复的集合
if (i == 0 || (i > 0 && num[i] != num[i-1])) {
//计算出了第二位数的循环区间(lo,hi)和第二第三位数的加和sum
int lo = i+1, hi = num.length-1, sum = 0 - num[i];
//这里计算的是第二个数,第二个数每次都要在第一位数的后一位开始,即i+1位到第length-1位
//循环里做的事情是:当第一位数一定时,找出所有可能的第二和第三位数
while (lo < hi) {
//当第二个和第三个数符合题目条件时,那么上下线都应该同时移动
if (num[lo] + num[hi] == sum) {
res.add(Arrays.asList(num[i], num[lo], num[hi]));
//两个while功能是避免第二和第三个数的重复出现
while (lo < hi && num[lo] == num[lo+1]) lo++;
while (lo < hi && num[hi] == num[hi-1]) hi--;
lo++; hi--;
}
//如果不符合条件,就应该按照实际情况只移动上限或者下限
else if (num[lo] + num[hi] < sum)
lo++;
else hi--;
}
}
}
return res;
}
标签:tco result class 顺序 题目 复杂 一个 arrays 超级
原文地址:http://www.cnblogs.com/K-artorias/p/7909071.html