• 【LEETCODE】72、分割回文串 III 第1278题


    package y2019.Algorithm.dynamicprogramming.hard;
    
    /**
     * @Auther: xiaof
     * @Date: 2019/12/11 08:59
     * @Description:  1278. 分割回文串 III
     *
     * 给你一个由小写字母组成的字符串 s,和一个整数 k。
     * 请你按下面的要求分割字符串:
     * 首先,你可以将 s 中的部分字符修改为其他的小写英文字母。
     * 接着,你需要把 s 分割成 k 个非空且不相交的子串,并且每个子串都是回文串。
     * 请返回以这种方式分割字符串所需修改的最少字符数。
     *
     * 示例 1:
     * 输入:s = "abc", k = 2
     * 输出:1
     * 解释:你可以把字符串分割成 "ab" 和 "c",并修改 "ab" 中的 1 个字符,将它变成回文串。
     * 示例 2:
     * 输入:s = "aabbc", k = 3
     * 输出:0
     * 解释:你可以把字符串分割成 "aa"、"bb" 和 "c",它们都是回文串。
     * 示例 3:
     * 输入:s = "leetcode", k = 8
     * 输出:0
     *
     * 来源:力扣(LeetCode)
     * 链接:https://leetcode-cn.com/problems/palindrome-partitioning-iii
     * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
     *
     * 状态转移方程:f[i][j] = min {f[i0][j - 1] + cost(s, i0+1, i)}
     *
     */
    public class PalindromePartition {
    
        /**
         * 执行用时 : 22 ms , 在所有 java 提交中击败了 40.30% 的用户
         * 内存消耗 : 34.3 MB , 在所有 java 提交中击败了 100.00% 的用户
         * @param s
         * @param k
         * @return
         *
         * 状态转移:f[i][j] = min {f[i0][j - 1] + cost(s, i0+1, i)} 主要参考这个
         * 参考:https://leetcode-cn.com/problems/palindrome-partitioning-iii/solution/fen-ge-hui-wen-chuan-iii-by-leetcode/
         */
        public int solution(String s, int k) {
            int[][] f = new int[s.length() + 1][k];
    
            for (int i = 0; i <= s.length(); ++i) {
                //当N个字符,分割成k个区域,也就是整个字符作为回文的时候
                for (int j = 0; j < k; ++j) {
                    if (i == 0) {
                        f[i][j] = 0;
                    } else if (j == 0) {
                        f[i][j] = cost(s, 0, i);
                    } else {
                        f[i][j] = Integer.MAX_VALUE;
                    }
                }
            }
            //其余节点初始化为最大值
            //遍历获取所有的吧前i个字符,分割成j块回文需要修改的字符数
            for (int i = 1; i < f.length; ++i) {
                for (int j = 1; j < f[i].length; ++j) {
                    //如果分割点比字符还多,无法分割
                    if (i < j) {
                        continue;
                    }
                    //最后遍历所有分割点
                    for (int x = 1; x <= i; ++x) {
                        //如果分割点比字符还多,无法分割
                        if (x < j) {
                            continue;
                        }
                        f[i][j] = Math.min(f[i][j], f[x][j - 1] + cost(s, x, i));
                    }
                }
            }
    
            return f[s.length()][k - 1];
        }
    
        public int cost(String s, int l, int r) {
            //判断前后遍历的过程中有多少字符不相同
            int index1 = l, index2 = r - 1, res = 0;
            while (index1 < index2) {
                //当没有相遇的时候
                if (s.charAt(index1) != s.charAt(index2)) {
                    res++;
                }
                ++index1;
                --index2;
            }
    
            return res;
        }
    
        public static void main(String[] args) {
            String s1 = "abc";
            int k1 = 2;
    
            String s2 = "aabbc"; int k2 = 3;
    
            String s3 = "leetcode"; int k3 = 8;
    
            PalindromePartition fuc = new PalindromePartition();
    
            fuc.solution(s3, k3);
    
        }
    }
  • 相关阅读:
    用JLabel显示时间-- JAVA初学者遇到的一个困难
    linux下观看b站视频,解决字体乱码
    fedora21 codeblocks在编辑装态下无法输入
    fedora21安装无线驱动
    Hdu 1053 Entropy
    linux下的压缩解压命令 tar 的简单描述
    表的截断、删除、创建
    列的维护
    非分区表的重组
    创建高效且易于管理的表以及表的管理和维护
  • 原文地址:https://www.cnblogs.com/cutter-point/p/12021183.html
Copyright © 2020-2023  润新知