【整体思路】

  • 先Arrays.sort()排序,不然后续指针没法用
  • 对于K数之和,固定K-2个指针(循环),再用两指针一头一尾,根据sum大了小了,调左或调右
    • 4数之和,2固定2移动;
    • 3数之和,1固定2移动;
  • 一定要记得去重,不仅为了减少工作量,也是确保输出结果的唯一

 

【题目】

leetcode15 三数之和=0

https://www.cnblogs.com/inku/p/9955638.html

 

leetcode16 三数之和最接近

class Solution {
    public int threeSumClosest(int[] nums, int target) {
        int ans=0;
        int gap=Integer.MAX_VALUE;
        Arrays.sort(nums);
        for(int i=0;i<nums.length-2;i++){
            
            int left=i+1;
            int right=nums.length-1;
            
            
            while (left<right){
                int sum=nums[i]+nums[left]+nums[right];
//如果sum更接近target,则更新ans
if(Math.abs(sum-target)<gap){ ans=sum; gap=Math.abs(sum-target); }
//比目标值小,升序排列,左边小的右移
if(sum<target) left++; else right--; } } return ans; } }

 

leetcode 18 四数之和

https://www.cnblogs.com/inku/p/9977917.html

测试用例(之前出错的)

[-2,-1,-1,1,1,2,2]
0

[-1,0,-5,-2,-2,-4,0,1,-2]
-9

 

【题目】

leetcode 454 四数之和II

https://leetcode.com/problems/4sum-ii/

四个长度相等的数组,从中分别取一个数,组成的target=0,问有多少种组合

【思路】

暴力解法复杂度太高O(n^4),将四数之和俩俩拆分2+2降低时间

即(a+b)+(c+d)=target=0

先遍历nums1、nums2,那么target-nums1-nums2就是nums3和nums4的目标值

再遍历num3、num4时,只要找是否存在target-nums1-nums2即可

*要注意,不能直接用list存储,因为存在相加后值相同的情况。每次存储时,要记录这个值出现的次数+1。

【代码】

class Solution {
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        int ans=0;
        Map<Integer,Integer> sum=new HashMap<>();

        for(int a:nums1){
            for(int b:nums2){
                sum.put(-a-b,sum.getOrDefault(-a-b,0)+1);
            }
        }
        for(int c:nums3){
            for(int d:nums4){
                ans+=sum.getOrDefault(c+d,0);
            }
        }
        return ans;
    }
}

 

 posted on 2021-08-23 22:39  alau  阅读(96)  评论(0)    收藏  举报