題目描述
給定一個數組 nums,編寫函數將所有 0 移動到數組的末尾,且保持非零元素的相對順序。
示例:
輸入: [0,1,0,3,12]
輸出: [1,3,12,0,0]
要求:
1.必須在原數組上操作,不能拷貝額外的數組。
2.儘量減少操作次數。
解題思路
思路1:先複製最後置0,複製完成後數組中沒有0元素
兩個標誌位同時向後移動,遇到非零元素則將其向前複製,最後當第一個標誌位到數組末尾時,將兩個標誌位之間的元素全部置0。
思路2:一邊遍歷一邊交換,始終保持原數組本身的數據組成
兩個標誌位同時先後移動,遇到非零元素則將兩個標誌位所指向的元素互換(此時會包含兩個標誌位指向同一個元素,本身和本身互換的情況,對算法本身沒有影響),遍歷到最後,零元素就全部位於數組末尾了。
以上兩種思路均能保持非零元素的相對順序
思路3:利用輔助數組
這個比較好理解,遇到非零元素就複製到新數組,剩下的位補0,但是這是違背要求的。
代碼實現(Java)
// 思路1:先複製最後置0,複製完成後數組中沒有0元素
public class Solution {
public void moveZeros(int[] nums){
int len = nums.length;
if (len == 0){
return;
}
int count = 0;
for (int i = 0; i < len; i++){ // 先複製
if (nums[i] != 0){
nums[count++] = nums[i];
}
}
// 此時數組中沒有0元素了
for (int i = count; i < len; i++){// 然後置末尾的i 和j之間的元素全爲0
nums[i] = 0;
}
}
}
// 思路2::一邊遍歷一邊交換,始終保持原數組本身的數據組成
public class Solution {
public void moveZeros(int[] nums){
int len = nums.length;
if (len == 0){
return;
}
int i, j = 0;
for (i = 0; i < len; i++){
// 交換呀交換,只要遇到0元素,i和j總能錯開的,所有肯定保證非零元素和零元素的交換
if (nums[i] != 0){
int temp = nums[i];
nums[i] = nums[j];
nums[j++] = temp;
}
}
}
}