132-分隔字符串,得到回文II

标签: 算法 数据结构 leetcode
6人阅读 评论(0) 收藏 举报
分类:

Description
Given a string s, partition s such that every substring of the partition is a palindrome.

Return the minimum cuts needed for a palindrome partitioning of s.


For example, given s = “aab”,
Return 1 since the palindrome partitioning [“aa”,”b”] could be produced using 1 cut.


问题描述
给定字符串s,对其分段,使得每个子串为回文串。
返回最小切分数


问题分析

两种解法,DFS + Memorization和动态规划

动态规划

状态为dp[i], 表示[i, len - 1]需要的最小切分数

转移
若s.substring(i, j + 1)为回文,那么dp[i] = Math.min(dp[i + 1] + 1, dp[i])
需要注意,每轮更新dp[i]时先将其设置为len - i - 1(最大切分数)


解法1(DFS + Memorization)

class Solution {
    public int minCut(String s) {
        int len = s.length();

        Map<String, Integer> memo = new HashMap();
        //注意这里需要先放入空串,其对应切分数为0
        memo.put("", 0);

        return dfs(s, memo) - 1;
    }
    public int dfs(String s, Map<String, Integer> memo){
        if(memo.containsKey(s))    return memo.get(s);

        int min = s.length();
        for(int i = s.length() - 1;i >= 0;i--){
            if(isPalindrome(s, 0, i)){
                min = Math.min(min, 1 + dfs(s.substring(i + 1), memo));
            }
            //注意这里,若得到1或者2,退出循环,因为1或者2已经是最小的结果了
            if(min == 1 || min == 2)    break;
        }
        memo.put(s, min);

        return min;
    }
    //判断是否为回文
    public boolean isPalindrome(String s, int left, int right){
        while(left < right){
            if(s.charAt(left) != s.charAt(right))   return false;
            left++;
            right--;
        }

        return true;
    }
}

解法2(动态规划)

class Solution {
    public int minCut(String s) {
        int len = s.length();

        int[] dp = new int[len];
        //回文bool数组,若pal[i][j] = true,表示s.substring(i, j + 1)为回文
        boolean[][] pal =  new boolean[len][len];

        for(int i = len - 1;i >= 0;i--){
            dp[i] = len - i - 1;
            for(int j = i;j < len;j++){
                //判断s.substring(i, j + 1)是否为回文
                if(s.charAt(i) == s.charAt(j) && (j - i < 2 || pal[i + 1][j - 1])){
                    //若是回文,将pal[i][j]标为true
                    pal[i][j] = true;
                    //若j == len - 1,说明s.substring(i, len)为回文,直接为0
                    if(j == len - 1)    dp[i] = 0;
                    else                dp[i] = Math.min(dp[i], dp[j + 1] + 1);
                }
            }
        }

        return dp[0];
    }
}

解法3(最优解)

/*
.......aba...
|<-X->| ^
|<---Y-->|
看下这个例子,aba 为回文串,那么Y的最小切分数一定不大于X + 1
这就是这个算法的核心思想
通过由i向两端遍历得到奇数长度回文串和偶数长度回文串,s[e] = Math.min(s[e], s[s - 1] + 1)
*/
class Solution {
    public int minCut(String s) {
        if (s == null || s.length() < 2) return 0 ;

        int N = s.length() ;
        int C[] = new int[N] ;
        Arrays.fill(C, N-1) ;

        char[] str = s.toCharArray() ;
        for (int l = 0 ; l < N ; ++ l) {
            //奇数长度的回文串
            updateCutForPalindrome(str, l, l, C, N) ;
            //偶数长度的回文串
            updateCutForPalindrome(str, l, l+1, C, N) ;
        }

        return C[N-1] ; 
    }

    void updateCutForPalindrome(char[] str, int s, int e, int[] C, int N){
        while ( s >= 0 && e < N && str[s] == str[e]) {
            C[e] = Math.min(C[e], (s-1 >= 0 ? C[s-1] : -1) + 1) ;
            ++ e ;
            -- s ;
        }
    }
}
查看评论

leetcode之 Palindrome Partitioning I&II

1 Palindrome Partitioning 问题来源:PalindromePartitioning 该问题简单来说就是给定一个字符串,将字符串分成多个部分,满足每一部分都是回文串,请输出所有...
  • yutianzuijin
  • yutianzuijin
  • 2013-11-20 21:06:00
  • 13922

【LeetCode】132. Palindrome Partitioning II 基于动态规划DP、C++、Java的分析及解法

132. Palindrome Partitioning II Total Accepted: 50256 Total Submissions: 230441 Difficulty: Hard ...
  • Jin_Kwok
  • Jin_Kwok
  • 2016-05-16 20:29:43
  • 921

LeetCode 132. Palindrome Partitioning II(回文切分)

原题网址:https://leetcode.com/problems/palindrome-partitioning-ii/ Given a string s, partition s such ...
  • jmspan
  • jmspan
  • 2016-05-27 00:22:56
  • 372

Leetcode(132) Palindrome Partitioning II

题目如下: Given a string s, partition s such that every substring of the partition is a palindrome. Retu...
  • feliciafay
  • feliciafay
  • 2014-12-17 03:47:14
  • 1080

LeetCode 132 Palindrome Partitioning II (动态规划)

LeetCode 132 Palindrome Partitioning II (动态规划)
  • Tc_To_Top
  • Tc_To_Top
  • 2016-10-23 11:59:51
  • 767

Leetocde: Palindrome Partitioning II

Given a string s, partition s such that every substring of the partition is a palindrome. Return th...
  • doc_sgl
  • doc_sgl
  • 2013-10-28 23:41:31
  • 6352

#108 Palindrome Partitioning II

题目描述: Given a string s, cut s into some substrings such that every substring is a palindrome....
  • haifischxia
  • haifischxia
  • 2016-08-25 14:39:18
  • 94

Palindrome Partitioning II Leetcode Python

Given a string s, partition s such that every substring of the partition is a palindrome. Retur...
  • hyperbolechi
  • hyperbolechi
  • 2015-01-25 02:24:16
  • 302

分区(partitioning)概述

--分区概述 /* 分区使用了一种分而治之的方法,使用管理非常大的表和索引。 分区引用了一种分区键(partition key)的概念,数据会根据其他分区键值分到对应的分区。 划分分区的方法可以是...
  • u013169075
  • u013169075
  • 2016-11-09 13:32:27
  • 151

Oracle未启用Partitioning功能解决

本文针对Oracle64位企业版,其他版本未做尝试。 1.使用SQL*Plus的srvctl命令关闭数据库 srvctl stop database -d myDb 2.Win+R打开运行窗口,输入...
  • shujudeliu
  • shujudeliu
  • 2015-06-01 09:06:13
  • 6292
    个人资料
    专栏达人 持之以恒
    等级:
    访问量: 2万+
    积分: 6912
    排名: 4202
    博客专栏
    文章存档
    最新评论