package 链表;
import java.util.ArrayList
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
/**
* 官网上的: ListNode dummy = new ListNode(0, head);头结点:避免了前一个节点为空的的判断
* @author Huangyujun
*
*/
//进阶:你能尝试使用一趟扫描实现吗?~~之所以需要先求长度,就是倒数的话,不知道n这个结点位置~~~让其有索引,不就可以随意找到他吗
// 放进去vector里
public class _19_删除链表的倒数第N个结点 {
//方法一:通过求总长len - N + 1 得到需要删除链表的前一个结点
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(0, head);
int length = getLength(head);
ListNode cur = dummy;
for (int i = 1; i < length - n + 1; ++i) {
cur = cur.next;
}
cur.next = cur.next.next;
ListNode ans = dummy.next;
return ans;
}
public int getLength(ListNode head) {
int length = 0;
while (head != null) {
++length;
head = head.next;
}
return length;
}
}
// 方法二:通过栈(后进先出(pop掉 后面 第N个,从而可以拿到待删除结点的前一个结点))~ 倒序思维~ 联想到数据结构栈
class Solution2 {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(0, head);
Deque<ListNode> stack = new LinkedList<ListNode>();
ListNode cur = dummy;
while (cur != null) {
stack.push(cur);
cur = cur.next;
}
for (int i = 0; i < n; ++i) {
stack.pop();
}
ListNode prev = stack.peek();
prev.next = prev.next.next;
ListNode ans = dummy.next;
return ans;
}
}
// 方法三: 通过 设置两个距离是n 的指针(不断的往后走,走到最后,差距便是倒数
//本质上是将倒数 转化成(两个点之间)具体的距离,而这距离是需要通过遍历到达的
class Solution3 {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(0, head);
ListNode first = head;
ListNode second = dummy;
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;
}
}
}