#include <iostream>
#include <stdio.h>
#include <vector>
using namespace std;
/*
问题:
Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list.
For example,
Given 1->2->3->3->4->4->5, return 1->2->5.
Given 1->1->1->2->3, return 2->3.
分析:这道题目实际上就是要删除所有重复元素对应的所有节点。
那么问题的关键就是如何记录重复元素前面的指针和后面的指针。
我们可以在遍历某个节点的时候,维护指向前一个元素和后一个元素的指针。
一旦判定当前元素是重复元素,还得追溯到前一个元素的的前一个指针。
这样我们在判定当前元素时,顺便判定该元素后面一个元素是否和它相同;
如果两者是一样的,说明当前元素是重复的,就将当前元素的前一个节点保存下来,记为preious。
同时从当前元素继续向下找到第一个和当前元素不同的节点,保存下来记为next。
然后用previous指向next。
这样只需要扫描一遍。
输入:
7(节点个数)
1 2 3 3 4 4 5
5
1 1 1 2 3
3
1 1 1
1
1
2
1 1
2
1 2
输出:
1 2 5
2 3
no result
1
no result
1 2
关键:
1 这样我们在判定当前元素时,顺便判定该元素后面一个元素是否和它相同;
如果两者是一样的,说明当前元素是重复的,就将当前元素的前一个节点保存下来,记为preious。
同时从当前元素继续向下找到第一个和当前元素不同的节点,保存下来记为next。
2 设置删除重复节点后,不能更新previous,新指向的节点仍有可能重复
if(previousNode)
{
previousNode->next = nextNode;
//这里不能更新previous,
}
*/
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
if(NULL == head)
{
return NULL;
}
//如果只有一个节点,直接返回
if(NULL == head->next)
{
return head;
}
//一次读取两个节点
ListNode* nextNode;
ListNode* previousNode = NULL;
ListNode* node;
node = head;
nextNode = head->next;
int repeatedValue;
ListNode* tempPreviousNode;
ListNode* tempNode;
while(nextNode)
{
//如果是重复节点,记录previous节点,并寻找真正的重复节点后第一个不同的节点
if(node->val == nextNode->val)
{
repeatedValue = node->val;
while(nextNode && nextNode->val == repeatedValue)
{
node = nextNode;
nextNode = nextNode->next;
}
//如果上一个节点为空,说明头结点就是重复元素,需要重新设置head为第一个
if(NULL == previousNode)
{
tempPreviousNode = head;
}
else
{
tempPreviousNode = previousNode->next;
}
//如果还没有走到末尾,此时nextNode就是下一个保存的节点;如果走到末尾,说明从node本身及其后面所有节点都需要删除
//删除节点
while(tempPreviousNode && tempPreviousNode->val == repeatedValue)
{
tempNode = tempPreviousNode->next;
delete tempPreviousNode;
tempPreviousNode = tempNode;
}
//设置节点指向
if(previousNode)
{
previousNode->next = nextNode;
//这里不能更新previous,新指向的节点仍有可能重复
}
else
{
head = nextNode;
}
}
//node节点肯定不是重复节点
else
{
previousNode = node;
}
node = nextNode;
//这里可能由于整个链表重复,导致nextNode为空
if(!nextNode)
{
break;
}
nextNode = nextNode->next;
}
return head;
}
};
void print(ListNode* head)
{
if(!head)
{
cout << "no result" << endl;
}
ListNode* tempHead = head;
while(head)
{
cout << head->val << " ";
head = head->next;
}
cout << endl;
head = tempHead;
}
ListNode* buildList(vector<int>& nums)
{
if(nums.empty())
{
return NULL;
}
int size = nums.size();
ListNode* head ;
ListNode *tail;
ListNode* node;
for(int i = 0 ; i < size ; i++)
{
if(i)
{
node = new ListNode(nums.at(i));
tail->next = node;
tail = node;
}
else
{
head = new ListNode(nums.at(i));
tail = head;
}
}
return head;
}
void deleteList(ListNode* head)
{
ListNode* node;
while(head)
{
node = head->next;
delete head;
head = node;
}
}
void process()
{
vector<int> nums;
int value;
int num;
Solution solution;
vector<int> result;
while(cin >> num )
{
nums.clear();
for(int i = 0 ; i < num ; i++)
{
cin >> value;
nums.push_back(value);
}
ListNode* head = buildList(nums);
ListNode* newHead = solution.deleteDuplicates(head);
print(newHead);
deleteList(head);
}
}
int main(int argc , char* argv[])
{
process();
getchar();
return 0;
}
leecode 解题总结:82. Remove Duplicates from Sorted List II
最新推荐文章于 2024-01-17 14:07:10 发布
