Nameless Site

But one day, you will stand before its decrepit gate,without really knowing why.

0%

移动0

来源Leetcode第283题移动0

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

示例:

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

说明:

  1. 必须在原数组上操作,不能拷贝额外的数组。
  2. 尽量减少操作次数。

队列

遍历一次数组,将非空元素入队,之后出队按序填充数组,数组剩下的元素赋0.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void moveZeroes(int[] nums) {
Queue<Integer> que = new LinkedList<>();

for(int i = 0; i < nums.length; i++){
if(nums[i] != 0){
que.add(nums[i]);
}
}
int i = 0 ;
while(!que.isEmpty()){
nums[i++] = que.poll();
}
for(;i < nums.length;i++)
nums[i] = 0;
}

双指针I

用一个指针记录当前非0元素的位置,另一个指针用于遍历数组。

1
2
3
4
5
6
7
8
public void moveZeroes(int[] nums) {
int pos = 0;
for(int i = 0 ; i < nums.length; i++)
if(nums[i] != 0)
nums[pos++] = nums[i];
for(;pos < nums.length;pos++)
nums[pos] = 0;
}

双指针II

如果当前元素是非 0 的,那么它的正确位置最多可以是当前位置或者更早的位置。如果是后者,则当前位置最终将被非 0 或 0 占据,该非 0 或 0 位于大于 “cur” 索引的索引处。我们马上用 0 填充当前位置,这样不像以前的解决方案,我们不需要在下一个迭代中回到这里。

换句话说,代码将保持以下不变:

  1. 慢指针(lastnonzerofoundat)之前的所有元素都是非零的。
  2. 当前指针和慢速指针之间的所有元素都是零。

因此,当我们遇到一个非零元素时,我们需要交换当前指针和慢速指针指向的元素,然后前进两个指针。如果它是零元素,我们只前进当前指针。

1
2
3
4
5
6
7
8
9
10
public void moveZeroes(int[] nums) {
int temp;
for(int i = 0 , j = 0 ; i < nums.length; i++){
if(nums[i] != 0){
temp = nums[j];
nums[j++] = nums[i];
nums[i] = temp;
}
}
}