用O(1)的時間復雜度刪除單鏈表中的某個節點


給定鏈表的頭指針和一個結點指針,在O(1)時間刪除該結點。鏈表結點的定義如下:

struct ListNode
{
      int        m_nKey;
      ListNode*  m_pNext;
};

函數的聲明如下:

void DeleteNode(ListNode* pListHead, ListNode* pToBeDeleted);

這是一道廣為流傳的Google面試題,考察我們對鏈表的操作和時間復雜度的了解,咋一看這道題還想不出什么較好的解法,但人家把題出在這,肯定是有解法的。一般單鏈表刪除某個節點,需要知道刪除節點的前一個節點,則需要O(n)的遍歷時間,顯然常規思路是不行的。在仔細看題目,換一種思路,既然不能在O(1)得到刪除節點的前一個元素,但我們可以輕松得到后一個元素,這樣,我們何不把后一個元素賦值給待刪除節點,這樣也就相當於是刪除了當前元素。可見,該方法可行,但如果待刪除節點為最后一個節點,則不能按照以上思路,沒有辦法,只能按照常規方法遍歷,時間復雜度為O(n),是不是不符合題目要求呢?可能很多人在這就會懷疑自己的思考,從而放棄這種思路,最后可能放棄這道題,這就是這道面試題有意思的地方,雖看簡單,但是考察了大家的分析判斷能力,是否擁有強大的心理,充分自信。其實我們分析一下,仍然是滿足題目要求的,如果刪除節點為前面的n-1個節點,則時間復雜度為O(1),只有刪除節點為最后一個時,時間復雜度才為O(n),所以平均的時間復雜度為:(O(1) * (n-1) + O(n))/n = O(1);仍然為O(1).下面見代碼:

 1 /* Delete a node in a list with O(1)
 2  * input:    pListHead - the head of list
 3  *            pToBeDeleted - the node to be deleted
 4  */
 5 
 6 struct  ListNode  
 7 {
 8     int            m_nKey;
 9     ListNode*    m_pNext;
10 };
11 
12 void DeleteNode(ListNode *pListHead, ListNode *pToBeDeleted)
13 {
14     if (!pListHead || !pToBeDeleted)
15         return;
16     
17     if (pToBeDeleted->m_pNext != NULL) { 
18         ListNode *pNext = pToBeDeleted->m_pNext;
19         pToBeDeleted->m_pNext = pNext->m_pNext;
20         pToBeDeleted->m_nKey = pNext->m_nKey;
21 
22         delete pNext;
23         pNext = NULL;
24     }
25     else { //待刪除節點為尾節點
26         ListNode *pTemp = pListHead;
27         while(pTemp->m_pNext != pToBeDeleted) 
28             pTemp = pTemp->m_pNext;
29         pTemp->m_pNext = NULL;
30 
31         delete pToBeDeleted;
32         pToBeDeleted = NULL;
33     }
34 }

 

 


我的公眾號 「Linux雲計算網絡」(id: cloud_dev),號內有 10T 書籍和視頻資源,后台回復 「1024」 即可領取,分享的內容包括但不限於 Linux、網絡、雲計算虛擬化、容器Docker、OpenStack、Kubernetes、工具、SDN、OVS、DPDK、Go、Python、C/C++編程技術等內容,歡迎大家關注。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM