给出一个仅由元音组成的字符串,在给定的字符串中找到最长的子序列,以使其由所有五个元音组成,并且是一个或多个a,一个或多个e,然后一个或多个i的序列。 ,然后是一个或多个o,然后是一个或多个u。
如果最长的子序列超过一个,则打印任何一个。
问题:您能否在下面显示如何向备忘录中添加备忘录/显示如何使用dp解决方案?我已经看到了如何递归求解(下面)。我在寻求帮助以寻求帮助。
示例:
输入:str =“ aeiaaioooaauuaeiou” 输出:{a,a,a,a,a,a,e,i,o,u} 在这种情况下,有两种可能的输出: {a,a,a,a,a,a,e,i,o,u}和, {a,e,i,i,o,o,o,u,u,u} 每个长度为10
输入:str =“ aaauuiieeou” 输出:不可能有子序列
方法: 我们递归遍历字符串中的所有字符,并遵循给定条件:
如果子序列为空,则仅当元音为“ a”时,我们才将其包含在当前索引中。否则,我们继续下一个索引。 如果当前索引处的元音与子序列中包含的最后一个元音相同,则将其包括在内。 如果当前索引处的元音是子序列中包含的最后一个元音之后的下一个可能的元音(即a–> e–> i–> o–> u),我们有两个选择:要么包含它,要么继续下一个索引。因此,我们选择一个给出最长子序列的序列。 如果以上条件都不满足,我们继续进行下一个索引(以避免子序列中元音的无效排序)。 如果已经到达字符串的末尾,则检查当前子序列是否有效。如果它是有效的(即,如果它包含所有元音),则返回它,否则返回一个空列表。
# Python3 program to find the longest subsequence
# of vowels in the specified order
vowels = ['a', 'e', 'i', 'o', 'u']
# Mapping values for vowels
mapping = {'a': 0, 'e': 1, 'i': 2, 'o': 3, 'u': 4}
# Function to check if given subsequence
# contains all the vowels or not
def isValidSequence(subList):
for vowel in vowels:
if vowel not in subList:
return False
return True
# Function to find the longest subsequence of vowels
# in the given string in specified order
def longestSubsequence(string, subList, index):
# If we have reached the end of the string,
# return the subsequence
# if it is valid, else return an empty list
if index == len(string):
if isValidSequence(subList) == True:
return subList
else:
return []
else:
# If there is no vowel in the subsequence yet,
# add vowel at current index if it is 'a',
# else move on to the next character
# in the string
if len(subList) == 0:
if string[index] != 'a':
return longestSubsequence(string, subList, index + 1)
else:
return longestSubsequence(string, subList + \
[string[index]], index + 1)
# If the last vowel in the subsequence until
# now is same as the vowel at current index,
# add it to the subsequence
elif mapping[subList[-1]] == mapping[string[index]]:
return longestSubsequence(string, subList + \
[string[index]], index + 1)
# If the vowel at the current index comes
# right after the last vowel
# in the subsequence, we have two options:
# either to add the vowel in
# the subsequence, or move on to next character.
# We choose the one which gives the longest subsequence.
elif (mapping[subList[-1]] + 1) == mapping[string[index]]:
sub1 = longestSubsequence(string, subList + \
[string[index]], index + 1)
sub2 = longestSubsequence(string, subList, index + 1)
if len(sub1) > len(sub2):
return sub1
else:
return sub2
else:
return longestSubsequence(string, subList, index + 1)
# Driver Code
if __name__ == "__main__":
string = "aeiaaioooauuaeiou"
subsequence = longestSubsequence(string, [], 0)
if len(subsequence) == 0:
print("No subsequence possible")
else:
print(subsequence)
输出: ['a','e','i','i','o','o','o','u','u','u']
答案 0 :(得分:1)
用于记忆功能的键实现是可以使用(last_chosen_char, length, index)
作为记忆键。换句话说,将"aaeeeiiioo", i=15
和"aaaaaaaeio", i=15
视为相同,因为它们的最后选择的字符,长度和当前索引是等效的。这两个调用的子问题将具有相同的解决方案,我们只需要麻烦计算其中一个即可。
一些补充说明:
"u"
,就可以循环并收集字符串中所有剩余的"u"
;没有更多的决定。您可能希望对输入字符串进行一些预处理,以减少更多的调用堆栈。例如,记录下每个索引的下一个字符位置,并在击中最后一个"u"
后提早保释。不过,这些方法都不会对最坏的情况有所帮助,因此使用自下而上的方法迭代地重写逻辑将是最佳选择。将其放在一起,现在可以输入不超过堆栈大小的字符串:
def longest_subsequence(string):
def helper(chosen="", i=0):
if i == len(string):
return chosen if set("aeiou").issubset(set(chosen)) else ""
hashable = (chosen[-1] if chosen else None, len(chosen), i)
if hashable in memo:
return memo[hashable]
if not chosen:
res = helper("a" if string[i] == "a" else chosen, i + 1)
elif chosen[-1] == string[i]:
res = helper(chosen + string[i], i + 1)
elif mapping[chosen[-1]] + 1 == mapping[string[i]]:
sub1 = helper(chosen + string[i], i + 1)
sub2 = helper(chosen, i + 1)
res = sub1 if len(sub1) > len(sub2) else sub2
else:
res = helper(chosen, i + 1)
memo[hashable] = res
return res
mapping = {x: i for i, x in enumerate("aeiou")}
memo = {}
return helper()
下面是一个在900个字符的字符串上运行的示例:
original: uouoouiuoueaeeiiiaaaouuuueuaiaeaioaaiouaouiaiiaiuuueaueaieeueeuuouioaoaeueoioeoeioiuiaiaoeuuuuauuaiuueiieaauuoieiuoiaiueeeoaeaueaaaiaiiieuaoaiaaoiaoaueouaiiooaeeoioiaoieouuuoeaoaeeaaiuieouaeeooiiuooeauueaoaoaeuoaieauooueeeuiueuaeoeouuuiaoiauiaoiaaeeoeouuuueuiiuueoeeoiieuuuauooeuuaaaueuaaaaoaieaiiuoaoouueeeooiuoieoaueooaaioaeoiiiauuoeiaioeauaueiiaeoueioeiieuoiueoeoueeiuiooaioeooueuioaoaeoaiiiauoooieueoeauaiauauuauoueeauouieeoeoeiaeeeeooooeoaueouuuuiioeeuioueeuiaiueooeueeuuuoooeeuooeuoeeeaiioeeiioauiaeaiuaiauooiioeoeueoeieuueouaeeuuoeuaueeeauiiaoeeaeuieoeiuoooeaeeiuaiauuieouuuiuouiuieieoueiiaoiuioaiououooieiauuuououuiiiuaoeeieueeiuoeiaouoeueieuoiaeuoeiieeeaaaeiaeeoauoaoeuuoiiaaeiuiouueaoeuueeoouiaeeeouiouaaaeiouaaeauauioeoeuiauaeaououoaiuuueuieiaeeaouuueeaaiauoieoioaoiuuaioaiauioueieuuuueiaeeuaoeeoeioeoaiauiiuaouuoouooouaeueaioiaouuiiuauiaaeooeueiuoiuoeeauueuuueuueouiiauiuaoiuuoeuoeeauaeoo
max subsequence: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeiiiiiiiiiiiooooouuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
答案 1 :(得分:0)
private static int longestSubSeqOfVowels(String input) {
char[] v = { 'a', 'e', 'i', 'o', 'u' };
HashMap<Character, Integer> charCount = new HashMap<Character, Integer>();
char c;
int vCount = -1;
for (int i = 0; i < input.length(); i++) {
c = input.charAt(i);
if (vCount == -1 && c != 'a') {
continue;
}
int value = charCount.get(c) == null ? 0 : charCount.get(c) + 1;
if (value == 0) {
if (c == v[vCount + 1]) {
value = vCount >= 0 ? charCount.get(v[vCount]) + 1 : 1;
vCount++;
}
charCount.put(c, value);
} else {
charCount.put(c, value);
}
}
return charCount.get('u').intValue();
}
以上是获取元音最长子序列的长度。由于我们在映射中保留每个字符的数量,因此可以修改相同的内容以获取String。