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. Loj #2554. 「CTSC2018」青蕈领主

    Loj #2554. 「CTSC2018」青蕈领主 题目描述 "也许,我的生命也已经如同风中残烛了吧."小绿如是说. 小绿同学因为微积分这门课,对"连续"这一概 ...

  2. LeetCode 209:最小长度的子数组 Minimum Size Subarray Sum

    公众号: 爱写bug(ID:icodebugs) 作者:爱写bug 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组.如果不存在符合条件的连续子 ...

  3. gperf heap profiler

    前言 gperf tools有很多功能,其中有一个heap profiler,可按函数级别定位分配内存的累积量 原理 gperf tools需要替换libc的malloc库,替换为tcmalloc:t ...

  4. 利用正则来查找字符串中第n个匹配字符索引

    1.string.IndexOf()方法可以获得第一个匹配项的索引 2.要获取第n个匹配项的索引:  方法1:利用IndexOf方法循环获取. 方法2:用正则来查找. System.Text.Regu ...

  5. WPF两个按钮来回切换样式

    <!-- 两个按钮来回切换样式 --> <Style x:Key="SwicthFunctionMetroToggleButton" TargetType=&qu ...

  6. web api 记录部署IIS获取服务器地址的类型

    获取服务器地址类型分多种,以下记录 1.HttpContext.Current.Server.MapPath("~/File") 返回的值为 D:\3Project\Code\Mo ...

  7. 设计模式之设计原则 C#

    成为一名资深架构师首先要懂设计模式,在懂之前,要清楚设计原则,原来我就吃过这个亏,很久以前有人问我设计原则,我是一头茫然,不是只有设计模式吗?且不知设计原则就像是写书法一样,楷体就是方正,竖道有垂露等 ...

  8. 设置 WPF 的全球化语言

    https://stackoverflow.com/questions/7454024/setting-culture-en-in-globally-in-wpf-app Thread.Current ...

  9. SQLMAP 速查手册

    /pentest/database/sqlmap/txt/ common-columns.txt 字段字典 common-outputs.txt common-tables.txt 表字典 keywo ...

  10. 【转】Git使用教程之BUG分支

    1.bug分支 在开发中,会经常碰到bug问题,那么有了bug就需要修复,在Git中,分支是很强大的,每个bug都可以通过一个临时分支来修复,修复完成后,合并分支,然后将临时的分支删除掉. 比如我在开 ...