LeetCode-python 1053.交换一次的先前排列

题目链接
难度:中等       类型: 贪心算法


给你一个正整数的数组 A(其中的元素不一定完全不同),请你返回可在 一次交换(交换两数字 A[i] 和 A[j] 的位置)后得到的、按字典序排列小于 A 的最大可能排列。

如果无法这么操作,就请返回原数组。

示例1

输入:[3,2,1]
输出:[3,1,2]
解释:交换 2 和 1

示例2

输入:[1,1,5]
输出:[1,1,5]
解释: 这已经是最小排列

示例3

输入:[1,9,4,6,7]
输出:[1,7,4,6,9]
解释:交换 9 和 7

示例4

输入:[3,1,1,3]
输出:[1,3,1,3]
解释:交换 1 和 3

解题思路


为了使交换后的数小于原数又尽可能的大,所以更希望靠后的数字交换
经过找规律发现,从后往前第一个递增的数就是要交换的数a,该数右边一定有一个比它小,找小的里面最大的那个跟它换,会使交换后的数尽可能的大,这个数字是从后往前第一个小于a的数b
例如示例3,从后往前第一个递增的数是9,从后往前第一个小于9的数是7,所以两者交换
有一种特殊的情况,即示例4,不仅要找到b,还要找到离a最近的b,代码实现起来很简单

代码实现

class Solution(object):
    def prevPermOpt1(self, A):
        """
        :type A: List[int]
        :rtype: List[int]
        """
        n = len(A)
        right = n-1
        for i in range(n-1,0,-1):
            if A[i-1] > A[i]:
                j = n-1
                while A[j]>=A[i-1] or A[j] == A[j-1]:
                    j -= 1   
                A[j], A[i-1] = A[i-1], A[j]
                break                   
        return A
                

本文链接:https://www.jianshu.com/p/84327e0a4b54

你可能感兴趣的:(LeetCode-python 1053.交换一次的先前排列)