// 演算法：雙指針（快/慢指針）。i 讀每個元素，k 是下一個寫入位置。
// Algorithm: two pointers. i scans every element; k is the next write slot.
// 遇到不等於 val 的元素就寫到 nums[k] 並 k++；等於 val 就跳過。
// When nums[i] != val we copy it to nums[k] and advance k; otherwise we skip.
// 時間 O(n)，空間 O(1)。 / Time O(n), space O(1).

int removeElement(int* nums, int numsSize, int val) {
    // int* nums 是指向陣列第一個元素的指標；numsSize 是陣列長度。
    // int* nums points to the first element; numsSize is the array length.

    int k = 0;  // k 是下一個該寫入的位置，也是目前保留元素的個數。
                // k is the next write index, and also the count of kept elements so far.

    for (int i = 0; i < numsSize; i++) {  // i 從 0 掃到 numsSize-1。 / i scans 0..numsSize-1.
        if (nums[i] != val) {             // 只有不等於 val 的元素才要保留。
                                          // Only keep elements different from val.
            nums[k] = nums[i];            // 把保留的元素寫到位置 k。 / Write the keeper to slot k.
                                          // 因為 k <= i，不會覆蓋還沒讀到的資料。
                                          // Since k <= i, this never overwrites unread data.
            k++;                          // 寫指針往前推一格。 / Advance the write pointer.
        }
        // 如果 nums[i] == val，什麼都不做，i 繼續往前。
        // If nums[i] == val, do nothing; i moves on.
    }

    return k;  // k 就是保留下來的元素個數，也是 LeetCode 要的答案。
               // k is the number of kept elements — exactly what the judge wants.
}
