Skip to content

Commit

Permalink
Update 0131.分割回文串.md
Browse files Browse the repository at this point in the history
补充python注释和规范代码
  • Loading branch information
casnz1601 authored Oct 10, 2021
1 parent b5dcc55 commit 01af589
Showing 1 changed file with 77 additions and 89 deletions.
166 changes: 77 additions & 89 deletions problems/0131.分割回文串.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,100 +290,88 @@ class Solution {
```

## Python
```python
# 版本一
**回溯+正反序判断回文串**
```python3
class Solution:
def __init__(self):
self.paths = []
self.path = []

def partition(self, s: str) -> List[List[str]]:
res = []
path = [] #放已经回文的子串
def backtrack(s,startIndex):
if startIndex >= len(s): #如果起始位置已经大于s的大小,说明已经找到了一组分割方案了
return res.append(path[:])
for i in range(startIndex,len(s)):
p = s[startIndex:i+1] #获取[startIndex,i+1]在s中的子串
if p == p[::-1]: path.append(p) #是回文子串
else: continue #不是回文,跳过
backtrack(s,i+1) #寻找i+1为起始位置的子串
path.pop() #回溯过程,弹出本次已经填在path的子串
backtrack(s,0)
return res

'''
递归用于纵向遍历
for循环用于横向遍历
当切割线迭代至字符串末尾,说明找到一种方法
类似组合问题,为了不重复切割同一位置,需要start_index来做标记下一轮递归的起始位置(切割线)
'''
self.path.clear()
self.paths.clear()
self.backtracking(s, 0)
return self.paths

def backtracking(self, s: str, start_index: int) -> None:
# Base Case
if start_index >= len(s):
self.paths.append(self.path[:])
return

# 单层递归逻辑
for i in range(start_index, len(s)):
# 此次比其他组合题目多了一步判断:
# 判断被截取的这一段子串([start_index, i])是否为回文串
temp = s[start_index:i+1]
if temp == temp[::-1]: # 若反序和正序相同,意味着这是回文串
self.path.append(temp)
self.backtracking(s, i+1) # 递归纵向遍历:从下一处进行切割,判断其余是否仍为回文串
self.path.pop()
else:
continue
```
```python
# 版本二
**回溯+函数判断回文串**
```python3
class Solution:
def partition(self, s: str) -> List[List[str]]:
res = []
path = [] #放已经回文的子串
# 双指针法判断是否是回文串
def isPalindrome(s):
n = len(s)
i, j = 0, n - 1
while i < j:
if s[i] != s[j]:return False
i += 1
j -= 1
return True

def backtrack(s, startIndex):
if startIndex >= len(s): # 如果起始位置已经大于s的大小,说明已经找到了一组分割方案了
res.append(path[:])
return
for i in range(startIndex, len(s)):
p = s[startIndex:i+1] # 获取[startIndex,i+1]在s中的子串
if isPalindrome(p): # 是回文子串
path.append(p)
else: continue #不是回文,跳过
backtrack(s, i + 1)
path.pop() #回溯过程,弹出本次已经填在path的子串
backtrack(s, 0)
return res
```
## Go

注意切片(go切片是披着值类型外衣的引用类型)
def __init__(self):
self.paths = []
self.path = []

```go
func partition(s string) [][]string {
var tmpString []string//切割字符串集合
var res [][]string//结果集合
backTracking(s,tmpString,0,&res)
return res
}
func backTracking(s string,tmpString []string,startIndex int,res *[][]string){
if startIndex==len(s){//到达字符串末尾了
//进行一次切片拷贝,怕之后的操作影响tmpString切片内的值
t := make([]string, len(tmpString))
copy(t, tmpString)
*res=append(*res,t)
}
for i:=startIndex;i<len(s);i++{
//处理(首先通过startIndex和i判断切割的区间,进而判断该区间的字符串是否为回文,若为回文,则加入到tmpString,否则继续后移,找到回文区间)(这里为一层处理)
if isPartition(s,startIndex,i){
tmpString=append(tmpString,s[startIndex:i+1])
}else{
continue
}
//递归
backTracking(s,tmpString,i+1,res)
//回溯
tmpString=tmpString[:len(tmpString)-1]
}
}
//判断是否为回文
func isPartition(s string,startIndex,end int)bool{
left:=startIndex
right:=end
for ;left<right;{
if s[left]!=s[right]{
return false
}
//移动左右指针
left++
right--
}
return true
}
def partition(self, s: str) -> List[List[str]]:
'''
递归用于纵向遍历
for循环用于横向遍历
当切割线迭代至字符串末尾,说明找到一种方法
类似组合问题,为了不重复切割同一位置,需要start_index来做标记下一轮递归的起始位置(切割线)
'''
self.path.clear()
self.paths.clear()
self.backtracking(s, 0)
return self.paths

def backtracking(self, s: str, start_index: int) -> None:
# Base Case
if start_index >= len(s):
self.paths.append(self.path[:])
return

# 单层递归逻辑
for i in range(start_index, len(s)):
# 此次比其他组合题目多了一步判断:
# 判断被截取的这一段子串([start_index, i])是否为回文串
if self.is_palindrome(s, start_index, i):
self.path.append(s[start_index:i+1])
self.backtracking(s, i+1) # 递归纵向遍历:从下一处进行切割,判断其余是否仍为回文串
self.path.pop() # 回溯
else:
continue

def is_palindrome(self, s: str, start: int, end: int) -> bool:
i: int = start
j: int = end
while i < j:
if s[i] != s[j]:
return False
i += 1
j -= 1
return True
```

## javaScript
Expand Down

0 comments on commit 01af589

Please sign in to comment.