110. 平衡二叉树
递归,后序遍历判断左右子树是不是平衡二叉树。
class Solution {
public boolean isBalanced(TreeNode root) {
return getHeight(root) != -1;
}
public int getHeight(TreeNode root) {
if (root == null) {
return 0;
}
int leftHeight = getHeight(root.left);
int rightHeight = getHeight(root.right);
if (leftHeight == -1 || rightHeight == -1) { // 如果左右字树有不是平衡二叉树的,那么这棵树一定不是
return -1;
}
if (Math.abs(rightHeight - leftHeight) > 1) {
return -1;
}
return 1 + Math.max(leftHeight, rightHeight);
}
}
257. 二叉树的所有路径
易错点:
把一条路径添加到集合时,要新建列表,不能用原来的,否则当移除时,路径也会跟着移除
递归 + 回溯
class Solution {
public List<String> binaryTreePaths(TreeNode root) {
List<Integer> path = new ArrayList<>();
List<List<Integer>> list = new ArrayList<>();
List<String> result = new ArrayList<>();
traversal(root, path, list);
for (List<Integer> e : list) {
StringBuilder sb = new StringBuilder();
int i = 0;
for (; i < e.size() - 1; i++) {
sb.append(e.get(i));
sb.append("->");
}
sb.append(e.get(i));
result.add(sb.toString());
}
return result;
}
public void traversal(TreeNode root, List<Integer> path, List<List<Integer>> list) {
path.add(root.val);
if (root.left == null && root.right == null) {
list.add(new ArrayList<>(path)); // 注意这里必须创建新列表,不然移除时,已经保存的路径也会跟着移除
return;
}
if (root.left != null) {
traversal(root.left, path, list);
path.remove(path.size() - 1); // 需要显示撤销,因为 path 是同一个引用,
// 改成 traversal(root.left, new ArrayList<>(path), list) 就不用 remove 了
}
if (root.right != null) {
traversal(root.right, path, list);
path.remove(path.size() - 1);
}
}
}
404. 左叶子之和
class Solution {
public int sumOfLeftLeaves(TreeNode root) {
if (root == null) {
return 0;
}
if (root.left == null && root.right == null) { // 叶子节点,返回 0
return 0;
}
int leftNum = sumOfLeftLeaves(root.left);
if (root.left != null && root.left.left == null && root.left.right == null) {
leftNum = root.left.val; // 特殊情况,要覆盖掉之前的 leftNum
}
int rightNum = sumOfLeftLeaves(root.right);
return leftNum + rightNum;
}
}
评论区题解看到的比较好的答案:
将是不是左叶子作为一个参数
class Solution {
public:
int result;
void dfs(TreeNode* root, bool is_left) {
if(!root) return;
dfs(root->left, true);
dfs(root->right, false);
if(!root->left && !root->right && is_left) {
result += root->val;
}
}
int sumOfLeftLeaves(TreeNode* root) {
result = 0;
dfs(root, false);
return result;
}
};
222. 完全二叉树的节点个数
层序遍历复杂度:O(n)
利用完全二叉树特性复杂度:O(logN * logN),见链接
思路:
利用完全二叉树的特性。
因为是一颗完全二叉树,所以子树也都是完全二叉树,只是可能不是满二叉树罢了。那么我们求满二叉树是很好求的,可以根据公式 2 ^ n - 1来求。
所以,如果能判断树是满二叉树,那么就很好求了。如果树不是满二叉树,就判断左右子树是不是满二叉树。由此得出递归思路。
如何判断是不是满二叉树呢?(注意这里的前提一定是一颗完全二叉树)
一直向左和一直向右遍历,如果深度相等,就是满二叉树。
易错点:
(2 << leftDepth) - 1 需加括号,<< 优先级低于 -
class Solution {
public int countNodes(TreeNode root) {
if (root == null) {
return 0;
}
int leftDepth = 0;
int rightDepth = 0;
for (TreeNode node = root.left; node != null; node = node.left) {
leftDepth++;
}
for (TreeNode node = root.right; node != null; node = node.right) {
rightDepth++;
}
if (leftDepth == rightDepth) {
return (2 << leftDepth) - 1;
}
int leftNum = countNodes(root.left); // 左
int rightNum = countNodes(root.right); // 右
return 1 + leftNum + rightNum; // 中
}
}
补充层序遍历(不重要):
class Solution {
public int countNodes(TreeNode root) {
Queue<TreeNode> queue = new ArrayDeque<>();
if (root == null) {
return 0;
}
queue.offer(root);
int cnt = 0;
while (!queue.isEmpty()) {
int size = queue.size();
for (; size > 0; size--) {
TreeNode temp = queue.poll();
if (temp.left != null) {
queue.offer(temp.left);
}
if (temp.right != null) {
queue.offer(temp.right);
}
cnt++;
}
}
return cnt;
}
}
640

被折叠的 条评论
为什么被折叠?



