算法日记 - 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;
    }
}
相关推荐
Zzz 小生6 小时前
Lazy Theta*:把昂贵的视线检测留到“真正需要”时再做
人工智能·算法·贪心算法·推荐算法
l1258656 小时前
# LangGraph Deep Research Agent 全流程设计:多轮研究、人机协同与真实来源管理
数据库·人工智能·python·算法·自然语言处理·oracle·langchain
青少儿编程课堂7 小时前
图形化编程实战:智能交通灯调度台,一个作品讲透循环、条件与广播
c++·python·算法·bfs·信息学竞赛
evans在进步7 小时前
LeetCode 438 找到字符串中所有字母异位词:滑动窗口与排序解法详解
算法·leetcode·职场和发展
M78佐菲7 小时前
Linux多线程:创建、回收与互斥同步
linux·笔记·学习·算法
小手cool7 小时前
使用递归对数组进行反转操作
java·数据结构·算法
兔兔兔兔17 小时前
记录C++ 13
开发语言·c++·算法
码行山野赴时序归途7 小时前
从暴力到最优:三道 C 语言入门题的解法思路
c语言·开发语言·数据结构·算法·leetcode·排序算法
土司大王7 小时前
LeetCode hot100——随机链表的复制
算法·leetcode·链表
叠层归一研究院8 小时前
螺旋时空:E框架的整合宇宙论
人工智能·经验分享·算法·机器学习·agi