LeetCode每日一题:将元素分配到两个数组中 II - 二叉索引树BIT

大家好!今天我们来聊聊一道有趣的LeetCode分配问题将元素分配到两个数组中 II。📊

问题描述

给你一个下标从 1 开始、长度为 n 的整数数组 nums 。

现定义函数 greaterCount ,使得 greaterCount(arr, val) 返回数组 arr 中 严格大于 val 的元素数量。

你需要使用 n 次操作,将 nums 的所有元素分配到两个数组 arr1 和 arr2 中。在第一次操作中,将 nums[1] 追加到 arr1 。在第二次操作中,将 nums[2] 追加到 arr2 。之后,在第 i 次操作中:

如果 greaterCount(arr1, nums[i]) > greaterCount(arr2, nums[i]) ,将 nums[i] 追加到 arr1 。
如果 greaterCount(arr1, nums[i]) < greaterCount(arr2, nums[i]) ,将 nums[i] 追加到 arr2 。
如果 greaterCount(arr1, nums[i]) == greaterCount(arr2, nums[i]) ,将 nums[i] 追加到元素数量较少的数组中。
如果仍然相等,那么将 nums[i] 追加到 arr1 。
连接数组 arr1 和 arr2 形成数组 result 。例如,如果 arr1 == [1,2,3] 且 arr2 == [4,5,6] ,那么 result = [1,2,3,4,5,6] 。

返回整数数组 result 。🙌

示例 1:

输入:nums = [2,1,3,3]
输出:[2,3,1,3]
解释:在前两次操作后,arr1 = [2] ,arr2 = [1] 。
在第 3 次操作中,两个数组中大于 3 的元素数量都是零,并且长度相等,因此,将 nums[3] 追加到 arr1 。
在第 4 次操作中,两个数组中大于 3 的元素数量都是零,但 arr2 的长度较小,因此,将 nums[4] 追加到 arr2 。
在 4 次操作后,arr1 = [2,3] ,arr2 = [1,3] 。
因此,连接形成的数组 result 是 [2,3,1,3] 。
示例 2:

输入:nums = [5,14,3,1,2]
输出:[5,3,1,2,14]
解释:在前两次操作后,arr1 = [5] ,arr2 = [14] 。
在第 3 次操作中,两个数组中大于 3 的元素数量都是一,并且长度相等,因此,将 nums[3] 追加到 arr1 。
在第 4 次操作中,arr1 中大于 1 的元素数量大于 arr2 中的数量(2 > 1),因此,将 nums[4] 追加到 arr1 。
在第 5 次操作中,arr1 中大于 2 的元素数量大于 arr2 中的数量(2 > 1),因此,将 nums[5] 追加到 arr1 。
在 5 次操作后,arr1 = [5,3,1,2] ,arr2 = [14] 。
因此,连接形成的数组 result 是 [5,3,1,2,14] 。
示例 3:

输入:nums = [3,3,3,3]
输出:[3,3,3,3]
解释:在 4 次操作后,arr1 = [3,3] ,arr2 = [3,3] 。
因此,连接形成的数组 result 是 [3,3,3,3] 。

提示:

3 <= n <= 105
1 <= nums[i] <= 109

解题思路

要解决这个问题,我们需要高效地统计数组中比当前元素大的元素数量。最直接的方式是遍历整个数组,但这样会导致时间复杂度过高,尤其是当数据量较大时。因此,我们引入了二叉索引树(Binary Indexed Tree, BIT)。🌳

为什么选择二叉索引树?

二叉索引树是一种非常适合频繁更新和查询区间和的问题的数据结构。它在以下几个方面具有优势:

  1. 高效更新:每次更新操作的时间复杂度是 (O(\log n)),相比于直接遍历数组要高效得多。
  2. 高效查询:每次查询操作的时间复杂度也是 (O(\log n)),能够快速获取区间和。

这些特点使得二叉索引树非常适合用于解决需要频繁统计和更新元素数量的问题。

代码实现
import scala.collection.mutable.{ArrayBuffer, Map}
import scala.util.Sortingclass BinaryIndexedTree(n: Int) {private val tree = new Array[Int](n + 1)def add(i: Int): Unit = {var index = iwhile (index < tree.length) {tree(index) += 1index += index & -index}}def get(i: Int): Int = {var index = ivar sum = 0while (index > 0) {sum += tree(index)index -= index & -index}sum}
}object Solution {def resultArray(nums: Array[Int]): Array[Int] = {val n = nums.lengthval sortedNums = nums.clone()Sorting.quickSort(sortedNums)val index = Map[Int, Int]()for (i <- sortedNums.indices) {index(sortedNums(i)) = i + 1}val arr1 = ArrayBuffer(nums(0))val arr2 = ArrayBuffer(nums(1))val tree1 = new BinaryIndexedTree(n)val tree2 = new BinaryIndexedTree(n)tree1.add(index(nums(0)))tree2.add(index(nums(1)))for (i <- 2 until n) {val count1 = arr1.size - tree1.get(index(nums(i)))val count2 = arr2.size - tree2.get(index(nums(i)))if (count1 > count2 || (count1 == count2 && arr1.size <= arr2.size)) {arr1 += nums(i)tree1.add(index(nums(i)))} else {arr2 += nums(i)tree2.add(index(nums(i)))}}(arr1 ++ arr2).toArray}
}// 测试示例
object Main extends App {val nums = Array(5, 14, 3, 1, 2)val result = Solution.resultArray(nums)println(result.mkString(", "))
}
代码解析
  • BinaryIndexedTree 类:实现了二叉索引树,用于高效计算比当前元素大的元素数量。
  • resultArray 方法:负责将元素分配到 arr1arr2 中,并返回最终结果。
时间复杂度分析 ⏱️
  1. 排序:需要 (O(n \log n)) 的时间。
  2. 构建映射:需要 (O(n)) 的时间。
  3. 遍历和分配:每个元素插入二叉索引树和查询的操作都是 (O(\log n)),因此总时间复杂度为 (O(n \log n))。
总结

通过使用二叉索引树(BIT),我们成功地解决了这一复杂的分配问题,保证了分配的高效性和准确性。希望这个方法能帮助到大家!如果有任何问题或者建议,欢迎在评论区留言。💬

#LeetCode #算法 #数据结构 #二叉索引树 #BIT #数组分配

发布时间:2024-06-05

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

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

相关文章

spring入门aop和ioc

文章目录 spring分层架构表现层服务层&#xff08;业务层&#xff09;持久层 spring核心ioc&#xff08;控制反转&#xff09;1)**接下来是代码示例&#xff1a;**2)**ioc容器的使用过程**3)ioc中的bean管理4)实例化bean的三种方式 aop&#xff08;面向切面开发&#xff09; 定…

数据结构与算法笔记:基础篇 - 数组:为什么数组都是从0开始编号

概述 提到数组&#xff0c;大家应该都不陌生。每一种编程语言基本都会有数组这种数据类型。不过&#xff0c;它不仅仅是一种编程语言中的数据类型&#xff0c;还是一种基础的数据结构。尽管数组看起来非常简单&#xff0c;但是我估计很多人并没有理解这个数据结构的精髓。 在…

AB测试实战

AB测试实战 1、AB测试介绍&#x1f43e; 很多网站/APP的首页都会挂一张头图(Banner)&#xff0c;用来展示重要信息&#xff0c;头图是否吸引人会对公司的营收带来重大影响&#xff0c;一家寿险公司Humana设计了如下三张头图&#xff0c;现在需要决定使用哪一张放到首页&#x…

FastDFS分布式文件系统

一、概述 FastDFS是一款由国人余庆开发的轻量级开源分布式文件系统&#xff0c;它对文件进行管理&#xff0c;功能包括&#xff1a;文件存储、文件同步、文件访问&#xff08;文件上传、文件下载&#xff09;等&#xff0c;主要解决大容量文件存储和高并发访问问题&#xff0c…

jenkins应用2-freestyle-job

1.jenkins应用 1.jenkins构建的流程 1.使用git参数化构建&#xff0c;用标签区分版本 2.git 拉取gitlab远程仓库代码 3.maven打包项目 4.sonarqube经行代码质量检测 5.自定义制作镜像发送到远程仓库harbor 6.在远程服务器上拉取代码启动容器 这个是构建的整个过程和步骤…

保姆级教程:Redis 主从复制原理及集群搭建

&#x1f604;作者简介&#xff1a; 小曾同学.com,一个致力于测试开发的博主⛽️&#xff0c;主要职责&#xff1a;测试开发、CI/CD 如果文章知识点有错误的地方&#xff0c;还请大家指正&#xff0c;让我们一起学习&#xff0c;一起进步。 &#x1f60a; 座右铭&#xff1a;不…

线程池的工作原理

文章目录 一、应用场景二、工作原理三、主要函数 一、应用场景 传统并发变成的缺陷&#xff1a; 1.创建和销毁线程上花费的时间和消耗的系统资源&#xff0c;甚至可能要比花在处理实际的用户请求的时间和资源要多得多 2. 活动的线程需要消耗系统资源&#xff0c;如果启动太多&…

Python基础教程教材:从入门到精通的全方位解析

Python基础教程教材&#xff1a;从入门到精通的全方位解析 Python&#xff0c;作为一门强大的编程语言&#xff0c;正日益受到全球开发者的青睐。无论是数据分析、人工智能还是Web开发&#xff0c;Python都展现出其独特的魅力。然而&#xff0c;对于初学者来说&#xff0c;如何…

新规:互联网政务应用安全管理规定将于7月1日正式执行

随着互联网技术的快速发展&#xff0c;政务服务也逐渐向数字化、智能化、便捷化转型。为了保障互联网政务应用的安全&#xff0c;保障公民信息不被泄露&#xff0c;为了让大家放心&#xff0c;我国政府出台了互联网政务应用安全管理规定。此规定将于24年7月1日正式执行。 1、规…

安卓自动化之minicap截图

安卓自动化之minicap截图 关于安卓自动化使用找图方法点击时&#xff0c;最大的痛点是使用原生adb截图速度太慢了&#xff0c;大概需要3s的时间&#xff0c;再加上我们使用opencv的找图算法&#xff0c;时间就去都三秒多了&#xff0c;为了解决这一个痛点&#xff0c;我们就可…

HBase数据库面试知识点:第二部分 - 核心技术(持续更新中)

目录 1. 分布式存储与HDFS 2. 面向列的存储 3. 数据版本控制 4. Region与RegionServer 5. 分布式协调服务&#xff08;ZooKeeper&#xff09; 1. 分布式存储与HDFS HBase利用Hadoop的HDFS作为其底层存储系统&#xff0c;确保数据的高可靠性和可扩展性。 数据块&#xff0…

Python爬虫如何入门:一步步走向精通的指南

Python爬虫如何入门&#xff1a;一步步走向精通的指南 在信息爆炸的时代&#xff0c;爬虫技术已经成为获取、整理和分析数据的必备技能。Python&#xff0c;以其简洁易懂的语法和强大的库支持&#xff0c;成为了爬虫开发的热门语言。那么&#xff0c;如何入门Python爬虫呢&…

研发质量测试工程师的笔试题

研发质量测试工程师的笔试题通常会考察候选人在测试理论、测试方法、测试工具使用以及实际案例分析等方面的知识和能力。以下是一些可能出现在研发质量测试工程师笔试中的题目类型和内容&#xff1a; 一、测试理论题 请简述软件测试的目的和基本原则。描述黑盒测试和白盒测试…

Python | 句子缩写

字符串大小的比较Unicode码值 类似于asc|| 码 小写字母从 a 到 z 对应的 Unicode 码值是从 97 到 122&#xff0c;而大写字母从 A 到 Z 对应的 Unicode 码值是从 65 到 90, 大小写字母之间的差值为32&#xff0c;所以可以通过数学运算将小写字符减去32后转换为大写字符。 字…

26、matlab多项式曲线拟合:polyfit ()函数

1、polyfit 多项式曲线拟合 语法 语法&#xff1a;p polyfit(x,y,n) 返回次数为 n 的多项式 p(x) 的系数&#xff0c;该阶数是 y 中数据的最佳拟合&#xff08;基于最小二乘指标&#xff09;。 语法&#xff1a;[p,S] polyfit(x,y,n) 还返回一个结构体 S 语法&#xff1a;[…

优化 mac 储存空间的方法 只需一招为你的苹果电脑提速

在职场中&#xff0c;许多人都对苹果电脑情有独钟。苹果电脑以其简洁美观的设计、流畅稳定的性能以及出色的用户体验&#xff0c;成为了众多职场人士的得力助手。无论是处理文档、制作演示文稿&#xff0c;还是进行创意设计等工作&#xff0c;苹果电脑都能展现出其独特的优势&a…

微信小程序公众号二合一分销商城源码系统 基于PHP+MySQL组合开发的 可多商户商家入驻 带完整的安装代码包以及搭建教程

系统概述 微信小程序公众号二合一分销商城源码系统&#xff0c;是基于PHPMySQL组合开发的一款高效、稳定的电子商务平台解决方案。该系统创新性地将微信公众号与小程序的功能进行了深度整合&#xff0c;为商家提供了一个功能齐全、易于管理的分销商城系统。通过此系统&#xf…

Vue3+vant 带你实现常见的历史记录的业务功能

前言 大部分小伙伴不管是开发PC端还是H5移动端&#xff0c;都会遇到历史搜索的功能。对用户的历史记录进行增删查可以是接口&#xff0c;也可以是前端用缓存实现&#xff0c;一般用浏览器缓存实现的比较多&#xff0c;这篇文章就来教你如何用LocalStorage对历史记录数据的存储、…

视创云展元宇宙虚拟展厅,带来沉浸式的逛展体验!

近年来&#xff0c;随着科技的飞速发展和市场需求的不断演变&#xff0c;众多企业纷纷将目光转向线上虚拟展厅的建设。视创云展元宇宙虚拟展厅凭借其创新性和实用性&#xff0c;为众多企业带来了前所未有的宣传体验&#xff0c;成为了商企展示自我、推广产品的全新舞台。 与传统…

Java 生成SSL证书

第一步&#xff1a; cmd打开指令窗口 第二步&#xff1a; 运行指令&#xff1a; keytool -keystore hk.jks -storepass 123456 -deststoretype jks -genkeypair -keyalg RSA -validity 365 -alias contrastserver -dname "CN111.230.63.59, OUHK, OHK, LZH, STGD, CCN&…