解决LeetCode题库第3044题出现频率最高的质数问题

文章讨论了如何通过遍历二维矩阵并遵循特定路径生成数字,然后筛选出大于10的质数,找出出现频率最高的质数。涉及到了编程技巧和数学逻辑。
摘要由CSDN通过智能技术生成

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

分析:

解决本问题要解决下面的几个小问题

  1. 给定mat二维矩阵中的任意一个点,能够找出从这个点开始沿东、东南、南、西南、西、西北、北、东北八个方向顺序产生的一系列数字
  2. 如何判定一个整数是质数
  3. 最后将mat矩阵中的每一个点用步骤1产生一系列数字合并到一个新的列表中,然后按“大于10的质数”的规则进行筛选,并统计各个数字出现的频次,输出频次最高的那个质数或频次最高且最大的那个质数

为此设计了三个函数:

  1. oneP(x,y,mat),返回一个列表,对于给定的任意一个点,按确定的八个方向生成的一系列数据,特别要注意在mat二维矩阵中按“东南、西南、西北、东北”四个斜向搜索时,要精确控制搜索的范围,防止出现index out of range的错误,最好反复测试,直到输入矩阵中每一个点都能够得到正确结果
  2. prime(x),如果x是质数,返回True,否则返回False
  3. 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

感悟:

有时知道解决问题的方法,但如果不够细心也是难以完成任务的。逻辑严密,分析细心,养成良好的数据处理习惯,才能最后成功。

  • 19
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值