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
62 changes: 62 additions & 0 deletions memo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
## 今回解いた問題と次に解く問題
- 今回解いた問題:392. Is Subsequence https://leetcode.com/problems/is-subsequence?envType=problem-list-v2&envId=xo2bgr0r
- 次に解く問題:141. Linked List Cycle https://leetcode.com/problems/linked-list-cycle?envType=problem-list-v2&envId=xo2bgr0r

## Step 1
### 方針
部分文字列sのどの文字をチェックしているか確かめる変数indexを用意して、チェックされる対象のtの前の数字からs[index]と同じかどうかを確かめていく。同じだった場合、indexを1つ後ろにずらして続ける。sの一番後ろの文字について、同じものが見つかったらその時点でTrueを返す。見つからなかったらFalseを返す。時間計算量はO(n)、空間計算量はO(1)。

### 考えたこと
- sが""だったときはTrueを返すべきなのに、s[0]でアクセスできずエラーになるのでsの長さが0の場合はTrueを返すような処理を加えた。""が入力される場合をあらかじめ考慮すべきであった。
- indexは変数の名前として適切ではない気がしたが、ほかに何か適切な名前が思い浮かばなかった。

```python
class Solution:
def isSubsequence(self, s: str, t: str) -> bool:
index = 0
if len(s) == 0:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

こちらのコメントをご参照ください。
mamo3gr/arai60#6 (comment)

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.

ありがとうございます! Implicit False を用いることでコードが簡潔になることを確認しました。これからは使おうと思います。

return True
for i in range(len(t)):
if s[index] == t[i]:
index += 1
if index == len(s):
return True
return False
```
## Step 2
### 読んだコード
- https://github.com/tom4649/Coding/pull/52/changes
- https://github.com/dxxsxsxkx/leetcode/pull/57/changes
### 考えたこと
- indexはs_indexやt_indexなどと書き換えることができる。
- sが空な判定に加えて、tが空かどうかの判定も加えたほうがいい。
- 正規表現で書くやり方もある。この場合、reというモジュールを使う(https://docs.python.org/ja/3/library/re.html)。matchはstringの前方の正規表現がpatternと一致した場合にMatchオブジェクトを返し、一致しなかった場合はNoneを返す関数。文字列の結合の時間計算量はO(n^2)だが、sが小さいので許容範囲か。

```python
class Solution:
def isSubsequence(self, s: str, t: str) -> bool:
if len(s) == 0:
return True
if len(t) == 0:
return False
s_index = 0
for i in range(len(t)):
if s[s_index] == t[i]:
s_index += 1
if s_index == len(s):
return True
return False
```
## Step 3(正規表現で書く)

```python
import re

class Solution:
def isSubsequence(self, s: str, t: str) -> bool:
pattern = ""
for c in s:
pattern += ".*" + c

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

この書き方の場合、時間計算量が O(N2) かかる点に注意が必要です。 Python は文字列は Immutable で、文字列を連結するたびに新しいインスタンスが作られます。新しいインスタンスが作られる度に、既存の文字列をコピーし、新しい文字を連結するため、トータルで O(N2) かかります。
特定の条件下で in-place な処理に置き換わりますが、置き換わる条件は常識には含まれていないと思います。これを前提とした処理を書くのは避けたほうが無難だと思います。

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.

ありがとうございます。Pythonの文字列の連結は新しいインスタンスが作られるたびに既存の文字列をコピーし、時間計算量がO(n^2)になるため、避けることが無難であることを理解しました。

Match = re.match(pattern, t)
return Match is not None
```