题目:输入一个链表,输出该链表中倒数第k个结点。
思路一:最简单的思路是:先遍历一次链表,得出共n个节点,倒数第k个,既是正数第n-k+1个节点,直接遍历到第n-k+1个节点即可,但是需要遍历两次链表,如果需要遍历一次链表的方法时用思路二。
思路二:定义两个指针,第一个指针先指向第k个节点,既向前走k-1步,然后另第二个指针指向头结点,然后两个指针一起向后移动,直到第一个指针走到最后一个节点时,此时第二个指针正好指向倒数第k个节点。
但需注意:1.要判断输入是否为空指针,若为空指针,代码试图访问空指针会造成程序崩溃,所以此时要返回NULL。
2.若k大于链表的节点数,此时也会试图访问空指针,也要返回NULL。
3.k==0时,k-1是无符号数,不是-1,也会造成崩溃。
class Solution {
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k)
{
if (pListHead==NULL||k==0)
return NULL;
ListNode* p1= pListHead;
ListNode* p2= NULL;
for(unsigned int i=0;i<k-1;i++)
{
if( p1->next!= NULL) //
{
p1=p1->next;
}
else
{
return NULL;
}
}
p2=pListHead;
while (p1->next!=NULL) //
{
p1=p1->next;
p2=p2->next;
}
return p2;
}
};
补充题型:删除链表的倒数第N个节点
思路:同上题,找到倒数第k个节点,讲k的前一节点指向k的后一节点,既实现了删除节点的功能。
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n)
{
if(head==NULL||n==0)
return NULL;
ListNode* p1=head;
ListNode* p2=head;
ListNode* p3=NULL;
for(int i=0;i<=n-1;i++)
{
if(p1!=NULL)
p1=p1->next;
else
{
return NULL;
}
}
while(p1!=NULL)
{
p1=p1->next;
p3=p2; //保存要删除节点的前一节点
p2=p2->next;
}
if(p2==head) //如果要删除节点为头结点
{head=head->next;}
else
{p3->next=p2->next;}
return head;
}
};