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
91 changes: 91 additions & 0 deletions longest_substring_without_.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
## Step1

- 空文字列の処理は別だった。right=1から始めてるので。
- スペースの処理は迷ったが、普通の文字列と同じように扱われるらしい。
- len()の書き方を忘れていた。
- while True:をleftに関するfor文にしようとしていた。left = left+1の処理をしているのでいらない。
- if(right ≥ length) ではない。最後にright = right+1をするので。
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

というより、そのようにrightを定めている(exclusive)ためですかね。


```python
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
if(s==''):
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

if not s:

で良いと思います。

参考までにスタイルガイドへのリンクを貼ります。

https://google.github.io/styleguide/pyguide.html#2144-decision

Use the “implicit” false if possible, e.g., if foo: rather than if foo != []:. There are a few caveats that you should keep in mind though:

ただし、上記のスタイルガイドは唯一絶対のルールではなく、複数あるスタイルガイドの一つに過ぎないということを念頭に置くことをお勧めします。また、所属するチームにより何が良いとされているかは変わります。自分の中で良い書き方の基準を持ちつつ、チームの平均的な書き方で書くことをお勧めいたします。

return 0
left = 0
right = 1
longest = 0
length = len(s)
while True:
current_length = right - left
current_kind = len(set(s[left:right]))
if(current_length != current_kind):
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

if 文の条件式は () で囲わないほうが多いと思います。

if current_length != current_kind:

() で囲うのは複数行に分けるときなどになると思います。

left = left + 1
else:
longest = max(right - left, longest)
right = right + 1
if(right > length):
return(longest)

```

## Step2

- なんか嫌な予感がしたのでたまたま見たら、配列のスライスはO(k)であることを知る。https://wiki.python.org/moin/TimeComplexity
- 他の方の実装を見る限り、素直にsetの中で同じ文字があるかの判定が良さそう。
- 上のTime Complexityのページ曰く、setのx in sはなぜかAverageではO(1)らしい WorstではO(n)
- lenもO(1)らしい
- left, right = 0, 0の方がまとまりあるかも
- 別々に定義するより良いし、空文字列の場合に場合分けしなくて良い
- whileの代わりにfor文を使うことも考えたが、同じ文字がある場合はleft、ない場合はrightを進める、という論理の方がわかりやすいと思った
- while True: if(条件) returnよりも、while 条件 return の方がいいかも(ahayashiさんの実装)
- https://github.com/hayashi-ay/leetcode/pull/47/files
- 登場文字の位置を管理するコードも見た、比較のために管理するものが増えるのでやめたhttps://github.com/usatie/leetcode/blob/main/Blind75/02. Longest Substring Without Repeating Characters/ans_01_20240125.cpp
- ついでにASCII などについて知る https://discordapp.com/channels/1084280443945353267/1198621745565937764/1211683153668866139

```python
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
left, right = 0, 0
longest = 0
length = len(s)
current_set = set()
while right<length:
  if s[right] in current_set:
current_set.remove(s[left])
left = left + 1
else:
current_set.add(s[right])
longest = max(longest, right - left + 1)
right = right + 1
return longest

```

## Step3

- left, right = 0としてしまった

```python
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
left, right = 0, 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.

length = len(s)
longest = 0
unique_char_set = set()
while right < length:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

right < length:
は、
right < len(s):
のほうが、right が s を走ることが明確化するので、私はいいと思います。

if s[right] in unique_char_set:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

while のほうが素直な気がしますがこれも趣味ですかね。
こうすると、上の while が for right in range(len(s)): にできるんじゃないですかね。

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.

ありがとうございます。
この部分をwhileにして、上をfor文にしたいという理由は何がありますか。
自分の感覚としては、違反せずに範囲を広げられるならrightを足す、違反するなら範囲を狭めたいのでleftを足す、という対称的な処理ができるイメージでこのコードを採用しました。

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

どちらでもいいですが、ループは仕事の引き継ぎのようなものだと思っていて、どこで引き継ぐかです。そのときに、right が動くたびに引き継ぐというのは一つ素直、というくらいの感覚です。

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

他の人のコードを見たら、たぶん、皆さん色々だと思うのです。別に、その選択肢の範囲が見えていて選んでいるならばいいです。

unique_char_set.remove(s[left])
left = left + 1
else:
unique_char_set.add(s[right])
longest = max(longest, right-left+1)
right = right + 1
return longest
```

## 参考にした資料
[Pythonの計算量のドキュメント](<https://wiki.python.org/moin/TimeComplexity>)
[ASCIIについて](<https://discordapp.com/channels/1084280443945353267/1198621745565937764/1211683153668866139>)
[ahayashiさんの実装](<https://github.com/hayashi-ay/leetcode/pull/47/files>)
[usatieさんの実装](<https://github.com/usatie/leetcode/blob/main/Blind75/02.%20Longest%20Substring%20Without%20Repeating%20Characters/ans_01_20240125.cpp>)
[hashについて](https://discordapp.com/channels/1084280443945353267/1199984201521430588/1200295973050650664)