三数之和_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; }

 

posted @ 2022-04-03 22:39  2022年总冠军gogogo  阅读(29)  评论(0)    收藏  举报