Skip to content

Commit 96908f2

Browse files
committed
feat: add Word Break
1 parent 61ef1f6 commit 96908f2

File tree

21 files changed

+929
-1
lines changed

21 files changed

+929
-1
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{
2+
"problem_name": "sort_colors",
3+
"solution_class_name": "Solution",
4+
"problem_number": "75",
5+
"problem_title": "Sort Colors",
6+
"difficulty": "Medium",
7+
"topics": "Array, Two Pointers, Sorting",
8+
"tags": ["grind-75"],
9+
"readme_description": "Given an array `nums` with `n` objects colored red, white, or blue, sort them **in-place** so that objects of the same color are adjacent, with the colors in the order red, white, and blue.\n\nWe will use the integers `0`, `1`, and `2` to represent the color red, white, and blue, respectively.\n\nYou must solve this problem without using the library's sort function.",
10+
"readme_examples": [
11+
{ "content": "```\nInput: nums = [2,0,2,1,1,0]\nOutput: [0,0,1,1,2,2]\n```" },
12+
{ "content": "```\nInput: nums = [2,0,1]\nOutput: [0,1,2]\n```" }
13+
],
14+
"readme_constraints": "- `n == nums.length`\n- `1 <= n <= 300`\n- `nums[i]` is either `0`, `1`, or `2`.",
15+
"readme_additional": "**Follow up:** Could you come up with a one-pass algorithm using only constant extra space?",
16+
"solution_imports": "",
17+
"solution_methods": [
18+
{
19+
"name": "sort_colors",
20+
"parameters": "nums: list[int]",
21+
"return_type": "None",
22+
"dummy_return": ""
23+
}
24+
],
25+
"test_imports": "import pytest\nfrom leetcode_py.test_utils import logged_test\nfrom .solution import Solution",
26+
"test_class_name": "SortColors",
27+
"test_helper_methods": [
28+
{ "name": "setup_method", "parameters": "", "body": "self.solution = Solution()" }
29+
],
30+
"test_methods": [
31+
{
32+
"name": "test_sort_colors",
33+
"parametrize": "nums, expected",
34+
"parametrize_typed": "nums: list[int], expected: list[int]",
35+
"test_cases": "[([2, 0, 2, 1, 1, 0], [0, 0, 1, 1, 2, 2]), ([2, 0, 1], [0, 1, 2]), ([0], [0]), ([1], [1]), ([2], [2]), ([0, 1, 2], [0, 1, 2])]",
36+
"body": "nums_copy = nums.copy()\nself.solution.sort_colors(nums_copy)\nassert nums_copy == expected"
37+
}
38+
],
39+
"playground_imports": "from solution import Solution",
40+
"playground_test_case": "# Example test case\nnums = [2, 0, 2, 1, 1, 0]\nexpected = [0, 0, 1, 1, 2, 2]",
41+
"playground_execution": "nums_copy = nums.copy()\nSolution().sort_colors(nums_copy)\nnums_copy",
42+
"playground_assertion": "assert nums_copy == expected"
43+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{
2+
"problem_name": "time_based_key_value_store",
3+
"solution_class_name": "TimeMap",
4+
"problem_number": "981",
5+
"problem_title": "Time Based Key-Value Store",
6+
"difficulty": "Medium",
7+
"topics": "Hash Table, String, Binary Search, Design",
8+
"tags": ["grind-75"],
9+
"readme_description": "Design a time-based key-value data structure that can store multiple values for the same key at different time stamps and retrieve the key's value at a certain timestamp.\n\nImplement the `TimeMap` class:\n\n- `TimeMap()` Initializes the object of the data structure.\n- `void set(String key, String value, int timestamp)` Stores the key `key` with the value `value` at the given time `timestamp`.\n- `String get(String key, int timestamp)` Returns a value such that `set` was called previously, with `timestamp_prev <= timestamp`. If there are multiple such values, it returns the value associated with the largest `timestamp_prev`. If there are no values, it returns `\"\"`.",
10+
"readme_examples": [
11+
{
12+
"content": "```\nInput\n[\"TimeMap\", \"set\", \"get\", \"get\", \"set\", \"get\", \"get\"]\n[[], [\"foo\", \"bar\", 1], [\"foo\", 1], [\"foo\", 3], [\"foo\", \"bar2\", 4], [\"foo\", 4], [\"foo\", 5]]\nOutput\n[null, null, \"bar\", \"bar\", null, \"bar2\", \"bar2\"]\n```\n\n**Explanation:**\n```\nTimeMap timeMap = new TimeMap();\ntimeMap.set(\"foo\", \"bar\", 1); // store the key \"foo\" and value \"bar\" along with timestamp = 1.\ntimeMap.get(\"foo\", 1); // return \"bar\"\ntimeMap.get(\"foo\", 3); // return \"bar\", since there is no value corresponding to foo at timestamp 3 and timestamp 2, then the only value is at timestamp 1 is \"bar\".\ntimeMap.set(\"foo\", \"bar2\", 4); // store the key \"foo\" and value \"bar2\" along with timestamp = 4.\ntimeMap.get(\"foo\", 4); // return \"bar2\"\ntimeMap.get(\"foo\", 5); // return \"bar2\"\n```"
13+
}
14+
],
15+
"readme_constraints": "- `1 <= key.length, value.length <= 100`\n- `key` and `value` consist of lowercase English letters and digits.\n- `1 <= timestamp <= 10^7`\n- All the timestamps `timestamp` of `set` are strictly increasing.\n- At most `2 * 10^5` calls will be made to `set` and `get`.",
16+
"readme_additional": "",
17+
"solution_imports": "",
18+
"solution_methods": [
19+
{ "name": "__init__", "parameters": "", "return_type": "None", "dummy_return": "" },
20+
{
21+
"name": "set",
22+
"parameters": "key: str, value: str, timestamp: int",
23+
"return_type": "None",
24+
"dummy_return": ""
25+
},
26+
{
27+
"name": "get",
28+
"parameters": "key: str, timestamp: int",
29+
"return_type": "str",
30+
"dummy_return": "\"\""
31+
}
32+
],
33+
"test_imports": "import pytest\nfrom leetcode_py.test_utils import logged_test\nfrom .solution import TimeMap",
34+
"test_class_name": "TimeBasedKeyValueStore",
35+
"test_helper_methods": [],
36+
"test_methods": [
37+
{
38+
"name": "test_time_map_operations",
39+
"parametrize": "operations, inputs, expected",
40+
"parametrize_typed": "operations: list[str], inputs: list[list], expected: list",
41+
"test_cases": "[(['TimeMap', 'set', 'get', 'get', 'set', 'get', 'get'], [[], ['foo', 'bar', 1], ['foo', 1], ['foo', 3], ['foo', 'bar2', 4], ['foo', 4], ['foo', 5]], [None, None, 'bar', 'bar', None, 'bar2', 'bar2'])]",
42+
"body": "time_map: TimeMap | None = None\nresult: list[str | None] = []\nfor i, op in enumerate(operations):\n if op == 'TimeMap':\n time_map = TimeMap()\n result.append(None)\n elif op == 'set' and time_map is not None:\n time_map.set(*inputs[i])\n result.append(None)\n elif op == 'get' and time_map is not None:\n result.append(time_map.get(*inputs[i]))\nassert result == expected"
43+
}
44+
],
45+
"playground_imports": "from solution import TimeMap",
46+
"playground_test_case": "# Example test case\ntime_map = TimeMap()\ntime_map.set('foo', 'bar', 1)\nresult1 = time_map.get('foo', 1)\nresult2 = time_map.get('foo', 3)\ntime_map.set('foo', 'bar2', 4)\nresult3 = time_map.get('foo', 4)\nresult4 = time_map.get('foo', 5)",
47+
"playground_execution": "print(f'get(foo, 1): {result1}')\nprint(f'get(foo, 3): {result2}')\nprint(f'get(foo, 4): {result3}')\nprint(f'get(foo, 5): {result4}')",
48+
"playground_assertion": "assert result1 == 'bar'\nassert result2 == 'bar'\nassert result3 == 'bar2'\nassert result4 == 'bar2'"
49+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{
2+
"problem_name": "word_break",
3+
"solution_class_name": "Solution",
4+
"problem_number": "139",
5+
"problem_title": "Word Break",
6+
"difficulty": "Medium",
7+
"topics": "Array, Hash Table, String, Dynamic Programming, Trie, Memoization",
8+
"tags": ["grind-75"],
9+
"readme_description": "Given a string `s` and a dictionary of strings `wordDict`, return `true` if `s` can be segmented into a space-separated sequence of one or more dictionary words.\n\n**Note** that the same word in the dictionary may be reused multiple times in the segmentation.",
10+
"readme_examples": [
11+
{
12+
"content": "```\nInput: s = \"leetcode\", wordDict = [\"leet\",\"code\"]\nOutput: true\n```\n**Explanation:** Return true because \"leetcode\" can be segmented as \"leet code\"."
13+
},
14+
{
15+
"content": "```\nInput: s = \"applepenapple\", wordDict = [\"apple\",\"pen\"]\nOutput: true\n```\n**Explanation:** Return true because \"applepenapple\" can be segmented as \"apple pen apple\".\nNote that you are allowed to reuse a dictionary word."
16+
},
17+
{
18+
"content": "```\nInput: s = \"catsandog\", wordDict = [\"cats\",\"dog\",\"sand\",\"and\",\"cat\"]\nOutput: false\n```"
19+
}
20+
],
21+
"readme_constraints": "- `1 <= s.length <= 300`\n- `1 <= wordDict.length <= 1000`\n- `1 <= wordDict[i].length <= 20`\n- `s` and `wordDict[i]` consist of only lowercase English letters.\n- All the strings of `wordDict` are **unique**.",
22+
"readme_additional": "",
23+
"solution_imports": "",
24+
"solution_methods": [
25+
{
26+
"name": "word_break",
27+
"parameters": "s: str, word_dict: list[str]",
28+
"return_type": "bool",
29+
"dummy_return": "False"
30+
}
31+
],
32+
"test_imports": "import pytest\nfrom leetcode_py.test_utils import logged_test\nfrom .solution import Solution",
33+
"test_class_name": "WordBreak",
34+
"test_helper_methods": [
35+
{ "name": "setup_method", "parameters": "", "body": "self.solution = Solution()" }
36+
],
37+
"test_methods": [
38+
{
39+
"name": "test_word_break",
40+
"parametrize": "s, word_dict, expected",
41+
"parametrize_typed": "s: str, word_dict: list[str], expected: bool",
42+
"test_cases": "[('leetcode', ['leet', 'code'], True), ('applepenapple', ['apple', 'pen'], True), ('catsandog', ['cats', 'dog', 'sand', 'and', 'cat'], False), ('', [], True), ('a', ['a'], True), ('ab', ['a', 'b'], True), ('abcd', ['a', 'abc', 'd'], True)]",
43+
"body": "result = self.solution.word_break(s, word_dict)\nassert result == expected"
44+
}
45+
],
46+
"playground_imports": "from solution import Solution",
47+
"playground_test_case": "# Example test case\ns = 'leetcode'\nword_dict = ['leet', 'code']\nexpected = True",
48+
"playground_execution": "result = Solution().word_break(s, word_dict)\nresult",
49+
"playground_assertion": "assert result == expected"
50+
}

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 ?= permutations
2+
PROBLEM ?= word_break
33
FORCE ?= 0
44
COMMA := ,
55

leetcode/combination_sum/tests.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ def setup_method(self):
2424
[
2525
[2, 2, 2, 2, 2, 2, 2, 2, 2],
2626
[2, 2, 2, 2, 2, 2, 3, 3],
27+
[2, 2, 2, 2, 3, 7],
2728
[2, 2, 2, 3, 3, 3, 3],
2829
[2, 2, 7, 7],
2930
[2, 3, 3, 3, 7],

leetcode/sort_colors/README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Sort Colors
2+
3+
**Difficulty:** Medium
4+
**Topics:** Array, Two Pointers, Sorting
5+
**Tags:** grind-75
6+
7+
**LeetCode:** [Problem 75](https://leetcode.com/problems/sort-colors/description/)
8+
9+
## Problem Description
10+
11+
Given an array `nums` with `n` objects colored red, white, or blue, sort them **in-place** so that objects of the same color are adjacent, with the colors in the order red, white, and blue.
12+
13+
We will use the integers `0`, `1`, and `2` to represent the color red, white, and blue, respectively.
14+
15+
You must solve this problem without using the library's sort function.
16+
17+
## Examples
18+
19+
### Example 1:
20+
21+
```
22+
Input: nums = [2,0,2,1,1,0]
23+
Output: [0,0,1,1,2,2]
24+
```
25+
26+
### Example 2:
27+
28+
```
29+
Input: nums = [2,0,1]
30+
Output: [0,1,2]
31+
```
32+
33+
## Constraints
34+
35+
- `n == nums.length`
36+
- `1 <= n <= 300`
37+
- `nums[i]` is either `0`, `1`, or `2`.
38+
39+
**Follow up:** Could you come up with a one-pass algorithm using only constant extra space?

leetcode/sort_colors/__init__.py

Whitespace-only changes.
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": 1,
6+
"id": "imports",
7+
"metadata": {},
8+
"outputs": [],
9+
"source": [
10+
"from solution import Solution"
11+
]
12+
},
13+
{
14+
"cell_type": "code",
15+
"execution_count": 2,
16+
"id": "setup",
17+
"metadata": {},
18+
"outputs": [],
19+
"source": [
20+
"# Example test case\n",
21+
"nums = [2, 0, 2, 1, 1, 0]\n",
22+
"expected = [0, 0, 1, 1, 2, 2]"
23+
]
24+
},
25+
{
26+
"cell_type": "code",
27+
"execution_count": 3,
28+
"id": "execute",
29+
"metadata": {},
30+
"outputs": [
31+
{
32+
"data": {
33+
"text/plain": [
34+
"[0, 0, 1, 1, 2, 2]"
35+
]
36+
},
37+
"execution_count": 3,
38+
"metadata": {},
39+
"output_type": "execute_result"
40+
}
41+
],
42+
"source": [
43+
"nums_copy = nums.copy()\n",
44+
"Solution().sort_colors(nums_copy)\n",
45+
"nums_copy"
46+
]
47+
},
48+
{
49+
"cell_type": "code",
50+
"execution_count": 4,
51+
"id": "test",
52+
"metadata": {},
53+
"outputs": [],
54+
"source": [
55+
"assert nums_copy == expected"
56+
]
57+
}
58+
],
59+
"metadata": {
60+
"kernelspec": {
61+
"display_name": "leetcode-py-py3.13",
62+
"language": "python",
63+
"name": "python3"
64+
},
65+
"language_info": {
66+
"codemirror_mode": {
67+
"name": "ipython",
68+
"version": 3
69+
},
70+
"file_extension": ".py",
71+
"mimetype": "text/x-python",
72+
"name": "python",
73+
"nbconvert_exporter": "python",
74+
"pygments_lexer": "ipython3",
75+
"version": "3.13.7"
76+
}
77+
},
78+
"nbformat": 4,
79+
"nbformat_minor": 5
80+
}

leetcode/sort_colors/solution.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
class Solution:
2+
# Dutch National Flag Algorithm - partitions array into 3 regions using 2 pointers
3+
# Creates: [0s][1s][2s] with left/right boundaries, mid processes unvisited elements
4+
# Time: O(n)
5+
# Space: O(1)
6+
def sort_colors(self, nums: list[int]) -> None:
7+
left = mid = 0
8+
right = len(nums) - 1
9+
10+
while mid <= right:
11+
if nums[mid] == 0:
12+
nums[left], nums[mid] = nums[mid], nums[left]
13+
left += 1
14+
mid += 1
15+
elif nums[mid] == 1:
16+
mid += 1
17+
else:
18+
nums[mid], nums[right] = nums[right], nums[mid]
19+
right -= 1

leetcode/sort_colors/tests.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import pytest
2+
3+
from leetcode_py.test_utils import logged_test
4+
5+
from .solution import Solution
6+
7+
8+
class TestSortColors:
9+
def setup_method(self):
10+
self.solution = Solution()
11+
12+
@pytest.mark.parametrize(
13+
"nums, expected",
14+
[
15+
([2, 0, 2, 1, 1, 0], [0, 0, 1, 1, 2, 2]),
16+
([2, 0, 1], [0, 1, 2]),
17+
([0], [0]),
18+
([1], [1]),
19+
([2], [2]),
20+
([0, 1, 2], [0, 1, 2]),
21+
],
22+
)
23+
@logged_test
24+
def test_sort_colors(self, nums: list[int], expected: list[int]):
25+
nums_copy = nums.copy()
26+
self.solution.sort_colors(nums_copy)
27+
assert nums_copy == expected

0 commit comments

Comments
 (0)