Leetcode15 - 三数之和

例题:

Leetcode15 - 三数之和_第1张图片

其实这道题类似于力扣的40题组合的题目。

https://blog.csdn.net/qq_63748940/article/details/134979657?spm=1001.2014.3001.5501

分析:

给定了一个数组,先排好序:nums = [ -4, -1, -1, 0, 1, 2],     题目要求返回所有和为0且不重复的三元组。

这道题可以用之前两数之和的解法。三数之和,我们可以先固定一个数,比如先固定 - 4,那么接下来我们要找的两个数之和等于 4 就行了,看看能不能找到解,若找到解了,先把存储在栈中的元素放入集合,然后再向集合中加入其它满足要求的元素;若不能找到解,则固定其他的数。固定 -1, 0,1,2(数组中重复的元素不用再次固定) 

注意:运用之前两数之和的解法需要数组先排好序。

Leetcode15 - 三数之和_第2张图片

此图中已经固定了 - 4,接下来找剩下两数之和等于target = 4 就可以了。

代码实现:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

public class SumLeetcode15 {
    public static List> threeSum(int[] nums) {
        List> result = new ArrayList<>();
        Arrays.sort(nums);
        dfs(3, 0, nums.length - 1, 0, nums, new LinkedList<>(), result);
        return result;
    }

    /**
     * @param n      一共有n个数,n数之和
     * @param i      固定好一个元素后,该元素右边的一个数的索引
     * @param j      数组最右侧的元素
     * @param target 目标元素
     * @param nums   原始数组
     * @param stack  把固定的元素存入栈中
     * @param result 用于返回的大集合
     */
    public static void dfs(int n, int i, int j, int target, int[] nums,
                           LinkedList stack, List> result) {
        if (n == 2) { //剩下两个数
            twoSum(i, j, nums, target, stack, result);
            return;
        }

        //先固定一个数
        for (int k = i; k < j - (n - 2); k++) {
            //检查是否重复固定
            if (k > i && nums[k] == nums[k - 1]) {
                continue;
            }
            //固定一个数字,再尝试 n - 1 数字之和
            stack.push(nums[k]);
            dfs(n - 1, k + 1, j, target - nums[k], nums, stack, result);
            stack.pop();
        }
    }

    public static void twoSum(int i, int j, int[] numbers, int target,
                              LinkedList stack, List> result) {
        while (i < j) {
            int sum = numbers[i] + numbers[j];
            if (sum < target) {
                i++;
            } else if (target < sum) {
                j--;
            } else { //找到了
                List list = new ArrayList<>(stack);  //把固定的元素加入集合中
                list.add(numbers[i]);
                list.add(numbers[j]);
                result.add(list);
                //缩小范围找其它解
                i++;
                j--;
                while (i < j && numbers[i] == numbers[i - 1]) {
                    i++;
                }
                while (i < j && numbers[j] == numbers[j + 1]) {
                    j--;
                }
            }
        }
    }

    public static void main(String[] args) {
        //int[] candidates = {-4, -1, -1, 0, 0, 1, 1, 2};  //[-1,0,1,2,-1,-4]
        int[] candidates = {-1, 0, 1, 2, -1, -4};

        System.out.println(threeSum(candidates));
    }
}

你可能感兴趣的:(算法,数据结构)