题意

给定n个数构成的数字,我们定义一个k-amazing数的概念。如果数a同时出现在数组中所有k个连续元素构成的序列当中,并且a是其中最小的那个,那么就称为a是一个k-amazing数字。
我们抽象一下,其实有两个条件,第一个条件是同时出现。我们假设数组是[1, 2, 3, 4, 5],当k=3时,我们可以找到的序列是[1, 2, 3], [2, 3, 3], [3, 4, 5]。这三个序列当中的共有元素是3,并且只有3,所以3就是一个k-amazing数。第二个条件是最小,如果这样的数字可以找到多个,只有最小的那个数字才是k-amazing数。
现在给定数组a,要求所有的1-n的k-amazing数。

样例

题解

这道题的题意倒是挺明确的,没什么含糊不清的情况。但是我们分析一下会发现,想要顺着题意去解决是不可能的。因为我们没有什么特别好的方法可以快速寻找多个集合当中的交集,并且查询到交集之后还需要分析交集当中的最小值。
也尝试过引入线段树或者是树状数组等数据结构,依然一无所获。最后能够解出来其实挺取巧的,是因为注意到了一个细节,这个细节就是元素的范围,题目当中给定的是
。这和我们以往的题目都不太一样,一般来说都会给定一个具体的值作为范围,而不是给定一个变量。
如果有过一定算法题基础和经验的同学,注意到这个应该能想到桶排序或者是基数排序。如果我们保证所有的元素都小于数组的长度,那么我们可以用一种很取巧的方式来完成排序。
我们直接来看代码:

a = [4, 3, 2, 5, 1]
ret = []
base = [0 for _ in range(6)]for i in a:base[i] += 1for i in range(6):if base[i] > 0:for j in range(base[i]):ret.append(i)

这个算法的复杂度是
,要比一般的排序算法更快,因为我们利用了下标的天然有序性。顺着这条线我想到了问题的关键,发现我们一开始的思路其实走入了误区。

思维误区与提示

这道题最大的trick就是我们对于算法的初印象,我一直在想一种方法可以快速地根据k求出k-amazing数。然后我发现情况非常复杂,并且涉及到集合的处理,比较麻烦。
这道题需要我们反其道而行之,并不是根据k去寻找k-amazing数,而是根据一个数在数组当中出现的分布,来判断它可以构成什么k-amazing。这也是为什么所有出现的数要小于n的原因,并不是说一定要小于n才有解,而是为了给我们一个思维提示。
我简单来解释一下这其中的原理,大家立刻就明白了,其实非常非常简单,有点像是魔术师用很简单的障眼法欺骗了我们的感觉。

我们假设上面这条线是题目给定的数组,我们假设其中某一个数m出现了3次,分别是a1, a2和a3。那么请问,如果m是一个k-amazing数,这个k应该至少是多大?
很简单,应该是
,我们肉眼观察一下应该是a2-a1,那么我们画出来应该是这样的:

其实就是简单的区间覆盖问题,如果k小于这个值,那么a1到a2中间的部分一定无法满足。你可能还是会觉得有问题,不对啊,我们要找的是最小值,你怎么能知道这个m是不是最小的呢?
这个问题也非常简单,我们只需要按照顺序从小到大去寻找k,那么第一个找到的一定就是答案。想明白了之后有没有醍醐灌顶,有没有豁然开朗的感觉?是不是还有我居然想到了,又有一点觉得自己早就应该想到了的矛盾感?这也是做算法题的乐趣所在,所谓的难者不会,会者不难,体现得淋漓尽致。
不过还有一个小trick,有可能对于有些k我们找不到答案,但是它并不一定不存在。这也很好理解,我们假设找到了k=3时的答案是m,我们没有直接找到间隔是4的数,那么问题来了,m满不满足k=4呢?当然是满足的,因为小的间隔都能成立,大的间隔一定也可以。
最后,贴上代码:

from collections import defaultdictt = int(input())for _ in range(t):n = int(input())arr = list(map(int, input().split(' ')))# 我们要记录元素的出现位置,会有多个,所以要用map[int]list的结构dt = defaultdict(list)for i, v in enumerate(arr):dt[v].append(i)ret = [-1 for _ in range(n+2)]for i in range(1, n+1):if i not in dt:continue# 由于下标是0开始的,所以第一段区间长度是下标+1tmp = dt[i][0] + 1# 寻找元素i出现的最大间隔for idx in range(1, len(dt[i])):tmp = max(tmp, dt[i][idx] - dt[i][idx-1])tmp = max(tmp, n - dt[i][-1])# 如果这个长度的答案没有出现过,就赋值if ret[tmp] == -1:ret[tmp] = i# 如果m是k-amazing数,那么它也是k+1-amazing数for i in range(2, n+1):if ret[i-1] == -1:continueif ret[i] == -1 or ret[i] > ret[i-1]:ret[i] = ret[i-1]print(' '.join(map(str, ret[1: n+1])))

这题非常有趣,强烈建议大家都试着做一下。

牛客网-数据结构笔试题目(七)-k-amazing数字求解相关推荐

  1. 牛客网-数据结构笔试题目(一)-猫咪特征提取思路解析(附源码)

    题意 小明是一名算法工程师,同时也是一名铲屎官.某天,他突发奇想,想从猫咪的视频里挖掘一些猫咪的运动信息.为了提取运动信息,他需要从视频的每一帧提取"猫咪特征".一个猫咪特征是一个 ...

  2. 牛客网-数据结构笔试题目(八)-离子能力跃迁问题求解

    题意 有一个人在玩一个离子激活的游戏,题目的背景是模拟的化学当中的离子能量跃迁.在化学当中,离子吸收能量可以从低能态跃迁到高能态,并且放出一定的能量. 现在有N粒离子排成一排(下标1-N),每一个离子 ...

  3. 牛客网-数据结构笔试题目(五)-动态规划问题求解

    题意 给定n个整数,对于这n个整数我们可以采取两种操作.第一种操作是在数组左侧选择连续的k个整数减1,第二种操作是选择右侧的连续k个整数减1. 比如假设数组是[3, 2, 2, 1, 4],比如我们选 ...

  4. 牛客网-数据结构笔试题目(四)-Powerful Ksenia问题解决方案(附源码)

    题意 现在我们想要在n步这样的神奇异或操作之内让数组当中的所有元素全部相等,请问这一点是否可能呢?首先输出YES或NO,表示是否有解.如果有解输出需要操作的步数,以及对应选择的元素下标. 样例 在第一 ...

  5. 牛客网-数据结构笔试题目(三)-博弈论圆圈游戏(Circle Game)(附源码)

    题意 从前有两个人,一个叫Utkarsh,另外一个叫Ashish. 这两个人在一个2D的棋盘上玩移动棋子的游戏,一开始从原点出发,Ashish先手.每次可以把棋子向上或者是向右移动k个单位的距离.两人 ...

  6. 牛客网-数据结构笔试题目(二)-万万没想到之抓捕孔连顺思路解析(附源码)

    题意 我叫王大锤,是一名特工.我刚刚接到任务:在字节跳动大街进行埋伏,抓捕恐怖分子孔连顺.和我一起行动的还有另外两名特工,我提议 我们在字节跳动大街的N个建筑中选定3个埋伏地点. 为了相互照应,我们决 ...

  7. 牛客网-数据结构笔试题目(六)-最近点对问题求解思路

    题意 我们先来看下题意吧,题意很简单,在一个平面当中分布着n个点.现在我们知道这n个点的坐标,要求找出这n个点当中距离最近的两个点的间距. 分治法 如果我们仔细思考一下,会发现这个问题和排序其实非常类 ...

  8. 牛客网校招题题目收集----数据结构与算法篇

    选择题 a,b,c,d,e 对应出现的频率为4,6,11,13,15:以下符合哈夫曼编码的选项是?() A. a=000.b=01.c=001.d=10.e=11 B. a=000.b=001.c=0 ...

  9. 爬虫实现爬取牛客网数据结构试题

    1 目标 爬取牛客网上关于<数据结构>的试题. 试题链接 进入网页可以看到,如果选择<数据结构>的某个知识点组卷,一次最多只能出30题. 因此,想法就是用程序一次将30题全部爬 ...

最新文章

  1. SQL Server 2008中的hierarchyid
  2. 指针:自定义函数sumDiff(),调用它来求两个数的和、差
  3. Spring Boot中的一些常用配置介绍!
  4. 华中科技大学计算机卓越计划,计算机卓越计划实验班培养计划.doc
  5. java实现无序数组结构
  6. java 调用jira_java调用jira接口
  7. Lua中的操作系统库
  8. oracle 取记录最大的那条记录_新记录!国内跨高速铁路最大、吊装高度最高的钢横梁顺利吊装到位...
  9. android本地图片,Android中ImageView实现选择本地图片并显示功能
  10. 【图像去噪】基于matlab全变分算法图像去噪【含Matlab源码 1324期】
  11. Zoox 的自动驾驶汽车方法
  12. 计算机操作系统出现死锁的原因
  13. Linux学习第一节课学习心得
  14. java 实验室管理系统_java实验室设备管理系统
  15. 一文教你如何使用Mybatis Plugin 以及Druid Filer 改写SQL
  16. 疫情之后,SaaS的春天就来了吗?
  17. vue ie报错:SCRIPT5022: [vuex] vuex requires a Promise polyfill in this browser.
  18. CLI 钱包操作(十):订阅设置
  19. 获取网页内所有图片地址
  20. 大坝安全监测系统:水库“守坝人”!

热门文章

  1. 光纤收发器和协议转换器之间有哪些区别?
  2. 音频光端机的几个重要指标
  3. 高低温湿热试验箱使用的注意事项
  4. pandas 遍历并修改_Pandas循环提速7万多倍!Python数据分析攻略
  5. 修改网站首页批处理_几个神奇的批处理,万事不求人!
  6. Java集合(6)--Map接口
  7. linux启动weblogic指令,linux下如何启动和关闭weblogic .
  8. 分段概率密度矩估计_考研数学:高数、线代、概率3科目知识框架梳理
  9. 快速搭建redis单机版和redis集群版
  10. 再论EM算法的收敛性和K-Means的收敛性