版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/N1neDing/article/details/82716481
题目描述:
输入一个链表,输出该链表中倒数第k个结点
注意事项:
应注意代码鲁棒性,当头节点为空时,k小于等于0,k大于节点总数目时,都应进行处理,以避免程序崩溃。
解题思路1:
先遍历一次计算出链表中节点总数目num,然后倒数第k个节点就是正数第num-k+1个节点。
参考源码1:
class Solution {
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k)
{
if(pListHead == NULL || k <= 0) return NULL;
int num = 0;
ListNode* tmp = pListHead;
while(tmp != NULL)
{
num++;
tmp = tmp->next;
}
if(num < k) return NULL;
int pos = num - k + 1;
for(int i = 1;i < pos;i++)
{
pListHead = pListHead->next;
}
return pListHead;
}
};
解题思路2:
分别设立两个前后指针,前方指针在后方指针前k-1个位置,当前方指针到达尾节点时,后方指针所在位置即为倒数第k个节点。
参考源码2:
class Solution {
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k)
{
if(pListHead == NULL || k <= 0) return NULL;
ListNode* fast = pListHead;
ListNode* slow = pListHead;
for(int i = 1;i < k;i++)
{
fast = fast->next;
if(fast == NULL) return NULL;
}
while(fast->next != NULL)
{
fast = fast->next;
slow = slow->next;
}
return slow;
}
};
相关题目:
求链表的中间结点。如果链表中结点总数为奇数,返回中间结点;如果结点总数是偶数,返回中间两个结点的任意一个。
解题思路:
需要首先判断链表是否是环状结构,再求中间节点,同样是使用一前一后两个节点的操作。前方节点每次移动两次,后方节点每次移动一次,(这里需要注意,除了(fast != NULL)这个条件,一定要加上(fast->next != NULL)的判断条件,因为fast每次移动两次,当移动到结尾的时候,再连续向后移动两次会发生错误),当前方节点移动到结尾时,后方节点则是中间节点。
参考源码:
#include <iostream>
using namespace std;
struct ListNode
{
int val;
struct ListNode* next;
ListNode(int x):val(x),next(NULL)
{
}
};
class Solution
{
public:
ListNode* FindMid(ListNode* pHead)
{
if(pHead == NULL) return NULL;
if(pHead->next == NULL) return NULL;
ListNode* fast = pHead;
ListNode* slow = pHead;
//判断是否是环状链表
bool judge = false;
while(fast != NULL && fast->next != NULL)
{
fast = fast->next->next;
slow = slow->next;
if(fast == slow)
{
judge = true;
break;
}
}
if(judge)
{
return NULL;
}
fast = pHead;
slow = pHead;
while(fast != NULL && fast->next != NULL)
{
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
};
int main()
{
ListNode* begin = new ListNode(1);
ListNode* begin1 = new ListNode(2);
ListNode* begin2 = new ListNode(3);
ListNode* begin3 = new ListNode(4);
ListNode* begin4 = new ListNode(5);
begin->next = begin1;
begin1->next = begin2;
begin2->next = begin3;
begin3->next = begin4;
Solution s;
ListNode* res = s.FindMid(begin);
cout<<res->val<<endl;
return 0;
}