LeetCode286.墙与门

题目描述

你被给定一个 m × n 的二维网格,网格中有以下三种可能的初始化值:

-1 表示墙或是障碍物
0 表示一扇门
INF 无限表示一个空的房间。然后,我们用 231 - 1 = 2147483647 代表 INF。你可以认为通往门的距离总是小于 2147483647 的。
你要给每个空房间位上填上该房间到 最近 门的距离,如果无法到达门,则填 INF 即可。

示例:

给定二维网格:

INF -1 0 INF
INF INF INF -1
INF -1 INF -1
0 -1 INF INF
运行完你的函数后,该网格应该变成:

3 -1 0 1
2 2 1 -1
1 -1 2 -1
0 -1 3 4

题解

计算最近门的距离,第一反应应该是用BFS。
反向从门开始考虑,即计算0与INF的最短距离。
首先将所有0入队,然后开始出队,访问到INF后入队,并将其值更新为前一个节点的值+1;此后均为经典的BFS操作。
这里更改INF的值后,确保了INF不会重复入队。

#define WALL -1
#define DOOR 0
#define ROOM 2147483647
typedef struct {
	int x;
	int y;
}POS;

typedef struct {
	POS *pos;
	int head;
	int tail;
	int len;
	int size;
}QUEUE;

void enQueue(QUEUE *que, int x, int y) {
    //printf("len=%d,%d;",que->len, que->size);
	if (que->len == que->size) {
        return;
    }
	que->tail = (que->tail + 1) % que->size;
	que->pos[que->tail].x = x;
	que->pos[que->tail].y = y;
	que->len++;
}

void deQueue(QUEUE *que, int *outx, int *outy) {
	int head = que->head; 
	if (que->len == 0) return;
	que->head = (que->head + 1) % que->size;
	que->len--;
	*outx = que->pos[head].x;
	*outy = que->pos[head].y;
}

QUEUE * initQueue(int size) {
    QUEUE *que;
	que = (QUEUE *)malloc(sizeof(QUEUE));
	que->pos = (POS *)malloc(sizeof(POS) * size);
	que->head = 0;
	que->tail = -1;
	que->size = size;
	que->len = 0;
    return que;
}

void wallsAndGates(int** rooms, int roomsSize, int* roomsColSize){
	int i, j, k, col, totalSize;
	int *visit;
	QUEUE *que;
	int tmpx, tmpy;
	POS dp[4] = {{0,1}, {1,0}, {0,-1}, {-1,0}};
	if (roomsSize == 0) {
		return;
	}
	if (roomsSize == NULL) return;
	if (*roomsColSize == 0) return;
	if (rooms == NULL) return;
	col = *roomsColSize;
	totalSize = roomsSize * col;
	visit = (int *)malloc(totalSize * sizeof(int));
	memset(visit, 0, sizeof(int) * totalSize);
	que = initQueue(totalSize);
	for (i = 0; i < roomsSize; i++) {
		for (j = 0; j < col; j++) {
			if (rooms[i][j] == DOOR) enQueue(que, i, j);
		}
	}
    
	while (que->len != 0) {
		deQueue(que, &tmpx, &tmpy);
		*(visit+tmpx * col + tmpy) = 1;
		for (k = 0; k < 4; k++) {
			if ((tmpx + dp[k].x >= 0) && (tmpx + dp[k].x < roomsSize) && (tmpy + dp[k].y >= 0) && (tmpy + dp[k].y < col)) {
				if (rooms[tmpx + dp[k].x][tmpy + dp[k].y] == ROOM) {
					enQueue(que, tmpx + dp[k].x, tmpy + dp[k].y);
					rooms[tmpx + dp[k].x][tmpy + dp[k].y] = rooms[tmpx][tmpy] + 1;
				}
			}
		}
	}
}

ps:9/14 第一个战胜100%的题,Y(^ _ ^)Y (虽然可能是提交C的人不多。。。)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值