Skip to content

feat(algorithms): sliding window#155

Merged
BrianLusina merged 18 commits intomainfrom
feat/algorithms-sliding-window
Jan 21, 2026
Merged

feat(algorithms): sliding window#155
BrianLusina merged 18 commits intomainfrom
feat/algorithms-sliding-window

Conversation

@BrianLusina
Copy link
Copy Markdown
Owner

@BrianLusina BrianLusina commented Jan 19, 2026

Describe your change:

Sliding window algorithm problems

  • Add an algorithm?
  • Fix a bug or typo in an existing algorithm?
  • Documentation change?

Checklist:

  • I have read CONTRIBUTING.md.
  • This pull request is all my own work -- I have not plagiarized.
  • I know that pull requests will not be merged if they fail the automated tests.
  • This PR only changes one algorithm file. To ease review, please open separate PRs for separate algorithms.
  • All new Python files are placed inside an existing directory.
  • All filenames are in all lowercase characters with no spaces or dashes.
  • All functions and variable names follow Python naming conventions.
  • All function parameters and return values are annotated with Python type hints.
  • All functions have doctests that pass the automated testing.
  • All new algorithms have a URL in its comments that points to Wikipedia or other similar explanation.
  • If this pull request resolves one or more open issues then the commit message contains Fixes: #{$ISSUE_NO}.

Summary by CodeRabbit

  • New Features

    • Added several algorithm solutions: sliding-window (max sum subarray, max points from cards), greedy (assign cookies, minimum refuel stops, two-city scheduling), and a binary-tree invert operation.
  • Documentation

    • Added or expanded READMEs across sliding-window, greedy, gas stations, jump game, fast-and-slow, and binary tree topics.
  • Tests

    • Added parameterized test suites covering new algorithms and tree inversion; expanded test cases.
  • Utilities

    • Added tree construction and level-order traversal helpers.
  • Refactor

    • Standardized import paths and improved some algorithm implementations.

✏️ Tip: You can customize this high-level summary in your review settings.

@BrianLusina BrianLusina self-assigned this Jan 19, 2026
@BrianLusina BrianLusina added enhancement Algorithm Algorithm Problem Datastructures Datastructures Documentation Documentation Updates Array Array data structure Sliding Window labels Jan 19, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 19, 2026

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Adds multiple sliding-window and greedy algorithm implementations and READMEs, binary tree utilities and invert/mirror functions, accompanying unit tests, and several test import/path adjustments and DIRECTORY.md entries.

Changes

Cohort / File(s) Summary
Directory index
DIRECTORY.md
Added entries for new Sliding Window and Trees/Binary sections (Max Points From Cards, Max Sum Of Subarray, Invert Tree, Tree Utils).
Sliding Window — Max Sum Of Subarray
algorithms/sliding_window/max_sum_of_subarray/README.md, algorithms/sliding_window/max_sum_of_subarray/__init__.py, algorithms/sliding_window/max_sum_of_subarray/test_max_sum_sub_array.py
New README; three implementations (max_sum_subarray, max_sum_subarray_2, max_sum_subarray_3) for max-sum contiguous subarray of size k; parameterized tests.
Sliding Window — Max Points From Cards
algorithms/sliding_window/max_points_from_cards/README.md, algorithms/sliding_window/max_points_from_cards/__init__.py, algorithms/sliding_window/max_points_from_cards/test_max_points_from_cards.py
New README; max_score(card_points, k) implementation minimizing middle window (n−k) with sliding window; parameterized tests.
Greedy — Assign Cookies
algorithms/greedy/assign_cookies/README.md, algorithms/greedy/assign_cookies/__init__.py, algorithms/greedy/assign_cookies/test_assign_cookies.py
New README; find_content_children(greeds, cookies) two-pointer solution; tests added.
Greedy — Minimum Refuel Stops
algorithms/greedy/minimum_refuel_stops/README.md, algorithms/greedy/minimum_refuel_stops/__init__.py, algorithms/greedy/minimum_refuel_stops/test_min_refueling_stops.py
New README; two implementations (min_refuel_stops, min_refuel_stops_2) using max-heap greedy strategy; comprehensive tests.
Greedy — Two City Scheduling
algorithms/greedy/two_city_scheduling/README.md, algorithms/greedy/two_city_scheduling/__init__.py, algorithms/greedy/two_city_scheduling/test_two_city_scheduling.py
New README; two_city_scheduling(costs) greedy sort-by-difference implementation; tests added.
Greedy — Misc updates
algorithms/greedy/gas_stations/..., algorithms/greedy/jump_game/...
Documentation expansions; small variable rename/comments in gas_stations; can_jump rewritten to max_reach approach; added/centralized jump-game test cases.
Dynamic Programming — Buy Sell Stock
algorithms/dynamic_programming/buy_sell_stock/__init__.py, .../README.md, .../test_max_profit.py
Minor loop style and docstring tweaks; test import path updated.
Binary Tree — Utilities & traversal
datastructures/trees/binary/tree/tree_utils.py, datastructures/trees/binary/test_utils.py
Added create_tree_from_nodes(nodes) and level_order_traversal(root); tests updated to use these utilities (mirror/invert tests).
Binary Tree — Core & mirror/invert
datastructures/trees/binary/tree/binary_tree.py, datastructures/trees/binary/utils.py
Added BinaryTree.invert_tree(); added mirror_binary_tree(root) utility (duplicate definitions present in utils.py — review for dedup).
Binary Tree — Tests & import fixes
datastructures/trees/binary/tree/test_binary_tree*.py, datastructures/trees/binary/tree/test_binary_tree_invert_tree.py
New invert-tree test file; multiple tests switched from relative to absolute imports for BinaryTree/BinaryTreeNode; added mirror/invert test cases.
Fast & Slow — Find Duplicate
algorithms/fast_and_slow/find_duplicate/__init__.py, .../test_find_duplicate.py
Refactored Floyd control flow and return alignment; tests consolidated into parameterized cases replacing many old tests.

Sequence Diagram(s)

(Skipped)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

Two Pointers

Poem

🐇 I hop through nodes and sliding panes today,
New windows, greedy hops, and trees that sway.
Tests bound tight, READMEs in view,
A mirrored branch — code fresh and new. 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.93% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(algorithms): sliding window' is concise and directly summarizes the primary change of adding sliding window algorithm implementations, making it clear and appropriately scoped.
Description check ✅ Passed The description matches the template structure with all required sections completed, including a clear change description (Sliding window algorithm problems), appropriate checkboxes marked, and adherence to contributing guidelines documented.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@algorithms/sliding_window/max_sum_of_subarray/__init__.py`:
- Around line 4-23: The function max_sum_subarray incorrectly initializes
max_sum to 0 which yields wrong results for all-negative inputs; fix it by
setting max_sum to the sum of the first window (or to negative infinity) before
the sliding loop so comparisons are correct for negative sums—compute
initial_window = sum(nums[0:k]) and set max_sum = initial_window (and set state
= initial_window and start = 0, then iterate end from k to n updating state,
max_sum, and start accordingly) or alternatively set max_sum = float("-inf") and
preserve the existing loop but rely on comparisons to update it.
🧹 Nitpick comments (1)
algorithms/sliding_window/max_sum_of_subarray/__init__.py (1)

45-64: Performance: O(n·k) time complexity due to repeated sum() calls.

The sum(nums[lower_bound:upper_bound]) on line 59 is called for each window position, making this O(k) per iteration and O(n·k) overall. For large inputs (e.g., n = 10^5), this will be significantly slower than the O(n) implementations above.

Additionally, max_sum = 0 has the same negative-value issue as max_sum_subarray.

♻️ Suggested refactor for O(n) complexity
     lower_bound = 0
     upper_bound = k
-    max_sum = 0
+    current_sum = sum(nums[:k])
+    max_sum = current_sum

     while upper_bound <= n:
-        current_sum = sum(nums[lower_bound:upper_bound])
         max_sum = max(current_sum, max_sum)
+        if upper_bound < n:
+            current_sum = current_sum - nums[lower_bound] + nums[upper_bound]
         lower_bound += 1
         upper_bound += 1

     return max_sum

BrianLusina and others added 2 commits January 19, 2026 14:54
…negative values

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In `@datastructures/trees/binary/test_utils.py`:
- Around line 230-247: Test expectations in MIRROR_BINARY_TREE_TEST_CASES
include None placeholders that will never be produced by create_tree_from_nodes
or level_order_traversal; update the two affected tuples so expected lists omit
None values (change the second case expected from [1, None, 2, None, 3, None, 4]
to [1,2,3,4] and the third listed mirrored expectation to remove the spurious
None so it becomes [25,75,50,350,125,100]) so
MirrorBinaryTreeTestCase.test_mirror_binary_tree compares against the actual
output produced by mirror_binary_tree and level_order_traversal.

In `@datastructures/trees/binary/tree/test_binary_tree_invert_tree.py`:
- Around line 1-18: This file is a duplicate that tests BinaryTree.create_tree
but is named test_binary_tree_invert_tree.py and imports an unused
BinaryTreeNode; either delete this file to remove the duplicate, or replace its
contents with proper invert_tree tests: remove the unused BinaryTreeNode import,
rename the test class/methods appropriately, and add tests that call
BinaryTree.invert_tree on constructed trees (using BinaryTree.create_tree to
build inputs) and assert the expected root/child structure after inversion;
ensure test file name, class, and test functions reflect invert_tree behavior if
you choose to keep and repurpose it.

In `@datastructures/trees/binary/tree/tree_utils.py`:
- Around line 1-44: The function create_tree_from_nodes currently constructs a
BinaryTreeNode from nodes[0] without guarding against a None root; add a check
after the empty-list guard to return None if nodes[0] is None. Replace the use
of queue.Queue with collections.deque: change the queue variable type to deque,
initialize with deque(), and replace queue.put(...) with queue.append(...) and
queue.get() with queue.popleft(); update any type hints from
Queue[BinaryTreeNode] to deque[BinaryTreeNode] or typing.Deque[BinaryTreeNode]
as appropriate. Ensure all references to curr.left / curr.right assignments
remain the same and the function still returns the root or None.

In `@DIRECTORY.md`:
- Around line 234-237: Fix the MD007 list indentation by aligning the new
bullets with the surrounding nested list levels: ensure the "Max Points From
Cards" and its test link, and the "Max Sum Of Subarray" and its test link
entries use the same indentation spacing as other nested list items (match the
parent bullet's indent level), and apply the same correction to the equivalent
block at lines referenced (489-493); adjust the leading spaces so each
sub-bullet is consistently indented under its parent list item.
♻️ Duplicate comments (1)
algorithms/sliding_window/max_sum_of_subarray/__init__.py (1)

52-61: Handle all-negative inputs in max_sum_subarray_3.
max_sum starts at 0, which yields incorrect results for arrays with all negative sums. Initialize from the first window (or -inf) instead.

🐛 Proposed fix
-    max_sum = 0
+    max_sum = sum(nums[:k])
🧹 Nitpick comments (1)
datastructures/trees/binary/tree/tree_utils.py (1)

47-73: Clarify placeholder behavior in level_order_traversal.
The current implementation never enqueues None children, so the None branch is effectively dead code. If you intend to preserve shape with placeholders, enqueue both children (including None) and stop when an entire level is empty; otherwise, remove the placeholder logic for clarity.

♻️ One way to preserve structure safely
-    while current_level:
+    while current_level and any(node is not None for node in current_level):
         level: List[Any] = []
         next_level: List[Optional[BinaryTreeNode]] = []
 
         for node in current_level:
-            if not node:
-                level.append(None)
-                next_level.append(None)
-            else:
-                level.append(node.data)
-
-                if node.left:
-                    next_level.append(node.left)
-                if node.right:
-                    next_level.append(node.right)
+            if node is None:
+                level.append(None)
+                next_level.extend([None, None])
+                continue
+            level.append(node.data)
+            next_level.append(node.left)
+            next_level.append(node.right)

@github-actions
Copy link
Copy Markdown

github-actions bot commented Jan 20, 2026

Warnings
⚠️ ❗ Big PR

: Pull Request size seems relatively large. If Pull Request contains multiple changes, split each into separate PR will helps faster, easier review.

Generated by 🚫 dangerJS against e19a1fc

@BrianLusina BrianLusina added the Greedy Greedy Algorithm label Jan 20, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
algorithms/greedy/jump_game/README.md (1)

72-93: Fix heading level skip (MD001).

The ###### headings jump from h4 to h6. Use h5 to keep levels consistent.

✏️ Suggested fix
-###### Algorithm
+##### Algorithm
@@
-###### Solution Summary
+##### Solution Summary
🤖 Fix all issues with AI agents
In `@algorithms/dynamic_programming/buy_sell_stock/__init__.py`:
- Around line 36-37: The code calls len(prices) before checking for None which
can raise TypeError; in the function max_profit (and where number_of_prices is
set), move the None check for prices before computing number_of_prices (or
compute number_of_prices only after verifying prices is not None), i.e., ensure
the guard `if prices is None or ...` runs before any len(prices) invocation and
update references to number_of_prices accordingly.

In `@algorithms/greedy/assign_cookies/README.md`:
- Around line 1-3: Revise the README opener to a more formal sentence (e.g.,
"Given children with greed factors and cookies with sizes, assign cookies to
maximize content children.") and correct the misspelling of "Intuitively"
wherever it appears (intro and the solution section, including the occurrences
around lines 46–47); ensure consistent tone and spelling across the entire
document.
- Around line 12-14: The numeric upper bound for element values is incorrectly
written as "231 - 1" and should be the 2^31−1 integer limit; update the README
to replace "231 - 1" with "2^31 - 1" (or "2³¹−1") so the constraint for greed[i]
and cookies[j] correctly reads "1 <= greed[i], cookies[j] <= 2^31 - 1"; leave
the existing constraints for greed.length and cookies.length unchanged.

In `@algorithms/greedy/gas_stations/README.md`:
- Around line 56-75: The walkthrough uses numeric values that don't match
Example 1; update the README's walkthrough to either explicitly state the input
arrays (e.g., gas = [...], cost = [...]) used for this step-by-step example or
change the walkthrough numbers to match the existing Example 1 arrays so the
arithmetic matches; update the descriptive text around the station sequence
(references to gas[0], cost[0], etc.) to reflect the chosen arrays and ensure
consistency with the "gas" and "cost" examples shown earlier.

In `@algorithms/greedy/jump_game/__init__.py`:
- Around line 13-20: can_jump and can_jump_2 behave inconsistently for empty
input: can_jump([]) returns True (loop skipped) while can_jump_2([]) returns
False; add a consistent guard at the start of both functions (can_jump and
can_jump_2) to handle empty lists the same way (either return True or False)
depending on intended semantics, e.g., check if not nums then return
<chosen_boolean>, so callers get the same result for the empty case and behavior
is documented/explicit.
🧹 Nitpick comments (2)
algorithms/greedy/assign_cookies/__init__.py (1)

4-21: Clarify in-place mutation of inputs.

Sorting in place mutates caller lists; consider documenting this explicitly to avoid surprises (or switch to sorted copies if you want a pure function).

🔧 Suggested docstring
 def find_content_children(greeds: List[int], cookies: List[int]) -> int:
+    """Return the max number of content children.
+
+    Note: mutates `greeds` and `cookies` by sorting them in place.
+    """
     # This in-place sorting of both g and s results in a time complexity of O(n log(n) + m log(m))
     greeds.sort()
     cookies.sort()
datastructures/trees/binary/tree/tree_utils.py (1)

57-67: Dead code: the if not node branch is unreachable.

The branch at lines 58-60 can never execute because:

  1. current_level is initialized with [root], and root is guaranteed non-None (line 47 returns early for None)
  2. The only additions to next_level are non-None nodes (lines 65, 67 check if node.left/right)

This orphaned branch suggests incomplete None-placeholder logic. Consider removing it for clarity.

♻️ Suggested simplification
     for node in current_level:
-        if not node:
-            level.append(None)
-            next_level.append(None)
-        else:
-            level.append(node.data)
+        level.append(node.data)
 
-            if node.left:
-                next_level.append(node.left)
-            if node.right:
-                next_level.append(node.right)
+        if node.left:
+            next_level.append(node.left)
+        if node.right:
+            next_level.append(node.right)

Alternatively, if you intend to include None placeholders in the output (for full BFS serialization), the logic would need to always append both children and track when to stop:

if node.left is not None:
    next_level.append(node.left)
else:
    next_level.append(None)
# similar for right

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@algorithms/greedy/minimum_refuel_stops/__init__.py`:
- Line 51: The code mutates the caller's stations list by calling
stations.append([target, 0]); change the logic in the function (e.g., the
minimumRefuelStops function) to avoid mutating the input by first creating a
local copy (or building a new list) and appending [target, 0] to that copy
before using it, or iterate over the original stations plus an extra virtual
station without modifying stations; update all references in that function
(stations.append, any loops over stations) to use the local copy or new iterable
instead.

In `@algorithms/greedy/minimum_refuel_stops/test_min_refueling_stops.py`:
- Around line 6-16: Tests share mutable MIN_REFUELING_STOPS_TEST_CASES and
min_refuel_stops_2 mutates its stations argument by appending a sentinel,
causing cross-test corruption; either update the tests that call
min_refuel_stops_2 to pass an independent deep copy of the stations data (so the
shared MIN_REFUELING_STOPS_TEST_CASES is never mutated) or change
min_refuel_stops_2 to avoid mutating its input by making a local copy of
stations inside the function before appending the target sentinel; locate the
mutation in min_refuel_stops_2 and apply one of these fixes so callers and
global test data remain unchanged.
🧹 Nitpick comments (2)
algorithms/greedy/two_city_scheduling/__init__.py (1)

10-10: Input list is mutated.

costs.sort() modifies the caller's list in-place, which may be unexpected. Consider using sorted() to preserve the original input.

♻️ Suggested fix
-    costs.sort(key=lambda x: x[0] - x[1])
+    costs = sorted(costs, key=lambda x: x[0] - x[1])
DIRECTORY.md (1)

136-153: Fix MD007 list indentation for new Greedy entries.

markdownlint reports list indentation issues at these lines. The repository may use a different indentation convention, but for consistency with MD007 (which expects 2-space indentation for nested lists), consider adjusting the indentation.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@algorithms/fast_and_slow/find_duplicate/README.md`:
- Around line 64-69: Replace the indented sequence example "x, nums[x],
nums[nums[x]], nums[nums[nums[x]]], ..." with a fenced code block using triple
backticks so the snippet is rendered as a code block (e.g., ```\nx, nums[x],
nums[nums[x]], nums[nums[nums[x]]], ...\n```), which resolves the MD046
markdownlint warning; update the README paragraph that explains f(x)=nums[x] to
use this fenced block for the sequence.

BrianLusina and others added 2 commits January 21, 2026 13:09
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@BrianLusina BrianLusina merged commit 51f4e7c into main Jan 21, 2026
4 of 6 checks passed
@BrianLusina BrianLusina deleted the feat/algorithms-sliding-window branch January 21, 2026 10:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Algorithm Algorithm Problem Array Array data structure Binary Tree Binary Tree Data Structure Datastructures Datastructures Depth First Search Documentation Documentation Updates enhancement Greedy Greedy Algorithm Sliding Window Trees

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant