劍指offer——刪除連結串列中的節點
阿新 • • 發佈:2019-01-04
題目1:在O(1)內刪除連結串列節點。給定單向連結串列的頭指標和一個節點的指標,在規定時間複雜度內刪除該節點
解題思路:首先在時間複雜度O(1)就不可能從頭遍歷連結串列查詢節點。我們把下一個要刪除節點的下一個節點的值賦值給指定的節點,然後刪除下一個節點即可,再改變一下next指標的指向即可。
具體程式碼如下:
#include <iostream> using namespace std; struct ListNode { int val; ListNode* next; ListNode(int v):val(v){ } }; void DelteNode(ListNode **head,ListNode *node) { if(head==NULL || node==NULL) { return ; } if(node->next!=NULL) { ListNode *n=node->next; node->val=n->val; node->next=n->next; delete n; n=NULL; } else if(*head==node) { delete node; node=NULL; *head=NULL; } else{ ListNode *tmp=*head; while(tmp->next!=node) { tmp=tmp->next; } delete node; node=NULL; tmp->next=NULL; } return ; } int main() { int num=5,k; ListNode *head=new ListNode(0); head->next=NULL; ListNode *p=head; for(int i=0;i<num;i++) { cin>>k; ListNode *l=new ListNode(k); l->next=NULL; p->next=l; p=p->next; } for(ListNode *t=head;t!=NULL;t=t->next) { cout<<t->val<<" "; } cout<<endl; DelteNode(&head,head->next->next->next); for(ListNode *t=head;t!=NULL;t=t->next) { cout<<t->val<<" "; } return 0; }
題目2:刪除排序連結串列中重複的節點(重點)
這道題目是很經典的一道題,首先因為要刪除指標,所以必須要一個指標指向刪除節點的前一個節點,又因為首節點也有可能重複,所以要在連結串列開始處增加一個頭節點。迴圈過程:如果發現某個節點與下一個節點的值相同,則從該節點往後迴圈刪除所有值相同的節點,然後再把遍歷的指標指向第一個值不同的節點,再根據前一個指標pre是否為空判斷其next的指向。
具體程式碼如下:
class Solution { public: ListNode* deleteDuplication(ListNode* pHead)//刪除連結串列中重複的節點 { if(pHead==NULL ||pHead->next==NULL) { return pHead; } ListNode *node=pHead; ListNode *pre=NULL; while(node) { ListNode *n=node->next; if(n!=NULL && n->val==node->val) { int tmp=node->val; ListNode *k=node; while(k!=NULL && k->val==tmp) { n=k->next; delete(k); k=n; } if(pre!=NULL) pre->next=n; else pHead=n; node=n; } else{ pre=node; node=n; } } return pHead; } };