ACwing842.全排列+LeetCode46.全排列(dfs+回溯)

 ACwing842.全排列

先引入这个全排列理解一下如何递归和回溯的(可以在本子上画画,或者一步步调试看看)

题目描述(来源ACwing):

思路:1 2 3全排列,我们肯定会怎么排1 2 3,1 3 2,2 1 3,2 3 1,3 1 2,3 2 1,其实写成代码就是一个回溯的过程,1 2 3全部排完我们就输出,然后回退到1 2,三已经选过,再回退到1,此时2 也已经选过,我们选3,然后选2,1 3 2排完我们再输出再继续回溯,一回到数组全部遍历结束并且此时已经全部选过,那我们既要有一个数组来标记当前元素是否已被选择过,回溯的过程要将该元素的标记取出以参与下一次排列

 代码实现C++:

#include<iostream>
using namespace std;
const int N=10;
int p[N],st[N];
int n;
void dfs(int x){
    if(x==n){//当x==n说明当前数组里已经有n个元素了,直接输出然后return即回溯
          for(int i=0;i<n;i++){
              cout<<p[i]<<" ";
          }  
          cout<<endl;
          return;
    }
    for(int i=1;i<=n;i++){
        if(!st[i]){//该元素没有被标记,那就加入当前数组并修改标记
            p[x]=i;
            st[i]=true;
            dfs(x+1);
            st[i]=false;
        }
    }
}
int main()
{
    cin>>n;
    dfs(0);
    return;
}

LeetCode46.全排列(dfs+回溯)

题目描述(来源LeetCode):

 有是开启回溯的一天,我似乎还是没有掌握到精髓,这个题又做了半个小时,我做的时候,我觉得难点可能就是递归函数的参数问题,(纠结了老半天)然后想到了之前做的一个全排列,从1~n的全排列,其实递归的出口就是当前数组里有n个元素了,说明本次搜索结束,开始回溯

思路:递归+回溯,首先递归的结束条件:当前数组的元素个数等于题目给出的数组的元素个数,则这就是一组可行解。其他情况,我们每次都要考虑当前位置应该填什么,那就要遍历题目给出的数组,肯定不能填目前数组里已经存在的,那怎么判断存不存在,就可以用一个st数组来标记当前元素是否已被填入,如果没有被标记st[i]=false,我们就将该元素填入并从数组的下一个位置继续递归,如果被标记过了,那就继续遍历题目所给数组即可

代码实现C++:

class Solution {
public:
        vector<int> num;
        vector<vector<int>> res;
        vector<bool> st;
    vector<vector<int>> permute(vector<int>& nums) {
        if(nums.size()==0) return res;
        st.resize(nums.size(), false);
        dfs(nums);
        return res;
    }
    void dfs(vector<int>& nums){
        if(num.size()==nums.size()){//当前数组里的元素个数等于题目数组的元素个数的时候,说明本次搜索结束,开始回溯
            res.push_back(num);//将当前数组加入答案当中去
            return;
        }
        for(int i=0;i<nums.size();i++){//遍历题目所给的数组
            if(!st[i]){//如果该元素没有被标记就将该元素加入数组并修改标记
                num.push_back(nums[i]);
                st[i]=true;
                dfs(nums);
                st[i]=false;//回溯的过程要修改标记
                num.pop_back();
            }
        }
    }
};

其实可以发现,回溯的题,在递归的前后代码一般是对称的哦!

1.递归结束的条件,2.对什么进行回溯,3从哪里开始

今日刷题任务完成,希望下次遇到回溯可以快点写出。明天见~(欢迎留言交流呀!)

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值