问题是找到一棵树最近的共同祖先但有一个扭曲的变化.树很像图形,即可以连接子节点.例:
A / B | \ C E | | D F \ / G
在这种情况下,给定这个树和节点F和D,得到的最接近的共同的祖先将是B.第二个扭曲是树被呈现为数组.实现方法有以下输入:
public String getCA(String [] nodes,String [] [] parentNodes,String targetNode1,String targetNode2)
在这个例子中,节点= {“G”,“F”,“E”,“D”,“C”,“B”,“A”}和parentNodes = {{“F”,“D”},{“ E“},{”B“},{”C“},{”A“},null}
基本上对于nodes [i],父节点是parentNodes [i].
说实话,我完全惊慌失措(已经非常紧张)并且花了很长时间才找到答案.
虽然我认为这是递归求解的,但我想出了一个迭代解决方案,据我所知可行:我在队列中推送节点,然后首先上升第一个目标节点然后是第二个节点.一旦我找到一个已经遇到的节点,我认为它是解决方案(已添加注释以清除事物).
public String getCA(String[] nodes,String[][] parentNodes,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; }
我没有得到前进的电话.现在由于我“自学成才”,我有兴趣了解我是如何搞砸到这里的.由于这是技术问题,我认为这不是主观问题,希望我能从经验丰富的人那里得到帮助.
因此,作为同事程序员,您将如何处理该问题?您如何评估我的解决方案?我需要做些什么来提高我的技能?
你可以尽可能地直截了当.只要我能理解出了什么问题并且学会了我就会感到满意
解决方法
I /\ / \ / \ H E |\ /| | \ / | G \/ D | /\ | | / F C |/ \| A B
这里有2个共同的祖先A和B,H和E. H是A和B的距离2.E是距离A的距离1但距离B的距离是3.我选择哪个?
此外,无论你对这个问题的答案是什么,从一个人那里找到一组祖先,然后从另一个人那里做一个BFS也行不通.找到A的所有祖先然后从B做BFS首先找到H,找到B的所有祖先然后从A做BFS首先找到E.作为对手,我可以切换A和B,使你的算法失败,无论你做出什么选择(选择2/2还是1/3更好).
因此,正确的算法必须比祖先集计算加上BFS更复杂.除非你告诉我如何做出这个选择,否则我不确定我是否可以确定正确的算法.