標籤:turn top dup input mono int dal art 分析
題目:
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)
題意:
給定一個包括n個整數的數組S,在數組S中是否存在元素a,b,c和d,使得 a + b + c + d = target.找出數組S中全部這種組合。
注意:
1.這四個元素必須是升序排列(ie, a ≤ b ≤ c ≤ d)
2.終於結果中不嫩包括反覆的解。
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)
演算法分析:
* 利用了題目《3Sum》的代碼 https://leetcode.com/problems/3sum/
* 首先升序排列數組,然後從第一個元素開始依次遍曆《3Sum》演算法,目標值為(target-nums[i]),遍曆的數組為該元素後面的數組
* 這樣既滿足終於的arraylist中元素升序排列,也不會出現反覆。由於每次以其為開始。進行遍曆的元素都是數組中的最小的元素
AC代碼:
public class Solution { private static ArrayList<ArrayList<Integer>> ret = new ArrayList<ArrayList<Integer>>(); public ArrayList<ArrayList<Integer>> fourSum(int[] nums, int target) { int newtarget=0; ArrayList<ArrayList<Integer>> finalres = new ArrayList<ArrayList<Integer>>(); Arrays.sort(nums); for (int i = 0; i < nums.length; i++) { ArrayList<ArrayList<Integer>> temlist= new ArrayList<ArrayList<Integer>>(); if (i > 0 && nums[i] == nums[i-1]) continue;//避免結果反覆,其後面和它相等的直接被跳過。 newtarget=target-nums[i]; int inputnums[]=new int[nums.length -i-1]; for(int ii=0;ii<nums.length -i-1;ii++) inputnums[ii]=nums[ii+1+i];//每次選取該元素後面的數組作為《3sum》演算法的輸入數組 temlist=threeSum(inputnums,newtarget,nums[i]); finalres.addAll(temlist); ret.clear(); }return finalres; } public static ArrayList<ArrayList<Integer>> threeSum(int[] num,int newtarget,int firstnum) { if (num == null || num.length < 3) return ret; Arrays.sort(num); int len = num.length; for (int i = 0; i < len-2; i++) { if (i > 0 && num[i] == num[i-1]) continue;//避免結果反覆,其後面和它相等的直接被跳過。 find(num, i+1, len-1, num[i],newtarget, firstnum); //尋找兩個數與num[i]的和為0 } return ret; } public static void find(int[] num, int begin, int end, int target,int newtarget,int firstnum) { int l = begin, r = end; while (l < r) { if (num[l] + num[r] + target == newtarget) { ArrayList<Integer> ans = new ArrayList<Integer>(); ans.add(firstnum);//與原始的《3Sum》演算法不同的地方為:記得把每次的啟發遍曆元素增加進去。就是4個數中的最小的那一個 ans.add(target); ans.add(num[l]); ans.add(num[r]); ret.add(ans); //放入結果集中 while (l < r && num[l] == num[l+1]) l++;//避免結果反覆,其後面和它相等的直接被跳過。 while (l < r && num[r] == num[r-1]) r--;////避免結果反覆,其後面和它相等的直接被跳過。 l++; r--; } else if (num[l] + num[r] + target < newtarget) l++; else r--; } }}
[LeetCode][Java] 4Sum