1. 程式人生 > >427. 建立四叉樹(python 3)

427. 建立四叉樹(python 3)

我們想要使用一棵四叉樹來儲存一個 N x N 的布林值網路。網路中每一格的值只會是真或假。樹的根結點代表整個網路。對於每個結點, 它將被分等成四個孩子結點直到這個區域內的值都是相同的.

每個結點還有另外兩個布林變數: isLeaf 和 valisLeaf 當這個節點是一個葉子結點時為真。val 變數儲存葉子結點所代表的區域的值。

你的任務是使用一個四叉樹表示給定的網路。下面的例子將有助於你理解這個問題:

給定下面這個8 x 8 網路,我們將這樣建立一個對應的四叉樹:

由上文的定義,它能被這樣分割:

對應的四叉樹應該像下面這樣,每個結點由一對 (isLeaf, val) 所代表.

對於非葉子結點,val 可以是任意的,所以使用 * 代替。

提示:

  1. N 將小於 1000 且確保是 2 的整次冪。
  2. 如果你想了解更多關於四叉樹的知識,你可以參考這個 wiki 頁面。

思路:

看到這道題,似乎很難的樣子,不過仔細分析的話,還是有規律可循。構建一棵樹顯然需要用到遞迴的方法,先是根節點,然後是四個子結點。

重難點:

  1. 新建函式 allValueSame(grid),判斷網格所有值是否相等。這是判斷網格是否為葉子結點的依據。
  2. 若grid只有一個元素,那麼必然為葉子結點,且此節點的val根據這元素的1/0來賦值True/False。
  3. 若grid所有值相等,同2。
  4. 若grid存在不相等的元素,那麼此節點就不是葉子節點,需要把grid分成四份,分別遞迴呼叫四次。
  5. 匯入numpy.array,來完成二維陣列(即網格)的切片操作。

網格的切片:先將 list 轉換為 array,然後使用[ : ,: ]來切片,最後再轉換成列表 .tolist()

"""
# Definition for a QuadTree node.
class Node:
    def __init__(self, val, isLeaf, topLeft, topRight, bottomLeft, bottomRight):
        self.val = val
        self.isLeaf = isLeaf
        self.topLeft = topLeft
        self.topRight = topRight
        self.bottomLeft = bottomLeft
        self.bottomRight = bottomRight
"""

from numpy import array
class Solution:
    def construct(self, grid):
        """
        :type grid: List[List[int]]
        :rtype: Node
        """
        root = Node('*', True, None, None, None, None);
        if len(grid) == 1:
            root.isLeaf = True;
            root.val = True if grid[0][0] == 1 else False;
        if self.allValueSame(grid):       # 所有值相等
            root.isLeaf = True;
            root.val = True if grid[0][0] == 1 else False;
        else:                             # 並非所有值相等
            halfLength = len(grid) // 2;  # 使用 // 表示整除
            root.isLeaf = False;          # 如果網格中有值不相等,這個節點就不是葉子節點
            # 使用array來完成二維陣列的切片
            root.topLeft = self.construct(array(grid)[:halfLength, :halfLength].tolist());
            root.topRight = self.construct(array(grid)[:halfLength, halfLength:].tolist());
            root.bottomLeft = self.construct(array(grid)[halfLength:, :halfLength].tolist());
            root.bottomRight = self.construct(array(grid)[halfLength:, halfLength:].tolist());
        return root;
                    
    def allValueSame(self, grid):
        """
        :type grid: List[List[int]]
        :rtype: boolean
        """
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if grid[0][0] != grid[i][j]:
                    return False;
        return True;