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 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.

Rust Solution

struct Solution;
use std::collections::HashMap;

impl Solution {
    fn palindrome_partition(s: String, k: i32) -> i32 {
        let s: Vec<char> = s.chars().collect();
        let n = s.len();
        let k = k as usize;
        let mut memo: HashMap<(usize, usize, usize), i32> = HashMap::new();
        let res = Self::dp(0, n, k, &mut memo, &s);
        dbg!(memo);
        res
    }

    fn dp(
        start: usize,
        end: usize,
        k: usize,
        memo: &mut HashMap<(usize, usize, usize), i32>,
        s: &[char],
    ) -> i32 {
        if k == end - start {
            return 0;
        }

        if let Some(&res) = memo.get(&(start, end, k)) {
            return res;
        }

        let res = if k == 1 {
            let n = end - start;
            s[start..end]
                .iter()
                .zip(s[start..end].iter().rev())
                .take(n / 2)
                .map(|v| if v.0 == v.1 { 0 } else { 1 })
                .sum()
        } else {
            let mut min = std::i32::MAX;
            for i in start + 1..=end - k + 1 {
                min = min.min(Self::dp(start, i, 1, memo, s) + Self::dp(i, end, k - 1, memo, s));
            }
            min
        };
        memo.insert((start, end, k), res);
        res
    }
}

#[test]
fn test() {
    let s = "abc".to_string();
    let k = 2;
    let res = 1;
    assert_eq!(Solution::palindrome_partition(s, k), res);
    let s = "aabbc".to_string();
    let k = 3;
    let res = 0;
    assert_eq!(Solution::palindrome_partition(s, k), res);
    let s = "leetcode".to_string();
    let k = 8;
    let res = 0;
    assert_eq!(Solution::palindrome_partition(s, k), res);
}

Having problems with this solution? Click here to submit an issue on github.