题目名称

给你一个正整数数组 arr(可能存在重复的元素),请你返回可在 一次交换(交换两数字 arr[i] 和 arr[j] 的位置)后得到的、按字典序排列小于 arr 的最大排列。

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

示例

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

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

题解

这道题我觉得应该先搞明白什么是字典序。
例如:
字符串的字典序是 字符串按照从 a-z 的大小排列,也就是 ASCII 码
数字的字典序是将 数字转成字符串 然后按照从 0-9 的顺序排列
数组的字典序 是对比对应序号的数字大小排列

因此知道上面的内容后,我们就可以得出以下结论:
如果想要得到小于当前数组的最大字典序排列,需要我们从数组最后开始遍历,找出第一个满足递减的数字的下标,然后找出右侧第一个小于当前数字的下标(也就是右侧的最大值),然后进行替换,得到了我们想要的数组

答案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* @param {number[]} arr
* @return {number[]}
*/
var prevPermOpt1 = function(arr) {
let l = arr.length
for(let i = l - 2; i >= 0; i--) {
if(arr[i] > arr[i + 1]) {
let j = l - 1
while(arr[j] >= arr[i] || arr[j] === arr[j - 1]) {
j--
}
[arr[i], arr[j]] = [arr[j], arr[i]]
break;
}
}
return arr
};