Skip to content

349. Intersection of Two Arrays #12

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
42 changes: 42 additions & 0 deletions lc349.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# step1
思考ログ
- set()で比較して終わりか?
- for分でもできそうだが, 同じ配列内で重複したものを条件分岐するのがめんどそう + そもそも前から全て走査しなきゃいけないので微妙が, 結局別のリストを作成して, 条件分岐で見る方法しか思いつかなかった

'''python
Copy link

Choose a reason for hiding this comment

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

` と ' があって、ここをバッククォートの方にすると色がつきます。

Copy link
Owner Author

Choose a reason for hiding this comment

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

ご指摘のとおりです, ありがとうございます

class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
duplicate_nums = []

for num1 in nums1:
if num1 in nums2 and num1 not in duplicate_nums:
duplicate_nums.append(num1)

return (duplicate_nums)
'''

# step2
参考にした方のPR
- https://github.com/potrue/leetcode/pull/13/files?short_path=a9a8c8e#diff-a9a8c8e566d7cbecc2ccd43ec4c0c4eb0e11cfe2068a27977617b6bce73849fd
- duplicate_numsとしたが, intersected_numsの方が適切か
- [set()で和集合を取る方法](https://github.com/potrue/leetcode/pull/13/files?short_path=a9a8c8e#diff-a9a8c8e566d7cbecc2ccd43ec4c0c4eb0e11cfe2068a27977617b6bce73849fd), ただ以下のような文を発見したので気をつけたいと思う.つまり、演算子を使う場合はどちらも集合でないといけない, 演算子を使うことはあまり推奨されていない(?)
Copy link

Choose a reason for hiding this comment

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

片方がsetで片方がイテラブルの場合に演算子を使うと「誤りがち」になる(&の左右を逆にすると別の結果が返ってくるようになる場合があるから?)ので使えないようになってるということではないですかね、違ったらすみません

Copy link
Owner Author

@rinost081 rinost081 May 20, 2025

Choose a reason for hiding this comment

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

調べる限りだと &のような演算子はビット演算子(bit operator)に分類されるため, str型に対応していないそうです. そのためset('abc') & 'cbs'のようなケースではstrを比較しているためエラーを引き起こすと理解しています.
押し問答みたいになっていたらすいません、質問に対する答えになっていますかね

Copy link

@potrue potrue May 20, 2025

Choose a reason for hiding this comment

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

すみません、説明不足でした。
恐らく&演算子自体は__and__メソッドをクラスに定義することで任意のクラスに実装することができると思います。
(私の理解が正しければ、a & ba.__and__(b)と同じだと思います)

なので、

なお、演算子でない版の union(), intersection(), difference(), symmetric_difference(), issubset(), issuperset() メソッドは、任意のイテラブルを引数として受け付けます。対して、演算子を使う版では、引数は集合でなくてはなりません。これは、set('abc') & 'cbs' のような誤りがちな構文を予防し、より読みやすい set('abc').intersection('cbs') を支持します。

この文の意味としては、setにおいて演算子を使うことが推奨されていないというよりは、型が異なるとき(set('abc') & 'cbs'など)はそもそもpythonがintersectionではなくエラーを返すようにすることによって、&において非対称性を考慮しなければならないような読みにくいコードが生まれないようになっている、ということなのではないかという話でした。

Copy link

Choose a reason for hiding this comment

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

自分が全然見当違いの解釈をしている可能性もあるので参考程度に、、、

Copy link
Owner Author

Choose a reason for hiding this comment

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

私のコメントが適当だったのが原因な気がするので軌道修正をしていただいて助かります. 詳しい説明までありがとうございます.

```
なお、演算子でない版の union(), intersection(), difference(), symmetric_difference(), issubset(), issuperset() メソッドは、任意のイテラブルを引数として受け付けます。対して、演算子を使う版では、引数は集合でなくてはなりません。これは、set('abc') & 'cbs' のような誤りがちな構文を予防し、より読みやすい set('abc').intersection('cbs') を支持します。

Choose a reason for hiding this comment

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

Copy link
Owner Author

Choose a reason for hiding this comment

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

そうですねこれです, mdにすると横にスライドする必要があって見にくいですね. ありがとうございます

```

- https://github.com/hayashi-ay/leetcode/pull/21/files?short_path=801d96f#diff-801d96f7c65ed1087c93c1615e70fa43096cfbb3478152533d182c4f72933a40
- 思考ログの段階で, set()だとindexをもてないと書いたが, この人のようにlist(set(nums1))のようにすればかけることが判明

- https://github.com/chanseok-lim/arai60/pull/5/files#diff-a9a8c8e566d7cbecc2ccd43ec4c0c4eb0e11cfe2068a27977617b6bce73849fd
- 様々な解法が出ていて面白かった, set()を使わない解放, bisectを使った解放, 任意のケースにおける発想など

- https://github.com/nktr-cp/leetcode/pull/14/files?short_path=0c860cd#diff-0c860cd754249868513e4f9054206317fa33d0f548fc3896ac2b3e11822fd852
- c++だと走査する方をあえて長い方にすることで, ハッシュ衝突の可能性を下げるため短い方でハッシュマップの構築をするという考え方があった.

# step3
```python
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
intersected_nums = set(nums1).intersection(set(nums2))
return list(intersected_nums)
Copy link

Choose a reason for hiding this comment

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

intersectionを使う場合はnum2をsetに変換する必要はないかもしれません。
setの内部実装を見るとどちらにせよnums2を一つ一つ走査してset(nums1)に入っているかをチェックしていることになるように見えます。(C言語に慣れてないのでこれも違ったらすみません)
https://github.com/python/cpython/blob/main/Objects/setobject.c#L1400

Copy link
Owner Author

Choose a reason for hiding this comment

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

ここの部分を見る限りそうっぽいですね, ありがとうございます!

Choose a reason for hiding this comment

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

set(nums2) にしておくと、以下の部分で走査するsetがサイズの小さい方になるという違いはありますね。
https://github.com/python/cpython/blob/652d6938ef8c42c1c4c180c3f0e257c26c6677da/Objects/setobject.c#L1418

```