18. 4Sum
阿新 • • 發佈:2017-05-30
continue i+1 數組 color ray 技術 目標 [0 targe
一、描述
1、題目
2、題意
給一個數組,和一個目標數,求滿足數組中的4個數的和為目標數的所有組合!
二、解答
1、思路:
數組排序後,依次從前向後取一個數 num[i], target - num[i] 即為下標 i 後面 三數之和。再依次遍歷 i 後的數,將目標數記為 target - num[i] - num[j],化為兩數之和。最終采用2變量分別指向 j 後一個數與數組最後一個數,相對遍歷,查出滿足的所有情況!
public List<List<Integer>> fourSum(int[] nums, int target) { Arrays.sort(nums); List<List<Integer>> resultList = new ArrayList<List<Integer>>(); List<Integer> targetList = null; int tempTarget = 0, maxLen = nums.length - 1; for(int i = 0; i <= maxLen; i++) { if(i == 0 || nums[i] != nums[i-1]) for(intj = i + 1; j <= maxLen; j++) { tempTarget = (target - nums[i] - nums[j]); int low = j+1; int high = maxLen; while(low < high) { if(nums[low] + nums[high] == tempTarget) { targetList= Arrays.asList(nums[i], nums[j], nums[low], nums[high]); resultList.add(targetList); low++; high--; } else if(nums[low] + nums[high] < tempTarget) low++; else high--; } } } List newList = new ArrayList(new HashSet(resultList)); return newList; }
2、改進
查看到大神回答,可以過濾更多的不符合情況,來增加遍歷的速度!測試的速度提高了一半多!
public class Solution { public List<List<Integer>> fourSum(int[] nums, int target) { List<List<Integer>> res = new ArrayList<List<Integer>>(); int len = nums.length; if(nums == null || len < 4) return res; Arrays.sort(nums); int max = nums[len-1]; if(4*nums[0] > target || 4*max < target) return res; int z; for(int i = 0; i < len; i++) { z = nums[i]; if(i > 0 && z == nums[i-1]) continue; if(z + 3*max < target) continue; if(4*z > target) break; if(4*z == target) { if(i + 3 < len && nums[i+3] == z) res.add(Arrays.asList(z, z, z, z)); break; } threeSumForFourSum(nums, target - z, i+1, len - 1, res, z); } return res; } private void threeSumForFourSum(int[] nums, int target, int low, int high, List<List<Integer>> fourSumList, int z) { if(low + 1 >= high) return; int max = nums[high]; if(3 * nums[low] > target || 3 * max < target) return; int z1; for(int i = low; i < high - 1; i++) { z1 = nums[i]; if( i > low && z1 == nums[i-1]) continue; if(z1 + 2*max < target) continue; if(3*z1 > target) break; if(3 * z1 == target) { if(i + 1 < high && nums[i+2] == z1) fourSumList.add(Arrays.asList(z1, z1, z1, z)); break; } twoSumForFourSum(nums, target - z1, i + 1, high, fourSumList, z1, z); } } private void twoSumForFourSum(int[] nums, int target, int low, int high, List<List<Integer>> fourSumList, int z1, int z2) { if(low >= high) return; if(2 * nums[low] > target || 2 * nums[high] < target) return; int i = low, j = high, sum, x; while(i < j) { sum = nums[i] + nums[j]; if(sum == target) { fourSumList.add(Arrays.asList(z1, z2, nums[i], nums[j])); x = nums[i]; while(++i < j && x == nums[i]) ; x = nums[j]; while(i < --j && x == nums[j]) ; } if(sum < target) ++i; if(sum > target) j--; } } }
三、總結
在遍歷嵌套層次較多的情況下,用 if 判斷過濾不符條件,可以明顯提高運行速度!
18. 4Sum