一、Problem
給你一個正整數的數組 A(其中的元素不一定完全不同),請你返回可在 一次交換(交換兩數字 A[i] 和 A[j] 的位置)後得到的、按字典序排列小於 A 的最大可能排列。
如果無法這麼操作,就請返回原數組
輸入:[3,2,1]
輸出:[3,1,2]
解釋:
交換 2 和 1
輸入:[3,1,1,3]
輸出:[1,3,1,3]
解釋:
交換 1 和 3
二、Solution
方法一:規律
先交換位於後面的元素對字典序影響最小,所以從後往前找第一個升序對,將他們交換後返回,這是錯的,沒有那麼簡單…
比如這個樣例的答案就錯了
輸入:[3,1,1,3]
輸出:[1,1,3,3]
預期:[1,3,1,3]
class Solution {
public int[] prevPermOpt1(int[] A) {
int n = A.length, ans[] = new int[n], min = -1;
for (int i = n-2; i >= 0; i--)
for (int j = n-1; j > i; j--) {
if (A[i] > A[j]) {
int t = A[i];
A[i] = A[j];
A[j] = t;
return A;
}
}
return A;
}
}
但出發點是對的,這是代碼寫錯了,上面找的升序數對不是挨地最近的,而交換最近的升序數對才能確保答案正確
class Solution {
public int[] prevPermOpt1(int[] A) {
int n = A.length, ans[] = new int[n], min = -1;
for (int i = n-2; i >= 0; i--) if (A[i] > A[i+1]) {
for (int j = n-1; j > i; j--) {
if (A[i] > A[j] && A[j] != A[j-1]) {
int t = A[i];
A[i] = A[j];
A[j] = t;
return A;
}
}
}
return A;
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,