dfs构造N叉树面试算法题

简介: dfs构造N叉树面试算法题

今天遇到一个没有写出来的算法题,记录一下。

如下:要求我补充完整printCategory()buildTree()两个函数。

printCategory()函数负责打印

buildTree()负责构造树节点

public class Interview001 {
    static class Category {
        /**
         * 分类id
         */
        Integer id;
        /**
         * 名称
         */
        String name;
        /**
         * 父级分类id
         */
        Integer parentId;
        static Category create(Integer id, String name, Integer parentId) {
            Category category = new Category();
            category.id = id;
            category.name = name;
            category.parentId = parentId;
            return category;
        }
    }
    static class TreeNode {
        /**
         * 节点数据
         */
        Category data;
        /**
         * 子节点列表
         */
        List<TreeNode> childNodes;
        /**
         * 父节点
         */
        TreeNode parentNode;
        static TreeNode create(Category data) {
            TreeNode node = new TreeNode();
            node.data = data;
            node.childNodes = new ArrayList<>();
            return node;
        }
    }
    public static void main(String[] args) {
        Interview001 interview001 = new Interview001();
        List<Category> categoryList = new ArrayList<>();
        categoryList.add(Category.create(0, "女装", null));
        categoryList.add(Category.create(1, "上装", 0));
        categoryList.add(Category.create(3, "衬衫", 1));
        categoryList.add(Category.create(4, "短袖衬衫", 3));
        categoryList.add(Category.create(5, "长袖衬衫", 3));
        categoryList.add(Category.create(6, "T恤", 1));
        categoryList.add(Category.create(7, "长袖T", 6));
        categoryList.add(Category.create(8, "短袖T", 6));
        categoryList.add(Category.create(9, "毛衣", 1));
        categoryList.add(Category.create(10, "外套", 1));
        categoryList.add(Category.create(11, "下装", 0));
        categoryList.add(Category.create(12, "裙子", 11));
        categoryList.add(Category.create(13, "短裙", 12));
        categoryList.add(Category.create(14, "长裙", 12));
        categoryList.add(Category.create(15, "裤子", 11));
        categoryList.add(Category.create(16, "长裤", 15));
        TreeNode root = interview001.buildTree(categoryList);
        interview001.printCategory(root);
    }
    /**
     * 按如下格式打印出分类树:
     * 女装
     *     上装
     *         衬衫
     *             短袖衬衫
     *             长袖衬衫
     *         T恤
     *             长袖T
     *             短袖T
     *         毛衣
     *         外套
     *     下装
     *         裙子
     *             短裙
     *             长裙
     *         裤子
     *             长裤
     */
    // TODO: 实现打印分类树逻辑
    private void printCategory(TreeNode root) {
    }
    // TODO: 构建分类树
    private TreeNode buildTree(List<Category> categoryList) {
    }
}

其实这题考察的点也很明显,深度优先遍历。通常而言,树的题目都是会考察深度优先遍历或者广度优先遍历的,然后深度优先遍历或者广度优先遍历通常又会用到递归的思想去做。

  • 构造树
  1. 用一个Map存储对应的id和TreeNode
  2. 遍历传进来的List categoryList ,如果对于Category的父节点为null的那它肯定是根节点。
  3. 根据HashMap去得到其父节点,如果父节点不为null,那就把self.parentNode 指向其父节点,然后根据map得到的父节点来把当前节点添加进它的子节点
  4. 最后返回根节点就可以了

我在做这个题的时候也是用HashMap存储的id和TreeNode,但是后面我总是想着把root移到下一层去,回不来。这里认知错误,其实对于这种构造树的情况,通常是root不用动,每次遇到子节点的时候,把子节点和父节点的相关信息通过map就可以得到了。

最后贴一下大佬写的

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import  java.util.Map;
public class Interview001 {
    static class Category {
        /**
         * 分类id
         */
        Integer id;
        /**
         * 名称
         */
        String name;
        /**
         * 父级分类id
         */
        Integer parentId;
        static Category create(Integer id, String name, Integer parentId) {
            Category category = new Category();
            category.id = id;
            category.name = name;
            category.parentId = parentId;
            return category;
        }
    }
    static class TreeNode {
        /**
         * 节点数据
         */
        Category data;
        /**
         * 子节点列表
         */
        List<TreeNode> childNodes;
        /**
         * 父节点
         */
        TreeNode parentNode;
        static TreeNode create(Category data) {
            TreeNode node = new TreeNode();
            node.data = data;
            node.childNodes = new ArrayList<>();
            return node;
        }
    }
    public static void main(String[] args) {
        Interview001 interview001 = new Interview001();
        List<Category> categoryList = new ArrayList<>();
        categoryList.add(Category.create(0, "女装", null));
        categoryList.add(Category.create(1, "上装", 0));
        categoryList.add(Category.create(3, "衬衫", 1));
        categoryList.add(Category.create(4, "短袖衬衫", 3));
        categoryList.add(Category.create(5, "长袖衬衫", 3));
        categoryList.add(Category.create(6, "T恤", 1));
        categoryList.add(Category.create(7, "长袖T", 6));
        categoryList.add(Category.create(8, "短袖T", 6));
        categoryList.add(Category.create(9, "毛衣", 1));
        categoryList.add(Category.create(10, "外套", 1));
        categoryList.add(Category.create(11, "下装", 0));
        categoryList.add(Category.create(12, "裙子", 11));
        categoryList.add(Category.create(13, "短裙", 12));
        categoryList.add(Category.create(14, "长裙", 12));
        categoryList.add(Category.create(15, "裤子", 11));
        categoryList.add(Category.create(16, "长裤", 15));
        TreeNode root = interview001.buildTree(categoryList);
        interview001.printCategory(root);
    }
    /**
     * 按如下格式打印出分类树:
     * 女装
     *     上装
     *         衬衫
     *             短袖衬衫
     *             长袖衬衫
     *         T恤
     *             长袖T
     *             短袖T
     *         毛衣
     *         外套
     *     下装
     *         裙子
     *             短裙
     *             长裙
     *         裤子
     *             长裤
     */
    // TODO: 实现打印分类树逻辑
    private void printCategory(TreeNode root) {
        this.dfs(root, 0);
    }
    private void dfs(TreeNode node, Integer level){
        String prefix =  new String(new char[level]).replace("\0", "\t");
        if (node != null){
            System.out.print(prefix);
            System.out.println(node.data.name);
        }
        for (TreeNode child : node.childNodes){
            this.dfs(child, level+1);
        }
    }
    // TODO: 构建分类树
    private TreeNode buildTree(List<Category> categoryList) {
        Map<Integer, TreeNode> nodeMap = new HashMap();
        TreeNode root = null;
        for (Category category:  categoryList) {
            TreeNode self = TreeNode.create(category);
            nodeMap.put(category.id, self);
            if (category.parentId==null){
                root = self;
                continue;
            }
            TreeNode parent =  nodeMap.get(category.parentId);
            if (parent!=null){
                self.parentNode = parent;
                parent.childNodes.add(self);
            }
        }
        return root;
    }
}


相关文章
|
1月前
|
算法 测试技术 定位技术
数据结构与算法——DFS(深度优先搜索)
数据结构与算法——DFS(深度优先搜索)
|
7天前
|
算法
树的遍历算法有哪些?
不同的遍历算法适用于不同的应用场景。深度优先搜索常用于搜索、路径查找等问题;广度优先搜索则在图的最短路径、层次相关的问题中较为常用;而二叉搜索树的遍历在数据排序、查找等方面有重要应用。
13 2
|
29天前
|
算法 Java 数据库
美团面试:百亿级分片,如何设计基因算法?
40岁老架构师尼恩分享分库分表的基因算法设计,涵盖分片键选择、水平拆分策略及基因法优化查询效率等内容,助力面试者应对大厂技术面试,提高架构设计能力。
美团面试:百亿级分片,如何设计基因算法?
|
1月前
|
算法 前端开发 Java
数据结构与算法学习四:单链表面试题,新浪、腾讯【有难度】、百度面试题
这篇文章总结了单链表的常见面试题,并提供了详细的问题分析、思路分析以及Java代码实现,包括求单链表中有效节点的个数、查找单链表中的倒数第k个节点、单链表的反转以及从尾到头打印单链表等题目。
31 1
数据结构与算法学习四:单链表面试题,新浪、腾讯【有难度】、百度面试题
|
23天前
|
机器学习/深度学习 算法 Java
机器学习、基础算法、python常见面试题必知必答系列大全:(面试问题持续更新)
机器学习、基础算法、python常见面试题必知必答系列大全:(面试问题持续更新)
|
28天前
|
算法 Java 数据库
美团面试:百亿级分片,如何设计基因算法?
40岁老架构师尼恩在读者群中分享了关于分库分表的基因算法设计,旨在帮助大家应对一线互联网企业的面试题。文章详细介绍了分库分表的背景、分片键的设计目标和建议,以及基因法的具体应用和优缺点。通过系统化的梳理,帮助读者提升架构、设计和开发水平,顺利通过面试。
美团面试:百亿级分片,如何设计基因算法?
|
1月前
|
存储 算法 关系型数据库
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
这篇文章主要介绍了多路查找树的基本概念,包括二叉树的局限性、多叉树的优化、B树及其变体(如2-3树、B+树、B*树)的特点和应用,旨在帮助读者理解这些数据结构在文件系统和数据库系统中的重要性和效率。
18 0
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
|
1月前
|
算法 Java 数据中心
探讨面试常见问题雪花算法、时钟回拨问题,java中优雅的实现方式
【10月更文挑战第2天】在大数据量系统中,分布式ID生成是一个关键问题。为了保证在分布式环境下生成的ID唯一、有序且高效,业界提出了多种解决方案,其中雪花算法(Snowflake Algorithm)是一种广泛应用的分布式ID生成算法。本文将详细介绍雪花算法的原理、实现及其处理时钟回拨问题的方法,并提供Java代码示例。
66 2
|
1月前
|
存储 算法
数据结构与算法学习十六:树的知识、二叉树、二叉树的遍历(前序、中序、后序、层次)、二叉树的查找(前序、中序、后序、层次)、二叉树的删除
这篇文章主要介绍了树和二叉树的基础知识,包括树的存储方式、二叉树的定义、遍历方法(前序、中序、后序、层次遍历),以及二叉树的查找和删除操作。
23 0