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

leetCode-19(删除链表的倒数第N个结点)

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

示例 1:

img

1
2
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]

示例 2:

1
2
输入:head = [1], n = 1
输出:[]

示例 3:

1
2
输入:head = [1,2], n = 1
输出:[1]

解法一,自己瞎写

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
28
29
30
31
32
33
34
35
36
37
38
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode node = head;
int count = 0;
//计算链表中所有节点的数量
while (node!=null){
node = node.next;
count++;
}
//特殊情况的判断
if (count==0) return head;
if (count==1) return null;
node = head;
//如果删除的节点是倒数第count个节点,则直接删除第一个即可
if (count-n==0) {
head = head.next;
return head;
}
//定位到倒数第几个节点的前一个节点
for (int i = 1;i<count-n;i++){
node = node.next;
}
//删除节点操作
node.next = node.next.next;
node = head;
return node;
}
}

解法二:栈

代码为:

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
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(0, head);//定义辅助节点,防止删除头结点
Stack<ListNode> stack = new Stack<>();
ListNode node = dummy;
while (node!=null){
stack.push(node);
node = node.next;
}
for (int i = 1;i<=n;i++){
stack.pop();
}
ListNode pre = stack.peek();
pre.next = pre.next.next;
return dummy.next;
}
}

不用辅助节点:

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
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
Stack<ListNode> stack = new Stack<>();
ListNode node = head;
while (node!=null){
stack.push(node);
node = node.next;
}
for (int i = 1;i<=n;i++){
stack.pop();
}
if (stack.size()==0) return head.next;//判断一下是否删除的是头结点
node = stack.pop();
node.next = node.next.next;
return head;
}
}

解法三:双指针

  • 定义两个指针,一个first,一个second。
  • first指针先走n步
  • 再将first和second两个指针,同时后移,直到first为null。
  • 则second指向的是倒是n+1个节点。

代码为:

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
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(0,head);
ListNode first = head;
ListNode second = dummy;
for (int i = 1;i<=n;i++){
first = first.next;
}
while (first!=null){
first = first.next;
second = second.next;
}
second.next = second.next.next;
ListNode node = dummy.next;
return node;
}
}

不用辅助节点时:

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
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode first = head;
ListNode second = head;
for (int i = 1;i<=n;i++){
first = first.next;//使得first与second之间间隔n-1个节点
}
//判断是否删除的是头结点
if (first==null) return head.next;
while (first.next!=null){//将index2移至最后一个节点
first = first.next;
second = second.next;
}
second.next = second.next.next;
return head;
}
}

删除链表的倒数第N个结点
http://example.com/2022/08/16/删除链表的倒数第N个结点/
作者
zlw
发布于
2022年8月16日
许可协议