題目描述:python
給你一個正整數的數組 A
(其中的元素不必定徹底不一樣),請你返回可在 一次交換(交換兩數字 A[i]
和 A[j]
的位置)後獲得的、按字典序排列小於 A
的最大可能排列。數組
若是沒法這麼操做,就請返回原數組。spa
示例 1:code
輸入:[3,2,1]
輸出:[3,1,2]
解釋:
交換 2 和 1
示例 2:blog
輸入:[1,1,5]
輸出:[1,1,5]
解釋:
這已是最小排列
示例 3:io
輸入:[1,9,4,6,7] 輸出:[1,7,4,6,9] 解釋: 交換 9 和 7
思路:
對數組A(A.size()=n),從後往前遍歷,找到第一個A[i]<A[i-1]的i(i>0,找不到說明沒辦法調整,返回A),而後在下標i到n-1的數中找到小於A[i-1]的最大值max,找到下標i到n-1數中第一個等於max的j,交換A[j]和A[i-1].
C++:
class Solution { public: vector<int> prevPermOpt1(vector<int>& A) { if (A.size() == 1) return A; for (int i = A.size() - 1; i > 0; i--){ if (A[i] < A[i - 1]){ int max = A[i]; for (int j = i; j < A.size(); j++){ if (A[j] < A[i - 1] && max < A[j]) max = A[j]; } for (int j = i; j < A.size(); j++){ if (A[j] == max){ A[j] = A[i - 1]; A[i - 1] = max; return A; } } } } return A; } };
python:class
class Solution: def prevPermOpt1(self, A: List[int]) -> List[int]: if len(A)==1: return A for i in range(len(A)-1,0,-1): if A[i]<A[i-1]: max=A[i] for j in range(i,len(A)): if A[j]<A[i-1] and max<A[j]: max=A[j] for j in range(i,len(A)): if A[j]==max: A[j]=A[i-1] A[i-1]=max return A return A
C++運行時間152 ms,暫時超過90.57%的提交,目前最快的解法112ms,code:List
class Solution { public: vector<int> prevPermOpt1(vector<int>& A) { int length = A.size(); if(length <= 1){ return A; } int flag = false; int i = 1; int index = -1; while(i < length){ if(A[i] < A[i - 1]){ index = i - 1; } i++; } if(index != -1){ int swapIndex = index + 1; int maxTemp = A[index + 1]; for(int j = index + 1; j < length; j++){ if(A[j] < A[index] && A[j] > maxTemp){ maxTemp = A[j]; swapIndex = j; } } A[swapIndex] = A[index]; A[index] = maxTemp; } return A; } };