Longest Palindromic Substring in DSA C++ - Time & Space Complexity
We want to understand how the time needed to find the longest palindromic substring changes as the input string gets longer.
How does the number of steps grow when the string size increases?
Analyze the time complexity of the following code snippet.
int expandAroundCenter(const string &s, int left, int right) {
while (left >= 0 && right < (int)s.size() && s[left] == s[right]) {
left--;
right++;
}
return right - left - 1;
}
string longestPalindrome(string s) {
int start = 0, maxLen = 0;
for (int i = 0; i < (int)s.size(); i++) {
int len1 = expandAroundCenter(s, i, i);
int len2 = expandAroundCenter(s, i, i + 1);
int len = max(len1, len2);
if (len > maxLen) {
maxLen = len;
start = i - (len - 1) / 2;
}
}
return s.substr(start, maxLen);
}
This code finds the longest palindromic substring by expanding around each character and its neighbor.
- Primary operation: Expanding around each center to check palindrome length.
- How many times: For each character (n times), two expansions happen, each can expand up to n steps in worst case.
As the string length grows, the number of expansions grows roughly with the square of the length.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 100 expansions |
| 100 | About 10,000 expansions |
| 1000 | About 1,000,000 expansions |
Pattern observation: Doubling the input size roughly quadruples the work.
Time Complexity: O(n²)
This means the time needed grows roughly with the square of the string length.
[X] Wrong: "Checking palindromes around each center is only O(n) because it looks like a single loop."
[OK] Correct: Each center can expand up to n steps, so the inner expansions multiply the work, making it O(n²).
Understanding this time complexity helps you explain why some palindrome solutions are slower and shows your grasp of nested operations in strings.
"What if we used dynamic programming to store palindrome results? How would the time complexity change?"
Practice
Longest Palindromic Substring problem?Solution
Step 1: Understand the problem statement
The problem asks to find the longest part of a string that is a palindrome, meaning it reads the same forwards and backwards.Step 2: Compare options with the problem goal
Only Find the longest substring that reads the same forwards and backwards describes finding a substring that reads the same forwards and backwards, which matches the palindrome definition.Final Answer:
Find the longest substring that reads the same forwards and backwards -> Option AQuick Check:
Longest Palindromic Substring = Find the longest substring that reads the same forwards and backwards [OK]
- Confusing palindrome with unique characters
- Thinking about substrings with vowels only
- Mixing substring with subsequence
dp of size n x n with false values for the Longest Palindromic Substring problem?Solution
Step 1: Understand 2D vector initialization syntax
To create a 2D vector of booleans with size n x n, use vector of vectors: std::vector dp(n, std::vector<bool>(n, false));Step 2: Check each option's correctness
std::vector dp(n, std::vector<bool>(n, false)); uses correct syntax. std::vector<bool> dp(n, std::vector<bool>(n, false)); tries to assign vector<bool> to vector<bool>, which is invalid. std::vector dp(n, std::vector<int>(n, false)); uses int instead of bool. std::vector dp(n, n, false); uses invalid constructor syntax.Final Answer:
std::vector dp(n, std::vector<bool>(n, false)); -> Option DQuick Check:
Correct 2D vector initialization = std::vector dp(n, std::vector<bool>(n, false)); [OK]
- Using wrong data type for dp vector
- Incorrect constructor syntax for 2D vector
- Confusing vector<bool> with vector
std::string s = "babad";
int n = s.size();
int maxLength = 1;
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
int left = i, right = j;
bool isPalindrome = true;
while (left < right) {
if (s[left] != s[right]) {
isPalindrome = false;
break;
}
left++; right--;
}
if (isPalindrome && (j - i + 1) > maxLength) {
maxLength = j - i + 1;
}
}
}
std::cout << maxLength << std::endl;Solution
Step 1: Understand the code logic
The code checks all substrings of "babad" and updates maxLength if the substring is a palindrome and longer than current maxLength.Step 2: Identify longest palindromic substrings in "babad"
"bab" and "aba" are palindromes of length 3. No longer palindrome exists.Final Answer:
3 -> Option AQuick Check:
Longest palindrome length in "babad" = 3 [OK]
- Assuming entire string is palindrome
- Counting non-palindromic substrings
- Off-by-one errors in substring length
std::string s = "cbbd";
int n = s.size();
int maxLength = 1;
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
int left = i, right = j;
while (left < right) {
if (s[left] != s[right]) {
break;
}
left++; right--;
}
if ((j - i + 1) > maxLength) {
maxLength = j - i + 1;
}
}
}
std::cout << maxLength << std::endl;Solution
Step 1: Analyze palindrome check logic
The code breaks out of while loop if characters don't match but does not track if substring is palindrome.Step 2: Check maxLength update condition
maxLength is updated without confirming substring is palindrome, causing incorrect results.Final Answer:
Missing check if substring is palindrome before updating maxLength -> Option CQuick Check:
Must confirm palindrome before updating maxLength [OK]
- Updating maxLength without palindrome check
- Confusing break and continue in loops
- Incorrect loop boundaries
"forgeeksskeegfor", which approach below efficiently finds the longest palindromic substring and what is its length?Solution
Step 1: Identify longest palindrome in "forgeeksskeegfor"
The longest palindromic substring is "geeksskeeg" with length 10.Step 2: Choose efficient approach
Expand Around Center approach efficiently finds palindromes by expanding from each center, suitable for this problem.Final Answer:
Expand Around Center approach, length 10 -> Option BQuick Check:
Longest palindrome length = 10 using Expand Around Center [OK]
- Confusing length of palindrome substring
- Choosing less efficient brute force for large strings
- Mixing up algorithm names and their complexities
Ready to prove it?
Pass the test and this pattern moves unknown
