分割回文串
Given a string s, partition s such that every substring of the partition is a palindrome.
Return all possible palindrome partitioning of s.
Example:
Input: "aab" Output: [ ["aa","b"], ["a","a","b"] ]
Code(By myself):
class Solution(object):
def partition(self, s):
"""
:type s: str
:rtype: List[List[str]]
"""
res = []
if not s:
return res
for i in range(len(s)):
if self.isPalindrome(s[:i+1]):
temp = [s[:i+1]]
p = self.partition(s[i+1:])
if p:
for j in p:
res.append(temp + j)
else:
res.append(temp)
return res
def isPalindrome(self,s):
if s == s[::-1]:
return True
else:
return False
Code(others):
class Solution(object):
def partition(self, s):
"""
:type s: str
:rtype: List[List[str]]
"""
def search(s,i,path,res):
if i==len(s):
res.append(path[:])
return
if len(path)>=1 and path[-1]==s[i]:
a=path[-1]
c=a+a
path[-1]=c
search(s,i+1,path,res)
path[-1]=a
if len(path)>1 and path[-2]==s[i]:
a,b=path[-2:]
path.pop()
c=a+b+a
path[-1]=c
search(s,i+1,path,res)
path[-1]=a
path.append(b)
path.append(s[i])
search(s,i+1,path,res)
path.pop()
path=[]
res=[]
search(s,0,path,res)
return res
class Solution(object):
def partition(self, s):
"""
:type s: str
:rtype: List[List[str]]
"""
l = len(s)
matrix = [[False for _ in range(l)] for _ in range(l)]
ans = [[[]]] + [[] for _ in range(l)]
for i in range(l):
for j in range(i+1):
if (s[j] == s[i]) and ((j + 1 > i - 1) or matrix[j+1][i-1]):
matrix[j][i] = True
for k in ans[j]:
tmp = k + [s[j: i+1]]
ans[i+1].append(tmp)
return ans[-1]
总结:
dfs算法
单词搜索Ⅱ
Given a 2D board and a list of words from the dictionary, find all words in the board.
Each word must be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once in a word.
Example:
Input: words =["oath","pea","eat","rain"]
and board = [ ['o','a','a','n'], ['e','t','a','e'], ['i','h','k','r'], ['i','f','l','v'] ] Output:["eat","oath"]
Code(By myself):
class Trie(object):
def __init__(self,value):
self.value = value
self.children = {}
self.end = False
class Solution(object):
def findWords(self, board, words):
"""
:type board: List[List[str]]
:type words: List[str]
:rtype: List[str]
"""
res = []
if not board or not words:
return res
root = Trie(None)
def builtTrie(root,word):
temp = root
for i in word:
if i in temp.children:
temp = temp.children[i]
else:
node = Trie(i)
temp.children[i] = node
temp = node
temp.end = True
def search(board,root,i,j,result):
result += board[i][j]
if root.end:
res.append(result)
if not root.children:
return
val = board[i][j]
board[i][j] = 'F'
if i > 0 and board[i-1][j] in root.children:
search(board,root.children[board[i-1][j]],i-1,j,result)
if i < len(board)-1 and board[i+1][j] in root.children:
search(board,root.children[board[i+1][j]],i+1,j,result)
if j > 0 and board[i][j-1] in root.children:
search(board,root.children[board[i][j-1]],i,j-1,result)
if j < len(board[0])-1 and board[i][j+1] in root.children:
search(board,root.children[board[i][j+1]],i,j+1,result)
board[i][j] = val
return
for word in words:
builtTrie(root,word)
for i in range(len(board)):
for j in range(len(board[0])):
if board[i][j] in root.children:
result = ''
search(board,root.children[board[i][j]],i,j,result)
return list(set(res))
Code(others):
class Solution(object):
def findWords(self, board, words):
"""
:type board: List[List[str]]
:type words: List[str]
:rtype: List[str]
"""
if not board:
return False
# 构建Trie树
trie = {}
for w in words:
t = trie
for c in w:
if c not in t:
t[c] = {}
t = t[c]
t['#'] = '#'
# DFS
self.res = set()
self.visited = [ [False] * len(board[0]) for i in range(len(board))]
for i in range(len(board)):
for j in range(len(board[0])):
self.DFS(board, i, j, trie, '')
return list(self.res)
def DFS(self, board, i, j, trie, pre):
# 所有字母都存在
if '#' in trie:
self.res.add(pre)
if i < 0 or i >= len(board) or j < 0 or j >= len(board[0]):
return
if not self.visited[i][j] and board[i][j] in trie:
tmp = board[i][j] # 第一个字母匹配,接着判断剩下的
self.visited[i][j] = True # 代表已经访问过哦
self.DFS(board, i + 1, j, trie[tmp], pre + tmp)
self.DFS(board, i - 1, j, trie[tmp], pre + tmp)
self.DFS(board, i, j + 1, trie[tmp], pre + tmp)
self.DFS(board, i, j - 1, trie[tmp], pre + tmp)
self.visited[i][j] = False
总结:
为单词表建立前缀树Trie,再在字典之中匹配,可以参考单词搜索Ⅰ,dfs算法和kahn算法,实现的是dfs算法
删除无效括号
Remove the minimum number of invalid parentheses in order to make the input string valid. Return all possible results.
Note: The input string may contain letters other than the parentheses (
and )
.
Example:
Input: "()())()" Output: ["()()()", "(())()"]
Code(By myself):
class Solution(object):
def removeInvalidParentheses(self, s):
"""
:type s: str
:rtype: List[str]
"""
res = []
if not s:
return ['']
def count(s):
right = 0
left = 0
for i in s:
if i == '(':
left += 1
if left == 0:
if i == ')':
right += 1
else:
if i == ')':
left -= 1
return [left,right]
def isInvalid(s):
stark = []
for i in s:
if i == '(':
stark.append('(')
if i == ')':
if not stark:
return False
else:
stark.pop()
if stark:
return False
else:
return True
def delete(s,start,left,right):
if left == 0 and right == 0:
if isInvalid(s):
res.append(s)
return
for i in range(start,len(s)):
if i != start and s[i] == s[i-1]:
continue
if left > 0 and s[i] == '(':
delete(s[:i]+s[i+1:],i,left-1,right)
if right > 0 and s[i] == ')':
delete(s[:i]+s[i+1:],i,left,right-1)
num = count(s)
delete(s,0,num[0],num[1])
return
Code(others):
class Solution(object):
def __init__( self ) :
self._result = []
def removeValid(self, s, last_i, last_j, keys ) :
'''
@s : string for target
@last_i : 上一次统计的开始位置
@last_j : 上一次删除的位置
@keys : ('(', ')') 先匹配左号 ( ')','(' ) 先匹配右括号
'''
cnt = 0
i = last_i
#统计keys[0]
while i < len( s ) :
if s[i] == keys[0] : cnt += 1
elif s[i] == keys[1] : cnt -= 1
#keys[0] 数量大于等于 keys[1] 不进行字符串删除操作 需要做反向统计
if cnt >= 0 :
i += 1
continue
j = last_j
while j <= i :
#删除符合条件的括号 比如 ())) ---> 只需删除第一个右括号的就可以了 后面的不用再操作 或者 当前删除字符就是第一个需要删除字符
if keys[1] == s[j] and ( j == last_j or s[j] != s[j-1] ) :
newString = s[:j] + s[j+1:]
#print( newString, i, j ,"new string ")
self.removeValid(newString, i, j, keys )
j += 1
return
newString = s[::-1]
if keys[0] == '(' :
self.removeValid(newString, 0, 0, (')','(') )
#反转后的结果
else : self._result.append( newString )
def removeInvalidParentheses(self, s):
"""
:type s: str
:rtype: List[str]
"""
self.removeValid( s, 0, 0, ('(',')' ) )
return self._result
总结:
三种方法,可参考https://www.cnblogs.com/grandyang/p/4944875.html
通配符匹配
Given an input string (s
) and a pattern (p
), implement wildcard pattern matching with support for '?'
and '*'
.
Example:
Input: s = "aa" p = "a" Output: false Explanation: "a" does not match the entire string "aa".
Input: s = "adceb" p = "*a*b" Output: true Explanation: The first '*' matches the empty sequence, while the second '*' matches the substring "dce".
Code(By myself):
class Solution(object):
def isMatch(self, s, p):
"""
:type s: str
:type p: str
:rtype: bool
"""
sBegin = None
pBegin = None
i = 0
j = 0
while i < len(s):
if j < len(p) and (s[i] == p[j] or p[j] == '?'):
i += 1
j += 1
elif j < len(p) and p[j] == '*':
sBegin = i
pBegin = j
j += 1
elif pBegin != None:
sBegin += 1
i = sBegin
j = pBegin
else:
return False
while j < len(p) and p[j] == '*':
j += 1
return j == len(p)
Code(others):
class Solution(object):
def isMatch(self, s, p):
"""
:type s: str
:type p: str
:rtype: bool
"""
si, pi = 0, 0;
sn, pn = len(s), len(p)
while pn > 0 and p[pn-1]!='*' :
if sn>0 and pn>0 and (s[sn-1]==p[pn-1] or p[pn-1]=='?'):
sn -= 1
pn -= 1
else:
return False
while si<sn:
if pi==pn : return False
if s[si]==p[pi] or p[pi]=='?':
si += 1
pi += 1
continue
if p[pi]=='*':
while pi<pn and p[pi]=='*': pi+=1
if pi==pn: return True
# find block
ppos = pi
while ppos<pn and (p[ppos]!='*'and p[ppos]!='?'): ppos+=1
while si<sn and pi<pn:
i, j = si, pi
if s[i]!=p[j] and p[j]!='?' :
si += 1
continue
while i<sn and j<pn and (s[i]==p[j] or p[j]=='?'):
i += 1
j += 1
if i==sn or j==pn or p[j]=='*':
si = i
pi = j
break
else:
si += 1
else: return False
while pi < pn and p[pi]=='*': pi+=1
if pi == pn : return True
else : return False
总结:
可使用贪心算法,遇到*记录其位置,从匹配0个开始往上加匹配个数,若匹配失败返回并多匹配一个字符
正则表达式匹配
Given an input string (s
) and a pattern (p
), implement regular expression matching with support for '.'
and '*'
.
'.' Matches any single character. '*' Matches zero or more of the preceding element.
The matching should cover the entire input string (not partial).
Note:
s
could be empty and contains only lowercase lettersa-z
.p
could be empty and contains only lowercase lettersa-z
, and characters like.
or*
.
Example:
Input: s = "aa" p = "a" Output: false Explanation: "a" does not match the entire string "aa".
Input: s = "aa" p = "a*" Output: true Explanation: '*' means zero or more of the precedeng element, 'a'. Therefore, by repeating 'a' once, it becomes "aa".
Code(By myself):
class Solution(object):
def isMatch(self, s, p):
"""
:type s: str
:type p: str
:rtype: bool
"""
i = 0
if not p:
return (not s)
if (1 < len(p) and p[1] != '*') or len(p) == 1:
if i < len(s) and (s[i] == p[0] or p[0] == '.'):
return self.isMatch(s[i+1:],p[1:])
elif len(p) > 1 and p[1] == '*':
while i < len(s) and (s[i] == p[0] or p[0] == '.'):
if self.isMatch(s[i:],p[2:]):
return True
i += 1
return self.isMatch(s[i:],p[2:])
return False
Code(others):
class Solution(object):
def isMatch(self, text, pattern):
"""
:type s: str
:type p: str
:rtype: bool
"""
dp = [[False] * (len(pattern) + 1) for _ in range(len(text) + 1)]
dp[-1][-1] = True
for i in range(len(text), -1, -1):
for j in range(len(pattern) - 1, -1, -1):
first_match = i < len(text) and pattern[j] in {text[i], '.'}
if j+1 < len(pattern) and pattern[j+1] == '*':
dp[i][j] = dp[i][j+2] or first_match and dp[i+1][j]
else:
dp[i][j] = first_match and dp[i+1][j+1]
return dp[0][0]
总结:
利用空间换时间,dp[i][j]用来存储是s[i]和p[j]之后的部分是否能够匹配上。