剑指offer-刷题笔记-中等题-JZ23 链表中环的入口结点

剑指offer-刷题笔记-中等题-JZ23 链表中环的入口结点

版本1-自己写的,可以过,但是空间复杂度稍大,通过增加一个map,对每次访问的节点做标记,找到重复访问的节点

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead) {
        map<ListNode*,int> flag;;
        while(pHead)
        {
            //cout<<pHead->val<<endl;
            if(flag[pHead] == 0)
            {
                flag[pHead] = 1;
                //break;
            }
            else if(flag[pHead] == 1)
            {
                break;
            }
            else{
                flag.insert(map<ListNode*,int>::value_type(pHead,0));
            }
            pHead = pHead->next;
                
        }
        return pHead;
    }
};

版本2-双指针-两个指针步长不一致,快指针步长为2,慢指针步长为1,如果有环,两个指针会相遇,相遇的位置就是环的入口节点

class Solution {
public:
    //判断有没有环,返回相遇的地方
    ListNode* hasCycle(ListNode *head) { 
        //先判断链表为空的情况
        if(head == NULL) 
            return NULL;
        //快慢双指针
        ListNode* fast = head; 
        ListNode* slow = head;
        //如果没环快指针会先到链表尾
        while(fast != NULL && fast->next != NULL){ 
            //快指针移动两步
            fast = fast->next->next; 
            //慢指针移动一步
            slow = slow->next; 
            //相遇则有环
            if(fast == slow) 
                //返回相遇的地方
                return slow; 
        }
        //到末尾则没有环
        return NULL; 
    }
    
    ListNode* EntryNodeOfLoop(ListNode* pHead) {
        ListNode* slow = hasCycle(pHead);
        //没有环
        if(slow == NULL) 
            return NULL;
        //快指针回到表头
        ListNode* fast = pHead; 
        //再次相遇即是环入口
        while(fast != slow){ 
            fast = fast->next;
            slow = slow->next;
        }
        return slow;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值