-
Notifications
You must be signed in to change notification settings - Fork 0
283. Move Zeroes #54
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: main
Are you sure you want to change the base?
283. Move Zeroes #54
Conversation
for i in range(len(nums)): | ||
if nums[i] == 0: | ||
continue | ||
nums[last_nonzero_index], nums[i] = nums[i], nums[last_nonzero_index] |
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.
もし時間にめちゃくちゃシビアな場合は、Step2の①の別解のスワップしない実装の方が速そうですね。(そんなシビアな事をpythonでするなという感じもありますが)
ただ、この方法の方が意味がわかりやすいのと、仮に仕様変更で0ではなくて0以下を端に寄せたいとなった場合にもcontinueする条件をnums[i] <= 0とするだけでワークするので、良いと思います。
この辺、3rdで最終的にこの方法を選んだ理由や考えが明示されていると良いかもしれないですね。
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.
3rdで最終的にこの方法を選んだ理由や考えが明示されていると良いかもしれないですね。
なるほど、これから書いてみます。ありがとうございます
ちなみに大体の場合は挙げた解法の中で自分なりに一番素直かなと思う方法で3rdを書いており、今回もそうです。動作が想像しやすいからか保守性も高くなることが多いかなと思い。
仮に仕様変更で0ではなくて0以下を端に寄せたいとなった場合にもcontinueする条件をnums[i] <= 0とするだけでワークする
こうは考えていかなったですが、たしかにそうですね
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.
まとめて 0 fill は、loop unrolling できたりするのでちょっと嬉しいこともあるでしょう。
- 空間計算量: O(1) | ||
|
||
```py | ||
class Solution: |
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.
C++ の std:remove() を思い出しました。
last_nonzero_index = 0 # any elements in nums[:last_nonzero_index] are not 0 | ||
for i in range(len(nums)): | ||
if nums[i] != 0: | ||
nums[last_nonzero_index], nums[i] = nums[i], nums[last_nonzero_index] |
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.
last_nonzero_indexだとそこより右にnonzeroが無いように一瞬思ってしまいましたが、それを防ぐための代案が難しいですね、、、
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.
一応上のコメントでnums[:last_nonzero_index]の各要素が非ゼロだよと補足してみましたが、名前自体変えた方が良さそうですかね?
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.
コメントだとlast_nonzero_indexより左に言及していますが、パッと読んだ時には右にはnonzeroの要素がないように思ってしましました。
nonzero_lengthとかの方がわかりやすいかな、難しい選択ですね
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.
なるほど、コメントだけにして単純にleftとかにして、ループ変数をrightとする方が変に迷わせないのかもと思いました
while next_nonzero_index < len(nums) and nums[next_nonzero_index] == 0: | ||
next_nonzero_index += 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.
L111~112と!= と==のみが違う操作なので、関数化してもいいかもですね
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.
具体的にどう書くと良さそうでしょうか?
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.
def find_leftmost_index_by_condition(nums, condition, index=0):
while index < len(nums):
if condition(nums[index]):
return index
index += 1
return index
find_leftmost_index_by_condition(nums, last_nonzero_index, lambda x: x != 0)
みたいな感じですかね(思ったよりややこしかった)
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.
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
def find_leftmost_index_by(condition: Callable[[int], bool], start: int):
i = start
while i < len(nums) and not condition(nums[i]):
i += 1
return i
next_nonzero_index = -1
last_nonzero_index = 0 # any elements in nums[:last_nonzero_index] are not 0
while True:
last_nonzero_index = find_leftmost_index_by(lambda x: x == 0, last_nonzero_index)
next_nonzero_index = find_leftmost_index_by(lambda x: x != 0, max(next_nonzero_index, last_nonzero_index))
if next_nonzero_index == len(nums):
break
nums[last_nonzero_index], nums[next_nonzero_index] = nums[next_nonzero_index], nums[last_nonzero_index]
last_nonzero_index += 1
自分なりに解釈してみました!PRのコードより良くなった気がします、ありがとうございます 🙏
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.
おお、自分のやつより良くなってますね、ありがとうございます(後少し違っていた)
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.
Generator を使って変なコードを書いてみました。
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
eq0 = (i for i, x in enumerate(nums) if x == 0)
neq0 = (i for i, x in enumerate(nums) if x != 0)
try:
while 1:
pos0 = next(eq0)
while (posn0 := next(neq0)) < pos0:
pass
nums[pos0], nums[posn0] = nums[posn0], nums[pos0]
except:
pass
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.
try:
# なんかのエラーがある処理
except:
pass
でエラーを消せるのなるほどでした
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.
このコードは遊びで書いているので、あまり参考にしないでください。
except ですべてを握りつぶすと、SIGINT つまり、キーボード入力の ^C も捕まえます。
https://discord.com/channels/1084280443945353267/1347375192065703986/1353569957581164615
StopIteration を捕まえるのが正しいでしょうね。
https://leetcode.com/problems/move-zeroes/description/