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;
    }
}


相关文章
|
4天前
|
机器学习/深度学习 数据采集 算法
Python用逻辑回归、决策树、SVM、XGBoost 算法机器学习预测用户信贷行为数据分析报告
Python用逻辑回归、决策树、SVM、XGBoost 算法机器学习预测用户信贷行为数据分析报告
13 1
|
2天前
|
机器学习/深度学习 算法 数据可视化
Matlab决策树、模糊C-均值聚类算法分析高校教师职称学历评分可视化
Matlab决策树、模糊C-均值聚类算法分析高校教师职称学历评分可视化
10 0
|
2天前
|
机器学习/深度学习 算法 数据可视化
【Python机器学习专栏】决策树算法的实现与解释
【4月更文挑战第30天】本文探讨了决策树算法,一种流行的监督学习方法,用于分类和回归。文章阐述了决策树的基本原理,其中内部节点代表特征判断,分支表示判断结果,叶节点代表类别。信息增益等标准用于衡量特征重要性。通过Python的scikit-learn库展示了构建鸢尾花数据集分类器的示例,包括训练、预测、评估和可视化决策树。最后,讨论了模型解释和特征重要性评估在优化中的作用。
|
3天前
|
存储 缓存 算法
面试遇到算法题:实现LRU缓存
V哥的这个实现的关键在于维护一个双向链表,它可以帮助我们快速地访问、更新和删除最近最少使用的节点,同时使用哈希表来提供快速的查找能力。这样,我们就可以在 O(1) 的时间复杂度内完成所有的缓存操作。哈哈干净利索,回答完毕。
|
3天前
|
机器学习/深度学习 算法 搜索推荐
R语言LASSO特征选择、决策树CART算法和CHAID算法电商网站购物行为预测分析
R语言LASSO特征选择、决策树CART算法和CHAID算法电商网站购物行为预测分析
|
6天前
|
算法
数据结构与算法-AVL树入门
数据结构与算法-AVL树入门
9 0
|
6天前
|
算法
数据结构与算法-Trie树添加与搜索
数据结构与算法-Trie树添加与搜索
5 0
|
6天前
|
算法 数据可视化 Java
数据结构与算法-单向链表的实现以及相关面试题
数据结构与算法-单向链表的实现以及相关面试题
7 0
|
6天前
|
机器学习/深度学习 数据采集 算法
共享单车需求量数据用CART决策树、随机森林以及XGBOOST算法登记分类及影响因素分析
共享单车需求量数据用CART决策树、随机森林以及XGBOOST算法登记分类及影响因素分析
13 0
|
8天前
|
机器学习/深度学习 算法 数据挖掘
数据分享|R语言逻辑回归、Naive Bayes贝叶斯、决策树、随机森林算法预测心脏病
数据分享|R语言逻辑回归、Naive Bayes贝叶斯、决策树、随机森林算法预测心脏病
23 6