Permutation Sequence LT60

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 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.
  • Given k will be between 1 and n! inclusive.

Example 1:

Input: n = 3, k = 3
Output: "213"

Example 2:

Input: n = 4, k = 9
Output: "2314"

By observing the sequence for n = 3, we can see the permutation sequence is 1 + [2, 3] permutation, 2 + [1, 3] permutation, 3 + [1, 2] permutation. The sequence with first element = 1 has value k = 1, 2, with first element = 2 has value 3, 4, with first elemnt = 3 has value 5, 6, it's not hard to see that the index of the first element is (k-1)/2!

Next, we want to find the first element for n = 2, since there is only 2! permutation, the new k would be in the range [1, 2!],  if you observe the original k and the permutation: 

    [2, 3] k = 0 -> new k = 0

    [3, 2] k = 1 -> new k = 1

    [1, 3] k = 2 -> new k = 0

    [3, 1] k = 3 -> new k = 1

    [1, 2] k = 4 -> new k = 0

    [2, 1] k = 5 -> new k = 1

    new k = old k / 2!, it's just the same problem, with smaller n and k, hence we can use either recursive or iterative to solve it.

Key taken: --k, which makes the caculation easier also rules easier to observe, if k == 0, it's the first sequence in the permutation, no further work needed.

Time complexity: O(n*2)

Iterative:

public class PermutationSequenceLT60 {
    private int calculateFactorial(int n) {
        int factorial = 1;
        for(int i = 2; i <= n; ++i) {
            factorial *= i;
        }
        return factorial;
    }

    public String permutation(int n, int k) {
       StringBuilder result = new StringBuilder();

       List<Integer> nums = new LinkedList<>();
       for(int i = 1; i <= n; ++i) {
           nums.add(i);
       }

       int factorial = calculateFactorial(n);

       --k;
       for(int i = n; k > 0 && i >= 1; --i) {
           factorial = factorial/i;
           int pos = k/factorial;
           result.append(nums.remove(pos));
           k = k%factorial;
       }

       for(int num: nums) {
           result.append(num);
       }

       return result.toString();
    }

    public static void main(String[] args) {
        PermutationSequenceLT60 p = new PermutationSequenceLT60();
        System.out.println(p.permutation(4, 9));
        for(int i = 1; i <= 6; ++i) {
            System.out.println(p.permutation(3, i));
        }
        for(int i = 1; i<= 24; ++i) {
            System.out.println(p.permutation(4, i));
        }
    }
}

Recursive:

public class PermutationSequenceLT60 {
    private int calculateFactorial(int n) {
        int factorial = 1;
        for(int i = 2; i <= n; ++i) {
            factorial *= i;
        }
        return factorial;
    }

    private void permutationHelper(int k, List<Integer> nums, StringBuilder result, int factorial) {
        if(k == 0) {
            for(int num: nums) {
                result.append(num);
            }
            return;
        }

        int pos = k/factorial;
        result.append(nums.remove(pos));
        permutationHelper(k%factorial, nums, result, factorial/nums.size());
    }

    public String permutation(int n, int k) {
        StringBuilder result = new StringBuilder();

        List<Integer> nums = new LinkedList<>();
        for(int i = 1; i <= n; ++i) {
            nums.add(i);
        }

        int factorial = calculateFactorial(n-1);
        permutationHelper(k-1, nums, result, factorial);

        return result.toString();
    }

    public static void main(String[] args) {
        PermutationSequenceLT60 p = new PermutationSequenceLT60();
        System.out.println(p.permutation(4, 9));
        for(int i = 1; i <= 6; ++i) {
            System.out.println(p.permutation(3, i));
        }
        for(int i = 1; i<= 24; ++i) {
            System.out.println(p.permutation(4, i));
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/taste-it-own-it-love-it/p/10349574.html