[各种面试题] 链表相关

1.判断是否有环

bool existCircle(ListNode* head)
{
	if(!head)
		return false;
	ListNode* pSlow=head;
	ListNode* pFast=head->next;
	while(pFast!=NULL)
	{
		if ( pSlow==pFast )
			return true;
		pSlow=pSlow->next;
		pFast=pFast->next;
		if (pFast)
			pFast=pFast->next;
	}
	return false;
}


2.找环的起始位置

这个在纸上画个环就能看出相遇的地方到起始位置与表头到起始位置的距离是相等的。所以相遇后把一个放到头去再相遇就好了。

ListNode* findCircleStart(ListNode* head)
{
	if(!head)
		return NULL;
	ListNode* pSlow=head;
	ListNode* pFast=head->next;
	while(pFast!=NULL)
	{
		if ( pSlow==pFast )
		{
			pSlow=head;
			while(pSlow!=pFast)
			{
				pSlow=pSlow->next;
				pFast=pFast->next;
			}
			return pSlow;
		}
		pSlow=pSlow->next;
		pFast=pFast->next;
		if (pFast)
			pFast=pFast->next;
	}
	return NULL;
}

 

3.反转链表

ListNode* reverseList(ListNode* head)
{
	if (!head || !head->next )
		return head;
	ListNode* Guard=new ListNode(-1,NULL);
	ListNode* pCur=head;
	while(pCur)
	{
		ListNode* pTemp=pCur->next;
		pCur->next=Guard->next;
		Guard->next=pCur;
		pCur=pTemp;
	}
	ListNode* newHead=Guard->next;
	delete Guard;
	Gurad=0;
	return newHead;
}


4.删除中间节点

同样用快慢指针即可。

void removeMiddle(ListNode*& head)
{
	if (!head )
		return ;

	ListNode* pPre=NULL;
	ListNode* pSlow=head;
	ListNode* pFast=head->next;

	while( pFast )
	{
		pPre=pSlow;
		pSlow=pSlow->next;
		pFast=pFast->Next;
		if (pFast)
			pFast=pFast->next;
	}
	if ( pPre==NULL )  //head is middle
	{
		head=pSlow->next;
	}
	else
	{
		pPre->next=pSlow->next;
	}
	delete pSlow;
	pSlow=0;
}

 

5.倒数第K个节点

ListNode* findKthFromBack(ListNode* head,int k)
{
	assert(k>0);  //last one is the 1st node
	ListNode* pForward=head;
	while(pForward&&k)
	{
		pForward=pForward->next;
		k--;
	}
	if ( k>0 )
		return NULL;

	ListNode* pBack=head;
	while(pForward)
	{
		pForward=pForward->next;
		pBack=pBack->next;
	}
	return pBack;
}



 

你可能感兴趣的:([各种面试题] 链表相关)