// 演算法同 C 版：雙指針從後往前合併 nums1 與 nums2，原地完成。
// Same algorithm as the C version: merge from the back with two pointers, in-place.
// 時間 O(m+n)，空間 O(1)。 / O(m+n) time, O(1) space.

class Solution {
public:
    // vector<int>& 是「對 int 向量的參考」：不會複製，直接改呼叫者傳入的陣列。
    // vector<int>& is a reference to an int vector: no copy, we mutate the caller's array.
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int i = m - 1;        // nums1 最後一個真實元素的索引 / index of last real nums1 element
        int j = n - 1;        // nums2 最後一個元素的索引 / index of last nums2 element
        int k = m + n - 1;    // nums1 寫入位置，從最尾端開始 / write slot, starting at nums1's tail

        // while 條件合併兩個指針：任何一邊還有東西、就繼續。
        // Loop while either side still has unplaced elements.
        while (i >= 0 && j >= 0) {
            // 三元運算子 cond ? a : b：若 cond 為真取 a，否則取 b。
            // Ternary operator cond ? a : b: pick a if cond is true, else b.
            // 取兩邊末端較大者放到 nums1[k]，並把對應讀指針往左推一格。
            // Place the larger tail value at nums1[k] and step that read pointer left.
            if (nums1[i] > nums2[j]) {
                nums1[k--] = nums1[i--];  // 等同寫 nums1[k]=nums1[i]; k--; i--; / shorthand for three statements
            } else {
                nums1[k--] = nums2[j--];  // 相等時走這條分支也沒問題 / tie-breaking via this branch is safe
            }
        }

        // 若 nums1 先耗盡 (i < 0)，剩下的 nums2 還需要倒進 nums1 前面。
        // If nums1 was exhausted first (i < 0), drain remaining nums2 into the front.
        // 若 nums2 先耗盡 (j < 0)，nums1 前段已經在正確位置，不必動。
        // If nums2 was exhausted first (j < 0), nums1's prefix is already in place — skip.
        while (j >= 0) {
            nums1[k--] = nums2[j--];  // 繼續由後往前把 nums2 剩餘值複製過去 / keep copying leftover nums2 back-to-front
        }
        // 此處無 return：函式回傳型別 void，且題目要求原地修改 nums1。
        // No return: the function is void and the problem requires in-place mutation of nums1.
    }
};
