【Leetcode】19.删除链表的倒数第 N 个结点(倒数第k个节点)

leetcode-19.png

删除倒数第n个节点
总结到,知道到倒数第n个节点
如何找到倒数第n个节点呢?
两种思路
【1,2,3,4,5】 2
1.暴力法
遍历两次链表,第一次记录链表的长度m,然后第二次找到 m-n+1个节点就好
比如说链表长为5,找到倒数第二个节点,那么就是顺数的第4个节点,也就是 5 - 2 + 1 = 4
2.使用两个节点来同时遍历链表,第一个节点先走n步,然后两个再同时走
还是拿上面的例子,第一个p节点先走2步,到了第三个节点
然后两个节点一起走,当p节点到尾部的时候,q节点在3节点上,q节点的下一个节点就是倒数第n个节点

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode res = new ListNode(-1);
        ListNode p = new ListNode(-1);
        ListNode q = res;
        res.next = head;
        p.next = head;
        for(int i = 0; i < n; ++i){
            p = p.next;
        }
        while(p.next != null){
            p = p.next;
            q = q.next;
        }
        q.next = q.next.next;
        return res.next;
    }
}

for循环开始就是p节点开始走n步的地方
while循环就是p、q节点一起走

一个小坑:初始化了3个节点,分别为 res、p、q,然后我都将3个节点分别初始化,然后都指向了head节点
此时出现一个坑,就是当给定的节点只有1个时,然后要删除的是倒数第1个节点
此时,返回的res.next始终指向了head节点。应该将res和q设为同一个节点即可。
因为上面是3个不同的节点,所以删除与否,res.next 始终指向head节点
必须将res和q设为同一个节点,这样当q.next = null时,res.next = null

节点指向图.JPG

增加一段js代码

/**
 * @param {ListNode} head
 * @param {number} n
 * @return {ListNode}
 */
var removeNthFromEnd = function(head, n) {
  let dummy = new ListNode(-1);
  dummy.next = head;
  let fast = dummy, slow = dummy;
  let i = 0;
  while (i <= n) {
    fast = fast.next;
    i++;
  }
  while (fast != null) {
    fast = fast.next;
    slow = slow.next;
  }
  slow.next = slow.next.next;
  return dummy.next;
};

看了下上面的记录,犯了同样的错,就是返回的节点是自己定的头节点的next,而不是直接返回head,这样会造成错误

你可能感兴趣的:(【Leetcode】19.删除链表的倒数第 N 个结点(倒数第k个节点))