[C++]LeetCode: 6 Remove Duplicates from Sorted List II

来源:互联网 发布:sql select 两个表 编辑:程序博客网 时间:2024/05/08 04:10

题目:

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.

这道题不同之处在于,要把重复的所有节点删除。要稍微复杂点。

思路:链表排序说明重复节点都处于相邻位置,遍历链表并比较当前节点是否和下一个节点重复.如果重复:删除下一个节点,重复该操作直到下一个节点为空或者和当前节点不重复,只要执行过删除操作,就说明原链表曾经有和当前节点重复的节点,根据题目要求,此时还需要将当前节点删除掉,所以在判断下一个节点为空或者和当前节点值不同时,将当前节点删除。如果不同:则移动到链表的下一个节点继续重复以上判断,直到链表结束。   

Attention: 判断是否删除当前重复节点的条件很重要!如果删除掉一个重复节点后,之后的节点和当前节点一致,则保留当前节点,进行下次判断;否则删除当前节点;(当前节点是最后一个节点时也要删除)    !!!!解决了重复节点奇偶数的问题(奇数保留当前节点,偶数删除当前节点)。

AC Code:

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode *deleteDuplicates(ListNode *head) {     //除排序链表中所有重复的节点,删除完成后,原链表中的重复节点全部删除。     //链表排序说明重复节点都处于相邻位置,遍历链表并比较当前节点是否和下一个节点重复     //如果重复:删除下一个节点,重复该操作直到下一个节点为空或者和当前节点不重复,只要执行过删除操作,就说明原链表曾经有和当前节点重复的节点,根据题目要求,此时还需要将当前节点删除掉,所以在判断下一个节点为空或者和当前节点值不同时,将当前节点删除。     //如果不同:则移动到链表的下一个节点继续重复以上判断,直到链表结束。             //Attention: 如果删除掉一个重复节点后,之后的节点和当前节点一致,则保留当前节点,进行下次判断;否则删除当前节点;(当前节点是最后一个节点时也要删除)    !!!!解决了重复节点奇偶数的问题(奇数保留当前节点,偶数删除当前节点)。        if(head == NULL || head->next == NULL)        return head;            ListNode* dummyhead = new ListNode(0);    dummyhead->next = head;    ListNode* p, *q ,*pre;    p = head;    pre = dummyhead;        while( p != NULL)    {        //存在当前节点的下一个节点时        if(p->next != NULL && p->val == p->next->val)        {           //删除下一个重复节点           q = p->next;           p->next = q->next;           delete q;                      //符合条件删除当前节点,否则保留   !!!!此处删除当前节点的判断条件很重要           if(p->next == NULL || (p->next != NULL && p->val != p->next->val))           {              // pre = p->next;               pre->next = p->next;  //pre->next始终指向下一个要判断的节点 如1 1' 2 3 删除1'后,令pre指向2,再删除1,之后p重置为指向2               delete p;               p = pre->next;    //重置p为下一个节点   pre起到一个游标尺的作用,始终卡在下一个节点,用于重置p。           }        }        else                {            //移动pre和p节点            pre = pre->next;     //此处移动pre,不会影响dummyhead. 令pre指向新的地址。            p = p->next;        }    }        head = dummyhead->next;       //dummyhead->next始终指向新链表的头结点(dummyhead是虚拟头结点)    delete dummyhead;    return head;            }};




0 0
原创粉丝点击