Leetcode Next permutation

Source: Internet
Author: User

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

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

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

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

The principle is relatively clear see blog: http://www.cnblogs.com/devymex/archive/2010/08/17/1801122.html

Concept

There are many kinds of algorithms, such as recursive iteration, cyclic shift and so on. The next_permutation and prev_permutation functions defined in C++/stl are a very flexible and efficient method that is widely used to generate different permutations for a given sequence. This article will describe in detail the internal algorithm of the Prev_permutation function.

As described in the STL documentation, the Next_permutation function generates the next larger sequence of the given sequence in alphabetical order until the entire sequence is reduced. The Prev_permutation function, in contrast, is the generation of the previous smaller sequence of a given sequence. The two principles are the same, only in the case of the reverse order, here only next_permutation as an example to introduce the algorithm.

The following is based on the assumption that the same element does not exist in the sequence. Define the sequence size comparison: Two sequences of the same length, starting from the first element of the two, until a different element (or perhaps the first element of them) is present, the larger sequence of the element is large, the inverse sequence is small, and if the last element is the same, then two sequences are equal.

Set the current sequence to PN, the next larger sequence is pn+1, then there is no PM, which makes PN < PM < pn+1.

Problem

Given any non-empty sequence, the next larger or smaller sequence is generated.

Mathematical derivation

According to the above concept, for an arbitrary sequence, the smallest sequence is the increment sequence, the largest sequence is the subtraction. So how do you generate pn+1 for a given PN? Let's take a look at the following example:

We use <A1 A2. Am> to represent a sequence of M numbers. Set sequence Pn=<3 6 4 2>, according to the definition can calculate the next sequence pn+1=<4 2 3 6>. Observing PN can be found that its sub-sequence <6 4 2> has been reduced order, then this sub-sequence can not be swapped element position to obtain a larger sequence, so must move the position of the highest bit 3 (i.e., A1), and to find a number in the Subsequence <6 4 2> to replace the position of 3. Sub-sequences <6 4 2> 6 and 4 are larger than 3, but 6 is greater than 4. If you use 6 to replace 3 The resulting sequence must be greater than 4 to replace the 3 resulting sequence, so only select 4. The positions of 4 and 3 are swapped to form an arrangement <4 6 3 2>. The resulting subsequence <6 3 2> remains reduced, i.e. the largest sequence that these 3 numbers can generate. and 4 is the 1th time as the first, need to the right of the sub-sequence of the smallest, so 4 to the right of the sub-sequence should be <2 3 6>, so that the correct one sequence Pn+1=<4 2 3 6>.

The following is an inductive analysis of the process. Assuming a sequence PN with M elements, the next larger sequence is pn+1.

1) If the 2 elements of the right end of the PN form an order sequence, then the direct inversion of the 2 elements makes the subsequence reduced order and can be pn+1.

2) If the right end of the PN has a continuous s-element form a sequence of the reduction sequence, so i = m-s, there is PN (i) < PN (i+1), wherein PN (i) is the first element of the arrangement PN. For example pn=<1 2 5 4 3>, then the right end of the PN has a maximum of 3 elements constituting a reduced-order subset <5 4 3>,i=5-3=2, there is PN (i) =2 < 5=PN (i+1). Therefore, if the PN (i) and its right subset s {pn (i+1), PN (i+2), ..., PN (M)}, any element in the exchange must be able to get a larger sequence (not necessarily the next). To ensure that the next larger sequence, the element on the left of PN (i) must remain fixed and the smallest PN (j) in the subset S {pn (i+1), PN (i+2), ..., PN (M)} is found, i.e. there is no pn (k) ∈s and PN (i) < PN (k) < PN (j), then swap the two positions. Now just make the new subset {PN (i+1), PN (i+2), ..., PN (i), ..., PN (M)} become the smallest sequence to get pn+1. Notice that the new subset remains reduced, and then it is reversed directly to get pn+1 {pn (1), PN (2), ..., Pn (j), PN (M), PN (m-1), ..., PN (i), ..., PN (i+2), PN (i+1)}.

Complexity of

The best case scenario is that the rightmost 2 elements of the PN form a minimum order subset, an interchange number of 1, a complexity of O (1), a worst case of 1 elements, and a reduced subset of all elements on the right, so that the 1th element is first replaced with the rightmost one, and then all the elements to the left are reversed. The number of interchanges is 1+ (n-1)/2, and the complexity is O (n). The average complexity is O (n) because various permutations can occur.

Extended

1. Can I calculate the nth permutation of the set {1, 2, ..., m} directly?

Set a collection {a1, A2, ..., am} (a1<a2<...<am) to form a sequence of PN, based on the above analysis is easy to verify: If the As<at, then as the 1th element of all the sequence must be less than at as the 1th element of any sequence. The same can be said: After the 1th element is determined, the remainder of the elements if as ' <at ', then all sequences as the 2nd element must be less than any sequence as the 2nd element. For example, the 4-digit set of {2, 3, 4, 6} sequences, with 3 as the 1th element of the sequence must be less than 4 or 6 as the 1th element of the sequence; 3 as the predecessor of the 1th element, 2 as a sequence of 2nd elements must be less than 4 or 6 as a sequence of 2nd elements.

Generalization shows that after determining the elements of the former I (I<n), in the set of the remaining m-i=s elements {aq1, aq2, ..., aq3} (AQ1<AQ2<...<AQM), the sequence with AQJ as the i+1 element must be less than aqj+ 1 as the sequence of the first i+1 elements. It can be concluded that after determining the first I elements, a sequence of successive sizes of s! is generated.

According to the above analysis, for a given n (must have n<=m!) can start from the 1th bit to the right to determine the position of each element. In the 1th invariant front, the back m-1 bits can be generated altogether (M-1)! The sequential size of the sequence. If n> (m-1)!, then the 1th bit will not be a1,n can accommodate X (M-1)! That is, the 1th bit is ax. After determining the 1th bit, delete the 1th bit from the original collection, get the new collection {aq1, AQ2, ..., aq3} (AQ1<AQ2<...<AQM), and then make N1=n-x (m-1)!, to the 1th bit of the m-1 sequence generated in this N1 number.

Example: If the set of 7 numbers is {1, 2, 3, 4, 5, 6, 7}, the first n=1654 is required.

(1654/6!) Rounding 2, determine the 1th digit is 3, the remaining 6 number {1, 2, 4, 5, 6, 7}, the 1654th 6!=214 sequence;

(214/5!) Rounding is 1, the 2nd digit is 2, the remaining 5 numbers are {1, 4, 5, 6, 7}, and the No. 214 5!=94 sequence is determined;

(94/4!) Take the whole 3, determine the 3rd bit is 6, the remaining 4 number {1, 4, 5, 7}, the 94th 4!=22 sequence;

(22/3!) Rounding 3, determine the 4th bit is 7, the remaining 3 number {1, 4, 5}, the 22nd 3!=4 sequence;

(4/2!) 2, determine the 5th is 5, the remaining 2 number {1, 4}; Due to 4 2!=0, 6th and 7th digits are <1 4>;

All permutations are therefore: 3267514.

2. Given an arrangement, how do you figure out which is the first permutation?

Contrary to the derivation process of the previous question. For example 3267514:

The 6-bit full arrangement is 6!,3 {1, 2, 3, 4, 5, 6, 7} in the 2nd element (counting from 0), so 2*720=1440;

The 5!,2 is the 1th element in {1, 2, 4, 5, 6, 7}, so 1*5!=120;

The 4!,6 is the 3rd element of {1, 4, 5, 6, 7} in the full arrangement of the second 4 bits, so 3*4!=72;

The 3!,7 is the 3rd element in {1, 4, 5, 7}, so 3*3!=18;

The 2!,5 is the 2nd element of {1, 4, 5} in the full arrangement of the second 2 bits, so 2*2!=4;

The last 2 bits are added sequentially, so count 0, sum: 1440+120+72+18+4=1654

Here is the version I implemented in Java:

 Public classSolution4 {/*** Next permutation *@paramNums*/     Public voidNextpermutation (int[] nums) {        if(nums.length<=1)            return; inti = Nums.length-1;  while(i>0){                        if(nums[i]>nums[i-1]){                                 Break; }                            ElseI--; } quickSort (Nums,i,nums.length-1); if(i = = 0)            return; intj = I-1;  while(i<nums.length&&nums[j]>=Nums[i]) I++; /*** 5,1,1*/        if(i==nums.length) I--;    Swap (Nums, J, i); }     Public voidQuickSort (int[] num,intXinty) {        if(x>=y)return; intQ =partition (Num,x,y);                Swap (num,q,y); QuickSort (num, x, q-1); QuickSort (num, q+1, y); }    /**Quick Line * Note to P-1 first, so that there is no need for subsequent exchanges when multiple steps *@paramnum *@paramp *@paramR *@return     */     Public intPartitionint[] num,intPintR) {        intPivotindex = (p+r)/2;        Swap (num, pivotindex, R); intPivot =Num[r]; P--;  Do{             while(num[++p]<pivot);  while(r>0&&num[--r]>pivot);        Swap (num, p, R); } while(p<R);        Swap (num, p, R); returnp; }    /*** Be sure to determine if two elements are equal or update to 0 *@paramINTs *@paramx *@paramy*/     Public  voidSwapint[] INTs,intXinty) {if(x==y)return; INTS[X]= ints[x]^Ints[y]; Ints[y]= ints[x]^Ints[y]; INTS[X]= ints[x]^Ints[y]; }       Public Static voidMain (string[] args) {int[] A = {}; Solution4 So=NewSolution4 ();                        So.nextpermutation (a);  for(inti = 0;i<a.length;i++) System.out.print (A[i]+" "); }}
View Code

Leetcode Next permutation

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.