代码随想录算法训练营第24天|● 理论基础 ● 77. 组合

发布于:2024-06-07 ⋅ 阅读:(116) ⋅ 点赞:(0)

回溯理论基础

回溯:回溯搜索法,本质就是暴力搜索,效率并不高

回溯法解决的问题

回溯法,一般可以解决如下几种问题:

  • 组合问题:N个数里面按一定规则找出k个数的集合
  • 切割问题:一个字符串按一定规则有几种切割方式
  • 子集问题:一个N个数的集合里有多少符合条件的子集
  • 排列问题:N个数按一定规则全排列,有几种排列方式
  • 棋盘问题:N皇后,解数独等等

回溯算法模板

void backtracking(参数) {
    if (终止条件) {
        存放结果;
        return;
    }

    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
        处理节点;
        backtracking(路径,选择列表); // 递归
        回溯,撤销处理结果
    }
}

组合问题

题目链接:

77. 组合 - 力扣(LeetCode)

这段Java代码定义了两个静态函数dfs和combine以及两个静态变量res和list。其中,res是一个存储结果的二维列表,list是一个临时列表,用于存储当前组合的数字。
dfs函数通过深度优先搜索的方式生成所有长度为k的组合,这些组合由1到n之间的数字构成。函数的参数包括k(组合的长度)、n(数字的上限)和start(当前搜索的起始数字)

代码:

class Solution {

    public List<List<Integer>> res = new ArrayList<>();
    public List<Integer> list = new ArrayList<>();

    public void dfs(int k, int n, int start) {
        if (list.size() == k) {//当list的大小大于k,说明已经搜集了k个结果
            res.add(new ArrayList<>(list));
            return ;
        }
        for (int i = start; i <= n ; i++) {//对1-n进行遍历
            list.add(i);
            dfs(k, n, i + 1);//向下一个位置递归
            list.remove(list.size() - 1);//回溯
        }
        return ;
    }

    public List<List<Integer>> combine(int n, int k) {
        dfs(k,n,1);
        return res;
    }
}

 剪枝优化:

 for (int i = start; i <= n - (k - list.size()) + 1; i++) {
            list.add(i);
            dfs(k, n, i + 1);
            list.remove(list.size() - 1);
        }


网站公告

今日签到

点亮在社区的每一天
去签到