LeetCode题解 - 树
树
树的遍历框架*
/* 二叉树遍历框架 */
void traverse(TreeNode root) {
// 前序遍历
traverse(root.left)
// 中序遍历
traverse(root.right)
// 后序遍历
}
101.对称二叉树
- 递归
class Solution {
public:
bool isSymmetric(TreeNode* root) {
return check(root, root);
}
bool check(TreeNode* Node1, TreeNode* Node2)
{
if (Node1 == nullptr && Node2 == nullptr) return true;
if (Node1 == nullptr || Node2 == nullptr) return false;
return (Node1->val == Node2->val) && check(Node1->left, Node2->right) && check(Node1->right, Node2->left);
}
};
- 迭代
一层一层地放入队列
终止迭代:continue
class Solution {
public:
bool isSymmetric(TreeNode* root) {
return check(root, root);
}
bool check(TreeNode* Node1, TreeNode* Node2)
{
queue<TreeNode*> myQue;
myQue.push(Node1);
myQue.push(Node2);
while (!myQue.empty())
{
auto temp1 = myQue.front();
myQue.pop();
auto temp2 = myQue.front();
myQue.pop();
if (!temp1 && !temp2) continue;//终止当前迭代
if (!temp1 || !temp2) return false;
if (temp1->val != temp2->val) return false;
myQue.push(temp1->right);
myQue.push(temp2->left);
myQue.push(temp1->left);
myQue.push(temp2->right);
}
return true;
}
};
104.二叉树的最大深度
- 递归
父树深度 = 子树深度 + 1
class Solution {
public:
int maxDepth(TreeNode* root) {
if (root == nullptr) return 0;
return max(maxDepth(root->left), maxDepth(root->right)) + 1;
}
};
- 迭代
一层一层地放入队列
用size作为标记,标记每层是否遍历完毕
class Solution {
public:
int maxDepth(TreeNode* root) {
if (root == nullptr) return 0;
int count = 0;
queue<TreeNode*> que;
que.push(root);
while(!que.empty())
{
for (int i = que.size() - 1; i >= 0; i--)
{
auto node = que.front();
que.pop();
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
}
count++;
}
return count;
}
};
226.翻转二叉树
- 写法1
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if (root == nullptr) {
return nullptr;
}
TreeNode* temp = root->left;
root->left = root->right;
root->right = temp;
invertTree(root->left);
invertTree(root->right);
return root;
}
};
- 写法2
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if (root == nullptr) return nullptr;
TreeNode* r = invertTree(root->right);
TreeNode* l = invertTree(root->left);
root->left = r;
root->right = l;
return root;
}
};
543.二叉树的直径
- 递归
class Solution {
public:
int res = 0;
int diameterOfBinaryTree(TreeNode* root) {
depth (root);
return res;
}
int depth(TreeNode* root)
{
if (root == nullptr) return 0;
int L = depth(root->left);
int R = depth(root->right);
res = max(L + R, res);//比较当前子树的深度和此前的最大深度,取其大者
return max(L, R) + 1;//返回深度
}
};
617.合并二叉树
class Solution {
public:
TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
if (!t1) return t2;
if (!t2) return t1;
TreeNode* sumTree = new TreeNode(t1->val + t2->val);
sumTree->left = mergeTrees(t1->left, t2->left);
sumTree->right = mergeTrees(t1->right, t2->right);
return sumTree;
}
};
98.验证二叉搜索树
- 递归
- 利用不等关系,递归判断
- root的整个左子树都要小于root.val,整个右子树都要大于root.val
- 使用辅助函数,增加函数参数列表,在参数中携带额外信息(root信息),将这种约束传递给子树的所有节点
class Solution {
public:
bool isValidBST(TreeNode* root) {
return isValid(root, nullptr, nullptr);
}
bool isValid(TreeNode* root, TreeNode* minNode, TreeNode* maxNode)
{
if (root == nullptr) return true;
if (minNode != nullptr && root->val <= minNode->val) return false;
if (maxNode != nullptr && root->val >= maxNode->val) return false;
return isValid(root->left, minNode, root) && isValid(root->right, root, maxNode);//此处的root是关键。
}
};
- 中序遍历
- 根据二叉搜索树的定义,不难知道,树的中序遍历是升序排列的
- 首先中序遍历输出数组,在判断数组是否是升序即可
操作(root->left) 操作(root) 操作(root->right)
class Solution {
public:
bool isValidBST(TreeNode* root) {
if (root == nullptr) return true;
vector<TreeNode*> res;//直接存数也可以
inorder(root, res);
for (int i = 1; i < res.size(); ++i)
{
if (res.at(i - 1)->val >= res.at(i)->val)
return false;
}
return true;
}
void inorder(TreeNode* root, vector<TreeNode*>& res)
{
if (root == nullptr) return;
inorder(root->left, res);//左
res.push_back(root);//存
inorder(root->right,res);//右
}
};
114.二叉树展开为链表
class Solution {
public:
void flatten(TreeNode* root) {
if (root == nullptr) return;
flatten(root->left);//拉平左侧
flatten(root->right);//拉平右侧
auto rightTemp = root->right;
root->right = root->left;//把左侧复制到根节点右边
root->left = nullptr;//原本左侧置空
auto cur = root;
while (cur->right)
{
cur = cur->right;
}
cur->right = rightTemp;//把原本拉平的右侧接到末尾
}
};
116.填充每个节点的下一个右侧节点指针
class Solution {
public:
Node* connect(Node* root) {
if (root == nullptr) return nullptr;
makeConnect(root->left, root->right);
return root;
}
void makeConnect(Node* N1, Node* N2)
{
if (N1 == nullptr || N2 == nullptr) return;
N1->next = N2;
makeConnect(N1->left, N1->right);//左子树的左节点连接左子树的右节点
makeConnect(N1->right, N2->left);//左子树的右节点连接右子树的左节点
makeConnect(N2->left, N2->right);//右子树的左节点连接右子树的右节点
}
};
654.最大二叉树
class Solution {
public:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
if (nums.empty()) return nullptr;
return construct(nums, 0, nums.size() - 1);
}
TreeNode* construct(vector<int>& nums, int lo, int hi)
{
if (lo > hi) return nullptr;
int maxValue = INT_MIN;
int index = -1;
for (int i = lo; i <= hi; ++i)
{
if (nums[i] > maxValue)
{
maxValue = nums[i];
index = i;
}
}
TreeNode* root = new TreeNode(maxValue);
root->left = construct(nums, lo, index - 1);
root->right = construct(nums, index + 1, hi);
return root;
}
};
持续更新ing
GitHub:SongHuaxiong/LeetCode
可下载完整文档
欢迎 Fork & Start