📌  相关文章
📜  按每对相邻索引最多进行一次交换形成的按词典顺序排列的最小数组(1)

📅  最后修改于: 2023-12-03 15:39:48.825000             🧑  作者: Mango

按每对相邻索引最多进行一次交换形成的按词典顺序排列的最小数组

介绍

给定一个数组(字符串),你需要通过将数组中的元素重新排列,将其重新排列成字典序最小的情况。其中,对相邻元素进行最多一次交换操作,以实现重新排序。

解法

我们可以先遍历数组,找到第一个下降的元素,例如 nums[i] > nums[i+1]。然后再次遍历,找到最后一个大于元素 nums[i] 的元素 nums[j],并交换 nums[i]nums[j]。将第 i+1 个元素到最后一个元素,按照升序排列。

def minimum_lexicographically(nums: List[int]) -> List[int]:
    n = len(nums)
    if n <= 1:
        return nums

    i = 0
    while i < n - 1 and nums[i] <= nums[i+1]:
        i += 1

    if i == n - 1:
        return nums

    j = n - 1
    while j > i and nums[j] >= nums[i]:
        j -= 1

    nums[i], nums[j] = nums[j], nums[i]
    nums[i+1:] = sorted(nums[i+1:])

    return nums
示例
>>> nums = [3, 2, 1]
>>> minimum_lexicographically(nums)
[1, 2, 3]

>>> nums = [1, 5, 8, 4, 7, 6, 5, 3, 1]
>>> minimum_lexicographically(nums)
[1, 5, 8, 4, 7, 6, 5, 1, 3]
总结

以上的解法时间复杂度为 $O(n \log n)$,即对相邻元素的比较需要 $O(n)$,而排序需要 $O(n \log n)$。空间复杂度为 $O(1)$,即只用了常数个变量来保存需要交换的元素索引。这是一种比较简单的贪心算法,利用了交换相邻元素可以使得字典序变小的特性。