LeetCode-1719 重构一棵树的方案数

简介: LeetCode-1719 重构一棵树的方案数

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/number-of-ways-to-reconstruct-a-tree

题目描述

给你一个数组 pairs ,其中 pairs[i] = [xi, yi] ,并且满足:

pairs 中没有重复元素

xi < yi

令 ways 为满足下面条件的有根树的方案数:

树所包含的所有节点值都在 pairs 中。

一个数对 [xi, yi] 出现在 pairs 中 当且仅当 xi 是 yi 的祖先或者 yi 是 xi 的祖先。

注意:构造出来的树不一定是二叉树。

两棵树被视为不同的方案当存在至少一个节点在两棵树中有不同的父节点。

请你返回:

如果 ways == 0 ,返回 0 。

如果 ways == 1 ,返回 1 。

如果 ways > 1 ,返回 2 。

一棵 有根树 指的是只有一个根节点的树,所有边都是从根往外的方向。

我们称从根到一个节点路径上的任意一个节点(除去节点本身)都是该节点的 祖先 。根节点没有祖先。

 

示例 1:

 

输入:pairs = [[1,2],[2,3]]
输出:1

解释:如上图所示,有且只有一个符合规定的有根树。

示例 2:

 

 

输入:pairs = [[1,2],[2,3],[1,3]]
输出:2

解释:有多个符合规定的有根树,其中三个如上图所示。

示例 3:

输入:pairs = [[1,2],[2,3],[2,4],[1,5]]
输出:0

解释:没有符合规定的有根树。

 

提示:

1 <= pairs.length <= 105
1 <= xi < yi <= 500
pairs 中的元素互不相同。

解题思路

这道题确实很难。光是思路就十分难想。

首先,如果是一棵树,那么他肯定有一个根结点,并且这个根结点与其他结点的连接数应该是n-1 所以,我们可以统计所有结点的连接数,如果没有n-1的结点,那么可以判断无法构成一棵树。

已知如果一个结点是某些结点的祖先,那么其父节点也是这些结点的祖先。所以我们依次判断结点的父结点连接的结点是否全部包含该结点所连接的结点。

寻找父节点的方法是寻找该结点中,结点连接数最小的并且连接数大于等于该结点的连接数的结点,则这个结点就是该结点的父结点。同时,如果一个结点与其父节点连接数相同,那么他们可以互相交换,这种情况发生就表示构成的树种类大于1。

代码展示

class Solution {
public:
    int checkWays(vector<vector<int>>& pairs) {
        unordered_map<int, unordered_set<int>> mapisetAdj;//degree 等于set的大小
        int iRoot = 0, iN = 0, iRet = 1;
        for(auto iter: pairs)
        {
            mapisetAdj[iter[0]].emplace(iter[1]);
            mapisetAdj[iter[1]].emplace(iter[0]);
        }
        iN = mapisetAdj.size();
        for(auto iter: mapisetAdj)
        {
            if(iter.second.size() == iN - 1)
            {
                iRoot = iter.first;
            }
        }
        if(!iRoot)
            return 0;
        for(auto iter: mapisetAdj)
        {
            if(iter.first == iRoot)
                continue;
            int iParent = 0, iParentDegree = INT_MAX;
            for(auto iter2: iter.second)
            {
                if(iParentDegree > mapisetAdj[iter2].size() && mapisetAdj[iter2].size() >= iter.second.size())
                {
                    iParent = iter2;
                    iParentDegree = mapisetAdj[iter2].size();
                }
            }
            if(!iParent)
                return 0;
            for(auto iter2: iter.second)
            {
                if (iter2 == iParent)
                    continue;
                if(!mapisetAdj[iParent].count(iter2))
                    return 0;
            }
            if(iParentDegree == iter.second.size())
            {
                iRet = 2;
            }
        }
        return iRet;
    }
};


运行结果

 

相关文章
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 26. 树的子结构
这篇文章提供了解决LeetCode上"剑指Offer 26. 树的子结构"问题的Python代码实现和解析,判断一棵树B是否是另一棵树A的子结构。
55 4
|
4月前
|
Python
【Leetcode刷题Python】538. 把二叉搜索树转换为累加树
LeetCode上538号问题"把二叉搜索树转换为累加树"的Python实现,使用反向中序遍历并记录节点值之和来更新每个节点的新值。
25 3
|
7月前
|
算法 C语言 容器
从C语言到C++_25(树的十道OJ题)力扣:606+102+107+236+426+105+106+144+94+145(下)
从C语言到C++_25(树的十道OJ题)力扣:606+102+107+236+426+105+106+144+94+145
69 7
|
7月前
|
C语言
从C语言到C++_25(树的十道OJ题)力扣:606+102+107+236+426+105+106+144+94+145(中)
从C语言到C++_25(树的十道OJ题)力扣:606+102+107+236+426+105+106+144+94+145
59 1
|
7月前
|
算法 C语言 C++
从C语言到C++_25(树的十道OJ题)力扣:606+102+107+236+426+105+106+144+94+145(上)
从C语言到C++_25(树的十道OJ题)力扣:606+102+107+236+426+105+106+144+94+145
46 1
|
7月前
LeetCode———100——相同的树
LeetCode———100——相同的树
|
7月前
力扣337.打家劫舍3(树形dp)
力扣337.打家劫舍3(树形dp)
|
6月前
|
SQL 算法 数据可视化
LeetCode题目99:图解中叙遍历、Morris遍历实现恢复二叉树搜索树【python】
LeetCode题目99:图解中叙遍历、Morris遍历实现恢复二叉树搜索树【python】
|
6月前
|
存储 SQL 算法
LeetCode题目100:递归、迭代、dfs使用栈多种算法图解相同的树
LeetCode题目100:递归、迭代、dfs使用栈多种算法图解相同的树
|
6月前
|
存储 算法 数据可视化
python多种算法对比图解实现 验证二叉树搜索树【力扣98】
python多种算法对比图解实现 验证二叉树搜索树【力扣98】