|
1 | 1 | --- |
2 | 2 | title: 670.最大交换 |
3 | 3 | date: 2022-09-13 08:24:45 |
4 | | -tags: [题解, LeetCode, 中等, 贪心, 数学] |
| 4 | +tags: [题解, LeetCode, 中等, 贪心, 数学, 暴力] |
5 | 5 | --- |
6 | 6 |
|
7 | 7 | # 【LetMeFly】670.最大交换 |
@@ -33,8 +33,34 @@ tags: [题解, LeetCode, 中等, 贪心, 数学] |
33 | 33 | </ol> |
34 | 34 |
|
35 | 35 |
|
| 36 | + |
| 37 | +## 方法一:两层遍历 + 暴力 |
| 38 | + |
| 39 | +二话不说直接枚举两个要交换的位置,交换之并取所有结果中最大的一个作为答案返回。 |
| 40 | + |
| 41 | +### AC代码 |
| 42 | + |
| 43 | +#### Python |
| 44 | + |
| 45 | +```python |
| 46 | +class Solution: |
| 47 | + def maximumSwap(self, num: int) -> int: |
| 48 | + ans = num |
| 49 | + s = str(num) |
| 50 | + for i in range(len(s)): |
| 51 | + for j in range(i + 1, len(s)): |
| 52 | + temp = list(s) |
| 53 | + temp[i], temp[j] = temp[j], temp[i] |
| 54 | + ans = max(ans, int(''.join(temp))) |
| 55 | + return ans |
| 56 | +``` |
| 57 | + |
| 58 | ++ 时间复杂度$O(\log^2 num)$ |
| 59 | ++ 空间复杂度$O(\log num)$ |
| 60 | + |
| 61 | +如果再加上一点小贪心,就变成了方法二(方法二相比于方法一而言实现起来变复杂了,但是可能提前结束循环) |
36 | 62 |
|
37 | | -## 方法一:两次遍历 |
| 63 | +## 方法二:两层遍历 + 贪心 |
38 | 64 |
|
39 | 65 | 要想使得一次交换的结果尽量大,那么越大的数就要尽可能地越靠前。 |
40 | 66 |
|
@@ -72,5 +98,78 @@ public: |
72 | 98 | }; |
73 | 99 | ``` |
74 | 100 |
|
| 101 | +2024.1.22日看上述提交代码,执行耗时0ms击败```100.00%```使用C++的用户,消耗内存5.70MB击败```100.00%```使用C++的用户。 |
| 102 | +
|
| 103 | +小数据下复杂度低不一定慢,但面试的话可能会问有无复杂的更低的算法。 |
| 104 | +
|
| 105 | +## 方法三:一层遍历 + 贪心 |
| 106 | +
|
| 107 | +类似方法一: |
| 108 | +
|
| 109 | +> 要想使得一次交换的结果尽量大,那么越大的数就要尽可能地越靠前。 |
| 110 | +
|
| 111 | +将数字(字符串的形式)分为两部分:前面非递增的一部分 + 后续部分。例如```998755738786```可以分为```998755```和```738786```两部分。 |
| 112 | +
|
| 113 | +两个元素的交换肯定不会**都**在第一部分的非递增区域,一定发生在第二部分和第一部分之间。 |
| 114 | +
|
| 115 | +假设第二部分的最大的数(如有同大取其后)的位置是```loc2```,第一个小于```num[loc2]```的数的位置是```loc1```(一定在第一部分),则交换```num[loc1]```和```num[loc2]```既能得到最大的数。 |
| 116 | +
|
| 117 | ++ 时间复杂度$O(\log num)$ |
| 118 | ++ 空间复杂度$O(\log num)$ |
| 119 | +
|
| 120 | +### AC代码 |
| 121 | +
|
| 122 | +#### C++ |
| 123 | +
|
| 124 | +```cpp |
| 125 | +class Solution { |
| 126 | +private: |
| 127 | + string s; |
| 128 | + |
| 129 | + int getFirstIncreaseLoc() { |
| 130 | + for (int i = 1; i < s.size(); i++) { |
| 131 | + if (s[i] > s[i - 1]) { |
| 132 | + return i; |
| 133 | + } |
| 134 | + } |
| 135 | + return s.size(); |
| 136 | + } |
| 137 | + |
| 138 | + int getMaxLocFromA(int a) { |
| 139 | + int ans = a; |
| 140 | + int M = s[a]; |
| 141 | + for (; a < s.size(); a++) { |
| 142 | + if (s[a] >= M) { |
| 143 | + ans = a; |
| 144 | + M = s[a]; |
| 145 | + } |
| 146 | + } |
| 147 | + return ans; |
| 148 | + } |
| 149 | +
|
| 150 | + int getFirstLessthanLoc(char n) { |
| 151 | + for (int i = 0; i < s.size(); i++) { |
| 152 | + if (s[i] < n) { |
| 153 | + return i; |
| 154 | + } |
| 155 | + } |
| 156 | + return s.size(); // Fake Return |
| 157 | + } |
| 158 | +public: |
| 159 | + int maximumSwap(int num) { |
| 160 | + s = to_string(num); |
| 161 | + int firstIncreaseLoc = getFirstIncreaseLoc(); // 将字符串分为两部分 |
| 162 | + if (firstIncreaseLoc == s.size()) { |
| 163 | + return num; |
| 164 | + } |
| 165 | + int maxLoc = getMaxLocFromA(firstIncreaseLoc); // 第二部分的最大的位置 |
| 166 | + int firstLessthanLoc = getFirstLessthanLoc(s[maxLoc]); // 第一部分第一个小于num[maxLoc]的数 |
| 167 | + swap(s[firstLessthanLoc], s[maxLoc]); // 交换之 |
| 168 | + return atoi(s.c_str()); |
| 169 | + } |
| 170 | +}; |
| 171 | +``` |
| 172 | + |
| 173 | + |
75 | 174 | > 同步发文于CSDN,原创不易,转载请附上[原文链接](https://blog.tisfy.eu.org/2022/09/13/LeetCode%200670.%E6%9C%80%E5%A4%A7%E4%BA%A4%E6%8D%A2/)哦~ |
76 | 175 | > Tisfy:[https://letmefly.blog.csdn.net/article/details/126826280](https://letmefly.blog.csdn.net/article/details/126826280) |
0 commit comments