一、题目
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
二、示例
2.1> 示例 1:
【输入】 nums = [0,1,0,3,12]
【输出】 [1,3,12,0,0]
2.2> 示例 2:
【输入】 nums = [0]
【输出】 [0]
提示:
- 1 <= nums.length <= 10^4
- -2^31 <= nums[i] <= 2^31 - 1
- 进阶:你能尽量减少完成的操作次数吗?
三、解题思路
3.1> 思路1:标记数字0的下标,然后进行互换
首先,第一个解题思路就是,我们记录一下数字0
出现的位置,然后当我们发现有非数字的时候,与数字0的位置互换即可。所以,为了记录数字0
出现的位置,我们创建一个数组zeros
,其中,zeros[i]
表示第i
个数字0
的下标位置。
然后我们开始遍历整个数组nums
,此处需要注意的是,除了当我们发现数字0的时候,需要对zeros赋值之外,当我们执行数字0与非数字0互换操作的时候,数字0所在的新的位置,也需要记录到zeros数组中。
以上就是思路1的解题逻辑,下面我们以nums=[0,1,0,3,12]
为例,看一下具体的操作过程:
3.2> 思路2:移动非0数字
在思路2中,我们采用移动非0数字的方式,即:我们创建一个指针p
,指向nums
的第一个元素,即:index=0
;然后我们对数组nums
进行遍历操作,当发现遍历到的元素是非0数字的话,则执行p指针元素与i指针元素的互换操作,操作完毕后,p指针执行+1操作。当所有nums
数组遍历完毕后,就是最终本题的结果啦。下面我们还是以nums=[0,1,0,3,12]
为例,看一下具体的操作过程:
3.3> 思路3:非0数字左移,剩余置为0
在思路3中,我们的关注点也是在非0的数字上,核心算法思想只有一个:将所有非0的数字靠左移动,先不用管0的元素;那么,当所有的非0数字都被移动到左侧之后,那么剩余的所有元素,我们都将其赋值为0即可。下面我们还是以nums=[0,1,0,3,12]
为例,看一下具体的操作过程:
四、代码实现
4.1> 实现1:标记数字0的下标,然后进行互换
class Solution { public void moveZeroes(int[] nums) { int[] zeros = new int[nums.length]; Arrays.fill(zeros, -1); int index = 0, p = 0; for (int i = 0; i < nums.length; i++) { if (nums[i] == 0) zeros[index++] = i; else if (zeros[p] != -1 && zeros[p] < i) { nums[zeros[p++]] = nums[i]; nums[i] = 0; zeros[index++] = i; } } } }
4.2> 实现2:移动非0数字
class Solution { public void moveZeroes(int[] nums) { int p = 0; for (int i = 0; i < nums.length; i++) { if (nums[i] != 0) { int temp = nums[p]; nums[p++] = nums[i]; nums[i] = temp; } } } }
4.3> 实现3:非0数字左移,剩余置为0
class Solution { public void moveZeroes(int[] nums) { int p = 0; for (int i = 0; i < nums.length; i++) if (nums[i] != 0) nums[p++] = nums[i]; for (int i = p; i < nums.length; i++) nums[i] = 0; } }
今天的文章内容就这些了:
写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享 。
更多技术干货,欢迎大家关注公众号“爪哇缪斯” ~ \(^o^)/ ~ 「干货分享,每天更新」