题目描述
给你一个正整数数组 arr(可能存在重复的元素),请你返回可在 一次交换(交换两数字 arr[i] 和 arr[j] 的位置)后得到的、按字典序排列小于 arr 的最大排列。
如果无法这么操作,就请返回原数组。
示例 1:
输入:arr = [3,2,1]
输出:[3,1,2]
解释:交换 2 和 1
示例 2:
输入:arr = [1,1,5]
输出:[1,1,5]
解释:已经是最小排列
示例 3:
输入:arr = [1,9,4,6,7]
输出:[1,7,4,6,9]
解释:交换 9 和 7
提示:
- 1 <= arr.length <= 104
- 1 <= arr[i] <= 104
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/previous-permutation-with-one-swap
题目分析
如果arr中所有元素都是升序排列,那么不能通过交换得到更小的排列。只需要找到位置最靠后的一组arr[i]和arr[j],其中i<j,arr[i]>arr[j],i尽可能大
class Solution {
public:
vector<int> prevPermOpt1(vector<int>& arr) {
int len=arr.size();
int flag=0;
for(int i=len-2;i>=0;i--){ //从最后一位向前遍历,可以保证找到的第一组数交换后排列最大
if(flag) break;
for(int j=len-1;j>i;j--){
if(j>i+1){ //如果有连续多位数相同,需要将位置最靠前的一位与前面找到的值交换
if(arr[j]==arr[j-1]) continue;
}
if(arr[i]>arr[j]){
flag=1;
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
break;
}
}
}
return arr;
}
};
和官方题解给的思路相同,代码大同小异
总结
贪心算法,比较简单。力扣还是很喜欢玩序列相关的题