144题 二叉树的前序遍历
之前都是递归做的,很好理解,直接return。这里要求用迭代算法做。这个答案也是官方题解的python答案,翻了好多发现这个最好理解...
1. 左子树value逐步推入答案,以推完作为循环结束条件,登记每一个根节点、左value的左子树;
2. 对于以上的左子树们按照从远到近的距离和依然从左到右的顺序对其右子树进行循环。距离优先级使用临时栈pop来实现,很巧妙!
3. 以临时栈的全部推入作为退出大循环的条件。
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
if not root: return []
result = []
stack = []
node = root
while stack or node:
while node:
result.append(node.val)
stack.append(node)
node = node.left
node = stack.pop()
node = node.right
return result
145题 二叉树的后序遍历
1. [root]作为一个元素,pop出来第一个就是它,根节点存入result;
2. 先左再右将子树从近到远放进临时栈。就会按照从右到左的顺序pop出子树,将逐个节点存入result,result就会是中右左+近到远,翻转即可。
class Solution:
def postorderTraversal(self, root: TreeNode) -> List[int]:
if not root: return []
result = []
s = [root]
while s:
node = s.pop()
result.append(node.val)
if node.left:
s.append(node.left)
if node.right:
s.append(node.right)
return result[::-1]
108题 有序数组转换为二叉搜索树
选择地板除中间值作为根节点,子树逐次递归。要注意一个地方:if nums必不可少。在nums存时再进行操作,否则会报各种奇怪的错。(主要是IndexError)
class Solution:
def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
if nums:
mid = len(nums) // 2
root = TreeNode(nums[mid])
root.left = self.sortedArrayToBST(nums[0:mid])
root.right = self.sortedArrayToBST(nums[mid+1:])
return root
110题 平衡二叉树
肯定是要用递归的,递归本身判断balance的函数是从顶到底,这样时间复杂度比较高。
class Solution:
def isBalanced(self, root: TreeNode) -> bool:
def treedepth(root):
if not root: return 0
return 1 + max(treedepth(root.left), treedepth(root.right))
if not root: return True
return abs(treedepth(root.left) - treedepth(root.right)) <= 1 and self.isBalanced(root.left) and self.isBalanced(root.right)
也可以递归判断高度的函数,在函数里定下条件要求:一旦出现了绝对值>1就return大函数的false同等条件。(这个题解来源于官方题解下的一个用户Halo的热评。)
每一个节点的左右子树都判断一次,失败时直接反映到最终result
class Solution:
def isBalanced(self, root: TreeNode) -> bool:
def judge_treedepth(root):
if not root: return 0
left_depth = judge_treedepth(root.left)
right_depth = judge_treedepth(root.right)
if abs(left_depth - right_depth) > 1:
result[0] = False
return 1 + max(left_depth, right_depth)
result = [True]
judge_treedepth(root)
return result[0]
112题 路径总和
DFS算法 深度优先搜索,尽可能深的搜索树的分支。递归简单,一定是体现左右孩子不存在的条件下,和等于目标值才算数。
class Solution:
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
if not root: return False
if not root.left and not root.right:
return root.val == targetSum
return self.hasPathSum(root.left, targetSum - root.val) or self.hasPathSum(root.right, targetSum - root.val)
栈 DFS的迭代算法。把路径和节点同时保存。(来自用户 负雪明烛 题解。)这个题始终记得是要遍历到最深处的叶子节点(即节点的左右子树都不存在)并且当和等于目标值,条件成立时返回True
class Solution:
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
if not root: return False
stack = []
stack.append((root, root.val))
while stack:
node, path = stack.pop()
if not node.left and not node.right and path == targetSum:
return True
if node.right:
stack.append((node.right, path + node.right.val))
if node.left:
stack.append((node.left, path + node.left.val))
return False #遍历完还没能返回True即返回Fasle
二叉树这边的题做了三四天,其实根本上套路是一样的,在这个过程中细致的了解,还是要反复再去做做体会其中的算法,主要是DFS,递归以及思路上写算法问题都有点长进