110.平衡二叉树
思路:平衡二叉树是所有节点的左右子树深度相差小于1,可以理解为左右节点的高度相差小于1。求节点深度可以使用前序遍历和后序遍历,但后序遍历好写一点。可以在递归过程中就判断是否为平衡二叉树,也可以单纯使用递归求节点高度,然后在遍历二叉树节点时候进行判断。
题解:
递归法后序遍历:
class Solution {
public:
int getdepth(TreeNode *node)
{
if (node == nullptr) return 0;
int leftdepth = getdepth(node->left);
int rightdepth = getdepth(node->right);
if (leftdepth == -1) return -1;
if (rightdepth == -1) return -1;
if (abs(leftdepth - rightdepth) > 1)
return -1;
else
return 1 + max(leftdepth, rightdepth);
}
bool isBalanced(TreeNode* root) {
return getdepth(root) == -1 ? false : true;
}
};
递归法后序遍历求节点深度,前序遍历二叉树进行判断:
class Solution {
public:
int getdepth(TreeNode *node)
{
if (node == nullptr) return 0;
int leftdepth = getdepth(node->left);
int rightdepth = getdepth(node->right);
return 1 + max(leftdepth, rightdepth);
}
bool isBalanced(TreeNode* root) {
stack<TreeNode*> st;
if (root == nullptr) return true;
st.push(root);
while(!st.empty())
{
TreeNode *node = st.top();
st.pop();
int leftheight = getdepth(node->left);
int rightheight = getdepth(node->right);
if (abs(leftheight - rightheight) > 1)
return false;
if (node->right) st.push(node->right);
if (node->left) st.push(node->left);
}
return true;
}
};
257. 二叉树的所有路径
思路:处理节点和访问节点相同,使用前序遍历,方便从根节点到子节点。
题解:
递归法前序遍历:
class Solution {
public:
void traversal(TreeNode *node, vector<int>&path, vector<string>&res)
{
path.push_back(node->val);
if (node->left==nullptr && node->right==nullptr)
{
string spath;
for (int i=0; i < path.size()-1; ++i)
{
spath += to_string(path[i]);
spath += "->";
}
spath += to_string(path[path.size()-1]);
res.push_back(spath);
return;
}
if (node->left)
{
traversal(node->left, path, res);
path.pop_back();
}
if (node->right)
{
traversal(node->right, path, res);
path.pop_back();
}
}
vector<string> binaryTreePaths(TreeNode* root) {
vector<int> path;
vector<string> res;
traversal(root, path, res);
return res;
}
};
迭代法前序遍历:
class Solution {
public:
vector<string> binaryTreePaths(TreeNode* root) {
stack<TreeNode*> st;
stack<string> stpath;
vector<string> res;
if (root == nullptr) return res;
st.push(root);
stpath.push(to_string(root->val));
while(!st.empty())
{
TreeNode* node = st.top();
st.pop();
string path = stpath.top();
stpath.pop();
if (!node->left && !node->right) res.push_back(path);
if (node->right)
{
st.push(node->right);
stpath.push(path + "->" + to_string(node->right->val));
}
if (node->left)
{
st.push(node->left);
stpath.push(path + "->" + to_string(node->left->val));
}
}
return res;
}
};
404.左叶子之和
思路:一个节点的左节点不为空,左节点的左右节点为空,则该节点的左节点为左叶子节点。递归的话,因为需要对返回值进行累加,所以使用后序遍历,而遍历的情况,前中后序都可以,在遍历时判断处理节点是否满足左叶子节点条件即可。
题解:
递归后序遍历:
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
if (root == nullptr) return 0;
if (root->left != nullptr && root->left->left == nullptr && root->left->right == nullptr)
return root->left->val + sumOfLeftLeaves(root->right);
return sumOfLeftLeaves(root->left) + sumOfLeftLeaves(root->right);
}
};
迭代前序遍历:
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
int res{0};
stack<TreeNode*> st;
if (!root) return res;
st.push(root);
while(!st.empty())
{
TreeNode* node = st.top();
st.pop();
if (node->left && !node->left->left && !node->left->right)
res += node->left->val;
if (node->right) st.push(node->right);
if (node->left) st.push(node->left);
}
return res;
}
};
222.完全二叉树的节点个数
思路:不利用完全二叉树特性,即求普通二叉树的节点个树可以考虑递归后序遍历,层序遍历求节点个数。利用完全二叉树特性,则可以利用必有子树是满二叉树的特性减少遍历的节点数。
题解:
普通二叉树递归后序遍历:
class Solution {
public:
int countNodes(TreeNode* root) {
if (!root) return 0;
return 1 + countNodes(root->left) + countNodes(root->right);
}
};
普通二叉树层序遍历:
class Solution {
public:
int countNodes(TreeNode* root) {
queue<TreeNode*> que;
int res{0};
if (!root) return res;
que.push(root);
while(!que.empty())
{
TreeNode* node = que.front();
que.pop();
++res;
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
}
return res;
}
};
完全二叉树递归后序遍历:
class Solution {
public:
int countNodes(TreeNode* root) {
if (root == nullptr) return 0;
TreeNode *left = root -> left;
TreeNode *right = root -> right;
int leftlen = 0;
int rightlen = 0;
while (left)
{
left = left -> left;
++leftlen;
}
while (right)
{
right = right -> right;
++rightlen;
}
if (leftlen == rightlen)
return (2 << leftlen) - 1;
return 1 + countNodes(root->left) + countNodes(root->right);
}
};