Skip to content

Conversation

hroc135
Copy link
Owner

@hroc135 hroc135 commented Feb 18, 2025

middle<right<=nums.back()だから、nums[middle]<nums.back()ならnums[middle]<nums[right]だし、
nums[middle]>nums.back()ならnums[middle]>nums[right]なので
- 個人的には二分探索は調べるべき区間を狭めていくアルゴリズムなので、left~right間で完結させたい気持ちがあり、
nums[right]を比較に用いる方が好み
Copy link

Choose a reason for hiding this comment

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

私の気持ちは、大小関係の真偽をはじめに固定して、一番左の true を探したいと考えたほうが(条件が変わっていくよりも)素直というものです。

このチェックリストよくできていますね。{F,T}^4 の 16通りについて答えてもよいです。

Copy link
Owner Author

Choose a reason for hiding this comment

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

動くものは
(切り上げにする, nums[middle] <= nums[right]で<に変更, nums[right]をnums[len(nums)-1]に変更, rightの初期値をlen(nums)に変更)
= (F, F, F, F),
(F, T, F, F),
(F, T, T, F),
(F, F, T, F),
(F, F, T, T)
だと思います。

Copy link

@nodchip nodchip left a comment

Choose a reason for hiding this comment

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

良いと思います。

left = middle + 1
case nums[middle] == nums[right]:
// This code should be unreachable because all elements of nums are unique and middle<right.
log.Fatal("Something went wrong.")

Choose a reason for hiding this comment

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

想定外の入力に対するエラーケースがあるの非常に良いと思いました。

@Mike0121
Copy link

よく考えられており、良いと思いました。(半開区間の不採用の理由(辻褄合わせ?)がちょっと自分には読み取れなかったですが。)

case nums[middle] > nums[right]:
left = middle + 1
case nums[middle] == nums[right]:
// This code should be unreachable because all elements of nums are unique and middle<right.
Copy link
Owner Author

Choose a reason for hiding this comment

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

訂正: "This code" -> "This block"

@hroc135
Copy link
Owner Author

hroc135 commented Feb 25, 2025

@Mike0121
今回の二分探索において、自分は閉区間を用いるのが素直な解法だと思いましたが、理由は終了条件でleft==rightとなった際に、left以上right以下の区間に含まれる要素はただ一つでその要素が最小値である、と読み取れるからです。一方、半開区間を用いてleft==rightとなった際はleft以上right未満の要素は存在せず、答えをnums[left]であると解釈するのは不自然であると感じました。終了条件をleft==right-1と設定すれば[left,right)に含まれる要素はただ一つになりますが、そのように終了条件を設定するのも辻褄合わせに感じました。

反対にinsert positionを探すような際には半開区間を用いても自然な解釈ができると思います。終了条件でleft==rightとなった際に、leftの左側にinsertすれば良い、と解釈できるからです。

- https://github.com/seal-azarashi/leetcode/pull/39/files#r1851404872
- https://discord.com/channels/1084280443945353267/1233295449985650688/1240269414415339571
- https://github.com/Ryotaro25/leetcode_first60/pull/46#discussion_r1869993674

Copy link

Choose a reason for hiding this comment

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

トップダウンというよりも、言葉の定義、たとえば「left, right をなんだと思っているのか」がぶれていないことを気にしています。

たとえば、「left とは、いままで見つかった false の位置の最大」で「right とは、いままで見つかった true の位置の最小」というのでもいいのです。そうすると、left, right が隣り合ったところで探索終了のはずです。

でも、だいたいの場合、「left は、左のあたり」くらいの理解しかしていないので、読んでいくと何を言っているのかが分からなくなります。そんで辻褄合わせに最後になんか場合分けがついたりします。それに加えて、閉区間というワードを言うと納得してもらえるようだという学習をしていて、とりあえず、言ってみたりします。分かって唱えているならばただの情報の圧縮で効率的なコミュニケーションですが分からずに唱えているのは分かります。

どういうものだと考えていてもいいのだから、決めて話してくれればいいんですが。

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.

4 participants