最近我进行了一次电话面试,面试过程中需要编写代码解决问题。这个问题是树的最近公共祖先的变形,但有一些特别之处。这棵树更像一个图,即子节点可以连接在一起。例如:
A
/
B
| \
C E
| |
D F
\ /
G
在这个例子中,给定这棵树和节点
F
和D
,得到的最近共同祖先将是B
。第二个难点是树被表示为数组。要实现的方法具有以下输入:public String getCA(String[] nodes, String[][] parentNodes, String targetNode1, String targetNode2)
在这个例子中,
nodes
= {"G", "F", "E", "D", "C", "B", "A"}
,parentNodes
= {{"F","D"},{"E"}, {"B"}, {"C"}, {"B"}, {"A"}, null}
对于
nodes[i]
,其父节点是parentNodes[i]
。老实说,我完全慌了(已经非常紧张了),花了很长时间才想出一个答案。
虽然我认为这可以通过递归来解决,但我想出了一种迭代解决方案,据我所知,它可以工作:我将节点推入队列并首先沿着路径找到第一个目标节点,然后是第二个节点。一旦我找到一个已经遇到的节点,我就将其视为解决方案(添加了注释以澄清问题)。
public String getCA(String[] nodes, String[][] parentNodes, String targetNode1, String targetNode2) {
if(nodes == null || parentNodes == null){
throw new IllegalArgumentException();
}
Map<String, String[]> map = new HashMap<String, String[]>();
for(int i = 0; i < nodes.length; i++){
map.put(nodes[i], parentNodes[i]);
}
//These are the parents visited as we go up
Set<String> parentsSeen = new HashSet<String>();
parentsSeen.add(targetNode1);
Queue<String> path = new LinkedList<String>();
String[] parents = map.get(targetNode1);
//The root is the common parent
if(parents == null){
return targetNode1;
}
//Build the path up
for(String parent:parents){
path.add(parent);
}
while(!path.isEmpty()){
String currentParent = path.remove();
parentsSeen.add(currentParent);
parents = map.get(currentParent);
if(parents == null){
continue;
}
for(String parent:parents){
path.add(parent);
}
}
parents = map.get(targetNode2);
//It is the root, so it is the common parent
if(parents == null){
return targetNode2;
}
//Start going up for the targetNode2. The first parent that we have already visited is the common parent
for(String parent:parents){
if(parentsSeen.contains(parent)){
return parent;
}
path.add(parent);
}
while(!path.isEmpty()){
String currentParent = path.remove();
if(parentsSeen.contains(currentParent)){
return currentParent;
}
parents = map.get(currentParent);
if(parents == null){
continue;
}
for(String parent:parents){
path.add(parent);
}
}
return null;
}
我没有收到前进的电话。由于我是“自学”的,我很想了解我在这里出了什么问题。由于这是技术问题,我相信这不是主观问题,希望我能从有经验的人那里得到帮助。
作为同事程序员,你会如何处理这个问题,以及如何评估我的解决方案?我需要做什么来提高我的技能?
您可以尽可能直接地表达。只要我能理解出了什么问题并且能够学习,我就满意。
LinkedHashSet
,它保留了节点的插入顺序,因此您可以从左到右查找第一个匹配项。无论如何,面试不成功可能有很多其他原因... - Tudor