Order matters. Every arrangement counts.
A permutation is an ordered arrangement of all or part of a set of objects. Unlike combinations, the specific order is crucial — ABC and BAC are two different permutations.
When you allow different lengths — picking 1, 2, or all characters — the total count becomes a sum:
All items are unique. The standard case — no repeats allowed.
Elements can be reused. "AAB" and "ABA" are both valid.
Circular arrangements where rotations of the same order are identical.
For a 3-character string with variable length, here are all 15 permutations. Hover to highlight. Color = length.
Before writing a single line of code, build the mental model:
I can pick just one character at a time.
I can pick any two characters in any order.
I can pick all characters.
For every character I choose, I have options from all remaining characters — so I recurse, tracking what I've already used.
for every character: print current result // every prefix is valid for every other character not yet used: add it, recurse, then remove it // backtrack
The key insight: print before the loop so empty strings and prefixes are captured, then backtrack to explore every branch.
You're building permutations one character at a time. After fully exploring one path, you need to undo your last choice so you can try a different one. That undoing is backtracking.
These two lines are where it happens:
After exploring A→AB→ABC, your result still holds "ABC" and used still has {0,1,2} marked. You're stuck — no way to go back and try ACB, BAC, or any other branch.
After ABC, you undo C, undo B, then try C next — giving ACB. Then undo A entirely and start from B. Every branch gets explored cleanly.
Here is a concrete trace through "ABC":
The used set prevents picking the same index twice on one path. Removing from it on backtrack makes that index available again for sibling branches — without this, you would never generate "BAC" because index 0 (A) would still appear used when starting from B.
import java.util.*; class Main { public static void main(String[] args) { permutation("ABC", new StringBuilder(), new HashSet<>()); } static void permutation(String in, StringBuilder result, Set<Integer> used) { System.out.println(result.toString()); // print every prefix for (int i = 0; i < in.length(); i++) { if (!used.contains(i)) { char c = in.charAt(i); used.add(i); // mark as used permutation(in, result.append(c), used); result.deleteCharAt(result.length() - 1); used.remove(i); // backtrack } } } }
Probability calculations and sample space enumeration
Twelve-tone technique and serial composition tone rows
Brute-force search, test generation, algorithm optimization