Listing all permutations of a string/integer

后端 未结 29 2720
没有蜡笔的小新
没有蜡笔的小新 2020-11-22 00:44

A common task in programming interviews (not from my experience of interviews though) is to take a string or an integer and list every possible permutation.

Is there

29条回答
  •  生来不讨喜
    2020-11-22 01:32

    Recursion is not necessary, here is good information about this solution.

    var values1 = new[] { 1, 2, 3, 4, 5 };
    
    foreach (var permutation in values1.GetPermutations())
    {
        Console.WriteLine(string.Join(", ", permutation));
    }
    
    var values2 = new[] { 'a', 'b', 'c', 'd', 'e' };
    
    foreach (var permutation in values2.GetPermutations())
    {
        Console.WriteLine(string.Join(", ", permutation));
    }
    
    Console.ReadLine();
    

    I have been used this algorithm for years, it has O(N) time and space complexity to calculate each permutation.

    public static class SomeExtensions
    {
        public static IEnumerable> GetPermutations(this IEnumerable enumerable)
        {
            var array = enumerable as T[] ?? enumerable.ToArray();
    
            var factorials = Enumerable.Range(0, array.Length + 1)
                .Select(Factorial)
                .ToArray();
    
            for (var i = 0L; i < factorials[array.Length]; i++)
            {
                var sequence = GenerateSequence(i, array.Length - 1, factorials);
    
                yield return GeneratePermutation(array, sequence);
            }
        }
    
        private static IEnumerable GeneratePermutation(T[] array, IReadOnlyList sequence)
        {
            var clone = (T[]) array.Clone();
    
            for (int i = 0; i < clone.Length - 1; i++)
            {
                Swap(ref clone[i], ref clone[i + sequence[i]]);
            }
    
            return clone;
        }
    
        private static int[] GenerateSequence(long number, int size, IReadOnlyList factorials)
        {
            var sequence = new int[size];
    
            for (var j = 0; j < sequence.Length; j++)
            {
                var facto = factorials[sequence.Length - j];
    
                sequence[j] = (int)(number / facto);
                number = (int)(number % facto);
            }
    
            return sequence;
        }
    
        static void Swap(ref T a, ref T b)
        {
            T temp = a;
            a = b;
            b = temp;
        }
    
        private static long Factorial(int n)
        {
            long result = n;
    
            for (int i = 1; i < n; i++)
            {
                result = result * i;
            }
    
            return result;
        }
    }
    

提交回复
热议问题