一、问题描述
Given an array nums
, write a function to move all 0
's to the end of it while maintaining the relative order of the non-zero elements.
For example, given nums = [0, 1, 0, 3, 12]
, after calling your function, nums
should be [1, 3, 12, 0, 0]
.
Note:
- You must do this in-place without making a copy of the array.
- Minimize the total number of operations.
用count记录0的个数。遍历数组,一直保持处理过的子数组保证0全部在末尾。如[0,1,2,0,5,6,7,0],处理完元素1时保证[1,0],处理完元素2时保证[1,2,0]...
如果下一个处理的第num[i]元素是0时,count++,不用交换,直接移动到下一个元素;
如果下一个元素num[i]是非零数,把当前数字交换到处理过的子数组里第一个0所在的位置。该位置的index是i-count。
需要注意交换的方法和条件。如果写成直接交换的话,没什么问题。但是我写的是0变成当前元素,然后给当前元素赋值为0.当处理的字符串里没有0时(如nums = {1}),这样做会把当前元素赋为0.
class Solution {
public void moveZeroes(int[] nums) {
int zeroNum = 0;
int i = 0;
while(i < nums.length){
if(nums[i] == 0){
zeroNum ++;
i ++;
}
else{
if(zeroNum > 0){//注意交换条件
nums[i-zeroNum] = nums[i];
nums[i] = 0;
}
i ++;
}
}
}
}
三、别人的淫奇技巧
public void moveZeroes(int[] nums) {
if (nums == null || nums.length == 0) return;
int insertPos = 0;
for (int num: nums) {
if (num != 0) nums[insertPos++] = num;
}
while (insertPos < nums.length) {
nums[insertPos++] = 0;
}
}
上来先判断数组的情况,很棒~
然后直接先记录不为0的个数,把它们放在数组前面。处理完以后,剩下的全部是0.。。。太简单了。。。。
public void moveZeroes(int[] nums) {
int j = 0;
for(int i = 0; i < nums.length; i++) {
if(nums[i] != 0) {
int temp = nums[j];
nums[j] = nums[i];
nums[i] = temp;
j++;
}
}
}
我记录的是0的个数,这个大神记录的是不为0的个数。简单了好多啊~~
而且他的交换步骤做的特别到位。
四、知识点
数组的操作掌握的还好,但是对于这种分类处理问题还不是很熟练。因为现在练习的题目很少,所以不知道还有什么相关的知识点。。
另外思维不缜密,多想想可能出现的情况。
数组的话上来先判断是不是null或长度为0!!!
五、碎碎念
一道easy题目写了这么久。。I have a long way to go.....