#include <iostream>
#include <stdio.h>
#include <map>
using namespace std;
const int MAXSIZE = 10000;
/*
问题:编写代码,移除未排序链表中的重复节点
分析:删除重复节点,关键未排序,如果按照不排序做,那么第一遍需要统计所有元素及出现次数,
第二遍扫描的时候,对于重复节点,没删除一次,计数器减1.
时间复杂度为O(N)
如果先对链表排序,时间复杂度为O(nlogN),没有必要
应该是先删前面每次碰到的,然后减少计数器次数
输入:
5(元素个数)
1 3 1 2 3
输出:
1 2 3
书上解法:在链表建立好后,遍历链表,如果当前元素没有再散列表中出现,
则将当前元素加入散列表;否则,说明当前元素重复,删除该节点
时间复杂度为O(N),我使用的方法时间复杂度相同,但是优先删除前面
重复的元素,书上的解法优先删除后面重复的元素
关键:
1 判断当前节点的值是否在散列表出现,没有出现则加入散列表;否则删除当前节点
*/
typedef struct Node
{
int value;
Node* pNext;
}Node;
void deleteRepeatedNode(Node* pHead)
{
}
//构建连边,按照尾插法来做,返回节点值到出现次数的映射
map<int , int> buildList(int* pArray , Node* head , int num)
{
map<int,int> valueToCount;
if(pArray == NULL)
{
return valueToCount;
}
if(head == NULL)
{
return valueToCount;
}
//尾插法: 保留最后一个结尾节点,将新生成的节点插入在结尾节点,并令结尾节点为当前节点
Node* pLast = head;
//int num = sizeof(pArray) / sizeof(int);
for(int i = 0 ; i < num ; i++)
{
int value = *(pArray + i);
Node* pNode = new Node();
pNode->value = value;
pLast->pNext = pNode;
pLast = pNode;
//统计<结点值,出现次数的映射>
map<int,int>::iterator it = valueToCount.find(value);
//如果找到结点值,累加出现次数
if(it != valueToCount.end() )
{
it->second += 1;
}
else
{
valueToCount.insert(pair<int,int>(value , 1));
}
}
return valueToCount;
}
//删除重复节点
void deleteRepeatedNodes(map<int,int>& valueToCount , Node* pHead)
{
if(pHead == NULL)
{
return;
}
if( valueToCount.empty() )
{
return;
}
Node* pNode = pHead->pNext;
Node* pPrevious = pHead;
//如果当前节点非空,开始统计
while(pNode)
{
int value = pNode->value;
map<int,int>::iterator it = valueToCount.find(value);
//如果没找到,直接跳过
if(it == valueToCount.end())
{
pPrevious = pNode;
pNode = pNode->pNext;
continue;
}
int count = it->second;
//如果出现次数为1,无需删除,直接跳过
if(count == 1)
{
pPrevious = pNode;
pNode = pNode->pNext;
continue;
}
//说明有重复节点,删除当前节点,这里设置之前的节点保留下来。删除节点的时候,要不要使得previous变更(不需要)
if(count > 1)
{
Node* pDeleteNode = pNode;
pNode = pNode->pNext;
pPrevious->pNext = pNode;
delete pDeleteNode;
//更新出现次数
valueToCount[value] = count - 1;
}
}
}
void printList(Node* pHead)
{
if(NULL == pHead)
{
return;
}
Node* pNode = pHead->pNext;
while(pNode)
{
cout << pNode->value << " ";
pNode = pNode->pNext;
}
cout << endl;
}
void releaseList(Node* pHead)
{
if(NULL == pHead)
{
return;
}
Node* pNode = pHead->pNext;
Node* pPrevious = pHead;
while(pNode)
{
Node* pDeleteNode = pNode;
pPrevious->pNext = pNode->pNext;
pNode = pNode->pNext;
pPrevious = pPrevious->pNext;
delete pDeleteNode;
}
//删除头结点
delete pHead;
}
int main(int argc,char* argv[])
{
int n;
while(cin >> n)
{
int* pArr = new int[n];
for(int i = 0 ; i < n ; i++)
{
cin >> pArr[i];
}
Node* pHead = new Node();
map<int,int> valueToCount = buildList(pArr , pHead , n);
deleteRepeatedNodes(valueToCount , pHead);
printList(pHead);
releaseList(pHead);
}
system("pause");
return 0;
}
程序员面试金典: 9.2链表 2.1移除未排序链表中重复的节点
最新推荐文章于 2023-04-19 11:17:36 发布