I. Opening
After the previous article <generate a full arrangement using the exchange Method and Its Application>, we will discuss some problems based on the permutation itself, including: finding the next full arrangement (next permutation ); returns the permutation sequence of the specified position, and returns the position where the specified position is located.
Ii. Example
1. Find the next full arrangement, next permuation
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,3
→1,3,2
3,2,1
→1,2,3
1,1,5
→1,5,1
class Solution {public: void nextPermutation(vector<int> &num) { }};
The topic indicates that all topics are arranged in alphabetical order and the next topic is located.
My idea is: the next full arrangement is actually to rearrange a subset of the current vetor. How to divide this subset?
Consider sorting 1237456. Its next sorting is 1243567. The method for finding a subset is actually: find the last pair that satisfies num [I + 1]> num [I] From start to end (the traversal can be performed from the end to the end, find a pair of the first num [I + 1]> num [I], and the subset to be rearranged is num [I ~ Size-1] This subset. This subset num [I ~ Size-1] one condition is met: the first two elements increase progressively, followed by decreasing or followed by no element. In special cases, if the numbers of num [I] And num [I + 1] With an incremental relationship cannot be found, the whole sequence is in descending order, that is, there is no larger arrangement, sort the sequence in reverse order as required.
The way to rearrange is from num [I + 1 ~ Size-1] select oneSmallest element larger than num [I], Swap it with num [I], and then replace num [+ 1 ~ Size-1] Reverse Order.
Code:
Class solution {public: void nextpermutation (vector <int> & num) {int size = num. size (); If (size = 0 | size = 1) return; int aschead = size-2; // The Last num [I] <num [I + 1] I for (; aschead> = 0 & num [aschead]> = num [aschead + 1]; -- aschead); If (aschead <0) {reverse (Num, 0, size-1); return;} int insert = size-1; // store the index for (; Insert> aschead & num [insert] <= num [aschead]; -- insert) That is the minimum value greater than num [aschead ); swap (Num, aschead, insert); reverse (Num, aschead + 1, size-1);} PRIVATE: void swap (vector <int> & num, int left, int right) {int temp = num [left]; num [left] = num [right]; num [right] = temp;} void reverse (vector <int> & num, int start, int end) {While (start <End) {swap (Num, start ++, end --);}}};
2. Give a full arrangement, so that it is in the nth position in all the full permutation.
There is no example on leetcode in this question.
For example, if a given 356421 sorting rule is given, because the first digit is 3, the full sorting starting with 1 and 2 has passed, and the number of full sorting starting with 1 is 5 !, 2. Therefore, the ranking in the full ranking is greater than 2*5!
The second digit is 5. For the full arrangement starting with 3, there are three full orders starting with and 34 in front of 35. In 356421, the right side of 5 is also 1, 2, and 4 smaller than 5.
We can find that the sequence length is N. For a given number on P, we assume that the number is in the m position from right on p, we only need to check that there are several smaller digits on the right side of the number, and we will know that the right part of the number ranks in all corresponding subsequences.
Therefore, the total ranking of P is Σ K * m! (M ranges from 0 to n-1. k indicates the number of digits smaller than m + 1 after the first digit.
3. Find the full arrangement of the specified position
Permutation sequence
The Set[1,2,3,…,n]
Contains a totalN! Unique permutations.
By listing and labeling all of the permutations in order,
We get the following sequence (ie,N= 3 ):
"123"
"132"
"213"
"231"
"312"
"321"
GivenNAndK, ReturnKTh permutation sequence.
Note: GivenNWill be between 1 and 9 random sive
class Solution {public: string getPermutation(int n, int k) { }};
With the idea of the previous question, this question is very easy.
It's nothing more than dividing by M !, M is decreasing, and the remainder is used as the denominator to continue the cycle.
Class solution {public: String getpermutation (int n, int K) {bool dig [N]; unsigned int Mul = 1; Int J = 0, IND = 0, I = 0; string res = ""; for (I = 0; I <n; Mul * = (I> 0? I: 1), dig [I] = false, ++ I); -- k; // offset K, 0 as the first for (I = N; I> 0; -- I, K % = Mul, mul/= (I> 0? I: 1) {Ind = K/MUL; For (j = 0; j <n; ++ J) {If (! Dig [J]) -- ind; If (IND <0) break;} Dig [J] = true; Res. push_back (J + '1'); // here, J starts from 0, so the conversion to a character must be + '1'} return res ;}};
Iii. Summary:
There are many questions based on the full arrangement, but we only need to know that the number of the full arrangement is k! You can start from here.
If you want to construct a full arrangement, the exchange method in the previous article is an idea.
[Leetcode] "Full Arrangement" problem series (II)-based on the problem of full arrangement itself, example: Next permutation, permutation sequence