题目描述:
个人题解:
由于需要找到倒数第 n 个节点,因此可以使用两个指针 first 和 second 同时对链表进行遍历,并且 first 比 second 超前 n 个节点。当 first 遍历到链表的末尾时,second 就恰好处于倒数第 n 个节点。
开始时 first 和 second 均指向头节点。然后首先使用 first 对链表进行遍历,遍历的次数为 n。此时,first 和 second 之间间隔了 n−1 个节点,即 first 比 second 超前了 n 个节点。
然后同时使用 first 和 second 对链表进行遍历。当 first 遍历到链表的末尾(即 first 为空指针)时,second 恰好指向倒数第 n 个节点。
如上方法如果能够得到的是倒数第 n 个节点的前驱节点而不是倒数第 n 个节点的话,删除操作会更加方便。因此可以考虑在初始时将 second 指向哑节点,其余的操作步骤不变。这样一来,当 first 遍历到链表的末尾时,second 的下一个节点就是需要删除的节点。
代码实现:
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {struct ListNode* dummy = malloc(sizeof(struct ListNode));dummy->val = 0, dummy->next = head;struct ListNode* first = head;struct ListNode* second = dummy;for (int i = 0; i < n; ++i) {first = first->next;}while (first) {first = first->next;second = second->next;}second->next = second->next->next;struct ListNode* ans = dummy->next;free(dummy);return ans;
}
复杂度分析:
时间复杂度:O(L),其中 L 是链表的长度。
空间复杂度:O(1)。