Skip to content

Commit b6d632f

Browse files
authored
Merge pull request Dijkstra-Edu#94 from AmanDeol7/aman/sol-2
Solution Dijkstra-Edu#5 - Aman Deol - 02/09/2025
2 parents 43b520f + 249cd5b commit b6d632f

File tree

4 files changed

+304
-0
lines changed

4 files changed

+304
-0
lines changed
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# Longest Palindromic Substring
2+
3+
**Difficulty:** Medium
4+
**Category:** String, Dynamic Programming, Expand Around Center
5+
**Leetcode Link:** [Problem Link](https://leetcode.com/problems/longest-palindromic-substring/)
6+
7+
---
8+
9+
## 📝 Introduction
10+
11+
We are given a string `s` and need to return the **longest palindromic substring** in `s`.
12+
13+
A palindrome is a string that reads the same forward and backward (e.g., `"aba"`, `"abba"`).
14+
We want the **longest substring** (continuous segment) that satisfies this property.
15+
16+
---
17+
18+
## 💡 Approach & Key Insights
19+
20+
1. **Brute Force**
21+
- Generate all substrings and check if each is a palindrome.
22+
- Too slow: O(n³) (substring generation + palindrome check).
23+
24+
2. **Expand Around Center (Optimal for interview)**
25+
- A palindrome mirrors around its center.
26+
- For each index in `s`, try to expand outwards for:
27+
- Odd length palindrome (center at one character).
28+
- Even length palindrome (center between two characters).
29+
- Keep track of the longest one.
30+
- Time: O(n²), Space: O(1).
31+
32+
3. **Dynamic Programming**
33+
- Use a DP table where `dp[i][j] = true` if substring `s[i..j]` is a palindrome.
34+
- Build up from length 1 → n.
35+
- Time: O(n²), Space: O(n²).
36+
37+
4. **Manacher’s Algorithm (Advanced)**
38+
- Linear time O(n). Rarely required in interviews.
39+
- Uses transformed string with separators (`#`) to handle even/odd uniformly.
40+
41+
👉 For coding interviews, **Expand Around Center** is the most elegant and accepted solution.
42+
43+
---
44+
45+
## 🛠️ Breakdown of Approaches
46+
47+
### 1️⃣ Expand Around Center
48+
49+
- For each index `i` in `s`, expand outward to find:
50+
- Longest odd palindrome centered at `i`.
51+
- Longest even palindrome centered between `i` and `i+1`.
52+
- Track the maximum length found.
53+
54+
**Time Complexity:** O(n²)
55+
**Space Complexity:** O(1)
56+
57+
---
58+
59+
### 2️⃣ Dynamic Programming
60+
61+
- Fill a DP table `dp[i][j]`.
62+
- Base cases:
63+
- Single characters are palindromes.
64+
- Two equal characters form a palindrome of length 2.
65+
- For longer substrings, use relation:
66+
```
67+
dp[i][j] = (s[i] == s[j]) && dp[i+1][j-1]
68+
```
69+
- Track longest palindrome.
70+
71+
**Time Complexity:** O(n²)
72+
**Space Complexity:** O(n²)
73+
74+
---
75+
76+
## 📊 Complexity Analysis
77+
78+
| Approach | Time Complexity | Space Complexity |
79+
| --------------------- | --------------- | ---------------- |
80+
| Brute Force | O(n³) | O(1) |
81+
| Expand Around Center | O(n²) | O(1) |
82+
| Dynamic Programming | O(n²) | O(n²) |
83+
| Manacher’s Algorithm | O(n) | O(n) |
84+
85+
---
86+
87+
## 📌 Example Walkthroughs & Dry Runs
88+
89+
Example 1:
90+
```
91+
Input: s = "babad"
92+
93+
Centers:
94+
- Expand at 'b' → "bab"
95+
- Expand at 'a' → "aba"
96+
Longest found = "bab" (or "aba")
97+
98+
Output: "bab"
99+
```
100+
101+
Example 2:
102+
```
103+
Input: s = "cbbd"
104+
105+
Centers:
106+
- Expand at 'c' → "c"
107+
- Expand between "bb" → "bb"
108+
Longest = "bb"
109+
110+
Output: "bb"
111+
```
112+
113+
---
114+
115+
116+
## 🔗 Additional Resources
117+
118+
- [Palindrome Explanation (Wikipedia)](https://en.wikipedia.org/wiki/Palindrome)
119+
- [Manacher’s Algorithm Explanation](https://cp-algorithms.com/string/manacher.html)
120+
- [Leetcode Discuss - Longest Palindromic Substring Solutions](https://leetcode.com/problems/longest-palindromic-substring/discuss/)
121+
- [Youtube Video Explanation](https://www.youtube.com/watch?v=UflHuQj6MVA)
122+
123+
---
124+
125+
Author: Aman Deol
126+
Date: 02/09/2025
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#include <bits/stdc++.h>
2+
using namespace std;
3+
4+
// Approach 1: Brute Force
5+
class SolutionBruteForce {
6+
public:
7+
string longestPalindrome(string s) {
8+
string res = "";
9+
int n = s.size();
10+
for (int i = 0; i < n; i++) {
11+
for (int j = i; j < n; j++) {
12+
string sub = s.substr(i, j - i + 1);
13+
string rev = sub;
14+
reverse(rev.begin(), rev.end());
15+
if (sub == rev && sub.size() > res.size()) {
16+
res = sub;
17+
}
18+
}
19+
}
20+
return res;
21+
}
22+
};
23+
24+
// Approach 2: Expand Around Center
25+
class SolutionExpand {
26+
public:
27+
string expand(string& s, int l, int r) {
28+
while (l >= 0 && r < s.size() && s[l] == s[r]) {
29+
l--; r++;
30+
}
31+
return s.substr(l+1, r-l-1);
32+
}
33+
34+
string longestPalindrome(string s) {
35+
string res = "";
36+
for (int i = 0; i < s.size(); i++) {
37+
string odd = expand(s, i, i);
38+
if (odd.size() > res.size()) res = odd;
39+
string even = expand(s, i, i+1);
40+
if (even.size() > res.size()) res = even;
41+
}
42+
return res;
43+
}
44+
};
45+
46+
// Approach 3: Dynamic Programming
47+
class SolutionDP {
48+
public:
49+
string longestPalindrome(string s) {
50+
int n = s.size();
51+
vector<vector<bool>> dp(n, vector<bool>(n, false));
52+
string res = "";
53+
54+
for (int i = n-1; i >= 0; i--) {
55+
for (int j = i; j < n; j++) {
56+
if (s[i] == s[j] && (j - i < 3 || dp[i+1][j-1])) {
57+
dp[i][j] = true;
58+
}
59+
if (dp[i][j] && (j - i + 1) > res.size()) {
60+
res = s.substr(i, j - i + 1);
61+
}
62+
}
63+
}
64+
return res;
65+
}
66+
};
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Approach 1: Brute Force
2+
class SolutionBruteForce {
3+
private boolean isPalindrome(String str) {
4+
int l = 0, r = str.length() - 1;
5+
while (l < r) {
6+
if (str.charAt(l++) != str.charAt(r--)) return false;
7+
}
8+
return true;
9+
}
10+
11+
public String longestPalindrome(String s) {
12+
String res = "";
13+
int n = s.length();
14+
for (int i = 0; i < n; i++) {
15+
for (int j = i; j < n; j++) {
16+
String sub = s.substring(i, j + 1);
17+
if (isPalindrome(sub) && sub.length() > res.length()) {
18+
res = sub;
19+
}
20+
}
21+
}
22+
return res;
23+
}
24+
}
25+
26+
// Approach 2: Expand Around Center
27+
class SolutionExpand {
28+
private String expand(String s, int l, int r) {
29+
while (l >= 0 && r < s.length() && s.charAt(l) == s.charAt(r)) {
30+
l--; r++;
31+
}
32+
return s.substring(l+1, r);
33+
}
34+
35+
public String longestPalindrome(String s) {
36+
String res = "";
37+
for (int i = 0; i < s.length(); i++) {
38+
String odd = expand(s, i, i);
39+
if (odd.length() > res.length()) res = odd;
40+
String even = expand(s, i, i+1);
41+
if (even.length() > res.length()) res = even;
42+
}
43+
return res;
44+
}
45+
}
46+
47+
// Approach 3: Dynamic Programming
48+
class SolutionDP {
49+
public String longestPalindrome(String s) {
50+
int n = s.length();
51+
boolean[][] dp = new boolean[n][n];
52+
String res = "";
53+
54+
for (int i = n-1; i >= 0; i--) {
55+
for (int j = i; j < n; j++) {
56+
if (s.charAt(i) == s.charAt(j) && (j - i < 3 || dp[i+1][j-1])) {
57+
dp[i][j] = true;
58+
}
59+
if (dp[i][j] && (j - i + 1) > res.length()) {
60+
res = s.substring(i, j+1);
61+
}
62+
}
63+
}
64+
return res;
65+
}
66+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Approach 1: Brute Force
2+
class SolutionBruteForce:
3+
def longestPalindrome(self, s: str) -> str:
4+
def is_palindrome(sub):
5+
return sub == sub[::-1]
6+
res = ""
7+
n = len(s)
8+
for i in range(n):
9+
for j in range(i, n):
10+
if is_palindrome(s[i:j+1]) and len(s[i:j+1]) > len(res):
11+
res = s[i:j+1]
12+
return res
13+
14+
15+
# Approach 2: Expand Around Center
16+
class SolutionExpand:
17+
def longestPalindrome(self, s: str) -> str:
18+
def expand(l, r):
19+
while l >= 0 and r < len(s) and s[l] == s[r]:
20+
l -= 1
21+
r += 1
22+
return s[l+1:r]
23+
24+
res = ""
25+
for i in range(len(s)):
26+
odd = expand(i, i)
27+
if len(odd) > len(res): res = odd
28+
even = expand(i, i+1)
29+
if len(even) > len(res): res = even
30+
return res
31+
32+
33+
# Approach 3: Dynamic Programming
34+
class SolutionDP:
35+
def longestPalindrome(self, s: str) -> str:
36+
n = len(s)
37+
dp = [[False] * n for _ in range(n)]
38+
res = ""
39+
40+
for i in range(n-1, -1, -1):
41+
for j in range(i, n):
42+
if s[i] == s[j] and (j - i < 3 or dp[i+1][j-1]):
43+
dp[i][j] = True
44+
if dp[i][j] and (j - i + 1) > len(res):
45+
res = s[i:j+1]
46+
return res

0 commit comments

Comments
 (0)