374. 猜数字大小
使用二分查找,来找出目标数字
/* 时间复杂度:O(logN) 每次还是缩小一半范围,执行次数是logN次
空间复杂度:递归是调用堆栈,在栈里面变量是要被存起来的,没有被释放,变量存储的值是线性增长,
执行次数要看递归堆栈多少层 O(logN),建议不用递归,用while
*/
var guessNumber = function(n) {
const rec = (low, high) => {
// 递归终结条件
if(low > high) return;
const mid = Math.floor((low+high)/2)
const res = guess(mid) // 放入猜的数字去判断大小
if(res === 0){ // 目标数字等于我猜的数字
return mid
}else if(res === 1){ // 目标数字大于我猜的数字,所以+1在右边找
// 缩小范围,递归到相似的但是更小的小问题上去解决
return rec(mid+1, high)
}else{ // -1 目标数字大于我猜的数字,所以-1在左侧找
return rec(1, mid-1)
}
}
return rec(1, n)
}
226. 翻转二叉树
先翻转左右子树,再将子树换个位置
分:获取左右子树
解:递归地翻转左右子树
合:将翻转后的左右子树换个位置放到根节点上
/* 时间复杂度:树的每个节点都访问到了,所以是O(n)
空间复杂度:递归是调用堆栈,线性增长趋势,O(h) h是这棵树的高度,递归多少层
*/
var invertTree = function(root) {
// 递归终结条件:叶子节点没有左右子节点
if(!root) return null;
return {
val:root.val,
left: invertTree(root.right),
right: invertTree(root.left)
}
}
100. 相同的树
两个树相等:即根节点的值相同,左子树相同,右子树相同
分:获取两个树的左子树和右子树
解:递归地判断两个数的左、右子树是否相同,树就相同
合:将上述结果合并,如果根节点的值也相同,树就相同
/* 时间复杂度:是递归且遍历了树的所有节点,所以是O(n)
空间复杂度:递归,内部形成调用堆栈,线性增长趋势,O(h) h是这棵树的高度,递归多少层
*/
var isSameTree = function(p, q) {
if(!p&&!q) return true
if(p && q && p.val===q.val &&
isSameTree(p.left, q.left) && // 左子树相同
isSameTree(p.right, q.right) // 右子树相同
){
return true
}
return false
}
101. 对称二叉树
转化为:左右子树是否镜像
分解:树1的左子树和树2的右子树是否镜像,树1的右子树和树2的左子树是否镜像,如果都成立且根节点值还相同就是对称二叉树
分:获取两个树的左子树和右子树
解:递归地判断树1的左子树和树2的右子树是否镜像,树1的右子树和树2的左子树是否镜像
/* 时间复杂度:是递归且遍历了树的所有节点,所以是O(n)
空间复杂度:递归,内部形成调用堆栈,线性增长趋势,O(h) h是这棵树的高度,递归多少层
*/
var isSymmetric = function(root) {
if(!root) return true;
const isMirror = (l, r) =>{ // l树1,r树2
// 递归终点
if(!l && !r) return true;
if(l&&r&&l.val === r.val &&
isMirror(l.left, r.right) && // 树1的左边和树2的右边是否镜像,且值是否相等
isMirror(l.right, r.left) // 树1的右边和树2的左边是否镜像,且值是否相等
){
return true
}
return false
}
return isMirror(root.left, root.right)
}