题目:
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:
必须在原数组上操作,不能拷贝额外的数组。
尽量减少操作次数。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/move-zeroes
思路1:
定义两个下标 ,为 zeroIndex 与 notZeroIndex,zeroIndex 代表从最左边到右边数第一个元素为 0 的下标,notZeroIndex 代表 zeroIndex 之后,第一个元素不为0的下标,然后将两者元素值交换。
重复该操作,直到 zeroIndex 到大数组最后
Java代码如下:
public class Test2 {
public static void main(String[] args) {
int[] nums = {0,0,1,4,-3,0,6,7,0,0,0,7};
moveZero(nums);
for(int a:nums){
System.out.print(a+"\t");
}
System.out.println();
}
// 给定整数数组,将非零整数保持原相对顺序移到数组的前段,零移到后段,
// 要求不能重新拷贝数组,考虑O(n)时间复杂度实现。
//例如:输入数组为{1,2,0,0,5,6},输出为{1,2,5,6,0,0}。
//
//注:不需要从控制台读取输入,不考虑异常输入,直接实现核心算法,例如实现方法
private static void moveZero(int[] a){
int zeroIndex = 0, notZeroIndex = 0;
while (zeroIndex<a.length&¬ZeroIndex<a.length) {
while (zeroIndex < a.length && a[zeroIndex] != 0) {
zeroIndex++;
}
notZeroIndex = zeroIndex;
while (notZeroIndex < a.length && a[notZeroIndex] == 0) {
notZeroIndex++;
}
swap(a, zeroIndex, notZeroIndex);
zeroIndex++;
notZeroIndex++;
}
}
static void swap(int[] nums, int a, int b) {
int tmp = nums[a];
nums[a] = nums[b];
nums[b] = tmp;
}
}
class Solution {
public void moveZeroes(int[] nums) {
int count = 0;
boolean flag = false;
for(int i=nums.length-2;i>=0;i--){
for(int j=i;j<nums.length-1-count;j++){
if(nums[j] == 0) {
int tmp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = tmp;
flag = true;
}
}
if(flag){
count++;
flag = false;
}
}
}
}
思路2:
双指针方法。
定义两个下标 p 与 q ,移动 q ,直到不为 0 的元素为止,将该元素 copy 到 nums[ p ] ,同时 p 自增 1 为止,直到 q 遍历完所有元素为止;
然后将所有大于 p 下标的元素均修改为 0
c++
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int p = 0;
int q = 0;
while(q < nums.size()) {
if(nums[q] != 0) {
nums[p++] = nums[q];
}
q++;
}
while(p < nums.size()) {
nums[p++] = 0;
}
}
};