Skip to content

Conversation

@SuperHotDogCat
Copy link
Owner

MAX = 2 ** 32
return self.isValidHelper(root, MIN, MAX)

def isValidHelper(self, node: Optional[TreeNode], left, right) -> bool:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

node.left と left が違う型のものなのがわりと混乱する感じがします。

# fhiyo: https://github.com/fhiyo/leetcode/pull/30/files
# inorderでやる方法, アルゴリズムイントロダクションでもやったので真っ先に思い浮かんだが親のポインタがないので面倒だなと思っていたがyieldを使えばいいことを学ぶ
# あとはnode.valをif文の左側にもってくるなどの修正を加えるなど

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

下から上に再帰するのもありかもしれませんね。
あるノードの下のノードの val の範囲、そこから下が valid かどうか、が求められる関数があれば、再帰できそうです。

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

phase5に解いてみました

# left, rightは子に対する制約 left < node.child.val < rightであることを課す
# left, rightは親の値によってきまる

if node.left and node.right:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

子の値を親が確認している点にやや違和感を感じました。この関数は、 node.val のみをチェックし、子の val のチェックは再帰関数の呼び出し先で行うのが良いと思います。

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

子の値を親が確認しないように変更したものをphase4にupいたしました。


return self.isValidBSTHelper(node.left, lower_bound, node.val) and self.isValidBSTHelper(node.right, node.val, upper_bound)

def isWithinIntervals(self, node: TreeNode, lower_bound: Optional[TreeNode], upper_bound: Optional[TreeNode]) -> bool:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

node.val を渡しているため、 Optional[int] でしょうか。

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

あ、本当だ。ありがとうございます。

def isValidBST(self, root: Optional[TreeNode]) -> bool:
# -2 ** 31 <= Node.val <= 2 ** 31 - 1なので開区間でとる
MIN = -2 ** 31 - 1
MAX = 2 ** 32
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

infでいいのではないでしょうか?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fhiyo/leetcode#41 (comment)

この辺の会話を思い出しており, 型がfloat型なのでmath.infを使いたくなかったというのが正直なところです。どのみちマジックナンバーであまりよくはないのですが...

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

なるほどです。自分ならPythonは型の柔軟性が高いので気にせず使っちゃってコード量の削減を優先するかなと思いました。OptionalだとNoneの確認が面倒なので
好みの問題だとは思います。


return self.isValidBSTHelper(node.left, lower_bound, node.val) and self.isValidBSTHelper(node.right, node.val, upper_bound)

def isWithinIntervals(self, node: TreeNode, lower_bound: Optional[int], upper_bound: Optional[int]) -> bool:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_isWithinIntervals, _isValidBSTHelperとしてプライベート関数として定義するといいと思いました

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ありがとうございます。是非そうさせていただきます🙇

@@ -0,0 +1,31 @@
class Solution:
def isValidBST(self, root: Optional[TreeNode]) -> bool:
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

引数名がrootのままなのが少し嫌な気がする

def isValidBST(self, root: Optional[TreeNode]) -> bool:
# -2 ** 31 <= Node.val <= 2 ** 31 - 1なので開区間でとる
MIN = -2 ** 31 - 1
MAX = 2 ** 32
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

このMAXの2^32は、2^31の間違いですか?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

あ、ミスっとりますね...そうです

return self.isValidBSTHelper(node.left, lower_bound, node.val) and self.isValidBSTHelper(node.right, node.val, upper_bound)

def isWithinIntervals(self, node: TreeNode, lower_bound: Optional[int], upper_bound: Optional[int]) -> bool:
if lower_bound and upper_bound:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

自分だったら最初に、lower_bound is None and upper_bound is None return Trueを書きます(特別な処理を先に書きたい)

if not self.isWithinIntervals(node, lower_bound, upper_bound):
return False

return self.isValidBSTHelper(node.left, lower_bound, node.val) and self.isValidBSTHelper(node.right, node.val, upper_bound)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

自分なら

if not self.isValidBSTHelper(node.left, lower_bound, node.val):
    return False
if not self.isValidBSTHelper(node.right, node.val, upper_bound):
    return False
return True

とします。


return self.isValidBST(root.left) and self.isValidBST(root.right)

@cache
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここにキャッシュがついていると、上の isValidBST を2回呼んだ時、つまり、木を変更してもう一回呼んだときに、TreeNode の id でキャッシュされると思われるので、木の先のほうが変更されていても、同じ値が返るという意味でうまくいかないのではないでしょうか。

なので、isValidBST をヘルパー関数に変更して、インナーファンクションとして isValidBST と subtreeMinMax を書いたほうがいいのではないでしょうかね。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants