题目地址:
https://leetcode.com/problems/previous-permutation-with-one-swap/
给定一个长 n n n的数组 A A A,求一次交换下,字典序比 A A A小的最大的 A A A的重排。
由于要得到字典序尽量大的,我们考虑尽量改变靠后的数字,所以我们从后向前遍历,第一次遍历到 A [ i ] < A [ i − 1 ] A[i]<A[i-1] A[i]<A[i−1]的时候,由于 A [ i ] A[i] A[i]之后已经是升序了,字典序已经最小了不能变小,从而变 A [ i ] A[i] A[i]是最好的。将其与其后比其小的最大数交换即可。有个特殊情况,如果后面有若干相等的比其小的最大数,则需要交换最左边那个,这样字典序最大。代码如下:
class Solution {
public:
vector<int> prevPermOpt1(vector<int>& a) {
for (int i = a.size() - 1; i; i--)
if (a[i] < a[i - 1]) {
int j = i;
while (j < a.size() && a[j] < a[i - 1]) j++;
j--;
while (a[j] == a[j - 1]) j--;
swap(a[i - 1], a[j]);
break;
}
return a;
}
};
时间复杂度 O ( n ) O(n) O(n),空间 O ( 1 ) O(1) O(1)。