leetcode-capture-helper 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli.js +92 -0
- package/config.js +25 -0
- package/framing.js +57 -0
- package/host.js +346 -0
- package/install.js +290 -0
- package/package.json +31 -4
- package/runtime/bundle.json +42 -0
- package/runtime/companion/capture-log.js +83 -0
- package/runtime/companion/codex-backend.js +337 -0
- package/runtime/companion/companion.js +2193 -0
- package/runtime/companion/mouse-input.js +154 -0
- package/runtime/companion/package.json +4 -0
- package/runtime/companion/panel-bridge.js +273 -0
- package/runtime/companion/settings-rpc.js +228 -0
- package/runtime/companion/settings.js +464 -0
- package/runtime/companion/terminal-format.js +330 -0
- package/runtime/companion/vault-summary.js +169 -0
- package/runtime/companion/virtual-terminal.js +138 -0
- package/runtime/extension/shared/anthropic-backend.js +193 -0
- package/runtime/extension/shared/catalog.js +415 -0
- package/runtime/extension/shared/code-ledger.js +333 -0
- package/runtime/extension/shared/context-budget.js +259 -0
- package/runtime/extension/shared/context-summary.js +271 -0
- package/runtime/extension/shared/conversation.js +81 -0
- package/runtime/extension/shared/event-hub.js +126 -0
- package/runtime/extension/shared/extension-settings.js +445 -0
- package/runtime/extension/shared/helper-launcher.js +248 -0
- package/runtime/extension/shared/local-backend.js +706 -0
- package/runtime/extension/shared/local-server.js +149 -0
- package/runtime/extension/shared/package.json +4 -0
- package/runtime/extension/shared/practice.js +228 -0
- package/runtime/extension/shared/problem-index.js +4128 -0
- package/runtime/extension/shared/profiles.js +106 -0
- package/runtime/extension/shared/providers.js +58 -0
- package/runtime/extension/shared/reply-guard.js +864 -0
- package/runtime/extension/shared/roadmap.js +1344 -0
- package/runtime/extension/shared/sanitize.js +68 -0
- package/runtime/extension/shared/solved.js +277 -0
- package/runtime/extension/shared/tutor-engine.js +369 -0
- package/runtime/extension/shared/tutor-prompt.js +108 -0
- package/runtime/extension/shared/tutor-service.js +520 -0
- package/runtime/relay-server/package.json +4 -0
- package/runtime/relay-server/panel-broker.js +797 -0
- package/runtime/relay-server/server.js +241 -0
- package/runtime/vault-tool/log-session.js +230 -0
- package/runtime/vault-tool/package.json +4 -0
- package/runtime/vault-tool/vault-notes.js +206 -0
- package/README.md +0 -3
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
// extension/shared/anthropic-backend.js - the tutor backend for the Anthropic
|
|
2
|
+
// Messages API with the user's own API key, used by the extension's
|
|
3
|
+
// background engine (the companion uses the Claude Agent SDK instead).
|
|
4
|
+
//
|
|
5
|
+
// It is LocalBackend with a different wire format: the same history, pinned
|
|
6
|
+
// problem and code, context fitting and "earlier in this session" summary,
|
|
7
|
+
// so a long session behaves the same on every provider. Only request() is
|
|
8
|
+
// replaced. Raw fetch rather than the SDK, because the extension has no build
|
|
9
|
+
// step and no dependencies.
|
|
10
|
+
//
|
|
11
|
+
// Called straight from the browser, so the request carries
|
|
12
|
+
// `anthropic-dangerous-direct-browser-access: true`. The key comes from the
|
|
13
|
+
// extension's own storage and only ever goes to the Anthropic API.
|
|
14
|
+
//
|
|
15
|
+
// Pure JavaScript with no Node API (extension/shared.test.js checks that).
|
|
16
|
+
|
|
17
|
+
import { LocalBackend } from './local-backend.js';
|
|
18
|
+
|
|
19
|
+
export const ANTHROPIC_BASE_URL = 'https://api.anthropic.com';
|
|
20
|
+
export const ANTHROPIC_VERSION = '2026-10-21';
|
|
21
|
+
export const DEFAULT_ANTHROPIC_MODEL = 'claude-opus-5-5';
|
|
22
|
+
// What one reply may use. Also the reserve held back from the window, so a
|
|
23
|
+
// request that fits always leaves the model this much room.
|
|
24
|
+
export const ANTHROPIC_MAX_TOKENS = 16000;
|
|
25
|
+
// The window budgeted for. Current models take far more, but a tutoring
|
|
26
|
+
// session never needs it, and a smaller budget keeps a runaway session from
|
|
27
|
+
// getting expensive: older exchanges are condensed long before this.
|
|
28
|
+
export const ANTHROPIC_CONTEXT_TOKENS = 200000;
|
|
29
|
+
|
|
30
|
+
// The Messages API takes the system prompt on its own and only user and
|
|
31
|
+
// assistant turns in `messages`. Every leading system message (the persona,
|
|
32
|
+
// the pinned problem and code, the summary; see context-budget.js's
|
|
33
|
+
// buildMessages) is joined into `system`, in order; a system message anywhere
|
|
34
|
+
// later, which buildMessages never makes, is sent as a user note rather than
|
|
35
|
+
// dropped.
|
|
36
|
+
export function toAnthropicRequest(messages) {
|
|
37
|
+
const system = [];
|
|
38
|
+
const turns = [];
|
|
39
|
+
for (const message of messages) {
|
|
40
|
+
if (message.role === 'system' && turns.length === 0) {
|
|
41
|
+
system.push(message.content);
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
const role = message.role === 'assistant' ? 'assistant' : 'user';
|
|
45
|
+
const content = message.role === 'system' ? `(Note: ${message.content})` : message.content;
|
|
46
|
+
const last = turns[turns.length - 1];
|
|
47
|
+
// Two turns in a row from the same side are merged, which the API would
|
|
48
|
+
// do anyway, so the request is always well formed.
|
|
49
|
+
if (last && last.role === role) last.content = `${last.content}\n\n${content}`;
|
|
50
|
+
else turns.push({ role, content });
|
|
51
|
+
}
|
|
52
|
+
return { system: system.join('\n\n'), messages: turns };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function anthropicError(status, statusText, bodyText) {
|
|
56
|
+
let detail = bodyText;
|
|
57
|
+
try {
|
|
58
|
+
const parsed = JSON.parse(bodyText);
|
|
59
|
+
if (parsed?.error?.message) detail = parsed.error.message;
|
|
60
|
+
} catch {
|
|
61
|
+
// keep the raw text
|
|
62
|
+
}
|
|
63
|
+
if (status === 401) return new Error('the Anthropic API key was refused (401). Check the key in the options page.');
|
|
64
|
+
if (status === 429) return new Error(`the Anthropic API is rate limiting this key (429): ${detail}`);
|
|
65
|
+
return new Error(`Anthropic API request failed: ${status} ${statusText} ${detail}`.trim());
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export class AnthropicBackend extends LocalBackend {
|
|
69
|
+
constructor({
|
|
70
|
+
apiKey,
|
|
71
|
+
model,
|
|
72
|
+
maxHistoryTurns,
|
|
73
|
+
baseUrl = ANTHROPIC_BASE_URL,
|
|
74
|
+
contextTokens = ANTHROPIC_CONTEXT_TOKENS,
|
|
75
|
+
maxTokens = ANTHROPIC_MAX_TOKENS,
|
|
76
|
+
}) {
|
|
77
|
+
if (!apiKey) throw new Error('the Anthropic provider needs an API key');
|
|
78
|
+
super({
|
|
79
|
+
baseUrl,
|
|
80
|
+
model: model || DEFAULT_ANTHROPIC_MODEL,
|
|
81
|
+
apiKey,
|
|
82
|
+
maxHistoryTurns,
|
|
83
|
+
apiStyle: 'openai',
|
|
84
|
+
numCtx: contextTokens,
|
|
85
|
+
reserveTokens: maxTokens,
|
|
86
|
+
// Nothing to probe: the window is known and the API never silently
|
|
87
|
+
// truncates (an over-long request is refused instead).
|
|
88
|
+
probe: async () => null,
|
|
89
|
+
windowSetting: 'the Anthropic provider',
|
|
90
|
+
});
|
|
91
|
+
this.maxTokens = maxTokens;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async request(onChunk, messages, { signal } = {}) {
|
|
95
|
+
const { system, messages: turns } = toAnthropicRequest(messages);
|
|
96
|
+
const stream = Boolean(onChunk);
|
|
97
|
+
let response;
|
|
98
|
+
try {
|
|
99
|
+
response = await fetch(`${this.baseUrl}/v1/messages`, {
|
|
100
|
+
method: 'POST',
|
|
101
|
+
signal,
|
|
102
|
+
headers: {
|
|
103
|
+
'Content-Type': 'application/json',
|
|
104
|
+
'x-api-key': this.apiKey,
|
|
105
|
+
'anthropic-version': ANTHROPIC_VERSION,
|
|
106
|
+
'anthropic-dangerous-direct-browser-access': 'true',
|
|
107
|
+
},
|
|
108
|
+
body: JSON.stringify({ model: this.model, max_tokens: this.maxTokens, system, messages: turns, stream }),
|
|
109
|
+
});
|
|
110
|
+
} catch (err) {
|
|
111
|
+
throw new Error(`could not reach ${this.baseUrl} (${err.message})`);
|
|
112
|
+
}
|
|
113
|
+
if (!response.ok) {
|
|
114
|
+
const bodyText = await response.text().catch(() => '');
|
|
115
|
+
throw anthropicError(response.status, response.statusText, bodyText);
|
|
116
|
+
}
|
|
117
|
+
if (stream) return this.streamAnthropic(response, onChunk);
|
|
118
|
+
const data = await response.json();
|
|
119
|
+
const content = (data?.content || [])
|
|
120
|
+
.filter((block) => block?.type === 'text')
|
|
121
|
+
.map((block) => block.text)
|
|
122
|
+
.join('');
|
|
123
|
+
return { content, reasoning: '', finishReason: finishReasonFor(data?.stop_reason), promptTokens: null };
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Reads the Messages API's SSE stream: text arrives in
|
|
127
|
+
// `content_block_delta` events with a `text_delta`, the stop reason in
|
|
128
|
+
// `message_delta`, and a failure mid-stream as an `error` event. Thinking
|
|
129
|
+
// deltas are never shown.
|
|
130
|
+
async streamAnthropic(response, onChunk) {
|
|
131
|
+
const reader = response.body.getReader();
|
|
132
|
+
const decoder = new TextDecoder();
|
|
133
|
+
let buffer = '';
|
|
134
|
+
let content = '';
|
|
135
|
+
let stopReason = null;
|
|
136
|
+
for (;;) {
|
|
137
|
+
// eslint-disable-next-line no-await-in-loop
|
|
138
|
+
const { done, value } = await reader.read();
|
|
139
|
+
if (done) break;
|
|
140
|
+
buffer += decoder.decode(value, { stream: true });
|
|
141
|
+
let newlineIndex;
|
|
142
|
+
while ((newlineIndex = buffer.indexOf('\n')) !== -1) {
|
|
143
|
+
const line = buffer.slice(0, newlineIndex).trim();
|
|
144
|
+
buffer = buffer.slice(newlineIndex + 1);
|
|
145
|
+
if (!line.startsWith('data:')) continue;
|
|
146
|
+
let event;
|
|
147
|
+
try {
|
|
148
|
+
event = JSON.parse(line.slice(5).trim());
|
|
149
|
+
} catch {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
if (event?.type === 'content_block_delta' && event.delta?.type === 'text_delta' && event.delta.text) {
|
|
153
|
+
content += event.delta.text;
|
|
154
|
+
onChunk(event.delta.text);
|
|
155
|
+
} else if (event?.type === 'message_delta' && event.delta?.stop_reason) {
|
|
156
|
+
stopReason = event.delta.stop_reason;
|
|
157
|
+
} else if (event?.type === 'error') {
|
|
158
|
+
throw new Error(`Anthropic API error: ${event.error?.message || event.error?.type || 'unknown error'}`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return { content, reasoning: '', finishReason: finishReasonFor(stopReason), promptTokens: null };
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// The Messages API's stop reasons in the OpenAI terms resolveReplyText
|
|
167
|
+
// understands: a reply cut off at max_tokens is 'length'; a refusal is an
|
|
168
|
+
// error, never shown as a reply.
|
|
169
|
+
function finishReasonFor(stopReason) {
|
|
170
|
+
if (stopReason === 'max_tokens') return 'length';
|
|
171
|
+
if (stopReason === 'refusal') {
|
|
172
|
+
throw new Error('the model declined to answer this message (stop reason "refusal")');
|
|
173
|
+
}
|
|
174
|
+
return stopReason || 'stop';
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// The model ids this key can use (GET /v1/models), for the options page.
|
|
178
|
+
export async function listAnthropicModels({ apiKey, baseUrl = ANTHROPIC_BASE_URL, signal } = {}) {
|
|
179
|
+
const response = await fetch(`${baseUrl}/v1/models?limit=100`, {
|
|
180
|
+
signal,
|
|
181
|
+
headers: {
|
|
182
|
+
'x-api-key': apiKey,
|
|
183
|
+
'anthropic-version': ANTHROPIC_VERSION,
|
|
184
|
+
'anthropic-dangerous-direct-browser-access': 'true',
|
|
185
|
+
},
|
|
186
|
+
});
|
|
187
|
+
if (!response.ok) {
|
|
188
|
+
const bodyText = await response.text().catch(() => '');
|
|
189
|
+
throw anthropicError(response.status, response.statusText, bodyText);
|
|
190
|
+
}
|
|
191
|
+
const data = await response.json();
|
|
192
|
+
return (data?.data || []).map((m) => m?.id).filter((id) => typeof id === 'string' && id);
|
|
193
|
+
}
|
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
// Every problem any bundled list uses, once, keyed by LeetCode's own slug,
|
|
2
|
+
// with LeetCode's own title (its exact casing) and difficulty. Lists
|
|
3
|
+
// (shared/roadmap.js) refer to problems by slug only, so a problem shared by
|
|
4
|
+
// several lists has one title and one difficulty, and solving it once counts
|
|
5
|
+
// in every list.
|
|
6
|
+
//
|
|
7
|
+
// One line per problem: slug | title | E, M or H. Grouped by the first list
|
|
8
|
+
// that uses it, only to keep the file readable. extension/e2e/list-slugs.json
|
|
9
|
+
// is generated from this (node extension/scripts/list-slugs.mjs) so the
|
|
10
|
+
// slugs can be checked against LeetCode itself; roadmap.test.mjs fails when
|
|
11
|
+
// the two differ.
|
|
12
|
+
//
|
|
13
|
+
// Pure data, no Node or browser APIs (extension/shared.test.js checks that).
|
|
14
|
+
|
|
15
|
+
const DIFFICULTY = { E: 'Easy', M: 'Medium', H: 'Hard' };
|
|
16
|
+
|
|
17
|
+
const SOURCE = `
|
|
18
|
+
# NeetCode 150
|
|
19
|
+
contains-duplicate|Contains Duplicate|E
|
|
20
|
+
valid-anagram|Valid Anagram|E
|
|
21
|
+
two-sum|Two Sum|E
|
|
22
|
+
group-anagrams|Group Anagrams|M
|
|
23
|
+
top-k-frequent-elements|Top K Frequent Elements|M
|
|
24
|
+
encode-and-decode-strings|Encode and Decode Strings|M
|
|
25
|
+
product-of-array-except-self|Product of Array Except Self|M
|
|
26
|
+
valid-sudoku|Valid Sudoku|M
|
|
27
|
+
longest-consecutive-sequence|Longest Consecutive Sequence|M
|
|
28
|
+
valid-palindrome|Valid Palindrome|E
|
|
29
|
+
two-sum-ii-input-array-is-sorted|Two Sum II - Input Array Is Sorted|M
|
|
30
|
+
3sum|3Sum|M
|
|
31
|
+
container-with-most-water|Container With Most Water|M
|
|
32
|
+
trapping-rain-water|Trapping Rain Water|H
|
|
33
|
+
best-time-to-buy-and-sell-stock|Best Time to Buy and Sell Stock|E
|
|
34
|
+
longest-substring-without-repeating-characters|Longest Substring Without Repeating Characters|M
|
|
35
|
+
longest-repeating-character-replacement|Longest Repeating Character Replacement|M
|
|
36
|
+
permutation-in-string|Permutation in String|M
|
|
37
|
+
minimum-window-substring|Minimum Window Substring|H
|
|
38
|
+
sliding-window-maximum|Sliding Window Maximum|H
|
|
39
|
+
valid-parentheses|Valid Parentheses|E
|
|
40
|
+
min-stack|Min Stack|M
|
|
41
|
+
evaluate-reverse-polish-notation|Evaluate Reverse Polish Notation|M
|
|
42
|
+
generate-parentheses|Generate Parentheses|M
|
|
43
|
+
daily-temperatures|Daily Temperatures|M
|
|
44
|
+
car-fleet|Car Fleet|M
|
|
45
|
+
largest-rectangle-in-histogram|Largest Rectangle in Histogram|H
|
|
46
|
+
binary-search|Binary Search|E
|
|
47
|
+
search-a-2d-matrix|Search a 2D Matrix|M
|
|
48
|
+
koko-eating-bananas|Koko Eating Bananas|M
|
|
49
|
+
find-minimum-in-rotated-sorted-array|Find Minimum in Rotated Sorted Array|M
|
|
50
|
+
search-in-rotated-sorted-array|Search in Rotated Sorted Array|M
|
|
51
|
+
time-based-key-value-store|Time Based Key-Value Store|M
|
|
52
|
+
median-of-two-sorted-arrays|Median of Two Sorted Arrays|H
|
|
53
|
+
reverse-linked-list|Reverse Linked List|E
|
|
54
|
+
merge-two-sorted-lists|Merge Two Sorted Lists|E
|
|
55
|
+
linked-list-cycle|Linked List Cycle|E
|
|
56
|
+
reorder-list|Reorder List|M
|
|
57
|
+
remove-nth-node-from-end-of-list|Remove Nth Node From End of List|M
|
|
58
|
+
copy-list-with-random-pointer|Copy List with Random Pointer|M
|
|
59
|
+
add-two-numbers|Add Two Numbers|M
|
|
60
|
+
find-the-duplicate-number|Find the Duplicate Number|M
|
|
61
|
+
lru-cache|LRU Cache|M
|
|
62
|
+
merge-k-sorted-lists|Merge k Sorted Lists|H
|
|
63
|
+
reverse-nodes-in-k-group|Reverse Nodes in k-Group|H
|
|
64
|
+
invert-binary-tree|Invert Binary Tree|E
|
|
65
|
+
maximum-depth-of-binary-tree|Maximum Depth of Binary Tree|E
|
|
66
|
+
diameter-of-binary-tree|Diameter of Binary Tree|E
|
|
67
|
+
balanced-binary-tree|Balanced Binary Tree|E
|
|
68
|
+
same-tree|Same Tree|E
|
|
69
|
+
subtree-of-another-tree|Subtree of Another Tree|E
|
|
70
|
+
lowest-common-ancestor-of-a-binary-search-tree|Lowest Common Ancestor of a Binary Search Tree|M
|
|
71
|
+
binary-tree-level-order-traversal|Binary Tree Level Order Traversal|M
|
|
72
|
+
binary-tree-right-side-view|Binary Tree Right Side View|M
|
|
73
|
+
count-good-nodes-in-binary-tree|Count Good Nodes in Binary Tree|M
|
|
74
|
+
validate-binary-search-tree|Validate Binary Search Tree|M
|
|
75
|
+
kth-smallest-element-in-a-bst|Kth Smallest Element in a BST|M
|
|
76
|
+
construct-binary-tree-from-preorder-and-inorder-traversal|Construct Binary Tree from Preorder and Inorder Traversal|M
|
|
77
|
+
binary-tree-maximum-path-sum|Binary Tree Maximum Path Sum|H
|
|
78
|
+
serialize-and-deserialize-binary-tree|Serialize and Deserialize Binary Tree|H
|
|
79
|
+
kth-largest-element-in-a-stream|Kth Largest Element in a Stream|E
|
|
80
|
+
last-stone-weight|Last Stone Weight|E
|
|
81
|
+
k-closest-points-to-origin|K Closest Points to Origin|M
|
|
82
|
+
kth-largest-element-in-an-array|Kth Largest Element in an Array|M
|
|
83
|
+
task-scheduler|Task Scheduler|M
|
|
84
|
+
design-twitter|Design Twitter|M
|
|
85
|
+
find-median-from-data-stream|Find Median from Data Stream|H
|
|
86
|
+
subsets|Subsets|M
|
|
87
|
+
combination-sum|Combination Sum|M
|
|
88
|
+
permutations|Permutations|M
|
|
89
|
+
subsets-ii|Subsets II|M
|
|
90
|
+
combination-sum-ii|Combination Sum II|M
|
|
91
|
+
word-search|Word Search|M
|
|
92
|
+
palindrome-partitioning|Palindrome Partitioning|M
|
|
93
|
+
letter-combinations-of-a-phone-number|Letter Combinations of a Phone Number|M
|
|
94
|
+
n-queens|N-Queens|H
|
|
95
|
+
implement-trie-prefix-tree|Implement Trie (Prefix Tree)|M
|
|
96
|
+
design-add-and-search-words-data-structure|Design Add and Search Words Data Structure|M
|
|
97
|
+
word-search-ii|Word Search II|H
|
|
98
|
+
number-of-islands|Number of Islands|M
|
|
99
|
+
max-area-of-island|Max Area of Island|M
|
|
100
|
+
clone-graph|Clone Graph|M
|
|
101
|
+
walls-and-gates|Walls and Gates|M
|
|
102
|
+
rotting-oranges|Rotting Oranges|M
|
|
103
|
+
pacific-atlantic-water-flow|Pacific Atlantic Water Flow|M
|
|
104
|
+
surrounded-regions|Surrounded Regions|M
|
|
105
|
+
course-schedule|Course Schedule|M
|
|
106
|
+
course-schedule-ii|Course Schedule II|M
|
|
107
|
+
graph-valid-tree|Graph Valid Tree|M
|
|
108
|
+
number-of-connected-components-in-an-undirected-graph|Number of Connected Components in an Undirected Graph|M
|
|
109
|
+
redundant-connection|Redundant Connection|M
|
|
110
|
+
word-ladder|Word Ladder|H
|
|
111
|
+
reconstruct-itinerary|Reconstruct Itinerary|H
|
|
112
|
+
min-cost-to-connect-all-points|Min Cost to Connect All Points|M
|
|
113
|
+
network-delay-time|Network Delay Time|M
|
|
114
|
+
swim-in-rising-water|Swim in Rising Water|H
|
|
115
|
+
alien-dictionary|Alien Dictionary|H
|
|
116
|
+
cheapest-flights-within-k-stops|Cheapest Flights Within K Stops|M
|
|
117
|
+
climbing-stairs|Climbing Stairs|E
|
|
118
|
+
min-cost-climbing-stairs|Min Cost Climbing Stairs|E
|
|
119
|
+
house-robber|House Robber|M
|
|
120
|
+
house-robber-ii|House Robber II|M
|
|
121
|
+
longest-palindromic-substring|Longest Palindromic Substring|M
|
|
122
|
+
palindromic-substrings|Palindromic Substrings|M
|
|
123
|
+
decode-ways|Decode Ways|M
|
|
124
|
+
coin-change|Coin Change|M
|
|
125
|
+
maximum-product-subarray|Maximum Product Subarray|M
|
|
126
|
+
word-break|Word Break|M
|
|
127
|
+
longest-increasing-subsequence|Longest Increasing Subsequence|M
|
|
128
|
+
partition-equal-subset-sum|Partition Equal Subset Sum|M
|
|
129
|
+
unique-paths|Unique Paths|M
|
|
130
|
+
longest-common-subsequence|Longest Common Subsequence|M
|
|
131
|
+
best-time-to-buy-and-sell-stock-with-cooldown|Best Time to Buy and Sell Stock with Cooldown|M
|
|
132
|
+
coin-change-ii|Coin Change II|M
|
|
133
|
+
target-sum|Target Sum|M
|
|
134
|
+
interleaving-string|Interleaving String|M
|
|
135
|
+
longest-increasing-path-in-a-matrix|Longest Increasing Path in a Matrix|H
|
|
136
|
+
distinct-subsequences|Distinct Subsequences|H
|
|
137
|
+
edit-distance|Edit Distance|M
|
|
138
|
+
burst-balloons|Burst Balloons|H
|
|
139
|
+
regular-expression-matching|Regular Expression Matching|H
|
|
140
|
+
maximum-subarray|Maximum Subarray|M
|
|
141
|
+
jump-game|Jump Game|M
|
|
142
|
+
jump-game-ii|Jump Game II|M
|
|
143
|
+
gas-station|Gas Station|M
|
|
144
|
+
hand-of-straights|Hand of Straights|M
|
|
145
|
+
merge-triplets-to-form-target-triplet|Merge Triplets to Form Target Triplet|M
|
|
146
|
+
partition-labels|Partition Labels|M
|
|
147
|
+
valid-parenthesis-string|Valid Parenthesis String|M
|
|
148
|
+
insert-interval|Insert Interval|M
|
|
149
|
+
merge-intervals|Merge Intervals|M
|
|
150
|
+
non-overlapping-intervals|Non-overlapping Intervals|M
|
|
151
|
+
meeting-rooms|Meeting Rooms|E
|
|
152
|
+
meeting-rooms-ii|Meeting Rooms II|M
|
|
153
|
+
minimum-interval-to-include-each-query|Minimum Interval to Include Each Query|H
|
|
154
|
+
single-number|Single Number|E
|
|
155
|
+
number-of-1-bits|Number of 1 Bits|E
|
|
156
|
+
counting-bits|Counting Bits|E
|
|
157
|
+
reverse-bits|Reverse Bits|E
|
|
158
|
+
missing-number|Missing Number|E
|
|
159
|
+
sum-of-two-integers|Sum of Two Integers|M
|
|
160
|
+
reverse-integer|Reverse Integer|M
|
|
161
|
+
rotate-image|Rotate Image|M
|
|
162
|
+
spiral-matrix|Spiral Matrix|M
|
|
163
|
+
set-matrix-zeroes|Set Matrix Zeroes|M
|
|
164
|
+
happy-number|Happy Number|E
|
|
165
|
+
plus-one|Plus One|E
|
|
166
|
+
powx-n|Pow(x, n)|M
|
|
167
|
+
multiply-strings|Multiply Strings|M
|
|
168
|
+
detect-squares|Detect Squares|M
|
|
169
|
+
|
|
170
|
+
# Blind 75
|
|
171
|
+
combination-sum-iv|Combination Sum IV|M
|
|
172
|
+
|
|
173
|
+
# Grind 75
|
|
174
|
+
flood-fill|Flood Fill|E
|
|
175
|
+
implement-queue-using-stacks|Implement Queue using Stacks|E
|
|
176
|
+
first-bad-version|First Bad Version|E
|
|
177
|
+
ransom-note|Ransom Note|E
|
|
178
|
+
longest-palindrome|Longest Palindrome|E
|
|
179
|
+
majority-element|Majority Element|E
|
|
180
|
+
add-binary|Add Binary|E
|
|
181
|
+
middle-of-the-linked-list|Middle of the Linked List|E
|
|
182
|
+
01-matrix|01 Matrix|M
|
|
183
|
+
lowest-common-ancestor-of-a-binary-tree|Lowest Common Ancestor of a Binary Tree|M
|
|
184
|
+
accounts-merge|Accounts Merge|M
|
|
185
|
+
sort-colors|Sort Colors|M
|
|
186
|
+
string-to-integer-atoi|String to Integer (atoi)|M
|
|
187
|
+
find-all-anagrams-in-a-string|Find All Anagrams in a String|M
|
|
188
|
+
minimum-height-trees|Minimum Height Trees|M
|
|
189
|
+
basic-calculator|Basic Calculator|H
|
|
190
|
+
maximum-profit-in-job-scheduling|Maximum Profit in Job Scheduling|H
|
|
191
|
+
|
|
192
|
+
# Top Interview 150
|
|
193
|
+
merge-sorted-array|Merge Sorted Array|E
|
|
194
|
+
remove-element|Remove Element|E
|
|
195
|
+
remove-duplicates-from-sorted-array|Remove Duplicates from Sorted Array|E
|
|
196
|
+
remove-duplicates-from-sorted-array-ii|Remove Duplicates from Sorted Array II|M
|
|
197
|
+
rotate-array|Rotate Array|M
|
|
198
|
+
best-time-to-buy-and-sell-stock-ii|Best Time to Buy and Sell Stock II|M
|
|
199
|
+
h-index|H-Index|M
|
|
200
|
+
insert-delete-getrandom-o1|Insert Delete GetRandom O(1)|M
|
|
201
|
+
candy|Candy|H
|
|
202
|
+
roman-to-integer|Roman to Integer|E
|
|
203
|
+
integer-to-roman|Integer to Roman|M
|
|
204
|
+
length-of-last-word|Length of Last Word|E
|
|
205
|
+
longest-common-prefix|Longest Common Prefix|E
|
|
206
|
+
reverse-words-in-a-string|Reverse Words in a String|M
|
|
207
|
+
zigzag-conversion|Zigzag Conversion|M
|
|
208
|
+
find-the-index-of-the-first-occurrence-in-a-string|Find the Index of the First Occurrence in a String|E
|
|
209
|
+
text-justification|Text Justification|H
|
|
210
|
+
is-subsequence|Is Subsequence|E
|
|
211
|
+
minimum-size-subarray-sum|Minimum Size Subarray Sum|M
|
|
212
|
+
substring-with-concatenation-of-all-words|Substring with Concatenation of All Words|H
|
|
213
|
+
game-of-life|Game of Life|M
|
|
214
|
+
isomorphic-strings|Isomorphic Strings|E
|
|
215
|
+
word-pattern|Word Pattern|E
|
|
216
|
+
contains-duplicate-ii|Contains Duplicate II|E
|
|
217
|
+
summary-ranges|Summary Ranges|E
|
|
218
|
+
minimum-number-of-arrows-to-burst-balloons|Minimum Number of Arrows to Burst Balloons|M
|
|
219
|
+
simplify-path|Simplify Path|M
|
|
220
|
+
reverse-linked-list-ii|Reverse Linked List II|M
|
|
221
|
+
remove-duplicates-from-sorted-list-ii|Remove Duplicates from Sorted List II|M
|
|
222
|
+
rotate-list|Rotate List|M
|
|
223
|
+
partition-list|Partition List|M
|
|
224
|
+
symmetric-tree|Symmetric Tree|E
|
|
225
|
+
construct-binary-tree-from-inorder-and-postorder-traversal|Construct Binary Tree from Inorder and Postorder Traversal|M
|
|
226
|
+
populating-next-right-pointers-in-each-node-ii|Populating Next Right Pointers in Each Node II|M
|
|
227
|
+
flatten-binary-tree-to-linked-list|Flatten Binary Tree to Linked List|M
|
|
228
|
+
path-sum|Path Sum|E
|
|
229
|
+
sum-root-to-leaf-numbers|Sum Root to Leaf Numbers|M
|
|
230
|
+
binary-search-tree-iterator|Binary Search Tree Iterator|M
|
|
231
|
+
count-complete-tree-nodes|Count Complete Tree Nodes|M
|
|
232
|
+
average-of-levels-in-binary-tree|Average of Levels in Binary Tree|E
|
|
233
|
+
binary-tree-zigzag-level-order-traversal|Binary Tree Zigzag Level Order Traversal|M
|
|
234
|
+
minimum-absolute-difference-in-bst|Minimum Absolute Difference in BST|E
|
|
235
|
+
evaluate-division|Evaluate Division|M
|
|
236
|
+
snakes-and-ladders|Snakes and Ladders|M
|
|
237
|
+
minimum-genetic-mutation|Minimum Genetic Mutation|M
|
|
238
|
+
combinations|Combinations|M
|
|
239
|
+
n-queens-ii|N-Queens II|H
|
|
240
|
+
convert-sorted-array-to-binary-search-tree|Convert Sorted Array to Binary Search Tree|E
|
|
241
|
+
sort-list|Sort List|M
|
|
242
|
+
construct-quad-tree|Construct Quad Tree|M
|
|
243
|
+
maximum-sum-circular-subarray|Maximum Sum Circular Subarray|M
|
|
244
|
+
search-insert-position|Search Insert Position|E
|
|
245
|
+
find-peak-element|Find Peak Element|M
|
|
246
|
+
find-first-and-last-position-of-element-in-sorted-array|Find First and Last Position of Element in Sorted Array|M
|
|
247
|
+
ipo|IPO|H
|
|
248
|
+
find-k-pairs-with-smallest-sums|Find K Pairs with Smallest Sums|M
|
|
249
|
+
single-number-ii|Single Number II|M
|
|
250
|
+
bitwise-and-of-numbers-range|Bitwise AND of Numbers Range|M
|
|
251
|
+
palindrome-number|Palindrome Number|E
|
|
252
|
+
factorial-trailing-zeroes|Factorial Trailing Zeroes|M
|
|
253
|
+
sqrtx|Sqrt(x)|E
|
|
254
|
+
max-points-on-a-line|Max Points on a Line|H
|
|
255
|
+
triangle|Triangle|M
|
|
256
|
+
minimum-path-sum|Minimum Path Sum|M
|
|
257
|
+
unique-paths-ii|Unique Paths II|M
|
|
258
|
+
best-time-to-buy-and-sell-stock-iii|Best Time to Buy and Sell Stock III|H
|
|
259
|
+
best-time-to-buy-and-sell-stock-iv|Best Time to Buy and Sell Stock IV|H
|
|
260
|
+
maximal-square|Maximal Square|M
|
|
261
|
+
|
|
262
|
+
# SQL 50
|
|
263
|
+
recyclable-and-low-fat-products|Recyclable and Low Fat Products|E
|
|
264
|
+
find-customer-referee|Find Customer Referee|E
|
|
265
|
+
big-countries|Big Countries|E
|
|
266
|
+
article-views-i|Article Views I|E
|
|
267
|
+
invalid-tweets|Invalid Tweets|E
|
|
268
|
+
replace-employee-id-with-the-unique-identifier|Replace Employee ID With The Unique Identifier|E
|
|
269
|
+
product-sales-analysis-i|Product Sales Analysis I|E
|
|
270
|
+
customer-who-visited-but-did-not-make-any-transactions|Customer Who Visited but Did Not Make Any Transactions|E
|
|
271
|
+
rising-temperature|Rising Temperature|E
|
|
272
|
+
average-time-of-process-per-machine|Average Time of Process per Machine|E
|
|
273
|
+
employee-bonus|Employee Bonus|E
|
|
274
|
+
students-and-examinations|Students and Examinations|E
|
|
275
|
+
managers-with-at-least-5-direct-reports|Managers with at Least 5 Direct Reports|M
|
|
276
|
+
confirmation-rate|Confirmation Rate|M
|
|
277
|
+
not-boring-movies|Not Boring Movies|E
|
|
278
|
+
average-selling-price|Average Selling Price|E
|
|
279
|
+
project-employees-i|Project Employees I|E
|
|
280
|
+
percentage-of-users-attended-a-contest|Percentage of Users Attended a Contest|E
|
|
281
|
+
queries-quality-and-percentage|Queries Quality and Percentage|E
|
|
282
|
+
monthly-transactions-i|Monthly Transactions I|M
|
|
283
|
+
immediate-food-delivery-ii|Immediate Food Delivery II|M
|
|
284
|
+
game-play-analysis-iv|Game Play Analysis IV|M
|
|
285
|
+
number-of-unique-subjects-taught-by-each-teacher|Number of Unique Subjects Taught by Each Teacher|E
|
|
286
|
+
user-activity-for-the-past-30-days-i|User Activity for the Past 30 Days I|E
|
|
287
|
+
product-sales-analysis-iii|Product Sales Analysis III|M
|
|
288
|
+
classes-with-at-least-5-students|Classes With at Least 5 Students|E
|
|
289
|
+
find-followers-count|Find Followers Count|E
|
|
290
|
+
biggest-single-number|Biggest Single Number|E
|
|
291
|
+
customers-who-bought-all-products|Customers Who Bought All Products|M
|
|
292
|
+
the-number-of-employees-which-report-to-each-employee|The Number of Employees Which Report to Each Employee|E
|
|
293
|
+
primary-department-for-each-employee|Primary Department for Each Employee|E
|
|
294
|
+
triangle-judgement|Triangle Judgement|E
|
|
295
|
+
consecutive-numbers|Consecutive Numbers|M
|
|
296
|
+
product-price-at-a-given-date|Product Price at a Given Date|M
|
|
297
|
+
last-person-to-fit-in-the-bus|Last Person to Fit in the Bus|M
|
|
298
|
+
count-salary-categories|Count Salary Categories|M
|
|
299
|
+
employees-whose-manager-left-the-company|Employees Whose Manager Left the Company|E
|
|
300
|
+
exchange-seats|Exchange Seats|M
|
|
301
|
+
movie-rating|Movie Rating|M
|
|
302
|
+
restaurant-growth|Restaurant Growth|M
|
|
303
|
+
friend-requests-ii-who-has-the-most-friends|Friend Requests II: Who Has the Most Friends|M
|
|
304
|
+
investments-in-2016|Investments in 2016|M
|
|
305
|
+
department-top-three-salaries|Department Top Three Salaries|H
|
|
306
|
+
fix-names-in-a-table|Fix Names in a Table|E
|
|
307
|
+
patients-with-a-condition|Patients With a Condition|E
|
|
308
|
+
delete-duplicate-emails|Delete Duplicate Emails|E
|
|
309
|
+
second-highest-salary|Second Highest Salary|M
|
|
310
|
+
group-sold-products-by-the-date|Group Sold Products By The Date|E
|
|
311
|
+
list-the-products-ordered-in-a-period|List the Products Ordered in a Period|E
|
|
312
|
+
find-users-with-valid-e-mails|Find Users With Valid E-Mails|E
|
|
313
|
+
# Top 100 Liked
|
|
314
|
+
binary-tree-inorder-traversal|Binary Tree Inorder Traversal|E
|
|
315
|
+
path-sum-iii|Path Sum III|M
|
|
316
|
+
longest-valid-parentheses|Longest Valid Parentheses|H
|
|
317
|
+
pascals-triangle|Pascal's Triangle|E
|
|
318
|
+
perfect-squares|Perfect Squares|M
|
|
319
|
+
subarray-sum-equals-k|Subarray Sum Equals K|M
|
|
320
|
+
swap-nodes-in-pairs|Swap Nodes in Pairs|M
|
|
321
|
+
linked-list-cycle-ii|Linked List Cycle II|M
|
|
322
|
+
intersection-of-two-linked-lists|Intersection of Two Linked Lists|E
|
|
323
|
+
palindrome-linked-list|Palindrome Linked List|E
|
|
324
|
+
search-a-2d-matrix-ii|Search a 2D Matrix II|M
|
|
325
|
+
decode-string|Decode String|M
|
|
326
|
+
move-zeroes|Move Zeroes|E
|
|
327
|
+
next-permutation|Next Permutation|M
|
|
328
|
+
first-missing-positive|First Missing Positive|H
|
|
329
|
+
# NeetCode 250
|
|
330
|
+
concatenation-of-array|Concatenation of Array|E
|
|
331
|
+
design-hashset|Design HashSet|E
|
|
332
|
+
design-hashmap|Design HashMap|E
|
|
333
|
+
sort-an-array|Sort an Array|M
|
|
334
|
+
range-sum-query-2d-immutable|Range Sum Query 2D - Immutable|M
|
|
335
|
+
majority-element-ii|Majority Element II|M
|
|
336
|
+
reverse-string|Reverse String|E
|
|
337
|
+
valid-palindrome-ii|Valid Palindrome II|E
|
|
338
|
+
merge-strings-alternately|Merge Strings Alternately|E
|
|
339
|
+
4sum|4Sum|M
|
|
340
|
+
boats-to-save-people|Boats to Save People|M
|
|
341
|
+
find-k-closest-elements|Find K Closest Elements|M
|
|
342
|
+
baseball-game|Baseball Game|E
|
|
343
|
+
implement-stack-using-queues|Implement Stack using Queues|E
|
|
344
|
+
asteroid-collision|Asteroid Collision|M
|
|
345
|
+
online-stock-span|Online Stock Span|M
|
|
346
|
+
maximum-frequency-stack|Maximum Frequency Stack|H
|
|
347
|
+
guess-number-higher-or-lower|Guess Number Higher or Lower|E
|
|
348
|
+
capacity-to-ship-packages-within-d-days|Capacity To Ship Packages Within D Days|M
|
|
349
|
+
search-in-rotated-sorted-array-ii|Search in Rotated Sorted Array II|M
|
|
350
|
+
split-array-largest-sum|Split Array Largest Sum|H
|
|
351
|
+
find-in-mountain-array|Find in Mountain Array|H
|
|
352
|
+
design-circular-queue|Design Circular Queue|M
|
|
353
|
+
lfu-cache|LFU Cache|H
|
|
354
|
+
binary-tree-preorder-traversal|Binary Tree Preorder Traversal|E
|
|
355
|
+
binary-tree-postorder-traversal|Binary Tree Postorder Traversal|E
|
|
356
|
+
insert-into-a-binary-search-tree|Insert into a Binary Search Tree|M
|
|
357
|
+
delete-node-in-a-bst|Delete Node in a BST|M
|
|
358
|
+
house-robber-iii|House Robber III|M
|
|
359
|
+
delete-leaves-with-a-given-value|Delete Leaves With a Given Value|M
|
|
360
|
+
single-threaded-cpu|Single-Threaded CPU|M
|
|
361
|
+
reorganize-string|Reorganize String|M
|
|
362
|
+
longest-happy-string|Longest Happy String|M
|
|
363
|
+
car-pooling|Car Pooling|M
|
|
364
|
+
sum-of-all-subset-xor-totals|Sum of All Subset XOR Totals|E
|
|
365
|
+
permutations-ii|Permutations II|M
|
|
366
|
+
matchsticks-to-square|Matchsticks to Square|M
|
|
367
|
+
partition-to-k-equal-sum-subsets|Partition to K Equal Sum Subsets|M
|
|
368
|
+
word-break-ii|Word Break II|H
|
|
369
|
+
extra-characters-in-a-string|Extra Characters in a String|M
|
|
370
|
+
island-perimeter|Island Perimeter|E
|
|
371
|
+
verifying-an-alien-dictionary|Verifying an Alien Dictionary|E
|
|
372
|
+
find-the-town-judge|Find the Town Judge|E
|
|
373
|
+
open-the-lock|Open the Lock|M
|
|
374
|
+
course-schedule-iv|Course Schedule IV|M
|
|
375
|
+
path-with-minimum-effort|Path With Minimum Effort|M
|
|
376
|
+
find-critical-and-pseudo-critical-edges-in-minimum-spanning-tree|Find Critical and Pseudo-Critical Edges in Minimum Spanning Tree|H
|
|
377
|
+
build-a-matrix-with-conditions|Build a Matrix With Conditions|H
|
|
378
|
+
greatest-common-divisor-traversal|Greatest Common Divisor Traversal|H
|
|
379
|
+
n-th-tribonacci-number|N-th Tribonacci Number|E
|
|
380
|
+
integer-break|Integer Break|M
|
|
381
|
+
stone-game-iii|Stone Game III|H
|
|
382
|
+
last-stone-weight-ii|Last Stone Weight II|M
|
|
383
|
+
stone-game|Stone Game|M
|
|
384
|
+
stone-game-ii|Stone Game II|M
|
|
385
|
+
lemonade-change|Lemonade Change|E
|
|
386
|
+
longest-turbulent-subarray|Longest Turbulent Subarray|M
|
|
387
|
+
jump-game-vii|Jump Game VII|M
|
|
388
|
+
dota2-senate|Dota2 Senate|M
|
|
389
|
+
meeting-rooms-iii|Meeting Rooms III|H
|
|
390
|
+
minimum-array-end|Minimum Array End|M
|
|
391
|
+
excel-sheet-column-title|Excel Sheet Column Title|E
|
|
392
|
+
greatest-common-divisor-of-strings|Greatest Common Divisor of Strings|E
|
|
393
|
+
insert-greatest-common-divisors-in-linked-list|Insert Greatest Common Divisors in Linked List|M
|
|
394
|
+
transpose-matrix|Transpose Matrix|E
|
|
395
|
+
`;
|
|
396
|
+
|
|
397
|
+
function parse(source) {
|
|
398
|
+
const out = new Map();
|
|
399
|
+
for (const raw of source.split('\n')) {
|
|
400
|
+
const line = raw.trim();
|
|
401
|
+
if (!line || line.startsWith('#')) continue;
|
|
402
|
+
const [slug, title, d] = line.split('|');
|
|
403
|
+
if (out.has(slug)) throw new Error(`catalog: ${slug} twice`);
|
|
404
|
+
if (!DIFFICULTY[d]) throw new Error(`catalog: bad difficulty for ${slug}`);
|
|
405
|
+
out.set(slug, Object.freeze({ slug, title, difficulty: DIFFICULTY[d] }));
|
|
406
|
+
}
|
|
407
|
+
return out;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// slug -> { slug, title, difficulty }, in the order above.
|
|
411
|
+
export const CATALOG = parse(SOURCE);
|
|
412
|
+
|
|
413
|
+
export function catalogEntry(slug) {
|
|
414
|
+
return CATALOG.get(slug) || null;
|
|
415
|
+
}
|