算法日记 - Day10

二叉树的中序遍历

递归

java 复制代码
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> ans = new ArrayList<>();
        inorder(root, ans);
        return ans;
    }

    public void inorder(TreeNode root, List<Integer> ans) {
        if (root == null) return;
        inorder(root.left, ans);
        ans.add(root.val);
        inorder(root.right, ans);
    }
}

二叉树的最大深度

递归计算

java 复制代码
class Solution {
    public int maxDepth(TreeNode root) {
        if (root == null) return 0;
        // 左右子树的最大深度 + 1
        return 1 + Math.max(maxDepth(root.left), maxDepth(root.right));
    }
}

深度优先搜索、广度优先搜索都可以做

翻转二叉树

一看也是个递归问题,翻转二叉树就是翻转左右子树,然后依次递归翻转子树的左右子树。

  • 这里本来想通过交换左右的值来实现,但是不可以,比如左子树不为空,右子树为空就没办法做了
java 复制代码
class Solution {
    public TreeNode invertTree(TreeNode root) {
        if (root == null) return null;
        TreeNode temp = root.left;
        root.left = root.right;
        root.right = temp;
        invertTree(root.left);
        invertTree(root.right);
        return root;
    }
}

对称二叉树

递归

java 复制代码
class Solution {
    public boolean isSymmetric(TreeNode root) {
        return isSymmetric1(root.left, root.right);
    }

    private boolean isSymmetric1(TreeNode l, TreeNode r) {
    	// 如果都为空,那就是相等
        if (l == null && r == null) return true;
        // 如果一个为空一个不为空那就是不相等
        if (l == null && r != null || l != null && r == null) return false;
        boolean r1 = isSymmetric1(l.left, r.right);
        boolean r2 = isSymmetric1(l.right, r.left);
        return r1 && r2 && l.val == r.val;
        
    }
}

这两个 if 判断可以简化为

java 复制代码
class Solution {
    public boolean isSymmetric(TreeNode root) {
        return isSymmetric1(root.left, root.right);
    }

    private boolean isSymmetric1(TreeNode l, TreeNode r) {
    	// 简化
        if (l == null || r == null) return l == r;
        boolean r1 = isSymmetric1(l.left, r.right);
        boolean r2 = isSymmetric1(l.right, r.left);
        return r1 && r2 && l.val == r.val;
        
    }
}

迭代

使用队列,左队列记录左边节点,右队列记录右边节点,队列元素不能为空,那我们在遍历的时候,出现两个队列元素不相等的时候就可以直接判断不对称。

java 复制代码
class Solution {
    public boolean isSymmetric(TreeNode root) {
    	// 放入左右节点
        Deque<TreeNode> queueLeft = new LinkedList<>() {{ if (root.left != null) add(root.left); }};
        Deque<TreeNode> queueRight = new LinkedList<>() {{ if (root.right != null) add(root.right); }};
        while (queueLeft.size() == queueRight.size() && queueLeft.size() > 0) {
        	// 分别取一个元素
            TreeNode l = queueLeft.removeFirst();
            TreeNode r = queueRight.removeFirst();
			// 如果值不等那就不对称了
            if (l.val != r.val) return false;
            // 对应节点不对称,返回 false
            if (l.left != null && r.right == null || l.left == null && r.right != null) 
            	return false;
            	// 不为空则加入,此时经过前面的判断,现在只有都为空或者都不为空的情况
            if (l.left != null)
                queueLeft.add(l.left);
            if (r.right != null)
                queueRight.add(r.right);
            if (l.right != null && r.left == null || l.right == null && r.left != null) 
            	return false;
            if (l.right != null)
                queueLeft.add(l.right);
            if (r.left != null)
                queueRight.add(r.left);
        }
        return queueLeft.size() == queueRight.size();
    }
}

有没有更简化的写法呢?这好多 if 啊!有,我们可以让队列存 null 值,取出来的时候再判断,并且用一个队列就可以,只要我们保证联系取出来的两个元素是对应关系就行

java 复制代码
class Solution {
    public boolean isSymmetric(TreeNode root) {
        Deque<TreeNode> q = new LinkedList<>();
        q.add(root.left);
        q.add(root.right);
        while (!q.isEmpty()) {
            TreeNode l = q.removeFirst();
            TreeNode r = q.removeFirst();
            // 下一轮循环
            if (l == null && r == null) continue;
            // 断定不对称
            if (l == null || r == null || l.val != r.val) 
                return false;
            // 存入两对判断
            q.offer(l.left);
            q.offer(r.right);
            
            q.offer(l.right);
            q.offer(r.left);
        }
        return true;
    }
}
相关推荐
戴西软件1 小时前
戴西CAxWorks.VPG车辆工程仿真软件技术解析(上)——安全仿真体系的自动化构建
运维·网络·数据库·人工智能·算法·安全·自动化
zander2581 小时前
4. 寻找两个正序数组的中位数:用分割点代替合并
数据结构·算法
Kisorge1 小时前
【电机控制器】 基于STSPIN32G4的FOC控制
stm32·嵌入式硬件·算法
Elivs2 小时前
RMSNorm函数
人工智能·算法·机器学习
tudousisi2222 小时前
P4447 [AHOI2018初中组] 分组 题解复盘
算法
SNAKEpc121382 小时前
OpenGL(十一)- 变换管线
c语言·c++·算法·矩阵·图形渲染
饼饼学习空间智能4 小时前
遥操作数据能否提升机器人自主化水平?详解模仿学习、仿真放大与Sim2Real闭环
人工智能·算法
间歇性努力持续性发呆的野生快乐选手5 小时前
dfs回溯,bfs枚举,完全背包
c++·算法·深度优先·宽度优先
嵌入式冰箱5 小时前
2026年华数杯B题完整解题思路与建模方案
算法