diff --git a/pullrequests/merge_two_sorted_lists/step1.go b/pullrequests/merge_two_sorted_lists/step1.go new file mode 100644 index 0000000..8dac4a4 --- /dev/null +++ b/pullrequests/merge_two_sorted_lists/step1.go @@ -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 + } + } +} diff --git a/pullrequests/merge_two_sorted_lists/step2.go b/pullrequests/merge_two_sorted_lists/step2.go new file mode 100644 index 0000000..ea5a58c --- /dev/null +++ b/pullrequests/merge_two_sorted_lists/step2.go @@ -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 +} diff --git a/pullrequests/merge_two_sorted_lists/step3.go b/pullrequests/merge_two_sorted_lists/step3.go new file mode 100644 index 0000000..8dfaac0 --- /dev/null +++ b/pullrequests/merge_two_sorted_lists/step3.go @@ -0,0 +1,73 @@ +//lint:file-ignore U1000 Ignore all unused code +package mergetwosortedlists + +/* + 感想: + 現在(6月)解いたコードになります。大分余裕を持って書けるようになってきました。一番初めはポ + インタの向きがよくわからなくなるということがあったのですが、そういったこともなくなり、ポイ + ンタの操作を余裕を持って書けるようになってきました。暗記ではなく、自然と同じようなコードが + 出てくるようになりました。またGo自体も初期に比べて無理なく自然に書けるようになりました。 + + Step2に比べて変数名が改善されています(curではなくtailに変更)。また個人的にシンプルで見 + やすいと思っているので多重代入をよく使うようになりました。 + + また、個人的な感覚として、list1またはlist2のどちらか片方がnilの場合の処理をfor文の中に入 + れるか、外に出すかをその時の気分で意図的に変えるようになりました。 + + 質問したいこと: + - tailという変数名についてどう思いますか? + - 多重代入は使った方がシンプルで見やすいと個人的に思ってるのですがどう思いますか?もちろん + 互いに影響を与え合ってしまうような変数同士の場合は挙動がundefinedだと思うので避けるべき + だとは思いますが。 + - 個人的には上と下の回答はどちらも大差ないと思っていてどちらでも良いと思っているのですが、 + どう思いますか? +*/ + +func mergeTwoLists_step3(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 +} + +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 +} diff --git a/pullrequests/merge_two_sorted_lists/step4.go b/pullrequests/merge_two_sorted_lists/step4.go new file mode 100644 index 0000000..88f9858 --- /dev/null +++ b/pullrequests/merge_two_sorted_lists/step4.go @@ -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 +}