LeetCode 283移动零
300 Words|Read in about 1 Min|本文总阅读量次
leetcode第283题,移动零。采用双指针的算法来完成。
LeetCode 283移动零
给定一个数组 nums
,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
1输入: nums = [0,1,0,3,12]
2输出: [1,3,12,0,0]
示例 2:
1输入: nums = [0]
2输出: [0]
提示:
- 1 <=
nums.length
<= 104 - -231 <=
nums[i]
<= 231 - 1
**进阶:**你能尽量减少完成的操作次数吗?
思路(双指针)
- 一个指针指向
nums
数组的头部,用于遍历数组,一个指针指向nums
数组的头部,用于非0元素的指向。 - 用于遍历数组的指针指向了非0元素,那么将直接赋值到非0元素指向的指针,并且两个指针同时往后移动一位。
- 用于遍历数组的指针指向了0元素,那么自己往后移动一个元素。
- 如果用于遍历数组的指针遍历完了数组,那么对于非0元素的指向的指针之后在数组的元素,全部赋值为0。
解题
1class Solution {
2 //使用双指针
3 public void moveZeroes(int[] nums) {
4 if(nums.length == 0)
5 {
6 return;
7 }
8
9 //第一次遍历,j指针记录非0的个数,只要是非0统统都赋值给nums[j]
10 int j = 0;//用于记录非0元素的指针
11 for(int i = 0; i < nums.length; i++)
12 {
13 if(nums[i] != 0)
14 {
15 //如果是非0元素,比较是否是双指针指向同一元素,如果是那么不交换
16 if(i != j)
17 {
18 nums[j] = nums[i];
19 }
20 j++;
21 }
22 }
23 //非0元素遍历完,剩下全是0
24 for(int i = j; i < nums.length; i++)
25 {
26 nums[i] = 0;
27 }
28
29 }
30}
思路(双指针+交换)
这里参考了快速排序的思想,快速排序首先要确定一个待分割的元素做中间点x,然后把所有小于等于x的元素放到x的左边,大于x的元素放到其右边。
这里我们可以用0当做这个中间点,把不等于0(注意题目没说不能有负数)的放到中间点的左边,等于0的放到其右边。
这的中间点就是0本身,所以实现起来比快速排序简单很多,我们使用两个指针i和j,只要nums[i]
!=0,我们就交换nums[i]
和nums[j]
1class Solution {
2 //双指针+交换
3 public void moveZeroes(int[] nums) {
4 if(nums == null) {
5 return;
6 }
7 //两个指针i和j
8 int j = 0;
9 for(int i = 0; i < nums.length; i++) {
10 //当前元素!=0,就把其交换到左边,等于0的交换到右边
11 if(nums[i] != 0) {
12 //如果是非0元素,比较是否是双指针指向同一元素,如果是那么不交换
13 if (i != j)
14 {
15 nums[j] = nums[i];
16 nums[i] = 0;
17 }
18 j++;
19 }
20 }
21 }
22}