力扣40. 组合总和 II(java 回溯法)

Problem: 40. 组合总和 II

文章目录

  • 题目描述
  • 思路
  • 解题方法
  • 复杂度
  • Code

题目描述

力扣40. 组合总和 II(java 回溯法)_第1张图片力扣40. 组合总和 II(java 回溯法)_第2张图片

思路

在使用回溯之前我们首先可以明确该题目也是一种元素存在重复但不可复用的组合类型问题。而此题目可以参考下面一题的大体处理思路:

Problem: 90. 子集 II

具体的:

1.首先对给定的数组排序
2.我们要记录一个决策路径path,一个路径和pathSum,我们在回溯的过程中若当前的路劲和pathSum等于给定的target时我们将当前的决策路径添加到结果集和中并返回;若路径和pathSum在递归过程中大于了target则直接返回;
3.在回溯函数中我们每次循环开始穷举,起始位置(i)为当前的决策阶段(start),并判断若i > start && candidates[i] == candidates[i - 1]此处的candidates为回溯函数中的可选列表,则不递归达到去重的效果,最后恢复当前决策路径path与路径和pathSum

解题方法

1.定义二维结果集合result,决策路径path,路径和pathSum
2.对给定数组排序
3.编写调用回溯函数,初始决策阶段为0:

3.1当前的路劲和pathSum等于给定的target时我们将当前的决策路径添加到结果集和中并返回;若路径和pathSum在递归过程中大于了target则直接返回;
3.2for循环穷举,起始位置i为当前的决策阶段start,并判断若i > start && candidates[i] == candidates[i - 1],c则continue,不递归该分支
3.3每次将当前可选列表上的值添加到路径值pathSum,并递归调用,最后恢复当前决策路径,和路径和

复杂度

时间复杂度:

O ( n × 2 n ) O(n \times 2^n) O(n×2n)

空间复杂度:

O ( n ) O(n) O(n)

Code

class Solution {
    //Result list
    private List<List<Integer>> result = new ArrayList<>();
    //Decision path
    private List<Integer> path = new ArrayList<>();
    //Recode the sum of path
    private int pathSum = 0;

    /**
     * Gets all and a subset of the specified values
     *
     * @param candidates Specific list
     * @param target     target
     * @return List>
     */
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        Arrays.sort(candidates);
        backtrack(candidates, 0, target);
        return result;
    }

    /**
     * Solve for all subsets of specified values using backtracking
     *
     * @param candidates Optional list
     * @param start      Decision stage
     * @param target     target
     */
    private void backtrack(int[] candidates, int start, int target) {
        //End condition
        //if the pathSum equals the target
        if (pathSum == target) {
            result.add(new ArrayList<>(path));
            return;
        }
        //End condition
        //If the path bigger than target
        if (pathSum > target) {
            return;
        }
        for (int i = start; i < candidates.length; ++i) {
            if (i > start && candidates[i] == candidates[i - 1]) {
                continue;
            }
            path.add(candidates[i]);
            pathSum += candidates[i];
            backtrack(candidates, i + 1, target);
            //Recover the current Decision Path of path
            path.remove(path.size() - 1);
            pathSum -= candidates[i];
        }
    }
}

你可能感兴趣的:(力扣题目,leetcode,java,算法)