LeetCode最大交换

670. 最大交换

给定一个非负整数,你至多可以交换一次数字中的任意两位。返回你能得到的最大值。

示例 1 :

输入: 2736

输出: 7236

解释: 交换数字2和数字7

示例 2 :

输入: 9973

输出: 9973

解释: 不需要交换。

注意:

  1. 给定数字的范围是 [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))

posted @   JunanP  阅读(13)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示