翻转二叉树,感觉做二叉树的问题好像都是那一套公式,除了个别的问题解决不了,用上篇博客leetcode刷题之树(二)的模型基本可以解决。总体来说就是树基本都可以利用递归和迭代的方法去解决,在涉及到树的遍历的时候偏向于利用栈来存储数据,在求和树的层次相关的问题时偏向于利用队列来存储数据。 个人感觉迭代更好理解,因为递归涉及回溯
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
queue<TreeNode*>s;
s.push(root);
if(root==NULL)
return root;
while(!s.empty())
{ TreeNode*h=s.front();
TreeNode* temp=NULL;
temp=h->left;
h->left=h->right;
h->right=temp;
s.pop();
if(h->left!=NULL)
s.push(h->left);
if(h->right!=NULL)
s.push(h->right);
}
return root;
}
};
递归解决代码较少,理解起来不如用队列。
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if(root==NULL)
return root;
TreeNode* temp;
temp=root->left;
root->left=invertTree(root->right);
root->right=invertTree(temp);
return root;
}
};
这道题我按照官方思路,写成c++的形式,应该是哈希表定义的不对,老提示我有错误,说stl库里没有insert这个函数,以后再解决。
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
queue<TreeNode*> s;
unordered_map<TreeNode*,TreeNode*> parent;
parent.insert(root,NULL);
s.push(root);
while(!parent.find(p) ||!parent.find(q))
{
TreeNode* node=s.top();
s.pop();
if(node->left!=NULL)
{
parent.insert(node->left,node);
s.push(node->left);
}
if(node->right!=NULL)
{
parent.insert(node->right,node);
s.push(node->right);
}
}
set<TreeNode*>ancestors;
while (p!=NULL)
{
ancestors.insert(p);
p=parent.find(p);
}
while(!ancestors.find(q))
q=parent.find(q);
return q;
}
};
这个题比较抽象想到了就很好解决,属于树得动态规划问题。
class Solution {
public:
pair<int, int> dfs(TreeNode *root) {
if (root == nullptr) {
return { 0, 0 };
}
auto left_pair = dfs(root->left);
auto right_pair = dfs(root->right);
return { root->val + left_pair.second + right_pair.second,
max(left_pair.first, left_pair.second) + max(right_pair.first, right_pair.second) };
}
int rob(TreeNode* root) {
auto p = dfs(root);
return max(p.first, p.second);
}
};
//(1)当前结点选择偷+左右孩子不偷能拿出的钱
//(2)当前结点不偷即求左右孩子最多能偷到的钱