上一个排列

题目描述:给定一个整数数组来表示排列,找出其上一个排列。

样例:给出排列[1,3,2,3],其上一个排列是[1,2,3,3];给出排列[1,2,3,4],其上一个排列是[4,3,2,1]


方法与之前的“下一个排列”问题类似(详见:点击打开链接),如果上一个问题没有搞明白,请先移步给出的链接。在讲解这个问题之前,我会假设你已经完全明白“字典序”,“高位”,“低位”这些概念。


好了,看本题。找上一个排列,其实两个相邻的排列一定是满足拥有最长前缀的。所以,在“下一个排列”的问题中,我们是从右往左开始寻找需要改变的高位,这里,依然是类似的,我们从右往左开始寻找需要改变的高位。但是,不同的是,因为求取的是上一个排列,所以,我们找寻的目的是找到一个数值高的高位,将其数值变低,这一点与“下一个排列”是相反的。

所以,可以这样寻找:从右往左,找第一个不是降序的位置:例如,[2, 1, 3],3到1,降序;1到2,升序。于是定位需要改变的高位为数值2所在的位置。然后再从右往左寻找第一个比这个高位数值小的数,交换。这里,我们找到了1,于是,交换1和2,变成[1, 2, 3];最后,与“下一个排列”同理,因为只是上“一”个,所以,需要将高位之后的部分数组按降序排列。此处[1, 2, 3] -> [1, 3, 2]. 整个过程完成。


代码如下:

class Solution:
    # @param num :  a list of integer
    # @return : a list of integer
    def previousPermuation(self, num):
        n = len(num)
        right = n - 1
        # 从右往左,找第一个升序
        while right > 0:
            if num[right] < num[right - 1]:
                break
            else:
                right -= 1
        # 如果整个数组是降序排列,颠倒过来
        if right == 0:
            num.reverse()
            return num
        # 定位需要交换的高位
        right -= 1
        index = n - 1
        # 从右往左,找第一个比这个高位小的低位
        while index > right:
            # 交换高地位
            if num[index] < num[right]:
                num[index], num[right] = num[right], num[index]
                break
            else:
                index -= 1
        # 将被交换的高位之后的部分数组按逆序排列,因为只是上1个
        return num[:right + 1] + sorted(num[right + 1:], reverse=True)
        # write your code here


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值