diff --git a/2.-Add-Two-Numbers/memo.md b/2.-Add-Two-Numbers/memo.md new file mode 100644 index 0000000..b6cdc73 --- /dev/null +++ b/2.-Add-Two-Numbers/memo.md @@ -0,0 +1,84 @@ +レビューの利便性のため、各ステップで書いたコードはこちらにも転記してみます。 + +# step1 +元のリストに対して非破壊的であるようにしたい。素直に繰り上がりを記録しながら足していく方針で解いた。 +```cpp +class Solution { + public: + ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { + ListNode dummy(0, nullptr); + ListNode* tail = &dummy; + int carry = 0; + while (l1 != nullptr || l2 != nullptr || carry != 0) { + int val = (l1 ? l1->val : 0) + (l2 ? l2->val : 0) + carry; + carry = val / 10; + ListNode* append = new ListNode(val % 10, nullptr); + tail->next = append; + l1 = l1 ? l1->next : nullptr; + l2 = l2 ? l2->next : nullptr; + tail = tail->next; + } + return dummy.next; + } +}; +``` + +# step2 +他の人のコードを見る。 +- [ryosuketcさんのコード](https://github.com/ryosuketc/leetcode_arai60/blob/2_add_two_numbers/2_add_two_numbers/step3.py)と本質的に同じだがこちらのほうが丁寧に関数や定数を切り出している。 +- 他の演算も実装する必要があったら補助関数を設定すると思う。 +- 他のコメントでも三項演算子は避けられているようだが、今回のようなnullでないことだけ判定するくらいなら左から右に読みやすいと思うので許されたい… +- l1, l2がnullptrだったときだけ使うfakeを置いたら場合分けする部分が集約できた。 + +```cpp +class Solution { + public: + ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { + ListNode dummy(-1, nullptr); + ListNode* tail = &dummy; + int carry = 0; + while (l1 || l2 || carry) { + // l1, l2がnullptrだった場合0ノードを一時的に設定する。このブロックを抜けると解放される。 + ListNode fake(0); + l1 = l1 ? l1 : &fake; + l2 = l2 ? l2 : &fake; + + int total = l1->val + l2->val + carry; + carry = total / 10; + tail->next = new ListNode(total % 10, nullptr); + tail = tail->next; + l1 = l1->next; + l2 = l2->next; + } + return dummy.next; + } +}; + +``` + +# step3 +fakeをwhileの外においてみた。 +```cpp +class Solution { + public: + ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { + ListNode dummy = ListNode(-1); + ListNode* tail = &dummy; + int carry = 0; + + ListNode fake = ListNode(0); + while (l1 || l2 || carry) { + l1 = l1 ? l1 : &fake; + l2 = l2 ? l2 : &fake; + int total = l1->val + l2->val + carry; + carry = total / 10; + tail->next = new ListNode(total % 10); + + tail = tail->next; + l1 = l1->next; + l2 = l2->next; + } + return dummy.next; + } +}; +``` diff --git a/2.-Add-Two-Numbers/step1.cpp b/2.-Add-Two-Numbers/step1.cpp new file mode 100644 index 0000000..13bcd23 --- /dev/null +++ b/2.-Add-Two-Numbers/step1.cpp @@ -0,0 +1,26 @@ +struct ListNode { + int val; + ListNode* next; + ListNode() : val(0), next(nullptr) {} + ListNode(int x) : val(x), next(nullptr) {} + ListNode(int x, ListNode* next) : val(x), next(next) {} +}; + +class Solution { + public: + ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { + ListNode dummy(0, nullptr); + ListNode* tail = &dummy; + int carry = 0; + while (l1 != nullptr || l2 != nullptr || carry != 0) { + int val = (l1 ? l1->val : 0) + (l2 ? l2->val : 0) + carry; + carry = val / 10; + ListNode* append = new ListNode(val % 10, nullptr); + tail->next = append; + l1 = l1 ? l1->next : nullptr; + l2 = l2 ? l2->next : nullptr; + tail = tail->next; + } + return dummy.next; + } +}; diff --git a/2.-Add-Two-Numbers/step2.cpp b/2.-Add-Two-Numbers/step2.cpp new file mode 100644 index 0000000..93a8990 --- /dev/null +++ b/2.-Add-Two-Numbers/step2.cpp @@ -0,0 +1,30 @@ +struct ListNode { + int val; + ListNode* next; + ListNode() : val(0), next(nullptr) {} + ListNode(int x) : val(x), next(nullptr) {} + ListNode(int x, ListNode* next) : val(x), next(next) {} +}; + +class Solution { + public: + ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { + ListNode dummy(-1, nullptr); + ListNode* tail = &dummy; + int carry = 0; + while (l1 || l2 || carry) { + // l1, l2がnullptrだった場合0ノードを一時的に設定する。このブロックを抜けると解放される。 + ListNode fake(0); + l1 = l1 ? l1 : &fake; + l2 = l2 ? l2 : &fake; + + int total = l1->val + l2->val + carry; + carry = total / 10; + tail->next = new ListNode(total % 10, nullptr); + tail = tail->next; + l1 = l1->next; + l2 = l2->next; + } + return dummy.next; + } +}; diff --git a/2.-Add-Two-Numbers/step3.cpp b/2.-Add-Two-Numbers/step3.cpp new file mode 100644 index 0000000..6e178b6 --- /dev/null +++ b/2.-Add-Two-Numbers/step3.cpp @@ -0,0 +1,30 @@ +struct ListNode { + int val; + ListNode* next; + ListNode() : val(0), next(nullptr) {} + ListNode(int x) : val(x), next(nullptr) {} + ListNode(int x, ListNode* next) : val(x), next(next) {} +}; + +class Solution { + public: + ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { + ListNode dummy = ListNode(-1); + ListNode* tail = &dummy; + int carry = 0; + + ListNode fake = ListNode(0); + while (l1 || l2 || carry) { + l1 = l1 ? l1 : &fake; + l2 = l2 ? l2 : &fake; + int total = l1->val + l2->val + carry; + carry = total / 10; + tail->next = new ListNode(total % 10); + + tail = tail->next; + l1 = l1->next; + l2 = l2->next; + } + return dummy.next; + } +};