递归和迭代、二叉树--刷题笔记(一)

一、极基础的迭代和递归

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值