算法-回溯算法

之前写的回溯算法题,都没有时间整理,导致过了一段时间,再重新写这些题,就很懵的样子,所以来重新整理一下,这篇估计会不断的更新.

我理解的回溯算法,其实就是一种暴力的for循环,只是这种循环是可以通过代码实现的,比如要实现k层的for循环,k是一个未知数,那么代码其实是写不出来的,因为k未知,就不知道要写多少个for循环,但是可以通过回溯,当然这么一说,回溯又有点像递归了。

回溯解决的问题:

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

题目依次会慢慢记录下来

1.组合问题的基础题
Leetcode-77题-组合

给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。

示例:

输入: n = 4, k = 2
输出:
[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]

核心Java代码如下
public class Main{
  public List<List<Integer>> combine(int n, int k) {
        List<List<Integer>> res= new ArrayList<>();
        backTracking(res,new ArrayList<>(),1,n,k);
        return res;
    }
  
  public void backTracking(List<List<Integer>> res, List<Integer> list, int index, int n, int k){
        //首先要写退出,即返回上一层,当数组list的长度==k的时候 就退出 并保存下来 存到res
        if(list.size() == k){
          res.add(new ArrayList<>(list));
          return;
        }

        // n - ( k - list.size()) + 1 就是一个剪枝的过程 把不可能的数据直接过滤掉 就不会进一步回溯 节省时间
        for(int i = index, i <= n - ( k - list.size()) + 1; i++){
          list.add(i);
          //进行回溯
          backTracking(res,list,i+1,n,k);
          // 还要清除掉刚加入的数据
          list.remove(list.size() - 1);
        }
  }
}


posted @ 2021-03-31 23:33  宇。  阅读(57)  评论(0)    收藏  举报