当前位置

网站首页> 程序设计 > 开源项目 > 程序开发 > 浏览文章

[Leetcode] 3Sum 4Sum 多数和

作者:小梦 来源: 网络 时间: 2024-01-14 阅读:

2Sum

在分析多数和之前,请先看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;    }}

热点阅读

网友最爱