动态规划进阶ing-分割回文串 II|Go主题月

2,676 阅读1分钟

【Golang主题学习月】周末肝了几道动态规划题,发了一个超细腻的教学版,反响很不错哦,接下来我会使用两种语言进行编码刷题,分别是GO和JAVA,各位菁英们,坚持刷题吧。

如果你对动态规划不熟悉,望转到该篇 \color{red}{如果你对动态规划不熟悉,望转到该篇~}

肝了好多天-动态规划十连-超细腻解析|刷题打卡

这道题很经典啦😄😄😄 \color{green}{这道题很经典啦😄 😄 😄 ~}

什么题可以选择动态规划来做?

1.计数

  • 有多少种方式走到右下角
  • 有多少种方法选出k个数是的和是sum

2.求最大值最小值

  • 从左上角走到右下角路径的最大数字和
  • 最长上升子序列长度

3.求存在性

  • 取石子游戏,先手是否必胜
  • 能不能选出k个数使得和是sum

leecode 132. 分割回文串 II

给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是回文。

返回符合要求的 最少分割次数 。

 

示例 1:

输入:s = "aab"

输出:1

解释:只需一次分割就可将 s 分割成 ["aa","b"] 这样两个回文子串。

示例 2:

输入:s = "a"

输出:0

示例 3:

输入:s = "ab"

输出:1  

提示:

1 <= s.length <= 2000

s 仅由小写英文字母组成


--

这道题跟前面有道最长回文串右相似之处,可以参考一下~~~ ❤️❤️❤️❤️

参考代码

GO语言版

func partition(s string) (ans [][]string) {
    n := len(s)
    f := make([][]bool, n)
    for i := range f {
        f[i] = make([]bool, n)
        for j := range f[i] {
            f[i][j] = true
        }
    }
    for i := n - 1; i >= 0; i-- {
        for j := i + 1; j < n; j++ {
            f[i][j] = s[i] == s[j] && f[i+1][j-1]
        }
    }

    splits := []string{}
    var dfs func(int)
    dfs = func(i int) {    // 1.
        if i == n {        
            ans = append(ans, append([]string(nil), splits...))
            return
        }
        for j := i; j < n; j++ {  // 
            if f[i][j] {      // 2.
                splits = append(splits, s[i:j+1])  // 3.
                dfs(j + 1)     
                splits = splits[:len(splits)-1]  // 4.
            }
        }
    }
     f := make([]int, n)
    for i := range f {
        if g[0][i] {
            continue
        }
        f[i] = math.MaxInt64
        for j := 0; j < i; j++ {
            if g[j+1][i] && f[j]+1 < f[i] { // j+ 1的原因是,不用从0开始,我们已经判断了f[0][i]了
                f[i] = f[j] + 1  // 这里请看上面说明。
            }
        }
    }
    return f[n-1]

}


java版

class Solution {
    boolean[][] dp;
    List<List<String>> ret = new ArrayList<List<String>>();
    List<String> ans = new ArrayList<String>();
    int n;

    public List<List<String>> partition(String s) {
        n = s.length();
        dp = new boolean[n][n];
       char[] charArray = s.toCharArray();
        for (int i = 0; i < n; i++) {
            dp[i][i] = true; // 对本身来说就是回文
        }
        for (int j = 1; j < n; j++) {
            for (int i = 0; i < j; i++) {
                if (charArray[i] != charArray[j]) {
                    dp[i][j] = false;
                } else {
                    if (j - i < 3) {
                        dp[i][j] = true;
                    } else {
                        dp[i][j] = dp[i + 1][j - 1]; // 要满足这个条件,必需先满足j - i > 3考虑边界
                    }
                }
            }
        }
        int[] f = new int[n];
        Arrays.fill(f, Integer.MAX_VALUE);
        for (int i = 0; i < n; ++i) {
            if (g[0][i]) {
                f[i] = 0;
            } else {
                for (int j = 0; j < i; ++j) {
                    if (g[j + 1][i]) {  // j+ 1的原因是,不用从0开始,我们已经判断了f[0][i]了
                        f[i] = Math.min(f[i], f[j] + 1);  // 这里请看上面说明。
                    }
                }
            }
        }
        return f[n - 1];
    }
    
}




❤️❤️❤️❤️

非常感谢人才们能看到这里,如果这个文章写得还不错,觉得有点东西的话 求点赞👍 求关注❤️ 求分享👥 对帅气欧巴的我来说真的 非常有用!!!

如果本篇博客有任何错误,请批评指教,不胜感激 !

文末福利,最近整理一份面试资料《Java面试通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。获取方式:GitHub github.com/Tingyu-Note…,更多内容关注公号:汀雨笔记,陆续奉上。