二叉树常见算法题

44 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第31天,点击查看活动详情

98. 验证二叉搜索树

首先看一下二叉搜索树的定义,

  • 节点的左子树只包含 小于 当前节点的数。
  • 节点的右子树只包含 大于 当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

简单来说就是:左子树<根节点<右子树,所有子树也满足这个点

根据这个条件,我们发现和中序遍历顺序一致,那么只要中序遍历是升序,那么一定是二叉搜索树。也就是中序遍历过程中,一旦出现降序或相等,则不是二叉搜索树

var isValidBST = function(root) {
    if (!root) {
        return true
    }
    let inorder = -Infinity
    let stack = []
    while(root || stack.length) {
        while(root) {
            stack.push(root)
            root = root.left
        }
        root = stack.pop()
        // 左节点 = 右节点值 不算二叉搜索树
        if (root.val <= inorder) {
            return false
        }
        inorder = root.val
        root = root.right
    }
    return true
};

image.png

102. 二叉树的层序遍历

和前中后序遍历不同的是,层序遍历需要遵循先进先出规则,所以需要用到队列结构,每遍历到一个节点,先判断是否有左右节点,有则入队

var levelOrder = function(root) {
    if (!root) {
        return []
    }
    let queen = []
    let res = []
    queen.push(root)
    while(queen.length) {
        let len = queen.length
        res.push([])
        for (let i = 0; i < len; i++) {
            let item = queen.shift()
            res[res.length - 1].push(item.val)
            item.left && queen.push(item.left)
            item.right && queen.push(item.right)
        }
    }
    return res
};

image.png

107. 二叉树的层序遍历 II

与上题不同点在于,本题是自底向上遍历。

最简单的方案当然是在上题的基础上直接将结果reverse。但其实调用一遍reverse有些多余,在遍历过程中,可以在每次加入结果时,改成向头部添加,这样后面遍历到的层级会添加到前面,就完成了反向遍历,代码如下:

var levelOrderBottom = function(root) {
    if (!root) {
        return []
    }
    let queen = []
    let res = []
    queen.push(root)
    while(queen.length) {
        let len = queen.length
        res.unshift([])
        for (let i = 0; i < len; i++) {
            let item = queen.shift()
            res[0].push(item.val)
            item.left && queen.push(item.left)
            item.right && queen.push(item.right)
        }
    }
    return res
};

image.png