Skip to content
Open
Show file tree
Hide file tree
Changes from 70 commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
f911604
feat(vertex): add adjacent vertex
BrianLusina Dec 5, 2023
dbe61b5
Merge branch 'main' into feat/graphs
BrianLusina Oct 24, 2025
53aa2f4
refactor(datastructures, graphs): refactor edge implementation
BrianLusina Oct 24, 2025
69d657a
updating DIRECTORY.md
Oct 24, 2025
502928b
feat(puzzles, datastructures): find closest value in bst
BrianLusina Oct 28, 2025
44c442d
updating DIRECTORY.md
Oct 28, 2025
ac33051
refactor(datastructures, binary-search-tree, puzzles): remove the use…
BrianLusina Oct 29, 2025
badaa22
feat(algorithms, sliding-window): repeated dna sequences
BrianLusina Nov 5, 2025
b934a2d
updating DIRECTORY.md
Nov 5, 2025
50547f3
chore(algorithms, sliding-window, find-repeated-dna-sequences: minor …
BrianLusina Nov 5, 2025
1e5f6da
chore: add validation for dna sequences
BrianLusina Nov 5, 2025
8e19362
feat(strings, anagrams): group anagrams
BrianLusina Nov 10, 2025
60234c8
updating DIRECTORY.md
Nov 10, 2025
7b997b0
test: add parameterized tests
BrianLusina Nov 10, 2025
46edc29
refactor(datastructures, trees): add return type
BrianLusina Nov 10, 2025
736d8f3
feat(arrays, matrices): set matrix to zero
BrianLusina Nov 11, 2025
16b6e36
updating DIRECTORY.md
Nov 11, 2025
232c1ac
chore(arrays, matrices: documentation fixes
BrianLusina Nov 11, 2025
4d8302b
feat(arrays, subarrays): count subarrays with fixed bounds
BrianLusina Nov 12, 2025
e8a7919
updating DIRECTORY.md
Nov 12, 2025
bd2fd35
refactor(arrays, subarrays): add doctests and edge cae
BrianLusina Nov 12, 2025
7543aca
refactor(algorithms, graphs, course-schedule): additional alternative…
BrianLusina Nov 13, 2025
34dda31
updating DIRECTORY.md
Nov 13, 2025
a5811b8
ci(github): update pre-commit workflow versions
BrianLusina Nov 13, 2025
95f2f54
docs(readme): add codacy badge
BrianLusina Nov 13, 2025
0c8fe96
chore(lint): format fixes
BrianLusina Nov 13, 2025
e59bb5f
chore(lint): minor format fixes
BrianLusina Nov 13, 2025
acb0d35
feat(datastructures, bst): construct min height bst
BrianLusina Nov 13, 2025
bbb1880
feat(datastructures, binary-tree): zig zag level order traversal
BrianLusina Nov 14, 2025
ec4c328
refactor(binary-trees, zig-zag-level-order): add else condition
BrianLusina Nov 15, 2025
b0464e6
feat(strings, datastructures): similar string groups with disjoint se…
BrianLusina Nov 15, 2025
68432de
updating DIRECTORY.md
Nov 15, 2025
4a09528
refactor(datastructures, union-find): add type hints and doc comments
BrianLusina Nov 16, 2025
689437f
refactor(strings, similar string groups): is similar string function
BrianLusina Nov 16, 2025
2a95ed1
refactor(strings, similar-string-groups): add length check
BrianLusina Nov 16, 2025
b1e465e
feat(strings, self-contained-substring): longest self contained subst…
BrianLusina Nov 16, 2025
6266c10
updating DIRECTORY.md
Nov 16, 2025
aad41ed
refactor(strings, longest_self_contained_substring): add type hints
BrianLusina Nov 16, 2025
daee2ef
test(strings, longest_self_contained_substring): doc tests
BrianLusina Nov 16, 2025
e635cfe
feat(heaps, maximal-score): maximal score after k operations
BrianLusina Nov 17, 2025
0c0965c
updating DIRECTORY.md
Nov 17, 2025
f6e12d6
doc(readme, max-score-after-k-ops): minor doc update
BrianLusina Nov 17, 2025
7e92ec7
feat(data-structures, trie, stream-checker): adds a stream checker data
BrianLusina Nov 19, 2025
d8f758a
updating DIRECTORY.md
Nov 19, 2025
b7f1b76
feat(strings, trie): is prefix of word
BrianLusina Nov 21, 2025
d24f593
chore: remove redundant test
BrianLusina Nov 21, 2025
426ac00
refactor(trie): fix none check
BrianLusina Nov 22, 2025
0222ac7
updating DIRECTORY.md
Nov 21, 2025
2d9ffa0
feat(algorithms, arrays, binary search): two sum less than k
BrianLusina Nov 22, 2025
688c6bd
updating DIRECTORY.md
Nov 22, 2025
9d6cd6d
docs: remove missing example
BrianLusina Nov 23, 2025
af2d1f3
feat(algorithms, binary-search): max runtime for n computers
BrianLusina Nov 23, 2025
3788d94
updating DIRECTORY.md
Nov 23, 2025
2246a92
feat(datastructures, binary tree): lowest common ancestor
BrianLusina Nov 24, 2025
c0919e4
updating DIRECTORY.md
Nov 24, 2025
0fe2997
feat(datastructures, binary tree): lowest common ancestor
BrianLusina Nov 24, 2025
58f5e42
chore(lint): format files
BrianLusina Nov 24, 2025
07c7752
chore(lint): format files
BrianLusina Nov 24, 2025
512075b
feat(trees): longest common suffix queries
BrianLusina Nov 26, 2025
9a24ee7
updating DIRECTORY.md
Nov 26, 2025
49d4166
refactor(strings, anagram): is anagram improvements
BrianLusina Nov 26, 2025
077817c
feat(trees): find kth largest in binary search tree
BrianLusina Nov 26, 2025
1ed25b4
feat(data structures, heaps): min cost to connect sticks
BrianLusina Nov 27, 2025
330873c
refactor(datastructures, linkedlist): cleans up reverse_between method
BrianLusina Nov 28, 2025
e3838ff
feat(data structures, linked list): additional algorithm to reverse_b…
BrianLusina Nov 28, 2025
85adea4
updating DIRECTORY.md
Nov 28, 2025
2c8b4c1
reafactor(data structure, linked list): add negative values validation
BrianLusina Nov 28, 2025
46f9f29
feat(data structures, binary trees): min camera cover
BrianLusina Nov 29, 2025
678e2fd
feat(data structures, graphs): frog position after t seconds
BrianLusina Nov 30, 2025
d851df5
updating DIRECTORY.md
Dec 1, 2025
b50ebc0
feat(graphs, bfs): closest node in tree along path
BrianLusina Dec 1, 2025
9dbfe8c
updating DIRECTORY.md
Dec 1, 2025
b04dc64
Merge branch 'main' into feat/graphs
BrianLusina Dec 1, 2025
0730fe9
chore(lint): fix linting issues
BrianLusina Dec 1, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 2 additions & 2 deletions .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/cache@v2
- uses: actions/checkout@v5
- uses: actions/cache@v4
Comment on lines +9 to +10
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n .github/workflows/pre-commit.yml | head -30

Repository: BrianLusina/PythonSnips

Length of output: 852


🌐 Web query:

actions/setup-python latest version GitHub Actions

💡 Result:

The latest release is actions/setup-python v6.1.0 — published Nov 25, 2025. [1][2]

Sources:
[1] actions/setup-python Releases (GitHub).
[2] actions/setup-python README / Marketplace page (GitHub).


🌐 Web query:

psf/black latest version GitHub Actions

💡 Result:

Use the official action at psf/black@stable to track the latest released Black from PyPI; or pin to a specific release like psf/black@24.4.0 to lock the version. [1][2]

Sources:

  • psf/black releases (example: 24.4.0). [1]
  • Usage: psf/black@stable (official GitHub Action / docs/examples). [2]

Update remaining outdated actions for consistency.

The checkout@v5 and cache@v4 upgrades are good, but also update:

  • actions/setup-python@v2 → current latest is v6.1.0
  • psf/black@21.4b0 → use psf/black@stable or pin to a recent version like psf/black@24.4.0
🤖 Prompt for AI Agents
.github/workflows/pre-commit.yml around lines 9 to 10: the workflow updates
checkout and cache actions but leaves older pins for setup-python and psf/black;
change uses: actions/setup-python@v2 to actions/setup-python@v6 or
actions/setup-python@v6.1.0 (or the latest v6.x tag) and change uses:
psf/black@21.4b0 to either psf/black@stable or pin to a recent release such as
psf/black@24.4.0 so all actions are consistent and up-to-date.

with:
path: |
~/.cache/pre-commit
Expand Down
58 changes: 57 additions & 1 deletion DIRECTORY.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## Python Snippets

[![Build Status](https://travis-ci.org/BrianLusina/Python_Snippets.svg?branch=master)](https://travis-ci.org/BrianLusina/Python_Snippets)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/11cfc8e125c54bdb833fe19ed9ddad72)](https://app.codacy.com/gh/BrianLusina/Python_Snippets/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)

Repository for some of my simple [Python](https://www.python.org/ "Python") functions and snippets. Each directory
and/or python package has a readme for more information about the Python program
Expand Down
9 changes: 7 additions & 2 deletions algorithms/arrays/intersection/intersection_two.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
T = TypeVar("T")


def intersect(list_one: List[T], list_two: List[T], include_duplicates: bool = True) -> List[T]:
def intersect(
list_one: List[T], list_two: List[T], include_duplicates: bool = True
) -> List[T]:
"""
Given two arrays, find their intersection. This assumes that the lists are not sorted. First sorting takes place
on both lists which will incur a cost of O(nlog(n)) + O(mlog(m)) depending on the algorithm used. Time will also
Expand Down Expand Up @@ -35,7 +37,10 @@ def intersect(list_one: List[T], list_two: List[T], include_duplicates: bool = T
if include_duplicates:
result.append(first_element)
else:
if pointer_one == 0 or first_element != sorted_list_one[pointer_one - 1]:
if (
pointer_one == 0
or first_element != sorted_list_one[pointer_one - 1]
):
result.append(first_element)
pointer_one += 1
pointer_two += 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,12 @@ def test_13(self):
self.assertEqual(actual, expected)

def test_input_not_mutated(self):
"""should not mutate the input coins list"""
coins = [5, 7, 1, 1, 2, 3, 22]
snapshot = coins[:]
_ = non_constructible_change(coins)
self.assertEqual(coins, snapshot)
"""should not mutate the input coins list"""
coins = [5, 7, 1, 1, 2, 3, 22]
snapshot = coins[:]
_ = non_constructible_change(coins)
self.assertEqual(coins, snapshot)


if __name__ == '__main__':
if __name__ == "__main__":
unittest.main()
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ def test_1(self):
self.assertEqual(expected, actual)


if __name__ == '__main__':
if __name__ == "__main__":
unittest.main()
4 changes: 2 additions & 2 deletions algorithms/arrays/sorted_squared_array/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def sorted_squared_array(array: List[int]) -> List[int]:
left, right = 0, n - 1

# file result array from right to left (largest to smallest squares
for i in range(n-1, -1, -1):
for i in range(n - 1, -1, -1):
left_abs = abs(array[left])
right_abs = abs(array[right])

Expand Down Expand Up @@ -56,7 +56,7 @@ def sorted_squared_array_2(array: List[int]) -> List[int]:
left, right = 0, n - 1

# file result array from right to left (largest to smallest squares
for i in range(n-1, -1, -1):
for i in range(n - 1, -1, -1):
left_square = array[left] ** 2
right_square = array[right] ** 2

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ def test_2(self):

def test_3(self):
"""for an input of [-7,-3,2,3,11] it should return [4,9,9,49,121]"""
input_array = [-7,-3,2,3,11]
expected = [4,9,9,49,121]
input_array = [-7, -3, 2, 3, 11]
expected = [4, 9, 9, 49, 121]
actual = sorted_squared_array(input_array)
self.assertEqual(expected, actual)

Expand All @@ -42,11 +42,11 @@ def test_2(self):

def test_3(self):
"""for an input of [-7,-3,2,3,11] it should return [4,9,9,49,121]"""
input_array = [-7,-3,2,3,11]
expected = [4,9,9,49,121]
input_array = [-7, -3, 2, 3, 11]
expected = [4, 9, 9, 49, 121]
actual = sorted_squared_array_2(input_array)
self.assertEqual(expected, actual)


if __name__ == '__main__':
if __name__ == "__main__":
unittest.main()
1 change: 1 addition & 0 deletions algorithms/arrays/subsequence/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def is_valid_subsequence(array: List[int], sequence: List[int]) -> bool:

return False


def is_valid_subsequence_v2(array: List[int], sequence: List[int]) -> bool:
"""
Returns true if a sequence is a subsequence of the provided array
Expand Down
27 changes: 14 additions & 13 deletions algorithms/arrays/subsequence/test_is_valid_subsequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,33 @@ def test_1(self):

def test_2(self):
"""should return True for array = [5, 1, 22, 25, 6, -1, 8, 10], sequence = [5, 1, 22, 6, -1, 8, 10]"""
array = [5, 1, 22, 25, 6, -1, 8, 10]
array = [5, 1, 22, 25, 6, -1, 8, 10]
sequence = [5, 1, 22, 6, -1, 8, 10]
actual = is_valid_subsequence(array, sequence)
self.assertTrue(actual)

def test_3(self):
"""should return False for array = [5, 1, 22, 25, 6, -1, 8, 10], sequence = [5, 6, 1, 10, 22, 8, -1, 25]"""
array = [5, 1, 22, 25, 6, -1, 8, 10]
array = [5, 1, 22, 25, 6, -1, 8, 10]
sequence = [5, 6, 1, 10, 22, 8, -1, 25]
actual = is_valid_subsequence(array, sequence)
self.assertFalse(actual)

def test_4(self):
"""should return True for array = [1,2,3,4], sequence = [1,3,4]"""
array = [1,2,3,4]
sequence = [1,3,4]
array = [1, 2, 3, 4]
sequence = [1, 3, 4]
actual = is_valid_subsequence(array, sequence)
self.assertTrue(actual)

def test_5(self):
"""should return True for array = [1,2,3,4], sequence = [2,4]"""
array = [1,2,3,4]
sequence = [2,4]
array = [1, 2, 3, 4]
sequence = [2, 4]
actual = is_valid_subsequence(array, sequence)
self.assertTrue(actual)


class IsValidSubsequenceV2TestCase(unittest.TestCase):
def test_1(self):
"""array = [5, 1, 22, 25, 6, -1, 8, 10], sequence = [1, 6, -1, 10]"""
Expand All @@ -48,32 +49,32 @@ def test_1(self):

def test_2(self):
"""should return True for array = [5, 1, 22, 25, 6, -1, 8, 10], sequence = [5, 1, 22, 6, -1, 8, 10]"""
array = [5, 1, 22, 25, 6, -1, 8, 10]
array = [5, 1, 22, 25, 6, -1, 8, 10]
sequence = [5, 1, 22, 6, -1, 8, 10]
actual = is_valid_subsequence_v2(array, sequence)
self.assertTrue(actual)

def test_3(self):
"""should return False for array = [5, 1, 22, 25, 6, -1, 8, 10], sequence = [5, 6, 1, 10, 22, 8, -1, 25]"""
array = [5, 1, 22, 25, 6, -1, 8, 10]
array = [5, 1, 22, 25, 6, -1, 8, 10]
sequence = [5, 6, 1, 10, 22, 8, -1, 25]
actual = is_valid_subsequence_v2(array, sequence)
self.assertFalse(actual)

def test_4(self):
"""should return True for array = [1,2,3,4], sequence = [1,3,4]"""
array = [1,2,3,4]
sequence = [1,3,4]
array = [1, 2, 3, 4]
sequence = [1, 3, 4]
actual = is_valid_subsequence_v2(array, sequence)
self.assertTrue(actual)

def test_5(self):
"""should return True for array = [1,2,3,4], sequence = [2,4]"""
array = [1,2,3,4]
sequence = [2,4]
array = [1, 2, 3, 4]
sequence = [2, 4]
actual = is_valid_subsequence_v2(array, sequence)
self.assertTrue(actual)


if __name__ == '__main__':
if __name__ == "__main__":
unittest.main()
1 change: 1 addition & 0 deletions algorithms/arrays/two_sum/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def two_sum(numbers: List[int], target: int) -> List[int]:
if complement in m:
return [m[complement], idx]
m[num] = idx
return []


def two_sum_with_pointers(numbers: List[int], target: int) -> List[int]:
Expand Down
23 changes: 23 additions & 0 deletions algorithms/arrays/two_sum_less_k/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Two Sum Less Than K

Given an array of integers, nums, and an integer k, find the maximum sum of two elements in nums less than k. Otherwise,
return −1 if no such pair exists.

Constraints

- 1 ≤ nums.length ≤ 100
- 1 ≤ nums[i] ≤ 10^3
- 1 ≤ k ≤ 10^3

## Examples

![Example 1](./images/examples/two_sum_less_k_example_1.png)
![Example 2](./images/examples/two_sum_less_k_example_2.png)
![Example 3](./images/examples/two_sum_less_k_example_3.png)
![Example 4](./images/examples/two_sum_less_k_example_4.png)

## Related Topics

- Array
- Two Pointers
- Binary Search
56 changes: 56 additions & 0 deletions algorithms/arrays/two_sum_less_k/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from typing import List


def two_sum_less_than_k(nums: List[int], k: int) -> int:
"""
Finds the maximum sum of two elements in a given list of numbers that is less than k.
Uses binary search to achieve a time complexity of O(n log n) and find the maximum sum of two elements
that is less than k. It takes the nums array and the target value k as input.
Args:
nums (List[int]): A sorted list of integers
k int: The target value to search for
Returns:
The maximum sum of two elements that is less than k
"""
max_sum = -1

# sort the numbers in ascending order to facilitate binary search
nums.sort()

for x in range(len(nums)):
# find the maximum sum of two elements that is less than k, with the first element being nums[x]
y = search(nums, k - nums[x], x + 1)
if y > x:
# update max_sum with the maximum sum found so far
max_sum = max(max_sum, nums[x] + nums[y])

return max_sum


def search(nums: List[int], target: int, start: int) -> int:
"""
Searches for a number that is less than the target in a sorted list of numbers.
Uses binary search to achieve a time complexity of O(log n) and find the index j such that the sum
nums[i]+nums[j] < k. It takes the nums array, target value, and the start range of the search as input.
Args:
nums (List[int]): A sorted list of integers
target int: The target value to search for
start int: The starting index of the search range
Returns:
The index of the number that is less than the target, or -1 if no such number is found
"""
left, right = start, len(nums) - 1
result = -1

while left <= right:
# calculate the midpoint of the search range
mid = (left + right) // 2
if nums[mid] < target:
# update result to mid and move left to mid + 1 to look for larger values.
result = mid
left = mid + 1
else:
# move right to mid - 1 to check smaller values.
right = mid - 1

return result
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
48 changes: 48 additions & 0 deletions algorithms/arrays/two_sum_less_k/test_two_sum.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import unittest
from . import two_sum_less_than_k


class TwoSumLessKTestCase(unittest.TestCase):
def test_1(self):
"""numbers = [4,2,11,2,5,3,5,8], target = 7"""
numbers = [4, 2, 11, 2, 5, 3, 5, 8]
target = 7
expected = 6
actual = two_sum_less_than_k(numbers, target)
self.assertEqual(expected, actual)

def test_2(self):
"""numbers = [10,20,30], target = 15"""
numbers = [10, 20, 30]
target = 15
expected = -1
actual = two_sum_less_than_k(numbers, target)
self.assertEqual(expected, actual)

def test_3(self):
"""numbers = [34,23,1,24,75,33,54,8], k = 60"""
numbers = [34, 23, 1, 24, 75, 33, 54, 8]
k = 60
expected = 58
actual = two_sum_less_than_k(numbers, k)
self.assertEqual(expected, actual)

def test_4(self):
"""numbers = [5,5,5,5,5,5], k = 15"""
numbers = [5, 5, 5, 5, 5, 5]
k = 15
expected = 10
actual = two_sum_less_than_k(numbers, k)
self.assertEqual(expected, actual)

def test_5(self):
"""numbers = [1,2,3,4,5], k = 3"""
numbers = [1, 2, 3, 4, 5]
k = 3
expected = -1
actual = two_sum_less_than_k(numbers, k)
self.assertEqual(expected, actual)


if __name__ == "__main__":
unittest.main()
Loading