//三数和为0的问题。要求去重,并且输出数字有序。
public List<List<Integer>> threeSum(int[] nums) { Arrays.sort(nums); List<List<Integer>> lists = new ArrayList<List<Integer>>(); //对于i去重,因为p在i后面,所以不能往后去重,可能会把p的值去掉,所以要往前去重。 for(int i = 0; i < nums.length; i ++) { if(i>0&&nums[i] == nums[i-1]) { continue; } int p = i+1, q = nums.length - 1; while(p < q) { int sum = nums[i]+nums[p]+nums[q]; if(sum == 0) { List<Integer> list = new ArrayList<>(); list.add(nums[i]); list.add(nums[p]); list.add(nums[q]); lists.add(list); //p去重很巧妙,先自加,然后判断之前p的值和自加后的值是不是相等,如果相等,再次自加,同时也避免的去重时和q重叠。 while(++p < q && nums[p] == nums[p-1]) { } while(--q > p && nums[q] == nums[q+1]) { } } if(sum < 0) { p++; } if(sum > 0) { q--; } } } return lists; }
//三数和最接近某个值
public int threeSumClosest(int[] nums, int target) { Arrays.sort(nums); int temp = 0; int dist = Integer.MAX_VALUE; for(int i = 0; i < nums.length; i ++) { if(i > 0 && nums[i]==nums[i-1]) { continue; } int p = i + 1, q = nums.length-1; while(p < q) { int sum = nums[i] + nums[p] + nums[q]; if(sum > target) { if((sum - target) < dist) { dist = sum - target; temp = sum; } q--; } else if(sum < target) { if((target - sum) < dist) { dist = target - sum; temp = sum; } p++; } else { return sum; } } } return temp; }
四数和问题,感觉并不是最优解。
public class Solution { public List<List<Integer>> fourSum(int[] num, int target) { Arrays.sort(num); Set<List<Integer>> hashSet = new HashSet<>(); List<List<Integer>> result = new ArrayList<>(); for (int i = 0; i < num.length; i++) { for (int j = i + 1; j < num.length; j++) { int k = j + 1; int l = num.length - 1; while (k < l) { int sum = num[i] + num[j] + num[k] + num[l]; if (sum > target) { l--; } else if (sum < target) { k++; } else if (sum == target) { ArrayList<Integer> temp = new ArrayList<Integer>(); temp.add(num[i]); temp.add(num[j]); temp.add(num[k]); temp.add(num[l]); if (!hashSet.contains(temp)) { hashSet.add(temp); result.add(temp); } k++; l--; } } } } return result; } }