返回

在模拟和 数学 中,最大交换最小切换才最优 : LeetCode 670

后端

直奔主题:最大交换

在计算机科学中,最大交换 问题要求您找到一种方法,将一个非负整数中的两个数字交换位置,使得交换后的数字最大。例如,如果给定的数字是 1234,那么最大交换后得到的数字将是 4231。

解决这个问题的一种简单方法是,首先将数字转换为字符串,然后将字符串中的两个字符交换位置。然而,这种方法的效率并不高,因为它需要创建和修改字符串。

一种更有效的方法是,使用数学运算来直接交换数字中的两个数字。为此,您需要找到两个数字的索引,然后使用位操作来交换它们的二进制表示。

模拟的力量:一步一步解决问题

我们首先将给定数字转换为字符串。然后,我们找到需要交换的两个数字的索引。最后,我们使用位操作来交换它们的二进制表示。

def maximumSwap(num):
    num_str = str(num)
    max_idx = len(num_str) - 1
    for i in range(len(num_str) - 2, -1, -1):
        if num_str[i] > num_str[max_idx]:
            max_idx = i

    min_idx = -1
    for i in range(len(num_str) - 1, -1, -1):
        if num_str[i] < num_str[max_idx]:
            min_idx = i
            break

    num_str = list(num_str)
    num_str[max_idx], num_str[min_idx] = num_str[min_idx], num_str[max_idx]
    return int(''.join(num_str))

数学之美:巧妙利用位操作

位操作是计算机科学中的一项基本技术,它允许您直接操作数字的二进制表示。在我们的解决方案中,我们使用位操作来交换两个数字的二进制表示。

def swapBits(num, i, j):
    mask = (1 << i) | (1 << j)
    num ^= mask
    return num

优化:从 O(n^2) 到 O(n)

上面的解决方案的时间复杂度为 O(n^2),其中 n 是给定数字的位数。我们可以通过使用哈希表来将时间复杂度降低到 O(n)。

def maximumSwap(num):
    num_str = str(num)
    max_idx = len(num_str) - 1
    last_idx = {}
    for i in range(len(num_str)):
        if num_str[i] > num_str[max_idx]:
            max_idx = i
        last_idx[num_str[i]] = i

    min_idx = -1
    for i in range(len(num_str) - 1, -1, -1):
        if num_str[i] < num_str[max_idx] and last_idx[num_str[max_idx]] > i:
            min_idx = i
            break

    num_str = list(num_str)
    num_str[max_idx], num_str[min_idx] = num_str[min_idx], num_str[max_idx]
    return int(''.join(num_str))

总结

最大交换问题是一个经典的模拟和 数学 问题。它要求您找到一种方法,将一个非负整数中的两个数字交换位置,使得交换后的数字最大。我们介绍了两种解决这个问题的方法:一种是使用字符串操作,另一种是使用数学运算。我们还讨论了如何使用哈希表来将时间复杂度从 O(n^2) 降低到 O(n)。