From c89a1c7e548913f6e2a5d40b196c879c197bf3d4 Mon Sep 17 00:00:00 2001 From: rihib Date: Tue, 3 Sep 2024 13:17:05 +0900 Subject: [PATCH 1/2] pullrequests/lowest_common_ancester_of_a_binary_search_tree --- .../step1.go | 31 ++++++++++++++++++ .../step2.go | 32 +++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 pullrequests/lowest_common_ancester_of_a_binary_search_tree/step1.go create mode 100644 pullrequests/lowest_common_ancester_of_a_binary_search_tree/step2.go diff --git a/pullrequests/lowest_common_ancester_of_a_binary_search_tree/step1.go b/pullrequests/lowest_common_ancester_of_a_binary_search_tree/step1.go new file mode 100644 index 0000000..db07c2b --- /dev/null +++ b/pullrequests/lowest_common_ancester_of_a_binary_search_tree/step1.go @@ -0,0 +1,31 @@ +//lint:file-ignore U1000 Ignore all unused code +package lowestcommonancesterofabinarysearchtree + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +/* +時間:6分30秒 + +ルートから見ていく時、共通の祖先になっていないときは必ず、pとqは左か右のどちらかの同じ部分木にいるはず。pとqの間の値になったら共通の祖先になったとわかる。 + +本来は見つからなかった場合は返り値としてerrorを返したかったのですが、LeetCodeの制約上変えられないのでnilを返すようにしています。 +*/ +func lowestCommonAncestorIterativeStep1(root, p, q *TreeNode) *TreeNode { + node := root + for node != nil { + if p.Val <= node.Val && node.Val <= q.Val || q.Val <= node.Val && node.Val <= p.Val { + return node + } + if p.Val < node.Val && q.Val < node.Val { + node = node.Left + } + if node.Val < p.Val && node.Val < q.Val { + node = node.Right + } + } + return nil +} diff --git a/pullrequests/lowest_common_ancester_of_a_binary_search_tree/step2.go b/pullrequests/lowest_common_ancester_of_a_binary_search_tree/step2.go new file mode 100644 index 0000000..9c72e0b --- /dev/null +++ b/pullrequests/lowest_common_ancester_of_a_binary_search_tree/step2.go @@ -0,0 +1,32 @@ +//lint:file-ignore U1000 Ignore all unused code +package lowestcommonancesterofabinarysearchtree + +/* +より見やすくなるようにリファクタしました。また、再帰を使った実装もしてみました。 +エラー処理についてはStep1と同様です。 +*/ +func lowestCommonAncestorIterative(root, p, q *TreeNode) *TreeNode { + node := root + for node != nil { + if p.Val < node.Val && q.Val < node.Val { + node = node.Left + continue + } + if node.Val < p.Val && node.Val < q.Val { + node = node.Right + continue + } + return node + } + return nil +} + +func lowestCommonAncestorRecursive(root, p, q *TreeNode) *TreeNode { + if p.Val < root.Val && q.Val < root.Val { + return lowestCommonAncestorRecursive(root.Left, p, q) + } + if root.Val < p.Val && root.Val < q.Val { + return lowestCommonAncestorRecursive(root.Right, p, q) + } + return root +} From 79fd1fce53e6d29ea8c984c63549957a1695d37c Mon Sep 17 00:00:00 2001 From: rihib Date: Tue, 3 Sep 2024 13:35:09 +0900 Subject: [PATCH 2/2] pullrequests/lowest_common_ancester_of_a_binary_search_tree --- .../lowest_common_ancester_of_a_binary_search_tree/step1.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pullrequests/lowest_common_ancester_of_a_binary_search_tree/step1.go b/pullrequests/lowest_common_ancester_of_a_binary_search_tree/step1.go index db07c2b..109c01b 100644 --- a/pullrequests/lowest_common_ancester_of_a_binary_search_tree/step1.go +++ b/pullrequests/lowest_common_ancester_of_a_binary_search_tree/step1.go @@ -13,6 +13,11 @@ type TreeNode struct { ルートから見ていく時、共通の祖先になっていないときは必ず、pとqは左か右のどちらかの同じ部分木にいるはず。pとqの間の値になったら共通の祖先になったとわかる。 本来は見つからなかった場合は返り値としてerrorを返したかったのですが、LeetCodeの制約上変えられないのでnilを返すようにしています。 + +該当ノードが見つからなかったからといってプログラムの実行の継続が困難になるわけではないと思うので、panicやlog.Panicを使うのはやり過ぎだと思います。 +場合によっては絶対に見つからないことが起こる入力はしないはずだと言える状況であればlog.Fatalを使ってログに書き込んだ後にos.Exit(1)を呼び出してプログラムを終了させるのが良い可能性もありますが、それも通常の場合やりすぎな気がします。 +他にはlog.Printなどを使ってログに見つからなかったことを記録しても良いかもしれませんが、見つからないことが起こる入力があり得るのであれば単にerrorを返り値として返して呼び出し側で処理するのが良いと思っています。 +他には単に見つからなかった場合はnilを返すなども手としてはあると思いますが、そうする場合は呼び出し側にもわかるようにコメント等で書いておいて欲しいなと思います。 */ func lowestCommonAncestorIterativeStep1(root, p, q *TreeNode) *TreeNode { node := root