📜  在给定的矩阵中查找山脉的数量(1)

📅  最后修改于: 2023-12-03 14:51:32.852000             🧑  作者: Mango

在给定的矩阵中查找山脉的数量

介绍

本题要求在一个二维矩阵中查找山脉的数量,其中山脉被定义为从左上角到右下角至少有一条由相邻格子上下左右连接的递增路径,并且从右下角到左上角至少有一条由相邻格子上下左右连接的递减路径。例如以下矩阵:

1 4 7 
2 5 8 
3 6 9 

其中就包含了一个山脉。本题要求实现一个函数,输入一个矩阵,输出其中山脉的数量。

解法

本题可以使用DFS和BFS两种方式来实现。

DFS

DFS的基本思路为,从左上角开始遍历整个矩阵,对于当前格子,分别检查其上下左右四个方向是否可以前往,并且判断前往的那个格子是否满足递增或递减的条件。对于已经访问过的格子,需要将其打上标记,以免重复访问。

具体实现时,可以使用一个visited数组记录每个格子是否已经被访问过,以及一个helper函数来检查格子是否符合条件。在实现过程中,需要注意递归的终止条件、visited数组的传递方式、以及标志位的重置等问题。

代码示例:

def countMountainsDFS(matrix):
    if not matrix:
        return 0

    m, n = len(matrix), len(matrix[0])
    visited = [[False] * n for _ in range(m)]

    def helper(i, j, isIncreasing):
        # check if current cell is within the matrix
        if i < 0 or i >= m or j < 0 or j >= n:
            return False
        # check if current cell is already visited
        if visited[i][j]:
            return False
        # check if current cell is increasing or decreasing
        if (isIncreasing and (i == 0 or matrix[i][j] <= matrix[i-1][j])) or \
                (not isIncreasing and (j == 0 or matrix[i][j] <= matrix[i][j-1])):
            return False
        # mark current cell as visited
        visited[i][j] = True
        # continue searching in all four directions
        up = helper(i-1, j, isIncreasing)
        down = helper(i+1, j, isIncreasing)
        left = helper(i, j-1, isIncreasing)
        right = helper(i, j+1, isIncreasing)
        # backtracking
        visited[i][j] = False
        # return True if current cell is mountain peak
        return up or down or left or right

    count = 0
    # search for increasing mountains
    for i in range(m):
        for j in range(n):
            if helper(i, j, True):
                count += 1
    # search for decreasing mountains
    for i in range(m-1, -1, -1):
        for j in range(n-1, -1, -1):
            if helper(i, j, False):
                count += 1

    return count
BFS

BFS的基本思路为,从左上角开始将整个矩阵作为一个图进行遍历,使用一个队列存储待遍历的格子,对于队首格子,分别检查其上下左右四个方向是否可以前往,并且将可前往的格子加入队列。BFS的优点是可以避免递归过程中出现栈溢出的情况,但其代码实现会稍微复杂一些。

代码示例:

def countMountainsBFS(matrix):
    if not matrix:
        return 0

    m, n = len(matrix), len(matrix[0])
    visited = [[False] * n for _ in range(m)]

    def helper(i, j, isIncreasing):
        q = [(i, j)]
        visited[i][j] = True

        while q:
            x, y = q.pop(0)
            # check if current cell is increasing or decreasing
            if (isIncreasing and (x > 0 and matrix[x][y] <= matrix[x-1][y])) or \
                    (not isIncreasing and (y > 0 and matrix[x][y] <= matrix[x][y-1])):
                continue
            # continue searching in all four directions
            if x > 0 and not visited[x-1][y]:
                q.append((x-1, y))
                visited[x-1][y] = True
            if x < m-1 and not visited[x+1][y]:
                q.append((x+1, y))
                visited[x+1][y] = True
            if y > 0 and not visited[x][y-1]:
                q.append((x, y-1))
                visited[x][y-1] = True
            if y < n-1 and not visited[x][y+1]:
                q.append((x, y+1))
                visited[x][y+1] = True

        return True

    count = 0
    # search for increasing mountains
    for i in range(m):
        for j in range(n):
            if not visited[i][j] and helper(i, j, True):
                count += 1
    # search for decreasing mountains
    visited = [[False] * n for _ in range(m)]
    for i in range(m-1, -1, -1):
        for j in range(n-1, -1, -1):
            if not visited[i][j] and helper(i, j, False):
                count += 1

    return count
总结

本题可以使用DFS和BFS两种方式来实现,其中DFS实现简单但有栈溢出的风险,BFS实现稍微复杂但可以避免栈溢出的情况。在实现过程中需要注意递归的终止条件、visited数组的传递方式、以及标志位的重置等问题。