Skip to content

Commit e4e4733

Browse files
committed
add ten easy problems
1 parent 9249b4a commit e4e4733

File tree

9 files changed

+189
-19
lines changed

9 files changed

+189
-19
lines changed

.github/workflows/publish.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
name: Publish Python 🐍 distribution 📦 to PyPI and TestPyPI
22

3-
on: push
3+
on:
4+
push:
5+
branches:
6+
- main
47

58
jobs:
69
build:
@@ -30,7 +33,7 @@ jobs:
3033
publish-to-pypi:
3134
name: >-
3235
Publish Python 🐍 distribution 📦 to PyPI
33-
if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes
36+
# if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes
3437
needs:
3538
- build
3639
runs-on: ubuntu-latest

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
"tests"
44
],
55
"python.testing.unittestEnabled": false,
6-
"python.testing.pytestEnabled": true
6+
"python.testing.pytestEnabled": true,
7+
"python.analysis.typeCheckingMode": "strict"
78
}

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "leetcodepy"
3-
version = "0.0.1"
3+
version = "0.0.2"
44
authors = [{ name = "tarolling", email = "benitojoens@gmail.com" }]
55
description = "Implementations of LeetCode problem solutions in Python"
66
readme = "README.md"

src/leetcodepy/__init__.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +0,0 @@
1-
class ListNode:
2-
def __init__(self, val=0, next=None):
3-
self.val = val
4-
self.next = next

src/leetcodepy/easy.py

Lines changed: 101 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
from typing import Optional
2+
from .utils import ListNode
3+
4+
15
def two_sum(nums: list[int], target: int) -> list[int]:
26
"""Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.
37
@@ -33,16 +37,107 @@ def two_sum(nums: list[int], target: int) -> list[int]:
3337
Only one valid answer exists.
3438
3539
"""
36-
# Constraints
37-
assert 2 <= len(nums) <= 10**4
38-
assert all(map(lambda x: -(10**9) <= x <= 10**9, nums))
39-
assert -(10**9) <= target <= 10**9
40-
41-
# Implementation
4240
hashmap = {}
4341
for i in range(len(nums)):
4442
complement = target - nums[i]
4543
if complement in hashmap:
4644
return [i, hashmap[complement]]
4745
hashmap[nums[i]] = i
4846
return []
47+
48+
49+
def palindrome_number(x: int) -> bool:
50+
if x < 0:
51+
return False
52+
x_str = str(x)
53+
return x_str == x_str[::-1]
54+
55+
56+
def roman_to_integer(s: str) -> int:
57+
translations = {"I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000}
58+
number = 0
59+
s = s.replace("IV", "IIII").replace("IX", "VIIII")
60+
s = s.replace("XL", "XXXX").replace("XC", "LXXXX")
61+
s = s.replace("CD", "CCCC").replace("CM", "DCCCC")
62+
for char in s:
63+
number += translations[char]
64+
return number
65+
66+
67+
def longest_common_prefix(strs: list[str]) -> str:
68+
ans = ""
69+
v = sorted(strs)
70+
first = v[0]
71+
last = v[-1]
72+
for i in range(min(len(first), len(last))):
73+
if first[i] != last[i]:
74+
return ans
75+
ans += first[i]
76+
return ans
77+
78+
79+
def valid_parentheses(s: str) -> bool:
80+
d = {"(": ")", "{": "}", "[": "]"}
81+
stack: list[str] = []
82+
for i in s:
83+
if i in d:
84+
stack.append(i)
85+
elif len(stack) == 0 or d[stack.pop()] != i:
86+
return False
87+
return len(stack) == 0
88+
89+
90+
def merge_two_sorted_lists(
91+
list1: Optional[ListNode], list2: Optional[ListNode]
92+
) -> Optional[ListNode]:
93+
if not list1 or not list2:
94+
return list1 or list2
95+
if list1.val <= list2.val:
96+
list1.next = merge_two_sorted_lists(list1.next, list2)
97+
return list1
98+
else:
99+
list2.next = merge_two_sorted_lists(list1, list2.next)
100+
return list2
101+
102+
103+
def remove_duplicates_from_sorted_array(nums: list[int]) -> int:
104+
j = 1
105+
for i in range(1, len(nums)):
106+
if nums[i] != nums[i - 1]:
107+
nums[j] = nums[i]
108+
j += 1
109+
return j
110+
111+
112+
def remove_element(nums: list[int], val: int) -> int:
113+
j = 0
114+
for i in range(len(nums)):
115+
if nums[i] != val:
116+
nums[j] = nums[i]
117+
j += 1
118+
return j
119+
120+
121+
def find_the_index_of_the_first_occurrence_in_a_string(
122+
haystack: str, needle: str
123+
) -> int:
124+
if len(haystack) < len(needle):
125+
return -1
126+
for i in range(len(haystack)):
127+
if haystack[i : i + len(needle)] == needle:
128+
return i
129+
return -1
130+
131+
132+
def search_insert_position(nums: list[int], target: int) -> int:
133+
left = 0
134+
right = len(nums) - 1
135+
while left <= right:
136+
mid = (left + right) // 2
137+
if nums[mid] == target:
138+
return mid
139+
elif nums[mid] > target:
140+
right = mid - 1
141+
else:
142+
left = mid + 1
143+
return left

src/leetcodepy/medium.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import re
22

3-
from . import ListNode
3+
from .utils import ListNode
44

55

66
def add_two_numbers(l1: ListNode | None, l2: ListNode | None) -> ListNode | None:
@@ -87,7 +87,7 @@ def longest_substring_without_repeating_characters(s: str) -> int:
8787
assert 0 <= len(s) <= 5 * 10**4
8888

8989
max_length = left = 0
90-
count = {}
90+
count: dict[str, int] = {}
9191

9292
for right, c in enumerate(s):
9393
count[c] = 1 + count.get(c, 0)

src/leetcodepy/utils.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class ListNode:
2+
def __init__(self, val: int = 0, next: "ListNode | None" = None):
3+
self.val = val
4+
self.next = next
5+
6+
def __eq__(self, value: object) -> bool:
7+
if not isinstance(value, ListNode):
8+
return False
9+
return self.val == value.val and self.next == value.next

tests/test_easy.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,69 @@ def test_two_sum():
2323
assert set(two_sum([2, 7, 11, 15], 9)) == set([0, 1])
2424
assert set(two_sum([3, 2, 4], 6)) == set([1, 2])
2525
assert set(two_sum([3, 3], 6)) == set([0, 1])
26+
27+
28+
def test_palindrome_number():
29+
assert palindrome_number(121)
30+
assert not palindrome_number(-121)
31+
assert not palindrome_number(10)
32+
33+
34+
def test_roman_to_integer():
35+
assert roman_to_integer("III") == 3
36+
assert roman_to_integer("LVIII") == 58
37+
assert roman_to_integer("MCMXCIV") == 1994
38+
39+
40+
def test_longest_common_prefix():
41+
assert longest_common_prefix(["flower", "flow", "flight"]) == "fl"
42+
assert longest_common_prefix(["dog", "racecar", "car"]) == ""
43+
44+
45+
def test_valid_parentheses():
46+
assert valid_parentheses("()")
47+
assert valid_parentheses("()[]{}")
48+
assert not valid_parentheses("(]")
49+
assert valid_parentheses("([])")
50+
51+
52+
def test_merge_two_sorted_lists():
53+
list1 = ListNode(1, ListNode(2, ListNode(4)))
54+
list2 = ListNode(1, ListNode(3, ListNode(4)))
55+
assert merge_two_sorted_lists(list1, list2) == ListNode(
56+
1, ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(4)))))
57+
)
58+
59+
assert merge_two_sorted_lists(None, None) == None
60+
assert merge_two_sorted_lists(None, ListNode(0)) == ListNode(0)
61+
62+
63+
def test_remove_duplicates_from_sorted_array():
64+
nums = [1, 1, 2]
65+
assert remove_duplicates_from_sorted_array(nums) == 2
66+
assert nums[:2] == [1, 2]
67+
68+
nums = [0, 0, 1, 1, 1, 2, 2, 3, 3, 4]
69+
assert remove_duplicates_from_sorted_array(nums) == 5
70+
assert nums[:5] == [0, 1, 2, 3, 4]
71+
72+
73+
def test_remove_element():
74+
nums = [3, 2, 2, 3]
75+
assert remove_element(nums, 3) == 2
76+
assert set(nums[:2]) == set([2, 2])
77+
78+
nums = [0, 1, 2, 2, 3, 0, 4, 2]
79+
assert remove_element(nums, 2) == 5
80+
assert set(nums[:5]) == set([0, 1, 4, 0, 3])
81+
82+
83+
def test_find_the_index_of_the_first_occurrence_in_a_string():
84+
assert find_the_index_of_the_first_occurrence_in_a_string("sadbutsad", "sad") == 0
85+
assert find_the_index_of_the_first_occurrence_in_a_string("leetcode", "leeto") == -1
86+
87+
88+
def test_search_insert_position():
89+
assert search_insert_position([1, 3, 5, 6], 5) == 2
90+
assert search_insert_position([1, 3, 5, 6], 2) == 1
91+
assert search_insert_position([1, 3, 5, 6], 7) == 4

tests/test_medium.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
from src.leetcodepy.medium import *
2-
from src.leetcodepy import ListNode
2+
from src.leetcodepy.utils import ListNode
33

44

55
def test_add_two_numbers():
6-
def list_node_to_list(l: ListNode) -> list:
7-
result = []
6+
def list_node_to_list(l: ListNode) -> list[int]:
7+
result: list[int] = []
88
current_node = l
99
while current_node.next is not None:
1010
result.append(current_node.val)

0 commit comments

Comments
 (0)