leetcode 46 全排列(Medium)

题目来源:leetcode 46 全排列

题目描述:

给定一个 没有重复 数字的序列,返回其所有可能的全排列。

示例:

输入: [1,2,3]

输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]

解题思路:

回溯,先固定第一个数(第一个数和所有数交换,取的所有结果),然后递归求的后面数的全排列,再撤销交换。结束的出口是,只剩一个字符。

class Solution {
public:
    vector<vector<int>> permute(vector<int>& nums) {
        vector<vector<int>> ans;
        permute(nums,ans,0);
        return ans;
    }
    void permute(vector<int>nums,vector<vector<int>> &ans,int start)
    {
        //所有数都填完了,加入结果中
        if(start==nums.size()-1) 
        {
            if(find(ans.begin(),ans.end(),nums)==ans.end()) ans.push_back(nums);
            return;
        }
        else
        {
            for(int i=0;i<nums.size();i++)
            {
                //不断交换,动态固定第一个数
                swap(nums[start],nums[i]);
                //递归取得后面数的全排列
                permute(nums,ans,start+1);
                //撤销操作
                swap(nums[start],nums[i]);
            }
        }
    }
};

另一种写法:

class Solution {
public:
    vector<vector<int>> ans;
    vector<vector<int>> permute(vector<int>& nums) {
        vector<int> track;
        backtrack(nums,track);
        return ans;
    }
    void backtrack(vector<int> &nums,vector<int> &track){
        //结束条件
        if(track.size()==nums.size()){
            ans.push_back(track);
            return;
        }
        for(int i=0;i<nums.size();i++){
            //排除不合法的选择
            if(find(track.begin(),track.end(),nums[i])!=track.end()) continue;
            //做选择
            track.push_back(nums[i]);
            //下一层决策
            backtrack(nums,track);
            //撤销选择
            track.pop_back();
        }
    }
};

类似题目:

剑指offer27:字符串的排列

posted @ 2020-07-01 10:34  拉里拉里啦啦  阅读(118)  评论(0编辑  收藏  举报