方法一:暴力集合
- 耗费空间,不是本题的本意
package com.company.linked;
import java.util.ArrayList;
import java.util.List;
public class Solution4_1 {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode p = head;
List<ListNode> nodeList = new ArrayList<>();
while (p != null) {
nodeList.add(p);
p = p.next;
}
for (int i = nodeList.size() - 1; i >= 0; i--) {
if (n + i == nodeList.size()) {
if (i == 0) {
head = head.next;
return head;
}
ListNode pre = nodeList.get(i - 1);
ListNode cur = nodeList.get(i);
pre.next = cur.next;
return head;
}
}
return head;
}
}
方法二:用队列,或栈
- 核心思想是只存储优先个的元素,相比方法一空间有节约
- 算是一个改良版本
- 不是题目的本意
package com.company.linked;
import java.util.ArrayDeque;
import java.util.Deque;
public class Solution4_2 {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode p = head;
Deque<ListNode> nodeDeque = new ArrayDeque<>();
while (p != null) {
nodeDeque.offerLast(p);
p = p.next;
if (nodeDeque.size() > n + 1) {
nodeDeque.removeFirst();
}
}
if (nodeDeque.size() == 1 && nodeDeque.poll() == head) {
return null;
}
if (nodeDeque.size() == n && nodeDeque.poll() == head) {
head = head.next;
return head;
}
ListNode pre = nodeDeque.getFirst();
ListNode cur = pre.next;
if (cur != null) {
pre.next = cur.next;
}
return head;
}
}
方法三:先计算对队列的长度
- 最多需要遍历两趟
- 也不是题目的本意
package com.company.linked;
public class Solution4_3 {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode p = head;
int count = 0;
while (p != null) {
count++;
p = p.next;
}
if (count == n) {
head = head.next;
return head;
}
p = head;
for (int i = 1; i <= count; i++) {
if (i + n == count) {
ListNode cur = p.next;
if (cur != null) {
p.next = cur.next;
return head;
}
}
p = p.next;
}
return head;
}
}
方法四:双指针
- 快慢指针移动
- 快慢指针的速度差就是 倒数第K个的K
- 快慢指针类似栈和队列的思路,只是用指针模拟了滑动窗口,节省空间
- 本题考点就是此
package com.company.linked;
public class Solution4_4 {
public ListNode removeNthFromEnd(ListNode head, int n) {
//哨兵指针:值为0,next执行head
ListNode dummy = new ListNode(0, head);
ListNode first = head;
ListNode second = dummy;
//快慢指针拉开距离 n
for (int i = 0; i < n; ++i) {
first = first.next;
}
while (first != null) {
first = first.next;
second = second.next;
}
second.next = second.next.next;
ListNode ans = dummy.next;
return ans;
}
}