🧠
Brute Force (Backtracking / Permutation Generation)
💡 This approach exists to understand the problem deeply by trying all possible rearrangements. It is impractical for large inputs but helps grasp the constraints and why smarter methods are needed.
Intuition
Try every possible permutation of the string and check if any permutation has no two adjacent identical characters.
Algorithm
- Generate all permutations of the input string.
- For each permutation, check if any two adjacent characters are the same.
- If a valid permutation is found, return it immediately.
- If no valid permutation exists, return an empty string.
💡 The main challenge is generating permutations efficiently and checking adjacency, which is straightforward but computationally expensive.
from itertools import permutations
def reorganizeString(s: str) -> str:
for perm in permutations(s):
if all(perm[i] != perm[i+1] for i in range(len(perm)-1)):
return ''.join(perm)
return ""
# Driver code
if __name__ == "__main__":
test_cases = ["aab", "aaab", "abc", "a"]
for s in test_cases:
print(f"Input: {s} -> Output: {reorganizeString(s)}")
Line Notes
from itertools import permutationsImport permutations to generate all possible orderings of characters
for perm in permutations(s):Try every possible arrangement of characters
if all(perm[i] != perm[i+1] for i in range(len(perm)-1))Check if no two adjacent characters are the same
return ''.join(perm)Return the first valid permutation found
return ""If no valid permutation exists, return empty string
import java.util.*;
public class ReorganizeString {
public static String reorganizeString(String s) {
List<String> permutations = new ArrayList<>();
permute(s.toCharArray(), 0, permutations);
for (String perm : permutations) {
if (isValid(perm)) return perm;
}
return "";
}
private static void permute(char[] arr, int l, List<String> res) {
if (l == arr.length) {
res.add(new String(arr));
return;
}
for (int i = l; i < arr.length; i++) {
swap(arr, l, i);
permute(arr, l + 1, res);
swap(arr, l, i);
}
}
private static boolean isValid(String s) {
for (int i = 0; i < s.length() - 1; i++) {
if (s.charAt(i) == s.charAt(i + 1)) return false;
}
return true;
}
private 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[] tests = {"aab", "aaab", "abc", "a"};
for (String s : tests) {
System.out.println("Input: " + s + " -> Output: " + reorganizeString(s));
}
}
}
Line Notes
permute(char[] arr, int l, List<String> res)Generate all permutations by swapping characters recursively
if (l == arr.length)Base case: one permutation generated, add to results
swap(arr, l, i)Backtrack by swapping back to restore original array
permute(arr, l + 1, res)Recursively generate permutations for next position
isValid(String s)Check if no two adjacent characters are the same
return ""Return empty string if no valid permutation found
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
bool isValid(const string& s) {
for (int i = 0; i < (int)s.size() - 1; i++) {
if (s[i] == s[i + 1]) return false;
}
return true;
}
void permute(string& s, int l, vector<string>& res) {
if (l == (int)s.size()) {
res.push_back(s);
return;
}
for (int i = l; i < (int)s.size(); i++) {
swap(s[l], s[i]);
permute(s, l + 1, res);
swap(s[l], s[i]);
}
}
string reorganizeString(string s) {
vector<string> permutations;
permute(s, 0, permutations);
for (auto& perm : permutations) {
if (isValid(perm)) return perm;
}
return "";
}
int main() {
vector<string> tests = {"aab", "aaab", "abc", "a"};
for (auto& s : tests) {
cout << "Input: " << s << " -> Output: " << reorganizeString(s) << endl;
}
return 0;
}
Line Notes
void permute(string& s, int l, vector<string>& res)Recursively generate all permutations by swapping characters
if (l == (int)s.size())Base case: add current permutation to results
swap(s[l], s[i])Backtrack by swapping back to restore original string
permute(s, l + 1, res)Recursively generate permutations for next position
isValid(const string& s)Check if no two adjacent characters are the same
return ""Return empty string if no valid permutation found
function reorganizeString(s) {
const results = [];
const arr = s.split('');
function permute(l) {
if (l === arr.length) {
results.push(arr.join(''));
return;
}
for (let i = l; i < arr.length; i++) {
[arr[l], arr[i]] = [arr[i], arr[l]];
permute(l + 1);
[arr[l], arr[i]] = [arr[i], arr[l]];
}
}
function isValid(str) {
for (let i = 0; i < str.length - 1; i++) {
if (str[i] === str[i + 1]) return false;
}
return true;
}
permute(0);
for (const perm of results) {
if (isValid(perm)) return perm;
}
return "";
}
// Test cases
const tests = ["aab", "aaab", "abc", "a"];
tests.forEach(s => console.log(`Input: ${s} -> Output: ${reorganizeString(s)}`));
Line Notes
function permute(l)Generate all permutations recursively by swapping characters
if (l === arr.length)Base case: add current permutation to results
[arr[l], arr[i]] = [arr[i], arr[l]]Backtrack by swapping back to restore original array
permute(l + 1)Recursively generate permutations for next position
function isValid(str)Check if no two adjacent characters are the same
return ""Return empty string if no valid permutation found
TimeO(n! * n)
SpaceO(n! * n)
Generating all permutations is O(n!) and checking adjacency is O(n) per permutation, making this approach infeasible for large n.
💡 For n=10, this means over 3 million permutations, each checked for adjacency, which is too slow for interviews.
Interview Verdict: TLE
This approach is too slow for large inputs but is useful to understand the problem and motivate better solutions.