题目描述
给定一个由 0 和 1 组成的矩阵 mat ,请输出一个大小相同的矩阵,其中每一个格子是 mat 中对应位置元素到最近的 0 的距离。
两个相邻元素间的距离为 1 。
示例
示例 1:
输入:mat = [[0,0,0],[0,1,0],[0,0,0]]
输出:[[0,0,0],[0,1,0],[0,0,0]]
来源:力扣(LeetCode)
链接:leetcode-cn.com/problems/01…
实现
/* 解法1 bfs
int flag[4][2] = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
typedef struct {
int x;
int y;
} Point; // 节点结构体,包含横纵坐标
typedef struct {
Point data[100000];
int rear;
int front;
} MyQueue; // 队列
void initQueue(MyQueue *queue)
{
queue->front = -1;
queue->rear = -1;
memset(queue->data, 0, sizeof(queue->data));
}
void push(MyQueue *a, Point x) // 入队
{
(a->rear)++;
a->data[a->rear] = x;
}
bool isEmpty(MyQueue *a) // 判空
{
if(a->rear == a->front)
{
return true;
}
return false;
}
void pop(MyQueue* a) // 出队
{
a->front++;
}
// 找最短路径,想到bfs
int **updateMatrix(int **mat, int matSize, int *matColSize, int *returnSize, int **returnColumnSizes)
{
*returnSize = 0;
bool visited[matSize][matColSize[0]]; // 用于记录是否被访问过了,防止出现来回互相调用的情况
memset(visited, false, sizeof(visited));
int **res = (int**)malloc(sizeof(int*) * matSize); // 包含matSize个指针,每个指针都指向一个matColSize[0]大小的数组
memset(res, 0, sizeof(int*) * matSize);
for (int i = 0; i < matSize; i++) {
res[i] = (int*)malloc(sizeof(int) * matColSize[0]);
memset(res[i], 0, sizeof(int) * matColSize[0]);
}
// bfs队列
MyQueue queue;
initQueue(&queue);
for (int i = 0; i < matSize; i++) {
for (int j = 0; j <matColSize[i]; j++) {
if (mat[i][j] == 0) {
Point tmp = {i, j};
push(&queue, tmp);
visited[i][j] = true;
}
}
}
while (!isEmpty(&queue)) {
// 取队首元素,并bfs
Point tmp = queue.data[queue.front + 1];
pop(&queue); // 出队
// 对队首元素做bfs
for (int i = 0; i < 4; i++) {
Point cur;
cur.x = tmp.x + flag[i][0];
cur.y = tmp.y + flag[i][1];
if (cur.x < 0 || cur.x >= matSize || cur.y < 0 || cur.y >= matColSize[0] || visited[cur.x][cur.y] == true) {
continue;
}
// 走到这里,说明没有越界,并且没有访问过(没有访问过的肯定是1)
res[cur.x][cur.y] = res[tmp.x][tmp.y] + 1;
visited[cur.x][cur.y] = true;
push(&queue, cur);
}
}
*returnSize = matSize;
*returnColumnSizes = (int*)malloc(sizeof(int) * matSize * matColSize[0]); // 对于每个元素都要求最近的0,因此大小就是数组大小
memset(*returnColumnSizes, 0, sizeof(int) * matSize * matColSize[0]);
for (int i = 0; i < matSize * matColSize[0]; i++) {
(*returnColumnSizes)[i] = matColSize[0];
}
return res;
}
*/
// 方法2:dp 动态规划
int **updateMatrix(int **mat, int matSize, int *matColSize, int *returnSize, int **returnColumnSizes)
{
// 1. 建立res数组,保存结果
int **res = (int**)malloc(sizeof(int*) * matSize);
memset(res, 0, sizeof(int) * matSize);
for (int i = 0; i < matSize; i++) {
res[i] = (int*)malloc(sizeof(int) * matColSize[0]);
for (int j = 0; j < matColSize[0]; j++) {
res[i][j] = INT_MAX / 2;
}
}
// 2. dp
// 2.1 只有 水平向左移动 和 竖直向上移动
for (int i = 0; i < matSize; i++) {
for (int j = 0; j < matColSize[0]; j++) {
if (mat[i][j] == 0) {
res[i][j] = 0;
} else {
if (i > 0) {
res[i][j] = res[i][j] > res[i-1][j] + 1 ? res[i-1][j] + 1 : res[i][j];
}
if (j > 0) {
res[i][j] = res[i][j] > res[i][j-1] + 1 ? res[i][j-1] + 1 : res[i][j];
}
}
}
}
// 2.2 只有 水平向左移动 和 竖直向下移动
for (int i = matSize - 1; i >= 0; i--) {
for (int j = 0; j < matColSize[0]; j++) {
if (mat[i][j] != 0) {
if (i < matSize - 1) {
res[i][j] = res[i][j] > res[i+1][j] + 1 ? res[i+1][j] + 1 : res[i][j];
}
if (j > 0) {
res[i][j] = res[i][j] > res[i][j-1] + 1 ? res[i][j-1] + 1 : res[i][j];
}
}
}
}
// 2.3 只有 水平向右移动 和 竖直向上移动
for (int i = 0; i < matSize; i++) {
for (int j = matColSize[0] - 1; j >= 0; j--) {
if (mat[i][j] != 0) {
if (i > 0) {
res[i][j] = res[i][j] > res[i-1][j] + 1 ? res[i-1][j] + 1 : res[i][j];
}
if (j < matColSize[0] - 1) {
res[i][j] = res[i][j] > res[i][j+1] + 1 ? res[i][j+1] + 1 : res[i][j];
}
}
}
}
// 2.4 只有 水平向右移动 和 竖直向下移动
for (int i = matSize - 1; i >= 0; i--) {
for (int j = matColSize[0] - 1; j >= 0; j--) {
if (mat[i][j] != 0) {
if (i < matSize - 1) {
res[i][j] = res[i][j] > res[i+1][j] + 1 ? res[i+1][j] + 1 : res[i][j];
}
if (j < matColSize[0] - 1) {
res[i][j] = res[i][j] > res[i][j+1] + 1 ? res[i][j+1] + 1 : res[i][j];
}
}
}
}
/*
// 2.1 左上到右下
for (int i = 0; i < matSize; i++) {
for (int j = 0; j < matColSize[0]; j++) {
if (mat[i][j] == 0) {
res[i][j] = 0;
} else {
if (j > 0) {
res[i][j] = res[i][j] > res[i][j-1] + 1 ? res[i][j-1] + 1 : res[i][j];
}
if (i > 0) {
res[i][j] = res[i][j] > res[i-1][j] + 1 ? res[i-1][j] + 1 : res[i][j];
}
}
}
}
// 2.2 右下到左上
for (int i = matSize - 1; i >= 0; i--) {
for (int j = matColSize[0] - 1; j >= 0; j--) {
if (mat[i][j] != 0) {
if (j < matColSize[0] - 1) {
res[i][j] = res[i][j] > res[i][j+1] + 1 ? res[i][j+1] + 1 : res[i][j];
}
if (i < matSize - 1) {
res[i][j] = res[i][j] > res[i+1][j] + 1 ? res[i+1][j] + 1 : res[i][j];
}
}
}
}
*/
*returnSize = matSize;
*returnColumnSizes = (int*)malloc(sizeof(int) * matSize * matColSize[0]);
for (int i = 0; i < matSize * matColSize[0]; i++) {
(*returnColumnSizes)[i] = matColSize[0];
}
return res;
}
/*
int main()
{
int **mat = (int**)malloc(sizeof(int*) * 3); // 包含matSize个指针,每个指针都指向一个matColSize[0]大小的数组
memset(mat, 0, sizeof(int*) * 3);
int *matColSize = (int*)malloc(sizeof(int) * 3);
for (int i = 0; i < 3; i++) {
mat[i] = (int*)malloc(sizeof(int) * 3);
memset(mat[i], 0, sizeof(int) * 3);
matColSize[i] = 3;
}
mat[1][1] = 1;
mat[2][0] = 1;
mat[2][1] = 1;
mat[2][2] = 1;
int returnSize = 0;
int **returnColumnSizes = (int**)malloc(sizeof(int*) * 3);
int **res = updateMatrix(mat, 3, matColSize, &returnSize, returnColumnSizes);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
printf("%d\n", res[i][j]);
}
}
return 0;
}
*/
复制代码