题目描述
给定一个 m x n 的非负整数矩阵来表示一片大陆上各个单元格的高度。“太平洋”处于大陆的左边界和上边界,而“大西洋”处于大陆的右边界和下边界。
规定水流只能按照上、下、左、右四个方向流动,且只能从高到低或者在同等高度上流动。
请找出那些水流既可以流动到“太平洋”,又能流动到“大西洋”的陆地单元的坐标。
提示:
输出坐标的顺序不重要 m 和 n 都小于150
示例
示例:
给定下面的 5x5 矩阵:
来源:力扣(LeetCode)
链接:leetcode-cn.com/problems/pa…
实现
// 4个方向进行遍历
void dfs(int **matrix, int x, int y, int **flow, int matrixSize, int *matrixColSize)
{
int area[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; // 表示坐标可以移动的方向,(i不变,j+1或j-1; j不变,i+1或i-1)
for (int i = 0; i < 4; i++) {
int newX = x + area[i][0];
int newY = y + area[i][1];
if (newX < 0 || newX >= matrixSize || newY < 0 || newY >= matrixColSize[0]) {
continue;
}
if (flow[newX][newY] == 0 && matrix[newX][newY] >= matrix[x][y]) {
flow[newX][newY] = 1;
dfs(matrix, newX, newY, flow, matrixSize, matrixColSize);
}
}
}
int **pacificAtlantic(int **matrix, int matrixSize, int *matrixColSize, int *returnSize, int **returnColumnSizes)
{
*returnSize = 0;
if (matrix == NULL || matrixSize == 0) {
returnColumnSizes = NULL;
return NULL;
}
// 分配空间以及初始化
int **pacificFlow = (int **)malloc(matrixColSize[0] * matrixSize * sizeof(int*)); // 标记是否可流到太平洋
if (pacificFlow != NULL) {
memset(pacificFlow, 0 , matrixColSize[0] * matrixSize * sizeof(int*));
}
int **atlanticFlow = (int **)malloc(matrixColSize[0] * matrixSize * sizeof(int*)); // 标记是否可流到大西洋
if (atlanticFlow != NULL) {
memset(atlanticFlow, 0 , matrixColSize[0] * matrixSize * sizeof(int*));
}
// 初始化
for (int i = 0; i < matrixSize; i++) {
pacificFlow[i] = (int*)malloc(matrixColSize[0] * sizeof(int));
memset(pacificFlow[i], 0 , matrixColSize[0] * sizeof(int));
atlanticFlow[i] = (int*)malloc(matrixColSize[0] * sizeof(int));
memset(atlanticFlow[i], 0 , matrixColSize[0] * sizeof(int));
}
// 返回结果的指针分配空间及初始化
*returnColumnSizes = (int*)malloc(sizeof(int) * matrixColSize[0] * matrixSize);
int **result = (int**)malloc(sizeof(int*) * matrixColSize[0] * matrixSize);
if (result != NULL) {
memset(result, 0 , matrixColSize[0] * matrixSize * sizeof(int*));
}
// DFS 从太平洋和大西洋(4个边界)分别往中间进行搜索(下一个节点的满足条件是比该节点的值大),用2个数组分别记录每一个点是否可以流向2个大洋,
// 最后对2个数组进行遍历,找到满足要求的点。
for (int i = 0; i < matrixSize; i++) {
for (int j = 0; j < matrixColSize[0]; j++) {
if ((i == 0 || j == 0) && (pacificFlow[i][j] == 0)) { // 从上方和左方出发
pacificFlow[i][j] = 1;
dfs(matrix, i, j, pacificFlow, matrixSize, matrixColSize);
}
if ((i == matrixSize - 1 || j == matrixColSize[0] - 1) && (atlanticFlow[i][j] == 0)) { // 从下方和右方出发
atlanticFlow[i][j] = 1;
dfs(matrix, i, j, atlanticFlow, matrixSize, matrixColSize);
}
}
}
// 结果中atlanticFlow和pacificFlow对应位置都为1时,表明可以到达两条河
for (int i = 0; i < matrixSize; i++) {
for (int j = 0; j < matrixColSize[0]; j++) {
if (pacificFlow[i][j] == 1 && atlanticFlow[i][j] == 1) {
result[*returnSize] = (int*)malloc(sizeof(int) * 2);
result[*returnSize][0] = i;
result[*returnSize][1] = j;
(*returnSize)++;
}
}
}
for (int i = 0; i < (*returnSize); i++) {
(*returnColumnSizes)[i] = 2;
}
return result;
}