解法一:一次遍历+数组存储
用数组存储遍历过的点,根据索引得到第N个结点和它的前驱结点,然后进行删除操作。注意考虑边界情况。
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val = val; }* ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/class Solution {public ListNode removeNthFromEnd(ListNode head, int n) {if (head == null) {return head;}List<ListNode> list = new ArrayList<>(n);ListNode p = head;while (p != null) {list.add(p);p = p.next;}if (list.size() > n) {ListNode toDeleteNode = list.get(list.size() - n);ListNode preNode = list.get(list.size() - n - 1);preNode.next = toDeleteNode.next;toDeleteNode = null;} else {p = head;head = head.next;p = null;}return head;}}
解法二:一次遍历+快慢指针
在第一个结点前面再创建一个头指针,作为慢指针的出发点,快指针以第一个结点为出发点,先走 n 步,然后慢指针和快指针一起遍历。这样,当快指针走到终点时,慢指针位于倒数第 N 个结点的前驱。
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val = val; }* ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/class Solution {public ListNode removeNthFromEnd(ListNode head, int n) {if ((head == null) || (head.next == null)) {return null;}ListNode fast = head;ListNode slow = new ListNode(0, head);head = slow;for (int i = 0; i < n; ++i) {fast = fast.next;}while (fast != null) {fast = fast.next;slow = slow.next;}slow.next = slow.next.next;return head.next;}}
