zoukankan      html  css  js  c++  java
  • 132.Palindrome Partitioning II

    题目链接

    题目大意:给出一个字符串,对其进行划分,形成所有子串是回文串,找出最小需要划分的次数。比如字符串"aab",最小的划分次数是1,形成"aa","b",都是回文串。

    法一:利用131题的DFS,超时。代码如下:

     1     private static int dfs(String s, int res, int start, ArrayList<String> tmp) {
     2         //如果找到一种划分情况,则将其接入结果集中
     3         if(start == s.length()) {
     4             if(tmp.size() - 1 < res) {
     5                 res = tmp.size() - 1;
     6             }
     7             return res;
     8         }
     9         //寻找每一个可能的回文字符串
    10         for(int i = start; i < s.length(); i++) {
    11             //判断字符串的其中一个子串,如果是回文
    12             if(isPalindrome(s, start, i) == true) {
    13                 //将这个回文子串加入结果中,记住substring(start,end),是从start到end-1的字符串。
    14                 tmp.add(s.substring(start, i + 1));
    15                 //注意,下次划分的子串起始点应该是i+1,因为i已经在上一个子串中了
    16                 res = dfs(s, res, i + 1, tmp);
    17                 //回溯移除
    18                 tmp.remove(tmp.size() - 1);
    19             }
    20         }
    21         return res;
    22     }
    23     //判断回文
    24     private static boolean isPalindrome(String s, int start, int end) {
    25         while(start <= end) {
    26             if(s.charAt(start) != s.charAt(end)) {
    27                 return false;
    28             }
    29             start++;
    30             end--;
    31         }
    32         return true;
    33     }
    View Code

    法二:用到了5题的DP,就是利用DP求解回文子字符串的问题,但是这题还扩展了,不仅求解回文子串,还要求解最小分割数,使得所有子串都是回文串,比如"aab",最后的DP数组就是,dp[0][0],dp[1][1],dp[2][2],这是一次分割;dp[0][1],dp[2][2],这是一次分割。可以看出dp[i][j]就是代表i到j的字符串是否是回文串,然后根据dp数组,再计算分割数。为了节约时间,两者放在一起同时计算,而分割数的dp方程是mi[i] = Math.min(mi[i], mi[j + 1] + 1)。mi[i]表示i到n-1的字符串需要分割的最小次数。代码如下(耗时20ms):

     1     public int minCut(String s) {
     2         //dp[i][j]表示在i到j之间的字符串是否是回文串
     3         boolean[][] dp = new boolean[s.length()][s.length()];
     4         for(int i = 0; i < s.length(); i++) {
     5             dp[i][i] = true;
     6         }
     7         //mi[i]表示i到n-1之间的字符串最小需要分割的次数
     8         //从后往前计算
     9         int[] mi = new int[s.length() + 1];
    10         for(int i = s.length() - 1; i >= 0; i--) {
    11             mi[i] = Integer.MAX_VALUE;//初始化在i的后面分割一下
    12             for(int j = i; j < s.length(); j++) {
    13                 if(s.charAt(i) == s.charAt(j) && (j - i <= 1 || dp[i + 1][j - 1] == true)) {
    14                     dp[i][j] = true;
    15                     //因为i到j构成回文串,所以可以考虑在j后面分割,然后与在i后面分割进行比较
    16                     mi[i] = Math.min(mi[i], 1 + mi[j + 1]);
    17                 }
    18             }
    19         }
    20         return mi[0] - 1;
    21     }
    View Code
  • 相关阅读:
    xls与csv文件的区别
    青音,经典爱情语录
    win7用户账户自动登录方法汇总
    How to using Procedure found Lead Blocker
    FTS(3) BSD 库函数手册 遍历文件夹(二)
    FTS(3) BSD 库函数手册 遍历文件夹(一)
    DisplayMetrics类 获取手机显示屏的基本信息 包括尺寸、密度、字体缩放等信息
    About App Distribution 关于应用发布
    FTS(3) 遍历文件夹实例
    OpenCV 2.1.0 with Visual Studio 2008
  • 原文地址:https://www.cnblogs.com/cing/p/8796072.html
Copyright © 2011-2022 走看看