二分查找题目:在线选举

文章目录

  • 题目
    • 标题和出处
    • 难度
    • 题目描述
      • 要求
      • 示例
      • 数据范围
  • 解法
    • 思路和算法
    • 代码
    • 复杂度分析

题目

标题和出处

标题:在线选举

出处:911. 在线选举

难度

7 级

题目描述

要求

给定两个整数数组 persons \texttt{persons} persons times \texttt{times} times。在选举中,第 i \texttt{i} i 张票在时刻 times[i] \texttt{times[i]} times[i] 投给候选人 persons[i] \texttt{persons[i]} persons[i]

对于发生在时刻 t \texttt{t} t 的每个查询,需要找出 t \texttt{t} t 时刻在选举中领先的候选人的编号。在 t \texttt{t} t 时刻投出的选票也将被计入查询中。在平局的情况下,票数最多的候选人中最近获得投票的候选人将会获胜。

实现 TopVotedCandidate \texttt{TopVotedCandidate} TopVotedCandidate 类:

  • TopVotedCandidate(int[] persons, int[] times) \texttt{TopVotedCandidate(int[] persons, int[] times)} TopVotedCandidate(int[] persons, int[] times) 使用 persons \texttt{persons} persons times \texttt{times} times 数组初始化对象。
  • int q(int t) \texttt{int q(int t)} int q(int t) 根据前面描述的规则,返回时刻 t \texttt{t} t 在选举中领先的候选人的编号。

示例

示例 1:

输入:
["TopVotedCandidate", "q", "q", "q", "q", "q", "q"] \texttt{["TopVotedCandidate", "q", "q", "q", "q", "q", "q"]} ["TopVotedCandidate", "q", "q", "q", "q", "q", "q"]
[[[0, 1, 1, 0, 0, 1, 0], [0, 5, 10, 15, 20, 25, 30]], [3], [12], [25], [15], [24], [8]] \texttt{[[[0, 1, 1, 0, 0, 1, 0], [0, 5, 10, 15, 20, 25, 30]], [3], [12], [25], [15], [24], [8]]} [[[0, 1, 1, 0, 0, 1, 0], [0, 5, 10, 15, 20, 25, 30]], [3], [12], [25], [15], [24], [8]]
输出:
[null, 0, 1, 1, 0, 0, 1] \texttt{[null, 0, 1, 1, 0, 0, 1]} [null, 0, 1, 1, 0, 0, 1]
解释:
TopVotedCandidate topVotedCandidate = new TopVotedCandidate([0, 1, 1, 0, 0, 1, 0], [0, 5, 10, 15, 20, 25, 30]); \texttt{TopVotedCandidate topVotedCandidate = new TopVotedCandidate([0, 1, 1, 0, 0, 1, 0], [0, 5, 10, 15, 20, 25, 30]);} TopVotedCandidate topVotedCandidate = new TopVotedCandidate([0, 1, 1, 0, 0, 1, 0], [0, 5, 10, 15, 20, 25, 30]);
topVotedCandidate.q(3); \texttt{topVotedCandidate.q(3);} topVotedCandidate.q(3); // 返回 0 \texttt{0} 0,在时刻 3 \texttt{3} 3,票数分布为 [0] \texttt{[0]} [0],编号为 0 \texttt{0} 0 的候选人领先。
topVotedCandidate.q(12); \texttt{topVotedCandidate.q(12);} topVotedCandidate.q(12); // 返回 1 \texttt{1} 1,在时刻 12 \texttt{12} 12,票数分布为 [0,1,1] \texttt{[0,1,1]} [0,1,1],编号为 1 \texttt{1} 1 的候选人领先。
topVotedCandidate.q(25); \texttt{topVotedCandidate.q(25);} topVotedCandidate.q(25); // 返回 1 \texttt{1} 1,在时刻 25 \texttt{25} 25,票数分布为 [0,1,1,0,0,1] \texttt{[0,1,1,0,0,1]} [0,1,1,0,0,1],编号为 1 \texttt{1} 1 的候选人领先(在平局的情况下, 1 \texttt{1} 1 是最近获得投票的候选人)。
topVotedCandidate.q(15); \texttt{topVotedCandidate.q(15);} topVotedCandidate.q(15); // 返回 0 \texttt{0} 0
topVotedCandidate.q(24); \texttt{topVotedCandidate.q(24);} topVotedCandidate.q(24); // 返回 0 \texttt{0} 0
topVotedCandidate.q(8); \texttt{topVotedCandidate.q(8);} topVotedCandidate.q(8); // 返回 1 \texttt{1} 1

数据范围

  • 1 ≤ persons.length ≤ 5000 \texttt{1} \le \texttt{persons.length} \le \texttt{5000} 1persons.length5000
  • times.length = persons.length \texttt{times.length} = \texttt{persons.length} times.length=persons.length
  • 0 ≤ persons[i] < persons.length \texttt{0} \le \texttt{persons[i]} < \texttt{persons.length} 0persons[i]<persons.length
  • 0 ≤ times[i] ≤ 10 9 \texttt{0} \le \texttt{times[i]} \le \texttt{10}^\texttt{9} 0times[i]109
  • times \texttt{times} times 严格升序排序
  • times[0] ≤ t ≤ 10 9 \texttt{times[0]} \le \texttt{t} \le \texttt{10}^\texttt{9} times[0]t109
  • 最多调用 10 4 \texttt{10}^\texttt{4} 104 q \texttt{q} q

解法

思路和算法

查询时刻 t t t 在选举中领先的候选人时,需要找到不晚于时刻 t t t 的最后一次投票时刻,并计算该时刻每个候选人的票数,得到在选举中领先的候选人。

为了快速得到选举中特定时刻领先的候选人,需要在初始化时预处理投票信息,对于每张选票,更新候选人的票数,并记录该时刻领先的候选人。在预处理之后,每次查询时,对于给定的时刻 t t t,需要找到不晚于时刻 t t t 的最后一次投票时刻,得到该时刻领先的候选人。由于数组 times \textit{times} times 严格升序,因此可以使用二分查找的方式找到特定时刻。

为了记录预处理信息,需要维护时刻数组、每个时刻领先的候选人数组(与时刻数组等长)以及每个候选人的票数。

构造方法中预处理投票信息。用给定的数组 times \textit{times} times 作为时刻数组,并维护当前领先的候选人编号。同时遍历给定的数组 persons \textit{persons} persons times \textit{times} times,对于每个时刻的选票,更新该选票投给的候选人的票数,如果该候选人的票数大于等于当前领先的候选人的票数(由于平局时最近获得选票的候选人领先,因此也需要考虑票数相等的情况),则更新当前领先的候选人编号。遍历结束之后,即可得到每个时刻领先的候选人数组。

对于调用 q q q 的操作,首先使用二分查找得到不晚于时刻 t t t 的最后一次投票时刻,然后在每个时刻领先的候选人数组中找到该时刻领先的候选人并返回。

low \textit{low} low high \textit{high} high 分别表示二分查找的下界和上界。由于需要在时刻数组中查找小于等于 t t t 的最大元素所在下标,且 t t t 不小于时刻数组的首个元素(即下标 0 0 0 处的元素),因此初始时 low \textit{low} low high \textit{high} high 分别为时刻数组的最小下标和最大下标。每次查找时,取 mid \textit{mid} mid low \textit{low} low high \textit{high} high 的平均数向上取整,得到时刻数组中下标 mid \textit{mid} mid 处的元素并与时刻 t t t 比较,调整查找的下标范围。

  • 如果时刻数组中下标 mid \textit{mid} mid 处的元素小于等于 t t t,则不晚于时刻 t t t 的最后一次投票时刻所在下标大于等于 mid \textit{mid} mid,因此在下标范围 [ mid , high ] [\textit{mid}, \textit{high}] [mid,high] 中继续查找。

  • 如果时刻数组中下标 mid \textit{mid} mid 处的元素大于 t t t,则不晚于时刻 t t t 的最后一次投票时刻所在下标小于 mid \textit{mid} mid,因此在下标范围 [ low , mid − 1 ] [\textit{low}, \textit{mid} - 1] [low,mid1] 中继续查找。

low = high \textit{low} = \textit{high} low=high 时,查找结束,此时 low \textit{low} low 即为不晚于时刻 t t t 的最后一次投票时刻所在下标。每个时刻领先的候选人数组中的下标 low \textit{low} low 处的元素即为时刻 t t t 在选举中领先的候选人的编号。

代码

class TopVotedCandidate {int[] times;int[] tops;Map<Integer, Integer> votes;public TopVotedCandidate(int[] persons, int[] times) {this.times = times;int length = persons.length;this.tops = new int[length];this.votes = new HashMap<Integer, Integer>();int top = -1;for (int i = 0; i < length; i++) {int person = persons[i], time = times[i];votes.put(person, votes.getOrDefault(person, 0) + 1);if (i == 0 || votes.get(person) >= votes.get(top)) {top = person;}tops[i] = top;}}public int q(int t) {int low = 0, high = times.length - 1;while (low < high) {int mid = low + (high - low + 1) / 2;if (times[mid] <= t) {low = mid;} else {high = mid - 1;}}return tops[low];}
}

复杂度分析

  • 时间复杂度:构造方法的时间复杂度是 O ( n ) O(n) O(n),每次查询的时间复杂度是 O ( log ⁡ n ) O(\log n) O(logn),其中 n n n 是数组 persons \textit{persons} persons times \textit{times} times 的长度。构造方法需要遍历数组 persons \textit{persons} persons times \textit{times} times 预处理投票信息,需要 O ( n ) O(n) O(n) 的时间。每次查询时,二分查找定位到不晚于时刻 t t t 的最后一次投票时刻需要 O ( log ⁡ n ) O(\log n) O(logn) 的时间,得到该时刻在选举中领先的候选人的编号的时间是 O ( 1 ) O(1) O(1)

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组 persons \textit{persons} persons times \textit{times} times 的长度。存储时刻数组、每个时刻领先的候选人数组以及每个候选人的票数需要 O ( n ) O(n) O(n) 的空间。

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

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

相关文章

Mybatis-Plus:乐观锁与悲观锁

文章目录 一、场景二、乐观锁与悲观锁三、模拟修改冲突3.1 数据库中增加商品表3.2 添加数据3.3 添加实体3.4 添加mapper3.5 测试 四、乐观锁实现流程4.1 Mybatis-Plus实现乐观锁 一、场景 一件商品&#xff0c;成本价是80元&#xff0c;售价是100元。老板先是通知小李&#xf…

卷积神经网络——食物分类

整体框架&#xff1a; 导入库 导入了各种必需的Python库&#xff0c;用于数据处理、图像读取、模型构建和训练。 设置随机种子 seed_everything: 用于设置所有随机数生成器的种子&#xff0c;确保每次运行时的结果都是相同的。 图像预处理&#xff08;transform&#xff09; 对…

Jmeter配置服务代理器 Proxy(二)

1.创建脚本记录器 2.配置&#xff1a;Jmeter代理、端口、记录目标等 3.配置谷歌浏览器代理 浏览器配置代理的详细教程可参考&#xff1a;使用whistle代理-CSDN博客 4.启动Jmeter记录器 点击ok后弹出这个界面&#xff0c;生成了证书&#xff1a; 5.给浏览器安装Jmeter代理的证书…

灰色预测and BP神经网络 (详细上手使用)

灰色预测模型 基础知识&#xff1a; 白色系统&#xff1a;系统的信息是完全明确的。 灰色系统&#xff1a;系统的部分信息已知&#xff0c;部分信息未知。 黑色系统&#xff1a;系统的内部信息是未知的。 灰色预测是对既含有已知信息又含有不确定信息的系统进行预则&#xf…

mac 安装 node

brew versions node // 安装 node brew versions node14 // 安装指定版本 卸载node: sudo npm uninstall npm -g sudo rm -rf /usr/local/lib/node /usr/local/lib/node_modules /var/db/receipts/org.nodejs.* sudo rm -rf /usr/local/include/node /Users/$USER/.npm su…

(处理 Kafka 消息积压) - 高吞吐 + 零丢失的阻塞队列实战方案

一、分布式日志消费场景与挑战 在分布式日志系统中&#xff0c;Kafka 通常作为消息队列中间件&#xff0c;负责从日志生产者接收日志&#xff0c;并将其分发给日志消费者进行处理。为了平衡 Kafka 消费速度与日志处理速度&#xff0c;BlockingQueue 常被用作缓冲区&#xff0c…

【Unity】unity3D 调用LoadSceneAsync 场景切换后比较暗 部门材质丢失

解决方法&#xff1a;两个场景使用同样灯光 现象 直接进入第二个场景是可以正常显示 调用LoadSceneAsync来切换后&#xff0c;第二个场景出现比较暗的情况 解决方法&#xff1a;两个场景使用同样灯光&#xff0c;在loading 的场景中加入灯光。 Light—Directional Light 如果…

红日-VulnStack靶场一

http://vulnstack.qiyuanxuetang.net/vuln/ 一、环境部署 win7(被攻击机/关火墙) web服务器 1张外网网卡(桥接192.168.1.105)&#xff0c;一张内网网卡192.168.52.143/255.255.255.0/192.168.52.2 DNS 192.168.52.138 winser2008 域控服务器 1张…

【单片机通过蜂鸣器模拟警号 救护车 警车 等声音 】

单片机通过蜂鸣器模拟警号 救护车 警车 等声音 模拟原理实现代码 模拟原理 该函数利用定时器中断&#xff0c;通过改变 u16Compare 的值&#xff0c;并使用 Adt_SetPeriodBuf 和 Adt_SetCompareValue 函数调整定时器的周期和比较值&#xff0c;产生不同类型的声音。 SoundType…

实现linux硬盘smart检测

一、下载交叉编译libatasmart库 下载链接&#xff1a;https://www.linuxfromscratch.org/blfs/view/svn/general/libatasmart.html libatasmart库编译依赖libudev库&#xff0c;交叉编译器前先准备依赖的libudev: 设置libudev的环境变量&#xff0c;并通过configure编译文件生…

蓝桥杯算法|基础笔记(1)

**时间复杂度** 一、概念理解 时间复杂度是用来衡量算法运行时间随输入规模增长而增长的量级。它主要关注的是当输入规模趋向于无穷大时&#xff0c;算法执行基本操作的次数的增长趋势&#xff0c;而不是精确的运行时间。 二、分析代码中的基本操作 确定关键操作 在一段代码…

Uniapp判断设备是安卓还是 iOS,并调用不同的方法

在 UniApp 中&#xff0c;可以通过 uni.getSystemInfoSync() 方法来获取设备信息&#xff0c;然后根据系统类型判断当前设备是安卓还是 iOS&#xff0c;并调用不同的方法。 示例代码 export default {onLoad() {this.checkPlatform();},methods: {checkPlatform() {// 获取系…

K8S 节点选择器

今天我们来实验 pod 调度的 nodeName 与 nodeSelector。官网描述如下&#xff1a; 假设有如下三个节点的 K8S 集群&#xff1a; k8s31master 是控制节点 k8s31node1、k8s31node2 是工作节点 容器运行时是 containerd 一、镜像准备 1.1、镜像拉取 docker pull tomcat:8.5-jre8…

【Go】:深入解析 Go 1.24:新特性、改进与最佳实践

前言 Go 1.24 尚未发布。这些是正在进行中的发布说明。Go 1.24 预计将于 2025 年 2 月发布。本文将深入探讨 Go 1.24 中引入的各项更新&#xff0c;并通过具体示例展示这些变化如何影响日常开发工作&#xff0c;确保为读者提供详尽而有价值的参考。 新特性及改进综述 HTTP/2 …

macos arm 本地/docker/本地k8s 安装jupyterhub 并登陆

概述 很多文章写的启动官方docker镜像后,新建linux用户即可直接登录,不知道是否版本原因,总之目前最新版我亲测不可以,踩坑两天,这里记录下解决过程,以及各种细节在文档中的位置.以及为什么官方镜像不能直接使用的原因. part1 本地安装jupyterhub https://jupyterhub.readth…

Multi-Agent如何设计

文章小结 研究背景和目的 在单一大语言模型长期主导人工智能领域的背景下&#xff0c;多智能体系统在对话任务解决中逐渐崭露头角。 虽然先前的研究已经展示了多智能体系统在推理任务和创造性工作中的潜力&#xff0c;但对于其在对话范式方面的局限性以及单个智能体的影响&am…

Web端实时播放RTSP视频流(监控)

一、安装ffmpeg: 1、官网下载FFmpeg: Download FFmpeg 2、点击Windows图标,选第一个:Windows builds from gyan.dev 3、跳转到下载页面: 4、下载后放到合适的位置,不用安装,解压即可: 5、配置path 复制解压后的\bin路径,配置环境变量如图: <

Linux 机器学习

Linux 机器学习是指在 Linux 操作系统环境下进行机器学习相关的开发、训练和应用。 具体步骤 环境搭建&#xff1a; 选择合适的 Linux 发行版&#xff1a;如 Ubuntu、Fedora、Arch Linux 等。Ubuntu 因其易用性和丰富的软件包管理系统&#xff0c;适合初学者&#xff1b;Fed…

keepalived双机热备(LVS+keepalived)实验笔记

目录 前提准备&#xff1a; keepalived1&#xff1a; keepalived2&#xff1a; web1&#xff1a; web2&#xff1a; keepalived介绍 功能特点 工作原理 应用场景 前提准备&#xff1a; 准备4台centos&#xff0c;其中两台为keepalived&#xff0c;两台为webkeepalive…

CentOS 7 下 Nginx 的详细安装与配置

1、安装方式 1.1、通过编译方式安装 下载Nginx1.16.1的安装包 https://nginx.org/download/nginx-1.16.1.tar.gz 下载后上传至/home目录下。 1.2、通过yum方式安装 这种方式安装更简单。 2、通过编译源码包安装Nginx 2.1、安装必要依赖 sudo yum -y install gcc gcc-c sudo…