1. 程式人生 > >Leetcode 959:由斜槓劃分區域(超詳細的解法!!!)

Leetcode 959:由斜槓劃分區域(超詳細的解法!!!)

在由 1 x 1 方格組成的 N x N 網格 grid 中,每個 1 x 1 方塊由 /\ 或空格構成。這些字元會將方塊劃分為一些共邊的區域。

(請注意,反斜槓字元是轉義的,因此 \"\\" 表示。)。

返回區域的數目。

示例 1:

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

示例 2:

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

示例 3:

輸入:
[
  "\\/",
  "/\\"
]
輸出:4
解釋:(回想一下,因為 \ 字元是轉義的,所以 "\\/" 表示 \/,而 "/\\" 表示 /\。)
2x2 網格如下:

示例 4:

輸入:
[
  "/\\",
  "\\/"
]
輸出:5
解釋:(回想一下,因為 \ 字元是轉義的,所以 "/\\" 表示 /\,而 "\\/" 表示 \/。)
2x2 網格如下:

示例 5:

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

提示:

  1. 1 <= grid.length == grid[0].length <= 30
  2. grid[i][j]'/''\'、或 ' '

解題思路

這個問題非常有意思,這實際是一個島嶼個數的問題,所以不難想到通過DFS

來做。

這裡我們使用3×3個畫素表示一個最小單元最為合適。

class Solution:
    def regionsBySlashes(self, grid):
        """
        :type grid: List[str]
        :rtype: int
        """
        grid_len = len(grid)
        g_len = grid_len*3
        g = [[0]*g_len for _ in range(g_len)]
        def dfs(g, i, j):
            if
i >= 0 and j >= 0 and i < g_len and j < g_len and g[i][j] == 0: g[i][j] = 1 dfs(g, i - 1, j) dfs(g, i + 1, j) dfs(g, i, j - 1) dfs(g, i, j + 1) for i in range(grid_len): for j in range(grid_len): if grid[i][j] == '/': g[i*3+2][j*3], g[i*3+1][j*3+1], g[i*3][j*3+2] = 1, 1, 1 if grid[i][j] == '\\': g[i*3][j*3], g[i*3+1][j*3+1], g[i*3+2][j*3+2] = 1, 1, 1 res = 0 for i in range(g_len): for j in range(g_len): if g[i][j] == 0: dfs(g, i, j) res += 1 return res

我們也可以參考Leetcode 947:移除最多的同行或同列石頭(超詳細的解法!!!)採用並查集來做。

我們可以通過/\將一個區域劃分為四塊,然後我們按照順時針自頂開始的順序標記劃分後的區域為1234。我們此時就可以開始遍歷輸入的grid

如果碰到'/',我們就將03進行歸併。如果碰到'\\',我們就將12歸併。如果碰到' ', 我們就將1234全部歸併。對於更加複雜的例子,如例5

我們首先碰到'/',所以我們就將第一個方格中的0312分別歸併。

同理接著將後面碰到的'/'' '一次歸併。

最後我們將橫向第二個小方格中的0和第一個小方格中的2歸併,將縱向第二個小方格中的3和第一個小方格中的1歸併,這樣我們就把中間這個部分歸併為了一個集合。對於下方的三角形區域做同樣的操作。

class Solution:
    def regionsBySlashes(self, grid):
        """
        :type grid: List[str]
        :rtype: int
        """
        s = dict()
        
        def find(x):
            s.setdefault(x, x)
            if s[x] != x:
                s[x] = find(s[x])
                
            return s[x]
        
        def union(x, y):
            s[find(x)] = find(y)
            
        grid_len = len(grid)
        for i in range(grid_len):
            for j in range(grid_len):
                if i:
                    union((i, j, 0), (i-1, j, 2))
                if j:
                    union((i, j, 3), (i, j-1, 1))
                if grid[i][j] != '/':
                    union((i, j, 0), (i, j, 1))
                    union((i, j, 3), (i, j, 2))
                if grid[i][j] != '\\':
                    union((i, j, 0), (i, j, 3))
                    union((i, j, 2), (i, j, 1))
                    
        return len(set(map(find, s)))

reference:

https://leetcode.com/problems/regions-cut-by-slashes/solution/

https://leetcode.com/problems/regions-cut-by-slashes/discuss/205674/C%2B%2B-with-picture-DFS-on-upscaled-grid

我將該問題的其他語言版本新增到了我的GitHub Leetcode

如有問題,希望大家指出!!!