Agent skill
LC Java
the other half of the tree
leetcode_java/ is the most-churned directory in this repo and the one
furthest behind: 1244 README rows carry a Java link against 2898 that carry a Python
one. /lc-java files a solution into it the way the other 1626 files are
filed — the package its pattern owns, markers that match the method names, a
compile and a run, and the [Java] link added to the row the problem
already has.
1 row README:0025 already exists — Hard, _O(n)_ / _O(1)_, Python only
so the title, difficulty and complexity are already settled
2 draft ws/Workspace26.java → // LC 25, with your "reverse in iteration" note
3 neighbour read LinkedList/ReverseLinkedList.java, matched its shape
4 write LeetCodeJava/LinkedList/ReverseNodesInKGroup.java
package LeetCodeJava.LinkedList;
V0 · IDEA: REVERSE IN GROUPS OF K · time = O(N), space = O(1)
5 variant + V0-1, dummy-node walk — O(1) space, not O(n/k) frames
6 compile javac clean · [1,2,3,4,5] k=2 → [2,1,4,3,5] · k=3 → [3,2,1,4,5]
k=1 → unchanged · single node — V0 and V0-1 agree
7 readme [Java] appended to row 0025's Solution cell. No other cell touched.
8 coverage find_missing_java.py no longer lists 25
9 assumed package LinkedList over TwoPointer. Correct me.
A real run, in the order it always happens: find the row that exists, pick up the draft, copy a neighbour, write, compile, file, check the coverage join, then say what was guessed.
Why a skill and not a habit
Three ways filing Java goes wrong
None of these are hypothetical — each one has actually landed in this repo, at a scale that took a 1481-file sweep to undo. They are why the recipe is written down once instead of remembered differently every time.
The marker names the method: // V1-2 documents findMedianSortedArrays_1_2. Closing a gap in the numbering silently renames a method, so markers are never renumbered — only a genuine collision is reassigned.
Cost: 47 collisions, where two solutions answered to one name.
A statement pasted from leetcode.com drags its furniture in — Solved, Topics, Companies, Hint, the premium lock, and sometimes the whole page footer with vote counts and Acceptance Rate.
Cost: 1445 headers had to have it stripped back out.
Most problems here are Python-first, so the row already exists and the Java link belongs in it. A second row for the same problem is invisible in a diff and nothing in the build catches it.
Rule: update the row, never add one.
One pass, no branches
Nine steps, in order
The steps never reorder and none of them is optional. Pick one to see what it does and the rule that step exists to enforce.
What lands in the tree
The house layout
Two artefacts, every time: one Java file and one edited README row. Both are shown here as they were actually written for LC 25 — the run the skill's own worked example describes.
package LeetCodeJava.LinkedList; <- the directory, spelled out
// https://leetcode.com/problems/reverse-nodes-in-k-group/description/
<- load-bearing: the coverage join reads it
import LeetCodeJava.DataStructure.ListNode;
<- imported, never re-declared
/**
* 25. Reverse Nodes in k-Group <- number, exact title
* Hard <- difficulty, own line, nothing else
*
* Given the head of a linked list, reverse the nodes of the list k at
* a time, and return the modified list.
*
* Example 1:
*
* Input: head = [1,2,3,4,5], k = 2
* Output: [2,1,4,3,5]
*
* Constraints:
*
* 1 <= k <= n <= 5000
*
*/
public class ReverseNodesInKGroup { <- title in PascalCase, = the file name
// V0 <- zero, not the letter O
// IDEA: REVERSE IN GROUPS OF K
/**
* time = O(N) <- equals sign, not a colon
* space = O(1)
*/
public ListNode reverseKGroup(ListNode head, int k) {
// edge case
if (head == null || k <= 1) {
return head;
}
int len = 0;
ListNode dummy = new ListNode();
dummy.next = head;
ListNode cur = head;
while (cur != null) { len += 1; cur = cur.next; }
ListNode prevGroupEnd = dummy;
cur = head;
// NOTE !!! only reverse while a FULL group of k remains
while (len >= k) {
...
}
return dummy.next;
}
}
No main method in a solution file, and no test file left behind — step 6
compiles it against the tree and drives it from a throwaway class.
The row already existed, filed with the Python solution. Only the Solution cell
changes — the [Java] link is appended after the Python one:
| 0025 | [Reverse Nodes in k-Group](https://leetcode.com/problems/reverse-nodes-in-k-group/) | [Python](./leetcode_python/Linked_list/reverse-nodes-in-k-group.py), [Java](./leetcode_java/src/main/java/LeetCodeJava/LinkedList/ReverseNodesInKGroup.java) | _O(n)_ | _O(1)_ | Hard | **linked list**, `reverse in k group` | AGAIN** (2) |
| Column | What happens to it |
|---|---|
| Title | Untouched. It was settled when the Python file was filed. |
| Solution | The only cell edited. [Java](…) appended after the Python link, matching the spacing already there. |
| O(t) / O(s) | Untouched. Complexity belongs to the problem, not the language — and re-deriving it here is how the row and the Python file drift apart. |
| Tags | Untouched. |
| Status | Untouched. It is your own record of how the problem went, and a Java port is not an attempt at it. |
Only a problem with no row at all gets a new one — inserted in ascending LC-number order, exactly as /lc-python does it.
A second block is justified here by a real space bound, and its marker and its method name move together:
// V0-1 <- the marker
// IDEA: DUMMY NODE + IN-PLACE GROUP REVERSE (gpt)
/**
* time = O(N)
* space = O(1)
*/
public ListNode reverseKGroup_0_1(ListNode head, int k) {
^^^ the method name IS the marker
...
}
This pairing is why markers are never renumbered to close a gap: renumbering silently renames a method. Only a genuine collision — two blocks answering to one name — is reassigned, and 47 of those had to be untangled once already.
Arguments are inferred, not interrogated
How to call it
The slash form and plain English do the same thing. Paste a draft under the command and
it becomes the solution; leave it out and the draft is usually already in
ws/Workspace26.java, which is step 2's job to find.
/lc-java 25 LinkedList # + paste your draft under it
/lc-java 239 SlideWindow
add LC 25 to leetcode_java in java
file my workspace draft
port LC 207 to java
| Left out | What happens |
|---|---|
| Package | Inferred from the technique the solution actually uses — not from the problem's LeetCode tags. Flagged in the report when the call was close. |
| Class name | The problem title in PascalCase. Never derived from the method name. |
| Title / difficulty / complexity | Read off the README row that already exists, not re-derived. Only a Java-first problem sends it to the problem page. |
| LC number | The one thing it will ask for. Everything else keys off it. |
End to end
A worked run
/lc-java 25 LinkedList with the draft picked up from the workspace — the
run the hero terminal is showing, step by step and with what each one actually produced.
| Step | What it produced |
|---|---|
| 1 row | README row 0025 already there — Reverse Nodes in k-Group, Hard, _O(n)_ / _O(1)_, Python-only |
| 2 draft | ws/Workspace26.java → the // LC 25 draft plus the // IDEA: reverse in iteration note above it |
| 3 neighbour | read LinkedList/ReverseLinkedList.java, matched its shape |
| 4 write | ReverseNodesInKGroup.java — package line, url comment, 25. Reverse Nodes in k-Group / Hard javadoc, ListNode imported |
| 5 variant | V0 the iterative pass; V0-1 the dummy-node variant — justified: O(1) space instead of O(n/k) recursion frames |
| 6 compile | javac clean; k=2 → [2,1,4,3,5], k=3 → [3,2,1,4,5], k=1 → unchanged, single node — both variants agreeing |
| 7 readme | [Java](…) appended to row 0025's Solution cell; no other cell touched |
| 8 coverage | find_missing_java.py no longer lists 25 |
| 9 report | flagged: package chosen as LinkedList over TwoPointer; complexity columns left as the Python pass set them |
The file it produced is in the tree: ReverseNodesInKGroup.java.
The guardrails
What it will not do
A filing tool that quietly does more than filing is one you have to review line by line, which defeats the point of having it.
- Renumber a
// Vmarker.The marker names the method, so closing a gap in the numbering renames one. Only a genuine collision is reassigned. - Write clever instead of clear.The standard approach, explicit loops, real names and a comment on each non-obvious step — no stream pipelines, nested ternaries,
a[0] - b[0]comparators or uncommented bit tricks. - File one approach when there are several.Every solution that passes and is worth knowing gets its own
// V1,// V2, … — and a second spelling of the same loop does not count as one. - Add a second README row.The problem almost always has one already. Nothing in the build catches a duplicate, which is what makes it the expensive mistake.
- Re-derive the other columns.Complexity, difficulty and tags belong to the problem, not the language. A Java port is not a reason to touch them.
- Hand back code that was not compiled.A
javacplus the javadoc's own examples run before anything is reported done. - Touch
data/progress.txt.The practice log is your own record and gets its own commit — it is also the single source for the review plan, so nothing else writes to it. - Commit or push unless asked.It writes files and stops. The commit is yours to shape.
One markdown file, no dependencies
Install
SKILL.md is the whole recipe — nothing to build and no network calls, so
the same source runs on any agent that takes a system prompt. Pick yours.
Drop the skill directory into your user-level skills folder and it loads in every repo:
git clone --depth 1 https://github.com/yennanliu/CS_basics.git /tmp/cs_basics
mkdir -p ~/.claude/skills
cp -r /tmp/cs_basics/.claude/skills/lc-java ~/.claude/skills/
Already installed inside this repo at .claude/skills/lc-java/, so a clone
of CS_basics needs no setup at all. Claude Code matches it on the description, or you
can call /lc-java by name — the directory name is the command.
Zip the directory, then Customize → Skills → + → + Create skill → Upload a skill:
cd .claude/skills && zip -r lc-java.zip lc-java
Leave the YAML frontmatter in SKILL.md intact. description is
what Claude matches your request against when deciding to load the skill on its own;
name is the display label, and the directory name is what supplies the
slash command.
Codex reads AGENTS.md at the repo root automatically. Point it at the skill:
## Filing a LeetCode Java solution
When asked to add an LC problem in Java, to file a draft out of the
workspace scratch file, or to port an existing Python solution, follow
`.claude/skills/lc-java/SKILL.md`.
A pointer, not a copy — one source of truth means a fix reaches every agent at once.
Same shape in GEMINI.md, or point at it for a single session:
gemini -p "Follow the recipe in .claude/skills/lc-java/SKILL.md. \
File LC 25 into LeetCodeJava/LinkedList — draft in @Draft.java"
Paste SKILL.md in as the system prompt. It is self-contained and has no
references/ to carry. For Cursor or Windsurf, put the Codex pointer above
into a rule file (.cursor/rules/lc-java.mdc or the editor's equivalent).
curl -sL https://raw.githubusercontent.com/yennanliu/CS_basics/master/.claude/skills/lc-java/SKILL.md
Two caveats away from this repo: steps 1 and 7 read an existing README table, and
step 8 runs find_missing_java.py. Point it at whatever plays those roles
in your own tree, or it falls back to the layout documented in SKILL.md.
Under the hood
What is inside
One file. The steps live there and nowhere else — this page describes them, but
SKILL.md is what actually runs, so the two cannot drift into two recipes.
- SKILL.md The whole recipe — the five prime directives, the nine steps with their commands, the file layout, the README row rule, the do-not list, and the LC 25 worked example.
Gated in CI by check_skills.py — frontmatter every host can parse, the directory name pinned to the command name, and whether the links on this page still resolve.
The rest of the loop
Where it fits
/lc-java is /lc-python's counterpart: the same
recipe shape, a different tree, and one README row shared between them rather than one
each.
/add-time-space
is the one to run over a whole package once the files are in. From there the
explorer indexes it, the
review plan schedules it once you log the attempt,
and LC Coach is the one to ask whether the solution you just
filed would actually have passed.