实现的时候参考了http://blog.sina.com.cn/s/blog_71d59f9a01018dh3.html 的思路。
Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.
Note:
- Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d)
- The solution set must not contain duplicate quadruplets.
For example, given array S = {1 0 -1 0 -2 2}, and target = 0. A solution set is: (-1, 0, 0, 1) (-2, -1, 1, 2) (-2, 0, 0, 2)
这道题如果暴力破解的话可以想到复杂度比较高。当时在考虑是否能够拿递归来做,但是想了很久也不知道该怎么做。之前做过一道最大盛水容积的题,思路是宽由大变小的搜索最大容积,我觉得思路可以拿过来思考这道题。那么这样来看,四个参数有两个已经定上了,还需要考虑另外两个变量。由于不能够保存重复的结果,所以最好还是先排序下。(一开始是这么想的,无论后面干什么先排下序。后来发现排序是有好处的)既然已经排好序了,那么可以从收尾的中间开始寻找是否有满足条件的结果。扫的方式是由左边界的右侧一位开始,右边界的左侧一位开始。如果结果计算小于target值,那么说明小的那部分要变大一些,因此p1++;同理,如果大于target值,说明右侧的值需要变小,p2--。至此发现排序是有好处的。 再就是注意去重就好了,用arraylist自带的方法就可以了。
代码:
package leetcode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.text.html.HTMLDocument.Iterator;
public class FourSum {
public static void main(String[] args) {
FourSum four = new FourSum();
int[] nums={1,3,5,7,4,8,8,10};
int [] nums2={1, 0, -1, 0, -2, 2,0,-2};
List<List<Integer>> res = four.fourSum(nums2, 0);
System.out.println("result:");
for (List<Integer> list : res) {
for (Integer integer : list) {
System.out.print(integer+" ");
}
System.out.println();
}
}
public List<List<Integer>> fourSum(int[] nums, int target) {
//固定两头 里面两个指针往中间扫,如何想办法去重
List<List<Integer>> res =new ArrayList<List<Integer>>();
int len = nums.length;
//先排序
Arrays.sort(nums);
/* for(int i=0;i<len;i++){
System.out.println(nums[i]);
}*/
//注意范围
for(int i=0;i<len-3;i++){
for(int j = len-1; j > i+2; j--) {
//两边的暂时固定,里边选中间的两位
int p1 = i+1;
int p2 = j-1;
int fandl = nums[i]+nums[j];
int tar2 = target - fandl;
while(p1<p2){
//如果有满足条件的加入到res中,还要判断去重
int sandt = nums[p1]+nums[p2];
if(sandt == tar2){
ArrayList temp =new ArrayList<Integer>();
temp.add(nums[i]);
temp.add(nums[p1]);
temp.add(nums[p2]);
temp.add(nums[j]);
if(! res.contains(temp)){
res.add(temp);
}
p1++;
p2--;
}
else if(sandt > tar2){
//应该让结果变小
p2--;
}else{
p1++;
}
}
}
}
return res;
}
}