专栏:《数据结构必刷题》 题目来自:牛客网和力扣
题目:链表中倒数第k个结点
题目链接:点击即可跳转
题目描述:
输入一个长度为 n 的链表,设链表中的元素的值为 ai ,返回该链表中倒数第k个节点。 如果该链表长度小于k,请返回一个长度为 0 的链表。
数据范围:0 <= n <= 10^5 , 0 <= ai <= 10^9, 0 <= k <= 10^9 要求:空间复杂度 O(n)O(n),时间复杂度 O(n)O(n) 进阶:空间复杂度 O(1)O(1),时间复杂度 O(n)O(n)
例如输入{1,2,3,4,5},2时,对应的链表结构如下图所示:
其中蓝色部分为该链表的最后2个结点,所以返回倒数第2个结点(也即结点值为4的结点)即可,系统会打印后面所有的节点来比较。
示例1:
输入:{1,2,3,4,5},2 返回值:{4,5} 说明:返回倒数第2个节点4,系统会打印后面所有的节点来比较
示例2:
输入: {2},8 返回值:{}
解题思路: 对于这道题,我们可以遍历链表,然后记录链表的长度,再输出倒数第K个结点。这虽然可以解决问题,但是时间复杂度高了,因为遍历了两遍链表。 如果要遍历一遍链表来解决问题,那么这道题可以使用
快慢指针
\color{#FF0000}{快慢指针}
快慢指针来解决。
快慢指针 所谓快慢指针中的快慢指的是指针向前移动的步长,每次移动的步长较大即为快,步长较小即为慢,常用的快慢指针一般是在单链表中让快指针每次向前移动2,慢指针则每次向前移动1。
我们先定义快慢指针,快指针为
f
a
s
t
\color{#FF0000}{fast}
fast ,慢指针为
s
l
o
w
\color{#0000FF}{slow}
slow。 既然我们要得到倒数第K个结点,因此我们可以先让快指针走K步。当快指针走完后,它们在以相同的速度出发。看下图: 我们由上图可知,当
f
a
s
t
=
=
n
u
l
l
\color{#FF0000}{fast==null}
fast==null,此时
s
l
o
w
\color{#0000FF}{slow}
slow开始之后的结点都是我们要的结点 ,我们只需要返回
s
l
o
w
\color{#0000FF}{slow}
slow结点就可以了。 做题要要严谨,我们还要考虑到
空链表、
K
的值不是正数、当
K
过大,
f
a
s
t
为空
\color{#FF0000}{空链表、K的值不是正数、当K过大,fast为空}
空链表、K的值不是正数、当K过大,fast为空 这几种情况。接下来就可以写代码了。
public ListNode FindKthToTail (ListNode pHead, int k) {
if(pHead == null || k <= 0){
return null;
}
ListNode slow = pHead;
ListNode fast = pHead;
for(int i = 0;i < k;i++){
if(fast == null){
return null;
}
fast = fast.next;
}
while(fast != null){
fast = fast.next;
slow = slow.next;
}
return slow;
}
|