LeetCode1日目にやった内容を振り返っていきます~
自分のコードの振り返りとランキング上位の実装との比較をやっていきます。
217. Contains Duplicate
数値の配列が渡されて、同じ数値が出現すればtrue
なければfalse
という問題
制約:
1 <= nums.length <= 10^5
-10^9 <= nums[i] <= 10^9
自分のコードはこんな感じ
function containsDuplicate(nums: number[]): boolean {
let hasDuplicate: boolean = false;
for (let i = 0; i < nums.length; i++) {
for (let j = i + 1; j < nums.length; j++) {
if (nums[i] == nums[j]) {
hasDuplicate = true;
break;
}
}
}
return hasDuplicate;
};
愚直な実装、、Map関数くらい使えばいいのに。。。
これでも制約上は問題なかったけど実行速度が6900ms、遅すぎる。。
ランキング上位の実装などを見たところ、SetオブジェクトやMapオブジェクトを利用している。
なぜ実行速度が速くなるかというと。。
Setは、オブジェクトと配列の長さを比較するだけなので速くて
Mapは、Arrayのように要素一つ一つを確認する必要がないから速いらしい
分かり易い解説は以下参照
100倍速い!? Set, Mapでパフォーマンス改善 | 株式会社ヌーラボ(Nulab inc.)
function containsDuplicate(nums: number[]): boolean {
const uniqueSet = new Set(nums);
return uniqueSet.size !== nums.length;
};
ハッシュテーブルつかうぞー!
さて次の問題は、、
242. Valid Anagram
s
とt
の二つの文字列が渡されて、t
がs
のアナグラムならtrue
、そうでなければfalse
とする
制約:
1 <= s.length, t.length <= 5 * 10^4
s
andt
consist of lowercase English letters.
自分のコード
function isAnagram(s: string, t: string): boolean {
let sToArray = [...s];
let tToArray = [...t];
sToArray.sort();
tToArray.sort();
let sToString = sToArray.toString();
let tToString = tToArray.toString();
if (sToString == tToString) {
return true;
}
return false;
};
こっちも単純に文字列を配列にしてソートして文字列に戻して比較しているだけの実装
実行速度は110ms、メモリは50.1MB
実行速度もメモリもあと少し改善する余地がある模様。
ランキング上位の解答確認したところ、t
とs
のアルファベットの出現回数を加算、減算するだけでよいとのこと。
たしかに制約条件の2個目にまんま記載がある。。
ということで改修版ドン!
function isAnagram(s: string, t: string): boolean {
if (s.length !== t.length) {
return false;
}
let alphabetCount = [...Array(26)].map(() => 0);
for(let i = 0; i < s.length; i++) {
let sCode = s.charCodeAt(i) - 97;
let tCode = t.charCodeAt(i) - 97;
alphabetCount[sCode]++;
alphabetCount[tCode]--;
}
const isAnagram = alphabetCount.every((element) => element === 0);
return isAnagram
};
今日の反省点
- 配列よりもハッシュテーブルが使えないか検討しましょう。
- 制約条件をよく読みましょう。
同じ失敗はしないように気を付けなければ・・・
ではまた。