Given a non-empty, singly linked list with the head node head
, return a middle node of the 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
and100
.
Solution 1
The immediate approach that came to my mind was as follows –
- Find the size of the linked list – One Traversal – O(n) [if n is the length of linkedlist]
- the middle will be (size of linkedlist/2)
- traverse until the (size of linkedlist/2) node and return it as the answer.
This solution’s time complexity is O(n), but we are traversing through the linked list twice. And the space complexity os O(1).
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class MiddleNode1 {
public ListNode middleNode(ListNode head) {
// Initialize size of linkedlist, middle variable and current node
int size = 0, middle = 0;
ListNode current = head;
// Traverse through linked list to find the size;
while(current != null){
current = current.next;
size++;
}
// Calculate middle
middle = size/2;
// Traverse linkedlist until i becomes middle
int i = 0;
current = head;
while(i != middle){
current = current.next;
i++;
}
// return the middle node
return current;
}
}
Solution 2
The next approach is little optimization over solution 1. We store the values of a node in a linked list and return the element to the middle index. This requires just one traversal. The time complexity for this solution is O(n), and space complexity is also O(n).
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class MiddleNode2 {
public ListNode middleNode(ListNode head) {
//Initialize the arraylist to store nodes
ArrayList<ListNode> list = new ArrayList<>();
ListNode current = head;
// Traverse the linkedlist and add node to the list
while(current != null){
list.add(current);
current = current.next;
}
// Find the middle index
int middle = list.size()/2;
// return the listnode at the middle index.
return list.get(middle);
}
}
Solution 3
Using the fast and slow pointer method to find the middle element of a LinkedList. The idea is slow pointer moves one node at a time and the fast pointer moves two nodes at a time. The node where fast becomes null is the middle node. The time complexity for this solution is O(n) and space complexity is O(1).
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class MiddleNode3 {
public ListNode middleNode(ListNode head) {
//Initialize the fast and slow pointers
ListNode fast = head, slow = head;
// Traverse the linkedlist and update fast and slow pointers
while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
}
// return the slow pointer.
return slow;
}
}
Code – MiddleNode1.java, MiddleNode2.java, MiddleNode3.java
Source – leetcode