我在接受采访时被问到这个问题。假设您有一个有序字典,并给出一个无序字符列表 - 您将如何按优先顺序排列这些字符?此词典包含保证显示所有26个字符的单词。但请注意,字典的大小可能是任何内容。字典可以小到几个单词,并且可能没有针对每个字符的单独部分,例如,可能没有以a
开头的单词的部分;虽然a
将作为另一个词的一部分出现,例如" bat"。
字典可能是"有序" (/讽刺)就像这样"斑马',"苹果","猫","粗鲁",如果你被给予列表{a
,z
,r
},正确的顺序为{z
,a
,r
}。因为" zebra"是在" apple"之前在字典中,我们知道z
出现在a
之前。因为" apple"来自" cat"之前,我们知道a
出现在c
之前。因为" cat"来自" crass",我们知道a
出现在r
之前。这个排序使c
和r
留下了一个圆满的演讲,但由于字母列表是{a
,z
,r
},我们知道解决方案是{z
,a
,r
}。
答案 0 :(得分:11)
使用带有26个顶点的有向图,每个顶点代表一个字符。从顶点A到顶点B的边缘表示字母B在A的前面。
第一步是建立只有顶点但没有边缘的图形。
其次,您逐字扫描输入字典。并将每个单词与前一个单词进行比较。您应该为扫描的每个单词找到确切的关系。因此,您在此图表中添加了一条边。假设字典是正确的,应该没有冲突。
完成字典后,按
输出字母编辑: 为了更好地解释这个算法,让我们在你的样本输入上运行它。
输入:{“zebra”,“apple”,“cat”,“crass”}
Word 0和word 1,我们立即知道z在a之前,所以我们创建了一个边缘a-> z
单词1和单词2,我们立即知道a出现在c之前,所以我们创建另一个边缘c-> a
Word 2和Word 3,第一个字母是相同的“c”,但第二个字母不同,所以我们知道a在r之前,所以我们有另一个边r-> a
现在阅读所有单词。通过随机拾取顶点来输出顺序(比如我们选择c),然后我们在图中有c-> a-> z。输出z并从图形中删除z(将其标记为NULL)。现在选择另一个(比如我们选择r),然后我们在图中找到r-> a。我们输出并删除图表。现在我们选择另一个(比如我们再次选择c),找不到路径,所以我们只输出c并删除它。现在我们选择最后一个,r,再没有路径,所以我们输出r并删除它。由于删除了所有顶点,因此算法已完成。
输出为z,a,c,r。 “c”和“r”的排序是随机的,因为我们并不真正知道它们与输入的关系。
答案 1 :(得分:1)
来自&#34;斑马&#39; &LT; &#34;苹果&#34; &LT; &#34;猫&#34; &LT; &#34;粗鲁&#34;,导出每个字符关系的最有效方法是让循环考虑所有单词的第N个字符,其中N最初为0,产生关系&#34; z&#34; &LT; &#34;&#34; &LT; &#34; C&#34 ;.该循环可以递归地提取具有相同前缀的单词组的第(N + 1)个字符的关系(即,位置<= N的文本)。使用相同前缀&#34; cat&#34;为N == 1执行此操作和&#34;粗鲁&#34;产生关系&#34; a&#34; &LT; &#34; R&#34;
我们可以在x < y
真值的二维数组中表示已知关系。
y\x a b c...r...z
a - N N Y
b -
c Y - Y
r Y -
z N N -
蛮力方法是迭代输入列表中的所有字符对(即{a,z,r} - > az,ar,zr)查找表a<z
,{{ 1}},a<r
:如果这是假的,那么交换字符并重启整个she-bang。当您完成整个过程而无需交换任何其他字符时,输出将与规则一致地排序。这有点像做冒泡分类。
为了加快速度,我们可以更积极主动地在表格中填充隐含关系的单元格:例如,我们知道&#34; z&#34; &LT; &#34;&#34; &LT; &#34; C&#34;和&#34; a&#34; &LT; &#34; r&#34;,所以我们推断出&#34; z&#34; &LT; &#34; R&#34 ;.我们可以通过运行&#34;天真&#34;上面的表格可以找到我们对每个角色所知的一切(例如z<r
和z<a
) - 然后查看我们对a和c的了解。为了避免过度深度的树,你可以按照这样的一个间接级别,然后重复直到表稳定。
答案 2 :(得分:-3)
根据您描述问题的方式,您的示例不正确。你的答案应该是{z,r,a}
。然而,可能是,下面是解决问题的代码。您可以修改它以返回与我所假设的{z,r,a}
不同的订单。
Set<Character> charPrecedence(List<String> dictionary, char[] letters){
Set<Character> result = new HashSet<Character>();
//since your characters are the 26 letters instead of the 256 chars
// a bit vector won't do; you need a map or set
Set<Character> alphabets = new HashSet<Character>();
for(char c: letters)
alphabets.add(c);
//now get to work
for(String word: dictionary){
if(alphabets.isEmpty()) return result;
for(char c: word.toCharArray()){
if(alphabets.remove(c))
result.add(c);
}
}
//since the dictionary is guaranteed to contain all the 26 letters,
//per the problem statement, then at this point your work is done.
return result;
}
最佳案例O(1);最坏情况O(n)其中n是字典中的字符数,即一个特定字母只出现一次,是你检查的最后一个字符。