Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenDocCN
awesome-algorithm
提交
8b0c27a5
A
awesome-algorithm
项目概览
OpenDocCN
/
awesome-algorithm
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
A
awesome-algorithm
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
8b0c27a5
编写于
3月 16, 2019
作者:
K
Keqi Huang
提交者:
GitHub
3月 16, 2019
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Create 0132._Palindrome_Partitioning_II.md
上级
d8faf02f
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
123 addition
and
0 deletion
+123
-0
docs/Leetcode_Solutions/Python/0132._Palindrome_Partitioning_II.md
...code_Solutions/Python/0132._Palindrome_Partitioning_II.md
+123
-0
未找到文件。
docs/Leetcode_Solutions/Python/0132._Palindrome_Partitioning_II.md
0 → 100644
浏览文件 @
8b0c27a5
# 132. Palindrome Partitioning II
**<font color=red>难度: Hard</font>**
## 刷题内容
> 原题连接
*
https://leetcode.com/problems/palindrome-partitioning-ii/
> 内容描述
```
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.
Example:
Input: "aab"
Output: 1
Explanation: The palindrome partitioning ["aa","b"] could be produced using 1 cut.
```
## 解题方案
> 思路 1
******- 时间复杂度: O(N^3)******
- 空间复杂度: O(N^2)
****
**
-
我们维护一个一维数组cut,cut[i]代表s[:i+1]最少需要多少次cut
-
然后我们发现对于j
<
=
i
,
如果s
[
j:i
+1]
是Palindrome
。
则cut[i] =
min(cut[i],
cut
[
j-1
]
+
1)
if
j
>
0 else 0,
因为如果j为0的话说明s[:i+1]都是Palindrome了,完全不需要cut,所以当j==0的时候cut[i] = 0
-
最后返回cut[-1]即可
```
python
class
Solution
:
def
minCut
(
self
,
s
:
str
)
->
int
:
cut
=
list
(
range
(
len
(
s
)))
for
i
in
range
(
len
(
s
)):
for
j
in
range
(
i
+
1
):
if
s
[
j
:
i
+
1
]
==
s
[
j
:
i
+
1
][::
-
1
]:
cut
[
i
]
=
min
(
cut
[
i
],
cut
[
j
-
1
]
+
1
)
if
j
>
0
else
0
return
cut
[
-
1
]
```
> 思路 2
******- 时间复杂度: O(N^2)******
- 空间复杂度: O(N^2)
****
**
我们发现每次都要算s[j:i+1]是否为Palindrome太浪费时间了, 用一个dp数组记录一下
-
我们维护一个二维数组dp,dp
[
i
][
j
]
代表s[i:j+1]是否为Palindrome
-
然后维护一个一维数组cut,cut[i]代表s[:i+1]最少需要多少次cut
-
然后我们发现对于j
<
=
i
,
如果s
[
j:i
+1]
是Palindrome
。
则cut[i] =
min(cut[i],
cut
[
j-1
]
+
1)
if
j
>
0 else 0,
因为如果j为0的话说明s[:i+1]都是Palindrome了,完全不需要cut,所以当j==0的时候cut[i] = 0
-
最后返回cut[-1]即可
```
python
class
Solution
:
def
minCut
(
self
,
s
:
str
)
->
int
:
dp
=
[[
False
]
*
len
(
s
)
for
_
in
range
(
len
(
s
))]
cut
=
[
0
]
*
len
(
s
)
for
i
in
range
(
len
(
s
)):
cut
[
i
]
=
i
for
j
in
range
(
i
+
1
):
if
s
[
i
]
==
s
[
j
]
and
(
j
+
1
>=
i
-
1
or
dp
[
j
+
1
][
i
-
1
]):
dp
[
j
][
i
]
=
True
cut
[
i
]
=
min
(
cut
[
i
],
cut
[
j
-
1
]
+
1
)
if
j
>
0
else
0
return
cut
[
-
1
]
```
> 思路 3
******- 时间复杂度: O(N^2)******
- 空间复杂度: O(N)
****
**
我们在空间上也可以继续优化
-
我们维护一个一维数组cut,cut[i] 代表前i个字符最少需要几次cut
-
然后对于每一个字符s[i],我们分两种情况讨论
-
将s[i]作为palindrome的中间字符(odd length),向两边各扩展j个字符,使得s[i-j:i+j+1]是palindrome,同时保证不越界,
此时cut[i+j+1] = min(cut[i+j+1], cut[i-j] + 1)
-
将s[i]作为palindrome的中间靠前的那个字符(even length),向左边扩展j-1个字符,向右边扩展j个字符,使得s[i-j+1:i+j+1]是palindrome,同时保证不越界,
此时cut[i+j+1] = min(cut[i+j+1], cut[i-j+1] + 1)
-
最后返回cut[-1]
```
python
class
Solution
:
def
minCut
(
self
,
s
:
str
)
->
int
:
cut
=
list
(
range
(
-
1
,
len
(
s
)))
# cut[i] 代表前i个字符最少需要几次cut
for
i
in
range
(
len
(
s
)):
j
=
0
while
i
-
j
>=
0
and
i
+
j
<
len
(
s
)
and
s
[
i
-
j
]
==
s
[
i
+
j
]:
# odd length palindrome
cut
[
i
+
j
+
1
]
=
min
(
cut
[
i
+
j
+
1
],
cut
[
i
-
j
]
+
1
)
j
+=
1
j
=
1
while
i
-
j
+
1
>=
0
and
i
+
j
<
len
(
s
)
and
s
[
i
-
j
+
1
]
==
s
[
i
+
j
]:
# even length palindrome
cut
[
i
+
j
+
1
]
=
min
(
cut
[
i
+
j
+
1
],
cut
[
i
-
j
+
1
]
+
1
)
j
+=
1
return
cut
[
-
1
]
```
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录