leetcode - 31 Next Permutation

31. Next Permutation

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

If such arrangement is not possible, it must rearrange it as thelowest 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 andits 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

 

 

刚刚看到这个题目真的很迷糊。下一个序列很抽象,然后看了例子就发现其实也还行。通俗地说(不是很准确)就是利用当前序列的各个元素的值组成一个新的序列,这个序列是最为接近当前序列的。

 

比如:

123456

next Permutation= 123465

 

123456< 123465

 

只需要调换最后两位。

 

接下来:

123465

next Permutation= 123465

123546

 

调换最后3位的位置。

这里只是示例,但通过这些例子大概也可以看出一些规律了。

 

也就是找到一个比当前序列大,但是与当前序列绝对值差最为小的一个序列。(绝大多数情况),特殊情况是一个降序序列,那么下一个序列就是升序序列。比如654321 下一个序列就是123456,是一个循环。

 

可以归纳为2种情况:非降序;降序。

 

若为降序,就直接输出一个升序序列,复杂度O(n)

 

若为非降序,就需找到一个最接近当前序列值的一个较大序列。设i为数组a元素下标,n为数组长度,在n>1情况下,i = n – 2,从最后一位开始判断,如果找到a[i] < a[i+1] 说明a[i+1]…a[n-1] 是一个降序序列,降序序列的比如

                                                         

0

 

 

i

i+1

 

 

n-1

1

3

4

1

7

5

3

1

 

只需要将a[i]…a[n-1]变成一个较大一些的数就可以,也就是17531,因为数字比较少,很容易就可以猜得出来是31157,但是这个数字是怎么来的。

 

0

 

 

 

 

 

j

n-1

1

3

4

3

7

5

1

1

 

 

先找到3,也就是找到最接近1,但是却比1要大的数字,在这里设下标为j

然后将他们交换,得到7511,最后把降序变为升序,也就是来一次全交换。

 

。主要的时间花在寻找ij的值,在最坏的情况就是需要找近似2n次才能找到这两个值,然后就是交换时间,最坏情况下也是为2/n。所以这个算法的复杂度也是为O(n)


int Next_Permutation(vector<int>& nums)  {	
        
    int endindex = nums.size() - 1;
    int j;
 	int i = endindex - 1;//start from arrays end - 1
 	while(i >= 0 )
 	{
 	    if(nums[i] >= nums[i+1])i--;
 	    else break;
 	}
 	if(i >= 0){
    	j = i + 1;
 	
    	while(j  <= endindex ){
 	        if(nums[j] > nums[i])j++;
 	        else break;
    	}
 		
    	j--;//Step back one step
 	 swap(nums[i] , nums[j]); 		   
 	}
 	i++;//position of exchange start
 	j = endindex;
 	while(i < j ){
 		swap(nums[i++] , nums[j--]);		
	 }
    	
}
    


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值