leetcode:46. Permutations 排列

46. Permutations

问题描述

Given a collection of distinct numbers, return all possible permutations.

For example,
[1,2,3] have the following permutations:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]

思路
  1. 思路1
    1. m个不同数的所有排列,可以这么得到:首先得到前m-1个数的所有排列,然后将第m个数分别插入到每种排列的不同位置得到。如果前m-1个数的所有排列数为 cntm1 , 则m个数的所有排列数 cntm=cntm1×m
    2. 由此思路可采用递归的方法。
  2. 思路2
    1. 可先实现nextPermutation()来获取当前排列的下一个排列
    2. 设置初始排列和终止条件,则可由nextPermutation获得所有排列
  3. 思路3
    1. 可采用深度优先搜索来实现
算法描述1:递归
  1. 如果nums的长度为1,则将nums入栈result,返回result。
  2. 设nums的长度为m,截取前m-1个数nums_tmp,并保留最后一个数为num_new。
  3. 递归执行permute(result_tmp),获得前m-1个数的所有排列result_tmp
  4. 遍历result_tmp:i
    1. 每个排列的长度为m-1,由m个位置可以插入num_new,遍历插入,并将新的排列压栈result
  5. 得到m个数的所有排列,返回result。
实现代码1:递归
vector<vector<int>> permute(vector<int>& nums)
{
    vector<vector <int> > result;
    if(nums.size() == 1)
    {
        vector<int> tmp;
        tmp.push_back(nums[0]);
        result.push_back(tmp);
        return result;
    }

    vector<int> nums_tmp;
    nums_tmp.assign(nums.begin(),prev(nums.end()));
    int num_new= *prev(nums.end());

    vector<vector<int>> result_tmp;
    result_tmp = permute(nums_tmp);
    const int m = result_tmp.size();
    const int n = result_tmp[0].size();
    for(int i =0; i< m;i++)
    {
        for (int j = 0; j <= n;j++)
        {
            vector<int> tmp2=result_tmp[i];
            tmp2.insert(tmp2.begin()+j,num_new);
            result.push_back(tmp2);
        }

    }
    return result;
}
算法描述2
  1. 如果nums为空,则返回空
  2. 设nums的长度为m,计算所有排列的数 m!
  3. 遍历m!次,调用nextPermutation(),得到下一个排列,并压栈result
  4. 返回result
    注:nextPermutation()的实现在 nextPermutation 下一个排列中可以查看
代码实现2
vector<vector<int>> permute(vector<int>& nums)
{
    vector<vector<int>> result;
    if(nums.empty())
        return result;
    sort(nums.begin(),nums.end());
    long m=factorial(nums.size());
    for(int i=0;i<m;i++)
    {
        result.push_back(nums);
        nextPermutation(nums);
    }
    return result;
}
bool Solution::nextPermutation2(vector<int>& nums)
{
    if(nums.size()==0)
        return false;
    for(int i=nums.size()-2;i>=0;i--)
    {
        int min=INT_MAX;
        int k=-1;
        for(int j=nums.size()-1;j>i;j--)
        {
            if(nums[i]<nums[j] && nums[j]< min)
            {
                k=j;
                min=nums[j];
            }
        }
        if(k != -1)
        {
            int temp=nums[k];
            nums[k]=nums[i];
            nums[i]=temp;
            sort(nums.begin()+i+1,nums.end());
            return false;
        }
    }
    // 如果是最大时
    for(int i=0;i<nums.size()/2;i++)
    {
        int temp=nums[i];
        nums[i]=nums[nums.size()-i-1];
        nums[nums.size()-i-1]=temp;
    }
    return true;
}
算法描述3:深度优先搜索
  1. 如果为空,则返回空
  2. 将数组排序
  3. 定义初始路径path,然后调用dps_permute(nums,path,result)实现
    1. 如果path的长度为nums的长度,则将path压栈result,并返回
    2. 遍历数组nums:i
      1. 在path中查找i,如果不存在:
        1. 将i压栈path,递归调用dps_permuter(nums)
        2. path出栈
  4. 返回result
实现代码3
vector<vector<int>> Solution::permute(vector<int>& nums)
{
    vector<vector<int>> result;
    if(nums.empty())
        return result;
    sort(nums.begin(),nums.end());
    vector<int> path;
    dps_permute(nums,path,result);
    return result;
}
void Solution::dps_permute(vector<int>& nums, vector<int>& path, vector<vector<int>>& result)
{
    if(path.size() == nums.size())
    {
        result.push_back(path);
        return;
    }
    for(auto i: nums)
    {
        auto pos = find(path.begin(),path.end(),i);
        if(pos == path.end())
        {
            path.push_back(i);
            dps_permute(nums,path,result);
            path.pop_back();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值