练习链表的小应用

 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表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;

    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值