2026/2/2 20:37:18
网站建设
项目流程
网站设计 做鼠标效果,六安做网站的公司,做网站尽在美橙互联,建设网站有什么法律么问题描述给定一个整数数组 nums#xff0c;编写一个函数将所有 0 移动到数组的末尾#xff0c;同时保持非零元素的相对顺序。示例#xff1a;输入: [0,1,0,3,12]
输出: [1,3,12,0,0]要求#xff1a;必须在原数组上操作#xff0c;不能拷贝额外的数组尽量减少操作次数思路编写一个函数将所有0移动到数组的末尾同时保持非零元素的相对顺序。示例输入: [0,1,0,3,12] 输出: [1,3,12,0,0]要求必须在原数组上操作不能拷贝额外的数组尽量减少操作次数思路双指针交换法算法思想这道题的难点在于如何在不使用额外空间的情况下原地完成零的移动并且保持非零元素的顺序。双指针交换法巧妙地解决了这个问题。我们使用两个指针慢指针left指向下一个非零元素应该放置的位置快指针right遍历整个数组寻找非零元素算法步骤初始化两个指针都指向数组开头快指针遍历整个数组当快指针遇到非零元素时与慢指针指向的元素交换交换后慢指针向前移动一位继续遍历直到数组结束Java实现代码class Solution { public void moveZeroes(int[] nums) { int left 0; // 慢指针 // 快指针遍历数组 for (int right 0; right nums.length; right) { // 找到非零元素 if (nums[right] ! 0) { // 交换非零元素到前面 int temp nums[left]; nums[left] nums[right]; nums[right] temp; left; // 慢指针右移 } } } }逐步解析执行过程让我们以示例[0, 1, 0, 3, 12]为例一步步解析代码的执行初始状态text数组: [0, 1, 0, 3, 12] 指针: left0, right0第1步right0textnums[0] 0不满足条件不交换 数组: [0, 1, 0, 3, 12] 指针: left0, right1第2步right1textnums[1] 1 ≠ 0满足条件 交换 nums[0] 和 nums[1] 交换后left0 → nums[0]1, right1 → nums[1]0 数组: [1, 0, 0, 3, 12] 指针: left1, right2第3步right2textnums[2] 0不满足条件不交换 数组: [1, 0, 0, 3, 12] 指针: left1, right3第4步right3textnums[3] 3 ≠ 0满足条件 交换 nums[1] 和 nums[3] 交换后left1 → nums[1]3, right3 → nums[3]0 数组: [1, 3, 0, 0, 12] 指针: left2, right4第5步right4textnums[4] 12 ≠ 0满足条件 交换 nums[2] 和 nums[4] 交换后left2 → nums[2]12, right4 → nums[4]0 数组: [1, 3, 12, 0, 0] 指针: left3, right5最终结果遍历结束得到最终结果[1, 3, 12, 0, 0]算法复杂度分析时间复杂度O(n)我们只需要遍历数组一次快指针从0到n-1总共n次操作每次操作都是常数时间空间复杂度O(1)只使用了常数个额外变量left, right, temp真正实现了原地算法算法优化虽然上述代码已经非常高效但我们可以做一个小优化避免不必要的自交换。优化版本class Solution { public void moveZeroes(int[] nums) { int left 0; for (int right 0; right nums.length; right) { if (nums[right] ! 0) { // 只有当两个指针位置不同时才需要交换 if (left ! right) { nums[left] nums[right]; nums[right] 0; } left; } } } }优化点当left right时说明当前位置已经正确不需要交换直接赋值而非交换在某些情况下可以减少操作次数双指针法的精妙1.分区思想双指针法实际上实现了数组的分区[0, left)已处理的非零元素[left, right)已处理的零元素如果有[right, n)待处理的元素2.保持顺序的机制通过交换而非直接覆盖我们确保了非零元素的相对顺序不会被打乱。每次交换都是将当前的非零元素与最前面的零交换。3.高效性只需一次遍历就完成了所有操作没有冗余的移动或比较。实际应用场景这种双指针技巧不仅适用于移动零问题还可以解决多种类似问题删除排序数组中的重复项LeetCode 26移除元素LeetCode 27颜色分类LeetCode 75荷兰国旗问题快速排序的分区操作总结双指针交换法是解决移动零问题的经典且最优解法。它的核心思想是使用两个指针区分已处理和未处理的区域通过交换将非零元素移动到前面在一次遍历中完成所有操作这种解法的优点非常明显高效时间复杂度O(n)空间复杂度O(1)简洁代码量少逻辑清晰通用可以推广到其他类似问题希望这篇解析能帮助你深入理解双指针技巧并在实际问题中灵活应用。掌握这种核心算法思想对于提高编程能力和解决复杂问题都有重要意义。