重构一棵树的方案数(2022-2-16)每日一练(未解决)

1719. 重构一棵树的方案数(2022-2-16)

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

  • pairs 中没有重复元素
  • xi < yi

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

  • 树所包含的所有节点值都在 pairs 中。
  • 一个数对 [xi, yi] 出现在 pairs当且仅当 xiyi 的祖先或者 yixi 的祖先。
  • **注意:**构造出来的树不一定是二叉树。

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

请你返回:

  • 如果 ways == 0 ,返回 0
  • 如果 ways == 1 ,返回 1
  • 如果 ways > 1 ,返回 2

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

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

示例 1:

img

输入:pairs = [[1,2],[2,3]]
输出:1
解释:如上图所示,有且只有一个符合规定的有根树。

示例 2:

img

输入: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 中的元素互不相同。

解题思路

这道题实在是不会写,看题解也一知半解,不太懂。

只好先放这里了,下边是我仿照官方题解(就是抄的)写的代码

var checkWays = function (pairs) {
  let adj = new Map()
  for (let n of pairs) {
    if (!adj.has(n[0])) adj.set(n[0], new Set())
    if (!adj.has(n[1])) adj.set(n[1], new Set())
    adj.get(n[0]).add(n[1])
    adj.get(n[1]).add(n[0])
  }
  let root = -1
  for (let [node, neg] of adj.entries()) {
    console.log(node, neg)
    if (neg.size === adj.size - 1) root = node
  }
  if (root == -1) return 0
  let res = 1
  for (const [node, neg] of adj.entries()) {
    if (root == node) continue
    let curDegree = neg.size
    let parentNode = -1, parentDegree = Infinity
    for (const neighbor of neg) {
      if (adj.has(neighbor) &&
        adj.get(neighbor).size < parentDegree &&
        adj.get(neighbor).size >= curDegree) {
        parentNode = neighbor
        parentDegree = adj.get(neighbor).size
      }
    }
    if (parentNode == -1) return 0
    for (const neighbour of neg) {
      if (neighbour === parentNode) {
        continue;
      }
      if (!adj.get(parentNode).has(neighbour)) {
        return 0;
      }
    }
    if (parentDegree === curDegree) {
      res = 2;
    }
  }
  return res
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值