【整体思路】
- 先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
浙公网安备 33010602011771号