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
136 changes: 136 additions & 0 deletions 46. Permutations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# 進め方

Step1 : 問題を解く。

Step2 : 他の人のPRを参照し、コメントする。

Step3 : 3回続けてエラーが出ないように書く。ドキュメントを参照する。

# 実践

## Step1

### 思考ログ

う、意外とかけないかも。

nums.lengthが6個なので全部書ききれる可能性はある。(笑)

全部生成して、setで間引くか。

```python
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
stack = []
for num in nums:
stack.append([num])
for i in range(1, len(nums)):
Comment on lines +25 to +27
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

これでいきませんか?

stack.append([])
for i in range(len(nums)):

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

行けました。今見返すと変なことをしていますね。

next_stack = []
while stack:
used = set(stack[-1])
for num in nums:
possible = stack[-1][:] # コピーでないと動かない
if num in used:
continue
possible.append(num)
next_stack.append(possible)
used.add(num)
stack.pop()
stack = next_stack
return stack
```

コピーをせずにそのままやったらオブジェクトを共有していた。

浅いコピーでいけるのか。30分くらいかかってしまった。

### GPT

a = [1, 2]
b = a[:] # 浅いコピー(外側だけ別物)

b.append(3) # b の外側を変更
print(a) # [1, 2] ← a は影響なし
print(b) # [1, 2, 3]

- **外側**=入れ物(リスト自体)、**内側**=その要素。
- 順列生成では外側だけ複製すれば目的を達成でき、内側は整数で安全。
- だから **浅いコピーで十分** というわけです。

## Step2

### 同じ問題を解いた人のプルリクを見る

バックトラック・バックトラッキングとは

[https://ja.wikipedia.org/wiki/バックトラッキング](https://ja.wikipedia.org/wiki/%E3%83%90%E3%83%83%E3%82%AF%E3%83%88%E3%83%A9%E3%83%83%E3%82%AD%E3%83%B3%E3%82%B0)

組み合わせをすべて見つける方法ということでしょうか。

https://www.cc.kyoto-su.ac.jp/~yamada/ap/backtrack.html

すべての組み合わせを見つけるためのアルゴリズムということですね。

https://github.com/hroc135/leetcode/pull/47

- 片付けして分類するイメージ
- 分類、あんまりよくわからないなあ。
- この問題だと、持っているカードを出していくイメージでした。

https://github.com/olsen-blue/Arai60/pull/51/files

- なるほど、苦戦する場所っぽいですね。安心?
- 再起とスタックで。これ書いているうちにつかめるタイプの問題な気がする。
- Cpython読めなかった。
- https://github.com/python/cpython/blob/a31bbc951a9d74cd7b9092555c101e51a2b9482b/Modules/itertoolsmodule.c#L2820

```python
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
def generate_permutation(creating_nums, rest_nums):
if not rest_nums:
print(creating_nums)
return [creating_nums]
result = []
for i, num in enumerate(rest_nums):
making = creating_nums[:]
making.append(num)
result.extend(generate_permutation(making, rest_nums[:i] + rest_nums[i+1:]))
return result

return generate_permutation([], nums)
```

上手な変数名を付けれないときは、理解できていないのかもしれない。

## Step3

### 3回連続で再現

10m, 7m,7mくらい

あと何問か同じようなものがあるらしいので次に進む。

```python
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
def permute_helper(takeover_nums, rest_nums):
assert rest_nums is not None
if not rest_nums:
return [takeover_nums]
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

return takeover_nums にして result に append でもいいのではないでしょうか?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

レビューありがとうございます。
128行目がList[List[int]] を返すので、型の整合性が取れなくなってしまいます。

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

なるほどです。ありがとうございます。

result = []
for i, num in enumerate(rest_nums):
handover_nums = takeover_nums[:]
handover_nums.append(num)
next_rest_nums = rest_nums[:i] + rest_nums[i+1:]
permutation = permute_helper(handover_nums, next_rest_nums)
result.extend(permutation)
return result

return permute_helper([], nums)

```

引き継ぎのイメージをそのまま変数名にしてみた。

意外と悪くないか。