-
Notifications
You must be signed in to change notification settings - Fork 0
387. First Unique Character in a String #20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
7dc074e
c9efa6b
15e376f
60bf09f
df475cf
cb43b3d
db53a63
734e0db
6cfaf86
ca56160
441303e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| # step1 | ||
| 自分で解いた。 | ||
|
|
||
| # step1-1 | ||
| すぐに解法が浮かんだ。 | ||
| 1回目の走査で文字をカウントして、2回目の走査でカウント1のもののindexを返すという考え。 | ||
| 時間計算量:O(n) n:文字列の長さ、空間計算量:O(n) | ||
|
|
||
| # step1-2 | ||
| 次に解法が浮かんだ。小文字英字しか使わないパターンでは配列を使ったカウントがよく使われるイメージだったのですぐ実装できた。 | ||
| ただ実際の入力は英小文字以外も入ってるくる可能性があるので、条件を交渉するか1改善案くらいのイメージ。 | ||
| 時間計算量:O(n) n:文字列の長さ、空間計算量:O(1) | ||
| 実行時間がかなりはやくなったのはboxing/unboxingのオーバーヘッドのせいかなと予想。 | ||
|
|
||
| # step2 | ||
| 他の人、もしくは回答をみて参考にしたもの | ||
|
|
||
| # step2-1 | ||
| https://github.com/seal-azarashi/leetcode/pull/15/files | ||
| を参考にした。特に入力条件としてサロゲートなどを意識できていなかったので大変勉強になった。(odaさんのコメントのこちらも:https://note.com/ttuusskk/n/n1bff5d8e638c) | ||
| マジックナンバーを使わないようにいくつか定数を設定した。 | ||
|
|
||
| # step3 | ||
| いただいたコメントを元に修正したもの | ||
| 特に変数名について意味をもう少し具体的にして、読む人が大体正しくイメージができるくらいにすることを忘れないようにしたい。 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| class Solution { | ||
| // leetcode | ||
| public int firstUniqChar(String s) { | ||
| Map<Character, Integer> indices = new HashMap<>(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. step1-2 以降のように、配列を使ったほうが処理が軽くなると思います。 |
||
| for (int i = 0; i < s.length(); i++) { | ||
| char c = s.charAt(i); | ||
| indices.put(c, indices.getOrDefault(c, 0) + 1); | ||
| } | ||
| for (int i = 0; i < s.length(); i++) { | ||
| char c = s.charAt(i); | ||
| if (indices.get(c) == 1) { | ||
| return i; | ||
| } | ||
| } | ||
| return -1; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| class Solution { | ||
| // leetcode | ||
| public int firstUniqChar(String s) { | ||
| int[] cs = new int[26]; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| for (int i = 0; i < s.length(); i++) { | ||
| char c = s.charAt(i); | ||
| cs[c - 'a']++; | ||
| } | ||
| for (int i = 0; i < s.length(); i++) { | ||
| char c = s.charAt(i); | ||
| if (cs[c - 'a'] == 1) { | ||
| return i; | ||
| } | ||
| } | ||
| return -1; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| class Solution { | ||
| // leetcode | ||
| private static final int ALPHABET_SIZE = 26; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 自分なら There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 小文字のアルファベットの数のことなので、大きさを表す size は適当でないように思います。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. このままでも良さそうです。https://csrc.nist.gov/glossary/term/alphabet_size There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. なんと、一般的な語彙だったのですね。失礼しました。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ちょっと上記のソース読んでみたのですが、どうやら上記の alphabet とは一般的に想起される abc... とは違うみたいです。全く専門外なのであまり自信がないですが、ソースになっている論文での使われ方を見るに size は可変であるようなので、恐らく形式言語における alphabet の事を指しているのかと思われます。 abc... の方の alphabet について、これの size が a-z の数26を指すという例は、私の方で少しググった限りでは見つけられませんでした。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (もし英語ネイティブで形式言語についての知識がある方がいらっしゃったら意見伺いたい...) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. https://www.ldoceonline.com/dictionary/alphabet
setに対してsizeを使うのは、普通の表現だと思います。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
なるほど確かに。 |
||
| private static final char ALPHABET_OFFSET = 'a'; | ||
| public static final int NOT_FOUND = -1; | ||
|
|
||
| public int firstUniqChar(String s) { | ||
| int[] frequency = new int[ALPHABET_SIZE]; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 頻度の配列であることがわかるように |
||
| for (int i = 0; i < s.length(); i++) { | ||
| char c = s.charAt(i); | ||
| frequency[c - ALPHABET_OFFSET]++; | ||
| } | ||
| for (int i = 0; i < s.length(); i++) { | ||
| char c = s.charAt(i); | ||
| if (frequency[c - ALPHABET_OFFSET] == 1) { | ||
| return i; | ||
| } | ||
| } | ||
| return NOT_FOUND; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. LeetCodeの制約上仕方がないですが、そもそも
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. おっしゃるとおり実際のシステムだったら There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. あ、はい、ここは「使う人の気持ちになって私はこうするのが一番いいと思ったのでこうしたのだ、もしかしたらもっといい方法があるのかもしれないが、少なくとも私はそう判断したのだ」と言えるならばいいと思います。 小学校の低学年の頃に、母に「きれいな字を書けるかは能力であるから人による。しかし、誠実な字を書くことは誰にでもできる。誠実な字とは読み手に伝えようという意思を持った字である。」といわれたことを思い出します。 |
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| class Solution { | ||
| // leetcode | ||
| private static final int NUM_ALPHABETS = 26; | ||
| private static final char ALPHABET_OFFSET = 'a'; | ||
| public static final int NOT_FOUND = -1; | ||
|
|
||
| public int firstUniqChar(String s) { | ||
| int[] frequencies = new int[NUM_ALPHABETS]; | ||
| for (int i = 0; i < s.length(); i++) { | ||
| char c = s.charAt(i); | ||
| frequencies[c - ALPHABET_OFFSET]++; | ||
| } | ||
| for (int i = 0; i < s.length(); i++) { | ||
| char c = s.charAt(i); | ||
| if (frequencies[c - ALPHABET_OFFSET] == 1) { | ||
| return i; | ||
| } | ||
| } | ||
| return NOT_FOUND; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| class Solution { | ||
| // leetcode | ||
| public int firstUniqChar(String s) { | ||
| Map<Character, Integer> characterToFrequencies = new HashMap<>(); | ||
| for (int i = 0; i < s.length(); i++) { | ||
| char c = s.charAt(i); | ||
| characterToFrequencies.put(c, characterToFrequencies.getOrDefault(c, 0) + 1); | ||
| } | ||
| for (int i = 0; i < s.length(); i++) { | ||
| char c = s.charAt(i); | ||
| if (characterToFrequencies.get(c) == 1) { | ||
| return i; | ||
| } | ||
| } | ||
| return -1; | ||
| } | ||
| } |

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
変数名
indicesから、文字と出現頻度のマップだということが分かりにくく感じました。charcterToCountsやcharacterToFrequenciesといった、文字と出現頻度のマップであることが想起しやすい変数名を付けることをお勧めいたします。