返回

LeetCode 41:深度探索“in-place”思想,轻松解决经典数组问题

人工智能

导语

LeetCode 41 是 LeetCode 题解系列的第 21 篇。今天,我们将通过这道题目来深入理解“in-place”思想。题目看似简单,但却蘊含着深刻的算法思想。

题目剖析

给定一个整数数组,要求返回最小的不在数组当中的正整数。乍看之下,题目有些绕口,但其实可以简单理解为:从 1 开始找到第一个不在数组中的元素。

核心思想

为了解决这个问题,我们可以巧妙地利用“in-place”思想。这种思想的核心是直接在原数组上进行操作,而不创建新的数组。这样可以节省空间,并使算法更加高效。

具体步骤

  1. 首先,我们将数组中的所有元素都标记为负数,但需要注意的是,如果数组中存在 0,则将其跳过,不改变它的值。
  2. 然后,我们遍历数组,对于每一个正数,我们将其对应的负数位置上的值置为正数。
  3. 最后,我们再遍历一次数组,找到第一个为负数的位置,该位置对应的正整数就是我们要求的缺失的最小正整数。

代码示例

def first_missing_positive(nums):
    # 将所有元素标记为负数
    for i in range(len(nums)):
        if nums[i] <= 0:
            continue
        nums[i] = -abs(nums[i])

    # 将正数对应位置上的值置为正数
    for i in range(len(nums)):
        index = abs(nums[i]) - 1
        if index < len(nums) and nums[index] > 0:
            nums[index] = -nums[index]

    # 寻找第一个为负数的位置
    for i in range(len(nums)):
        if nums[i] > 0:
            return i + 1

    # 如果没有找到缺失的正整数,则返回数组长度加 1
    return len(nums) + 1

# 测试用例
nums = [3, 4, -1, 1]
print(first_missing_positive(nums))  # 2

nums = [1, 2, 0]
print(first_missing_positive(nums))  # 3

nums = [7, 8, 9, 11, 12]
print(first_missing_positive(nums))  # 1

nums = [-3, -1, 1, 2, 0]
print(first_missing_positive(nums))  # 3

复杂度分析

  • 时间复杂度:O(n),其中 n 是数组的长度。
  • 空间复杂度:O(1),因为我们直接在原数组上进行操作,没有创建新的数组。

总结

LeetCode 41 是一道经典的数组问题,它巧妙地利用了“in-place”思想,在原数组上进行操作,高效地解决了问题。这种思想在算法中非常有用,因为它可以节省空间,并提高算法的效率。希望通过本文,您对“in-place”思想有了更深刻的理解。