
こんにちは
今回の学びは
・方向性はあっているのだが、デバッグに時間がかかる見込みと見たので切り替えた。(時間勝負の時はこれ大事。)
問題はhttps://leetcode.com/problems/vertical-order-traversal-of-a-binary-tree
(時間配分は5分問題理解 10分検討 10分実装 20分振り返り の一文45分構成)
終始、わからないことは声にだして、明確にしていきましょう。
1,まずは入出力をしっかりおさえましょう。(問題を自分の言葉で復唱すること、わからないことをクリアにすると)
同じレベルの数字が2つあった時は小さい方から並べる。
深さの浅い順に並べる。というマイナールールは結構細かい。
2,いくつかのソリューションを声にだして出してみましょう。(もちろんtime complexit, space complexityの分析を付け加えて)
dfsでうまいこと、x軸とy軸ごとにデータを挿入していく。
3,どれでいくか、一緒に決定しましょう。
timespace analysis (時間とスペースの分析)は 〇〇です
O(N)でデータを揃えたあと
アベレージでLogN* Log(LogN) * LogN* Log(LogN) とう微妙なdefaultdictをソートしまくる
ロジックがあったがら、速さは94%と良かった。
4、実装しましょう。
from collections import defaultdict
class Solution:
def verticalTraversal(self, root: TreeNode) -> List[List[int]]:
if root is None: return []
res = defaultdict(lambda : defaultdict(list))
def dfs(node: TreeNode, x: int, y: int, res):
if node is None: return
_y = abs(y)
res[x][_y].append(node.val) # _y is abs y is guarateed that 1 direction
dfs(node.left, x - 1, y - 1, res)
dfs(node.right, x + 1, y - 1, res)
dfs(root, 0, 0, res)
# cost of sorted(dict.iteritems())??
ans = []
for x, xaxis in sorted(res.items()):
v_res = []
for y, vertical_ary in sorted(xaxis.items()):
v_res += sorted(vertical_ary)
ans.append(v_res)
return ans
5、エッジケースとサンプルテストを忘れずに!
木がNoneとき何をかえす?前述の細かいルールに従った結果になっているか?
振り返り
「次のこの問題を解くばあい知っていればよい一つの事実とは?」
defaultdict自体はdictと一緒で速いので、どんどん使えばよい。bisectも使っても良い問題だと思う。
ボツ案に対して見切りが比較的早かったので吉。ボツ案はこちら。
方向性はあっているのだが、デバッグに時間がかかる見込みと見たので切り替えた。(時間勝負の時はこれ大事。)
class Solution_botsu:
"""
複雑過ぎて、デバッグできなかったコード。
"""
def verticalTraversal(self, root: TreeNode) -> List[List[int]]:
if root is None: return []
res0, resM, resP = [], [], []
def dfs(node: TreeNode, x: int, y: int, res0, resM, resP):
if node is None: return
# do something with node.val
if x == 0: # I don't have to generate
if len(res0) == 0:
res0.append([node.val])
else:
res0[0].append(node.val)
elif x < 0:
if len(resM) < abs(x):
resM.append([node.val])
else:
resM[abs(x)-1].append(node.val)
else: # x > 0
if len(resP) < abs(x):
resP.append([node.val])
else:
resP[abs(x)-1].append(node.val)
dfs(node.left, x - 1, y - 1, res0, resM, resP)
dfs(node.right, x + 1, y - 1, res0, resM, resP)
dfs(root, 0, 0, res0, resM, resP)
res = []
for vertical in reversed(resM):
res.append(vertical)
for vertical in res0:
res.append(vertical)
for vertical in resP:
res.append(vertical)
return res
まとめ
・方向性はあっているのだが、デバッグに時間がかかる見込みと見たので切り替えた。(時間勝負の時はこれ大事。)
以上です