Python剑指offer打卡-6

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
    
  • 代码

    图解

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cwk0eElX-1619654842819)(./imgs/BFS.png)]

    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)
    

从上往下打印二叉树

  • 问题描述

    问题描述:
    从上往下打印出二叉树的每个节点,同层节点从左至右打印
    
    解决方案:
    简单的层序遍历
    
  • 代码

    图解

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jcKMbT54-1619654842823)(./imgs/层序遍历.png)]

    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。
    
  • 代码(解题思路

    图解最大堆

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pzgbX1vb-1619654842826)(./imgs/最大堆.gif)]

    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]
    

参考

最大最小堆整理 & heapq最小最大堆

数据结构与算法(4)——优先队列和堆

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值