目录
1.题目
- 1.题目
- 2.思路
- 3.代码实现(Java)
给定一个头结点为 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 之间。
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/middle-of-the-linked-list
2.思路(1)双指针
- 定义快慢指针 slow 和 fast,初始时分别指向链表头结点 head;
- 在快慢指针移动的过程中,慢指针一次走一步,快指针一次走两步;
- 当 fast 走到链表末尾时,slow 就指向了链表中点。
(2)计算链表长度 先计算链表长度 length,并且让指针p指向链表头节点 head,该指针移动 length / 2 步后指向的节点即为链表的中间节点。
3.代码实现(Java)//思路1————双指针
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode middleNode(ListNode head) {
//定义快慢指针
ListNode slow = head;
ListNode fast = head;
//当快指针走到链表末尾时结束循环
while (fast != null && fast.next != null) {
//慢指针一次走一步
slow = slow.next;
//快指针一次走两步
fast = fast.next.next;
}
return slow;
}
}
//思路2————计算链表长度
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode middleNode(ListNode head) {
//计算链表长度length
int length = 0;
ListNode p = head;
while (p != null) {
p = p.next;
length++;
}
//让指针p重新指向链表头节点
p = head;
int dis = length / 2 + 1;
//指针 p 移动 dis 步后指向的节点即为链表的中间节点
while (dis != 0) {
p = p.next;
dis--;
}
return p;
}