class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
res = 0
def dfs(i, j):
if i<0 or i>=len(grid) or j<0 or j>=len(grid[0]) or grid[i][j]!="1": return
grid[i][j] = '0'
dfs(i+1, j)
dfs(i-1, j)
dfs(i, j+1)
dfs(i, j-1)
for i in range(len(grid)):
for j in range(len(grid[0])):
if grid[i][j] == '1':
res = res+1
dfs(i, j)
return res
301. Remove Invalid Parentheses
Brute Force
each parenthese can exist or not -> see if becomes valid:O(2^n)
怎样优化Pruning?
1.每个左括号会先出现于右括号:从左向右累计括号数,左括号数应该大于右括号数;小于则停止?
2.不大于min_count
DFS + Pruning
class Solution:
def __init__(self):
self.res = None
self.min_count = None
def reset(self):
self.res = set()
self.min_count = float("inf")
def removeInvalidParentheses(self, s: str) -> List[str]:
self.reset()
self.helper(s, 0, 0, 0, 0)
return list(self.res)
def helper(self, string, pos, left, right, count):
if len(string)==pos:
if left==right:
if count<self.min_count:
self.res = set([string])
self.min_count=count
elif count==self.min_count:
self.res.add(string)
return
elif right>left or count>self.min_count:
return
else:
if string[pos]!='(' and string[pos]!=')':
self.helper(string, pos+1, left, right, count)
else:
if string[pos]=='(':
self.helper(string, pos+1, left+1, right, count)
self.helper(string[:pos]+string[pos+1:], pos, left, right, count+1)
else:
self.helper(string, pos+1, left, right+1, count)
self.helper(string[:pos]+string[pos+1:], pos, left, right, count+1)
BFS + Pruning
class Solution:
def removeInvalidParentheses(self, s: str) -> List[str]:
ans = []
queue = collections.deque([s])
done = False
visited = set([s])
while queue:
t = queue.popleft()
mi = self.cal(t)
if mi==0:
done = True
ans.append(t)
if done:
continue
for i in range(len(t)):
if t[i] not in ['(', ')']:
continue
s = t[:i]+t[i+1:]
if s not in visited and self.cal(s)<mi:
queue.append(s)
visited.add(s)
return ans
def cal(self, string):
a = b = 0
for c in string:
a += {'(':1, ')':-1}.get(c, 0)
b += a<0
a = max(a, 0)
return a+b
BFS - 变形
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def isSymmetric(self, root: TreeNode) -> bool:
if not root: return True
row = [root.left, root.right]
while row:
row_temp = []
l = 0
r = len(row)-1
while l<r:
if row[l] and row[r]:
if row[l].val!=row[r].val:
return False
elif row[l] or row[r]:
return False
mid = int(len(row_temp)/2)
ll = [row[l].left, row[l].right] if row[l] else []
rr = [row[r].left, row[r].right] if row[r] else []
row_temp = row_temp[:mid]+ll+rr+row_temp[mid:]
l += 1
r -= 1
row = row_temp
return True
102. Binary Tree Level Order Traversal
iterative
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
if not root: return []
res = []
queue = collections.deque([root])
while queue:
row = []
size = len(queue)
for i in range(size):
t = queue.popleft()
row.append(t.val)
if t.left:
queue.append(t.left)
if t.right:
queue.append(t.right)
res.append(row)
return res
recursive
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
res = []
self.helper(root, 0, res)
return res
def helper(self, node, level, res):
if not node: return
if len(res)==level:
res.append([])
res[level].append(node.val)
self.helper(node.left, level+1, res)
self.helper(node.right, level+1, res)
无论是求最短路径长度还是求所有最短路径,都是用BFS。在BFS中有三个关键步骤需要实现:
1. 如何找到与当前节点相邻的所有节点。
2. 如何标记一个节点已经被访问过,以避免重复访问。
3. 一旦BFS找到目标单词,如何backtracking找回路径?
class Solution:
def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
wordDict = set(wordList)
if not endWord in wordDict: return 0
queue = collections.deque([beginWord])
res = 1
while queue:
size = len(queue)
for i in range(size): #each word
w = queue.popleft()
for j in range(len(w)): #each character
for c in string.ascii_lowercase:
temp = w[:j]+c+w[j+1:]
if temp == endWord: return res+1
if temp in wordDict:
queue.append(temp)
wordDict.remove(temp)
res += 1
return 0;