寻找链表中倒数第k个结点

Posted ssopp24

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了寻找链表中倒数第k个结点相关的知识,希望对你有一定的参考价值。

//1.相当于遍历链表两次,第一次结点指针全部入栈,第二次找到倒数第k个结点
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) 

	//注意防御性编程: 
	//1.如果k大于链表的个数.
	//2.如果k为0
	//3.如果链表为空
	if ( NULL == pListHead || 0 == k )
		return NULL;

	stack<ListNode*> s;

	while ( NULL != pListHead )
		s.push( pListHead );
		pListHead = pListHead->next;
	

	if ( s.size( ) < k )
		return NULL;
        
	for ( size_t i = 1; i < k; ++i )
            s.pop( );

	return s.top( );



//2.只需遍历链表一次的解法:
//大致思路: 两个指针都指向头节点,第一个指针先在链表上走k-1步,此时第二个指针和第一个指针同时向后走,当第一个指针走到结尾时,第二个指针的指向就是倒数第k个结点。
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k)

	if ( NULL == pListHead || 0 == k )
		return NULL;

	size_t count = 0;
	ListNode* pNode1 = pListHead;
	ListNode* pNode2 = pListHead;

	//根据我们思路以及前面判断过的k不等于0. 所以k-1至少为0.
	for ( size_t i = 0; i < k-1; ++i, ++count )
		if ( NULL == pNode1 )
			return NULL;

		pNode1 = pNode1->next;
	
	//注意,如果k给的有问题,如大于链表元素个数
	//程序到这时pNode1已有可能为NULL
	if ( NULL == pNode1 )
		return NULL;

	while ( NULL != pNode1->next )
		++count;

		pNode1 = pNode1->next;
		pNode2 = pNode2->next;
	

	if ( count+1 < k/*count + 1 为链表中结点个数*/ )
		return NULL;
	else
		return pNode2;

//注意,我们写完这种思路后再来分析,和第一种思路相比,第二种思路确实只遍历了链表一次。
//可是第二种思路边界情况太多,需要注意可能会出错地方太多,相比之下,第一种思路通俗易懂也不易出错。
//注意有unsigned int 类型变量时一定要小心注意 这种变量值为0 时减去一个正数。

//下面是 剑指offer上代码,比上述代码简洁,也少去了不必要的判断.

ListNode* FindKthToTail(ListNode* pListHead, unsigned int k)

	if ( NULL == pListHead || 0 == k )
		return NULL;

	ListNode* pAhead = pListHead;
	ListNode* pBehind = NULL;


	for ( size_t i = 0; i < k-1; ++i )
		if ( NULL != pAhead->next )
			pAhead = pAhead->next;
		else
			return NULL;
	

	pBehind = pListHead;
	while ( NULL != pAhead->next )
		pAhead = pAhead->next;
		pBehind = pBehind->next;
	

	return pBehind;

以上是关于寻找链表中倒数第k个结点的主要内容,如果未能解决你的问题,请参考以下文章

AcWing32:链表中倒数第k个节点

AcWing32:链表中倒数第k个节点

链表中倒数第k个结点

二种方法查找链表倒数第K个结点

《剑指offer》---输出链表倒数第k个结点

剑指Offer-代码的鲁棒性面试题22:链表中倒数第k个节点