Talentd
FleetCode
Make and follow sheets.Sign in

Smallest Palindromic Rearrangement I solution and explanation

MediumCounting SortSortingString4 min read74.5% acceptanceUpdated 24 Mar 2026
LeetCode 3517. Smallest Palindromic Rearrangement I | Map | palindrome Property | MediumLeet's Code · 13:07 · 528 viewsWatch on YouTube
6 more videos on this problem
  1. LeetCode 3517. Smallest Palindromic Rearrangement I | Map | palindrome Property | MediumLeet's Code · 13:07 · 528 views
  2. 3517. Smallest Palindromic Rearrangement I (Leetcode Medium)Programming Live with Larry · 4:59 · 202 views
  3. Smallest Palindromic Rearrangement I | Leetcode Contest Solution | Solution Only | @Solution_spotSolution Spot · 0:57 · 140 views
  4. Leetcode 3517. Smallest Palindromic Rearrangement I | Beats 100% | Weekly contest 445 Q2Algo Forces · 12:20 · 99 views
  5. Smallest Palindromic Rearrangement i LeetCode Weekly Contest 445 LeetCode Contest LeetCodeR Sai Siddhu · 13:09 · 74 views
  6. Leetcode | weekly-contest-445 | Smallest Palindromic Rearrangement ICodeWithMe21 · 8:55 · 20 views
  7. Q2. Smallest Palindrome Rearrangement I || LeetCode Weekly Contest 445ExpertFunda · 10:21 · 101 views

The problem

You are given a palindromic string s.

Return the lexicographically smallest palindromic permutation of s.

Example 1:

Input: s = "z"

Output: "z"

Explanation:

A string of only one character is already the lexicographically smallest palindrome.

Example 2:

Input: s = "babab"

Output: "abbba"

Explanation:

Rearranging "babab" → "abbba" gives the smallest lexicographic palindrome.

Example 3:

Input: s = "daccad"

Output: "acddca"

Explanation:

Rearranging "daccad" → "acddca" gives the smallest lexicographic palindrome.

Constraints:

  • 1 <= s.length <= 105
  • s consists of lowercase English letters.
  • s is guaranteed to be palindromic.

Approach overview

Problem Overview: You are given a string and must rearrange its characters to form a palindrome. Among all valid palindromes, return the lexicographically smallest one. If the characters cannot form a palindrome, the rearrangement is impossible. The challenge is balancing palindrome constraints with lexicographic ordering.

Approach 1: Generate All Rearrangements (Brute Force) (Time: O(n! * n), Space: O(n))

The most direct idea is to generate every permutation of the string and check whether it forms a palindrome. For each valid palindrome, track the lexicographically smallest candidate. While this demonstrates the problem mechanics, the factorial growth makes it unusable for realistic input sizes. Even for moderate strings, the number of permutations explodes quickly. This approach mainly serves as a conceptual baseline showing why a smarter counting strategy is necessary.

Approach 2: Sort + Greedy Palindrome Construction (Time: O(n log n), Space: O(n))

Sort the characters first so lexicographically smaller letters appear earlier. Then count occurrences while building the palindrome greedily. Add half of each character's occurrences to the left side, track a single odd-count character for the center, and mirror the left side to form the right half. Sorting guarantees that smaller characters are placed earlier in the palindrome, producing the smallest valid arrangement. This approach is intuitive and works well, but the sort step adds an O(n log n) cost.

Approach 3: Frequency Counting (Optimal) (Time: O(n + k), Space: O(k))

The optimal solution replaces sorting with frequency counting. Use an array or hash map to count occurrences of each character in the string. For a palindrome to exist, at most one character may have an odd frequency. Build the left half by iterating characters in alphabetical order and appending freq[c] / 2 copies of each. If a character has an odd count, place one instance in the center. Finally, mirror the left half to create the right half.

This method effectively behaves like counting sort. Because characters are processed in sorted order implicitly through the frequency array, the resulting palindrome is automatically the smallest lexicographically. No explicit sorting is needed, which reduces the complexity to linear time relative to the input size.

Recommended for interviews: The frequency counting approach is what interviewers expect. It shows you understand palindrome constraints, lexicographic ordering, and how to replace sorting with counting. Mentioning the brute force approach briefly demonstrates problem exploration, but implementing the counting-based construction proves strong mastery of sorting and frequency techniques.

Solution

We first count the occurrence of each character in the string and record it in a hash table or array cnt. Since the string is a palindrome, the count of each character is either even, or there is exactly one character with an odd count.

Next, starting from the lexicographically smallest character, we sequentially add half of each character's count to the first half of the result string t. If a character appears an odd number of times, we record it as the middle character ch. Finally, we concatenate t, ch, and the reverse of t to obtain the final lexicographically smallest palindromic rearrangement.

The time complexity is O(n), where n is the length of the string. The space complexity is O(|\Sigma|), where |\Sigma| is the size of the character set, which is 26 in this problem.

class Solution:
    def smallestPalindrome(self, s: str) -> str:
        cnt = Counter(s)
        t = []
        ch = ""
        for c in ascii_lowercase:
            v = cnt[c] // 2
            t.append(c * v)
            cnt[c] -= v * 2
            if cnt[c] == 1:
                ch = c
        ans = "".join(t)
        ans = ans + ch + ans[::-1]
        return ans
class Solution {
    public String smallestPalindrome(String s) {
        int[] cnt = new int[26];
        for (char c : s.toCharArray()) {
            cnt[c - 'a']++;
        }

        StringBuilder t = new StringBuilder();
        String ch = "";

        for (char c = 'a'; c <= 'z'; c++) {
            int idx = c - 'a';
            int v = cnt[idx] / 2;
            if (v > 0) {
                t.append(String.valueOf(c).repeat(v));
            }
            cnt[idx] -= v * 2;
            if (cnt[idx] == 1) {
                ch = String.valueOf(c);
            }
        }

        String ans = t.toString();
        ans = ans + ch + new StringBuilder(ans).reverse();
        return ans;
    }
}
class Solution {
public:
    string smallestPalindrome(string s) {
        vector<int> cnt(26);
        for (char c : s) {
            cnt[c - 'a']++;
        }
        string t = "";
        string ch = "";
        for (char c = 'a'; c <= 'z'; ++c) {
            int v = cnt[c - 'a'] / 2;
            if (v > 0) {
                t.append(v, c);
            }
            cnt[c - 'a'] -= v * 2;
            if (cnt[c - 'a'] == 1) {
                ch = string(1, c);
            }
        }
        string ans = t;
        ans += ch;
        string rev = t;
        reverse(rev.begin(), rev.end());
        ans += rev;
        return ans;
    }
};
function smallestPalindrome(s: string): string {
    const ascii_lowercase = 'abcdefghijklmnopqrstuvwxyz';
    const cnt = new Array<number>(26).fill(0);
    for (const chKey of s) {
        cnt[chKey.charCodeAt(0) - 97]++;
    }

    const t: string[] = [];
    let ch = '';
    for (let i = 0; i < 26; i++) {
        const c = ascii_lowercase[i];
        const v = Math.floor(cnt[i] / 2);
        t.push(c.repeat(v));
        cnt[i] -= v * 2;
        if (cnt[i] === 1) {
            ch = c;
        }
    }

    let ans = t.join('');
    ans = ans + ch + ans.split('').reverse().join('');
    return ans;
}
func smallestPalindrome(s string) string {
	cnt := make([]int, 26)
	for i := 0; i < len(s); i++ {
		cnt[s[i]-'a']++
	}

	t := make([]byte, 0, len(s)/2)
	var ch byte
	for c := byte('a'); c <= 'z'; c++ {
		v := cnt[c-'a'] / 2
		for i := 0; i < v; i++ {
			t = append(t, c)
		}
		cnt[c-'a'] -= v * 2
		if cnt[c-'a'] == 1 {
			ch = c
		}
	}

	totalLen := len(t) * 2
	if ch != 0 {
		totalLen++
	}
	var sb strings.Builder
	sb.Grow(totalLen)

	sb.Write(t)
	if ch != 0 {
		sb.WriteByte(ch)
	}
	for i := len(t) - 1; i >= 0; i-- {
		sb.WriteByte(t[i])
	}
	return sb.String()
}
Try this approach in the editor

Complexity analysis

ApproachTimeSpaceWhen to Use
Generate All Permutations (Brute Force)O(n! * n)O(n)Only for conceptual understanding or extremely small strings
Sort + Greedy Palindrome BuildO(n log n)O(n)When simplicity matters and sorting overhead is acceptable
Frequency Counting (Counting Sort Style)O(n + k)O(k)Best general solution for interview and production code

Frequently asked questions

Is Smallest Palindromic Rearrangement I easy or hard?

The problem is typically rated Medium. The challenge is recognizing the palindrome frequency constraint and ensuring the final result is the smallest lexicographically. Once you apply a counting strategy, the implementation becomes straightforward.

Smallest Palindromic Rearrangement I Python/Java solution

Most implementations follow the same logic across languages: count character frequencies, construct the left half using freq[c] // 2 copies, optionally add a middle character with odd frequency, and mirror the left side. The FleetCode solution provides implementations in Python, Java, C++, Go, and TypeScript.

How to solve Smallest Palindromic Rearrangement I in O(n)?

Use a counting approach. First compute the frequency of each character, verify that at most one character has an odd count, then append freq[c] / 2 characters to the left half in alphabetical order. Place the odd character in the middle if it exists and append the reverse of the left half to complete the palindrome.

What is the best approach for Smallest Palindromic Rearrangement I?

The best approach uses frequency counting. Count how many times each character appears, ensure at most one character has an odd frequency, then build half the palindrome in lexicographic order and mirror it. This method runs in O(n + k) time where k is the alphabet size and guarantees the smallest lexicographic palindrome.

Is Smallest Palindromic Rearrangement I asked at Google/Amazon/Meta?

Palindrome construction and character frequency problems appear frequently in interviews at companies like Amazon, Google, and Meta. Variants involving palindrome permutations, rearrangements, and lexicographic constraints are common string interview questions.

What data structure is used in Smallest Palindromic Rearrangement I?

A frequency array or hash map is the main data structure. It stores how many times each character appears, enabling a counting-sort style traversal to build the lexicographically smallest palindrome efficiently.

What is the time complexity of Smallest Palindromic Rearrangement I?

The optimal solution runs in O(n + k) time using a counting frequency array, where n is the length of the string and k is the character set size. Building the palindrome requires iterating through the frequency counts and constructing two halves of the result string.

Comments

Now write it yourselfClose this page and solve Smallest Palindromic Rearrangement I in the editor, without looking.
Practise Smallest Palindromic Rearrangement I