You are given the head of a singly linked list, return the middle node of the linked list.
If there are two middle nodes, return the second middle node.
Example 1:
Input: head = [1,2,3,4,5]
Output: [3,4,5]Example 2:
Input: head = [1,2,3,4,5,6]
Output: [4,5,6]Constraints:
1 <= The length of the list <= 1001 <= Node.val <= 100Before attempting this problem, you should be comfortable with:
Linked lists do not support random access, so finding the middle node directly is not straightforward. By storing all nodes in an array, we gain index-based access. Once we have the array, the middle node is simply at index length / 2.
length / 2.# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def middleNode(self, head: Optional[ListNode]) -> Optional[ListNode]:
cur = head
arr = []
while cur:
arr.append(cur)
cur = cur.next
return arr[len(arr) // 2]We can avoid storing all nodes by first counting the total number of nodes, then making a second pass to reach the middle. This uses constant extra space since we only store the count and a pointer.
n.n / 2.n / 2 steps from the head.# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def middleNode(self, head: Optional[ListNode]) -> Optional[ListNode]:
n, cur = 0, head
while cur:
cur = cur.next
n += 1
n //= 2
cur = head
while n:
n -= 1
cur = cur.next
return curThe fast and slow pointer technique finds the middle in a single pass. The slow pointer moves one step at a time, while the fast pointer moves two steps. When the fast pointer reaches the end, the slow pointer will be at the middle. This works because the fast pointer covers twice the distance in the same number of iterations.
slow and fast pointers at the head.fast is not null and fast.next is not null:slow one step forward.fast two steps forward.slow, which now points to the middle node.# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def middleNode(self, head: Optional[ListNode]) -> Optional[ListNode]:
slow, fast = head, head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
return slowWhen using the fast and slow pointer technique, the loop condition must check both fast and fast.next before advancing. Checking only fast can cause a null pointer exception when trying to access fast.next.next. The correct condition is while (fast != null && fast.next != null).
For lists with an even number of nodes, there are two middle nodes. The problem typically asks for the second middle node, but some implementations accidentally return the first. Ensure your pointer movement logic returns the correct middle based on the problem requirements.