链表翻转和链表环入口点

链表环和环入口点

0.单链表节点定义:

	struct Node
    {
        int _val;
        Node* next;
        
        Node()
        {
            next = NULL;
        }
        
        Node(int val):_val(val),next(NULL){}
    };

1.单链表翻转
用双指针, 一个指针指向当前节点, 一个指针指向当前节点的前一个节点, 用临时变量记录当前指针的next, 当前指针的next指向前一个节点, 前一个指针指向当前节点, 当前节点指针指向临时变量记录的节点。

void Reverse(Node* pHead)
{
	Node* pPre = NULL;
    Node* pCur = pHead;
    Node* pTmp;
    while(pCur != NULL)
    {
        pTmp = pCur->next;
        pCur->next = pPre;
        pPre = pCur;
        
        pCur = pTmp;
    }
    pHead = pPre;
}

2.判断链表是否有环
用双指针, 一个指针一次走一步, 一个指针一次走两步, 如果指向同一块内存,则说明链表有环。

bool IsLoopList(Node* pHead)
{
    Node* pSlow = pHead;
    Node* pFast = pHead;
    while(pFast != NULL && pFast->next != NULL)
    {
        pSlow = pSlow->next;
        pFast = pFast->next->next;
        if(pSlow == pFast)
        {
            return true;
        }
    }
    return false;
}

3.链表的环入口点
在2的基础上相遇后展开分析:
寻找入口点思路
快慢指针相遇后,假设慢指针经过k个节点,则快指针经过2k个节点, 从链表头到环入口经过x个节点,从环入口到相遇点经过y个节点,从相遇点继续走到到环入口结果z个节点(环的长度l = y+z)
x + y = z 慢指针
n(y+z) + x+y = 2k; 快指针, n > 0
则 n(y+z) = k
则 (n-1)(y+z) + y+z = k; => (n-1)(y+z) + y + z = x + y
=> (n-1)*(y+z) + z = x
所以从链表头经过x个节点 和 从相遇点经过 x个节点后两个指针又会相遇, 且相遇点是链表入口点


Node* GetLoopListEnterNode(Node* pHead)
{
    Node* pSlow = pHead;
    Node* pFast = pHead;
    while(pFast != NULL && pFast->next != NULL)
    {
        pSlow = pSlow->next;
        pFast = pFast->next->next;
        if(pSlow == pFast)
        {
            //寻找环入口
            pSlow = pHead;
            while(pSlow != pFast)
            {
                pSlow = pSlow->next;
                pFast = pFast->next;
            }
            Node* loopEnterNode = pSlow;
            return loopEnterNode;
        }
    }
    return NULL;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值