剑指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);

 

 

 

                                          

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