递归专题训练详解(回溯,剪枝,深度优先)

这篇具有很好参考价值的文章主要介绍了递归专题训练详解(回溯,剪枝,深度优先)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.汉诺塔问题

在经典汉诺塔问题中,有 3 根柱子及 N 个不同大小的穿孔圆盘,盘子可以滑入任意一根柱子。一开始,所有盘子自上而下按升序依次套在第一根柱子上(即每一个盘子只能放在更大的盘子上面)。移动圆盘时受到以下限制:
(1) 每次只能移动一个盘子;
(2) 盘子只能从柱子顶端滑出移到下一根柱子;
(3) 盘子只能叠在比它大的盘子上。

//确定子问题处理方式是相同的
//确定递归函数的函数头传参
//确定函数体也就子问题的处理方式
//判断函数出口

class Solution {
public:
    void hanota(vector<int>& A, vector<int>& B, vector<int>& C) {
        int n=A.size();
        dfs(A,B,C,n);
    }

    void dfs(vector<int>& A,vector<int>&B ,vector<int>& C,int n){
        if(n==1){
        C.push_back(A.back());//这里一定是要A.back(),可以画一下递归展开图
        A.pop_back();
        return;
        }//函数出口

        dfs(A,C,B,n-1);//不关心如何递归下去的,认为该函数一定能够帮我做到把a上的n-1数据借助c挪动b上

        C.push_back(A.back());//这里一定是要A.back(),可以画一下递归展开图
        A.pop_back();

        dfs(B,A,C,n-1);//同样认为该函数一定能把b上残留的n-1个数据借助a放到c上面
    }
};

2.合并升序链表

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        ListNode* newHead=merge(list1,list2);
        return newHead;
    }

    ListNode* merge(ListNode* l1,ListNode* l2){
        if(l1==nullptr) return l2;
        if(l2==nullptr) return l1;


        if(l1->val<l2->val){
            l1->next=merge(l1->next,l2);
            return l1;//返回拼好的头节点
        }

        else{
            l2->next=merge(l2->next,l1);
            return l2;
        }

    }
};

3. 反转链表

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(head==nullptr||head->next==nullptr)return head;
        ListNode* newhead=reverseList(head->next);//认为一定可以返回一个已经逆序的子链表
        head->next->next=head;//让已经逆序的子序列的头节点指向子序列的上一个头节点
        head->next=nullptr;
        return newhead;//这里newhead一直是没有移动过的,一直都是新的链表的头结点。
    }
};

4. 两两交换链表中的节点

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        if(head==nullptr||head->next==nullptr)
        {
            return head;
        }

        ListNode* new_head=head->next;
        ListNode* tmp=head->next->next;//小心中途修改的问题
        head->next->next=head;
        head->next=swapPairs(tmp);
        return new_head;
    }
};

5. Pow(x,n)

  • -100.0 < x < 100.0
  • -2^31 <= n <= 2^31-1
  • -10^4 <= x^n <= 10^4

本题需要注意负数的情况和超int取值范围的情况

这样会语法报错。。。

递归专题训练详解(回溯,剪枝,深度优先),深度优先,算法

class Solution {
public:
    double myPow(double x, int n) 
    {
        return n > 0 ?pow(x,n) : 1.0/pow(x,-(long long)n );
    }

    double pow(double x,long long n)
    {
        if(n==0) return 1.0;

        double ret=pow(x,n/2);

        if(n%2==0){return ret*ret;}
        else{return ret*ret*x;}
    }
};

6. 布尔逻辑二叉树

class Solution {
public:
    bool evaluateTree(TreeNode* root) {
        if(root->left==nullptr)
        {
            if(root->val==1)return true; 
            else return false;
        }

        bool left=evaluateTree(root->left);
        bool right=evaluateTree(root->right);
        if(root->val==2)
        {
            return left || right;
        }
        else 
        {
            return left && right;
        }

    }
};

7.根到叶子之和 

给你一个二叉树的根节点 root ,树中每个节点都存放有一个 0 到 9 之间的数字。

每条从根节点到叶节点的路径都代表一个数字:

  • 例如,从根节点到叶节点的路径 1 -> 2 -> 3 表示数字 123 。

计算从根节点到叶节点生成的 所有数字之和 。

叶节点 是指没有子节点的节点。

递归专题训练详解(回溯,剪枝,深度优先),深度优先,算法

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */

//函数头设计,我们认为传入一个节点,那么就会算出此节点到所有节点的数字之和
//函数体:从上一层获得此前的所有数字组合再拼上此层,所以需要多设计一个参数来记录
//函数出口:当没有孩子的时候
class Solution {
public:
    int sumNumbers(TreeNode* root) {
        return dfs(root,0);
    }

    int dfs(TreeNode* root,int presum)
    {
        // if(root==nullptr)
        // {
        //     return presum;题目给的一定是有一个节点
        // }

        presum=presum*10+root->val;
        std::cout<<presum<<std::endl;
        int ret=0;//因为函数的功能是用来计算之和并返回,所以不能直接presum传入,此处presum只是用于记录已经遍历了的数字。

        if(root->left==nullptr&&root->right==nullptr){
            return presum;
        }

        if(root->left) ret+=dfs(root->left,presum);
        if(root->right) ret+= dfs(root->right,presum);

        return ret;
    }
};

8.二叉树剪枝

给定一个二叉树 根节点 root ,树的每个节点的值要么是 0,要么是 1。请剪除该二叉树中所有节点的值为 0 的子树。

节点 node 的子树为 node 本身,以及所有 node 的后代。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
//函数体设计
//返回一个已经剪枝的根节点

//函数出口:当自己是空的时候返回空,处理动作一致

class Solution {
public:
    TreeNode* pruneTree(TreeNode* root) {
        // if(root==nullptr)
        // {
        //     return nullptr;
        // }

        if(root->left) root->left=pruneTree(root->left);
        if(root->right) root->right=pruneTree(root->right);

        if(root->left==nullptr&&root->right==nullptr&&root->val==0)
        //走到头才算是树枝当树枝被剪完了自己也就是树枝的。
        {
            //delete root;
            root=nullptr;
            // return nullptr;
        }

        return root;
    }
};

9.验证二叉搜索树(注意剪枝)

递归专题训练详解(回溯,剪枝,深度优先),深度优先,算法

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
long long prev_val=LONG_MIN;

    bool isValidBST(TreeNode* root) {
        if(root==nullptr)
        {
            return true;
        }
        bool left=isValidBST(root->left);

        if(left==false) return false;//剪枝
        
        bool cur=false;
        if(root->val>prev_val)
        {
            prev_val=root->val;
            cur=true;
        }

        if(right==false) return false;//剪枝

        bool right=isValidBST(root->right);
        //cout<< root->val;



        return left&&right&&cur;
    }
};

10. 二叉搜索树第k小的元素(二叉搜索树中序遍历是一个有序序列)

递归专题训练详解(回溯,剪枝,深度优先),深度优先,算法

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int count;
    int ret;

    int kthSmallest(TreeNode* root, int k) {
        count=k;
        return dfs(root);
    }

    int dfs(TreeNode* root)
    {
        if(root==nullptr){
            return ret;
        }
        ret=dfs(root->left);
        if(count==0)
        {
            return ret;
        }
        ret=root->val;
        count--;
        ret=dfs(root->right);

        return ret;
    }
};

11. 二叉树的所有路径

12. 全排列

1.此处path设置为全局变量更好,虽然回溯时需要修改,但是节省一些空间并且效率更高。:

class Solution {
public:

    vector<vector<int>> ret;
    vector<bool> check;//用于记录哪些数字使用过了而达到剪枝的效果,回溯的时候需要把使用过的数字还回去
    vector<int> path;//这里的path最好使用全局变量
    vector<vector<int>> permute(vector<int>& nums) {
        check.resize(nums.size());
        dfs(nums,path);
        return ret;
    }

    void dfs(vector<int>& nums,vector<int> path)
    {
        if(nums.size()==path.size())
        {
            ret.push_back(path);
            return ;
        }

        for(int i=0;i<nums.size();i++)
        {


            if(check[i]==true)
            {
                continue;
            }
            check[i]=true;
            vector<int> tmp=path;
            tmp.push_back(nums[i]);
            dfs(nums,tmp);

            check[i]=false;
        }
    }
};

2. 修改后:

class Solution {
public:

    vector<vector<int>> ret;
    vector<bool> check;//用于记录哪些数字使用过了而达到剪枝的效果,回溯的时候需要把使用过的数字还回去
    vector<int> path;//这里的path最好使用全局变量
    vector<vector<int>> permute(vector<int>& nums) {
        check.resize(nums.size());
        dfs(nums,path);
        return ret;
    }

    void dfs(vector<int>& nums,vector<int>& path)
    {
        if(nums.size()==path.size())
        {
            ret.push_back(path);
            return ;
        }

        for(int i=0;i<nums.size();i++)
        {


            if(check[i]==true)
            {
                continue;
            }
            check[i]=true;
            // vector<int> tmp=path;
            // tmp.push_back(nums[i]);
            path.push_back(nums[i]);
            dfs(nums,path);

            check[i]=false;//向下递归完后恢复现场
            path.pop_back();
        }
    }
};

13. 二叉树的所有路径

给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。

叶子节点 是指没有子节点的节点。

13. 二叉树的所有路径

给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。

叶子节点 是指没有子节点的节点。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<string> ret;
    string path;
    int i=0;
    vector<string> binaryTreePaths(TreeNode* root) 
    {
        if(root==nullptr) return ret;//假设会传入空,最好不要写在dfs函数里面
        dfs(root,path);
        return ret;
    }

    void dfs(TreeNode* root,string path)
    {
        path+=to_string(root->val);
        if(root->left==nullptr&&root->right==nullptr)
        {
            ret.push_back(path);
            return;
        }
        path+="->";
        if(root->left) dfs(root->left,path);
        if(root->right) dfs(root->right,path);//剪枝,并且达到了不会传入空的效果

    }
};

14. 子集

class Solution {
public:
    vector<vector<int>> ret;
    vector<int> path;
    //vector<bool> check;
    vector<vector<int>> subsets(vector<int>& nums) 
    {
        dfs(nums,0);
        return ret;
    }

    void dfs(vector<int>& nums ,int pos)
    {
        ret.push_back(path);

        for(int i=pos;i<nums.size();i++)
        {
            path.push_back(nums[i]);
            dfs(nums,i+1);
            path.pop_back();
        }

    }
};

15. 异或和按位或分清楚

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

递归专题训练详解(回溯,剪枝,深度优先),深度优先,算法

class Solution {
public:
    int ret;//返回值总和

    int tmp=0;//记录当前层异或的值
    int subsetXORSum(vector<int>& nums) {
        dfs(nums,0);
        return ret;
    }

    void dfs(vector<int>& nums,int pos)
    {
        ret+=tmp;
        for(int i=pos;i<nums.size();i++)
        {
            tmp^=nums[i];

            dfs(nums,i+1);

            tmp^=nums[i];
        }
    }
};

16. 全排列 ||

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

递归专题训练详解(回溯,剪枝,深度优先),深度优先,算法

class Solution {
public:
    vector<vector<int>> ret;
    vector<bool> check;
    vector<int> path;
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        check.resize(nums.size(),false);
        //没有上句会报错Line 84: Char 2: runtime error: store to null pointer of type 'std::_Bit_type' (aka 'unsigned long') (stl_bvector.h)
        dfs(nums);
        return ret;
    }

    void dfs(vector<int>& nums)
    {
        if(path.size()==nums.size())
        {
            ret.push_back(path);
            return;
        }

        for(int i=0;i<nums.size();i++)
        {


            if(check[i]==true ||( i!=0 && nums[i]==nums[i-1] && check[i-1] == false ))
            //check[i-1]==false;说明nums[i]和nums[i-1]同层进行判断比较。
            {
                continue;
            }
            
            check[i]=true;
            path.push_back(nums[i]);
            dfs(nums);
            check[i]=false;
            path.pop_back();
        }
    }
};

17. 电话号码

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

递归专题训练详解(回溯,剪枝,深度优先),深度优先,算法

class Solution {
public:
    vector<string> ret;
    string path;
    vector<string> hash={" ", " ", "abc", "def", "ghi","jkl","mno","pqrs","tuv","wxyz"};

    vector<string> letterCombinations(string digits) 
    {
        if(digits.size()==0){
            return ret;
        }
        dfs(digits,0);
        return ret;
    }

    void dfs(string& digits,int pos)
    {

        if(path.size()==digits.size())
        {
            ret.push_back(path);
            return;
        }

        for(auto a: hash[digits[pos]-'0'] )
        {
            path.push_back(a);
            dfs(digits,pos+1);
            path.pop_back();
        }
    }
};

18. 括号生成

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

递归专题训练详解(回溯,剪枝,深度优先),深度优先,算法

class Solution {
public:
    int max;
    int left,right;
    vector<string> ret;
    string path;
    vector<string> generateParenthesis(int n)
    {
        max=n;
        dfs();
        return ret;
    }

    void dfs()
    {
        if(right == max)
        {
            ret.push_back(path);
            return;
        }

        if(left < max)
        {
            path.push_back('(');
            ++left;
            dfs();
            --left;
            path.pop_back();
        }

        if(right < left)
        {
            path.push_back(')');
            right++;
            dfs();
            right--;
            path.pop_back();
        }
    }
};

19. 组合

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

递归专题训练详解(回溯,剪枝,深度优先),深度优先,算法

class Solution {
public:
    int max;
    vector<int> path;
    vector<vector<int>> ret;
    vector<vector<int>> combine(int n, int k) {
        max=k;
        dfs(1,n);
        return ret;
    }

    void dfs(int pos,int& n)
    {
        if(path.size() == max )
        {
            ret.push_back(path);
            return;
        }

        for(int i=pos;i<n+1;++i)
        {
            path.push_back(i);
            dfs(i+1,n);//是要传入i+1而不是pos+1
            path.pop_back();
        }
    }
};

20.目标和

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

注意单单int的反复加加减减还是非常耗时的,这里不是拷贝一个vector之类的对象,所以反而恢复现场的操作会更慢从而超时。

递归专题训练详解(回溯,剪枝,深度优先),深度优先,算法

class Solution {
public:
    // int ret=0;
    // int path;
    // int now_target;
    // int findTargetSumWays(vector<int>& nums, int target) 
    // {
    //     now_target=target;
    //     dfs(0,1,nums);
    //     return ret;

    // }

    // void dfs(int pos,int level,vector<int>& nums)
    // {
    //     if(nums.size()+1 == level)
    //     {
    //         if(path==now_target)
    //         {
    //             ret++;
    //         }
    //         return;
    //     }

    //     {
    //         path+=nums[pos];
    //         dfs(pos+1,level+1,nums);
    //         path-=nums[pos];
    //     }

    //     {
    //         path-=nums[pos];
    //         dfs(pos+1,level+1,nums);
    //         path+=nums[pos];
    //     }
    // }
    int ret=0;
    //int path;
    int now_target;
    int findTargetSumWays(vector<int>& nums, int target) 
    {
        int path=0;
        now_target=target;
        dfs(0,1,nums,path);
        return ret;

    }

    void dfs(int pos,int level,vector<int>& nums,int path)
    {
        if(nums.size()+1 == level)
        {
            if(path==now_target)
            {
                ret++;
            }
            return;
        }

        {
            //path+=nums[pos];
            dfs(pos+1,level+1,nums,path+nums[pos]);
            //path-=nums[pos];
        }

        {
            dfs(pos+1,level+1,nums,path-nums[pos]);
        }
    }

};

21. 组合总和

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

递归专题训练详解(回溯,剪枝,深度优先),深度优先,算法

class Solution {
public:
//第一个位置的数选一个两个三个依次往下递归
//第二个数也是如此
//恢复现场时候要把本层push_back进去的所有数据全部pop_back出去
    vector<vector<int>> ret;
    vector<int> path;
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) 
    {
        dfs(candidates,0,target,0);
        return ret;
    }

    void dfs(vector<int>& candidates,int sum,const int& target,int pos)//sum为递归到本层的和
    {
        if(sum>=target)
        {
            if(sum==target)ret.push_back(path);
            return;
        }
        if(pos==candidates.size())//防止越界访问而导致的内存问题
        {
            return;
        }

        for(int i=0;sum+i*candidates[pos]<=target;i++)
        {
            //cout<<candidates[pos];
            if(i) path.push_back(candidates[pos]); //注意这个if(i)
            dfs(candidates,sum+i*candidates[pos],target,pos+1);
        }
        //cout<<endl;

        for(int i=1;sum+i*candidates[pos]<=target;i++)//上面的if(i)决定了这里从i==1开始删除
        {
            //cout<<candidates[pos];
            path.pop_back();
        }
        //cout<<endl;

    }

};

此题还有另一种解法

就是每一个位置的数对其所有可能进行枚举

22. 字母大小写全排列

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

递归专题训练详解(回溯,剪枝,深度优先),深度优先,算法

class Solution {
public:
    string path;
    vector<string> ret;
    vector<string> letterCasePermutation(string s) 
    {
        dfs(0,s);
        return ret;
    }

    void dfs(int pos,const string& s)
    {
        if(pos==s.size())
        {
            ret.push_back(path);
            return;
        }
        char tmp=s[pos];

        path.push_back(tmp);
        dfs(pos+1,s);
        path.pop_back();
        if(tmp<'0'||tmp>'9')//如果是字符
        {
            change(tmp);
            path.push_back(tmp);
            dfs(pos+1,s);
            path.pop_back();

        }

    }

    void change(char& ch)
    {
        if(ch>='a'&&ch<='z')//这里的-= +=l弄错了
        {
            ch-=32;
        }
        else if(ch>='A'&&ch<='Z')
        {
            ch+=32;
        }
    }
};

23. 优美的排列

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

递归专题训练详解(回溯,剪枝,深度优先),深度优先,算法文章来源地址https://www.toymoban.com/news/detail-723626.html

class Solution {
public:
    vector<int> path;
    int ret;
    vector<bool> check;
    int max=0;
    int countArrangement(int n) {
        check.resize(n+1,false);
        path.resize(n+1);
        max=n;
        dfs(1);
        return ret;
    }
    void dfs(int pos)
    {
        if(max==pos)
        {
            ++ret;
            return;
        }

        for(int i=1;i<max+1;i++)
        {
            if(check[i]==true)
            {
                continue;
            }

            if(pos%i==0||i%pos==0)
            {
                check[i]=true;
                path.push_back(i);
                dfs(pos+1);
                path.pop_back();
                check[i]=false;
            }
        }
    }
};

到了这里,关于递归专题训练详解(回溯,剪枝,深度优先)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【算法】回溯:与递归,dfs的同质与分别,剪枝与恢复现场的详细理解,n皇后的回溯解法及算法复杂度分析。

    目录 ​编辑 1.什么是回溯 2.关于剪枝 3.关于恢复现场 4.题目:二叉树的所有路径(凸显恢复现场:切实感受回溯与深搜) 问题分析 ①函数设置为:void Dfs(root) ②函数设置为:void Dfs(root,path) 解题思想:使⽤深度优先遍历(DFS)求解。 代码实现 5.N后问题 问题分析 4皇后的放置

    2024年04月16日
    浏览(29)
  • 递归、搜索与回溯算法(专题六:记忆化搜索)

    目录 1. 什么是记忆化搜索(例子:斐波那契数) 1.1 解法一:递归 1.2 解法二:记忆化搜索 1.2.1 记忆化搜索比递归多了什么? 1.2.2 提出一个问题:什么时候要使用记忆化搜索呢? 1.3 解法三:动态规划 1.3.1 先复习一下动态规划的核心步骤(5个),并将动态规划的每一步对应

    2024年01月20日
    浏览(39)
  • 【C++】递归,搜索与回溯算法入门介绍和专题一讲解

    个人主页:🍝在肯德基吃麻辣烫 我的gitee:C++仓库 个人专栏:C++专栏 从本文开始进入递归,搜索与回溯算法专题讲解。 递归就是函数自己调用自己。 递归的本质是: 主问题:—相同的子问题 子问题:—相同的子问题 通过: 1)通过递归的细节展开图(前期可以,过了前期

    2024年02月09日
    浏览(27)
  • C语言递归+DFS(深度优先搜索算法)详解 图文并茂,手把手教你画树状图

    目录 一.标准定义 二.跳台阶(典型递归题目) 三.递归实现指数型枚举 四.递归实现排列型枚举 五.递归实现组合型枚举 六.DFS算法模板 深度优先搜索算法(Depth First Search,简称DFS): 一种用于遍历或搜索树或图的算法 。 沿着树的深度遍历树的节点, 尽可能深的搜索树的分

    2024年02月04日
    浏览(54)
  • 力扣--深度优先算法/回溯算法47.全排列 Ⅱ

    思路分析: 使用DFS算法进行全排列,递归地尝试每个可能的排列方式。 使用 path 向量保存当前正在生成的排列,当其大小达到输入数组的大小时,将其加入结果集。 使用 numvisited 向量标记每个数字是否已经被访问过,以确保每个数字在一个排列中只使用一次。 在递归过程中

    2024年03月13日
    浏览(36)
  • DFS(深度优先搜索)详解(概念讲解,图片辅助,例题解释,剪枝技巧)

    目录 那年深夏 引入 1.什么是深度优先搜索(DFS)? 2.什么是栈? 3.什么是递归? 图解过程  问题示例 1、全排列问题 2、迷宫问题 3、棋盘问题(N皇后)  4、加法分解 模板 剪枝 1.简介 2.剪枝的原则   3.剪枝策略的寻找的方法 4.常见剪枝方法 最后 他终于抬起头,眨了眨眼睛

    2023年04月08日
    浏览(28)
  • 专题一:递归【递归、搜索、回溯】

    什么是递归 函数自己调用自己的情况。 为什么要用递归 主问题-子问题        子问题-子问题 宏观看待递归 不要在意细节展开图,把函数当成一个黑盒,相信这个黑盒一定能完成任务。  如何写好递归   分析跟上一题差不多,不详解。 实现 pow(x, n) ,即计算  x  的整

    2024年02月07日
    浏览(33)
  • 专题二:二叉树的深搜【递归、搜索、回溯】

    深度优先遍历 (DFS,全称为DepthFirstTraversal),是我们树或者图这样的数据结构中常用的⼀种遍历算法。这个算法会尽可能深的搜索树或者图的分⽀,直到⼀条路径上的所有节点都被遍历完毕,然后再回溯到上⼀层,继续找⼀条路遍历。 在⼆叉树中,常⻅的深度优先遍历为:

    2024年02月07日
    浏览(30)
  • 第一周算法训练(dfs)(深度优先搜索算法)

    dfs: 深度优先搜索算法 ,是一种用于遍历或 搜索树或图的算法 .沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被

    2024年02月20日
    浏览(39)
  • 【剪枝】【广度优先】【深度优先】488祖玛游戏

    【动态规划】458:可怜的小猪 剪枝 广度优先 深度优先 在这个祖玛游戏变体中,桌面上有 一排 彩球,每个球的颜色可能是:红色 ‘R’、黄色 ‘Y’、蓝色 ‘B’、绿色 ‘G’ 或白色 ‘W’ 。你的手中也有一些彩球。 你的目标是 清空 桌面上所有的球。每一回合: 从你手上的

    2024年01月22日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包