剑指offer--数据结构之链表(9、19、35)

offer9

输入一个单向链表,输出该链表中倒数第k个结点。链表的倒数第0个结点为链表的尾指针。

可以先设置一个指针 p1,在链表中前进k步,然后加入新的指针 p2,和 p1同步遍历,直到 p1到尾部,那么 p2就是倒数第k个结点。

需要注意两个地方,当链表长度不足k时,和倒数是从0开始的。

代码:链表附带头节点。

Node* FindKthTotail(Node* pHead, int k)
{
	if (!pHead || k<0)
		return NULL;

	Node* pFront=pHead;
	Node* pBehind=pHead;

	for (int i=0; i<k; i++)
	{
		//pFront前进k步,链表长度不足k是返回空指针
		pFront=pFront->pNext;
		if (pFront==NULL)
			return NULL;
	}

	while (pFront->pNext)
	{
		pFront=pFront->pNext;
		pBehind=pBehind->pNext;
	}
	if (pBehind==pHead)
		return NULL;

	return pBehind;
}

offer19

题目:输入一个链表的头结点,反转该链表,并返回反转后链表的头结点。

题目很简单,3个指针即可。

代码:


void ReverseList(ListNode* pHead)
{
	ListNode* pPre=NULL;
	ListNode* p=pHead->m_pNext;
	ListNode* pNext=NULL;

	while (p)
	{
		pNext=p->m_pNext;
		p->m_pNext=pPre;
		pPre=p;
		p=pNext;
	}
	pHead->m_pNext=pPre;
}

offer35

两个单向链表,找出它们的第一个公共结点。

这个没有考虑链表中有环的情况,类似第9题,可以先遍历两个链表的长度,那么两个链表长的那个指针先向前走差值,然后和短的同步向前,那么两个指针值相同时,就是第一个公共节点。

代码:

bool FindFirstCommon(ListNode* pH1, ListNode* pH2, ListNode* &pResulte)
{
	if (!pH1 || !pH2)
		return false;

	int len1, len2;
	len1=len2=0;
	ListNode *p1, *p2;
	p1=pH1; 	p2=pH2;

	while (p1)
	{
		len1++;
		p1=p1->m_pNext;
	}
	while (p2)
	{
		len2++;
		p2=p2->m_pNext;
	}

	//链表长度差值
	int k=abs(len1-len2);
	p1=pH1; p2=pH2;
	//长的链表指针向前k步
	if (len1>len2)
	{
		while (k)
		{
			p1=p1->m_pNext;
			k--;
		}
	}
	else
	{
		while (k)
		{
			p2=p2->m_pNext;
			k--;
		}
	}
	//找到第一个公共节点
	while (p1!=p2)
	{
		p1=p1->m_pNext;
		p2=p2->m_pNext;
	}
	//没有公共节点
	if (!p1)
		return false;

	pResulte=p1;
	return true;
}
编程之美上有考虑环路的情况,以后更新。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值