剑指offer-----输出该链表中倒数第k个结点

题目:

输入一个链表,输出该链表中倒数第k个结点。为符合计数习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。

例子

如:一个链表有6个节点,从头节点开始,它们的值一次是1、2、3、4、5、6。这个链表的倒数第3个节点是值为4的节点。

链接:

剑指Offer:15题

思路标签:

  • 数据结构:链表
  • 算法:双指针
  • 代码的鲁棒性

解答:

1. C++

  • 因为是单向链表,所以无法从后向前遍历;
  • 一种直观的思路是先遍历链表得到链表的长度,然后第二次遍历就能找到第k个节点,但是需要进行两次遍历,不是好的方法;
  • 这里使用两个指针实现一次遍历,第一个指针先走k-1步,第二个指针一直不动;然后两个指针同时移动,知道第一个指针遍历完成。因为两个指针间隔为k-1,所以第二个指针指向的节点即为倒数第k个节点。
  • 需要注意代码的鲁棒性: 
    • 链表为空;
    • k == 0,以为k为无符号整数,k-1=0xFFFFFFFF,导致错误;
    • 链表数不够k的情况,也就是第一个指针移动过程中变为nullptr。

/*
struct Listnode
{
	int value;
	struct Listnode *next
}
*/
class Solution
{
public:
	Listnode* FindthToTail(Listnode* pListHead,unsigned int k)
	{
		if(pListHead=NULL||k==0)
			return NULL;
		
		//定义两个指针
		Listnode* pAhead = pListHead;
		Listnode* pBehind = NULL;
		
		for(unsigned int i=0;i<k-1;i++)
		{
			if(pAhead->next!=NULL)
				pAhead=pAhead->next;
			else
				return NULL;
		}
		
		pBehind=pListHead;
		while(pAhead->next!=NULL)
		{
			pAhead=pAhead->next;
			pBehind=pBehind->next;
		}
		
		return pBehind;
		}
	}
}

参考:

《剑指offer》

猜你喜欢

转载自blog.csdn.net/qq_39503189/article/details/82117040