在給定單向鏈表的頭指針和一個結點指針,定義一個函數在O(1)時間內刪除該結點。鏈表結點與函數的定義以下:函數
struct ListNode{ int val; ListNode* next; }; void deleteNode(ListNode** pListHead,ListNode* pToBeDeleted)
刪除鏈表結點的通常思路是:從頭指針開始遍歷,找到要刪除結點的前一結點pPrev,而後pPrev->next=pToBeDeleted->next,(還需考慮刪除結點是否爲頭結點),這樣的時間複雜度爲O(n)。指針
而題目要求爲O(1),找到刪除結點的前一結點複雜度爲O(n),但找到後一結點的複雜度爲O(1),若是咱們把後一結點的東西拷貝到要刪除結點上,再把後一結點刪除,豈不就是至關於把當前須要刪除的結點刪除了?blog
ListNode* pNext=pToBeDeleted->next;
pToBeDeleted->val=pNext->val;
pToBeDeleted->next=pNext->next;
delete pNext;
pNext=NULL;內存
考慮特殊狀況,若是要刪除的結點爲頭結點和尾結點怎麼辦?class
頭結點:要刪除的結點爲頭結點,刪除以後,鏈表爲空,此時須要將頭結點置爲NULL,這時候改變的頭指針的內存地址,所以須要傳遞二級指針,*pHead=NULL;List
尾結點:要刪除的結點爲尾結點,尾結點沒有後一結點,所以,不能經過上述方法來解決,還要回到傳統的遍歷方法,找到它的前一結點,而後將它的下一結點置爲NULL,同時刪除尾指針。遍歷
struct ListNode{ int val; ListNode* next; }; void deleteNode(ListNode** pListHead,ListNode* pToBeDeleted){ if(pListHead==NULL || pToBeDeleted==NULL) return; if(pToBeDeleted->next!=NULL){ ListNode* pNext=pToBeDeleted->next; pToBeDeleted->val=pNext->val; pToBeDeleted->next=pNext->next; delete pNext; pNext=NULL; } else if(*pListHead==pToBeDeleted){ delete pToBeDeleted; pToBeDeleted=NULL; *pListHead=NULL; } else{ ListNode* pNode=*pListHead; while(pNode->next!=pToBeDeleted) pNode=pNode->next; pNode->next=NULL; delete pToBeDeleted; pToBeDeleted=NULL; } }