283. Move Zeroes
EasyDescription
給定整數陣列
nums,將所有0移到陣列末尾,同時保持非零元素的相對順序。必須原地操作。
Example:
Input: nums = [0,1,0,3,12] Output: [1,3,12,0,0]
Intuition#
核心思路:用一個慢指針記錄下一個非零元素該放的位置,快指針掃描所有元素。
- 類似「移除特定元素」的模式(LC 27 Remove Element)
- 慢指針維護「已處理區域」的尾端,快指針不斷找非零元素往前搬
- 最後慢指針之後的位置全部填 0
Approaches#
1: 額外陣列#
- 概念: 建立新陣列,先放非零元素,再補 0
- 時間複雜度:
O(n) - 空間複雜度:
O(n)
額外陣列程式碼
class Solution {
fun moveZeroes(nums: IntArray): Unit {
val result = IntArray(nums.size)
var idx = 0
for (num in nums) {
if (num != 0) result[idx++] = num
}
for (i in nums.indices) nums[i] = result[i]
}
}⭐2: Two Pointers(快慢指針)#
- 概念: 慢指針
slow追蹤下一個非零元素的位置,快指針fast掃描整個陣列,遇到非零就交換到 slow 位置 - 時間複雜度:
O(n)- 一次遍歷 - 空間複雜度:
O(1)- 原地操作
class Solution {
fun moveZeroes(nums: IntArray): Unit {
var slow = 0
for (fast in nums.indices) {
if (nums[fast] != 0) {
val temp = nums[slow]
nums[slow] = nums[fast]
nums[fast] = temp
slow++
}
}
}
}使用交換而非覆蓋(先寫非零再補零),可以在一次遍歷中完成,不需要第二次迴圈填零。
🔑 Takeaways#
- Pattern: 快慢指針分區(類似 partition),慢指針維護「已處理」邊界
- 關鍵技巧: 與 LC 27 Remove Element 同一模板;交換比覆蓋更優雅,一次遍歷搞定