Skip to content

Create 46. Permutations.md#50

Open
tokuhirat wants to merge 1 commit intomainfrom
46.-Permutations
Open

Create 46. Permutations.md#50
tokuhirat wants to merge 1 commit intomainfrom
46.-Permutations

Conversation

@tokuhirat
Copy link
Owner

This Problem
46. Permutations
Next Ploblem
78. Subsets
言語: Python

Comment on lines +104 to +117
for i in reversed(range(r)): # 辞書順で出るように index が大きい方から探索
cycles[i] -= 1
if cycles[i] == 0:
# i番目の探索のために swap した状態を元に戻す
indices[i:] = indices[i+1:] + indices[i:i+1]
cycles[i] = n - i
# break されず i - 1 番目の探索に移行
else:
j = cycles[i] # 交換対象の index を取得
indices[i], indices[-j] = indices[-j], indices[i] # swap
yield tuple(pool[i] for i in indices[:r])
break
else:
return
Copy link

Choose a reason for hiding this comment

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

私はこの部分が特に気に食わなくて、

  • if else を入れ替えます。
  • else のインデントを下げます。
  • break を先に書いて、yield を for の外に追い出します。

とすると思います。

Copy link
Owner Author

Choose a reason for hiding this comment

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

私も読んでいる時 if else の部分は微妙だと思っていました。
yield を for の外に追い出すのは思いつきませんでした。while の役割が明確になってわかりやすくなると感じます。

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        n = len(nums)
        indices = list(range(n))
        cycles = list(range(n, 0, -1))
        results = []
        results.append([nums[i] for i in indices])
        while True:
            for i in reversed(range(n)):
                cycles[i] -= 1
                if cycles[i] > 0:
                    j = cycles[i]
                    indices[i], indices[-j] = indices[-j], indices[i]
                    break
                indices[i:] = indices[i + 1 :] + indices[i : i + 1]
                cycles[i] = n - i
            else:
                break
            results.append([nums[i] for i in indices])
        return results

Copy link

Choose a reason for hiding this comment

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

2つの append をまとめてループの先頭に回すこともできますね。

                    j = cycles[i]
                    indices[i], indices[-j] = indices[-j], indices[i]

これも for の外に追い出せます。(どちらがいいかは難しいところ。)

Copy link
Owner Author

Choose a reason for hiding this comment

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

そうですね。do-while のような処理をまとめる形で書くのが苦手だなと感じています。
for の仕事として適切な i を見つけるところで終わるのか、indices の変更までしてもらうのかというところですね。
cycles[i] == 0 の時 for 内で indices を整えている点、cycles[i] > 0 で break してから for の処理がやや複雑な点(else:break がある)、を考えると for 内に書くのが個人的には自然に思います。

permutations.append(sub_permutation[:])
return
for num in nums:
if num in sub_permutation:
Copy link

Choose a reason for hiding this comment

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

使用中の num を set に入れておくと、時間計算量は下がりそうです。ただ、 1 <= nums.length <= 6 のため、こちらのほうが速いかもしれません。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants