Skip to content

Commit 527cc76

Browse files
committed
feat: add 2 more leetcode problems
1 parent a1847af commit 527cc76

28 files changed

+843
-181
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
PYTHON_VERSION = 3.13
2-
PROBLEM ?= find_k_closest_elements
2+
PROBLEM ?= alien_dictionary
33
FORCE ?= 0
44
COMMA := ,
55

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
[![pypi](https://img.shields.io/pypi/v/leetcode-py-sdk.svg?color=blue)](https://pypi.python.org/pypi/leetcode-py-sdk)
1010
[![downloads](https://static.pepy.tech/personalized-badge/leetcode-py-sdk?period=total&units=international_system&left_color=grey&right_color=blue&left_text=pypi%20downloads)](https://pepy.tech/projects/leetcode-py-sdk)
1111
[![python](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-blue?logo=python)](https://github.com/wisarootl/leetcode-py/)
12+
[![Star ⭐](https://img.shields.io/github/stars/wisarootl/leetcode-py?style=flat&logo=github&color=ffcc00)](https://github.com/wisarootl/leetcode-py)
13+
[![Sponsor 💖](https://img.shields.io/badge/Sponsor-💖-pink?style=flat)](https://github.com/sponsors/wisarootl)
1214

1315
A Python package to generate professional LeetCode practice environments. Features automated problem generation from LeetCode URLs, beautiful data structure visualizations (TreeNode, ListNode, GraphNode), and comprehensive testing with 10+ test cases per problem. Built with professional development practices including CI/CD, type hints, and quality gates.
1416

@@ -298,3 +300,11 @@ make gen-all-problems # Regenerate all problems (destructive)
298300
- **CI/CD**: GitHub Actions for testing, security, pre-commit hooks, and release automation
299301

300302
Perfect for systematic coding interview preparation with professional development practices and enhanced debugging capabilities.
303+
304+
## 💖 Support This Project
305+
306+
[![Star ⭐](https://img.shields.io/github/stars/wisarootl/leetcode-py?style=flat&logo=github&color=ffcc00)](https://github.com/wisarootl/leetcode-py)
307+
[![Sponsor 💖](https://img.shields.io/badge/Sponsor-💖-pink?style=flat)](https://github.com/sponsors/wisarootl)
308+
309+
If you find this project helpful, please consider **starring the repo ⭐** or **sponsoring my work 💖**.
310+
Your support helps me maintain and improve this project. Thank you!
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Alien Dictionary
2+
3+
**Difficulty:** Hard
4+
**Topics:** Array, String, Depth-First Search, Breadth-First Search, Graph, Topological Sort
5+
**Tags:** grind-75, grind
6+
7+
**LeetCode:** [Problem 269](https://leetcode.com/problems/alien-dictionary/description/)
8+
9+
## Problem Description
10+
11+
There is a new alien language that uses the English alphabet. However, the order among the letters is unknown to you.
12+
13+
You are given a list of strings `words` from the alien language's dictionary, where the strings in `words` are **sorted lexicographically** by the rules of this new language.
14+
15+
Return _a string of the unique letters in the new alien language sorted in **lexicographically increasing order** by the new language's rules. If there is no solution, return_ `""`\*. If there are multiple solutions, return **any of them\***.
16+
17+
## Examples
18+
19+
### Example 1:
20+
21+
```
22+
Input: words = ["wrt","wrf","er","ett","rftt"]
23+
Output: "wertf"
24+
```
25+
26+
### Example 2:
27+
28+
```
29+
Input: words = ["z","x"]
30+
Output: "zx"
31+
```
32+
33+
### Example 3:
34+
35+
```
36+
Input: words = ["z","x","z"]
37+
Output: ""
38+
Explanation: The order is invalid, so return "".
39+
```
40+
41+
## Constraints
42+
43+
- `1 <= words.length <= 100`
44+
- `1 <= words[i].length <= 100`
45+
- `words[i]` consists of only lowercase English letters.

leetcode/alien_dictionary/__init__.py

Whitespace-only changes.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
def run_alien_order(solution_class: type, words: list[str]):
2+
implementation = solution_class()
3+
return implementation.alien_order(words)
4+
5+
6+
def assert_alien_order(result: str, expected: str) -> bool:
7+
if expected == "":
8+
assert result == ""
9+
else:
10+
# Multiple valid solutions possible, check if result is valid
11+
assert len(result) == len(expected)
12+
assert set(result) == set(expected)
13+
return True
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# ---
2+
# jupyter:
3+
# jupytext:
4+
# text_representation:
5+
# extension: .py
6+
# format_name: percent
7+
# format_version: '1.3'
8+
# jupytext_version: 1.17.3
9+
# kernelspec:
10+
# display_name: leetcode-py-py3.13
11+
# language: python
12+
# name: python3
13+
# ---
14+
15+
# %%
16+
from helpers import assert_alien_order, run_alien_order
17+
from solution import Solution
18+
19+
# %%
20+
# Example test case
21+
words = ["wrt", "wrf", "er", "ett", "rftt"]
22+
expected = "wertf"
23+
24+
# %%
25+
result = run_alien_order(Solution, words)
26+
result
27+
28+
# %%
29+
assert_alien_order(result, expected)
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
class Solution:
2+
3+
# Time: O(C) where C is total number of characters in all words
4+
# Space: O(1) since at most 26 characters in alphabet
5+
def alien_order(self, words: list[str]) -> str:
6+
# Build adjacency list and in-degree count
7+
adj: dict[str, set[str]] = {c: set() for word in words for c in word}
8+
in_degree = {c: 0 for c in adj}
9+
10+
# Build graph by comparing adjacent words
11+
for i in range(len(words) - 1):
12+
w1, w2 = words[i], words[i + 1]
13+
min_len = min(len(w1), len(w2))
14+
15+
# Check for invalid case: longer word is prefix of shorter word
16+
if len(w1) > len(w2) and w1[:min_len] == w2[:min_len]:
17+
return ""
18+
19+
# Find first different character and add edge
20+
for j in range(min_len):
21+
if w1[j] != w2[j]:
22+
if w2[j] not in adj[w1[j]]:
23+
adj[w1[j]].add(w2[j])
24+
in_degree[w2[j]] += 1
25+
break
26+
27+
# Topological sort using Kahn's algorithm
28+
queue = [c for c in in_degree if in_degree[c] == 0]
29+
result = []
30+
31+
while queue:
32+
c = queue.pop(0)
33+
result.append(c)
34+
35+
for neighbor in adj[c]:
36+
in_degree[neighbor] -= 1
37+
if in_degree[neighbor] == 0:
38+
queue.append(neighbor)
39+
40+
# Check for cycle (invalid ordering)
41+
return "".join(result) if len(result) == len(in_degree) else ""
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import pytest
2+
3+
from leetcode_py import logged_test
4+
5+
from .helpers import assert_alien_order, run_alien_order
6+
from .solution import Solution
7+
8+
9+
class TestAlienDictionary:
10+
def setup_method(self):
11+
self.solution = Solution()
12+
13+
@logged_test
14+
@pytest.mark.parametrize(
15+
"words, expected",
16+
[
17+
(["wrt", "wrf", "er", "ett", "rftt"], "wertf"),
18+
(["z", "x"], "zx"),
19+
(["z", "x", "z"], ""),
20+
(["z", "z"], "z"),
21+
(["abc", "ab"], ""),
22+
(["ab", "adc"], "abdc"),
23+
(["ac", "ab", "zc", "zb"], "acbz"),
24+
(["z"], "z"),
25+
(["za", "zb", "ca", "cb"], "zcab"),
26+
(["zy", "zx"], "zyx"),
27+
(["a", "b", "ca", "cc"], "abc"),
28+
(["abc", "bcd", "cde"], "abcde"),
29+
(["a", "aa"], "a"),
30+
(["ab", "abc"], "abc"),
31+
(["abc", "ab"], ""),
32+
(["a", "b", "c", "d"], "abcd"),
33+
(["d", "c", "b", "a"], "dcba"),
34+
(["ac", "ab", "b"], "acb"),
35+
],
36+
)
37+
def test_alien_order(self, words: list[str], expected: str):
38+
result = run_alien_order(Solution, words)
39+
assert_alien_order(result, expected)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Design In-Memory File System
2+
3+
**Difficulty:** Hard
4+
**Topics:** Design, Trie, Hash Table, String
5+
**Tags:** grind
6+
7+
**LeetCode:** [Problem 588](https://leetcode.com/problems/design-in-memory-file-system/description/)
8+
9+
## Problem Description
10+
11+
Design an in-memory file system to simulate the following functions:
12+
13+
`ls`: Given a path in string format. If it is a file path, return a list that only contains this file's name. If it is a directory path, return the list of file and directory names **in this directory**. Your output (file and directory names together) should in **lexicographic order**.
14+
15+
`mkdir`: Given a **directory path** that does not exist, you should make a new directory according to the path. If the middle directories in the path don't exist either, you should create them as well. This function has void return type.
16+
17+
`addContentToFile`: Given a **file path** and **file content** in string format. If the file doesn't exist, you need to create that file containing given content. If the file already exists, you need to **append** given content to original content. This function has void return type.
18+
19+
`readContentFromFile`: Given a **file path**, return its **content** in string format.
20+
21+
## Examples
22+
23+
### Example 1:
24+
25+
![filesystem](https://assets.leetcode.com/uploads/2018/10/12/filesystem.png)
26+
27+
```
28+
Input:
29+
["FileSystem","ls","mkdir","addContentToFile","ls","readContentFromFile"]
30+
[[],["/"],["a/b/c"],["/a/b/c/d","hello"],["/"],["/a/b/c/d"]]
31+
32+
Output:
33+
[null,[],null,null,["a"],"hello"]
34+
```
35+
36+
## Constraints
37+
38+
- You can assume all file or directory paths are absolute paths which begin with `/` and do not end with `/` except that the path is just `"/"`.
39+
- You can assume that all operations will be passed valid parameters and users will not attempt to retrieve file content or list a directory or file that does not exist.
40+
- You can assume that all directory names and file names only contain lower-case letters, and same names won't exist in the same directory.

leetcode/design_in_memory_file_system/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)