链表反转算法中变量初始化位置引发超时问题咨询
反转链表实现的问题解析
正确代码的工作原理
先看能正常运行的反转链表实现:
const reverseList = (head) => { let curr = head; let prev = null; while(curr !== null){ let next = curr.next; curr.next = prev; prev = curr; curr = next } return prev; };
它的执行逻辑拆解:
- 初始化
curr指向链表的头节点,prev设为null(反转后的链表尾节点需要指向null) - 循环遍历整个链表,直到
curr变为null(遍历到原链表的末尾) - 每次循环的核心操作:
- 用
next临时保存当前节点的下一个节点——这一步很关键,因为接下来要修改curr.next,如果不提前保存,就会丢失后续节点的引用,没法继续遍历 - 把当前节点的
next指向prev,完成当前节点的反转(让它指向之前已经反转好的链表部分) - 将
prev更新为当前节点,因为下一个节点反转后要指向它 - 将
curr移动到之前保存的next节点,继续处理下一个节点
- 用
- 循环结束时,
curr已经走到原链表末尾的null,而prev就是反转后的链表头节点,返回它即可
错误代码超时的原因
再看你修改后超时的代码:
const reverseList = (head) => { let curr = head; let prev = null; let next = curr.next; while(curr !== null){ curr.next = prev; prev = curr; curr = next } return prev; };
问题根本不是作用域(你用的是let,和var作用域无关),而是**next没有在每次循环中更新**:
- 你只在循环外初始化了一次
next,它的值是原链表头节点的下一个节点 - 第一次循环结束后,
curr被赋值为next(也就是原第二个节点),但之后的循环里,next的值再也没变化过 - 第二次循环时,执行
curr = next,curr还是原第二个节点,永远不会变成null,直接进入死循环,导致代码超时 - 必须在每次循环里重新获取当前
curr的下一个节点,所以next得在循环内部声明赋值,才能保证每次遍历都能拿到最新的后续节点引用
内容的提问来源于stack exchange,提问作者Mathias
相关产品推荐
相关产品推荐

