0
点赞
收藏
分享

微信扫一扫

[ C++ ] STL---list的模拟实现

流计算Alink 03-27 23:30 阅读 2
算法java

层序遍历

我们是用队列来保存元素。同时记录队列的大小,用来表示一层有几个节点。从而实现分层进行操作

遍历每一层(每一层遍历size次)的同时,把它的左右孩子都入队(插入队尾)(如果有的话)。

  • java代码
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();
        Deque<TreeNode> queue = new ArrayDeque<>();  //初始化队列
        if(root == null) return res;
        queue.push(root);

        while(!queue.isEmpty()) {
            List<Integer> floor = new ArrayList<>();  //存放每一层的结果
            int len = queue.size();
            for(int i = 0; i < len; i++) {  //对每一层进行操作
                TreeNode tmp = queue.pop();  //取出队头,加入结果数组同时将左右孩子入队(插入队尾用offer)
                floor.add(tmp.val);
                if(tmp.left != null) queue.offer(tmp.left);
                if(tmp.right != null) queue.offer(tmp.right);
            }
            //每一层遍历完后添加一次floor数组
            res.add(floor);
        }
        return res;
    }
}

107.二叉树的层次遍历 II

直接Collections.reverse(res);就行

199.二叉树的右视图

题目是一维数组,在每层的for循环里加一个判断,if(i == len-1) 才加到答案数组里。

637.二叉树的层平均值

每层用sum累加,在每层的for循环里加一个判断,if(i == len-1) 才把sum/len加到答案数组里。

429.N叉树的层序遍历

注意要改变添加每层的孩子节点的逻辑!

List<Node> children = tmp.children;   //先把孩子结点list取出来
if (children == null || children.size() == 0) {  //如果没有孩子了就跳过这次循环
	continue;
}
for (Node child : children) {  //遍历孩子结点list 不为空就加到队列里
	if (child != null) {
		queue.offer(child);
	}
}

515.在每个树行中找最大值

在每次进while(相当于处理下一层)的时候,初始化max=Integer.MIN_VALUE,然后在for循环里max=Math.max(max,node.val)

116.填充每个节点的下一个右侧节点指针

在单层遍历的时候记录一下本层的头部节点(先取出,然后把左右孩子入队一次),然后在遍历的时候让前一个节点指向本节点就行(size-1次)

104.二叉树的最大深度

遍历每一层的同时depth++

111.二叉树的最小深度

只有当左右孩子都为空的时候,才说明遍历的最低点了。如果其中一个孩子为空则不是最低点。只要遇到了就直接返回depth即可

226. 翻转二叉树

想要翻转它,其实把每一个节点的左右孩子交换一下就可以了。

那我们采用什么方式遍历呢?前 后 层序都可以,唯独中序不行!(其实也可以,只要修改一下right成left就行)中序反转左子树后,回到根节点,此时的右子树实际上是原来的左子树!

在这里插入图片描述

递归三部曲

  1. 确定递归函数的参数和返回值

参数就是要传入节点的指针,不需要返回值

void reverse(TreeNode root)
  1. 确定终止条件

当前节点为空的时候,就返回

if (root == NULL) return root;
  1. 确定单层递归的逻辑

先前序遍历,所以先进行交换左右孩子节点,然后反转左子树,反转右子树。

swap(root->left, root->right);
invertTree(root->left);
invertTree(root->right);

注意swap函数要写成swap(TreeNode root)!不能直接交换left和right

  • java代码(前序)
class Solution {
    public void reverse(TreeNode root) {
        if(root == null) return;
        swap(root);
        reverse(root.left);
        reverse(root.right);
    }

    public void swap(TreeNode root) {
        TreeNode tmp = root.left;
        root.left = root.right;
        root.right = tmp;
    }

    public TreeNode invertTree(TreeNode root) {
        reverse(root);
        return root;
    }
}

101.对称二叉树

我们判断是否对称,实际是判断根节点的左子树和右子树是否可以相互翻转。同为内侧节点两两比较,同为外侧节点两两比较。

确定遍历顺序

这题==只能用后序!==因为我们要不断收集左右孩子的信息,然后返回给上一个节点(上一层)。我才能知道左节点为根的树和 右节点为根的树 是否是相互反转的。

后序:左 右 中

在这里插入图片描述

代码实现

  1. 确定递归函数的返回值和参数
bool compare(TreeNode left, TreeNode right)
  1. 确定终止条件

左为空 && 右不为空 false

左不为空 && 右为空 false

左为空 && 右为空 true

左右都不为空 && 值不相等 false

左右都不为空 && 值相等 true

  1. 单次递归逻辑

分别判断左右侧 孩子是否都对称相等!(这个结果最终会传回来,一直传到根节点)

boolean outside = compare(left.left, right.right);  //左
boolean inside = compare(left.right, right.left);  //右
boolean result = inside && outside;  //中
  • java代码
class Solution {
    //后序遍历 左右中
    public boolean compare(TreeNode left, TreeNode right) {
        if(left == null && right != null) return false;
        else if(left != null && right == null) return false;
        else if (left == null && right == null) return true;
        else if(left.val != right.val) return false;
        boolean outside = compare(left.left, right.right); //左
        boolean inside = compare(left.right, right.left); //左
        boolean result = outside && inside; //中
        return result;
    }

    public boolean isSymmetric(TreeNode root) {
        return compare(root.left,root.right);
    }
}
举报

相关推荐

0 条评论