Skip to content

Commit 1eda993

Browse files
Create 1053. 交换一次的先前排列.md
1 parent 064d6ef commit 1eda993

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#### 1053. 交换一次的先前排列
2+
3+
难度:中等
4+
5+
---
6+
7+
给你一个正整数数组 `arr`(可能存在重复的元素),请你返回可在  **一次交换** (交换两数字 `arr[i]``arr[j]` 的位置)后得到的、按字典序排列小于 `arr` 的最大排列。
8+
9+
如果无法这么操作,就请返回原数组。
10+
11+
**示例 1:**
12+
13+
```
14+
输入:arr = [3,2,1]
15+
输出:[3,1,2]
16+
解释:交换 2 和 1
17+
```
18+
19+
**示例 2:**
20+
21+
```
22+
输入:arr = [1,1,5]
23+
输出:[1,1,5]
24+
解释:已经是最小排列
25+
```
26+
27+
**示例 3:**
28+
29+
```
30+
输入:arr = [1,9,4,6,7]
31+
输出:[1,7,4,6,9]
32+
解释:交换 9 和 7
33+
```
34+
35+
**提示:**
36+
37+
* `1 <= arr.length <= 10^4`
38+
* `1 <= arr[i] <= 10^4`
39+
40+
---
41+
42+
贪心:
43+
44+
1. 首先,当前序列开始从后往前找,找到第一个降序的位置(`A[i]>A[i+1]`),则必存在能构造比当前小的序列。
45+
46+
2. 接着,在 `A[i]` 后面的数字中,找出小于 `A[i]` 且最接近 `A[i]` 的值的数字并和 `A[i]` 交换,经过第一步的倒序遍历后,`A[i]` 后面的数字一定是**非降序**的。
47+
48+
```Java
49+
class Solution {
50+
public int[] prevPermOpt1(int[] arr) {
51+
int n = arr.length;
52+
for(int i = n - 2; i >= 0; i--){
53+
if(arr[i] > arr[i + 1]){
54+
int j = n - 1;
55+
while(arr[j] >= arr[i] || arr[j] == arr[j - 1]) j--;
56+
swap(arr, i , j);
57+
break;
58+
}
59+
}
60+
return arr;
61+
}
62+
63+
private void swap(int[] arr, int i, int j){
64+
int temp = arr[i];
65+
arr[i] = arr[j];
66+
arr[j] = temp;
67+
}
68+
}
69+
```

0 commit comments

Comments
 (0)