Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
みんなで書こう二分探索
Search
matumoto
June 10, 2021
Technology
70
0
Share
みんなで書こう二分探索
2021/7月の大LTでの発表資料です
イベントページはこちら
https://zli.connpass.com/event/216615/
matumoto
June 10, 2021
More Decks by matumoto
See All by matumoto
Go標準パッケージのI/O処理をながめる
matumoto
0
400
testingを眺める
matumoto
1
200
sync/v2 プロポーザルの 背景と sync.Pool について
matumoto
0
710
Goトランザクション処理
matumoto
1
78
いまいちどスライスの 挙動を見直してみる
matumoto
0
400
Go1.22のリリース予定の機能を見る
matumoto
0
82
GoのUnderlying typeについて
matumoto
0
220
Typed-nilについて
matumoto
0
370
GoのType Setsという概念
matumoto
0
48
Other Decks in Technology
See All in Technology
[Oracle TechNight#99] 生成AI時代のAI/ML入門 ~ AIとオラクルデータベースの関係 (前半)
oracle4engineer
PRO
2
240
世界の中心でApp Runnerを叫ぶ FINAL
tsukuboshi
0
260
多角的な視点から見たAGI
terisuke
0
130
データモデリング通り #5オンライン勉強会: AIに『ビジネスの文脈』を教え込むデータモデリング
datayokocho
0
220
生成AI時代に信頼性をどう保ち続けるか - Policy as Code の実践
akitok_
0
180
いつの間にかデータエンジニア以外の業務も増えていたけど、意外と経験が役に立ってる
zozotech
PRO
0
360
生成AIはソフトウェア開発の革命か、ソフトウェア工学の宿題再提出なのか -ソフトウェア品質特性の追加提案-
kyonmm
PRO
2
870
CyberAgent YJC Connect
shimaf4979
1
170
アプリブロック機能のつくりかたと、AIとHTMLの不合理な相性の良さについて
kumamotone
1
230
AI時代の品質はテストプロセスの作り直し #scrumniigata
kyonmm
PRO
4
1.4k
AI飲み会幹事エージェントを作っただけなのに
ykimi
0
120
Modernizing Your HCL Connections Experience: Visual Report to chain, Profile Enhancements, and AI Integration
wannesrams
0
300
Featured
See All Featured
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
270
Rails Girls Zürich Keynote
gr2m
96
14k
Building Flexible Design Systems
yeseniaperezcruz
330
40k
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
130
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.3k
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
510
The Language of Interfaces
destraynor
162
26k
Accessibility Awareness
sabderemane
1
110
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
170
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
1
540
Raft: Consensus for Rubyists
vanstee
141
7.4k
Transcript
みんなで書こう二分探索 会津大学2年松本響輝
二分探索って? ・二分していく探索です それ以上でもそれ以下でもない 探索する区間の長さをNとして なんと計算量オーダーがO(logN)ではやい! 半分,半分,半分,半分,......................
強い方のツイートで一時期盛り上がりました
どういう動き方か
どう動くの? 端っこを決めて、その真ん中で区間を分けていく。 使う方 使う方 使う方
なにを求められるのか
なにができるの ・ある境界を求められる 例 A = {3, 5, 10, 20, 33,
90, 98}の配列で値が15以上を満たす最小の index を返す場合 left : 0 right : 6 mid : 3 ← ( left + right ) / 2 A mid は20なので、15以上! ということは、探索する区間を左側にずらす→ right を mid にする
A = {3, 5, 10, 20, 33, 90, 98}の配列で値が15以上を満たす最小の index
を返す場合 left : 0 right : 3 ← mid mid : 1 ← ( left + right ) / 2 A mid は5なので、15以上じゃない! ということは、探索する区間を右側にずらす→ left を mid + 1にする
A = {3, 5, 10, 20, 33, 90, 98}の配列で値が15以上を満たす最小の index
を返す場合 left : 2 ← mid + 1 right : 3 mid : 2 ← ( left + right ) / 2 A mid は10なので、15以上! ということは、探索する区間を右側にずらす→ left を mid + 1にする
A = {3, 5, 10, 20, 33, 90, 98}の配列で値が15以上を満たす最小の index
を返す場合 left : 3 ← mid + 1 right : 3 mid : 3 ← ( left + right ) / 2 A mid は20なので、15以上! left と right が同じになったので left を返す( right でもよい)
なにを求めるの? ・ある境界を求められる つまり、条件を定めたときの境界を求めることができる ・ソート済みの配列の中で値が10以上を満たす最小の index ・0~n以下の素数の中で200000以上の最小の素数 条件が有効でない部分 条件が有効な部分 ※境界は整数でないこともあります
なにがうれしいのか
なにがうれしい? ・応用ができる! 例:値の検索 配列の中で値が x 以上を満たす最小の index → index 番目が
x ならOK、そうでないならその配列にはない ・計算量が少ない! 最悪でも計算量がO(logN) 0~1018くらいの区間だったとしても十分に高速(そんな大きい数を扱う職場...)
None
実装は? 1. 二分探索を使わない 2. 標準の関数を使う 3. 自分で作る
1.二分探索を使わない
1.二分探索を使わない (´・ω・`) え?
2.標準の関数を使う
2.標準の関数を使う • C++ ◦ lower_bound ◦ upper_bound • Python ◦
bisect • java ◦ Arrays.binarySearch ただ、配列に対して二分探索はできるが それ以外への二分探索ができない...
3.自分で作る
3.自分で作る(C++) 関数にするより、テンプレを覚えて書いた方が汎用性がよい! そんなあなたにめぐる式二分探索! ※競技プログラミング界隈はキャラがおおいがち 因幡めぐるアカウント様( https://twitter.com/meguru_comp)より
めぐる式二分探索の前に.. ・二分探索の実装上の工夫(先人たちの汗と涙の知恵) • 区間は半開区間[ left, right )で扱う 閉区間[ left, right
] これは left 以上 right 以下 半開区間 [ left, right ) これは left 以上 right 未満 今まで [ left, right ] → [ left, mid - 1 ]だったが [ left, right ) → [ left, mid )と簡潔に! ※ left を mid にする場合もおなじ ついでに、長さが N の配列のとき [ 0, N - 1 ] としてたのが [ 0, N ) にできる
めぐる式二分探索とは • めぐる式二分探索の特徴 ・ループの条件に絶対値を使っている ・ok, ng などの変数がある ・半開区間 ・最終的には ok
に求めたい値が入っている ・判定部分を関数にしている(←これについては諸説ありです) (ok, ng 以外の変数名の候補としては valid, invalid がある)
valid, invalid(ok, ng)みたいな変数には何の値が入るの? • ある条件を元にその境界を求めたい→二分探索でのis_valid関数を作る • validにはis_valid(valid)としたときに必ずtrueとなる値を入れる • invalidにはis_valid(invalid)としたときに必ずfalseとなる値を入れる •
例 ◦ n要素のソート済み配列 aからx以上の要素の最小のインデックスを見つけたい ▪ (配列aにはx以上の要素が少なくとも 1つは存在するものとする ) ◦ is_valid関数はindexを受け取ってa[i] >= x かどうかを判定するように作る ◦ validの初期値にはn-1を入れておく ◦ invalidの初期値には-1を入れておく(今回は invalidが開区間なので0じゃない) ◦ これであとは二分探索するだけ ▪ ※実際には、配列aの末尾に番兵として INFを挿入してvalid=nとする方が多いと思います
閉区間の実装と比較 ・+1, -1 を考えるのが混乱させる ・left か right のどちらにほしい値があるのか考える必要がある
閉区間の実装と比較 ・is_valid 関数を作ると、条件だけ考えることができる ・最終的にほしい値が valid だと分かりやすい ←の is_valid 関数は C++
のラムダ式です
これであなたも快適な二分探索ライフを! ご清聴ありがとうございました