From 435ef9eeebbf53af66f080f65f776aeef9864692 Mon Sep 17 00:00:00 2001 From: rihib Date: Tue, 6 Aug 2024 15:52:45 +0900 Subject: [PATCH] pullrequests/add_two_numbers --- pullrequests/add_two_numbers/step1.go | 48 +++++++++++++++++++++++++++ pullrequests/add_two_numbers/step2.go | 31 +++++++++++++++++ pullrequests/add_two_numbers/step3.go | 27 +++++++++++++++ 3 files changed, 106 insertions(+) create mode 100644 pullrequests/add_two_numbers/step1.go create mode 100644 pullrequests/add_two_numbers/step2.go create mode 100644 pullrequests/add_two_numbers/step3.go diff --git a/pullrequests/add_two_numbers/step1.go b/pullrequests/add_two_numbers/step1.go new file mode 100644 index 0000000..6e21428 --- /dev/null +++ b/pullrequests/add_two_numbers/step1.go @@ -0,0 +1,48 @@ +//lint:file-ignore U1000 Ignore all unused code +package addtwonumbers + +type ListNode struct { + Val int + Next *ListNode +} + +/* +時間:8分35秒 + +方針自体はすぐに決まり、繰り上げと2つの数の桁数の違いに気をつけて、足していけばいいと考えました。末端のノードの値が0になるときの対処に少し悩みました。 +とりあえず動くように書いたのでコードの重複などが多く、こなれていないコードだなと思います。 +*/ +func addTwoNumbers_step1(l1 *ListNode, l2 *ListNode) *ListNode { + dummy := new(ListNode) + dummy.Next = new(ListNode) + dummy.Next.Val = 0 + curr := dummy + for l1 != nil && l2 != nil { + curr = curr.Next + sum := l1.Val + l2.Val + curr.Val + curr.Val = sum % 10 + curr.Next = new(ListNode) + curr.Next.Val = sum / 10 + l1, l2 = l1.Next, l2.Next + } + for l1 != nil { + curr = curr.Next + sum := l1.Val + curr.Val + curr.Val = sum % 10 + curr.Next = new(ListNode) + curr.Next.Val = sum / 10 + l1 = l1.Next + } + for l2 != nil { + curr = curr.Next + sum := l2.Val + curr.Val + curr.Val = sum % 10 + curr.Next = new(ListNode) + curr.Next.Val = sum / 10 + l2 = l2.Next + } + if curr.Next.Val == 0 { + curr.Next = nil + } + return dummy.Next +} diff --git a/pullrequests/add_two_numbers/step2.go b/pullrequests/add_two_numbers/step2.go new file mode 100644 index 0000000..317506d --- /dev/null +++ b/pullrequests/add_two_numbers/step2.go @@ -0,0 +1,31 @@ +//lint:file-ignore U1000 Ignore all unused code +package addtwonumbers + +/* +コードの重複を排除しました。ただまだ無駄な処理が多いです。 +*/ +func addTwoNumbers_step2(l1 *ListNode, l2 *ListNode) *ListNode { + dummy := new(ListNode) + dummy.Next = new(ListNode) + dummy.Next.Val = 0 + curr := dummy + for l1 != nil || l2 != nil { + curr = curr.Next + sum := curr.Val + if l1 != nil { + sum += l1.Val + l1 = l1.Next + } + if l2 != nil { + sum += l2.Val + l2 = l2.Next + } + curr.Val = sum % 10 + curr.Next = new(ListNode) + curr.Next.Val = sum / 10 + } + if curr.Next.Val == 0 { + curr.Next = nil + } + return dummy.Next +} diff --git a/pullrequests/add_two_numbers/step3.go b/pullrequests/add_two_numbers/step3.go new file mode 100644 index 0000000..b1cb8f9 --- /dev/null +++ b/pullrequests/add_two_numbers/step3.go @@ -0,0 +1,27 @@ +//lint:file-ignore U1000 Ignore all unused code +package addtwonumbers + +/* +carryを導入した方がより明確でシンプルに書けると気づき変更しました。 +carryを導入したことにより、末端に余計なノード(値が0のノード)が発生しなくなりました。 +*/ +func addTwoNumbers_step3(l1 *ListNode, l2 *ListNode) *ListNode { + dummy := new(ListNode) + curr := dummy + carry := 0 + for l1 != nil || l2 != nil || carry != 0 { + sum := carry + if l1 != nil { + sum += l1.Val + l1 = l1.Next + } + if l2 != nil { + sum += l2.Val + l2 = l2.Next + } + curr.Next = &ListNode{Val: sum % 10} + carry = sum / 10 + curr = curr.Next + } + return dummy.Next +}