问题陈述:在树中查找k元组(未提及为二叉树)
你有一棵树,N个节点的根目录为1,其中第i个节点与值Ai相关联。现在考虑以下定义:
K-Tuple :K + 1节点(X1,X2,X3,...,XK + 1)的元组是K-Tuple,如果:
1.)Xi是Xi +1∀1≤i≤K的祖先
2.)AXi> AXi +1∀1≤i≤K
计算树中K-Tuples的数量。
输入:
第1行:2个整数N和K,树中节点的数量以及您需要计算答案的元组类型的值。
第2行:N空格分隔整数所在的位置
ith整数表示值Ai
N-1行:X和Y表示它们之间存在边缘。
约束:
1≤N,Ai≤100000,1≤X,Y≤N,1≤K≤20
输出:元组数
这是我试过的代码
public class Solutions {
static class Node {
int index, value, tupleLength;
Node parent;
boolean inTuple, hasChildren;
static int tupleCount = 0;
Node (int index, int value) {
this.index = index;
this.value = value;
this.tupleLength = 0;
this.parent = null;
this.inTuple = false;
this.hasChildren = false;
}
// to add an edge between child and parent
void addChild (Node child) {
this.hasChildren = true;
child.parent = this;
}
void setTupleLengths (int k) {
// stop looking for tuple if root node is encountered
if (this.parent == null)
return;
// conditions for a parent node to be in a tuple
if ((this.parent.index < this.index) && (this.parent.value > this.value)) {
// if parent is already part of a k-tuple, no need to proceed further, just increment the tuple count and return
if ((this.parent.tupleLength >= this.tupleLength + 1) && (this.parent.tupleLength >= k)) {
tupleCount++;
return;
}
// if parent satisfies the tuple conditions, then add it to the m-1 tuple to get m-tuple
this.parent.tupleLength = this.tupleLength + 1;
// wrote this condition as any (k+1)-tuple will have 2 k-tuples etc.
if (this.parent.tupleLength >= k)
tupleCount++;
this.parent.inTuple = true;
this.parent.setTupleLengths(k);
}
else {
// if parent is not in tuple, then start looking for a new tuple which covers this parent's ancestors starting from it.
if (!this.parent.inTuple)
this.parent.setTupleLengths(k);
}
}
}
// to get all leaf nodes
static ArrayList<Node> getLeaves (ArrayList<Node> nodes) {
ArrayList<Node> leaves = new ArrayList<>();
for (Node node : nodes) {
if (!node.hasChildren)
leaves.add(node);
}
return leaves;
}
// prints the max length of a tuple starting from each node for all nodes
static void printTupleLengths (ArrayList<Node> nodes) {
for (Node node : nodes)
System.out.print ("(" + node.index + "," + node.value + "," + node.tupleLength + ") ");
System.out.println ();
}
public static void main (String args[]) {
String fileName = "/home/user/Downloads/750ac6c427-input-750a1f8.txt.clean.txt";
File file = new File(fileName);
try {
Scanner sc = new Scanner (file);
//int t = sc.nextInt();
int n = sc.nextInt(), k = sc.nextInt();
ArrayList<Node> nodes= new ArrayList<>();
for (int i = 0; i<n; i++) {
int value = sc.nextInt();
Node node = new Node(i+1, value);
nodes.add(node);
}
for (int i = 1; i<n; i++) {
int x = sc.nextInt(), y = sc.nextInt();
nodes.get(x-1).addChild(nodes.get(y-1));
}
//printTupleLengths(nodes);
ArrayList<Node> leaves = getLeaves(nodes);
for (Node leaf : leaves) {
leaf.setTupleLengths(k);
}
//printTupleLengths(nodes);
System.out.println (Node.tupleCount);
} catch (Exception e) {
System.out.println (e);
}
}
}
输入文件包含测试用例数据 - 如下所示:
7 2
7 6 5 4 3 2 1
1 2
1 3
2 4
2 5
3 6
3 7
输出:4
说明:
共有4个2元组:(1,2,4),(1,2,5),(1,3,6),(1,3,7)。
我的代码为上述测试用例提供了正确的答案,但对其他所有测试用例都没有。有人可以解释一下我做错了什么,或者我是否错过了一些案例?
另外我不清楚这个解决方案的时间复杂性,是O(n)因为我只是检查所有节点可能不会超过一次?那么有更好(正确)的方法吗?