美文网首页
5870. 每棵子树内缺失的最小基因值

5870. 每棵子树内缺失的最小基因值

作者: 来到了没有知识的荒原 | 来源:发表于2021-09-12 10:46 被阅读0次

5870. 每棵子树内缺失的最小基因值

方法1:dfs(利用基因值不同的性质,先找1,后做1)

题解

题解中找1和做1的前提是:只有在含有1的链上,才满足单调递增(不严格,non-decreasing)。
不含1的其他所有分支的节点的ans都是1。

如图所示,只有含1的链(红色)上面的答案是单调递增的

两边dfs搜索,复杂度为O(n)

另外:

    for (auto c : g[u])
      if (has1[c]) dfs2(c, nums);
    for (auto c : g[u])
      if (!has1[c]) dfs3(c, nums);

必须先遍历含有1(在链上的节点),否则,先遍历不含1的节点会干扰到含1链上的答案计算:

这棵树就是例子:计算节点3的时候,原本是[1,2,3],res[3]为4。但是如果先访问了左边的节点1,数字4就会被标记已经访问,已访问变成了[1,2,3,4],res[3]就会被记为5。
const int N = 1e5 + 10;
class Solution {
 public:
  vector<vector<int>> g;
  bool has1[N], vis[N];
  vector<int> res;
  int now;

  void dfs1(int u, vector<int>& nums) {
    if (nums[u] == 1) has1[u] = true;
    for (auto c : g[u]) {
      dfs1(c, nums);
      has1[u] |= has1[c];
    }
  }
  void dfs3(int u, vector<int>& nums) {
    for (auto c : g[u]) dfs3(c, nums);
    vis[nums[u]] = true;
  }
  void dfs2(int u, vector<int>& nums) {
    for (auto c : g[u])
      if (has1[c]) dfs2(c, nums);
    for (auto c : g[u])
      if (!has1[c]) dfs3(c, nums);
    vis[nums[u]] = true;
    while (vis[now]) now++;
    res[u] = now;
  }

  vector<int> smallestMissingValueSubtree(vector<int>& parents,
                                          vector<int>& nums) {
    memset(has1, 0, sizeof has1), memset(vis, 0, sizeof vis);
    int n = nums.size();
    now = 1;
    res.resize(n, 1), g.resize(n, vector<int>());
    for (int i = 1; i < n; i++) {
      g[parents[i]].push_back(i);
    }
    dfs1(0, nums);
    dfs2(0, nums);
    return res;
  }
};

方法2:启发式合并

类似于并查集的按秩合并
树上启发式合并
思想很简单,就是每次都把小集合并到大集合中去。
复杂度O(nlogn)

class Solution {
 public:
  vector<vector<int>> g;
  vector<int> mex;
  vector<int> arr;
  set<int> f(int v) {
    set<int> inSet;
    mex[v] = 1;
    for (int w : g[v]) {
      set<int> s = f(w);
      // 启发式合并:保证从小的集合合并到大的集合
      if (s.size() > inSet.size()) swap(s, inSet);

      for (auto x : s) inSet.insert(x);

      if (mex[w] > mex[v]) mex[v] = mex[w];
    }
    inSet.insert(arr[v]);
    while (inSet.count(mex[v])) {
      mex[v]++;  // 不断自增直至 mex[v] 不在集合中
    }
    return inSet;
  }
  vector<int> smallestMissingValueSubtree(vector<int>& parents,
                                          vector<int>& nums) {
    int n = parents.size();
    arr = nums;
    g.resize(n, vector<int>());
    mex.resize(n, 0);

    for (int i = 1; i < n; i++) {
      g[parents[i]].push_back(i);
    }

    f(0);
    return mex;
  }
};

两种做法有明显的时间差距:

n,利用性质dfs nlogn,启发式合并

相关文章

  • 5870. 每棵子树内缺失的最小基因值

    5870. 每棵子树内缺失的最小基因值[https://leetcode-cn.com/problems/smal...

  • 数据清洗 & 处理

    1. 数据清洗方法 缺失值:平均值、最大值、最小值或更为复杂的概率估计代替缺失值 去重:相等的记录合并为一条记录(...

  • 七.一元微分学的几何应用

    1.极值与最值的概念 点在某个邻域内函数是最大值值或最小值就是极值 点在定义域内函数是最大值值或最小值就是最值 需...

  • 利用堆实现排序和解决topk问题之Java实现

    如下图,将一个数组转化堆,有如下性质 所有父节点的值小于或等于两个子节点的值(最小堆) 如果有左子树,那么左子树的...

  • Odin Inspector 系列教程 --- Min Valu

    Min Value Attribute用于基本字段。它将字段的值限制为最小值。使用此定义字段的最小值。 更多教程内...

  • AgumentBST---MaxMinBinarySearchT

    MaxMinBinarySearchTree中的每个节点会存储以他为根结点的子树的最大值最小值,这样可以使得之前介...

  • 数据诊断常见指标

    均值/中位数/最大值/最小值等常规指标 计数类,如0值,1值,-1值等 缺失值/方差,方差为零,说明该特征没有区分...

  • 2.1.1 堆排序

    堆可以理解成用数组实现的完全二叉树结构完全二叉树中如果每课子树的最大值都在顶部就是大根堆完全二叉树中如果每棵子树的...

  • 1111总结,missing value,文本操作,datafr

    missing value 缺失值 检测缺失值,丢弃缺失值,填充缺失值,缺失值一般不会被计算 pd.isnull(...

  • 【python】数据清洗

    1.处理缺失值 判断是否含缺失值/统计缺失值 筛选所有含缺失值的表格 删除含缺失值的数据 用新值填充空值 对应值替...

网友评论

      本文标题:5870. 每棵子树内缺失的最小基因值

      本文链接:https://www.haomeiwen.com/subject/mbojwltx.html