1278. Palindrome Partitioning III
You are given a string s containing lowercase letters and an integer k. You need to :
- First, change some characters of s to other lowercase English letters.
- Then divide s into k non-empty disjoint substrings such that each substring is a palindrome.
Return the minimal number of characters that you need to change to divide the string.
Example 1:
Input: s = "abc", k = 2
Output: 1
Explanation: You can split the string into "ab" and "c", and change 1 character in "ab" to make it palindrome.
Example 2:
Input: s = "aabbc", k = 3
Output: 0
Explanation: You can split the string into "aa", "bb" and "c", all of them are palindrome.
Example 3:
Input: s = "leetcode", k = 8
Output: 0
Constraints:
- 1 <= k <= s.length <= 100.
- s only contains lowercase English letters.
From: LeetCode
Link: 1278. Palindrome Partitioning III
Solution:
Ideas:
Precompute the cost to convert every substring into a palindrome, then use dynamic programming to find the minimum cost of splitting the string into exactly k parts.
Code:
c
#include <string.h>
#include <limits.h>
int palindromePartition(char* s, int k) {
int n = strlen(s);
// cost[i][j] = minimum changes needed to make s[i..j] a palindrome
int cost[100][100] = {0};
for (int length = 2; length <= n; length++) {
for (int i = 0; i + length <= n; i++) {
int j = i + length - 1;
cost[i][j] = cost[i + 1][j - 1];
if (s[i] != s[j]) {
cost[i][j]++;
}
}
}
// dp[parts][i] = minimum changes to split first i characters
// into exactly parts palindromic substrings
int dp[101][101];
for (int parts = 0; parts <= k; parts++) {
for (int i = 0; i <= n; i++) {
dp[parts][i] = INT_MAX / 2;
}
}
dp[0][0] = 0;
for (int parts = 1; parts <= k; parts++) {
for (int i = parts; i <= n; i++) {
for (int split = parts - 1; split < i; split++) {
int current =
dp[parts - 1][split] + cost[split][i - 1];
if (current < dp[parts][i]) {
dp[parts][i] = current;
}
}
}
}
return dp[k][n];
}