題目描述
給定一個二維的矩陣,包含 '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);
}