第22题:链表中倒数第k个结点
题目描述
题目:输入一个链表,输出该链表中倒数第k个结点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾结点是倒数第1个结点。例如一个链表有6个结点,从头结点开始它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个结点是值为4的结点。
考点
鲁棒性:指针为nullptr,链表节点数少于K,输入的K为0
双指针遍历:只用遍历一次,复杂度O(n)
unsigned int: 为0的时候,k-1会变成0xFFFFFFFFF,4294967295,进入无限死循环
第一遍
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k)
{
//1.鲁棒性检查,nullptr链表,k=0的情况,返回nullptr
if (pListHead == nullptr || k == 0)
return nullptr;
//2.定义双指针,第一个指向头节点,第二个指向nullptr
ListNode* first = pListHead;
ListNode* second = nullptr;
//3.第一个指针向前走k-1步
for (int i = 0; i < k-1; i++)
{
//3.1如果k比链表节点大,返回nullptr
if (first->m_pNext == nullptr)
return nullptr;
//3.2 否则,向前走一步
else
first = first->m_pNext;
}
//4.第二个指针开始走
second = pListHead;
//5.当第一个指针直到最后一个节点时,第二个指针指向倒数第k个节点
while (first->m_pNext!=nullptr)
{
first = first->m_pNext;
second = second->m_pNext;
}
//6.返回第二个指针的值
return second;
}
注意:
//3.第一个指针向前走k-1步 for (int i = 0; i < k-1; i++) { //3.1如果k比链表节点大,返回nullptr if (first->m_pNext == nullptr) return nullptr; //3.2 否则,向前走一步 else first = first->m_pNext; }
要先判断first->m_pNext是否存在,再往后走一个
第二遍
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
//1.鲁棒性检查
if(pListHead==nullptr||k==0)
return nullptr;
//2.定义双指针
ListNode* first=pListHead;
ListNode* second=nullptr;
//3.第一指针先走K-1步
for(int i=0;i<k-1;i++)
{
//3.1 鲁棒性检查,如果k大于链表节点,返回nullptr
if(first->next==nullptr)
return nullptr;
//3.2 否则往下走一步
else
first=first->next;
}
//4.第二个指针开始走
second = pListHead;
//5.直到第一个指针走到最后一个节点,第二个指针就是倒数第K个数,他们的距离是k-1
while(first->next!=nullptr)
{
first=first->next;
second=second->next;
}
//6.返回这时的第二个指针
return second;
}
};
相关题目
求链表的中间节点,如果链表中的节点总数为奇数,则返回中间节点;如果节点总数是偶数,则返回中间两个节点的任意一个。
为了解决这个问题,我们也可以定义两个指针,同时从链表的头节点出发,一个指针一次走一步,另一个指针一次走两步。
当走得快的指针走到链表的末尾时,走得慢的指针正好在链表的中间。
struct ListNode {
int val;
ListNode *next;
};
ListNode* FindIntermediateNode(ListNode* pHead) {
if (pHead ==nullptr)
return nullptr;
ListNode* pFast = pHead;
ListNode* pSlow = pHead;
while (pFast != NULL && pFast->next != NULL) {
pFast = pFast->next->next;
pSlow = pSlow->next;
}
return pSlow;
}