拿捏链表(四)—— 链表中倒数第k个结点

题目描述

输入一个链表,输出该链表中倒数第k个结点。(题目来源

在这里插入图片描述

思路一

由于这道题目并没有要求时间复杂度,我们完全可以先遍历一遍链表,得到链表的结点总数(count),然后再遍历一遍链表,从第一个结点开始,后面的第count - k个结点即为目标结点。

但是在求解过程中有两个情况需要中途便返回NULL:
1.当传入的链表为空时,直接返回空(NULL)。
2.当计算出的链表总结点数count小于k时,返回空(NULL)。

代码实现

struct ListNode {
	int val;
	struct ListNode *next;
};

struct ListNode* FindKthToTail(struct ListNode* pListHead, int k)
{
	if (pListHead == NULL)//判断链表是否为空
		return NULL;
	struct ListNode* cur = pListHead;//记录当前结点位置
	int count = 0;//记录链表的总结点数
	while (cur)
	{
		count++;//结点总数加一
		cur = cur->next;//指针后移
	}
	if (count < k)//count小于k,此时不存在倒数第k个结点
		return NULL;
	struct ListNode* ret = pListHead;
	int pos = count - k;//倒数第k个结点距离第一个结点的结点数
	while (pos--)
	{
		ret = ret->next;//指针后移
	}
	return ret;//返回目标结点
}

思路二

我们若是仅仅为了解决这个问题,那么用上面这种解法解决这道题完全没问题。但我们若是为了提高自身的代码能力,上面这种思路是远远不够的,在实际运行时该代码的效率不高,而且这种代码在面试时根本不能“打动”面试官。
其实我们还是可以运用“快慢指针”的思想来解决这道题,这样可以使得代码的时间复杂度直接从O(n2)变为O(n) 。需要注意的是:这里所说的“快慢指针”并非一个指针走得快,另一个指针走得慢,而是快指针先走,慢指针在快指针走到某一位置后再开始走。

因为从最后一个结点开始,再往后走一步便是NULL;从倒数第二个结点开始,再往后走两步便是NULL;从倒数第k个结点开始,再往后走k步便是NULL。所以我们可以先让快指针(fast)先走k步,然后慢指针(slow)再和快指针一起往后走,这样,当快指针走到NULL时,慢指针指向的结点就是倒数第k个结点。
在这里插入图片描述
注意:在快指针(fast)先向后走k步这个过程中,若遇到了NULL,那么说明链表为空,或是k的值大于链表中结点的总数,此时需返回NULL。

代码实现

struct ListNode {
	int val;
	struct ListNode *next;
};

struct ListNode* FindKthToTail(struct ListNode* pListHead, int k)
{
	struct ListNode* fast = pListHead;//快指针
	struct ListNode* slow = pListHead;//慢指针
	while (k--)//快指针先向后移动k步
	{
		if (fast == NULL)//快指针移动过程中链表遍历结束,不存在倒数第k个结点
			return NULL;
		fast = fast->next;//快指针后移
	}
	while (fast)//快指针遍历完链表时结束遍历
	{
		fast = fast->next;//快指针后移
		slow = slow->next;//慢指针后移
	}
	return slow;//返回慢指针的值
}
  • 12
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

2021dragon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值