Algorithm 获取构成给定字符串的所有数组元素的组合
我被这个面试问题困住了。 给定一个单词S和一个字符串数组a。如何找到可以形成S的元素的所有可能组合。 例如:Algorithm 获取构成给定字符串的所有数组元素的组合,algorithm,recursion,Algorithm,Recursion,我被这个面试问题困住了。 给定一个单词S和一个字符串数组a。如何找到可以形成S的元素的所有可能组合。 例如: S = "hotday" A = ["o","ho","h","tday"] 可能的组合是:(“h”+“o”+“tday”)和(“ho”+“tday”) 谢谢您可以遍历A的所有排列,看看哪一个适合。Python示例实现: import itertools S = "hotday" A = ["o","ho","h","tday"] for count in range(len(A)):
S = "hotday"
A = ["o","ho","h","tday"]
可能的组合是:(“h”+“o”+“tday”)和(“ho”+“tday”)
谢谢您可以遍历A的所有排列,看看哪一个适合。Python示例实现:
import itertools
S = "hotday"
A = ["o","ho","h","tday"]
for count in range(len(A)):
for pieces in itertools.permutations(A, count):
if "".join(pieces) == S:
print pieces
结果:
('ho', 'tday')
('h', 'o', 'tday')
是的,这是O(N!),但对于您提供的小型
A
,这是可以的。您可以使用回溯。下面是一些伪代码:
def generateSolutions(unusedWords, usedWords, string, position):
if position == string.length():
print(usedWords)
else:
for word in unusedWords:
if word is a prefix of string[position ... s.length() - 1]:
generateSolutions(unusedWords - word, usedWords + word,
string, position + word.length())
generateSolution(words, an empty list, input string, 0)
这个想法非常简单:我们只需选择一个与输入字符串其余部分的前缀匹配的未使用单词,并不断递归地生成所有有效组合(我假设我们只能使用给定单词列表中的每个单词一次)。此解决方案具有指数时间复杂性,但在最坏的情况下不可能做得更好。例如,如果给定的字符串是
abcdef…yz
,单词列表是[a,b,c,…,z,ab,cd,…,yz]
,那么这样的组合的数量是2^n/2
,其中n
是给定字符串的长度。这是我的java解决方案,它是“ILoveCoding”伪代码的实现:
import java.util.ArrayList;
导入java.util.array;
导入java.util.HashSet;
公共类可能组合{
公共静态void printPossibleCombinations(字符串[]选项卡,字符串S)
{
ArrayList used=新的ArrayList();
arraylistnotused=新的ArrayList(Arrays.asList(tab));
可打印组合(已使用、未使用、S、0);
}
私有静态void可打印组合(使用ArrayList,
ArrayList未使用,字符串s,整数位置){
如果(pos==s.length())
{System.out.println(“可能的组合:”);
for(字符串e:已使用)
{
系统输出打印(e+“-”);
System.out.println();
}
}
HashSet前缀=getPossiblePrefixes(s,pos);
for(字符串e:未使用)
{
if(前缀.contains(e))
{
ArrayList isused=新的ArrayList(已使用);
添加(e);
ArrayList isnotused=新的ArrayList(notused);
未使用。移除(e);
可打印组合(已使用、未使用、s、pos+e.长度());
}
}
}
私有静态HashSet getPossiblePrefixes(字符串s,int-pos){
HashSet前缀=新HashSet();
对于(int i=pos;我可能很高兴有a元素的a。这样您就可以更快地识别作为字符串前缀的单词。@凯文:我如何在这个解决方案中集成前缀树?@user199当我们需要确定单词是否是字符串[position…]的前缀时,我们可以遍历前缀树,而不是遍历所有单词。@ILoveCoding:我用java实现了您的解决方案(请参见下面的代码),效果很好。但您不认为不需要使用Tries吗?我只使用了一个方法;getPrefixes(S,pos)这将生成一组可能的前缀。我不知道Trie如何改进这一点。你能解释这一点吗?@user199 Trie可以提高其性能。如果没有性能问题,就不需要Trie。我不会否认这一点。但慢算法总比没有算法好;-)
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
public class PossibleCombination {
public static void printPossibleCombinations(String[] tab, String S)
{
ArrayList<String> used = new ArrayList<String>();
ArrayList<String> notused = new ArrayList<String>(Arrays.asList(tab));
printPossibleCombinations(used, notused, S,0);
}
private static void printPossibleCombinations(ArrayList<String> used,
ArrayList<String> notused, String s,int pos) {
if (pos == s.length())
{ System.out.println("Possible combinaiton : ");
for(String e : used)
{
System.out.print(e + " - ");
System.out.println();
}
}
HashSet<String> prefixes = getPossiblePrefixes(s,pos);
for(String e : notused)
{
if (prefixes.contains(e))
{
ArrayList<String> isused = new ArrayList<String>(used);
isused.add(e);
ArrayList<String> isnotused = new ArrayList<String>(notused);
isnotused.remove(e);
printPossibleCombinations(isused, isnotused,s, pos + e.length());
}
}
}
private static HashSet<String> getPossiblePrefixes(String s, int pos) {
HashSet<String> prefixes = new HashSet<String>();
for(int i = pos ; i<= s.length() ; i++)
{
prefixes.add(s.substring(pos,i));
}
return prefixes;
}
public static void main(String[] args) {
String[] tab = {"o","ho","h","tday"};
String S = "hotday";
printPossibleCombinations(tab, S);
}
}