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

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

目录

链表的中间节点

链表中倒数第k个结点

链表的中间节点

OJ链接:链表的中间结点


给你单链表的头结点 head ,请你找出并返回链表的中间结点。

如果有两个中间结点,则返回第二个中间结点。


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


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


定义slow指针和fast指针

slow一次走一步,fast一次走两步


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



dc9c839aab2042068ea977c2b4f5462d.png



过程如下:



ed0893c6b98c4d708e8e1f727fd3feee.gif



可以看到,当fast移动到最后时,slow的位置恰好是中间节点:




929c09cbc3f641328e5b7062c7d69310.png



所以就可以得,其代码的循环条件为fast->next!=NULL


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


1cc00804ccb649e786f7f59f9bb220aa.gif




过程如下:

同样可以发现:

最后当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步,之后slow和fast一起移动,每次移动一步,直到fast->next==NULL

先让fast指针移动k步,之后slow和fast一起移动,每次移动一步,直到fast==NULL


过程如下:


b9bcd830a5e14cbb9164b36386948c46.gif







代码如下:


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;
}


目录
相关文章
|
29天前
【bug记录】旋转链表与力扣报错:member access within null pointer of type ‘struct ListNode‘
【bug记录】旋转链表与力扣报错:member access within null pointer of type ‘struct ListNode‘
|
27天前
|
算法
LeetCode第24题两两交换链表中的节点
这篇文章介绍了LeetCode第24题"两两交换链表中的节点"的解题方法,通过使用虚拟节点和前驱节点技巧,实现了链表中相邻节点的交换。
LeetCode第24题两两交换链表中的节点
|
26天前
|
存储 算法
LeetCode第86题分隔链表
文章介绍了LeetCode第86题"分隔链表"的解法,通过创建两个新链表分别存储小于和大于等于给定值x的节点,然后合并这两个链表来解决问题,提供了一种简单易懂且操作原链表的解决方案。
LeetCode第86题分隔链表
|
26天前
|
存储 算法
LeetCode第83题删除排序链表中的重复元素
文章介绍了LeetCode第83题"删除排序链表中的重复元素"的解法,使用双指针技术在原链表上原地删除重复元素,提供了一种时间和空间效率都较高的解决方案。
LeetCode第83题删除排序链表中的重复元素
|
27天前
|
算法
LeetCode第23题合并 K 个升序链表
这篇文章介绍了LeetCode第23题"合并K个升序链表"的解题方法,使用分而治之的思想,通过递归合并链表的方式解决了这个难题。
LeetCode第23题合并 K 个升序链表
|
1月前
|
Python
【Leetcode刷题Python】114. 二叉树展开为链表
LeetCode上114号问题"二叉树展开为链表"的Python实现,通过先序遍历二叉树并调整节点的左右指针,将二叉树转换为先序遍历顺序的单链表。
20 3
【Leetcode刷题Python】114. 二叉树展开为链表
|
14天前
|
C++ 索引
leetcode 707.设计链表
本文提供了解决LeetCode 707题"设计链表"的C++实现,包括单链表的节点定义和类方法实现,如添加节点、获取节点值、删除节点等。
|
26天前
|
算法
LeetCode第92题反转链表 II
文章分享了LeetCode第92题"反转链表 II"的解法,通过使用四个指针来记录和更新反转链表段的头部、尾部以及前一个和后一个节点,提供了一种清晰且易于理解的解决方案。
LeetCode第92题反转链表 II
|
27天前
|
算法
LeetCode第21题合并两个有序链表
该文章介绍了 LeetCode 第 21 题合并两个有序链表的解法,通过创建新链表,依次比较两个链表的头节点值,将较小的值插入新链表,直至其中一个链表遍历完,再将另一个链表剩余部分接到新链表后面,实现合并。
LeetCode第21题合并两个有序链表
|
27天前
|
算法
LeetCode第19题删除链表的倒数第 N 个结点
该文章介绍了 LeetCode 第 19 题删除链表的倒数第 N 个结点的解法,通过使用快慢双指针,先将快指针移动 n 步,然后快慢指针一起遍历,直到快指针到达链尾,从而找到倒数第 N 个结点的前一个结点进行删除,同时总结了快慢指针可减少链表遍历次数的特点。
LeetCode第19题删除链表的倒数第 N 个结点