题目描述:
给你一个正整数的数组 A
(其中的元素不一定完全不同),请你返回可在 一次交换(交换两数字 A[i]
和 A[j]
的位置)后得到的、按字典序排列小于 A
的最大可能排列。
如果无法这么操作,就请返回原数组。
示例 1:
输入:[3,2,1]
输出:[3,1,2]
解释:
交换 2 和 1
示例 2:
输入:[1,1,5]
输出:[1,1,5]
解释:
这已经是最小排列
示例 3:
输入:[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 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:
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; } };