Given a non-empty, singly linked list with head node `head`, return a middle node of linked list.

If there are two middle nodes, return the second middle node.

Example 1:

Input: [1,2,3,4,5]
Output: Node 3 from this list (Serialization: [3,4,5])
The returned node has value 3. (The judge's serialization of this node is [3,4,5]).
Note that we returned a ListNode object ans, such that:
ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, and ans.next.next.next = NULL.

Example 2:

Input: [1,2,3,4,5,6]
Output: Node 4 from this list (Serialization: [4,5,6])
Since the list has two middle nodes with values 3 and 4, we return the second one.

Note:

  • The number of nodes in the given list will be between 1 and 100.

这道题给了一个链表,让我们找其中间结点。由于链表不像数组,不能通过坐标位置来直接访问元素,而是只能从头结点开始,使用 next 指针来访问之后的结点,为了知道当前结点的位置,还得使用计数器来记录。由于在不知道链表的总长度之前,是无法知道中间结点的位置的,那么可以首先遍历一遍,统计出链表的长度,此时长度有了,除以2就是中间结点的位置了,再从头遍历一遍,就可以找出中间结点的位置了,参见代码如下:


解法一:

class Solution {
public:
ListNode* middleNode(ListNode* head) {
ListNode *cur = head;
int cnt = 0;
while (cur) {
++cnt;
cur = cur->next;
}
cnt /= 2;
while (cnt > 0) {
--cnt;
head = head->next;
}
return head;
}
};

由于链表无法通过坐标位置来访问元素,但我们可以将所有的结点按顺序存入到一个数组中,那么之后就可以直接根据坐标位置来访问结点了,参见代码如下:


解法二:

class Solution {
public:
ListNode* middleNode(ListNode* head) {
vector<ListNode*> vec(100);
int cur = 0;
while (head) {
vec[cur++] = head;
head = head->next;
}
return vec[cur / 2];
}
};

上面两种方法一个多用了时间,一个多用了空间,其实都不是最优的解法,最好的方法其实是使用快慢指针来做。在之前那道 [Linked List Cycle](https://www.cnblogs.com/grandyang/p/4137187.html) 链表中找环的题,我们介绍过快慢指针,就是两个指针,慢指针一次走一步,快指针一次走两步,那么这里当快指针走到末尾的时候,慢指针刚好走到中间,这样就在一次遍历中,且不需要额外空间的情况下解决了问题,参见代码如下:


解法三:

class Solution {
public:
ListNode* middleNode(ListNode* head) {
ListNode *slow = head, *fast = head;
while (head && head->next) {
slow = slow->next;
head = head->next->next;
}
return slow;
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/876

类似题目:

Linked List Cycle

参考资料:

https://leetcode.com/problems/middle-of-the-linked-list/

https://leetcode.com/problems/middle-of-the-linked-list/discuss/154619/C%2B%2BJavaPython-Slow-and-Fast-Pointers

https://leetcode.com/problems/middle-of-the-linked-list/discuss/155148/Java-O(n)-time-and-O(1)-space-solution-without-using-fastslow-pointer

[LeetCode All in One 题目讲解汇总(持续更新中...)](https://www.cnblogs.com/grandyang/p/4606334.html)

[LeetCode] 876. Middle of the Linked List 链表的中间结点的更多相关文章

  1. LeetCode 876 Middle of the Linked List 解题报告

    题目要求 Given a non-empty, singly linked list with head node head, return a middle node of linked list. ...

  2. [LeetCode] 876. Middle of the Linked List_Easy tag: Linked List ** slow, fast pointers

    Given a non-empty, singly linked list with head node head, return a middle node of linked list. If t ...

  3. LeetCode 876. Middle of the Linked List(获得链表中心结点)

    题意:获得链表中心结点.当有两个中心结点时,返回第二个. 分析:快慢指针. /** * Definition for singly-linked list. * struct ListNode { * ...

  4. 876. Middle of the Linked List - LeetCode

    Question 876. Middle of the Linked List Solution 题目大意:求链表的中间节点 思路:构造两个节点,遍历链接,一个每次走一步,另一个每次走两步,一个遍历完 ...

  5. 【Leetcode_easy】876. Middle of the Linked List

    problem 876. Middle of the Linked List 参考 1. Leetcode_easy_876. Middle of the Linked List; 完

  6. 【LeetCode】876. Middle of the Linked List 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 使用哑结点 不使用哑结点 日期 题目地址:https ...

  7. [LeetCode&Python] Problem 876. Middle of the Linked List

    Given a non-empty, singly linked list with head node head, return a middle node of linked list. If t ...

  8. 876. Middle of the Linked List【Easy】【单链表中点】

    Given a non-empty, singly linked list with head node head, return a middle node of linked list. If t ...

  9. 876. Middle of the Linked List

    1. 原始题目 Given a non-empty, singly linked list with head node head, return a middle node of linked li ...

随机推荐

  1. MyBatis-Generator 用法介绍

    ”工欲善其事,必先利其器“,古人说的很对,虽然不能做一个单纯的”工具帝“,但是自己有合适的工具集真的很关键.以前认识一个做逆向工程的高手,有自己的”反马套装“,其实不外乎就是 OD . IDA .Sy ...

  2. Shell基本运算符之算术、关系运算符

    Shell 运算符 =============================摘自菜鸟教程================================= Shell和其他编程语言一样,支持多种运算 ...

  3. Kubernetes 部署集群内部DNS服务

    Kubernetes 部署集群内部DNS服务 部署官网:https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/dns/ ...

  4. netcore sdk版本选择

    NetCore sdk并不是每个版本都支持VS2017工具,也不是每个版本的sdk版本号和Runtime版本号都一样,这就需要我们在创建某个版本的net core应用时注意: 使用不同版本的vs时需要 ...

  5. Java多线程——查看线程堆栈信息

    Java多线程——查看线程堆栈信息 摘要:本文主要介绍了查看线程堆栈信息的方法. 使用Thread类的getAllStackTraces()方法 方法定义 可以看到getAllStackTraces( ...

  6. CMake编译的VS工程,安装时遇到错误:error MSB3073: 命令“setlocal

    错误提示 70>CMake Error at src/base/cmake_install.cmake:63 (file): 70> file INSTALL cannot find 70 ...

  7. canvas的常用功能(电脑版)

    前言: canvas可以单独算为前端的一大知识模块, 今天就研究一下. 先做下前文铺垫: ①创建canvas <canvas id="myCanvas" width=&quo ...

  8. 中国爬虫违法违规案例汇总github项目介绍

    中国爬虫违法违规案例汇总github项目介绍 GitHub - 本项目用来整理所有中国大陆爬虫开发者涉诉与违规相关的新闻.资料与法律法规.致力于帮助在中国大陆工作的爬虫行业从业者了解我国相关法律,避免 ...

  9. CTF挑战赛丨网络内生安全试验场第一季答题赛火热开启

    前期回顾:挑战世界级“人机大战”,更有万元奖金等你来拿 网络内生安全试验场自上线以来,受到了业内的极大重视与关注. 自9月2日报名通道开启后,报名量更是持续高升,上百名精英白帽踊跃报名. 至此,网络内 ...

  10. Android系统源码目录

    Android系统源码目录 我们要先了解Android系统源码目录,为后期源码学习打下基础.关于源码的阅读,你可以访问http://androidxref.com/来阅读系统源码.当然,最好是将源码下 ...