Leetcode 46

46. 全排列

中等

相关标签

相关企业

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

示例 1:

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

示例 2:

输入:nums = [0,1]
输出:[[0,1],[1,0]]

示例 3:

输入:nums = [1]
输出:[[1]]

提示:

  • 1 <= nums.length <= 6
  • -10 <= nums[i] <= 10
  • nums 中的所有整数 互不相同

解法:

这道题是一道回溯剪枝的模版题,形如求全排列,求二叉树到某个节点的所有的路径都可以用这套模版

void backtrack(State* &state,vector<Choice*> &choices,vector<State*> &res)

{

if(isSolution(state,choices)){

recordSolution(state,res);

return;

for(Choice* choice:choices)

{

if(isValid(choices))//剪枝

{

makeChoice(state,choice);

backtreck(state,choices,res);//向下探路

undoChoice(state);//回溯

}

}

}

}

这道题中我们判断isSolution的条件就是state的长度等于choices,isValid的条件就是没有重复数字,这里我们利用一个哈希表selected来存储数字是否被插入过了,

makeChoice就是添加新的choice到state当中,然后设置selected[choice]=true,undoChoice就是将state最后一个元素pop,并且设置哈希表当中的相应元素为false

答案代码如下

class Solution {
public:
    bool isSolution(vector<int> &state,vector<int> &choices)
    {
        return state.size()==choices.size();
    }
    void addSolution(vector<int> &state,vector<vector<int>> &res)
    {
        res.push_back(state);
    }
    bool isValid(unordered_map<int,bool>selected,int choice)//当没有重复元素的时候
    {
        return !selected[choice];
    }
    void makeChoice(vector<int> &state,int choice,unordered_map<int,bool>&selected)
    {
        state.push_back(choice);
        selected[choice]=true;
    }
    void undoChoice(vector<int> &state,unordered_map<int,bool> &selected){
        int i=state.back();
        state.pop_back();
        selected[i]=false;
    }
    void backTrack(vector<int>&state,vector<int> &choices,unordered_map<int,bool>&selected,vector<vector<int>>&res)
    {
        if(isSolution(state,choices))
        {
            addSolution(state,res);
            return;
        }
        for(int i=0;i<choices.size();i++)
        {
            if(isValid(selected,choices[i]))
            {
                makeChoice(state,choices[i],selected);
                backTrack(state,choices,selected,res);
                undoChoice(state,selected);
            }
        }
    }
    vector<vector<int>> permute(vector<int>& nums) {
        unordered_map<int,bool>selected;
        for(int var:nums)
        {
            selected[var]=false;
        }
        vector<vector<int>> res={};
        vector<int> state={};
        backTrack(state,nums,selected,res);
        return res;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值