思维开发题——下一个排序

最近从《编程谜题》上面看到一道很有意思的题目,这里摘录一下大意:

题目概述:

有n组数据,每组数据给出m和m个数(每个数之间用空格隔开),这m个数组成一个m位数,请你求出下一个比当前m位数大的排列组成的m位数

若是没有,请输出-1

输入样例:

2
4
1 2 3 4
3
3 2 1

输出样例:

1243
-1

还是那句话:看到这里请自行思考10分钟左右。

解法
1.暴力

思路:求出这m个数的全排列,然后找到给定的数据,下一个就是答案了
这里设定一个标记变量flag,如果都没有找到就输出-1。
时间复杂度:省去常数复杂度 O(n!)
代码这里就不贴了,想写的童鞋可以自己练练手
好像还可以有一个递归检索法(我自己发明的【笑】)
就是对于每一位数都可以通过递归找到全排列中的位置

2.“数学解法”

这里还是一个所谓的数学解法
这里比较玄学,我尽量讲明白吧。

先来看解题步骤,最后再解释:
拿序列3 4 2 1举例子
1.从右往左找到第一个反递增的数a,将这个数所在的位置(下标)记为pos
在这个例子里头,a=3,pos=1

2.从右到左找到比a大的第一个数b
在这里,b=4

3.交换a和b
例子中的序列就变成了:4 3 2 1

4.将pos右边的所有数都翻转(最后一位变为第一位,倒数第二位变为第二位……)
例子中的序列就变成了4 1 2 3

此时的序列就是所求的解

怎么样,玄学吧【笑】
看到这里,还是请自行思考5~10分钟
一步一步理解(也可以画图,也可以论证,理解就行)

我的理解

我理解了蛮久,大概也是10min这样才看懂。

第一步,找到a和pos
我们反过来理解,a是右到左反递增数,那么说,从右到左在pos之前的一直都是保持递增的序列
ps:如果没找到就直接输出-1,自己想想为什么

第二步,找到b
这一步还是要连着第三步一起讲

第三步:交换a和b
这一步就是使新得到的序列比原序列大,连第二步来说,就是让新的到的序列在其他比原序列大的序列中尽可能小,因为b是第一个比a大的数

第四步:pos后面的翻转
因为pos后的都是递增,翻转后就也是递增,不过方向不一样,翻转后的递增是使b为关键的序列最小

我尽力解释清楚了
如果不相信诸位可以自己再试试
代码太简单也不贴了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值