翻转二叉树
leetcode 翻转二叉树
给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。
示例 1:
输入:root = [4,2,7,1,3,6,9]
输出:[4,7,2,9,6,3,1]
BFS
class Solution {
public:
// 返回类型为 TreeNode*
TreeNode* invertTree(TreeNode* root) {
if (!root) return {};
queue<TreeNode*> que;
vector<int> result;
que.push(root);
while (!que.empty()) {
int size = que.size();
vector<int> level;
for (int i = 0; i < size; i++) {
TreeNode* cur = que.front(); // 取出队首元素
que.pop(); // 出队
swap(cur->left, cur->right);
result.push_back(cur->val);
if (cur->left) que.push(cur->left);
if (cur->right) que.push(cur->right);
}
}
return root;
}
};
DFS
class Solution {
public:
// 返回类型为 TreeNode*
TreeNode* invertTree(TreeNode* root) {
if (!root) return nullptr;
// 递归翻转左子树和右子树
TreeNode* temp = invertTree(root->left);
root->left = invertTree(root->right);
root->right = temp;
return root;
}
};
翻转二叉树
给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。
示例 1:
输入:root = [4,2,7,1,3,6,9]
输出:[4,7,2,9,6,3,1]
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if (!root) return true;
// 调用辅助函数检查左右子树是否对称
return isSameval(root->left, root->right);
}
private:
bool isSameval(TreeNode* t1, TreeNode* t2) {
// 如果两个子树都为空,则他们是对称的
if (!t1 && !t2) return true;
// 如果其中一个子树为空而另外一个不为空,则它们不对称
if (!t1 || !t2) return false;
// 检查当前节点的值是否相等,并且左子树的左子树和右子树的右子树、左子树的右子树与右子树的左子树是否对称
return (t1->val == t2->val) && isSameval(t1->right, t2->left) && isSameval(t1->left, t2->right);
}
};
完全二叉树的节点个数
二叉树——完全二叉树的节点个数
给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。
完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层(从第 0 层开始),则该层包含 1~ 2h 个节点。
示例 1:
输入:root = [1,2,3,4,5,6]
输出:6
BFS
class Solution {
public:
int countNodes(TreeNode* root) {
if (!root) return 0;
queue<TreeNode*> que;
que.push(root);
int result = 0;
while(!que.empty()) {
int size = que.size();
for (int i = 0; i < size; i++) {
TreeNode* cur = que.front(); // 取出队首元素
que.pop();
result += 1;
if (cur->left) que.push(cur->left);
if (cur->right) que.push(cur->right);
}
}
return result;
}
};
给定一个二叉树,判断它是否是 平衡二叉树
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:true
class Solution {
public:
bool isBalanced(TreeNode* root) {
return getHeight(root) == -1 ? false : true;
}
int getHeight(TreeNode* node) {
// 如果当前节点为空,那么高度为0
if (node==nullptr) return 0;
// 递归的计算当前节点 node 的左子树高度
int leftHight = getHeight(node->left);
// 如果发现为 -1,即表示左子树中出现了高度差大于 2 的情况,已经不是平衡二叉树了,可以直接返回这个结果给上层
// 提前推出
if (leftHight == -1) return -1;
// 递归的计算当前节点 node 的右子树高度
int rightHight = getHeight(node->right);
// 如果发现为 -1,即表示左子树中出现了高度差大于 2 的情况,已经不是平衡二叉树了,可以直接返回这个结果给上层
if (rightHight == -1) return -1;
// 说明当前node节点的左子树和右子树没有发现不是平衡二叉树的情况
// 因此计算一下当前节点 curNode 是否是平衡二叉树
// 即计算 curNode 的左子树高度与右子树高度差
// 如果发现小于 2,那么返回以当前节点 curNode 为根节点的子树的最大高度
// 即节点 curNode 的左右子树中最大高度加 1
if (abs(leftHight-rightHight) > 1) return -1;
else
return 1 + max(leftHight, rightHight);
}
};
class Solution:
def isBalanced(self, root: Optional[TreeNode]) -> bool:
if self.getHeight(root) == -1:
return False
else:
return True
def getHeight(self, node: Optional[TreeNode]) -> bool:
if node == None:
return 0
leftHeight = self.getHeight(node.left)
if leftHeight == -1:
return -1
rightHeight = self.getHeight(node.right)
if rightHeight == -1:
return -1
if abs(rightHeight-leftHeight) > 1:
return -1
else:
return 1 + max(leftHeight, rightHeight)
二叉树的所有路径
给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。
叶子节点 是指没有子节点的节点。
示例 1:
输入:root = [1,2,3,null,5]
输出:["1->2->5","1->3"]
解题思路:
1. 前序遍历 (递归寻找中左右)。
2. path 收集要放在判断叶子结点之前,因为如果一旦到了最下面的一个叶子节点,收集结果后就会直接返回。
3. 返回的类型和参数 (所有的path)。
4. 终止条件节点的左右子树都为空,将sPath加入到result
class Solution:
def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
if root is None:
return []
result = []
# 注意:这里不再需要接收 traversal 的返回值
self.traversal(root, [], result)
print("Final result:", result) # 调试输出
return result
def traversal(self, cur, path, result):
path.append(cur.val)
if cur.left is None and cur.right is None: # 当前节点是叶子节点
sPath = '->'.join(map(str, path))
result.append(sPath)
print("Adding path:", sPath) # 调试输出
else:
if cur.left: # 遍历左子树
self.traversal(cur.left, path, result)
path.pop() # 回溯,移除当前节点
if cur.right: # 遍历右子树
self.traversal(cur.right, path, result)
path.pop() # 回溯,移除当前节点
class Solution {
public:
vector<string> binaryTreePaths(TreeNode* root) {
if (root == nullptr) {
return {};
}
std:;vector<int> path;
std::vector<std::string> result;
traveral(root, path, result);
std::cout << "Final result";
for (const auto& str : result) {
std::cout << str << " ";
}
std::cout << std::endl;
return result;
}
void traveral(TreeNode* cur, std::vector<int>& path, std::vector<std::string>& result) {
path.push_back(cur->val);
if (cur->right == nullptr && cur->left == nullptr) {
std::string sPath;
for (auto i = 0; i < path.size(); i++) {
if (i > 0) sPath += "->";
sPath += std::to_string(path[i]);
}
result.push_back(sPath);
std::cout << "Adding path" << sPath << std::endl;
}
else {
if (cur->left != nullptr) {
traveral(cur->left, path, result);
path.pop_back(); // 回溯,移除当前节点
}
if (cur->right != nullptr) {
traveral(cur->right, path, result);
path.pop_back(); // 回溯,移除当前节点
}
}
}
};
左叶子之和
给定二叉树的根节点 root ,返回所有左叶子之和。
示例 1:
解题思路:
1. 后序遍历.
2. 递归三部曲
2.1 返回类型和传入参数
2.2 终止条件 cur.left.left == None and cur.left.right == None 但是要注意 cur.left != None
2.3 单个二叉树的遍历
class Solution:
def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
result = []
self.leteTree(root, result)
return sum(result)
def leteTree(self, cur, result):
if cur.left != None and cur.left.left == None and cur.left.right == None:
result.append(cur.left.val)
if cur.left != None:
self.leteTree(cur.left, result)
if cur.right != None:
self.leteTree(cur.right, result)
输入: root = [3,9,20,null,null,15,7]
输出: 24
解释: 在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24
找树左下角的值
二叉树——找树左下角的值
给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。
假设二叉树中至少有一个节点。
示例 1:
输入: [1,2,3,4,null,5,6,null,null,7]
输出: 7
class Solution:
def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
queue = deque([root])
result = None
while(queue):
level = []
for _ in range(len(queue)):
cur = queue.popleft()
level.append(cur.val)
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
result = level[0]
return result
路径总和
二叉树——路径总和
给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。
叶子节点 是指没有子节点的节点。
示例 1:
输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
输出:true
解释:等于目标和的根节点到叶节点路径如上图所示。
class Solution:
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
if not root:
return False
path = []
traget_bool = False
traget_bool = self.sumPath(root, path, traget_bool, targetSum)
return traget_bool
def sumPath(self, cur, path, traget_bool, targetSum):
# Add the current node's value to the path
path.append(cur.val)
# Check if it's a leaf node and the path sum equals targetSum
if cur.left is None and cur.right is None:
if sum(path) == targetSum:
traget_bool = True
# If we found a valid path, return immediately
if traget_bool:
return traget_bool
# Recursively check left subtree
if cur.left:
traget_bool = self.sumPath(cur.left, path, traget_bool, targetSum)
if traget_bool: # If a valid path was found in the left subtree, return immediately
return traget_bool
path.pop() # Backtrack
# Recursively check right subtree
if cur.right:
traget_bool = self.sumPath(cur.right, path, traget_bool, targetSum)
if traget_bool: # If a valid path was found in the right subtree, return immediately
return traget_bool
path.pop() # Backtrack
return traget_bool