LeetCode[15, 16] - Sum of three numbers && Sum of nearest three numbers


text

There is no complicated algorithmic logic for this kind of topic, and dynamic programming is not used. What is tested is a thinking ability. If you can understand it, you can write it. Of course, in the final implementation of the code, there are many situations that need to be considered, and the logic is rigorous.

Topic 1: Sum of three numbers

[From LeetCode - 15] (Moderate)

Given an array nums containing n integers, determine whether there are three elements a, b, c in nums such that a + b + c = 0? Please find all triples whose sum is 0 and does not repeat. Note: Answers cannot contain duplicate triples.

示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]

示例 2:
输入:nums = []
输出:[]

示例 3:
输入:nums = [0]
输出:[]

My train of thought:

My teacher once said: "There is no problem that two for loops can't solve, if there is, add another". The editor adopts the concept of brute force solution and bubble sort. After looking at other people's plans, I found that the one I wrote is easier to understand, and the time and memory consumption are at a medium-to-high level, which is not bad.

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        // 先排序,方便计算
        Arrays.sort(nums);
        // 把题干中的0当成变量设置,让代码更灵活
        int sum = 0;
        for (int i = 0;i < nums.length;i++) {
            // 排序之后如果第一个元素已经大于 sum,那么无论如何组合都不可能凑成三元组
            // 直接返回结果就可以了
            if (nums[i] > sum)  break;

            // 错误去重方法,将会漏掉-1,-1,2 这种情况
            // if (nums[i] == nums[i + 1]) continue;

            if (i > 0 && nums[i] == nums[i - 1]) continue;

            int left = i + 1, right = nums.length - 1;
            while (right > left) {
                int temp = nums[i] + nums[left] + nums[right];
                if (temp == sum) {
                    result.add(Arrays.asList(nums[i], nums[left], nums[right]));

                    // 去重用的
                    while (right > left && nums[left] == nums[left+1]) left++;
                    while (right > left && nums[right] == nums[right-1]) right--;

                    // 找到答案时,双指针同时收缩
                    left++;
                    right--;
                } else if (temp > sum) {
                    right--;
                } else {
                    left++;
                }
            }
        }
        return result;
    }
}

Topic 2: Sum of the three closest numbers

[From LeetCode - 16] (Moderate)

You are given an integer array nums of length n and a target value target. Please select the three integers from nums whose sum is closest to target. Returns the sum of these three numbers. Note: It is assumed that exactly one solution exists for each set of inputs.

示例 1:
输入:nums = [-1,2,1,-4], target = 1
输出:2
解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。

示例 2:
输入:nums = [0,0,0], target = 1
输出:0
 
提示:
3 <= nums.length <= 1000
-1000 <= nums[i] <= 1000
-104 <= target <= 104

My train of thought:

This is a variation of the LeetCode - 15 question. The idea is the same, but the question does not necessarily equal the target value. The closest idea is to use the absolute value Math.abs() to ensure the closest result.

class Solution {
    public int threeSumClosest(int[] nums, int target) {
        // 先排序
        Arrays.sort(nums);
        int min = nums[0] + nums[1] + nums[2];
        for (int i = 0;i < nums.length;i++) {
            // 设置左右指针
            int left = i+1, right = nums.length-1;
            while (right > left) {
                int threeSum = nums[i] + nums[left] + nums[right];
                // 计算最小绝对值的min
                if (Math.abs(threeSum - target) < Math.abs(min - target)) {
                    min = threeSum;
                }
                if (threeSum > target) {
                    right--;
                } else if (threeSum < target) {
                    left++;
                } else {
                    // 如果已经等于 target 的话, 肯定是最接近的
                    return threeSum;
                }
            }
        }
        // 通知GC,本行代码影响不大
        System.gc();
        return min;
    }
}

Guess you like

Origin blog.csdn.net/weixin_44259720/article/details/123200449