三数之和_15_16_259
LeetCode_15原题链接:https://leetcode-cn.com/problems/3sum/
LeetCode_16原题链接:https://leetcode-cn.com/problems/3sum-closest/submissions/
LeetCode_259原题链接:https://leetcode-cn.com/problems/3sum-smaller/
package Leetcode; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * @date 2022/4/3-21:59 * 给你一个包含 n 个整数的数组nums,判断nums中是否存在三个元素 a,b,c * 使得a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。 * 注意:答案中不可以包含重复的三元组。 */ public class ThreeSum_15 { // 此类题目,不管是两数,还是3,4数之和,都可以用双指针的方法,注意边界控制。 public static List<List<Integer>> threeSum(int[] nums) { int n = nums.length; Arrays.sort(nums); List<List<Integer>> res = new ArrayList<>(); if (n < 3) { // 初始化判断 return res; } for (int i = 0; i < n; i++) { if (i > 0 && nums[i] == nums[i - 1]) { // 对 i 去重化 continue; } int target = -nums[i]; int k = n - 1; for (int j = i + 1; j < k; j++) { if (j > i + 1 && nums[j] == nums[j - 1]) { // 对 j 去重化 continue; } while (j < k && nums[j] + nums[k] > target) { k--; } if (j == k) { break; } if (nums[j] + nums[k] == target) { List<Integer> list = new ArrayList<>(); list.add(nums[i]); list.add(nums[j]); list.add(nums[k]); res.add(list); } } } return res; } public static void main(String[] args) { List<List<Integer>> res; // int[] nums = {-1, 0, 1, 2, -1, -4}; int[] nums = {-1, -1, 1, 2, -1}; res = threeSum(nums); System.out.println(res); } }
LeetCode_16: 给你一个长度为 n 的整数数组nums和 一个目标值 target。 请你从 nums 中选出三个整数,使它们的和与target最接近。返回这三个数的和。 思路:比 LeetCode_15 更容易处理,只需判断三数相加的 和 target 大小关系,然后再作变化。 另外需要保留每次相加的值,用作比较,取最小值。
public int threeSumClosest(int[] nums, int target) { int n = nums.length; if (n < 3) { throw new IllegalArgumentException("The length of array is lower than three"); } Arrays.sort(nums); int ans = nums[0] + nums[1] + nums[2]; if (ans > target) { return ans; } for (int i = 0; i < n; i++) { if (i > 0 && nums[i] == nums[i-1]) { continue; } int j = i + 1; int right = n - 1; while (j < right) { int sum = nums[i] + nums[j] + nums[right]; if (sum == target) { return sum; } if(Math.abs(target - sum) < Math.abs(target - ans)) { ans = sum; } if (sum > target) { right--; while(j < right && nums[right] == nums[right+1]) { right--; } } else { j++; while(j <right && nums[j] == nums[j-1]) { j++; } } } } return ans; }
LeetCode_259:题目要求在数组nums中寻找3个元素的和,小于目标值target的个数,返回int类型。
public int solution(int[] nums, int target) { Arrays.sort(nums); int ans = 0; if (nums == null || nums.Length < 3){ return ans; } for (int i = 0; i < nums.length - 2; i++) { if (nums[i] >= target) { // 适当优化 break; } int left = i + 1; int right = nums.length - 1; while (left < right) { int curSum = nums[i] + nums[left] + nums[right]; if (curSum >= target) { right--; } else { // curSum < target 符合条件,则说明从当前 left 到 right的范围都满足 ans += right - left; break; } } } return ans; }

浙公网安备 33010602011771号