一、题目:删除链表的倒数第 N 个结点
二、题目解析:
题目解析:该题难点在于单向链表没有办法从尾部向前遍历。
- 第一种解法:
假设链表长度是5,删除倒数第2个,则相当于删除 5-2+1 第4个结点,4次.next即可删除,但是因为我们不知道链表的长度所以不可行,需要先遍历一遍链表,对结点个数进行+1记录,到了链表尾部,即可统计出链表的长度。这种做法还需要一次遍历才能删除指定结点。- 进阶:
利用双指针的思想
看图理解双指针的过程:
三、代码如下:
public ListNode removeNthFromEnd(ListNode head, int n) {
//特殊情况下,链表只有一个结点,删除倒数第一个结点
//需要定义一个哑结点,作为指向真正的第一个结点,便于链表操作。
//创建dummy结点
ListNode dummy = new ListNode(0);
//将dummy结点放到链表头部
dummy.next = head;
//定义p1,p2指针,指向dummy结点
ListNode p1 = dummy;
ListNode p2 = dummy;
//让p2指针先走 (这里如果是<n,下面的循环就要判断p2.next!=null,这里<=n走了n+1步)
for (int i = 0; i <= n; i++) {
p2 = p2.next;
}
//然后循环让p2和p1一起走,当p2走到结尾,p1刚好走到要删除的前一个结点
while (p2 != null) {
p1 = p1.next;
p2 = p2.next;
}
//p1结点是要删除的前一个结点,根据链表特性删除即可
p1.next = p1.next.next;
return dummy.next;
}
四、测试
五、结束