Creating permutations by changing case in JavaScript

We are required to write a JavaScript function that takes in a string of characters as input and generates all possible permutations by changing the case of alphabetic characters.

Our function can transform every letter individually to be lowercase or uppercase to create different strings. Non-alphabetic characters remain unchanged. We should return a list of all possible strings we could create.

Problem Statement

Given a string containing letters and numbers, generate all possible case permutations where each letter can be either uppercase or lowercase.

Input:

const str = 'k1l2';

Expected Output:

["k1l2", "k1L2", "K1l2", "K1L2"]

Solution Using Recursive Backtracking

We'll use a recursive approach to generate all combinations. For each alphabetic character, we create two branches: one with lowercase and one with uppercase.

const str = 'k1l2';

const changeCase = function(S = '') {
    const res = [];
    
    const helper = (ind = 0, current = '') => {
        // Base case: if we've processed all characters
        if (ind >= S.length) {
            res.push(current);
            return;
        }
        
        // Check if current character is a letter
        if (/[a-zA-Z]/.test(S[ind])) {
            // Try both lowercase and uppercase
            helper(ind + 1, current + S[ind].toLowerCase());
            helper(ind + 1, current + S[ind].toUpperCase());
        } else {
            // Non-letter characters remain unchanged
            helper(ind + 1, current + S[ind]);
        }
    };
    
    helper();
    return res;
};

console.log(changeCase(str));
[ 'k1l2', 'k1L2', 'K1l2', 'K1L2' ]

How It Works

The algorithm works by:

  • Recursive traversal: Process each character in the string one by one
  • Branch creation: For alphabetic characters, create two recursive calls (lowercase and uppercase)
  • Non-letter handling: Numbers and symbols are added as-is without branching
  • Base case: When we reach the end of the string, add the current permutation to results

Alternative Implementation with Iterative Approach

Here's an iterative solution that builds permutations step by step:

function changeCaseIterative(str) {
    let result = [''];
    
    for (let char of str) {
        if (/[a-zA-Z]/.test(char)) {
            // For each existing string, create two versions
            let newResult = [];
            for (let existing of result) {
                newResult.push(existing + char.toLowerCase());
                newResult.push(existing + char.toUpperCase());
            }
            result = newResult;
        } else {
            // Add non-letter character to all existing strings
            result = result.map(s => s + char);
        }
    }
    
    return result;
}

console.log(changeCaseIterative('a1b'));
[ 'a1b', 'a1B', 'A1b', 'A1B' ]

Time and Space Complexity

For a string with n alphabetic characters:

  • Time Complexity: O(2^n) - we generate 2^n permutations
  • Space Complexity: O(2^n) - to store all permutations

Conclusion

Both recursive and iterative approaches effectively generate case permutations. The recursive solution is more intuitive for backtracking problems, while the iterative approach builds results incrementally. Choose based on your preference for readability and stack usage considerations.

Updated on: 2026-03-15T23:19:00+05:30

309 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements