You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

链表去重问题:快慢指针法遇空指针异常及返回头节点困惑

解决链表去重的空指针异常与头节点丢失问题

看起来你的快慢指针逻辑有点走偏啦,咱们一步步捋清楚问题出在哪,再修正代码:

你的代码存在的核心问题

  • 丢失原始头节点:你最后返回的current在遍历过程中一直往后移动,循环结束后它指向的是链表的末尾(甚至null),自然没法返回修改后的完整链表头。
  • 快慢指针逻辑错误:你把runner和current同步移动了,这不是快慢指针去重的正确用法——慢指针应该停在当前不重复的节点,快指针负责跳过所有重复的节点。
  • 空指针风险:当current.next已经是null的时候,你还去访问current.next.next,这必然会抛出空指针异常。
  • 循环条件冗余且混乱:同时判断current、runner、runner.next会导致逻辑混乱,而且runner是从current衍生出来的,不需要单独提前判断。

修正后的代码实现

Node RemoveDuplicates(Node head) {
    // 空链表直接返回
    if (head == null) {
        return null;
    }
    // 保存原始头节点,最后要返回它
    Node current = head;
    // 当current还有下一个节点时继续处理
    while (current != null && current.next != null) {
        // runner从current的下一个节点开始遍历
        Node runner = current.next;
        // 跳过所有和current.data相同的节点
        while (runner != null && runner.data == current.data) {
            runner = runner.next;
        }
        // 把current的next指向第一个不重复的节点
        current.next = runner;
        // current移动到下一个不重复的节点
        current = runner;
    }
    // 原始头节点一直没被修改,直接返回
    return head;
}

代码解释

  1. 保留头节点:一开始就用current指向头节点,但最后返回的是原始的head,因为头节点本身不会被移除(除非整个链表为空,已经提前处理)。
  2. 正确的快慢指针逻辑:
    • 慢指针current:停在当前已经确认不重复的节点。
    • 快指针runner:从current.next出发,跳过所有和current.data相同的节点,直到找到第一个不同的节点或者链表末尾。
  3. 避免空指针:每次访问runner之前都先判断runner != null,修改current.next时也确保不会访问null的下一级。
  4. 清晰的循环条件:外层循环只需要判断current和current.next不为null,确保我们有节点可以处理。

这样修改后,既能正确移除所有重复节点,也不会出现空指针异常,最后返回的是修改后的完整链表头节点。

内容的提问来源于stack exchange,提问作者Bo Jackson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:33:32