diff --git a/arai60/reverse-linked-list/README.md b/arai60/reverse-linked-list/README.md new file mode 100644 index 0000000..08d11b8 --- /dev/null +++ b/arai60/reverse-linked-list/README.md @@ -0,0 +1,30 @@ +## 考察 +- 過去に解いたことあり +- 方針は2つ思い浮かんだ + - 再帰の帰りがけで後ろから繋ぎ変えていく + - time: O(n), space: O(n) + - stackに一旦積んで、取り出しながら後ろから繋ぎ変えていく + - time: O(n), space: O(n) +- ノードの数は最大で5000 -> スタックオーバーフローも大丈夫そうなので再帰でやってみる +- あとは実装 + +## Step1 +- 上のアルゴリズムを実装 +- stackを使っても考え方は一緒なのでやってみた +- time: O(n), space: O(n) + +## Step2 +- Solutionsを覗いてみた +- 後ろからやらなくても、前から繋ぎ変えていくこともできたみたい +- 前から繋ぎ変えていけば、再帰呼び出しのコールスタックやスタックがなくなるので、メモリ使用量がO(1)で済んだ + +## Step3 +- 1回目: 1m03s +- 2回目: 54s +- 3回目: 48s + +## Step4 +- レビューを元に修正 +- 変数名を変更 + - temp -> next_node + diff --git a/arai60/reverse-linked-list/step1_recursion.cpp b/arai60/reverse-linked-list/step1_recursion.cpp new file mode 100644 index 0000000..eef5202 --- /dev/null +++ b/arai60/reverse-linked-list/step1_recursion.cpp @@ -0,0 +1,21 @@ +/** + * 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* reverseList(ListNode* head) { + if (!head || !head->next) return head; + + ListNode* new_head = reverseList(head->next); + head->next->next = head; + head->next = nullptr; + return new_head; + } +}; diff --git a/arai60/reverse-linked-list/step1_recursion_with_helper.cpp b/arai60/reverse-linked-list/step1_recursion_with_helper.cpp new file mode 100644 index 0000000..cf6ced9 --- /dev/null +++ b/arai60/reverse-linked-list/step1_recursion_with_helper.cpp @@ -0,0 +1,29 @@ +/** + * 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* reverseList(ListNode* head) { + auto result = reverseListHelper(head); + return result.first; + } + +private: + pair reverseListHelper(ListNode* node) { + if (!node) return {nullptr, nullptr}; + if (!node->next) return {node, node}; + + ListNode* next_node = node->next; + node->next = nullptr; + auto [head, tail] = reverseListHelper(next_node); + tail->next = node; + return {head, node}; + } +}; diff --git a/arai60/reverse-linked-list/step1_stack.cpp b/arai60/reverse-linked-list/step1_stack.cpp new file mode 100644 index 0000000..f88e6ab --- /dev/null +++ b/arai60/reverse-linked-list/step1_stack.cpp @@ -0,0 +1,33 @@ +/** + * 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* reverseList(ListNode* head) { + if (!head) return nullptr; + + stack node_stack; + ListNode* node = head; + while (node) { + node_stack.push(node); + node = node->next; + } + + ListNode* new_head = node_stack.top(); + node_stack.pop(); + while (!node_stack.empty()) { + node = node_stack.top(); + node_stack.pop(); + node->next->next = node; + node->next = nullptr; + } + return new_head; + } +}; diff --git a/arai60/reverse-linked-list/step2.cpp b/arai60/reverse-linked-list/step2.cpp new file mode 100644 index 0000000..451217f --- /dev/null +++ b/arai60/reverse-linked-list/step2.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) {} + * }; + */ +class Solution { +public: + ListNode* reverseList(ListNode* head) { + ListNode* previous_node = nullptr; + ListNode* node = head; + while (node) { + ListNode* temp = node->next; + node->next = previous_node; + previous_node = node; + node = temp; + } + return previous_node; + } +}; diff --git a/arai60/reverse-linked-list/step3.cpp b/arai60/reverse-linked-list/step3.cpp new file mode 100644 index 0000000..451217f --- /dev/null +++ b/arai60/reverse-linked-list/step3.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) {} + * }; + */ +class Solution { +public: + ListNode* reverseList(ListNode* head) { + ListNode* previous_node = nullptr; + ListNode* node = head; + while (node) { + ListNode* temp = node->next; + node->next = previous_node; + previous_node = node; + node = temp; + } + return previous_node; + } +}; diff --git a/arai60/reverse-linked-list/step4.cpp b/arai60/reverse-linked-list/step4.cpp new file mode 100644 index 0000000..dd10fd3 --- /dev/null +++ b/arai60/reverse-linked-list/step4.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) {} + * }; + */ +class Solution { +public: + ListNode* reverseList(ListNode* head) { + ListNode* previous_node = nullptr; + ListNode* node = head; + while (node) { + ListNode* next_node = node->next; + node->next = previous_node; + previous_node = node; + node = next_node; + } + return previous_node; + } +};