diff --git a/876_middle_of_the_linked_list/memo.md b/876_middle_of_the_linked_list/memo.md new file mode 100644 index 0000000..2e29a81 --- /dev/null +++ b/876_middle_of_the_linked_list/memo.md @@ -0,0 +1,30 @@ +# 876. Middle of the Linked List + +https://leetcode.com/problems/middle-of-the-linked-list/ + +## Comments + +### step1 + +* slow, fast を使うか、あるいは 2 pass でノードの総数を求めてから 2nd pass で返すというのもできるだろう +* slow, fast が 1 pass なのと、シミュレーションする限りシンプルに書けそうだったのでそうした。 +* ただ production なら後者の方法で書くかもしれない。読み手にとってはより直感的だと思う +* 問題の例に与えられている、node が偶数、奇数のときでそれぞれシミュレーションした + +```cpp +// 1,1 -> 2,3 -> 3,5 (fast->next == nullptr) +// 1,1 -> 2,3 -> 3,5 -> 4,nullptr (fast == nullptr) +``` + +* あとは edge case として node 数が 0, 1, 2 のあたりも脳内でテストした。 +* 7:00 くらいで AC + +### step2 + +* 2 pass も一応書いた。思ったより冗長になったけど、一応こっちのほうがわかりやすいかなという気はする。 + * size (length) を求める関数だったので、例に倣って 1-index にしたが 0-index でもよかったかもしれない。ただその場合 head == nullptr のとき何を返すのかとか、関数名どうするかとか考慮すべき要素が増える気はする。 + * two "middle"s のとき first を返してください、みたいなのにも対応しやすいとは思う。 + +### step3 + +* step1 のほうがよいかなという気がする。`fast`, `slow` の変数名は好みがあるかもしれない。 diff --git a/876_middle_of_the_linked_list/step1.cpp b/876_middle_of_the_linked_list/step1.cpp new file mode 100644 index 0000000..c8e09d1 --- /dev/null +++ b/876_middle_of_the_linked_list/step1.cpp @@ -0,0 +1,24 @@ +/** + * Definition for singly-linked list. + * 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) {} + * }; + */ +// 1,1 -> 2,3 -> 3,5 (fast->next == nullptr) +// 1,1 -> 2,3 -> 3,5 -> 4,nullptr (fast == nullptr) +class Solution { +public: + ListNode* middleNode(ListNode* head) { + ListNode* slow = head; + ListNode* fast = head; + while (fast && fast->next) { + slow = slow->next; + fast = fast->next->next; + } + return slow; + } +}; diff --git a/876_middle_of_the_linked_list/step2.cpp b/876_middle_of_the_linked_list/step2.cpp new file mode 100644 index 0000000..2cd8239 --- /dev/null +++ b/876_middle_of_the_linked_list/step2.cpp @@ -0,0 +1,36 @@ +/** + * Definition for singly-linked list. + * 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) {} + * }; + */ +// 1,1 -> 2,3 -> 3,5 (fast->next == nullptr) +// 1,1 -> 2,3 -> 3,5 -> 4,nullptr (fast == nullptr) +class Solution { +public: + ListNode* middleNode(ListNode* head) { + // Return the second node when there are two "middle"s. 1-indexed. + int middle_index = GetListSize(head) / 2 + 1; + int index = 1; + ListNode* node = head; + while (index != middle_index) { + ++index; + node = node->next; + } + return node; + } +private: + int GetListSize(ListNode* head) { + int size = 0; + ListNode* node = head; + while (node) { + ++size; + node = node->next; + } + return size; + } +}; diff --git a/876_middle_of_the_linked_list/step3.cpp b/876_middle_of_the_linked_list/step3.cpp new file mode 100644 index 0000000..84f2ca9 --- /dev/null +++ b/876_middle_of_the_linked_list/step3.cpp @@ -0,0 +1,22 @@ +/** + * Definition for singly-linked list. + * 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* middleNode(ListNode* head) { + ListNode* slow = head; + ListNode* fast = head; + while (fast && fast->next) { + slow = slow->next; + fast = fast->next->next; + } + return slow; + } +};