首页 > 编程语言 >算法面试题:逆时针打印二叉树外围边缘

算法面试题:逆时针打印二叉树外围边缘

时间:2023-06-14 11:31:51浏览次数:41  
标签:node 面试题 逆时针 边缘 二叉树 root 节点 antiClockWiseNodeList


给定一颗二叉树如下:

算法面试题:逆时针打印二叉树外围边缘_面试题

要求把二叉树的外边缘按照逆时针的方式打印出来,也就是你需要打印出以下节点:
314, 6, 271, 28, 0, 17, 641, 257, 29 ,278, 7

整个二叉树的外边缘分三部分,第一部分是最左边缘,也就是节点314, 6, 271, 28。第二部分是底边节点,他们分别是0, 17, 641, 257, 29。第三部分是右边缘,他们分别是7, 278.

左边缘的节点从根节点开始,一直访问左孩子,直到左孩子为空;
底部节点实际上是二叉树的所以叶子节点;
右边缘节点是从根节点开始,一直访问右节点,直到右孩子为空;

根据以上三种情况,通过遍历二叉树,获得三种性质的节点,把他们组合起来就是二叉树的逆时针外边缘了。由此代码实现如下:

import java.util.ArrayList;
import java.util.Stack;

public class AntiClockWiseTravel {

    private ArrayList<TreeNode> antiClockWiseNodeList = new ArrayList<TreeNode>();
    private TreeNode root;

    private void getLeftSizeNodes() {
        TreeNode node = root;
        while (node != null) {
            antiClockWiseNodeList.add(node);
            node = node.left;
        }
    }

    private void inorder(TreeNode node) {
        if (node == null) {
            return;
        }

        inorder(node.left);

        if (node.left == null && node.right == null) {
            if (antiClockWiseNodeList.get(antiClockWiseNodeList.size() - 1) != node) {
                antiClockWiseNodeList.add(node);    
            }

            return;
        }

        inorder(node.right);
    }

    private void getBottomSizeNodes() {
        TreeNode node = root;
        inorder(node);
    }

    private void getRightSizeNodes() {
        TreeNode node = root;
        Stack<TreeNode> stack = new Stack<TreeNode>();

        node = node.right;
        while (node != null) {
            stack.push(node);
            node = node.right;
        }

        while (stack.empty() != true) {
            TreeNode n = stack.pop();
            if (antiClockWiseNodeList.get(antiClockWiseNodeList.size() - 1 ) != n) {
                antiClockWiseNodeList.add(n);
            }
        }
    }

    public AntiClockWiseTravel(TreeNode root) {
        this.root = root;

        getLeftSizeNodes();
        getBottomSizeNodes();
        getRightSizeNodes();
    }

    public ArrayList<TreeNode> getAntiClockWiseNodes() {
        return antiClockWiseNodeList;
    }
}

antiClockWiseNodeList是一个二叉树节点队列,专门用来存储二叉树外边缘的节点,首先我们通过getLeftSizeNodes来获取左边缘的几点,它实现方法简单,只是从跟节点开始,始终访问左孩子,并把他们加入队列。

getBottomSizeNodes用来获得边缘的底部节点,它使用中序遍历二叉树节点,每遍历一个节点就判断其是否是叶子节点,如果是,则把它加入队列,这里要注意的是,底部节点与左边缘节点有可能会发送重复,例如节点28既是左边缘节点,也是底部节点,因此加入的时候要做个判断,代码中的if判断,作用就是防止把左边缘和底部边缘的重合节点加入队列两次。

函数getRightSizeNodes目的是获得右边缘节点,这里需要注意的是,当我们从根节点开始,依次访问右孩子时,所得节点的次序是顺时针的,例如从根节点开始访问右边缘节点是,节点次序是7, 278, 29, 但我们需要的是逆时针次序,也就是说,我们想要的节点次序是29, 278, 7,所以在代码实现中,使用了一个小技巧,当获得右边缘节点时,先将他们压入堆栈,因为堆栈的特点是后进先出,压入堆栈后再把堆栈中的节点依次弹出,这样的话我们得到的节点次序就是逆时针的了。这里还需要注意的一点是,右边缘节点和底部节点有重复节点,例如节点29就是他们的重复节点,代码中的if判断就是为了防止把重复节点添加两次。

我们再看看主入口代码:

import java.util.ArrayList;


public class BinaryTree {
   public static void main(String[] s) {

       int[] inorder = new int[]{28, 271, 0, 6, 561, 17, 3, 314, 2, 401, 641, 1, 257, 7, 278, 29};
       int[] preorder= new int[] {314, 6, 271, 28, 0, 561, 3, 17, 7, 2, 1, 401, 641, 257, 278, 29};
       BTreeBuilder treeBuilder = new BTreeBuilder(inorder, preorder);
       TreeNode root = treeBuilder.getTreeRoot();
       PrintTreeList pt = new PrintTreeList(root);
       pt.printTree();

       System.out.print("\n");
       AntiClockWiseTravel at = new AntiClockWiseTravel(root);
       ArrayList<TreeNode> list = at.getAntiClockWiseNodes();
       for (int i = 0; i < list.size(); i++) {
           TreeNode n = list.get(i);
           System.out.print(n.val + " ");
       }
   }
}

首先我们给定二叉树的中序遍历节点和前序遍历节点,上一节我们给出了如何根据两种节点次序构建二叉树的算法,构建出给定的二叉树后,把二叉树的根节点传递给AntiClockWiseTravel,通过该类获得一个节点队列,这个节点队列包含了二叉树以逆时针次序存放的外部边缘节点,上面的代码运行后得到结果如下:

314 6 271 28 0 17 641 257 29 278 7

由此可见,我们的算法准确的以逆时针方式打印了二叉树的外部边缘节点。

更多技术信息,包括操作系统,编译器,面试算法,机器学习,人工智能,请关照我的公众号:

算法面试题:逆时针打印二叉树外围边缘_二叉树_02


标签:node,面试题,逆时针,边缘,二叉树,root,节点,antiClockWiseNodeList
From: https://blog.51cto.com/u_16160261/6476561

相关文章

  • 《数据结构与算法》之二叉树(补充树)
    一.树结构之二叉树操作二叉树的查找二叉搜索树,也称二叉排序树或二叉查找树二叉搜索树:一棵二叉树,可以为空,如果不为空,应该满足以下性质:非空左子树的所有结点小于其根结点的键值非空右子树的所有结点大于其根结点的键值左右子树都是二叉搜索树对于二叉树的查找,其实沿用的是......
  • 杭州吉利面试题___整理汇总
    吉利面试======================================吉利面试三面    lyc  2023年6月13日1、自动测试经验有多久?==4左右年2、你用什么语言做的自动化? python3、你做过那些自动 化? ui自动化和接口自动化4、问下你python中去重有几种方法?五种,具体(set  ,if not、 conut==1......
  • 杭州华数面试题___整理汇总
    杭州华数面试题===================================6.8 华数 腾讯会议 一面1.项目介绍2.项目里面的测试点介绍一下3.接口是怎么测的4.怎么根据接口文档去测试的5.怎么看接口测试结果对不对6.接口自动化做了多久7.自己独立做还是跟团队做8.接口是用什么做的9.请求的报文是从......
  • 1145.二叉树着色游戏
    问题描述1145.二叉树着色游戏解题思路贪心策略:对二号玩家来说,想要取胜,选择染色节点只有三种可能:选择x的父节点,则通过深度优先搜索可以求得红色节点数,蓝色节点数为$n$减去红色节点数选择x的左子节点,则通过dfs可以求得蓝色节点数,红色节点数为$n$减去蓝色节点数选择x的右子节......
  • 面试题 17.05. 字母与数字 (Medium)
    问题描述面试题17.05.字母与数字(Medium)给定一个放有字母和数字的数组,找到最长的子数组,且包含的字母和数字的个数相同。返回该子数组,若存在多个最长子数组,返回左端点下标值最小的子数组。若不存在这样的数组,返回一个空数组。示例1:输入:["A","1","B","C","D","2","3",......
  • leetcode 104. 二叉树的最大深度(java实现)
    104.二叉树的最大深度标题解法标题给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。说明:叶子节点是指没有子节点的节点。解法publicclassSolution{publicintmaxDepth(TreeNoderoot){//如果节点为空,返回深度为0......
  • php面试题:一张表中,id 是主键索引,name是普通索引,下列语句都只取一条,分别有什么不同
    一张表中,id是主键索引,name是普通索引,下列语句都只取一条,分别有什么不同select*fromtable_namewherename='smith'select*fromtable_namewhereid=1考查普通索引与主键索引的运行机制。主键索引=唯一索引+非空约束,优先级高于普通索引索引运行机制:对于索引中的每一项,My......
  • 二叉树看递归问题(下)
    112. 路径总和112.路径总和-力扣(Leetcode)给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。叶子节点 是指没有子......
  • 最近面试题
    面试题1.业务流程的测试点2.考虑哪些异常场景3.余额怎么看4.余额存在网站上吗?5.产品出货你关吗?6.自动化怎么做的7.文本会检查哪些东西8.有没有检查过数据库9.做自动化时不会自动检查数据库吗?10.接口测试测什么11.怎么考虑接口案例12.接口案例是自己设计的吗?13.检查接......
  • 计算机体系结构面试题
    1、请解释什么是指令级并行(Instruction-LevelParallelism,ILP)并提供一个示例说明? 在计算机体系结构中,指令级并行是指同时执行多个计算机指令的能力,以提高程序的执行速度。这种并行性的实现通常涉及到在单个指令流中发现和执行多个独立指令的方法。示例:假设有以下三个指令:ADD......