这不是家庭作业,只是我在网上发现的一个看起来很有趣的面试问题。
所以我首先看了一下这个:Telephone Words problem - 但它似乎措辞不力/引起了一些争议。我的问题几乎是一样的,除了我的问题更多的是它背后的时间复杂性。
当您输入10位数的电话号码时,您希望列出所有可能的单词。所以这就是我所做的:`
def main(telephone_string)
hsh = {1 => "1", 2 => ["a","b","c"], 3 => ["d","e","f"], 4 => ["g","h","i"],
5 => ["j","k","l"], 6 => ["m","n","o"], 7 => ["p","q","r","s"],
8 => ["t","u","v"], 9 => ["w","x","y","z"], 0 => "0" }
telephone_array = telephone_string.split("-")
three_number_string = telephone_array[1]
four_number_string = telephone_array[2]
string = ""
result_array = []
hsh[three_number_string[0].to_i].each do |letter|
hsh[three_number_string[1].to_i].each do |second_letter|
string = letter + second_letter
hsh[three_number_string[2].to_i].each do |third_letter|
new_string = string + third_letter
result_array << new_string
end
end
end
second_string = ""
second_result = []
hsh[four_number_string[0].to_i].each do |letter|
hsh[four_number_string[1].to_i].each do |second_letter|
second_string = letter + second_letter
hsh[four_number_string[2].to_i].each do |third_letter|
new_string = second_string + third_letter
hsh[four_number_string[3].to_i].each do |fourth_letter|
last_string = new_string + fourth_letter
second_result << last_string
end
end
end
end
puts result_array.inspect
puts second_result.inspect
end
首先,这是我在几分钟内一起攻击的内容,没有进行任何重构。所以我为凌乱的代码道歉,我刚刚开始学习Ruby 6周前,所以请耐心等待我!
所以终于到我的问题:我想知道这种方法的时间复杂性是多少。我的猜测是它会是O(n ^ 4),因为第二个循环(对于四个字母的单词)嵌套了四次。虽然我不是很积极。所以我想知道这是否正确,以及是否有更好的方法来解决这个问题。
答案 0 :(得分:0)
这实际上是一个恒定时间算法,所以O(1)(或更明确,O(4 ^ 3 + 4 ^ 4))
这是一个恒定时间算法的原因是,对于电话号码中的每个数字,您将迭代一个固定数字(最多4个)可能的字母,这是事先已知的(这就是为什么你可以放{{ 1}}静态地进入你的方法)。
一种可能的优化方法是在您知道当前前缀没有单词时停止搜索。例如,如果3位数字是“234”,你可以忽略所有以“bd”开头的字符串(有一些bd-words,比如“bdellid”,但没有三字母,至少在我的的/ usr /共享/字典/字)。
答案 1 :(得分:-1)
从原来的措辞来看,我认为这是要求所有可能性,而不是作为输出的可能性数量。
不幸的是,如果您需要返回每个组合,则无法将复杂性降低到指定键所确定的范围之下。
如果它只是数字,它可能是恒定的时间。但是,要将它们全部打印出来,最终结果在很大程度上取决于假设:
1)假设你要检查的所有单词都是由字母组成的,你只需要检查2到9中的8个键。如果这不正确,只需在下面的函数中输出8。 / p>
2)假设所有键的布局与此处设置完全一样(没有octothorpes或星号),空数组的内容在最后一个单词中不占用空间。
{
1 => [],
2 => ["a", "b", "c"],
3 => ["d", "e", "f"],
4 => ["g", "h", "i"],
5 => ["j", "k", "l"],
6 => ["m", "n", "o"],
7 => ["p", "q", "r", "s"],
8 => ["t", "u", "v"],
9 => ["w", "x", "y", "z"],
0 => []
}
在每个阶段,您只需检查下一步的可能性数量,并将每个可能的选择附加到字符串的末尾。如果你这样做,那么,最小时间(基本上)是恒定时间(0,如果数字由全1和0组成)。然而,函数将是O(4 ^ n),其中n在10处达到最大值。如果它们每次达到7或9,则最大可能的组合数将是4 ^ 10。
至于你的代码,我会建议一个循环,带有一些基本的嵌套循环。这是Ruby中的代码,虽然我还没有运行它,所以可能存在语法错误。
def get_words(number_string)
hsh = {"2" => ["a", "b", "c"],
"3" => ["d", "e", "f"],
"4" => ["g", "h", "i"],
"5" => ["j", "k", "l"],
"6" => ["m", "n", "o"],
"7" => ["p", "q", "r", "s"],
"8" => ["t", "u", "v"],
"9" => ["w", "x", "y", "z"]}
possible_array = hsh.keys
number_array = number_string.split("").reject{|x| possible_array.include?(x)}
if number_array.length > 0
array = hsh[number_array[0]]
end
unless number_array[1,-1].nil?
number_array.each do |digit|
new_array = Array.new()
array.each do |combo|
hsh[digit].each do |new|
new_array = new_array + [combo + new]
end
end
array = new_array
end
new_array
end