lintcode 1813 · 构造二叉树 题解

题目链接

https://www.lintcode.com/problem/1813/

题目描述

描述
给你一系列的边,你需要通过这些边来判断是否能够正确生成二叉树,如果可以生成一个二叉树则返回"successful",不可以则按照错误类型进行返回优先级最高的错误。

在输入中,[“A”,“B”]表示存在一条由节点A指向节点B的边。
你需要判断输入数据是否是正确的。若数据中所有节点的值都是"A"-"Z"之间的长度为1的字符串,则我们认为该数据是正确的。
错误类型的优先级从大到小排序是:“more children”, “repeat edge”, “have cycle”, “more parent”, “input error”。
北大学霸的《算法通关手册.pdf》

微信加【jiuzhang1104】备注【通关】即可参加

pair.length> = 1。
“more children” 表示一个节点有两个以上的节点。
“repeat edge” 表示某一条边出现了多次。
“have cycle” 表示有一个周期。
“more parent” 表示一个节点具有两个父节点或这颗树具有更多根节点。
“input error” 表示输入是不正确的。
样例
示例1:
输入:
pair: [[“A”,“C”],[“A”,“B”],[“A”,“D”]]
输出: “more children”
解释:A 有3个孩子节点,因此你应该返回 “more children” 的错误类型
示例2:
输入:
pair:[[“A”,“C”],[“C”,“A”],[“C”,“B”],[“A”,“C”]]
输出: “repeat edge”
解释: A->C和C->A两条边形成了一个环,但是两条有两条边为A->C,按照错误优先级应该返回“repeat edge”.

java答案

public class Solution {
    /**
     * @param pair: a list of [parent, children]
     * @return: a string of error type
     */
    public String constructBinaryTree(List<List<String>> pair) {
        UF uf = new UF(); //并查集,主要用于判断并查集集合数,如果大于1,是input error
        int size = pair.size();
        Map<String, String> issampe = new HashMap<>(); //k:开始点 v:结束点,判断2条边相同
        Map<String, String> curparent = new HashMap<>(); //k: 自己 v:父节点  判断自己是否有多个父节点
        Map<String, List<String>> childs = new HashMap<>(); //k: 自己 v:父节点    判断自己的子节点是否大于2
        for (int i = 0; i < size; i++) {
            String p = pair.get(i).get(0);
            String c = pair.get(i).get(1);
            uf.find(p);
            uf.find(c);
            uf.union(p, c);

            if (!childs.containsKey(p))
                childs.put(p, new ArrayList<>());

            childs.get(p).add(c);
            if (childs.containsKey(p) && childs.get(p).size() > 2) return "more children";
        }

        for (int i = 0; i < size; i++) {
            String p = pair.get(i).get(0);
            String c = pair.get(i).get(1);
            if (issampe.containsKey(p) && issampe.get(p).equals(c)) return "repeat edge";
            issampe.put(p, c);
        }

        for (int i = 0; i < size; i++) {
            String p = pair.get(i).get(0);
            String c = pair.get(i).get(1);

            String cparent = uf.find(c);
            if (c.equals(cparent)) return "have cycle";
        }

        for (int i = 0; i < size; i++) {
            String p = pair.get(i).get(0);
            String c = pair.get(i).get(1);

            if (curparent.containsKey(c) && !curparent.get(c).equals(p)) return "more parent";
            curparent.put(c, p);

        }
        for (int i = 0; i < size; i++) {
            String p = pair.get(i).get(0);
            String c = pair.get(i).get(1);
            if (!childs.containsKey(p))
                childs.put(p, new ArrayList<>());

            if (p.length() > 1 || c.length() > 1) return "input error";
        }


        if (uf.sets > 1) return "input error";
        return "successful";
    }

    static class UF {
        Map<String, String> parents = new HashMap<>();
        Map<String, Integer> size = new HashMap<>();
        Map<Integer, String> help = new HashMap<>();
        int sets;

        public String find(String x) {
            if (!parents.containsKey(x)) {
                parents.put(x, x);
                size.put(x, 1);
                sets++;
            }

            int hi = 0;
            while (!x.equals(parents.get(x))) {
                help.put(hi++, x);
                x = parents.get(x);
            }
            for (hi--; hi >= 0; hi--) {
                parents.put(help.get(hi), x);
            }
            return x;
        }

        public void union(String a, String b) {
            String f1 = find(a);
            String f2 = find(b);
            if (!f1.equals(f2)) {
                int s1 = size.get(a);
                int s2 = size.get(b);
                if (s1 >= s2) {
                    size.put(f1, s1 + s2);
                    parents.put(f2, f1);
                } else {
                    size.put(f2, s1 + s2);
                    parents.put(f1, f2);
                }
                sets--;
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵长辉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值