Finding All the Permutations of an Array in C#

by Chad
Published June 21, 2019
Last updated November 10, 2024

Waves Waves

Admittedly, I'm a sucker for these kind of coding problems. I recently ran across this problem in particular on the Internet. Given an array of integers, we need to find all the possible permuations. In this article I want to share my C# solution.

The Problem

Given an array of integers (they must each be unique), find the set of possible permutations.

Input

Our input is a simple array of unique integers. For this example we'll use [1,2,3].

[1,2,3]

Output

Our output needs to be all the possible permuations of [1,2,3]. In this C# example I'll output this as an IList<IList<int>>.

[
    [1,2,3],
    [1,3,2],
    [2,1,3],
    [2,3,1],
    [3,1,2],
    [3,2,1]
]

The Solution

Permutations are the possible ways we could order, or arrange, a set. Given a set of n elements, there are n! (n factorial) possible permutations, where n is the number of elements in the set. For this problem we have three elements in our array of integers, so there are 1 * 2 * 3 = 6 possible permutations. It's likely our algorithm will run O(n!) at a minimum.

Backtracking

Backtracking algorithms work to build the solution incrementally through recursion. This is an approach we can use to solve this problem. Here's the approach I'm going to use in the eventual solution below:

static IList<IList> DoPermute(int[] nums, int start, int end, IList<IList> list)
{
    if (start == end)
    {
        // We have one of our possible n! solutions,
        // add it to the list.
        list.Add(new List(nums));
    }
    else
    {
        for (var i = start; i <= end; i++)
        {
            Swap(ref nums[start], ref nums[i]);
            DoPermute(nums, start + 1, end, list);
            Swap(ref nums[start], ref nums[i]); // reset for next pass
        }
    }

    return list;
}
  • We start by iterating through each element of our input array.
  • Swap the elements within nums at i and start (the first element is fixed on the first iterations), and then recursively call DoPermute on the remaining elements.
  • Swap the previously swapped elements back for the next iteration (backtrack).
  • When we reach start == end on each of our recursive calls, we've reached part of the solution, so add nums to our list.

The Code

And now, here's the complete source code.

using System;
using System.Collections.Generic;

namespace PermutationsOfInteger
{
    class Program
    {
        static void Main(string[] args)
        {
            PrintResult(
                Permute(new int[] { 1,2,3 })
            );
        }

        static IList<IList<int>> Permute(int[] nums)
        {
            var list = new List<IList<int>>();
            return DoPermute(nums, 0, nums.Length - 1, list);
        }

        static IList<IList<int>> DoPermute(int[] nums, int start, int end, IList<IList<int>> list)
        {
            if (start == end)
            {
                // We have one of our possible n! solutions,
                // add it to the list.
                list.Add(new List<int>(nums));
            }
            else
            {
                for (var i = start; i <= end; i++)
                {
                    Swap(ref nums[start], ref nums[i]);
                    DoPermute(nums, start + 1, end, list);
                    Swap(ref nums[start], ref nums[i]);
                }
            }

            return list;
        }

        static void Swap(ref int a, ref int b)
        {
            var temp = a;
            a = b;
            b = temp;
        }

        static void PrintResult(IList<IList<int>> lists)
        {
            Console.WriteLine("[");
            foreach (var list in lists)
            {
                Console.WriteLine($"    [{string.Join(',', list)}]");
            }
            Console.WriteLine("]");
        }
    }
}

Conclusion

Now that we've got a working solution, I'm sure there are other (potentially more efficient) approaches to this problem. I'm curious to see other algorithms or shorthands (I suspect this solution could be rewritten into something more elegant using LINQ, for example), but I'll save this for another day.

Happy coding!

Read Next

Multi-Tenanted Entity Framework Core Migration Deployment image

April 11, 2021 by Chad

Multi-Tenanted Entity Framework Core Migration Deployment

There's many ways to deploy pending Entity Framework Core (EF Core) migrations, especially for multi-tenanted scenarios. In this post, I'll demonstrate a strategy to efficiently apply pending EF Core 6 migrations using a .NET 6 console app.

Read Article
Multi-Tenanted Entity Framework 6 Migration Deployment image

April 10, 2021 by Chad

Multi-Tenanted Entity Framework 6 Migration Deployment

There's many ways to deploy pending Entity Framework 6 (EF6) migrations, especially for multi-tenanted production scenarios. In this post, I'll demonstrate a strategy to efficiently apply pending migrations using a .NET 6 console app.

Read Article
Add TypeScript to Your Project image

May 04, 2020 by Chad

Add TypeScript to Your Project

TypeScript helps bring your JavaScript projects sanity by providing strong type checking and all the latest and greatest ECMAScript features. This article will show you how to quickly and easily add TypeScript to your project, old or new.

Read Article