多数之和小结 在刷leetcode的时候发现了一类多数之和的问题,基本上都是采用排序+双指针解决,所有总结一下。
两数之和 题目描述 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
示例:
1 2 3 4 5 给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/two-sum 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution { public int [] twoSum(int [] nums, int target) { if (nums==null || nums.length<=1 ) { return null ; } int []ans = new int [2 ]; Map<Integer,Integer> helperMap = new HashMap<>(); for (int i = 0 ; i < nums.length; i++) { if (helperMap.containsKey(target-nums[i]) && helperMap.get(target-nums[i])!=i) { ans[0 ] = helperMap.get(target-nums[i]); ans[1 ] = i; break ; } helperMap.put(nums[i],i); } if (ans[0 ]!=ans[1 ]) { return ans; } return null ; } }
这是一个很简单的题目。我们也可以使用排序+双指针解决,但是这题时间上最好的方法是哈希表,所以使用哈希表完成了。
两数之和II-输入有序数组 题目描述 给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。
函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。
说明 :
返回的下标值(index1 和 index2)不是从零开始的。
你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
示例 :
1 2 3 输入: numbers = [2, 7, 11, 15], target = 9 输出: [1,2] 解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码 由于已经进行了排序我们直接使用双指针即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution { public int [] twoSum(int [] numbers, int target) { if (numbers == null || numbers.length == 0 ) { return null ; } int p1 = 0 ; int p2 = numbers.length - 1 ; while (p1 < p2) { if (numbers[p1] + numbers[p2] == target) { return new int [] { p1+1 , p2+1 }; } else if (numbers[p1] + numbers[p2] < target) { ++p1; } else { --p2; } } return null ; } }
三数之和 题目描述 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例:
1 2 3 4 5 6 7 给定数组 nums = [-1, 0, 1, 2, -1, -4], 满足要求的三元组集合为: [ [-1, 0, 1], [-1, -1, 2] ]
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/3sum 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 class Solution { public List<List<Integer>> threeSum(int [] nums) { List<List<Integer>> res = new ArrayList<>(); Arrays.sort(nums); int p1 =0 ; int p2 =nums.length-1 ; int target = 0 ; for (int i = 0 ; i < nums.length; i++) { if (i > 0 && nums[i] == nums[i - 1 ]) continue ; p1=i+1 ;p2 = nums.length-1 ; while (p1<p2) { int sum = nums[i]+nums[p1]+nums[p2]; if (sum==target){ List<Integer> ans = new ArrayList<>(); ans.add(nums[i]); ans.add(nums[p1]); ans.add(nums[p2]); res.add(ans); while (p1<p2&&nums[p1]==nums[p1+1 ]){ p1++; } p1++; while (p1<p2&&nums[p2]==nums[p2-1 ]) { p2--; } p2--; }else if (sum<target){ p1++; }else if (sum>target){ p2--; } } } return res; } }
为了解决重复以及转化为两数之和,我们使用排序加双指针完成
最接近的三数之和 题目描述 给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。
示例:
1 2 3 输入:nums = [-1,2,1,-4], target = 1 输出:2 解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。
提示:
3 <= nums.length <= 10^3 -10^3 <= nums[i] <= 10^3 -10^4 <= target <= 10^4
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/3sum-closest 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class Solution { public int threeSumClosest (int [] nums, int target) { Arrays.sort(nums); int p1 =0 ; int p2 =nums.length-1 ; int closetNum = nums[0 ]+nums[1 ]+nums[2 ]; for (int i = 0 ; i < nums.length; i++) { if (i > 0 && nums[i] == nums[i - 1 ]) continue ; p1=i+1 ;p2 = nums.length-1 ; int sum = 0 ; while (p1<p2) { sum = nums[p1]+nums[p2]+nums[i]; if (Math.abs(sum-target)<Math.abs(closetNum-target)){ closetNum = sum; } if (sum==target){ return target; }else if (sum<target){ p1++; }else if (sum>target){ p2--; } } } return closetNum; } }
跟上一题思路相同,同样可以使用排序+双指针
四数之和 题目描述 给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。
注意:
答案中不可以包含重复的四元组。
示例:
1 2 3 4 5 6 7 8 给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。 满足要求的四元组集合为: [ [-1, 0, 0, 1], [-2, -1, 1, 2], [-2, 0, 0, 2] ]
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/4sum 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 class Solution { public List<List<Integer>> fourSum(int [] nums, int target) { List<List<Integer>> res = new ArrayList<>(); Arrays.sort(nums); int p1 =0 ; int p2 =nums.length-1 ; for (int i = 0 ; i < nums.length-3 ; i++) { if (i > 0 && nums[i] == nums[i - 1 ]) continue ; for (int j = i+1 ; j < nums.length-2 ; j++) { if (j>i+1 && nums[j] == nums[j - 1 ]) continue ; p1=j+1 ;p2 = nums.length-1 ; while (p1<p2) { int sum = nums[i]+nums[j]+nums[p1]+nums[p2]; if (sum==target){ List<Integer> ans = new ArrayList<>(); ans.add(nums[i]); ans.add(nums[j]); ans.add(nums[p1]); ans.add(nums[p2]); res.add(ans); while (p1<p2&&nums[p1]==nums[p1+1 ]){ p1++; } p1++; while (p1<p2&&nums[p2]==nums[p2-1 ]) { p2--; } p2--; }else if (sum<target){ p1++; }else if (sum>target){ p2--; } } } } return res; } }
四数之和再三数之和的基础上再次升级,不过换汤不换药,我们还是使用一样的方法。