Q:
Write code to remove duplicates from an unsorted linked list.
FOLLOW UP
How would you solve this problem if a temporary buffer is not allowed?
A:
用哈希表记录某一值是否已经存在,下面的程序只对小于100的数有效。
1、当访问的链表节点置为i时,如果此时hash[i] == false, 那么将其置true, 继续访问下一个节点,直到遍历结束。
2、如果hash[i] == true, 说明已经出现过值为i的节点了,要将该节点删除,继续访问下一个节点,直到遍历结束。
如果只允许常量的空间,那么就要用两次遍历。需要两个指针,第一个指针指向链表中某个元素, 第二个元素从第一个指针的下一个元素开始遍历,删除与第一个指针指向的元素值相同的节点。
#include <iostream>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
bool hash[100];
ListNode *init(int a[], int n) {
ListNode *head = NULL;
ListNode *p = NULL;
for (int i = 0; i < n; i++) {
ListNode *cur = new ListNode(a[i]);
if (i == 0) {
head = cur;
p = cur;
}
p->next = cur;
p = cur;
}
return head;
}
void removedulicate1(ListNode *head){
if(head==NULL) return;
ListNode *p=head;
hash[head->val] = true;
while(p->next){
if(hash[p->next->val]){
ListNode *t = p->next;
p->next = p->next->next;
delete t;
}
else{
hash[p->next->val] = true;
p = p->next;
}
}
}
void removedulicate2(ListNode *head){
ListNode *cur=head;
while(cur){
ListNode *run = cur;
while (run->next) {
if (run->next->val == cur->val) {
ListNode *t = run->next;
run->next = run->next->next;
delete t;
} else {
run = run->next;
}
}
cur = cur->next;
}
}
void printList(ListNode *head) {
ListNode *p = head;
for( ; p; p = p->next) {
cout<<p->val<<" ";
}
cout<<endl;
}
int main() {
int a[10] = {1,5,2,6,7,4,6,2,8,9};
ListNode *head = init(a, 10);
printList(head);
//removedulicate1(head);
removedulicate2(head);
printList(head);
return 0;
}