代码的鲁棒性

100 阅读2分钟

前言

  今天做了一道关于链表的题目,题目本身非常简单,但是其中需要注意的一些细节很值得探讨,也让我注意到写代码过程中代码的鲁棒性问题。根据题目写出正确的解法是基础要求,能够进一步考虑到一些细节,排除潜在的崩溃风险,则是锦上添花。

剑指Offer 22 链表中倒数第K个节点

题目详情

输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。
例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点。
示例:给定一个链表: 1->2->3->4->5, 和 k = 2.返回链表 4->5.
来源:力扣(LeetCode)

题解

  题目本身非常的简单,使用双指针便可以轻松解决,这样只需要遍历整个链表一次便可以得到题目要求的倒数第K个节点。根据这样的思路,可以给出基础的算法:

public class Offer22 {
    //有缺陷的代码
    public ListNode getKthFromEnd(ListNode head, int k) {
        ListNode left = head;
        ListNode right = head;
        while (k > 0) {
            right = right.next;
            --k;
        }
        while (right != null) {
            right =right.next;
            left = left.next;
        }
        return left;
    }
}

总体上来说这个算法的思路是正确的,但是里面有一些小细节需要注意:

  1. 空指针异常
    当然Java中并没有指针的概念,但是如果这道题使用C/C++进行解答的话,就需要考虑如果head给的是一个空指针的情况。

  2. 链表节点数量少于k   这主要是针对代码中第一个while循环,假设k大于链表的长度,右指针在指向到链表结尾时不会停下,仍会继续尝试寻找下一个节点,因此需要对此加以限制和判断。

考虑到这些问题以后,我们可以对代码进行进一步完善:

public class Offer22 {
    public ListNode getKthFromEnd(ListNode head, int k) {
        ListNode left = head;
        ListNode right = head;
        while (k > 0 && right != null) {
            //增加对k大于链表节点总数的判断
            right = right.next;
            --k;
        }
        while (right != null) {
            right =right.next;
            left = left.next;
        }
        return left;
    }
}

  因为k=0和输入为空的情况在这道题里没有实际意义,同时官方题目也没有给出k的限制,因此没有做进一步的处理,但是从代码的角度来说,以上的问题都是需要去考虑的和处理的。

总结

  暂时没什么好写的,等以后遇到新的题目再进行补充吧。