给定一个非负整数,你至多可以交换一次数字中的任意两位。返回你能得到的最大值。
输入: 2736
输出: 7236
解释: 交换数字2和数字7。
输入: 9973
输出: 9973
解释: 不需要交换。
注意:
- 给定数字的范围是 [ 0 , 1 0 8 ] [0, 10^8] [0,108]
由于对于整数 $num $的十进制数字位长最长为 8 8 8 位,任意两个数字交换一次最多有 28 28 28 种不同的交换方法,因此可以尝试遍历所有可能的数字交换方法即可,并找到交换后的最大数字即可。
找每位右侧的最大值然后贪心地从高位向低位考察, 当有数值相同的多个大数时,选择低位的数字
比如
86599, 交换最高位和最低位的收益(96598)是大于交换最高位和次低位的收益的(96589)
class Solution:
def maximumSwap(self, num: int) -> int:
ans = num
s = list(str(num))
for i in range(len(s)):
for j in range(i):
# 交换i,j的位置
s[i], s[j] = s[j], s[i]
ans = max(ans, int(''.join(s)))
# 还原s数组,方便后续比较
s[i], s[j] = s[j], s[i]
return ans
复杂度分析:
- 时间复杂度: O ( l o g 2 n u m ) O(log^2num) O(log2num),其中整数 num \textit{num} num 为给定的数字。 num \textit{num} num 转换为十进制数,有 O ( log num ) O(\log \textit{num}) O(lognum)个数字,一共有 O ( log 2 num ) O(\log^2 \textit{num}) O(log2num)种不同的交换方法。
- 空间复杂度: O ( l o g n u m ) O(lognum) O(lognum),其中整数 num \textit{num} num 为给定的数字。 num \textit{num} num 转换为十进制数,有 O ( log num ) O(\log \textit{num}) O(lognum)O 个数字,需要保存 num \textit{num} num 所有的数字。
class Solution:
def maximumSwap(self, num: int) -> int:
nums = []
# nums数组中高位在数组右边
while num:
nums.append(num % 10)
num //= 10
print(nums)
# 建立索引
right_max = [i for i in range(len(nums))]
print(right_max)
# 从低位到高位遍历,找到每位的右侧最大数字,记录的是下标
for i in range(1, len(nums)):
if nums[right_max[i - 1]] >= nums[right_max[i]]:
right_max[i] = right_max[i - 1]
# 从高位向低位遍历,
for i in range(len(right_max)-1, -1, -1):
if nums[right_max[i]] > nums[i]:
nums[i], nums[right_max[i]] = nums[right_max[i]], nums[i]
break
ans = 0
for i in range(len(nums)-1, -1, -1):
ans *= 10
ans += nums[i]
return ans
复杂度分析:
- 时间复杂度: O ( l o g n u m ) O(lognum) O(lognum),其中整数 num \textit{num} num 为给定的数字。
- 空间复杂度: O ( l o g n u m ) O(lognum) O(lognum),其中整数 num \textit{num} num 为给定的数字。
参考:
1.https://leetcode.cn/problems/maximum-swap/solution/zui-da-jiao-huan-by-leetcode-solution-lnd5/
2.https://leetcode.cn/problems/maximum-swap/solution/by-isuxiz-d3sh/