---
# System prepended metadata

title: 'LeetCode 日記 #009: 283. Move Zeroes | 快慢雙指針'
tags: [LeetCode, Java, Algorithm, Data Structure]

---

# 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) 且有特定排序或分組要求的問題中非常有效。

### 快慢雙指針題型
通常，以下幾種題型特性可以考慮使用快慢雙指針：

* 需要將陣列「**分成兩類**」：比如移動特定元素（如零、偶數、負數等）到陣列一端。
* 需要原地刪除或移動元素：例如**刪除重複元素**、**移除**滿足特定條件的元素等。
* 需要保持元素的相對**順序**：當操作不能打亂元素間的相對位置時。
* 需要檢測或操作**相鄰元素關係**：如合併相鄰的相同元素。
* **鏈結串列**操作：**尋找中點**、檢測環、刪除節點等鏈結串列問題。
* 滑動窗口問題：當需要**維護一個滿足特定條件的窗口**時。
* 子陣列或子序列問題：例如尋找最長的不含重複字符的子串。