(劍指Offer)面試題13:在O(1)時間內刪除鏈表結點

題目:

在給定單向鏈表的頭指針和一個結點指針,定義一個函數在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;
    }
}
相關文章
相關標籤/搜索