題目描述
給定一個排序好的鏈表(升序),刪除所有重復的元素,使每個元素只出現一次。
示例:
輸入:1 → 1 → 2 → 3 → 3
輸出:1 → 2 → 3
解題思路
核心觀察:鏈表已排序,重復節點一定「相鄰」(無需考慮非相鄰重復)。
遍歷邏輯:用一個指針 current 從表頭開始遍歷:
若 current 的值 == current->next 的值(發現重復),則跳過 current->next(讓 current->next 指向 current->next->next);
若不重復,current 移動到下一個節點(current = current->next)。
邊界處理:鏈表為空或只有 1 個節點時,直接返回原鏈表(無重復可刪)。
C++ 代碼實現
#include <iostream>
using namespace std;// 先定義鏈表節點(復用你熟悉的結構)
struct ListNode {int val;ListNode* next;ListNode(int v = 0, ListNode* n = nullptr) : val(v), next(n) {}
};// 打印鏈表(輔助函數)
void printList(ListNode* head) {ListNode* curr = head;while (curr != nullptr) {cout << curr->val << " → ";curr = curr->next;}cout << "nullptr" << endl;
}// 核心函數:刪除重復節點
ListNode* deleteDuplicates(ListNode* head) {// 邊界:空鏈表或只有1個節點,直接返回if (head == nullptr || head->next == nullptr) {return head;}ListNode* current = head; // 遍歷指針while (current != nullptr && current->next != nullptr) {if (current->val == current->next->val) {// 發現重復:跳過 current->next(先存臨時指針避免內存泄漏)ListNode* temp = current->next;current->next = current->next->next;delete temp; // 釋放重復節點的內存} else {// 不重復:移動到下一個節點current = current->next;}}return head;
}// 測試代碼
int main() {// 構造示例鏈表:1 → 1 → 2 → 3 → 3ListNode* head = new ListNode(1);head->next = new ListNode(1);head->next->next = new ListNode(2);head->next->next->next = new ListNode(3);head->next->next->next->next = new ListNode(3);cout << "原鏈表:";printList(head);head = deleteDuplicates(head);cout << "刪除重復后:";printList(head);// 釋放鏈表內存(避免泄漏)ListNode* curr = head;while (curr != nullptr) {ListNode* temp = curr;curr = curr->next;delete temp;}return 0;
}
123