Middle of the LinkedList

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 and 100.

Solution 1

The immediate approach that came to my mind was as follows –

  1. Find the size of the linked list – One Traversal – O(n) [if n is the length of linkedlist]
  2. the middle will be (size of linkedlist/2)
  3. 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

,