Python剑指offer打卡-6
二叉树中和为某一值的路径
-
问题描述
问题描述: 输入一颗二叉树的根节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树 的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数 组靠前). 解决方案: 递归 注意: 路径表示为根结点到叶子结点的全路径
-
代码(解题思路)
class Solution: def FindPath(self, root, expectNumber): if root is None: return [] res = [] if root.val == expectNumber and root.left is None and root.right is None: res.append(root.val) left = self.FindPath(root.left, expectNumber - root.val) right = self.FindPath(root.right, expectNumber - root.val) for path in left + right: # 向上添加路径 res.append([root.val] + path) return res
判断是否是二叉搜索树的后序遍历序列结果
-
问题描述
问题描述: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes, 否则输出No。假设输入的数组的任意两个数字都互不相同。 解决方案: BST:整体上应该保证结点数值右大左小 递归 注意: 即:空列表也空树的结果 if []: return True
-
代码
图解
class Solution: def VerifySquenceOfBST(self, sequence): # write code here if not sequence: return False def isTree(sequence): """判断是否为搜索树""" root = sequence[-1] length = len(sequence) # 左小右大原则 # 左子树 for i in range(length): if sequence[i] > root: break left = True # 右子树 for j in range(i, length - 1): if sequence[j] < root: return False right = True # 递归遍历 if i > 0: left = isTree(sequence[:i]) if i < length - 1: right = isTree(sequence[i: length - 1]) return left and right return isTree(sequence)
从上往下打印二叉树
-
问题描述
问题描述: 从上往下打印出二叉树的每个节点,同层节点从左至右打印 解决方案: 简单的层序遍历
-
代码
图解
class Solution: def levelOrder(self, root: TreeNode) -> List[int]: """"层序遍历""" if not root: return [] res, queue = [], collections.deque() queue.append(root) while queue: node = queue.popleft() res.append(node.val) if node.left: queue.append(node.left) if node.right: queue.append(node.right) return res def levelOrder(self, root): """层序遍历(每一层遍历)""" if root is None: return [] res, deque = [], collections.deque() deque.append(root) while deque: tmp = [] for _ in range(len(deque)): node = deque.popleft() tmp.append(node.val) if node.left: deque.append(node.left) if node.right: deque.append(node.right) res.append(tmp) rerurn res def levelOrder(self, root: TreeNode) -> List[List[int]]: """Z字形遍历""" if not root: return [] res, deque = [], collections.deque([root]) while deque: tmp = collections.deque() for _ in range(len(deque)): node = deque.popleft() # 从左向右遍历 if len(res) % 2: tmp.appendleft(node.val) # 偶数层,队列首部 else: tmp.append(node.val) # 奇数层,队列尾部 if node.left: deque.append(node.left) if node.right: deque.append(node.right) res.append(list(tmp)) return res
最小的k个数
-
问题描述
问题描述: 输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字, 则最小的4个数字是1、2、3、4。
-
代码(解题思路)
图解最大堆
import heapq # 默认构建最小堆,即父节点的值大于其任意子节点的值 class Solution: def getLeastNumbersfForHeap(self, arr, k): """"获取最小k个数字""" if k == 0: return list() # 构建最大堆 hp = [-x for x in arr[:k]] heapq.heapify(hp) for i in range(k, len(arr)): if hp[0] <= -arr[i]: heapq.heappop(hp) heapq.heappush(hp, -arr[i]) res = [-x for x in hp] return res def getLeastNumbersForSort(self, numbs, k): def quickSort(nums, start, end): """"快速排序法""" if start >= end: return list() low = start high = end mid = nums[start] while low < high: while low < high and nums[high] >= mid: high -= 1 nums[low] = nums[high] while low < high and nums[low] < mid: low += 1 nums[high] = nums[low] # 交换基准 nums[low] = mid quickSort(nums, start, low - 1) quickSort(nums, low + 1, end) quickSort(numbs, 0, len(numbs) - 1) return numbs[:k]
数据流中的中位数
-
问题描述
问题描述: 中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。 例如: [2,3,4] 的中位数是 3 [2,3] 的中位数是 (2 + 3) / 2 = 2.5
-
代码(解题思路)
import heapq class Solution: def __init__(self): """初始化最大最小堆""" self.max_heap = [] self.min_heap = [] def addNum(self, num: int) -> None: """添加元素""" # 相等保证最小堆个数大于等于最大堆(最大相差一个) # 最大堆->最小堆 —>最大堆 if len(self.max_heap) == len(self.min_heap): heapq.heappush(self.min_heap, -heapq.heappushpop(self.max_heap, -num)) else: heapq.heappush(self.max_heap, -heapq.heappushpop(self.min_heap, num)) def findMedian(self) -> float: if len(self.min_heap) == len(self.max_heap): return (-self.max_heap[0] + self.min_heap[0]) / 2 else: return self.min_heap[0]