定位单向链表的倒数第n个节点

问题:有单链表LinkNode,请写一算法返回该链表的倒数第n个节点.
由于是单向链表,倒数往回数的可能性好像不大.于是诞生以下三种思路,借以参考。
假设单链表的头指针为root,链表定义的两个域(data,next),为简化讨论,假设n小于单链表的节点数。

思路1:要做到从尾往回数,就必须让单链表逆向。这可谓是最愚蠢的想法,因为把单链表逆向之后,很快能够得到第n个,但是好像返回结果后,我们必须恢复现场,这样算来最坏的情况下有O(3n)的时间复杂度.完成这个思路的代码大致像:

//第1步.逆向单链表
LinkNode *newRoot=NULL;
LinkNode *temp=root;
while(root != NULL){
  temp = root->next;
  root->next = newRoot;
  newRoot = root;;
  root = temp;
}
root = newRoot;

//第2步:顺序查找第n个元素
temp = root;
while((temp=temp->next) && n-->0);
if(n==0) return temp;

//第3步:如果需要恢复,执行第1步中的代码

思路2:不管是顺数n个还是倒数n个,其实都是距离-标尺问题。
标尺是一段距离可以用线段的两个端点来衡量,我们能够判断倒数第一个节点,因为他的next==NULL。
如果我们用两个指针,并保持他们的距离为n,那么当这个线段的右端指向末尾节点时,左端节点就指向倒数第n个节点。
真是进了一大步,这个思路的算法时间复杂度为O(n).代码大致像这样:

//第1步:建立标尺
LinkNode *pLeft,*pRight;
pLeft=pRight=root;
while(n-->0) pRight=pRight->next;

//第2步:让标尺向右移动,直到右端指向末尾.左端即结果
while(pRight->next != NULL){
   pLeft = pLeft->next;
   pRight = pRight->next;
}
return pLeft;

 思路3:偷懒最省事的办法!让单链表有一个头节点,并在头节点中保存该单向列表的节点数目。
这个思路的时间复杂度最小,只跟参数n有关系.代码大致为:

//第1步:计算顺数的位置
int reN = count-n;

//第2步:向右移动reN的节点即是.
LinkNode * temp=root;
while(reN-->0) temp = temp->next;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值