Java Program to Find All Permutations of a String
permute(String str, int l, int r) that swaps characters and calls itself to generate all permutations of the string.Examples
How to Think About It
Algorithm
Code
public class Permutations { public static void permute(String str, int l, int r) { if (l == r) { System.out.print(str + " "); } else { for (int i = l; i <= r; i++) { str = swap(str, l, i); permute(str, l + 1, r); str = swap(str, l, i); // backtrack } } } public static String swap(String str, int i, int j) { char[] charArray = str.toCharArray(); char temp = charArray[i]; charArray[i] = charArray[j]; charArray[j] = temp; return String.valueOf(charArray); } public static void main(String[] args) { String s = "abc"; permute(s, 0, s.length() - 1); } }
Dry Run
Let's trace the input "abc" through the code to see how permutations are generated.
Initial call
permute("abc", 0, 2) - start=0, end=2
First loop i=0
Swap indices 0 and 0: "abc"; call permute("abc", 1, 2)
Second level loop i=1
Swap indices 1 and 1: "abc"; call permute("abc", 2, 2)
Base case reached
Print "abc"
Backtrack and second level loop i=2
Swap indices 1 and 2: "acb"; call permute("acb", 2, 2)
Base case reached
Print "acb"
Backtrack to first level loop i=1
Swap indices 0 and 1: "bac"; call permute("bac", 1, 2)
Second level loop i=1
Swap indices 1 and 1: "bac"; call permute("bac", 2, 2)
Base case reached
Print "bac"
Backtrack and second level loop i=2
Swap indices 1 and 2: "bca"; call permute("bca", 2, 2)
Base case reached
Print "bca"
Backtrack to first level loop i=2
Swap indices 0 and 2: "cba"; call permute("cba", 1, 2)
Second level loop i=1
Swap indices 1 and 1: "cba"; call permute("cba", 2, 2)
Base case reached
Print "cba"
Backtrack and second level loop i=2
Swap indices 1 and 2: "cab"; call permute("cab", 2, 2)
Base case reached
Print "cab"
| Call | String | Action |
|---|---|---|
| permute("abc",0,2) | abc | Swap(0,0), recurse |
| permute("abc",1,2) | abc | Swap(1,1), recurse |
| permute("abc",2,2) | abc | Print permutation |
| permute("abc",1,2) | abc | Swap(1,2), recurse |
| permute("acb",2,2) | acb | Print permutation |
| permute("abc",0,2) | abc | Swap(0,1), recurse |
| permute("bac",1,2) | bac | Swap(1,1), recurse |
| permute("bac",2,2) | bac | Print permutation |
| permute("bac",1,2) | bac | Swap(1,2), recurse |
| permute("bca",2,2) | bca | Print permutation |
| permute("abc",0,2) | abc | Swap(0,2), recurse |
| permute("cba",1,2) | cba | Swap(1,1), recurse |
| permute("cba",2,2) | cba | Print permutation |
| permute("cba",1,2) | cba | Swap(1,2), recurse |
| permute("cab",2,2) | cab | Print permutation |
Why This Works
Step 1: Recursive swapping
The code swaps characters to fix one character at a time and recursively permutes the rest, exploring all possible orders.
Step 2: Base case prints permutation
When the start index equals the end index, the current string is a complete permutation and is printed.
Step 3: Backtracking restores string
After recursive calls, swapping back restores the string to its original state to try other permutations.
Alternative Approaches
public class Permutations { public static void permute(char[] arr, int l, int r) { if (l == r) { System.out.print(new String(arr) + " "); } else { for (int i = l; i <= r; i++) { swap(arr, l, i); permute(arr, l + 1, r); swap(arr, l, i); // backtrack } } } public static void swap(char[] arr, int i, int j) { char temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } public static void main(String[] args) { String s = "abc"; permute(s.toCharArray(), 0, s.length() - 1); } }
import java.util.*; public class Permutations { public static void permute(String str) { List<Character> path = new ArrayList<>(); boolean[] used = new boolean[str.length()]; backtrack(str, path, used); } private static void backtrack(String str, List<Character> path, boolean[] used) { if (path.size() == str.length()) { for (char c : path) System.out.print(c); System.out.print(" "); return; } for (int i = 0; i < str.length(); i++) { if (used[i]) continue; used[i] = true; path.add(str.charAt(i)); backtrack(str, path, used); path.remove(path.size() - 1); used[i] = false; } } public static void main(String[] args) { permute("abc"); } }
Complexity: O(n!) time, O(n) space
Time Complexity
Generating all permutations requires factorial time O(n!) because there are n! permutations for a string of length n.
Space Complexity
The recursion stack and temporary storage use O(n) space, where n is the string length.
Which Approach is Fastest?
Swapping characters in a char array is faster than creating new strings each time, reducing overhead.
| Approach | Time | Space | Best For |
|---|---|---|---|
| String swapping with new strings | O(n!) | O(n) | Simple code, less efficient |
| In-place char array swapping | O(n!) | O(n) | Better performance, less memory |
| Backtracking with visited array | O(n!) | O(n) | Handles duplicates well |