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
相关产品推荐
相关产品推荐

