Leetcode 刷题总结——树
1. 二叉树的中序遍历(非递归版)
点我
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
inOrder(root, res);
return res;
}
void inOrder(TreeNode* root, vector<int>& res){
// 使用栈
stack<TreeNode*> st;
TreeNode *p = root;
while(p || !st.empty()){
if(p){
st.push(p);
p = p->left;
}
else{
TreeNode *node = st.top();
st.pop();
res.push_back(node->val);
p = node->right;
}
}
}
};
2. 二叉树的前序遍历(非递归版)
点我
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
// 原来是已经建好树了
vector<int> res;
stack<TreeNode*> st;
TreeNode* p = root;
while(p || !st.empty()){
if(p){
st.push(p);
// 访问p
res.push_back(p->val);
p = p->left;
}
else{
// 弹栈,访问右孩子
p = st.top();
st.pop();
p = p->right;
}
}
return res;
}
};
3. 二叉树的后序遍历(非递归版)
点我
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> res;
TreeNode* p = root;
stack<TreeNode*> st;
TreeNode* r = nullptr;
while(p || !st.empty()){
if(p){
st.push(p);
p = p->left;
}
else{
// 需要左右孩子都访问完成,才能弹栈
// 此时左孩子已经访问完成
// 检查是否有右孩子,要记录是否访问过右孩子
// 只需要记下上次访问的结点就可以
p = st.top();
if(p->right && p->right != r){
p = p->right;
}else{
// 弹栈访问
p = st.top();
st.pop();
res.push_back(p->val);
r = p;
p = nullptr; // 每次访问完一个节点,相当于遍历完以该节点为根的子树
}
}
}
return res;
}
};
4. 比较两棵树是否相同
注意节点的值并不是两两不同,因此不能使用前序+中序序列相同来判断。
其实关于树的题目,一个很自然的思路就是 递归!
点我
class Solution {
public:
// 很自然的想法是递归,枯了
bool isSameTree(TreeNode* p, TreeNode* q) {
if(!p && !q) return true;
if(!p || !q) return false;
if(p->val == q->val)
return (isSameTree(p->left, q->left) && isSameTree(p->right, q->right));
else
return false;
}
};
5. 对称二叉树
要梳理好思路,找到可以递归的点在哪里。
现将 评论区haventmetyou大佬的指点 总结如下:
一棵树是否对称→左树、右树是否对称→左树左孩、右树右孩是否对称 && 左树右孩、右树左孩是否对称(此时句法结构已经体现出递归的解决思路了)。
其实还有迭代版本~(后续补)
下面是我自己的实现:
点我
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if(!root) return true;
return leftRightSymmetric(root->left, root->right);
}
bool leftRightSymmetric(TreeNode* p, TreeNode* q){
if(!p && !q) return true;
if(!p || !q) return false;
if(p->val == q->val)
return leftRightSymmetric(p->left, q->right) && leftRightSymmetric(p->right, q->left);
else
return false;
}
};
6. 将有序数组转换为二叉树
已知中序序列,建立一棵平衡二叉树。递归找根。
点我
class Solution {
public:
TreeNode* sortedArrayToBST(vector<int>& nums) {
return buildBalancedTreeByInOrderSequence(nums, 0, nums.size()-1);
}
TreeNode* buildBalancedTreeByInOrderSequence(vector<int>& nums, int start, int end){
if(start <= end){
int mid = (start+end) / 2; // 闭区间
int rootVal = nums[mid];
TreeNode* p = new TreeNode(rootVal);
p->left = buildBalancedTreeByInOrderSequence(nums, start, mid - 1);
p->right = buildBalancedTreeByInOrderSequence(nums, mid + 1, end);
return p;
}
else
return nullptr;
}
};
7. 二叉树的最小深度
深搜。
点我
class Solution {
public:
int minDepth(TreeNode* root) {
if(root == nullptr) return 0;
if(root->left == nullptr) return minDepth(root->right) + 1;
if(root->right == nullptr) return minDepth(root->left) + 1;
return min(minDepth(root->left), minDepth(root->right)) + 1;
}
};
8. 路径总和
点我
class Solution {
public:
bool hasPathSum(TreeNode* root, int targetSum) {
if(root == nullptr){
return false;
}
return pathcount(root, targetSum); //这个位置写得略冗余
}
bool pathcount(TreeNode* root, int targetSum){
//当前节点是叶子节点
if(root->left == nullptr && root->right == nullptr && targetSum == root->val){
return true;
}
else{
bool leftExist = false, rightExist = false;
if(root->left)
leftExist = pathcount(root->left, targetSum - root->val);
if(root->right)
rightExist = pathcount(root->right, targetSum - root->val);
return leftExist || rightExist;
}
}
};
9. 翻转二叉树
对于每个节点,翻转其左右子树。
点我
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if(root == nullptr) return nullptr;
// 对于一个节点,他的左子树和右子树都要翻转
TreeNode* left = nullptr, *right = nullptr;
if(root->left)
left = invertTree(root->left);
if(root->right)
right = invertTree(root->right);
// 交换左右子树
root->left = right;
root->right = left;
return root;
}
};

leetcode狗狗重拳出击。
浙公网安备 33010602011771号