Skip to content

Commit 229e29b

Browse files
author
Yan Cao
committed
Palin II is working now and added summary to dp[N] or dp[N-1] problem
1 parent a8612b7 commit 229e29b

File tree

3 files changed

+71
-29
lines changed

3 files changed

+71
-29
lines changed

Leetcode/Palindrome_Partitioning_II.py

+39-11
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,54 @@
66
For example, given s = "aab",
77
Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut.
88
"""
9-
9+
import sys
1010
class Solution:
1111
# @param s, a string
1212
# @return an integer
1313
def minCut(self, s):
14+
is_palin = self.get_is_palindrome(s)
1415
N = len(s)
15-
dp = [ N for i in range(N)]
16+
dp = [ N-1 for i in range(N+1)]
1617
dp[0] = 0
17-
for i in range(1, N):
18-
dp[i] = sys.maxint
18+
for i in range(1, N+1):
19+
dp[i] = 9223372036854775807
1920
for j in range(i)[::-1]:
20-
if self.isPalindrome(s[j:i]):
21+
if is_palin[j][i-1]:
2122
dp[i] = min(dp[i], dp[j]+1)
22-
return dp[N-1]
23+
return dp[N] - 1
2324

24-
def isPalindrome(self, s):
25-
return s == s[::-1]
25+
def get_is_palindrome(self, s):
26+
N = len(s)
27+
is_palin = [ [ False for j in range(N)] for i in range(N) ]
28+
for i in range(N):
29+
is_palin[i][i] = True
30+
31+
for i in range(N-1):
32+
is_palin[i][i+1] = s[i] == s[i+1]
2633

27-
# 1. dp means from 0 ... i the mean cut of palin
34+
length = 2
35+
while length < N:
36+
start = 0
37+
while start + length < N:
38+
is_palin[start][start+length] = is_palin[start+1][start+length-1] and s[start] == s[start+length]
39+
start += 1
40+
length += 1
41+
return is_palin
42+
43+
"""
44+
This func is no longer used
45+
def is_palin(s):
46+
return s == s[::-1]
47+
"""
48+
# 1. dp means from 0 ... i the min cut times of palin
2849
# 2. dp[0] = 0
2950
# 3. dp[i] = min(dp[i], dp[j]+1) for j = i-1 ... 0 if isPalin(s[j:i])
30-
# 4. dp[N-1]
31-
# This idea is correct, but next thing is to reduce the cost of isPalindrome
51+
# 4. dp[N] - 1
52+
53+
# get_is_palindrome is used to reduce the cost for line 21
54+
# it's returning dp[N] - 1, very tricky
55+
# Beacause in definition, we define as min cut times of palin
56+
# But actually, we just want the min cut
57+
# abbacdc
58+
# dp[3] = 0 but actually dp[3] = 1. So dp[N] = 1 + 1 = 2 but should be 1
59+
# We need to reduce a delete here

coding_index.md

+29-15
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,9 @@ _____
151151
* [x] Palindrome Partitioning II
152152
* [x] Word Break
153153
* [x] Decode Ways
154-
* [x] Longest Palindromic Substring
155154
* [x] Maximum Subarray(勉强)
156155
* [x] LIS
156+
* [x] Longest Palindrome Substring(上课题没用)
157157

158158
-----
159159

@@ -236,17 +236,17 @@ _____
236236
* initialize: ```dp[0] = True``` | ```dp[0] = 0```
237237
* answer: ```dp[N-1]```
238238

239-
######[Palindrom Partitioning II](./Leetcode/Palindrome_Partitioning_II.py)
240-
* state: ```dp[i]```表示前i个字符组成的字符串需要最少几次cut
239+
######[Palindrome Partitioning II](./Leetcode/Palindrome_Partitioning_II.py)
240+
* state: ```dp[i]```表示前i-1个字符组成的字符串需要最少几次cut
241241
* function: ```dp[i] = min( dp[j]+1, j<i and j+1 ~ i 这一段是一个palindrome```) (这里需要用另外一个数组来储存是否是palindrome))
242-
* initialize: ```dp[0] = -1``` (这里好像也不太对)
243-
* answer: ```dp[N]```(这里有些不一样)
242+
* initialize: ```dp[0] = N-1```最少N-1次cut就行了
243+
* answer: ```dp[N]-1```(这里有些不一样,主要原因是)
244244

245245
######[Word Break](./Leetcode/Word_Break.py)
246-
* state: ```dp[i]```表示前i个字符能否被完美切分
246+
* state: ```dp[i]```表示前i-1个字符能否被完美切分
247247
* function: ```dp[i] = for j in (i-1 ... 0) if dp[j] and j ~ i是一个字典中的单词)```
248248
* initialize: ```dp[0] = True```
249-
* answer: ```dp[N]``` (这里也是比较特殊)
249+
* answer: ```dp[N]``` (这里也是比较特殊,因为是i-1个字符,不能从0算起)
250250

251251
注意j的枚举 -> 枚举单词长度
252252
O(NL) N: 字符串长度 L:最长单词的长度
@@ -259,7 +259,7 @@ _____
259259
任何一个位置都可能为开始, 所以所有都要初始化为1, 因为最少LIS是1
260260

261261
######[Decode Ways](./Leetcode/Decode_Ways.py)
262-
* state: ```dp[i]```表示前i个数字的DW
262+
* state: ```dp[i]```表示前i-1个数字的DW
263263
* function:
264264

265265
```python
@@ -268,7 +268,7 @@ _____
268268
+= dp[i-2] # if 10 <= int(A[i-2:i]) <= 26
269269
```
270270
* initialize: ```dp[0] = 1```
271-
* answer: ```dp[N]``` (这里比较特殊)
271+
* answer: ```dp[N]``` (这里比较特殊,因为是前i-1个数字,且dp[0]只是作为一个起始数字来的)
272272

273273
-----
274274

@@ -288,7 +288,7 @@ _____
288288
= max(dp[i][j-1],dp[i-1][j]) # if a[i-1] != b[j-1]
289289
```
290290
* initialize: ```dp[i][0] = 0, dp[0][j] = 0```
291-
* answer: ```dp[len(a)][len(b)]```
291+
* answer: ```dp[M][N]```
292292

293293
######[Longest Common Substring](./Interviews/Longest_Common_Substring.py) [(Not in Leetcode)](http://www.geeksforgeeks.org/longest-common-substring/)
294294
* state: ```dp[i][j]```表示前i个字符配上前j个字符的LCS的长度(一定以第i个和第j个结尾的LCS)
@@ -310,7 +310,7 @@ _____
310310
= min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1])) + 1 # if a[i] != b[j]
311311
```
312312
* initialize: ```dp[i][0] = i, dp[0][j] = j```
313-
* answer: ```dp[len(a)][len(b)]```
313+
* answer: ```dp[M][N]```
314314

315315
######[Distinct Subsequence](./Leetcode/Distinct_Subsequences.py)(需要再领会一下)
316316
* state: ```dp[i][j]```表示T的前i个字符和S的前j个字符的DS个数
@@ -360,9 +360,19 @@ _____
360360
####7. Knapsack
361361

362362

363-
###复杂度
364-
* 一个变量 O(n)
365-
* 两个变量 O(n^2)
363+
###总结
364+
365+
####复杂度
366+
直接看循环嵌套个数
367+
368+
####关于取dp[N]还是dp[N-1]还有dp[N]-1
369+
1. 首先先分析dp维度,Matrix和Two Sequence dp都是二维,One Sequence是一维
370+
2. Matrix dp一般都是初始(0,0)跳到(M-1,N-1)所以取的是```dp[M-1][N-1]```
371+
3. 如果dp[i]或者dp[i][j]表示前i个什么的时候,需要以N/MN作为结尾,主要原因是这种情况下前0个字符串是没有意义的,至少从1开始,所以取dp的时候也是从dp[1]开始才有意义,所以dp[i]的含义是前i-1个东西的性质,而```dp[0] or dp[0][0]```需要强制赋值
372+
4. 至于dp[N] - 1纯粹是因为Palindrome题目比较特殊,实际我们算的cut-1才是结果
373+
374+
####关于已知dp题然后回问方法数问题
375+
一般这种情况就是根据已知的dp matrix和结论,从最后开始往前回溯,满足的就挑进去,不满足的就不放来解决.
366376

367377
-----
368378

@@ -636,7 +646,7 @@ __去想关于数据结构的题目的时候, 只需要考虑数据结构里处
636646
* [ ] Word Ladder II
637647
* [ ] decode ways
638648
* [ ] Median of two sorted arrays
639-
* [ ] Longest Palindromic Substring
649+
* [ ] Longest Palindrome Substring
640650
* [ ] Regular Expression Matching
641651
* [ ] Wildcard Matching
642652
* [ ] Max Points on a Line
@@ -696,3 +706,7 @@ c-a| = 2(a-c) )
696706

697707

698708
证明写的有点乱 求大神更好更清楚的证明
709+
710+
711+
##Some Note
712+
1. 一定要看清题,比如这次就被问了find all palindrome,但是理解成palindrome partitioning了,所以错了

run.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
#!/usr/bin/env python
22

3-
file_name = 'Minimum_Window_Substring'
4-
func_name = 'minWindow'
3+
file_name = 'Palindrome_Partitioning_II'
4+
func_name = 'minCut'
55

66
import importlib
77
module = importlib.import_module('Leetcode.%s' % file_name)
88
instance = module.Solution()
99

10-
print getattr(instance, func_name)("ADOBECODEBANC", 'ABC')
10+
print getattr(instance, func_name)("bb")

0 commit comments

Comments
 (0)