文章目录
一、极基础的迭代和递归
344 反转字符串
Easy
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。
示例 1:
输入:[“h”,“e”,“l”,“l”,“o”]
输出:[“o”,“l”,“l”,“e”,“h”]
示例 2:
输入:[“H”,“a”,“n”,“n”,“a”,“h”]
输出:[“h”,“a”,“n”,“n”,“a”,“H”]
双指针用迭代的话非常简单(solution 1),如果非要写成递归形式的话,注意,不要每次对子函数输入s1=s[1:len(s)-1],交换首尾元素,因为这样交换的值是另外的s1的首尾值,而并不作用到s上。所以对递归子函数,输入固定是s,和变动的两个指针。
p.s.二者的速度都慢,200ms+。
Slution1 迭代
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
if not s or len(s)==1:
return
l,r= 0,len(s)-1
while l<r:
s[l],s[r]=s[r],s[l]
l+=1
r-=1
Slution2 递归
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
def helper(s,l,r):
if l==r or l-1==r:
return s
else:
s[l],s[r]=s[r],s[l]
l+=1
r-=1
helper(s,l,r)
return helper(s,0,len(s)-1)
#interative
def sumOfLeftLeaves(self, root):
"""
:type root: TreeNode
:rtype: int
"""
if not root:
return 0
sum = 0
node = [root] #存放节点
while node:
cur = node.pop(0) #当前节点
if cur.left:
if not cur.left.left and not cur.left.right:
sum += cur.left.val
else:
node.append(cur.left)
if cur.right:
node.append(cur.right)
return sum
#recusive
def sumOfLeftLeaves(self, root):
"""
:type root: TreeNode
:rtype: int
"""
if not root:
return 0
sum = 0
if root.left and not root.left.left and not root.left.right:
sum += root.left.val
sum += self.sumOfLeftLeaves(root.left)
sum += self.sumOfLeftLeaves(root.right)
return sum
二、二叉树的遍历(前序、中序、后序)
144. Binary Tree Preorder Traversal
Medium
Given a binary tree, return the preorder traversal of its nodes’ values.
Example:
Input: [1,null,2,3]
1
\
2
/
3
Output: [1,2,3]
Follow up: Recursive solution is trivial, could you do it iteratively?
Slution1 递归
Slution2 迭代
# recursively
def preorderTraversal1(self, root):
res = []
self.dfs(root, res)
return res
def dfs(self, root, res):
if root:
res.append(root.val)
self.dfs(root.left, res)
self.dfs(root.right, res)
# iteratively
def preorderTraversal(self, root):
stack, res = [root], []
while stack:
node = stack.pop()
if node:
res.append(node.val)
stack.append(node.right)
stack.append(node.left)
return res
94. Binary Tree Inorder Traversal
Medium
Given a binary tree, return the inorder traversal of its nodes’ values.
Example:
Input: [1,null,2,3]
1
\
2
/
3
Output: [1,3,2]
Follow up: Recursive solution is trivial, could you do it iteratively?
# recursively
def inorderTraversal1(self, root):
res = []
self.helper(root, res)
return res
def helper(self, root, res):
if root:
self.helper(root.left, res)
res.append(root.val)
self.helper(root.right, res)
# iteratively
def inorderTraversal(self, root):
res, stack = [], []
while True:
while root:
stack.append(root)
root = root.left
if not stack:
return res
node = stack.pop()
res.append(node.val)
root = node.right
145. Binary Tree Postorder Traversal
Hard
Given a binary tree, return the postorder traversal of its nodes’ values.
Example:
Input: [1,null,2,3]
1
\
2
/
3
Output: [3,2,1]
Follow up: Recursive solution is trivial, could you do it iteratively?
Slution1 递归
Slution2 迭代
# recursively
def postorderTraversal1(self, root):
res = []
self.dfs(root, res)
return res
def dfs(self, root, res):
if root:
self.dfs(root.left, res)
self.dfs(root.right, res)
res.append(root.val)
# iteratively1
class Solution:
def postorderTraversal(self, root):
traversal, stack = [], [(root, False)]
while stack:
node, visited = stack.pop()
if node:
if visited:
# add to result if visited
traversal.append(node.val)
else:
# post-order
stack.append((node, True))
stack.append((node.right, False))
stack.append((node.left, False))
return traversal
# iteratively2(前序遍历取反,实在想不出来了写这个)
def postorderTraversal(self, root):
res, stack = [], [root]
while stack:
node = stack.pop()
if node:
res.append(node.val)
stack.append(node.left)
stack.append(node.right)
return res[::-1]
三、DFS和BFS的迭代写法
DFS和BFS的迭代写法,
二叉树的迭代总用栈。
一个简单的例子e.g:
111. 二叉树的最小深度
Easy
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7]
Slution
# DFS递归,最简单也最慢
def minDepth1(self, root):
if not root:
return 0
if None in [root.left, root.right]:
return max(self.minDepth(root.left), self.minDepth(root.right)) + 1
else:
return min(self.minDepth(root.left), self.minDepth(root.right)) + 1
# DFS迭代
def minDepth(self, root):
if not root:
return 0
# res can be set as max_int
res, stack = 9999, [(root, 1)]
while stack:
node, level = stack.pop()
if node and not node.left and not node.right:
res = min(res, level)
if node:
stack.append((node.left, level+1))
stack.append((node.right, level+1))
return res
# BFS迭代,推荐
def minDepth(self, root):
if not root:
return 0
queue = collections.deque([(root, 1)])
while queue:
node, level = queue.popleft()
if node:
if not node.left and not node.right:
return level
else:
queue.append((node.left, level+1))
queue.append((node.right, level+1))
429 N叉树的层次遍历
迭代写法容易,注意递归写法
迭代
#iterative
"""
# Definition for a Node.
class Node:
def __init__(self, val, children):
self.val = val
self.children = children
"""
class Solution:
def levelOrder(self, root: 'Node') -> List[List[int]]:
if not root:
return []
level,ans=[root],[]
while level:
ans.append([node.val for node in level])
tmp=[]
for node in level:
if node.children:
tmp.extend(node.children)
level = tmp
return ans
递归
#recursive
class Solution(object):
def levelOrder(self, root):
self.res = []
if not root: return self.res
def helper(root, level):
if root:
if len(self.res) <= level:
self.res.append([])
self.res[level].append(root.val)
for child in root.children:
helper(child, level +1)
helper(root, level = 0)
return self.res