Skip to content

Commit 0ed0402

Browse files
committed
feat: add Merge Two Sorted Lists
1 parent 8f83609 commit 0ed0402

File tree

7 files changed

+226
-1
lines changed

7 files changed

+226
-1
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{
2+
"problem_name": "merge_two_sorted_lists",
3+
"solution_class_name": "Solution",
4+
"problem_number": "21",
5+
"problem_title": "Merge Two Sorted Lists",
6+
"difficulty": "Easy",
7+
"topics": "Linked List, Recursion",
8+
"tags": ["grind-75"],
9+
"readme_description": "You are given the heads of two sorted linked lists `list1` and `list2`.\n\nMerge the two lists into one **sorted** list. The list should be made by splicing together the nodes of the first two lists.\n\nReturn *the head of the merged linked list*.",
10+
"readme_examples": [
11+
{
12+
"content": "![Example 1](https://assets.leetcode.com/uploads/2020/10/03/merge_ex1.jpg)\n\n```\nInput: list1 = [1,2,4], list2 = [1,3,4]\nOutput: [1,1,2,3,4,4]\n```"
13+
},
14+
{ "content": "```\nInput: list1 = [], list2 = []\nOutput: []\n```" },
15+
{ "content": "```\nInput: list1 = [], list2 = [0]\nOutput: [0]\n```" }
16+
],
17+
"readme_constraints": "- The number of nodes in both lists is in the range `[0, 50]`.\n- `-100 <= Node.val <= 100`\n- Both `list1` and `list2` are sorted in **non-decreasing** order.",
18+
"readme_additional": "",
19+
"solution_imports": "from leetcode_py import ListNode",
20+
"solution_methods": [
21+
{
22+
"name": "merge_two_lists",
23+
"parameters": "list1: ListNode | None, list2: ListNode | None",
24+
"return_type": "ListNode | None",
25+
"dummy_return": "None"
26+
}
27+
],
28+
"test_imports": "import pytest\nfrom leetcode_py.test_utils import logged_test\nfrom leetcode_py import ListNode\nfrom .solution import Solution",
29+
"test_class_name": "MergeTwoSortedLists",
30+
"test_helper_methods": [
31+
{ "name": "setup_method", "parameters": "", "body": "self.solution = Solution()" }
32+
],
33+
"test_methods": [
34+
{
35+
"name": "test_merge_two_lists",
36+
"parametrize": "list1_vals, list2_vals, expected_vals",
37+
"parametrize_typed": "list1_vals: list[int], list2_vals: list[int], expected_vals: list[int]",
38+
"test_cases": "[([1, 2, 4], [1, 3, 4], [1, 1, 2, 3, 4, 4]), ([], [], []), ([], [0], [0]), ([1], [2], [1, 2]), ([2], [1], [1, 2])]",
39+
"body": "list1 = ListNode.from_list(list1_vals)\nlist2 = ListNode.from_list(list2_vals)\nexpected = ListNode.from_list(expected_vals)\nresult = self.solution.merge_two_lists(list1, list2)\nassert result == expected"
40+
}
41+
],
42+
"playground_imports": "from solution import Solution\nfrom leetcode_py import ListNode",
43+
"playground_test_case": "# Example test case\nlist1_vals = [1, 2, 4]\nlist2_vals = [1, 3, 4]\nexpected_vals = [1, 1, 2, 3, 4, 4]",
44+
"playground_execution": "list1 = ListNode.from_list(list1_vals)\nlist2 = ListNode.from_list(list2_vals)\nresult = Solution().merge_two_lists(list1, list2)\nresult",
45+
"playground_assertion": "expected = ListNode.from_list(expected_vals)\nassert result == expected"
46+
}

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

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Merge Two Sorted Lists
2+
3+
**Difficulty:** Easy
4+
**Topics:** Linked List, Recursion
5+
**Tags:** grind-75
6+
7+
**LeetCode:** [Problem 21](https://leetcode.com/problems/merge-two-sorted-lists/description/)
8+
9+
## Problem Description
10+
11+
You are given the heads of two sorted linked lists `list1` and `list2`.
12+
13+
Merge the two lists into one **sorted** list. The list should be made by splicing together the nodes of the first two lists.
14+
15+
Return _the head of the merged linked list_.
16+
17+
## Examples
18+
19+
### Example 1:
20+
21+
![Example 1](https://assets.leetcode.com/uploads/2020/10/03/merge_ex1.jpg)
22+
23+
```
24+
Input: list1 = [1,2,4], list2 = [1,3,4]
25+
Output: [1,1,2,3,4,4]
26+
```
27+
28+
### Example 2:
29+
30+
```
31+
Input: list1 = [], list2 = []
32+
Output: []
33+
```
34+
35+
### Example 3:
36+
37+
```
38+
Input: list1 = [], list2 = [0]
39+
Output: [0]
40+
```
41+
42+
## Constraints
43+
44+
- The number of nodes in both lists is in the range `[0, 50]`.
45+
- `-100 <= Node.val <= 100`
46+
- Both `list1` and `list2` are sorted in **non-decreasing** order.

leetcode/merge_two_sorted_lists/__init__.py

Whitespace-only changes.
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"id": "imports",
7+
"metadata": {},
8+
"outputs": [],
9+
"source": [
10+
"from solution import Solution\n",
11+
"\n",
12+
"from leetcode_py import ListNode"
13+
]
14+
},
15+
{
16+
"cell_type": "code",
17+
"execution_count": null,
18+
"id": "setup",
19+
"metadata": {},
20+
"outputs": [],
21+
"source": [
22+
"# Example test case\n",
23+
"list1_vals = [1, 2, 4]\n",
24+
"list2_vals = [1, 3, 4]\n",
25+
"expected_vals = [1, 1, 2, 3, 4, 4]"
26+
]
27+
},
28+
{
29+
"cell_type": "code",
30+
"execution_count": null,
31+
"id": "execute",
32+
"metadata": {},
33+
"outputs": [],
34+
"source": [
35+
"list1 = ListNode.from_list(list1_vals)\n",
36+
"list2 = ListNode.from_list(list2_vals)\n",
37+
"result = Solution().merge_two_lists(list1, list2)\n",
38+
"result"
39+
]
40+
},
41+
{
42+
"cell_type": "code",
43+
"execution_count": null,
44+
"id": "test",
45+
"metadata": {},
46+
"outputs": [],
47+
"source": [
48+
"expected = ListNode.from_list(expected_vals)\n",
49+
"assert result == expected"
50+
]
51+
}
52+
],
53+
"metadata": {
54+
"kernelspec": {
55+
"display_name": "leetcode-py-py3.13",
56+
"language": "python",
57+
"name": "python3"
58+
},
59+
"language_info": {
60+
"codemirror_mode": {
61+
"name": "ipython",
62+
"version": 3
63+
},
64+
"file_extension": ".py",
65+
"mimetype": "text/x-python",
66+
"name": "python",
67+
"nbconvert_exporter": "python3",
68+
"pygments_lexer": "ipython3",
69+
"version": "3.13.7"
70+
}
71+
},
72+
"nbformat": 4,
73+
"nbformat_minor": 5
74+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from leetcode_py import ListNode
2+
3+
4+
class Solution:
5+
# Time: O(m + n)
6+
# Space: O(1)
7+
def merge_two_lists(self, list1: ListNode | None, list2: ListNode | None) -> ListNode | None:
8+
9+
dummy = ListNode(0)
10+
current = dummy
11+
12+
while list1 and list2:
13+
if list1.val <= list2.val:
14+
current.next = list1
15+
list1 = list1.next
16+
else:
17+
current.next = list2
18+
list2 = list2.next
19+
current = current.next
20+
21+
current.next = list1 or list2
22+
return dummy.next
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import pytest
2+
3+
from leetcode_py import ListNode
4+
from leetcode_py.test_utils import logged_test
5+
6+
from .solution import Solution
7+
8+
9+
class TestMergeTwoSortedLists:
10+
def setup_method(self):
11+
self.solution = Solution()
12+
13+
@pytest.mark.parametrize(
14+
"list1_vals, list2_vals, expected_vals",
15+
[
16+
([1, 2, 4], [1, 3, 4], [1, 1, 2, 3, 4, 4]),
17+
([], [], []),
18+
([], [0], [0]),
19+
([0], [], [0]),
20+
([1], [2], [1, 2]),
21+
([2], [1], [1, 2]),
22+
([1, 1, 1], [2, 2, 2], [1, 1, 1, 2, 2, 2]),
23+
([1, 3, 5], [2, 4, 6], [1, 2, 3, 4, 5, 6]),
24+
([-10, -5, 0], [-8, -3, 1], [-10, -8, -5, -3, 0, 1]),
25+
([5], [1, 2, 3, 4], [1, 2, 3, 4, 5]),
26+
([1, 2, 3, 4], [5], [1, 2, 3, 4, 5]),
27+
],
28+
)
29+
@logged_test
30+
def test_merge_two_lists(
31+
self, list1_vals: list[int], list2_vals: list[int], expected_vals: list[int]
32+
):
33+
list1 = ListNode.from_list(list1_vals)
34+
list2 = ListNode.from_list(list2_vals)
35+
expected = ListNode.from_list(expected_vals)
36+
result = self.solution.merge_two_lists(list1, list2)
37+
assert result == expected

0 commit comments

Comments
 (0)