LeetCode刷题知识点总结——回溯算法

回溯算法

一、理论基础

1.回溯算法主要用于解决以下问题:组合、排列、切割、子集、排列、棋盘。

2.回溯算法分析模板如下:

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

3.组合问题

 class Solution {
 public:
     vector<vector<int>> result; // 存放符合条件结果的集合
     vector<int> path; // 用来存放符合条件结果
     void backtracking(int n, int k, int startIndex) {
         if (path.size() == k) {
             result.push_back(path);
             return;
        }
         for (int i = startIndex; i <= n; i++) {  
 //剪枝优化:在集合n中至多可开始的位置:n-(k-path.size())+1
             path.push_back(i); // 处理节点
             backtracking(n, k, i + 1); // 递归
             path.pop_back(); // 回溯,撤销处理的节点
        }
    }
     vector<vector<int>> combine(int n, int k) {
         result.clear(); // 可以不写
         path.clear();   // 可以不写
         backtracking(n, k, 1);
         return result;
    }
 };

4.组合总和问题

 class Solution {
 public:
     vector<vector<int>> result; // 存放符合条件结果的集合
     vector<int> path; // 用来存放符合条件结果
     void backtracking(vector<int>& num, int target,int sums,int startIndex) {
         if(sums>target) return;
         if (sums==target) {
             result.push_back(path);
             return;
        }
         for (int i = startIndex; i < num.size(); i++) {  
 //剪枝优化:在集合n中至多可开始的位置:n-(k-path.size())+1(如果规定了组合个数,且是递增数组)
             path.push_back(num[i]); // 处理节点
             sums +=num[i];
             backtracking(num, target, sums,i ); // 递归
             sums-=num[i];
             path.pop_back(); // 回溯,撤销处理的节点
        }
    }
     vector<vector<int>> combine(vector<int>& num, int target) {
         result.clear(); // 可以不写
         path.clear();   // 可以不写
         backtracking(num, target,0,1);
         return result;
    }
 };

 

 

 
posted @ 2022-04-05 17:20  Whp_bicycle  阅读(79)  评论(0编辑  收藏  举报