Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Balanced Binary Tree #30

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions pullrequests/balanced_binary_tree/step1.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//lint:file-ignore U1000 Ignore all unused code
package template

import "math"

type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}

/*
時間:12分

左右の木の高さを比べてバランスしているかを確かめるのと、そもそもその部分木自体がバランスしているのかも確かめる必要があるので、別途再帰用の補助関数を作ることにした。
*/
type Balance struct {
isBalanced bool
height int
}

func isBalancedStep1(root *TreeNode) bool {
return isHeightBalanced(root).isBalanced
}

func isHeightBalanced(root *TreeNode) *Balance {
if root == nil {
return &Balance{true, 0}
}
leftBalance := isHeightBalanced(root.Left)
rightBalance := isHeightBalanced(root.Right)
isBalanced := leftBalance.isBalanced && rightBalance.isBalanced && (math.Abs(float64(leftBalance.height-rightBalance.height)) <= 1.0)
return &Balance{isBalanced, max(leftBalance.height, rightBalance.height) + 1}
}
30 changes: 30 additions & 0 deletions pullrequests/balanced_binary_tree/step2.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//lint:file-ignore U1000 Ignore all unused code
package template

import "math"

/*
読みやすくなるようにリファクタした。
Go的にはleftBalance.isBalancedのように同じ名前が繰り返されるのを嫌う(Go styleguideにも書いてある)ので、繰り返さないように直したりした。

正直、TreeBalanceやcheckBalanceという関数名はしっくりきていないけど、より良い名前が思いつかなかった。
*/
type TreeBalance struct {
isBalanced bool
height int
}

func isBalancedStep2(root *TreeNode) bool {
return checkBalanceStep2(root).isBalanced
}

func checkBalanceStep2(root *TreeNode) *TreeBalance {
if root == nil {
return &TreeBalance{true, 0}
}
left, right := checkBalanceStep2(root.Left), checkBalanceStep2(root.Right)
isBalanced := left.isBalanced && right.isBalanced &&
math.Abs(float64(left.height-right.height)) <= 1.0
height := max(left.height, right.height) + 1
return &TreeBalance{isBalanced, height}
}
31 changes: 31 additions & 0 deletions pullrequests/balanced_binary_tree/step3.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//lint:file-ignore U1000 Ignore all unused code
package template

import "math"

/*
Go styleguideを見ると、下記のように書かれているのでポインタではなく、直接構造体を渡すように直した。

> Do not pass pointers as function arguments just to save a few bytes. If a function reads its argument x only as *x throughout, then the argument shouldn’t be a pointer. Common instances of this include passing a pointer to a string (*string) or a pointer to an interface value (*io.Reader). In both cases, the value itself is a fixed size and can be passed directly.
>
> This advice does not apply to large structs, or even small structs that may increase in size. In particular, protocol buffer messages should generally be handled by pointer rather than by value. The pointer type satisfies the proto.Message interface (accepted by proto.Marshal, protocmp.Transform, etc.), and protocol buffer messages can be quite large and often grow larger over time.
*/
type treeBalance struct {
isBalanced bool
height int
}

func isBalancedStep3(root *TreeNode) bool {
return checkBalanceStep3(root).isBalanced
}

func checkBalanceStep3(root *TreeNode) treeBalance {
if root == nil {
return treeBalance{true, 0}
}
left, right := checkBalanceStep3(root.Left), checkBalanceStep3(root.Right)
Copy link

Choose a reason for hiding this comment

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

私は、この , 代入は好まないですねー。

isBalanced := left.isBalanced && right.isBalanced &&
math.Abs(float64(left.height-right.height)) <= 1.0
Copy link

Choose a reason for hiding this comment

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

math.Abs(float64()) <= 1 も整数のまま処理したいですね。一回変数を別にいれておいて、-1と1と比較するだけですから。

height := max(left.height, right.height) + 1
return treeBalance{isBalanced, height}
}