目标子矩阵的数量
小M最近在研究矩阵,他对矩阵中的子矩阵很感兴趣。给定一个矩阵 matrix 和一个日标值target,他的任务是找到所有总和等于日标值的非空了知阵的数量。
子矩阵通过选择矩阵的某个矩形区域定义,形式为(x1,y1,x2,y2),其中(x1,y1)表示左上角的坐标,(x2,y2)表示右下角的坐标。一个子矩阵包含短阵中所有位于这个矩形区域内的单元格。如果两个子短阵的坐标不同(如 x1 != x1'或 y1 != y1'),则这两个子短阵被认为是不同的。
你需要返回满足条件的子矩阵数量。
测试样例
样例1:
输入:matrix=[[-1,1,0],[1,1,1],[0,1,0]] ,target = @输出:7
样例2:
输入:matrix=[[-1,-1],[-1,1]],target = 0
输出:2
样例3:
输入:matrix=[[-1,2,3],[4,5,6],[7,8,9]],target = 10
输出:2
解题思路
- 初始化变量:
-
rows:矩阵的行数。cols:矩阵的列数。count:用于记录满足条件的子矩阵数量。
- 外层循环 (
x1和y1):确定子矩阵的左上角坐标。
-
x1从 0 到rows-1,表示子矩阵可能的起始行。y1从 0 到cols-1,表示子矩阵可能的起始列。
- 内层循环 (
x2和y2):确定子矩阵的右下角坐标。
-
x2从x1到rows-1,表示子矩阵可能的结束行,必须大于等于x1。y2从y1到cols-1,表示子矩阵可能的结束列,必须大于等于y1。
- 计算子矩阵的和:
-
- 使用列表推导式
sum(matrix[i][j] for i in range(x1, x2+1) for j in range(y1, y2+1))来计算当前子矩阵的元素和。 - 这个列表推导式会遍历子矩阵中的所有元素,并将它们相加。
- 使用列表推导式
- 判断和是否等于目标值:
-
- 如果计算出的子矩阵和等于
target,则count加一。
- 如果计算出的子矩阵和等于
- 返回结果:
-
- 循环结束后,返回
count,即满足条件的子矩阵数量。
- 循环结束后,返回
算法复杂度:
- 时间复杂度:O(n^4),其中 n 是矩阵的边长。这是因为我们有两层循环来确定子矩阵的起始点(
x1,y1),另外两层循环来确定子矩阵的结束点(x2,y2)。 - 空间复杂度:O(1),除了输入矩阵外,我们只需要常数级别的额外空间来存储计数器和循环变量。
性能考虑:
- 这个算法在小矩阵上运行良好,但对于大矩阵,由于其高时间复杂度,可能会非常慢。
- 在实际应用中,可能需要更高效的算法,如使用前缀和、哈希表或其他数据结构来优化子矩阵和的计算。
优化思路:
- 可以使用前缀和数组来减少计算子矩阵和的时间,将时间复杂度降低到 O(n^3)。
- 可以使用哈希表来存储已经计算过的子矩阵和,以避免重复计算,这可能会进一步优化性能
代码实现
def solution(matrix: list, target: int) -> int:
rows = len(matrix)
cols = len(matrix[0])
count = 0
for x1 in range(rows):
for y1 in range(cols):
for x2 in range(x1, rows):
for y2 in range(y1, cols):
current_sum = sum(matrix[i][j] for i in range(x1, x2+1) for j in range(y1, y2+1))
if current_sum == target:
count += 1
return count
if __name__ == '__main__':
print(solution(matrix=[[-1, 1, 0], [1, 1, 1], [0, 1, 0]], target=0) == 7)
print(solution(matrix=[[-1, -1], [-1, 1]], target=0) == 2)
print(solution(matrix=[[-1, 2, 3], [4, 5, 6], [7, 8, 9]], target=10) == 2)
出现最多的质数判断
给定一个由小写字母组成的字符串s,要求统计每个字符出现的次数,并判断出现次数最多的字符的出现次数是否为质数。如果是质数,则输出“YES”,否则输出“NO”。
以下步骤进行:
- 字符频率统计:遍历字符串,使用一个字典(或哈希表)来记录每个字符出现的次数。
- 找出最大频率:在字典中找到出现次数最多的字符及其次数。
- 质数判断:编写一个函数来判断一个数是否为质数。
- 输出结果:根据最大频率是否为质数,输出 "YES" 或 "NO"。
下面是具体的解答思路:
步骤1: 字符频率统计
- 初始化一个空字典
frequency。 - 遍历字符串
s中的每个字符char。 - 对于每个字符,如果它不在
frequency字典中,添加它并设置其计数为1。 - 如果它已经在字典中,将其计数加1。
步骤2: 找出最大频率
- 初始化两个变量
max_count和max_char来存储出现次数最多的字符及其次数。 - 遍历
frequency字典,比较每个字符的计数,更新max_count和max_char。
步骤3: 质数判断
- 编写一个函数
is_prime(n)来判断一个数n是否为质数。 - 如果
n小于2,返回False。 - 从2到
sqrt(n)(包括2),检查n是否能被任何数整除。如果能,返回False。 - 如果没有找到除数,返回
True。
步骤4: 输出结果
- 使用
is_prime函数检查max_count是否为质数。 - 如果是,输出 "YES";否则,输出 "NO"。
代码实现
from collections import Counter
from math import sqrt
def is_prime(num):
"""判断一个数是否为质数"""
if num <= 1:
return False
for i in range(2, int(sqrt(num)) + 1):
if num % i == 0:
return False
return True
def solution(s: str) -> str:
# 统计每个字符出现的次数
count = Counter(s)
# 找到出现次数最多的字符的次数
max_count = max(count.values())
# 判断这个次数是否为质数
if is_prime(max_count):
return "YES"
else:
return "NO"
if __name__ == '__main__':
print(solution("abccckjskw") == "YES")
print(solution("qwqwtttqqttttt") == "NO")
print(solution("aabbbccddd") == "YES")
print(solution("xyzzzz") == "NO")
print(solution("mmnnooo") == "YES")