zoukankan      html  css  js  c++  java
  • 一天一道算法题---6.12---链表结点的删除

    感谢微信平台---一天一道算法题---每天多一点进步--

    problem:

      给定链表的头指针和一个节点指针 在O(1)时间删除该结点。链表结点的定义如下:

      

    1 struct listNode
    2 {
    3     int m_nkey;
    4     ListNode* m_pNext;
    5 };
    6 
    7 void DeleteNode( ListNode* pListHead , ListNode* pToBeDeleted );

    这题 来头很大   是goodle面试题...

    对于 链表 我只写过几次....  太渣了。。 这边 微信给出的分析 很到位 很好 我将它贴上来

    在链表中删除一个结点:--最常规做法

    从链表的头结点开始 顺序查找要删除的结点 找到之后再删除 由于是需要顺序查找 时间复杂度O(n)

    接下里是重点:  

    我们之所以需要从头结点开始查找要删除的结点 是因为我们需要得到要删除的结点的前面一个结点。

    我们试着换一种思路

    我们可以从给定的结点得到它的下一个结点 这个时候我们实际删除的是它的下一个结点 由于我们已经得到实际删除的结点的前面一个结点 因此完全是可以实现的

    当然 在删除之前 我们需要把给定结点的下一个结点的数据拷贝到给定的结点之中 此时 时间复杂度O(1)

    假设 链表有n个结点 这个算法在N-1下为O(1) 只有当给定的结点处于链表末端时为O(n)

    那么 平均o(X)为[ (n-1) * O(1)+O(n)]/n 仍然为O(1)

    代码 稍后贴出.... think 

    主要   我要去洗澡了.......

    晓爷说 讲了一大串 不知所云.... 那我来 讲下我个人的理解....  错误 望 留言 提出 thanks

    这里 和我们一般删除结点有个很不一样的地方 通常我们是根据要删除结点的数据 来删除这个结点..

    就是满足 value == node->data 然后才删掉这个node

    然后 我们删除一般是采用 “ 先连后断” 原则--- 假如  node = ptr->next  那么 我们就让 ptr->next = node->next 然后delete node(如果是 C 就 free(node) )

    这样的话 是O(n) 因为我们需要从head开始 遍历整个链表 直到找到 满足数据相等的条件为止..

    这里呢 很特殊 它直接告诉了我们要删除的结点指针 注意 这里是 单链表.

    这个方法真的 很 巧妙..

    既然我们知道了要删除的结点指针 那么我们肯定就知道了它的下一个结点 通过node->next

    我们可以选择 让下一个结点的 指针域 和 数据域 来覆盖node结点的数据域和指针域  然后 delete node->next 因为它的东西 已经全 copy给了 node 这相当于做到了给 node的删除操作

    这边 有一个例外 假如node是尾结点..此时node->next == NULL

    so 遍历整个链表.....

    end....

    贴下 微信给出的代码及注释

     1 // delete a node in a list
     2 //Input:  pListHead - the head of list
     3 //          pToBeDeleted - the node of to be deleted
     4 
     5 
     6 void DeleteNode( ListNode* pListNode , ListNode* pToBeDeleted )
     7 {
     8     if( !pListHead || !pToBeDeleted )
     9         return;
    10     // if pToBeDeleted is not the last node in the list
    11     if( pToBeDeleted->m_pNext!=NULL )
    12     {
    13         // copy data from the node to pToBeDeleted
    14         ListNode* pNext = pToBeDeleted->m_pNext;
    15         pToBeDeleted->m_nKey = pNext->m_nKey;
    16         pToBeDeleted->m_pNext = pNext->m_pNext;
    17         // delete the node next to the pToBeDeleted
    18         delete pNext;
    19         pNext = NULL;
    20     }    
    21     // if pToBeDeleted is the last node in the list
    22     else
    23     {
    24         // get the node prior to pToBeDeleted
    25         ListNode* pNode = pListNode;
    26         while( pNode->m_pNext != pToBeDeleted )
    27         {
    28             pNode = pNode->m_pNext;
    29         }
    30         // delete pToBeDeleted;
    31         pNode->m_pNext = NULL;
    32         delete pToBeDeleted;
    33         pToBeDeleted = NULL;
    34     }
    35 }
    View Code

    凌晨4点 4年

    4年变了好多啊.......

    又是4年....

    下一个4年 毕业了..

    just follow your heart
  • 相关阅读:
    bzoj4758: [Usaco2017 Jan]Subsequence Reversal(区间dp)
    bzoj4580: [Usaco2016 Open]248(区间dp)
    1617: [Usaco2008 Mar]River Crossing渡河问题(dp)
    bzoj21012101: [Usaco2010 Dec]Treasure Chest 藏宝箱(滚动数组优化dp)
    P2339 提交作业usaco(区间dp)
    day11
    bzoj2330: [SCOI2011]糖果(差分约束)
    P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm(Tarjan+记忆化)
    P2700逐个击破(并查集/树形dp)
    bzoj1770: [Usaco2009 Nov]lights 燈(折半搜索)
  • 原文地址:https://www.cnblogs.com/radical/p/3783472.html
Copyright © 2011-2022 走看看