LeetCode最大交换
给定一个非负整数,你至多可以交换一次数字中的任意两位。返回你能得到的最大值。
示例 1 :
输入: 2736
输出: 7236
解释: 交换数字2和数字7。
示例 2 :
输入: 9973
输出: 9973
解释: 不需要交换。
注意:
- 给定数字的范围是 [0, 108]
思路:
主要要找两个数,一前一后做交换嘛。
找第一个数:要让交换一次后的数字就有最大,我们只需要从数字的左边开始找,找到第一个比后面数字小的那个数字,这个数字就是我们要用来交换的第一个数。这个很好理解,因为我们要让数字交换后变成最大,那么肯定是要尽可能的影响到高位数。
找第二个数:那么找到这个数后,要和谁做交换呢?我们要在后面比这个数大的数字中找到最大、最靠后的那个数。找最大的数很好理解,毕竟要把这个数换到高位来,肯定是越大越能让整个数值变大;其次是要靠后的,假如百位和十位都是9,那么我们选出来的第一个数要和十位上的9去做交换,这样可以让我们把小的数往后放,让交换后的数达到最大。
所以整体思路就是,找到第一个数(上面第一段),找到第二个数(上面第二段),交换。其中找到第一个数其实就是找“下一个较大值”是否存在,可以用我们的单调栈来辅助做。关于单调栈可以看这篇文章,后面代码就不解释直接用啦~
代码:
class Solution(object):
def maximumSwap(self, num):
#先来一波单调栈 找到有下一个比它大的值的值位置,那么这个位置就是交换的起点
stack=[]
num=list(str(num))#将数字变成列表 方便操作
lenth = len(num)
res = [0]*lenth
for i in range(lenth-1,-1,-1):
while(stack and num[stack[-1]]<=num[i]):
stack.pop()
res[i]=stack[-1] if stack else -1
stack.append(i)
#这里往上都是单调栈的模板调用
#开始根据单调栈结果找第一个交换值
begin=-1
for i,r in enumerate(res):
if r==-1:continue
begin=i
break
#至此 找到了begin的开始位置 假如begin没动的话,说明数据是递减的
if begin==-1:
return int(''.join(num))#直接返回原数字
#接下来 从begin开始,往后找比他大的 且靠后的最大值作为第二个交换值
maxx=0
index=None
for i,n in enumerate(num):
if i<=begin:continue
if n>num[begin]:#如果遇到比这个值大的
if n>=maxx:#这个值还大于等于当前最大值
maxx=n#更新maxx 和下标
index=i
num[begin],num[index] = num[index],num[begin]#两个交换值作交换
return int(''.join(num))
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了