427. 建立四叉樹(python 3)
阿新 • • 發佈:2019-02-04
我們想要使用一棵四叉樹來儲存一個 N x N
的布林值網路。網路中每一格的值只會是真或假。樹的根結點代表整個網路。對於每個結點, 它將被分等成四個孩子結點直到這個區域內的值都是相同的.
每個結點還有另外兩個布林變數: isLeaf
和 val
。isLeaf
當這個節點是一個葉子結點時為真。val
變數儲存葉子結點所代表的區域的值。
你的任務是使用一個四叉樹表示給定的網路。下面的例子將有助於你理解這個問題:
給定下面這個8 x 8
網路,我們將這樣建立一個對應的四叉樹:
由上文的定義,它能被這樣分割:
對應的四叉樹應該像下面這樣,每個結點由一對 (isLeaf, val)
所代表.
對於非葉子結點,val
可以是任意的,所以使用 *
代替。
提示:
N
將小於1000
且確保是 2 的整次冪。- 如果你想了解更多關於四叉樹的知識,你可以參考這個 wiki 頁面。
思路:
看到這道題,似乎很難的樣子,不過仔細分析的話,還是有規律可循。構建一棵樹顯然需要用到遞迴的方法,先是根節點,然後是四個子結點。
重難點:
- 新建函式 allValueSame(grid),判斷網格所有值是否相等。這是判斷網格是否為葉子結點的依據。
- 若grid只有一個元素,那麼必然為葉子結點,且此節點的val根據這元素的1/0來賦值True/False。
- 若grid所有值相等,同2。
- 若grid存在不相等的元素,那麼此節點就不是葉子節點,需要把grid分成四份,分別遞迴呼叫四次。
- 匯入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;