Fundamentals 7 min read

How to Generate All Permutations with Backtracking: A Step‑by‑Step Guide

This article explains how to enumerate every permutation of an array using a depth‑first search backtracking algorithm, illustrates the process with a tree diagram, compares DFS with BFS, and provides a complete C implementation along with a generic Python template.

JavaEdge
JavaEdge
JavaEdge
How to Generate All Permutations with Backtracking: A Step‑by‑Step Guide

Permutation generation via backtracking

To list all permutations of an array such as [1, 2, 3], fix each possible first element, then recursively fix the second, and finally the third, producing six orders. This can be visualized as a tree where each node is a partial permutation; a depth‑first search (DFS) from the root to each leaf yields one full permutation.

Why DFS

Simple to implement.

Uses a single global state variable, avoiding extra memory.

State transitions are straightforward, making backtracking easy.

Recursive structure

Each non‑leaf node chooses the next element from the remaining pool. Recursion stops when the permutation is complete. Two state variables are needed:

A list (or the current prefix) of already chosen elements.

A boolean array used (initially false) indicating whether each element has been selected, giving O(1) duplicate checks.

Backtracking

After returning from a deeper recursive call, the previous state must be restored (undo the last swap) so that subsequent branches start from the correct configuration.

Complete C implementation

#include <stdio.h>
static int count = 0;

void swap(char *str, int a, int b) {
    char tmp = str[a];
    str[a] = str[b];
    str[b] = tmp;
}

/* Return 1 if str[k] has not appeared between begin and k‑1 */
int isSwapped(char *str, int begin, int k) {
    for (int i = begin; i < k; ++i) {
        if (str[i] == str[k]) {
            return 0;
        }
    }
    return 1;
}

/* Generate all permutations of str[begin..end] */
void full_permutation(char *str, int begin, int end) {
    if (begin == end) {
        count++;               /* a leaf – one permutation */
        return;
    }
    for (int i = begin; i <= end; ++i) {
        if (!isSwapped(str, begin, i)) {
            continue;          /* skip duplicates */
        }
        swap(str, begin, i);                /* fix element at position begin */
        full_permutation(str, begin + 1, end); /* recurse */
        swap(str, begin, i);                /* undo swap (backtrack) */
    }
}

Python backtracking template

result = []

def backtrack(path, choices):
    if end_condition:
        result.append(path)
        return
    for choice in choices:
        # make a choice
        backtrack(path + [choice], new_choices)
        # undo the choice (implicitly by returning)
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

algorithmCBacktrackingDFSRecursionpermutations
JavaEdge
Written by

JavaEdge

First‑line development experience at multiple leading tech firms; now a software architect at a Shanghai state‑owned enterprise and founder of Programming Yanxuan. Nearly 300k followers online; expertise in distributed system design, AIGC application development, and quantitative finance investing.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.