「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的做法。
如非注明,原创内容遵循GFDLv1.3发布;其中的代码遵循GPLv3发布。