John Dalesandro

Java Permutation Generator: Partial and Full Strings

Given any string, how many different ways can its characters be arranged?

That question originally motivated me to write this small Java program. At first glance, it sounds simple. You take a few letters and list every possible ordering. But once you start working on it, you quickly see how fast the number of results grows and how important small design decisions become.

Partial and Full Permutations

Most basic permutation generators only produce results that match the length of the input. If you give them three characters, they return three-character results and nothing else.

This program takes a different approach. It generates all permutations from length 1 through n, where n is the length of the input string.

Example: Permutations of “abc”

If the input is:

abc

The program produces:

a, b, c
ab, ac, ba, bc, ca, cb
abc, acb, bac, bca, cab, cba

This includes:

Together, these form the complete set of partial and full permutations.

This is especially useful for word-based games where valid solutions are not always the same length. Being able to generate every possible option makes filtering much easier later.

Why Explore Permutations?

It is a common introductory computer science problem. Working through it helps reinforce key concepts such as recursion, performance trade-offs, and time complexity.

I originally wrote this code to see just how quickly things got out of hand as more characters were added. Even small inputs can produce thousands or millions of combinations. That makes permutation generation a useful way to understand growth rates and algorithmic limits.

From a more practical perspective, a permutation generator powers several of my puzzle solvers, including the Quartiles Solver, Wordle Solver, and Spelling Bee Solver. The general pattern is always the same: generate possible letter arrangements, apply game rules, and compare the remaining candidates to a dictionary file.

Common Problems with Basic Generators

Simple permutation algorithms often work well for small examples, but they tend to break down in more realistic situations.

Duplicate Characters

Consider this input:

aab

A basic generator may produce:

aab, aba, aab, aba, baa, baa

These repeated results waste time and memory and require extra filtering.

Performance Overhead

Many implementations rely heavily on string concatenation and substring operations. This creates large numbers of temporary objects and slows things down as the input grows.

Recursion Limits

Recursive solutions are elegant and easy to read, but deep recursion can lead to stack overflow errors with larger inputs.

These problems are easy to overlook in small demos, but they become very noticeable when you try to build real tools on top of them.

Iterative Permutation Generator

To avoid these issues, this implementation uses an iterative, stack-based approach with built-in duplicate handling.

Instead of relying on the call stack, the program keeps track of partial results explicitly. This makes its behavior more predictable and easier to control.

Key Design Ideas

These ideas keep the code efficient without making it overly complex.

Java Implementation

import java.util.*;

public class PermutationGenerator {

  private static class State {
    StringBuilder current;
    boolean[] used;

    State(StringBuilder current, boolean[] used) {
      this.current = current;
      this.used = used;
    }
  }

  public static List<String> generateAll(String input) {
    List<String> result = new ArrayList<>();

    if (input == null || input.isEmpty()) {
      return result;
    }

    // Sort to group duplicates
    char[] chars = input.toCharArray();
    Arrays.sort(chars);

    int n = chars.length;

    Deque<State> stack = new ArrayDeque<>();

    // Initial empty state
    stack.push(new State(new StringBuilder(), new boolean[n]));

    while (!stack.isEmpty()) {
      State state = stack.pop();

      StringBuilder current = state.current;
      boolean[] used = state.used;

      // Add every non-empty prefix (partial permutation)
      if (current.length() > 0) {
        result.add(current.toString());
      }

      // Stop at full length
      if (current.length() == n) {
        continue;
      }

      // Iterate backwards so smaller indexes are processed first
      for (int i = n - 1; i >= 0; i--) {
        if (used[i])
          continue;

        // Skip duplicates
        if (i > 0 && chars[i] == chars[i - 1] && !used[i - 1]) {
          continue;
        }

        // Copy state
        StringBuilder next = new StringBuilder(current);
        next.append(chars[i]);

        boolean[] nextUsed = Arrays.copyOf(used, n);
        nextUsed[i] = true;

        stack.push(new State(next, nextUsed));
      }
    }

    return result;
  }

  public static void main(String[] args) {
    for (String s : args) {
      System.out.println("Permutations of: " + s);

      List<String> perms = generateAll(s);

      for (String p : perms) {
        System.out.println(p);
      }

      System.out.println();
    }
  }
}

Performance and Complexity

Permutation generation grows extremely quickly.

For a string of length n, the total number of partial and full permutations from length 1 through n is calculated using the following formula:

Formula to calculate the total number of possible partial and full permutations.

For example, with a three-letter string like abc, there are 15 total arrangements when you include single characters, pairs, and full strings.

As n increases, this number rises very quickly. This is why permutation generators are best used with careful filtering and clear limits.

Usage Example

Compile and run the program using the input “abc”:

javac PermutationGenerator.java
java PermutationGenerator abc

Sample output:

Permutations of: abc
a
ab
abc
ac
acb
b
ba
bac
bc
bca
c
ca
cab
cb
cba

Summary

This Java permutation generator produces both partial and full permutations while avoiding duplicate results and recursion limits. Used thoughtfully, it turns a classic programming exercise into a reliable building block for real projects.