在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
链表的应用都是在了解了基本操作后,能够对应不同的问题有不同的算法思路,这个其实是相当难的,所以需要我们多多练习
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if(pHead == NULL)
return NULL;
ListNode* p1 = pHead;
ListNode* p2 = pHead;
ListNode* pre = pHead;
while(p1 != NULL)
{
if(p1!= NULL && p1->next != NULL &&p1->next->val == p1->val)
{
p2 = p1->next;
while(p2 != NULL && p2->next != NULL && p2->next->val == p1->val)
{
p2 = p2->next;
}
if(p1 == pHead)
{
pHead = p2->next;
}
else
{
pre->next = p2->next;
}
p1 = p2->next;
}
else
{
pre = p1;
p1 = p1->next;
}
}
return pHead;
}
};
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
链表找环这个应给可以理解为一个公式,基本的思路在于找到环的节点个数N,让一个指针先走N步,然后第二个指针在头结点开始,两个指针一起匀速移动,最后一定会在环的入口相遇,因为它们相差的就是N,刚好是一个环的长度。理解了这步算是成功了一大半,接着是算出环的节点数N',这点可能需要根据代码理解,本人语言表达能力恐怕不能详细准确地阐述。大概意思是两个指针同时移动,*fast和*slow,fast每次移动两个节点,slow每次移动一个节点,当两个节点相遇时,一定是在环中,这点是一定要理解的,并且fast比slow多移动的其实就是一圈,而且fast移动的步数是slow的两倍,所以可以知道slow移动了N步。此时把fast重新指向头指针,两个指针相差的步数就是N。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
if(pHead == NULL || pHead->next == NULL)
return NULL;
ListNode *fast = pHead;
ListNode *slow = pHead;
while(fast != NULL && fast->next != NULL)
{
fast = fast->next->next;
slow = slow->next;
if(fast == slow)
break;
}
slow = pHead;
while(fast != slow)
{
fast = fast->next;
slow = slow->next;
}
return slow;
}
};