| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 数据结构与算法 -> LeetCode-132. 分割回文串 II -> 正文阅读 |
|
[数据结构与算法]LeetCode-132. 分割回文串 II |
132. 分割回文串 II
示例 1:
示例 2:
分析阶段
把字符串分割成多个子串,要求所有子串是回文串,返回最少的分割次数。最直接的做法是,把所有的子串都列举出来,从中找到最少的一种组合。题目 131. 分割回文串 就是找到所有的回文串组合,但是使用这种方法在 LeetCode 提交结果如下,需要使用新的解法: 假设字符串 s s s 只有一种分割方法,如下所示: s [ 0 , i 1 ] , s [ i 1 + 1 , i 2 ] , s [ i 2 + 1 , i 3 ] , . . . , s [ i k ? 1 , i k ] , s [ i k + 1 , n ? 1 ] s[0,i_1],s[i_1+1,i_2],s[i_2+1,i_3],...,s[i_{k-1},i_k],s[i_k+1,n-1] s[0,i1?],s[i1?+1,i2?],s[i2?+1,i3?],...,s[ik?1?,ik?],s[ik?+1,n?1],分割次数 k k k 可以看出,如果 s [ i k + 1 , n ? 1 ] s[i_k+1,n-1] s[ik?+1,n?1] 是回文串,那么 s [ 0 , n ? 1 ] s[0,n-1] s[0,n?1]的最少分割次数就是 “ s [ 0 , k ] s[0,k] s[0,k]的最少分割次数加1”。 如果字符串 s s s有多种分割方法,假设有三种方法,如下所示: 1、 s [ 0 , i 11 ] , s [ i 11 + 1 , i 1 2 ] , s [ i 12 + 1 , i 13 ] , . . . , s [ i k 1 ? 1 , i k 1 ] , s [ i k 1 + 1 , n ? 1 ] s[0,i_{11}],s[i_{11}+1,i_12],s[i_{12}+1,i_{13}],...,s[i_{k1-1},i_{k1}],s[i_{k1}+1,n-1] s[0,i11?],s[i11?+1,i1?2],s[i12?+1,i13?],...,s[ik1?1?,ik1?],s[ik1?+1,n?1],分割次数 k 1 k1 k1 2、 s [ 0 , i 21 ] , s [ i 21 + 1 , i 22 ] , s [ i 22 + 1 , i 23 ] , . . . , s [ i k 2 ? 1 , i k 2 ] , s [ i k 2 + 1 , n ? 1 ] s[0,i_{21}],s[i_{21}+1,i_{22}],s[i_{22}+1,i_{23}],...,s[i_{k2-1},i_{k2}],s[i_{k2}+1,n-1] s[0,i21?],s[i21?+1,i22?],s[i22?+1,i23?],...,s[ik2?1?,ik2?],s[ik2?+1,n?1],分割次数 k 2 k2 k2 3、 s [ 0 , i 31 ] , s [ i 31 + 1 , i 32 ] , s [ i 32 + 1 , i 33 ] , . . . , s [ i k 3 ? 1 , i k 3 ] , s [ i k 3 + 1 , n ? 1 ] s[0,i_{31}],s[i_{31}+1,i_{32}],s[i_{32}+1,i_{33}],...,s[i_{k3-1},i_{k3}],s[i_{k3}+1,n-1] s[0,i31?],s[i31?+1,i32?],s[i32?+1,i33?],...,s[ik3?1?,ik3?],s[ik3?+1,n?1],分割次数 k 3 k3 k3 要找到最少的分割次数,就是在 k 1 、 k 2 、 k 3 k1、k2、k3 k1、k2、k3 中找到最小值,而 k 1 、 k 2 、 k 3 k1、k2、k3 k1、k2、k3 分别是 s [ 0 , i k 1 ] 、 s [ 0 , i k 2 ] 、 s [ 0 , i k 3 ] s[0,i_{k1}]、s[0,i_{k2}]、s[0,i_{k3}] s[0,ik1?]、s[0,ik2?]、s[0,ik3?] 的最少分割次数加1。 因此,问题的子问题就为:在 s [ 0 , i k 1 ] 、 s [ 0 , i k 2 ] 、 s [ 0 , i k 3 ] s[0,i_{k1}]、s[0,i_{k2}]、s[0,i_{k3}] s[0,ik1?]、s[0,ik2?]、s[0,ik3?]的分割次数中找到最小值,并且 s [ 0 , i k 1 ] 、 s [ 0 , i k 2 ] 、 s [ 0 , i k 3 ] s[0,i_{k1}]、s[0,i_{k2}]、s[0,i_{k3}] s[0,ik1?]、s[0,ik2?]、s[0,ik3?]的分割次数也可以通过求解它们的子问题得到。 1、问题类型第二类:对某种数据结构和算法的使用 使用的算法:动态规划 数据结构:构造状态数组 2、解题思路从前面已经知道,在 s [ 0 , n ? 1 ] s[0,n-1] s[0,n?1] 范围内找到最少分割次数,就是要找到所有的回文子串下标 k ( k 1 、 k 2 、 k 3.... ) k(k1、k2、k3....) k(k1、k2、k3....), s [ 0 , n ? 1 ] s[0,n-1] s[0,n?1] 的最少分割次数等于$ s[0,k1]、s[0,k2]、s[0,k3]、… $ 中最小分割次数加1。 因此,我们可以构造一个数组,使用动态规划来求解最少分割次数,求解过程如下: 1、要求解的“状态”是:到字符串任意下标 i i i 处, s [ 0 , i ] s[0,i] s[0,i] 的最少的回文子串分割次数; 2、简化状态,得到“base case”: i = = 0 i == 0 i==0 或者 s [ 0 , i ] s[0,i] s[0,i] 本身就是回文串,分割次数为0; 3、构造“数组”:构造数组 d p [ n ] dp[n] dp[n]???, d p [ i ] dp[i] dp[i]??? 表示子串 s [ 0 , i ] s[0,i] s[0,i]??? 的最少分割次数; 4、构造状态转移方程: 代码实现在“编码阶段”,在 LeetCode 的提交结果如下: 编码阶段
总结阶段“分割回文串II”解题思路: 1、先用一个简单的例子,找到问题的子问题:最少次数是在多个回文子串中取最小值加1,再不断缩小子问题; 2、构造状态数组,直接保存状态: s [ 0 , i ] s[0,i] s[0,i] 的最少分割次数。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/25 18:32:09- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |