27. Remove Element

練習日期:2026-01-16

難度:Easy

類型:Array、Two Pointers

📘 題目敘述

給定一個整數陣列 nums 與一個整數 val,請你原地(in-place)移除所有數值等於 val 的元素。

移除後,回傳「不等於 val 的元素個數 k」。

  • k 個位置必須是不等於 val 的元素
  • 超過 k 之後的內容不重要
  • 不需要額外配置新的陣列空間(O(1) 額外空間)

條件限制

  • 0 ≤ nums.length ≤ 100
  • 0 ≤ nums[i] ≤ 50
  • 0 ≤ val ≤ 100

🧠 解題思路

這題我的核心想法是:

用一個指標 k 來記錄「下一個可以放有效元素的位置」

我不真的「刪掉」陣列中的元素,而是:

  • 從左到右掃描整個 nums
  • 只要遇到不等於 val 的元素
  • 就把它搬到陣列前面、依序排好

最後:

  • k 個位置就是答案要的結果
  • k 也正好是「剩下有效元素的數量」

這種寫法符合題目要求的in-place 修改,而且時間與空間都很省。

所有變數

  • n:原本陣列 nums 的長度
  • k
    • 表示目前已經放了多少個「不等於 val」的元素
    • 同時也是「下一個有效元素要放的位置索引」
  • i:掃描整個陣列的指標,用來檢查每一個元素

🪜 主要流程步驟

第一步:初始化計數指標 k

  • 一開始 k = 0
  • 代表目前還沒有放任何有效元素

第二步:從左到右掃描整個陣列

我用 i0 走到 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/

作者: scottnick
撰寫日期: 2026-01-16
類別:
原文連結: https://scottnick.github.io/cpp-notes/all%20problems/27-remove-element.html