[Leetcode] 3Sum 4Sum 多數和
• java教程• 發佈:2018-10-03
在分析多數和之前,請先看Two Sum的詳解
3Sum 雙指標法 複雜度時間 O(N^2) 空間 O(1)
思路3Sum其實可以轉化成一個2Sum的題,我們先從陣列中選一個數,並將目標數減去這個數,得到一個新目標數。然後再在剩下的數中找一對和是這個新目標數的數,其實就轉化為2Sum了。為了避免得到重複結果,我們不僅要跳過重複元素,而且要保證2Sum找的範圍要是在我們最先選定的那個數之後的。
程式碼public class Solution {public List<List<Integer>> threeSum(int[] nums) {Arrays.sort(nums);ArrayList<List<Integer>> res = new ArrayList<List<Integer>>();for(int i = 0; i < nums.length - 2; i++){// 跳過重複元素if(i > 0 &;&; nums[i] == nums[i-1]) continue;// 計算2SumArrayList<List<Integer>> curr = twoSum(nums, i, 0 - nums[i]);res.addAll(curr);}return res;}private ArrayList<List<Integer>> twoSum(int[] nums, int i, int target){int left = i + 1, right = nums.length - 1;ArrayList<List<Integer>> res = new ArrayList<List<Integer>>();while(left < right){if(nums[left] + nums[right] == target){ArrayList<Integer> curr = new ArrayList<Integer>();curr.add(nums[i]);curr.add(nums[left]);curr.add(nums[right]);res.add(curr);do {left++;}while(left < nums.length &;&; nums[left] == nums[left-1]);do {right--;} while(right >= 0 &;&; nums[right] == nums[right+1]);} else if (nums[left] + nums[right] > target){right--;} else {left++;}}return res;}} 4Sum 雙指標法 複雜度時間 O(N^3) 空間 O(1)
思路和3Sum的思路一樣,在計算4Sum時我們可以先選一個數,然後在剩下的數中計算3Sum。而計算3Sum則同樣是先選一個數,然後再剩下的數中計算2Sum。
程式碼public class Solution {public List<List<Integer>> fourSum(int[] nums, int target) {Arrays.sort(nums);ArrayList<List<Integer>> res = new ArrayList<List<Integer>>();for(int i = 0; i < nums.length - 3; i++){if(i > 0 &;&; nums[i] == nums[i-1]) continue;List<List<Integer>> curr = threeSum(nums, i, target - nums[i]);res.addAll(curr);}return res;}private List<List<Integer>> threeSum(int[] nums, int i, int target) {ArrayList<List<Integer>> res = new ArrayList<List<Integer>>();for(int j = i + 1; j < nums.length - 2; j++){if(j > i + 1 &;&; nums[j] == nums[j-1]) continue;List<List<Integer>> curr = twoSum(nums, i, j, target - nums[j]);res.addAll(curr);}return res;}private ArrayList<List<Integer>> twoSum(int[] nums, int i, int j, int target){int left = j + 1, right = nums.length - 1;ArrayList<List<Integer>> res = new ArrayList<List<Integer>>();while(left < right){if(nums[left] + nums[right] == target){ArrayList<Integer> curr = new ArrayList<Integer>();curr.add(nums[i]);curr.add(nums[j]);curr.add(nums[left]);curr.add(nums[right]);res.add(curr);do {left++;}while(left < nums.length &;&; nums[left] == nums[left-1]);do {right--;} while(right >= 0 &;&; nums[right] == nums[right+1]);} else if (nums[left] + nums[right] > target){right--;} else {left++;}}return res;}}