Skip to content
Merged
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
60 changes: 60 additions & 0 deletions pullrequests/merge_two_sorted_lists/step1.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//lint:file-ignore U1000 Ignore all unused code
package mergetwosortedlists

/*
個人的にLeetCodeを進めていて、2月ごろに解いたもの。GitHubのコミット履歴から引っ張ってきま
した。

解いた時間を記録していなかったのですが、恐らく20~30分ぐらいかかった気がします。解いている途
中でポインタの向きがよくわからなくなってしまい、時間がかかってしまった記憶があります。また、
Goの勉強も兼ねて書いたので、言語自体の知識も少ない状態で書きました。

綺麗に書いている余裕がなかったので、とりあえず動くコードを書いたという感じです。とりあえず値
の小さいノードから順番にポインタの向きを変えてマージしていけば良いとはわかったのですが、実装
力に余裕がなく、コードが冗長になってしまったという印象です。
*/

type ListNode struct {
Val int
Next *ListNode
}

func mergeTwoLists_step1(list1 *ListNode, list2 *ListNode) *ListNode {
if list1 == nil {
return list2
}
if list2 == nil {
return list1
}

var res *ListNode
if list1.Val <= list2.Val {
res = list1
list1 = list1.Next
} else {
res = list2
list2 = list2.Next
}

curNode := res
for {
if list1 == nil {
curNode.Next = list2
return res
}
if list2 == nil {
curNode.Next = list1
return res
}

if list1.Val <= list2.Val {
curNode.Next = list1
curNode = curNode.Next
list1 = list1.Next
} else {
curNode.Next = list2
curNode = curNode.Next
list2 = list2.Next
}
}
}
30 changes: 30 additions & 0 deletions pullrequests/merge_two_sorted_lists/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 mergetwosortedlists

/*
他の人のコードを色々見て、冗長な部分を消し、リファクタをしました。
*/

func mergeTwoLists_step2(list1 *ListNode, list2 *ListNode) *ListNode {
dummy := new(ListNode)
cur := dummy

for list1 != nil && list2 != nil {
if list1.Val <= list2.Val {
cur.Next = list1
list1 = list1.Next
} else {
cur.Next = list2
list2 = list2.Next
}
cur = cur.Next
}

if list1 != nil {
cur.Next = list1
} else {
cur.Next = list2
}

return dummy.Next
}
73 changes: 73 additions & 0 deletions pullrequests/merge_two_sorted_lists/step3.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//lint:file-ignore U1000 Ignore all unused code
package mergetwosortedlists

/*
感想:
現在(6月)解いたコードになります。大分余裕を持って書けるようになってきました。一番初めはポ
インタの向きがよくわからなくなるということがあったのですが、そういったこともなくなり、ポイ
ンタの操作を余裕を持って書けるようになってきました。暗記ではなく、自然と同じようなコードが
出てくるようになりました。またGo自体も初期に比べて無理なく自然に書けるようになりました。

Step2に比べて変数名が改善されています(curではなくtailに変更)。また個人的にシンプルで見
やすいと思っているので多重代入をよく使うようになりました。

また、個人的な感覚として、list1またはlist2のどちらか片方がnilの場合の処理をfor文の中に入
れるか、外に出すかをその時の気分で意図的に変えるようになりました。

質問したいこと:
- tailという変数名についてどう思いますか?
Comment thread
rihib marked this conversation as resolved.
- 多重代入は使った方がシンプルで見やすいと個人的に思ってるのですがどう思いますか?もちろん
互いに影響を与え合ってしまうような変数同士の場合は挙動がundefinedだと思うので避けるべき
だとは思いますが。
Comment thread
rihib marked this conversation as resolved.
- 個人的には上と下の回答はどちらも大差ないと思っていてどちらでも良いと思っているのですが、
Comment thread
rihib marked this conversation as resolved.
どう思いますか?
*/

func mergeTwoLists_step3(list1 *ListNode, list2 *ListNode) *ListNode {
Comment thread
rihib marked this conversation as resolved.
dummy := new(ListNode)
tail := dummy

for list1 != nil && list2 != nil {
if list1.Val < list2.Val {
tail.Next, list1 = list1, list1.Next
} else {
tail.Next, list2 = list2, list2.Next
}
tail = tail.Next
}

if list1 != nil {
tail.Next = list1
}
if list2 != nil {
tail.Next = list2
}

return dummy.Next
}

func mergeTwoLists_step3_anothersolution(list1 *ListNode, list2 *ListNode) *ListNode {
dummy := new(ListNode)
tail := dummy

for list1 != nil || list2 != nil {
if list1 == nil {
tail.Next = list2
break
}
if list2 == nil {
tail.Next = list1
break
}

if list1.Val < list2.Val {
tail.Next, list1 = list1, list1.Next
} else {
tail.Next, list2 = list2, list2.Next
}
tail = tail.Next
tail.Next = nil
}

return dummy.Next
}
22 changes: 22 additions & 0 deletions pullrequests/merge_two_sorted_lists/step4.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//lint:file-ignore U1000 Ignore all unused code
package mergetwosortedlists

func mergeTwoLists_step4(list1 *ListNode, list2 *ListNode) *ListNode {
dummy := new(ListNode)
tail := dummy
for list1 != nil && list2 != nil {
if list1.Val < list2.Val {
tail.Next, list1 = list1, list1.Next
} else {
tail.Next, list2 = list2, list2.Next
}
tail = tail.Next
}
if list1 != nil {
tail.Next = list1
}
if list2 != nil {
tail.Next = list2
}
return dummy.Next
}