Total Accepted: 67074
Total Submissions: 253195
Difficulty: Medium
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.
我的AC:(4ms,最快一批)
struct ListNode* deleteDuplicates(struct ListNode* head) {
if(!head || !head->next)
return head;
struct ListNode *dummy = (struct ListNode*)malloc(sizeof(struct ListNode));
dummy->next = head;
struct ListNode *p = dummy;
struct ListNode *last = NULL;
while(p->next && p->next->next){//p->next->next必须要加,不然runtime error
if(p->next->val == p->next->next->val){
last = p->next;
p->next = p->next->next;
}
else if(last && p->next->val == last->val)
p->next = p->next->next;
else
p = p->next;
}
if(last && p->next->val == last->val)
p->next = p->next->next;
return dummy->next;
}
关键:
循环后还要再加一个if判断。
if(last && p->next->val == last->val)
p->next = p->next->next;
如果不加则【1,1,1,1,1】和【1,1,1,1】输出为【1】
但这是用了testcase才知道的,自己想不到。
另一种写法:
struct ListNode* deleteDuplicates(struct ListNode* head) {
if(!head || !head->next)
return head;
struct ListNode *dummy = (struct ListNode*)malloc(sizeof(struct ListNode));
dummy->next = head;
struct ListNode *p = dummy;
struct ListNode *curr = head;
while(curr){
if(curr->next && curr->val == curr->next->val){
while(curr->next && curr->val == curr->next->val)
curr = curr->next;
}
else{
p->next = curr;
p = p->next;
}
curr = curr->next;
}
p->next=NULL;
return dummy->next;
}
更简洁的写法:
struct ListNode* deleteDuplicates(struct ListNode* head) {
if(!head || !head->next)
return head;
struct ListNode *dummy = (struct ListNode*)malloc(sizeof(struct ListNode));
dummy->next = head;
struct ListNode *pre = dummy, *cur = head;
int preVal = head->val-1; //记录下当前节点的值以便下次循环对比使用,初始值应该对头节点产生影响,所以设成与头节点值有区别。
while(cur){
if(cur->val != preVal && ( !cur->next || cur->next->val != cur->val)) {//only when both the previous value and the next are not equal to the current one - by the way, the next node is null will definitely considered unequal, we can then collect it;
pre->next = cur;
pre = pre->next;
}
preVal = cur->val;
cur = cur->next;
}
pre->next = NULL; //terminate the list;
return dummy->next;
}
剑指offer57题:
一.返回类型为void
void DeleteNode(ListNode** pListHead, ListNode* pToBeDeleted)
{
if(!pListHead || !pToBeDeleted)
return;
// 要删除的结点不是尾结点
if(pToBeDeleted->m_pNext != NULL)
{
ListNode* pNext = pToBeDeleted->m_pNext;
pToBeDeleted->m_nValue = pNext->m_nValue;
pToBeDeleted->m_pNext = pNext->m_pNext;
delete pNext;
pNext = NULL;
}
// 链表只有一个结点,删除头结点(也是尾结点)
else if(*pListHead == pToBeDeleted)
{
delete pToBeDeleted;
pToBeDeleted = NULL;
*pListHead = NULL;
}
// 链表中有多个结点,删除尾结点
else
{
ListNode* pNode = *pListHead;
while(pNode->m_pNext != pToBeDeleted)
{
pNode = pNode->m_pNext;
}
pNode->m_pNext = NULL;
delete pToBeDeleted;
pToBeDeleted = NULL;
}
}
二、返回类型是ListNode*
ListNode* deleteDuplication(ListNode* pHead)
{
if (pHead == NULL) return NULL;
ListNode *curr = pHead;
ListNode *prev = NULL;
ListNode *pNext;
ListNode *newHead = pHead;
while(curr){
pNext = curr->next;
int value = curr->val;
bool shouldDel = false;
if(pNext != NULL && pNext->val == value)
shouldDel = true;
if(shouldDel){//要删除
ListNode *pToBeDel = curr;
while(pToBeDel != NULL && pToBeDel->val == value){
pNext = pToBeDel->next;
delete pToBeDel;
pToBeDel = NULL;
pToBeDel = pNext;
}
if(prev == NULL)//头结点改变
newHead = pNext;
else
prev->next = pNext;
curr = pNext;
}
else{//不要删除
prev = curr;
curr = curr->next;
}
}
return newHead;
}
本文介绍了一种高效算法,用于从已排序的链表中移除所有重复出现的元素,只保留唯一的数值。提供了三种不同的实现方式,并附带了剑指Offer 57题的两种解题思路。
129

被折叠的 条评论
为什么被折叠?



