题目:输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第一个节点。例如,一个链表有6个节点,从头节点开始,它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个节点是值为4的节点。链表节点定义如下:
struct ListNode
{
int m_nValue;
ListNode* m_pNext;
};
定义两个指针,第一个指针从链表的头指针开始遍历向前走k-1步,第二个指针保持不动;从第k步开始,第二个指针也开始从链表的头指针开始遍历。由于两个指针的距离保持在k-1,当第一个(走在前面的)指针到达链表的尾节点时,第二个(走在后面的)指针正好指向倒数第k个节点。
ListNode* FindKthToTail(ListNode* pListHead,unsigned int k)
{
ListNode *pAhead=pListHead;
ListNode *pBehind=nullptr;
for(unsigned int i=0;i<k-1;i++)
pAhead=pAhead->m_pNext;
pBehind=pListHead;
while(pAhead->m_pNext!=nullptr)
{
pAhead=pAhead->m_pNext;
pBehind=pBehind->m_pNext;
}
return pBehind;
}
- 输入的pListHead为空指针。由于代码会试图访问空指针指向的内存,从而造成程序崩溃。
- 输入的以pListHead为头节点的链表的节点总数少于k。由于在for循环中会在链表上向前走k-1步,仍然会由于空指针而造成程序崩溃。
- 输入的参数k为0。由于k是一个无符号整数,那么在for循环中k-1得到的将不是-1,而是无符号的0xFFFFFFFF。因此,for循环执行的次数远远超出我们的预计,同样也会造成程序崩溃。
ListNode* FindKthToTail(ListNode* pListHead,unsigned int k)
{
if(pListHead==nullptr||k==0)
return nullptr;
ListNode *pAhead=pListHead;
ListNode *pBehind=nullptr;
for(unsigned int i=0;i<k-1;i++)
{
if(pAhead->m_pNext!=nullptr)
pAhead=pAhead->m_pNext;
else
return nullptr;
}
pBehind=pListHead;
while(pAhead->m_pNext!=nullptr)
{
pAhead=pAhead->m_pNext;
pBehind=pBehind->m_pNext;
}
return pBehind;
}