java - MEX 从根节点到树中的每个其他节点
问题描述
给定一棵有 N 个节点的有根树。根节点是节点 1。每个第 i 个节点都有一些与之关联的值 val[i]。
对于每个节点 i (1<=i<=N),我们想知道从根节点到节点 i 的路径值的 MEX。
数组的 MEX 是数组中不存在的最小正整数,例如 {1,2,4} 的 MEX 为 3
示例: 假设我们有 4 个节点的树。节点的值为 [1,3,2,8] 并且我们还有每个节点 i 的父节点(节点 1 除外,因为它是根节点)。在本示例中,父数组定义为 [1,2,2]。这意味着节点2的父节点是节点1,节点3的父节点是节点2,节点4的父节点也是节点2。
Node 1 : MEX(1) = 2
Node 2 : MEX(1,3) = 2
Node 3 : MEX(1,3,2) = 4
Node 4 : MEX(1,3,8) = 2
因此答案是 [2,2,4,2]
在最坏的情况下,节点的总数可以达到 10^6,每个节点的值可以达到 10^9。
试图 :
方法 1:我们知道 N 个元素的 MEX 总是在 1 到 N+1 之间。我试图用这种理解来解决这个树问题,但是在这种情况下,N 将随着向叶节点前进而继续动态变化。
方法 2:另一个想法是创建一个包含 N+1 个空值的数组,然后尝试从根节点开始填充它们。但随后我面临的挑战是跟踪该数组中的第一个未填充值。
解决方案
public class TestClass {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
PrintWriter wr = new PrintWriter(System.out);
int T = Integer.parseInt(br.readLine().trim());
for(int t_i = 0; t_i < T; t_i++)
{
int N = Integer.parseInt(br.readLine().trim());
String[] arr_val = br.readLine().split(" ");
int[] val = new int[N];
for(int i_val = 0; i_val < arr_val.length; i_val++)
{
val[i_val] = Integer.parseInt(arr_val[i_val]);
}
String[] arr_parent = br.readLine().split(" ");
int[] parent = new int[N-1];
for(int i_parent = 0; i_parent < arr_parent.length; i_parent++)
{
parent[i_parent] = Integer.parseInt(arr_parent[i_parent]);
}
int[] out_ = solve(N, val, parent);
System.out.print(out_[0]);
for(int i_out_ = 1; i_out_ < out_.length; i_out_++)
{
System.out.print(" " + out_[i_out_]);
}
System.out.println();
}
wr.close();
br.close();
}
static int[] solve(int N, int[] val, int[] parent){
// Write your code here
int[] result = new int[val.length];
ArrayList<ArrayList<Integer>> temp = new ArrayList<>();
ArrayList<Integer> curr = new ArrayList<>();
if(val[0]==1)
curr.add(2);
else{
curr.add(1);
curr.add(val[0]);
}
result[0]=curr.get(0);
temp.add(new ArrayList<>(curr));
for(int i=1;i<val.length;i++){
int parentIndex = parent[i-1]-1;
curr = new ArrayList<>(temp.get(parentIndex));
int nodeValue = val[i];
boolean enter = false;
while(curr.size()>0 && nodeValue == curr.get(0)){
curr.remove(0);
nodeValue++;
enter=true;
}
if(curr.isEmpty())
curr.add(nodeValue);
else if(!curr.isEmpty() && curr.contains(nodeValue) ==false && (enter|| curr.get(0)<nodeValue))
curr.add(nodeValue);
Collections.sort(curr);
temp.add(new ArrayList<>(curr));
result[i]=curr.get(0);
}
return result;
}
}
推荐阅读
- ios - iOS 原生用户界面和 Qt 核心代码
- twitter-bootstrap - 如何使用 Vue.js 在第一次单击而不是第二次单击时打开 Bootstrap 4 模式
- networking - 如何在 scapy 中创建自定义顶层第 2 层标头?
- asp.net-core - 从 ASP.NET Core 2.2 中的控制器调用 SignalR 组
- python - 用列表倒退
- algorithm - “合并 2 个包”问题的大 O 时间复杂度
- python - 计算特定列中 0 的数量
- php - 进行 laravel 查询以搜索两次之间的数据
- pygame - 如何修复,Pygame 不会进入下一个文本
- python-3.x - windows7 64位环境下的pypy3.6-v7.1.1-win32