【单链表面试题】-----链表带环问题

  1. 判断单链表是否带环,并求得相遇点
    思路:快慢指针问题,(前面已经讲过快慢指针原理,在这里不再详细描述)
    当快指针比慢指针多走一步,在某个环内一定会相遇在某一点;反过来则有:当两个快慢指针在某一点相遇,这个链表一定是带环的链表,反之不带环(具体过程如图)

这里写图片描述

具体代码:

//链表是否带环(并返回相遇点)
SListNode* SListIsCircle(SListNode* list)
{
    assert(list);
    SListNode* fast = list;
    SListNode* slow = list;

    while (fast&&fast->_next!=NULL)
    {
        fast = fast->_next->_next;
        slow = slow->_next;
        if (slow == fast)
        {
            return slow;
        }
    }
    return NULL;
}

2.环的长度
思路:环的长度可由计数器来完成,我们已经知道环内的相遇点,故而可以从相遇点开始遍历,同时记录所遍历的节点数,当回到相遇点时,记录的节点数就是环的长度

具体代码:

//求环的长度
int  SListCircleLenth(SListNode* list, SListNode* meet)
{
    assert(list);
    SListNode* cur = meet;
    size_t count = 1;
    while (cur->_next != meet)
    {
        cur = cur->_next;
        count++;
    }
    return count;
}
  1. 求环的入口点
    思路:一个结论:链表的头到入口点的距离恰好是相遇点到入口点的距离(证明如下图)

这里写图片描述

具体代码:

//求环的入口点
SListNode*  SListNodeEntryNode(SListNode* list, SListNode* meet)
{
    assert(list);
    assert(meet);
    SListNode* pHead = list;
    SListNode* cur = meet;
    while (pHead != cur)
    {
        pHead = pHead->_next;
        cur = cur->_next;
    }
    return pHead;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值