321.三国势力划分问题
问题描述
小C在一个大小为 n * m 的棋盘状土地上发现了三个国家的势力分布s。每个格子上都有一个数字,表示该格子的归属国家。上下左右相邻且属于同一个国家的格子被认为是同一股势力。现在小C想知道,这片土地上总共有多少股不同的势力。
你需要编写一个程序来计算土地上总共的势力股数。
测试样例
样例1:
输入:
n = 4 ,m = 4 ,s = ["1122", "1222", "3111", "3333"]
输出:4
样例2:
输入:
n = 2 ,m = 2 ,s = ["11", "11"]
输出:1
样例3:
输入:
n = 3 ,m = 3 ,s = ["123", "123", "123"]
输出:3
思路
需要计算一个 n * m 的棋盘上有多少个不同的势力区域,每个格子的数字表示所属的国家,两个数字相同并且相邻的格子属于同一股势力。等价于寻找一个图的连通分量问题,使用简单的搜索算法即可。
- 初始化一个与棋盘相同大小的布尔数组
visited,记录每个格子是否被访问过。 - 遍历棋盘的每一个格子,如果该格子没有被访问过,则从该格子开始进行 DFS 或 BFS,遍历所有与其连通的格子,并将它们标记为已访问。
- 每次进行 DFS 或 BFS 时,势力区域数增加 1。
代码实现
def solution(n, m, s):
# 将字符串s转换为二维数组
grid = [list(row) for row in s]
# 初始化一个访问标记数组
visited = [[False] * m for _ in range(n)]
# DFS 辅助函数
def dfs(x, y):
# 标记当前格子为已访问
visited[x][y] = True
# 四个方向的移动 (上下左右)
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
# 遍历四个方向
for dx, dy in directions:
nx, ny = x + dx, y + dy
# 检查新的坐标是否在范围内,并且未访问且与当前格子的国家相同
if 0 <= nx < n and 0 <= ny < m and not visited[nx][ny] and grid[nx][ny] == grid[x][y]:
dfs(nx, ny)
# 计算连通区域的个数
force_count = 0
for i in range(n):
for j in range(m):
if not visited[i][j]: # 如果当前格子没有被访问过
# 从当前格子开始进行DFS
dfs(i, j)
force_count += 1
return force_count
复杂度分析:
- 时间复杂度:O(n * m),其中
n是棋盘的行数,m是棋盘的列数。我们需要遍历棋盘中的每个格子,对于每个格子执行 DFS,DFS 的时间复杂度是 O(1)。 - 空间复杂度:O(n * m),主要用于存储访问标记数组
visited和递归调用栈。