110.平衡二叉树
- 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数。
- 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数。
重点:求深度可以从上到下去查 所以需要前序遍历(中左右),而高度只能从下到上去查,所以只能后序遍历(左右中)
public:
// 求深度——>前序遍历,求高度——>后序遍历
// 后序遍历+递归法
int getHeight(TreeNode* node) {
if (node == NULL) {
return 0;
}
int leftHeight = getHeight(node->left);
if (leftHeight == -1) {
return -1;
}
int rightHeight = getHeight(node->right);
if (rightHeight == -1) {
return -1;
}
return abs(leftHeight - rightHeight) > 1 ? -1 : max(leftHeight, rightHeight) + 1;
}
bool isBalanced1(TreeNode* root) {
int res = getHeight(root);
if (res == -1) {
return false;
}
else {
return true;
}
}
// 迭代法
int getDepth(TreeNode* cur) {
stack<TreeNode*> st;
if (cur != NULL) {
st.push(cur);
}
int depth = 0;
int result = 0;
while (!st.empty()) {
TreeNode* node = st.top();
if (node != NULL) {
st.pop();
st.push(node);
st.push(NULL);
depth++;
if (node->right) {
st.push(node->right);
}
if (node->left) {
st.push(node->left);
}
} else {
st.pop();
node = st.top();
st.pop();
depth--;
}
result = result > depth ? result : depth;
}
return result;
}
bool isBalanced2(TreeNode* root) {
stack<TreeNode*> st;
if (root == NULL) {
return true;
}
st.push(root);
while (!st.empty()) {
TreeNode* node = st.top();
st.pop();
if (abs(getDepth(node->left) - getDepth(node->right)) > 1 ) {
return false;
}
if (node->right) {
st.push(node->right);
}
if (node->left) {
st.push(node->left);
}
}
return true;
}
257. 二叉树的所有路径
// 递归一
void traversal1(TreeNode* cur, vector<int>& path, vector<string>& result) {
// 根,保证最后一个节点也能加入
path.push_back(cur->val);
// 到了叶子节点
if (cur->left == NULL && cur->right == NULL) {
// 输出路径
string sPath;
for (int i = 0; i < path.size() - 1; ++i) {
sPath += to_string(path[i]);
sPath += "->";
}
sPath += to_string(path[path.size() - 1]);
result.push_back(sPath);
return;
}
// 左
if (cur->left) {
traversal1(cur->left, path, result);
// 回溯
path.pop_back();
}
// 右
if (cur->right) {
traversal1(cur->right, path, result);
path.pop_back();
}
}
vector<string> binaryTreePaths1(TreeNode* root) {
vector<string> result;
vector<int> path;
if (root == NULL) {
return result;
}
traversal1(root, path, result);
return result;
}
// 递归一简化版
void traversal1_(TreeNode* cur, string path, vector<string>& result) {
path += to_string(cur->val);
if (cur->left == NULL && cur->right == NULL) {
result.push_back(path);
return;
}
if (cur->left) {
traversal1_(cur->left, path + "->", result);
}
if (cur->right) {
traversal1_(cur->right, path + "->", result);
}
}
vector<string> binaryTreePaths1_(TreeNode* root) {
vector<string> result;
string path;
if (root == NULL) {
return result;
}
traversal1_(root, path, result);
return result;
}
// 递归二
void traversal2(TreeNode* cur, string path, vector<string>& result) {
path += to_string(cur->val); // 中,中为什么写在这里,因为最后一个节点也要加入到path中
if (cur->left == NULL && cur->right == NULL) {
result.push_back(path);
return;
}
if (cur->left) {
path += "->";
traversal2(cur->left, path, result); // 左
path.pop_back(); // 回溯 '>'
path.pop_back(); // 回溯 '-'
}
if (cur->right) {
path += "->";
traversal2(cur->right, path, result); // 右
path.pop_back(); // 回溯'>'
path.pop_back(); // 回溯 '-'
}
}
vector<string> binaryTreePaths2(TreeNode* root) {
vector<string> result;
string path;
if (root == NULL) return result;
traversal2(root, path, result);
return result;
}
// 迭代法
vector<string> binaryTreePaths(TreeNode* root) {
// 保存树的遍历节点
stack<TreeNode*> treeSt;
// 保存遍历路径的节点
stack<string> pathSt;
// 保存最终路径集合
vector<string> result;
if (root == NULL) {
return result;
}
treeSt.push(root);
pathSt.push(to_string(root->val));
while (!treeSt.empty()) {
// 根,取出节点
TreeNode* node = treeSt.top();
treeSt.pop();
string path = pathSt.top();
pathSt.pop();
// 叶子节点,路径加入结果
if (node->left == NULL && node->right == NULL) {
result.push_back(path);
}
// 右
if (node->right) {
treeSt.push(node->right);
pathSt.push(path + "->" + to_string(node->right->val));
}
// 左
if (node->left) {
treeSt.push(node->left);
pathSt.push(path + "->" + to_string(node->left->val));
}
}
return result;
}
404.左叶子之和
// 递归法
int sumOfLeftLeaves1(TreeNode* root) {
// 根节点
if (root == NULL) {
return 0;
}
if (root->left == NULL && root->right == NULL) {
return 0;
}
// 根节点的左子树
int leftVal = sumOfLeftLeaves1(root->left);
// 找到了左子叶
if (root->left != NULL && root->left->left == NULL && root->left->right == NULL) {
leftVal += root->left->val;
}
// 根节点的右子树
int rightVal = sumOfLeftLeaves1(root->right);
return leftVal + rightVal;
}
// 递归法简化版
int sumOfLeftLeaves1_(TreeNode* root) {
if (root == NULL) {
return 0;
}
int leftValue = 0;
if (root->left != NULL && root->left->left == NULL && root->left->right == NULL) {
leftValue = root->left->val;
}
return leftValue + sumOfLeftLeaves1_(root->left) + sumOfLeftLeaves1_(root->right);
}
// 迭代法
int sumOfLeftLeaves2(TreeNode* root) {
stack<TreeNode*> st;
if (root == NULL) {
return 0;
}
st.push(root);
int result = 0;
while (!st.empty()) {
TreeNode* node = st.top();
st.pop();
if (node->left != NULL && node->left->left == NULL && node->left->right == NULL) {
result += node->left->val;
}
if (node->right) st.push(node->right);
if (node->left) st.push(node->left);
}
return result;
}