Talentd
FleetCode
Make and follow sheets.Sign in

Unique Length-3 Palindromic Subsequences solution and explanation

MediumBit ManipulationHash TablePrefix SumString6 min read73.8% acceptanceUpdated 9 Apr 2026
Unique Length-3 Palindromic Subsequences - Leetcode 1930 - PythonNeetCode · 12:33 · 28K viewsWatch on YouTube
9 more videos on this problem
  1. Unique Length-3 Palindromic Subsequences - Leetcode 1930 - PythonNeetCode · 12:33 · 28K views
  2. Unique Length-3 Palindromic Subsequences - Leetcode 1930 - PythonNeetCodeIO · 11:58 · 12K views
  3. Unique Length 3 Palindromic Subsequences | Leetcode 1930Techdose · 16:28 · 6K views
  4. Unique Length 3 Palindromic Subsequences - Leetcode 1930 - PythonNeetCodeIO · 11:58 · 5K views
  5. Unique Length-3 Palindromic Subsequences | LeetCode 1930 | Complete Intuition ExplainedSanyam IIT Guwahati · 11:17 · 1K views
  6. 1930. Unique Length-3 Palindromic Subsequences (Leetcode Medium)Programming Live with Larry · 8:17 · 507 views
  7. Unique Length-3 Palindromic Subsequences | Leetcode 1930 | DSA | HIndi Explain | Code With DeepakCode with Deepak · 17:44 · 389 views
  8. Unique Length 3 Palindromic Subsequences - Leetcode 1930 - C++ - عربيTech Time · 18:20 · 258 views
  9. 1930. Unique Length-3 Palindromic Subsequences | Leetcode Daily - PythonLeetcode Daily · 10:04 · 114 views
  10. LeetCode 1930: Unique Length-3 Palindromic Subsequences | Full C++ Explanation + Optimal LogicThe Daily Algorithm · 17:11 · 84 views

The problem

Given a string s, return the number of unique palindromes of length three that are a subsequence of s.

Note that even if there are multiple ways to obtain the same subsequence, it is still only counted once.

A palindrome is a string that reads the same forwards and backwards.

A subsequence of a string is a new string generated from the original string with some characters (can be none) deleted without changing the relative order of the remaining characters.

  • For example, "ace" is a subsequence of "abcde".

Example 1:

Input: s = "aabca"
Output: 3
Explanation: The 3 palindromic subsequences of length 3 are:
- "aba" (subsequence of "aabca")
- "aaa" (subsequence of "aabca")
- "aca" (subsequence of "aabca")

Example 2:

Input: s = "adc"
Output: 0
Explanation: There are no palindromic subsequences of length 3 in "adc".

Example 3:

Input: s = "bbcbaba"
Output: 4
Explanation: The 4 palindromic subsequences of length 3 are:
- "bbb" (subsequence of "bbcbaba")
- "bcb" (subsequence of "bbcbaba")
- "bab" (subsequence of "bbcbaba")
- "aba" (subsequence of "bbcbaba")

Constraints:

  • 3 <= s.length <= 105
  • s consists of only lowercase English letters.

Approach overview

Problem Overview: Given a string s, count how many unique palindromic subsequences of length 3 exist. A valid subsequence has the pattern a ? a where the first and last characters are the same and the middle character can be anything, but each resulting palindrome must be counted only once.

Approach 1: Character Frequency and Set Method (O(n) time, O(1) space)

This approach leverages the fact that a length‑3 palindrome must look like c x c. For each character from 'a' to 'z', find its first and last occurrence in the string. If both exist and there is at least one character between them, every unique character inside that range can serve as the middle element. Use a set to collect distinct middle characters between the two indices, then add the set size to the answer. The alphabet size is fixed (26), so scanning for each character keeps the overall complexity linear. This method relies on simple lookups and is a natural application of a hash table or set for uniqueness while iterating through the string.

Approach 2: Two-Pointer Sliding Window with Prefix Tracking (O(n) time, O(1) space)

This method processes the string while maintaining information about characters seen on the left and characters remaining on the right. A frequency array or bitmask tracks which characters still appear ahead. As you move a pointer through the string, treat the current character as the potential middle of the palindrome. If a character exists both in the left side and the right side, it can form c middle c. Bitmasks or boolean arrays help detect these matches efficiently without storing large sets. This strategy resembles a sliding window combined with prefix/suffix tracking and can be implemented using compact operations common in bit manipulation or lightweight prefix counts similar to a prefix sum pattern.

Recommended for interviews: The character frequency and set method is usually the expected solution. It clearly demonstrates the key observation that the first and last occurrences of each character define the possible palindromes. A brute-force approach checking all subsequences would be O(n³) and impractical. Showing that baseline reasoning is useful, but the O(n) solution proves you can recognize structural constraints in the problem and reduce the search space efficiently.

Approach 1: Character Frequency and Set Method

This approach focuses on tracking the occurrence of characters in the string and how they can form palindromes. We maintain a set of palindromic subsequences to ensure uniqueness.

We iterate through the string, and for each character, we find possible 'b' for our 'aba' structure by looking at all characters that occurred before and after in the string. By maintaining sets of characters seen before and characters seen after each index, we can efficiently determine possible 'a' characters for our palindrome. After finding valid 'aba' subsequences, we add these to a set to ensure each palindrome is only counted once.

def countUniquePalindromes(s):
    n = len(s)
    result = set()
    after = [{} for _ in range(n)]
    before = [{} for _ in range(n)]

    for i in range(n - 2, -1, -1):
        after[i] = after[i + 1].copy()
        after[i][s[i + 1]] = after[i].get(s[i + 1], 0) + 1

    for i in range(1, n - 1):
        c = s[i]
        before[i] = before[i - 1].copy()
        before[i][s[i - 1]] = before[i].get(s[i - 1], 0) + 1

        for ch in before[i]:
            if ch in after[i]:
                result.add((ch, c, ch))

    return len(result)

# Example Usage
s = "aabca"
print(countUniquePalindromes(s))  # Output: 3
#include <stdio.h>
#include <string.h>
#include <stdbool.h>

#define ALPHABET_SIZE 26

bool containsChar(char *set, char ch) {
    return set[ch - 'a'];
}

void addToSet(char *set, char ch) {
    set[ch - 'a'] = true;
}

int countUniquePalindromes(const char *s) {
    int n = strlen(s);
    int result = 0;
    bool before[ALPHABET_SIZE] = {0};
    bool after[ALPHABET_SIZE] = {0};
    bool found[ALPHABET_SIZE][ALPHABET_SIZE] = {0};

    for (int i = 0; i < n; i++)
        addToSet(after, s[i]);

    for (int i = 0; i < n; i++) {
        after[s[i] - 'a'] = false;
        for (int b = 0; b < ALPHABET_SIZE; b++) {
            if (containsChar(before, b + 'a') && containsChar(after, b + 'a')) {
                if (!found[s[i] - 'a'][b]) {
                    found[s[i] - 'a'][b] = true;
                    result++;
                }
            }
        }
        addToSet(before, s[i]);
    }
    return result;
}

int main() {
    char s[] = "aabca";
    printf("%d\n", countUniquePalindromes(s));
    return 0;
}

The solution iterates through the string, updating dictionaries to maintain counts of characters seen before and after each index. For each possible middle character, it checks if it can form a palindrome with any character that appears before and after the current character using the dictionaries to track these possibilities. Subsequence palindromes are stored in a set to ensure they are counted uniquely.

Complexity

Time Complexity: O(n^2), where n is the length of the string, primarily due to the dictionary operations for checking palindromic conditions.

Space Complexity: O(1) additional space beyond input storage and result tracking.

Try this approach in the editor

Approach 2: Two-Pointer Sliding Window

This approach simplifies processing using a two-pointer technique to fix the letters 'a' at the two ends of the palindrome and then check for any characters in between that can be 'b'. We count each found sequence as one unique palindrome. This results in a quick search for matching pairs with just linear passes for each character.

import java.util.HashSet;
import java.util.Set;

public class PalindromeSubsequences {
    public static int countUniquePalindromes(String s) {
        int n = s.length();
        Set<String> uniquePalindromes = new HashSet<>();

        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (s.charAt(i) == s.charAt(j)) {
                    for (int k = i + 1; k < j; k++) {
                        uniquePalindromes.add("" + s.charAt(i) + s.charAt(k) + s.charAt(j));
                    }
                }
            }
        }

        return uniquePalindromes.size();
    }

    public static void main(String[] args) {
        String s = "aabca";
        System.out.println(countUniquePalindromes(s)); // Output: 3
    }
}
function countUniquePalindromes(s) {
    const n = s.length;
    const uniquePalindromes = new Set();
    for (let i = 0; i < n; i++) {
        for (let j = i + 1; j < n; j++) {
            if (s[i] === s[j]) {
                for (let k = i + 1; k < j; k++) {
                    uniquePalindromes.add(`${s[i]}${s[k]}${s[j]}`);
                }
            }
        }
    }
    return uniquePalindromes.size;
}

// Example Usage
console.log(countUniquePalindromes('aabca'));  // Output: 3

The Java solution employs a similar two-pointer strategy, iterating over possible positions for 'a' and another 'a', while searching for middle 'b' between them. Each unique palindrome is added to a set.

Complexity

Time Complexity: O(n^3), due to iterating over potential 'a', 'b', 'a' combinations.

Space Complexity: O(n), using a set for storage of unique palindromes.

Try this approach in the editor

Approach 3: Enumerate Both End Characters + Hash Table

Since the string contains only lowercase letters, we can directly enumerate all pairs of end characters. For each pair of end characters c, we find their first and last occurrence positions l and r in the string. If r - l > 1, it means we have found a palindromic subsequence that meets the conditions. We then count the number of unique characters between [l+1,..r-1], which gives the number of palindromic subsequences with c as the end characters, and add it to the answer.

After enumerating all pairs, we get the answer.

The time complexity is O(n times |\Sigma|), where n is the length of the string and \Sigma is the size of the character set. In this problem, |\Sigma| = 26. The space complexity is O(|\Sigma|) or O(1).

class Solution {
public:
    int countPalindromicSubsequence(string s) {
        int ans = 0;
        for (char c = 'a'; c <= 'z'; ++c) {
            int l = s.find_first_of(c), r = s.find_last_of(c);
            int mask = 0;
            for (int i = l + 1; i < r; ++i) {
                int j = s[i] - 'a';
                if (mask >> j & 1 ^ 1) {
                    mask |= 1 << j;
                    ++ans;
                }
            }
        }
        return ans;
    }
};
function countPalindromicSubsequence(s: string): number {
    let ans = 0;
    const a = 'a'.charCodeAt(0);
    for (let ch = 0; ch < 26; ++ch) {
        const c = String.fromCharCode(ch + a);
        const l = s.indexOf(c);
        const r = s.lastIndexOf(c);
        let mask = 0;
        for (let i = l + 1; i < r; ++i) {
            const j = s.charCodeAt(i) - a;
            if (((mask >> j) & 1) ^ 1) {
                mask |= 1 << j;
                ++ans;
            }
        }
    }
    return ans;
}
public class Solution {
    public int CountPalindromicSubsequence(string s) {
        int ans = 0;
        for (char c = 'a'; c <= 'z'; ++c) {
            int l = s.IndexOf(c), r = s.LastIndexOf(c);
            int mask = 0;
            for (int i = l + 1; i < r; ++i) {
                int j = s[i] - 'a';
                if ((mask >> j & 1) == 0) {
                    mask |= 1 << j;
                    ++ans;
                }
            }
        }
        return ans;
    }
}
func countPalindromicSubsequence(s string) (ans int) {
	for c := 'a'; c <= 'z'; c++ {
		l, r := strings.Index(s, string(c)), strings.LastIndex(s, string(c))
		mask := 0
		for i := l + 1; i < r; i++ {
			j := int(s[i] - 'a')
			if mask>>j&1 == 0 {
				mask |= 1 << j
				ans++
			}
		}
	}
	return
}
impl Solution {
    pub fn count_palindromic_subsequence(s: String) -> i32 {
        let s_bytes = s.as_bytes();
        let mut ans = 0;
        for c in b'a'..=b'z' {
            if let (Some(l), Some(r)) = (
                s_bytes.iter().position(|&ch| ch == c),
                s_bytes.iter().rposition(|&ch| ch == c),
            ) {
                let mut mask = 0u32;
                for i in (l + 1)..r {
                    let j = (s_bytes[i] - b'a') as u32;
                    if (mask >> j & 1) == 0 {
                        mask |= 1 << j;
                        ans += 1;
                    }
                }
            }
        }
        ans
    }
}
Try this approach in the editor

Complexity comparison

ApproachComplexity
Character Frequency and Set Method

Time Complexity: O(n^2), where n is the length of the string, primarily due to the dictionary operations for checking palindromic conditions.

Space Complexity: O(1) additional space beyond input storage and result tracking.

Two-Pointer Sliding Window

Time Complexity: O(n^3), due to iterating over potential 'a', 'b', 'a' combinations.

Space Complexity: O(n), using a set for storage of unique palindromes.

Enumerate Both End Characters + Hash Table–

Complexity analysis

ApproachTimeSpaceWhen to Use
Character Frequency and Set MethodO(n)O(1)Best general solution. Simple logic using first/last positions and a set for unique middle characters.
Two-Pointer Sliding Window with Prefix TrackingO(n)O(1)Useful when maintaining prefix/suffix character states or when implementing with bitmasks.

Frequently asked questions

Is Unique Length-3 Palindromic Subsequences easy or hard?

The problem is rated Medium on LeetCode with an acceptance rate around 73%. The difficulty comes from recognizing that only the first and last occurrence of each character matter, which reduces the search space from all subsequences to a linear scan.

Unique Length-3 Palindromic Subsequences Python/Java solution

Python implementations usually use a set to track distinct middle characters between the first and last occurrence of each letter. Java solutions commonly rely on HashSet or boolean arrays for the same purpose. Both achieve O(n) time and constant auxiliary space.

How to solve Unique Length-3 Palindromic Subsequences in O(n)?

First record the first and last index of each character. For a character c, any palindrome must look like c ? c. Collect all distinct characters between those two indices using a set and add the count to the answer. Since there are only 26 possible outer characters, the total processing remains linear in the length of the string.

What is the best approach for Unique Length-3 Palindromic Subsequences?

The most common solution iterates over each character as the outer pair of the palindrome. For every letter, find its first and last occurrence in the string and count the unique characters between them using a set. This runs in O(n) time with O(1) extra space because the alphabet size is fixed at 26.

Is Unique Length-3 Palindromic Subsequences asked at Google/Amazon/Meta?

This problem tests string processing, hashing, and observation of structural constraints, which are common interview themes at companies like Amazon, Google, and Meta. Variants involving palindromes, subsequences, and character frequency appear frequently in coding interviews.

What data structure is used in Unique Length-3 Palindromic Subsequences?

Typical solutions use sets or hash tables to ensure uniqueness of the middle character. Some implementations also use frequency arrays or bitmasks to track characters seen on the left and right while scanning the string.

What is the time complexity of Unique Length-3 Palindromic Subsequences?

The optimal solutions run in O(n) time. The algorithm scans the string and performs constant‑size operations for each of the 26 characters or maintains prefix/suffix counts while traversing once. Space complexity remains O(1) since only small arrays or sets of alphabet characters are stored.

Comments

Now write it yourselfClose this page and solve Unique Length-3 Palindromic Subsequences in the editor, without looking.
Practise Unique Length-3 Palindromic Subsequences