python_ACM模式《剑指offer刷题》二叉树2

题目:

面试tips:

面试官有可能问到:

如果你需要频繁地查找第 k 小的值,你将如何优化算法?(见思路三)

思路:

思路一:二叉搜索树最大的特点就是中序遍历是递增的。因此最容易想到的是对二叉树进行中序遍历存入数组中,再遍历数组至第k个数,就是二叉树的第k小的数/节点。这样的时间复杂度就是O(N+K),空复为O(N)。显然不是最优。

思路二:在思路一的基础上不采用数组,直接对二叉搜索树进行中序遍历,在遍历的过程中目标是找到第k个小的节点。此时因为是中序要先遍历到最左节点后再退回遍历k个,因此最理想(即二叉搜索树为平衡二叉树)的时复为O(logN+K),最不理想(此二叉搜索树没有右子树)才达到O(N+K),此方法需要用到栈或递归(因为其遍历到的节点并不处理,它要遍历到最左节点再从最左节点开始处理,是一个后进先出的处理思想)因此需要用到递归或栈,因此空复最理想为O(logN),最不理想为O(N). 已经比思路一好很多了。

思路三:虽然思路二已经好很多,且觉得应付大部分面试应该没问题。但如果需要频繁查找第k小的值,要如何优化?(这是从leetcode上看来的)觉得有点意思。这个思路是如果能知道以node为根节点的子树有多少个节点(假设存为了一个字典node_count),则起初node = root。如果node_count[node] < k-1, 则等价于找node.right的第k - (left + 1)个节点;如果node_count[node] == k-1, 则node即为第k个节点;如果node_count[node] > k-1, 则等价于找node.left的第k个节点,一直下去直至找到为止。显然这里就需要预处理node_count,遍历整颗二叉搜索树,统计以每个节点node为根节点的子树的节点个数存入字典中,时复O(N), 空复O(N). 后多次查询第k小的节点时时复最理解为O(logN),最不理想为O(N).

代码实现:

思路一略

思路二的迭代法:

class TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = rightdef arr2tree(arr, index):# 满二叉树数组格式构造二叉树# 构造arr[index]的二叉树# 满二叉树数组格式: 是指首先按层序遍历顺序,且二叉树的非空节点的左右孩子(尽管为空)都会打印出来,空节点的左右孩子则不打印if index >= len(arr) or arr[index] == None:return Noneroot = TreeNode(val = arr[index])left = arr2tree(arr, 2 * index + 1)right = arr2tree(arr, 2 * index + 2)root.left = leftroot.right = rightreturn rootclass Solution:def kthSmallest(self, root, k) :# 刚才中序遍历递归法查找# 现用中序遍历的迭代法查找第k小的数# 题中说明没有非空的情况 因此不对非空进行处理stack = [root]while stack:node = stack.pop()if node:# 如果不是空 说明第一次遍历至此,用None标记是第二次遍历到此时才开始处理# 中序 为左中右,因此存入栈中是右中左if node.right:stack.append(node.right)stack.append(node)stack.append(None)if node.left:stack.append(node.left)else:node = stack.pop()# 每遇到一个None时 说明这个节点被遍历第二次了 即开始处理了k -= 1if k == 0:return node.valif __name__ == '__main__':arr = [5, 3, 6, 2, 4, None, None, 1]k = 3root = arr2tree(arr, 0)a = Solution()print(a.kthSmallest(root, k))  # 3

思路二的递归法:

class TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = rightdef arr2tree(arr, index):# 满二叉树数组格式构造二叉树# 构造arr[index]的二叉树# 满二叉树数组格式: 是指首先按层序遍历顺序,且二叉树的非空节点的左右孩子(尽管为空)都会打印出来,空节点的左右孩子则不打印if index >= len(arr) or arr[index] == None:return Noneroot = TreeNode(val = arr[index])left = arr2tree(arr, 2 * index + 1)right = arr2tree(arr, 2 * index + 2)root.left = leftroot.right = rightreturn rootclass Solution:def __init__(self):# 初始化全局变量,这里让self.k作为全局变量是想找整棵树上第k小的数self.k = -1self.result = -1def kthSmallest(self, root, k: int):# 直接在二叉树中找第k小的元素def dfs(root):# 找以root为根节点的第k小的数,找到就【更新】self.result并返回,此函数只需更新因此不用返回值# 终止条件if not root:return# 单层dfs(root.left)self.k -= 1if self.k == 0:self.result = root.valdfs(root.right)self.k = kdfs(root)return self.resultif __name__ == '__main__':arr = [5, 3, 6, 2, 4, None, None, 1]k = 3root = arr2tree(arr, 0)a = Solution()print(a.kthSmallest(root, k))

思路三:

class TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = rightdef arr2tree(arr, index):# 满二叉树数组格式构造二叉树# 构造arr[index]的二叉树# 满二叉树数组格式: 是指首先按层序遍历顺序,且二叉树的非空节点的左右孩子(尽管为空)都会打印出来,空节点的左右孩子则不打印if index >= len(arr) or arr[index] == None:return Noneroot = TreeNode(val = arr[index])left = arr2tree(arr, 2 * index + 1)right = arr2tree(arr, 2 * index + 2)root.left = leftroot.right = rightreturn rootclass pre_do:def __init__(self, root):self.root = rootself.count_node = {}self.cal_count_node(root)def cal_count_node(self, node):# 得到预处理好的self.count_node字典--后序遍历# 统计以子树中某个节点 为根节点的子树的节点个数# 注意这里如果node为空是不会被存到字典中,因此后面get时要对空作特殊处理if not node:return 0self.count_node[node] = 1 + self.cal_count_node(node.left) + self.cal_count_node(node.right)return self.count_node[node]def get_count_node(self, node):return self.count_node[node] if node else 0def find_kthSmallest(self, k):node = self.rootwhile node:left_count = self.get_count_node(node.left)if left_count < k - 1:node = node.rightk -= left_count + 1elif left_count == k - 1:return node.valelse:node = node.leftclass Solution:def kthSmallest(self, root, k: int) -> int:result = pre_do(root)return result.find_kthSmallest(k)if __name__ == '__main__':arr = [5, 3, 6, 2, 4, None, None, 1]k = 3root = arr2tree(arr, 0)a = Solution()print(a.kthSmallest(root, k))  # 3

参考资料:

1. 《剑指offer》

2. 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/677259.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯每日一题------背包问题(一)

背包问题 阅读小提示&#xff1a;这篇文章稍微有点长&#xff0c;希望可以对背包问题进行系统详细的讲解&#xff0c;在看的过程中如果有任何疑问请在评论区里指出。因为篇幅过长也可以进行选择性阅读&#xff0c;读取自己想要的那一部分即可。 前言 背包问题可以看作动态规…

CTFSHOW命令执行web入门29-54

description: >- 这里就记录一下ctfshow的刷题记录是web入门的命令执行专题里面的题目,他是有分类,并且覆盖也很广泛,所以就通过刷这个来,不过里面有一些脚本的题目发现我自己根本不会笑死。 如果还不怎么知道写题的话,可以去看我的gitbook,当然csdn我也转载了我自己的…

12.3 OpenGL顶点后处理:平面着色

平面着色 Flatshading Flat shading (平面着色)是一种简化渲染技术&#xff0c;它在光栅化阶段将一个图元&#xff08;primitive&#xff09;的所有顶点赋予相同的颜色或其它输出变量的值。这些赋予的值来自于该图元的“引发顶点”&#xff08;provoking vertex&#xff09;。…

幻兽帕鲁服务器怎么更新?如何快速在腾讯云更新幻兽帕鲁Palworld服务器,显示版本不兼容怎么解决

幻兽帕鲁服务器怎么更新&#xff1f;如何快速在腾讯云更新幻兽帕鲁Palworld服务器&#xff0c;显示版本不兼容怎么解决。最近的幻兽帕鲁服务器又更新了。 如何在不需要远程登录服务器的情况下&#xff0c;通过一行命令来更新幻兽帕鲁呢&#xff1f; 腾讯云轻量云一键部署幻兽…

为什么说重载发生在编译期而重写发生在运行期

为什么说重载发生在编译期而重写发生在运行期 重载发生在编译期而重写发生在运行期。具体解释如下&#xff1a; 重载&#xff08;Overloading&#xff09;&#xff1a;是在同一类中发生的&#xff0c;编译器在编译时期就能根据方法名和参数列表确定调用哪个方法。因此&#x…

Android编程权威指南(第四版)- 第 4 章 UI状态的保存与恢复

文章目录 代码&#xff1a;依赖MainActivityQuizViewModelQuestion知识点 代码&#xff1a; 大体是一样的&#xff0c;修改了一些 依赖 implementation("androidx.lifecycle:lifecycle-extensions:2.2.0")MainActivity package com.example.geoquizimport android…

今年春节,德施曼成“春晚御用”智能锁,亮相总台春晚直播间

总台春晚&#xff0c;是每年春节期间的最大热点。 今年除夕夜&#xff0c;高端智能锁品牌德施曼&#xff0c;不仅成为“春晚御用”智能锁&#xff0c;还将旗下的哨兵猫眼智能锁&#xff0c;卖到了总台春晚的直播间里。龙年春节&#xff0c;德施曼智能锁携手小红书《大家的春晚》…

金融信贷风控评分卡模型

评分卡模型概念 评分模型是根据借款人的历史数据&#xff0c;选取不同维度的数据类型&#xff0c;通过计算而得出的对借款人信用情况打分的模型。不同等级的信用分数代表了借款人信用情况的好坏&#xff0c;以此来分析借款人按时还款的可能性。 评分卡模型分类 A卡&#xff…

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 2月10日,星期六

每天一分钟&#xff0c;知晓天下事&#xff01; 2024年2月10日 星期六 农历正月初一 春节 1、 国务院&#xff1a;到2025年&#xff0c;初步建成覆盖各领域、各环节的废弃物循环利用体系。 2、 国家移民管理局&#xff1a;部分国家人员可以用更多事由免签入境海南。 3、 市场…

华为配置无线监测环境与反制

华为配置无线环境检测与反制&#xff08;WIDS/WIPS&#xff09; 组网图形 图1 配置非法设备检测和反制示例组网图 业务需求组网需求数据规划配置思路配置注意事项操作步骤配置文件 业务需求 某企业分支机构为了保证工作人员可以随时随地访问公司网络资源&#xff0c;部署WLAN基…

Spring 如何配置 bean (XML 方式)

请直接看原文:Spring 如何配置 bean (XML 方式)_spring 在哪配置bean 文件-CSDN博客 -------------------------------------------------------------------------------------------------------------------------------- Java Bean 如何配置配置到 spring 容器中 基于 XM…

css的布局(BFC)

一、css中常规的定位方案 1、普通流 元素按照其在HTML中的先后位置自上而下布局。 行内元素水平排列&#xff0c;当行被占满后换行&#xff1b;块级元素则会被渲染为完整的一行。 所有元素默认都是普通流定位。 2、浮动 元素首先按照普通流的位置出现&#xff0c; 然后根据浮动…

【ETOJ P1046】斐波那契数列 题解(数学+动态规划)

题目描述 给定一个整数 T T T&#xff0c;表示样例数。 对于每个样例&#xff0c;给定一个整数 n n n&#xff0c;求斐波那契数列的第 n n n 项。 斐波那契数列定义为 f ( 1 ) f ( 2 ) 1 f(1) f(2) 1 f(1)f(2)1&#xff0c; f ( n ) f ( n − 1 ) f ( n − 2 ) f(…

跟着cherno手搓游戏引擎【23】项目维护、2D引擎之前的一些准备

项目维护&#xff1a; 修改文件结构&#xff1a; 头文件自己改改就好了 创建2DRendererLayer&#xff1a; Sandbox2D.h: #pragma once #include "YOTO.h" class Sandbox2D :public YOTO::Layer {public:Sandbox2D();virtual ~Sandbox2D() default;virtual void O…

图神经网络与图表示学习: 从基础概念到前沿技术

目录 前言1 图的形式化定义和类型1.1 图的形式化定义1.2 图的类型 2 图表示学习2.1 DeepWalk: 融合语义相似性与图结构2.2 Node2Vec: 灵活调整随机游走策略2.3 LINE: 一阶与二阶邻接建模2.4 NetMF: 矩阵分解的可扩展图表示学习2.5 Metapath2Vec: 异构图的全面捕捉 3 图神经网络…

mysql-面试题

一、SQL语句 1、SQL语句的分类 DQL:数据查询语言—selectDML:数据操作语言—insert/update/deleteDDL:数据定义语言—create/drop/alterDCL:数据控制语言—start transaction/commit/rollback2、Sql语句的执行顺序 SQL 语句的执行顺序与编写顺序并不相同FROM、ON、JOIN、W…

【正式】今年第一篇CSDN(纯技术教学)

一、文件上传简介 文件上传漏洞是指用户上传了一个可执行的脚本文件&#xff08;木马、病毒、恶意脚本、webshell等&#xff09;&#xff0c;并通过此脚本文件获得了执行服务器端命令的能力。上传点一般出现在头像、导入数据、上传压缩包等地方&#xff0c;由于程序对用户上传…

Ubuntu in VMware的问题

文章目录 安装单用户模式(安全模式)扩容硬盘复制粘贴必装共享文件夹在虚拟机中不显示猫孔堵塞需要通过VMware来实现重启效果后记 just 安装 下载iso文件后 安装向导中兼容性选14x 版本的VMware 后面不会出现vcpu问题 cpu 4x4 装完后启动会出现vcpu问题 重启虚拟机Ubuntu 此问题…

使用内联函数,降低函数调用开销,实现移动时绘制

easyx devc 开发。 AWSD移动&#xff0c;移动时可以左键绘制 左键绘制 左上角画笔颜色 右键拖拽 #include <graphics.h> // 使用关键字 inline 声明为内联函数&#xff0c;减少贴图函数频繁调用的开销导致的卡顿。 // 缓冲区纹理映射函数&#xff1a;bkmesh 映射目…

Python语言例题集(002)

#!/usr/bin/python3 #使用del语句删除元素 motorcycles[‘honda’,‘yamaha’,‘suzuki’] print(motorcycles) del motorcycles[0] print(motorcycles) motorcycles[‘honda’,‘yamaha’,‘suzuki’] print(motorcycles) del motorcycles[1] print(motorcycles) #使用方法po…