链表面试题1:求链表中倒数第K个结点
-
分析题目:
-
根据题意可知,此链表为单向链表,无法从尾端回溯K步。
-
我们按照从k=1开始计数,即链表的倒数第一个结点是链表最后一个结点
-
-
解题思路:
-
方法一:
-
1、先遍历一遍链表,统计链表中结点的个数N(每经过一个结点计数器加1)
-
2、从链表的头节点开始遍历N-K步即可找到倒数第K个结点(假设共6个结点,求倒数第二个结点,即为整数第5个,需要从头节点向后走4步(N-K))
-
此方法需要遍历两次链表
-
-
方法二:
-
1、定义两个指针均指向头节点
-
2、第一个指针先向前走K-1步,然后两个指针再同步向前
-
3、当第一个指针指向最后一个结点时,第二个指针指向倒数第K个结点
-
此方法只遍历一次链表
-
-
-
图解法二:
-
代码实现
//定义结构体
struct ListNode
{
int value;
struct ListNode* pNext;
};
ListNode* FindKthToTail(ListNode* pHead, unsigned int k) //k必须大于0
{
//pHead为空时直接返回NULL,且K必须大于0
if (pHead == NULL || k == 0)
{
return NULL;
}
//定义两个指针,均指向头结点
ListNode * p1 = pHead;
ListNode * p2 = pHead;
//p1先向前走K-1步
unsigned int i = 1;
while (i = 1,i < k,i++)
{
if (p1->pNext != NULL)
{
p1 = p1->pNext;
}
//解决k不能大于链表总结点数的问题
else
{
printf("The value of K is error\n");
return NULL;
}
}
//p1、p2共同前进,当p的下一个结点为空时停止
while (p1->pNext != NULL)
{
p1 = p1->pNext;
p2 = p2->pNext;
}
return p2;
}
- 注意事项
-
k必须大于0
-
k必须小于链表总结点数
-
链表不能为空,若为空直接返回NULL
-
-
测试用例需考虑:
-
k<=0
-
k>链表总结点数
-
0<k<N
-
链表为空
-
倒数第k个为链表头结点
-
倒数第K个为链表的尾结点
-
倒数第k个在链表的中间
-