数据结构与算法之 leetcode 数组移动零 双指针原地操作

数据结构与算法阿木 发布于 9 天前 3 次阅读


数组移动零(双指针原地操作)——LeetCode算法解析

在LeetCode等编程竞赛平台中,数组移动零是一个经典的算法问题。该问题要求我们将数组中的所有零移动到数组的末尾,同时保持非零元素的相对位置不变。这个问题不仅考察了我们对数组操作的理解,还考验了我们的算法优化能力,尤其是原地操作和双指针技术的应用。本文将围绕这一主题,详细解析解决方案,并探讨其背后的数据结构与算法原理。

问题分析

题目描述

给定一个数组 `nums`,编写一个函数,将数组中的所有零移动到数组的末尾,同时保持非零元素的相对位置不变。

输入与输出

- 输入:一个整数数组 `nums`。

- 输出:原地修改后的数组 `nums`。

示例

plaintext

输入:[0, 1, 0, 3, 12]


输出:[1, 3, 12, 0, 0]


难度

- 简单

解题思路

为了解决这个问题,我们可以采用双指针技术。具体步骤如下:

1. 初始化指针:设置两个指针 `left` 和 `right`,其中 `left` 用于遍历数组,`right` 用于指向下一个非零元素应该放置的位置。

2. 遍历数组:使用 `left` 指针遍历数组,对于每个元素:

- 如果元素为非零,将其与 `right` 指向的元素交换。

- 如果元素为零,则不进行操作。

3. 移动指针:每次交换后,将 `right` 指针向右移动一位。

4. 结束条件:当 `left` 指针移动到数组末尾时,所有非零元素已经移动到数组的前面,零元素被移动到后面。

这种方法不需要额外的空间,因此是原地操作。

代码实现

以下是使用Python实现的代码示例:

python

def moveZeroes(nums):


left, right = 0, 0


while left < len(nums):


if nums[left] != 0:


nums[left], nums[right] = nums[right], nums[left]


right += 1


left += 1


return nums

测试代码


nums = [0, 1, 0, 3, 12]


print(moveZeroes(nums)) 输出:[1, 3, 12, 0, 0]


时间复杂度与空间复杂度

- 时间复杂度:O(n),其中 n 是数组的长度。我们只需要遍历一次数组。

- 空间复杂度:O(1),我们只使用了常数个额外空间。

总结

数组移动零问题是一个典型的双指针问题,通过巧妙地使用双指针技术,我们可以实现原地操作,优化空间复杂度。在解决这类问题时,理解数据结构和算法原理至关重要,这有助于我们更好地设计高效的解决方案。

扩展与思考

- 如果数组中包含负数,上述方法仍然有效。

- 如果要求移动零的保持非零元素的相对顺序不变,上述方法仍然适用。

- 如果数组非常大,可以考虑使用位操作来进一步优化空间复杂度。

通过解决这类问题,我们可以加深对双指针技术和原地操作的理解,为解决更复杂的算法问题打下坚实的基础。