力扣876 - 链表的中间结点【快慢指针】

简介: 力扣876 - 链表的中间结点,利用快慢指针的逻辑寻找中间的那个结点

@TOC

一、题目描述

给定一个头结点为 head 的非空单链表,返回链表的中间结点。

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

示例 1:

输入:[1,2,3,4,5]
输出:此列表中的结点 3 (序列化形式:[3,4,5])
返回的结点值为 3 。 (测评系统对该结点序列化表述是 [3,4,5])。
注意,我们返回了一个 ListNode 类型的对象 ans,这样:
ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = NULL.

示例 2:

输入:[1,2,3,4,5,6]
输出:此列表中的结点 4 (序列化形式:[4,5,6])
由于该列表有两个中间结点,值分别为 3 和 4,我们返回第二个结点。

提示:

  • 给定链表的结点数介于 1 和 100 之间。

二、思路分析

好,看完题目的描述,我们来分析一下去求解这道题目
  • 从题目的描述来看很清晰,就是去求出一个链表的中间结点,我们知道,对于【单链表】而言,只能是通过头结点指针一一地遍历下去才能找到对应的结点,不像是数组那样支持随机访问,那这里也是一样,我们也是要去进行遍历,但是使用的不是一个指针,而是两个,这里我们俗称叫做【双指针】,我是用的是双指针中的一种,叫做【快慢指针】,很多力扣上链表方面的题目都会使用到双指针,而且使用这个【快慢指针】的也是很多,==因此你需要掌握==。
  • 好,话不多说,我们来分析一下如何去求解这道题目,所谓快慢指针,也就是快指针走得快一些,通常上就是快指针走两步,慢指针走一步,首先来看看两个快慢指针初始化的样子,可以看到一开始均位于【head】头结点处。从这里我们可以知晓中间结点为【3
在这里插入图片描述
  • 然后每次快指针走两步,慢指针走一步,没到结尾,继续走
在这里插入图片描述
  • 然后可以看到,此时慢指针其实已经走到我们需要寻找的中间结点位置,这个时候其实已经不需要在遍历了,结束即可
  • 但是结束的条件是什么呢?可以看到此时【fast->next == NULL】,这其实就是循环遍历结束的条件
在这里插入图片描述

  • 然后你是不是认为这样就可以了,我们提交一下看看。但是可以看到后台给出了报错,然后可以知晓结点的个数不一样了。我们使用这个例子再去做做看
在这里插入图片描述
  • 此时快慢指针走的距离还是不变:快指针走两步,慢指针走一步
在这里插入图片描述

在这里插入图片描述

  • 可以看到,此时【fast】指针遍历完毕,【slow】此时指向了4这个结点
在这里插入图片描述
  • 然后我们来看一下题目给出的要求:因为这里是两个中间结点,所以我们需要返回第二个,也就是【4
  • 那可以看出本题还有第二种需要考虑的场景就是偶数个结点的链表,那结束循环的条件是什么呢?可以看到此时【fast == NULL】,上面奇数个结点的时候是【fast->next == NULL】,因此这两个结束条件我们都需要写入循环中
  • 那它们怎么进行一个连接呢?你觉得是哪一种,没错,就是第一种,因为这两个情况只要满足一个就可以跳出进行【return】了,而且return的都是【slow】,
while(fast != NULL && fast->next != NULL)
while(fast != NULL || fast->next != NULL)
在这里插入图片描述

三、整体代码展示

题目代码很简单,以下是使用C++实现的
class Solution {
public:
    ListNode* middleNode(ListNode* head) {
        ListNode* slow, *fast;
        slow = fast = head;
        while(fast != NULL && fast->next != NULL)
        {      
            fast = fast->next->next;      
            slow = slow->next;
        }
        return slow;
    }
};

四、总结与提炼

  • 最后我们来总结一下本文所介绍的内容,本文讲解的是一道力扣中有关求解链表中间结点的题目,从上面可以看出本题的代码并不复杂,但是要考虑到链表的个数时奇数还是偶数,然后需要在循环中加上一些限制条件,才能通过所有的测试案例
  • 所以大家在思考题目的时候要尽量考虑的周全一些,因为有公司在面试的时候给出的网站链接是不给测试用例的,这就需要我们自己去思考了🤔,这个能力大家也是需要锻炼,才可以沉着冷静地去面试
以上就是本文所要描述的所有内容,感谢您对本文的观看,如有疑问请于评论区留言或者私信我都可以:four_leaf_clover:
相关文章
|
1天前
|
索引
【力扣刷题】删除链表的倒数第 N 个结点、两两交换链表中的节点、随机链表的复制
【力扣刷题】删除链表的倒数第 N 个结点、两两交换链表中的节点、随机链表的复制
6 0
|
1天前
|
存储 算法 索引
【力扣刷题】只出现一次的数字、多数元素、环形链表 II、两数相加
【力扣刷题】只出现一次的数字、多数元素、环形链表 II、两数相加
12 1
|
1天前
|
索引
【力扣刷题】回文链表、环形链表、合并两个有序链表
【力扣刷题】回文链表、环形链表、合并两个有序链表
8 0
|
1天前
|
索引
【力扣刷题】两数求和、移动零、相交链表、反转链表
【力扣刷题】两数求和、移动零、相交链表、反转链表
10 2
【力扣刷题】两数求和、移动零、相交链表、反转链表
|
6天前
|
算法 索引
【数据结构与算法 | 基础篇】[链表专题]力扣141, 142
【数据结构与算法 | 基础篇】[链表专题]力扣141, 142
|
1天前
|
算法
"刷题记录:哈希表+双指针 | leetcode-2465. 不同的平均值数目 "
该文段是一篇关于编程题目的解答,主要讨论如何找到数组中所有不同平均值的个数。作者首先使用排序和哈希集来解决,将数组转为列表排序后,通过双指针计算平均值并存入哈希集以去重。然后,作者发现可以优化方案,通过双指针在排序后的数组中直接计算两数之和,用哈希集记录不重复的和,从而避免实际计算平均值,提高了算法效率。最终代码展示了这两种方法。
8 0
|
1天前
【力扣刷题】二叉树的中序遍历、二叉树的最大深度、翻转二叉树、对称二叉树
【力扣刷题】二叉树的中序遍历、二叉树的最大深度、翻转二叉树、对称二叉树
7 0
|
1天前
|
索引
【力扣刷题】数组实现栈、后缀表达式(逆波兰表达式)求值、中缀表达式转换为后缀表达式(无括号&&有括号)
【力扣刷题】数组实现栈、后缀表达式(逆波兰表达式)求值、中缀表达式转换为后缀表达式(无括号&&有括号)
5 0
|
4天前
|
算法 索引
力扣刷题【第一期】
这是一个关于算法的总结,包含7个不同的问题。1)爬楼梯问题,使用动态规划,通过迭代找到到达n阶楼梯的不同方法数。2)两数之和,通过双重循环找出数组中和为目标值的两个数的索引。3)移动零,使用双指针将数组中的0移到末尾。4)合并有序链表,创建新链表按升序合并两个链表。5)删除链表重复值,遍历链表删除重复元素。6)环形链表检测,使用快慢指针判断链表是否有环。7)相交链表,计算链表长度找
9 1
|
4天前
|
存储 Java
JAVA数据结构刷题 -- 力扣二叉树
JAVA数据结构刷题 -- 力扣二叉树
10 0

热门文章

最新文章