首页 > 试题广场 >

Department list to tree

[编程题]Department list to tree
  • 热度指数:1112 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
Convert the department list to preorder traversal of the name of department tree
示例1

输入

[["d1", "d0", "IT"], ["d2", "d0", "RD"], ["d0", "", "The Company"], ["d3", "d0", "HR"]]

输出

["The Company","HR","IT","RD"]

说明

On each level of the department tree, departments are listed in alphabetical order of the name
从头到尾没有看懂题目意思
发表于 2020-08-11 15:24:24 回复(8)
import java.util.*;

/**
 * 规律:先序遍历 但是每一层要按照字典序进行
 */
public class Solution {
    /**
     * Convert the department list to preorder traversal of the department tree
     * @param departments string字符串二维数组 [["id1", "parentId", "name"]...], there's only one root department with empty parent id.
     * @return string字符串一维数组
     */
     /**
     * 节点结构
     */
    class Node {
        String id;
        List<Node> sons;
        String name;

        Node(String id, String name) {
            this.id = id;
            this.sons = new ArrayList<>();
            this.name = name;
        }
    }

    List<String> res = new ArrayList<>();

    public String[] listToTree(String[][] departments) {

        System.out.println("z".compareTo("def"));

        //排序 每一层按照字典序进行
        for (int i = 0; i < departments.length; i++) {
            for (int j = i + 1; j < departments.length; j++) {
                if (departments[i][2].compareTo(departments[j][2]) > 0) {
                    String[] temp = departments[i];
                    departments[i] = departments[j];
                    departments[j] = temp;
                }
            }
        }


        //记录父节点
        Deque<String> parents = new ArrayDeque<>();

        //hashMap id Node
        HashMap<String, Node> hashMap = new HashMap<>();
        //超级节点
        hashMap.put("", new Node("", ""));
        //添加节点
        for (int i = 0; i < departments.length; i++) {
            //添加一个节点
            Node n = new Node(departments[i][0], departments[i][2]);
            hashMap.put(departments[i][0], n);
        }
        //添加儿子节点
        for (int i = 0; i < departments.length; i++) {
            //添加一个节点
            hashMap.get(departments[i][1]).sons.add(hashMap.get(departments[i][0]));
        }

        //先序
        preOrder(hashMap, hashMap.get("").sons.get(0).id);

        String[] result = new String[departments.length];

        for (int i = 0; i < res.size(); i++) {
            result[i] = res.get(i);
        }

        return result;
    }

    /**
     * 先序遍历
     *
     * @param hashMap
     * @param curNodeId
     */
    public void preOrder(HashMap<String, Node> hashMap, String curNodeId) {

        res.add(hashMap.get(curNodeId).name);
        if (hashMap.get(curNodeId).sons.size() == 0) {
            return;
        }
        for (Node n : hashMap.get(curNodeId).sons) {
            preOrder(hashMap, n.id);
        }

    }
}

发表于 2020-08-06 00:06:13 回复(1)
class TreeNode:
    def __init__(self, ID, name):
        self.ID = ID
        self.name = name
        self.children = []
class Solution:
    def listToTree(self , departments ):
        # write code here
        node_dict = {}
        for de in departments:
            node = TreeNode(de[0], de[2])
            node_dict[de[0]] = node
            if de[1] == '':
                root = node
        for de in departments:
            if de[1] != '':
                node = node_dict[de[1]]
                node.children.append(node_dict[de[0]])
        result = [root.name]
        def preorder(tree_node):
            if tree_node is None:
                return
            for child in sorted(tree_node.children, key=lambda x:x.name):
                result.append(child.name)
                preorder(child)
        preorder(root)
        return result
import json
input_ = json.loads(input())
result = Solution().listToTree(input_)
result = str(result).replace('\'','\"')
result = result.replace('\", ','\",')
print(result)

发表于 2020-08-02 23:30:29 回复(0)
class Solution {
public:

vector<string> listToTree(string** departments, int departmentsRowLen, int* departmentsColLen) 
{
    map<string, string> idToName;
    map<string, set<string>> departTree;
    vector<string> res;
    int root;
//1.找到根节点 2.建立id到名字的映射
    for (int i = 0; i<departmentsRowLen; ++i)
    {
            idToName[departments[i][0]] = departments[i][2];
            if (departments[i][1]=="")    
            {   
                root = i;
            }
            departTree[departments[i][2]] = {};

    }
//找爹,借助map建立多叉树,以set为子节点集合
    for (int i = 0; i < departmentsRowLen; i++)
    {
        if (departments[i][1] != "")        
            departTree[idToName[departments[i][1]]].insert(departments[i][2]);
    }
// 递归 前序遍历
    preOrder(departments[root][2],departTree,res);
    return res;
}
//多叉树前序遍历
void preOrder(string s, map<string, set<string>>& departTree,vector<string>& res)
{
    res.push_back(s);
    if (departTree[s].empty()==false)
    {
        for (auto it= departTree[s].begin(); it!= departTree[s].end(); it++)
            {
                preOrder(*it, departTree, res);
            }
    }
}

};
编辑于 2020-07-31 09:45:27 回复(0)
贴一个我个人用Python表示树结构时比较习惯的做法
每个结点有唯一的标签和其他数据属性,放到一个dict(C++中对应map或unordered_map,Java中称为Map)里,标签为键,属性为值
如果属性有多个,把属性写成dict(就像下面这样)
{
    "tuple": {
        "classification": "sequential",
        "element_type_constraints": [],
        "mutable": False
    },
    "list": {
        "classification": "sequential",
        "element_type_constraints": [],
        "mutable": True
    },
    "set": {
        "classification": "unordered",
        "element_type_constraints": ["hash"],
        "mutable": True
    }
}

结点之间的层次关系,每个结点的标签为键,子结点标签的list(有些情况是set)为值(就像下面这样)
{
    "java.util.Collection": [
        "java.util.Queue",
        "java.util.List",
        "java.util.Set",
        ...
    ],
    "java.util.Queue": [
        "java.util.BlockingQueue",
        "java.util.Deque",
        "java.util.PriorityQueue",
        ...
    ],
    "java.util.Deque": [
        "java.util.ArrayDeque",
        "java.util.LinkedList",
        ...
    ],
    "java.util.List": [
        "java.util.ArrayList",
        "java.util.LinkedList",
        ...
    ],
    "java.util.Set": [
        "java.util.HashSet",
        "java.util.TreeSet",
        "java.util.LinkedHashSet",
        "java.util.EnumSet",
        ...
    ]
}


最后是本题代码
class Solution:
    def build_tree(self, items):
        name_index = {}
        branch_index = {}
        root = None
        for _id, _parent, _name in items:
            try:
                branch_index[_parent].append(_id)
            except KeyError:
                branch_index[_parent] = [_id]
            name_index[_id] = _name
            if not _parent:
                root = _id
        for _k, _v in branch_index.items():
            _v.sort(key=name_index.__getitem__)
        return name_index, branch_index, root
    
    def listToTree(self , departments ):
        name_index, branch_index, root = self.build_tree(departments)
        
        result = []
        
        def pre_order(temp_root):
            result.append(name_index[temp_root])
            try:
                _children = branch_index[temp_root]
            except KeyError:
                return
            else:
                for _child in _children:
                    pre_order(_child)
        
        pre_order(root)
        return result



发表于 2020-08-26 18:00:56 回复(0)
题目并不难,只是题干描述。。。,看代码注释才明白是干什么,根据一个给定列表恢复树,并且返回前序遍历该树的结果,
列表的格式:[["id1", "parentId", "name"]...] 意思是 这个节点的id, 父节点id,节点名称,root的parentid为空。
1. 建立一个id-name转换表,并且找到根节点
2. 找到每个节点的父节点 (在父节点中插入该节点)
3. 先序遍历
发表于 2020-09-09 11:12:49 回复(0)
轮头像
三步走:
1、构建id->对象的map
2、构建父子关系
3、遍历

import java.util.*;


public class Solution {
    /**
     * Convert the department list to preorder traversal of the department tree
     * @param departments string字符串二维数组 [["id1", "parentId", "name"]...], there's only one root department with empty parent id.
     * @return string字符串一维数组
     */
    public String[] listToTree (String[][] departments) {
        Map<String, Department> depById = new HashMap<>(departments.length);
        
        // 生成map
        for (String[] department: departments) {
            depById.put(department[0], new Department(department[0], department[1], department[2]));
        }
        
        Department root = null;
        
        // 生成父子关系
        for (Map.Entry<String, Department> entry: depById.entrySet()) {
            Department department = entry.getValue();
            if (Objects.equals(department.parentName, "")) {
                root = department;
            } else {
                Department parent = depById.get(department.parentName);
                parent.children.add(department);
            }
        }
        
        if (root == null) throw new RuntimeException("找不到根节点!" + Arrays.deepToString(departments));
        
        // 排序
        for (Map.Entry<String, Department> entry: depById.entrySet()) {
            Department department = entry.getValue();
            department.children.sort(new Comparator<Department>() {
                public int compare(Department a, Department b) {
                    return a.name.compareTo(b.name);
                }
            });
        }
        
        List<String> res = new ArrayList<>(departments.length);
        res.add(root.name);
        return out(root, res).toArray(new String[0]);
    }
    
    static List<String> out(Department department, List<String> res) {
        for (Department child: department.children) {
            res.add(child.name);
            out(child, res);
        }
        return res;
    }
    
    public static class Department {
        public String id;
        public String parentName;
        public String name;
        public List<Department> children = new ArrayList<>();
        public Department(String id, String parentName, String name) {
            this.id = id;
            this.parentName = parentName;
            this.name = name;
        }
    }
}


发表于 2020-10-24 20:17:47 回复(0)
import java.util.*;
 
 
public class Solution {
    /**
     * Convert the department list to preorder traversal of the department tree
     * @param departments string字符串二维数组 [["id1", "parentId", "name"]...], there's only one root department with empty parent id.
     * @return string字符串一维数组
     */
    int index = 0;
    public String[] listToTree (String[][] departments) {
        // write code here
        Map<String,List<String>> map = new HashMap<>();
        Map<String,String> nameMapper = new HashMap<>();
        for(int i = 0;i < departments.length;i++){
            String id = departments[i][0];
            String parentId = departments[i][1];
            String name = departments[i][2];
            if(map.get(parentId) == null){
                List<String> tmp = new ArrayList<>();
                map.put(parentId,tmp);
            }
            if(map.get(id) == null){
                List<String> tmp = new ArrayList<>();
                map.put(id,tmp);
            }
            map.get(parentId).add(id);
            nameMapper.put(id,name);
        }
        int len = departments.length;
        String[] ans = new String[len];
        dfs(map.get("").get(0),map,nameMapper,ans);
        return ans;
    }
    void dfs(String cur,Map<String,List<String>> map,Map<String,String> nameMapper,String[] ans){
        ans[index++] = nameMapper.get(cur);
        List<String> list = new ArrayList<>();
        for(int i = 0;i < map.get(cur).size();i++){
            String id = map.get(cur).get(i);
            list.add(id);
        }
        Collections.sort(list,(st1,st2)->{
            String cur1 = nameMapper.get(st1);
            String cur2 = nameMapper.get(st2);
            for(int i = 0;i < Math.min(cur1.length(),cur2.length());i++){
                if(cur1.charAt(i) != cur2.charAt(i)){
                    return cur1.charAt(i) - cur2.charAt(i);
                }
            }
            return cur1.length() - cur2.length();
        });
        for(int i = 0;i < list.size();i++){
            dfs(list.get(i),map,nameMapper,ans);
        }
        return;
    }
}

发表于 2021-01-04 22:08:08 回复(0)
// 直接递归就行,注意加进去的顺序
functionlistToTree(departments) {
  let res = {};
  getDepartOrder(departments, "", res, 1);
  returnObject.keys(res).reduce((cur, level) => {
    returncur.concat(res[level].sort())
  }, []);
}
 
functiongetDepartOrder(departments, curId, res, level) {
  const order = departments
    .filter(([id, pId]) => pId === curId)
    .sort((a, b) => a[2].localeCompare(b[2]));
  order.forEach(i => {
    res[level] = res[level] || [];
    res[level].push(i[2])
    getDepartOrder(departments.filter(([id, pId]) => pId !== curId), i[0], res, ++level)
  })
}
module.exports = {
    listToTree : listToTree
};
发表于 2020-12-02 18:00:44 回复(0)
import queue
class Node:
    def __init__(self,id:str, name:str) :
        self.id = id
        self.sons = []
        self.name = name
    


class Solution :
   

    res = []

    def listToTree(self,departments) :



        
        for  i in range(len(departments)):
            for j in range(i + 1,len( departments)):
                if departments[i][2] > departments[j][2] :
                    temp = departments[i]
                    departments[i] = departments[j]
                    departments[j] = temp


       
        parents = queue.Queue()

    
        hashMap = dict()
        
       
        hashMap[""] =  Node("", "")
      
        for i in range(len( departments)):
      
            hashMap[departments[i][0]] = Node(departments[i][0], departments[i][2])
        

        for i in range(len( departments)):
    
            hashMap.get(departments[i][1]).sons.append(hashMap.get(departments[i][0]))


        self.preOrder(hashMap, hashMap.get("").sons[0].id)

        result = []

        for i in range(len( self.res)):
            result.append(self.res[i])
        

        return result
    


    def preOrder(self,hashMap:dict, curNodeId:str):

        self.res.append(hashMap.get(curNodeId).name);
        if len(hashMap.get(curNodeId).sons) == 0 :
            return
        
        for n in hashMap.get(curNodeId).sons :
            self.preOrder(hashMap, n.id)

发表于 2020-11-15 09:23:43 回复(0)
建树  dfs  常见的操作   非递归dfs写法   
函数的第三个参数固定是3

class Solution {
    public:
    vector<string> listToTree(string** departments,
                              int departmentsRowLen, int* departmentsColLen){
         // 儿子  父亲  儿子名字
        int l=departmentsRowLen;

        static const int maxn=1e5+10;
        vector<string> vs[maxn];
        map<string,int> mp;
        string root;

        int k=0;  // 名字重新映射
        for(int i=0;i<l;i++){
            string aa,bb,cc;
            aa=departments[i][0];
            bb=departments[i][1];
            cc=departments[i][2];
            // 映射
            if(mp.find(aa)==mp.end()){  mp[aa]=++k; } mp[cc]=mp[aa];
            if(mp.find(bb)==mp.end()){  mp[bb]=++k; }
            // 建树
            if(bb=="")  root=cc;
            else {  vs[mp[bb]].push_back(cc); }

        }
        for(int i=1;i<=k;i++) sort(vs[i].begin(),vs[i].end());
        vector<string> ans;
        deque<string> dq; dq.push_back(root);
        while(!dq.empty()){
            string kk; kk=dq.front();  dq.pop_front();
            ans.push_back(kk);
            for(int i=vs[mp[kk]].size()-1;i>=0;i--){
                dq.push_front(vs[mp[kk]][i]);
            }
        }
        return ans;

    }
};




发表于 2020-09-16 19:31:27 回复(0)
不知道是我智商有问题还是题目有问题,我还是老老实实算题库得了
发表于 2020-09-13 18:47:03 回复(0)
public String[] listToTree (String[][] departments) {
        Map<String, String> keyToValue = new HashMap<String, String>();
        for(int i=0; i<departments.length; i++){
            keyToValue.put(departments[i][0], departments[i][2]);
        }
        List<String> one = null;
        Map<String, List<String>> map = new HashMap<String, List<String>>();
        String first = null;
        String firstKey = null;
        for(int i=0; i<departments.length; i++){
            if("".equals(departments[i][1])){
                firstKey = departments[i][0];
                first = departments[i][2];
            }else {
                if(map.get(departments[i][1])==null){
                    one = new ArrayList<String>();
                    one.add(departments[i][0]);
                    map.put(departments[i][1], one);
                }else{
                    map.get(departments[i][1]).add(departments[i][0]);
                }
            }
        }
        List<String> list = new ArrayList<String>();
        list.add(first);
        //递归放入列表
        set(list, map, keyToValue, firstKey);
        String[] re = list.parallelStream().toArray(String[]::new);
        return re;
    }
    
    public void set(List<String> list, Map<String, List<String>> map, 
            Map<String, String> keyToValue, String key){
        //冒泡排序
        mySort(map.get(key), keyToValue);
        for(String k : map.get(key)){
            if(map.get(k)==null){
                list.add(keyToValue.get(k));
            }else{
                list.add(keyToValue.get(k));
                set(list, map, keyToValue, k);
            }
        }
    }
    
    public List<String> mySort(List<String> list, Map<String, String> keyToValue){
        for(int i=0; i<list.size()-1; i++){
            for(int j=0; j<list.size()-1-i; j++){
                if(keyToValue.get(list.get(j)).compareTo(keyToValue.get(list.get(j+1)))>0){
                    String temp = list.get(j);
                    list.set(j, list.get(j+1));
                    list.set(j+1, temp);
                }
            }
        }
        return list;
    }
发表于 2020-09-08 15:17:13 回复(0)

departmentsColLen是一个不需要的参数,而本题也表意不明,ColLen确定是3了却给出一个变量,折腾了半天。

发表于 2020-09-07 16:31:00 回复(0)
      /**
     * N叉树前序遍历的非递归实现
     * @param departments
     * @return 先序遍历序列
     */
    public String[] listToTree (String[][] departments) {
        
        // 建立ID与Name的映射关系
        Map<String, String> idNameMap = new HashMap<String, String>();
        for (int i = 0; i < departments.length; i++) {
            idNameMap.put(departments[i][0],departments[i][2]);
        }
        
        // 用邻接表存储树形结构 由于部门名称唯一 故可将部门名称作为Key
        Map<String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>();
        String root = null;
        for (int i = 0; i < departments.length; i++) {
            if (map.containsKey(idNameMap.get(departments[i][1]))) {
                map.get(idNameMap.get(departments[i][1])).add(idNameMap.get(departments[i][0]));
            }else {
                if (!departments[i][1].equals("")) {
                    ArrayList<String> list = new ArrayList<String>();
                    list.add(idNameMap.get(departments[i][0]));
                    map.put(idNameMap.get(departments[i][1]), list);
                }
                
                if (departments[i][1].equals("")) {
                    root = idNameMap.get(departments[i][0]);
                }
            }    
        }
        
        // 利用栈实现N叉树前序遍历的非递归
        String[] result = new String[departments.length];
        LinkedList<String> stack = new LinkedList<String>();
        
        stack.push(root);
        int index = 0;
        ArrayList<String> list = null;
        while (! stack.isEmpty()) {
            String currentNode = stack.pop();
            result[index++] = currentNode; // 访问当前节点

            if (map.get(currentNode) != null) { // 当前节点有孩子节点
                list = map.get(currentNode);
                Collections.sort(list); // 按字典排序
                for (int i = list.size() - 1; i >= 0; i--) {  // 注意这里安排字典序的倒序插入栈中
                    stack.push(list.get(i));
                }
            }    
        }
        
        return result;
    }

编辑于 2020-07-31 16:56:40 回复(0)