Skip to content

Commit 8b3644e

Browse files
committed
feat: update multi-domain problem solutions and documentation (Algorithm, JS, SQL)
1 parent 6b5b387 commit 8b3644e

8 files changed

Lines changed: 161 additions & 123 deletions

File tree

Algorithm/Other/leetcode/83. Remove Duplicates from Sorted List/Claude 4.6 extended/README_React.html

Lines changed: 56 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
66
<title>LeetCode #83 - Remove Duplicates from Sorted List</title>
7-
<script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
8-
<script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
7+
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
8+
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
99
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
1010
<script src="https://cdn.tailwindcss.com"></script>
1111
<link rel="preconnect" href="https://fonts.googleapis.com" />
@@ -344,42 +344,58 @@ <h3 class="outfit font-bold text-teal-800 text-lg mb-3">問題の要点</h3>
344344

345345
<div class="mt-2 overflow-x-auto" id="mermaid-diagram">
346346
<div class="mermaid">
347-
flowchart TD Start([" 開始 "]) Guard["ガード節<br />head is None OR
348-
head.next is None ?"] GuardTrue["return head<br />変更なしで即時返却"]
349-
Init["初期化<br />current = head"] LoopCheck{"current.next<br />is not None
350-
?"} Cache["nxt = current.next<br />次ノードをキャッシュ"]
351-
DupCheck{"current.val<br />== nxt.val ?"} Skip["nxt をスキップ<br />current.next
352-
= nxt.next<br />※ current は動かさない"] Advance["current を前進<br />current
353-
= nxt"] Return["return head<br />重複除去済みリストを返す"] End([" 終了 "])
354-
Start --> Guard Guard -- "True<br />空 or 単一ノード" --> GuardTrue Guard --
355-
"False<br />複数ノード存在" --> Init GuardTrue --> End Init --> LoopCheck
356-
LoopCheck -- "False<br />current.next が None<br />ループ終了" --> Return
357-
LoopCheck -- "True<br />次ノード存在" --> Cache Cache --> DupCheck DupCheck
358-
-- "True<br />重複あり" --> Skip DupCheck -- "False<br />重複なし" -->
359-
Advance Skip -- "再チェック<br />同じ current で<br />ループ先頭へ戻る" -->
360-
LoopCheck Advance -- "次ノードへ<br />ループ先頭へ戻る" --> LoopCheck Return
361-
--> End style Start
362-
fill:#d1fae5,stroke:#10b981,stroke-width:2px,color:#065f46 style End
363-
fill:#d1fae5,stroke:#10b981,stroke-width:2px,color:#065f46 style Guard
364-
fill:#e0f2fe,stroke:#0284c7,stroke-width:2px,color:#0c4a6e style GuardTrue
365-
fill:#d1fae5,stroke:#059669,stroke-width:2px,color:#065f46 style Init
366-
fill:#e0f2fe,stroke:#0284c7,stroke-width:2px,color:#0c4a6e style LoopCheck
367-
fill:#fef3c7,stroke:#f59e0b,stroke-width:2px,color:#92400e style Cache
368-
fill:#f1f5f9,stroke:#64748b,stroke-width:2px,color:#1e293b style DupCheck
369-
fill:#fef3c7,stroke:#f59e0b,stroke-width:2px,color:#92400e style Skip
370-
fill:#fee2e2,stroke:#dc2626,stroke-width:2px,color:#991b1b style Advance
371-
fill:#f1f5f9,stroke:#64748b,stroke-width:2px,color:#1e293b style Return
372-
fill:#d1fae5,stroke:#059669,stroke-width:2.5px,color:#065f46 linkStyle 0
373-
stroke:#64748b,stroke-width:2px linkStyle 1 stroke:#059669,stroke-width:2px
374-
linkStyle 2 stroke:#64748b,stroke-width:2px linkStyle 3
375-
stroke:#059669,stroke-width:2px linkStyle 4 stroke:#64748b,stroke-width:2px
376-
linkStyle 5 stroke:#059669,stroke-width:2px linkStyle 6
377-
stroke:#64748b,stroke-width:2px linkStyle 7 stroke:#64748b,stroke-width:2px
378-
linkStyle 8 stroke:#dc2626,stroke-width:2px linkStyle 9
379-
stroke:#64748b,stroke-width:2px linkStyle 10
380-
stroke:#a855f7,stroke-width:2px,stroke-dasharray:6 4 linkStyle 11
381-
stroke:#a855f7,stroke-width:2px,stroke-dasharray:6 4 linkStyle 12
382-
stroke:#059669,stroke-width:2px
347+
flowchart TD
348+
Start([" 開始 "])
349+
Guard["ガード節<br/>head is None OR head.next is None ?"]
350+
GuardTrue["return head<br/>変更なしで即時返却"]
351+
Init["初期化<br/>current = head"]
352+
LoopCheck{"current.next<br/>is not None ?"}
353+
Cache["nxt = current.next<br/>次ノードをキャッシュ"]
354+
DupCheck{"current.val<br/>== nxt.val ?"}
355+
Skip["nxt をスキップ<br/>current.next = nxt.next<br/>※ current は動かさない"]
356+
Advance["current を前進<br/>current = nxt"]
357+
Return["return head<br/>重複除去済みリストを返す"]
358+
End([" 終了 "])
359+
360+
Start --> Guard
361+
Guard -- "True<br/>空 or 単一ノード" --> GuardTrue
362+
Guard -- "False<br/>複数ノード存在" --> Init
363+
GuardTrue --> End
364+
Init --> LoopCheck
365+
LoopCheck -- "False<br/>current.next が None<br/>ループ終了" --> Return
366+
LoopCheck -- "True<br/>次ノード存在" --> Cache
367+
Cache --> DupCheck
368+
DupCheck -- "True<br/>重複あり" --> Skip
369+
DupCheck -- "False<br/>重複なし" --> Advance
370+
Skip -- "再チェック<br/>同じ current で<br/>ループ先頭へ戻る" --> LoopCheck
371+
Advance -- "次ノードへ<br/>ループ先頭へ戻る" --> LoopCheck
372+
Return --> End
373+
374+
style Start fill:#d1fae5,stroke:#10b981,stroke-width:2px,color:#065f46
375+
style End fill:#d1fae5,stroke:#10b981,stroke-width:2px,color:#065f46
376+
style Guard fill:#e0f2fe,stroke:#0284c7,stroke-width:2px,color:#0c4a6e
377+
style GuardTrue fill:#d1fae5,stroke:#059669,stroke-width:2px,color:#065f46
378+
style Init fill:#e0f2fe,stroke:#0284c7,stroke-width:2px,color:#0c4a6e
379+
style LoopCheck fill:#fef3c7,stroke:#f59e0b,stroke-width:2px,color:#92400e
380+
style Cache fill:#f1f5f9,stroke:#64748b,stroke-width:2px,color:#1e293b
381+
style DupCheck fill:#fef3c7,stroke:#f59e0b,stroke-width:2px,color:#92400e
382+
style Skip fill:#fee2e2,stroke:#dc2626,stroke-width:2px,color:#991b1b
383+
style Advance fill:#f1f5f9,stroke:#64748b,stroke-width:2px,color:#1e293b
384+
style Return fill:#d1fae5,stroke:#059669,stroke-width:2.5px,color:#065f46
385+
386+
linkStyle 0 stroke:#64748b,stroke-width:2px
387+
linkStyle 1 stroke:#059669,stroke-width:2px
388+
linkStyle 2 stroke:#64748b,stroke-width:2px
389+
linkStyle 3 stroke:#059669,stroke-width:2px
390+
linkStyle 4 stroke:#64748b,stroke-width:2px
391+
linkStyle 5 stroke:#059669,stroke-width:2px
392+
linkStyle 6 stroke:#64748b,stroke-width:2px
393+
linkStyle 7 stroke:#64748b,stroke-width:2px
394+
linkStyle 8 stroke:#dc2626,stroke-width:2px
395+
linkStyle 9 stroke:#64748b,stroke-width:2px
396+
linkStyle 10 stroke:#a855f7,stroke-width:2px,stroke-dasharray:6 4
397+
linkStyle 11 stroke:#a855f7,stroke-width:2px,stroke-dasharray:6 4
398+
linkStyle 12 stroke:#059669,stroke-width:2px
383399
</div>
384400
</div>
385401

@@ -712,7 +728,8 @@ <h3 class="outfit font-bold text-teal-800 text-lg mb-3">アプローチ比較</h
712728
const BOX = 52,
713729
GAP = 16,
714730
ARR = 20;
715-
const W = Math.max(520, nodes.length * (BOX + GAP + ARR));
731+
const allNodes = nodes;
732+
const W = Math.max(520, allNodes.length * (BOX + GAP + ARR));
716733
const H = 120;
717734

718735
// compute x positions for all nodes (including skipped)
@@ -727,11 +744,6 @@ <h3 class="outfit font-bold text-teal-800 text-lg mb-3">アプローチ比較</h
727744
<svg
728745
viewBox={`0 0 ${W} ${H}`}
729746
style={{ width: '100%', height: 'auto', display: 'block', maxWidth: W }}
730-
role="img"
731-
aria-label={`連結リストの可視化: ${nodes
732-
.filter((n) => !n.skip)
733-
.map((n) => n.val)
734-
.join(' → ')} → None`}
735747
>
736748
{allNodes.map((node, i) => {
737749
if (node.skip) {

JavaScript/2627. Debounce/Claude Code Sonnet 4.5 extended/README.md

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,7 @@ graph LR
143143
```python
144144
from __future__ import annotations
145145
from typing import Callable, Any
146-
from threading import Timer
147-
146+
from threading import Timer, Lock
148147

149148
def debounce(fn: Callable[..., Any], t: float) -> Callable[..., None]:
150149
"""
@@ -171,18 +170,20 @@ def debounce(fn: Callable[..., Any], t: float) -> Callable[..., None]:
171170
"""
172171
# タイマーオブジェクトを保持するクロージャ変数
173172
timer: Timer | None = None
173+
lock = Lock()
174174

175175
def debounced_func(*args: Any, **kwargs: Any) -> None:
176176
nonlocal timer
177177

178-
# 既存のタイマーがあればキャンセル
179-
if timer is not None:
180-
timer.cancel()
178+
with lock:
179+
# 既存のタイマーがあればキャンセル
180+
if timer is not None:
181+
timer.cancel()
181182

182-
# 新しいタイマーをセット(t/1000 秒後に fn を実行)
183-
# threading.Timer は秒単位なので、ミリ秒を秒に変換
184-
timer = Timer(t / 1000.0, fn, args=args, kwargs=kwargs)
185-
timer.start()
183+
# 新しいタイマーをセット(t/1000 秒後に fn を実行)
184+
# threading.Timer は秒単位なので、ミリ秒を秒に変換
185+
timer = Timer(t / 1000.0, fn, args=args, kwargs=kwargs)
186+
timer.start()
186187

187188
return debounced_func
188189

@@ -194,6 +195,7 @@ class Solution:
194195
実際のLeetCodeにはこの問題はJavaScript/TypeScriptのみだが、
195196
Pythonで同等の機能を提供
196197
"""
198+
from threading import Timer, Lock
197199

198200
def debounce(self, fn: Callable[..., Any], t: int) -> Callable[..., None]:
199201
"""
@@ -205,18 +207,19 @@ class Solution:
205207
デバウンスされた関数
206208
"""
207209
timer: Timer | None = None
210+
lock = Lock()
208211

209212
def debounced(*args: Any, **kwargs: Any) -> None:
210213
nonlocal timer
214+
with lock:
215+
# 基底条件: タイマーが存在すればキャンセル
216+
if timer is not None:
217+
timer.cancel()
211218

212-
# 基底条件: タイマーが存在すればキャンセル
213-
if timer is not None:
214-
timer.cancel()
215-
216-
# 遷移: 新しいタイマーを作成して開始
217-
# t ミリ秒 = t/1000 秒
218-
timer = Timer(t / 1000.0, fn, args=args, kwargs=kwargs)
219-
timer.start()
219+
# 遷移: 新しいタイマーを作成して開始
220+
# t ミリ秒 = t/1000 秒
221+
timer = Timer(t / 1000.0, fn, args=args, kwargs=kwargs)
222+
timer.start()
220223

221224
return debounced
222225

@@ -290,7 +293,9 @@ def debounce_async(fn: Callable, t: float) -> Callable[..., Coroutine[Any, Any,
290293

291294
async def delayed():
292295
await asyncio.sleep(t / 1000.0)
293-
fn(*args, **kwargs)
296+
result = fn(*args, **kwargs)
297+
if asyncio.iscoroutine(result):
298+
await result
294299

295300
task = asyncio.create_task(delayed())
296301

@@ -318,17 +323,21 @@ if timer is not None:
318323
**クラスベース**:
319324

320325
```python
326+
from threading import Timer, Lock
327+
321328
class Debouncer:
322329
def __init__(self, fn: Callable, t: float):
323330
self.fn = fn
324331
self.t = t
325332
self.timer: Timer | None = None
333+
self.lock = Lock()
326334

327335
def __call__(self, *args, **kwargs):
328-
if self.timer:
329-
self.timer.cancel()
330-
self.timer = Timer(self.t / 1000.0, self.fn, args, kwargs)
331-
self.timer.start()
336+
with self.lock:
337+
if self.timer:
338+
self.timer.cancel()
339+
self.timer = Timer(self.t / 1000.0, self.fn, args, kwargs)
340+
self.timer.start()
332341
```
333342

334343
### 4. GIL(Global Interpreter Lock)の影響
@@ -470,6 +479,7 @@ my_func_debounced = debounce(my_func, 100)
470479
- **throttle**: 最初の呼び出しを即座に実行し、以降 `t` ミリ秒間は無視
471480

472481
```python
482+
import time
473483
# throttle の例(参考)
474484
def throttle(fn: Callable, t: float) -> Callable:
475485
last_call = [0.0]

SQL/Leetcode/Intermediate Join/1164. Product Price at a Given Date/Claude Sonnet 4.5 Extended/Product_Price_at_a_Given_Date.html

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
<title>Product Prices - 価格履歴管理 | Pandas解説</title>
77

88
<!-- React 18 CDN -->
9-
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
9+
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
1010
<script
1111
crossorigin
12-
src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"
12+
src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"
1313
></script>
1414

1515
<!-- Babel Standalone -->
@@ -337,7 +337,7 @@ <h3 class="text-xl font-bold text-cyan-800 mb-3">主要ポイント</h3>
337337
</h2>
338338
<div class="mt-[20px] overflow-x-auto">
339339
<svg
340-
viewBox="0 0 840 900"
340+
viewBox="0 0 840 960"
341341
style="max-width: 100%; height: auto; color: #333"
342342
role="img"
343343
aria-label="Product Prices flowchart"
@@ -2657,7 +2657,8 @@ <h3 className="mt-0 text-teal-800 text-xl font-semibold">
26572657
return null;
26582658
}
26592659

2660-
ReactDOM.render(<StepByStepGuide />, document.getElementById('step-root'));
2660+
const root = ReactDOM.createRoot(document.getElementById('step-root'));
2661+
root.render(<StepByStepGuide />);
26612662
</script>
26622663

26632664
<script>

SQL/Leetcode/Intermediate Join/1164. Product Price at a Given Date/Claude Sonnet 4.5 Extended/Product_Price_at_a_Given_Date_pandas.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ def price_at_given_date(products: pd.DataFrame) -> pd.DataFrame:
4646

4747
# --- 各製品の最新価格を取得(groupby + idxmax)
4848
if not before_target.empty:
49-
latest_idx = before_target.groupby('product_id')['change_date'].idxmax()
49+
# 同じ日付の場合は最新のインデックスを使用
50+
latest_idx = before_target.sort_values('change_date').groupby('product_id').tail(1).index
51+
5052
latest_prices = before_target.loc[latest_idx, ['product_id', 'new_price']]
5153
else:
5254
latest_prices = pd.DataFrame(columns=['product_id', 'new_price'])

SQL/Leetcode/Intermediate Select/1174. Immediate Food Delivery II/Claude Sonnet 4.5 Extended/Immediate_Food_Delivery_II.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ <h1 class="text-[2.5rem] font-bold text-teal-800 mb-2">
9595
Immediate Food Delivery II
9696
</h1>
9797
<p class="text-xl text-cyan-700 font-semibold mt-2">
98-
グループ内最小値抽出 + 条件集計 による O(N) 実装
98+
グループ内最小値抽出 + 条件集計 による O(N log N) 実装
9999
</p>
100100
<nav
101101
class="flex flex-wrap gap-4 mt-6"
@@ -202,7 +202,7 @@ <h3 class="text-xl font-semibold text-teal-800 mt-6 mb-3">解法戦略</h3>
202202

203203
<h3 class="text-xl font-semibold text-teal-800 mt-6 mb-3">主要ポイント</h3>
204204
<ul class="list-disc list-inside text-slate-600 leading-7 space-y-2">
205-
<li><strong>時間計算量</strong>: O(N) - 全行を1回走査</li>
205+
<li><strong>時間計算量</strong>: O(N log N) - グループ内ソートが必要</li>
206206
<li><strong>空間計算量</strong>: O(顧客数) - 最初の注文のみ保持</li>
207207
<li><strong>最適化</strong>: ウィンドウ関数を使用して1パスで処理</li>
208208
</ul>

0 commit comments

Comments
 (0)