劍指offer——刪除鏈表的某一個節點

                                                                     刪除鏈表的某一個節點

題目:給定單鏈表的頭指針和一個節點指針,定義一個函數在O(1)時間內刪除該節點。鏈表的定義如下:

struct ListNode
{
	int val;
	ListNode next;
}

void DeleteNode(ListNode * Head,ListNode * ptr);

看完這個題目,大家就感覺很開心,覺得這個題目非常的簡單。我們只需要找到這個結點的前一個結點,然後刪除這個結點。

如下:

這時候我們就感覺自己已經完成了任務,但是我們可以來看看這個程序,我們需要找到要刪除結點的前一個結點,則需要遍歷一遍這個鏈表,我們需要的時間複雜度即爲O(n)

我們怎樣纔可以將我們的時間複雜度變爲O(1)呢,我們可以做如下的假設:

  1. 若刪除的爲頭結點;
  2. 若刪除的爲尾結點;
  3. 若刪除的是中間結點。

 

接下來,我們就一種一種的分析:

TO1

如果是頭結點,我們直接刪除頭結點,這個比較簡單,時間複雜度爲O(1);

TO2

如果是尾結點,這時候我們就需要遍歷整個鏈表去找到尾結點的前一個結點,然後去刪除尾結點,時間複雜度即爲O(n);

TO3

我們直接將這個結點的下一個結點的 val 和naxt 賦值到要這個結點,然後刪除下一個接結點,時間複雜度爲O(1)

代碼如下:

void DeleteNode(ListNode * Head,ListNode * ptr);
{
	if(Head&&ptr)
		return ;
	if(ptr->next!=NULL)
	{
		ListNode *q=ptr->next;
		ptr->val=q->val;
		ptr->next=q->next;
		delete q;
		q=NULL;
	} 
	else if(Head==ptr)
	{
		delete Head;
		Head=NULL;
		ptr=NULL;
	}
	else
	{
		ListNode *q=Head;
		while(q->next!=ptr)
		{
			q=q->next;
		}
		q->next=ptr->next;
		delete ptr;
		ptr=NULL;
	}
} 

雖然刪除尾結點的時候,他的時間複雜度是O(n)。但是平均複雜度是((n-1)*O(1)+O(n))/O(n)=O(1);

 

 

 

                                          

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章