Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
C Program to Find Minimum Insertions to Form a Palindrome
A palindrome is a string that reads the same forwards and backwards. Given a string, we need to find the minimum number of character insertions required to make it a palindrome. We will explore three approaches recursive, memoization, and dynamic programming.
Syntax
int minInsertions(char str[], int start, int end);
Method 1: Recursive Approach
The recursive approach compares characters from both ends. If they match, we move inward; otherwise, we try inserting at either end and take the minimum ?
#include <stdio.h>
#include <limits.h>
#include <string.h>
int findMin(int a, int b) {
return (a < b) ? a : b;
}
int findAns(char str[], int start, int end) {
if (start > end) {
return INT_MAX;
}
if (start == end) {
return 0;
}
if (start == end - 1) {
return (str[start] == str[end]) ? 0 : 1;
}
if (str[start] == str[end]) {
return findAns(str, start + 1, end - 1);
} else {
return 1 + findMin(findAns(str, start, end - 1), findAns(str, start + 1, end));
}
}
int main() {
char str[] = "abcda";
int len = strlen(str);
printf("String: %s
", str);
printf("Minimum insertions required: %d
", findAns(str, 0, len - 1));
return 0;
}
String: abcda Minimum insertions required: 2
Method 2: Memoization Approach
This optimizes the recursive approach by storing computed results to avoid redundant calculations ?
#include <stdio.h>
#include <limits.h>
#include <string.h>
int memo[1005][1005];
int findMin(int a, int b) {
return (a < b) ? a : b;
}
int findAns(char str[], int start, int end) {
if (start > end) {
return INT_MAX;
}
if (start == end) {
return 0;
}
if (start == end - 1) {
return (str[start] == str[end]) ? 0 : 1;
}
if (memo[start][end] != -1) {
return memo[start][end];
}
if (str[start] == str[end]) {
memo[start][end] = findAns(str, start + 1, end - 1);
} else {
memo[start][end] = 1 + findMin(findAns(str, start, end - 1), findAns(str, start + 1, end));
}
return memo[start][end];
}
int main() {
char str[] = "abcda";
int len = strlen(str);
memset(memo, -1, sizeof(memo));
printf("String: %s
", str);
printf("Minimum insertions required: %d
", findAns(str, 0, len - 1));
return 0;
}
String: abcda Minimum insertions required: 2
Method 3: Dynamic Programming Approach
This bottom-up approach builds a table where dp[i][j] represents minimum insertions needed for substring from index i to j ?
#include <stdio.h>
#include <string.h>
int findMin(int a, int b) {
return (a < b) ? a : b;
}
int findAns(char str[], int len) {
int dp[1005][1005];
memset(dp, 0, sizeof(dp));
for (int gap = 1; gap < len; gap++) {
for (int start = 0, end = gap; end < len; start++, end++) {
if (str[start] == str[end]) {
dp[start][end] = dp[start + 1][end - 1];
} else {
dp[start][end] = 1 + findMin(dp[start][end - 1], dp[start + 1][end]);
}
}
}
return dp[0][len - 1];
}
int main() {
char str[] = "abcda";
int len = strlen(str);
printf("String: %s
", str);
printf("Minimum insertions required: %d
", findAns(str, len));
return 0;
}
String: abcda Minimum insertions required: 2
Time Complexity Comparison
| Approach | Time Complexity | Space Complexity |
|---|---|---|
| Recursive | O(2^n) | O(n) |
| Memoization | O(n²) | O(n²) |
| Dynamic Programming | O(n²) | O(n²) |
Conclusion
The dynamic programming approach is most efficient for finding minimum palindrome insertions. While recursive approach is intuitive, memoization and DP provide optimal O(n²) time complexity for practical use cases.
