题干:
输入一个链表,输出该链表中倒数第k个结点
思路:
分析,链表没有直接出长度的函数,所以涉及到输出链表中的倒数第几个结点,首先要把链表中的节点数搞清楚,然后再输出即可,主要判断几个条件:链表是否为空了,k是否大于链表中的结点数了。这是最常规的做法,时间复杂度会达到O(2n),这里暂且叫做method1。代码见下:
public static ListNode FindKthToTail(ListNode head,int k) {
if(head==null || (head.next==null && k!=1)){//程序鲁棒性检测
return null;
}
if(head.next==null && k==1){
return head;
}
int i=1;//i代表这个链表的节点数
ListNode index = head;
while (index.next!=null){
i++;
index=index.next;
}
if(k>i){
return null;
}
for(int j=0;j<i-k;j++){
head=head.next;
}
return head;
}
然后这种方法实际做了很多无用功,要先去统计链表中的节点数目。
这种题目的最经典解法是利用双指针求解。
原理如下:
设置两个指针分别指向头结点,一个是快指针fhead,一个慢指针lhead。fhead先出发,走出k-1步之后,lhead开始出发。二者始终差k-1个距离,当fhead到达链表末尾的时候,lhead所在位置就是链表中倒数第k个数。
代码实现如下:
public ListNode FindKthToTail(ListNode head,int k) {
if(head==null){//增强程序的鲁棒性(强壮性):输入链表为null时,保证正确输出。
return null;
}
ListNode fast= head;
ListNode low = head;
while (fast.next!=null){
fast=fast.next;
k--;
if(k==0){
low=low.next;
k++;
}
}
if(k!=1){//增强程序的鲁棒性(强壮性):保证在k值比链表长度还长的是时候正确输出。
return null;
}
return low;
}
双指针法的思路非常优秀,且简单明了,非常推荐使用!