力扣题解 19th 删除链表的倒数第N个节点
19th 删除链表的倒数第N个节点
-
双重循环思路/利用数学特性
倒数第n个数的位置是正数第length - n + 1,我们只需要先数出链表长度,再利用这个特性删除即可。
需要注意的是,如果不对原链表做任何操作的情况下,这样的算法会在首链表失效,(首节点之前再无其他节点用来使用previous.next = head.next来删除它),因此需要在首部添加一个哑节点,用以删除首节点。
/** * 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) { ListNode newHead = new ListNode(0); newHead.next = head; int len = 0; for (ListNode t = head; t != null; t = t.next) { len++; } int cnt = 0; for (ListNode t = newHead; t != null; t = t.next) { if (len - cnt == n) { t.next = t.next.next; } cnt++; } return newHead.next; } }
-
单循环思路/利用双指针思路
first指针先走,走到距离second指针n+1个位置上,之后两指针一起走,这样就保证了第一个指针始终与第二个指针距离n+1个位置。在first指针到达链表尾时就意味着second.next即是待删除节点。
/** * 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) { ListNode newHead = new ListNode(0); newHead.next = head; ListNode first = newHead; ListNode second = newHead; for (int i = 1; i <= n + 1; i++) first = first.next; while (first != null) { first = first.next; second = second.next; } second.next = second.next.next; return newHead.next; } }