3044. 出现频率最高的质数
中等
问题描述:
给你一个大小为 m x n 、下标从 0 开始的二维矩阵 mat 。在每个单元格,你可以按以下方式生成数字:
最多有 8 条路径可以选择:东、东南、南、西南、西、西北、北、东北。
选择其中一条路径,沿着这个方向移动,并且将路径上的数字添加到正在形成的数字后面。
注意,每一步都会生成数字,例如,如果路径上的数字是 1, 9, 1,那么在这个方向上会生成三个数字:1, 19, 191 。
返回在遍历矩阵所创建的所有数字中,出现频率最高的、大于 10的质数;如果不存在这样的质数,则返回 -1 。如果存在多个出现频率最高的质数,那么返回其中最大的那个。
注意:移动过程中不允许改变方向。
示例 1:
输入:mat = [[1,1],[9,9],[1,1]]
输出:19
解释:
从单元格 (0,0) 出发,有 3 个可能的方向,这些方向上可以生成的大于 10 的数字有:
东方向: [11], 东南方向: [19], 南方向: [19,191] 。
从单元格 (0,1) 出发,所有可能方向上生成的大于 10 的数字有:[19,191,19,11] 。
从单元格 (1,0) 出发,所有可能方向上生成的大于 10 的数字有:[99,91,91,91,91] 。
从单元格 (1,1) 出发,所有可能方向上生成的大于 10 的数字有:[91,91,99,91,91] 。
从单元格 (2,0) 出发,所有可能方向上生成的大于 10 的数字有:[11,19,191,19] 。
从单元格 (2,1) 出发,所有可能方向上生成的大于 10 的数字有:[11,19,19,191] 。
在所有生成的数字中,出现频率最高的质数是 19 。
示例 2:
输入:mat = [[7]]
输出:-1
解释:唯一可以生成的数字是 7 。它是一个质数,但不大于 10 ,所以返回 -1 。
示例 3:
输入:mat = [[9,7,8],[4,6,5],[2,8,6]]
输出:97
解释:
从单元格 (0,0) 出发,所有可能方向上生成的大于 10 的数字有: [97,978,96,966,94,942] 。
从单元格 (0,1) 出发,所有可能方向上生成的大于 10 的数字有: [78,75,76,768,74,79] 。
从单元格 (0,2) 出发,所有可能方向上生成的大于 10 的数字有: [85,856,86,862,87,879] 。
从单元格 (1,0) 出发,所有可能方向上生成的大于 10 的数字有: [46,465,48,42,49,47] 。
从单元格 (1,1) 出发,所有可能方向上生成的大于 10 的数字有: [65,66,68,62,64,69,67,68] 。
从单元格 (1,2) 出发,所有可能方向上生成的大于 10 的数字有: [56,58,56,564,57,58] 。
从单元格 (2,0) 出发,所有可能方向上生成的大于 10 的数字有: [28,286,24,249,26,268] 。
从单元格 (2,1) 出发,所有可能方向上生成的大于 10 的数字有: [86,82,84,86,867,85] 。
从单元格 (2,2) 出发,所有可能方向上生成的大于 10 的数字有: [68,682,66,669,65,658] 。
在所有生成的数字中,出现频率最高的质数是 97 。
提示:
m == mat.length
n == mat[i].length
1 <= m, n <= 6
1 <= mat[i][j] <= 9
分析:
解决本问题要解决下面的几个小问题
- 给定mat二维矩阵中的任意一个点,能够找出从这个点开始沿东、东南、南、西南、西、西北、北、东北八个方向顺序产生的一系列数字
- 如何判定一个整数是质数
- 最后将mat矩阵中的每一个点用步骤1产生一系列数字合并到一个新的列表中,然后按“大于10的质数”的规则进行筛选,并统计各个数字出现的频次,输出频次最高的那个质数或频次最高且最大的那个质数
为此设计了三个函数:
- oneP(x,y,mat),返回一个列表,对于给定的任意一个点,按确定的八个方向生成的一系列数据,特别要注意在mat二维矩阵中按“东南、西南、西北、东北”四个斜向搜索时,要精确控制搜索的范围,防止出现index out of range的错误,最好反复测试,直到输入矩阵中每一个点都能够得到正确结果
- prime(x),如果x是质数,返回True,否则返回False
- outMax(mat),输出频次最高或频次最高且最大的那个质数
程序如下:
#给定一个点,返回产生的数据
def oneP(x,y,mat):
a=[]
a.append(mat[y][x])
m=len(mat)
n=len(mat[0])
#东
if x!=n-1:
k=mat[y][x]
for i in range(x+1,n):
k=str(k)+str(mat[y][i])
a.append(int(k))
#东南
if x!=n-1 or y!=m-1:
k=mat[y][x]
r=min(n-x,m-y)
for i in range(1,r):
k=str(k)+str(mat[y+i][x+i])
a.append(int(k))
#南
if y!=m-1:
k=mat[y][x]
for i in range(y+1,m):
k=str(k)+str(mat[i][x])
a.append(int(k))
#西南
if x!=0 or y!=m-1:
k=mat[y][x]
r=min(x,m-1-y)+1
for i in range(1,r):
k=str(k)+str(mat[y+i][x-i])
a.append(int(k))
#西
if x!=0:
k=mat[y][x]
for i in range(1,x+1):
k=str(k)+str(mat[y][x-i])
a.append(int(k))
#西北
if x!=0 or y!=0:
k=mat[y][x]
r=min(x,y)+1
for i in range(1,r):
k=str(k)+str(mat[y-i][x-i])
a.append(int(k))
#北
if y!=0:
k=mat[y][x]
for i in range(1,y+1):
k=str(k)+str(mat[y-i][x])
a.append(int(k))
#东北
if x!=n-1 or y!=0:
k=mat[y][x]
r=min(n-1-x,y)+1
for i in range(1,r):
k=str(k)+str(mat[y-i][x+i])
a.append(int(k))
return a
#判定x是否是质数
def prime(x):
for i in range(2,int(x**0.5)+1):
if x%i==0:
return False
else:
return True
#输出频次最高或频次最高且最大的质数
def outMax(mat):
#a用于存储从mat中产生的数字
a=[]
m=len(mat)
n=len(mat[0])
for i in range(m):
for j in range(n):
a.extend(oneP(j,i,mat))
print('按八个方向搜索出的原始数据:')
print(a)
#b用于存储从a中提取出的大于10的素数
b=[x for x in a if x>10 and prime(x)]
print('筛出大于10的质数数据:')
print(b)
if b==[]:
return -1
#c用于存储b中去重之后的数字
c=list(set(b))
#d统计c中各数字在b中出现的次数
d=[]
for i in c:
j=b.count(i)
d.append((i,j))
print('统计出各数出现的频次,按(质数,频次)的格式呈现:')
print(d)
#maxN用于统计最高频率次数
maxN=max(x[1] for x in d)
#count用于统计最高频率出现的次数
count=[x[1] for x in d].count(maxN)
if count==1:
return [x[0] for x in d if x[1]==maxN][0]
else:
return max([x[0] for x in d if x[1]==maxN])
mat=eval(input('mat='))
print(outMax(mat))
运行实例1
mat=[[1,3,9,7,2],[3,7,1,5,6],[4,3,1,8,9]]
按八个方向搜索出的原始数据:
[1, 13, 139, 1397, 13972, 17, 171, 13, 134, 3, 39, 397, 3972, 31, 318, 37, 373, 33, 31, 9, 97, 972, 95, 959, 91, 911, 97, 974, 93, 931, 7, 72, 76, 75, 758, 71, 713, 79, 793, 7931, 2, 26, 269, 25, 251, 27, 279, 2793, 27931, 3, 37, 371, 3715, 37156, 33, 34, 31, 33, 7, 71, 715, 7156, 71, 73, 74, 73, 71, 73, 79, 1, 15, 156, 18, 11, 13, 17, 173, 13, 19, 17, 5, 56, 59, 58, 51, 51, 517, 5173, 59, 57, 52, 6, 69, 68, 65, 651, 6517, 65173, 67, 62, 4, 43, 431, 4318, 43189, 43, 431, 47, 479, 3, 31, 318, 3189, 34, 33, 37, 373, 31, 317, 1, 18, 189, 13, 134, 17, 171, 11, 119, 15, 152, 8, 89, 81, 813, 8134, 81, 813, 85, 857, 86, 9, 98, 981, 9813, 98134, 95, 959, 96, 962]
筛出大于10的质数数据:
[13, 139, 17, 13, 397, 31, 37, 373, 31, 97, 911, 97, 71, 79, 269, 251, 37, 31, 71, 71, 73, 73, 71, 73, 79, 11, 13, 17, 173, 13, 19, 17, 59, 59, 65173, 67, 43, 431, 43189, 43, 431, 47, 479, 31, 37, 373, 31, 317, 13, 17, 11, 89, 857]
统计出各数出现的频次,按(质数,频次)的格式呈现:
[(139, 1), (11, 2), (13, 5), (397, 1), (911, 1), (269, 1), (17, 4), (19, 1), (65173, 1), (31, 5), (37, 3), (43, 2), (173, 1), (431, 2), (47, 1), (43189, 1), (59, 2), (317, 1), (67, 1), (71, 4), (73, 3), (79, 2), (89, 1), (857, 1), (479, 1), (97, 2), (373, 2), (251, 1)]
31
运行实例2
mat=[[9,7,8],[4,6,5],[2,8,6]]
按八个方向搜索出的原始数据:
[9, 97, 978, 96, 966, 94, 942, 7, 78, 75, 76, 768, 74, 79, 8, 85, 856, 86, 862, 87, 879, 4, 46, 465, 48, 42, 49, 47, 6, 65, 66, 68, 62, 64, 69, 67, 68, 5, 56, 58, 56, 564, 57, 58, 2, 28, 286, 24, 249, 26, 268, 8, 86, 82, 84, 86, 867, 85, 6, 68, 682, 66, 669, 65, 658]
筛出大于10的质数数据:
[97, 79, 47, 67]
统计出各数出现的频次,按(质数,频次)的格式呈现:
[(97, 1), (67, 1), (47, 1), (79, 1)]
97
感悟:
有时知道解决问题的方法,但如果不够细心也是难以完成任务的。逻辑严密,分析细心,养成良好的数据处理习惯,才能最后成功。