给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:
给定的 n 保证是有效的。
进阶:
你能尝试使用一趟扫描实现吗?
题解
递归法
利用递归的特性,从递归栈底向上累加即为倒数索引。
removeNode
最终返回的值为输入链表的长度,若该返回值与 n
相等,则说明去掉的是第一个节点,此时头节点为 head.next
。
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class ListNode { int val; ListNode next; ListNode(int x) { val = x; } }
public class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { return removeNode(head, n) == n ? head.next : head; }
public int removeNode(ListNode node, int n) { if (node.next == null) return 1; int m = removeNode(node.next, n); if (m == n) node.next = node.next.next;
return m + 1; } }
|
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class ListNode: def __init__(self, x): self.val = x self.next = None
class Solution: def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode: return head.next if self.remove_node(head, n) == n else head
def remove_node(self, head: ListNode, n: int) -> int: if not head.next: return 1 m = self.remove_node(head.next, n) if m == n: head.next = head.next.next
return m + 1
|
Go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| package main
type ListNode struct { Val int Next *ListNode }
func removeNthFromEnd(head *ListNode, n int) *ListNode { if removeNode(head, n) == n { return head.Next } else { return head } }
func removeNode(head *ListNode, n int) int { if head.Next == nil { return 1 }
m := removeNode(head.Next, n) if m == n { head.Next = head.Next.Next }
return m + 1 }
|
双指针法
使用快慢指针来查找索引,快指针先移动 n
个位置,再同时移动两指针,当快指针指向链表的尾节点时,慢指针所指即为倒数第 n
个节点。
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { if (head == null || head.next == null) return null;
ListNode fast = head, slow = head; for (int i = 0; i < n; i++) fast = fast.next;
if (fast == null) return head.next;
while (fast.next != null) { fast = fast.next; slow = slow.next; }
slow.next = slow.next.next; return head; } }
|
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class Solution: def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode: fast, slow = head, head for i in range(n): fast = fast.next
if not fast: return head.next
while fast.next: fast = fast.next slow = slow.next
slow.next = slow.next.next
return head
|
Go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| func removeNthFromEnd(head *ListNode, n int) *ListNode { fast, slow := head, head
for i := 0; i < n; i++ { fast = fast.Next }
if fast == nil { return head.Next }
for fast.Next != nil { fast = fast.Next slow = slow.Next } slow.Next = slow.Next.Next
return head }
|