Under my umbrella.

SKII

Less is more.

力扣题解 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;
        }
    }
    
posted @ 2020-07-09 09:13  NLYang  阅读(113)  评论(0编辑  收藏  举报