成都市网站备案国内网站开发 框架

web/2025/10/7 18:13:42/文章来源:
成都市网站备案,国内网站开发 框架,网站域名解析页面,asp网站目录权限优质博文#xff1a;IT-BLOG-CN 一、题目 给定一个二叉搜索树的根节点root#xff0c;和一个整数k#xff0c;请你设计一个算法查找其中第k个最小元素#xff08;从1开始计数#xff09;。 示例 1#xff1a; 输入#xff1a;root [3,1,4,null,2], k 1 输出#x…优质博文IT-BLOG-CN 一、题目 给定一个二叉搜索树的根节点root和一个整数k请你设计一个算法查找其中第k个最小元素从1开始计数。 示例 1 输入root [3,1,4,null,2], k 1 输出1 示例 2 输入root [5,3,6,2,4,null,null,1], k 3 输出3 树中的节点数为n。 1 k n 104 0 Node.val 104 进阶如果二叉搜索树经常被修改插入/删除操作并且你需要频繁地查找第 k 小的值你将如何优化算法 二、代码 【1】中序遍历 二叉搜索树具有如下性质   ● 结点的左子树只包含小于当前结点的数。   ● 结点的右子树只包含大于当前结点的数。   ● 所有左子树和右子树自身必须也是二叉搜索树。 二叉树的中序遍历即按照访问左子树——根结点——右子树的方式遍历二叉树在访问其左子树和右子树时我们也按照同样的方式遍历直到遍历完整棵树。 思路和算法 因为二叉搜索树和中序遍历的性质所以二叉搜索树的中序遍历是按照键增加的顺序进行的。于是我们可以通过中序遍历找到第k个最小元素。 class Solution {public int kthSmallest(TreeNode root, int k) {DequeTreeNode stack new ArrayDequeTreeNode();while (root ! null || !stack.isEmpty()) {while (root ! null) {stack.push(root);root root.left;}root stack.pop();--k;if (k 0) {break;}root root.right;}return root.val;} }时间复杂度 时间复杂度O(Hk)其中H是树的高度。在开始遍历之前我们需要O(H)到达叶结点。当树是平衡树时时间复杂度取得最小值O(log⁡Nk)当树是线性树树中每个结点都只有一个子结点或没有子结点时时间复杂度取得最大值O(Nk)。 空间复杂度 O(H)栈中最多需要存储H个元素。当树是平衡树时空间复杂度取得最小值O(log⁡N)当树是线性树时空间复杂度取得最大值O(N)。 【2】记录子树的结点数 如果你需要频繁地查找第k小的值你将如何优化算法 思路和算法 在方法一中我们之所以需要中序遍历前k个元素是因为我们不知道子树的结点数量不得不通过遍历子树的方式来获知。因此我们可以记录下以每个结点为根结点的子树的结点数并在查找第k小的值时使用如下方法搜索   ● 令node等于根结点开始搜索。   ● 对当前结点node进行如下操作     ○ 如果node的左子树的结点数left小于k−1则第k小的元素一定在node的右子树中令node等于其的右子结点k等于k−left−1并继续搜索     ○ 如果node的左子树的结点数left等于k−1则第k小的元素即为node结束搜索并返回node即可     ○ 如果node的左子树的结点数left大于k−1则第k小的元素一定在node的左子树中令node等于其左子结点并继续搜索。 在实现中我们既可以将以每个结点为根结点的子树的结点数存储在结点中也可以将其记录在哈希表中。 class Solution {public int kthSmallest(TreeNode root, int k) {MyBst bst new MyBst(root);return bst.kthSmallest(k);} }class MyBst {TreeNode root;MapTreeNode, Integer nodeNum;public MyBst(TreeNode root) {this.root root;this.nodeNum new HashMapTreeNode, Integer();countNodeNum(root);}// 返回二叉搜索树中第k小的元素public int kthSmallest(int k) {TreeNode node root;while (node ! null) {int left getNodeNum(node.left);if (left k - 1) {node node.right;k - left 1;} else if (left k - 1) {break;} else {node node.left;}}return node.val;}// 统计以node为根结点的子树的结点数private int countNodeNum(TreeNode node) {if (node null) {return 0;}nodeNum.put(node, 1 countNodeNum(node.left) countNodeNum(node.right));return nodeNum.get(node);}// 获取以node为根结点的子树的结点数private int getNodeNum(TreeNode node) {return nodeNum.getOrDefault(node, 0);} }时间复杂度 预处理的时间复杂度为O(N)其中N是树中结点的总数我们需要遍历树中所有结点来统计以每个结点为根结点的子树的结点数。搜索的时间复杂度为O(H)其中H是树的高度当树是平衡树时时间复杂度取得最小值O(log⁡N)当树是线性树时时间复杂度取得最大值O(N)。 空间复杂度 O(N)用于存储以每个结点为根结点的子树的结点数。 【3】平衡二叉搜索树 如果二叉搜索树经常被修改插入/删除操作并且你需要频繁地查找第k小的值你将如何优化算法 方法三需要先掌握 平衡二叉搜索树AVL树 的知识。平衡二叉搜索树具有如下性质   ● 平衡二叉搜索树中每个结点的左子树和右子树的高度最多相差1   ● 平衡二叉搜索树的子树也是平衡二叉搜索树   ● 一棵存有 nnn 个结点的平衡二叉搜索树的高度是O(log⁡n)。 思路和算法 我们注意到在方法二中搜索二叉搜索树的时间复杂度为O(H)其中H是树的高度当树是平衡树时时间复杂度取得最小值O(log⁡N)。因此我们在记录子树的结点数的基础上将二叉搜索树转换为平衡二叉搜索树并在插入和删除操作中维护它的平衡状态。 class Solution {public int kthSmallest(TreeNode root, int k) {// 中序遍历生成数值列表ListInteger inorderList new ArrayListInteger();inorder(root, inorderList);// 构造平衡二叉搜索树AVL avl new AVL(inorderList);// 模拟1000次插入和删除操作int[] randomNums new int[1000];Random random new Random();for (int i 0; i 1000; i) {randomNums[i] random.nextInt(10001);avl.insert(randomNums[i]);}shuffle(randomNums); // 列表乱序for (int i 0; i 1000; i) {avl.delete(randomNums[i]);}return avl.kthSmallest(k);}private void inorder(TreeNode node, ListInteger inorderList) {if (node.left ! null) {inorder(node.left, inorderList);}inorderList.add(node.val);if (node.right ! null) {inorder(node.right, inorderList);}}private void shuffle(int[] arr) {Random random new Random();int length arr.length;for (int i 0; i length; i) {int randIndex random.nextInt(length);int temp arr[i];arr[i] arr[randIndex];arr[randIndex] temp;}} }// 平衡二叉搜索树AVL树允许重复值 class AVL {Node root;// 平衡二叉搜索树结点class Node {int val;Node parent;Node left;Node right;int size;int height;public Node(int val) {this(val, null);}public Node(int val, Node parent) {this(val, parent, null, null);}public Node(int val, Node parent, Node left, Node right) {this.val val;this.parent parent;this.left left;this.right right;this.height 0; // 结点高度以node为根节点的子树的高度高度定义叶结点的高度是0this.size 1; // 结点元素数以node为根节点的子树的节点总数}}public AVL(ListInteger vals) {if (vals ! null) {this.root build(vals, 0, vals.size() - 1, null);}}// 根据vals[l:r]构造平衡二叉搜索树 - 返回根结点private Node build(ListInteger vals, int l, int r, Node parent) {int m (l r) 1;Node node new Node(vals.get(m), parent);if (l m - 1) {node.left build(vals, l, m - 1, node);}if (m 1 r) {node.right build(vals, m 1, r, node);}recompute(node);return node;}// 返回二叉搜索树中第k小的元素public int kthSmallest(int k) {Node node root;while (node ! null) {int left getSize(node.left);if (left k - 1) {node node.right;k - left 1;} else if (left k - 1) {break;} else {node node.left;}}return node.val;}public void insert(int v) {if (root null) {root new Node(v);} else {// 计算新结点的添加位置Node node subtreeSearch(root, v);boolean isAddLeft v node.val; // 是否将新结点添加到node的左子结点if (node.val v) { // 如果值为v的结点已存在if (node.left ! null) { // 值为v的结点存在左子结点则添加到其左子树的最右侧node subtreeLast(node.left);isAddLeft false;} else { // 值为v的结点不存在左子结点则添加到其左子结点isAddLeft true;}}// 添加新结点Node leaf new Node(v, node);if (isAddLeft) {node.left leaf;} else {node.right leaf;}rebalance(leaf);}}// 删除值为v的结点 - 返回是否成功删除结点public boolean delete(int v) {if (root null) {return false;}Node node subtreeSearch(root, v);if (node.val ! v) { // 没有找到需要删除的结点return false;}// 处理当前结点既有左子树也有右子树的情况// 若左子树比右子树高度低则将当前结点替换为右子树最左侧的结点并移除右子树最左侧的结点// 若右子树比左子树高度低则将当前结点替换为左子树最右侧的结点并移除左子树最右侧的结点if (node.left ! null node.right ! null) {Node replacement null;if (node.left.height node.right.height) {replacement subtreeFirst(node.right);} else {replacement subtreeLast(node.left);}node.val replacement.val;node replacement;}Node parent node.parent;delete(node);rebalance(parent);return true;}// 删除结点p并用它的子结点代替它结点p至多只能有1个子结点private void delete(Node node) {if (node.left ! null node.right ! null) {return;// throw new Exception(Node has two children);}Node child node.left ! null ? node.left : node.right;if (child ! null) {child.parent node.parent;}if (node root) {root child;} else {Node parent node.parent;if (node parent.left) {parent.left child;} else {parent.right child;}}node.parent node;}// 在以node为根结点的子树中搜索值为v的结点如果没有值为v的结点则返回值为v的结点应该在的位置的父结点private Node subtreeSearch(Node node, int v) {if (node.val v node.right ! null) {return subtreeSearch(node.right, v);} else if (node.val v node.left ! null) {return subtreeSearch(node.left, v);} else {return node;}}// 重新计算node结点的高度和元素数private void recompute(Node node) {node.height 1 Math.max(getHeight(node.left), getHeight(node.right));node.size 1 getSize(node.left) getSize(node.right);}// 从node结点开始含node结点逐个向上重新平衡二叉树并更新结点高度和元素数private void rebalance(Node node) {while (node ! null) {int oldHeight node.height, oldSize node.size;if (!isBalanced(node)) {node restructure(tallGrandchild(node));recompute(node.left);recompute(node.right);}recompute(node);if (node.height oldHeight node.size oldSize) {node null; // 如果结点高度和元素数都没有变化则不需要再继续向上调整} else {node node.parent;}}}// 判断node结点是否平衡private boolean isBalanced(Node node) {return Math.abs(getHeight(node.left) - getHeight(node.right)) 1;}// 获取node结点更高的子树private Node tallChild(Node node) {if (getHeight(node.left) getHeight(node.right)) {return node.left;} else {return node.right;}}// 获取node结点更高的子树中的更高的子树private Node tallGrandchild(Node node) {Node child tallChild(node);return tallChild(child);}// 重新连接父结点和子结点子结点允许为空private static void relink(Node parent, Node child, boolean isLeft) {if (isLeft) {parent.left child;} else {parent.right child;}if (child ! null) {child.parent parent;}}// 旋转操作private void rotate(Node node) {Node parent node.parent;Node grandparent parent.parent;if (grandparent null) {root node;node.parent null;} else {relink(grandparent, node, parent grandparent.left);}if (node parent.left) {relink(parent, node.right, true);relink(node, parent, false);} else {relink(parent, node.left, false);relink(node, parent, true);}}// trinode操作private Node restructure(Node node) {Node parent node.parent;Node grandparent parent.parent;if ((node parent.right) (parent grandparent.right)) { // 处理需要一次旋转的情况rotate(parent);return parent;} else { // 处理需要两次旋转的情况第1次旋转后即成为需要一次旋转的情况rotate(node);rotate(node);return node;}}// 返回以node为根结点的子树的第1个元素private static Node subtreeFirst(Node node) {while (node.left ! null) {node node.left;}return node;}// 返回以node为根结点的子树的最后1个元素private static Node subtreeLast(Node node) {while (node.right ! null) {node node.right;}return node;}// 获取以node为根结点的子树的高度private static int getHeight(Node node) {return node ! null ? node.height : 0;}// 获取以node为根结点的子树的结点数private static int getSize(Node node) {return node ! null ? node.size : 0;} }时间复杂度 预处理的时间复杂度为O(N)其中N是树中结点的总数。插入、删除和搜索的时间复杂度均为 O(log⁡N)。 空间复杂度 O(N)用于存储平衡二叉搜索树。

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

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

相关文章

企业网站的高跳出率应该如何解决快速排名seo软件

文章目录 获取源码方法一方法二方法三了解S3C6410内核相关1 设备文件2 mach-文件3 plat-文件配置real6410编译镜像测试问题1获取源码 方法一 进入官网,如下界面,点击http, 再依次

技术支持 东莞网站建设防水工程网站开发申请微信支付

2427: [HAOI2010]软件安装 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 960 Solved: 380[Submit][Status][Discuss]Description 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi。我们希望从中选择一些软件…

行业门户网站营销案例挖矿网站开发

使用ts的最佳境界:化类型于无形 在项目中使用ts可以带来类型智能提示与校验的诸多好处。同时,为了减少类型标注,达到化类型于无形的效果,CabloyJS引入了ioc和依赖查找的机制。在上一篇文章中,我们创建了一个业务模块t…

在线flash相册网站源码做网站的公司利润多少呢

目录 引言 一、生成对抗网络的基本原理 1 初始化生成器和判别器 2 训练判别器 3 训练生成器 4 交替训练 5 评估和调整 二、生成对抗网络的应用领域 1 图像生成与编辑 2 语音合成与音频处理 3 文本生成与对话系统

网站开发详细流程图中国机房建设公司排名

运行Hello World Hello World 工程可以运行在模拟器中,或者运行在真机设备中。本示例先以选择将 Hello World 工程运行在模拟器中进行说明,如果选择运行在真机设备中,需要先对工程进行签名,然后才能运行在真机设备中。 DevEco S…

戴南做网站wordpress 下载统计

前言ANSYS程序中的SHELL181单元是用于复合材料层合板结构分析比较好的单元之一。原文在ANSYS程序的在线帮助中,这篇文章是它的译文,是我们从专业角度对原文的翻译。目的在于帮助那些英语水平不高,而且从事复合材料结构计算分析的技术人员能够…

江苏 网站建设网站分享到朋友圈

需求:文字内容位置保持不变,向下增加,背景框随之同步扩展。 1.UGUI 九宫格 拉伸 对背景框图片资源处理,避免图片拉伸。 (10条消息) unity UGUI 九宫格 拉伸_unity九宫格拉伸_野区捕龙为宠的博客-CSDN博客 2.背景框添加组件 3.…

网站pv uv 多少算好站wordpress版权加密

今天我们要来聊聊一个让人又爱又恨的话题——局部变量与全局变量的八大迷雾。在Python的世界里,变量就像是你的小宠物,有时候它们乖乖听话,但一不小心就给你挖了个大坑!别担心,今天我们就一起把这些陷阱挖出来&#xf…

网站简介 title织梦网站必须下载

协同工作和发布 - 协同工作 1. 了解权限管理需求 在中大型的公司里,人员的分工非常仔细:同一个小程序项目,一般会有不同岗位、不同角色的员工同时参与设计与开发。 此时出于管理需要,我们迫切需要对不同岗位、不同角色的员工的…

国外建筑设计网站推荐泉州一个网站多少钱

1231312转载于:https://www.cnblogs.com/ZHONGZHENHUA/p/7097077.html

网站着陆页有多少个seo优化啥意思

欢迎回到 TypeScript 高级技巧系列文章。我们之前已经讨论了Extract、Exclude和Indexed Access Types,接下来我们将深入探讨我最喜欢的TypeScript特性之一:判别联合类型(Discriminated Unions)。为什么我如此钟爱它呢?…

江门企业网站建设公司两学一做 官方网站

为实现Jwt简单的权限管理,我们需要用Jwt工具来生成token,也需要用Jwt来解码token,同时需要添加Jwt拦截器来决定放行还是拦截。下面来实现: 1、gradle引入Jwt、hutool插件 implementation com.auth0:java-jwt:3.10.3implementatio…

分析对手网站的优化方法网站建设 化工

题目:给定一个已按照 非递减顺序排列 的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target 。 我的代码: 对撞指针 class Solution {public int[] twoSum(int[] numbers, int target) {int low 0;//指向头int high numbers.le…

佛山免费建站怎样个人建设网站还要备案么

转载自 Java IO: InputStreamReader和OutputStreamWriter作者: Jakob Jenkov 译者: 李璟(jlee381344197gmail.com) 本章节将简要介绍InputStreamReader和OutputStreamWriter。细心的读者可能会发现,在之前的文章中,IO中的类要么以Stream结尾&#xff0c…

网站开发的工作内容深圳网站制作公司电话

机电一体化专业英语宋主民章第 3 章 中间转换电路3.1 前言传感器在测量系统中是把所测的机械信号转换为电量的一次仪表。这些电量可能是所用元件的电阻、电容或电感参数的变化,需要用电桥将它们转换为电压或电流信号。另一方面,实际上由一次仪表产生的电…

怎么创建免费自己的网站平台网站制作老了

文章目录 docker-compose命令启动单个容器重启容器停止和启动容器停止和启动所有容器演示一个简单示范 docker-compose 部署有依赖问题 Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。它允许您使用简单的 YAML 文件来配置应用程序的服务、网络和存储等方…

网站生成pc应用网络推广营销方案免费

事件与事件流 事件,这里指和网页进行互动。比如点击链接,移动鼠标等网页被触发,做出响应,形成交互。 js 采用事件监听器来监听事件是否发生。 事件流 事件流描述了从页面中接收事件的顺序。当一个事件发生在某个元素上时&…

色块设计网站自己做淘宝客网站

一.海康可见USB3.0工业面阵相机 海康usb相机需要去海康官网上下载对应系统的MVS客户端及SDK开发包 海康机器人-机器视觉-下载中心 选择Windows系统和unbtun(我是linux aarch64,所以选择了对应压缩包解压) Windows系统 1.双击安装包进入安装界面&…

做个网站 一般费用建设什么企业网站

目录 1.首先引入依赖2.main中配置注解3.src/main/resources/application.yml配置文件 本文的主要工作是介绍如何搭建一个Eureka服务 1.首先引入依赖 pom文件中加入依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring…

天河网站建设系统网络广告视频

通信是指线程之间以何种机制来交换信息&#xff0c;同步是指程序中用于控制不同线程间操作发生相对顺序的机制 进程由线程组成&#xff0c;所以进程中有的通讯机制线程中全都有 线程的通讯方式&#xff1a; 1. 锁机制&#xff1a;包括互斥锁、条件变量、读写锁 互斥锁提供了以…