1/25力扣每日一題959. 由斜槓劃分區域
阿新 • • 發佈:2021-01-27
技術標籤:c語言
如題~
在由 1 x 1 方格組成的 N x N 網格 grid 中,每個 1 x 1 方塊由 /、\ 或空格構成。這些字元會將方塊劃分為一些共邊的區域。
(請注意,反斜槓字元是轉義的,因此 \ 用 “\” 表示。)。
返回區域的數目。
示例 1:
輸入:
[
" /",
"/ "
]
輸出:2
解釋:2x2 網格如下:
示例 2:
輸入:
[
" /",
" "
]
輸出:1
解釋:2x2 網格如下:
示例 3:
輸入:
[
“\/”,
“/\”
]
輸出:4
解釋:(回想一下,因為 \ 字元是轉義的,所以 “\/” 表示 /,而 “/\” 表示 /\。)2x2 網格如下:
程式碼直接列上吧,這力扣又是不做人的一天、、
完全看不懂之後,通過看題解,勉強搞明白了題解
將每個大方塊分成0,1,2,3四個小方塊
從正上方編號為0, 其餘順時針編號
當字元為’’,可以想象一下,正方形被斜劈開 0-1連通, 2-3連通
當字元為’/’, 0-3連通, 1-2連通
當字元為’ ',也就是沒有的時候, 0-1-2-3連通
相鄰的大方塊之間也需要連通
左右相鄰的需要連通1(左)-3(右)
上下相鄰的需要連通2(上)-0(下)
最終返回大的並查集的連通塊個數 也就是有多少個樹
/*
這道題本來開始沒看懂,後來看的解析教程
才看懂的,然後還不會寫。。。。。
這是看的題解
*/
void swap(int* a, int* b) {
int tmp = *a;
*a = *b, *b = tmp;//首先定義交換型別函式 ,將a,b交換
}
struct DisjointSetUnion {//①定義並查集 這個結構體,ps:下面有具體啥是結構體struct
int *f, *size;//size是長度,一個相連的有多長
int n, setCount;//setcount是指分開部分的總數
};
void initDSU(struct DisjointSetUnion* obj, int n) {//定義函式過程中,用結構體給了obj
obj-> f = malloc(sizeof(int) * n);//這裡obj中的f是上面的*f
obj->size = malloc(sizeof(int) * n);//size是上面的*size
obj->n = n;
obj->setCount = n;
for (int i = 0; i < n; i++) {
obj->f[i] = i;
obj->size[i] = 1;
}
}
int find(struct DisjointSetUnion* obj, int x) {
return obj->f[x] == x ? x : (obj->f[x] = find(obj, obj->f[x]));//找到他們的根節點,壓縮路徑
}
int unionSet(struct DisjointSetUnion* obj, int x, int y) {//這裡開始權值壓縮,減少長度
int fx = find(obj, x), fy = find(obj, y);//fx,和fy是他們的長度
if (fx == fy) {
return false;
}//長度相等的話都一樣
if (obj->size[fx] < obj->size[fy]) {
swap(&fx, &fy);//交換fx和fy
}
obj->size[fx] += obj->size[fy];
obj->f[fy] = fx;
obj->setCount--;
return true;//把他們連線起來。分離的部分 - 1
}
struct HashTable {//建立雜湊表
int value;
UT_hash_handle hh;
};
int regionsBySlashes(char** grid, int gridSize) {
int n = gridSize;
struct DisjointSetUnion* uf = malloc(sizeof(struct DisjointSetUnion));
initDSU(uf, n * n * 4);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
int idx = i * n + j;//開始聯通方塊
if (grid[i][j] == '/') {
unionSet(uf, idx * 4, idx * 4 + 3);
unionSet(uf, idx * 4 + 1, idx * 4 + 2);
} else if (grid[i][j] == '\\') {
unionSet(uf, idx * 4, idx * 4 + 1);
unionSet(uf, idx * 4 + 2, idx * 4 + 3);
} else {
unionSet(uf, idx * 4, idx * 4 + 1);
unionSet(uf, idx * 4 + 1, idx * 4 + 2);
unionSet(uf, idx * 4 + 2, idx * 4 + 3);
}
if (i < n - 1) {
int bottom = idx + n;
unionSet(uf, idx * 4 + 2, bottom * 4);
}
if (j < n - 1) {
int right = idx + 1;
unionSet(uf, idx * 4 + 1, right * 4 + 3);
}
}
}
struct HashTable* fathers = NULL;//這裡雜湊表那部分就搞不太懂,本來以為沒必要的
for (int i = 0; i < n * n * 4; i++) {
int fa = find(uf, i);
struct HashTable* tmp;
HASH_FIND_INT(fathers, &fa, tmp);
if (tmp == NULL) {
tmp = malloc(sizeof(struct HashTable));
tmp->value = fa;
HASH_ADD_INT(fathers, value, tmp);
}
}
return HASH_COUNT(fathers);
}