牛客网-数据结构笔试题目(七)-k-amazing数字求解
题意
给定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数字求解相关推荐
- 牛客网-数据结构笔试题目(一)-猫咪特征提取思路解析(附源码)
题意 小明是一名算法工程师,同时也是一名铲屎官.某天,他突发奇想,想从猫咪的视频里挖掘一些猫咪的运动信息.为了提取运动信息,他需要从视频的每一帧提取"猫咪特征".一个猫咪特征是一个 ...
- 牛客网-数据结构笔试题目(八)-离子能力跃迁问题求解
题意 有一个人在玩一个离子激活的游戏,题目的背景是模拟的化学当中的离子能量跃迁.在化学当中,离子吸收能量可以从低能态跃迁到高能态,并且放出一定的能量. 现在有N粒离子排成一排(下标1-N),每一个离子 ...
- 牛客网-数据结构笔试题目(五)-动态规划问题求解
题意 给定n个整数,对于这n个整数我们可以采取两种操作.第一种操作是在数组左侧选择连续的k个整数减1,第二种操作是选择右侧的连续k个整数减1. 比如假设数组是[3, 2, 2, 1, 4],比如我们选 ...
- 牛客网-数据结构笔试题目(四)-Powerful Ksenia问题解决方案(附源码)
题意 现在我们想要在n步这样的神奇异或操作之内让数组当中的所有元素全部相等,请问这一点是否可能呢?首先输出YES或NO,表示是否有解.如果有解输出需要操作的步数,以及对应选择的元素下标. 样例 在第一 ...
- 牛客网-数据结构笔试题目(三)-博弈论圆圈游戏(Circle Game)(附源码)
题意 从前有两个人,一个叫Utkarsh,另外一个叫Ashish. 这两个人在一个2D的棋盘上玩移动棋子的游戏,一开始从原点出发,Ashish先手.每次可以把棋子向上或者是向右移动k个单位的距离.两人 ...
- 牛客网-数据结构笔试题目(二)-万万没想到之抓捕孔连顺思路解析(附源码)
题意 我叫王大锤,是一名特工.我刚刚接到任务:在字节跳动大街进行埋伏,抓捕恐怖分子孔连顺.和我一起行动的还有另外两名特工,我提议 我们在字节跳动大街的N个建筑中选定3个埋伏地点. 为了相互照应,我们决 ...
- 牛客网-数据结构笔试题目(六)-最近点对问题求解思路
题意 我们先来看下题意吧,题意很简单,在一个平面当中分布着n个点.现在我们知道这n个点的坐标,要求找出这n个点当中距离最近的两个点的间距. 分治法 如果我们仔细思考一下,会发现这个问题和排序其实非常类 ...
- 牛客网校招题题目收集----数据结构与算法篇
选择题 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 ...
- 爬虫实现爬取牛客网数据结构试题
1 目标 爬取牛客网上关于<数据结构>的试题. 试题链接 进入网页可以看到,如果选择<数据结构>的某个知识点组卷,一次最多只能出30题. 因此,想法就是用程序一次将30题全部爬 ...
最新文章
- SQL Server 2008中的hierarchyid
- 指针:自定义函数sumDiff(),调用它来求两个数的和、差
- Spring Boot中的一些常用配置介绍!
- 华中科技大学计算机卓越计划,计算机卓越计划实验班培养计划.doc
- java实现无序数组结构
- java 调用jira_java调用jira接口
- Lua中的操作系统库
- oracle 取记录最大的那条记录_新记录!国内跨高速铁路最大、吊装高度最高的钢横梁顺利吊装到位...
- android本地图片,Android中ImageView实现选择本地图片并显示功能
- 【图像去噪】基于matlab全变分算法图像去噪【含Matlab源码 1324期】
- Zoox 的自动驾驶汽车方法
- 计算机操作系统出现死锁的原因
- Linux学习第一节课学习心得
- java 实验室管理系统_java实验室设备管理系统
- 一文教你如何使用Mybatis Plugin 以及Druid Filer 改写SQL
- 疫情之后,SaaS的春天就来了吗?
- vue ie报错:SCRIPT5022: [vuex] vuex requires a Promise polyfill in this browser.
- CLI 钱包操作(十):订阅设置
- 获取网页内所有图片地址
- 大坝安全监测系统:水库“守坝人”!