[路飞]_leetcode刷题 _19. 删除链表的倒数第 N 个结点

142 阅读2分钟

「这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战

题目_删除链表的倒数第 N 个结点

给你一个链表,删除链表的倒数第 n **个结点,并且返回链表的头结点。

 

示例 1:

思路:

一看到这个题,就想到双指针解法。

  1. 定义两个指针first和second
  2. 先让first从头节点向前走n-1步
  3. 这时再让second也从头节点开始向前走,当first到达尾节点的时候,second刚好在第n个节点的前一个节点。
  4. 这时再进行节点删除操作即可

说时迟那时快,代码赶紧撸出来

第二次才通过,因为如果删的刚好是头节点,有点麻烦,我的处理是first和second指针都是fakeNode,他们都指向head,那么需要删头节点的话,只需要改变second的指针就好了。

/**
 * @param {ListNode} head
 * @param {number} n
 * @return {ListNode}
 */
var removeNthFromEnd = function(head, n) {
    if(head == null){
        return ;
    }
    let first = new ListNode(0);
    let second = new ListNode(0);
    first.next = head;
    second.next = head;
    while(first.next){
        if(n>0){
            n--
        }else{
            second = second.next;
        }
        first = first.next;
    }

    if(second.next == head){
        return head.next;
    }else{
        second.next = second.next.next;
        return head;
    }
};

官方题解

看了题解,给了三种方法

1.遍历整个链表,计算长度l,再遍历一遍,遍历到l-n的时候执行删除操作

2.使用栈,遍历完之后,再遍历栈,弹出第n个

3.双指针

很开心,我的暴力解法就是目前看来比较好的解法。

官方题解在我的解法上做了一些优化,

  • first可以不用是fakeNode。
  • return的时候可以不用做头节点的判断,提前把second存一份到变量fakeNode,return的时候就return这个fakeNode的next即可

贴出官方代码如下

/**
 * @param {ListNode} head
 * @param {number} n
 * @return {ListNode}
 */
var removeNthFromEnd = function(head, n) {
    let fakeNode = new ListNode(0)
    fakeNode.next = head;
    let first = head;
    let second = fakeNode;

    for(let i=0;i<n-1;i++){
        first = first.next;
    }

    while(first.next){
        first = first.next;
        second = second.next;
    }
    second.next = second.next.next;
    let answer = fakeNode.next;
    return answer;
};