77. 组合 | 暴力求解 | 组合 | 暴力递归 | 回溯

力扣打卡:77. 组合

解题思路

  • 需要求解所有的可能, 并且没有子问题重复的题目,那么一定是暴力求解,可以考虑回溯
回溯的框架
// 常用的结果储存
List<T> track = new LinkedList<>();
List<List<T>> res = new LinkedList<>();

public void backtrack(){ // 先将需要的参数确定下来,然后一边写流程一边考虑是否加参数
    if(终止条件){
        存放结果集,return ;
    }
    for(所有的可能){ // 三步骤 做选择, 去递归, 撤销选择 -- > 做选择 去尝试 再反悔
        1. 做选择
        2. backtrack()
        3. 撤销选择
    }
}
思路
  1. 根据题目的要求可以知道, 有k个数字在组合, 那么也就是说明了终止条件, 存放可能的 tracksize 只要等于 k,那么久开始存放结果
  2. 因为任意一个元素不是使用任意次,而是只是使用一次
    • for 的遍历所有可能, 应该变为 这个元素后的所有元素 或者 这个元素前的所有元素
  3. 遍历所有的可能的同时, 每次都需要做三个步骤
    • 做选择 (做选择)
    • 去递归 (去尝试)
    • 撤销选择 (再反悔)

代码

class Solution {

    List<Integer> track = new LinkedList<>();
    List<List<Integer>> res = new LinkedList<>();

    public List<List<Integer>> combine(int n, int k) {
        // 所有可能的集合,没有重叠的子问题,暴力求解,也就是回溯
        backtrack(1, n, k);
        return res;
    }
    public void backtrack(int p, int n, int k){
        if(track.size()==k){// 根据题目给定的内容和条件,写出终止条件
            res.add(new LinkedList<>(track));
            return ;
        }

        // 暴力穷举出所有的可能
        for(int i=p; i<=n; i++){

            track.add(i); // 做选择
            backtrack(i+1, n, k); // 继续递归
            track.remove(track.size()-1); // 递归之后撤销选择

        }
    }   
}

你可能感兴趣的:(学习记录,笔记,leetcode,算法,动态规划)