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
51 changes: 51 additions & 0 deletions 217.ContainsDuplicate/memo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
## ステップ1
実装前のイメージ
トランプのようなカードをイメージする。
裏向けにシャッフルに並べられた山札があるとして一枚引くごとに表に向けて並べていく
重複があればその時点で終了。山札がなくなれば重複なし


numsをループで回して、set内に含まれているか確認すれば解けそう
acceptまで1分30秒

mapを使う解法も思いついたが、
すでに存在しているかどうかを判断するだけでいいのでsetを選んだ

時間計算量
O(n)

空間計算量
O(n)

## ステップ2
* step1の変更点
unique_numsはsetということからuniqueであることが分かるので微妙そう
他の方がseenを使っていて良さそうだと思ったのでこちらに変更

* 他の方法がないか考えたが思いつかなかったので解法をみる
sortして前後のnumを比較する
これだと空間計算量をO(n) => O(1)にすることが可能
時間計算量はsortの分O(n log n)となる
sort.cppに実装

入力値は参照渡しなので、sortを直に使うときは破壊的変更となることは覚えておく
<=> コピーコストは掛かるが入力値に影響を与えない選択肢もある

## ステップ3
**3回書き直しやりましょう、といっているのは、不自然なところや負荷の高いところは覚えられないからです。**

## 他の解法
setの方が自然ではないかというコメントがあった。実装時にこれはよぎった
https://github.com/shintaroyoshida20/leetcode/pull/32/commits/3c8d72cb432e48abe4f507a246a24bc4303dad74

>return len(nums) != len(set(nums))
この解法も思いつかなかった。setに入れる際に重複があれば確かに長さが異なる
brute forceは見落としていた。
https://github.com/NobukiFukui/Grind75-ProgrammingTraining/pull/39/commits/a2a595caddbcc5b46bab24d18f03356314e7ecd0

自分が思いついたイメージに近い
resultにtrue、falseを持つよりは重複があったタイミングですぐにreturn trueした方が素直な気がする
https://github.com/erutako/leetcode/pull/5/commits/d902e9ffb35d089948576c15f4b93b200e860182

## Discorなど

12 changes: 12 additions & 0 deletions 217.ContainsDuplicate/sort.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class Solution {
public:
bool containsDuplicate(vector<int>& nums) {
sort(nums.begin(), nums.end());
for (int i = 0; i < nums.size() - 1; i++) {
if (nums[i] == nums[i + 1]) {
return true;
}
}
return false;
}
};
13 changes: 13 additions & 0 deletions 217.ContainsDuplicate/step1.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class Solution {
public:
bool containsDuplicate(vector<int>& nums) {
set<int> unique_nums;
for (auto num : nums) {
if (unique_nums.contains(num)) {

Choose a reason for hiding this comment

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

C++20 の新機能 以前のstd::find()を使った方法もありますかね。
142の問題で、重複判定でも使用されていたので仕様は問題ないと思いますが、
念の為示しておきます。

Copy link
Owner Author

Choose a reason for hiding this comment

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

コメントありがとうございます🙇
単に存在するかどうかの場合はcontainsをよく使います。

return true;
}
unique_nums.insert(num);
}
return false;
}
};
13 changes: 13 additions & 0 deletions 217.ContainsDuplicate/step2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class Solution {
public:
bool containsDuplicate(vector<int>& nums) {
set<int> seen;

Choose a reason for hiding this comment

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

seen という変数名は、少しわかりずらいように思います。

Copy link
Owner Author

Choose a reason for hiding this comment

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

unique_numsとしておりましたが、uniqueであること、numsが格納されていることは明らかなので既に見たものとしてseenを使っておりました。
seen_numsやvisited(グラフ問題っぽい?)などはいかがでしょうか?🙇

Choose a reason for hiding this comment

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

すいません。私のコメントが言葉足らずでした。

このくらいの長さのコードでしたら、seenでも分かると思うんです。
ただ、勉強会の趣旨としては「専門家の8割9割ができる常識」を養うですよね。
https://discord.com/channels/1084280443945353267/1237649827240742942/1240307605314867321

私は初心者なので、seen_numsやvisitedのいずれがいいかの判断はできないのですが、(ごめんなさい)
ただ意識して書かれてますか?という感覚でコメントしました。

他の方のコメントで、命名する時の参考があったので、下記に貼っておきます。
一緒に頑張っていきましょう!
https://source.chromium.org/search?q=char&ss=chromium%2Fchromium%2Fsrc

Copy link

Choose a reason for hiding this comment

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

私は、seen くらいでいいかと思っています。
何も知らない人が上から読んでいって、

  bool containsDuplicate(vector<int>& nums) {
    set<int> seen;

この seen の役割はなにか想像がつきますか。その想像裏切られないですよね。よく分かるならば短いほうがいいんです。

コメント集に結構あります。
https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0#heading=h.fcs3httrll4l

Choose a reason for hiding this comment

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

なるほど。。。確かにsetからのseenの役割を考えると、すぐ想像がつくものなので難しく考えることもなかったかもしれないです。seenNums, numsSetくらいに考えてましたが、短くて分かるならそれでいいですね。もう少し素直になります。

for (auto num : nums) {
if (seen.contains(num)) {
return true;
}
seen.insert(num);
}
return false;
}
};
13 changes: 13 additions & 0 deletions 217.ContainsDuplicate/step3.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class Solution {
public:
bool containsDuplicate(vector<int>& nums) {
set<int> seen;
for (auto num : nums) {
if (seen.contains(num)) {
return true;
}
seen.insert(num);
}
return false;
}
};