剑指Offer第15题(链表中倒数第k个结点)
作者:互联网
(本博客旨在个人总结回顾)
题目描述:
输入一个链表,输出该链表中倒数第k个结点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾结点是倒数第1个结点。例如一个链表有6个结点,从头结点开始它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个结点是值为4的结点。
链表结点定义如下:
struct ListNode
{
int m_nValue;
ListNode* m_pNext;
};
解题思路:
使用两个指针A,B,将B指针移动到第K个结点,然后将A设置为头结点,将两结点同时一步一步往下一结点移动,当B结点移动到尾结点时,A结点就刚好移动到倒数第K个结点。
考虑输入的异常情况:①链表结点数少于k的情况;②k<=0的情况。③链表为NULL
目标函数:
/*
* @name GetKthToTail
* @brief 获取链表的倒数第k个结点
* @param [in] ListNode * pListHead
* @param [in] int k
* @return ListNode*
*/
ListNode* GetKthToTail(ListNode* pListHead, int k)
{
if (NULL == pListHead || k <= 0)
{
return NULL;
}
ListNode* pAHead = pListHead;
ListNode* pFind = pListHead;
//pAHead设置为第K个结点(从1开始计算)
for (int i = 1; i < k ; i++)
{
if (pAHead->m_pNext != NULL)
{
pAHead = pAHead->m_pNext;
}
else
{
return NULL;
}
}
//pAHead移动的最后一个结点
//pFind刚好就移动至第K个结点
while (pAHead->m_pNext != NULL)
{
pAHead = pAHead->m_pNext;
pFind = pFind->m_pNext;
}
return pFind;
}
完整测试代码:
#include "stdafx.h"
#include <iostream>
using namespace std;
struct ListNode
{
int m_nValue;
ListNode* m_pNext;
};
/*
* @name GetKthToTail
* @brief 获取链表的倒数第k个结点
* @param [in] ListNode * pListHead
* @param [in] int k
* @return ListNode*
*/
ListNode* GetKthToTail(ListNode* pListHead, int k)
{
if (NULL == pListHead || k <= 0)
{
return NULL;
}
ListNode* pAHead = pListHead;
ListNode* pFind = pListHead;
//pAHead设置为第K个结点(从1开始计算)
for (int i = 1; i < k ; i++)
{
if (pAHead->m_pNext != NULL)
{
pAHead = pAHead->m_pNext;
}
else
{
return NULL;
}
}
//pAHead移动的最后一个结点
//pFind刚好就移动至第K个结点
while (pAHead->m_pNext != NULL)
{
pAHead = pAHead->m_pNext;
pFind = pFind->m_pNext;
}
return pFind;
}
int _tmain(int argc, _TCHAR* argv[])
{
//测试1题描述例子
ListNode* pHead1 = new ListNode();
pHead1->m_nValue = 1;
ListNode* pTmp = new ListNode();
pTmp->m_nValue = 2;
pHead1->m_pNext = pTmp;
pTmp->m_pNext = new ListNode();
pTmp = pTmp->m_pNext;
pTmp->m_nValue = 3;
pTmp->m_pNext = new ListNode();
pTmp = pTmp->m_pNext;
pTmp->m_nValue = 4;
pTmp->m_pNext = new ListNode();
pTmp = pTmp->m_pNext;
pTmp->m_nValue = 5;
pTmp->m_pNext = new ListNode();
pTmp = pTmp->m_pNext;
pTmp->m_nValue = 6;
ListNode* pKNode = GetKthToTail(pHead1, 3);
if (pKNode != NULL)
{
cout << "测试例子1:倒数第3个结点值为" << pKNode->m_nValue << endl;
}
else
{
cout << "测试例子1:不存在该结点" << endl;
}
//测试2链表结点数小于K
pKNode = GetKthToTail(pHead1, 7);
if (pKNode != NULL)
{
cout << "测试例子2:倒数第7个结点值为" << pKNode->m_nValue << endl;
}
else
{
cout << "测试例子2:不存在该结点" << endl;
}
//测试3链表结点数等于1,k=1
pKNode = GetKthToTail(pTmp, 1);
if (pKNode != NULL)
{
cout << "测试例子3:倒数第1个结点值为" << pKNode->m_nValue << endl;
}
else
{
cout << "测试例子3:不存在该结点" << endl;
}
//测试4:K <= 0
pKNode = GetKthToTail(pTmp, 0);
if (NULL == pKNode)
{
cout << "测试例子4:不存在该结点" << endl;
}
pKNode = GetKthToTail(pTmp, -1);
if (NULL == pKNode)
{
cout << "测试例子4:不存在该结点" << endl;
}
//测试5:链表NULL
pKNode = GetKthToTail(NULL, 1);
if (NULL == pKNode)
{
cout << "测试例子5:不存在该结点" << endl;
}
system("pause");
return 0;
}
运行结果:
标签:结点,ListNode,nValue,链表,pAHead,pTmp,15,倒数第,pNext 来源: https://blog.csdn.net/qq_23903863/article/details/103269311