我在接受采访时被问到这个问题。
给定一个字符数组,找到包含所有字符的字典中的最短单词。此外,提出了一个优化此函数调用的字典实现。
例如char [] chars = {' R' ,' C' }。结果应该是" CAR"。
我无法想出任何能够合理快速运行的东西。我想通过构建一个哈希表来检索特定长度的所有单词来预处理字典。然后我只能想到以递增的长度顺序检索所有单词并检查所有单词中是否存在所需的字符(可能使用位掩码。)
答案 0 :(得分:5)
这是一个常见的软件访谈问题,其解决方案是:按字母长度对字典进行排序,并按字母顺序对每个值进行排序。给出字符时,对它们进行排序并找到所需的字母。
答案 1 :(得分:2)
首先按照长度的升序对字典进行排序。
对于每个字母,构造包含该字母的单词字典中位置的位图。每个位图都很长,但不会很多。
对于每次搜索,请获取数组中字母的位图交集。结果中的第一位将位于与包含所有字母的最短单词的字典中的位置对应的索引处。
答案 2 :(得分:2)
其他答案更好,但我意识到这完全可以预先计算。
这将需要大量的设置时间,并且随后的关联存储将在1.7GB附近,但是您将能够在O(1)时间内找到包含字母超集的最短字。保证。
答案 3 :(得分:1)
明显的预处理是按字母长度和字母顺序重新排序对字典中的所有单词进行排序:例如,“dorw”下的“单词”。然后,您可以使用常规搜索算法(例如,正则表达式)来搜索您需要的字母。在最坏的情况下,高效(DFA)搜索只需要通过字典一次,如果第一次匹配很短,则需要更少。
答案 4 :(得分:0)
一个。将单词排序为字母char数组。保留从排序到原始单词的映射
湾按照建议的字长拆分字典
℃。按字母顺序对每个字长设置条目
有趣的扩展。多个单词可能映射到a中的相同条目。你应该返回哪一个......
答案 5 :(得分:0)
这是C#中的解决方案:
using System.Collections.Generic;
using System.Linq;
public class ShortestWordFinder
{
public ShortestWordFinder(IEnumerable<string> dictionary)
{
this.dictionary = dictionary;
}
public string ShortestWordContaining(IEnumerable<char> chars)
{
var wordsContaining = dictionary.Where(s =>
{
foreach (var c in chars)
{
if (!s.Contains(c))
{
return false;
}
s = s.Remove(s.IndexOf(c), 1);
}
return true;
}).ToList();
if (!wordsContaining.Any())
{
return null;
}
var minLength = wordsContaining.Min(word => word.Length);
return wordsContaining.First(word => word.Length == minLength);
}
private readonly IEnumerable<string> dictionary;
}
简单测试:
using System.Diagnostics;
using Xunit;
public class ShortestWordFinderTests
{
[Fact]
public void Works()
{
var words = new[] { "dog", "moose", "gargoyle" };
var finder = new ShortestWordFinder(words);
Trace.WriteLine(finder.ShortestWordContaining("o"));
Trace.WriteLine(finder.ShortestWordContaining("oo"));
Trace.WriteLine(finder.ShortestWordContaining("oy"));
Trace.WriteLine(finder.ShortestWordContaining("eyg"));
Trace.WriteLine(finder.ShortestWordContaining("go"));
Assert.Null(finder.ShortestWordContaining("ooo"));
}
}