heray0 2019-12-07
题目如下:
You are given a string
s
containing lowercase letters and an integerk
. You need to :
- First, change some characters of
s
to other lowercase English letters.- Then divide
s
intok
non-empty disjoint substrings such that each substring is 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: 0Constraints:
1 <= k <= s.length <= 100
.s
only contains lowercase English letters.
解题思路:记dp[i][j] = v 表示s[0:j]区间内分割成j段,只需要改变v个字符就可以使得每一段的子串都是回文串。要求dp[i][j]的值,关键就是找出j和j-1的分割点。很显然有dp[i][j] = min(dp[m][j-1] + s[m:j]需要改变的字符的个数),只需要找出最小的分割点m即可。
代码如下:
class Solution(object): def palindromePartition(self, s, k): """ :type s: str :type k: int :rtype: int """ def calc(substr): count = 0 for i in range(len(substr)/2): if substr[i] != substr[len(substr)-i - 1]:count += 1 return count dp = [[float(‘inf‘)] * k for _ in s] dp[0][0] = 0 for i in range(len(s)): for j in range(k): if j == 0: dp[i][j] = calc(s[:i+1]) continue for m in range(j-1,i): dp[i][j] = min(dp[i][j],dp[m][j-1] + calc(s[m+1:i+1])) #print dp return dp[-1][-1]