zoukankan      html  css  js  c++  java
  • Next Permutation&&Permutation Sequence

    Next Permutation

    Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.

    If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).

    The replacement must be in-place, do not allocate extra memory.

    Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.
    1,2,31,3,2
    3,2,11,2,3
    1,1,51,5,1

      题目的意思是:123的全排列按字典顺序为:

        123 132 213 231 312 321

        如果输入其中某一个序列,返回它的下一个序列。如:输入:213 输出:231 ;输入:321 输出:123

        算法思想:举例如下

        输入:1 4 6 5 3 2

        step1:从右往左找到第一个破坏升序(非严格)的元素,此例中为4.记下标为 i

        step2: 依然从右往左,找到第一个大于4的元素,此例中5,交换4和5.

        step3:从i+1到最右端,逆置。6 4 3 2 to 2 3 4 6

        so,1 5 2 3 4 6 即为所求。

    class Solution {
    public:
        void nextPermutation(vector<int>& nums) {
            int i,j,len=nums.size();
            for(i=len-2;i>=0;--i)
            {
                if(nums[i+1]>nums[i])
                {
                    for(j=len-1;j>i-1;--j)if(nums[j]>nums[i])break;
                    swap(nums[i],nums[j]);
                    reverse(nums.begin()+i+1,nums.end());
                    return;
                }
            }
            reverse(nums.begin(),nums.end());
            return;
            
        }
    };

    Permutation Sequence

    The set [1,2,3,…,n] contains a total of n! unique permutations.

    By listing and labeling all of the permutations in order,
    We get the following sequence (ie, for n = 3):

    1. "123"
    2. "132"
    3. "213"
    4. "231"
    5. "312"
    6. "321"

    Given n and k, return the kth permutation sequence.

    Note: Given n will be between 1 and 9 inclusive.

    解法参考了:http://blog.csdn.net/lanxu_yy/article/details/17261527

    思路:

    思路1是用NP的方式来罗列出所有的排列再找出第k个结果,这种方法的时间复杂度与空间复杂度比较高。思路2是研究排序结果的规律,例如取n是,结果可以分为n个组,第一组是第一个数字取最小的那个(即1),第k组是取数字排第k小的那个(即k),每组的数字个数是(n-1)!。依次类推可以递归到n为1时。最终k可以表示为k=A1(n-1)!+A2(n-2)!+...+An,其中Ak代表该数为剩余数字中第Ak小的数字。
    例如,n=3,k=5时,我们首先将k换算成4(第一个元素为0而不是1),由于(n-1)!=2,所以第一个元素应该是第4/2=2小的元素。第二个元素的k=4%2=0,且(n-1)!=1,所以第二个元素应该是第0小的元素。第三个元素的k=0%1=0,且(n-1)!=1,所以第三个元素应该是第0小元素。一开始的数字为(1,2,3)第一位是第2(0表示第一位)小元素,故取3,第二位是剩余数字(1,2)中第0小的元素,即为1,第三位是剩余数字(2)中第0小的元素,即2。所以结果为312。
     
    我刚开始用的就是思路一的方法,结果测试不通过,运行超时,换成思路二的就好了,注意代码27行的break,不然代码就错了。其实感觉这道题和算法关系不大,完全就是在考数学。
     class Solution {
     public:
         string getPermutation(int n, int k) {
            vector<bool> flag(n,false);
            int *A=new int[n];
            int base=1;
            for(int i=2;i<n;i++)
                 base*=i;
            int sum=k-1;
            for(int i=0;i<n;i++)
           {
                A[i]=sum/base;
                sum=sum%base;
                if(base!=1)  
                     base=base/(n-1-i);
            }
           string str;
            for(int i=0;i<n;i++)
             for(int j=0;j<n;j++)
             {
                 if(!flag[j])
                 {
                     if(A[i]==0)
                     {
                         str.push_back(j+'1');
                         flag[j]=true;
                         break;
                     }
                     else
                     {
                         A[i]--;
                     }
                 }
             }
             return str;
         }
     };
  • 相关阅读:
    leetcode 1301. 最大得分的路径数目
    LeetCode 1306 跳跃游戏 III Jump Game III
    LeetCode 1302. 层数最深叶子节点的和 Deepest Leaves Sum
    LeetCode 1300. 转变数组后最接近目标值的数组和 Sum of Mutated Array Closest to Target
    LeetCode 1299. 将每个元素替换为右侧最大元素 Replace Elements with Greatest Element on Right Side
    acwing 239. 奇偶游戏 并查集
    acwing 238. 银河英雄传说 并查集
    acwing 237程序自动分析 并查集
    算法问题实战策略 MATCHORDER 贪心
    Linux 安装Redis全过程日志
  • 原文地址:https://www.cnblogs.com/qiaozhoulin/p/4536986.html
Copyright © 2011-2022 走看看