# LeetCode 日記 #009: 283. Move Zeroes | 快慢雙指針
> Given an integer array nums, move all 0's to the end of it while maintaining the relative order of the non-zero elements.Note that you must do this in-place without making a copy of the array.
- **Example 1**:
Input: nums = [0,1,0,3,12]
Output: [1,3,12,0,0]
- **Example 2**:
Input: nums = [0]
Output: [0]
## 思路
1. in-place 的移動通常使用雙指針。
2. 要求不能改變非零元素的排序,使用快慢雙指針。
3. 快指針去尋找非零元素,賦值到慢指針所在的位置。
4. 快指針迭代完以後,代表所以非零元素都已經按照原排序移到開頭了。
5. 剩下慢指針元素到最後一個元素都應該是零,迭代賦值。
### Code
```java
class Solution {
public void moveZeroes(int[] nums) {
if (nums.length == 1) {
return;
}
int slow = 0;
for (int fast = 0; fast < nums.length; fast++) {
if (nums[fast] != 0) {
nums[slow] = nums[fast];
slow++;
}
}
while (slow < nums.length) {
nums[slow] = 0;
slow++;
}
}
}
```
## 快慢指針特性
快慢雙指針的核心思想是,**慢指針**通常負責維護結果陣列的狀態,而**快指針**負責迭代和探索。這種方法在很多需要原地操作 (in-place) 且有特定排序或分組要求的問題中非常有效。
### 快慢雙指針題型
通常,以下幾種題型特性可以考慮使用快慢雙指針:
* 需要將陣列「**分成兩類**」:比如移動特定元素(如零、偶數、負數等)到陣列一端。
* 需要原地刪除或移動元素:例如**刪除重複元素**、**移除**滿足特定條件的元素等。
* 需要保持元素的相對**順序**:當操作不能打亂元素間的相對位置時。
* 需要檢測或操作**相鄰元素關係**:如合併相鄰的相同元素。
* **鏈結串列**操作:**尋找中點**、檢測環、刪除節點等鏈結串列問題。
* 滑動窗口問題:當需要**維護一個滿足特定條件的窗口**時。
* 子陣列或子序列問題:例如尋找最長的不含重複字符的子串。