题目

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

请注意 ,必须在不复制数组的情况下原地对数组进行操作。

示例 1:

1
2
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]

示例 2:

1
2
输入: nums = [0]
输出: [0]

提示:

  • 1 <= nums.length <= 104
  • -231 <= nums[i] <= 231 - 1

**进阶:**你能尽量减少完成的操作次数吗?

题解

Python

这里最好还是使用双指针解法啦:

第一个指针先指向 0 ,然后再遍历 nums,如果 index 指向的 num 不为 0,就和 j 指向的数据进行交换。

一开始两者指向同一个元素,所以说如果不是 0,自身和自身进行交换;如果 index 指向的数字是 0,index 会往后移动,直到遇到一个不为 0 的数据和 j 指向的数据(此时是 0 )进行交换。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.

思路:
利用双指针, 前一个指针标记0, 后一个指针标记非0元素。
从前往后遍历, 前指针遇到了0, 后指针就找第一个非0元素进行交换, 直到前指针遍历完。
"""
if nums == None:
return
j = 0
for index, num in enumerate(nums):
# 当 index 指向的数据不为 0 时, 就和 j 指向的数进行交换
if num != 0:
temp = num
nums[index] = nums[j]
nums[j] = temp
j += 1

JAVA

这个方法没什么好说的,一个列表存放不为0,一个存放0,然后再进行修改值就好了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
public void moveZeroes(int[] nums) {
// 两个数组,第一个存放不为0,第二个只存0
List<Integer> pos = new ArrayList<>();
List<Integer> zero = new ArrayList<>();
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 0) {
zero.add(nums[i]);
} else {
pos.add(nums[i]);
}
}
int index = 0;
while (!pos.isEmpty()) {
nums[index++] = pos.remove(0);
}
while (!zero.isEmpty()) {
nums[index++] = zero.remove(0);
}
}
}

双指针解法:

后面的指针i,如果i当前的值不为0,就和j处的元素进行交换,然后j的值加1,保证j左边的数据均不为0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public void moveZeroes(int[] nums) {
if (nums == null) {
return;
}
// 两个指针i和j
int j = 0;
for (int i = 0; i < nums.length; i++) {
// 当前元素!=0,就把其交换到左边,等于0的交换到右边
if (nums[i] != 0) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j++] = tmp;
}
}
}
}