LeetCode 46. 全排列(回溯法)

LeetCode 46. 全排列(回溯法)_第1张图片
全排列问题,可用回溯法求解。
求n个数的全排列,可以想象有n个空格,从左到右依次填入一个数,且每个数只能用一次,直到填满空格。可以想到用一种穷举的方法,即每个空格都都尝试填1-n中的一个数,直到填完n个空格。
代码(有点繁琐):

class Solution {
private:
    vector<int> v;
    vector<vector<int> >ans;
    int size;
    bool* vis;
public:
    vector<vector<int>> permute(vector<int>& nums) {
        size=nums.size();
        vis=new bool[size];
        for(int i=0; i<size; i++)
            vis[i]=false;
        dfs(0, nums);
        delete[] vis;
        return ans;
    }
    void dfs(int k, vector<int>& nums){
        if(k==size){  //填满所有的空格后,则保存结果并返回
            ans.push_back(v);
            return;
        }
        for(int i=0; i<size; i++){
            if(!vis[i]){  //若下标为i的数未被使用,则填入空格
                v.push_back(nums[i]);
                vis[i]=true;
                dfs(k+1, nums);
                vis[i]=false;//回溯,标记为未访问
                v.pop_back();//同时也要弹出一个数
            }
        }
    }
};

这是官方题解的代码:

class Solution {
public:
    void backtrack(vector<vector<int>>& res, vector<int>& output, int first, int len){
        // 所有数都填完了
        if (first == len) {
            res.emplace_back(output);
            return;
        }
        for (int i = first; i < len; ++i) {
            // 动态维护数组
            swap(output[i], output[first]);
            // 继续递归填下一个数
            backtrack(res, output, first + 1, len);
            // 撤销操作
            swap(output[i], output[first]);
        }
    }
    vector<vector<int>> permute(vector<int>& nums) {
        vector<vector<int> > res;
        backtrack(res, nums, 0, (int)nums.size());
        return res;
    }
};

由全排列问题可以引出很多经典的问题,例如n皇后问题,就是带有筛选条件的全排列。

你可能感兴趣的:(LEETCODE,leetcode,算法,数据结构)