算法日记 - 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;
    }
}
相关推荐
yi0119 小时前
LeetCode 219:存在重复元素 II——哈希表记录“最近一次出现的位置”
数据结构·人工智能·笔记·python·算法·leetcode·哈希表
灯澜忆梦12 小时前
【面向对象编程C++】| 基础语法
java·c++·算法
小蒋观天下12 小时前
专项方案:大场景港口AI安防、多干扰环境下的算法调优与落地实操
人工智能·深度学习·算法·安全·机器学习·计算机视觉·ai大模型
Evand J12 小时前
【电机滤波例程5】渐消因子自适应扩展卡尔曼滤波(EKF),MATLAB。PMSM负载突变下的状态估计。附下载链接
算法·matlab
H.莓飛12 小时前
【数据结构】二叉树_OJ题
linux·开发语言·数据结构·算法
好想像大佬一样能够ak所有13 小时前
Leetcode35.搜索插入位置
数据结构·算法·leetcode
aqiu11111113 小时前
【C++算法打怪专栏】LeetCode 165. 比较版本号(双指针与字符串流法)
c++·算法·leetcode
黄金龙PLUS13 小时前
如何基于置换算法来设计对称加密算法
算法·网络安全·密码学·哈希算法·同态加密
不会就选b13 小时前
算法日常・每日刷题--<动态规划>14
算法
赛博守夜人14 小时前
跨境业务与出海合规之九:海外买量投放与营销虚假流量(Ad Fraud):跨国机房群控与归因欺诈识别算法
算法·安全