Ruby 由字符串的最大不同字符组成的最小子字符串
给定一个字符串,我需要找到包含该字符串中所有唯一字符的最小子字符串。以下是三个例子:Ruby 由字符串的最大不同字符组成的最小子字符串,ruby,algorithm,Ruby,Algorithm,给定一个字符串,我需要找到包含该字符串中所有唯一字符的最小子字符串。以下是三个例子: Input: "AABBBCBB" Shortest substring: "ABBBC" Input: "AABBBCBBAC", Shortest substring: "BAC" Input: "aabcaadcc", Shortest substring: "bcaad" 第一个子字符串中的唯一字符是“A”、“B”和“C”。包含这些字符的子字符串是“AABBBC”、“A
Input: "AABBBCBB" Shortest substring: "ABBBC"
Input: "AABBBCBBAC", Shortest substring: "BAC"
Input: "aabcaadcc", Shortest substring: "bcaad"
第一个子字符串中的唯一字符是“A”、“B”和“C”。包含这些字符的子字符串是“AABBBC”、“AABBBCB”、“AABBBCBB”、“ABBBC”、“ABBBCB”和“ABBBCBB”。其中最短的是“ABBBC”。如果有两个或多个最短的子字符串,则可以返回任何一个。我已经用下面的方法解决了这个算法
def max_distinct_char(str)
str.chars.uniq.count
end
def smallest_subset_str(str)
str_length = str.length
max_distinct = max_distinct_char(str)
min_str_len = str_length
for j in (0..str_length)
for k in (0..str_length)
sub_str = str[j..k]
sub_str_length = sub_str.length
sub_distinct_char_length = max_distinct_char(sub_str)
if (sub_str_length < min_str_len && max_distinct == sub_distinct_char_length)
min_str_len = sub_str_length
sub_string = sub_str
end
end
end
sub_string
end
代码
例子
解释
假设:
str = "AABBBCBB"
步骤如下
uniq_chars = str.each_char.uniq
#=> ["A", "B", "C"]
nbr_uniq_chars = uniq_chars.size
#=> 3
last_idx = str.size - 1
#=> 7
shortest = { idx: 0, size: str.size }
#=> {:idx=>0, :size=>8}
shortest描述迄今为止找到的最短子字符串。它是子串
str[shortest[:idx], shortest[:size]]
最初它描述整个字符串。继续
last_start_idx = last_idx - nbr_uniq_chars + 1
#=> 5
我将把起始索引,StaseIdx初始固定为零,然后考虑从该索引开始的所有子串。在这种情况下,没有理由考虑STARTIDIDX> LASTHIDIDX。StutsIdxIX…-1。大小< nBrUnqQuaCARS,因此不可能。
enum1 = (0..last_start_idx).each
#=> #<Enumerator: 0..5:each>
start_idx = enum1.next
#=> 0
first_end_idx = start_idx + nbr_uniq_chars - 1
#=> 3
last_end_idx = start_idx + shortest[:size] - 1
#=> 7
我们现在发现了一个包含字符串中所有唯一字符的子字符串,但我们知道它比前一个最短的子字符串短。不需要测试!因此,我们更新:
其中描述了子字符串:
str[shortest[:idx], shortest[:size]]
#=> "AABBBC"
我们不再需要为start_idx的这个值执行end_idx=enum2.next,因为我们知道关联的子字符串将以刚刚标识的字符串开头,因此在str中会有所有唯一的字符,但会比刚刚找到的子字符串长。因此,我们执行:
break
终止内部循环。下一步是生成enum1的第二个元素并从那里开始:
start_idx = enum1.next
#=> 1
first_end_idx = start_idx + nbr_uniq_chars - 1
#=> 3
last_end_idx = start_idx + shortest[:size] - 1
#=> 6
这将导致最近一次更新到:
shortest
#=> { idx: 1, size: 5 }
其余的计算结果是相似的。当你说“尝试”时,这是否意味着这不起作用?如果是这样,为什么要将其作为答案发布?这确实有效!,但这也意味着可能有更好的答案。可能有,但a不是你的问题,b也不是此类问题的论坛。请尝试CodeReview。也不是博客。除非你打算选择你的答案作为问题的适当解决方案,否则请不要添加答案。这样做只会让其他人在寻找同一问题的解决方案时感到困惑。我从代码中找到了您想要的。我相信你会发现我对你的问题的编辑是正确的。请阅读并回答。您要求我们编写代码来解决您的问题,这是离题的。我们需要看到你努力的证据,你在哪里研究,你尝试了什么,为什么不奏效,等等。
end_idx = enum2.next
#=> 3
a = str[start_idx..end_idx].chars
#=> ["A", "A", "B", "B"]
b = uniq_chars - a
#=> ["C"]
b.empty?
#=> false, so do not update `shortest`
end_idx = enum2.next
#=> 4
a = str[start_idx..end_idx].chars
#=> ["A", "A", "B", "B", "B"]
b = uniq_chars - a
#=> ["C"]
b.empty?
#=> false, so do not update `shortest`
end_idx = enum2.next
#=> 5
a = str[start_idx..end_idx].chars
#=> ["A", "A", "B", "B", "B", "C"]
b = uniq_chars - a
#=> []
b.empty?
#=> true
shortest = { idx: start_idx, size: end_idx - start_idx + 1 }
#=> {:idx=>0, :size=>6}
str[shortest[:idx], shortest[:size]]
#=> "AABBBC"
break
start_idx = enum1.next
#=> 1
first_end_idx = start_idx + nbr_uniq_chars - 1
#=> 3
last_end_idx = start_idx + shortest[:size] - 1
#=> 6
shortest
#=> { idx: 1, size: 5 }