思路
双指针,快指针先走n次,保持快慢指针直接的间距是n
然后快慢指针同时后移,快指针为null时,满指针后一个就是要删除的节点。
关键点
哨兵节点,减少特殊节点的判断
代码
Node
逻辑
package leetcode.linked;
import leetcode.ListNode;
/**
* 给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
* <p>
* 给定一个链表: 1->2->3->4->5, 和 n = 2.
* <p>
* 当删除了倒数第二个节点后,链表变为 1->2->3->5.
*/
public class N19 {
/**
* 使用哨兵节点的原因在于减少边界条件的判断,如12345 取倒数第5个
* 如果没有哨兵节点,倒数第五个就是首节点,需要额外判断
* @param head
* @param n
* @return
*/
public ListNode removeNthFromEnd(ListNode head, int n){
if (head == null) {
return head;
}
if (head.next == null && n == 1) {
return null;
}
ListNode tempHead = new ListNode(-1);
tempHead.next = head;
ListNode fast = tempHead;
ListNode slow = tempHead;
while (n > 0 && fast != null) {
fast = fast.next;
n--;
}
while (fast.next != null) {
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return tempHead.next;
}
public static void main(String[] args) {
int[] ints = new int[]{1, 2, 3, 4, 5};
// int[] ints = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// int[] ints = new int[]{1};
ListNode listNode = ListNode.makeNode(ints);
ListNode.print(listNode);
N19 n19 = new N19();
ListNode listNode1 = n19.removeNthFromEnd(listNode, 5);
ListNode.print(listNode1);
}
}
结果
1,2,3,4,5,
2,3,4,5,
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。