刷题记录 321.三国势力划分问题

157 阅读2分钟

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 的棋盘上有多少个不同的势力区域,每个格子的数字表示所属的国家,两个数字相同并且相邻的格子属于同一股势力。等价于寻找一个图的连通分量问题,使用简单的搜索算法即可。

  1. 初始化一个与棋盘相同大小的布尔数组 visited,记录每个格子是否被访问过。
  2. 遍历棋盘的每一个格子,如果该格子没有被访问过,则从该格子开始进行 DFS 或 BFS,遍历所有与其连通的格子,并将它们标记为已访问。
  3. 每次进行 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

复杂度分析:

  1. 时间复杂度:O(n * m),其中 n 是棋盘的行数,m 是棋盘的列数。我们需要遍历棋盘中的每个格子,对于每个格子执行 DFS,DFS 的时间复杂度是 O(1)。
  2. 空间复杂度:O(n * m),主要用于存储访问标记数组 visited 和递归调用栈。