0%

删除链表的倒数第N个节点

题目(LeetCode #19)

给定一个链表,删除链表的倒数第 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
}