题目描述
输入一个链表,输出该链表中倒数第k个结点。
解法1:
新建2个指针p1p2,p1将链表从头到位遍历,得到链表的总长度count。若count>=k,则将p2移动count-k下即可得到倒数第k个节点;若count<k,则返回空。
代码如下,此解法无辅助空间,空间复杂度为O(1),时间复杂度为O(n):
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
if(k == 0 || pListHead == NULL)
{
return NULL;
}
ListNode* p1 = pListHead;
ListNode* p2 = pListHead;
unsigned int count = 0;
while(p1)
{
count++;
p1 = p1->next;
}
if(count >= k)
{
count = count - k;
while(count)
{
p2 = p2->next;
count--;
}
return p2;
}
return NULL;
}
};
解法2:
解法1这种思路需要将链表遍历两遍,因此可以先让p1遍历k-1次,然后让p1p2一起遍历,直到p1到达链表尾部,此时p2正好指向倒数第k个节点。
代码如下,此解法无辅助空间,空间复杂度为O(1),时间复杂度为O(n):
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
if(k == 0 || pListHead == NULL)
{
return NULL;
}
ListNode* p1 = pListHead;
ListNode* p2 = pListHead;
while(k)
{
if(p1 == NULL)
{
return NULL;
}
p1 = p1->next;
k--;
}
while(p1)
{
p1 = p1->next;
p2 = p2->next;
}
return p2;
}
};
解法3:
新建一个辅助空间vector,遍历后将对应位置的数据取出即可。代码如下,此解法有辅助空间,空间复杂度为O(n),时间复杂度为O(n)::
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
if(k == 0 || pListHead == NULL)
{
return NULL;
}
vector<ListNode*> tvec;
ListNode* p1 = pListHead;
unsigned int count = 0;
while(p1)
{
count++;
tvec.push_back(p1);
p1 = p1->next;
}
if(count >= k)
{
return tvec[count-k];
}
return NULL;
}
};