CareerCup之2.1無序鏈表刪除重複元素
【題目】
原文:
2.1 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?
譯文:
從一個未排序的鏈表中移除重複的項
進一步地,
如果不允許使用臨時的緩存,你如何解決這個問題?
【分析】
(1)如果可以使用額外的存儲空間,我們就開一個數組來保存一個元素的出現情況。 對於這種情況,最好的解決方法當然是使用哈希表,但令人非常不爽的是C++標準裏是沒有 哈希表的(java裏有)。所以,在這用一個數組模擬一下就好了。但,這裏要注意一個問題, 就是元素的邊界,比如鏈表裏存儲的是int型變量。那麼,如果有負值,這個方法就不奏效 了。而如果元素裏的最大值非常大,那麼這個數組也要開得很大,而數組中大部分空間是用 不上的,會造成空間的大量浪費。
簡言之,如果可以用哈希表,還是用哈希表靠譜。
如下代碼遍曆一遍鏈表即可,如果某個元素在數組裏記錄的是已經出現過, 那麼將該元素刪除。時間複雜度O(n):
(2)如果不允許使用臨時的緩存(即不能使用額外的存儲空間),那需要兩個指針,cur做正常的迭代,runner指針遍曆cur指針之前的所有元素,判斷當前元素的值是否已經出現過。如果出現過就刪除cur指向的元素。
【代碼一】
/*********************************
* 日期:2014-05-17
* 作者:SJF0115
* 題目: Set Matrix Zeroes
* 來源:CareerCup
**********************************/
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
#define N 100000
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
bool Hash[N];
ListNode* DeleteDuplicatesFromUnSortedList(ListNode *head) {
if(head == NULL || head->next == NULL){
return head;
}
memset(Hash,0,sizeof(Hash));
ListNode* pre = head;
ListNode* cur = head->next;
while(cur != NULL){
//存在重複元素刪除
if(Hash[cur->val]){
ListNode* node = cur;
pre->next = cur->next;
cur = cur->next;
delete node;
}
else{
Hash[cur->val] = true;
pre = cur;
cur = cur->next;
}
}
return head;
}
int main(){
int i,j;
//freopen("C:\\Users\\XIAOSI\\Desktop\\acm.txt","r",stdin);
ListNode *head = (ListNode*)malloc(sizeof(ListNode));
head->next = NULL;
ListNode *node;
ListNode *pre = head;
int A[] = {6,5,3,3,6,5,6,7,3,7,1,2,1,4,6,7,2,3};
for(int i = 0;i < 18;i++){
node = (ListNode*)malloc(sizeof(ListNode));
node->val = A[i];
node->next = NULL;
pre->next = node;
pre = node;
}
head = DeleteDuplicatesFromUnSortedList(head);
ListNode* cur = head->next;
while(cur != NULL){
printf("%d ",cur->val);
cur = cur->next;
}
return 0;
}
【代碼二】
/*********************************
* 日期:2014-05-17
* 作者:SJF0115
* 題目: Set Matrix Zeroes
* 來源:CareerCup
**********************************/
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
ListNode* DeleteDuplicatesFromUnSortedList(ListNode *head) {
if(head == NULL || head->next == NULL){
return head;
}
ListNode* pre = head;
ListNode* cur = head->next;
//刪除重複元素
while(cur != NULL){
ListNode* runner = head->next;
//判斷是否是重複
while(runner != cur){
if(runner->val == cur->val){
ListNode* node = cur;
//刪除node
pre->next = cur->next;
cur = pre->next;
delete node;
break;
}
runner = runner->next;
}
//如果上麵沒有刪除元素,需要更新指針
if(runner == cur){
pre = cur;
cur = cur->next;
}
}
return head;
}
int main(){
int i,j;
//freopen("C:\\Users\\XIAOSI\\Desktop\\acm.txt","r",stdin);
ListNode *head = (ListNode*)malloc(sizeof(ListNode));
head->next = NULL;
ListNode *node;
ListNode *pre = head;
int A[] = {6,5,3,3,6,5,6,7,3,7,1,2,1,4,6,7,2,3};
//輸入
for(int i = 0;i < 18;i++){
node = (ListNode*)malloc(sizeof(ListNode));
node->val = A[i];
node->next = NULL;
pre->next = node;
pre = node;
}
//刪除重複元素
head = DeleteDuplicatesFromUnSortedList(head);
//輸出
ListNode* cur = head->next;
while(cur != NULL){
printf("%d ",cur->val);
cur = cur->next;
}
return 0;
}
最後更新:2017-04-03 08:26:11