1. 程式人生 > 其它 >LeetCode 每日一題959. 由斜槓劃分區域

LeetCode 每日一題959. 由斜槓劃分區域

技術標籤:每日一題演算法實戰leetcodejava圖論演算法

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 <= grid.length == grid[0].length <= 30
  • grid[i][j]'/''\'、或 ' '

方法一:並查集

解題思路

下圖來自「官方解答」,懶得畫了。
圖片來自「官方解答」

  • 此題最終還是「連通性」的問題。如圖所示,把每一個單元格劃分成 4 個區域。
  • 一共有 n = len * len * 4 個區域,其中 lengrid 的長度。
  • 初始狀態,n 個單元格都沒有連通,即被分為 n 個區域。
  • 遍歷 grid (注意:grid[i] 是字串,我們需要遍歷 grid[i] 的每一個字元)
    1. 遇到 '/' 時:連通 [0][3]
      ,連通 [1][2]
    2. 遇到 '\' 時:連通 [0][1] ,連通 [2][3]
    3. 遇到 ' ' 時:連通 [0][1][2][3]
  • 此外,[1] 和右邊的單元格是連通的,[2] 和下方的單元格是連通的,需要分別將其連通。(因為是從左往右,從上往下遍歷,所以只需處理 兩個方向)
  • 每連通一次,區域數量 n = n - 1,返回遍歷完成後的 n

參考程式碼

public int regionsBySlashes(String[] grid) {
    int len = grid.length;
    int n = len * len * 4;
    UnionFind unionFind = new UnionFind(n);
    for (int i = 0; i < len; i++) {
        for (int j = 0; j < len; j++) {
            int num = (i * len + j) * 4;
            char ch = grid[i].charAt(j);
            if (ch == '/') {
                unionFind.union(num, num + 3);
                unionFind.union(num + 1, num + 2);
            } else if (ch == '\\') {
                unionFind.union(num, num + 1);
                unionFind.union(num + 2, num + 3);
            } else {
                unionFind.union(num, num + 1);
                unionFind.union(num, num + 2);
                unionFind.union(num, num + 3);
            }

            if (i < len - 1) {
                unionFind.union(num + 2, num + len * 4);
            }
            if (j < len - 1) {
                unionFind.union(num + 1, num + 7);
            }
        }
    }
    return unionFind.getCount();
}


class UnionFind {

    private int[] parent;

    private int count;

    public UnionFind(int n) {
        parent = new int[n];
        count = n;
        for (int i = 0; i < n; i++) {
            parent[i] = i;
        }
    }

    public void union(int x, int y) {
        int rootX = find(x), rootY = find(y);
        if (rootX == rootY) {
            return;
        }
        parent[rootX] = rootY;
        count--;
    }

    public int find(int x) {
        return parent[x] == x ? parent[x] : (parent[x] = find(parent[x]));
    }

    public int getCount() {
        return count;
    }
}

執行結果
在這裡插入圖片描述