✅ 4 simple solutions explained: Recursion, two pointers 100%, stack, two runs
In the time complexity, I will refer to the length of the list as m and n and the index from the end.\nNote: all of the solutions are run in less than  or equal
In the time complexity, I will refer to the length of the list as `m` and n and the index from the end.\nNote: all of the solutions are run in less than  or equal to O(2 * n) but with closer look some are faster than others\n\nSolution 1:\nThis solution runs in O(m + (m - n)) time with two runs once to count length second to get to the n -1 node from the end.\nSpace O(1).\n```\nListNode *removeNthFromEnd(ListNode *head, int &n) // exection with two runs\n    {\n        int length = 0;\n        ListNode *p = head;\n\n        while (p) // find length\n        {\n            length++;\n            p = p->next;\n        }\n\n        if (n == length) // check if need to remove the first node\n            return head->next;\n\n        length -= n;\n        length--;\n\n        p = head;\n        while (length--) // get p the node before the n-th from the end\n            p = p->next;\n        p->next = p->next->next; // the move the node\n\n        return head;\n    }\n```\n\nSolution 2:\nThis solution runs in O(m + n) time using a stack.\nspace O(m).\n```\nListNode *removeNthFromEnd(ListNode *head, int &n) // excution using stack\n{\n\tstack<ListNode *> s;\n\tint length = 0;\n\n\tListNode *t = head;\n\twhile (t) // push all nodes\n\t{\n\t\ts.push(t);\n\t\tt = t->next;\n\t\tlength++;\n\t}\n\n\tif (length == n) // if need to remove the first node\n\t\treturn head->next;\n\n\twhile (n--) // get the n-1 node from the end\n\t\ts.pop();\n\tt = s.top();\n\tt->next = t->next->next; // remove the node\n\n\treturn head;\n}\n```\n\nSolution 3:\nThis solution runs in O(m) time using backtracking and rebuilding the list.\nSpace O(m)\n```\nListNode *removeNthFromEnd(ListNode *head, int &n)\n{\n\tif(head == NULL) // if end\n\t\treturn NULL;\n\n\thead->next = removeNthFromEnd(head->next,n);// set to the next node\n\n\tif(--n == 0) // do I need to remove this node\n\t\treturn head->next;\n\treturn head;\n}\n```\n\n\n\nSolution 4:\nThis solution runs in O(m) time with two pointers with space between them thus when the one before the end the other can remove the node.\nspace O(1).\n```\nListNode *removeNthFromEnd(ListNode *head, int &n) // execution with two pointers\n{\n\tListNode *t1 = head;\n\n\twhile (t1 && n--) // get t1 to the  n+1 node thus the difference between t1 and t2 is n at all times\n\t\tt1 = t1->next;\n\n\tif (t1 == NULL) // if need to remove teh first Node\n\t\treturn head->next;\n\n\tListNode *t2 = head;\n\twhile (t1->next) // find the node before n-th from the end\n\t{\n\t\tt1 = t1->next;\n\t\tt2 = t2->next;\n\t}\n\tt2->next = t2->next->next;\n\n\treturn head;\n}\n```\nIf it helps vote up so it will reach others!
['Two Pointers', 'Stack', 'Recursion', 'C', 'C++']