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

  • 相关阅读:
    Windows Azure Storage (17) Azure Storage读取访问地域冗余(Read Access – Geo Redundant Storage, RA-GRS)
    SQL Azure (15) SQL Azure 新的规格
    Azure China (5) 管理Azure China Powershell
    Azure China (4) 管理Azure China Storage Account
    Azure China (3) 使用Visual Studio 2013证书发布Cloud Service至Azure China
    Azure China (2) Azure China管理界面初探
    Azure China (1) Azure公有云落地中国
    SQL Azure (14) 将云端SQL Azure中的数据库备份到本地SQL Server
    [New Portal]Windows Azure Virtual Machine (23) 使用Storage Space,提高Virtual Machine磁盘的IOPS
    Android数据库升级、降级、创建(onCreate() onUpgrade() onDowngrade())的注意点
  • 原文地址:https://www.cnblogs.com/Jessey-Ge/p/10993501.html
Copyright © 2011-2022 走看看