LeetCode 141环形链表:反转链表解法原理及疑问解答
针对LeetCode 141题《环形链表》的反转链表解法,我们先拆解核心疑问,再分析整体逻辑:
核心疑问解答:无环链表反转后原head的next为何是NULL?
看reverseList函数的执行步骤,第一步就直接修改了原head节点的next指针:
void reverseList(ListNode *head) { ListNode *temp = head; ListNode *next = head->next; head->next = NULL; // 这里直接把原head的next设为NULL // ...后续反转逻辑 }
在无环链表的反转过程中,后续的操作仅修改后续节点(原链表的第二个及以后节点)的next指针,不会再触碰原head节点的next。比如原链表是head -> A -> B -> C -> NULL:
- 初始阶段,
head->next被设为NULL; - 后续依次将A的next指向head,B的next指向A,C的next指向B,最终原head变成反转后链表的尾节点,其
next保持为NULL。
这就是无环时原head->next为NULL的原因。
该解法的整体运行逻辑
这个解法的核心思路是利用无环链表和环形链表反转后的状态差异:
无环链表的情况
反转后原head成为尾节点,next为NULL,对应hasCycle函数中head->next == NULL,返回false,符合预期。
环形链表的情况
如果链表存在环,反转过程中不会出现next为NULL的节点,你提供的代码中reverseList函数的循环条件是while(temp != NULL),这其实存在问题——环形链表中next永远不会为NULL,循环会一直执行,无法正常返回。
实际上正确的反转链表判断环的逻辑应该是:在反转过程中检查当前节点是否回到原head,如果回到了,说明存在环(因为无环链表反转时永远不会回到原head),此时立即终止反转并返回true。你提供的代码可能存在实现疏漏,正确的逻辑应该在反转时加入环的检测,而不是依赖反转后判断原head的next。
补充说明
你提供的代码中reverseList函数的参数是传值(ListNode *head),函数内部的head是局部副本,不会修改外部hasCycle函数中的head指针指向,这也是原head的next状态能被直接用来判断的原因——外部的head始终指向原链表的头节点。
内容的提问来源于stack exchange,提问作者Abdalla Abdelsabour

