题目:
给你一个正整数数组 arr(其中的元素不一定完全不同),请你返回可在 一次交换(交换两数字 arr[i] 和 arr[j] 的位置)后得到的、按字典序排列小于 arr 的最大可能排列。
如果无法这么操作,就请返回原数组。
算法:
leetcode.cn/problems/pr…
思路:从右到左遍历,找到升序的位置i(arr[i-1]<arr[i], i > 0),存在这样的i的话一定可以通过把换小arr[i-1]将arr变小,设它的交换对象为arr[j],从[i,n-1]找到一个小于arr[i-1]的最大的数交换,就可以得到小于当前数的最大数。
因为此时从n-1到i是降序或者等序,找到第一个小于arr[i-1]的数即可。
边界条件:如果arr[j-1]==arr[j],我们取arr[j]。
通过合理的分类讨论,是可以把问题简化分析清楚的。
func prevPermOpt1(arr []int) []int {
n := len(arr)
for i := n - 1; i > 0; i-- {
if arr[i - 1] > arr[i] {
for j := n - 1; j >= i; j -- {
if arr[j] < arr[i - 1] && arr[j] != arr[j - 1] {
arr[i - 1], arr[j] = arr[j], arr[i - 1]
return arr
}
}
}
}
return arr
}