【问题标题】:Valid Permutations of a String字符串的有效排列
【发布时间】:2016-12-18 05:26:43
【问题描述】:

在最近的一次亚马逊技术面试中向我提出了这个问题。如下:-

给定一个字符串 ex: "where am i" 和一个有效单词字典,您必须列出该字符串的所有有效不同排列。有效字符串由字典中存在的单词组成。例如:“we are him”、“whim aree”是有效的字符串,考虑到单词 (whim, aree) 是字典的一部分。此外,条件是仅仅重新排列单词不是有效的字符串,即“我在哪里”不是有效的组合。

任务是以最佳方式找到所有可能的此类字符串。

【问题讨论】:

  • 你有没有尝试回答这个面试问题,如果有,你能分享一下已经有的代码吗?
  • @TimBiegeleisen 我想生成字符串的各种排列并检查每个排列是否可以使用动态编程分解成有效的单词。
  • 字符串中有空格吗?
  • @Tony 空格不计,有效字符串可以有任意数量的空格
  • @ACV 是一个单词字谜解决方案,完全是微不足道的。我们谈论的是多词字谜。

标签: algorithm data-structures amazon


【解决方案1】:

正如您所说,空格不算数,因此输入可以仅视为字符列表。输出是单词的排列,所以一个明显的方法是找到所有有效的单词然后排列它们。

现在问题变成了将字符列表划分为子集,每个子​​集形成一个单词,您可以找到一些答案here,以下是我解决此子问题的版本。

如果字典不大,我们可以迭代字典到

  • 找到单词的 min_len/max_len,以估计我们可能有多少单词,即我们重复的深度
  • 将单词转换为地图以加速搜索;
  • 过滤掉包含不可能字符的单词(即我们输入没有的字符);
  • 如果这个词是我们输入的子集,我们可以递归地找到这个词。

以下是伪代码:

int maxDepth = input.length / min_len;

void findWord(List<Map<Character, Integer>> filteredDict, Map<Character, Integer> input, List<String> subsets, int level) {
  if (level < maxDepth) {
    for (Map<Character, Integer> word : filteredDict) {
      if (subset(input, word)) {
        subsets.add(word);
        findWord(filteredDict, removeSubset(input, word), subsets, level + 1);
      }
    }
  }
}

然后您可以轻松地在递归函数中排列单词。

从技术上讲,这个解决方案可以是O(n**d)——其中 n 是字典大小,d 是最大深度。但如果输入不是很大和复杂的,我们仍然可以在可行的时间内解决它。

【讨论】:

    猜你喜欢
    • 2021-05-26
    • 2022-09-27
    • 1970-01-01
    • 2011-06-24
    • 1970-01-01
    • 2011-05-24
    • 2014-11-01
    • 2010-10-19
    相关资源
    最近更新 更多