题目描述
给定一个二维的矩阵,包含 'X' 和 'O'(字母 O)。
找到所有被 'X' 围绕的区域,并将这些区域里所有的 'O' 用 'X' 填充。
示例:
X X X X
X O O X
X X O X
X O X X
运行你的函数后,矩阵变为:
X X X X
X X X X
X X X X
X O X X
解释:
被围绕的区间不会存在于边界上,换句话说,任何边界上的 'O' 都不会被填充为 'X'。 任何不在边界上,或不与边界上的 'O' 相连的 'O' 最终都会被填充为 'X'。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/surrounded-regions
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
白话题目:
算法:
详细解释关注 B站 【C语言全代码】学渣带你刷Leetcode 不走丢 https://www.bilibili.com/video/BV1C7411y7gB
C语言完全代码
typedef struct tagList {
struct tagList *next;
struct tagList *prev;
} List;
void ListInit(List *listHead)
{
listHead->next = listHead;
listHead->prev = listHead;
return;
}
void ListAddTail(List *head, List *entry)
{
head->prev->next = entry;
entry->prev = head->prev;
head->prev = entry;
entry->next = head;
}
bool ListEmpty(List *head)
{
return (head->next == head);
}
void ListRemoveHead(List *head)
{
head->next = head->next->next;
head->next->prev = head;
}
#define NODE_ENTRY(ptr, type, member) ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
typedef struct tagMyQueueObj {
List qHead;
int queueLen;
} MyQueueObj;
typedef struct tagPosition {
int x;
int y;
} Position;
typedef struct tagMyQueueNode {
List qEntry;
Position pos;
} MyQueueNode;
MyQueueObj *MyQueueInit(void)
{
MyQueueObj *queueObj = NULL;
queueObj = (MyQueueObj *)malloc(sizeof(MyQueueObj));
if (queueObj == NULL) {
return NULL;
}
ListInit(&(queueObj->qHead));
queueObj->queueLen = 0;
return queueObj;
}
void MyQueueAppend(MyQueueObj *queueObj, int x, int y)
{
MyQueueNode *queueNode = NULL;
queueNode = malloc(sizeof(MyQueueNode));
if (queueNode == NULL) {
return;
}
queueNode->qEntry.next = NULL;
queueNode->qEntry.prev = NULL;
queueNode->pos.x = x;
queueNode->pos.y = y;
ListAddTail(&(queueObj->qHead), &(queueNode->qEntry));
queueObj->queueLen++;
}
MyQueueNode *MyQueuePop(MyQueueObj *queueObj)
{
List *tmpEntry = NULL;
if (ListEmpty(&(queueObj->qHead))) {
return NULL;
}
tmpEntry = queueObj->qHead.next;
ListRemoveHead(&(queueObj->qHead));
tmpEntry->next = NULL;
tmpEntry->prev = NULL;
queueObj->queueLen--;
return (NODE_ENTRY(tmpEntry, MyQueueNode, qEntry));
}
void MyQueueNodeFree(MyQueueNode *queueNode)
{
if (queueNode != NULL) {
free(queueNode);
}
return;
}
bool MyQueueEmpty(MyQueueObj *queueObj)
{
if (ListEmpty(&(queueObj->qHead))) {
return true;
} else {
return false;
}
}
int g_boardSize = 0;
int g_boardColSize = 0;
bool mark[1000][1000] = {{false}};
int go[4][2] = {0,-1,1,0,0,1,-1,0}; //方向向量
bool CheckIsO(char** board, int x, int y)
{
if ((x <= 0) || (y <= 0) || (x >= g_boardSize - 1) || (y >= g_boardColSize - 1)) {
return false;
}
if (mark[x][y] == true) {
return false;
}
if (board[x][y] == 'O') {
return true;
}
return false;
}
void ChgO2Y(char** board, int x, int y, MyQueueObj *queue)
{
MyQueueNode *qNode = NULL;
MyQueueNode *nextNode = NULL;
MyQueueAppend(queue, x, y);
int tmpX = 0;
int tmpY = 0;
mark[x][y] = true;
while(!MyQueueEmpty(queue)) {
qNode = MyQueuePop(queue);
tmpX = qNode->pos.x;
tmpY = qNode->pos.y;
if ((board[tmpX][tmpY] == 'Y') || (board[tmpX][tmpY] == 'X')) {
continue;
}
board[tmpX][tmpY] = 'Y';
for (int i = 0; i < 4; i++) {
tmpX = qNode->pos.x + go[i][0];
tmpY = qNode->pos.y + go[i][1];
if(CheckIsO(board, tmpX, tmpY)) //如果状态满足条件则入队;
{
MyQueueAppend(queue, tmpX, tmpY);
}
}
mark[x][y] = false;
}
}
void solve(char** board, int boardSize, int* boardColSize){
MyQueueObj *queue = MyQueueInit();
memset(mark, false, 1000 * 1000 * sizeof(bool));
if ((boardSize == 0) || (boardColSize == NULL)) {
return;
}
g_boardSize = boardSize;
g_boardColSize = *boardColSize;
for (int i = 0; i < g_boardSize; i++) {
for (int j = 0; j < g_boardColSize; j++) {
if ((i == 0) || (i == boardSize - 1) || (j == 0) || (j == g_boardColSize - 1)) {
ChgO2Y(board, i, j, queue);
}
}
}
for (int i = 0; i < g_boardSize; i++) {
for (int j = 0; j < g_boardColSize; j++) {
if (board[i][j] == 'O') {
board[i][j] = 'X';
continue;
}
if (board[i][j] == 'Y') {
board[i][j] = 'O';
}
}
}
MyQueueNodeFree(queue);
}