2022-10-27:设计一个数据结构,有效地找到给定子数组的 多数元素 。 子数组的 多数元素 是在子数组中出现 threshold 次数或次数以上的元素。 实现 MajorityChecker 类
2022-10-27:设计一个数据结构,有效地找到给定子数组的 多数元素 。
子数组的 多数元素 是在子数组中出现 threshold 次数或次数以上的元素。
实现 MajorityChecker 类:
MajorityChecker(int[] arr)
会用给定的数组 arr 对 MajorityChecker 初始化。
int query(int left, int right, int threshold)
返回子数组中的元素 arr[left…right] 至少出现 threshold 次数,
如果不存在这样的元素则返回 -1。
答案2022-10-27:
线段树。
力扣1157,rust测试见图。
代码用rust编写。代码如下:
use std::iter::repeat;
struct MajorityChecker {
st: SegmentTree,
cq: CountQuicker,
}
struct SegmentTree {
n: i32,
candidate: Vec<i32>,
hp: Vec<i32>,
}
impl SegmentTree {
pub fn new(arr: &mut Vec<i32>) -> Self {
let n = arr.len() as i32;
let candidate: Vec<i32> = repeat(0).take(((n + 1) << 2) as usize).collect();
let hp: Vec<i32> = repeat(0).take(((n + 1) << 2) as usize).collect();
let mut ans = SegmentTree { n, candidate, hp };
ans.build(arr, 1, n, 1);
return ans;
}
fn build(&mut self, arr: &mut Vec<i32>, l: i32, r: i32, rt: i32) {
if l == r {
self.candidate[rt as usize] = arr[(l - 1) as usize];
self.hp[rt as usize] = 1;
} else {
let m = (l + r) >> 1;
self.build(arr, l, m, rt << 1);
self.build(arr, m + 1, r, rt << 1 | 1);
let lc = self.candidate[(rt << 1) as usize];
let rc = self.candidate[(rt << 1 | 1) as usize];
let lh = self.hp[(rt << 1) as usize];
let rh = self.hp[(rt << 1 | 1) as usize];
if lc == rc {
self.candidate[rt as usize] = lc;
self.hp[rt as usize] = lh + rh;
} else {
self.candidate[rt as usize] = if lh >= rh { lc } else { rc };
self.hp[rt as usize] = i32::abs(lh - rh);
}
}
}
pub fn query(&mut self, left: i32, right: i32) -> i32 {
return self.query0(left + 1, right + 1, 1, self.n, 1)[0];
}
fn query0(&mut self, ll: i32, rr: i32, l: i32, r: i32, rt: i32) -> Vec<i32> {
if ll <= l && r <= rr {
return vec![self.candidate[rt as usize], self.hp[rt as usize]];
}
let m = (l + r) >> 1;
if rr <= m {
return self.query0(ll, rr, l, m, rt << 1);
} else if ll > m {
return self.query0(ll, rr, m + 1, r, rt << 1 | 1);
} else {
let mut ansl = self.query0(ll, rr, l, m, rt << 1);
let mut ansr = self.query0(ll, rr, m + 1, r, rt << 1 | 1);
if ansl[0] == ansr[0] {
ansl[1] += ansr[1];
return ansl;
} else {
if ansl[1] >= ansr[1] {
ansl[1] -= ansr[1];
return ansl;
} else {
ansr[1] -= ansl[1];
return ansr;
}
}
}
}
}
struct CountQuicker {
cnt: Vec<Vec<i32>>,
}
impl CountQuicker {
pub fn new(arr: &mut Vec<i32>) -> Self {
let mut cnt: Vec<Vec<i32>> = vec![];
let max = *arr.iter().max().unwrap_or(&0);
for _i in 0..=max {
cnt.push(vec![]);
}
for i in 0..arr.len() as i32 {
cnt[arr[i as usize] as usize].push(i);
}
return Self { cnt };
}
pub fn real_times(&mut self, left: i32, right: i32, num: i32) -> i32 {
self.size(num, right) - self.size(num, left - 1)
}
fn size(&mut self, indies_index: i32, index: i32) -> i32 {
let mut l = 0;
let mut r = self.cnt[indies_index as usize].len() as i32 - 1;
let mut m: i32;
let mut ans = -1;
while l <= r {
m = (l + r) / 2;
if self.cnt[indies_index as usize][m as usize] <= index {
ans = m;
l = m + 1;
} else {
r = m - 1;
}
}
return ans + 1;
}
}
impl MajorityChecker {
fn new(arr: Vec<i32>) -> Self {
let mut arr = arr;
let st = SegmentTree::new(&mut arr);
let cq = CountQuicker::new(&mut arr);
Self { st, cq }
}
fn query(&mut self, left: i32, right: i32, threshold: i32) -> i32 {
let candidate = self.st.query(left, right);
return if self.cq.real_times(left, right, candidate) >= threshold {
candidate
} else {
-1
};
}
}
fn main() {
let arr = vec![1, 1, 2, 2, 1, 1];
let mut majority_checker = MajorityChecker::new(arr);
let ans = majority_checker.query(0, 5, 4); // 返回 1
println!("ans = {:?}", ans);
let ans = majority_checker.query(0, 3, 3); // 返回 -1
println!("ans = {:?}", ans);
let ans = majority_checker.query(2, 3, 2); // 返回 2
println!("ans = {:?}", ans);
}
执行结果如下:


2022-10-27:设计一个数据结构,有效地找到给定子数组的 多数元素 。 子数组的 多数元素 是在子数组中出现 threshold 次数或次数以上的元素。 实现 MajorityChecker 类的更多相关文章
- 10.23 开课一个月零十九天 (PHP数组)
<?php $s = "he8llo5wor6ld"; $s = preg_replace("/\d/","#",$s); //按照正 ...
- 2017.12.10 Java写一个杨辉三角(二维数组的应用)
杨辉三角的定律 第n行m列元素通项公式为: C(n-1,m-1)=(n-1)!/[(m-1)!(n-m)!] 需要用到创建二维数组 package com.glut.demo; /** * 杨辉三角 ...
- 对于一个字符串,请设计一个高效算法,找到第一次重复出现的字符。 给定一个字符串(不一定全为字母)A及它的长度n。请返回第一个重复出现的字符。保证字符串中有重复字符,字符串的长度小于等于500。
// 第一种方法 // ConsoleApplication10.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include < ...
- 如何设计一个LRU Cache
如何设计一个LRU Cache? Google和百度的面试题都出现了设计一个Cache的题目,什么是Cache,如何设计简单的Cache,通过搜集资料,本文给出个总结. 通常的问题描述可以是这样: Q ...
- 设计一个简单的devops系统
前言 公司设计的RDMS挺好用的,我也照猫画虎简单的设计一个DevOps系统,与大家分享,不足之处欢迎拍砖,以免误人子弟 前置条件 gitlab gitlab-runner k8s 1. gitlab ...
- 背水一战 Windows 10 (27) - 控件(文本类): TextBlock
[源码下载] 背水一战 Windows 10 (27) - 控件(文本类): TextBlock 作者:webabcd 介绍背水一战 Windows 10 之 控件(文本类) TextBlock 示例 ...
- 笔试题&面试题:设计一个复杂度为n的算法找到单向链表倒数第m个元素
设计一个复杂度为n的算法找到单向链表倒数第m个元素.最后一个元素假定是倒数第0个. 提示:双指针查找 相对于双向链表来说,单向链表仅仅能从头到尾依次訪问链表的各个节点,所以假设要找链表的倒数第m个元素 ...
- 算法与数据结构题目的 PHP 实现:栈和队列 设计一个有 getMin 功能的栈
刚入手了一本<程序员代码面试指南>,书中题目的代码都是 Java 实现的,琢磨着把这些代码用 PHP 敲一遍,加深印象. 题目:设计一个有 getMin 功能的栈 —— 实现一个特殊的栈, ...
- python小练习,打出1-100之间的所有偶数,设计一个函数,在桌面上创建10个文件,并以数字命名,复利计算函数
练习一:打出1-100之间的所有偶数 def even_print(): for i in range(1,101): if i % 2 == 0: print (i) even_print() #列 ...
- 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。 如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润. 注意你不能在买入股票前卖出股票. 示例 ...
随机推荐
- Nginx配置ThinkPHP3.1的PATHINFO模式
location / { if (!-e $request_filename) { rewrite ^/(.*)$ /index.php?$1 last; bre ...
- ES2016-ES2020
参考:https://zhuanlan.zhihu.com/p/59096242 备注:可以使用ES6取代的10个Lodash特性 https://www.w3cplus.com/javascript ...
- Linux部分文件管理类命令
1.创建空文件和刷新时间 touch命令可以用来创建空文件或刷新文件的时间 touch [OPTION]... FILE... 选项: -a 仅改变atime和ctime -m 仅改变mtime和ct ...
- 如何使用webgl(three.js)实现3D消防、3D建筑消防大楼、消防数字孪生、消防可视化解决方案——第十八课(一)
序: 又是很久没出随笔文章了,一篇文章有时候整理一天,实在是抽不出来时间. 最近在回顾几年前的项目时,发现这个智慧三维消防可视化项目很有回顾价值,索性就拿出来讲讲. 首先,我们要知道消防里的知识,不是 ...
- 被冰封的 Bug:Fishhook Crash 修复纪实
作者:郝连福,业界资深计算机技术专家,现任声网Agora 首席前端架构师.先后担任过 Principal Engineer/Engineering Director(UTStarcom).Sr. ar ...
- .Net 7 轻松上手Dapr之服务调用
前言 对于Dapr ,在项目中也有用过一段时间,优缺点并存,但是瑕不掩瑜,目前随着版本的迭代和第三方团队对它的支持也使得我们用得更加得心应手,所以借此也回顾一下Dapr的相关知识以及分享一下项目中用到 ...
- crontab使用说明【一文搞懂Linux定时任务Crontab】
1.简介 cron是一个在后台运行调度的守护进程,而crontab是一个设置cron的工具.cron调度的是/etc/crontab文件. 2.centos安装crontab yum install ...
- C++中va_list, va_start, va_arg, va_end的基本用法
关于va_list, va_start, va_arg, va_end 由于在C语言中没有函数重载,解决不定数目函数参数问题变得比较麻烦,即使采用C++,如果参数个数不能确定,也很难采用函数重载.对这 ...
- [Linux]常用命令之【top/uptime/w/vmstat/free】
1 top 语法:top [-s time] [-d count] [-q] [-u] [-h] [-n number] [-f filename] -s time 设置屏幕刷新的延时,单位为秒,默认 ...
- [数据库/Java]数据库开发过程中产生的MySQL错误代码及其解决方案
前言 吐槽一下,均是这两天遇到的破烂事儿,搞定了也好,以后出现此类问题也就放心些了. 下列遇到的问题大都是因为MySQL从5.x版本升级到8.0.11(MySQL8.0涉及重大改版)后,跟着连带着出现 ...