剑指offer(14)——C++实现输出链表倒数第K个节点

该博客介绍了如何在C++中解决链表问题,具体任务是找出链表中倒数第K个节点。文章讨论了问题的考察点,包括链表操作和代码鲁棒性,并提出了两种解题思路:先遍历获取链表长度再定位,以及使用双指针同步移动。还提到了编程过程中需要注意的循环条件和返回值问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

输入一个链表,输出该链表中倒数第k个结点。

考察点

  • 链表
  • 代码的鲁棒性

解题思路

  • 一开始想法:遍历下链表,然后从后往前回溯K个节点,输出即可。但因给定链表为单链表,其节点只有从前往后的指针,故该想法行不通。
  • 输出倒数第K个节点,就是输出正数第N-K+1个,故先遍历一遍链表给出链表长度,再遍历到底n-k+1个节点,输出即可。
  • 只遍历一次的方法:设置两个指针,phead先走K-1步,然后pbehind跟它同步走,当phead刚好走到尾结点时,pbehind刚好走到n-k+1节点(即倒数第k个节点)

完整代码

/*14-输出链表倒数第K个节点*/
#include<iostream>
using namespace std;
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};
class Solution {
public:
	//遍历两次
	ListNode* FindKthToTail01(ListNode* pListNode, unsigned int k) {
		if (pListNode->next == NULL) return NULL;//注意返回值为NULL而不是0
		if (k == 0) return NULL;

		ListNode *pcount = pListNode;
		unsigned int length = 0;
		while (pcount != NULL)
		{
			pcount = pListNode->next;
			length++;
			
		}
		if (k > length) return NULL;
		for (unsigned int i = 0; i < length - k + 1; i++)
		{
			pListNode = pListNode->next;
		}
		return pListNode;
	}
//遍历一次
	ListNode* FindKthToTail(ListNode* pListNode, unsigned int k) {
		ListNode* phead = pListNode;
		ListNode* pbehind = pListNode;
		if (pListNode == NULL || k == 0) return NULL;
		for (int i = 1; i < k; i++)//先走k-1步
		{
			if (phead->next == NULL)
				return NULL;
			phead = phead->next;
		}
		while (phead->next != NULL)//不是phead!=NULL
		{
			phead = phead->next;
			pbehind = pbehind->next;  
		}
		return pbehind;
	}
};

int main()
{
	ListNode *p1 = new ListNode(5); ListNode *p2 = new ListNode(4); ListNode *p3 = new ListNode(3);
	ListNode *p4 = new ListNode(2); ListNode *p5 = new ListNode(1);
	p1->next = p2; p2->next = p3; p3->next = p4; p4->next = p5;
	Solution s;
	ListNode* result;
	result = s.FindKthToTail(p1, 2);
	cout << result->val << endl;
	return 0;
}

编程遇到的问题

  • 循环条件:phead->next != NULL,不是phead!=NULL
  • 返回值:函数返回值要求什么返回什么,不能想当然
  • int 是有符号整型,int类型和unsigned int 类型进行运算时要注意。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值