day-24 代码随想录算法训练营(19)回溯part01

77.组合

思路一:回溯相当于枚举,所以我们遍历1-n的每一个数字,然后在遍历第i位的同时递归出第i+1~n位的组合结果,跟树的形式相似。

day-24 代码随想录算法训练营(19)回溯part01_第1张图片

  •  如上图所示,当长度为k时,即退出递归
  • 可对遍历到第i位以及剩下位数与k进行比较进行一个剪枝(比如遍历到4时,4后面没有数字,不能组成个数为2的组合)
class Solution {
public:
    vector>res;
    void judge(int n,int index,int k,vector&mid){
        if(mid.size()==k){
            res.push_back(mid);
            return;
        }
        for(int i=index;i<=n-(k-mid.size())+1;i++){
            mid.push_back(i);
            judge(n,i+1,k,mid);
            mid.pop_back(); //回溯,不回溯的话无法继续往下
        }
        
    }
    vector> combine(int n, int k) {
        //思路:遍历1-n为index,然后传入进行第k-index-1的组合,使用中间vector保存,当vector的size==k时加入res
        vectormid;
        judge(n,1,k,mid);
        return res;
    }
};

216.组合总和III

分析:和上一题如出一辙,只是多加了一个判断总和,不过数字固定到1-9
class Solution {
public:
    vector>res;
    vectormid;
    void backtrace(int k,int n,int sum,int startIndex){
        if(sum>n || mid.size()>k)
            return;
        if(sum==n && mid.size()==k){
            res.push_back(mid);
            return;
        }
        for(int i=startIndex;i<=9-(k-mid.size())+1;i++){
            sum+=i;
            mid.push_back(i);
            backtrace(k,n,sum,i+1);
            mid.pop_back();
            sum-=i;
        }
    }
    vector> combinationSum3(int k, int n) {
        //思路:和77题如出一辙
        backtrace(k,n,0,1);
        return res;

    }
};

17.电话号码的字母总和

画图分析:

day-24 代码随想录算法训练营(19)回溯part01_第2张图片

 思路一:首先横向递归,对每一个位置的字符串数组进行递归遍历
            其次在递归遍历之前,对该位置的字符串数组进行遍历添加
            在递归遍历数组结束之后,需要回溯删除本数组添加的字符,以便于回溯到上一数组
class Solution {
public:
    vectordists={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
    vectorres;
    void backtrace(string digits,int start,string&mid){
        if(start==digits.size()){//递归遍历终点
            res.push_back(mid);
            return;
        }
        for(int i=0;i letterCombinations(string digits) {
       if(digits.size()==0) return res;//极端情况
       string mid;
       backtrace(digits,0,mid);
       return res;
    }
};

131.分割回文串

思路:先使用for循环横向遍历,从每一个点截取,并且判断当前截取的字符串 i 是否为回文串
           1.当属于回文串时,把当前字符串加入数组,并且递归往下,从下一个字符开始再次使用for循环横向遍历,判断是否是回文字符
           2.当不属于回文串时,直接返回
 注意终止条件:当在递归过程中开始截取的位置startIndex大于等于原字符串的长度时,表示已经递归到了尽头

day-24 代码随想录算法训练营(19)回溯part01_第3张图片

你可能感兴趣的:(代码随想录算法训练营(19期),算法学习,C++,算法,leetcode,数据结构)