![Go程序员面试算法宝典](https://wfqqreader-1252317822.image.myqcloud.com/cover/262/26268262/b_26268262.jpg)
上QQ阅读APP看书,第一时间看更新
1.5 如何找出单链表中的倒数第k个元素
难度系数:★★★☆☆
被考查系数:★★★★★
题目描述:
找出单链表中的倒数第k个元素,例如给定单链表:1->2->3->4->5->6->7,则单链表的倒数第k=3个元素为5。
分析与解答:
方法一:顺序遍历两遍法
主要思路:首先遍历一遍单链表,求出整个单链表的长度n,然后把求倒数第k个元素转换为求顺数第n-k个元素,再去遍历一次单链表就可以得到结果。但是该方法需要对单链表进行两次遍历。
方法二:快慢指针法
由于单链表只能从头到尾依次访问链表的各个结点,因此,如果要找链表的倒数第k个元素,也只能从头到尾进行遍历查找,在查找过程中,设置两个指针,让其中一个指针比另一个指针先前移k步,然后两个指针同时往前移动。循环直到先行的指针值为null时,另一个指针所指的位置就是所要找的位置。实现代码如下:
![](https://epubservercos.yuewen.com/C814A1/14700476404565706/epubprivate/OEBPS/Images/47_01.jpg?sign=1738781772-rvcKfbx4UG4RZKkcoCP2y44ZoeLszaT8-0-6111c7b0391a1d66fe9a0c9df5031801)
程序的运行结果为
![](https://epubservercos.yuewen.com/C814A1/14700476404565706/epubprivate/OEBPS/Images/47_02.jpg?sign=1738781772-XtA0DEU1n32C4ZN7Gj9H4ZvTJQhT3Z9j-0-eda335bcfe92a67071d0fbc8a432479e)
算法性能分析:
这种方法只需要对链表进行一次遍历,因此,时间复杂度为O(n)。另外,由于只需要常量个指针变量来保存结点的地址信息,因此,空间复杂度为O(1)。
引申:如何将单链表向右旋转k个位置?
题目描述:给定单链表1->2->3->4->5->6->7,k=3,那么旋转后的单链表变为5->6->7->1->2->3->4。
分析与解答:
主要思路:①首先找到链表倒数第k+1个结点slow和尾结点fast(如下图所示);②把链表断开为两个子链表,其中,后半部分子链表结点的个数为k;③使原链表的尾结点指向链表的第一个结点;④使链表的头结点指向原链表倒数第k个结点。
![](https://epubservercos.yuewen.com/C814A1/14700476404565706/epubprivate/OEBPS/Images/48_01.jpg?sign=1738781772-dDSdybXaxumdEo8SkCprO0JnzyKaqxu9-0-2cd3c0a5ba485b715c2e154819971178)
实现代码如下:
![](https://epubservercos.yuewen.com/C814A1/14700476404565706/epubprivate/OEBPS/Images/48_02.jpg?sign=1738781772-H2dcYyj47UdaLhJZWZ5uq2vVxXXvMPzt-0-c424840f3e7fddf9c9ef14010726df0a)
程序的运行结果为
![](https://epubservercos.yuewen.com/C814A1/14700476404565706/epubprivate/OEBPS/Images/49_02.jpg?sign=1738781772-3bnJGX5ZP7ABHzZRDUuUoK1IcBHfRfnS-0-720f08be27c04001aa5c0bf7a763d9a2)
算法性能分析:
这种方法只需要对链表进行一次遍历,因此,时间复杂度为O(n)。另外,由于只需要几个指针变量来保存结点的地址信息,因此,空间复杂度为O(1)。