代码随想录算法训练营day21| 530.二叉搜索树的最小绝对差 、 501.二叉搜索树中的众数 、 236. 二叉树的最近公共祖先

 530.二叉搜索树的最小绝对差

题目链接/文章讲解/视频讲解

思路:

题目中要求在二叉搜索树上任意两节点的差的绝对值的最小值。

注意是二叉搜索树,二叉搜索树可是有序的。

遇到在二叉搜索树上求什么最值啊,差值之类的,就把它想成在一个有序数组上求最值,求差值,这样就简单多了。

代码实现:

  //递归 先转换为有序数组
    var getMinimumDifference = function (root) {
      let arr = [];
      const bulidArr = (root) => {
        if (root) {
          bulidArr(root.left)
          arr.push(root.val);
          bulidArr(root.right)
        }
      }
      bulidArr(root)
      //因为是一个有序数组 初始定义一个最大值进行比较
      let diff = arr[arr.length - 1];
      for (let i = 0; i < arr.length; i++) {
        if (diff > arr[i] - arr[i - 1]) {
          diff = arr[i] - arr[i - 1]
        }
      }
      return diff
    }
    //递归 在递归的过程中更新最小值
    var getMinimumDifference = function (root) {
      let res = Infinity
      let preNode = null;
      //中序遍历
      const inorder = (root) => {
        if (!root) {
          return
        }
        inorder(root.left);
        if (preNode) {
          res = Math.min(res, root.val - preNode.val)//3 3 

        }
        console.log(preNode)
        preNode = root// 1 4 7  
        inorder(root.right)
      }
      inorder(root)
      return res
    }
    //迭代 中序遍历
    var getMinimumDifference = function (root) {
      let stack = [];
      let pre = null;
      let cur = root;
      let res = Infinity;
      while (cur || stack.length) {
        if (cur) {
          stack.push(cur);
          cur = cur.left
        } else {
          cur = stack.pop();
          if (pre) {
            res = Math.min(res, cur.val - pre.val)
          }
          pre = cur
          cur = cur.right
        }
      }
      return res
    }


501.二叉搜索树中的众数 

题目链接/文章讲解/视频讲解

代码实现:

 // 使用额外空间map的方法
    var findMode = function (root) {
      let map = new Map()

      const searchBst = (root) => {
        if (!root) return;
        searchBst(root.left);
        map.set(root.val, map.has(root.val) ? map.get(root.val) + 1 : 1);
        searchBst(root.right)

      }
      searchBst(root)
      //上面把数据都存储到map
      //下面开始寻找map里面的
      // 定义一个最大出现次数的初始值为root.val的出现次数
      let maxCount = map.get(root.val);
      let res = [];
      for (let [key, value] of map) {
        if (value === maxCount) {
          res.push(key)
        } else if (value > maxCount) {
          // 如果value的值大于原本的maxCount就清空res的所有值,因为找到了更大的
          res = [];
          maxCount = value;
          res.push(key)
        }

      }
      return res
    };
    // 不使用额外空间,利用二叉树性质,中序遍历(有序):
    var findMode = function (root) {
      let count = 0, maxCount = 1;
      let pre = root, res = [];
      const travelTree = function (cur) {
        if (cur === null) {
          return;
        }
        travelTree(cur.left);
        if (pre.val === cur.val) {
          count++
        } else {
          count = 1
        }
        pre = cur
        if (count === maxCount) {
          res.push(cur.val)
        }
        if (count > maxCount) {
          res = [];
          maxCount = count
          res.push(cur.val)
        }
        travelTree(cur.right)
      }
      travelTree(root);
      return res
    };
    //迭代
    var findMode = function (root) {
      let count = 0, maxCount = 0;
      let cur = root, pre = null, stack = [];
      let result = [];
      while (cur || stack.length) {
        if (cur) {
          stack.push(cur)
          cur = cur.left
        } else {
          cur = stack[stack.length - 1]
          stack.pop()
          if (pre === null) {
            count = 1
          } else if (pre.val === cur.val) {
            count++
          } else {
            count = 1
          }
          if (count === maxCount) {
            result.push(cur.val)
          } else if (count > maxCount) {
            maxCount = count
            result = []
            result.push(cur.val)
          }
          pre = cur;
          cur = cur.right
        }
        return result
      }
    };

236. 二叉树的最近公共祖先 

题目链接/文章讲解/视频讲解

思路:

遇到这个题目首先想的是要是能自底向上查找就好了,这样就可以找到公共祖先了。

那么二叉树如何可以自底向上查找呢?

回溯啊,二叉树回溯的过程就是从低到上。

后序遍历(左右中)就是天然的回溯过程,可以根据左右子树的返回值,来处理中节点的逻辑。

代码实现

 var lowestCommonAncestor = function (root, p, q) {

      const travelTree = (root, p, q) => {
        if (root === q || root === p || root === null) return root
        let left = travelTree(root.left, p, q)
        let right = travelTree(root.right, p, q)
        if (left !== null && right !== null) {
          return root
        }
        if (left === null) {
          return right
        }
        return left;
      }
      return travelTree(root, p, q);
    };

总结

关于双指针回溯的问题这里需要多加注意

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值