1. 程式人生 > 其它 >力扣 leetcode 959. 由斜槓劃分區域 (python)

力扣 leetcode 959. 由斜槓劃分區域 (python)

技術標籤:pythonleetcodeleetcodepython並查集dfs

Topic

在由 1 x 1 方格組成的 N x N 網格 grid 中,每個 1 x 1 方塊由 /、\ 或空格構成。這些字元會將方塊劃分為一些共邊的區域。
(請注意,反斜槓字元是轉義的,因此 \ 用 “\” 表示。)。
返回區域的數目。

Example

Example_1:

輸入:
[
" /",
"/ "
]
輸出:2
解釋:2x2 網格如下:
在這裡插入圖片描述

Example_2

輸入:
[
" /",
" "
]
輸出:1
解釋:2x2 網格如下:

在這裡插入圖片描述

Example_3

輸入:
[
“\/”,
“/\”
]
輸出:4
解釋:(回想一下,因為 \ 字元是轉義的,所以 “\/” 表示 /,而 “/\” 表示 /\。)
2x2 網格如下:
在這裡插入圖片描述

Example_4

輸入:
[
“/\”,
“\/”
]
輸出:5
解釋:(回想一下,因為 \ 字元是轉義的,所以 “/\” 表示 /\,而 “\/” 表示 /。)
2x2 網格如下:
在這裡插入圖片描述

Example_5

輸入:
[
“//”,
"/ "
]
輸出:3
解釋:2x2 網格如下:
在這裡插入圖片描述

Solution

本思路基於並查集模板並查集size優化實現

題目比較新穎
但究其本質還是一道需要判斷是否連通的題
所以我們將它轉換為並查集求解

首先判斷被分割成了多少個區域
可以通過判斷有多少個封閉區域進行判斷
分割我們可以看成是連通分量連通的過程
而對於是否封閉
我們可以看作並查集是否成環進行判斷
如果構成了環,則區域封閉

對於判斷是否成環
我們僅需判斷連線時根節點是否相同
若相同則此次連線會導致成環

具體操作:

我們先要把 N x N 網格劃分成 (N + 1) * (N + 1) 個頂點
初始化並查集,並在初始化時設定一個res為最後返回的區域數
然後將頂點在在並查集中設定成節點
先將所有的網格邊緣的節點進行合併
之後遍歷grid進行如下判斷

如果字元為空格 ,跳過,
如果字元為 /,將小網格的 左下 和 右上 兩個頂點合併,

如果字元為 \,將小網格的 左上 和 右下 兩個頂點合併。

同時在遍歷的過程中判斷是否成環
若成環區域數加一
若不成環區域數不變

最後返回區域數res即可完成

Code

class UnionFind:
    def __init__(self):
        self.father = {}
        self.res = 1
        self.size = [0]

    def find(self, x):
        root = x
        while self.father[root] is not None:
            root = self.father[root]

        # 路徑壓縮
        while x != root:
            original_father = self.father[x]
            self.father[x] = root
            x = original_father

        return root

    def merge(self, x, y):
        root_x, root_y = self.find(x), self.find(y)

        if root_x == root_y:
            self.res += 1
        else:
            if self.size[root_x] < self.size[root_y]:
                root_x, root_y = root_y, root_x

            self.size[root_x] += self.size[root_y]
            self.father[root_x] = root_y

    def add(self, x):
        if x not in self.father:
            self.father[x] = None
            self.size.append(0)


class Solution:
    def regionsBySlashes(self, grid: List[str]) -> int:
        n = len(grid)
        m  = n + 1
        uf = UnionFind()

        for i in range(m * m + 1):
            uf.add(i)
        
        for j in range(m * m):
            if j % m == 0 or j % m == m - 1 or j // m == 0 or j // m == m - 1:
                uf.merge(j, m * m)

        for a in range(n):
            for b in range(n):
                if grid[a][b]=='/':
                    uf.merge(m * a + b + 1, m *(a + 1) + b)
                elif grid[a][b] == '\\':
                    uf.merge(m * a + b, m * (a + 1) + b + 1)

        return uf.res

Result

在這裡插入圖片描述