寻找链表的倒数第k个节点

过年实在闲得无聊,还是撸几道算法,写写博文,打发打发时间。

微软的面试题,难度系数低,描述如下:

题目:输入一个单向链表,输出该链表中倒数第k 个结点。链表的倒数第0 个结点为链表
的尾指针。 
链表结点定义如下: 

struct ListNode 
{ 
    int m_nKey; 
    ListNode* m_pNext; 
}; 


逻辑分析:

1、前几天和钧哥会晤的时候,刚好看到这道题,我想不只是我,多数人的第一想法,都是马上想到两次遍历(第一次遍历记录链表长度,第二次遍历到n-k+1节点),显然,空间考虑,我们需要一个指针变量,复杂度O(1),而时间上,因为两次都是线性遍历,所以是O(n)+O(n-k+1),时间复杂度O(n),尽管是线性,但是我们却遍历了两次,如果考虑将链表载入内存,那么显然,遍历两次是不可取的,链表的加载和释放会降低算法运行的效率。


2、那么,继而就有了这样一个想法,扩展空间,我们用两个指针来实现,将两个指针的差值记为k,当指针p1指向链表尾指针指向的NULL,指针p2如果能够与p1差k个节点,那么p2就指向了倒数第k个节点,显然,我们可以通过另p1先行k步,从而保持p2与p1的差值。显然时间复杂度也是O(n),只不过我们仅仅遍历了一次。


struct ListNode
{
    char data;
    ListNode* next;
};

ListNode* head,*p,*q;
ListNode *pone,*ptwo;

//@heyaming, 第一节,求链表倒数第k个结点应该考虑k大于链表长度的case。
ListNode* fun(ListNode *head,int k)
{
	assert(k >= 0);
	pone = ptwo = head;
	for( ; k > 0 && ptwo != NULL; k--)
		ptwo=ptwo->next;
	if (k > 0) return NULL;
	
	while(ptwo!=NULL)
	{
		pone=pone->next;
		ptwo=ptwo->next;
	}
	return pone;
} 


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值