算法通关村第九关黄金挑战——透彻理解二叉树中序遍历的应用

news2025/1/13 13:18:29

大家好,我是怒码少年小码。

上一篇讲了二分查找,今天我们看看它的难度扩展。

有序数组转为二叉搜索树

LeetCode 108:给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。

高度平衡:二叉树是一棵满足每个节点的左右两个子树的高度差的绝对值不超过1的二叉树。

二叉搜索树的中序遍历就是有序数组,相当于现在知道中序遍历的结果,让你构造二叉树,是不是很简单?答案也有很多种,但是这里限制了左右子树的高度差绝对值不能超过1,答案就少了。

分析:二叉搜索树的根节点的左子树上的结点的值都比根节点的值小,根节点的右子树上的结点的值都比根节点的值大;而根节点的左子树中的根节点也符合这一条件,根节点的右子树中的根节点也符合这一条件。

所以我们可以使用int mid = (left + right) / 2;将数组用中间元素分出左右数组,中间元素作为根节点,再从左右数组中分别找出左右数组中的中间元素当作根节点的左右结点,如此循环往复,知道数组为空。所以这本质上就是一个二分查找。

终止条件:left > right。代码如下:

TreeNode* helper(vector<int> nums, int left, int right) {
	if (left > right) {
		return nullptr;
	}
	
	//总是选择中间位置左边的数字为根节点
	int mid = (left + right) / 2;

	TreeNode* root = new TreeNode(nums[mid]);
	//返回mid左边数组构造的左子树
	root->left = helper(nums, left, mid - 1);
	//返回mid右边数组构造的右子树
	root->right = helper(nums, mid + 1, right);

	return root;
}

TreeNode* sortedArrayToBST(vector<int> nums) {
	return helper(nums, 0, nums.size() - 1);
}

寻找两个正序数组的中位数

LeetCode 4:给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和nums2。请你找出并返回这两个正序数组的中位数 。算法的时间复杂度应该为 O(log (m+n))

  • 输入:nums1 = [1,2] nums2 = [3, 4]
  • 输出:2.50000
  • 解释:合并数组 = [1,2,3,4], 中位数 (2 + 3) / 2 = 2.5

这道题如果没有时间复杂度的限制可以有很多种解决方法:

  1. 暴力解题:合并两个数组,然后再遍历找到中位数。
  2. 中位数就是 位于(m+n)/2 = k位置上的数,同时遍历两个数组,比较大小,移动指针,找到第k个大的元素。

但是很显然,时间复杂度都不对,想让有log , 一般都要使用二分、堆和快排的方法。

接下来使用二分的方法讲解:当m+n为奇数,中位数是有序数组的第(m+n)/2个元素;为偶数,中位数是第(m+n)/2个元素和第(m+n)/2 + 1个元素的平均值。所以,这道题转化成寻找两个有序数组的第 k 小的数,k为(m+n)/2或者(m+n)/2 + 1。

假如有两个有序数组nums1和nums2,要找到第k个元素,我们先比较nums1[k/2-1]和nums2[k/2-1]。比较完大小后有以下几种情况:

  • 如果nums1[k/2-1] < nums2[k/2-1],则比nums1[k/2-1]小的数最多只有nums1的前k/2 - 1个数和nums2的前k/2 - 1个,因此比其小的数最多只有k-2个,因此nums1[k/2 - 1]不可能是第k个数,那么便可以排除掉nums1[0]到nums1[k/2 - 1]的数,也就是一次砍掉一半。

如下图中第一种情况

  • 如果nums1[k/2-1] > nums2[k/2-1],便可以排除掉nums2[0]到nums2[k/2 - 1]的数。

如下图中第二种情况

  • 如果nums1[k/2-1] = nums2[k/2-1], 则归入第一种情况处理。

如下图中第三种情况

图片来自力扣

所以我们每次都能缩小一半范围,那最后我们就可以以log的时间复杂度找到我们要的中位数啦!

在此之前,我们还需要处理以下几个特殊情况:

  • 如果nums1[k/2 - 1] 或者 nums2[k/2 - 1]越界,那我们我们可以选取其对应数组的最后一个元素。在这种情况下,我们必须根据排除的个数减少k的值,而不能直接将k减去k/2。

  • 如果k=1,我们只需要返回两个数组首元素的最小值就可以了。

int getKthElement(const vector<int>& nums1, const vector<int>& nums2, int k) {
    int m = nums1.size();
    int n = nums2.size();
    int index1 = 0, index2 = 0;

    while (true) {
        // 边界情况
        if (index1 == m) {
            return nums2[index2 + k - 1];
        }
        if (index2 == n) {
            return nums1[index1 + k - 1];
        }
        if (k == 1) {
            return min(nums1[index1], nums2[index2]);
        }

        // 正常情况
        int newIndex1 = min(index1 + k / 2 - 1, m - 1);
        int newIndex2 = min(index2 + k / 2 - 1, n - 1);
        int pivot1 = nums1[newIndex1];
        int pivot2 = nums2[newIndex2];
        if (pivot1 <= pivot2) {
            k -= newIndex1 - index1 + 1;
            index1 = newIndex1 + 1;
        }
        else {
            k -= newIndex2 - index2 + 1;
            index2 = newIndex2 + 1;
        }
    }
}

double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
	int totalLength = nums1.size() + nums2.size();
	if (totalLength % 2 == 1) {
		return getKthElement(nums1, nums2, (totalLength + 1) / 2);
	}
	else {
		return (getKthElement(nums1, nums2, totalLength / 2) + getKthElement(nums1, nums2, totalLength / 2 + 1)) / 2.0;
	}
}

本篇参考了这篇文章

END

最后一道题是力扣上的困难题,这么说吧,我觉得我像一个废物😁😁。

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

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

相关文章

第0章:怎么入手tensorflow

近年来人工智能的火爆吸引了很多人&#xff0c;网上相关的热门课程报名的人很多&#xff0c;但是坚持下去的人却少。那些晦涩的原理没有一定知识的积累很难能理解。 如果你对人工智能感兴趣&#xff0c;且想利用人工智能去实现某项功能&#xff0c;而不是对人工智能本身感兴趣&…

如何利用BIGEMAP软件查看历史影像

工具 Bigemap gis office地图软件 BIGEMAP GIS Office-全能版 Bigemap APP_卫星地图APP_高清卫星地图APP 很多人都在寻找历史影像图&#xff0c;这块的需求是非常大&#xff0c;历史影像一般可以用于历史地貌的变迁分析&#xff0c;还原以前的生态场景&#xff0c;对范围面积…

SSM - Springboot - MyBatis-Plus 全栈体系(三十二)

第七章 MyBatis-Plus 二、MyBatis-Plus 核心功能 5. 核心注解使用 5.1 理解和介绍 MyBatis-Plus 是一个基于 MyBatis 框架的增强工具&#xff0c;提供了一系列简化和增强的功能&#xff0c;用于加快开发人员在使用 MyBatis 进行数据库访问时的效率。 MyBatis-Plus 提供了一…

嵌入式学习笔记(58)C语言的内存操作

1.2内存位宽 1.2.1.内存的逻辑抽象图 提到内存&#xff0c;脑中要有一张逻辑图。这张图是一行行大小相等的格子&#xff0c;对于32位内存来说&#xff0c;一行就是4个字节。CPU要访问一个int型数据&#xff0c;则首先取地址,这里的地址指的是int型数据单元的首地址&#xff0…

如何使用Python快速实现文件共享并通过内网穿透技术公网访问?

文章目录 1.前言2.本地文件服务器搭建2.1.Python的安装和设置2.2.cpolar的安装和注册 3.本地文件服务器的发布3.1.Cpolar云端设置3.2.Cpolar本地设置 4.公网访问测试5.结语 1.前言 数据共享作为和连接作为互联网的基础应用&#xff0c;不仅在商业和办公场景有广泛的应用&#…

OpenWRT通过内网穿透实现安全可靠的ssh远程连接

文章目录 1.安装cpolar内网穿透2.配置SSH远程访问隧道3.公网远程连接4.固定远程连接地址 简单几步实现openWRT结合cpolar内网穿透工具实现远程ssh连接 1.安装cpolar内网穿透 cpolar是一个非常棒的跨平台、内网穿透工具&#xff0c;可以通过安全隧道将NAT或防火墙后面的本地服…

正视AI技术发展利弊,国外高校如何看待文书中使用ChatGPT

ChatGPT是由美国人工智能实验室OpenAI开发的对话AI模型&#xff0c;因极其出色的对话交互和文本生成能力在世界范围内迅速走红&#xff0c;短短5天用户就破了百万。 ChatGPT自2022年11月正式推出以来&#xff0c;已经成为一个热门话题&#xff0c;它可以用于各种各样的事情&am…

c51单片机中不同定义变量的存储位置不同

keil中对不同变量的数据进行存储 上图中是很长看到的一种存储数据变量code&#xff0c;类似这种存储方式还有data,xdata,idata,bdata,这些方式制定了数据的存储位置&#xff0c;方便程序中数据能够更快的处理&#xff08;对于小数据量当然就没有这方面的考虑&#xff09;。 传…

校园智慧党建小程序源码系统 带完整的搭建教程

大家好啊&#xff0c;今天来给大家分享一款校园智慧党建小程序源码系统。一起来看看吧。以下是部分功能代码图&#xff1a; 系统特色功能一览&#xff1a; 智能化管理&#xff1a;采用人工智能、大数据、云计算等技术手段&#xff0c;实现自动化、智能化管理。例如&#xff0c…

PVE(Proxmox)8.0的一些问题汇总

目录 前言 杂谈 pve和esxi选啥 直通类 显卡怎么直通 win10显卡报错43 直通后进不去系统或者系统有问题自救 pci类 拔了显卡开机了但是进不去系统 虚拟机类 虚拟机显示问号&#xff0c;而且创建不了新的虚拟机 我想用pve的虚拟机ikuai来连接pve怎么搞 前言 pve折腾了快…

CS 61A Fall 2023 Lecture 1 - Functions [Python] - Notes01, Lab00 and HW01

CS 61A Fall 2023 Lecture 1 - Functions [Python] 文章目录 CS 61A Fall 2023 Lecture 1 - Functions [Python]Note 01lab00HW01 I am gonna make a plan for my future in advance, to consistently refine my coding skills. And this class is what I will try to finish t…

Matlab论文插图绘制模板第121期—图中图

不知不觉&#xff0c;《Matlab论文插图绘制模板》系列教程已经连载更新了120期&#xff0c;而《Matlab进阶绘图》系列也更新了30期&#xff0c;分享了一系列各式各样数据图的标准化绘制模板&#xff1a; 本期分享的内容比较特殊&#xff0c;它可以串联起之前分享的一众数据图&a…

postman发送soap报文示例

一、soap简介 soap是一种基于XML的协议 二、postman发送soap请求 1、发送post请求&#xff0c;url&#xff1a;​​​ https://www.dataaccess.com/webservicesserver/NumberConversion.wso 2、headers设置&#xff0c;添加Content-Type&#xff0c;值为text/xml 添加SOAP…

Java 新手如何使用Spring MVC 中的查询字符串和查询参数

文章目录 什么是查询字符串和查询参数&#xff1f;Spring MVC中的查询参数处理可选参数处理多个值处理查询参数的默认值处理查询字符串示例&#xff1a;创建一个RESTful服务结论 &#x1f389;欢迎来到Java学习路线专栏~Java 新手如何使用Spring MVC 中的查询字符串和查询参数 …

06 迪米特法则

官方定义 迪米特法则&#xff08;LoD&#xff1a;Law of Demeter&#xff09;又叫最少知识原则&#xff08;LKP&#xff1a;Least Knowledge Principle &#xff09;&#xff0c;指的是一个类/模块对其他的类/模块有越少的了解越 好。简言之&#xff1a;talk only to your imm…

MySQL的ACID和并发事务带来的问题简单总结

拓跋阿秀 ACID 原子性&#xff1a;一个事务&#xff08;transaction&#xff09;中的所有操作&#xff0c;要么全部完成&#xff0c;要么全部不完成&#xff0c;不会结束在中间某个环节。事务在执行过程中发生错误&#xff0c;会被恢复&#xff08;Rollback&#xff09;到事务…

【知识图谱】KBQA核心架构小结

KBQA是指基于知识图谱的问答系统&#xff0c;是知识图谱的重要应用形式&#xff0c;基于知识图谱的问答和基于LLM的问答殊途同归。 KBQA是一个系统&#xff0c;由多种功能模块组成&#xff0c;其核心架构梳理如下&#xff1a; 下面对各个模块简单小结 文本清洗 只有是文本的…

dashboard报错 错误:无法获取网络列表、dashboard报错 错误:无法获取云主机列表 解决流程

文章目录 错误说明dashboard上报错底层命令报错查看日志message日志httpd报错日志错误日志分析开始解决测试底层命令dashboard错误说明 dashboard上报错 首先,dashboard上无论是管理员还是其他项目,均无法获取云主机和网络信息,具体报错如下

广州虚拟动力携数字人全栈式产品,邀您来2023世界VR产业大会(南昌)一探虚实

2023年10月19-20日&#xff0c;由工业和信息化部、江西省人民政府联合主办&#xff0c;中国电子信息产业发展研究院、江西省工业和信息化厅、南昌市人民政府、虚拟现实产业联盟共同承办的2023世界VR产业大会将在南昌绿地国际博览中心盛大举办。 广州虚拟动力作为3D、AI虚拟人领…

【C++笔记】多态的原理、单继承和多继承关系的虚函数表、 override 和 final、抽象类、重载、覆盖(重写)、隐藏(重定义)的对比

1.final关键字 引出&#xff1a;设计一个不能被继承的类。有如下方法&#xff1a; class A { private:A(int a0):_a(a){} public:static A CreateOBj(int a0){return A(a);} protected:int _a; } //简介限制&#xff0c;子类构成函数无法调用父类构造函数初始化 //子类的构造…