You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Correctness across all five exercises: The implementations of binary search, recursive quicksort, iterative quicksort, merge sort, and the slow/fast pointer middle-of-linked-list are all algorithmically correct. Each function handles the standard cases (element present, absent, first/last position, empty input) and the test suites you wrote cover these scenarios well.
Time complexity: All five solutions hit the expected complexities — O(log n) for binary search, O(n log n) average for both quicksort variants, O(n log n) for merge sort, and O(n) for the linked-list middle finder. The median-of-three pivot selection in both quicksort implementations is a nice touch that reduces the probability of hitting the O(n²) worst case on already-sorted or reverse-sorted input.
Space complexity: Binary search is O(1), the linked-list middle is O(1), and merge sort is O(n) auxiliary due to the sliced sublists. The recursive quicksort is O(log n) average / O(n) worst case for the call stack, and the iterative quicksort with the smaller-side-loop optimization correctly bounds the stack to O(log n) in the worst case — good awareness on your part.
Code quality and structure: The code is clean, well-commented, and each file is self-contained with its own run_tests() / run_test() harness. Docstrings clearly state the approach, complexity, and LeetCode reference. Variable names are descriptive. One minor inconsistency: Exercise_4.py uses run_test() (singular) while the others use run_tests() — not a bug, just stylistic.
Minor improvements / things to watch:
In Exercise_1.py, the function signature binarySearch(arr, l, r, x) accepts l and r but then ignores them and recomputes left = 0, right = len(arr) - 1. This works, but it's misleading — either use the passed-in bounds or drop them from the signature.
In Exercise_4.py, the merge sort creates new lists via slicing on every recursive call (left_half = arr[left:mid + 1]), which is O(n) extra space per level and defeats the standard in-place merge optimization. A more idiomatic version uses indices (l, r) and a single auxiliary buffer.
The printMiddle method in Exercise_3.py prints but doesn't return — fine for the original driver, but consider returning the value so the method is more reusable.
In Exercise_5.py, the iterative quicksort's smaller-side-loop optimization is correct, but the comment "O(log n) in the worst case" for space is slightly misleading — it's O(log n) worst case for the stack, which is what you meant, but worth being precise.
Overall, this is a solid, well-tested submission that demonstrates clear understanding of the algorithms and their trade-offs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PreCourse-2: Exercise 1,2,3,4,5 Complete