-
Notifications
You must be signed in to change notification settings - Fork 0
Next permutation #8
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
base: arai60
Are you sure you want to change the base?
Changes from all commits
cc51a92
a7a0e16
0da8973
b7cb63b
95e6ce2
56cdf4c
b90357b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| class Solution: | ||
| def nextPermutation(self, nums: List[int]) -> None: | ||
| """ | ||
| Do not return anything, modify nums in-place instead. | ||
| """ | ||
| if len(nums) == 1: | ||
| return | ||
|
|
||
| pivot_index = len(nums) - 2 # 比較の中心となるindexを定義 | ||
| while pivot_index > -1 and nums[pivot_index] >= nums[pivot_index+1]: | ||
| pivot_index -= 1 | ||
|
|
||
| if pivot_index == -1: | ||
| nums.reverse() | ||
| return | ||
|
|
||
| swap_index = len(nums) - 1 # swapに使うindexを定義 | ||
| while nums[swap_index] <= nums[pivot_index]: | ||
| swap_index -= 1 | ||
|
|
||
| nums[swap_index], nums[pivot_index] = nums[pivot_index], nums[swap_index] | ||
|
|
||
| nums[pivot_index+1:] = reversed(nums[pivot_index+1:]) | ||
| return |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| class Solution: | ||
| def nextPermutation(self, nums: List[int]) -> None: | ||
| """ | ||
| Do not return anything, modify nums in-place instead. | ||
| """ | ||
| def _find_pivot_index(nums: List[int])->int: | ||
| # 比較の中心となるindexを定義 | ||
| # 末端から見ていって増加関係のないところを比較indexとする | ||
| pivot_index = len(nums) - 2 | ||
| while pivot_index > -1 and nums[pivot_index] >= nums[pivot_index+1]: | ||
| pivot_index -= 1 | ||
| return pivot_index | ||
|
|
||
| def _find_swap_index(nums: List[int], pivot_index: int)->int: | ||
| # swapに使うindexを定義 | ||
| # swapする位置のindexを求める | ||
| swap_index = len(nums) - 1 | ||
| while nums[swap_index] <= nums[pivot_index]: | ||
| swap_index -= 1 | ||
| return swap_index | ||
|
|
||
| if len(nums) == 1: | ||
| return | ||
|
|
||
| pivot_index = _find_pivot_index(nums) | ||
|
|
||
| if pivot_index == -1: | ||
| nums.reverse() | ||
| return | ||
|
|
||
| swap_index = _find_swap_index(nums, pivot_index) | ||
|
|
||
| nums[swap_index], nums[pivot_index] = nums[pivot_index], nums[swap_index] | ||
|
|
||
| nums[pivot_index+1:] = reversed(nums[pivot_index+1:]) | ||
| return | ||
|
|
||
| """ | ||
| None型を返すせいで, 正直PythonよりはC++とかの方が書きやすいと感じたが, とりあえずPythonで書く練習をした | ||
|
|
||
| Reference: | ||
| https://github.com/shining-ai/leetcode/pull/58/files 解くことに夢中になりすぎて関数での分割を忘れていた。 | ||
| nums[pivot_index+1:] = reversed(nums[pivot_index+1:])よりもnums[left + 1 :] = sorted(nums[left + 1 :]) | ||
| の方が認知コストは低いなあと感じた。reversedで良いことは紙とペンで確かめられるけど, それをしなきゃいけない感じのコードなら確かに書くべきではないのかも | ||
|
|
||
| https://github.com/hayashi-ay/leetcode/pull/67/files | ||
| markdownに書いてあるNext Permutationアルゴリズムの説明がわかりやすいと思いました。あとコメントにあった通り次から関数名は動詞から書き始めることを意識してみます。 | ||
| """ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| class Solution: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| def nextPermutation(self, nums: List[int]) -> None: | ||
| """ | ||
| Do not return anything, modify nums in-place instead. | ||
| """ | ||
| def _find_pivot_index(nums: List[int])->int: | ||
| # 比較の対象となる数のindexを見つける | ||
| pivot_index = len(nums) - 2 | ||
| while pivot_index > -1 and nums[pivot_index] >= nums[pivot_index+1]: | ||
| pivot_index -= 1 | ||
| return pivot_index | ||
|
|
||
| def _find_swap_index(nums: List[int], pivot_index: int)->int: | ||
| # 後ろからnums[pivot_index]より大きい数を見つけてswapするindexを取り出す | ||
| swap_index = len(nums) - 1 | ||
| while nums[swap_index] <= nums[pivot_index]: | ||
| swap_index -= 1 | ||
| return swap_index | ||
|
|
||
| if len(nums) == 1: | ||
| return | ||
|
|
||
| pivot_index = _find_pivot_index(nums) | ||
|
|
||
| if pivot_index == -1: | ||
| nums.reverse() | ||
| return | ||
|
|
||
| swap_index = _find_swap_index(nums, pivot_index) | ||
|
|
||
| nums[swap_index], nums[pivot_index] = nums[pivot_index], nums[swap_index] | ||
|
|
||
| nums[pivot_index+1:] = sorted(nums[pivot_index+1:]) | ||
|
|
||
| return nums | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| class Solution: | ||
| def nextPermutation(self, nums: List[int]) -> None: | ||
| """ | ||
| Do not return anything, modify nums in-place instead. | ||
| """ | ||
| def _find_first_not_sorted_index(nums: List[int])->int: | ||
| # 後ろから走査し, nums[index] >= nums[index+1]ではなくなる初めてのindexを取り出す | ||
| index = len(nums) - 2 | ||
| while index > -1 and nums[index] >= nums[index+1]: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| index -= 1 | ||
| return index | ||
|
|
||
| def _find_second_largest_index(nums: List[int], compare_index: int)->int: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. second largestは2番目に大きい数なので適切な表現ではないと思います。 numsは引数に含める必要はありません。 |
||
| # 後ろからnums[compare_index]より大きい数を見つけてswapするindexを取り出す | ||
| index = len(nums) - 1 | ||
| while nums[index] <= nums[compare_index]: | ||
| index -= 1 | ||
| return index | ||
|
|
||
| if len(nums) == 1: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 長さ1は特別扱いが必要ですか?
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. index = len(nums) - 2でindex = -1となるので不要でした |
||
| return | ||
|
|
||
| left = _find_first_not_sorted_index(nums) | ||
|
|
||
| if left == -1: | ||
| nums.reverse() | ||
| return | ||
|
|
||
| right = _find_second_largest_index(nums, left) | ||
|
|
||
| nums[right], nums[left] = nums[left], nums[right] | ||
|
|
||
| nums[left+1:] = sorted(nums[left+1:]) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 降順にソートされているので、reverseすればいいです。コピーするより、in-placeの方の関数を使った方がいいでしょう。 |
||
|
|
||
| return nums | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| class Solution: | ||
| def nextPermutation(self, nums: List[int]) -> None: | ||
| """ | ||
| Do not return anything, modify nums in-place instead. | ||
| """ | ||
| def _find_first_not_sorted_index() -> int: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not_sortedよりnot_decreasingの方がより関数内の処理が具体化されると思います。 |
||
| index = len(nums) - 2 | ||
| while index >= 0 and nums[index] >= nums[index+1]: | ||
| index -= 1 | ||
| return index | ||
|
|
||
| def _rfind_bigger_than(compare_index: int) -> int: | ||
| index = len(nums) - 1 | ||
| while nums[index] <= nums[compare_index]: | ||
| index -= 1 | ||
| return index | ||
|
|
||
| left = _find_first_not_sorted_index() | ||
|
|
||
| if left == -1: | ||
| nums.reverse() | ||
| return | ||
|
|
||
| right = _rfind_bigger_than(left) | ||
| nums[left], nums[right] = nums[right], nums[left] | ||
| nums[left+1:].reverse() | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. たぶんこの部分意図した挙動になっていないと思います。 Pythonのsliceは新しいリストを作ります。
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 知らなかったです。あと多分leetcodeでテストしたつもりになっていましたが多分し忘れていました。今in-place処理にしたphase6を追加してみました。 |
||
| return | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| class Solution: | ||
| def nextPermutation(self, nums: List[int]) -> None: | ||
| """ | ||
| Do not return anything, modify nums in-place instead. | ||
| """ | ||
| def _rfind_first_not_decreasing_index() -> int: | ||
| index = len(nums) - 2 | ||
| while index >= 0 and nums[index] >= nums[index+1]: | ||
| index -= 1 | ||
| return index | ||
|
|
||
| def _rfind_bigger_than(compare_index: int) -> int: | ||
| index = len(nums) - 1 | ||
| while nums[index] <= nums[compare_index]: | ||
| index -= 1 | ||
| return index | ||
|
|
||
| left = _rfind_first_not_decreasing_index() | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 全体的にちょっと空行多めかしら。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 19行目の空行だけ余分な気がします。23と26はあってもなくても良さそうな感じですかね。 |
||
|
|
||
| if left == -1: | ||
| nums.reverse() | ||
| return | ||
|
|
||
| right = _rfind_bigger_than(left) | ||
| nums[left], nums[right] = nums[right], nums[left] | ||
|
|
||
| swap_right = len(nums) - 1 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 関数に切り出しても良いですね。このままでも良いとは思います。 |
||
| swap_left = left + 1 | ||
| while swap_left < swap_right: | ||
| nums[swap_right], nums[swap_left] = nums[swap_left], nums[swap_right] | ||
| swap_left += 1 | ||
| swap_right -= 1 | ||
| return | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 最後のreturnはなくても挙動は変わらないですね。 |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| class Solution: | ||
| def nextPermutation(self, nums: List[int]) -> None: | ||
| """ | ||
| Do not return anything, modify nums in-place instead. | ||
| """ | ||
| def _rfind_first_not_decreasing_index() -> int: | ||
| index = len(nums) - 2 | ||
| while index >= 0 and nums[index] >= nums[index+1]: | ||
| index -= 1 | ||
| return index | ||
|
|
||
| def _rfind_bigger_than(compare_index: int) -> int: | ||
| index = len(nums) - 1 | ||
| while nums[index] <= nums[compare_index]: | ||
| index -= 1 | ||
| return index | ||
|
|
||
| left = _rfind_first_not_decreasing_index() | ||
| if left == -1: | ||
| nums.reverse() | ||
| return | ||
|
|
||
| right = _rfind_bigger_than(left) | ||
| nums[left], nums[right] = nums[right], nums[left] | ||
| swap_left = left + 1 | ||
| swap_right = len(nums) - 1 | ||
| # in-place reverse | ||
| while swap_left < swap_right: | ||
| nums[swap_left], nums[swap_right] = nums[swap_right], nums[swap_left] | ||
| swap_left += 1 | ||
| swap_right -= 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[]内の演算子の周りにスペースを入れるか入れないかはPEPではどうなっていますか?少なくとも一貫性のある書き方にはしてほしいです。