算法题法算day4
lief移动零
问题描述
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 :必须在不复制数组的情况下原地对数组进行操作。
示例 1:
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]
示例 2:
输入: nums = [0]
输出: [0]
提示:
1 <= nums.length <= 104
-231 <= nums[i] <= 231 - 1
java版
方法一:双指针法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| class Solution { public void moveZeroes(int[] nums) { // 边界情况检查:如果数组为空或长度为0,直接返回 if (nums == null || nums.length == 0) { return; } // 使用双指针法 // left指针:指向当前应该放置非零元素的位置 int left = 0; // 遍历数组 for (int right = 0; right < nums.length; right++) { // 如果当前元素不为0 if (nums[right] != 0) { // 将非零元素移动到left指针的位置 nums[left] = nums[right]; // 如果left和right不是同一个位置,说明移动了元素 // 需要将原位置设置为0(避免重复) if (left != right) { nums[right] = 0; } // left指针向右移动,准备放置下一个非零元素 left++; } // 如果当前元素为0,left指针不动,right指针继续向右移动 } } }
|
✅ 说明:
- left 指针:记录下一个非零元素应该放置的位置
right 指针:遍历整个数组,寻找非零元素
- 时间复杂度:O(n),只需要遍历数组一次(或两次)
- 空间复杂度:O(1),只使用了常数级别的额外空间
额外补充-增强for循环有一个严重缺陷!
1 2 3 4 5 6 7 8 9
| int[] nums = {0, 1, 0, 3, 12};
// 使用增强for循环(有问题!) for (int num : nums) { if (num != 0) { nums[insertPos] = num; // 这里会修改数组! insertPos++; } }
|
执行过程
1 2 3 4 5 6
| 初始: [0, 1, 0, 3, 12] 第1次循环: num=0 → 跳过 第2次循环: num=1 → nums[0]=1 → 数组变成 [1, 1, 0, 3, 12] 第3次循环: num=0 → 跳过 第4次循环: num=3 → nums[1]=3 → 数组变成 [1, 3, 0, 3, 12] 第5次循环: num=12 → nums[2]=12 → 数组变成 [1, 3, 12, 3, 12]
|
增强for循环适合只读操作,比如:
1 2 3 4 5 6 7 8 9 10
| // 只读操作 - 适合用增强for循环 int sum = 0; for (int num : nums) { sum += num; // 不修改数组,只是读取值 }
// 或者打印数组 for (int num : nums) { System.out.print(num + " "); }
|
✅ 总结:
增强for循环:语法简洁,适合只读遍历
传统for循环:功能更强大,可以通过索引修改数组,控制遍历过程
python版
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| def moveZeroes(nums): """ 将数组中的所有0移动到末尾,保持非零元素的相对顺序 参数: nums: List[int] - 输入的整数列表 思路: 使用双指针,left指针记录非零元素应该放置的位置 right指针遍历整个数组 """ left = 0 # left指针:指向下一个非零元素应该放置的位置 # right指针遍历整个数组 for right in range(len(nums)): # 如果当前元素不为0 if nums[right] != 0: # 将非零元素交换到left位置 nums[left], nums[right] = nums[right], nums[left] # left指针向右移动,准备放置下一个非零元素 left += 1 # 如果当前元素为0,left指针不动,right指针继续移动
|
测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| # 测试函数 def test_moveZeroes(): # 测试用例1 nums1 = [0, 1, 0, 3, 12] moveZeroes(nums1) print(f"测试1: {nums1}") # 应该输出 [1, 3, 12, 0, 0] # 测试用例2 nums2 = [0] moveZeroes(nums2) print(f"测试2: {nums2}") # 应该输出 [0] # 测试用例3 nums3 = [1, 2, 3, 4, 5] moveZeroes(nums3) print(f"测试3: {nums3}") # 应该输出 [1, 2, 3, 4, 5] # 测试用例4 nums4 = [0, 0, 0, 1, 2] moveZeroes(nums4) print(f"测试4: {nums4}") # 应该输出 [1, 2, 0, 0, 0]
# 运行测试 if __name__ == "__main__": test_moveZeroes()
|