15. Substrings with Same First and Last Characters
The problem can be found at the following link: 🔗 Question Link
🧩 Problem Description
Given a string s consisting of lowercase English letters, count all substrings in which the first and last characters are the same.
A substring is a contiguous sequence of characters within the string. Single-character substrings are always valid.
📘 Examples
Example 1:
Input:
s = "abcab"
Output:
7
Explanation:
The valid substrings are "a", "b", "c", "a", "b", "abca", and "bcab".
Example 2:
Input:
s = "aba"
Output:
4
Explanation:
The valid substrings are "a", "b", "a", and "aba".
🔒 Constraints
$1 \leq |s| \leq 10^4$
scontains only lowercase English alphabets ('a'to'z')
✅ My Approach
Frequency Count using Combinatorics
A substring starts and ends with the same character if we consider all positions where a character appears. For a character appearing f times, the number of such substrings is:
This accounts for:
fsingle-character substringsfC2substrings where both ends are the same character
We use a frequency array of size 256 (or 26 if lowercase only) to count characters, then sum this formula over all counts.
🧮 Time and Auxiliary Space Complexity
Expected Time Complexity: O(n), as we scan the string once to count character frequencies and once more to sum results.
Expected Auxiliary Space Complexity: O(1), as we use a fixed-size array of length 256 regardless of input size.
🧠 Code (C++)
⚡ Alternative Approaches
📊 2️⃣ HashMap-Based Frequency Count
💡 Algorithm Steps:
Initialize a
unordered_map<char, int>.Traverse the string
s, incrementing count for each character.For each
(char, freq)in the map, addfreq * (freq + 1) / 2to result.
✅ Why This Approach?
Reduces unnecessary storage compared to fixed-size array (good for limited character sets).
📝 Complexity Analysis:
Time: O(n)
Auxiliary Space: O(k), where
kis the number of unique characters
📊 3️⃣ Using C++ STL map or array<int, 26> (If Input is Lowercase Only)
map or array<int, 26> (If Input is Lowercase Only)💡 Algorithm Steps:
Initialize an array of size 26 for lowercase letter counts.
Traverse string and increment count.
Compute total using same formula.
✅ Why This Approach?
Fast and space-efficient when you know the character set (a–z).
Constant-size array is faster than unordered_map.
📝 Complexity Analysis:
Time: O(n)
Auxiliary Space: O(1) (since 26 is constant)
🆚 Comparison of Approaches
Approach
⏱️ Time
💾 Space
✅ Pros
⚠️ Cons
Frequency array (main)
🟢 O(n)
🟢 O(Σ=256)
Fastest, simplest
Wastes space for small charsets
unordered_map count
🟢 O(n)
🔸 O(k)
Efficient for limited unique chars
Slightly longer code
array<int, 26>
🟢 O(n)
🔸 O(1)
Best for lowercase-only strings
Only works with known charsets
✅ Best Choice by Scenario
Scenario
Recommended Approach
Performance-critical, any charset
🥇 Fixed-size array of 256
Lowercase input (a–z)
🥈 26-letter frequency array
Space-aware and clean design
🥉 HashMap
🧑💻 Code (Java)
🐍 Code (Python)
🧠 Contribution and Support
For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: 📬 Any Questions?. Let’s make this learning journey more collaborative!
⭐ If you find this helpful, please give this repository a star! ⭐
📍Visitor Count
Last updated