2

这是为文本生成字谜的最佳方式(最大 80 个字符长度)。示例:输入:dog 输出 dog dgo odg ogd gdo god

我只是在考虑回溯解决方案,但是如果文本更长,那将需要一段时间。

另一个想法是建立我尝试字典中的所有单词,但问题并不要求真正的单词。

有人可以指出最小时间复杂度的解决方案吗?

谢谢!

4

3 回答 3

8

这是一个简单的实现,以防万一您需要:

IEnumerable<List<T>> Permutations<T>(List<T> items)
{
    if (items.Count == 0) yield return new List<T>();

    var copy = new List<T>(items);
    foreach (var i in items)
    {
        copy.Remove(i);
        foreach (var rest in Permutations(copy))
        {
            rest.Insert(0, i);
            yield return rest;
        }
        copy.Insert(0, i);
    }

}

IEnumerable<string> Anagrams(string word)
{
    return Permutations(word.ToCharArray().ToList()).Select(x => new String(x.ToArray()));
}

关于时间复杂性的答案给了 Adithya。要了解他们的答案,您必须知道有 n! = n 项的 1*2*...*n 排列。我的算法就是一个证明(或基于直接证明)

于 2011-08-25T08:47:07.843 回答
5

这个问题看起来像生成排列列表;(字谜是排列的子集,形成一个有意义的词)。嗯!可以使用 STL 的next_permutation方法按时间顺序生成排列,(每个排列的线性时间复杂度);你可以在这里找到这个算法的讨论:http: //marknelson.us/2002/03/01/next-permutation/;STL 的算法甚至可以处理重复,在这种情况下,朴素的交换算法会失败。

有关生成排列的深入讨论,您可以查看 Donald Knuth 的TAOCP 的生成所有 Permutations部分。

于 2011-08-25T09:09:58.710 回答
3

回溯是最快的方法,当你想要一个文本的所有字谜时,这意味着你需要所有的 n! 它的排列。因此,假设打印/生成每个排列至少需要 O(1),那么您的算法无论如何都需要 O(n!),因此您不能比回溯解决方案做得更快。

于 2011-08-25T08:28:15.100 回答