• 算法复习:回溯法


    一、需要还原状态的递归回溯

    leetcode 46. 全排列

    打印一串数字的全排列,定义一颗树,树的每个节点map<int,int>used保存当前哪些点用了哪些点还没用,Tnode *next[100]保存接下来的每一个点的索引

    就是一个建树的过程,当前数字栈达到了最大长度就保存一次结果,每一个节点都遍历它的used域,直到used所有的元素都用过了才达到叶子节点,那么返回

    struct Tnode
    {
        map<int,int>used;
        Tnode *next[100];
    };
    class Solution {
    public:
        struct Tnode * root=new Tnode();
        vector<int >now;
        vector<vector<int>> result;
        void loop(struct Tnode *node,int num)
        {
            map<int,int>::iterator it;
            map<int,int> tmp=node->used;
            for(it=tmp.begin();it!=tmp.end();it++)
            {
                if(it->second==1)
                    continue;
                now.push_back(it->first);
                if(now.size()==num)
                    result.push_back(now);
                struct Tnode * new_node=new Tnode();
                new_node->used=tmp;
                new_node->used[it->first]=1;
                new_node->next[it->first]=new_node;
                loop(new_node,num);
                now.pop_back();
            }
        }
        vector<vector<int>> permute(vector<int>& nums) {
            int num=nums.size();
            for(int i=0;i<num;i++)
            {
                root->used[nums[i]]=-1;
            }
            struct Tnode * node=new Tnode();
            node=root;
            loop(node,num);
            return result;
    
        }
    };
    leetcode 46

    二、不需要还原状态的递归回溯

    leetcode 面试题13. 机器人的运动范围

    本质上还是一个深度优先遍历

    class Solution {
    public:
        int count=0;
        map<int,bool>lable;
        bool check(int m,int n,int k)
        {
            int sum=0;
            while(m)
            {
                sum+=m%10;
                m/=10;
            }
            while(n)
            {
                sum+=n%10;
                n/=10;
            }
            if(sum<=k)
                return true;
            return false;
        }
        void dfs(int x,int y,int m, int n, int k)//当前 x y ;最大m n ;限制为k
        {
            if(check(x,y,k)==false||x<0||x>=m||y<0||y>=n||lable[x*n+y]==true)
                return ;
            count++;
            lable[x*n+y]=true;
            dfs(x+1,y,m,n,k);
            dfs(x,y+1,m,n,k);
            dfs(x-1,y,m,n,k);
            dfs(x,y-1,m,n,k);
        }
        int movingCount(int m, int n, int k) {
            dfs(0,0,m,n,k);
            return count;
        }
    };
    回溯

    leetcode 19. 删除链表的倒数第N个节点

    保存上一个节点和当前节点,正向走到最后开始回溯,回溯到指定次数后找到位置,删除节点返回即可,一次扫描

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    #define maxl 999999
    class Solution {
    public:
        int global_lb=0;
        ListNode* loop(ListNode* last,ListNode* now,int &lable,int &count,int n)
        {
            //cout<<last->val<<" "<<now->val<<endl;
            if(now->next==nullptr)//正向走到尾开始回溯
            {
                lable=1;
                return now;
            }
            last=now;
            now=now->next;
            loop(last,now,lable,count,n);
            if(lable==1)
            {
                count++;
                //cout<<last->val<<" "<<now->val<<":"<<count<<endl;
                if(count==n)
                {
                    global_lb=1;
                    last->next=now->next;
                    lable=0;//lable置0不再进入
                }
            }
            return last;
        }
        ListNode* removeNthFromEnd(ListNode* head, int n) {
            int lb=0,count=0;
            ListNode* result;
            ListNode* tmp=new ListNode();//加一个空头
            tmp->val=maxl;
            tmp->next=head;
            result=loop(tmp,tmp->next,lb,count,n);
            if(global_lb==0)
                result=result->next;
            return result;
        }
    };
    leetcode 19
  • 相关阅读:
    理解java的三大特性之封装
    Spring_事务-注解代码
    Spring_使用 NamedParameterJdbcTemplate
    C#多线程简单例子讲解
    C#多线程编程
    ASP.NET MVC 的URL路由介绍
    NHibernate二级缓存(第十一篇)
    NHibernate之配置文件属性说明
    NHibernate之映射文件配置说明
    NHibernate 延迟加载与立即加载 (第七篇)
  • 原文地址:https://www.cnblogs.com/dzzy/p/12373357.html
Copyright © 2020-2023  润新知