略
题目:输入一个链表,输出该链表中倒数第k个结点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾结点是倒数第1个结点。
分析
初见
对于一个单向链表,如果要实现查找倒数的第k个结点,就需要在遍历链表时记录每个位置的值,到达最后一个值后,再倒着推出倒数第k个结点,但是如果要一一记录每个值需要更多的空间,有没有一个更好的方法呢。
可以用两个指针,一个指针先向后遍历,当遍历了k个结点时,第二个指针跟随着第一个指针一一向后移动,由于第一个指针先遍历的,所以他会先到达结尾,当它到达结尾时,第二个移动的指针就是需要的倒数第k个结点。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class Solution { public ListNode FindKthToTail(ListNode head,int k) {
ListNode pre=head; ListNode last=head; for(int i=1;i<k;i++){ pre=pre.next; } while(pre.next!=null){ pre = pre.next; last = last.next; } return last; } }
|
为了代码的鲁棒性
对于代码的鲁棒性,我们需要考虑的是:当链表的头指针为空时(链表为空);当链表结点总数小于k时(倒数到链表外了);当倒数第0个结点时(由于倒数是从1开始的)。这三个都需要考虑到是否会导致程序崩溃。
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
public class Solution { public ListNode FindKthToTail(ListNode head,int k) { if(head==null||k<=0){ return null; } ListNode pre=head; ListNode last=head; for(int i=1;i<k;i++){ if(pre.next!=null){ pre=pre.next; }else{ return null; } } while(pre.next!=null){ pre = pre.next; last=last.next; } return last; } }
|
总结
- 对链表的理解,单向链表遍历只能从头到尾的特点。
- 代码的鲁棒性,鲁棒英文为Robust,也可翻译为健壮性,就是对不合要求的输入予以合理的处理,比如要求输入的账户名为数字串,实际如果输入了字符,代码健壮的程序应该给出提示信息。