📘 題目敘述
給定一個整數陣列 nums 與一個整數 val,請你原地(in-place)移除所有數值等於 val 的元素。
移除後,回傳「不等於 val 的元素個數 k」。
- 前
k個位置必須是不等於val的元素 - 超過
k之後的內容不重要 - 不需要額外配置新的陣列空間(
O(1)額外空間)
條件限制
0 ≤ nums.length ≤ 1000 ≤ nums[i] ≤ 500 ≤ val ≤ 100
🧠 解題思路
這題我的核心想法是:
用一個指標
k來記錄「下一個可以放有效元素的位置」
我不真的「刪掉」陣列中的元素,而是:
- 從左到右掃描整個
nums - 只要遇到不等於
val的元素 - 就把它搬到陣列前面、依序排好
最後:
- 前
k個位置就是答案要的結果 k也正好是「剩下有效元素的數量」
這種寫法符合題目要求的in-place 修改,而且時間與空間都很省。
所有變數
n:原本陣列nums的長度k:- 表示目前已經放了多少個「不等於
val」的元素 - 同時也是「下一個有效元素要放的位置索引」
- 表示目前已經放了多少個「不等於
i:掃描整個陣列的指標,用來檢查每一個元素
🪜 主要流程步驟
第一步:初始化計數指標 k
- 一開始
k = 0 - 代表目前還沒有放任何有效元素
第二步:從左到右掃描整個陣列
我用 i 從 0 走到 n - 1,逐一檢查 nums[i]:
情況一:nums[i] != val
- 代表這個元素是要保留下來的
- 我把它放到
nums[k] - 然後
k++,表示已經多放了一個有效元素
這個動作的意思是:
把所有「不是
val的元素」往陣列前面集中
情況二:nums[i] == val
- 代表這個元素要被移除
- 我什麼都不做,直接跳過
- 等於是「不把它寫進前半段」
第三步:回傳 k
掃描完成後:
k就是不等於val的元素總數nums[0] ~ nums[k-1]就是題目要求的結果- 陣列後面的值不需要理會
💡 為什麼這樣做是正確的?
- 我沒有新增額外陣列 → 符合
O(1)空間 - 每個元素只看一次 →
O(n)時間 - 用覆蓋的方式「重建前半段陣列」 → 等效於移除指定元素
這題的關鍵不是刪除,而是重排有效元素。
💻 程式碼實作
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int n = nums.size();
int k = 0;
for (int i = 0; i < n; i++) {
if (nums[i] != val) {
nums[k] = nums[i];
k++;
}
}
return k;
}
};
🔗 題目連結
https://leetcode.com/problems/remove-element/