給定一個無序整數陣列,移除其中重複元素,返回去重後的新長度。面試常見題目,要求原地修改陣列、空間複雜度 O(1)。
i 遍歷陣列,j 指向下一個不重複元素的存放位置。遇到相鄰相等時移動 i 跳過重複,將不重複值寫入 j 並推進 j。時間複雜度:排序 O(n log n) + 掃描 O(n) = O(n log n)。空間複雜度:O(1)(原地修改)。
#include
#include // std::sort, std::swap
// 通用列印函數
template
void printArray(const T arr[], int size) {
for (int i = 0; i < size - 1; ++i) std::cout << arr[i] << ", ";
std::cout << arr[size-1] << '\n';
}
// 選擇排序(教學用,實際建議用 std::sort)
template
void selectionSort(T arr[], int size) {
for (int i = 0; i < size - 1; ++i) {
int minIdx = i;
for (int j = i + 1; j < size; ++j)
if (arr[j] < arr[minIdx]) minIdx = j;
if (minIdx != i) std::swap(arr[i], arr[minIdx]);
}
}
// 去重:要求陣列已排序
template
int removeDuplicates(T arr[], int size) {
if (size == 0) return 0;
int j = 0;
for (int i = 0; i < size - 1; ++i) {
while (i < size - 1 && arr[i] == arr[i+1]) ++i; // 跳過重複
arr[j++] = arr[i];
}
arr[j++] = arr[size-1]; // 處理最後一個元素
return j;
}
int main() {
int data[] = {9, 1, 1, 8, 2, 3, 3, 4, 3, 3, 5, 9, 7, 8, 2, 6, 9, 1, 9, 0, 9, 0};
int n = sizeof(data) / sizeof(int);
std::cout << "原始陣列: "; printArray(data, n);
selectionSort(data, n); // 實際專案請用 std::sort(data, data+n);
std::cout << "排序後: "; printArray(data, n);
n = removeDuplicates(data, n);
std::cout << "去重後: "; printArray(data, n);
return 0;
}
while (arr[i] == arr[i+1]) ++i; 將 i 移動到當前重複群組的最後一個元素。arr[j++] = arr[i]; 將該群組代表值寫入前端。i < size-1 會漏掉)。j 即為新長度,呼叫端可用此長度截取有效區間。#include
#include
std::vector vec = {9,1,1,8,2,3,3,4,3,3,5,9,7,8,2,6,9,1,9,0,9,0};
std::sort(vec.begin(), vec.end());
vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
// vec 即為去重後結果,自動管理記憶體
std::unique 將不重複元素前移並返回新邏輯結尾迭代器,配合 erase 實現真正刪除。這是生產代碼推薦做法。
std::unordered_set 輔助(O(n) 時間、O(n) 空間)。std::sort(內省排序,平均 O(n log n))。