题目:移动零
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]
示例 2:
输入: nums = [0]
输出: [0]
遇到一个问题
本来想用一下hash进行解决,打印输出的样例没有问题~ 但是提交就报错,后面发现是在不修改原数组的情况下进行移动!
public static void moveZeroes(int[] nums) {
// 定义一个LinkedList : 底层双链表实现
LinkedList<Integer> list = new LinkedList<>();
int temp = 0; // 用来统计0的数量
for (int num : nums) {
if (num == 0) {
temp++;
continue;
}
list.add(num);
}
list.sort(null); // 排序
// 在末尾添加0
while (temp > 0) {
list.add(0);
temp--;
}
for (int i : list) {
System.out.println(i);
}
}
官方双指针题解:
- 如果没有遇到0,left和right就不交换位置,如果遇到0,left停止一次+1,right正常+1,下一步,进行替换操作
- 注意替换,是把0替换到后面去
public static void moveZeroes(int[] nums) {
// 官方双指针解法
// 误区:开始自己认为这个要进行排序,样例测试中并不需要排序,在不改变数组的情况下,对数组进行一个移动0操作
int n = nums.length;
int left =0,right =0;
for (int i = 0; i < n; i++) {
if(nums[right]!=0) {
swap(nums,left,right);
left++;
}
right++;
}
}
private static void swap(int[] nums, int left, int right) {
int temp = nums[left];
nums[left]= nums[right];
nums[right]=temp;
}
优化一下
// 使用了一个替换的思想,先把所有非0的数,从nums[0]开始替换原来nums[0]的位置,替换完之后,把剩下的长度继续 // 循环,赋值为
public static void moveZeroes(int[] nums) {
int n = nums.length;
int i = 0;
for (int k = 0; k < n; k++) {
if (nums[k] != 0)
nums[i++] = nums[k];
}
for (int k = i; k < n; k++) {
nums[k] = 0;
}
}