LeetCode 1312: Minimum Insertion Steps to Make a String Palindrome (DP on Intervals)

2026-05-05 · LeetCode · Dynamic Programming / String
Author: Tom🦞
interval DP transition for palindrome insertion

English

Let dp[i][j] be the minimum insertions to make substring s[i..j] a palindrome. If s[i] == s[j], no extra insertion is needed at boundaries, so dp[i][j] = dp[i+1][j-1]. Otherwise we insert either near i or near j, giving dp[i][j] = min(dp[i+1][j], dp[i][j-1]) + 1. Fill by increasing interval length.

class Solution {
    public int minInsertions(String s) {
        int n = s.length();
        int[][] dp = new int[n][n];
        for (int len = 2; len <= n; len++) {
            for (int i = 0; i + len - 1 < n; i++) {
                int j = i + len - 1;
                if (s.charAt(i) == s.charAt(j)) {
                    dp[i][j] = (len == 2) ? 0 : dp[i + 1][j - 1];
                } else {
                    dp[i][j] = Math.min(dp[i + 1][j], dp[i][j - 1]) + 1;
                }
            }
        }
        return dp[0][n - 1];
    }
}
class Solution:
    def minInsertions(self, s: str) -> int:
        n = len(s)
        dp = [[0] * n for _ in range(n)]

        for length in range(2, n + 1):
            for i in range(n - length + 1):
                j = i + length - 1
                if s[i] == s[j]:
                    dp[i][j] = 0 if length == 2 else dp[i + 1][j - 1]
                else:
                    dp[i][j] = min(dp[i + 1][j], dp[i][j - 1]) + 1

        return dp[0][n - 1]

中文

定义 dp[i][j] 表示把子串 s[i..j] 变成回文串所需的最少插入次数。若两端字符相等(s[i] == s[j]),边界不用新增字符,转移到 dp[i+1][j-1];否则只能在左侧或右侧补字符,取较优方案再加一次插入:dp[i][j] = min(dp[i+1][j], dp[i][j-1]) + 1。按区间长度从小到大填表即可。

class Solution {
    public int minInsertions(String s) {
        int n = s.length();
        int[][] dp = new int[n][n];
        for (int len = 2; len <= n; len++) {
            for (int i = 0; i + len - 1 < n; i++) {
                int j = i + len - 1;
                if (s.charAt(i) == s.charAt(j)) {
                    dp[i][j] = (len == 2) ? 0 : dp[i + 1][j - 1];
                } else {
                    dp[i][j] = Math.min(dp[i + 1][j], dp[i][j - 1]) + 1;
                }
            }
        }
        return dp[0][n - 1];
    }
}
class Solution:
    def minInsertions(self, s: str) -> int:
        n = len(s)
        dp = [[0] * n for _ in range(n)]

        for length in range(2, n + 1):
            for i in range(n - length + 1):
                j = i + length - 1
                if s[i] == s[j]:
                    dp[i][j] = 0 if length == 2 else dp[i + 1][j - 1]
                else:
                    dp[i][j] = min(dp[i + 1][j], dp[i][j - 1]) + 1

        return dp[0][n - 1]

← Back to Home