public ListNode removeNthFromEnd(ListNode head, int n) {

    ListNode root = new ListNode(0);
    root.next = head;
    ListNode faster = root;
    
    // move faster pointer n nodes ahead
    for (int i = 0 ; i < n; i++) {
      faster = faster.next;
    }
    
    // if n equals the length of the list
    if(faster.next == null) {
      return head.next;
    }
    
    ListNode slower = root;
    // if n is greater than the length of the list
    // move both pointer until faster reaches the end
    while(faster.next != null) {
      faster = faster.next;
      slower = slower.next;
    }
    
    // delete Nth node
    slower.next = slower.next.next;
    
    return head;
  }