Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions arai60/reverse-linked-list/README.md
Original file line number Diff line number Diff line change
@@ -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

21 changes: 21 additions & 0 deletions arai60/reverse-linked-list/step1_recursion.cpp
Original file line number Diff line number Diff line change
@@ -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;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

私、head->next がお尻になることを考えさせないほうが負荷が軽いと思うんですよね。どこかでその議論をしていたはずです。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

なるほど。確かに返り値で次に処理すべきノードを返してあげれば脳の負担が減ります。
この考え方でも実装してみます。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

こちらに実装してみました。-> 0ce1690

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

head->next = nullptr;
return new_head;
}
};
29 changes: 29 additions & 0 deletions arai60/reverse-linked-list/step1_recursion_with_helper.cpp
Original file line number Diff line number Diff line change
@@ -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<ListNode*, ListNode*> 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};
}
};
33 changes: 33 additions & 0 deletions arai60/reverse-linked-list/step1_stack.cpp
Original file line number Diff line number Diff line change
@@ -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<ListNode*> 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;
}
};
24 changes: 24 additions & 0 deletions arai60/reverse-linked-list/step2.cpp
Original file line number Diff line number Diff line change
@@ -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;
}
};
24 changes: 24 additions & 0 deletions arai60/reverse-linked-list/step3.cpp
Original file line number Diff line number Diff line change
@@ -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;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tempよりnext_nodeとかの方が良さそうです。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

一時的な保存に使っているのでtempとしていました。見直してみます。

node->next = previous_node;
previous_node = node;
node = temp;
}
return previous_node;
}
};
24 changes: 24 additions & 0 deletions arai60/reverse-linked-list/step4.cpp
Original file line number Diff line number Diff line change
@@ -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;
}
};