- 先考虑最简单的情况,如果在首位之后有比它大的数字,那么显然交换这两个数字是最优解
- 其次如果比它大的数字在后面不止出现了一次,那面显然是用最后一次出现的那个位置进行交换(要使值最大,低位要小,高位要大)
- 继而考虑如果首位之后没有比它大的数字,那么我们就要考虑第二位该怎么交换,第二位的交换规则和第一步,第二步一样,以此类推,直到最后一位
- 上面的方法目前最坏情况下是O(n2)的,下面优化 “寻找下标 i ,之后最后一个比它大的值的下标” 问题
- 通过从后往前遍历一次数组,我们就可以得到我们需要的下标 i 之后的最大值,同时也可以记录下标
- 通过上面的优化,问题可以在O(n)时间内解决
class Solution:
def maximumSwap(self, num: int) -> int:
s = list(map(int, str(num)))
nextmax = [[0] * 2 for _ in range(len(s))]
nextmax[-1][0] = s[-1]
nextmax[-1][1] = -1
for i in range(len(s) - 2, -1, -1):
if s[i] > nextmax[i + 1][0]:
nextmax[i] = [s[i], i]
else:
nextmax[i] = nextmax[i + 1]
index = 0
while index < len(s) - 1 and nextmax[index + 1][0] <= s[index]:
index += 1
s[index], s[nextmax[index][1]] = s[nextmax[index][1]], s[index]
return int(''.join(list(map(str, s))))