zoukankan      html  css  js  c++  java
  • 19. Remove Nth Node From End of List[M]删除链表的倒数第N个节点

    题目

    Given a linked list, remove the n-th node from the end of list and return its head.
    Example:*
    Given linked list : 1->2->3->4->5, and n = 2.
    After removing the second node from the end, the linked list becomes 1->2->3->5.
    Note:
    Given n will always be valid.
    Follow up:
    Could you do this in one pass?


    思路

    思路一:Two Pass

    首先定义一个辅助节点auxList,使它的下一个节点指向链表head,用来简化边界判断的条件,例如一个链表只有一个节点,删除了头节点。第一次遍历(one pass),得到链表的长度L;第二次遍历(two pass)设置一个指针指向辅助节点auxList,并开始删除节点,一直到指定的n停止,此时到达第(L-n)个节点;将第(L-n)与第(L-n+2)个节点重新连接,于是就删除了第(L-n+1)个节点(因为人为增加一个节点)。

    思路二:One Pass

    题目让我们思考,如何通过一次循环来实现对链表倒数N个节点的删除。

    • 双指针法
      可以利用双指针法来解决倒数的问题:
      • 第一个指针快一点,用来控制循环的次数
      • 第二个指针慢一点,用于遍历
        两个指针都是指向链表,也就是两个指针对应两个一样的链表。要想一次遍历实现对第(L-n)个节点的删除,首先用第一个指针“跑”完n次,此时第二个指针开始“跑”,并且以第一个指针从第n个节点跑到第L-1个节点为循环次数,此时相当于第二个链表跑了(L-n)个数,这样就找到了链表中倒数第n个数。
    • 递归
      这种涉及单链表的插入与删除都可以考虑递归,因为插入和删除都要涉及到上一层节点的操作。将最后一个节点设置为第一层,逐层f返回,当返回到第n+1层开始删除。

    Tips

    单链表

    ![](https://i.loli.net/2019/05/20/5ce25ec0d432a91619.jpg)
    单链表示意图,表头为空,表头的后继节点是"1"
    **链表的搜索** 查找链表L中第一个关键字为k的元素,并返回指向该元素的指针。如果链表中没有关键字为k的对象,则返回空(NIL) ```cpp //List-Search(L,k) x = L.head; while x != NIL and x.key != k //NIL为空 x = x.next return x ``` **链表的插入**
    ![](https://i.loli.net/2019/05/20/5ce2611b14b8675624.jpg)
    图:链表的插入

    链表的删除

    ![](https://i.loli.net/2019/05/20/5ce26180b2ff342106.jpg)
    图:链表的删除
    --- #C++ * 思路一 ```cpp ListNode* removeNthFromEnd(ListNode* head, int n) { ListNode* auxList = new ListNode(0); auxList->next = head; int length = 0; ListNode* pass = head; while(pass != NULL){ length ++; pass = pass->next; }
        length -= n;
        pass = auxList;
        while(length > 0){
            length --;
             pass = pass->next;
        }
        
         pass->next = pass->next->next;
        
        return auxList->next; //这里返回next是因为auxList的next才是原来的链表
    }
    
    * 思路二(1)
    ```cpp
    ListNode* removeNthFromEnd(ListNode* head, int n) {
           ListNode* auxList = new ListNode(0);
            auxList->next = head;
            ListNode* point1 = auxList;
            ListNode* point2 = auxList;
            
            for(int i = 1; i <= n + 1;i++)
                point1 = point1->next;
            
            while(point1 != NULL){
                point1 = point1->next;
                point2 = point2->next;
            }
            
            point2->next = point2->next->next;
            
            return auxList->next;
        }
    
    • 思路二(2)
    ListNode* removeNthFromEnd(ListNode* head, int n) {
           ListNode* auxList = new ListNode(0);
            auxList->next = head;
            remove(auxList, n);
            return auxList->next;
        }
        
        int remove(ListNode* head, int n){
            if(head->next == NULL)
                return 1;
            int levels = remove(head->next, n) + 1; 
            if(levels == n+1)
                head->next = head->next->next;
            return levels;
        }
    

    Python


    参考

    [1] 算法导论第10章10.2,p131
    [2] http://www.cnblogs.com/skywang12345/p/3561803.html

  • 相关阅读:
    web常用自动化库——selenium总结(转)
    前端框架面试题
    SpringBoot整合Knife4j展示更美观的API文档
    JUC- ThreadLocal学习笔记
    JUC-ThreadPool线程池的使用与学习
    Java8 新特性
    SpringBoot 整合FreeMarker进行邮件发送
    IDEA 打开别人的项目的是Maevn插件依赖出错问题处理
    Liunx常用指令备查
    第四次作业
  • 原文地址:https://www.cnblogs.com/Jessey-Ge/p/10993501.html
Copyright © 2011-2022 走看看