This approach utilizes dynamic programming to find the longest palindromic subsequence in the given string. The minimum number of insertions required is the difference between the length of the string and this subsequence. The idea is to consider characters from both ends of the string and make decisions accordingly using a DP table.
Time Complexity: O(n^2), where 'n' is the length of the string. This is due to the nested loops filling the DP table.
Space Complexity: O(n^2), as it uses a two-dimensional array for the DP table.
1public class MinInsertions {
2 public static int minInsertions(String s) {
3 int n = s.length();
4 int[][] dp = new int[n][n];
5 for (int len = 1; len < n; len++) {
6 for (int i = 0, j = len; j < n; i++, j++) {
7 if (s.charAt(i) == s.charAt(j)) {
8 dp[i][j] = dp[i+1][j-1];
9 } else {
10 dp[i][j] = 1 + Math.min(dp[i+1][j], dp[i][j-1]);
11 }
12 }
13 }
14 return dp[0][n-1];
15 }
16
17 public static void main(String[] args) {
18 System.out.println(minInsertions("mbadm"));
19 }
20}
The Java solution uses a similar DP approach with a 2D array. The nested loops fill the DP table based on character matches from both ends.
This approach leverages a recursive function to explore all possibilities, but uses memoization to cache results of previously computed subproblems. This reduces redundant calculations.
Time Complexity: O(n^2)
Space Complexity: O(n^2) due to the memoization table.
1#include <iostream>
2#include <vector>
3#include <string>
4using namespace std;
5
6vector<vector<int>> dp;
7
8int solve(const string &s, int left, int right) {
9 if (left >= right) return 0;
10 if (dp[left][right] != -1) return dp[left][right];
11 if (s[left] == s[right])
12 dp[left][right] = solve(s, left + 1, right - 1);
13 else
14 dp[left][right] = 1 + min(solve(s, left + 1, right), solve(s, left, right - 1));
15 return dp[left][right];
16}
17
18int minInsertions(string s) {
19 int n = s.length();
20 dp.resize(n, vector<int>(n, -1));
21 return solve(s, 0, n - 1);
22}
23
24int main() {
25 cout << minInsertions("mbadm") << endl;
26 return 0;
27}
In C++, a recursive function solve
is utilized. Memoization is achieved using a 2D vector to store intermediate results, reducing redundant recursive calls.