给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:
给定的 n 保证是有效的。
进阶:
你能尝试使用一趟扫描实现吗?
这道题的是要倒数删除第n个结点并返回删除后的链表,有就是返回该链表的头指针。
- 我们用正常的思路考虑的话,删除倒数第几个结点,就得找到正向顺序的该结点,
- 那么要找到正向的该结点,就必须知道该链表的长度,所以就需要遍历一遍该链表。
- 知道链表的长度后,我们又得遍历一遍该表找到要删除的结点,所以至少得遍历两边该表,这样的话,程序的时间复杂度就会大大增加。
- 那么如何做到题目的要求尝试一趟扫描呢?
题目要的是删除倒数第n个结点,我们首先要做的是找到这个结点的前驱,我们可以这样想,倒数第n个结点离表尾的距离是多少呢?我们从这个距离差可以出发。定义两个快慢指针,让他两之差等于删除的这个结点到表尾的距离之差。
我们让fast指针先从头走n步,也就是距离之差步,然后让slow指针再从头开始走,此时两者之差就是删除的结点到表尾的距离,然后让两者同时出发,当fast走到表尾的时候,slow刚好走到要删除的结点的前驱,这样就找到了我们要删除的结点。
****这里我们得考虑这样一种情况,如果表长为5,我们要删除倒数第5个结点,其实就是删除正向的第一个结点,直接返回head.next就ok!!!具体代码如下:
`
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
if(head==null||head.next==null){
return null;
}
ListNode fast=head;
ListNode 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;
}
}