打卡-算法训练营-Day17 |654.最大二叉树; 617.合并二叉树;700.二叉搜索树中的搜索;98.验证二叉搜索树

62 阅读1分钟

最大二叉树

leetcode链接:leetcode.cn/problems/ma…

思路与上一篇的构造二叉树一致,会更简单些,只用操作一个数组就行

var constructMaximumBinaryTree = function(nums) {
  if (!nums.length) return null;

  let rootValue = Math.max(...nums);
  let root = new TreeNode(rootValue);
  let rootIndex = nums.indexOf(rootValue);

  let leftTree = nums.slice(0, rootIndex);
  let rightTree = nums.slice(rootIndex + 1);

  root.left = constructMaximumBinaryTree(leftTree);
  root.right = constructMaximumBinaryTree(rightTree);

  return root;
};

合并二叉树

leetcode链接:leetcode.cn/problems/me…

简单题,想清楚节点的三种情况怎么处理就行

var mergeTrees = function(root1, root2) {
  if (!root1 && !root2) return null;

  let root;
  
  if (root1 && root2) {
    let newValue = root1.val + root2.val;
    root = new TreeNode(newValue);
    root.left = mergeTrees(root1.left, root2.left);
    root.right = mergeTrees(root1.right, root2.right);
  }

  if (root1 === null) {
    root = new TreeNode(root2.val);
    root.left = root2.left;
    root.right = root2.right;
  }

  if (root2 === null) {
    root = new TreeNode(root1.val);
    root.left = root1.left;
    root.right = root1.right;
  }

  return root;
};

二叉搜索树中的搜索

leetcode链接:leetcode.cn/problems/se…

二叉搜索树有一个很重要的特性:二叉搜索树的中序遍历结果一定是递增的

通过判断当前节点值与目标值的大小,确定往左边还是右边走

// 递归法
var searchBST = function(root, val) {
    if (!root || root.val === val) return root;
    if (root.val > val) {
        return searchBST(root.left, val);
    }
    if (root.val < val) {
        return searchBST(root.right, val);
    }
};

// 迭代法
var searchBST = function(root, val) {
    while (root !== null) {
        if (root.val > val) {
            root = root.left;
        } else if (root.val < val) {
            root = root.right;
        } else {
            return root;
        }
    }
    return null;
};

验证二叉搜索树

leetcode链接:leetcode.cn/problems/va…

方法一:利用搜索二叉树的中序遍历特性

var isValidBST = function(root) {
    let arr = [];
    // 将中序遍历结果放入数组中
    let dfs = (node) => {
        if (!node) return;
        dfs(node.left);
        arr.push(node.val);
        dfs(node.right);
    }
    dfs(root);
    
    // 判断数组是否有序
    for (let i = 1; i < arr.length; i++) {
        if (arr[i-1] >= arr[i]) {
            return false;
        }
    }
    return true;
};

方法二:双指针

多定义一个pre的指针,指向中序遍历当前节点的上一个节点

var isValidBST = function(root) {
    let pre = null;

    let dfs = (node) => {
        if (!node) return true;

        let left = dfs(node.left); // 左

        // 中
        if (pre && pre.val >= node.val) {
            return false;
        }
        pre = node;

        let right = dfs(node.right); // 右

        return left && right;
    }
    return dfs(root);
};