输入一段不减的整数,如11111223333,怎么快速计算重复次数最多的那个数
输入
一段不减整数,如:11111223333
输出
出现次数最多的那个数字,如:本例中1的出现次数最多,输出1
输入的数字具有以下规律
1.数字为正整数,不一定从1开始
2.如果增长,则increment = 1
3.整数的总量不会超过1W,但是事先无法知道总共会输入多少整数
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
这题不用对所有数字计数,那样很慢。
如果增长,则increment = 1
把数字当作字符串来处理,只要找出所有增长的点的位置就可以了,然后把相邻的点的位置相减,即可得到长度。
因为不一定是从1开始,所有可能的增长的点为:"12","23","34",。。。"78","89"
例如:
将11111223333转为字符串,查找增长点
结果:12-位置4,23-位置6
增长点补正(加1):12-位置5,23-位置7
初始位置补0,末尾补字符串长度len,得到
[0,5,7,11]
取相邻两点之差
[5,2,4]
所以,出现次数最多的是第一个元素,5次
以下为6/14日更新
@刀之魂 和 @tedBear 的想法很棒,比我原来的回答好多了。
受大家的启发,我来更新一个不需要遍历的算法:
由于increment = 1,所以看开头和结尾2个数,即可算出出现数字有几种
(如11111223333,开头为1,结尾为3,则出现的数为1到3,共3种)
那么,考虑出现N种数的情况
N=1就不用说了,等于白送答案。
先从简单的N=2说起吧,因为有些细节在N=2的情况说了,后面N>2的情况类似的细节就省略了。
N=2
2分采样
若len为奇数,取len/2处的数,这个数就是出现次数最多的数。
若len为偶数,len/2处是间隙,所以取该间隙前后2个数,这2个数相同的话,答案就是这个数,如果不同的话,答案是这两个数出现次数一样,并列最多。
N>2
N分采样,取0、len/N、2len/N、...、(N-1)len/N、len处的(N+1)个点,(由于间隙的情况太复杂,这里省略,请参考N=2的处理方法)
然后统计这(N+1)个点里面,出现次数最多的数,把出现次数最多的数叫做M1,出现第二多的叫做M2,依次类推
若 (M1的次数 - M2次数) 大于等于2,则答案为M1
若 (M1的次数 - M2次数) 小于2,那么
2N分采样(若2N>len,则len分采样),取len/2N、3len/2N、5len/2N、。。。。、处的N个点,与前面N分法时候取的(N+1)个点组合,重新求M1,M2,。。。。
若 (M1的次数 - M2次数) 大于等于2,则答案为M1
若 (M1的次数 - M2次数) 小于2,
则4N分采样(若4N>len,则len分采样)
。。。。依次类推,8N,16N。。。。
直至找到 (M1的次数 - M2次数) 大于等于2为止。其中若变为len分采样,结束条件不需要(M1的次数 - M2次数)大于等于2,M1就是答案。
小结
这个算法大部分时候是比较快的,最差的情况是N个数的各个次数都相差很小,或者都相同,那就会进入最后的len分采样,等于遍历,那还不如一开始就直接遍历比较快。
但是数据的分布越是不均匀,这个算法就越快。
杂谈
写完这个算法之后,我觉得有似曾相识的感觉,大家了解通信原理的有没有一样的感觉?
如果把这段不减整数映射到频域,那么这就是递增阶梯的方波,问题就是确定其最长一段方波,如果这个方波太长,数据量太大,我们可以对其特征点采样来压缩数据,根据奈奎斯特采样定理(或者叫香农采样定理):
上文的2N分采样与此正好相似,是不是很有趣~
(描述的比较乱,大家如果有建议请指正)
不减整数是什么意思?
除了这两点你需要的就是一个大小为10的数组,然后foreach每个字符统计一个就好了。
二分。
看题意好像只有0-9这10个数,但如果输入是个数组那就不一定了。
如果只有0-9,假如一共有n个数字,那么重复最多的那一段必然会比 n/10 多,则可以以这个步长把区间分成 10 段,重复最多数字在某些区间一定上下界相等,用这个可以加快查找速度。
如果不是只有0-0,而数字大量重复,则复杂度可以达到O(logn),最坏情况是O(n)。
遍历每一个数字显然没利用到非降序这个条件,面试的时候必然被pass……
python3
@一代键客
方法不错 但是查找也时扫全部 如果数量大就麻烦了 比如 到 1000000 空间复杂度就时1000000 还不如 跳着查 这样效率可能比较高
例如:
假设现在暂存1是最多出现次数且
12-位置是X 1出现次数为Y 直接调到 X+Y位进行判断
if(f(X+Y)==2){
}else if(f(X+Y)>2){
}
提供一种最基础的方法,用javascript实现的findMaxCountNum函数如下:
'11111223333'.match(/(d)1+/g) =>
["11111", "22", "3333"]
写个循环 顶多也就9个字符串 比较下长度那个最长