题目
输入一个单向链表,输出该链表中倒数第 k 个结点。链表的倒数第 0 个结点为链表的尾指针。
思路
解法一:
可以先遍历一遍统计链表个数,然后找到倒数第k个的下标再遍历,这样时间复杂度比较高
解法二:
输入一个单向链表,输出该链表中倒数第 k 个结点。链表的倒数第 0 个结点为链表的尾指针。
思路
解法一:
可以先遍历一遍统计链表个数,然后找到倒数第k个的下标再遍历,这样时间复杂度比较高
解法二:
双指针联动:一个指针先跑K -1步,然后两个指针一起跑。当第一个指针跑到尾节点时,第二个指针恰好是倒数第K个节点。
需要注意的问题:
1.链表为空链表
2.链表的结点个数小于K时
3.K=0时的特殊情况
实现代码如下:
#ifndef LASTK_H
#define LASTK_H
#include <stdlib.h>
#include <iostream>
#include <time.h>
typedef struct ListNode{
int data;
struct ListNode* next;
}*Link;
Link CreateLink(){
Link head=NULL;
head=new ListNode();
head->data=0;
head->next=NULL;
Link temp=NULL,tail=head;
for(int i=1;i<11;i++){
temp=new ListNode();
temp->data=i;
temp->next=NULL;
tail->next=temp;
tail=temp;
}
return head;
}
void PrintLink(Link head){
while(head!=NULL){
std::cout<<head->data<<" ";
head=head->next;
}
std::cout<<std::endl;
}
Link findLastK(Link head,int k){
if(head==NULL || k<=0)
return NULL;
Link first=head,second=head;
int step=0;
//如果k合法,则second指向第k个结点;
while(second->next!=NULL){
second=second->next;
++step;
if(step==k-1)
break;
}
if(step!=k-1) //链表结点个数少于k个
return NULL;
while(second->next!=NULL){
first=first->next;
second=second->next;
}
return first;
}
void testLastK(){
Link head;
head=CreateLink();
std::cout<<"遍历链表: ";
PrintLink(head);
std::cout<<"输出倒数第12个结点: ";
Link result=findLastK(head,12);
if(result!=NULL)
std::cout<<result->data<<std::endl;
else
std::cout<<"k无效或者链表为空!"<<std::endl;
std::cout<<"输出倒数第10个结点: ";
result=findLastK(head,10);
if(result!=NULL)
std::cout<<result->data<<std::endl;
else
std::cout<<"k无效或者链表为空!"<<std::endl;
}
#endif
运行结果