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
113 changes: 113 additions & 0 deletions 125. Valid Palindrome.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
## step1 とりあえず解く
- 計算量
- 時間
- O(n)
- 空間
- O(n)
- 回文の対象がアルファベット・数値のみだったのでreplaceAllで対象の文字意外を空文字に変換した
- 空間計算量をO(1)にしたかったが思いつかず、愚直な方法で解いた

```java
class Solution {
public boolean isPalindrome(String s) {
s = s.replaceAll("[^a-zA-Z0-9]", "").toLowerCase();
System.out.println(s);
char[] chars = s.toCharArray();
int charsLength = chars.length;
for(int i = 0; i< charsLength/2; i++){
if(chars[i] != chars[charsLength-i-1]){
return false;
}
}
return true;
}
}
```

## step2 他の人の回答を見る
- `Character.isLetterOrDigit` というメソッドを学べた
- 空間的・時間的計算量は私の回答と変わらないがシンプルに書かれていて可読性が高く感じた
- String Builderで文字列連結しているところも `+` に比べメモリ効率が良さそう

```java
public class Solution {
public boolean isPalindrome(String s) {
StringBuilder newStr = new StringBuilder();
for (char c : s.toCharArray()) {
if (Character.isLetterOrDigit(c)) {
newStr.append(Character.toLowerCase(c));
}
}
return newStr.toString().equals(newStr.reverse().toString());
}
}
```

- こちらが模範解答に近そう
- 計算量
- 時間
- O(n)
- 空間
- O(1)
- 2つポインターを使い、与えられた文字列を加工せずに使うことで空間計算量を減らしている
-

```java
public class Solution {
public boolean isPalindrome(String s) {
int l = 0, r = s.length() - 1;

while (l < r) {
while (l < r && !alphaNum(s.charAt(l))) {
l++;
}
while (r > l && !alphaNum(s.charAt(r))) {
r--;
}
if (Character.toLowerCase(s.charAt(l)) != Character.toLowerCase(s.charAt(r))) {
return false;
}
l++; r--;
}
return true;
}

public boolean alphaNum(char c) {
return (c >= 'A' && c <= 'Z' ||
c >= 'a' && c <= 'z' ||
c >= '0' && c <= '9');
}
}
```

### step3 3回書く
- step2の回答とほぼおなじ
- 個人的にbooleanを返すメソッド名はis~とかにしたいのでそこを修正

```java
class Solution {
public boolean isPalindrome(String s) {
int r = s.length() -1;
int l = 0;
while(l < r){
while(l < r && !this.isAlphanumeric(s.charAt(r))){
r--;
}
while(l < r && !this.isAlphanumeric(s.charAt(l))){
l++;
}
if(Character.toLowerCase(s.charAt(r)) != Character.toLowerCase(s.charAt(l))){
Copy link

Choose a reason for hiding this comment

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

これ、入力に "***" などが来るとどうなりますかね。この行が実行されて、下に抜けるので一応問題はないはずですが、ちょっと予想した動きではないような感覚を持ちました。

この上で l, r を比較して break するか、while を if に変えて continue するか。
いくつか選択はありそうですが、あまりしっくり来ませんね。

return false;
}
r--;
l++;
}
return true;
}

private boolean isAlphanumeric(char c){
return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9');
}
}

```