給定一個(gè)數(shù)組 nums
,編寫一個(gè)函數(shù)將所有 0
移動(dòng)到它的末尾棋枕,同時(shí)保持非零元素的相對(duì)順序。
例如万矾, 定義 nums = [0, 1, 0, 3, 12]
伤疙,調(diào)用函數(shù)之后银酗,nums
應(yīng)為 [1, 3, 12, 0, 0]
辆影。
注意事項(xiàng):
必須在原數(shù)組上操作,不要為一個(gè)新數(shù)組分配額外空間黍特。
盡量減少操作總數(shù)蛙讥。
分析:
題目不難理解,把非0元素向前移動(dòng)灭衷,把0向后移動(dòng)次慢。最后讓數(shù)組的前段都是原順序的非零元素,數(shù)組后段都是0即可翔曲。題目要求不能創(chuàng)建新數(shù)組迫像,那么需要想辦法在原數(shù)組上下功夫。
下面給出兩種解法:
解法一:
仔細(xì)分析題意部默,可以遍歷數(shù)組侵蒙,如果遇到0,那么和右邊的第一個(gè)非零元素進(jìn)行交換傅蹂,然后再判斷下一個(gè)元素是否為0纷闺。類似于冒泡的行為。這種方法注重移動(dòng)元素的過程份蝴,時(shí)間復(fù)雜度高犁功,速度慢!
Java解答如下:
public void moveZeroes(int[] nums) {
if (nums == null || nums.length == 0 || nums.length == 1) {
return;
}
int j = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 0) {
j = i + 1;
while (j < nums.length) {
if (nums[j] != 0) {
nums[i] = nums[i] ^ nums[j];
nums[j] = nums[i] ^ nums[j];
nums[i] = nums[i] ^ nums[j];
break;
}
j += 1;
}
}
}
}
解法二:
仔細(xì)觀察運(yùn)行之后的結(jié)果婚夫,我們可以發(fā)現(xiàn)浸卦,不需要管中間移動(dòng)的過程,只關(guān)注最終的結(jié)果即可案糙。只要把數(shù)組中所有的非零元素限嫌,按順序給數(shù)組的前段元素位賦值,剩下的全部直接賦值0时捌,一切都OK了怒医。這種方法時(shí)最快的!
Java解答如下:
public void moveZeroes(int[] nums) {
if (nums == null || nums.length == 0 || nums.length == 1) {
return;
}
int index = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] != 0) {
nums[index] = nums[i];
index += 1;
}
}
for (int i = index; i < nums.length; i++) {
nums[i] = 0;
}
}