美文网首页优美编程
Leetcode - 删除链表的倒数第N个节点

Leetcode - 删除链表的倒数第N个节点

作者: 小遁哥 | 来源:发表于2020-01-17 17:41 被阅读0次

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

    示例:

    给定一个链表: 1->2->3->4->5, 和 n = 2.

    当删除了倒数第二个节点后,链表变为 1->2->3->5.
    说明:

    给定的 n 保证是有效的。

    进阶:

    你能尝试使用一趟扫描实现吗?

    链表的结构是这样的

    1解法

    链表的结构是这样的

    let ListNode = {
      val: 1,
      next: {
        val: 2,
        next: {
          val: 3,
          next: null,
        },
      },
    };
    

    分情况处理

    var removeNthFromEnd = function(head, n) {
        
        let list = [head];
        
        let node = head;
        while(node.next){
            
            node = node.next;
            list.push(node);
        }
        if(list.length === 1){
            //只有一个
            return null;
        }
        let pos = list.length - 1  - n;
        if(pos === -1 ){
            //删除第一个
            list[0].val = list[0].next.val;
            list[0].next = list[0].next.next;
        }
        else if(n === 1){
            //删除最后一个
            list[pos].next = null;
        }
        else{
             //中间接口
             list[pos].next = list[pos].next.next;
        }
     
        return head;
        
    };
    

    找到要删除节点的上一个节点。
    通过next属性将每一个节点分离出来=>放入数组
    在分删除第一个、删除最后一个、删除中间的、只有1一个的情况 分别处理

    不转化为数组

    var removeNthFromEnd = function(head, n) {
      const dummy = {
          next: head,
      };
      let slowP = dummy;
      let fastP = dummy.next;
      while (n && fastP) {
          n--;
          fastP = fastP.next;
      }
      while (fastP) {
          slowP = slowP.next;
          fastP = fastP.next;
      }
      slowP.next = slowP.next.next;
      return dummy.next;
    };
    

    上面解法的精髓在于,既然我们想要删除一个节点就要找到上一个节点,直接在前面加一个节点,这样就不用考虑一些特殊情况

    第二点,以a=>b=>c=>d=>e为例,想要删除d这个元素,也就是倒数第2个,p向前走2步到b,此时距离p走到e还有3,此时q一起走3步 ,就找到了c,这是就可以通过c删除d了

    可以通过一次while循环搞定

    var removeNthFromEnd = function(head, n) {
      if (!head) return null;
      let tmp = { next: head };
      let p = tmp,
        q = tmp;
      let count = 0;
      while (q.next) {
        if (count < n) {
          count++;
          q = q.next;
        } else {
          p = p.next;
          q = q.next;
        }
      }
      p.next = p.next.next;
      return tmp.next;
    };
    

    2结语

    最初的解法一开始并没有考虑到全部的情况

    看来好的算法可以减少逻辑错误,尽量利用数据结构自身的特点去解决问题是优化算法的不二法则。

    相关文章

      网友评论

        本文标题:Leetcode - 删除链表的倒数第N个节点

        本文链接:https://www.haomeiwen.com/subject/avthzctx.html