我可以发现,从后往前,如果是降序的,我们无论怎么代替都不会比现在小,因为降序本身就是最小的。如果不是降序,那么我们就要找到第一个不是降序的数字,也就是我们准备交换的数字,之后我们在该数字身后的数(一定是从右往左,越来越小)中找到第一个比他小的数字,与之交换,则得到最终答案(要处理相同数字的情况),如果后面降序中存在相同,那么我们选最靠前的那个数字来交换。
class Solution {
public int[] prevPermOpt1(int[] A) {
int l = A.length-2;
while(l>=0 && A[l]<=A[l+1]){
l--;
}
if(l<0) return A;
int r = A.length-1;
while(A[r]>=A[l]){
r--;
}
while(A[r]==A[r-1]){
r--;
}
int tmp = A[l];
A[l] = A[r];
A[r] = tmp;
return A;
}
}
这个问题其实和按照字典序来寻找当前数的下一个数这一问题是类似的。如果当前数从右到左是升序的,那说明当前数就是最大的。那它下一个数就是最小的数(形成个循环),其实就是不需要任何操作了。从右到左,找到第一个形成降序的位置,记为i。然后再从右到左,找到第一个比i位置大的数。交换i,j位置的数。然后将i位置之后的数从小到大排序。
这道题本身其实就是字典序问题,只不过不需要调整顺序那一步了,直接交换位置就完事了。