给定一个带有头结点 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 之间。
解法一:
遍历节点,统计节点个数count,count/2即为从头节点到中间节点需要next的次数。
如果节点个数为奇数,假设节点1–>2–>3,则count=1,从头节点next一次到中间节点2。
如果节点个数为偶数,假设节点1–>2–>3–>4,则count=2,从头节点next两次到中间节点3。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution{
public ListNode middleNode(ListNode head) {
int count = 0;
ListNode node = head;
while (node != null) {
node = node.next;
count++;
}
node = head;
for (int i = 0; i < count / 2; i++) {
node = node.next;
}
return node;
}
}
解法二:
快慢指针,解法参考:LeetCode官方题解
这里使用两个节点进行遍历,一个一次走一步,称为慢指针;一个一次走两步,称为快指针。当快指针的节点或是快指针的下一个节点为空时跳出循环,此时慢指针的节点就是所求节点。先判断,后执行。
如果节点个数为奇数,假设节点1–>2–>3。先判断快指针的节点和下一个节点是否为空,若都不为空。快指针走两步走到了3,慢指针走一步走到了2,此时判断快指针的下一个节点为空,则不再往后走,返回慢指针节点2
如果节点个数为奇数,假设节点1–>2–>3–>4。先判断快指针的节点和下一个节点是否为空,若都不为空。快指针走两步走到了3,慢指针走一步走到了2,此时快指针的节点和下一个节点都不为空,继续走。快指针走两步走到了5(不存在),慢指针走一步走到了3,此时判断快指针当前节点为空,则不再往后走,返回节点3。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
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;
}
}