題目連結:
題目意譯:
給定一個已排序陣列 nums ,原地(In-Place)將重複的元素清除掉,也就是使每個元素只出現一次。並回傳新的陣列長度。
請勿另開空間給另一個陣列,你只應藉由 O(1) 的額外空間並原地(In-Place)地更改輸入陣列。
說明:
為何明明回傳值是一個整數,但是你出現的答案卻是一個陣列?
注意輸入陣列是以「傳入參考」(Pass by Reference)進來的,其代表關於輸入陣列的任意更動,外層的函式呼叫者(Caller)也會接收到該更動。
總之,你可以想成是以下:
// 以「傳入參考」傳進 nums (換句話說,不做任何的複製)
int len = removeDuplicates(nums);
// 關於輸入陣列的任意更動,外層的函式呼叫者(Caller)都會接受到。
// 藉由你的函式回傳的長度,其輸出前 len 個元素。
for (int i = 0; i < len; i++) {
print(nums[i]);
}
範例測資:
範例 1:
給定 nums = [1,1,2],
你的函式應回傳長度 length = 2 ,且 nums 的前兩個元素應依序為 1 以及 2 。
長度 length 之後的字元(此為第 3 個)是何物都沒關係。
範例 2:
給定 nums = [0,0,1,1,1,2,2,3,3,4],
你的函式應回傳長度 length = 5 ,且 nums 的前五個元素應依序為 0 、 1 、 2 、 3 以及 4 。
長度 length 之後的字元(此為第 6 個元素(含)以後)被設定任何值都沒關係。
解題思維:
用一個變數 x 表示新的元素應擺在哪個位置。因為陣列元素已排序,因此從頭掃到尾,如果遇到該位置的元素與前一個位置的元素不一樣,則表示已經略過了前面被重複的元素(及前一個位置的元素)。此時可以將前一個位置的元素放到位置 x ,並將 x + 1。
以範例的 0, 0, 1, 1, 1, 2, 2, 3, 3, 4 舉例:
0, 0, 1, 1, 1, 2, 2, 3, 3, 4
直接跳到第二個元素(因為第一個元素沒有前一個元素),而 0 = 0 ,所以不變。
x = 0
0, 0, 1, 1, 1, 2, 2, 3, 3, 4
0 ≠ 1 ,所以將 0 放在位置 x ,也就是陣列位置 0 的地方。並將 x + 1 。
x = 1
0, 0, 1, 1, 1, 2, 2, 3, 3, 4
1 = 1 ,所以不變。
x = 1
0, 0, 1, 1, 1, 2, 2, 3, 3, 4
1 = 1 ,所以不變。
x = 1
0, 0, 1, 1, 1, 2, 2, 3, 3, 4
1 ≠ 2 ,所以將 1 放在位置 x ,也就是陣列位置 1 的地方。並將 x + 1 。
x = 2
0, 1, 1, 1, 1, 2, 2, 3, 3, 4
(注:此時陣列位置 1 的內容物已做更改)
2 = 2 ,所以不變。
x = 2
0, 1, 1, 1, 1, 2, 2, 3, 3, 4
2 ≠ 3 ,所以將 2 放在位置 x ,也就是陣列位置 2 的地方。並將 x + 1 。
x = 3
0, 1, 2, 1, 1, 2, 2, 3, 3, 4
3 = 3 ,所以不變。
x = 3
0, 1, 2, 3, 1, 2, 2, 3, 3, 4
4 ≠ 3 ,所以將 0 放在位置 x ,也就是陣列位置 3 的地方。並將 x + 1 。
x = 4
最後將最後一個元素放到位置 x ,並將 x + 1。因此陣列最終的內容為 0, 1, 2, 3, 4, 2, 2, 3, 3, 4 。而所求長度即為 x = 5 ,因此回傳 5 。
此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。