<LeetCode> 题15:全排列(不带重复元素)

题目描述:

给定一个数字列表,返回其所有可能的排列。
例如:
给出一个列表[1,2,3],其全排列为:
[
[1, 2, 3],
[1, 3, 2],
[2, 1, 3],
[2, 3, 1],
[3, 1, 2],
[3, 2, 1]
]

思路1:

从集合中依次选出每一个元素作为排列的第一个元素,然后对剩余的元素进行全排列,如此递归从而得到全排列。例如:
固定1,求后面2,3的排列123,132,求完后交换1和2得到213,
固定2,求后面1,3的排列213,231,求完后3放到第一个位置321,
固定3,求后面1,2的排列321,312

代码:

class Solution
{
public:
    vector<vector<int>> permute(vector<int> &num) 
    {
        vector<vector<int>> res;
        if(num.size() == 0)
            return res;
        vector<int> tempres;
        permuteRecur(num, 0, res, tempres);
        return res;
    }

    void permuteRecur(vector<int> &num, int index, vector<vector<int>> &res, vector<int> &tempres)
    {
        if(index == num.size())
        {
            res.push_back(tempres);
            return;
        }
        for(int i = index; i < num.size(); i++)
        {
            swap(num[index], num[i]);
            tempres.push_back(num[index]);
            permuteRecur(num, index+1, res, tempres);
            tempres.pop_back();
            swap(num[index], num[i]);
        }
    }
};

思路2:

采用DFS深搜的办法,并用一个数组标记该元素是否被访问过。

class Solution 
{  
public:  
    vector<vector<int>> permute(vector<int> &num)
    {  
        vector<vector<int>> res;  
        vector<int> cur;  

        int n=num.size();  
        if(n == 0)
        {  
            return res;  
        }  
        int *bit=new int[n];    //表示该元素是否被访问过
        memset(bit,0,sizeof(int)*n);  

        DFS(res,cur,num,0,bit);  

        return  res;  
    }  
private:  
   void DFS(vector<vector<int>> &res,vector<int> &cur,vector<int> &num,int count,int *bit)
   {  
       int n=num.size();  
       if(count==n)
       {  
            res.push_back(cur);  
            return;  
       }  
       for(int i=0;i<n;i++)
       {  
          if(!bit[i])
          {  
             cur.push_back(num[i]);  
             bit[i]=1;  
             DFS(res,cur,num,count+1,bit);  
             bit[i]=0;  
             cur.pop_back();  
          }  
       }  
    }  
};  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值