每日一题 670. 最大交换(中等,后缀)

在这里插入图片描述

  1. 先考虑最简单的情况,如果在首位之后有比它大的数字,那么显然交换这两个数字是最优解
  2. 其次如果比它大的数字在后面不止出现了一次,那面显然是用最后一次出现的那个位置进行交换(要使值最大,低位要小,高位要大)
  3. 继而考虑如果首位之后没有比它大的数字,那么我们就要考虑第二位该怎么交换,第二位的交换规则和第一步,第二步一样,以此类推,直到最后一位
  4. 上面的方法目前最坏情况下是O(n2)的,下面优化 “寻找下标 i ,之后最后一个比它大的值的下标” 问题
  5. 通过从后往前遍历一次数组,我们就可以得到我们需要的下标 i 之后的最大值,同时也可以记录下标
  6. 通过上面的优化,问题可以在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))))

你可能感兴趣的:(用Python刷力扣,python,leetcode,数据结构)