题目描述
输入一个链表,输出该链表中倒数第k个结点。
编程思路
由于单链表的结点只有从前往后的指针,没有从后往前的指针,因此,只能从链表头结点开始遍历。假设链表有n个结点,则倒数第k个结点就是从头结点开始第n-k+1个结点。为了实现只遍历一次就能找到倒数第k个结点,
需要定义两个指针
,第一个从链表的头指针开始遍历向前走k-1,第二个指针不动;从第k步开始,第二个指针也开始从链表的头指针开始遍历。由于两个指针的距离是k-1,因此当一个指针到达链表的尾结点时,第二个指针刚好是倒数第k个结点。
还要考虑到一些特殊情况:当输入的链表头指针为空时,整个链表就为空,结果返回NULL;当输入的k为0时,也返回NULL;当链表的结点数小于k时,在for循环中遍历链表可能会出现指向NULL的next,也会返回NULL.
程序代码(Java语言)
class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
public class Solution {
public ListNode FindKthToTail(ListNode head,int k) {
if(head == null || k == 0 )
return null ;
ListNode node = head;
for(int i=0;i < k-1;i++) {
if(head.next != null)
head = head.next;
else
return null;
}
while(head.next != null) {
head = head.next;
node = node.next;
}
return node;
}
}
举一反三
这种使用两个指针遍历链表的思路,可以用在很多地方。比如:
1.求链表的中间结点,若链表结点数为奇数,则返回中间结点,若结点数位偶数,则返回中间两个结点的任意一个。
我们可以定义两个指针,同时从链表的头结点出发,一个一次走一步,另一个一次走两步,当走的快的走到链表的末尾时,走的慢的正好在链表的中间。
2.判断一个单向链表是否形成了环形结构。
同样,定义两个指针,同时从链表的头结点出发,一个一次走一步,另一个一次走两步。如果走得快的指针追赶上走得慢的指针,那么链表就是环形链表,如果走得快的指针走到末尾都没有追上走得慢的指针,那么链表就不是环形链表。