Skip to content
Open
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
90 changes: 90 additions & 0 deletions 206. Reverse Linked List.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# [206. Reverse Linked List](https://leetcode.com/problems/reverse-linked-list/description/)

## Step1 
### 問題意図の考察
- 片方向連結リストの処理
- スタック

### 解法を考える
- LIFO で最後に入れた要素から取り出す。
- 全てのnodeをstd::stack<ListNode*>に積む。
- ダミーノード作成
- 逆順で連結
- 閉じる
- 新しい先頭に返す

### コメント
- これまで学習したLinked Listの問題とCSZAPで学習したstackの知識で初めて解くことができた。ただ、解けるようになる事にあまり意味はなく、あらゆる選択肢を手札として持ち正しい判断ができることが目的なので、その幅を広げていきたい。
- CSZAPで体系的に学んだことが、どういう挙動となるか意識することができた。問題を通して学ぶこともできるが、体系的に全体感と詳細を学ぶ事により時間をかけていきたい。インプット&アウトプットの割合。
- 計算量などはあまり意識できなかったので、ここは課題。

```cpp
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (head == nullptr) {
return head;
}
ListNode* node = head;
std::stack<ListNode*> nodes;
while (node != nullptr) {
nodes.push(node);
node = node->next;
}
ListNode reverse_node = ListNode();
node = &reverse_node;
while (!nodes.empty()) {
node->next = nodes.top();
nodes.pop();
node = node->next;
}
node->next = nullptr;
return reverse_node.next;
}
};

```

## Step2

```cpp
while (node != nullptr)

```
while (node)と記載していたが、pointerを条件式で使用すると、boolへ変換される。e.g. nullptr->false、非nullptr->true
可読性という点で、while (node) だとbool? int? と一瞬考えると感じ、上記の書き方のまま採用した。参考:https://google.github.io/styleguide/cppguide.html#Boolean_Expressions
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

以前私が調べた限りでは、どちらの派閥の方々もいらっしゃるようで、どちらでも良さげに見えました。柔軟に、所属しているチームのスタイルガイドに従うと良いかな、と思っています。

参考: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#es87-dont-add-redundant--or--to-conditions

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.

@huyfififi
こちら随分とご返信遅くなってしまい申し訳ありません。

貴重なご意見ありがとうございます。
未経験+9ヶ月ほどしか書いてないので、実際の現場での感覚など非常にありがたいです。
都度reference確認しながら、所属するスタイルガイドに都度合わせられるように学習進めてみます。

短い方がいいか、どっちがいいだろう。

- https://github.com/Ryotaro25/leetcode_first60/blob/main/206.ReverseLinkedList/step6.cpp
-> 上記の考えを考慮しないなら、こういう書き方もできる。
```cpp
if (!head) {
return nullptr;
}

```

- ポインタの反転版 (走査しながら リンクの向きを1本ずつ逆向きに付け替えるだけ)という考え方もある。
-> stackを使わないという点では、この問題意図とは異なるが、一つの例として。
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

私がもし、Stackで入力をひっくり返す、というテクニックを問いたいなら、Linked Listではなくもう少しシンプルな問題設計をするように思います。Linked Listを扱う問題なら、繋ぎかえが正しく行えるかが難しく、見たいところような気がするので、こちらが想定解かもしれませんね。

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.

@huyfififi
ご返信随分と遅くなり大変申し訳ございません。

ご意見頂きありがとうございます。
確かにLinked Listを扱う問題であれば、正しく繋ぎかえができるかがみたいと考えるのがみたい所ですかね。
改めて問題意図を意識して、書いてみようと思います。


```cpp
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* previous_node = nullptr;
ListNode* node = head;

while (node != nullptr) {
ListNode* next = node->next;
node->next = previous_node;
previous_node = node;
node = next;
}
return previous_node;
}
};

```

## Step3
20min