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

LeetCode 1721:交换节点代码出现无限循环,求协助排查修复

问题排查与修复方案

问题分析

你的代码出现无限循环或空指针的原因主要有以下几点:

  • 未处理交换节点为同一节点的情况:当k是链表中间位置(比如链表长度为5,k=3),此时curr和curr2指向同一个节点,执行交换逻辑会导致节点自环,进而引发无限循环。
  • 未处理头节点交换场景:当k=1(交换第一个节点)时,pre为null,执行pre.next = curr2会触发空指针异常;同时交换后新的头节点应为curr2,而非原head。同理当k等于链表长度(交换最后一个节点)时,pre2为null,也需要处理头节点变更。
  • 相邻节点交换逻辑错误:当两个待交换节点相邻时,当前的指针赋值顺序会导致链表断裂或自环。

修复后的代码

class Solution {
    public int size(ListNode head) {
        int size = 0;
        ListNode curr = head;
        while (curr != null) {
            size++;
            curr = curr.next;
        }
        return size;
    }

    public ListNode swapNodes(ListNode head, int k) {
        if (head == null || head.next == null) {
            return head;
        }

        int size = size(head);
        // 处理k超过链表长度的情况(题目中k应为有效值,做防御性判断)
        k = Math.min(k, size - k + 1);
        if (k == size - k + 1) {
            return head; // 两个节点是同一个,无需交换
        }

        ListNode curr = head;
        ListNode pre = null;
        // 找到第k个节点及其前驱
        for (int i = 1; i < k && curr != null; i++) {
            pre = curr;
            curr = curr.next;
        }

        ListNode curr2 = head;
        ListNode pre2 = null;
        // 找到倒数第k个节点及其前驱(即第size -k +1个节点)
        for (int i = 1; i < (size - k + 1) && curr2 != null; i++) {
            pre2 = curr2;
            curr2 = curr2.next;
        }

        // 处理头节点交换情况
        if (pre == null) {
            head = curr2;
        } else {
            pre.next = curr2;
        }

        // 区分相邻节点与非相邻节点的交换逻辑
        if (curr.next == curr2) {
            curr.next = curr2.next;
            curr2.next = curr;
        } else {
            // 常规非相邻节点交换
            ListNode tmp = curr.next;
            curr.next = curr2.next;
            curr2.next = tmp;

            if (pre2 != null) {
                pre2.next = curr;
            }
        }

        return head;
    }
}

关键修复点说明

  • 提前判断同一节点:通过k == size -k +1判断两个待交换节点是否为同一个,直接返回原链表,避免自环。
  • 处理头节点变更:当pre为null时,将新的头节点设为curr2;若pre2为null,交换后curr会自动成为新的头节点。
  • 区分相邻与非相邻节点:当两个节点相邻时,调整指针赋值顺序,避免链表断裂;非相邻节点则使用常规交换逻辑。
  • 防御性判断:增加对空链表或单节点链表的直接返回,避免无效计算。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 06:50:30