【前端算法系列】分而治之

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)
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值