作者:TeddyZhang,公众号:算法工程师之路
二叉树问题(一):
LeetCode # 110 617 101 814 655 98 654
1
编程题
【LeetCode #110】平衡二叉树
给定一个二叉树,判断它是否是高度平衡的二叉树。 本题中,一棵高度平衡二叉树定义为: 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1
解题思路:自上而下递归得到每个子树的高度,依据定义即可。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int height(TreeNode* node) {
if (node == nullptr) return ;
return max(height(node->left), height(node->right)) + ;
}
bool isBalanced(TreeNode* root) {
if (root == nullptr) return true;
int left = height(root->left);
int right = height(root->right);
return abs(left-right) <= && isBalanced(root->left) && isBalanced(root->right);
}
};
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/balanced-binary-tree/
【LeetCode #617】合并二叉树
给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。 你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
if (t1 == nullptr) return t2;
if (t2 == nullptr) return t1;
if (t1 && t2) {
t1->val += t2->val;
t1->left = mergeTrees(t1->left, t2->left);
t1->right = mergeTrees(t1->right, t2->right);
return t1;
}else return nullptr;
}
};
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/merge-two-binary-trees
【LeetCode #101】对称二叉树
给定一个二叉树,检查它是否是镜像对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
1 / \ 2 2 / \ / \ 3 4 4 3
class Solution {
public:
bool dfs(TreeNode* left, TreeNode* right) {
if (left == nullptr && right == nullptr)
return true;
if (!left || !right)
return false;
if (left->val != right->val){
return false;
} else {
return dfs(left->left, right->right) && dfs(left->right, right->left);
}
}
bool isSymmetric(TreeNode* root) {
return dfs(root, root);
}
};
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/symmetric-tree
【LeetCode #814】二叉树剪枝
给定二叉树根结点 root ,此外树的每个结点的值要么是 0,要么是 1。
返回移除了所有不包含 1 的子树的原二叉树。
( 节点 X 的子树为 X 本身,以及所有 X 的后代。)
示例1: 输入: [1,null,0,0,1] 输出: [1,null,0,null,1]
解题思路:
遍历的查找每个节点,然后判断该二叉树的某个子树中是否存在节点值为1的数字,如果存在,则对应子树的根节点置为nullptr,否则就不变化。
class Solution {
public:
bool containOne(TreeNode* root) {
if (root == nullptr) return false;
bool ll = containOne(root->left);
bool rr = containOne(root->right);
if (!ll) {
root->left = nullptr;
}
if (!rr) {
root->right = nullptr;
}
return ll || rr || root->val == ;
}
TreeNode* pruneTree(TreeNode* root) {
containOne(root);
return root;
}
};
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/binary-tree-pruning
【LeetCode #655】输出二叉树
在一个 m*n 的二维字符串数组中输出二叉树,并遵守以下规则:
行数 m 应当等于给定二叉树的高度。 列数 n 应当总是奇数。 根节点的值(以字符串格式给出)应当放在可放置的第一行正中间。根节点所在的行与列会将剩余空间划分为两部分(左下部分和右下部分)。你应该将左子树输出在左下部分,右子树输出在右下部分。左下和右下部分应当有相同的大小。即使一个子树为空而另一个非空,你不需要为空的子树输出任何东西,但仍需要为另一个子树留出足够的空间。然而,如果两个子树都为空则不需要为它们留出任何空间。 每个未使用的空间应包含一个空的字符串""。 使用相同的规则输出子树。
示例 1: 输入: 1 / 2 输出: [["", "1", ""], ["2", "", ""]]
解题思路:
首先求出二叉树的高度m,进而得到n = pow(1, m)-1; 然后我们二分的进行输出到二维vector中,使用二分法。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<string>> printTree(TreeNode* root) {
int m = getHeight(root);
int n = pow(, m) - ;
vector<vector<string>> res(m, vector<string>(n, ""));
dfsPrint(root, res, , , n-1);
return res;
}
private:
int getHeight(TreeNode* node) {
if (node == nullptr) return ;
return max(getHeight(node->left), getHeight(node->right)) + ;
}
void dfsPrint(TreeNode* root, vector<vector<string>>& res, int row, int start, int end) {
if(!root || (start > end)) return;
int mid = start + (end - start) / ;
res[row][mid] = to_string(root->val);
dfsPrint(root->left, res, row+, start, mid);
dfsPrint(root->right, res, row+, mid+, end);
}
};
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/print-binary-tree
【LeetCode #98】验证二叉搜索树
给定一个二叉树,判断其是否是一个有效的二叉搜索树。 假设一个二叉搜索树具有如下特征:
示例 1: 输入: 2 / \ 1 3 输出: true
解题思路:
复习中序遍历,对二叉树进行中序遍历,并使用pre节点储存当前节点的上一节点,然后保证边界结果为递增序列即可!
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isValidBST(TreeNode* root) {
stack<TreeNode*> sta;
TreeNode* pre = nullptr;
TreeNode* cur = root;
while(cur != nullptr || !sta.empty()) {
if (cur != nullptr) {
sta.push(cur);
cur = cur->left;
}else {
cur = sta.top();
sta.pop();
if (pre && (pre->val >= cur->val)) {
return false;
}
pre = cur;
cur = cur->right;
}
}
return true;
}
};
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/validate-binary-search-tree
【LeetCode #654】最大二叉树
给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下:
二叉树的根是数组中的最大元素。
解题思路:
首先找到最大值,然后构建结点,从最大值位置分成两个区间,然后分别使用相应的区间构造root的左右子树,递归构造即可!
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
if(nums.size() == ) return nullptr;
auto it = max_element(nums.begin(), nums.end());
TreeNode* root = new TreeNode(*it);
vector<int> ll(nums.begin(), it);
vector<int> rr(it+, nums.end());
root->left = constructMaximumBinaryTree(ll);
root->right = constructMaximumBinaryTree(rr);
return root;
}
};
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/maximum-binary-tree