題目:Move Zeroes
描述:
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:
1、You must do this in-place without making a copy of the array.
2、Minimize the total number of operations.
翻譯:
將數組中的所有0移動到末尾,並保持非0元素的順序不改變。
比如[0,1,0,3,12]移動後的期望數組爲[1,3,12,0,0]
小要求:
1、不能創建一個新的數組來做操作
2、儘量少的操作次數
答案:
public void moveZeroes(int[] nums) {
int size = nums.length;
int startIndex = 0;
// 0元素開始的位置
int endIndex = 0;
// 0元素結束的位置
int currentNum;
int i= 0;
// 第一步:找到第一個0元素開始的位置
// 並將第一個0元素的遊標賦值給startIndex&endIndex
while(i < size){
currentNum = nums[i];
if (currentNum == 0) {
startIndex = i;
endIndex = i;
break;
}
++i;
}
// 如果當前數組中沒有找到0元素,則推出
if (nums[endIndex] != 0)
return;
// 將當前i的值加1;直接從剛纔0元素位置的後一位置開始循環
++i;
while (i < size) {
currentNum = nums[i];
if (currentNum == 0){//如果當前元素等於0,則將i值賦值給endIndex
endIndex = i;
} else {
// 如果不爲0
//則將當前元素賦值給nums[startIndex]
// 並將當前位置的元素賦值爲0
// startIndex和endIndex都加1;
nums[startIndex] = currentNum;
nums[i] = 0;
++startIndex;
++endIndex;
}
++i;
}
}
算法解釋
此算法的精髓在於:在循環遍歷中將0元素全部集中起來,整體向後移位,但是由於連續的0元素都是相等的,因此就算往前移位,也只需要將最前面的0元素和連續0元素的結束位置的後一位元素進行調換,相當於整個0元素塊都向後移動了一位。
由於數組中可能有多個0,因此,第一次循環的時候,就將第一個0元素找出,並且記錄當前0元素的遊標(此時0元素開始的遊標和結束的遊標相等),第二次循環的時候,直接從0元素結束的遊標的後一位開始循環遍歷,如果循環遍歷過程中,遇到了0元素,則將0元素的結束遊標+1;如果沒有遇到0元素,則將0元素開始位置和當前位置的數進行置換,並且將0元素的開始遊標和結束遊標都+1。