在不使用額外緩存(或允許使用)前提下,移除無序單鏈表中的重複節點。
外層指針 pPos 遍歷每個節點,內層指針 q 掃描後續節點,發現重複則刪除。
void delete_duplicate1(node* head) {
node* pPos = head->next;
while (pPos) {
node *p = pPos, *q = pPos->next;
while (q) {
if (pPos->data == q->data) {
node* del = q;
p->next = q->next;
q = p->next;
free(del);
} else { p = q; q = q->next; }
}
pPos = pPos->next;
}
}
遍歷鏈表,哈希集合記錄已見值,遇到重複即刪除。
void delete_duplicate2(node* head) {
node *p = head->next, *q = p->next;
memset(hash, 0, sizeof(hash));
hash[p->data] = 1;
while (q) {
if (hash[q->data]) { /* 刪除 q */ }
else { hash[q->data] = 1; p = q; q = q->next; }
}
}
public static void deleteDups(LinkedListNode n) {
Set set = new HashSet<>();
LinkedListNode prev = null;
while (n != null) {
if (set.contains(n.data)) prev.next = n.next;
else { set.add(n.data); prev = n; }
n = n.next;
}
}
// 無緩存版 O(n²)
public static void deleteDups2(LinkedListNode head) {
if (head == null) return;
LinkedListNode prev = head, curr = head.next;
while (curr != null) {
LinkedListNode runner = head;
while (runner != curr) {
if (runner.data == curr.data) {
prev.next = curr.next;
curr = prev.next;
break;
}
runner = runner.next;
}
if (runner == curr) { prev = curr; curr = curr.next; }
}
}
| 方法 | 時間 | 空間 | 適用場景 |
|---|---|---|---|
| 雙指針 | O(n²) | O(1) | 嵌入式/內存受限、數據量小 |
| 哈希集合 | O(n) | O(n) | 通用業務、數據量大 |