当前位置:主页 > 查看内容

Leetcode-876.链表的中间结点-剑指22.到数第K个结点(快慢指针)

发布时间:2021-06-04 00:00| 位朋友查看

简介:中间结点 这种链表的题找第几个结点有个很骚的解法就是用计数器找到那个结点但是感觉完全避开了他想考察的算法。这种题应该要能熟练使用快慢指针这种算法。 这种算法就根据题目来一边分析一边介绍其用处 根据题目 要寻找中间的结点如果是有两个中间结点就返……

中间结点

在这里插入图片描述
这种链表的题,找第几个结点,有个很骚的解法,就是用计数器找到那个结点,但是感觉完全避开了他想考察的算法。这种题应该要能熟练使用快慢指针这种算法。

这种算法就根据题目来一边分析一边介绍其用处
根据题目
要寻找中间的结点,如果是有两个中间结点,就返回第二个结点。
通常是设置一个快指针,一个慢指针。而快指针的速度是慢指针的两倍。也就是每次快指针一次走两个元素,而慢指针一次走一个元素。
它要找中间结点。

初始时
在这里插入图片描述
移动
在这里插入图片描述
再移动
在这里插入图片描述
这一步就已经达到目的了,慢指针移动到了中间结点,而此时,循环应该已经结束了,而快指针则是到了最后一个元素,这应该是一个循环结束的条件。

当有两个中间结点时。
在这里插入图片描述
移动

在这里插入图片描述
移动,慢指针已经到了第一个中间结点,再移动一次就可以到达第二个中间结点。
在这里插入图片描述
这种情况下, 快指针应该是走到了最后一个指针的next时,才结束循环移动。

一种是当快指针移动到最后一个结点时,循环结束,
一种是当快指针移动到最后一个结点的next时才结束循环。

总结一下条件是
fast==NULL结束条件对应有两个中间结点的情况,
fast->next == NULL,是对应只有一个中间结点的情况

无论哪种情况,都是快指针走两个结点,慢指针走一个结点。
当循环遇到两个条件中的y一个都要结束循环,返回慢指针

struct ListNode* middleNode(struct ListNode* head)
{
    struct ListNode* fast = head;
    struct ListNode* slow = head;
    while (fast && fast->next)
    {
        fast = fast->next->next;
        slow = slow->next;
    }
    return slow;
}

再来看看利用快慢指针的另一道题

倒数第K个结点

在这里插入图片描述
这就比较不太一样。这是规定好特定的结点。但我们结束快指针移动到最后一个结点或NULL时结束,也就是说,当快指针移动到末尾时,慢指针要正好移动到到数第K个结点。
意味着,快指针于慢指针相差K个结点。
可以让快指针先走K个结点,再快慢指针一起走,当结束时,正好在倒数第K个结点处。

先走K个结点
在这里插入图片描述
再两指针一起走
在这里插入图片描述

继续
在这里插入图片描述

继续
在这里插入图片描述
最后一步
在这里插入图片描述
因为是倒数第K个快指针如果再最后一个结点,那么慢指针与快指针相差两个结点,就是倒数第3个结点,所以快指针要在NULL时,才满足。

struct ListNode* getKthFromEnd(struct ListNode* head, int k)
{
    struct ListNode* fast=head;
    struct ListNode* slow=head;
    for(int i=0;i<k;i++)
    {
     	if(fast==NULL)
            return NULL;
        fast=fast->next;
    }
    while(fast)
    {
        fast=fast->next;
        slow=slow->next;
    }
    return slow;
}

上面都是常规情况,但是还有一些比较奇怪的测试用例。
比如k会超过链表的结点数,那就只能在快指针达到NULL是就提前结束。
或者本身就是一个空链表,那就也是直接结束。
快慢指针感觉挺巧妙的,可以好好理解使用。

;原文链接:https://blog.csdn.net/weixin_52199109/article/details/115536312
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!
上一篇:CSS-粘连布局-实现以及变形实战 下一篇:没有了

推荐图文


随机推荐