为何相同C++代码IDE运行正常,提交LeetCode回文链表题报错
报错原因
你遇到的heap-use-after-free错误来自LeetCode后台的内存回收逻辑,你的本地IDE没有主动释放链表内存,所以不会触发该问题,核心问题有两个:
- 反转后半段链表后未断开循环
你通过快慢指针找到中点slow后,直接反转slow之后的节点,反转完成后,原slow->next对应的节点(反转前的后半段首节点)的next会指向slow,但slow->next仍然指向这个节点,直接形成了循环链表。LeetCode测试用例执行完成后会遍历整个链表释放所有节点内存,遇到循环链表时会重复访问已经被释放的节点,触发地址消毒的报错。 - 本地无内存释放逻辑
你本地的测试代码只做了节点new,没有对应的delete操作,不会触发内存回收的逻辑,自然不会暴露循环链表导致的重复释放问题。
修复方案
只需要在反转完后半段链表之后,新增一行代码断开slow的后续指针即可:
// 反转后半段的逻辑执行完后加这一行 slow->next = nullptr;
完整修复后的核心代码如下:
bool isPalindrome(ListNode* head) { if (!head->next) { return true; } ListNode* slow = head; ListNode* fast = head; while (fast && fast->next) { fast = fast->next->next; slow = slow->next; } ListNode* prev = slow; ListNode* current = prev->next; while (current) { ListNode* temp = current->next; current->next = prev; prev = current; current = temp; } // 新增这行,断开循环,避免内存回收时出现环 slow->next = nullptr; while (head != slow) { if (head->val != prev->val) { return false; } head = head->next; prev = prev->next; } return true; }
补充说明
如果需要严格符合O(1)空间的要求,还可以在判断完回文之后把后半段链表反转回来,恢复原链表的结构,避免修改输入参数,不过LeetCode的判题逻辑不要求恢复原链表,只要断开循环就可以通过测试。
内容的提问来源于stack exchange,提问作者AkitoSilver
相关产品推荐
相关产品推荐

