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


相关文章
|
6天前
|
机器学习/深度学习 数据采集 算法
Python用逻辑回归、决策树、SVM、XGBoost 算法机器学习预测用户信贷行为数据分析报告
Python用逻辑回归、决策树、SVM、XGBoost 算法机器学习预测用户信贷行为数据分析报告
|
3天前
|
机器学习/深度学习 算法 数据处理
探索机器学习中的决策树算法
【5月更文挑战第18天】探索机器学习中的决策树算法,一种基于树形结构的监督学习,常用于分类和回归。算法通过递归划分数据,选择最优特征以提高子集纯净度。优点包括直观、高效、健壮和可解释,但易过拟合、对连续数据处理不佳且不稳定。广泛应用于信贷风险评估、医疗诊断和商品推荐等领域。优化方法包括集成学习、特征工程、剪枝策略和参数调优。
|
4天前
|
算法 前端开发 Android开发
Android文字基线Baseline算法的使用讲解,Android开发面试题
Android文字基线Baseline算法的使用讲解,Android开发面试题
Android文字基线Baseline算法的使用讲解,Android开发面试题
|
4天前
|
算法 Java API
Groovy脚本基础全攻略,android面试算法题
Groovy脚本基础全攻略,android面试算法题
|
4天前
|
NoSQL 算法 Java
【redis源码学习】持久化机制,java程序员面试算法宝典pdf
【redis源码学习】持久化机制,java程序员面试算法宝典pdf
|
4天前
|
算法 架构师 网络协议
对标腾讯T9架构师的 Android 面试题新鲜出炉,算法真的太重要了
对标腾讯T9架构师的 Android 面试题新鲜出炉,算法真的太重要了
|
5天前
|
移动开发 算法 搜索推荐
2024最新Android算法相关面试大全,请查收
2024最新Android算法相关面试大全,请查收
|
6天前
|
机器学习/深度学习 算法
理解并应用机器学习算法:决策树
【5月更文挑战第12天】决策树是直观的分类与回归机器学习算法,通过树状结构模拟决策过程。每个内部节点代表特征属性,分支代表属性取值,叶子节点代表类别。构建过程包括特征选择(如信息增益、基尼指数等)、决策树生成和剪枝(预剪枝和后剪枝)以防止过拟合。广泛应用在信贷风险评估、医疗诊断等领域。理解并掌握决策树有助于解决实际问题。
|
6天前
|
存储 缓存 算法
数据结构与算法 树(B树,B+树,红黑树待完善)
数据结构与算法 树(B树,B+树,红黑树待完善)
20 0
|
6天前
|
算法 安全 定位技术
【刷题】备战蓝桥杯 — dfs 算法
dfs算法在数据较小的情况下可以使用。 一定一定要确定好终止条件,避免栈溢出。 相应做好回溯,保证每次的遍历都是不一样的选择,避免少结果。 针对题目进行对应细节处理,有能力的话可以进行剪枝优化!!!
14 0