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
41 changes: 41 additions & 0 deletions 0125.Valid-Palindrome/memo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# 125. Valid Palindrome

## step1
外側から判定していくO(len(s))解法。数字を無視しして一度間違えた。

## step2

### 他の人のコード

> 本質的にはそれほど変わりません。
>
> アルファベット以外を取り除く。
> 小文字にする。
> 頭からたどったものと尻からたどったものが同じかを確認する。
>
> これ、3つのループにもできますし、1つのループにもできます。

自分は1つのループで解いた。

https://github.com/hayashi-ay/leetcode/pull/9

isalnum()メソッドは知らなかった

https://docs.python.org/ja/3/library/stdtypes.html#str.isalnum

> A character c is alphanumeric if one of the following returns True: c.isalpha(), c.isdecimal(), c.isdigit(), or c.isnumeric()

ただし `isalpha() or isdecimal()`より範囲が広い

mapを使う書き方も参考になる

https://github.com/naoto-iwase/leetcode/pull/63

- `re.findall(r"[a-zA-Z0-9]", s)` で抽出 -> 小文字化 -> 両端比較。ASCII の英数字に限定したい意図なら正規表現がはっきりする。
- `isalnum()` は Unicode の「数字」まで拾う。問題の解釈次第。

https://github.com/TaisukeFujise/leetcode_tafujise/pull/10

https://github.com/Kitaken0107/GrindEasy/pull/8


21 changes: 21 additions & 0 deletions 0125.Valid-Palindrome/step1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class Solution:
def isPalindrome(self, s: str) -> bool:
def is_alphanumeric(c):
return "a" <= c <= "z" or "A" <= c <= "Z" or "0" <= c <= "9"

first = 0
last = len(s) - 1

while first < last:
if not is_alphanumeric(s[first]):
first += 1
continue
if not is_alphanumeric(s[last]):
last -= 1
continue
if s[first].lower() != s[last].lower():
return False
first += 1
last -= 1

return True
61 changes: 61 additions & 0 deletions 0125.Valid-Palindrome/step2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import re


class Solution:
def isPalindrome(self, s: str) -> bool:
filtered_lower = list(map(str.lower, filter(str.isalnum, s)))
return filtered_lower == filtered_lower[::-1]


class Solution:
def isPalindrome(self, s: str) -> bool:
left, right = 0, len(s) - 1
while left < right:
if not s[left].isalnum():
left += 1
elif not s[right].isalnum():
right -= 1
elif s[left].lower() == s[right].lower():
left += 1
right -= 1
else:
return False
return True


class Solution:
def isPalindrome(self, s: str) -> bool:
alnums = re.findall(r"[a-zA-Z0-9]", s)
normalized = [ch.lower() for ch in alnums]
left, right = 0, len(normalized) - 1
while left < right:
if normalized[left] != normalized[right]:
return False
left += 1
right -= 1
return True


class Solution:
def isPalindrome(self, s: str) -> bool:
cleaned = [c for c in s.lower() if c.isalnum()]
return cleaned == cleaned[::-1]


class Solution:
def isPalindrome(self, s: str) -> bool:
def next_alnum(index, step):
while 0 <= index < len(s):
if s[index].isalnum():
break
index += step
return index

left = next_alnum(0, 1)
right = next_alnum(len(s) - 1, -1)
while left < right:
if s[left].lower() != s[right].lower():
return False
left = next_alnum(left + 1, 1)
right = next_alnum(right - 1, -1)
return True