这是一个O(n) 算法当你有一个字符串而不是一个单词列表作为输入时的不同问题。。这是我的疏忽,但将解决方案留在这里,因为我不想删除它:)
由于我们只对字符感兴趣,这让问题变得容易多了。维护每个字符 [a-z] 到其在字符串中的位置的映射。仅此地图就足以确定我们是否有一个 pangram 以及它的长度。
1. Initialize a map of all alphabets to null
2. Initialize shortest_pangram to { length: ∞, value: undefined }
3. Loop through each "character" in given string
3.1 Update the value of map[character] to current string index
3.2 If we have a pangram, and its the shortest so far, record its length/value
4. shortest_pangram should have our result
我们创建的地图足以确定我们是否有一个 pangram - 如果我们的地图中的所有值都不为空,我们就有一个 pangram。
要找到当前 pangram 的长度,请从我们地图中的最小值中减去最大值。请记住,在找到长度之前,我们必须检查它是否是一个 pangram。
这是一个简单的 Ruby 中未优化的实现:
class Pangram
def initialize(string)
@input = string.downcase.split('')
@map = {}
('a'..'z').each { |c| @map[c] = nil }
infinity = 1.0/0.0
@best = { :length => infinity, :string => nil }
end
def shortest
@input.each_with_index do |c, index|
@map[c] = index if @map.key?(c)
if pangram? and length < @best[:length]
@best[:length] = length
@best[:string] = value
end
end
@best
end
def pangram?
@map.values.all? { |value| !value.nil? }
end
def length
@map.values.max - @map.values.min
end
def value
@input[@map.values.min..@map.values.max].join('')
end
end
要使用,实例化类并将整个字符串传递给它。调用 .shortest 查找最短 pangram 的长度和匹配的子串。
pangram = Pangram.new("..")
print pangram.shortest