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
  • 相关阅读:
    ActiveJDBC 学习笔记
    selenium相关技术研究(从1.0-3.0)
    如何记录selenium自动化测试过程中接口的调用信息
    TestNG进行接口测试,脚本及可维护性框架
    贪多必失,精通一样再往下一样
    测试开发之路:英雄迟暮,我心未老
    接口测试面试题
    自动化测试中的滚动
    maven配置环境变量失败解决办法
    注释——创建新的类(文件)时,自动添加作者创建时间(文件注释)等信息的设置方法
  • 原文地址:https://www.cnblogs.com/cing/p/8796072.html
Copyright © 2011-2022 走看看