「Leetcode」二叉搜索树相关题目简析

98. 验证二叉搜索树

这题啊有个概念上的小坑:注意了,左右子树的所有元素必须都满足相应要求!!所以朴素的做法是不能够的。
一个比较巧妙的想法是利用提供的性质,联想到中序遍历,然后中序遍历应当是一个严格递增的序列,检查这个序列即可。
但是,实际上我们并不需要构造出这个序列,只需要检查每次遍历前的上一个元素是否比当前元素小即可(递归保证我们能遍历所有元素)。
于是第二个坑:虽然数据是int范围,但是你保存的上一个元素的最小值应该是INT_MIN-1(因为完全有可能数据是[INT_MIN])。

class Solution {
    long long preVal = -2147483649;
public:
    bool isValidBST(TreeNode* root) {
        if(root == nullptr) return true;

        if(!isValidBST(root->left)) return false;

        if(preVal >= (long long)root->val) return false;
        preVal = root->val;

        if(!isValidBST(root->right)) return false;
        return true; 
    }
};

662. 二叉树最大宽度

这题也是个套路题,自己建一个struct存储深度信息与距离信息(就使用朴素的2^n定义法)即可。需要注意的是,由于深度很深,一定要使用unsigned long long 存储宽度,不然会溢出爆掉。

class Solution {
    struct QueueNode {
        TreeNode* pnt;
        unsigned long long dep;
        unsigned long long pos;
        QueueNode() = default;
        QueueNode(TreeNode* pn, unsigned long long d, unsigned long long po) :
            pnt(pn), dep(d), pos(po) {}
    };
public:
    int widthOfBinaryTree(TreeNode* root) {
        if(root == nullptr) return 0;
        queue<QueueNode> q;
        unsigned long long ans = 0, left = 0, leftdep = 0;
        q.push(QueueNode(root, 0, 0));
        while(!q.empty()) {
            auto now = q.front();
            q.pop();

            if(leftdep < now.dep) {
                leftdep = now.dep;
                left = now.pos;
            } else { // leftdep = now.dep
                left = min(left, now.pos);
            }
            if(now.pnt->left) {
                q.push(QueueNode(now.pnt->left, now.dep+1, now.pos*2));
            }
            if(now.pnt->right) {
                q.push(QueueNode(now.pnt->right, now.dep+1, now.pos*2+1));
            }
            ans = max(ans, now.pos - left + 1);
        }
        return ans;
    }
};

1339. 分裂二叉树的最大乘积

套路题。要想到这一点:分裂二叉树的实质就是把一个子树从二叉树里删去。这点想到以后问题就很简单了,遍历求出每个子树的和,然后再遍历一次求出删去每个子树后得到的代价,取最大值即可。

class Solution {
    unordered_map<TreeNode*, long long> sum;
    int treeSum(TreeNode* root) {
        if(root == nullptr) return 0;
        else return sum[root] = root->val + 
            treeSum(root->left) + treeSum(root->right);
    }
public:
    int maxProduct(TreeNode* root) {
        int tot_sum = treeSum(root);
        long long ans = -1;
        for(auto it: sum) {
            if(it.first == root) continue;
            ans = max(ans, it.second * (tot_sum - it.second));
        }

        return ans % (1000000000ll+7);
    }
};

501. 二叉搜索树中的众数

这题的朴素做法如下

# 遍历树上所有节点,然后求出最大值
class Solution:
    def __init__(self):
        self.index_ = {}

    def traverseTree(self, root: TreeNode):
        if root is None:
            return
        
        if root.val in self.index_:
            self.index_[root.val] += 1
        else:
            self.index_[root.val] = 1
        
        if root.left is not None:
            self.traverseTree(root.left)
        if root.right is not None:
            self.traverseTree(root.right)

    def findMode(self, root: TreeNode) -> List[int]:
        self.traverseTree(root)
        if self.index_.values():
            max_value = max(self.index_.values())
        else:
            return
        return [key for key, value in self.index_.items() if value == max_value]

之后补充一下不需要额外dict的做法。

posted @ 2020-09-27 22:58  ISoLT  阅读(237)  评论(0编辑  收藏  举报