力扣小周推荐——最大交换


小周让我做的一道题,俺kuakua两下,不到俩小时就做完了,虽然也不快,但也狠狠平复了轮换数组那道题的伤o(╥﹏╥)o
在这里插入图片描述

我的做法

  • 思路:从第一个位置开始,判断这个位置的值是否是后面数字中的最大值,若不是,就要交换这个位置的值和最大值所在的位置,注意,这个最大值所在的位置是最后一次出现最大值的位置,结束循环,返回;若是,则到下一位再重复操作,直到出现第一种情况或者已经到最后一位,到最后一位就说明这个数组不用换了
class Solution:    
    def maximumSwap(self, num: int) -> int:
        nums = list(str(num))
        n = len(nums)
        for i in range(n):
            nums[i] = int(nums[i])
        current =1        
        for i in range(n):
            best = i
            current = best+1
            while current < n:
                if nums[current] >= nums[best]:
                    best = current
                current += 1
            if nums[best]!=nums[i]:
                nums[i],nums[best] = nums[best],nums[i]
                count = 0
                for j in range(n):
                    count += nums[j] * 10**(n-1-j)
                return count
        return num
  • 具体操作:
  • 将数字每一位拆开变成数组
  • 指定两个指针 best和current,分别表示剩下的数字中最大的数字所处的索引和当前正进行到的位置
  • 第一个循环是对数组每个位置都要判断是否交换
  • while循环是找到当前位置的元素以后的元素中最大元素的最大索引
  • 只要这个索引不是当前判断的位置,都要换

在这里插入图片描述

更新时间复杂度更低的方法

  • 以上方法虽然也能做出来,但是机智的朋友们已经发现了,这个算法的时间复杂度是 O ( n 2 ) O(n^2) O(n2)
  • 小周告诉我,这道题还有 O ( n ) O(n) O(n)的解决办法!
  • 思路:逆序遍历一次,完成两个任务,1、找到最大的数;2、找到最大的数左边比它小的数,且位置要最靠左
  • 以上思路大致说清楚了,但是有一些奇怪的情况,让我震惊,比如99901,如果只按上面的思路是没办法获得99910的正确答案的,原因就在于少了一个备胎计划
    • 按以上思路,最大的数肯定是9,但是由于没有考虑到最大的数左边可能没有比它小的数(即没有考虑最大的数左边全是重复最大数的情况),最后的答案只能是99901
    • 而备胎计划则是,及时记录下在某个最大值下可以交换的位置索引,即使出现了这一特殊情况,也有备选
    • 我太牛了,“备胎计划”这个名字可取得真好哈哈哈
    • 在这里插入图片描述
class Solution:    
    def maximumSwap(self, num: int) -> int:
        nums = list(str(num))
        n = len(nums)
        for i in range(n):
            nums[i] = int(nums[i])
        best = n-1        
        k = False            
        for i in range(n-1,0,-1):            
            if nums[i]>nums[best]:                
                best = i                
            if nums[best]>nums[i-1]:
                k= True
                p,q= i-1,best                
        if k:
            nums[q],nums[p] = nums[p],nums[q]
            count = ''
            for j in range(n):
                count += str(nums[j])
            return int(count)
        else:
            return num

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

universe_1207

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值