Table of Contents
平时工作里都是每个变量单独声明赋值的,今天刷 leetcode 的时候用了连续赋值,然后就踩坑了。
问题
题目是:109. 有序链表转换二叉搜索树。
解法:
/**
快慢指针找中点
*/
var sortedListToBST = function(head) {
if (!head) return head
if (!head.next) {
head.left = null
head.right = null
return head
}
// let fast = slow = head
let fast = head
let slow = head
let pre = null
// 找中点
while(fast && fast.next) {
pre = slow
slow = slow.next
fast = fast.next.next
}
// 断开左侧
if (pre) pre.next = null
slow.left = sortedListToBST(head)
slow.right = sortedListToBST(slow.next)
return slow
}
声明赋值变量 fast 和 slow 的时候,第一次用的连续赋值,这导致解答错误。
[-10,-3,0,5,9] => [-3, -10]
换成分别声明赋值后才正确。
[-10,-3,0,5,9] => [0,-3,9,-10,null,5]
探索
连续声明赋值语句:let fast = slow = head 等于 let fast = (slow = head)。在函数 while 循环里开始和结束的位置打印出相关变量后发现,第一轮是没有问题的,问题在进入递归以后。
猜测进入递归以后的 slow 使用的是上一轮声明的 slow。
测验:
function test(end) {
let a = b = { a: 1 }
console.log(JSON.stringify(b))
if (end) {
b = 1
return
} else {
test(true)
}
console.log(JSON.stringify(b))
}
test()
// {"a":1}
// {"a":1}
// 1
第二轮的 b 影响了第一轮里的 b,这说明猜测是对的。连续声明赋值时,引擎从右往左执行,遇到已经存在的变量会直接使用。