876.链表的中间结点-力扣 链表中倒数第k个结点-牛客 (快慢指针方法)

链表的中间节点

OJ链接:链表的中间结点

给你单链表的头结点 head ,请你找出并返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。

这里,最容易想起的一个方法就是:先遍历一遍链表,得出链表长度,再遍历出这个链表的中间节点

其实还有一个更妙的方法,就是使用快慢指针

定义slow指针和fast指针
slow一次走一步,fast一次走两步

假设当前链表个数是奇数个:
在这里插入图片描述
过程如下:
请添加图片描述

可以看到,当fast移动到最后时,slow的位置恰好是中间节点:
在这里插入图片描述
所以就可以得,其代码的循环条件为fast->next!=NULL

假设当前链表个数是偶数个:

过程如下:请添加图片描述
同样可以发现:
最后当fast为空时,,slow指向中间节点,所以对于偶数个节点的链表来说,循环条件是fast!=NULL

所以,代码如下:

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

链表中倒数第k个结点

OJ链接:链表中倒数第k个结点

描述:
输入一个链表,输出该链表中倒数第k个结点。

示例1
输入: 1,{1,2,3,4,5}
返回值:{5}

这道题的思路是:
倒数第k个节点,距最后一个节点的距离是k-1
所以可以先让fast指针移动k-1步,之后slowfast一起移动,每次移动一步,直到fast->next==NULL
先让fast指针移动k步,之后slowfast一起移动,每次移动一步,直到fast==NULL

过程如下:
请添加图片描述
代码如下:

struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
    
    
    // write code here
    if(pListHead==NULL)
    {
    
    
        return NULL;
    }
    struct ListNode* slow,*fast;
    slow = fast = pListHead;
    while(k--)
    {
    
    
        if(fast==NULL)
        {
    
    
            return NULL;
        }
        fast = fast->next;
    }

    while(fast)
    {
    
    
        fast = fast->next;
        slow = slow->next;
    }
    return slow;
}

猜你喜欢

转载自blog.csdn.net/weixin_64116522/article/details/129326815
今日推荐