Bird
Raised Fist0
Interview Prepdp-lcs-stringmediumAmazonMicrosoftGoogleFacebook

Longest Palindromic Substring

Choose your preparation mode4 modes available
</>
IDE
def longest_palindrome_brute(s: str) -> str:public String longestPalindrome(String s)string longestPalindrome(string s)function longestPalindrome(s)
def longest_palindrome_brute(s: str) -> str:
    # Write your solution here
    pass
class Solution {
    public String longestPalindrome(String s) {
        // Write your solution here
        return "";
    }
}
#include <string>
using namespace std;

string longestPalindrome(string s) {
    // Write your solution here
    return "";
}
function longestPalindrome(s) {
    // Write your solution here
}
Coming soon
0/10
Common Bugs to Avoid
Wrong: empty stringNot initializing max palindrome length to at least 1 or returning empty when no longer palindrome found.✅ Initialize max_len = 1 and start = 0; return s[start:start+max_len].
Wrong: shorter palindrome substringGreedy approach returning first palindrome found instead of longest.✅ Check all centers and update longest palindrome substring only if longer found.
Wrong: incorrect substring boundaries (off-by-one)Incorrect substring slicing indices causing missing last character or wrong length.✅ Ensure substring includes both start and end indices fully: s[start:end+1].
Wrong: fails on even length palindromesOnly expanding around single characters, missing centers between characters.✅ Expand around centers at i and i+1 for even length palindromes.
Wrong: TLE on large inputUsing brute force O(n^3) approach on large input.✅ Implement O(n^2) expand around center or DP approach.
✓
Test Cases
t1_01basic
Input{"s":"babad"}
Expected"bab"

The longest palindromic substring is 'bab' (or 'aba'). Both are valid answers; here we expect 'bab'.

t1_02basic
Input{"s":"cbbd"}
Expected"bb"

The longest palindromic substring is 'bb' in 'cbbd'.

t2_01edge
Input{"s":"a"}
Expected"a"

Single character string is itself the longest palindrome.

t2_02edge
Input{"s":"aaaaaa"}
Expected"aaaaaa"

All characters same, entire string is the longest palindrome.

t2_03edge
Input{"s":"abcde"}
Expected"a"

No palindrome longer than 1, any single character is valid; here 'a' is expected.

t2_04edge
Input{"s":"racecar"}
Expected"racecar"

Palindrome at the start and end of string; entire string is palindrome.

t3_01corner
Input{"s":"abacdfgdcaba"}
Expected"aba"

Longest palindrome is 'aba' at start or end; tests greedy approach that picks longest prefix palindrome only.

t3_02corner
Input{"s":"abcbaefgfe"}
Expected"abcba"

Tests off-by-one errors in palindrome expansion; longest palindrome is 'efgfe' at end.

t3_03corner
Input{"s":"abccba"}
Expected"abccba"

Tests confusion between 0/1 indexing or substring boundaries; entire string is palindrome.

t4_01performance
Input{"s":"aaaaaaaaaabaaaaaaaaaabaaaaaaaaaa"}
⏱ Performance - must finish in 2000ms

Input length n=29, O(n^2) DP or expand around center expected to complete within 2s; brute force O(n^3) will TLE.

Practice

(1/5)
1. Consider the following code snippet for counting distinct subsequences of t in s. What is the final returned value when s = "abc" and t = "ac"?
easy
A. 0
B. 1
C. 3
D. 2

Solution

  1. Step 1: Trace dp array updates for s="abc", t="ac"

    Initialize dp=[1,0,0]. Iteration i=1 (s[0]='a'): j=2 no match, j=1 matches t[0]='a', dp[1]+=dp[0]=1 -> dp=[1,1,0].
  2. Step 2: Continue tracing for i=2 (s[1]='b') and i=3 (s[2]='c')

    i=2 no matches, dp unchanged. i=3 matches t[1]='c', dp[2]+=dp[1]=0+1=1 -> dp=[1,1,1]. Final dp[n]=dp[2]=1.
  3. Step 3: Count all subsequences matching "ac"

    Subsequences: "ac" only, total 1.
  4. Final Answer:

    Option D -> Option D
  5. Quick Check:

    dp array correctly counts 1 subsequence [OK]
Hint: Trace dp array backward updates carefully [OK]
Common Mistakes:
  • Off-by-one errors in indices
  • Forgetting to iterate j backward
2. You need to transform one string into another using the minimum number of insertions, deletions, and substitutions. Which algorithmic approach guarantees finding the optimal solution efficiently?
easy
A. Dynamic Programming that builds solutions for all prefixes of both strings
B. Greedy algorithm that replaces characters whenever they differ
C. Divide and conquer by splitting strings at midpoint and solving recursively
D. Backtracking all possible sequences of edits without memoization

Solution

  1. Step 1: Understand problem requires minimal edits including insertions, deletions, and substitutions

    These operations depend on overlapping subproblems, making DP suitable.
  2. Step 2: Identify approach that solves all subproblems efficiently

    Dynamic Programming computes minimal edits for all prefixes, ensuring optimality and polynomial time complexity.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    DP covers all prefix pairs systematically [OK]
Hint: Optimal edit distance requires DP over all prefix pairs [OK]
Common Mistakes:
  • Assuming greedy always works
  • Thinking divide and conquer alone suffices
  • Ignoring overlapping subproblems
3. You need to determine if a given input string matches a pattern that includes '.' which matches any single character, and '*' which matches zero or more of the preceding element. Which algorithmic approach guarantees an optimal solution for this problem?
easy
A. Dynamic Programming using a 2D table or space-optimized 1D array
B. Sorting the pattern and string then comparing character by character
C. Backtracking with pruning based on character classes
D. Greedy matching scanning the string once from left to right

Solution

  1. Step 1: Understand problem constraints

    The pattern includes '*' which can match zero or more of the preceding element, and '.' which matches any single character. This requires checking multiple matching possibilities.
  2. Step 2: Identify algorithmic approach

    Greedy or sorting approaches fail because '*' can match variable-length substrings and '.' matches any character. Backtracking is exponential in worst case. Dynamic Programming efficiently stores intermediate results to avoid recomputation, guaranteeing optimal solution.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    DP handles overlapping subproblems and variable-length matches [OK]
Hint: DP handles variable-length '*' matches optimally [OK]
Common Mistakes:
  • Assuming greedy works for '*' patterns
4. Consider the following Python code implementing the space-optimized DP solution for maximum uncrossed lines. What is the value of dp after the outer loop completes for i=2 when nums1 = [1,4,2] and nums2 = [1,2,4]?
easy
A. [0, 1, 2, 2]
B. [0, 1, 1, 1]
C. [0, 1, 1, 2]
D. [0, 0, 1, 1]

Solution

  1. Step 1: Trace dp after i=1

    For i=1 (nums1[0]=1), dp updates to [0,1,1,1] because nums2 has 1 at j=1, matches increment dp[1].
  2. Step 2: Trace dp after i=2

    For i=2 (nums1[1]=4), dp updates as follows: - j=1: no match, dp[1]=max(dp[1], dp[0])=1 - j=2: no match, dp[2]=max(dp[2], dp[1])=1 - j=3: match (4==4), dp[3]=prev+1=1+1=2 where prev is dp[2] before update which was 1, so dp after i=2 is [0,1,1,2].
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    Matches at positions (1,1) and (2,3) give dp[3]=2 after i=2 [OK]
Hint: Track prev and dp[j] carefully to avoid off-by-one errors [OK]
Common Mistakes:
  • Confusing prev and dp[j] updates
  • Off-by-one indexing in dp array
5. Suppose you want to count the number of distinct subsequences of t in s, but now characters in s can be reused multiple times (i.e., you can use the same character in s multiple times to form subsequences). Which modification to the DP approach correctly solves this variant?
hard
A. Use a 2D DP where dp[i][j] counts subsequences using first i chars of s and j chars of t, but allow reusing s[i] by not incrementing i on match
B. Change the recurrence to allow staying at the same i index when matching characters
C. Use the same DP but iterate j forward instead of backward in the inner loop
D. No change needed; original DP already counts subsequences with reuse

Solution

  1. Step 1: Understand reuse means characters in s can be used multiple times

    Original DP assumes each character in s can be used at most once per subsequence.
  2. Step 2: Modify DP to allow reusing s[i]

    Use 2D DP where dp[i][j] counts subsequences using first i chars of s for first j chars of t, and when s[i] matches t[j], allow staying at i (not incrementing) to reuse character.
  3. Step 3: Recognize that iterating j forward or no change won't handle reuse correctly

    Only explicit state allowing reuse by not advancing i on match works.
  4. Final Answer:

    Option A -> Option A
  5. Quick Check:

    Allowing reuse requires 2D DP with careful state transitions [OK]
Hint: Reuse means allowing same s[i] multiple times, so must not always increment i
Common Mistakes:
  • Assuming original DP handles reuse
  • Trying to fix by changing iteration order only
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard