Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .amazonq/rules/problem-creation.md
Original file line number Diff line number Diff line change
Expand Up @@ -329,4 +329,4 @@ make lint

## Tags (Optional)

Common tags: `["grind-75", "blind-75", "neetcode-150", "top-interview"]`
Common tags: `["grind-75", "grind", "blind-75", "neetcode-150", "algo-master-75"]`
2 changes: 2 additions & 0 deletions .github/workflows/ci-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ jobs:

steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 0

- name: Set up Python
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
PYTHON_VERSION = 3.13
PROBLEM ?= alien_dictionary
PROBLEM ?= jump_game
FORCE ?= 0
COMMA := ,

Expand Down
27 changes: 21 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,17 @@ A Python package to generate professional LeetCode practice environments. Featur

## <a id="whats-included"></a>🎯 What's Included

**Current**: All 75 problems from [Grind 75](https://www.techinterviewhandbook.org/grind75/) - the most essential coding interview questions curated by the creator of Blind 75.
**Current Problem Sets**:

**Future**: Planned expansion to all free Grind problems for comprehensive interview preparation. [Contributions welcome!](CONTRIBUTING.md)
- **grind-75** (75 problems) - Essential coding interview questions from [Grind 75](https://www.techinterviewhandbook.org/grind75/) ✅ Complete
- **grind** (100+ problems) - Extended Grind collection including all Grind 75 plus additional problems 🚧 Partial
- **blind-75** (75 problems) - Original [Blind 75](https://leetcode.com/problem-list/xi4ci4ig/) curated list 🚧 Partial
- **neetcode-150** (150+ problems) - Comprehensive [NeetCode 150](https://neetcode.io/practice) problem set 🚧 Partial
- **algo-master-75** (75 problems) - Curated algorithmic mastery problems 🚧 Partial

**Coverage**: 100+ unique problems across all major coding interview topics and difficulty levels.

**Note**: Some problem sets are partially covered. We're actively working to complete all collections. [Contributions welcome!](https://github.com/wisarootl/leetcode-py/blob/main/CONTRIBUTING.md)

## <a id="quick-start"></a>🚀 Quick Start

Expand All @@ -56,7 +64,9 @@ pip install leetcode-py-sdk
# Generate problems anywhere
lcpy gen -n 1 # Generate Two Sum
lcpy gen -t grind-75 # Generate all Grind 75 problems
lcpy list -t grind-75 # List available problems
lcpy gen -t neetcode-150 # Generate NeetCode 150 problems
lcpy list -t grind-75 # List Grind 75 problems
lcpy list -t blind-75 # List Blind 75 problems

# Start practicing
cd leetcode/two_sum
Expand All @@ -67,7 +77,9 @@ python -m pytest test_solution.py # Run tests
### Bulk Generation Example

```bash
lcpy gen --problem-tag grind-75 --output leetcode # Generate all Grind 75 problems
lcpy gen --problem-tag grind-75 --output leetcode # Generate all Grind 75 problems
lcpy gen --problem-tag neetcode-150 --output leetcode # Generate NeetCode 150 problems
lcpy gen --problem-tag blind-75 --output leetcode # Generate Blind 75 problems
```

![Problem Generation](https://raw.githubusercontent.com/wisarootl/leetcode-py/main/docs/images/problems-generation.png)
Expand Down Expand Up @@ -256,14 +268,17 @@ poetry run python -m leetcode_py.tools.check_test_cases --threshold=10
lcpy gen -n 1 # Single problem by number
lcpy gen -s two-sum # Single problem by slug
lcpy gen -t grind-75 # Bulk generation by tag
lcpy gen -t neetcode-150 # Generate NeetCode 150 problems
lcpy gen -n 1 -n 2 -n 3 # Multiple problems
lcpy gen -t grind-75 -d Easy # Filter by difficulty
lcpy gen -n 1 -o my-problems # Custom output directory

# List problems
lcpy list # All available problems
lcpy list -t grind-75 # Filter by tag
lcpy list -d Medium # Filter by difficulty
lcpy list -t grind-75 # Filter by Grind 75 tag
lcpy list -t blind-75 # Filter by Blind 75 tag
lcpy list -t neetcode-150 # Filter by NeetCode 150 tag
lcpy list -d Medium # Filter by difficulty

# Scrape problem data
lcpy scrape -n 1 # Fetch by number
Expand Down
13 changes: 11 additions & 2 deletions docs/cli-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,16 @@ lcpy list

# Filter by tag
lcpy list -t grind-75
lcpy list -t blind-75
lcpy list -t neetcode-150
lcpy list -t algo-master-75

# Filter by difficulty
lcpy list -d Easy

# Combine filters
lcpy list -t grind-75 -d Medium
lcpy list -t neetcode-150 -d Hard
```

## Problem Structure
Expand Down Expand Up @@ -181,8 +185,13 @@ _Comprehensive parametrized tests with 10+ test cases - executable and debuggabl

Available tags for bulk operations:

- `grind-75` - Essential 75 coding interview problems
- `grind` - Original Blind 75 problems
- `grind-75` - Essential 75 coding interview problems from [Grind 75](https://www.techinterviewhandbook.org/grind75/) ✅ Complete
- `grind` - Extended Grind collection (100+ problems) including all Grind 75 plus additional problems 🚧 Partial
- `blind-75` - Original [Blind 75](https://leetcode.com/discuss/general-discussion/460599/blind-75-leetcode-questions) curated list 🚧 Partial
- `neetcode-150` - Comprehensive [NeetCode 150](https://neetcode.io/practice) problem set (150+ problems) 🚧 Partial
- `algo-master-75` - Curated algorithmic mastery problems (75 problems) 🚧 Partial

**Note**: Some problem sets are partially covered. We're actively working to complete all collections. [Contributions welcome!](https://github.com/wisarootl/leetcode-py/blob/main/CONTRIBUTING.md)

## Output Directory

Expand Down
36 changes: 36 additions & 0 deletions leetcode/jump_game/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Jump Game

**Difficulty:** Medium
**Topics:** Array, Dynamic Programming, Greedy
**Tags:** blind-75

**LeetCode:** [Problem 55](https://leetcode.com/problems/jump-game/description/)

## Problem Description

You are given an integer array `nums`. You are initially positioned at the array's **first index**, and each element in the array represents your maximum jump length at that position.

Return `true` _if you can reach the last index, or_ `false` _otherwise_.

## Examples

### Example 1:

```
Input: nums = [2,3,1,1,4]
Output: true
Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index.
```

### Example 2:

```
Input: nums = [3,2,1,0,4]
Output: false
Explanation: You will always arrive at index 3 no matter what. Its maximum jump length is 0, which makes it impossible to reach the last index.
```

## Constraints

- `1 <= nums.length <= 10^4`
- `0 <= nums[i] <= 10^5`
Empty file added leetcode/jump_game/__init__.py
Empty file.
8 changes: 8 additions & 0 deletions leetcode/jump_game/helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
def run_can_jump(solution_class: type, nums: list[int]):
implementation = solution_class()
return implementation.can_jump(nums)


def assert_can_jump(result: bool, expected: bool) -> bool:
assert result == expected
return True
29 changes: 29 additions & 0 deletions leetcode/jump_game/playground.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# ---
# jupyter:
# jupytext:
# text_representation:
# extension: .py
# format_name: percent
# format_version: '1.3'
# jupytext_version: 1.17.3
# kernelspec:
# display_name: leetcode-py-py3.13
# language: python
# name: python3
# ---

# %%
from helpers import assert_can_jump, run_can_jump
from solution import Solution

# %%
# Example test case
nums = [2, 3, 1, 1, 4]
expected = True

# %%
result = run_can_jump(Solution, nums)
result

# %%
assert_can_jump(result, expected)
11 changes: 11 additions & 0 deletions leetcode/jump_game/solution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class Solution:

# Time: O(n)
# Space: O(1)
def can_jump(self, nums: list[int]) -> bool:
max_reach = 0
for i, jump in enumerate(nums):
if i > max_reach:
return False
max_reach = max(max_reach, i + jump)
return True
36 changes: 36 additions & 0 deletions leetcode/jump_game/test_solution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import pytest

from leetcode_py import logged_test

from .helpers import assert_can_jump, run_can_jump
from .solution import Solution


class TestJumpGame:
def setup_method(self):
self.solution = Solution()

@logged_test
@pytest.mark.parametrize(
"nums, expected",
[
([2, 3, 1, 1, 4], True),
([3, 2, 1, 0, 4], False),
([0], True),
([1], True),
([1, 0], True),
([0, 1], False),
([2, 0, 0], True),
([1, 1, 1, 0], True),
([3, 0, 8, 2, 0, 0, 1], True),
([1, 0, 1, 0], False),
([2, 5, 0, 0], True),
([1, 2, 3], True),
([5, 4, 3, 2, 1, 0, 0], False),
([1, 1, 2, 2, 0, 1, 1], True),
([4, 2, 0, 0, 1, 1, 4, 4, 4, 0, 4, 0], True),
],
)
def test_can_jump(self, nums: list[int], expected: bool):
result = run_can_jump(Solution, nums)
assert_can_jump(result, expected)
39 changes: 39 additions & 0 deletions leetcode/rotate_image/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Rotate Image

**Difficulty:** Medium
**Topics:** Array, Math, Matrix
**Tags:** blind

**LeetCode:** [Problem 48](https://leetcode.com/problems/rotate-image/description/)

## Problem Description

You are given an `n x n` 2D `matrix` representing an image, rotate the image by **90** degrees (clockwise).

You have to rotate the image **in-place**, which means you have to modify the input 2D matrix directly. **DO NOT** allocate another 2D matrix and do the rotation.

## Examples

### Example 1:

![Example 1](https://assets.leetcode.com/uploads/2020/08/28/mat1.jpg)

```
Input: matrix = [[1,2,3],[4,5,6],[7,8,9]]
Output: [[7,4,1],[8,5,2],[9,6,3]]
```

### Example 2:

![Example 2](https://assets.leetcode.com/uploads/2020/08/28/mat2.jpg)

```
Input: matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]]
Output: [[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]
```

## Constraints

- `n == matrix.length == matrix[i].length`
- `1 <= n <= 20`
- `-1000 <= matrix[i][j] <= 1000`
Empty file.
12 changes: 12 additions & 0 deletions leetcode/rotate_image/helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
def run_rotate(solution_class: type, matrix: list[list[int]]):
import copy

matrix_copy = copy.deepcopy(matrix)
implementation = solution_class()
implementation.rotate(matrix_copy)
return matrix_copy


def assert_rotate(result: list[list[int]], expected: list[list[int]]) -> bool:
assert result == expected
return True
29 changes: 29 additions & 0 deletions leetcode/rotate_image/playground.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# ---
# jupyter:
# jupytext:
# text_representation:
# extension: .py
# format_name: percent
# format_version: '1.3'
# jupytext_version: 1.17.3
# kernelspec:
# display_name: leetcode-py-py3.13
# language: python
# name: python3
# ---

# %%
from helpers import assert_rotate, run_rotate
from solution import Solution

# %%
# Example test case
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
expected = [[7, 4, 1], [8, 5, 2], [9, 6, 3]]

# %%
result = run_rotate(Solution, matrix)
result

# %%
assert_rotate(result, expected)
15 changes: 15 additions & 0 deletions leetcode/rotate_image/solution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class Solution:

# Time: O(n²)
# Space: O(1)
def rotate(self, matrix: list[list[int]]) -> None:
n = len(matrix)

# Transpose matrix
for i in range(n):
for j in range(i, n):
matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]

# Reverse each row
for i in range(n):
matrix[i].reverse()
Loading