Showing preview only (1,122K chars total). Download the full file or copy to clipboard to get everything.
Repository: keon/algorithms
Branch: main
Commit: a1bf1f39f95b
Files: 440
Total size: 1021.7 KB
Directory structure:
gitextract_s6ixwhb4/
├── .github/
│ └── workflows/
│ ├── publish.yml
│ └── python-app.yml
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── MANIFEST.in
├── README.md
├── algorithms/
│ ├── __init__.py
│ ├── array/
│ │ ├── __init__.py
│ │ ├── delete_nth.py
│ │ ├── flatten.py
│ │ ├── garage.py
│ │ ├── josephus.py
│ │ ├── limit.py
│ │ ├── longest_non_repeat.py
│ │ ├── max_ones_index.py
│ │ ├── merge_intervals.py
│ │ ├── missing_ranges.py
│ │ ├── move_zeros.py
│ │ ├── n_sum.py
│ │ ├── plus_one.py
│ │ ├── remove_duplicates.py
│ │ ├── rotate.py
│ │ ├── summarize_ranges.py
│ │ ├── three_sum.py
│ │ ├── top_1.py
│ │ ├── trimmean.py
│ │ └── two_sum.py
│ ├── backtracking/
│ │ ├── __init__.py
│ │ ├── add_operators.py
│ │ ├── anagram.py
│ │ ├── array_sum_combinations.py
│ │ ├── combination_sum.py
│ │ ├── factor_combinations.py
│ │ ├── find_words.py
│ │ ├── generate_abbreviations.py
│ │ ├── generate_parenthesis.py
│ │ ├── letter_combination.py
│ │ ├── minimax.py
│ │ ├── palindrome_partitioning.py
│ │ ├── pattern_match.py
│ │ ├── permute.py
│ │ ├── permute_unique.py
│ │ ├── subsets.py
│ │ └── subsets_unique.py
│ ├── bit_manipulation/
│ │ ├── __init__.py
│ │ ├── add_bitwise_operator.py
│ │ ├── binary_gap.py
│ │ ├── bit_operation.py
│ │ ├── bytes_int_conversion.py
│ │ ├── count_flips_to_convert.py
│ │ ├── count_ones.py
│ │ ├── find_difference.py
│ │ ├── find_missing_number.py
│ │ ├── flip_bit_longest_sequence.py
│ │ ├── gray_code.py
│ │ ├── has_alternative_bit.py
│ │ ├── insert_bit.py
│ │ ├── power_of_two.py
│ │ ├── remove_bit.py
│ │ ├── reverse_bits.py
│ │ ├── single_number.py
│ │ ├── single_number2.py
│ │ ├── single_number3.py
│ │ ├── subsets.py
│ │ └── swap_pair.py
│ ├── common/
│ │ ├── __init__.py
│ │ ├── graph.py
│ │ ├── list_node.py
│ │ └── tree_node.py
│ ├── compression/
│ │ ├── __init__.py
│ │ ├── elias.py
│ │ ├── huffman_coding.py
│ │ └── rle_compression.py
│ ├── data_structures/
│ │ ├── __init__.py
│ │ ├── avl_tree.py
│ │ ├── b_tree.py
│ │ ├── bst.py
│ │ ├── fenwick_tree.py
│ │ ├── graph.py
│ │ ├── hash_table.py
│ │ ├── heap.py
│ │ ├── iterative_segment_tree.py
│ │ ├── kd_tree.py
│ │ ├── linked_list.py
│ │ ├── priority_queue.py
│ │ ├── queue.py
│ │ ├── red_black_tree.py
│ │ ├── segment_tree.py
│ │ ├── separate_chaining_hash_table.py
│ │ ├── sqrt_decomposition.py
│ │ ├── stack.py
│ │ ├── trie.py
│ │ ├── union_find.py
│ │ └── veb_tree.py
│ ├── dynamic_programming/
│ │ ├── __init__.py
│ │ ├── bitmask.py
│ │ ├── buy_sell_stock.py
│ │ ├── climbing_stairs.py
│ │ ├── coin_change.py
│ │ ├── combination_sum.py
│ │ ├── count_paths_dp.py
│ │ ├── edit_distance.py
│ │ ├── egg_drop.py
│ │ ├── fib.py
│ │ ├── hosoya_triangle.py
│ │ ├── house_robber.py
│ │ ├── int_divide.py
│ │ ├── job_scheduling.py
│ │ ├── k_factor.py
│ │ ├── knapsack.py
│ │ ├── longest_common_subsequence.py
│ │ ├── longest_increasing.py
│ │ ├── matrix_chain_order.py
│ │ ├── max_product_subarray.py
│ │ ├── max_subarray.py
│ │ ├── min_cost_path.py
│ │ ├── num_decodings.py
│ │ ├── planting_trees.py
│ │ ├── regex_matching.py
│ │ ├── rod_cut.py
│ │ └── word_break.py
│ ├── graph/
│ │ ├── __init__.py
│ │ ├── a_star.py
│ │ ├── all_factors.py
│ │ ├── all_pairs_shortest_path.py
│ │ ├── bellman_ford.py
│ │ ├── blossom.py
│ │ ├── check_bipartite.py
│ │ ├── check_digraph_strongly_connected.py
│ │ ├── clone_graph.py
│ │ ├── count_connected_number_of_component.py
│ │ ├── count_islands_bfs.py
│ │ ├── count_islands_dfs.py
│ │ ├── count_islands_unionfind.py
│ │ ├── cycle_detection.py
│ │ ├── dijkstra.py
│ │ ├── dijkstra_heapq.py
│ │ ├── find_all_cliques.py
│ │ ├── find_path.py
│ │ ├── graph.py
│ │ ├── kahns_algorithm.py
│ │ ├── markov_chain.py
│ │ ├── maximum_flow.py
│ │ ├── maximum_flow_bfs.py
│ │ ├── maximum_flow_dfs.py
│ │ ├── maze_search_bfs.py
│ │ ├── maze_search_dfs.py
│ │ ├── minimum_spanning_tree.py
│ │ ├── pacific_atlantic.py
│ │ ├── path_between_two_vertices_in_digraph.py
│ │ ├── prims_minimum_spanning.py
│ │ ├── satisfiability.py
│ │ ├── shortest_distance_from_all_buildings.py
│ │ ├── strongly_connected_components_kosaraju.py
│ │ ├── sudoku_solver.py
│ │ ├── tarjan.py
│ │ ├── topological_sort_bfs.py
│ │ ├── topological_sort_dfs.py
│ │ ├── transitive_closure_dfs.py
│ │ ├── traversal.py
│ │ ├── walls_and_gates.py
│ │ └── word_ladder.py
│ ├── greedy/
│ │ ├── __init__.py
│ │ ├── gale_shapley.py
│ │ └── max_contiguous_subsequence_sum.py
│ ├── heap/
│ │ ├── __init__.py
│ │ ├── k_closest_points.py
│ │ ├── merge_sorted_k_lists.py
│ │ ├── skyline.py
│ │ └── sliding_window_max.py
│ ├── linked_list/
│ │ ├── __init__.py
│ │ ├── add_two_numbers.py
│ │ ├── copy_random_pointer.py
│ │ ├── delete_node.py
│ │ ├── first_cyclic_node.py
│ │ ├── intersection.py
│ │ ├── is_cyclic.py
│ │ ├── is_palindrome.py
│ │ ├── is_sorted.py
│ │ ├── kth_to_last.py
│ │ ├── merge_two_list.py
│ │ ├── partition.py
│ │ ├── remove_duplicates.py
│ │ ├── remove_range.py
│ │ ├── reverse.py
│ │ ├── rotate_list.py
│ │ └── swap_in_pairs.py
│ ├── map/
│ │ ├── __init__.py
│ │ ├── is_anagram.py
│ │ ├── is_isomorphic.py
│ │ ├── longest_common_subsequence.py
│ │ ├── longest_palindromic_subsequence.py
│ │ ├── randomized_set.py
│ │ ├── valid_sudoku.py
│ │ └── word_pattern.py
│ ├── math/
│ │ ├── __init__.py
│ │ ├── base_conversion.py
│ │ ├── chinese_remainder_theorem.py
│ │ ├── combination.py
│ │ ├── cosine_similarity.py
│ │ ├── decimal_to_binary_ip.py
│ │ ├── diffie_hellman_key_exchange.py
│ │ ├── distance_between_two_points.py
│ │ ├── euler_totient.py
│ │ ├── extended_gcd.py
│ │ ├── factorial.py
│ │ ├── fft.py
│ │ ├── find_order_simple.py
│ │ ├── find_primitive_root_simple.py
│ │ ├── gcd.py
│ │ ├── generate_strobogrammtic.py
│ │ ├── goldbach.py
│ │ ├── hailstone.py
│ │ ├── is_strobogrammatic.py
│ │ ├── krishnamurthy_number.py
│ │ ├── linear_regression.py
│ │ ├── magic_number.py
│ │ ├── manhattan_distance.py
│ │ ├── modular_exponential.py
│ │ ├── modular_inverse.py
│ │ ├── next_bigger.py
│ │ ├── next_perfect_square.py
│ │ ├── nth_digit.py
│ │ ├── num_digits.py
│ │ ├── num_perfect_squares.py
│ │ ├── polynomial.py
│ │ ├── polynomial_division.py
│ │ ├── power.py
│ │ ├── prime_check.py
│ │ ├── primes_sieve_of_eratosthenes.py
│ │ ├── pythagoras.py
│ │ ├── rabin_miller.py
│ │ ├── recursive_binomial_coefficient.py
│ │ ├── rsa.py
│ │ ├── sqrt_precision_factor.py
│ │ ├── summing_digits.py
│ │ ├── surface_area_of_torus.py
│ │ └── symmetry_group_cycle_index.py
│ ├── matrix/
│ │ ├── __init__.py
│ │ ├── bomb_enemy.py
│ │ ├── cholesky_matrix_decomposition.py
│ │ ├── copy_transform.py
│ │ ├── count_paths.py
│ │ ├── crout_matrix_decomposition.py
│ │ ├── matrix_exponentiation.py
│ │ ├── matrix_inversion.py
│ │ ├── multiply.py
│ │ ├── rotate_image.py
│ │ ├── search_in_sorted_matrix.py
│ │ ├── sort_matrix_diagonally.py
│ │ ├── sparse_dot_vector.py
│ │ ├── sparse_mul.py
│ │ ├── spiral_traversal.py
│ │ ├── sudoku_validator.py
│ │ └── sum_sub_squares.py
│ ├── py.typed
│ ├── queue/
│ │ ├── __init__.py
│ │ ├── max_sliding_window.py
│ │ ├── moving_average.py
│ │ ├── reconstruct_queue.py
│ │ └── zigzagiterator.py
│ ├── searching/
│ │ ├── __init__.py
│ │ ├── binary_search.py
│ │ ├── exponential_search.py
│ │ ├── find_min_rotate.py
│ │ ├── first_occurrence.py
│ │ ├── generalized_binary_search.py
│ │ ├── interpolation_search.py
│ │ ├── jump_search.py
│ │ ├── last_occurrence.py
│ │ ├── linear_search.py
│ │ ├── next_greatest_letter.py
│ │ ├── search_insert.py
│ │ ├── search_range.py
│ │ ├── search_rotate.py
│ │ ├── sentinel_search.py
│ │ ├── ternary_search.py
│ │ └── two_sum.py
│ ├── set/
│ │ ├── __init__.py
│ │ ├── find_keyboard_row.py
│ │ ├── randomized_set.py
│ │ └── set_covering.py
│ ├── sorting/
│ │ ├── __init__.py
│ │ ├── bead_sort.py
│ │ ├── bitonic_sort.py
│ │ ├── bogo_sort.py
│ │ ├── bubble_sort.py
│ │ ├── bucket_sort.py
│ │ ├── cocktail_shaker_sort.py
│ │ ├── comb_sort.py
│ │ ├── counting_sort.py
│ │ ├── cycle_sort.py
│ │ ├── exchange_sort.py
│ │ ├── gnome_sort.py
│ │ ├── heap_sort.py
│ │ ├── insertion_sort.py
│ │ ├── meeting_rooms.py
│ │ ├── merge_sort.py
│ │ ├── pancake_sort.py
│ │ ├── pigeonhole_sort.py
│ │ ├── quick_sort.py
│ │ ├── radix_sort.py
│ │ ├── selection_sort.py
│ │ ├── shell_sort.py
│ │ ├── sort_colors.py
│ │ ├── stooge_sort.py
│ │ └── wiggle_sort.py
│ ├── stack/
│ │ ├── __init__.py
│ │ ├── is_consecutive.py
│ │ ├── is_sorted.py
│ │ ├── longest_abs_path.py
│ │ ├── ordered_stack.py
│ │ ├── remove_min.py
│ │ ├── simplify_path.py
│ │ ├── stutter.py
│ │ ├── switch_pairs.py
│ │ └── valid_parenthesis.py
│ ├── streaming/
│ │ ├── __init__.py
│ │ ├── misra_gries.py
│ │ └── one_sparse_recovery.py
│ ├── string/
│ │ ├── __init__.py
│ │ ├── add_binary.py
│ │ ├── alphabet_board_path.py
│ │ ├── atbash_cipher.py
│ │ ├── breaking_bad.py
│ │ ├── caesar_cipher.py
│ │ ├── check_pangram.py
│ │ ├── contain_string.py
│ │ ├── count_binary_substring.py
│ │ ├── decode_string.py
│ │ ├── delete_reoccurring.py
│ │ ├── domain_extractor.py
│ │ ├── encode_decode.py
│ │ ├── first_unique_char.py
│ │ ├── fizzbuzz.py
│ │ ├── group_anagrams.py
│ │ ├── int_to_roman.py
│ │ ├── is_palindrome.py
│ │ ├── is_rotated.py
│ │ ├── judge_circle.py
│ │ ├── knuth_morris_pratt.py
│ │ ├── license_number.py
│ │ ├── longest_common_prefix.py
│ │ ├── longest_palindromic_substring.py
│ │ ├── make_sentence.py
│ │ ├── manacher.py
│ │ ├── merge_string_checker.py
│ │ ├── min_distance.py
│ │ ├── multiply_strings.py
│ │ ├── one_edit_distance.py
│ │ ├── panagram.py
│ │ ├── rabin_karp.py
│ │ ├── repeat_string.py
│ │ ├── repeat_substring.py
│ │ ├── reverse_string.py
│ │ ├── reverse_vowel.py
│ │ ├── reverse_words.py
│ │ ├── roman_to_int.py
│ │ ├── rotate.py
│ │ ├── strip_url_params.py
│ │ ├── strong_password.py
│ │ ├── swap_characters.py
│ │ ├── text_justification.py
│ │ ├── unique_morse.py
│ │ ├── validate_coordinates.py
│ │ ├── word_squares.py
│ │ └── z_algorithm.py
│ └── tree/
│ ├── __init__.py
│ ├── bin_tree_to_list.py
│ ├── binary_tree_paths.py
│ ├── binary_tree_views.py
│ ├── bst_array_to_bst.py
│ ├── bst_closest_value.py
│ ├── bst_count_left_node.py
│ ├── bst_delete_node.py
│ ├── bst_depth_sum.py
│ ├── bst_height.py
│ ├── bst_is_bst.py
│ ├── bst_iterator.py
│ ├── bst_kth_smallest.py
│ ├── bst_lowest_common_ancestor.py
│ ├── bst_num_empty.py
│ ├── bst_predecessor.py
│ ├── bst_serialize_deserialize.py
│ ├── bst_successor.py
│ ├── bst_unique_bst.py
│ ├── bst_validate_bst.py
│ ├── construct_tree_postorder_preorder.py
│ ├── deepest_left.py
│ ├── invert_tree.py
│ ├── is_balanced.py
│ ├── is_subtree.py
│ ├── is_symmetric.py
│ ├── longest_consecutive.py
│ ├── lowest_common_ancestor.py
│ ├── max_height.py
│ ├── max_path_sum.py
│ ├── min_height.py
│ ├── path_sum.py
│ ├── path_sum2.py
│ ├── pretty_print.py
│ ├── same_tree.py
│ ├── traversal_inorder.py
│ ├── traversal_level_order.py
│ ├── traversal_postorder.py
│ ├── traversal_preorder.py
│ ├── traversal_zigzag.py
│ ├── tree.py
│ └── trie_add_and_search.py
├── docs/
│ └── index.html
├── pyproject.toml
└── tests/
├── test_array.py
├── test_backtracking.py
├── test_bit_manipulation.py
├── test_community_algorithms.py
├── test_compression.py
├── test_data_structures.py
├── test_dynamic_programming.py
├── test_graph.py
├── test_greedy.py
├── test_heap.py
├── test_issue_fixes.py
├── test_iterative_segment_tree.py
├── test_linked_list.py
├── test_map.py
├── test_math.py
├── test_matrix.py
├── test_monomial.py
├── test_polynomial.py
├── test_queue.py
├── test_searching.py
├── test_set.py
├── test_sorting.py
├── test_stack.py
├── test_streaming.py
├── test_string.py
├── test_tree.py
└── test_veb_tree.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/workflows/publish.yml
================================================
name: Publish to PyPI
on:
release:
types: [published]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- name: Set up Python
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: "3.13"
- name: Install build tools
run: python -m pip install --upgrade pip build
- name: Build package
run: python -m build
- name: Upload build artifacts
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4
with:
name: dist
path: dist/
publish:
needs: build
runs-on: ubuntu-latest
environment: pypi
permissions:
id-token: write
steps:
- name: Download build artifacts
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4
with:
name: dist
path: dist/
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # release/v1
================================================
FILE: .github/workflows/python-app.yml
================================================
name: Tests
on:
push:
branches: [master, main]
pull_request:
branches: [master, main]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"
- name: Lint with ruff
run: ruff check algorithms/ tests/
- name: Test with pytest
run: python -m pytest
================================================
FILE: .gitignore
================================================
__pycache__/
*.py[cod]
*.iml
*.xml
.idea/
.cache/
.pytest_cache/
.coverage
# Setuptools distribution folder.
/dist/
# Python egg metadata, regenerated from source files by setuptools.
/*.egg-info
/*.egg
# docs
build/
pythonenv3.8/
.vscode/
# Ignoring the virtual Environment when using GitHub Codespaces
.venv/
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at kwk236@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing
We love pull requests from everyone. By contributing to this repository, you
agree to abide by the [Code of Conduct](CODE_OF_CONDUCT.md).
## Get Started
* First [fork][fork] the repository and then clone it using:
git clone git@github.com:your-username/algorithms.git
* After that create a branch for your changes. For example:
* add_XXX if you will add new algorithms or data structures.
* fix_XXX if you will fix a bug on a certain algorithm or data structure.
* test_XXX if you wrote a test/s.
* doc_XXX if you added to or edited documentation.
You may contribute by:
- implementing new algorithms in the repo. Be sure to keep it under
right section (e.g. [array](array), [dp](dp), etc). Make a new section for it if
it doesn't fall under any section. Make sure that your implementation works.
- optimizing or improving the existing algorithms.
- adding a different solution for the problem.
- finding and fixing bugs.
- adding examples to explain the algorithms better.
- adding test cases.
- improving documentation.
## Pull Requests
Push to your fork and [submit a pull request][pr].
We will review and may suggest some changes or improvements or alternatives.
Some things that will increase the chance that your pull request is accepted:
* All algorithms should be written in **Python 3**.
(There are a few algorithms still in _Python 2_ syntax. You can start by converting
[those][issue120] to _Python 3_.)
* Write clean and understandable code.
* Properly comment the code and briefly explain what the algorithm is doing in the [docstrings][docstr].
* You may also explain the output using a minimal example.
* Try to also include a couple of test cases for the algorithm.
* Write a [good commit message][commit].
## Issues
Submit a [new issue][newissue] if there is an algorithm to add, or if a bug was found in an existing algorithm. Before submitting a new issue please review the [existing issues][issues] to avoid creating duplicates. Also, consider resolving current issues or contributing to the discussion on an issue.
## Collaborators
You can ask for any help or clarifications from the collaborators.
[Keon Kim](https://github.com/keon)
[Rahul Goswami](https://github.com/goswami-rahul)
[Ankit Agarwal](https://github.com/ankit167)
[Hai Hoang Dang](https://github.com/danghai)
[Saad](https://github.com/SaadBenn)
[fork]: https://help.github.com/articles/fork-a-repo/
[docstr]: https://www.python.org/dev/peps/pep-0257/#multi-line-docstrings
[commit]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
[pr]: https://github.com/keon/algorithms/compare/
[newissue]: https://github.com/keon/algorithms/issues/new
[issue120]: https://github.com/keon/algorithms/issues/120
[issues]: https://github.com/keon/algorithms/issues/
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2017 Keon
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: MANIFEST.in
================================================
include README.md
include LICENSE
include algorithms/*
================================================
FILE: README.md
================================================
[](https://badge.fury.io/py/algorithms)
[](https://www.codetriage.com/keon/algorithms)
# algorithms
Minimal, clean, and well-documented implementations of data structures and algorithms in Python 3.
Each file is self-contained with docstrings, type hints, and complexity notes — designed to be read and learned from.
## Quick Start
### Install
```bash
pip install algorithms
```
### Use
```python
from algorithms.sorting import merge_sort
print(merge_sort([38, 27, 43, 3, 9, 82, 10]))
# [3, 9, 10, 27, 38, 43, 82]
```
```python
from algorithms.data_structures import BinaryHeap, Trie, BST
from algorithms.graph import dijkstra, bellman_ford
from algorithms.tree import TreeNode
```
### Examples
**Graph — Dijkstra's shortest path:**
```python
from algorithms.graph import dijkstra
graph = {
"s": {"a": 2, "b": 1},
"a": {"s": 3, "b": 4, "c": 8},
"b": {"s": 4, "a": 2, "d": 2},
"c": {"a": 2, "d": 7, "t": 4},
"d": {"b": 1, "c": 11, "t": 5},
"t": {"c": 3, "d": 5},
}
print(dijkstra(graph, "s", "t"))
# (8, ['s', 'b', 'd', 't'])
```
**Dynamic programming — coin change:**
```python
from algorithms.dynamic_programming import count
# Number of ways to make amount 10 using denominations [2, 5, 3, 6]
print(count([2, 5, 3, 6], 10))
# 5
```
**Backtracking — generate permutations:**
```python
from algorithms.backtracking import permute
print(permute([1, 2, 3]))
# [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
```
**Data structures — binary heap:**
```python
from algorithms.data_structures import BinaryHeap
heap = BinaryHeap()
for val in [5, 3, 8, 1, 9]:
heap.insert(val)
print(heap.remove_min()) # 1
print(heap.remove_min()) # 3
```
**Searching — binary search:**
```python
from algorithms.searching import binary_search
print(binary_search([1, 3, 5, 7, 9, 11], 7))
# 3 (index of target)
```
**Tree — inorder traversal:**
```python
from algorithms.tree import TreeNode
from algorithms.tree import inorder
root = TreeNode(4)
root.left = TreeNode(2)
root.right = TreeNode(6)
root.left.left = TreeNode(1)
root.left.right = TreeNode(3)
print(inorder(root))
# [1, 2, 3, 4, 6]
```
**String — Knuth-Morris-Pratt pattern matching:**
```python
from algorithms.string import knuth_morris_pratt
print(knuth_morris_pratt("abxabcabcaby", "abcaby"))
# 6 (starting index of match)
```
### Run Tests
```bash
python -m pytest tests/
```
## Project Structure
```
algorithms/
data_structures/ # Reusable data structure implementations
array/ # Array manipulation algorithms
backtracking/ # Constraint satisfaction & enumeration
bit_manipulation/ # Bitwise operations & tricks
compression/ # Encoding & compression schemes
dynamic_programming/ # Optimal substructure & memoization
graph/ # Graph algorithms (BFS, DFS, shortest path, flow, ...)
greedy/ # Greedy strategies
heap/ # Heap-based algorithms
linked_list/ # Linked list algorithms
map/ # Hash-map-based algorithms
math/ # Number theory, combinatorics, algebra
matrix/ # 2D array & linear algebra operations
queue/ # Queue-based algorithms
searching/ # Search algorithms (binary, linear, ...)
set/ # Set-based algorithms
sorting/ # Sorting algorithms
stack/ # Stack-based algorithms
streaming/ # Streaming & sketching algorithms
string/ # String matching, manipulation, parsing
tree/ # Tree algorithms (traversal, BST ops, ...)
tests/ # One test file per topic
```
## Data Structures
All core data structures live in [`algorithms/data_structures/`](algorithms/data_structures):
| Data Structure | Module | Key Classes |
|---|---|---|
| AVL Tree | `avl_tree.py` | `AvlTree` |
| B-Tree | `b_tree.py` | `BTree` |
| Binary Search Tree | `bst.py` | `BST` |
| Fenwick Tree | `fenwick_tree.py` | `Fenwick_Tree` |
| Graph | `graph.py` | `Node`, `DirectedEdge`, `DirectedGraph` |
| Hash Table | `hash_table.py` | `HashTable`, `ResizableHashTable` |
| Heap | `heap.py` | `BinaryHeap` |
| KD Tree | `kd_tree.py` | `KDTree` |
| Linked List | `linked_list.py` | `SinglyLinkedListNode`, `DoublyLinkedListNode` |
| Priority Queue | `priority_queue.py` | `PriorityQueue` |
| Queue | `queue.py` | `ArrayQueue`, `LinkedListQueue` |
| Red-Black Tree | `red_black_tree.py` | `RBTree` |
| Segment Tree | `segment_tree.py`, `iterative_segment_tree.py` | `SegmentTree` |
| Separate Chaining Hash Table | `separate_chaining_hash_table.py` | `SeparateChainingHashTable` |
| Sqrt Decomposition | `sqrt_decomposition.py` | `SqrtDecomposition` |
| Stack | `stack.py` | `ArrayStack`, `LinkedListStack` |
| Trie | `trie.py` | `Trie` |
| Union-Find | `union_find.py` | `Union` |
| vEB Tree | `veb_tree.py` | `VEBTree` |
## Algorithms
### Array
- [delete_nth](algorithms/array/delete_nth.py) — keep at most N occurrences of each element
- [flatten](algorithms/array/flatten.py) — recursively flatten nested arrays into a single list
- [garage](algorithms/array/garage.py) — minimum swaps to rearrange a parking lot
- [josephus](algorithms/array/josephus.py) — eliminate every k-th person in a circular arrangement
- [limit](algorithms/array/limit.py) — filter elements within min/max bounds
- [longest_non_repeat](algorithms/array/longest_non_repeat.py) — longest substring without repeating characters
- [max_ones_index](algorithms/array/max_ones_index.py) — find the zero to flip for the longest run of ones
- [merge_intervals](algorithms/array/merge_intervals.py) — combine overlapping intervals
- [missing_ranges](algorithms/array/missing_ranges.py) — find gaps between a low and high bound
- [move_zeros](algorithms/array/move_zeros.py) — move all zeros to the end, preserving order
- [n_sum](algorithms/array/n_sum.py) — find all unique n-tuples that sum to a target
- [plus_one](algorithms/array/plus_one.py) — add one to a number represented as a digit array
- [remove_duplicates](algorithms/array/remove_duplicates.py) — remove duplicate elements preserving order
- [rotate](algorithms/array/rotate.py) — rotate an array right by k positions
- [summarize_ranges](algorithms/array/summarize_ranges.py) — summarize consecutive integers as range tuples
- [three_sum](algorithms/array/three_sum.py) — find all unique triplets that sum to zero
- [top_1](algorithms/array/top_1.py) — find the most frequently occurring values
- [trimmean](algorithms/array/trimmean.py) — compute mean after trimming extreme values
- [two_sum](algorithms/array/two_sum.py) — find two indices whose values sum to a target
### Backtracking
- [add_operators](algorithms/backtracking/add_operators.py) — insert +, -, * between digits to reach a target
- [anagram](algorithms/backtracking/anagram.py) — check if two strings are anagrams
- [array_sum_combinations](algorithms/backtracking/array_sum_combinations.py) — find three-element combos from arrays that hit a target sum
- [combination_sum](algorithms/backtracking/combination_sum.py) — find combinations (with reuse) that sum to a target
- [factor_combinations](algorithms/backtracking/factor_combinations.py) — generate all factor combinations of a number
- [find_words](algorithms/backtracking/find_words.py) — find words on a letter board via trie-based search
- [generate_abbreviations](algorithms/backtracking/generate_abbreviations.py) — generate all possible abbreviations of a word
- [generate_parenthesis](algorithms/backtracking/generate_parenthesis.py) — generate all valid parenthesis combinations
- [letter_combination](algorithms/backtracking/letter_combination.py) — phone keypad digit-to-letter combinations
- [palindrome_partitioning](algorithms/backtracking/palindrome_partitioning.py) — partition a string into palindromic substrings
- [pattern_match](algorithms/backtracking/pattern_match.py) — match a string to a pattern via bijection mapping
- [permute](algorithms/backtracking/permute.py) — generate all permutations of distinct elements
- [permute_unique](algorithms/backtracking/permute_unique.py) — generate unique permutations when duplicates exist
- [subsets](algorithms/backtracking/subsets.py) — generate all subsets (power set)
- [minimax](algorithms/backtracking/minimax.py) — game-tree search with alpha-beta pruning
- [subsets_unique](algorithms/backtracking/subsets_unique.py) — generate unique subsets when duplicates exist
### Bit Manipulation
- [add_bitwise_operator](algorithms/bit_manipulation/add_bitwise_operator.py) — add two integers using only bitwise operations
- [binary_gap](algorithms/bit_manipulation/binary_gap.py) — longest distance between consecutive 1-bits
- [bit_operation](algorithms/bit_manipulation/bit_operation.py) — get, set, clear, and update individual bits
- [bytes_int_conversion](algorithms/bit_manipulation/bytes_int_conversion.py) — convert between integers and byte sequences
- [count_flips_to_convert](algorithms/bit_manipulation/count_flips_to_convert.py) — count bit flips needed to convert one integer to another
- [count_ones](algorithms/bit_manipulation/count_ones.py) — count the number of 1-bits (Hamming weight)
- [find_difference](algorithms/bit_manipulation/find_difference.py) — find the added character between two strings using XOR
- [find_missing_number](algorithms/bit_manipulation/find_missing_number.py) — find a missing number in a sequence using XOR
- [flip_bit_longest_sequence](algorithms/bit_manipulation/flip_bit_longest_sequence.py) — longest run of 1s after flipping a single 0
- [gray_code](algorithms/bit_manipulation/gray_code.py) — generate Gray code sequences and convert between Gray and binary
- [has_alternative_bit](algorithms/bit_manipulation/has_alternative_bit.py) — check if binary representation has alternating bits
- [insert_bit](algorithms/bit_manipulation/insert_bit.py) — insert bits at a specific position in an integer
- [power_of_two](algorithms/bit_manipulation/power_of_two.py) — check if an integer is a power of two
- [remove_bit](algorithms/bit_manipulation/remove_bit.py) — remove a bit at a given position
- [reverse_bits](algorithms/bit_manipulation/reverse_bits.py) — reverse all 32 bits of an unsigned integer
- [single_number](algorithms/bit_manipulation/single_number.py) — find the element appearing once (others appear twice) via XOR
- [single_number2](algorithms/bit_manipulation/single_number2.py) — find the element appearing once (others appear three times)
- [single_number3](algorithms/bit_manipulation/single_number3.py) — find two unique elements (others appear twice)
- [subsets](algorithms/bit_manipulation/subsets.py) — generate all subsets using bitmask enumeration
- [swap_pair](algorithms/bit_manipulation/swap_pair.py) — swap adjacent bit pairs in an integer
### Compression
- [elias](algorithms/compression/elias.py) — Elias gamma and delta universal integer coding
- [huffman_coding](algorithms/compression/huffman_coding.py) — variable-length prefix codes for lossless compression
- [rle_compression](algorithms/compression/rle_compression.py) — run-length encoding for consecutive character compression
### Dynamic Programming
- [bitmask](algorithms/dynamic_programming/bitmask.py) — travelling salesman problem via bitmask dynamic programming
- [buy_sell_stock](algorithms/dynamic_programming/buy_sell_stock.py) — maximize profit from a stock price array
- [climbing_stairs](algorithms/dynamic_programming/climbing_stairs.py) — count ways to climb stairs taking 1 or 2 steps
- [coin_change](algorithms/dynamic_programming/coin_change.py) — minimum coins to make a given amount
- [combination_sum](algorithms/dynamic_programming/combination_sum.py) — count combinations that sum to a target (with reuse)
- [count_paths_dp](algorithms/dynamic_programming/count_paths_dp.py) — count paths in a grid using recursion, memoization, and bottom-up DP
- [edit_distance](algorithms/dynamic_programming/edit_distance.py) — minimum edits to transform one string into another
- [egg_drop](algorithms/dynamic_programming/egg_drop.py) — minimize trials to find the critical floor
- [fibonacci](algorithms/dynamic_programming/fib.py) — compute Fibonacci numbers with memoization
- [hosoya_triangle](algorithms/dynamic_programming/hosoya_triangle.py) — generate the Hosoya triangle of Fibonacci-like numbers
- [house_robber](algorithms/dynamic_programming/house_robber.py) — maximize loot from non-adjacent houses
- [int_divide](algorithms/dynamic_programming/int_divide.py) — count the number of integer partitions
- [job_scheduling](algorithms/dynamic_programming/job_scheduling.py) — maximize profit from weighted job scheduling
- [k_factor](algorithms/dynamic_programming/k_factor.py) — find the k-factor of a string pattern
- [knapsack](algorithms/dynamic_programming/knapsack.py) — maximize value under a weight constraint
- [longest_common_subsequence](algorithms/dynamic_programming/longest_common_subsequence.py) — find the longest common subsequence of two strings
- [longest_increasing](algorithms/dynamic_programming/longest_increasing.py) — find the longest increasing subsequence
- [matrix_chain_order](algorithms/dynamic_programming/matrix_chain_order.py) — minimize scalar multiplications for matrix chain
- [max_product_subarray](algorithms/dynamic_programming/max_product_subarray.py) — find the contiguous subarray with maximum product
- [max_subarray](algorithms/dynamic_programming/max_subarray.py) — maximum sum subarray (Kadane's algorithm)
- [min_cost_path](algorithms/dynamic_programming/min_cost_path.py) — minimum-cost path through a grid
- [num_decodings](algorithms/dynamic_programming/num_decodings.py) — count ways to decode a digit string into letters
- [planting_trees](algorithms/dynamic_programming/planting_trees.py) — optimize tree planting for maximum profit
- [regex_matching](algorithms/dynamic_programming/regex_matching.py) — match a string against a pattern with `.` and `*` wildcards
- [rod_cut](algorithms/dynamic_programming/rod_cut.py) — maximize revenue from cutting a rod into pieces
- [word_break](algorithms/dynamic_programming/word_break.py) — check if a string can be segmented into dictionary words
### Graph
- [a_star](algorithms/graph/a_star.py) — heuristic shortest-path search (A* algorithm)
- [all_factors](algorithms/graph/all_factors.py) — find all factor combinations of a number
- [all_pairs_shortest_path](algorithms/graph/all_pairs_shortest_path.py) — Floyd-Warshall all-pairs shortest paths
- [bellman_ford](algorithms/graph/bellman_ford.py) — single-source shortest path with negative edge weights
- [blossom](algorithms/graph/blossom.py) — Edmonds' blossom algorithm for maximum matching in general graphs
- [check_bipartite](algorithms/graph/check_bipartite.py) — determine if a graph is two-colorable
- [check_digraph_strongly_connected](algorithms/graph/check_digraph_strongly_connected.py) — check if a directed graph is strongly connected
- [clone_graph](algorithms/graph/clone_graph.py) — deep-copy an undirected graph
- [count_connected_number_of_component](algorithms/graph/count_connected_number_of_component.py) — count connected components in an undirected graph
- [count_islands (BFS)](algorithms/graph/count_islands_bfs.py) — count islands in a grid using breadth-first search
- [count_islands (DFS)](algorithms/graph/count_islands_dfs.py) — count islands in a grid using depth-first search
- [count_islands (Union-Find)](algorithms/graph/count_islands_unionfind.py) — count islands using a disjoint-set structure
- [cycle_detection](algorithms/graph/cycle_detection.py) — detect cycles in a directed graph
- [dijkstra](algorithms/graph/dijkstra.py) — single-source shortest path for non-negative weights
- [dijkstra_heapq](algorithms/graph/dijkstra_heapq.py) — heap-optimised Dijkstra in O((V+E) log V) for sparse graphs
- [find_all_cliques](algorithms/graph/find_all_cliques.py) — Bron-Kerbosch algorithm for finding all cliques
- [find_path](algorithms/graph/find_path.py) — find paths between two vertices
- [kahns_algorithm](algorithms/graph/kahns_algorithm.py) — topological sort via in-degree counting (Kahn's)
- [markov_chain](algorithms/graph/markov_chain.py) — Markov chain probability modeling
- [maximum_flow](algorithms/graph/maximum_flow.py) — compute maximum flow in a flow network
- [maximum_flow (BFS)](algorithms/graph/maximum_flow_bfs.py) — Edmonds-Karp max-flow (BFS-based Ford-Fulkerson)
- [maximum_flow (DFS)](algorithms/graph/maximum_flow_dfs.py) — Ford-Fulkerson max-flow via DFS augmenting paths
- [maze_search (BFS)](algorithms/graph/maze_search_bfs.py) — find shortest path through a maze using BFS
- [maze_search (DFS)](algorithms/graph/maze_search_dfs.py) — find a path through a maze using DFS
- [minimum_spanning_tree](algorithms/graph/minimum_spanning_tree.py) — Kruskal's minimum spanning tree
- [pacific_atlantic](algorithms/graph/pacific_atlantic.py) — find cells that can flow to both oceans
- [path_between_two_vertices_in_digraph](algorithms/graph/path_between_two_vertices_in_digraph.py) — check if a path exists in a directed graph
- [prims_minimum_spanning](algorithms/graph/prims_minimum_spanning.py) — Prim's minimum spanning tree
- [satisfiability](algorithms/graph/satisfiability.py) — 2-SAT satisfiability via implication graph
- [shortest_distance_from_all_buildings](algorithms/graph/shortest_distance_from_all_buildings.py) — find the optimal meeting point in a grid
- [strongly_connected_components (Kosaraju)](algorithms/graph/strongly_connected_components_kosaraju.py) — Kosaraju's SCC algorithm
- [sudoku_solver](algorithms/graph/sudoku_solver.py) — solve a Sudoku puzzle using constraint backtracking
- [tarjan](algorithms/graph/tarjan.py) — Tarjan's strongly connected components algorithm
- [topological_sort (BFS)](algorithms/graph/topological_sort_bfs.py) — topological ordering using BFS (Kahn's variant)
- [topological_sort (DFS)](algorithms/graph/topological_sort_dfs.py) — topological ordering using DFS post-order
- [transitive_closure (DFS)](algorithms/graph/transitive_closure_dfs.py) — compute the transitive closure of a graph
- [traversal](algorithms/graph/traversal.py) — BFS and DFS graph traversal
- [walls_and_gates](algorithms/graph/walls_and_gates.py) — fill each empty room with distance to nearest gate
- [word_ladder](algorithms/graph/word_ladder.py) — shortest word-to-word transformation sequence
### Greedy
- [gale_shapley](algorithms/greedy/gale_shapley.py) — stable matching for bipartite preferences (Gale-Shapley)
- [max_contiguous_subsequence_sum](algorithms/greedy/max_contiguous_subsequence_sum.py) — maximum contiguous subarray sum (Kadane's algorithm)
### Heap
- [k_closest_points](algorithms/heap/k_closest_points.py) — find k points closest to the origin
- [merge_sorted_k_lists](algorithms/heap/merge_sorted_k_lists.py) — merge k sorted linked lists using a min-heap
- [skyline](algorithms/heap/skyline.py) — compute the skyline silhouette from building rectangles
- [sliding_window_max](algorithms/heap/sliding_window_max.py) — maximum value in each sliding window position
### Linked List
- [add_two_numbers](algorithms/linked_list/add_two_numbers.py) — add two numbers stored as reversed linked lists
- [copy_random_pointer](algorithms/linked_list/copy_random_pointer.py) — deep-copy a linked list with random pointers
- [delete_node](algorithms/linked_list/delete_node.py) — delete a node given only a reference to it
- [first_cyclic_node](algorithms/linked_list/first_cyclic_node.py) — find the first node where a cycle begins (Floyd's)
- [intersection](algorithms/linked_list/intersection.py) — find the intersection point of two singly linked lists
- [is_cyclic](algorithms/linked_list/is_cyclic.py) — detect whether a linked list has a cycle
- [is_palindrome](algorithms/linked_list/is_palindrome.py) — check if a linked list reads the same forwards and backwards
- [is_sorted](algorithms/linked_list/is_sorted.py) — check if a linked list is sorted in order
- [kth_to_last](algorithms/linked_list/kth_to_last.py) — find the k-th element from the end
- [merge_two_list](algorithms/linked_list/merge_two_list.py) — merge two sorted linked lists into one
- [partition](algorithms/linked_list/partition.py) — partition a list around a pivot value
- [remove_duplicates](algorithms/linked_list/remove_duplicates.py) — remove duplicate values from a linked list
- [remove_range](algorithms/linked_list/remove_range.py) — remove nodes within a given index range
- [reverse](algorithms/linked_list/reverse.py) — reverse a linked list iteratively and recursively
- [rotate_list](algorithms/linked_list/rotate_list.py) — rotate a list right by k positions
- [swap_in_pairs](algorithms/linked_list/swap_in_pairs.py) — swap every two adjacent nodes
### Map
- [is_anagram](algorithms/map/is_anagram.py) — check if two strings are anagrams via character counting
- [is_isomorphic](algorithms/map/is_isomorphic.py) — check if two strings have the same character mapping structure
- [longest_common_subsequence](algorithms/map/longest_common_subsequence.py) — longest common substring using a hash map
- [longest_palindromic_subsequence](algorithms/map/longest_palindromic_subsequence.py) — longest palindromic substring via hash map
- [randomized_set](algorithms/map/randomized_set.py) — O(1) insert, delete, and get-random data structure
- [valid_sudoku](algorithms/map/valid_sudoku.py) — validate a Sudoku board configuration
- [word_pattern](algorithms/map/word_pattern.py) — check if a string follows a given pattern mapping
### Math
- [base_conversion](algorithms/math/base_conversion.py) — convert integers between arbitrary number bases
- [chinese_remainder_theorem](algorithms/math/chinese_remainder_theorem.py) — solve a system of modular congruences
- [combination](algorithms/math/combination.py) — compute binomial coefficients (n choose r)
- [cosine_similarity](algorithms/math/cosine_similarity.py) — compute cosine similarity between two vectors
- [decimal_to_binary_ip](algorithms/math/decimal_to_binary_ip.py) — convert an IP address between decimal and binary
- [diffie_hellman_key_exchange](algorithms/math/diffie_hellman_key_exchange.py) — Diffie-Hellman cryptographic key exchange
- [distance_between_two_points](algorithms/math/distance_between_two_points.py) — Euclidean distance in 2D space
- [euler_totient](algorithms/math/euler_totient.py) — count integers up to n that are coprime to n
- [extended_gcd](algorithms/math/extended_gcd.py) — extended Euclidean algorithm (GCD with coefficients)
- [factorial](algorithms/math/factorial.py) — compute n! iteratively and recursively
- [fft](algorithms/math/fft.py) — Fast Fourier Transform (Cooley-Tukey)
- [find_order_simple](algorithms/math/find_order_simple.py) — find the multiplicative order of an element mod n
- [find_primitive_root_simple](algorithms/math/find_primitive_root_simple.py) — find a primitive root modulo a prime
- [gcd](algorithms/math/gcd.py) — greatest common divisor and least common multiple
- [generate_strobogrammtic](algorithms/math/generate_strobogrammtic.py) — generate strobogrammatic numbers of length n
- [goldbach](algorithms/math/goldbach.py) — decompose an even number into a sum of two primes (Goldbach's conjecture)
- [hailstone](algorithms/math/hailstone.py) — Collatz conjecture (hailstone) sequence
- [is_strobogrammatic](algorithms/math/is_strobogrammatic.py) — check if a number looks the same upside-down
- [krishnamurthy_number](algorithms/math/krishnamurthy_number.py) — check if a number equals the sum of the factorials of its digits
- [linear_regression](algorithms/math/linear_regression.py) — ordinary least-squares linear regression with R² and RMSE
- [magic_number](algorithms/math/magic_number.py) — check if a number is a magic number
- [manhattan_distance](algorithms/math/manhattan_distance.py) — compute Manhattan (L1) distance between two points in any dimension
- [modular_exponential](algorithms/math/modular_exponential.py) — compute (base^exp) mod m efficiently
- [modular_inverse](algorithms/math/modular_inverse.py) — compute the modular multiplicative inverse
- [next_bigger](algorithms/math/next_bigger.py) — next larger number with the same digits
- [next_perfect_square](algorithms/math/next_perfect_square.py) — find the next perfect square after n
- [nth_digit](algorithms/math/nth_digit.py) — find the n-th digit in the sequence 1, 2, 3, ...
- [num_digits](algorithms/math/num_digits.py) — count the number of digits in an integer
- [num_perfect_squares](algorithms/math/num_perfect_squares.py) — minimum perfect squares that sum to n
- [polynomial](algorithms/math/polynomial.py) — polynomial and monomial arithmetic operations
- [polynomial_division](algorithms/math/polynomial_division.py) — polynomial long division returning quotient and remainder
- [power](algorithms/math/power.py) — compute x^n via binary exponentiation
- [prime_check](algorithms/math/prime_check.py) — check if a number is prime
- [primes_sieve_of_eratosthenes](algorithms/math/primes_sieve_of_eratosthenes.py) — generate primes up to n using the Sieve of Eratosthenes
- [pythagoras](algorithms/math/pythagoras.py) — Pythagorean theorem calculations
- [rabin_miller](algorithms/math/rabin_miller.py) — Miller-Rabin probabilistic primality test
- [recursive_binomial_coefficient](algorithms/math/recursive_binomial_coefficient.py) — binomial coefficient via Pascal's triangle recursion
- [rsa](algorithms/math/rsa.py) — RSA public-key encryption and decryption
- [sqrt_precision_factor](algorithms/math/sqrt_precision_factor.py) — square root to arbitrary precision (Newton's method)
- [summing_digits](algorithms/math/summing_digits.py) — recursively sum the digits of a number
- [surface_area_of_torus](algorithms/math/surface_area_of_torus.py) — calculate the surface area of a torus
- [symmetry_group_cycle_index](algorithms/math/symmetry_group_cycle_index.py) — cycle index polynomials for symmetry groups
### Matrix
- [bomb_enemy](algorithms/matrix/bomb_enemy.py) — maximize enemies killed by a single bomb placement
- [cholesky_matrix_decomposition](algorithms/matrix/cholesky_matrix_decomposition.py) — Cholesky decomposition of a positive-definite matrix
- [copy_transform](algorithms/matrix/copy_transform.py) — copy and transform a matrix
- [count_paths](algorithms/matrix/count_paths.py) — count paths from top-left to bottom-right of a grid
- [crout_matrix_decomposition](algorithms/matrix/crout_matrix_decomposition.py) — Crout's LU matrix decomposition
- [matrix_exponentiation](algorithms/matrix/matrix_exponentiation.py) — raise a matrix to the n-th power efficiently
- [matrix_inversion](algorithms/matrix/matrix_inversion.py) — compute the inverse of a square matrix
- [multiply](algorithms/matrix/multiply.py) — standard and Strassen matrix multiplication
- [rotate_image](algorithms/matrix/rotate_image.py) — rotate an n x n matrix 90 degrees in-place
- [search_in_sorted_matrix](algorithms/matrix/search_in_sorted_matrix.py) — search in a row- and column-sorted matrix
- [sort_matrix_diagonally](algorithms/matrix/sort_matrix_diagonally.py) — sort each diagonal of a matrix independently
- [sparse_dot_vector](algorithms/matrix/sparse_dot_vector.py) — dot product of two sparse vectors
- [sparse_mul](algorithms/matrix/sparse_mul.py) — multiply two sparse matrices efficiently
- [spiral_traversal](algorithms/matrix/spiral_traversal.py) — traverse a matrix in spiral order
- [sudoku_validator](algorithms/matrix/sudoku_validator.py) — validate that a Sudoku board follows all rules
- [sum_sub_squares](algorithms/matrix/sum_sub_squares.py) — sum of all k x k sub-squares in a matrix
### Queue
- [max_sliding_window](algorithms/queue/max_sliding_window.py) — maximum in each sliding window using a deque
- [moving_average](algorithms/queue/moving_average.py) — compute a running moving average from a stream
- [reconstruct_queue](algorithms/queue/reconstruct_queue.py) — reconstruct a queue from (height, count) pairs
- [zigzagiterator](algorithms/queue/zigzagiterator.py) — alternate elements from multiple iterators
### Searching
- [binary_search](algorithms/searching/binary_search.py) — search a sorted array in O(log n)
- [exponential_search](algorithms/searching/exponential_search.py) — search a sorted array by doubling the range then binary searching
- [find_min_rotate](algorithms/searching/find_min_rotate.py) — find the minimum in a rotated sorted array
- [first_occurrence](algorithms/searching/first_occurrence.py) — find the first occurrence of a target value
- [generalized_binary_search](algorithms/searching/generalized_binary_search.py) — binary search with a custom predicate
- [interpolation_search](algorithms/searching/interpolation_search.py) — search using value-based interpolation
- [jump_search](algorithms/searching/jump_search.py) — search a sorted array by jumping in fixed blocks
- [last_occurrence](algorithms/searching/last_occurrence.py) — find the last occurrence of a target value
- [linear_search](algorithms/searching/linear_search.py) — sequential scan through an unsorted array
- [next_greatest_letter](algorithms/searching/next_greatest_letter.py) — find the smallest letter greater than a target
- [search_insert](algorithms/searching/search_insert.py) — find the insertion position for a target value
- [search_range](algorithms/searching/search_range.py) — find the first and last positions of a target
- [search_rotate](algorithms/searching/search_rotate.py) — search in a rotated sorted array
- [sentinel_search](algorithms/searching/sentinel_search.py) — linear search optimized by placing a sentinel at the end
- [ternary_search](algorithms/searching/ternary_search.py) — search by dividing the array into three parts
- [two_sum](algorithms/searching/two_sum.py) — find two numbers that sum to a target
### Set
- [find_keyboard_row](algorithms/set/find_keyboard_row.py) — filter words that can be typed on one keyboard row
- [randomized_set](algorithms/set/randomized_set.py) — O(1) insert, delete, and random-element access
- [set_covering](algorithms/set/set_covering.py) — greedy approximation for the set cover problem
### Sorting
- [bead_sort](algorithms/sorting/bead_sort.py) — gravity-based natural sorting (bead/abacus sort)
- [bitonic_sort](algorithms/sorting/bitonic_sort.py) — parallel-friendly comparison sort via bitonic sequences
- [bogo_sort](algorithms/sorting/bogo_sort.py) — random permutation sort (intentionally inefficient)
- [bubble_sort](algorithms/sorting/bubble_sort.py) — repeatedly swap adjacent out-of-order elements
- [bucket_sort](algorithms/sorting/bucket_sort.py) — distribute elements into buckets, then sort each
- [cocktail_shaker_sort](algorithms/sorting/cocktail_shaker_sort.py) — bidirectional bubble sort
- [comb_sort](algorithms/sorting/comb_sort.py) — bubble sort improved with a shrinking gap
- [counting_sort](algorithms/sorting/counting_sort.py) — sort integers by counting occurrences
- [cycle_sort](algorithms/sorting/cycle_sort.py) — in-place sort that minimizes total writes
- [exchange_sort](algorithms/sorting/exchange_sort.py) — simple pairwise comparison and exchange
- [gnome_sort](algorithms/sorting/gnome_sort.py) — sort by swapping elements backward until ordered
- [heap_sort](algorithms/sorting/heap_sort.py) — sort via a binary heap (in-place, O(n log n))
- [insertion_sort](algorithms/sorting/insertion_sort.py) — build a sorted portion one element at a time
- [meeting_rooms](algorithms/sorting/meeting_rooms.py) — determine if meeting intervals overlap
- [merge_sort](algorithms/sorting/merge_sort.py) — divide-and-conquer stable sort (O(n log n))
- [pancake_sort](algorithms/sorting/pancake_sort.py) — sort using only prefix reversals
- [pigeonhole_sort](algorithms/sorting/pigeonhole_sort.py) — sort by placing elements into pigeonhole buckets
- [quick_sort](algorithms/sorting/quick_sort.py) — partition-based divide-and-conquer sort
- [radix_sort](algorithms/sorting/radix_sort.py) — non-comparative sort processing one digit at a time
- [selection_sort](algorithms/sorting/selection_sort.py) — repeatedly select the minimum and swap it forward
- [shell_sort](algorithms/sorting/shell_sort.py) — generalized insertion sort with a decreasing gap sequence
- [sort_colors](algorithms/sorting/sort_colors.py) — Dutch national flag three-way partition
- [stooge_sort](algorithms/sorting/stooge_sort.py) — recursive sort by dividing into overlapping thirds
- [wiggle_sort](algorithms/sorting/wiggle_sort.py) — rearrange into an alternating peak-valley pattern
### Stack
- [is_consecutive](algorithms/stack/is_consecutive.py) — check if stack elements are consecutive integers
- [is_sorted](algorithms/stack/is_sorted.py) — check if a stack is sorted in ascending order
- [longest_abs_path](algorithms/stack/longest_abs_path.py) — find the longest absolute file path in a file system string
- [ordered_stack](algorithms/stack/ordered_stack.py) — maintain a stack in sorted order
- [remove_min](algorithms/stack/remove_min.py) — remove the minimum element from a stack
- [simplify_path](algorithms/stack/simplify_path.py) — simplify a Unix-style file path
- [stutter](algorithms/stack/stutter.py) — duplicate each element in a stack
- [switch_pairs](algorithms/stack/switch_pairs.py) — swap adjacent pairs of stack elements
- [valid_parenthesis](algorithms/stack/valid_parenthesis.py) — check for balanced parentheses / brackets
### Streaming
- [misra_gries](algorithms/streaming/misra_gries.py) — approximate frequent-item detection in a data stream
- [one_sparse_recovery](algorithms/streaming/one_sparse_recovery.py) — recover a single non-zero element from a stream
### String
- [add_binary](algorithms/string/add_binary.py) — add two binary number strings
- [alphabet_board_path](algorithms/string/alphabet_board_path.py) — navigate a 5×5 alphabet board to spell a target word
- [atbash_cipher](algorithms/string/atbash_cipher.py) — Atbash substitution cipher (reverse the alphabet)
- [breaking_bad](algorithms/string/breaking_bad.py) — spell a string using periodic-table element symbols
- [caesar_cipher](algorithms/string/caesar_cipher.py) — Caesar shift cipher encryption / decryption
- [check_pangram](algorithms/string/check_pangram.py) — check if a string contains every letter of the alphabet
- [contain_string](algorithms/string/contain_string.py) — find a substring in a string (strStr)
- [count_binary_substring](algorithms/string/count_binary_substring.py) — count substrings with equal consecutive 0s and 1s
- [decode_string](algorithms/string/decode_string.py) — decode a run-length encoded string like `3[a2[c]]`
- [delete_reoccurring](algorithms/string/delete_reoccurring.py) — remove consecutive duplicate characters
- [domain_extractor](algorithms/string/domain_extractor.py) — extract a domain name from a URL
- [encode_decode](algorithms/string/encode_decode.py) — encode and decode a list of strings
- [first_unique_char](algorithms/string/first_unique_char.py) — find the first non-repeating character
- [fizzbuzz](algorithms/string/fizzbuzz.py) — classic FizzBuzz problem
- [group_anagrams](algorithms/string/group_anagrams.py) — group strings that are anagrams of each other
- [int_to_roman](algorithms/string/int_to_roman.py) — convert an integer to a Roman numeral string
- [is_palindrome](algorithms/string/is_palindrome.py) — check if a string reads the same forwards and backwards
- [is_rotated](algorithms/string/is_rotated.py) — check if one string is a rotation of another
- [judge_circle](algorithms/string/judge_circle.py) — determine if a sequence of moves returns to the origin
- [knuth_morris_pratt](algorithms/string/knuth_morris_pratt.py) — KMP linear-time pattern matching
- [license_number](algorithms/string/license_number.py) — reformat a license key string with dashes
- [longest_common_prefix](algorithms/string/longest_common_prefix.py) — find the longest common prefix among strings
- [longest_palindromic_substring](algorithms/string/longest_palindromic_substring.py) — find the longest palindromic substring
- [make_sentence](algorithms/string/make_sentence.py) — break a string into valid dictionary words
- [manacher](algorithms/string/manacher.py) — find the longest palindromic substring in O(n) time
- [merge_string_checker](algorithms/string/merge_string_checker.py) — check if a string is a valid merge of two others
- [min_distance](algorithms/string/min_distance.py) — minimum deletions to make two strings equal
- [multiply_strings](algorithms/string/multiply_strings.py) — multiply two numbers represented as strings
- [one_edit_distance](algorithms/string/one_edit_distance.py) — check if two strings are exactly one edit apart
- [panagram](algorithms/string/panagram.py) — find missing letters to complete a pangram
- [rabin_karp](algorithms/string/rabin_karp.py) — Rabin-Karp rolling-hash pattern matching
- [repeat_string](algorithms/string/repeat_string.py) — minimum string repeats to contain a substring
- [repeat_substring](algorithms/string/repeat_substring.py) — check if a string is built from a repeating pattern
- [reverse_string](algorithms/string/reverse_string.py) — reverse a string in-place
- [reverse_vowel](algorithms/string/reverse_vowel.py) — reverse only the vowels in a string
- [reverse_words](algorithms/string/reverse_words.py) — reverse the order of words in a string
- [roman_to_int](algorithms/string/roman_to_int.py) — convert a Roman numeral string to an integer
- [rotate](algorithms/string/rotate.py) — rotate a string by k positions
- [strip_url_params](algorithms/string/strip_url_params.py) — remove duplicate query parameters from a URL
- [swap_characters](algorithms/string/swap_characters.py) — check if one character swap can make two strings equal
- [strong_password](algorithms/string/strong_password.py) — check minimum changes needed for a strong password
- [text_justification](algorithms/string/text_justification.py) — justify text lines to a specified width
- [unique_morse](algorithms/string/unique_morse.py) — count unique Morse code representations of words
- [validate_coordinates](algorithms/string/validate_coordinates.py) — validate geographic latitude/longitude coordinates
- [word_squares](algorithms/string/word_squares.py) — find all valid word squares from a word list
- [z_algorithm](algorithms/string/z_algorithm.py) — Z-array computation for linear-time pattern matching
### Tree
- [bin_tree_to_list](algorithms/tree/bin_tree_to_list.py) — convert a binary tree to a doubly linked list
- [binary_tree_paths](algorithms/tree/binary_tree_paths.py) — enumerate all root-to-leaf paths
- [binary_tree_views](algorithms/tree/binary_tree_views.py) — left, right, top, and bottom views of a binary tree
- [bst_array_to_bst](algorithms/tree/bst_array_to_bst.py) — convert a sorted array into a height-balanced BST
- [bst_closest_value](algorithms/tree/bst_closest_value.py) — find the value closest to a target in a BST
- [bst_count_left_node](algorithms/tree/bst_count_left_node.py) — count the number of left-child nodes
- [bst_delete_node](algorithms/tree/bst_delete_node.py) — delete a node from a BST while preserving order
- [bst_depth_sum](algorithms/tree/bst_depth_sum.py) — sum of node values weighted by their depth
- [bst_height](algorithms/tree/bst_height.py) — calculate the height of a binary tree
- [bst_is_bst](algorithms/tree/bst_is_bst.py) — validate the binary search tree property
- [bst_iterator](algorithms/tree/bst_iterator.py) — lazy in-order iterator for a BST
- [bst_kth_smallest](algorithms/tree/bst_kth_smallest.py) — find the k-th smallest element in a BST
- [bst_lowest_common_ancestor](algorithms/tree/bst_lowest_common_ancestor.py) — lowest common ancestor exploiting BST ordering
- [bst_num_empty](algorithms/tree/bst_num_empty.py) — count empty (null) branches in a tree
- [bst_predecessor](algorithms/tree/bst_predecessor.py) — find the in-order predecessor of a BST node
- [bst_serialize_deserialize](algorithms/tree/bst_serialize_deserialize.py) — serialize a BST to a string and back
- [bst_successor](algorithms/tree/bst_successor.py) — find the in-order successor of a BST node
- [bst_unique_bst](algorithms/tree/bst_unique_bst.py) — count structurally unique BSTs for n keys (Catalan number)
- [bst_validate_bst](algorithms/tree/bst_validate_bst.py) — validate a BST using min/max range constraints
- [construct_tree_postorder_preorder](algorithms/tree/construct_tree_postorder_preorder.py) — reconstruct a tree from pre-order and post-order traversals
- [deepest_left](algorithms/tree/deepest_left.py) — find the deepest left leaf node
- [invert_tree](algorithms/tree/invert_tree.py) — mirror a binary tree (swap all left/right children)
- [is_balanced](algorithms/tree/is_balanced.py) — check if a tree is height-balanced
- [is_subtree](algorithms/tree/is_subtree.py) — check if one tree is a subtree of another
- [is_symmetric](algorithms/tree/is_symmetric.py) — check if a tree is a mirror of itself
- [longest_consecutive](algorithms/tree/longest_consecutive.py) — longest consecutive-value sequence in a tree
- [lowest_common_ancestor](algorithms/tree/lowest_common_ancestor.py) — find the lowest common ancestor of two nodes
- [max_height](algorithms/tree/max_height.py) — maximum depth (height) of a binary tree
- [max_path_sum](algorithms/tree/max_path_sum.py) — maximum sum along any path between two nodes
- [min_height](algorithms/tree/min_height.py) — minimum depth from root to the nearest leaf
- [path_sum](algorithms/tree/path_sum.py) — check if any root-to-leaf path sums to a target
- [path_sum2](algorithms/tree/path_sum2.py) — find all root-to-leaf paths that sum to a target
- [pretty_print](algorithms/tree/pretty_print.py) — pretty-print a binary tree to the console
- [same_tree](algorithms/tree/same_tree.py) — check if two binary trees are structurally identical
- [traversal_inorder](algorithms/tree/traversal_inorder.py) — in-order traversal (left, root, right)
- [traversal_level_order](algorithms/tree/traversal_level_order.py) — level-order (breadth-first) traversal
- [traversal_postorder](algorithms/tree/traversal_postorder.py) — post-order traversal (left, right, root)
- [traversal_preorder](algorithms/tree/traversal_preorder.py) — pre-order traversal (root, left, right)
- [traversal_zigzag](algorithms/tree/traversal_zigzag.py) — zigzag (alternating direction) level-order traversal
- [trie_add_and_search](algorithms/tree/trie_add_and_search.py) — trie with wildcard `.` search support
## Contributing
Thanks for your interest in contributing! There are many ways to get involved. See [CONTRIBUTING.md](CONTRIBUTING.md) for details.
## Maintainers
- [Keon Kim](https://github.com/keon)
## Contributors
Thanks to [all the contributors](https://github.com/keon/algorithms/graphs/contributors) who helped build this repo.
## License
[MIT](LICENSE)
================================================
FILE: algorithms/__init__.py
================================================
"""Pythonic data structures and algorithms for education.
Shared types are available at the top level::
>>> from algorithms import TreeNode, ListNode, Graph
>>> from algorithms.data_structures import BinaryHeap, HashTable
>>> from algorithms.graph import dijkstra
"""
import algorithms.data_structures as data_structures # noqa: F401
from algorithms.common import Graph, ListNode, TreeNode
__all__ = ["TreeNode", "ListNode", "Graph", "data_structures"]
================================================
FILE: algorithms/array/__init__.py
================================================
from .delete_nth import delete_nth, delete_nth_naive
from .flatten import flatten, flatten_iter
from .garage import garage
from .josephus import josephus
from .limit import limit
from .longest_non_repeat import (
get_longest_non_repeat_v1,
get_longest_non_repeat_v2,
get_longest_non_repeat_v3,
longest_non_repeat_v1,
longest_non_repeat_v2,
)
from .max_ones_index import max_ones_index
from .merge_intervals import Interval, merge_intervals
from .missing_ranges import missing_ranges
from .move_zeros import move_zeros
from .n_sum import n_sum
from .plus_one import plus_one_v1, plus_one_v2, plus_one_v3
from .remove_duplicates import remove_duplicates
from .rotate import rotate_v1, rotate_v2, rotate_v3
from .summarize_ranges import summarize_ranges
from .three_sum import three_sum
from .top_1 import top_1
from .trimmean import trimmean
from .two_sum import two_sum
__all__ = [
"delete_nth",
"delete_nth_naive",
"flatten",
"flatten_iter",
"garage",
"josephus",
"limit",
"get_longest_non_repeat_v1",
"get_longest_non_repeat_v2",
"get_longest_non_repeat_v3",
"longest_non_repeat_v1",
"longest_non_repeat_v2",
"max_ones_index",
"Interval",
"merge_intervals",
"missing_ranges",
"move_zeros",
"n_sum",
"plus_one_v1",
"plus_one_v2",
"plus_one_v3",
"remove_duplicates",
"rotate_v1",
"rotate_v2",
"rotate_v3",
"summarize_ranges",
"three_sum",
"top_1",
"trimmean",
"two_sum",
]
================================================
FILE: algorithms/array/delete_nth.py
================================================
"""
Delete Nth Occurrence
Given a list and a number N, create a new list that contains each element
of the original list at most N times, without reordering.
Reference: https://www.geeksforgeeks.org/remove-duplicates-from-an-array/
Complexity:
delete_nth_naive:
Time: O(n^2) due to list.count()
Space: O(n)
delete_nth:
Time: O(n)
Space: O(n)
"""
from __future__ import annotations
import collections
def delete_nth_naive(array: list[int], n: int) -> list[int]:
"""Keep at most n copies of each element using naive counting.
Args:
array: Source list of integers.
n: Maximum number of allowed occurrences per element.
Returns:
New list with each element appearing at most n times.
Examples:
>>> delete_nth_naive([1, 2, 3, 1, 2, 1, 2, 3], 2)
[1, 2, 3, 1, 2, 3]
"""
result = []
for num in array:
if result.count(num) < n:
result.append(num)
return result
def delete_nth(array: list[int], n: int) -> list[int]:
"""Keep at most n copies of each element using a hash table.
Args:
array: Source list of integers.
n: Maximum number of allowed occurrences per element.
Returns:
New list with each element appearing at most n times.
Examples:
>>> delete_nth([1, 2, 3, 1, 2, 1, 2, 3], 2)
[1, 2, 3, 1, 2, 3]
"""
result = []
counts = collections.defaultdict(int)
for element in array:
if counts[element] < n:
result.append(element)
counts[element] += 1
return result
================================================
FILE: algorithms/array/flatten.py
================================================
"""
Flatten Arrays
Given an array that may contain nested arrays, produce a single
flat resultant array.
Reference: https://en.wikipedia.org/wiki/Flatten_(higher-order_function)
Complexity:
Time: O(n) where n is the total number of elements
Space: O(n)
"""
from __future__ import annotations
from collections.abc import Generator, Iterable
from typing import Any
def flatten(input_arr: Iterable[Any], output_arr: list[Any] | None = None) -> list[Any]:
"""Recursively flatten a nested iterable into a single list.
Args:
input_arr: A potentially nested iterable to flatten.
output_arr: Accumulator list for recursive calls (internal use).
Returns:
A flat list containing all leaf elements.
Examples:
>>> flatten([2, 1, [3, [4, 5], 6], 7, [8]])
[2, 1, 3, 4, 5, 6, 7, 8]
"""
if output_arr is None:
output_arr = []
for element in input_arr:
if not isinstance(element, str) and isinstance(element, Iterable):
flatten(element, output_arr)
else:
output_arr.append(element)
return output_arr
def flatten_iter(iterable: Iterable[Any]) -> Generator[Any, None, None]:
"""Lazily flatten a nested iterable, yielding one element at a time.
Args:
iterable: A potentially nested iterable to flatten.
Returns:
A generator producing one-dimensional output.
Examples:
>>> list(flatten_iter([2, 1, [3, [4, 5], 6], 7, [8]]))
[2, 1, 3, 4, 5, 6, 7, 8]
"""
for element in iterable:
if not isinstance(element, str) and isinstance(element, Iterable):
yield from flatten_iter(element)
else:
yield element
================================================
FILE: algorithms/array/garage.py
================================================
"""
Garage Parking Rearrangement
There is a parking lot with only one empty spot (represented by 0). Given the
initial and final states, find the minimum number of moves to rearrange the lot.
Each move swaps a car into the empty spot.
Reference: https://en.wikipedia.org/wiki/15_puzzle
Complexity:
Time: O(n^2) worst case
Space: O(n) for storing the sequence
"""
from __future__ import annotations
def garage(initial: list[int], final: list[int]) -> tuple[int, list[list[int]]]:
"""Find the minimum swaps to rearrange a parking lot from initial to final state.
Args:
initial: Starting arrangement where 0 represents the empty spot.
final: Desired arrangement where 0 represents the empty spot.
Returns:
A tuple of (number_of_steps, sequence_of_states) showing each
intermediate arrangement.
Examples:
>>> garage([1, 2, 3, 0, 4], [0, 3, 2, 1, 4])
(4, [[0, 2, 3, 1, 4], [2, 0, 3, 1, 4], [2, 3, 0, 1, 4], [0, 3, 2, 1, 4]])
"""
current = initial[::]
sequence = []
steps = 0
while current != final:
zero_pos = current.index(0)
if zero_pos != final.index(0):
target_car = final[zero_pos]
target_pos = current.index(target_car)
current[zero_pos], current[target_pos] = (
current[target_pos],
current[zero_pos],
)
else:
for i in range(len(current)):
if current[i] != final[i]:
current[zero_pos], current[i] = current[i], current[zero_pos]
break
sequence.append(current[::])
steps += 1
return steps, sequence
================================================
FILE: algorithms/array/josephus.py
================================================
"""
Josephus Problem
People sit in a circular fashion; every k-th person is eliminated until
everyone has been removed. Yield the elimination order.
Reference: https://en.wikipedia.org/wiki/Josephus_problem
Complexity:
Time: O(n^2) due to list.pop at arbitrary index
Space: O(1) auxiliary (yields in-place)
"""
from __future__ import annotations
from collections.abc import Generator
from typing import Any
def josephus(items: list[Any], skip: int) -> Generator[Any, None, None]:
"""Yield elements eliminated in Josephus-problem order.
Args:
items: List of participants arranged in a circle.
skip: Every *skip*-th person is eliminated each round.
Returns:
A generator yielding eliminated elements in order.
Examples:
>>> list(josephus([1, 2, 3, 4, 5, 6, 7, 8, 9], 3))
[3, 6, 9, 4, 8, 5, 2, 7, 1]
"""
skip = skip - 1
index = 0
remaining = len(items)
while remaining > 0:
index = (skip + index) % remaining
yield items.pop(index)
remaining -= 1
================================================
FILE: algorithms/array/limit.py
================================================
"""
Limit Array Values
Filter an array to include only elements within a specified minimum and
maximum range (inclusive).
Reference: https://en.wikipedia.org/wiki/Clipping_(signal_processing)
Complexity:
Time: O(n)
Space: O(n)
"""
from __future__ import annotations
def limit(
array: list[int],
min_lim: int | None = None,
max_lim: int | None = None,
) -> list[int]:
"""Return elements of array that fall within [min_lim, max_lim].
Args:
array: Source list of integers.
min_lim: Minimum value (inclusive). Defaults to the array minimum.
max_lim: Maximum value (inclusive). Defaults to the array maximum.
Returns:
A new list containing only values within the specified range.
Examples:
>>> limit([1, 2, 3, 4, 5], 2, 4)
[2, 3, 4]
"""
if len(array) == 0:
return array
if min_lim is None:
min_lim = min(array)
if max_lim is None:
max_lim = max(array)
return list(filter(lambda x: min_lim <= x <= max_lim, array))
================================================
FILE: algorithms/array/longest_non_repeat.py
================================================
"""
Longest Substring Without Repeating Characters
Given a string, find the length of the longest substring without repeating
characters. Multiple algorithm variants are provided.
Reference: https://leetcode.com/problems/longest-substring-without-repeating-characters/
Complexity:
Time: O(n) for all variants
Space: O(min(n, m)) where m is the charset size
"""
from __future__ import annotations
def longest_non_repeat_v1(string: str) -> int:
"""Find the length of the longest substring without repeating characters.
Args:
string: Input string to search.
Returns:
Length of the longest non-repeating substring.
Examples:
>>> longest_non_repeat_v1("abcabcbb")
3
"""
if string is None:
return 0
char_index = {}
max_length = 0
start = 0
for index in range(len(string)):
if string[index] in char_index:
start = max(char_index[string[index]], start)
char_index[string[index]] = index + 1
max_length = max(max_length, index - start + 1)
return max_length
def longest_non_repeat_v2(string: str) -> int:
"""Find the length of the longest substring without repeating characters.
Args:
string: Input string to search.
Returns:
Length of the longest non-repeating substring.
Examples:
>>> longest_non_repeat_v2("abcabcbb")
3
"""
if string is None:
return 0
start, max_length = 0, 0
used_char = {}
for index, char in enumerate(string):
if char in used_char and start <= used_char[char]:
start = used_char[char] + 1
else:
max_length = max(max_length, index - start + 1)
used_char[char] = index
return max_length
def get_longest_non_repeat_v1(string: str) -> tuple[int, str]:
"""Find the longest substring without repeating characters.
Args:
string: Input string to search.
Returns:
A tuple of (length, substring) for the longest non-repeating substring.
Examples:
>>> get_longest_non_repeat_v1("abcabcbb")
(3, 'abc')
"""
if string is None:
return 0, ""
substring = ""
char_index = {}
max_length = 0
start = 0
for index in range(len(string)):
if string[index] in char_index:
start = max(char_index[string[index]], start)
char_index[string[index]] = index + 1
if index - start + 1 > max_length:
max_length = index - start + 1
substring = string[start : index + 1]
return max_length, substring
def get_longest_non_repeat_v2(string: str) -> tuple[int, str]:
"""Find the longest substring without repeating characters.
Args:
string: Input string to search.
Returns:
A tuple of (length, substring) for the longest non-repeating substring.
Examples:
>>> get_longest_non_repeat_v2("abcabcbb")
(3, 'abc')
"""
if string is None:
return 0, ""
substring = ""
start, max_length = 0, 0
used_char = {}
for index, char in enumerate(string):
if char in used_char and start <= used_char[char]:
start = used_char[char] + 1
else:
if index - start + 1 > max_length:
max_length = index - start + 1
substring = string[start : index + 1]
used_char[char] = index
return max_length, substring
def get_longest_non_repeat_v3(string: str) -> tuple[int, str]:
"""Find the longest substring without repeating characters using sliding window.
Args:
string: Input string to search.
Returns:
A tuple of (length, substring) for the longest non-repeating substring.
Examples:
>>> get_longest_non_repeat_v3("abcabcbb")
(3, 'abc')
"""
longest_substring = ""
seen = set()
start_index = 0
for i in range(len(string)):
while string[i] in seen:
seen.remove(string[start_index])
start_index += 1
seen.add(string[i])
longest_substring = max(longest_substring, string[start_index : i + 1], key=len)
return len(longest_substring), longest_substring
================================================
FILE: algorithms/array/max_ones_index.py
================================================
"""
Max Ones Index
Find the index of the 0 that, when replaced with 1, produces the longest
continuous sequence of 1s in a binary array. Returns -1 if no 0 exists.
Reference: https://www.geeksforgeeks.org/find-index-0-replaced-1-get-longest-continuous-sequence-1s-binary-array/
Complexity:
Time: O(n)
Space: O(1)
"""
from __future__ import annotations
def max_ones_index(array: list[int]) -> int:
"""Find the index of 0 to replace with 1 for the longest run of 1s.
Args:
array: Binary array containing only 0s and 1s.
Returns:
Index of the 0 to flip, or -1 if no 0 exists.
Examples:
>>> max_ones_index([1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1])
3
"""
length = len(array)
max_count = 0
max_index = 0
prev_zero = -1
prev_prev_zero = -1
for current in range(length):
if array[current] == 0:
if current - prev_prev_zero > max_count:
max_count = current - prev_prev_zero
max_index = prev_zero
prev_prev_zero = prev_zero
prev_zero = current
if length - prev_prev_zero > max_count:
max_index = prev_zero
return max_index
================================================
FILE: algorithms/array/merge_intervals.py
================================================
"""
Merge Intervals
Given a collection of intervals, merge all overlapping intervals into a
consolidated set.
Reference: https://en.wikipedia.org/wiki/Interval_(mathematics)
Complexity:
Time: O(n log n) due to sorting
Space: O(n)
"""
from __future__ import annotations
class Interval:
"""A numeric interval [start, end) with merge and comparison support.
Args:
start: Lower bound of the interval.
end: Upper bound of the interval.
"""
def __init__(self, start: int = 0, end: int = 0) -> None:
self.start = start
self.end = end
def __repr__(self) -> str:
return f"Interval ({self.start}, {self.end})"
def __iter__(self):
return iter(range(self.start, self.end))
def __getitem__(self, index: int) -> int:
if index < 0:
return self.end + index
return self.start + index
def __len__(self) -> int:
return self.end - self.start
def __contains__(self, item: int) -> bool:
return self.start >= item >= self.end
def __eq__(self, other: object) -> bool:
if not isinstance(other, Interval):
return NotImplemented
return self.start == other.start and self.end == other.end
def as_list(self) -> list[int]:
"""Return interval as a list of integers.
Returns:
List of integers in the interval range.
"""
return list(self)
@staticmethod
def merge(intervals: list[Interval]) -> list[Interval]:
"""Merge overlapping intervals into a consolidated list.
Args:
intervals: List of Interval objects to merge.
Returns:
List of merged, non-overlapping Interval objects.
Examples:
>>> Interval.merge([Interval(1, 3), Interval(2, 6)])
[Interval (1, 6)]
"""
out = []
for interval in sorted(intervals, key=lambda i: i.start):
if out and interval.start <= out[-1].end:
out[-1].end = max(out[-1].end, interval.end)
else:
out += (interval,)
return out
@staticmethod
def print_intervals(intervals: list[Interval]) -> str:
"""Format intervals as a string representation.
Args:
intervals: List of Interval objects to format.
Returns:
String representation of all intervals.
Examples:
>>> Interval.print_intervals([Interval(1, 3)])
'Interval (1, 3)'
"""
result = []
for interval in intervals:
result.append(repr(interval))
return "".join(result)
def merge_intervals(intervals: list[list[int]]) -> list[list[int]] | None:
"""Merge overlapping intervals represented as nested lists.
Args:
intervals: List of [start, end] pairs to merge.
Returns:
List of merged [start, end] pairs, or None if input is None.
Examples:
>>> merge_intervals([[1, 3], [2, 6], [8, 10]])
[[1, 6], [8, 10]]
"""
if intervals is None:
return None
intervals.sort(key=lambda i: i[0])
out = [intervals.pop(0)]
for interval in intervals:
if out[-1][-1] >= interval[0]:
out[-1][-1] = max(out[-1][-1], interval[-1])
else:
out.append(interval)
return out
================================================
FILE: algorithms/array/missing_ranges.py
================================================
"""
Missing Ranges
Find the ranges of numbers that are missing between a given low and high
bound, given a sorted array of integers.
Reference: https://leetcode.com/problems/missing-ranges/
Complexity:
Time: O(n)
Space: O(n) for the result list
"""
from __future__ import annotations
def missing_ranges(array: list[int], low: int, high: int) -> list[tuple[int, int]]:
"""Find gaps between low and high not covered by elements in array.
Args:
array: Sorted list of integers within [low, high].
low: Lower bound of the expected range (inclusive).
high: Upper bound of the expected range (inclusive).
Returns:
List of (start, end) tuples representing missing ranges.
Examples:
>>> missing_ranges([3, 5], 1, 10)
[(1, 2), (4, 4), (6, 10)]
"""
result = []
start = low
for num in array:
if num == start:
start += 1
elif num > start:
result.append((start, num - 1))
start = num + 1
if start <= high:
result.append((start, high))
return result
================================================
FILE: algorithms/array/move_zeros.py
================================================
"""
Move Zeros
Move all zeros in an array to the end while preserving the relative order
of the non-zero (and non-integer-zero) elements.
Reference: https://leetcode.com/problems/move-zeroes/
Complexity:
Time: O(n)
Space: O(n)
"""
from __future__ import annotations
from typing import Any
def move_zeros(array: list[Any]) -> list[Any]:
"""Move all integer zeros to the end, preserving order of other elements.
Boolean False is not treated as zero.
Args:
array: Input list with mixed types.
Returns:
New list with all integer 0s moved to the end.
Examples:
>>> move_zeros([False, 1, 0, 1, 2, 0, 1, 3, "a"])
[False, 1, 1, 2, 1, 3, 'a', 0, 0]
"""
result = []
zeros = 0
for element in array:
if element == 0 and type(element) is not bool:
zeros += 1
else:
result.append(element)
result.extend([0] * zeros)
return result
================================================
FILE: algorithms/array/n_sum.py
================================================
"""
N-Sum
Given an array of integers, find all unique n-tuples that sum to a target
value. Supports custom sum, comparison, and equality closures for advanced
use cases with non-integer elements.
Reference: https://leetcode.com/problems/4sum/
Complexity:
Time: O(n^(k-1)) where k is the tuple size
Space: O(n^(k-1)) for storing results
"""
from __future__ import annotations
from collections.abc import Callable
from typing import Any
def n_sum(
n: int,
nums: list[Any],
target: Any,
**kv: Callable[..., Any],
) -> list[list[Any]]:
"""Find all unique n-tuples in nums that sum to target.
Args:
n: Size of each tuple to find.
nums: List of elements to search.
target: Desired sum for each n-tuple.
**kv: Optional closures:
sum_closure(a, b) - returns sum of two elements.
compare_closure(num, target) - returns -1, 0, or 1.
same_closure(a, b) - returns True if elements are equal.
Returns:
Sorted list of unique n-tuples (as lists) that sum to target.
Examples:
>>> n_sum(3, [-1, 0, 1, 2, -1, -4], 0)
[[-1, -1, 2], [-1, 0, 1]]
"""
def _sum_closure_default(a: Any, b: Any) -> Any:
return a + b
def _compare_closure_default(num: Any, target: Any) -> int:
if num < target:
return -1
elif num > target:
return 1
else:
return 0
def _same_closure_default(a: Any, b: Any) -> bool:
return a == b
def _n_sum_inner(n: int, nums: list[Any], target: Any) -> list[list[Any]]:
if n == 2:
results = _two_sum(nums, target)
else:
results = []
prev_num = None
for index, num in enumerate(nums):
if prev_num is not None and same_closure(prev_num, num):
continue
prev_num = num
n_minus1_results = _n_sum_inner(
n - 1,
nums[index + 1 :],
target - num,
)
n_minus1_results = _append_elem_to_each_list(num, n_minus1_results)
results += n_minus1_results
return _union(results)
def _two_sum(nums: list[Any], target: Any) -> list[list[Any]]:
nums.sort()
left = 0
right = len(nums) - 1
results = []
while left < right:
current_sum = sum_closure(nums[left], nums[right])
flag = compare_closure(current_sum, target)
if flag == -1:
left += 1
elif flag == 1:
right -= 1
else:
results.append(sorted([nums[left], nums[right]]))
left += 1
right -= 1
while left < len(nums) and same_closure(nums[left - 1], nums[left]):
left += 1
while right >= 0 and same_closure(nums[right], nums[right + 1]):
right -= 1
return results
def _append_elem_to_each_list(
elem: Any, container: list[list[Any]]
) -> list[list[Any]]:
results = []
for elems in container:
elems.append(elem)
results.append(sorted(elems))
return results
def _union(
duplicate_results: list[list[Any]],
) -> list[list[Any]]:
results = []
if len(duplicate_results) != 0:
duplicate_results.sort()
results.append(duplicate_results[0])
for result in duplicate_results[1:]:
if results[-1] != result:
results.append(result)
return results
sum_closure = kv.get("sum_closure", _sum_closure_default)
same_closure = kv.get("same_closure", _same_closure_default)
compare_closure = kv.get("compare_closure", _compare_closure_default)
nums.sort()
return _n_sum_inner(n, nums, target)
================================================
FILE: algorithms/array/plus_one.py
================================================
"""
Plus One
Given a non-negative number represented as an array of digits (big-endian),
add one to the number and return the resulting digit array.
Reference: https://leetcode.com/problems/plus-one/
Complexity:
Time: O(n)
Space: O(n) for v1, O(1) auxiliary for v2 and v3
"""
from __future__ import annotations
def plus_one_v1(digits: list[int]) -> list[int]:
"""Add one to a big-endian digit array using manual carry propagation.
Args:
digits: Non-empty list of digits representing a non-negative integer.
Returns:
New list of digits representing the input number plus one.
Examples:
>>> plus_one_v1([1, 2, 9])
[1, 3, 0]
"""
digits[-1] = digits[-1] + 1
result = []
carry = 0
index = len(digits) - 1
while index >= 0 or carry == 1:
digit_sum = 0
if index >= 0:
digit_sum += digits[index]
if carry:
digit_sum += 1
result.append(digit_sum % 10)
carry = digit_sum // 10
index -= 1
return result[::-1]
def plus_one_v2(digits: list[int]) -> list[int]:
"""Add one to a big-endian digit array by scanning from the right.
Args:
digits: Non-empty list of digits representing a non-negative integer.
Returns:
List of digits representing the input number plus one.
Examples:
>>> plus_one_v2([1, 2, 9])
[1, 3, 0]
"""
length = len(digits)
for index in range(length - 1, -1, -1):
if digits[index] < 9:
digits[index] += 1
return digits
digits[index] = 0
digits.insert(0, 1)
return digits
def plus_one_v3(num_arr: list[int]) -> list[int]:
"""Add one to a big-endian digit array using modular arithmetic.
Args:
num_arr: Non-empty list of digits representing a non-negative integer.
Returns:
List of digits representing the input number plus one.
Examples:
>>> plus_one_v3([1, 2, 9])
[1, 3, 0]
"""
for idx in reversed(list(enumerate(num_arr))):
num_arr[idx[0]] = (num_arr[idx[0]] + 1) % 10
if num_arr[idx[0]]:
return num_arr
return [1] + num_arr
================================================
FILE: algorithms/array/remove_duplicates.py
================================================
"""
Remove Duplicates
Remove duplicate elements from an array while preserving the original order.
Handles both hashable and unhashable items.
Reference: https://en.wikipedia.org/wiki/Duplicate_code
Complexity:
Time: O(n) for hashable items / O(n^2) worst case for unhashable items
Space: O(n)
"""
from __future__ import annotations
from collections.abc import Hashable
from typing import Any
def remove_duplicates(array: list[Any]) -> list[Any]:
"""Remove duplicate elements from an array, preserving order.
Uses a set for O(1) lookups on hashable items and falls back to
linear search for unhashable items.
Args:
array: Input list potentially containing duplicates.
Returns:
New list with duplicates removed, original order preserved.
Examples:
>>> remove_duplicates([1, 1, 2, 2, 3])
[1, 2, 3]
"""
seen = set()
unique_array = []
for item in array:
if isinstance(item, Hashable):
if item not in seen:
seen.add(item)
unique_array.append(item)
else:
if item not in unique_array:
unique_array.append(item)
return unique_array
================================================
FILE: algorithms/array/rotate.py
================================================
"""
Rotate Array
Rotate an array of n elements to the right by k steps.
Three algorithm variants are provided with different time complexities.
Reference: https://leetcode.com/problems/rotate-array/
Complexity:
rotate_v1: Time O(n*k), Space O(n)
rotate_v2: Time O(n), Space O(n)
rotate_v3: Time O(n), Space O(n)
"""
from __future__ import annotations
def rotate_v1(array: list[int], k: int) -> list[int]:
"""Rotate array to the right by k steps using repeated single shifts.
Args:
array: List of integers to rotate.
k: Number of positions to rotate right.
Returns:
New rotated list.
Examples:
>>> rotate_v1([1, 2, 3, 4, 5, 6, 7], 3)
[5, 6, 7, 1, 2, 3, 4]
"""
array = array[:]
length = len(array)
for _ in range(k):
temp = array[length - 1]
for position in range(length - 1, 0, -1):
array[position] = array[position - 1]
array[0] = temp
return array
def rotate_v2(array: list[int], k: int) -> list[int]:
"""Rotate array to the right by k steps using three reversals.
Args:
array: List of integers to rotate.
k: Number of positions to rotate right.
Returns:
New rotated list.
Examples:
>>> rotate_v2([1, 2, 3, 4, 5, 6, 7], 3)
[5, 6, 7, 1, 2, 3, 4]
"""
array = array[:]
def _reverse(arr: list[int], left: int, right: int) -> None:
while left < right:
arr[left], arr[right] = arr[right], arr[left]
left += 1
right -= 1
length = len(array)
k = k % length
_reverse(array, 0, length - k - 1)
_reverse(array, length - k, length - 1)
_reverse(array, 0, length - 1)
return array
def rotate_v3(array: list[int] | None, k: int) -> list[int] | None:
"""Rotate array to the right by k steps using slicing.
Args:
array: List of integers to rotate, or None.
k: Number of positions to rotate right.
Returns:
New rotated list, or None if input is None.
Examples:
>>> rotate_v3([1, 2, 3, 4, 5, 6, 7], 3)
[5, 6, 7, 1, 2, 3, 4]
"""
if array is None:
return None
length = len(array)
k = k % length
return array[length - k :] + array[: length - k]
================================================
FILE: algorithms/array/summarize_ranges.py
================================================
"""
Summarize Ranges
Given a sorted integer array without duplicates, return the summary of its
ranges as a list of (start, end) tuples.
Reference: https://leetcode.com/problems/summary-ranges/
Complexity:
Time: O(n)
Space: O(n) for the result list
"""
from __future__ import annotations
def summarize_ranges(array: list[int]) -> list[tuple[int, ...]]:
"""Summarize consecutive runs in a sorted array as (start, end) tuples.
Args:
array: Sorted list of unique integers.
Returns:
List of (start, end) tuples for each consecutive range.
Examples:
>>> summarize_ranges([0, 1, 2, 4, 5, 7])
[(0, 2), (4, 5), (7, 7)]
"""
result = []
if len(array) == 0:
return []
if len(array) == 1:
return [(array[0], array[0])]
iterator = iter(array)
start = end = next(iterator)
for num in iterator:
if num - end == 1:
end = num
else:
result.append((start, end))
start = end = num
result.append((start, end))
return result
================================================
FILE: algorithms/array/three_sum.py
================================================
"""
Three Sum
Given an array of integers, find all unique triplets that sum to zero
using the two-pointer technique.
Reference: https://leetcode.com/problems/3sum/
Complexity:
Time: O(n^2)
Space: O(n) for the result set
"""
from __future__ import annotations
def three_sum(array: list[int]) -> set[tuple[int, int, int]]:
"""Find all unique triplets in the array that sum to zero.
Args:
array: List of integers to search.
Returns:
Set of sorted tuples, each containing three integers summing to zero.
Examples:
>>> three_sum([-1, 0, 1, 2, -1, -4]) == {(-1, 0, 1), (-1, -1, 2)}
True
"""
result = set()
array.sort()
for i in range(len(array) - 2):
if i > 0 and array[i] == array[i - 1]:
continue
left, right = i + 1, len(array) - 1
while left < right:
current_sum = array[i] + array[left] + array[right]
if current_sum > 0:
right -= 1
elif current_sum < 0:
left += 1
else:
result.add((array[i], array[left], array[right]))
while left < right and array[left] == array[left + 1]:
left += 1
while left < right and array[right] == array[right - 1]:
right -= 1
left += 1
right -= 1
return result
================================================
FILE: algorithms/array/top_1.py
================================================
"""
Top 1 (Mode)
Find the most frequently occurring value(s) in an array. When multiple
values share the highest frequency, all are returned.
Reference: https://en.wikipedia.org/wiki/Mode_(statistics)
Complexity:
Time: O(n)
Space: O(n)
"""
from __future__ import annotations
from typing import Any
def top_1(array: list[Any]) -> list[Any]:
"""Find the statistical mode(s) of an array.
Args:
array: Input list of comparable elements.
Returns:
List of element(s) with the highest frequency.
Examples:
>>> top_1([1, 1, 2, 2, 3])
[1, 2]
"""
frequency = {}
for element in array:
if element in frequency:
frequency[element] += 1
else:
frequency[element] = 1
max_count = max(frequency.values())
result = []
for element, count in frequency.items():
if count == max_count:
result.append(element)
return result
================================================
FILE: algorithms/array/trimmean.py
================================================
"""
Trimmed Mean
Compute the mean of an array after discarding a given percentage of the
highest and lowest values. Useful for robust averaging in scoring systems.
Reference: https://en.wikipedia.org/wiki/Truncated_mean
Complexity:
Time: O(n log n) due to sorting
Space: O(n) for the trimmed copy
"""
from __future__ import annotations
def trimmean(array: list[float], percentage: float) -> float:
"""Calculate the trimmed mean of an array.
Discards the top and bottom halves of the given percentage before
computing the arithmetic mean.
Args:
array: List of numeric values.
percentage: Total percentage to trim (split equally between
top and bottom). E.g., 20 trims the top 10% and bottom 10%.
Returns:
The trimmed arithmetic mean.
Examples:
>>> trimmean([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 20)
5.5
"""
ratio = percentage / 200
array.sort()
trim_count = int(len(array) * ratio)
trimmed = array[trim_count : len(array) - trim_count]
total = 0
for value in trimmed:
total += value
return total / len(trimmed)
================================================
FILE: algorithms/array/two_sum.py
================================================
"""
Two Sum
Given an array of integers and a target sum, return the indices of the two
numbers that add up to the target.
Reference: https://leetcode.com/problems/two-sum/
Complexity:
Time: O(n)
Space: O(n)
"""
from __future__ import annotations
def two_sum(array: list[int], target: int) -> tuple[int, int] | None:
"""Find two indices whose corresponding values sum to target.
Args:
array: List of integers to search.
target: Desired sum of two elements.
Returns:
Tuple of (index1, index2) if a pair is found, or None otherwise.
Examples:
>>> two_sum([2, 7, 11, 15], 9)
(0, 1)
"""
seen = {}
for index, num in enumerate(array):
if num in seen:
return seen[num], index
else:
seen[target - num] = index
return None
================================================
FILE: algorithms/backtracking/__init__.py
================================================
from .add_operators import add_operators
from .anagram import anagram
from .array_sum_combinations import (
array_sum_combinations,
unique_array_sum_combinations,
)
from .combination_sum import combination_sum
from .factor_combinations import get_factors, recursive_get_factors
from .find_words import find_words
from .generate_abbreviations import generate_abbreviations
from .generate_parenthesis import generate_parenthesis_v1, generate_parenthesis_v2
from .letter_combination import letter_combinations
from .minimax import minimax
from .palindrome_partitioning import (
palindromic_substrings,
palindromic_substrings_iter,
)
from .pattern_match import pattern_match
from .permute import permute, permute_iter, permute_recursive
from .permute_unique import permute_unique
from .subsets import subsets, subsets_v2
from .subsets_unique import subsets_unique
__all__ = [
"add_operators",
"anagram",
"array_sum_combinations",
"unique_array_sum_combinations",
"combination_sum",
"get_factors",
"recursive_get_factors",
"find_words",
"generate_abbreviations",
"generate_parenthesis_v1",
"generate_parenthesis_v2",
"letter_combinations",
"palindromic_substrings",
"palindromic_substrings_iter",
"pattern_match",
"permute",
"permute_iter",
"permute_recursive",
"permute_unique",
"subsets",
"subsets_v2",
"subsets_unique",
"minimax",
]
================================================
FILE: algorithms/backtracking/add_operators.py
================================================
"""
Expression Add Operators
Given a string of digits and a target value, return all possibilities to
insert binary operators (+, -, *) between the digits so they evaluate to
the target value.
Reference: https://leetcode.com/problems/expression-add-operators/
Complexity:
Time: O(4^n) worst
Space: O(n) recursion depth
"""
from __future__ import annotations
def add_operators(digits: str, target: int) -> list[str]:
"""Return all expressions formed by inserting +, -, * that equal target.
Args:
digits: A string containing only digits 0-9.
target: The target integer value.
Returns:
A list of valid expression strings.
Examples:
>>> add_operators("123", 6)
['1+2+3', '1*2*3']
"""
result: list[str] = []
if not digits:
return result
_dfs(result, "", digits, target, 0, 0, 0)
return result
def _dfs(
result: list[str],
path: str,
digits: str,
target: int,
position: int,
evaluated: int,
multed: int,
) -> None:
"""Depth-first search helper that builds expressions recursively."""
if position == len(digits):
if target == evaluated:
result.append(path)
return
for i in range(position, len(digits)):
if i != position and digits[position] == "0":
break
current = int(digits[position : i + 1])
if position == 0:
_dfs(result, path + str(current), digits, target, i + 1, current, current)
else:
_dfs(
result,
path + "+" + str(current),
digits,
target,
i + 1,
evaluated + current,
current,
)
_dfs(
result,
path + "-" + str(current),
digits,
target,
i + 1,
evaluated - current,
-current,
)
_dfs(
result,
path + "*" + str(current),
digits,
target,
i + 1,
evaluated - multed + multed * current,
multed * current,
)
================================================
FILE: algorithms/backtracking/anagram.py
================================================
"""
Anagram Checker
Given two strings, determine if they are anagrams of each other (i.e. one
can be rearranged to form the other).
Reference: https://en.wikipedia.org/wiki/Anagram
Complexity:
Time: O(n) where n is the length of the strings
Space: O(1) fixed 26-character alphabet
"""
from __future__ import annotations
def anagram(first: str, second: str) -> bool:
"""Check whether two strings are anagrams of each other.
Args:
first: The first string (lowercase letters only).
second: The second string (lowercase letters only).
Returns:
True if the strings are anagrams, False otherwise.
Examples:
>>> anagram('apple', 'pleap')
True
>>> anagram('apple', 'cherry')
False
"""
count_first = [0] * 26
count_second = [0] * 26
for char in first:
index = ord(char) - ord("a")
count_first[index] += 1
for char in second:
index = ord(char) - ord("a")
count_second[index] += 1
return count_first == count_second
================================================
FILE: algorithms/backtracking/array_sum_combinations.py
================================================
"""
Array Sum Combinations
Given three arrays and a target sum, find all three-element combinations
(one element from each array) that add up to the target.
Reference: https://en.wikipedia.org/wiki/Subset_sum_problem
Complexity:
Time: O(n^3) brute-force product of three arrays
Space: O(k) where k is the number of valid combinations
"""
from __future__ import annotations
import itertools
from functools import partial
def array_sum_combinations(
array_a: list[int],
array_b: list[int],
array_c: list[int],
target: int,
) -> list[list[int]]:
"""Find all combinations of one element per array that sum to target.
Uses backtracking to enumerate valid combinations, allowing duplicates.
Args:
array_a: First array of integers.
array_b: Second array of integers.
array_c: Third array of integers.
target: The desired sum.
Returns:
A list of three-element lists that sum to target.
Examples:
>>> array_sum_combinations([1], [2], [3], 6)
[[1, 2, 3]]
"""
arrays = [array_a, array_b, array_c]
def _is_complete(constructed_so_far: list[int]) -> tuple[bool, bool]:
total = sum(constructed_so_far)
should_stop = total >= target or len(constructed_so_far) >= 3
reached_target = total == target and len(constructed_so_far) == 3
return should_stop, reached_target
def _get_candidates(constructed_so_far: list[int]) -> list[int]:
return arrays[len(constructed_so_far)]
def _backtrack(
constructed_so_far: list[int] | None = None,
result: list[list[int]] | None = None,
) -> None:
if constructed_so_far is None:
constructed_so_far = []
if result is None:
result = []
should_stop, reached_target = _is_complete(constructed_so_far)
if should_stop:
if reached_target:
result.append(constructed_so_far)
return
candidates = _get_candidates(constructed_so_far)
for candidate in candidates:
constructed_so_far.append(candidate)
_backtrack(constructed_so_far[:], result)
constructed_so_far.pop()
result: list[list[int]] = []
_backtrack([], result)
return result
def unique_array_sum_combinations(
array_a: list[int],
array_b: list[int],
array_c: list[int],
target: int,
) -> list[tuple[int, ...]]:
"""Find unique combinations of one element per array that sum to target.
Uses itertools.product and filters by target sum, returning only unique
tuples.
Args:
array_a: First array of integers.
array_b: Second array of integers.
array_c: Third array of integers.
target: The desired sum.
Returns:
A list of unique tuples that sum to target.
Examples:
>>> sorted(unique_array_sum_combinations([1, 2], [2, 3], [3, 4], 6))
[(1, 2, 3)]
"""
def _check_sum(expected: int, *nums: int) -> tuple[bool, tuple[int, ...]]:
if sum(nums) == expected:
return (True, nums)
else:
return (False, nums)
product = itertools.product(array_a, array_b, array_c)
func = partial(_check_sum, target)
sums = list(itertools.starmap(func, product))
seen: set[tuple[int, ...]] = set()
for is_match, values in sums:
if is_match and values not in seen:
seen.add(values)
return list(seen)
================================================
FILE: algorithms/backtracking/combination_sum.py
================================================
"""
Combination Sum
Given a set of candidate numbers (without duplicates) and a target number,
find all unique combinations where the candidate numbers sum to the target.
The same number may be chosen an unlimited number of times.
Reference: https://leetcode.com/problems/combination-sum/
Complexity:
Time: O(n^(T/M)) where T is target, M is minimum candidate
Space: O(T/M) recursion depth
"""
from __future__ import annotations
def combination_sum(candidates: list[int], target: int) -> list[list[int]]:
"""Find all unique combinations of candidates that sum to target.
Args:
candidates: A list of distinct positive integers.
target: The target sum.
Returns:
A list of lists, each containing a valid combination.
Examples:
>>> combination_sum([2, 3, 6, 7], 7)
[[2, 2, 3], [7]]
"""
result: list[list[int]] = []
candidates.sort()
_dfs(candidates, target, 0, [], result)
return result
def _dfs(
nums: list[int],
target: int,
index: int,
path: list[int],
result: list[list[int]],
) -> None:
"""Depth-first search helper for building combinations."""
if target < 0:
return
if target == 0:
result.append(path)
return
for i in range(index, len(nums)):
_dfs(nums, target - nums[i], i, path + [nums[i]], result)
================================================
FILE: algorithms/backtracking/factor_combinations.py
================================================
"""
Factor Combinations
Given an integer n, return all possible combinations of its factors.
Factors should be greater than 1 and less than n.
Reference: https://leetcode.com/problems/factor-combinations/
Complexity:
Time: O(n * log(n)) approximate
Space: O(log(n)) recursion depth
"""
from __future__ import annotations
def get_factors(number: int) -> list[list[int]]:
"""Return all factor combinations of number using iteration.
Args:
number: A positive integer.
Returns:
A list of lists, each containing a valid factorization.
Examples:
>>> get_factors(12)
[[2, 6], [2, 2, 3], [3, 4]]
"""
todo: list[tuple[int, int, list[int]]] = [(number, 2, [])]
combinations: list[list[int]] = []
while todo:
remaining, divisor, partial = todo.pop()
while divisor * divisor <= remaining:
if remaining % divisor == 0:
combinations.append(partial + [divisor, remaining // divisor])
todo.append((remaining // divisor, divisor, partial + [divisor]))
divisor += 1
return combinations
def recursive_get_factors(number: int) -> list[list[int]]:
"""Return all factor combinations of number using recursion.
Args:
number: A positive integer.
Returns:
A list of lists, each containing a valid factorization.
Examples:
>>> recursive_get_factors(12)
[[2, 6], [2, 2, 3], [3, 4]]
"""
def _factor(
remaining: int,
divisor: int,
partial: list[int],
combinations: list[list[int]],
) -> list[list[int]]:
while divisor * divisor <= remaining:
if remaining % divisor == 0:
combinations.append(partial + [divisor, remaining // divisor])
_factor(
remaining // divisor, divisor, partial + [divisor], combinations
)
divisor += 1
return combinations
return _factor(number, 2, [], [])
================================================
FILE: algorithms/backtracking/find_words.py
================================================
"""
Word Search II
Given a board of characters and a list of words, find all words that can
be constructed from adjacent cells (horizontally or vertically). Each cell
may only be used once per word. Uses a trie for efficient prefix matching.
Reference: https://leetcode.com/problems/word-search-ii/
Complexity:
Time: O(M * N * 4^L) where M*N is board size, L is max word length
Space: O(W * L) for the trie, where W is number of words
"""
from __future__ import annotations
def find_words(board: list[list[str]], words: list[str]) -> list[str]:
"""Find all words from the list that exist on the board.
Builds a trie from the word list, then uses backtracking to search
the board for each word.
Args:
board: A 2D grid of characters.
words: A list of words to search for.
Returns:
A list of words found on the board.
Examples:
>>> board = [['o','a','a','n'], ['e','t','a','e']]
>>> sorted(find_words(board, ['eat', 'oath']))
['eat']
"""
trie: dict = {}
for word in words:
current_node = trie
for char in word:
if char not in current_node:
current_node[char] = {}
current_node = current_node[char]
current_node["#"] = "#"
found: set[str] = set()
used = [[False] * len(board[0]) for _ in range(len(board))] if board else []
for row in range(len(board)):
for col in range(len(board[0])):
_backtrack(board, row, col, trie, "", used, found)
return list(found)
def _backtrack(
board: list[list[str]],
row: int,
col: int,
trie: dict,
prefix: str,
used: list[list[bool]],
found: set[str],
) -> None:
"""Recursively search the board for words matching the trie."""
if "#" in trie:
found.add(prefix)
if row < 0 or row >= len(board) or col < 0 or col >= len(board[0]):
return
if not used[row][col] and board[row][col] in trie:
used[row][col] = True
next_char = board[row][col]
_backtrack(
board, row + 1, col, trie[next_char], prefix + next_char, used, found
)
_backtrack(
board, row, col + 1, trie[next_char], prefix + next_char, used, found
)
_backtrack(
board, row - 1, col, trie[next_char], prefix + next_char, used, found
)
_backtrack(
board, row, col - 1, trie[next_char], prefix + next_char, used, found
)
used[row][col] = False
================================================
FILE: algorithms/backtracking/generate_abbreviations.py
================================================
"""
Generalized Abbreviations
Given a word, return all possible generalized abbreviations. Each
abbreviation replaces contiguous substrings with their lengths.
Reference: https://leetcode.com/problems/generalized-abbreviation/
Complexity:
Time: O(2^n) where n is the length of the word
Space: O(n) recursion depth
"""
from __future__ import annotations
def generate_abbreviations(word: str) -> list[str]:
"""Generate all possible abbreviations of a word.
Args:
word: The input word to abbreviate.
Returns:
A list of all valid abbreviations.
Examples:
>>> sorted(generate_abbreviations("ab"))
['1b', '2', 'a1', 'ab']
"""
result: list[str] = []
_backtrack(result, word, 0, 0, "")
return result
def _backtrack(
result: list[str],
word: str,
position: int,
count: int,
current: str,
) -> None:
"""Recursively build abbreviations by including or skipping characters."""
if position == len(word):
if count > 0:
current += str(count)
result.append(current)
return
if count > 0:
_backtrack(result, word, position + 1, 0, current + str(count) + word[position])
else:
_backtrack(result, word, position + 1, 0, current + word[position])
_backtrack(result, word, position + 1, count + 1, current)
================================================
FILE: algorithms/backtracking/generate_parenthesis.py
================================================
"""
Generate Parentheses
Given n pairs of parentheses, generate all combinations of well-formed
parentheses.
Reference: https://leetcode.com/problems/generate-parentheses/
Complexity:
Time: O(4^n / sqrt(n)) — the n-th Catalan number
Space: O(n) recursion depth
"""
from __future__ import annotations
def generate_parenthesis_v1(count: int) -> list[str]:
"""Generate all valid parenthesis combinations (right-first variant).
Builds combinations by tracking remaining left and right parentheses,
trying to add a closing paren before an opening one.
Args:
count: The number of parenthesis pairs.
Returns:
A list of all valid parenthesis strings.
Examples:
>>> generate_parenthesis_v1(2)
['()()', '(())']
"""
result: list[str] = []
_add_pair_v1(result, "", count, 0)
return result
def _add_pair_v1(
result: list[str],
current: str,
left: int,
right: int,
) -> None:
"""Recursive helper for v1: tries closing before opening."""
if left == 0 and right == 0:
result.append(current)
return
if right > 0:
_add_pair_v1(result, current + ")", left, right - 1)
if left > 0:
_add_pair_v1(result, current + "(", left - 1, right + 1)
def generate_parenthesis_v2(count: int) -> list[str]:
"""Generate all valid parenthesis combinations (left-first variant).
Builds combinations by tracking remaining left and right parentheses,
trying to add an opening paren before a closing one.
Args:
count: The number of parenthesis pairs.
Returns:
A list of all valid parenthesis strings.
Examples:
>>> generate_parenthesis_v2(2)
['(())', '()()']
"""
result: list[str] = []
_add_pair_v2(result, "", count, count)
return result
def _add_pair_v2(
result: list[str],
current: str,
left: int,
right: int,
) -> None:
"""Recursive helper for v2: tries opening before closing."""
if left == 0 and right == 0:
result.append(current)
if left > 0:
_add_pair_v2(result, current + "(", left - 1, right)
if right > 0 and left < right:
_add_pair_v2(result, current + ")", left, right - 1)
================================================
FILE: algorithms/backtracking/letter_combination.py
================================================
"""
Letter Combinations of a Phone Number
Given a digit string, return all possible letter combinations that the
number could represent using a telephone keypad mapping.
Reference: https://leetcode.com/problems/letter-combinations-of-a-phone-number/
Complexity:
Time: O(4^n) where n is the number of digits
Space: O(4^n) for the result list
"""
from __future__ import annotations
def letter_combinations(digits: str) -> list[str]:
"""Return all letter combinations for a digit string.
Args:
digits: A string of digits (2-9).
Returns:
A list of all possible letter combinations.
Examples:
>>> letter_combinations("23")
['ad', 'ae', 'af', 'bd', 'be', 'bf', 'cd', 'ce', 'cf']
"""
if digits == "":
return []
keypad_map = {
"2": "abc",
"3": "def",
"4": "ghi",
"5": "jkl",
"6": "mno",
"7": "pqrs",
"8": "tuv",
"9": "wxyz",
}
combinations: list[str] = [""]
for digit in digits:
expanded: list[str] = []
for existing in combinations:
for char in keypad_map[digit]:
expanded.append(existing + char)
combinations = expanded
return combinations
================================================
FILE: algorithms/backtracking/minimax.py
================================================
"""Minimax — game-tree search with alpha-beta pruning.
The minimax algorithm finds the optimal move for a two-player zero-sum
game. Alpha-beta pruning reduces the search space by eliminating branches
that cannot influence the final decision.
Inspired by PR #860 (DD2480-group16).
"""
from __future__ import annotations
import math
def minimax(
depth: int,
is_maximizing: bool,
scores: list[int],
alpha: float = -math.inf,
beta: float = math.inf,
) -> float:
"""Return the minimax value of a perfect binary game tree.
*scores* contains the leaf values (length must be a power of 2).
*depth* is the current depth (start with log2(len(scores))).
>>> minimax(2, True, [3, 5, 2, 9])
5
>>> minimax(3, True, [3, 5, 2, 9, 12, 5, 23, 23])
12
"""
if depth == 0:
return scores[0]
mid = len(scores) // 2
if is_maximizing:
value = -math.inf
value = max(
value,
minimax(depth - 1, False, scores[:mid], alpha, beta),
)
alpha = max(alpha, value)
if alpha < beta:
value = max(
value,
minimax(depth - 1, False, scores[mid:], alpha, beta),
)
return value
else:
value = math.inf
value = min(
value,
minimax(depth - 1, True, scores[:mid], alpha, beta),
)
beta = min(beta, value)
if alpha < beta:
value = min(
value,
minimax(depth - 1, True, scores[mid:], alpha, beta),
)
return value
================================================
FILE: algorithms/backtracking/palindrome_partitioning.py
================================================
"""
Palindrome Partitioning
Given a string, find all ways to partition it into palindromic substrings.
There is always at least one way since single characters are palindromes.
Reference: https://leetcode.com/problems/palindrome-partitioning/
Complexity:
Time: O(n * 2^n) where n is the string length
Space: O(n) recursion depth
"""
from __future__ import annotations
from collections.abc import Generator
def palindromic_substrings(text: str) -> list[list[str]]:
"""Return all palindrome partitions of the input string.
Args:
text: The string to partition.
Returns:
A list of partitions, each being a list of palindromic substrings.
Examples:
>>> palindromic_substrings("abc")
[['a', 'b', 'c']]
"""
if not text:
return [[]]
results: list[list[str]] = []
for i in range(len(text), 0, -1):
substring = text[:i]
if substring == substring[::-1]:
for rest in palindromic_substrings(text[i:]):
results.append([substring] + rest)
return results
def palindromic_substrings_iter(text: str) -> Generator[list[str], None, None]:
"""Yield all palindrome partitions of the input string via a generator.
A slightly more Pythonic approach using a recursive generator.
Args:
text: The string to partition.
Yields:
Lists of palindromic substrings forming a valid partition.
Examples:
>>> list(palindromic_substrings_iter("abc"))
[['a', 'b', 'c']]
"""
if not text:
yield []
return
for i in range(len(text), 0, -1):
substring = text[:i]
if substring == substring[::-1]:
for rest in palindromic_substrings_iter(text[i:]):
yield [substring] + rest
================================================
FILE: algorithms/backtracking/pattern_match.py
================================================
"""
Pattern Matching
Given a pattern and a string, determine if the string follows the same
pattern. A full match means a bijection between each letter in the pattern
and a non-empty substring in the string.
Reference: https://leetcode.com/problems/word-pattern-ii/
Complexity:
Time: O(n^m) where n is string length, m is pattern length
Space: O(m) recursion depth plus mapping storage
"""
from __future__ import annotations
def pattern_match(pattern: str, string: str) -> bool:
"""Check whether a string matches a given pattern via bijection.
Args:
pattern: A pattern string of lowercase letters.
string: The string to match against (lowercase letters).
Returns:
True if the string follows the pattern, False otherwise.
Examples:
>>> pattern_match("abab", "redblueredblue")
True
>>> pattern_match("aabb", "xyzabcxzyabc")
False
"""
return _backtrack(pattern, string, {})
def _backtrack(
pattern: str,
string: str,
mapping: dict[str, str],
) -> bool:
"""Recursively attempt to match pattern to string using a mapping."""
if len(pattern) == 0 and len(string) > 0:
return False
if len(pattern) == 0 and len(string) == 0:
return True
for end in range(1, len(string) - len(pattern) + 2):
if pattern[0] not in mapping and string[:end] not in mapping.values():
mapping[pattern[0]] = string[:end]
if _backtrack(pattern[1:], string[end:], mapping):
return True
del mapping[pattern[0]]
elif pattern[0] in mapping and mapping[pattern[0]] == string[:end]:
if _backtrack(pattern[1:], string[end:], mapping):
return True
return False
================================================
FILE: algorithms/backtracking/permute.py
================================================
"""
Permutations
Given a collection of distinct elements, return all possible permutations.
Reference: https://en.wikipedia.org/wiki/Permutation
Complexity:
Time: O(n * n!) where n is the number of elements
Space: O(n * n!) to store all permutations
"""
from __future__ import annotations
from collections.abc import Generator
def permute(elements: list | str) -> list:
"""Return all permutations of the given elements.
Args:
elements: A list or string of distinct elements.
Returns:
A list of all permutations (same type as input elements).
Examples:
>>> permute([1, 2, 3])
[[1, 2, 3], [2, 1, 3], [2, 3, 1], [1, 3, 2], [3, 1, 2], [3, 2, 1]]
"""
if len(elements) <= 1:
return [elements]
result = []
for perm in permute(elements[1:]):
for i in range(len(elements)):
result.append(perm[:i] + elements[0:1] + perm[i:])
return result
def permute_iter(elements: list | str) -> Generator:
"""Yield all permutations of the given elements one at a time.
Args:
elements: A list or string of distinct elements.
Yields:
One permutation at a time (same type as input elements).
Examples:
>>> list(permute_iter([1, 2]))
[[1, 2], [2, 1]]
"""
if len(elements) <= 1:
yield elements
else:
for perm in permute_iter(elements[1:]):
for i in range(len(elements)):
yield perm[:i] + elements[0:1] + perm[i:]
def permute_recursive(nums: list[int]) -> list[list[int]]:
"""Return all permutations using DFS backtracking.
Args:
nums: A list of distinct integers.
Returns:
A list of all permutations.
Examples:
>>> sorted(permute_recursive([1, 2]))
[[1, 2], [2, 1]]
"""
result: list[list[int]] = []
_dfs(result, nums, [])
return result
def _dfs(
result: list[list[int]],
nums: list[int],
path: list[int],
) -> None:
"""DFS helper that builds permutations by choosing remaining elements."""
if not nums:
result.append(path)
for i in range(len(nums)):
_dfs(result, nums[:i] + nums[i + 1 :], path + [nums[i]])
================================================
FILE: algorithms/backtracking/permute_unique.py
================================================
"""
Unique Permutations
Given a collection of numbers that might contain duplicates, return all
possible unique permutations.
Reference: https://leetcode.com/problems/permutations-ii/
Complexity:
Time: O(n * n!) worst case
Space: O(n * n!) to store all unique permutations
"""
from __future__ import annotations
def permute_unique(nums: list[int]) -> list[list[int]]:
"""Return all unique permutations of a list that may have duplicates.
Args:
nums: A list of integers, possibly with duplicates.
Returns:
A list of all unique permutations.
Examples:
>>> sorted(permute_unique([1, 1, 2]))
[[1, 1, 2], [1, 2, 1], [2, 1, 1]]
"""
permutations: list[list[int]] = [[]]
for number in nums:
new_permutations: list[list[int]] = []
for existing in permutations:
for i in range(len(existing) + 1):
new_permutations.append(existing[:i] + [number] + existing[i:])
if i < len(existing) and existing[i] == number:
break
permutations = new_permutations
return permutations
================================================
FILE: algorithms/backtracking/subsets.py
================================================
"""
Subsets
Given a set of distinct integers, return all possible subsets (the power
set). The solution set must not contain duplicate subsets.
Reference: https://en.wikipedia.org/wiki/Power_set
Complexity:
Time: O(2^n) where n is the number of elements
Space: O(2^n) to store all subsets
"""
from __future__ import annotations
def subsets(nums: list[int]) -> list[list[int]]:
"""Return all subsets of the given list using backtracking.
Args:
nums: A list of distinct integers.
Returns:
A list of all subsets.
Examples:
>>> sorted(subsets([1, 2]), key=str)
[[], [1], [1, 2], [2]]
"""
result: list[list[int]] = []
_backtrack(result, nums, [], 0)
return result
def _backtrack(
result: list[list[int]],
nums: list[int],
stack: list[int],
position: int,
) -> None:
"""Recursive helper that includes or excludes each element."""
if position == len(nums):
result.append(list(stack))
else:
stack.append(nums[position])
_backtrack(result, nums, stack, position + 1)
stack.pop()
_backtrack(result, nums, stack, position + 1)
def subsets_v2(nums: list[int]) -> list[list[int]]:
"""Return all subsets of the given list using iteration.
Builds subsets iteratively by extending each existing subset
with the next element.
Args:
nums: A list of distinct integers.
Returns:
A list of all subsets.
Examples:
>>> sorted(subsets_v2([1, 2]), key=str)
[[], [1], [1, 2], [2]]
"""
result: list[list[int]] = [[]]
for number in sorted(nums):
result += [item + [number] for item in result]
return result
================================================
FILE: algorithms/backtracking/subsets_unique.py
================================================
"""
Unique Subsets
Given a collection of integers that might contain duplicates, return all
possible unique subsets (the power set without duplicates).
Reference: https://leetcode.com/problems/subsets-ii/
Complexity:
Time: O(2^n) where n is the number of elements
Space: O(2^n) to store all subsets
"""
from __future__ import annotations
def subsets_unique(nums: list[int]) -> list[tuple[int, ...]]:
"""Return all unique subsets of a list that may have duplicates.
Args:
nums: A list of integers, possibly with duplicates.
Returns:
A list of unique tuples representing each subset.
Examples:
>>> sorted(subsets_unique([1, 2, 2]))
[(), (1,), (1, 2), (1, 2, 2), (2,), (2, 2)]
"""
found: set[tuple[int, ...]] = set()
_backtrack(found, nums, [], 0)
return list(found)
def _backtrack(
found: set[tuple[int, ...]],
nums: list[int],
stack: list[int],
position: int,
) -> None:
"""Recursive helper that includes or excludes each element."""
if position == len(nums):
found.add(tuple(stack))
else:
stack.append(nums[position])
_backtrack(found, nums, stack, position + 1)
stack.pop()
_backtrack(found, nums, stack, position + 1)
================================================
FILE: algorithms/bit_manipulation/__init__.py
================================================
from .add_bitwise_operator import add_bitwise_operator
from .binary_gap import binary_gap
from .bit_operation import clear_bit, get_bit, set_bit, update_bit
from .bytes_int_conversion import (
bytes_big_endian_to_int,
bytes_little_endian_to_int,
int_to_bytes_big_endian,
int_to_bytes_little_endian,
)
from .count_flips_to_convert import count_flips_to_convert
from .count_ones import count_ones_iter, count_ones_recur
from .find_difference import find_difference
from .find_missing_number import find_missing_number, find_missing_number2
from .flip_bit_longest_sequence import flip_bit_longest_seq
from .gray_code import gray_code, gray_to_binary
from .has_alternative_bit import has_alternative_bit, has_alternative_bit_fast
from .insert_bit import insert_mult_bits, insert_one_bit
from .power_of_two import is_power_of_two
from .remove_bit import remove_bit
from .reverse_bits import reverse_bits
from .single_number import single_number
from .single_number2 import single_number2
from .single_number3 import single_number3
from .subsets import subsets
from .swap_pair import swap_pair
__all__ = [
"add_bitwise_operator",
"binary_gap",
"bytes_big_endian_to_int",
"bytes_little_endian_to_int",
"clear_bit",
"count_flips_to_convert",
"count_ones_iter",
"count_ones_recur",
"find_difference",
"find_missing_number",
"find_missing_number2",
"flip_bit_longest_seq",
"get_bit",
"has_alternative_bit",
"has_alternative_bit_fast",
"insert_mult_bits",
"insert_one_bit",
"int_to_bytes_big_endian",
"int_to_bytes_little_endian",
"is_power_of_two",
"remove_bit",
"reverse_bits",
"set_bit",
"single_number",
"single_number2",
"single_number3",
"subsets",
"swap_pair",
"update_bit",
"gray_code",
"gray_to_binary",
]
================================================
FILE: algorithms/bit_manipulation/add_bitwise_operator.py
================================================
"""
Add Bitwise Operator
Add two positive integers without using the '+' operator, using only
bitwise operations (AND, XOR, shift).
Reference: https://en.wikipedia.org/wiki/Adder_(electronics)
Complexity:
Time: O(log n) where n is the larger of the two inputs
Space: O(1)
"""
from __future__ import annotations
def add_bitwise_operator(first: int, second: int) -> int:
"""Add two non-negative integers using only bitwise operations.
Args:
first: First non-negative integer operand.
second: Second non-negative integer operand.
Returns:
The sum of first and second.
Examples:
>>> add_bitwise_operator(2, 3)
5
>>> add_bitwise_operator(0, 0)
0
"""
while second:
carry = first & second
first = first ^ second
second = carry << 1
return first
================================================
FILE: algorithms/bit_manipulation/binary_gap.py
================================================
"""
Binary Gap
Given a positive integer N, find and return the longest distance between two
consecutive 1-bits in the binary representation of N. If there are not two
consecutive 1-bits, return 0.
Reference: https://en.wikipedia.org/wiki/Hamming_distance
Complexity:
Time: O(log n) where n is the input integer
Space: O(1)
"""
from __future__ import annotations
def binary_gap(number: int) -> int:
"""Find the longest distance between consecutive 1-bits in binary.
Args:
number: A positive integer to examine.
Returns:
The longest gap between consecutive 1-bits, or 0 if fewer
than two 1-bits exist.
Examples:
>>> binary_gap(22)
2
>>> binary_gap(8)
0
"""
last_one_position = None
longest_gap = 0
index = 0
while number != 0:
if number & 1:
if last_one_position is not None:
longest_gap = max(longest_gap, index - last_one_position)
last_one_position = index
index += 1
number >>= 1
return longest_gap
================================================
FILE: algorithms/bit_manipulation/bit_operation.py
================================================
"""
Fundamental Bit Operations
Basic bit manipulation operations: get, set, clear, and update individual
bits at a specific position in an integer.
Reference: https://en.wikipedia.org/wiki/Bit_manipulation
Complexity:
Time: O(1) for all operations
Space: O(1)
"""
from __future__ import annotations
def get_bit(number: int, position: int) -> int:
"""Get the bit value at a specific position.
Shifts 1 over by *position* bits and ANDs with *number* to isolate
the target bit.
Args:
number: The integer to inspect.
position: Zero-based bit index (0 is the least significant bit).
Returns:
1 if the bit at *position* is set, 0 otherwise.
Examples:
>>> get_bit(22, 2)
1
>>> get_bit(22, 3)
0
"""
return (number & (1 << position)) != 0
def set_bit(number: int, position: int) -> int:
"""Set the bit at a specific position to 1.
Shifts 1 over by *position* bits and ORs with *number* so that only
the bit at *position* is turned on.
Args:
number: The integer to modify.
position: Zero-based bit index to set.
Returns:
The integer with the bit at *position* set to 1.
Examples:
>>> set_bit(22, 3)
30
"""
return number | (1 << position)
def clear_bit(number: int, position: int) -> int:
"""Clear the bit at a specific position to 0.
Creates a mask with all bits set except at *position*, then ANDs
with *number*.
Args:
number: The integer to modify.
position: Zero-based bit index to clear.
Returns:
The integer with the bit at *position* cleared to 0.
Examples:
>>> clear_bit(22, 2)
18
"""
mask = ~(1 << position)
return number & mask
def update_bit(number: int, position: int, bit: int) -> int:
"""Update the bit at a specific position to a given value.
First clears the bit at *position*, then ORs in the new *bit* value
shifted to that position.
Args:
number: The integer to modify.
position: Zero-based bit index to update.
bit: The new bit value (0 or 1).
Returns:
The integer with the bit at *position* set to *bit*.
Examples:
>>> update_bit(22, 3, 1)
30
>>> update_bit(22, 2, 0)
18
"""
mask = ~(1 << position)
return (number & mask) | (bit << position)
================================================
FILE: algorithms/bit_manipulation/bytes_int_conversion.py
================================================
"""
Bytes-Integer Conversion
Convert between Python integers and raw byte sequences in both big-endian
and little-endian byte orders.
Reference: https://en.wikipedia.org/wiki/Endianness
Complexity:
Time: O(b) where b is the number of bytes in the representation
Space: O(b)
"""
from __future__ import annotations
from collections import deque
def int_to_bytes_big_endian(number: int) -> bytes:
"""Convert a non-negative integer to bytes in big-endian order.
Args:
number: A non-negative integer to convert.
Returns:
A bytes object with the most significant byte first.
Examples:
>>> int_to_bytes_big_endian(17)
b'\\x11'
"""
byte_buffer: deque[int] = deque()
while number > 0:
byte_buffer.appendleft(number & 0xFF)
number >>= 8
return bytes(byte_buffer)
def int_to_bytes_little_endian(number: int) -> bytes:
"""Convert a non-negative integer to bytes in little-endian order.
Args:
number: A non-negative integer to convert.
Returns:
A bytes object with the least significant byte first.
Examples:
>>> int_to_bytes_little_endian(17)
b'\\x11'
"""
byte_buffer: list[int] = []
while number > 0:
byte_buffer.append(number & 0xFF)
number >>= 8
return bytes(byte_buffer)
def bytes_big_endian_to_int(byte_string: bytes) -> int:
"""Convert a big-endian byte sequence to an integer.
Args:
byte_string: Bytes with the most significant byte first.
Returns:
The decoded integer value.
Examples:
>>> bytes_big_endian_to_int(b'\\x11')
17
"""
number = 0
for byte in byte_string:
number <<= 8
number += byte
return number
def bytes_little_endian_to_int(byte_string: bytes) -> int:
"""Convert a little-endian byte sequence to an integer.
Args:
byte_string: Bytes with the least significant byte first.
Returns:
The decoded integer value.
Examples:
>>> bytes_little_endian_to_int(b'\\x11')
17
"""
number = 0
exponent = 0
for byte in byte_string:
number += byte << exponent
exponent += 8
return number
================================================
FILE: algorithms/bit_manipulation/count_flips_to_convert.py
================================================
"""
Count Flips to Convert
Determine the minimal number of bits you would need to flip to convert
integer A to integer B. Uses XOR to find differing bits and Brian
Kernighan's algorithm to count them.
Reference: https://en.wikipedia.org/wiki/Hamming_distance
Complexity:
Time: O(k) where k is the number of differing bits
Space: O(1)
"""
from __future__ import annotations
def count_flips_to_convert(first: int, second: int) -> int:
"""Count the number of bit flips needed to convert one integer to another.
Args:
first: The source integer.
second: The target integer.
Returns:
The number of bits that differ between *first* and *second*.
Examples:
>>> count_flips_to_convert(29, 15)
2
>>> count_flips_to_convert(34, 34)
0
"""
diff = first ^ second
count = 0
while diff:
diff &= diff - 1
count += 1
return count
================================================
FILE: algorithms/bit_manipulation/count_ones.py
================================================
"""
Count Ones (Hamming Weight)
Count the number of 1-bits in the binary representation of an unsigned
integer using Brian Kernighan's algorithm.
Reference: https://en.wikipedia.org/wiki/Hamming_weight
Complexity:
Time: O(k) where k is the number of set bits
Space: O(1) iterative / O(k) recursive (call stack)
"""
from __future__ import annotations
def count_ones_recur(number: int) -> int:
"""Count set bits using Brian Kernighan's algorithm (recursive).
Args:
number: A non-negative integer.
Returns:
The number of 1-bits in the binary representation.
Examples:
>>> count_ones_recur(8)
1
>>> count_ones_recur(63)
6
"""
if not number:
return 0
return 1 + count_ones_recur(number & (number - 1))
def count_ones_iter(number: int) -> int:
"""Count set bits using Brian Kernighan's algorithm (iterative).
Args:
number: A non-negative integer.
Returns:
The number of 1-bits in the binary representation.
Examples:
>>> count_ones_iter(8)
1
>>> count_ones_iter(63)
6
"""
count = 0
while number:
number &= number - 1
count += 1
return count
================================================
FILE: algorithms/bit_manipulation/find_difference.py
================================================
"""
Find the Difference
Given two strings where the second is generated by shuffling the first and
adding one extra letter, find the added letter using XOR.
Reference: https://en.wikipedia.org/wiki/Exclusive_or
Complexity:
Time: O(n) where n is the length of the longer string
Space: O(1)
"""
from __future__ import annotations
def find_difference(original: str, shuffled: str) -> str:
"""Find the single character added to a shuffled copy of a string.
Uses XOR on all character code points; paired characters cancel out,
leaving only the extra character.
Args:
original: The original string.
shuffled: The shuffled string with one extra character.
Returns:
The single character that was added.
Examples:
>>> find_difference("abcd", "abecd")
'e'
"""
xor_result = 0
for character in original + shuffled:
xor_result ^= ord(character)
return chr(xor_result)
================================================
FILE: algorithms/bit_manipulation/find_missing_number.py
================================================
"""
Find Missing Number
Given a sequence of unique integers in the range [0..n] with one value
missing, find and return that missing number. Two approaches are provided:
XOR-based and summation-based.
Reference: https://en.wikipedia.org/wiki/Exclusive_or
Complexity:
Time: O(n)
Space: O(1)
"""
from __future__ import annotations
def find_missing_number(nums: list[int]) -> int:
"""Find the missing number using XOR.
XORs every element with its expected index so that all paired values
cancel out, leaving only the missing number.
Args:
nums: A list of unique integers from 0..n with one missing.
Returns:
The missing integer.
Examples:
>>> find_missing_number([4, 1, 3, 0, 6, 5, 2])
7
>>> find_missing_number([0])
1
"""
missing = 0
for index, number in enumerate(nums):
missing ^= number
missing ^= index + 1
return missing
def find_missing_number2(nums: list[int]) -> int:
"""Find the missing number using arithmetic summation.
Computes the expected sum of 0..n and subtracts the actual sum of
the list to isolate the missing value.
Args:
nums: A list of unique integers from 0..n with one missing.
Returns:
The missing integer.
Examples:
>>> find_missing_number2([4, 1, 3, 0, 6, 5, 2])
7
>>> find_missing_number2([0])
1
"""
total = sum(nums)
length = len(nums)
expected_total = length * (length + 1) // 2
return expected_total - total
================================================
FILE: algorithms/bit_manipulation/flip_bit_longest_sequence.py
================================================
"""
Flip Bit Longest Sequence
Given an integer, find the length of the longest sequence of 1-bits you
can create by flipping exactly one 0-bit to a 1-bit.
Reference: https://en.wikipedia.org/wiki/Bit_manipulation
Complexity:
Time: O(b) where b is the number of bits in the integer
Space: O(1)
"""
from __future__ import annotations
def flip_bit_longest_seq(number: int) -> int:
"""Find the longest 1-bit run achievable by flipping a single 0-bit.
Tracks the current run length and the previous run length to
determine the best sequence that can be formed by bridging two
runs with a single flipped bit.
Args:
number: A non-negative integer.
Returns:
The length of the longest sequence of 1-bits after one flip.
Examples:
>>> flip_bit_longest_seq(1775)
8
>>> flip_bit_longest_seq(0)
1
"""
current_length = 0
previous_length = 0
max_length = 0
while number:
if number & 1 == 1:
current_length += 1
elif number & 1 == 0:
previous_length = 0 if number & 2 == 0 else current_length
current_length = 0
max_length = max(max_length, previous_length + current_length)
number >>= 1
return max_length + 1
================================================
FILE: algorithms/bit_manipulation/gray_code.py
================================================
"""Gray code — generate n-bit Gray code sequences.
A Gray code is an ordering of binary numbers such that successive values
differ in exactly one bit. Used in error correction and rotary encoders.
Inspired by PR #932 (Simranstha045).
"""
from __future__ import annotations
def gray_code(n: int) -> list[int]:
"""Return the n-bit Gray code sequence as a list of integers.
Uses the reflection (mirror) construction:
gray(i) = i ^ (i >> 1)
>>> gray_code(2)
[0, 1, 3, 2]
>>> gray_code(3)
[0, 1, 3, 2, 6, 7, 5, 4]
"""
return [i ^ (i >> 1) for i in range(1 << n)]
def gray_to_binary(gray: int) -> int:
"""Convert a Gray-coded integer back to standard binary."""
mask = gray >> 1
while mask:
gray ^= mask
mask >>= 1
return gray
================================================
FILE: algorithms/bit_manipulation/has_alternative_bit.py
================================================
"""
Has Alternating Bits
Check whether a positive integer has alternating bits, meaning no two
adjacent bits share the same value.
Reference: https://en.wikipedia.org/wiki/Bit_manipulation
Complexity:
has_alternative_bit: O(number of bits)
has_alternative_bit_fast: O(1)
"""
from __future__ import annotations
def has_alternative_bit(number: int) -> bool:
"""Check for alternating bits by scanning each pair of adjacent bits.
Args:
number: A positive integer to check.
Returns:
True if every pair of adjacent bits differs, False otherwise.
Examples:
>>> has_alternative_bit(5)
True
>>> has_alternative_bit(7)
False
"""
first_bit = 0
second_bit = 0
while number:
first_bit = number & 1
if number >> 1:
second_bit = (number >> 1) & 1
if not first_bit ^ second_bit:
return False
else:
return True
number >>= 1
return True
def has_alternative_bit_fast(number: int) -> bool:
"""Check for alternating bits using O(1) bitmask arithmetic.
Args:
number: A positive integer to check.
Returns:
True if every pair of adjacent bits differs, False otherwise.
Examples:
>>> has_alternative_bit_fast(5)
True
>>> has_alternative_bit_fast(7)
False
"""
mask_even_bits = int("aaaaaaaa", 16) # ...10101010
mask_odd_bits = int("55555555", 16) # ...01010101
return mask_even_bits == (number + (number ^ mask_even_bits)) or mask_odd_bits == (
number + (number ^ mask_odd_bits)
)
================================================
FILE: algorithms/bit_manipulation/insert_bit.py
================================================
"""
Insert Bit
Insert one or more bits into an integer at a specific bit position.
Reference: https://en.wikipedia.org/wiki/Bit_manipulation
Complexity:
Time: O(1)
Space: O(1)
"""
from __future__ import annotations
def insert_one_bit(number: int, bit: int, position: int) -> int:
"""Insert a single bit at a specific position in an integer.
Splits the number at *position*, shifts the upper part left by one
to make room, inserts *bit*, and merges with the lower part.
Args:
number: The integer to modify.
bit: The bit value to insert (0 or 1).
position: Zero-based index at which to insert the bit.
Returns:
The resulting integer after insertion.
Examples:
>>> insert_one_bit(21, 1, 2)
45
>>> insert_one_bit(21, 0, 2)
41
"""
upper = number >> position
upper = (upper << 1) | bit
upper = upper << position
lower = ((1 << position) - 1) & number
return lower | upper
def insert_mult_bits(number: int, bits: int, length: int, position: int) -> int:
"""Insert multiple bits at a specific position in an integer.
Splits the number at *position*, shifts the upper part left by
*length* positions, inserts the *bits* value, and merges with the
lower part.
Args:
number: The integer to modify.
bits: The bit pattern to insert.
length: The number of bits in the pattern.
position: Zero-based index at which to insert.
Returns:
The resulting integer after insertion.
Examples:
>>> insert_mult_bits(5, 7, 3, 1)
47
>>> insert_mult_bits(5, 7, 3, 3)
61
"""
upper = number >> position
upper = (upper << length) | bits
upper = upper << position
lower = ((1 << position) - 1) & number
return lower | upper
================================================
FILE: algorithms/bit_manipulation/power_of_two.py
================================================
"""
Power of Two
Determine whether a given integer is a power of two using bit manipulation.
A power of two has exactly one set bit, so ``n & (n - 1)`` clears that bit
and yields zero.
Reference: https://en.wikipedia.org/wiki/Power_of_two
Complexity:
Time: O(1)
Space: O(1)
"""
from __future__ import annotations
def is_power_of_two(number: int) -> bool:
"""Check whether an integer is a power of two.
Args:
number: The integer to test.
Returns:
True if *number* is a positive power of two, False otherwise.
Examples:
>>> is_power_of_two(64)
True
>>> is_power_of_two(91)
False
>>> is_power_of_two(0)
False
"""
return number > 0 and not number & (number - 1)
================================================
FILE: algorithms/bit_manipulation/remove_bit.py
================================================
"""
Remove Bit
Remove a single bit at a specific position from an integer, shifting
higher bits down to fill the gap.
Reference: https://en.wikipedia.org/wiki/Bit_manipulation
Complexity:
Time: O(1)
Space: O(1)
"""
from __future__ import annotations
def remove_bit(number: int, position: int) -> int:
"""Remove the bit at a specific position from an integer.
Splits the number around *position*, shifts the upper part right
by one to collapse the gap, and merges with the lower part.
Args:
number: The integer to modify.
position: Zero-based index of the bit to remove.
Returns:
The resulting integer after removal.
Examples:
>>> remove_bit(21, 2)
9
>>> remove_bit(21, 4)
5
>>> remove_bit(21, 0)
10
"""
upper = number >> (position + 1)
upper = upper << position
lower = ((1 << position) - 1) & number
return upper | lower
================================================
FILE: algorithms/bit_manipulation/reverse_bits.py
================================================
"""
Reverse Bits
Reverse the bits of a 32-bit unsigned integer.
Reference: https://en.wikipedia.org/wiki/Bit_reversal
Complexity:
Time: O(1) -- always iterates exactly 32 times
Space: O(1)
"""
from __future__ import annotations
def reverse_bits(number: int) -> int:
"""Reverse all 32 bits of an unsigned integer.
Args:
number: A 32-bit unsigned integer (0 to 2**32 - 1).
Returns:
The integer formed by reversing the bit order.
Examples:
>>> reverse_bits(43261596)
964176192
>>> reverse_bits(0)
0
"""
result = 0
for _ in range(32):
result = (result << 1) + (number & 1)
number >>= 1
return result
================================================
FILE: algorithms/bit_manipulation/single_number.py
================================================
"""
Single Number
Given an array of integers where every element appears twice except for
one, find the unique element using XOR.
Reference: https://en.wikipedia.org/wiki/Exclusive_or
Complexity:
Time: O(n)
Space: O(1)
"""
from __future__ import annotations
def single_number(nums: list[int]) -> int:
"""Find the element that appears only once (all others appear twice).
XORs all values together; paired values cancel to zero, leaving the
unique value.
Args:
nums: A list of integers where every element except one appears
an even number of times.
Returns:
The single element, or 0 if all elements are paired.
Examples:
>>> single_number([1, 0, 2, 1, 2, 3, 3])
0
>>> single_number([101])
101
"""
result = 0
for number in nums:
result ^= number
return result
================================================
FILE: algorithms/bit_manipulation/single_number2.py
================================================
"""
Single Number 2
Given an array of integers where every element appears three times except
for one (which appears exactly once), find that unique element using
constant space and linear time.
Reference: https://en.wikipedia.org/wiki/Exclusive_or
Complexity:
Time: O(n)
Space: O(1)
"""
from __future__ import annotations
def single_number2(nums: list[int]) -> int:
"""Find the element that appears once (all others appear three times).
Uses two accumulators (*ones* and *twos*) to track bits that have
appeared once and twice respectively; bits appearing a third time
are cleared from both accumulators.
Args:
nums: A list of integers where every element except one appears
exactly three times.
Returns:
The single element that appears only once.
Examples:
>>> single_number2([4, 2, 3, 2, 1, 1, 4, 2, 4, 1])
3
"""
ones, twos = 0, 0
for index in range(len(nums)):
ones = (ones ^ nums[index]) & ~twos
twos = (twos ^ nums[index]) & ~ones
return ones
================================================
FILE: algorithms/bit_manipulation/single_number3.py
================================================
"""
Single Number 3
Given an array where exactly two elements appear once and all others
appear exactly twice, find those two unique elements in O(n) time and
O(1) space.
Reference: https://en.wikipedia.org/wiki/Exclusive_or
Complexity:
Time: O(n)
Space: O(1)
"""
from __future__ import annotations
def single_number3(nums: list[int]) -> list[int]:
"""Find the two elements that each appear exactly once.
Uses XOR to isolate the combined signature of the two unique values,
then partitions all numbers by a distinguishing bit to separate them.
Args:
nums: A list of integers where exactly two elements appear once
and all others appear exactly twice.
Returns:
A list containing the two unique elements.
Examples:
>>> sorted(single_number3([1, 2, 1, 3, 2, 5]))
[3, 5]
"""
xor_both = 0
for number in nums:
xor_both ^= number
rightmost_set_bit = xor_both & (-xor_both)
first, second = 0, 0
for number in nums:
if number & rightmost_set_bit:
first ^= number
else:
second ^= number
return [first, second]
================================================
FILE: algorithms/bit_manipulation/subsets.py
================================================
"""
Subsets via Bit Manipulation
Generate all possible subsets of a set of distinct integers using bitmask
enumeration. Each integer from 0 to 2^n - 1 represents a unique subset.
Reference: https://en.wikipedia.org/wiki/Power_set
Complexity:
Time: O(n * 2^n)
Space: O(n * 2^n)
"""
from __future__ import annotations
def subsets(nums: list[int]) -> set[tuple[int, ...]]:
"""Return all subsets of the given list as a set of tuples.
Uses bitmask enumeration: for each number from 0 to 2^n - 1, the
set bits indicate which elements are included in that subset.
Args:
nums: A list of distinct integers.
Returns:
A set of tuples, each representing one subset.
Examples:
>>> sorted(subsets([1, 2, 3]))
[(), (1,), (1, 2), (1, 2, 3), (1, 3), (2,), (2, 3), (3,)]
"""
length = len(nums)
total = 1 << length
result: set[tuple[int, ...]] = set()
for mask in range(total):
subset = tuple(
number for bit_index, number in enumerate(nums) if mask & 1 << bit_index
)
result.add(subset)
return result
================================================
FILE: algorithms/bit_manipulation/swap_pair.py
================================================
"""
Swap Pair
Swap odd and even bits of an integer using bitmask operations. Bit 0 is
swapped with bit 1, bit 2 with bit 3, and so on.
Reference: https://en.wikipedia.org/wiki/Bit_manipulation
Complexity:
Time: O(1)
Space: O(1)
"""
from __future__ import annotations
def swap_pair(number: int) -> int:
"""Swap every pair of adjacent bits in an integer.
Masks odd-positioned bits (0xAAAAAAAA), shifts them right by one,
masks even-positioned bits (0x55555555), shifts them left by one,
and merges the results.
Args:
number: A non-negative integer.
Returns:
The integer with each adjacent pair of bits swapped.
Examples:
>>> swap_pair(22)
41
>>> swap_pair(10)
5
"""
odd_bits = (number & int("AAAAAAAA", 16)) >> 1
even_bits = (number & int("55555555", 16)) << 1
return odd_bits | even_bits
================================================
FILE: algorithms/common/__init__.py
================================================
"""Shared data types used across all algorithm categories.
These types are the connective tissue of the library — every algorithm
accepts and returns these types, making them composable.
>>> from algorithms.common import TreeNode, ListNode, Graph
"""
from algorithms.common.graph import Graph
from algorithms.common.list_node import ListNode
from algorithms.common.tree_node import TreeNode
__all__ = ["TreeNode", "ListNode", "Graph"]
================================================
FILE: algorithms/common/graph.py
================================================
"""Graph type shared across all graph algorithms.
This module provides the universal Graph used by every graph algorithm
in this library. Using a single shared type means you can compose
algorithms: build a graph, run BFS to check connectivity, then run
Dijkstra for shortest paths — all on the same object.
"""
from __future__ import annotations
from dataclasses import dataclass, field
@dataclass
class Graph:
"""A weighted directed graph using adjacency dict representation.
Supports weighted/unweighted and directed/undirected graphs. The
graph is stored as ``{node: {neighbor: weight}}``. For unweighted
graphs, use the :meth:`unweighted` factory or set weights to 1.
Attributes:
adj: Adjacency dict mapping each node to ``{neighbor: weight}``.
directed: Whether this is a directed graph.
Examples:
>>> g = Graph({"a": {"b": 1, "c": 4}, "b": {"c": 2}})
>>> g.adj["a"]
{'b': 1, 'c': 4}
>>> g = Graph.unweighted({"a": ["b", "c"], "b": ["c"]})
>>> g.adj["a"]
{'b': 1, 'c': 1}
"""
adj: dict[str, dict[str, float]] = field(default_factory=dict)
directed: bool = True
@classmethod
def unweighted(cls, adj: dict[str, list[str]], directed: bool = True) -> Graph:
"""Create a graph from an unweighted adjacency list.
Args:
adj: Mapping of node to list of neighbors.
directed: Whether edges are one-directional.
Returns:
A Graph with all edge weights set to 1.
Examples:
>>> g = Graph.unweighted({"a": ["b", "c"], "b": ["c"]})
>>> g.adj["b"]
{'c': 1}
"""
weighted = {
node: {neighbor: 1 for neighbor in neighbors}
for node, neighbors in adj.items()
}
return cls(adj=weighted, directed=directed)
def nodes(self) -> set[str]:
"""Return all nodes in the graph.
Returns:
Set of all node identifiers, including nodes that only
appear as neighbors.
Examples:
>>> g = Graph({"a": {"b": 1}})
>>> sorted(g.nodes())
['a', 'b']
"""
all_nodes: set[str] = set(self.adj.keys())
for neighbors in self.adj.values():
all_nodes.update(neighbors.keys())
return all_nodes
def add_edge(self, source: str, target: str, weight: float = 1) -> None:
"""Add an edge to the graph.
For undirected graphs, the reverse edge is also added.
Args:
source: Source node.
target: Target node.
weight: Edge weight (default 1).
Examples:
>>> g = Graph()
>>> g.add_edge("a", "b", 5)
>>> g.adj["a"]["b"]
5
"""
if source not in self.adj:
self.adj[source] = {}
self.adj[source][target] = weight
if not self.directed:
if target not in self.adj:
self.adj[target] = {}
self.adj[target][source] = weight
================================================
FILE: algorithms/common/list_node.py
================================================
"""Singly linked list node shared across all linked list algorithms.
This module provides the universal ListNode used by every linked list
algorithm in this library. Using a single shared type means you can
compose algorithms: merge two lists, reverse the result, check if
it's a palindrome.
"""
from __future__ import annotations
from dataclasses import dataclass
@dataclass
class ListNode:
"""A node in a singly linked list.
Attributes:
val: The value stored in this node.
next: Reference to the next node.
Examples:
>>> head = ListNode(1, ListNode(2, ListNode(3)))
>>> head.val
1
>>> head.next.val
2
"""
val: int = 0
next: ListNode | None = None
================================================
FILE: algorithms/common/tree_node.py
================================================
"""Binary tree node shared across all tree algorithms.
This module provides the universal TreeNode used by every tree algorithm
in this library. Using a single shared type means you can compose
algorithms freely: build a BST, invert it, then traverse it.
"""
from __future__ import annotations
from dataclasses import dataclass
@dataclass
class TreeNode:
"""A node in a binary tree.
Attributes:
val: The value stored in this node.
left: Reference to the left child.
right: Reference to the right child.
Examples:
>>> root = TreeNode(1, TreeNode(2), TreeNode(3))
>>> root.left.val
2
>>> root.right.val
3
"""
val: int = 0
left: TreeNode | None = None
right: TreeNode | None = None
================================================
FILE: algorithms/compression/__init__.py
================================================
from .elias import elias_delta, elias_gamma
from .huffman_coding import HuffmanCoding
from .rle_compression import decode_rle, encode_rle
__all__ = [
"HuffmanCoding",
"decode_rle",
"elias_delta",
"elias_gamma",
"encode_rle",
]
================================================
FILE: algorithms/compression/elias.py
================================================
"""
Elias Gamma and Delta Coding
Universal codes for encoding positive integers. Elias gamma code uses a unary
prefix followed by a binary suffix. Elias delta code nests gamma coding for
the length prefix. Both were developed by Peter Elias.
Reference: https://en.wikipedia.org/wiki/Elias_gamma_coding
Complexity:
Time: O(log n) per encoded integer
Space: O(log n)
"""
from __future__ import annotations
from math import log
def _log2(x: int | float) -> float:
"""Compute log base 2.
Args:
x: A positive number.
Returns:
The base-2 logarithm of x.
"""
return log(x, 2)
def _binary(x: int, length: int = 1) -> str:
"""Return the binary representation of x zero-padded to length digits.
Args:
x: A non-negative integer.
length: Minimum number of binary digits.
Returns:
A binary string.
"""
fmt = f"{{0:0{length}b}}"
return fmt.format(x)
def _unary(x: int) -> str:
"""Return the unary representation of x.
Args:
x: A positive integer.
Returns:
A unary-coded string (x-1 ones followed by a zero).
"""
return (x - 1) * "1" + "0"
def _elias_generic(
length_encoding: callable,
x: int,
) -> str:
"""Generic Elias encoding using a pluggable length-encoding function.
Args:
length_encoding: A function to encode the length prefix.
x: A non-negative integer to encode.
Returns:
The Elias-coded bit string.
"""
if x == 0:
return "0"
first_part = 1 + int(_log2(x))
remainder = x - 2 ** int(_log2(x))
bit_count = int(_log2(x))
return length_encoding(first_part) + _binary(remainder, bit_count)
def elias_gamma(x: int) -> str:
"""Encode a positive integer using Elias gamma coding.
Args:
x: A non-negative integer.
Returns:
The Elias gamma coded bit string.
Examples:
>>> elias_gamma(1)
'0'
>>> elias_gamma(5)
'00101'
"""
return _elias_generic(_unary, x)
def elias_delta(x: int) -> str:
"""Encode a positive integer using Elias delta coding.
Args:
x: A non-negative integer.
Returns:
The Elias delta coded bit string.
Examples:
>>> elias_delta(1)
'0'
>>> elias_delta(5)
'01101'
"""
return _elias_generic(elias_gamma, x)
================================================
FILE: algorithms/compression/huffman_coding.py
================================================
"""
Huffman Coding
An efficient method of lossless data compression. Symbols appearing more
frequently are encoded with shorter bit strings while less frequent symbols
receive longer codes.
Reference: https://en.wikipedia.org/wiki/Huffman_coding
Complexity:
Time: O(n log n) for encoding (heap operations)
Space: O(n) for the code table
"""
from __future__ import annotations
import heapq
from collections import defaultdict, deque
class Node:
"""A node in the Huffman tree."""
def __init__(
self,
frequency: int = 0,
sign: int | None = None,
left: Node | None = None,
right: Node | None = None,
) -> None:
self.frequency = frequency
self.sign = sign
self.left = left
self.right = right
def __lt__(self, other: Node) -> bool:
return self.frequency < other.frequency
def __gt__(self, other: Node) -> bool:
return self.frequency > other.frequency
def __eq__(self, other: object) -> bool:
if not isinstance(other, Node):
return NotImplemented
return self.frequency == other.frequency
def __str__(self) -> str:
return f"<ch: {self.sign}: {self.frequency}>"
def __repr__(self) -> str:
return f"<ch: {self.sign}: {self.frequency}>"
class HuffmanReader:
"""Reads Huffman-encoded binary data from a file."""
def __init__(self, file: object) -> None:
self.file = file
self.buffer: list[str] = []
self.is_last_byte: bool = False
def get_number_of_additional_bits_in_the_last_byte(self) -> int:
"""Read the 3-bit header indicating extra padding bits.
Returns:
The number of additional padding bits in the last byte.
"""
bin_num = self.get_bit() + self.get_bit() + self.get_bit()
return int(bin_num, 2)
def load_tree(self) -> Node:
"""Reconstruct the Huffman tree from the file header.
Returns:
The root node of the reconstructed tree.
"""
node_stack: deque[Node] = deque()
queue_leaves: deque[Node] = deque()
root = Node()
current_node = root
is_end_of_tree = False
while not is_end_of_tree:
current_bit = self.get_bit()
if current_bit == "0":
current_node.left = Node()
current_node.right = Node()
node_stack.append(current_node.right)
current_node = current_node.left
else:
queue_leaves.append(current_node)
if node_stack:
current_node = node_stack.pop()
else:
is_end_of_tree = True
self._fill_tree(queue_leaves)
return root
def _fill_tree(self, leaves_queue: deque[Node]) -> None:
"""Load character values into leaf nodes.
Args:
leaves_queue: Queue of leaf nodes to populate.
"""
leaves_queue.reverse()
while leaves_queue:
node = leaves_queue.pop()
char_value = int(self.get_byte(), 2)
node.sign = char_value
def _load_byte(self, buff_limit: int = 8) -> bool:
"""Load the next byte into the buffer if needed.
Args:
buff_limit: Minimum buffer size before loading.
Returns:
True if enough bits are available for reading.
"""
if len(self.buffer) <= buff_limit:
byte = self.file.read(1)
if not byte:
return False
integer = int.from_bytes(byte, "big")
self.buffer.extend(list(f"{integer:08b}"))
return True
def get_bit(self, buff_limit: int = 8) -> str | int:
"""Read a single bit from the buffer.
Args:
buff_limit: Minimum buffer size before loading.
Returns:
A '0' or '1' character, or -1 if at end of file.
"""
if self._load_byte(buff_limit):
return self.buffer.pop(0)
return -1
def get_byte(self) -> str | int:
"""Read eight bits from the buffer.
Returns:
An 8-character binary string, or -1 if at end of file.
"""
if self._load_byte():
byte_list = self.buffer[:8]
self.buffer = self.buffer[8:]
return "".join(byte_list)
return -1
class HuffmanWriter:
"""Writes Huffman-encoded binary data to a file."""
def __init__(self, file: object) -> None:
self.file = file
self.buffer: str = ""
self.saved_bits: int = 0
def write_char(self, char: str) -> None:
"""Write a character as its 8-bit ordinal value.
Args:
char: A single character to write.
"""
self.write_int(ord(char))
def write_int(self, num: int) -> None:
"""Write an integer as an 8-bit binary value.
Args:
num: An integer (0-255) to write.
"""
bin_int = f"{num:08b}"
self.write_bits(bin_int)
def write_bits(self, bits: str) -> None:
"""Write a string of bits, flushing complete bytes.
Args:
bits: A string of '0' and '1' characters.
"""
self.saved_bits += len(bits)
self.buffer += bits
while len(self.buffer) >= 8:
integer = int(self.buffer[:8], 2)
self.file.write(bytes([integer]))
self.buffer = self.buffer[8:]
def save_tree(self, tree: Node) -> None:
"""Serialize the Huffman tree structure to the file.
Args:
tree: The root node of the Huffman tree.
"""
signs: list[int] = []
tree_code = ""
def _get_code_tree(node: Node) -> None:
nonlocal tree_code
if node.sign is not None:
signs.append(node.sign)
if node.left:
tree_code += "0"
_get_code_tree(node.left)
if node.right:
tree_code += "1"
_get_code_tree(node.right)
_get_code_tree(tree)
self.write_bits(tree_code + "1")
for int_sign in signs:
self.write_int(int_sign)
def _save_information_about_additional_bits(self, additional_bits: int) -> None:
"""Overwrite the first three bits to record padding count.
Args:
additional_bits: The number of padding bits appended.
"""
self.file.seek(0)
first_byte_raw = self.file.read(1)
self.file.seek(0)
first_byte = "{:08b}".format(int.from_bytes(first_byte_raw, "big"))
first_byte = f"{additional_bits:03b}" + first_byte[3:]
self.write_bits(first_byte)
def close(self) -> None:
"""Flush remaining bits with padding and finalize the file."""
additional_bits = 8 - len(self.buffer)
if additional_bits != 8:
self.write_bits("0" * additional_bits)
self._save_information_about_additional_bits(additional_bits)
class TreeFinder:
"""Traverses a Huffman tree to decode individual symbols."""
def __init__(self, tree: Node) -> None:
self.root = tree
self.current_node = tree
self.found: int | str | None = None
def find(self, bit: str) -> bool:
"""Advance one step in the tree and check for a decoded symbol.
Args:
bit: '0' for left, '1' for right.
Returns:
True if a symbol was found at the current node.
"""
if bit == "0":
self.current_node = self.current_node.left
elif bit == "1":
self.current_node = self.current_node.right
else:
self._reset()
return True
if self.current_node.sign is not None:
self._reset(self.current_node.sign)
return True
return False
def _reset(self, found: int | str = "") -> None:
"""Reset traversal to the root after finding a symbol.
Args:
found: The decoded symbol value.
"""
self.found = found
self.current_node = self.root
class HuffmanCoding:
"""Provides static methods for Huffman file encoding and decoding."""
def __init__(self) -> None:
pass
@staticmethod
def decode_file(file_in_name: str, file_out_name: str) -> None:
"""Decode a Huffman-encoded file.
Args:
file_in_name: Path to the encoded input file.
file_out_name: Path to the decoded output file.
"""
with open(file_in_name, "rb") as file_in, open(file_out_name, "wb") as file_out:
reader = HuffmanReader(file_in)
additional_bits = reader.get_number_of_additional_bits_in_the_last_byte()
tree = reader.load_tree()
HuffmanCoding._decode_and_write_signs_to_file(
file_out, reader, tree, additional_bits
)
@staticmethod
def _decode_and_write_signs_to_file(
file: object,
reader: HuffmanReader,
tree: Node,
additional_bits: int,
) -> None:
"""Decode bits from reader and write decoded bytes to file.
Args:
file: The output file object.
reader: The HuffmanReader providing encoded bits.
tree: The root of the Huffman tree.
additional_bits: Number of padding bits in the last byte.
"""
tree_finder = TreeFinder(tree)
is_end_of_file = False
while not is_end_of_file:
bit = reader.get_bit()
if bit != -1:
while not tree_finder.find(bit):
bit = reader.get_bit(0)
file.write(bytes([tree_finder.found]))
else:
is_end_of_file = True
last_byte = reader.buffer
last_byte = last_byte[:-additional_bits]
for bit in last_byte:
if tree_finder.find(bit):
file.write(bytes([tree_finder.found]))
@staticmethod
def encode_file(file_in_name: str, file_out_name: str) -> None:
"""Encode a file using Huffman coding.
Args:
file_in_name: Path to the raw input file.
file_out_name: Path to the encoded output file.
"""
with (
open(file_in_name, "rb") as file_in,
open(file_out_name, mode="wb+") as file_out,
):
signs_frequency = HuffmanCoding._get_char_frequency(file_in)
file_in.seek(0)
tree = HuffmanCoding._create_tree(signs_frequency)
codes = HuffmanCoding._generate_codes(tree)
writer = HuffmanWriter(file_out)
writer.write_bits("000")
writer.save_tree(tree)
HuffmanCoding._encode_and_write_signs_to_file(file_in, writer, codes)
writer.close()
@staticmethod
def _encode_and_write_signs_to_file(
file: object, writer: HuffmanWriter, codes: dict[int, str]
) -> None:
"""Read bytes from file and write their Huffman codes.
Args:
file: The input file object.
writer: The HuffmanWriter for output.
codes: Mapping of byte values to Huffman code strings.
"""
sign = file.read(1)
while sign:
int_char = int.from_bytes(sign, "big")
writer.write_bits(codes[int_char])
sign = file.read(1)
@staticmethod
def _get_char_frequency(file: object) -> dict[int, int]:
"""Count byte frequencies in a file.
Args:
file: The input file object.
Returns:
A dict mapping byte values to their frequencies.
"""
is_end_of_file = False
signs_frequency: dict[int, int] = defaultdict(lambda: 0)
while not is_end_of_file:
prev_pos = file.tell()
sign = file.read(1)
curr_pos = file.tell()
if prev_pos == curr_pos:
is_end_of_file = True
else:
signs_frequency[int.from_bytes(sign, "big")] += 1
return signs_frequency
@staticmethod
def _generate_codes(tree: Node) -> dict[int, str]:
"""Generate Huffman codes from the tree.
Args:
tree: The root of the Huffman tree.
Returns:
A dict mapping byte values to their binary code strings.
"""
codes: dict[int, str] = {}
HuffmanCoding._go_through_tree_and_create_codes(tree, "", codes)
return codes
@staticmethod
def _create_tree(signs_frequency: dict[int, int]) -> Node:
"""Build a Huffman tree from character frequencies.
Args:
signs_frequency: Mapping of byte values to frequencies.
Returns:
The root node of the constructed Huffman tree.
"""
nodes = [
Node(frequency=frequency, sign=char_int)
for char_int, frequency in signs_frequency.items()
]
heapq.heapify(nodes)
while len(nodes) > 1:
left = heapq.heappop(nodes)
right = heapq.heappop(nodes)
new_node = Node(
frequency=left.frequency + right.frequency,
left=left,
right=right,
)
heapq.heappush(nodes, new_node)
return nodes[0]
@staticmethod
def _go_through_tree_and_create_codes(
tree: Node, code: str, dict_codes: dict[int, str]
) -> None:
"""Recursively traverse the tree to build code mappings.
Args:
tree: The current node being visited.
code: The accumulated bit string for this path.
dict_codes: The output dict to populate.
"""
if tree.sign is not None:
dict_codes[tree.sign] = code
if tree.left:
HuffmanCoding._go_through_tree_and_create_codes(
tree.left, code + "0", dict_codes
)
if tree.right:
HuffmanCoding._go_through_tree_and_create_codes(
tree.right, code + "1", dict_codes
)
================================================
FILE: algorithms/compression/rle_compression.py
================================================
"""
Run-Length Encoding (RLE)
A simple lossless compression algorithm that encodes consecutive repeated
characters as a count followed by the character. Decompression fully recovers
the original data.
Reference: https://en.wikipedia.org/wiki/Run-length_encoding
Complexity:
Time: O(n)
Space: O(n)
"""
from __future__ import annotations
def encode_rle(data: str) -> str:
"""Compress a string using run-length encoding.
Args:
data: The input string to compress.
Returns:
The RLE-encoded string.
Examples:
>>> encode_rle("aaabbc")
'3a2b1c'
>>> encode_rle("")
''
"""
if not data:
return ""
encoded: str = ""
prev_char: str = ""
count: int = 1
for char in data:
if char != prev_char:
if prev_char:
encoded += str(count) + prev_char
count = 1
prev_char = char
else:
count += 1
return encoded + str(count) + prev_char
def decode_rle(data: str) -> str:
"""Decompress a run-length encoded string.
Args:
data: The RLE-encoded string.
Returns:
The decoded original string.
Examples:
>>> decode_rle("3a2b1c")
'aaabbc'
>>> decode_rle("")
''
"""
decoded: str = ""
count: str = ""
for char in data:
if not char.isdigit():
decoded += char * int(count)
count = ""
else:
count += char
return decoded
================================================
FILE: algorithms/data_structures/__init__.py
================================================
"""Reusable data structure implementations.
This package contains the core data structures used throughout the library.
Each module provides a self-contained implementation suitable for study.
>>> from algorithms.data_structures import BinaryHeap, ArrayStack
"""
# Tree data structures (moved from tree/ subdirectories in Phase 8)
from algorithms.data_structures.avl_tree import AvlTree
from algorithms.data_structures.b_tree import BTree
from algorithms.data_structures.bst import BST
from algorithms.data_structures.fenwick_tree import Fenwick_Tree
from algorithms.data_structures.graph import DirectedEdge, DirectedGraph, Node
from algorithms.data_structures.hash_table import HashTable, ResizableHashTable
from algorithms.data_structures.heap import AbstractHeap, BinaryHeap
from algorithms.data_structures.iterative_segment_tree import SegmentTree
from algorithms.data_structures.kd_tree import KDTree
from algorithms.data_structures.linked_list import (
DoublyLinkedListNode,
SinglyLinkedListNode,
)
from algorithms.data_structures.priority_queue import PriorityQueue, PriorityQueueNode
from algorithms.data_structures.queue import (
AbstractQueue,
ArrayQueue,
LinkedListQueue,
QueueNode,
)
from algorithms.data_structures.red_black_tree import RBTree
from algorithms.data_structures.segment_tree import SegmentTree as SegmentTreeRecursive
from algorithms.data_structures.separate_chaining_hash_table import (
SeparateChainingHashTable,
)
from algorithms.data_structures.sqrt_decomposition import SqrtDecomposition
from algorithms.data_structures.stack import (
AbstractStack,
ArrayStack,
LinkedListStack,
StackNode,
)
from algorithms.data_structures.trie import Trie
from algorithms.data_structures.union_find import Union
__all__ = [
"AbstractHeap",
"AbstractQueue",
"AbstractStack",
"ArrayQueue",
"ArrayStack",
"BinaryHeap",
"DirectedEdge",
"DirectedGraph",
"DoublyLinkedListNode",
"HashTable",
"LinkedListQueue",
"LinkedListStack",
"Node",
"PriorityQueue",
"PriorityQueueNode",
"QueueNode",
"ResizableHashTable",
"SeparateChainingHashTable",
"SinglyLinkedListNode",
"StackNode",
"Union",
# Tree data structures
"AvlTree",
"BTree",
"BST",
"Fenwick_Tree",
"RBTree",
"SegmentTree",
"SegmentTreeRecursive",
"Trie",
"KDTree",
"SqrtDecomposition",
]
================================================
FILE: algorithms/data_structures/avl_tree.py
================================================
"""Imports TreeNodes"""
from algorithms.common.tree_node import TreeNode
class AvlTree:
"""
An avl tree.
"""
def __init__(self):
# Root node of the tree.
self.node = None
self.height = -1
self.balance = 0
def insert(self, key):
"""
Insert new key into node
"""
# Create new node
node = TreeNode(key)
if not self.node:
self.node = node
self.node.left = AvlTree()
self.node.right = AvlTree()
elif key < self.node.val:
self.node.left.insert(key)
elif key > self.node.val:
self.node.right.insert(key)
self.re_balance()
def re_balance(self):
"""
Re balance tree. After inserting or deleting a node,
"""
self.update_heights(recursive=False)
self.update_balances(False)
while self.balance < -1 or self.balance > 1:
if self.balance > 1:
if self.node.left.balance < 0:
self.node.left.rotate_left()
self.update_heights()
self.update_balances()
self.rotate_right()
self.update_heights()
self.update_balances()
if self.balance < -1:
if self.node.right.balance > 0:
self.node.right.rotate_right()
self.update_heights()
self.update_balances()
self.rotate_left()
self.update_heights()
self.update_balances()
def update_heights(self, recursive=True):
"""
Update tree height
"""
if self.node:
if recursive:
if self.node.left:
self.node.left.update_heights()
if self.node.right:
self.node.right.update_heights()
self.height = 1 + max(self.node.left.height, self.node.right.height)
else:
self.height = -1
def update_balances(self, recursive=True):
"""
Calculate tree balance factor
"""
if self.node:
if recursive:
if self.node.left:
self.node.left.update_balances()
if self.node.right:
self.node.right.update_balances()
self.balance = self.node.left.height - self.node.right.height
else:
self.balance = 0
def rotate_right(self):
"""
Right rotation
"""
new_root = self.node.left.node
new_left_sub = new_root.right.node
old_root = self.node
self.node = new_root
old_root.left.node = new_left_sub
new_root.right.node = old_root
def rotate_left(self):
"""
Left rotation
"""
new_root = self.node.right.node
new_left_sub = new_root.left.node
old_root = self.node
self.node = new_root
old_root.right.node = new_left_sub
new_root.left.node = old_root
def in_order_traverse(self):
"""
In-order traversal of the tree
"""
result = []
if not self.node:
return result
result.extend(self.node.left.in_order_traverse())
result.append(self.node.val)
result.extend(self.node.right.in_order_traverse())
return result
================================================
FILE: algorithms/data_structures/b_tree.py
================================================
"""
B-Tree
A self-balancing tree data structure optimized for disk operations. Each node
(except root) contains at least t-1 keys and at most 2t-1 keys, where t is the
minimum degree. The tree grows upward from the root.
Reference: https://en.wikipedia.org/wiki/B-tree
Complexity:
Time: O(log n) for search, insert, and delete
Space: O(n)
"""
from __future__ import annotations
class Node:
"""A node in a B-tree containing keys and child pointers.
Examples:
>>> node = Node()
>>> node.keys
[]
"""
def __init__(self) -> None:
self.keys: list = []
self.children: list[Node] = []
def __repr__(self) -> str:
"""Return a string representation of the node.
Returns:
A string showing the node's keys.
"""
return f"<id_node: {self.keys}>"
@property
def is_leaf(self) -> bool:
"""Check whether this node is a leaf.
Returns:
True if the node has no children, False otherwise.
"""
return len(self.children) == 0
class BTree:
"""A B-tree data structure supporting search, insertion, and deletion.
Args:
t_val: The minimum degree of the B-tree.
Examples:
>>> bt = BTree(2)
>>> bt.insert_key(10)
>>> bt.find(10)
True
"""
def __init__(self, t_val: int = 2) -> None:
self.min_numbers_of_keys = t_val - 1
self.max_number_of_keys = 2 * t_val - 1
self.root = Node()
def _split_child(self, parent: Node, child_index: int) -> None:
"""Split a full child node into two nodes.
Args:
parent: The parent node whose child is being split.
child_index: The index of the child to split.
"""
new_right_child = Node()
half_max = self.max_number_of_keys // 2
child = parent.children[child_index]
middle_key = child.keys[half_max]
new_right_child.keys = child.keys[half_max + 1 :]
child.keys = child.keys[:half_max]
if not child.is_leaf:
new_right_child.children = child.children[half_max + 1 :]
child.children = child.children[: half_max + 1]
parent.keys.insert(child_index, middle_key)
parent.children.insert(child_index + 1, new_right_child)
def insert_key(self, key: int) -> None:
"""Insert a key into the B-tree.
Args:
key: The key to insert.
"""
if len(self.root.keys) >= self.max_number_of_keys:
new_root = Node()
new_root.children.append(self.root)
self.root = new_root
self._split_child(new_root, 0)
self._insert_to_nonfull_node(self.root, key)
else:
self._insert_to_nonfull_node(self.root, key)
def _insert_to_nonfull_node(self, node: Node, key: int) -> None:
"""Insert a key into a non-full node.
Args:
node: The non-full node to insert into.
key: The key to insert.
"""
i = len(node.keys) - 1
while i >= 0 and node.keys[i] >= key:
i -= 1
if node.is_leaf:
node.keys.insert(i + 1, key)
else:
if len(node.children[i + 1].keys) >= self.max_number_of_keys:
self._split_child(node, i + 1)
if node.keys[i + 1] < key:
i += 1
self._insert_to_nonfull_node(node.children[i + 1], key)
def find(self, key: int) -> bool:
"""Search for a key in the B-tree.
Args:
key: The key to search for.
Returns:
True if the key is found, False otherwise.
Examples:
>>> bt = BTree(2)
>>> bt.insert_key(5)
>>> bt.find(5)
True
>>> bt.find(3)
False
"""
current_node = self.root
while True:
i = len(current_node.keys) - 1
while i >= 0 and current_node.keys[i] > key:
i -= 1
if i >= 0 and current_node.keys[i] == key:
return True
if current_node.is_leaf:
return False
current_node = current_node.children[i + 1]
def remove_key(self, key: int) -> None:
"""Remove a key from the B-tree.
Args:
key: The key to remove.
"""
self._remove_key(self.root, key)
def _remove_key(self, node: Node, key: int) -> bool:
"""Recursively remove a key from the subtree rooted at node.
Args:
node: The root of the subtree to remove from.
key: The key to remove.
Returns:
True if the key was found and removed, False otherwise.
"""
try:
key_index = node.keys.index(key)
if node.is_leaf:
node.keys.remove(key)
else:
self._remove_from_nonleaf_node(node, key_index)
return True
except ValueError:
if node.is_leaf:
return False
else:
i = 0
number_of_keys = len(node.keys)
while i < number_of_keys and key > node.keys[i]:
i += 1
action_performed = self._repair_tree(node, i)
if action_performed:
return self._remove_key(node, key)
else:
return self._remove_key(node.children[i], key)
def _repair_tree(self, node: Node, child_index: int) -> bool:
"""Repair the tree after a deletion to maintain B-tree properties.
Args:
node: The parent node of the child that may need repair.
child_index: The index of the child to check.
Returns:
True if a structural repair was performed, False otherwise.
"""
child = node.children[child_index]
if self.min_numbers_of_keys < len(child.keys) <= self.max_number_of_keys:
return False
if (
child_index > 0
and len(node.children[child_index - 1].keys) > self.min_numbers_of_keys
):
self._rotate_right(node, child_index)
return True
if (
child_index < len(node.children) - 1
and len(node.children[child_index + 1].keys) > self.min_numbers_of_keys
):
self._rotate_left(node, child_index)
return True
if child_index > 0:
self._merge(node, child_index - 1, child_index)
else:
self._merge(node, child_index, child_index + 1)
return True
def _rotate_left(self, parent_node: Node, child_index: int) -> None:
"""Take a key from the right sibling and transfer it to the child.
Args:
parent_node: The parent node.
child_index: The index of the child receiving the key.
"""
new_child_key = parent_node.keys[child_index]
new_parent_key = parent_node.children[child_index + 1].keys.pop(0)
parent_node.children[child_index].keys.append(new_child_key)
parent_node.keys[child_index] = new_parent_key
if not parent_node.children[child_index + 1].is_leaf:
ownerless_child = parent_node.children[child_index + 1].children.pop(0)
parent_node.children[child_index].children.append(ownerless_child)
def _rotate_right(self, parent_node: Node, child_index: int) -> None:
"""Take a key from the left sibling and transfer it to the child.
Args:
parent_node: The parent node.
child_index: The index of the child receiving the key.
"""
parent_key = parent_node.keys[child_index - 1]
new_parent_key = parent_node.children[child_index - 1].keys.pop()
parent_node.children[child_index].keys.insert(0, parent_key)
parent_node.keys[child_index - 1] = new_parent_key
if not parent_node.children[child_index - 1].is_leaf:
ownerless_child = parent_node.children[child_index - 1].children.pop()
parent_node.children[child_index].children.insert(0, ownerless_child)
def _merge(
self, parent_node: Node, to_merge_index: int, transferred_child_index: int
) -> None:
"""Merge two child nodes and a parent key into a single node.
Args:
parent_node: The parent node.
to_merge_index: Index of the child that receives the merged data.
transferred_child_index: Index of the child being merged in.
"""
from_merge_node = parent_node.children.pop(transferred_child_index)
parent_key_to_merge = parent_node.keys.pop(to_merge_index)
to_merge_node = parent_node.children[to_merge_index]
to_merge_node.keys.append(parent_key_to_merge)
to_merge_node.keys.extend(from_merge_node.keys)
if not to_merge_node.is_leaf:
to_merge_node.children.extend(from_merge_node.children)
if parent_node == self.root and not parent_node.keys:
self.root = to_merge_node
def _remove_from_nonleaf_node(
self, node: Node, key_index: int
) -> None:
"""Remove a key from a non-leaf node by replacing with predecessor/successor.
Args:
node: The non-leaf node containing the key.
key_index: The index of the key to remove.
"""
key = node.keys[key_index]
left_subtree = node.children[key_index]
if len(left_subtree.keys) > self.min_numbers_of_keys:
largest_key = self._find_largest_and_delete_in_left_subtree(left_subtree)
elif len(node.children[key_index + 1].keys) > self.min_numbers_of_keys:
largest_key = self._find_largest_and_delete_in_right_subtree(
node.children[key_index + 1]
)
else:
self._merge(node, key_index, key_index + 1)
return self._remove_key(node, key)
node.keys[key_index] = largest_key
def _find_largest_and_delete_in_left_subtree(self, node: Node) -> int:
"""Find and remove the largest key in the left subtree.
Args:
node: The root of the subtree.
Returns:
The largest key that was removed.
"""
if node.is_leaf:
return node.keys.pop()
else:
ch_index = len(node.children) - 1
self._repair_tree(node, ch_index)
largest_key_in_subtree = self._find_largest_and_delete_in_left_subtree(
node.children[len(node.children) - 1]
)
return largest_key_in_subtree
def _find_largest_and_delete_in_right_subtree(self, node: Node) -> int:
"""Find and remove the smallest key in the right subtree.
Args:
node: The root of the subtree.
Returns:
The smallest key that was removed.
"""
if node.is_leaf:
return node.keys.pop(0)
else:
ch_index = 0
self._repair_tree(node, ch_index)
largest_key_in_subtree = self._find_largest_and_delete_in_right_subtree(
node.children[0]
)
return largest_key_in_subtree
def traverse_tree(self) -> list:
"""Traverse the B-tree in order and return all keys.
Returns:
A list of all keys in sorted order.
Examples:
>>> bt = BTree(2)
>>> for k in [3, 1, 2]: bt.insert_key(k)
>>> bt.traverse_tree()
[1, 2, 3]
"""
result: list = []
self._traverse_tree(self.root, result)
return result
def _traverse_tree(self, node: Node, result: list) -> None:
"""Recursively traverse the subtree and collect keys.
Args:
node: The root of the subtree to traverse.
result: The list to append keys to.
"""
if node.is_leaf:
result.extend(node.keys)
else:
for i, key in enumerate(node.keys):
self._traverse_tree(node.children[i], result)
result.append(key)
self._traverse_tree(node.children[-1], result)
================================================
FILE: algorithms/data_structures/bst.py
================================================
"""Binary Search Tree implementation.
A BST is a node-based binary tree where each node's left subtree contains
only nodes with data less than the node's data, and the right subtree
contains only nodes with data greater than the node's data.
Operations and complexities (n = number of nodes):
- insert: O(log n) average, O(n) worst case
- search: O(log n) average, O(n) worst case
- size: O(n)
- preorder: O(n)
- inorder: O(n)
- postorder: O(n)
"""
from __future__ import annotations
class Node:
def __init__(self, data: int) -> None:
self.data: int = data
self.left: Node | None = None
self.right: Node | None = None
class BST:
def __init__(self) -> None:
self.root: Node | None = None
def get_root(self) -> Node | None:
return self.root
def size(self) -> int:
gitextract_s6ixwhb4/
├── .github/
│ └── workflows/
│ ├── publish.yml
│ └── python-app.yml
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── MANIFEST.in
├── README.md
├── algorithms/
│ ├── __init__.py
│ ├── array/
│ │ ├── __init__.py
│ │ ├── delete_nth.py
│ │ ├── flatten.py
│ │ ├── garage.py
│ │ ├── josephus.py
│ │ ├── limit.py
│ │ ├── longest_non_repeat.py
│ │ ├── max_ones_index.py
│ │ ├── merge_intervals.py
│ │ ├── missing_ranges.py
│ │ ├── move_zeros.py
│ │ ├── n_sum.py
│ │ ├── plus_one.py
│ │ ├── remove_duplicates.py
│ │ ├── rotate.py
│ │ ├── summarize_ranges.py
│ │ ├── three_sum.py
│ │ ├── top_1.py
│ │ ├── trimmean.py
│ │ └── two_sum.py
│ ├── backtracking/
│ │ ├── __init__.py
│ │ ├── add_operators.py
│ │ ├── anagram.py
│ │ ├── array_sum_combinations.py
│ │ ├── combination_sum.py
│ │ ├── factor_combinations.py
│ │ ├── find_words.py
│ │ ├── generate_abbreviations.py
│ │ ├── generate_parenthesis.py
│ │ ├── letter_combination.py
│ │ ├── minimax.py
│ │ ├── palindrome_partitioning.py
│ │ ├── pattern_match.py
│ │ ├── permute.py
│ │ ├── permute_unique.py
│ │ ├── subsets.py
│ │ └── subsets_unique.py
│ ├── bit_manipulation/
│ │ ├── __init__.py
│ │ ├── add_bitwise_operator.py
│ │ ├── binary_gap.py
│ │ ├── bit_operation.py
│ │ ├── bytes_int_conversion.py
│ │ ├── count_flips_to_convert.py
│ │ ├── count_ones.py
│ │ ├── find_difference.py
│ │ ├── find_missing_number.py
│ │ ├── flip_bit_longest_sequence.py
│ │ ├── gray_code.py
│ │ ├── has_alternative_bit.py
│ │ ├── insert_bit.py
│ │ ├── power_of_two.py
│ │ ├── remove_bit.py
│ │ ├── reverse_bits.py
│ │ ├── single_number.py
│ │ ├── single_number2.py
│ │ ├── single_number3.py
│ │ ├── subsets.py
│ │ └── swap_pair.py
│ ├── common/
│ │ ├── __init__.py
│ │ ├── graph.py
│ │ ├── list_node.py
│ │ └── tree_node.py
│ ├── compression/
│ │ ├── __init__.py
│ │ ├── elias.py
│ │ ├── huffman_coding.py
│ │ └── rle_compression.py
│ ├── data_structures/
│ │ ├── __init__.py
│ │ ├── avl_tree.py
│ │ ├── b_tree.py
│ │ ├── bst.py
│ │ ├── fenwick_tree.py
│ │ ├── graph.py
│ │ ├── hash_table.py
│ │ ├── heap.py
│ │ ├── iterative_segment_tree.py
│ │ ├── kd_tree.py
│ │ ├── linked_list.py
│ │ ├── priority_queue.py
│ │ ├── queue.py
│ │ ├── red_black_tree.py
│ │ ├── segment_tree.py
│ │ ├── separate_chaining_hash_table.py
│ │ ├── sqrt_decomposition.py
│ │ ├── stack.py
│ │ ├── trie.py
│ │ ├── union_find.py
│ │ └── veb_tree.py
│ ├── dynamic_programming/
│ │ ├── __init__.py
│ │ ├── bitmask.py
│ │ ├── buy_sell_stock.py
│ │ ├── climbing_stairs.py
│ │ ├── coin_change.py
│ │ ├── combination_sum.py
│ │ ├── count_paths_dp.py
│ │ ├── edit_distance.py
│ │ ├── egg_drop.py
│ │ ├── fib.py
│ │ ├── hosoya_triangle.py
│ │ ├── house_robber.py
│ │ ├── int_divide.py
│ │ ├── job_scheduling.py
│ │ ├── k_factor.py
│ │ ├── knapsack.py
│ │ ├── longest_common_subsequence.py
│ │ ├── longest_increasing.py
│ │ ├── matrix_chain_order.py
│ │ ├── max_product_subarray.py
│ │ ├── max_subarray.py
│ │ ├── min_cost_path.py
│ │ ├── num_decodings.py
│ │ ├── planting_trees.py
│ │ ├── regex_matching.py
│ │ ├── rod_cut.py
│ │ └── word_break.py
│ ├── graph/
│ │ ├── __init__.py
│ │ ├── a_star.py
│ │ ├── all_factors.py
│ │ ├── all_pairs_shortest_path.py
│ │ ├── bellman_ford.py
│ │ ├── blossom.py
│ │ ├── check_bipartite.py
│ │ ├── check_digraph_strongly_connected.py
│ │ ├── clone_graph.py
│ │ ├── count_connected_number_of_component.py
│ │ ├── count_islands_bfs.py
│ │ ├── count_islands_dfs.py
│ │ ├── count_islands_unionfind.py
│ │ ├── cycle_detection.py
│ │ ├── dijkstra.py
│ │ ├── dijkstra_heapq.py
│ │ ├── find_all_cliques.py
│ │ ├── find_path.py
│ │ ├── graph.py
│ │ ├── kahns_algorithm.py
│ │ ├── markov_chain.py
│ │ ├── maximum_flow.py
│ │ ├── maximum_flow_bfs.py
│ │ ├── maximum_flow_dfs.py
│ │ ├── maze_search_bfs.py
│ │ ├── maze_search_dfs.py
│ │ ├── minimum_spanning_tree.py
│ │ ├── pacific_atlantic.py
│ │ ├── path_between_two_vertices_in_digraph.py
│ │ ├── prims_minimum_spanning.py
│ │ ├── satisfiability.py
│ │ ├── shortest_distance_from_all_buildings.py
│ │ ├── strongly_connected_components_kosaraju.py
│ │ ├── sudoku_solver.py
│ │ ├── tarjan.py
│ │ ├── topological_sort_bfs.py
│ │ ├── topological_sort_dfs.py
│ │ ├── transitive_closure_dfs.py
│ │ ├── traversal.py
│ │ ├── walls_and_gates.py
│ │ └── word_ladder.py
│ ├── greedy/
│ │ ├── __init__.py
│ │ ├── gale_shapley.py
│ │ └── max_contiguous_subsequence_sum.py
│ ├── heap/
│ │ ├── __init__.py
│ │ ├── k_closest_points.py
│ │ ├── merge_sorted_k_lists.py
│ │ ├── skyline.py
│ │ └── sliding_window_max.py
│ ├── linked_list/
│ │ ├── __init__.py
│ │ ├── add_two_numbers.py
│ │ ├── copy_random_pointer.py
│ │ ├── delete_node.py
│ │ ├── first_cyclic_node.py
│ │ ├── intersection.py
│ │ ├── is_cyclic.py
│ │ ├── is_palindrome.py
│ │ ├── is_sorted.py
│ │ ├── kth_to_last.py
│ │ ├── merge_two_list.py
│ │ ├── partition.py
│ │ ├── remove_duplicates.py
│ │ ├── remove_range.py
│ │ ├── reverse.py
│ │ ├── rotate_list.py
│ │ └── swap_in_pairs.py
│ ├── map/
│ │ ├── __init__.py
│ │ ├── is_anagram.py
│ │ ├── is_isomorphic.py
│ │ ├── longest_common_subsequence.py
│ │ ├── longest_palindromic_subsequence.py
│ │ ├── randomized_set.py
│ │ ├── valid_sudoku.py
│ │ └── word_pattern.py
│ ├── math/
│ │ ├── __init__.py
│ │ ├── base_conversion.py
│ │ ├── chinese_remainder_theorem.py
│ │ ├── combination.py
│ │ ├── cosine_similarity.py
│ │ ├── decimal_to_binary_ip.py
│ │ ├── diffie_hellman_key_exchange.py
│ │ ├── distance_between_two_points.py
│ │ ├── euler_totient.py
│ │ ├── extended_gcd.py
│ │ ├── factorial.py
│ │ ├── fft.py
│ │ ├── find_order_simple.py
│ │ ├── find_primitive_root_simple.py
│ │ ├── gcd.py
│ │ ├── generate_strobogrammtic.py
│ │ ├── goldbach.py
│ │ ├── hailstone.py
│ │ ├── is_strobogrammatic.py
│ │ ├── krishnamurthy_number.py
│ │ ├── linear_regression.py
│ │ ├── magic_number.py
│ │ ├── manhattan_distance.py
│ │ ├── modular_exponential.py
│ │ ├── modular_inverse.py
│ │ ├── next_bigger.py
│ │ ├── next_perfect_square.py
│ │ ├── nth_digit.py
│ │ ├── num_digits.py
│ │ ├── num_perfect_squares.py
│ │ ├── polynomial.py
│ │ ├── polynomial_division.py
│ │ ├── power.py
│ │ ├── prime_check.py
│ │ ├── primes_sieve_of_eratosthenes.py
│ │ ├── pythagoras.py
│ │ ├── rabin_miller.py
│ │ ├── recursive_binomial_coefficient.py
│ │ ├── rsa.py
│ │ ├── sqrt_precision_factor.py
│ │ ├── summing_digits.py
│ │ ├── surface_area_of_torus.py
│ │ └── symmetry_group_cycle_index.py
│ ├── matrix/
│ │ ├── __init__.py
│ │ ├── bomb_enemy.py
│ │ ├── cholesky_matrix_decomposition.py
│ │ ├── copy_transform.py
│ │ ├── count_paths.py
│ │ ├── crout_matrix_decomposition.py
│ │ ├── matrix_exponentiation.py
│ │ ├── matrix_inversion.py
│ │ ├── multiply.py
│ │ ├── rotate_image.py
│ │ ├── search_in_sorted_matrix.py
│ │ ├── sort_matrix_diagonally.py
│ │ ├── sparse_dot_vector.py
│ │ ├── sparse_mul.py
│ │ ├── spiral_traversal.py
│ │ ├── sudoku_validator.py
│ │ └── sum_sub_squares.py
│ ├── py.typed
│ ├── queue/
│ │ ├── __init__.py
│ │ ├── max_sliding_window.py
│ │ ├── moving_average.py
│ │ ├── reconstruct_queue.py
│ │ └── zigzagiterator.py
│ ├── searching/
│ │ ├── __init__.py
│ │ ├── binary_search.py
│ │ ├── exponential_search.py
│ │ ├── find_min_rotate.py
│ │ ├── first_occurrence.py
│ │ ├── generalized_binary_search.py
│ │ ├── interpolation_search.py
│ │ ├── jump_search.py
│ │ ├── last_occurrence.py
│ │ ├── linear_search.py
│ │ ├── next_greatest_letter.py
│ │ ├── search_insert.py
│ │ ├── search_range.py
│ │ ├── search_rotate.py
│ │ ├── sentinel_search.py
│ │ ├── ternary_search.py
│ │ └── two_sum.py
│ ├── set/
│ │ ├── __init__.py
│ │ ├── find_keyboard_row.py
│ │ ├── randomized_set.py
│ │ └── set_covering.py
│ ├── sorting/
│ │ ├── __init__.py
│ │ ├── bead_sort.py
│ │ ├── bitonic_sort.py
│ │ ├── bogo_sort.py
│ │ ├── bubble_sort.py
│ │ ├── bucket_sort.py
│ │ ├── cocktail_shaker_sort.py
│ │ ├── comb_sort.py
│ │ ├── counting_sort.py
│ │ ├── cycle_sort.py
│ │ ├── exchange_sort.py
│ │ ├── gnome_sort.py
│ │ ├── heap_sort.py
│ │ ├── insertion_sort.py
│ │ ├── meeting_rooms.py
│ │ ├── merge_sort.py
│ │ ├── pancake_sort.py
│ │ ├── pigeonhole_sort.py
│ │ ├── quick_sort.py
│ │ ├── radix_sort.py
│ │ ├── selection_sort.py
│ │ ├── shell_sort.py
│ │ ├── sort_colors.py
│ │ ├── stooge_sort.py
│ │ └── wiggle_sort.py
│ ├── stack/
│ │ ├── __init__.py
│ │ ├── is_consecutive.py
│ │ ├── is_sorted.py
│ │ ├── longest_abs_path.py
│ │ ├── ordered_stack.py
│ │ ├── remove_min.py
│ │ ├── simplify_path.py
│ │ ├── stutter.py
│ │ ├── switch_pairs.py
│ │ └── valid_parenthesis.py
│ ├── streaming/
│ │ ├── __init__.py
│ │ ├── misra_gries.py
│ │ └── one_sparse_recovery.py
│ ├── string/
│ │ ├── __init__.py
│ │ ├── add_binary.py
│ │ ├── alphabet_board_path.py
│ │ ├── atbash_cipher.py
│ │ ├── breaking_bad.py
│ │ ├── caesar_cipher.py
│ │ ├── check_pangram.py
│ │ ├── contain_string.py
│ │ ├── count_binary_substring.py
│ │ ├── decode_string.py
│ │ ├── delete_reoccurring.py
│ │ ├── domain_extractor.py
│ │ ├── encode_decode.py
│ │ ├── first_unique_char.py
│ │ ├── fizzbuzz.py
│ │ ├── group_anagrams.py
│ │ ├── int_to_roman.py
│ │ ├── is_palindrome.py
│ │ ├── is_rotated.py
│ │ ├── judge_circle.py
│ │ ├── knuth_morris_pratt.py
│ │ ├── license_number.py
│ │ ├── longest_common_prefix.py
│ │ ├── longest_palindromic_substring.py
│ │ ├── make_sentence.py
│ │ ├── manacher.py
│ │ ├── merge_string_checker.py
│ │ ├── min_distance.py
│ │ ├── multiply_strings.py
│ │ ├── one_edit_distance.py
│ │ ├── panagram.py
│ │ ├── rabin_karp.py
│ │ ├── repeat_string.py
│ │ ├── repeat_substring.py
│ │ ├── reverse_string.py
│ │ ├── reverse_vowel.py
│ │ ├── reverse_words.py
│ │ ├── roman_to_int.py
│ │ ├── rotate.py
│ │ ├── strip_url_params.py
│ │ ├── strong_password.py
│ │ ├── swap_characters.py
│ │ ├── text_justification.py
│ │ ├── unique_morse.py
│ │ ├── validate_coordinates.py
│ │ ├── word_squares.py
│ │ └── z_algorithm.py
│ └── tree/
│ ├── __init__.py
│ ├── bin_tree_to_list.py
│ ├── binary_tree_paths.py
│ ├── binary_tree_views.py
│ ├── bst_array_to_bst.py
│ ├── bst_closest_value.py
│ ├── bst_count_left_node.py
│ ├── bst_delete_node.py
│ ├── bst_depth_sum.py
│ ├── bst_height.py
│ ├── bst_is_bst.py
│ ├── bst_iterator.py
│ ├── bst_kth_smallest.py
│ ├── bst_lowest_common_ancestor.py
│ ├── bst_num_empty.py
│ ├── bst_predecessor.py
│ ├── bst_serialize_deserialize.py
│ ├── bst_successor.py
│ ├── bst_unique_bst.py
│ ├── bst_validate_bst.py
│ ├── construct_tree_postorder_preorder.py
│ ├── deepest_left.py
│ ├── invert_tree.py
│ ├── is_balanced.py
│ ├── is_subtree.py
│ ├── is_symmetric.py
│ ├── longest_consecutive.py
│ ├── lowest_common_ancestor.py
│ ├── max_height.py
│ ├── max_path_sum.py
│ ├── min_height.py
│ ├── path_sum.py
│ ├── path_sum2.py
│ ├── pretty_print.py
│ ├── same_tree.py
│ ├── traversal_inorder.py
│ ├── traversal_level_order.py
│ ├── traversal_postorder.py
│ ├── traversal_preorder.py
│ ├── traversal_zigzag.py
│ ├── tree.py
│ └── trie_add_and_search.py
├── docs/
│ └── index.html
├── pyproject.toml
└── tests/
├── test_array.py
├── test_backtracking.py
├── test_bit_manipulation.py
├── test_community_algorithms.py
├── test_compression.py
├── test_data_structures.py
├── test_dynamic_programming.py
├── test_graph.py
├── test_greedy.py
├── test_heap.py
├── test_issue_fixes.py
├── test_iterative_segment_tree.py
├── test_linked_list.py
├── test_map.py
├── test_math.py
├── test_matrix.py
├── test_monomial.py
├── test_polynomial.py
├── test_queue.py
├── test_searching.py
├── test_set.py
├── test_sorting.py
├── test_stack.py
├── test_streaming.py
├── test_string.py
├── test_tree.py
└── test_veb_tree.py
SYMBOL INDEX (1859 symbols across 404 files)
FILE: algorithms/array/delete_nth.py
function delete_nth_naive (line 23) | def delete_nth_naive(array: list[int], n: int) -> list[int]:
function delete_nth (line 44) | def delete_nth(array: list[int], n: int) -> list[int]:
FILE: algorithms/array/flatten.py
function flatten (line 20) | def flatten(input_arr: Iterable[Any], output_arr: list[Any] | None = Non...
function flatten_iter (line 44) | def flatten_iter(iterable: Iterable[Any]) -> Generator[Any, None, None]:
FILE: algorithms/array/garage.py
function garage (line 18) | def garage(initial: list[int], final: list[int]) -> tuple[int, list[list...
FILE: algorithms/array/josephus.py
function josephus (line 20) | def josephus(items: list[Any], skip: int) -> Generator[Any, None, None]:
FILE: algorithms/array/limit.py
function limit (line 17) | def limit(
FILE: algorithms/array/longest_non_repeat.py
function longest_non_repeat_v1 (line 17) | def longest_non_repeat_v1(string: str) -> int:
function longest_non_repeat_v2 (line 43) | def longest_non_repeat_v2(string: str) -> int:
function get_longest_non_repeat_v1 (line 69) | def get_longest_non_repeat_v1(string: str) -> tuple[int, str]:
function get_longest_non_repeat_v2 (line 98) | def get_longest_non_repeat_v2(string: str) -> tuple[int, str]:
function get_longest_non_repeat_v3 (line 127) | def get_longest_non_repeat_v3(string: str) -> tuple[int, str]:
FILE: algorithms/array/max_ones_index.py
function max_ones_index (line 17) | def max_ones_index(array: list[int]) -> int:
FILE: algorithms/array/merge_intervals.py
class Interval (line 17) | class Interval:
method __init__ (line 25) | def __init__(self, start: int = 0, end: int = 0) -> None:
method __repr__ (line 29) | def __repr__(self) -> str:
method __iter__ (line 32) | def __iter__(self):
method __getitem__ (line 35) | def __getitem__(self, index: int) -> int:
method __len__ (line 40) | def __len__(self) -> int:
method __contains__ (line 43) | def __contains__(self, item: int) -> bool:
method __eq__ (line 46) | def __eq__(self, other: object) -> bool:
method as_list (line 51) | def as_list(self) -> list[int]:
method merge (line 60) | def merge(intervals: list[Interval]) -> list[Interval]:
method print_intervals (line 82) | def print_intervals(intervals: list[Interval]) -> str:
function merge_intervals (line 101) | def merge_intervals(intervals: list[list[int]]) -> list[list[int]] | None:
FILE: algorithms/array/missing_ranges.py
function missing_ranges (line 17) | def missing_ranges(array: list[int], low: int, high: int) -> list[tuple[...
FILE: algorithms/array/move_zeros.py
function move_zeros (line 19) | def move_zeros(array: list[Any]) -> list[Any]:
FILE: algorithms/array/n_sum.py
function n_sum (line 21) | def n_sum(
FILE: algorithms/array/plus_one.py
function plus_one_v1 (line 17) | def plus_one_v1(digits: list[int]) -> list[int]:
function plus_one_v2 (line 46) | def plus_one_v2(digits: list[int]) -> list[int]:
function plus_one_v3 (line 69) | def plus_one_v3(num_arr: list[int]) -> list[int]:
FILE: algorithms/array/remove_duplicates.py
function remove_duplicates (line 20) | def remove_duplicates(array: list[Any]) -> list[Any]:
FILE: algorithms/array/rotate.py
function rotate_v1 (line 18) | def rotate_v1(array: list[int], k: int) -> list[int]:
function rotate_v2 (line 42) | def rotate_v2(array: list[int], k: int) -> list[int]:
function rotate_v3 (line 72) | def rotate_v3(array: list[int] | None, k: int) -> list[int] | None:
FILE: algorithms/array/summarize_ranges.py
function summarize_ranges (line 17) | def summarize_ranges(array: list[int]) -> list[tuple[int, ...]]:
FILE: algorithms/array/three_sum.py
function three_sum (line 17) | def three_sum(array: list[int]) -> set[tuple[int, int, int]]:
FILE: algorithms/array/top_1.py
function top_1 (line 19) | def top_1(array: list[Any]) -> list[Any]:
FILE: algorithms/array/trimmean.py
function trimmean (line 17) | def trimmean(array: list[float], percentage: float) -> float:
FILE: algorithms/array/two_sum.py
function two_sum (line 17) | def two_sum(array: list[int], target: int) -> tuple[int, int] | None:
FILE: algorithms/backtracking/add_operators.py
function add_operators (line 18) | def add_operators(digits: str, target: int) -> list[str]:
function _dfs (line 39) | def _dfs(
FILE: algorithms/backtracking/anagram.py
function anagram (line 17) | def anagram(first: str, second: str) -> bool:
FILE: algorithms/backtracking/array_sum_combinations.py
function array_sum_combinations (line 20) | def array_sum_combinations(
function unique_array_sum_combinations (line 78) | def unique_array_sum_combinations(
FILE: algorithms/backtracking/combination_sum.py
function combination_sum (line 18) | def combination_sum(candidates: list[int], target: int) -> list[list[int]]:
function _dfs (line 38) | def _dfs(
FILE: algorithms/backtracking/factor_combinations.py
function get_factors (line 17) | def get_factors(number: int) -> list[list[int]]:
function recursive_get_factors (line 42) | def recursive_get_factors(number: int) -> list[list[int]]:
FILE: algorithms/backtracking/find_words.py
function find_words (line 18) | def find_words(board: list[list[str]], words: list[str]) -> list[str]:
function _backtrack (line 55) | def _backtrack(
FILE: algorithms/backtracking/generate_abbreviations.py
function generate_abbreviations (line 17) | def generate_abbreviations(word: str) -> list[str]:
function _backtrack (line 35) | def _backtrack(
FILE: algorithms/backtracking/generate_parenthesis.py
function generate_parenthesis_v1 (line 17) | def generate_parenthesis_v1(count: int) -> list[str]:
function _add_pair_v1 (line 38) | def _add_pair_v1(
function generate_parenthesis_v2 (line 54) | def generate_parenthesis_v2(count: int) -> list[str]:
function _add_pair_v2 (line 75) | def _add_pair_v2(
FILE: algorithms/backtracking/letter_combination.py
function letter_combinations (line 17) | def letter_combinations(digits: str) -> list[str]:
FILE: algorithms/backtracking/minimax.py
function minimax (line 15) | def minimax(
FILE: algorithms/backtracking/palindrome_partitioning.py
function palindromic_substrings (line 19) | def palindromic_substrings(text: str) -> list[list[str]]:
function palindromic_substrings_iter (line 43) | def palindromic_substrings_iter(text: str) -> Generator[list[str], None,...
FILE: algorithms/backtracking/pattern_match.py
function pattern_match (line 18) | def pattern_match(pattern: str, string: str) -> bool:
function _backtrack (line 37) | def _backtrack(
FILE: algorithms/backtracking/permute.py
function permute (line 18) | def permute(elements: list | str) -> list:
function permute_iter (line 40) | def permute_iter(elements: list | str) -> Generator:
function permute_recursive (line 61) | def permute_recursive(nums: list[int]) -> list[list[int]]:
function _dfs (line 79) | def _dfs(
FILE: algorithms/backtracking/permute_unique.py
function permute_unique (line 17) | def permute_unique(nums: list[int]) -> list[list[int]]:
FILE: algorithms/backtracking/subsets.py
function subsets (line 17) | def subsets(nums: list[int]) -> list[list[int]]:
function _backtrack (line 35) | def _backtrack(
function subsets_v2 (line 51) | def subsets_v2(nums: list[int]) -> list[list[int]]:
FILE: algorithms/backtracking/subsets_unique.py
function subsets_unique (line 17) | def subsets_unique(nums: list[int]) -> list[tuple[int, ...]]:
function _backtrack (line 35) | def _backtrack(
FILE: algorithms/bit_manipulation/add_bitwise_operator.py
function add_bitwise_operator (line 17) | def add_bitwise_operator(first: int, second: int) -> int:
FILE: algorithms/bit_manipulation/binary_gap.py
function binary_gap (line 18) | def binary_gap(number: int) -> int:
FILE: algorithms/bit_manipulation/bit_operation.py
function get_bit (line 17) | def get_bit(number: int, position: int) -> int:
function set_bit (line 39) | def set_bit(number: int, position: int) -> int:
function clear_bit (line 59) | def clear_bit(number: int, position: int) -> int:
function update_bit (line 80) | def update_bit(number: int, position: int, bit: int) -> int:
FILE: algorithms/bit_manipulation/bytes_int_conversion.py
function int_to_bytes_big_endian (line 19) | def int_to_bytes_big_endian(number: int) -> bytes:
function int_to_bytes_little_endian (line 39) | def int_to_bytes_little_endian(number: int) -> bytes:
function bytes_big_endian_to_int (line 59) | def bytes_big_endian_to_int(byte_string: bytes) -> int:
function bytes_little_endian_to_int (line 79) | def bytes_little_endian_to_int(byte_string: bytes) -> int:
FILE: algorithms/bit_manipulation/count_flips_to_convert.py
function count_flips_to_convert (line 18) | def count_flips_to_convert(first: int, second: int) -> int:
FILE: algorithms/bit_manipulation/count_ones.py
function count_ones_recur (line 17) | def count_ones_recur(number: int) -> int:
function count_ones_iter (line 37) | def count_ones_iter(number: int) -> int:
FILE: algorithms/bit_manipulation/find_difference.py
function find_difference (line 17) | def find_difference(original: str, shuffled: str) -> str:
FILE: algorithms/bit_manipulation/find_missing_number.py
function find_missing_number (line 18) | def find_missing_number(nums: list[int]) -> int:
function find_missing_number2 (line 43) | def find_missing_number2(nums: list[int]) -> int:
FILE: algorithms/bit_manipulation/flip_bit_longest_sequence.py
function flip_bit_longest_seq (line 17) | def flip_bit_longest_seq(number: int) -> int:
FILE: algorithms/bit_manipulation/gray_code.py
function gray_code (line 12) | def gray_code(n: int) -> list[int]:
function gray_to_binary (line 26) | def gray_to_binary(gray: int) -> int:
FILE: algorithms/bit_manipulation/has_alternative_bit.py
function has_alternative_bit (line 17) | def has_alternative_bit(number: int) -> bool:
function has_alternative_bit_fast (line 46) | def has_alternative_bit_fast(number: int) -> bool:
FILE: algorithms/bit_manipulation/insert_bit.py
function insert_one_bit (line 16) | def insert_one_bit(number: int, bit: int, position: int) -> int:
function insert_mult_bits (line 43) | def insert_mult_bits(number: int, bits: int, length: int, position: int)...
FILE: algorithms/bit_manipulation/power_of_two.py
function is_power_of_two (line 18) | def is_power_of_two(number: int) -> bool:
FILE: algorithms/bit_manipulation/remove_bit.py
function remove_bit (line 17) | def remove_bit(number: int, position: int) -> int:
FILE: algorithms/bit_manipulation/reverse_bits.py
function reverse_bits (line 16) | def reverse_bits(number: int) -> int:
FILE: algorithms/bit_manipulation/single_number.py
function single_number (line 17) | def single_number(nums: list[int]) -> int:
FILE: algorithms/bit_manipulation/single_number2.py
function single_number2 (line 18) | def single_number2(nums: list[int]) -> int:
FILE: algorithms/bit_manipulation/single_number3.py
function single_number3 (line 18) | def single_number3(nums: list[int]) -> list[int]:
FILE: algorithms/bit_manipulation/subsets.py
function subsets (line 17) | def subsets(nums: list[int]) -> set[tuple[int, ...]]:
FILE: algorithms/bit_manipulation/swap_pair.py
function swap_pair (line 17) | def swap_pair(number: int) -> int:
FILE: algorithms/common/graph.py
class Graph (line 15) | class Graph:
method unweighted (line 40) | def unweighted(cls, adj: dict[str, list[str]], directed: bool = True) ...
method nodes (line 61) | def nodes(self) -> set[str]:
method add_edge (line 78) | def add_edge(self, source: str, target: str, weight: float = 1) -> None:
FILE: algorithms/common/list_node.py
class ListNode (line 15) | class ListNode:
FILE: algorithms/common/tree_node.py
class TreeNode (line 14) | class TreeNode:
FILE: algorithms/compression/elias.py
function _log2 (line 20) | def _log2(x: int | float) -> float:
function _binary (line 32) | def _binary(x: int, length: int = 1) -> str:
function _unary (line 46) | def _unary(x: int) -> str:
function _elias_generic (line 58) | def _elias_generic(
function elias_gamma (line 81) | def elias_gamma(x: int) -> str:
function elias_delta (line 99) | def elias_delta(x: int) -> str:
FILE: algorithms/compression/huffman_coding.py
class Node (line 21) | class Node:
method __init__ (line 24) | def __init__(
method __lt__ (line 36) | def __lt__(self, other: Node) -> bool:
method __gt__ (line 39) | def __gt__(self, other: Node) -> bool:
method __eq__ (line 42) | def __eq__(self, other: object) -> bool:
method __str__ (line 47) | def __str__(self) -> str:
method __repr__ (line 50) | def __repr__(self) -> str:
class HuffmanReader (line 54) | class HuffmanReader:
method __init__ (line 57) | def __init__(self, file: object) -> None:
method get_number_of_additional_bits_in_the_last_byte (line 62) | def get_number_of_additional_bits_in_the_last_byte(self) -> int:
method load_tree (line 71) | def load_tree(self) -> Node:
method _fill_tree (line 100) | def _fill_tree(self, leaves_queue: deque[Node]) -> None:
method _load_byte (line 112) | def _load_byte(self, buff_limit: int = 8) -> bool:
method get_bit (line 129) | def get_bit(self, buff_limit: int = 8) -> str | int:
method get_byte (line 142) | def get_byte(self) -> str | int:
class HuffmanWriter (line 155) | class HuffmanWriter:
method __init__ (line 158) | def __init__(self, file: object) -> None:
method write_char (line 163) | def write_char(self, char: str) -> None:
method write_int (line 171) | def write_int(self, num: int) -> None:
method write_bits (line 180) | def write_bits(self, bits: str) -> None:
method save_tree (line 193) | def save_tree(self, tree: Node) -> None:
method _save_information_about_additional_bits (line 218) | def _save_information_about_additional_bits(self, additional_bits: int...
method close (line 231) | def close(self) -> None:
class TreeFinder (line 239) | class TreeFinder:
method __init__ (line 242) | def __init__(self, tree: Node) -> None:
method find (line 247) | def find(self, bit: str) -> bool:
method _reset (line 269) | def _reset(self, found: int | str = "") -> None:
class HuffmanCoding (line 279) | class HuffmanCoding:
method __init__ (line 282) | def __init__(self) -> None:
method decode_file (line 286) | def decode_file(file_in_name: str, file_out_name: str) -> None:
method _decode_and_write_signs_to_file (line 302) | def _decode_and_write_signs_to_file(
method encode_file (line 334) | def encode_file(file_in_name: str, file_out_name: str) -> None:
method _encode_and_write_signs_to_file (line 357) | def _encode_and_write_signs_to_file(
method _get_char_frequency (line 374) | def _get_char_frequency(file: object) -> dict[int, int]:
method _generate_codes (line 396) | def _generate_codes(tree: Node) -> dict[int, str]:
method _create_tree (line 410) | def _create_tree(signs_frequency: dict[int, int]) -> Node:
method _go_through_tree_and_create_codes (line 438) | def _go_through_tree_and_create_codes(
FILE: algorithms/compression/rle_compression.py
function encode_rle (line 18) | def encode_rle(data: str) -> str:
function decode_rle (line 52) | def decode_rle(data: str) -> str:
FILE: algorithms/data_structures/avl_tree.py
class AvlTree (line 6) | class AvlTree:
method __init__ (line 11) | def __init__(self):
method insert (line 17) | def insert(self, key):
method re_balance (line 33) | def re_balance(self):
method update_heights (line 59) | def update_heights(self, recursive=True):
method update_balances (line 74) | def update_balances(self, recursive=True):
method rotate_right (line 90) | def rotate_right(self):
method rotate_left (line 102) | def rotate_left(self):
method in_order_traverse (line 114) | def in_order_traverse(self):
FILE: algorithms/data_structures/b_tree.py
class Node (line 18) | class Node:
method __init__ (line 27) | def __init__(self) -> None:
method __repr__ (line 31) | def __repr__(self) -> str:
method is_leaf (line 40) | def is_leaf(self) -> bool:
class BTree (line 49) | class BTree:
method __init__ (line 62) | def __init__(self, t_val: int = 2) -> None:
method _split_child (line 67) | def _split_child(self, parent: Node, child_index: int) -> None:
method insert_key (line 88) | def insert_key(self, key: int) -> None:
method _insert_to_nonfull_node (line 103) | def _insert_to_nonfull_node(self, node: Node, key: int) -> None:
method find (line 123) | def find(self, key: int) -> bool:
method remove_key (line 151) | def remove_key(self, key: int) -> None:
method _remove_key (line 159) | def _remove_key(self, node: Node, key: int) -> bool:
method _repair_tree (line 192) | def _repair_tree(self, node: Node, child_index: int) -> bool:
method _rotate_left (line 227) | def _rotate_left(self, parent_node: Node, child_index: int) -> None:
method _rotate_right (line 243) | def _rotate_right(self, parent_node: Node, child_index: int) -> None:
method _merge (line 259) | def _merge(
method _remove_from_nonleaf_node (line 281) | def _remove_from_nonleaf_node(
method _find_largest_and_delete_in_left_subtree (line 304) | def _find_largest_and_delete_in_left_subtree(self, node: Node) -> int:
method _find_largest_and_delete_in_right_subtree (line 323) | def _find_largest_and_delete_in_right_subtree(self, node: Node) -> int:
method traverse_tree (line 342) | def traverse_tree(self) -> list:
method _traverse_tree (line 358) | def _traverse_tree(self, node: Node, result: list) -> None:
FILE: algorithms/data_structures/bst.py
class Node (line 18) | class Node:
method __init__ (line 19) | def __init__(self, data: int) -> None:
class BST (line 25) | class BST:
method __init__ (line 26) | def __init__(self) -> None:
method get_root (line 29) | def get_root(self) -> Node | None:
method size (line 32) | def size(self) -> int:
method _recur_size (line 36) | def _recur_size(self, root: Node | None) -> int:
method search (line 41) | def search(self, data: int) -> bool:
method _recur_search (line 45) | def _recur_search(self, root: Node | None, data: int) -> bool:
method insert (line 55) | def insert(self, data: int) -> bool:
method _recur_insert (line 67) | def _recur_insert(self, root: Node, data: int) -> bool:
method preorder (line 83) | def preorder(self, root: Node | None) -> list[int]:
method inorder (line 92) | def inorder(self, root: Node | None) -> list[int]:
method postorder (line 101) | def postorder(self, root: Node | None) -> list[int]:
FILE: algorithms/data_structures/fenwick_tree.py
class Fenwick_Tree (line 30) | class Fenwick_Tree: # noqa: N801
method __init__ (line 31) | def __init__(self, freq):
method get_sum (line 35) | def get_sum(self, bit_tree, i):
method update_bit (line 56) | def update_bit(self, bit_tree, i, v):
method construct (line 74) | def construct(self):
FILE: algorithms/data_structures/graph.py
class Node (line 11) | class Node:
method __init__ (line 14) | def __init__(self, name: str) -> None:
method get_name (line 18) | def get_name(obj: object) -> str:
method __eq__ (line 33) | def __eq__(self, obj: object) -> bool:
method __repr__ (line 36) | def __repr__(self) -> str:
method __hash__ (line 39) | def __hash__(self) -> int:
method __ne__ (line 42) | def __ne__(self, obj: object) -> bool:
method __lt__ (line 45) | def __lt__(self, obj: object) -> bool:
method __le__ (line 48) | def __le__(self, obj: object) -> bool:
method __gt__ (line 51) | def __gt__(self, obj: object) -> bool:
method __ge__ (line 54) | def __ge__(self, obj: object) -> bool:
method __bool__ (line 57) | def __bool__(self) -> bool:
class DirectedEdge (line 61) | class DirectedEdge:
method __init__ (line 64) | def __init__(self, node_from: Node, node_to: Node) -> None:
method __eq__ (line 68) | def __eq__(self, obj: object) -> bool:
method __repr__ (line 73) | def __repr__(self) -> str:
class DirectedGraph (line 77) | class DirectedGraph:
method __init__ (line 80) | def __init__(self, load_dict: dict[str, list[str]] | None = None) -> N...
method add_node (line 101) | def add_node(self, node_name: str) -> Node:
method add_edge (line 117) | def add_edge(self, node_name_from: str, node_name_to: str) -> None:
FILE: algorithms/data_structures/hash_table.py
class HashTable (line 18) | class HashTable:
method __init__ (line 31) | def __init__(self, size: int = 11) -> None:
method put (line 42) | def put(self, key: int, value: object) -> None:
method get (line 70) | def get(self, key: int) -> object | None:
method del_ (line 90) | def del_(self, key: int) -> None:
method hash (line 110) | def hash(self, key: int) -> int:
method _rehash (line 121) | def _rehash(self, old_hash: int) -> int:
method __getitem__ (line 132) | def __getitem__(self, key: int) -> object | None:
method __delitem__ (line 135) | def __delitem__(self, key: int) -> None:
method __setitem__ (line 138) | def __setitem__(self, key: int, value: object) -> None:
method __len__ (line 141) | def __len__(self) -> int:
class ResizableHashTable (line 145) | class ResizableHashTable(HashTable):
method __init__ (line 157) | def __init__(self) -> None:
method put (line 160) | def put(self, key: int, value: object) -> None:
method _resize (line 171) | def _resize(self) -> None:
FILE: algorithms/data_structures/heap.py
class AbstractHeap (line 20) | class AbstractHeap(metaclass=ABCMeta):
method __init__ (line 23) | def __init__(self) -> None: # noqa: B027
method perc_up (line 27) | def perc_up(self, index: int) -> None:
method insert (line 35) | def insert(self, val: int) -> None:
method perc_down (line 43) | def perc_down(self, index: int) -> None:
method min_child (line 51) | def min_child(self, index: int) -> int:
method remove_min (line 62) | def remove_min(self) -> int:
class BinaryHeap (line 70) | class BinaryHeap(AbstractHeap):
method __init__ (line 81) | def __init__(self) -> None:
method perc_up (line 86) | def perc_up(self, index: int) -> None:
method insert (line 102) | def insert(self, val: int) -> None:
method min_child (line 112) | def min_child(self, index: int) -> int:
method perc_down (line 127) | def perc_down(self, index: int) -> None:
method remove_min (line 142) | def remove_min(self) -> int:
FILE: algorithms/data_structures/iterative_segment_tree.py
class SegmentTree (line 26) | class SegmentTree:
method __init__ (line 27) | def __init__(self, arr, function):
method build_tree (line 33) | def build_tree(self):
method update (line 37) | def update(self, p, v):
method query (line 44) | def query(self, left, r):
FILE: algorithms/data_structures/kd_tree.py
class KDNode (line 14) | class KDNode:
method __init__ (line 19) | def __init__(
class KDTree (line 32) | class KDTree:
method __init__ (line 40) | def __init__(self, points: list[tuple[float, ...]]) -> None:
method _build (line 44) | def _build(self, points: list[tuple[float, ...]], depth: int) -> KDNod...
method nearest (line 57) | def nearest(self, target: tuple[float, ...]) -> tuple[float, ...]:
method _nearest (line 63) | def _nearest(
function _sq_dist (line 82) | def _sq_dist(a: tuple[float, ...], b: tuple[float, ...]) -> float:
FILE: algorithms/data_structures/linked_list.py
class SinglyLinkedListNode (line 17) | class SinglyLinkedListNode:
method __init__ (line 25) | def __init__(self, value: object) -> None:
class DoublyLinkedListNode (line 30) | class DoublyLinkedListNode:
method __init__ (line 39) | def __init__(self, value: object) -> None:
FILE: algorithms/data_structures/priority_queue.py
class PriorityQueueNode (line 21) | class PriorityQueueNode:
method __init__ (line 29) | def __init__(self, data: Any, priority: Any) -> None:
method __repr__ (line 33) | def __repr__(self) -> str:
class PriorityQueue (line 42) | class PriorityQueue:
method __init__ (line 53) | def __init__(
method __repr__ (line 72) | def __repr__(self) -> str:
method size (line 80) | def size(self) -> int:
method push (line 88) | def push(self, item: Any, priority: Any = None) -> None:
method pop (line 103) | def pop(self) -> Any:
FILE: algorithms/data_structures/queue.py
class AbstractQueue (line 20) | class AbstractQueue(metaclass=ABCMeta):
method __init__ (line 23) | def __init__(self) -> None:
method __len__ (line 26) | def __len__(self) -> int:
method is_empty (line 29) | def is_empty(self) -> bool:
method enqueue (line 38) | def enqueue(self, value: object) -> None:
method dequeue (line 42) | def dequeue(self) -> object:
method peek (line 46) | def peek(self) -> object:
method __iter__ (line 50) | def __iter__(self) -> Iterator[object]:
class ArrayQueue (line 54) | class ArrayQueue(AbstractQueue):
method __init__ (line 64) | def __init__(self, capacity: int = 10) -> None:
method __iter__ (line 75) | def __iter__(self) -> Iterator[object]:
method enqueue (line 83) | def enqueue(self, value: object) -> None:
method dequeue (line 95) | def dequeue(self) -> object:
method peek (line 112) | def peek(self) -> object:
method _expand (line 125) | def _expand(self) -> None:
class QueueNode (line 130) | class QueueNode:
method __init__ (line 133) | def __init__(self, value: object) -> None:
class LinkedListQueue (line 138) | class LinkedListQueue(AbstractQueue):
method __init__ (line 148) | def __init__(self) -> None:
method __iter__ (line 153) | def __iter__(self) -> Iterator[object]:
method enqueue (line 161) | def enqueue(self, value: object) -> None:
method dequeue (line 176) | def dequeue(self) -> object:
method peek (line 196) | def peek(self) -> object:
FILE: algorithms/data_structures/red_black_tree.py
class RBNode (line 6) | class RBNode:
method __init__ (line 7) | def __init__(self, val, is_red, parent=None, left=None, right=None):
class RBTree (line 15) | class RBTree:
method __init__ (line 16) | def __init__(self):
method left_rotate (line 19) | def left_rotate(self, node):
method right_rotate (line 40) | def right_rotate(self, node):
method insert (line 61) | def insert(self, node):
method fix_insert (line 85) | def fix_insert(self, node):
method transplant (line 142) | def transplant(self, node_u, node_v):
method maximum (line 159) | def maximum(self, node):
method minimum (line 170) | def minimum(self, node):
method delete (line 181) | def delete(self, node):
method delete_fixup (line 208) | def delete_fixup(self, node):
method inorder (line 271) | def inorder(self):
FILE: algorithms/data_structures/segment_tree.py
class SegmentTree (line 8) | class SegmentTree:
method __init__ (line 9) | def __init__(self, arr, function):
method make_tree (line 15) | def make_tree(self, i, left, r):
method __query (line 25) | def __query(self, i, low, high, left, r):
method query (line 41) | def query(self, low, high):
FILE: algorithms/data_structures/separate_chaining_hash_table.py
class _Node (line 17) | class _Node:
method __init__ (line 26) | def __init__(
class SeparateChainingHashTable (line 37) | class SeparateChainingHashTable:
method __init__ (line 54) | def __init__(self, size: int = 11) -> None:
method put (line 64) | def put(self, key: object, value: object) -> None:
method get (line 84) | def get(self, key: object) -> object | None:
method del_ (line 101) | def del_(self, key: object) -> None:
method hash (line 120) | def hash(self, key: object) -> int:
method __len__ (line 131) | def __len__(self) -> int:
method __getitem__ (line 134) | def __getitem__(self, key: object) -> object | None:
method __delitem__ (line 137) | def __delitem__(self, key: object) -> None:
method __setitem__ (line 140) | def __setitem__(self, key: object, value: object) -> None:
FILE: algorithms/data_structures/sqrt_decomposition.py
class SqrtDecomposition (line 26) | class SqrtDecomposition:
method __init__ (line 45) | def __init__(self, arr: list[int | float]) -> None:
method update (line 60) | def update(self, index: int, value: int | float) -> None:
method query (line 84) | def query(self, left: int, right: int) -> int | float:
FILE: algorithms/data_structures/stack.py
class AbstractStack (line 20) | class AbstractStack(metaclass=ABCMeta):
method __init__ (line 23) | def __init__(self) -> None:
method __len__ (line 26) | def __len__(self) -> int:
method __str__ (line 29) | def __str__(self) -> str:
method is_empty (line 33) | def is_empty(self) -> bool:
method __iter__ (line 42) | def __iter__(self) -> Iterator[object]:
method push (line 46) | def push(self, value: object) -> None:
method pop (line 50) | def pop(self) -> object:
method peek (line 54) | def peek(self) -> object:
class ArrayStack (line 58) | class ArrayStack(AbstractStack):
method __init__ (line 68) | def __init__(self, size: int = 10) -> None:
method __iter__ (line 77) | def __iter__(self) -> Iterator[object]:
method push (line 85) | def push(self, value: object) -> None:
method pop (line 96) | def pop(self) -> object:
method peek (line 111) | def peek(self) -> object:
method _expand (line 124) | def _expand(self) -> None:
class StackNode (line 129) | class StackNode:
method __init__ (line 132) | def __init__(self, value: object) -> None:
class LinkedListStack (line 137) | class LinkedListStack(AbstractStack):
method __init__ (line 147) | def __init__(self) -> None:
method __iter__ (line 151) | def __iter__(self) -> Iterator[object]:
method push (line 159) | def push(self, value: object) -> None:
method pop (line 170) | def pop(self) -> object:
method peek (line 186) | def peek(self) -> object:
FILE: algorithms/data_structures/trie.py
class TrieNode (line 11) | class TrieNode:
method __init__ (line 12) | def __init__(self):
class Trie (line 17) | class Trie:
method __init__ (line 18) | def __init__(self):
method insert (line 21) | def insert(self, word):
method search (line 27) | def search(self, word):
method starts_with (line 35) | def starts_with(self, prefix):
FILE: algorithms/data_structures/union_find.py
class Union (line 17) | class Union:
method __init__ (line 33) | def __init__(self) -> None:
method add (line 38) | def add(self, element: object) -> None:
method root (line 48) | def root(self, element: object) -> object:
method unite (line 62) | def unite(self, element1: object, element2: object) -> None:
FILE: algorithms/data_structures/veb_tree.py
class VEBTree (line 20) | class VEBTree:
method __init__ (line 32) | def __init__(self, universe_size):
method _validate_key (line 64) | def _validate_key(self, x):
method high (line 77) | def high(self, x):
method low (line 89) | def low(self, x):
method index (line 101) | def index(self, high, low):
method empty_insert (line 114) | def empty_insert(self, x):
method insert (line 123) | def insert(self, x):
method member (line 154) | def member(self, x):
method successor (line 175) | def successor(self, x):
method delete (line 212) | def delete(self, x):
method minimum (line 256) | def minimum(self):
method maximum (line 265) | def maximum(self):
FILE: algorithms/dynamic_programming/bitmask.py
function tsp (line 17) | def tsp(dist: list[list[float]]) -> float:
FILE: algorithms/dynamic_programming/buy_sell_stock.py
function max_profit_naive (line 21) | def max_profit_naive(prices: list[int]) -> int:
function max_profit_optimized (line 43) | def max_profit_optimized(prices: list[int]) -> int:
FILE: algorithms/dynamic_programming/climbing_stairs.py
function climb_stairs (line 21) | def climb_stairs(steps: int) -> int:
function climb_stairs_optimized (line 42) | def climb_stairs_optimized(steps: int) -> int:
FILE: algorithms/dynamic_programming/coin_change.py
function count (line 17) | def count(coins: list[int], value: int) -> int:
FILE: algorithms/dynamic_programming/combination_sum.py
function _helper_topdown (line 21) | def _helper_topdown(nums: list[int], target: int, dp: list[int]) -> int:
function combination_sum_topdown (line 42) | def combination_sum_topdown(nums: list[int], target: int) -> int:
function combination_sum_bottom_up (line 61) | def combination_sum_bottom_up(nums: list[int], target: int) -> int:
FILE: algorithms/dynamic_programming/count_paths_dp.py
function count_paths_recursive (line 14) | def count_paths_recursive(m: int, n: int) -> int:
function count_paths_memo (line 21) | def count_paths_memo(m: int, n: int) -> int:
function count_paths_dp (line 33) | def count_paths_dp(m: int, n: int) -> int:
FILE: algorithms/dynamic_programming/edit_distance.py
function edit_distance (line 17) | def edit_distance(word_a: str, word_b: str) -> int:
FILE: algorithms/dynamic_programming/egg_drop.py
function egg_drop (line 19) | def egg_drop(n: int, k: int) -> int:
FILE: algorithms/dynamic_programming/fib.py
function fib_recursive (line 24) | def fib_recursive(n: int) -> int:
function fib_list (line 44) | def fib_list(n: int) -> int:
function fib_iter (line 65) | def fib_iter(n: int) -> int:
FILE: algorithms/dynamic_programming/hosoya_triangle.py
function hosoya (line 17) | def hosoya(height: int, width: int) -> int:
function hosoya_testing (line 42) | def hosoya_testing(height: int) -> list[int]:
FILE: algorithms/dynamic_programming/house_robber.py
function house_robber (line 17) | def house_robber(houses: list[int]) -> int:
FILE: algorithms/dynamic_programming/int_divide.py
function int_divide (line 17) | def int_divide(decompose: int) -> int:
FILE: algorithms/dynamic_programming/job_scheduling.py
class Job (line 17) | class Job:
method __init__ (line 20) | def __init__(self, start: int, finish: int, profit: int) -> None:
function _binary_search (line 26) | def _binary_search(job: list[Job], start_index: int) -> int:
function schedule (line 51) | def schedule(job: list[Job]) -> int:
FILE: algorithms/dynamic_programming/k_factor.py
function find_k_factor (line 18) | def find_k_factor(length: int, k_factor: int) -> int:
FILE: algorithms/dynamic_programming/knapsack.py
class Item (line 17) | class Item:
method __init__ (line 20) | def __init__(self, value: int, weight: int) -> None:
function get_maximum_value (line 25) | def get_maximum_value(items: list[Item], capacity: int) -> int:
FILE: algorithms/dynamic_programming/longest_common_subsequence.py
function longest_common_subsequence (line 16) | def longest_common_subsequence(s_1: str, s_2: str) -> int:
FILE: algorithms/dynamic_programming/longest_increasing.py
function longest_increasing_subsequence (line 23) | def longest_increasing_subsequence(sequence: list[int]) -> int:
function longest_increasing_subsequence_optimized (line 45) | def longest_increasing_subsequence_optimized(sequence: list[int]) -> int:
function longest_increasing_subsequence_optimized2 (line 91) | def longest_increasing_subsequence_optimized2(sequence: list[int]) -> int:
FILE: algorithms/dynamic_programming/matrix_chain_order.py
function matrix_chain_order (line 19) | def matrix_chain_order(array: list[int]) -> tuple[list[list[int]], list[...
FILE: algorithms/dynamic_programming/max_product_subarray.py
function max_product (line 22) | def max_product(nums: list[int]) -> int:
function subarray_with_max_product (line 45) | def subarray_with_max_product(arr: list[int]) -> tuple[int, list[int]]:
FILE: algorithms/dynamic_programming/max_subarray.py
function max_subarray (line 16) | def max_subarray(array: list[int]) -> int:
FILE: algorithms/dynamic_programming/min_cost_path.py
function min_cost (line 20) | def min_cost(cost: list[list[int]]) -> int:
FILE: algorithms/dynamic_programming/num_decodings.py
function num_decodings (line 17) | def num_decodings(enc_mes: str) -> int:
function num_decodings2 (line 47) | def num_decodings2(enc_mes: str) -> int:
FILE: algorithms/dynamic_programming/planting_trees.py
function planting_trees (line 20) | def planting_trees(trees: list[int], length: int, width: int) -> float:
FILE: algorithms/dynamic_programming/regex_matching.py
function is_match (line 17) | def is_match(str_a: str, str_b: str) -> bool:
FILE: algorithms/dynamic_programming/rod_cut.py
function cut_rod (line 19) | def cut_rod(price: list[int]) -> int:
FILE: algorithms/dynamic_programming/word_break.py
function word_break (line 17) | def word_break(word: str, word_dict: set[str]) -> bool:
FILE: algorithms/graph/a_star.py
function a_star (line 20) | def a_star(
FILE: algorithms/graph/all_factors.py
function get_factors (line 17) | def get_factors(n: int) -> list[list[int]]:
function get_factors_iterative1 (line 47) | def get_factors_iterative1(n: int) -> list[list[int]]:
function get_factors_iterative2 (line 72) | def get_factors_iterative2(n: int) -> list[list[int]]:
FILE: algorithms/graph/all_pairs_shortest_path.py
function all_pairs_shortest_path (line 19) | def all_pairs_shortest_path(
FILE: algorithms/graph/bellman_ford.py
function bellman_ford (line 18) | def bellman_ford(graph: dict[str, dict[str, float]], source: str) -> bool:
function _initialize_single_source (line 58) | def _initialize_single_source(
FILE: algorithms/graph/blossom.py
function max_matching (line 17) | def max_matching(n: int, edges: list[tuple[int, int]]) -> list[tuple[int...
function _augment (line 75) | def _augment(parent: list[int], match: list[int], u: int, v: int) -> None:
FILE: algorithms/graph/check_bipartite.py
function check_bipartite (line 18) | def check_bipartite(adj_list: list[list[int]]) -> bool:
FILE: algorithms/graph/check_digraph_strongly_connected.py
class Graph (line 20) | class Graph:
method __init__ (line 23) | def __init__(self, vertex_count: int) -> None:
method add_edge (line 32) | def add_edge(self, source: int, target: int) -> None:
method dfs (line 41) | def dfs(self) -> bool:
method _dfs_util (line 47) | def _dfs_util(self, source: int, visited: list[bool]) -> None:
method reverse_graph (line 59) | def reverse_graph(self) -> Graph:
method is_strongly_connected (line 71) | def is_strongly_connected(self) -> bool:
FILE: algorithms/graph/clone_graph.py
class UndirectedGraphNode (line 19) | class UndirectedGraphNode:
method __init__ (line 22) | def __init__(self, label: int) -> None:
method shallow_copy (line 26) | def shallow_copy(self) -> UndirectedGraphNode:
method add_neighbor (line 34) | def add_neighbor(self, node: UndirectedGraphNode) -> None:
function clone_graph1 (line 43) | def clone_graph1(node: UndirectedGraphNode | None) -> UndirectedGraphNod...
function clone_graph2 (line 70) | def clone_graph2(node: UndirectedGraphNode | None) -> UndirectedGraphNod...
function clone_graph (line 97) | def clone_graph(node: UndirectedGraphNode | None) -> UndirectedGraphNode...
function _dfs (line 114) | def _dfs(
FILE: algorithms/graph/count_connected_number_of_component.py
function count_components (line 16) | def count_components(adjacency_list: list[list[int]], size: int) -> int:
function _dfs (line 40) | def _dfs(
FILE: algorithms/graph/count_islands_bfs.py
function count_islands (line 20) | def count_islands(grid: list[list[int]]) -> int:
FILE: algorithms/graph/count_islands_dfs.py
function num_islands (line 17) | def num_islands(grid: list[list[int]]) -> int:
function _dfs (line 39) | def _dfs(grid: list[list[int]], i: int, j: int) -> None:
FILE: algorithms/graph/count_islands_unionfind.py
function num_islands (line 20) | def num_islands(positions: list[list[int]]) -> list[int]:
FILE: algorithms/graph/cycle_detection.py
class TraversalState (line 19) | class TraversalState(Enum):
function is_in_cycle (line 27) | def is_in_cycle(
function contains_cycle (line 52) | def contains_cycle(graph: dict[str, list[str]]) -> bool:
FILE: algorithms/graph/dijkstra.py
class Dijkstra (line 17) | class Dijkstra:
method __init__ (line 20) | def __init__(self, vertex_count: int) -> None:
method min_distance (line 31) | def min_distance(self, dist: list[float], min_dist_set: list[bool]) ->...
method dijkstra (line 51) | def dijkstra(self, src: int) -> list[float]:
FILE: algorithms/graph/dijkstra_heapq.py
function dijkstra (line 22) | def dijkstra(
FILE: algorithms/graph/find_all_cliques.py
function find_all_cliques (line 17) | def find_all_cliques(edges: dict[str, set[str]]) -> list[list[str]]:
FILE: algorithms/graph/find_path.py
function find_path (line 17) | def find_path(
function find_all_path (line 52) | def find_all_path(
function find_shortest_path (line 89) | def find_shortest_path(
FILE: algorithms/graph/kahns_algorithm.py
class Solution (line 19) | class Solution:
method topological_sort (line 22) | def topological_sort(
FILE: algorithms/graph/markov_chain.py
function _choose_state (line 21) | def _choose_state(state_map: dict[Any, float]) -> Any | None:
function next_state (line 39) | def next_state(chain: dict[Any, dict[Any, float]], current_state: Any) -...
function iterating_markov_chain (line 58) | def iterating_markov_chain(
FILE: algorithms/graph/maximum_flow.py
function _dfs (line 20) | def _dfs(
function ford_fulkerson (line 57) | def ford_fulkerson(capacity: list[list[int]], source: int, sink: int) ->...
function edmonds_karp (line 85) | def edmonds_karp(capacity: list[list[int]], source: int, sink: int) -> int:
function _dinic_bfs (line 136) | def _dinic_bfs(
function _dinic_dfs (line 168) | def _dinic_dfs(
function dinic (line 207) | def dinic(capacity: list[list[int]], source: int, sink: int) -> int:
FILE: algorithms/graph/maximum_flow_bfs.py
function maximum_flow_bfs (line 21) | def maximum_flow_bfs(adjacency_matrix: list[list[int]]) -> int:
FILE: algorithms/graph/maximum_flow_dfs.py
function maximum_flow_dfs (line 20) | def maximum_flow_dfs(adjacency_matrix: list[list[int]]) -> int:
FILE: algorithms/graph/maze_search_bfs.py
function maze_search (line 18) | def maze_search(maze: list[list[int]]) -> int:
FILE: algorithms/graph/maze_search_dfs.py
function find_path (line 16) | def find_path(maze: list[list[int]]) -> int:
function _dfs (line 33) | def _dfs(
FILE: algorithms/graph/minimum_spanning_tree.py
class Edge (line 17) | class Edge:
method __init__ (line 20) | def __init__(self, source: int, target: int, weight: int) -> None:
class DisjointSet (line 26) | class DisjointSet:
method __init__ (line 29) | def __init__(self, size: int) -> None:
method merge_set (line 38) | def merge_set(self, node1: int, node2: int) -> None:
method find_set (line 55) | def find_set(self, node: int) -> int:
function kruskal (line 69) | def kruskal(vertex_count: int, edges: list[Edge], forest: DisjointSet) -...
FILE: algorithms/graph/pacific_atlantic.py
function pacific_atlantic (line 18) | def pacific_atlantic(matrix: list[list[int]]) -> list[list[int]]:
function _dfs (line 53) | def _dfs(
FILE: algorithms/graph/path_between_two_vertices_in_digraph.py
class Graph (line 17) | class Graph:
method __init__ (line 20) | def __init__(self, vertex_count: int) -> None:
method add_edge (line 30) | def add_edge(self, source: int, target: int) -> None:
method _dfs (line 39) | def _dfs(self, source: int, target: int) -> None:
method _dfs_util (line 49) | def _dfs_util(self, visited: list[bool], source: int, target: int) -> ...
method is_reachable (line 65) | def is_reachable(self, source: int, target: int) -> bool:
FILE: algorithms/graph/prims_minimum_spanning.py
function prims_minimum_spanning (line 20) | def prims_minimum_spanning(
FILE: algorithms/graph/satisfiability.py
function _dfs_transposed (line 20) | def _dfs_transposed(
function _dfs (line 41) | def _dfs(
function _add_edge (line 64) | def _add_edge(graph: dict[Any, list[Any]], vertex_from: Any, vertex_to: ...
function _scc (line 77) | def _scc(graph: dict[Any, list[Any]]) -> dict[Any, int]:
function _build_graph (line 111) | def _build_graph(
function solve_sat (line 137) | def solve_sat(
FILE: algorithms/graph/shortest_distance_from_all_buildings.py
function shortest_distance (line 19) | def shortest_distance(grid: list[list[int]]) -> int:
function _bfs (line 53) | def _bfs(
FILE: algorithms/graph/strongly_connected_components_kosaraju.py
class Kosaraju (line 17) | class Kosaraju:
method dfs (line 20) | def dfs(
method kosaraju (line 45) | def kosaraju(self, vertices: int, adj: list[list[int]]) -> int:
FILE: algorithms/graph/sudoku_solver.py
class Sudoku (line 17) | class Sudoku:
method __init__ (line 20) | def __init__(
method _possible_values (line 38) | def _possible_values(self) -> dict[tuple[int, int], list[str]]:
method solve (line 63) | def solve(self) -> bool:
method _valid_one (line 80) | def _valid_one(
method _undo (line 111) | def _undo(
method __str__ (line 129) | def __str__(self) -> str:
FILE: algorithms/graph/tarjan.py
class Tarjan (line 18) | class Tarjan:
method __init__ (line 21) | def __init__(self, dict_graph: dict[str, list[str]]) -> None:
method _strongconnect (line 39) | def _strongconnect(self, vertex: object, sccs: list[list]) -> None:
FILE: algorithms/graph/topological_sort_bfs.py
function topological_sort (line 19) | def topological_sort(vertices: int, edges: list[tuple[int, int]]) -> lis...
FILE: algorithms/graph/topological_sort_dfs.py
function top_sort_recursive (line 21) | def top_sort_recursive(graph: dict[str, list[str]]) -> list[str]:
function top_sort (line 59) | def top_sort(graph: dict[str, list[str]]) -> list[str]:
FILE: algorithms/graph/transitive_closure_dfs.py
class Graph (line 17) | class Graph:
method __init__ (line 20) | def __init__(self, vertices: int) -> None:
method add_edge (line 30) | def add_edge(self, source: int, target: int) -> None:
method _dfs_util (line 42) | def _dfs_util(self, source: int, target: int) -> None:
method transitive_closure (line 55) | def transitive_closure(self) -> list[list[int]]:
FILE: algorithms/graph/traversal.py
function dfs_traverse (line 18) | def dfs_traverse(graph: dict[Any, list[Any]], start: Any) -> set[Any]:
function bfs_traverse (line 44) | def bfs_traverse(graph: dict[Any, list[Any]], start: Any) -> set[Any]:
function dfs_traverse_recursive (line 70) | def dfs_traverse_recursive(
FILE: algorithms/graph/walls_and_gates.py
function walls_and_gates (line 17) | def walls_and_gates(rooms: list[list[int]]) -> None:
function _dfs (line 33) | def _dfs(rooms: list[list[int]], i: int, j: int, depth: int) -> None:
FILE: algorithms/graph/word_ladder.py
function ladder_length (line 20) | def ladder_length(begin_word: str, end_word: str, word_list: list[str]) ...
function _word_range (line 66) | def _word_range(word: str) -> Iterator[str]:
FILE: algorithms/greedy/gale_shapley.py
function gale_shapley (line 18) | def gale_shapley(
FILE: algorithms/greedy/max_contiguous_subsequence_sum.py
function max_contiguous_subsequence_sum (line 17) | def max_contiguous_subsequence_sum(arr: list[int]) -> int:
FILE: algorithms/heap/k_closest_points.py
function k_closest (line 20) | def k_closest(
function _distance (line 49) | def _distance(point: tuple[int, int], origin: tuple[int, int] = (0, 0)) ...
FILE: algorithms/heap/merge_sorted_k_lists.py
class ListNode (line 19) | class ListNode:
method __init__ (line 26) | def __init__(self, val: int) -> None:
function merge_k_lists (line 31) | def merge_k_lists(lists: list[ListNode | None]) -> ListNode | None:
FILE: algorithms/heap/skyline.py
function get_skyline (line 19) | def get_skyline(lrh: list[list[int]]) -> list[list[int]]:
FILE: algorithms/heap/sliding_window_max.py
function max_sliding_window (line 19) | def max_sliding_window(nums: list[int], k: int) -> list[int]:
FILE: algorithms/linked_list/add_two_numbers.py
class Node (line 18) | class Node:
method __init__ (line 19) | def __init__(self, x: int) -> None:
function add_two_numbers (line 24) | def add_two_numbers(left: Node, right: Node) -> Node:
function convert_to_list (line 59) | def convert_to_list(number: int) -> Node | None:
function convert_to_str (line 88) | def convert_to_str(node: Node | None) -> str:
FILE: algorithms/linked_list/copy_random_pointer.py
class RandomListNode (line 19) | class RandomListNode:
method __init__ (line 22) | def __init__(self, label: int) -> None:
function copy_random_pointer_v1 (line 28) | def copy_random_pointer_v1(head: RandomListNode | None) -> RandomListNod...
function copy_random_pointer_v2 (line 57) | def copy_random_pointer_v2(head: RandomListNode | None) -> RandomListNod...
FILE: algorithms/linked_list/delete_node.py
class Node (line 17) | class Node:
method __init__ (line 18) | def __init__(self, x: int) -> None:
function delete_node (line 23) | def delete_node(node: Node | None) -> None:
FILE: algorithms/linked_list/first_cyclic_node.py
class Node (line 17) | class Node:
method __init__ (line 18) | def __init__(self, x: object) -> None:
function first_cyclic_node (line 23) | def first_cyclic_node(head: Node | None) -> Node | None:
FILE: algorithms/linked_list/intersection.py
class Node (line 17) | class Node:
method __init__ (line 18) | def __init__(self, val: object = None) -> None:
function intersection (line 23) | def intersection(h1: Node, h2: Node) -> Node | None:
FILE: algorithms/linked_list/is_cyclic.py
class Node (line 17) | class Node:
method __init__ (line 18) | def __init__(self, x: object) -> None:
function is_cyclic (line 23) | def is_cyclic(head: Node | None) -> bool:
FILE: algorithms/linked_list/is_palindrome.py
function is_palindrome (line 17) | def is_palindrome(head: object | None) -> bool:
function is_palindrome_stack (line 52) | def is_palindrome_stack(head: object | None) -> bool:
function is_palindrome_dict (line 85) | def is_palindrome_dict(head: object | None) -> bool:
FILE: algorithms/linked_list/is_sorted.py
function is_sorted (line 17) | def is_sorted(head: object | None) -> bool:
FILE: algorithms/linked_list/kth_to_last.py
class Node (line 17) | class Node:
method __init__ (line 18) | def __init__(self, val: object = None) -> None:
function kth_to_last_eval (line 23) | def kth_to_last_eval(head: Node, k: int) -> Node | bool:
function kth_to_last_dict (line 54) | def kth_to_last_dict(head: Node | None, k: int) -> Node | bool:
function kth_to_last (line 80) | def kth_to_last(head: Node | None, k: int) -> Node | bool:
FILE: algorithms/linked_list/merge_two_list.py
class Node (line 17) | class Node:
method __init__ (line 18) | def __init__(self, x: int) -> None:
function merge_two_list (line 23) | def merge_two_list(l1: Node | None, l2: Node | None) -> Node | None:
function merge_two_list_recur (line 53) | def merge_two_list_recur(l1: Node | None, l2: Node | None) -> Node | None:
FILE: algorithms/linked_list/partition.py
class Node (line 17) | class Node:
method __init__ (line 18) | def __init__(self, val: object = None) -> None:
function partition (line 23) | def partition(head: Node | None, x: int) -> None:
FILE: algorithms/linked_list/remove_duplicates.py
class Node (line 18) | class Node:
method __init__ (line 19) | def __init__(self, val: object = None) -> None:
function remove_dups (line 24) | def remove_dups(head: Node | None) -> None:
function remove_dups_wothout_set (line 51) | def remove_dups_wothout_set(head: Node | None) -> None:
FILE: algorithms/linked_list/remove_range.py
function remove_range (line 17) | def remove_range(head: object | None, start: int, end: int) -> object | ...
FILE: algorithms/linked_list/reverse.py
function reverse_list (line 17) | def reverse_list(head: object | None) -> object | None:
function reverse_list_recursive (line 41) | def reverse_list_recursive(head: object | None) -> object | None:
FILE: algorithms/linked_list/rotate_list.py
function rotate_right (line 17) | def rotate_right(head: object | None, k: int) -> object | None:
FILE: algorithms/linked_list/swap_in_pairs.py
class Node (line 17) | class Node:
method __init__ (line 18) | def __init__(self, x: int) -> None:
function swap_pairs (line 23) | def swap_pairs(head: Node | None) -> Node | None:
FILE: algorithms/map/is_anagram.py
function is_anagram (line 17) | def is_anagram(s: str, t: str) -> bool:
FILE: algorithms/map/is_isomorphic.py
function is_isomorphic (line 18) | def is_isomorphic(s: str, t: str) -> bool:
FILE: algorithms/map/longest_common_subsequence.py
function max_common_sub_string (line 17) | def max_common_sub_string(s1: str, s2: str) -> str:
FILE: algorithms/map/longest_palindromic_subsequence.py
function longest_palindromic_subsequence (line 17) | def longest_palindromic_subsequence(s: str) -> int:
FILE: algorithms/map/randomized_set.py
class RandomizedSet (line 20) | class RandomizedSet:
method __init__ (line 33) | def __init__(self) -> None:
method insert (line 38) | def insert(self, val: int) -> bool:
method remove (line 53) | def remove(self, val: int) -> bool:
method get_random (line 70) | def get_random(self) -> int:
FILE: algorithms/map/valid_sudoku.py
function is_valid_sudoku (line 17) | def is_valid_sudoku(board: list[list[str]]) -> bool:
FILE: algorithms/map/word_pattern.py
function word_pattern (line 17) | def word_pattern(pattern: str, string: str) -> bool:
FILE: algorithms/math/base_conversion.py
function int_to_base (line 19) | def int_to_base(num: int, base: int) -> str:
function base_to_int (line 53) | def base_to_int(str_to_convert: str, base: int) -> int:
FILE: algorithms/math/chinese_remainder_theorem.py
function solve_chinese_remainder (line 20) | def solve_chinese_remainder(nums: list[int], rems: list[int]) -> int:
function _check_coprime (line 59) | def _check_coprime(list_to_check: list[int]) -> bool:
FILE: algorithms/math/combination.py
function combination (line 17) | def combination(n: int, r: int) -> int:
function combination_memo (line 38) | def combination_memo(n: int, r: int) -> int:
FILE: algorithms/math/cosine_similarity.py
function _l2_distance (line 20) | def _l2_distance(vec: list[float]) -> float:
function cosine_similarity (line 36) | def cosine_similarity(vec1: list[float], vec2: list[float]) -> float:
FILE: algorithms/math/decimal_to_binary_ip.py
function decimal_to_binary_util (line 17) | def decimal_to_binary_util(val: str) -> str:
function decimal_to_binary_ip (line 43) | def decimal_to_binary_ip(ip: str) -> str:
FILE: algorithms/math/diffie_hellman_key_exchange.py
function _prime_check (line 21) | def _prime_check(num: int) -> bool:
function _find_order (line 44) | def _find_order(a: int, n: int) -> int:
function _euler_totient (line 64) | def _euler_totient(n: int) -> int:
function _find_primitive_root (line 84) | def _find_primitive_root(n: int) -> list[int]:
function alice_private_key (line 106) | def alice_private_key(p: int) -> int:
function alice_public_key (line 118) | def alice_public_key(a_pr_k: int, a: int, p: int) -> int:
function bob_private_key (line 132) | def bob_private_key(p: int) -> int:
function bob_public_key (line 144) | def bob_public_key(b_pr_k: int, a: int, p: int) -> int:
function alice_shared_key (line 158) | def alice_shared_key(b_pu_k: int, a_pr_k: int, p: int) -> int:
function bob_shared_key (line 172) | def bob_shared_key(a_pu_k: int, b_pr_k: int, p: int) -> int:
function diffie_hellman_key_exchange (line 186) | def diffie_hellman_key_exchange(a: int, p: int, option: int | None = Non...
FILE: algorithms/math/distance_between_two_points.py
function distance_between_two_points (line 19) | def distance_between_two_points(x1: float, y1: float, x2: float, y2: flo...
FILE: algorithms/math/euler_totient.py
function euler_totient (line 17) | def euler_totient(n: int) -> int:
FILE: algorithms/math/extended_gcd.py
function extended_gcd (line 17) | def extended_gcd(num1: int, num2: int) -> tuple[int, int, int]:
FILE: algorithms/math/factorial.py
function factorial (line 17) | def factorial(n: int, mod: int | None = None) -> int:
function factorial_recur (line 50) | def factorial_recur(n: int, mod: int | None = None) -> int:
FILE: algorithms/math/fft.py
function fft (line 19) | def fft(x: list[complex]) -> list[complex]:
FILE: algorithms/math/find_order_simple.py
function find_order (line 19) | def find_order(a: int, n: int) -> int:
FILE: algorithms/math/find_primitive_root_simple.py
function _find_order (line 20) | def _find_order(a: int, n: int) -> int:
function _euler_totient (line 40) | def _euler_totient(n: int) -> int:
function find_primitive_root (line 60) | def find_primitive_root(n: int) -> list[int]:
FILE: algorithms/math/gcd.py
function gcd (line 17) | def gcd(a: int, b: int) -> int:
function lcm (line 51) | def lcm(a: int, b: int) -> int:
function trailing_zero (line 68) | def trailing_zero(x: int) -> int:
function gcd_bit (line 90) | def gcd_bit(a: int, b: int) -> int:
FILE: algorithms/math/generate_strobogrammtic.py
function gen_strobogrammatic (line 17) | def gen_strobogrammatic(n: int) -> list[str]:
function _helper (line 33) | def _helper(n: int, length: int) -> list[str]:
function strobogrammatic_in_range (line 59) | def strobogrammatic_in_range(low: str, high: str) -> int:
function _helper2 (line 88) | def _helper2(n: int, length: int) -> list[str]:
FILE: algorithms/math/goldbach.py
function _is_prime (line 18) | def _is_prime(n: int) -> bool:
function goldbach (line 41) | def goldbach(n: int) -> tuple[int, int]:
function verify_goldbach (line 76) | def verify_goldbach(limit: int) -> bool:
FILE: algorithms/math/hailstone.py
function hailstone (line 17) | def hailstone(n: int) -> list[int]:
FILE: algorithms/math/is_strobogrammatic.py
function is_strobogrammatic (line 17) | def is_strobogrammatic(num: str) -> bool:
function is_strobogrammatic2 (line 43) | def is_strobogrammatic2(num: str) -> bool:
FILE: algorithms/math/krishnamurthy_number.py
function _find_factorial (line 17) | def _find_factorial(n: int) -> int:
function krishnamurthy_number (line 33) | def krishnamurthy_number(n: int) -> bool:
FILE: algorithms/math/linear_regression.py
function linear_regression (line 14) | def linear_regression(x: list[float], y: list[float]) -> tuple[float, fl...
function r_squared (line 40) | def r_squared(x: list[float], y: list[float]) -> float:
function rmse (line 53) | def rmse(x: list[float], y: list[float]) -> float:
FILE: algorithms/math/magic_number.py
function magic_number (line 17) | def magic_number(n: int) -> bool:
FILE: algorithms/math/manhattan_distance.py
function manhattan_distance (line 12) | def manhattan_distance(a: tuple[float, ...], b: tuple[float, ...]) -> fl...
FILE: algorithms/math/modular_exponential.py
function modular_exponential (line 17) | def modular_exponential(base: int, exponent: int, mod: int) -> int:
FILE: algorithms/math/modular_inverse.py
function _extended_gcd (line 17) | def _extended_gcd(a: int, b: int) -> tuple[int, int, int]:
function modular_inverse (line 41) | def modular_inverse(a: int, m: int) -> int:
FILE: algorithms/math/next_bigger.py
function next_bigger (line 17) | def next_bigger(num: int) -> int:
FILE: algorithms/math/next_perfect_square.py
function find_next_square (line 17) | def find_next_square(sq: float) -> float:
function find_next_square2 (line 38) | def find_next_square2(sq: float) -> float:
FILE: algorithms/math/nth_digit.py
function find_nth_digit (line 17) | def find_nth_digit(n: int) -> int:
FILE: algorithms/math/num_digits.py
function num_digits (line 19) | def num_digits(n: int) -> int:
FILE: algorithms/math/num_perfect_squares.py
function num_perfect_squares (line 19) | def num_perfect_squares(number: int) -> int:
FILE: algorithms/math/polynomial.py
class Monomial (line 23) | class Monomial:
method __init__ (line 26) | def __init__(
method _rationalize_if_possible (line 57) | def _rationalize_if_possible(
method equal_upto_scalar (line 74) | def equal_upto_scalar(self, other: object) -> bool:
method __add__ (line 90) | def __add__(self, other: int | float | Fraction) -> Monomial:
method __eq__ (line 119) | def __eq__(self, other: object) -> bool:
method __mul__ (line 132) | def __mul__(self, other: int | float | Fraction) -> Monomial:
method inverse (line 169) | def inverse(self) -> Monomial:
method __truediv__ (line 185) | def __truediv__(self, other: int | float | Fraction) -> Monomial:
method __floordiv__ (line 208) | def __floordiv__(self, other: int | float | Fraction) -> Monomial:
method clone (line 219) | def clone(self) -> Monomial:
method clean (line 230) | def clean(self) -> Monomial:
method __sub__ (line 241) | def __sub__(self, other: int | float | Fraction) -> Monomial:
method __hash__ (line 265) | def __hash__(self) -> int:
method all_variables (line 278) | def all_variables(self) -> set:
method substitute (line 286) | def substitute(
method __str__ (line 319) | def __str__(self) -> str:
class Polynomial (line 344) | class Polynomial:
method __init__ (line 347) | def __init__(
method _rationalize_if_possible (line 371) | def _rationalize_if_possible(
method __add__ (line 388) | def __add__(self, other: int | float | Fraction | Monomial) -> Polynom...
method __sub__ (line 435) | def __sub__(self, other: int | float | Fraction | Monomial) -> Polynom...
method __mul__ (line 484) | def __mul__(self, other: int | float | Fraction | Monomial) -> Polynom...
method __floordiv__ (line 519) | def __floordiv__(self, other: int | float | Fraction | Monomial) -> Po...
method __truediv__ (line 530) | def __truediv__(self, other: int | float | Fraction | Monomial) -> Pol...
method clone (line 560) | def clone(self) -> Polynomial:
method variables (line 568) | def variables(self) -> set:
method all_monomials (line 580) | def all_monomials(self) -> Iterable[Monomial]:
method __eq__ (line 588) | def __eq__(self, other: object) -> bool:
method subs (line 613) | def subs(
method __str__ (line 645) | def __str__(self) -> str:
method poly_long_division (line 658) | def poly_long_division(self, other: Polynomial) -> tuple[Polynomial, P...
FILE: algorithms/math/polynomial_division.py
function polynomial_division (line 13) | def polynomial_division(
FILE: algorithms/math/power.py
function power (line 17) | def power(a: int, n: int, mod: int | None = None) -> int:
function power_recur (line 46) | def power_recur(a: int, n: int, mod: int | None = None) -> int:
FILE: algorithms/math/prime_check.py
function prime_check (line 17) | def prime_check(n: int) -> bool:
FILE: algorithms/math/primes_sieve_of_eratosthenes.py
function get_primes (line 17) | def get_primes(n: int) -> list[int]:
FILE: algorithms/math/pythagoras.py
function pythagoras (line 17) | def pythagoras(
FILE: algorithms/math/rabin_miller.py
function is_prime (line 20) | def is_prime(n: int, k: int) -> bool:
FILE: algorithms/math/recursive_binomial_coefficient.py
function recursive_binomial_coefficient (line 17) | def recursive_binomial_coefficient(n: int, k: int) -> int:
FILE: algorithms/math/rsa.py
function _extended_gcd (line 19) | def _extended_gcd(a: int, b: int) -> tuple[int, int, int]:
function _modinv (line 31) | def _modinv(a: int, m: int) -> int:
function generate_key (line 38) | def generate_key(k: int, seed: int | None = None) -> tuple[int, int, int]:
function encrypt (line 100) | def encrypt(data: int, e: int, n: int) -> int:
function decrypt (line 118) | def decrypt(data: int, d: int, n: int) -> int:
FILE: algorithms/math/sqrt_precision_factor.py
function square_root (line 17) | def square_root(n: float, epsilon: float = 0.001) -> float:
FILE: algorithms/math/summing_digits.py
function sum_dig_pow (line 17) | def sum_dig_pow(low: int, high: int) -> list[int]:
FILE: algorithms/math/surface_area_of_torus.py
function surface_area_of_torus (line 19) | def surface_area_of_torus(major_radius: float, minor_radius: float) -> f...
FILE: algorithms/math/symmetry_group_cycle_index.py
function cycle_product (line 23) | def cycle_product(m1: Monomial, m2: Monomial) -> Monomial:
function cycle_product_for_two_polynomials (line 49) | def cycle_product_for_two_polynomials(
function _cycle_index_sym_helper (line 70) | def _cycle_index_sym_helper(n: int, memo: dict[int, Polynomial]) -> Poly...
function get_cycle_index_sym (line 93) | def get_cycle_index_sym(n: int) -> Polynomial:
FILE: algorithms/matrix/bomb_enemy.py
function max_killed_enemies (line 20) | def max_killed_enemies(grid: list[list[str]]) -> int:
function _row_kills (line 49) | def _row_kills(grid: list[list[str]], row: int, col: int) -> int:
function _col_kills (line 69) | def _col_kills(grid: list[list[str]], row: int, col: int) -> int:
FILE: algorithms/matrix/cholesky_matrix_decomposition.py
function cholesky_decomposition (line 20) | def cholesky_decomposition(matrix: list[list[float]]) -> list[list[float...
FILE: algorithms/matrix/copy_transform.py
function rotate_clockwise (line 18) | def rotate_clockwise(matrix: list[list[int]]) -> list[list[int]]:
function rotate_counterclockwise (line 42) | def rotate_counterclockwise(matrix: list[list[int]]) -> list[list[int]]:
function top_left_invert (line 66) | def top_left_invert(matrix: list[list[int]]) -> list[list[int]]:
function bottom_left_invert (line 90) | def bottom_left_invert(matrix: list[list[int]]) -> list[list[int]]:
FILE: algorithms/matrix/count_paths.py
function count_paths (line 18) | def count_paths(rows: int, cols: int) -> int:
FILE: algorithms/matrix/crout_matrix_decomposition.py
function crout_matrix_decomposition (line 19) | def crout_matrix_decomposition(
FILE: algorithms/matrix/matrix_exponentiation.py
function multiply (line 18) | def multiply(mat_a: list[list[int]], mat_b: list[list[int]]) -> list[lis...
function identity (line 41) | def identity(size: int) -> list[list[int]]:
function matrix_exponentiation (line 60) | def matrix_exponentiation(mat: list[list[int]], power: int) -> list[list...
FILE: algorithms/matrix/matrix_inversion.py
function invert_matrix (line 21) | def invert_matrix(
function get_determinant (line 61) | def get_determinant(matrix: list[list[int | float]]) -> int | float:
function _get_matrix_of_minors (line 84) | def _get_matrix_of_minors(
function _get_minor (line 104) | def _get_minor(
function _transpose_and_multiply (line 126) | def _transpose_and_multiply(
function _array_is_matrix (line 147) | def _array_is_matrix(matrix: list[list]) -> bool:
FILE: algorithms/matrix/multiply.py
function multiply (line 17) | def multiply(
FILE: algorithms/matrix/rotate_image.py
function rotate (line 17) | def rotate(mat: list[list[int]]) -> list[list[int]]:
FILE: algorithms/matrix/search_in_sorted_matrix.py
function search_in_a_sorted_matrix (line 18) | def search_in_a_sorted_matrix(
FILE: algorithms/matrix/sort_matrix_diagonally.py
function sort_diagonally (line 20) | def sort_diagonally(mat: list[list[int]]) -> list[list[int]]:
FILE: algorithms/matrix/sparse_dot_vector.py
function vector_to_index_value_list (line 17) | def vector_to_index_value_list(
function dot_product (line 35) | def dot_product(
FILE: algorithms/matrix/sparse_mul.py
function sparse_multiply (line 18) | def sparse_multiply(
FILE: algorithms/matrix/spiral_traversal.py
function spiral_traversal (line 17) | def spiral_traversal(matrix: list[list[int]]) -> list[int]:
FILE: algorithms/matrix/sudoku_validator.py
function valid_solution_hashtable (line 20) | def valid_solution_hashtable(board: list[list[int]]) -> bool:
function valid_solution (line 66) | def valid_solution(board: list[list[int]]) -> bool:
function valid_solution_set (line 105) | def valid_solution_set(board: list[list[int]]) -> bool:
FILE: algorithms/matrix/sum_sub_squares.py
function sum_sub_squares (line 17) | def sum_sub_squares(matrix: list[list[int]], k: int) -> list[list[int]] ...
FILE: algorithms/queue/max_sliding_window.py
function max_sliding_window (line 20) | def max_sliding_window(arr: list[int], k: int) -> list[int]:
FILE: algorithms/queue/moving_average.py
class MovingAverage (line 19) | class MovingAverage:
method __init__ (line 30) | def __init__(self, size: int) -> None:
method next (line 38) | def next(self, val: int) -> float:
FILE: algorithms/queue/reconstruct_queue.py
function reconstruct_queue (line 18) | def reconstruct_queue(people: list[list[int]]) -> list[list[int]]:
FILE: algorithms/queue/zigzagiterator.py
class ZigZagIterator (line 19) | class ZigZagIterator:
method __init__ (line 30) | def __init__(self, v1: list[int], v2: list[int]) -> None:
method next (line 39) | def next(self) -> int:
method has_next (line 51) | def has_next(self) -> bool:
FILE: algorithms/searching/binary_search.py
function binary_search (line 17) | def binary_search(array: list[int], query: int) -> int:
function binary_search_recur (line 46) | def binary_search_recur(array: list[int], low: int, high: int, val: int)...
FILE: algorithms/searching/exponential_search.py
function exponential_search (line 15) | def exponential_search(arr: list[int], target: int) -> int:
FILE: algorithms/searching/find_min_rotate.py
function find_min_rotate (line 17) | def find_min_rotate(array: list[int]) -> int:
function find_min_rotate_recur (line 43) | def find_min_rotate_recur(array: list[int], low: int, high: int) -> int:
FILE: algorithms/searching/first_occurrence.py
function first_occurrence (line 17) | def first_occurrence(array: list[int], query: int) -> int:
FILE: algorithms/searching/generalized_binary_search.py
function binary_search_first_true (line 21) | def binary_search_first_true(
FILE: algorithms/searching/interpolation_search.py
function interpolation_search (line 17) | def interpolation_search(array: list[int], search_key: int) -> int:
FILE: algorithms/searching/jump_search.py
function jump_search (line 19) | def jump_search(array: list[int], target: int) -> int:
FILE: algorithms/searching/last_occurrence.py
function last_occurrence (line 17) | def last_occurrence(array: list[int], query: int) -> int:
FILE: algorithms/searching/linear_search.py
function linear_search (line 17) | def linear_search(array: list[int], query: int) -> int:
FILE: algorithms/searching/next_greatest_letter.py
function next_greatest_letter (line 22) | def next_greatest_letter(letters: list[str], target: str) -> str:
function next_greatest_letter_v1 (line 43) | def next_greatest_letter_v1(letters: list[str], target: str) -> str:
function next_greatest_letter_v2 (line 72) | def next_greatest_letter_v2(letters: list[str], target: str) -> str:
FILE: algorithms/searching/search_insert.py
function search_insert (line 18) | def search_insert(array: list[int], val: int) -> int:
FILE: algorithms/searching/search_range.py
function search_range (line 18) | def search_range(nums: list[int], target: int) -> list[int]:
FILE: algorithms/searching/search_rotate.py
function search_rotate (line 18) | def search_rotate(array: list[int], val: int) -> int:
function search_rotate_recur (line 55) | def search_rotate_recur(
FILE: algorithms/searching/sentinel_search.py
function sentinel_search (line 14) | def sentinel_search(arr: list[int], target: int) -> int:
FILE: algorithms/searching/ternary_search.py
function ternary_search (line 18) | def ternary_search(left: int, right: int, key: int, array: list[int]) ->...
FILE: algorithms/searching/two_sum.py
function two_sum (line 19) | def two_sum(numbers: list[int], target: int) -> list[int] | None:
function two_sum1 (line 51) | def two_sum1(numbers: list[int], target: int) -> list[int] | None:
function two_sum2 (line 75) | def two_sum2(numbers: list[int], target: int) -> list[int] | None:
FILE: algorithms/set/find_keyboard_row.py
function find_keyboard_row (line 23) | def find_keyboard_row(words: list[str]) -> list[str]:
FILE: algorithms/set/randomized_set.py
class RandomizedSet (line 19) | class RandomizedSet:
method __init__ (line 22) | def __init__(self) -> None:
method insert (line 26) | def insert(self, new_one: int) -> None:
method remove (line 37) | def remove(self, old_one: int) -> None:
method random_element (line 53) | def random_element(self) -> int:
FILE: algorithms/set/set_covering.py
function _powerset (line 23) | def _powerset(iterable: list[str]) -> chain[tuple[str, ...]]:
function optimal_set_cover (line 36) | def optimal_set_cover(
function greedy_set_cover (line 76) | def greedy_set_cover(
FILE: algorithms/sorting/bead_sort.py
function bead_sort (line 17) | def bead_sort(array: list[int]) -> list[int]:
FILE: algorithms/sorting/bitonic_sort.py
function bitonic_sort (line 18) | def bitonic_sort(array: list[int], reverse: bool = False) -> list[int]:
function _compare (line 46) | def _compare(array: list[int], reverse: bool) -> list[int]:
function _bitonic_merge (line 55) | def _bitonic_merge(array: list[int], reverse: bool) -> list[int]:
FILE: algorithms/sorting/bogo_sort.py
function bogo_sort (line 19) | def bogo_sort(array: list[int]) -> list[int]:
function _is_sorted (line 37) | def _is_sorted(array: list[int]) -> bool:
FILE: algorithms/sorting/bubble_sort.py
function bubble_sort (line 17) | def bubble_sort(array: list[int]) -> list[int]:
FILE: algorithms/sorting/bucket_sort.py
function bucket_sort (line 18) | def bucket_sort(array: list[int]) -> list[int]:
function _insertion_sort (line 45) | def _insertion_sort(array: list[int]) -> list[int]:
FILE: algorithms/sorting/cocktail_shaker_sort.py
function cocktail_shaker_sort (line 17) | def cocktail_shaker_sort(array: list[int]) -> list[int]:
FILE: algorithms/sorting/comb_sort.py
function comb_sort (line 18) | def comb_sort(array: list[int]) -> list[int]:
FILE: algorithms/sorting/counting_sort.py
function counting_sort (line 18) | def counting_sort(array: list[int]) -> list[int]:
FILE: algorithms/sorting/cycle_sort.py
function cycle_sort (line 18) | def cycle_sort(array: list[int]) -> list[int]:
FILE: algorithms/sorting/exchange_sort.py
function exchange_sort (line 17) | def exchange_sort(array: list[int]) -> list[int]:
FILE: algorithms/sorting/gnome_sort.py
function gnome_sort (line 18) | def gnome_sort(array: list[int]) -> list[int]:
FILE: algorithms/sorting/heap_sort.py
function max_heap_sort (line 18) | def max_heap_sort(array: list[int]) -> list[int]:
function _max_heapify (line 36) | def _max_heapify(array: list[int], end: int) -> None:
function min_heap_sort (line 55) | def min_heap_sort(array: list[int]) -> list[int]:
function _min_heapify (line 73) | def _min_heapify(array: list[int], start: int) -> None:
FILE: algorithms/sorting/insertion_sort.py
function insertion_sort (line 17) | def insertion_sort(array: list[int]) -> list[int]:
FILE: algorithms/sorting/meeting_rooms.py
function can_attend_meetings (line 18) | def can_attend_meetings(intervals: list) -> bool:
FILE: algorithms/sorting/merge_sort.py
function merge_sort (line 17) | def merge_sort(array: list[int]) -> list[int]:
function _merge (line 41) | def _merge(left: list[int], right: list[int], merged: list[int]) -> None:
FILE: algorithms/sorting/pancake_sort.py
function pancake_sort (line 18) | def pancake_sort(array: list[int]) -> list[int]:
FILE: algorithms/sorting/pigeonhole_sort.py
function pigeonhole_sort (line 17) | def pigeonhole_sort(array: list[int]) -> list[int]:
FILE: algorithms/sorting/quick_sort.py
function quick_sort (line 17) | def quick_sort(array: list[int]) -> list[int]:
function _quick_sort_recursive (line 34) | def _quick_sort_recursive(array: list[int], first: int, last: int) -> None:
function _partition (line 42) | def _partition(array: list[int], first: int, last: int) -> int:
FILE: algorithms/sorting/radix_sort.py
function radix_sort (line 18) | def radix_sort(array: list[int]) -> list[int]:
FILE: algorithms/sorting/selection_sort.py
function selection_sort (line 17) | def selection_sort(array: list[int]) -> list[int]:
FILE: algorithms/sorting/shell_sort.py
function shell_sort (line 19) | def shell_sort(array: list[int]) -> list[int]:
FILE: algorithms/sorting/sort_colors.py
function sort_colors (line 18) | def sort_colors(array: list[int]) -> list[int]:
FILE: algorithms/sorting/stooge_sort.py
function stooge_sort (line 18) | def stooge_sort(array: list[int]) -> list[int]:
function _stooge_sort (line 35) | def _stooge_sort(array: list[int], low: int, high: int) -> None:
FILE: algorithms/sorting/wiggle_sort.py
function wiggle_sort (line 17) | def wiggle_sort(array: list[int]) -> list[int]:
FILE: algorithms/stack/is_consecutive.py
function first_is_consecutive (line 20) | def first_is_consecutive(stack: list[int]) -> bool:
function second_is_consecutive (line 51) | def second_is_consecutive(stack: list[int]) -> bool:
FILE: algorithms/stack/is_sorted.py
function is_sorted (line 17) | def is_sorted(stack: list[int]) -> bool:
FILE: algorithms/stack/longest_abs_path.py
function length_longest_path (line 18) | def length_longest_path(input_str: str) -> int:
FILE: algorithms/stack/ordered_stack.py
class OrderedStack (line 18) | class OrderedStack:
method __init__ (line 30) | def __init__(self) -> None:
method is_empty (line 34) | def is_empty(self) -> bool:
method _push_direct (line 42) | def _push_direct(self, item: int) -> None:
method push (line 50) | def push(self, item: int) -> None:
method pop (line 66) | def pop(self) -> int:
method peek (line 79) | def peek(self) -> int:
method size (line 87) | def size(self) -> int:
FILE: algorithms/stack/remove_min.py
function remove_min (line 17) | def remove_min(stack: list[int]) -> list[int]:
FILE: algorithms/stack/simplify_path.py
function simplify_path (line 17) | def simplify_path(path: str) -> str:
FILE: algorithms/stack/stutter.py
function first_stutter (line 19) | def first_stutter(stack: list[int]) -> list[int]:
function second_stutter (line 43) | def second_stutter(stack: list[int]) -> list[int]:
FILE: algorithms/stack/switch_pairs.py
function first_switch_pairs (line 20) | def first_switch_pairs(stack: list[int]) -> list[int]:
function second_switch_pairs (line 49) | def second_switch_pairs(stack: list[int]) -> list[int]:
FILE: algorithms/stack/valid_parenthesis.py
function is_valid (line 17) | def is_valid(s: str) -> bool:
FILE: algorithms/streaming/misra_gries.py
function misras_gries (line 18) | def misras_gries(array: list[int], k: int = 2) -> dict[str, int] | None:
function _count_frequency (line 60) | def _count_frequency(array: list[int], element: int) -> int:
FILE: algorithms/streaming/one_sparse_recovery.py
function one_sparse (line 18) | def one_sparse(array: list[tuple[int, str]]) -> int | None:
function _check_bit_sum_consistency (line 51) | def _check_bit_sum_consistency(bitsum: list[int], sum_signs: int) -> bool:
function _update_bit_sum (line 64) | def _update_bit_sum(bitsum: list[int], val: int, sign: str) -> None:
FILE: algorithms/string/add_binary.py
function add_binary (line 16) | def add_binary(first: str, second: str) -> str:
FILE: algorithms/string/alphabet_board_path.py
function alphabet_board_path (line 20) | def alphabet_board_path(target: str) -> str:
FILE: algorithms/string/atbash_cipher.py
function atbash (line 17) | def atbash(text: str) -> str:
FILE: algorithms/string/breaking_bad.py
function match_symbol (line 21) | def match_symbol(words: list[str], symbols: list[str]) -> list[str]:
function match_symbol_1 (line 44) | def match_symbol_1(words: list[str], symbols: list[str]) -> list[str]:
class _TrieNode (line 72) | class _TrieNode:
method __init__ (line 75) | def __init__(self) -> None:
function bracket (line 80) | def bracket(words: list[str], symbols: list[str]) -> tuple[str, ...]:
FILE: algorithms/string/caesar_cipher.py
function caesar_cipher (line 17) | def caesar_cipher(text: str, shift: int) -> str:
FILE: algorithms/string/check_pangram.py
function check_pangram (line 17) | def check_pangram(input_string: str) -> bool:
FILE: algorithms/string/contain_string.py
function contain_string (line 17) | def contain_string(haystack: str, needle: str) -> int:
FILE: algorithms/string/count_binary_substring.py
function count_binary_substring (line 17) | def count_binary_substring(text: str) -> int:
FILE: algorithms/string/decode_string.py
function decode_string (line 18) | def decode_string(text: str) -> str:
FILE: algorithms/string/delete_reoccurring.py
function delete_reoccurring_characters (line 17) | def delete_reoccurring_characters(string: str) -> str:
FILE: algorithms/string/domain_extractor.py
function domain_name_1 (line 17) | def domain_name_1(url: str) -> str:
function domain_name_2 (line 37) | def domain_name_2(url: str) -> str:
FILE: algorithms/string/encode_decode.py
function encode (line 17) | def encode(strs: str) -> str:
function decode (line 36) | def decode(text: str) -> list[str]:
FILE: algorithms/string/first_unique_char.py
function first_unique_char (line 17) | def first_unique_char(text: str) -> int:
FILE: algorithms/string/fizzbuzz.py
function fizzbuzz (line 17) | def fizzbuzz(number: int) -> list[int | str]:
function fizzbuzz_with_helper_func (line 53) | def fizzbuzz_with_helper_func(number: int) -> list[int | str]:
function _fb (line 69) | def _fb(value: int) -> int | str:
FILE: algorithms/string/group_anagrams.py
function group_anagrams (line 17) | def group_anagrams(strings: list[str]) -> list[list[str]]:
FILE: algorithms/string/int_to_roman.py
function int_to_roman (line 17) | def int_to_roman(num: int) -> str:
FILE: algorithms/string/is_palindrome.py
function is_palindrome (line 20) | def is_palindrome(text: str) -> bool:
function _remove_punctuation (line 46) | def _remove_punctuation(text: str) -> str:
function _string_reverse (line 58) | def _string_reverse(text: str) -> str:
function is_palindrome_reverse (line 70) | def is_palindrome_reverse(text: str) -> bool:
function is_palindrome_two_pointer (line 87) | def is_palindrome_two_pointer(text: str) -> bool:
function is_palindrome_stack (line 107) | def is_palindrome_stack(text: str) -> bool:
function is_palindrome_deque (line 127) | def is_palindrome_deque(text: str) -> bool:
FILE: algorithms/string/is_rotated.py
function is_rotated (line 17) | def is_rotated(first: str, second: str) -> bool:
function is_rotated_v1 (line 37) | def is_rotated_v1(first: str, second: str) -> bool:
FILE: algorithms/string/judge_circle.py
function judge_circle (line 17) | def judge_circle(moves: str) -> bool:
FILE: algorithms/string/knuth_morris_pratt.py
function knuth_morris_pratt (line 19) | def knuth_morris_pratt(text: Sequence, pattern: Sequence) -> list[int]:
FILE: algorithms/string/license_number.py
function license_number (line 17) | def license_number(key: str, group_size: int) -> str:
FILE: algorithms/string/longest_common_prefix.py
function _common_prefix (line 17) | def _common_prefix(first: str, second: str) -> str:
function longest_common_prefix_v1 (line 37) | def longest_common_prefix_v1(strings: list[str]) -> str:
function longest_common_prefix_v2 (line 58) | def longest_common_prefix_v2(strings: list[str]) -> str:
function longest_common_prefix_v3 (line 80) | def longest_common_prefix_v3(strings: list[str]) -> str:
function _longest_common_recursive (line 98) | def _longest_common_recursive(strings: list[str], left: int, right: int)...
FILE: algorithms/string/longest_palindromic_substring.py
function longest_palindrome (line 17) | def longest_palindrome(text: str) -> str:
FILE: algorithms/string/make_sentence.py
function make_sentence (line 19) | def make_sentence(text_piece: str, dictionaries: list[str]) -> bool:
FILE: algorithms/string/manacher.py
function manacher (line 11) | def manacher(s: str) -> str:
FILE: algorithms/string/merge_string_checker.py
function is_merge_recursive (line 17) | def is_merge_recursive(text: str, part1: str, part2: str) -> bool:
function is_merge_iterative (line 44) | def is_merge_iterative(text: str, part1: str, part2: str) -> bool:
FILE: algorithms/string/min_distance.py
function min_distance (line 17) | def min_distance(word1: str, word2: str) -> int:
function _lcs (line 34) | def _lcs(word1: str, word2: str, length1: int, length2: int) -> int:
function min_distance_dp (line 56) | def min_distance_dp(word1: str, word2: str) -> int:
FILE: algorithms/string/multiply_strings.py
function multiply (line 17) | def multiply(num1: str, num2: str) -> str:
FILE: algorithms/string/one_edit_distance.py
function is_one_edit (line 17) | def is_one_edit(source: str, target: str) -> bool:
function is_one_edit2 (line 44) | def is_one_edit2(source: str, target: str) -> bool:
FILE: algorithms/string/panagram.py
function panagram (line 19) | def panagram(string: str) -> bool:
FILE: algorithms/string/rabin_karp.py
class RollingHash (line 17) | class RollingHash:
method __init__ (line 25) | def __init__(self, text: str, window_size: int) -> None:
method move_window (line 38) | def move_window(self) -> None:
method window_text (line 49) | def window_text(self) -> str:
function rabin_karp (line 58) | def rabin_karp(word: str, text: str) -> int | None:
FILE: algorithms/string/repeat_string.py
function repeat_string (line 17) | def repeat_string(base: str, target: str) -> int:
FILE: algorithms/string/repeat_substring.py
function repeat_substring (line 17) | def repeat_substring(text: str) -> bool:
FILE: algorithms/string/reverse_string.py
function recursive (line 17) | def recursive(text: str) -> str:
function iterative (line 36) | def iterative(text: str) -> str:
function pythonic (line 61) | def pythonic(text: str) -> str:
function ultra_pythonic (line 78) | def ultra_pythonic(text: str) -> str:
FILE: algorithms/string/reverse_vowel.py
function reverse_vowel (line 17) | def reverse_vowel(text: str) -> str:
FILE: algorithms/string/reverse_words.py
function _reverse_list (line 17) | def _reverse_list(array: list[str], left: int, right: int) -> None:
function reverse_words (line 31) | def reverse_words(string: str) -> str:
FILE: algorithms/string/roman_to_int.py
function roman_to_int (line 17) | def roman_to_int(text: str) -> int:
FILE: algorithms/string/rotate.py
function rotate (line 17) | def rotate(text: str, positions: int) -> str:
function rotate_alt (line 38) | def rotate_alt(string: str, positions: int) -> str:
FILE: algorithms/string/strip_url_params.py
function strip_url_params1 (line 21) | def strip_url_params1(url: str, params_to_strip: list[str] | None = None...
function strip_url_params2 (line 94) | def strip_url_params2(url: str, param_to_strip: list[str] | None = None)...
function strip_url_params3 (line 125) | def strip_url_params3(url: str, strip: list[str] | None = None) -> str:
FILE: algorithms/string/strong_password.py
function strong_password (line 18) | def strong_password(length: int, password: str) -> int:
FILE: algorithms/string/swap_characters.py
function can_swap_to_equal (line 12) | def can_swap_to_equal(s: str, t: str) -> bool:
FILE: algorithms/string/text_justification.py
function text_justification (line 18) | def text_justification(words: list[str], max_width: int) -> list[str]:
FILE: algorithms/string/unique_morse.py
function convert_morse_word (line 46) | def convert_morse_word(word: str) -> str:
function unique_morse (line 66) | def unique_morse(words: list[str]) -> int:
FILE: algorithms/string/validate_coordinates.py
function is_valid_coordinates_0 (line 19) | def is_valid_coordinates_0(coordinates: str) -> bool:
function is_valid_coordinates_1 (line 46) | def is_valid_coordinates_1(coordinates: str) -> bool:
function is_valid_coordinates_regular_expression (line 68) | def is_valid_coordinates_regular_expression(coordinates: str) -> bool:
FILE: algorithms/string/word_squares.py
function word_squares (line 19) | def word_squares(words: list[str]) -> list[list[str]]:
FILE: algorithms/string/z_algorithm.py
function compute_z_array (line 14) | def compute_z_array(s: str) -> list[int]:
function z_search (line 32) | def z_search(text: str, pattern: str) -> list[int]:
FILE: algorithms/tree/bin_tree_to_list.py
function bin_tree_to_list (line 19) | def bin_tree_to_list(root: TreeNode | None) -> TreeNode | None:
function _bin_tree_to_list_util (line 41) | def _bin_tree_to_list_util(root: TreeNode | None) -> TreeNode | None:
FILE: algorithms/tree/binary_tree_paths.py
function binary_tree_paths (line 19) | def binary_tree_paths(root: TreeNode | None) -> list[str]:
function _dfs (line 39) | def _dfs(result: list[str], root: TreeNode, current: str) -> None:
FILE: algorithms/tree/binary_tree_views.py
function left_view (line 27) | def left_view(root: TreeNode | None) -> list[int]:
function right_view (line 59) | def right_view(root: TreeNode | None) -> list[int]:
function top_view (line 91) | def top_view(root: TreeNode | None) -> list[int]:
function bottom_view (line 125) | def bottom_view(root: TreeNode | None) -> list[int]:
FILE: algorithms/tree/bst_array_to_bst.py
function array_to_bst (line 9) | def array_to_bst(nums):
FILE: algorithms/tree/bst_closest_value.py
function closest_value (line 18) | def closest_value(root, target):
FILE: algorithms/tree/bst_count_left_node.py
function count_left_node (line 23) | def count_left_node(root):
class TestSuite (line 48) | class TestSuite(unittest.TestCase):
method setUp (line 49) | def setUp(self):
method test_count_left_node (line 61) | def test_count_left_node(self):
FILE: algorithms/tree/bst_delete_node.py
class Solution (line 43) | class Solution:
method delete_node (line 44) | def delete_node(self, root, key):
FILE: algorithms/tree/bst_depth_sum.py
function depth_sum (line 24) | def depth_sum(root, n):
function recur_depth_sum (line 29) | def recur_depth_sum(root, n):
class TestSuite (line 58) | class TestSuite(unittest.TestCase):
method setUp (line 59) | def setUp(self):
method test_depth_sum (line 71) | def test_depth_sum(self):
FILE: algorithms/tree/bst_height.py
function height (line 24) | def height(root):
class TestSuite (line 47) | class TestSuite(unittest.TestCase):
method setUp (line 48) | def setUp(self):
method test_height (line 60) | def test_height(self):
FILE: algorithms/tree/bst_is_bst.py
function is_bst (line 24) | def is_bst(root):
FILE: algorithms/tree/bst_iterator.py
class BSTIterator (line 1) | class BSTIterator:
method __init__ (line 2) | def __init__(self, root):
method has_next (line 8) | def has_next(self):
method next (line 11) | def next(self):
FILE: algorithms/tree/bst_kth_smallest.py
class Node (line 1) | class Node:
method __init__ (line 2) | def __init__(self, val, left=None, right=None):
function kth_smallest (line 8) | def kth_smallest(root, k):
class Solution (line 22) | class Solution:
method kth_smallest (line 23) | def kth_smallest(self, root, k):
method helper (line 33) | def helper(self, node, count):
FILE: algorithms/tree/bst_lowest_common_ancestor.py
function lowest_common_ancestor (line 24) | def lowest_common_ancestor(root, p, q):
FILE: algorithms/tree/bst_num_empty.py
function num_empty (line 27) | def num_empty(root):
class TestSuite (line 54) | class TestSuite(unittest.TestCase):
method setUp (line 55) | def setUp(self):
method test_num_empty (line 67) | def test_num_empty(self):
FILE: algorithms/tree/bst_predecessor.py
function predecessor (line 1) | def predecessor(root, node):
FILE: algorithms/tree/bst_serialize_deserialize.py
function serialize (line 4) | def serialize(root):
function deserialize (line 18) | def deserialize(data):
FILE: algorithms/tree/bst_successor.py
function successor (line 1) | def successor(root, node):
FILE: algorithms/tree/bst_unique_bst.py
function num_trees (line 30) | def num_trees(n):
FILE: algorithms/tree/bst_validate_bst.py
function validate_bst (line 19) | def validate_bst(node):
FILE: algorithms/tree/construct_tree_postorder_preorder.py
function construct_tree_util (line 22) | def construct_tree_util(
function construct_tree (line 71) | def construct_tree(pre: list[int], post: list[int], size: int) -> list[i...
function _inorder (line 91) | def _inorder(root: TreeNode | None, result: list[int] | None = None) -> ...
FILE: algorithms/tree/deepest_left.py
class DeepestLeft (line 19) | class DeepestLeft:
method __init__ (line 28) | def __init__(self) -> None:
function find_deepest_left (line 33) | def find_deepest_left(
FILE: algorithms/tree/invert_tree.py
function reverse (line 18) | def reverse(root: TreeNode | None) -> None:
FILE: algorithms/tree/is_balanced.py
function is_balanced (line 19) | def is_balanced(root: TreeNode | None) -> bool:
function _get_depth (line 35) | def _get_depth(root: TreeNode | None) -> int:
FILE: algorithms/tree/is_subtree.py
function is_subtree (line 21) | def is_subtree(big: TreeNode, small: TreeNode) -> bool:
function _comp (line 50) | def _comp(p: TreeNode | None, q: TreeNode | None) -> bool:
FILE: algorithms/tree/is_symmetric.py
function is_symmetric (line 19) | def is_symmetric(root: TreeNode | None) -> bool:
function _helper (line 37) | def _helper(p: TreeNode | None, q: TreeNode | None) -> bool:
function is_symmetric_iterative (line 54) | def is_symmetric_iterative(root: TreeNode | None) -> bool:
FILE: algorithms/tree/longest_consecutive.py
function longest_consecutive (line 19) | def longest_consecutive(root: TreeNode | None) -> int:
function _dfs (line 39) | def _dfs(root: TreeNode | None, current: int, target: int, max_len: int)...
FILE: algorithms/tree/lowest_common_ancestor.py
function lca (line 20) | def lca(root: TreeNode | None, p: TreeNode, q: TreeNode) -> TreeNode | N...
FILE: algorithms/tree/max_height.py
function max_height (line 21) | def max_height(root: TreeNode | None) -> int:
FILE: algorithms/tree/max_path_sum.py
function max_path_sum (line 20) | def max_path_sum(root: TreeNode | None) -> float:
function _helper (line 38) | def _helper(root: TreeNode | None, maximum: float) -> float:
FILE: algorithms/tree/min_height.py
function min_depth (line 19) | def min_depth(self: object, root: TreeNode | None) -> int:
function min_height (line 36) | def min_height(root: TreeNode | None) -> int:
FILE: algorithms/tree/path_sum.py
function has_path_sum (line 22) | def has_path_sum(root: TreeNode | None, sum: int) -> bool:
function has_path_sum2 (line 44) | def has_path_sum2(root: TreeNode | None, sum: int) -> bool:
function has_path_sum3 (line 72) | def has_path_sum3(root: TreeNode | None, sum: int) -> bool:
FILE: algorithms/tree/path_sum2.py
function path_sum (line 21) | def path_sum(root: TreeNode | None, sum: int) -> list[list[int]]:
function _dfs (line 42) | def _dfs(root: TreeNode, sum: int, path: list[int], result: list[list[in...
function path_sum2 (line 60) | def path_sum2(root: TreeNode | None, target: int) -> list[list[int]]:
function path_sum3 (line 89) | def path_sum3(root: TreeNode | None, sum: int) -> list[list[int]]:
FILE: algorithms/tree/pretty_print.py
function tree_print (line 17) | def tree_print(tree: dict) -> list[str]:
FILE: algorithms/tree/same_tree.py
function is_same_tree (line 19) | def is_same_tree(tree_p: TreeNode | None, tree_q: TreeNode | None) -> bool:
FILE: algorithms/tree/traversal_inorder.py
class Node (line 6) | class Node:
method __init__ (line 7) | def __init__(self, val, left=None, right=None):
function inorder (line 13) | def inorder(root):
function inorder_rec (line 29) | def inorder_rec(root, res=None):
FILE: algorithms/tree/traversal_level_order.py
function level_order (line 21) | def level_order(root):
FILE: algorithms/tree/traversal_postorder.py
class Node (line 6) | class Node:
method __init__ (line 7) | def __init__(self, val, left=None, right=None):
function postorder (line 13) | def postorder(root):
function postorder_rec (line 33) | def postorder_rec(root, res=None):
FILE: algorithms/tree/traversal_preorder.py
class Node (line 6) | class Node:
method __init__ (line 9) | def __init__(self, val, left=None, right=None):
function preorder (line 15) | def preorder(root):
function preorder_rec (line 32) | def preorder_rec(root, res=None):
FILE: algorithms/tree/traversal_zigzag.py
function zigzag_level (line 23) | def zigzag_level(root):
FILE: algorithms/tree/trie_add_and_search.py
class TrieNode (line 20) | class TrieNode:
method __init__ (line 21) | def __init__(self, letter, is_terminal=False):
class WordDictionary (line 27) | class WordDictionary:
method __init__ (line 28) | def __init__(self):
method add_word (line 31) | def add_word(self, word):
method search (line 39) | def search(self, word, node=None):
class WordDictionary2 (line 62) | class WordDictionary2:
method __init__ (line 63) | def __init__(self):
method add_word (line 66) | def add_word(self, word):
method search (line 70) | def search(self, word):
FILE: tests/test_array.py
class TestJosephus (line 36) | class TestJosephus(unittest.TestCase):
method test_josephus (line 37) | def test_josephus(self):
class TestDeleteNth (line 53) | class TestDeleteNth(unittest.TestCase):
method test_delete_nth_naive (line 54) | def test_delete_nth_naive(self):
method test_delete_nth (line 71) | def test_delete_nth(self):
class TestFlatten (line 89) | class TestFlatten(unittest.TestCase):
method test_flatten (line 90) | def test_flatten(self):
method test_flatten_iter (line 104) | def test_flatten_iter(self):
class TestGarage (line 134) | class TestGarage(unittest.TestCase):
method test_garage (line 135) | def test_garage(self):
class TestLongestNonRepeat (line 147) | class TestLongestNonRepeat(unittest.TestCase):
method test_longest_non_repeat_v1 (line 148) | def test_longest_non_repeat_v1(self):
method test_longest_non_repeat_v2 (line 165) | def test_longest_non_repeat_v2(self):
method test_get_longest_non_repeat_v1 (line 182) | def test_get_longest_non_repeat_v1(self):
method test_get_longest_non_repeat_v2 (line 198) | def test_get_longest_non_repeat_v2(self):
class TestMaxOnesIndex (line 215) | class TestMaxOnesIndex(unittest.TestCase):
method test_max_ones_index (line 216) | def test_max_ones_index(self):
class TestMergeInterval (line 223) | class TestMergeInterval(unittest.TestCase):
method test_merge (line 224) | def test_merge(self):
method test_merge_intervals (line 232) | def test_merge_intervals(self):
class TestMissingRanges (line 238) | class TestMissingRanges(unittest.TestCase):
method test_missing_ranges (line 239) | def test_missing_ranges(self):
class TestMoveZeros (line 253) | class TestMoveZeros(unittest.TestCase):
method test_move_zeros (line 254) | def test_move_zeros(self):
class TestPlusOne (line 267) | class TestPlusOne(unittest.TestCase):
method test_plus_one_v1 (line 268) | def test_plus_one_v1(self):
method test_plus_one_v2 (line 276) | def test_plus_one_v2(self):
method test_plus_one_v3 (line 284) | def test_plus_one_v3(self):
class TestRemoveDuplicate (line 293) | class TestRemoveDuplicate(unittest.TestCase):
method test_remove_duplicates (line 294) | def test_remove_duplicates(self):
class TestRotateArray (line 318) | class TestRotateArray(unittest.TestCase):
method test_rotate_v1 (line 319) | def test_rotate_v1(self):
method test_rotate_v2 (line 332) | def test_rotate_v2(self):
method test_rotate_v3 (line 345) | def test_rotate_v3(self):
class TestSummaryRanges (line 359) | class TestSummaryRanges(unittest.TestCase):
method test_summarize_ranges (line 360) | def test_summarize_ranges(self):
class TestThreeSum (line 371) | class TestThreeSum(unittest.TestCase):
method test_three_sum (line 372) | def test_three_sum(self):
class TestTwoSum (line 381) | class TestTwoSum(unittest.TestCase):
method test_two_sum (line 382) | def test_two_sum(self):
class TestTrimmean (line 390) | class TestTrimmean(unittest.TestCase):
method test_trimmean (line 391) | def test_trimmean(self):
class TestTop1 (line 397) | class TestTop1(unittest.TestCase):
method test_top_1 (line 398) | def test_top_1(self):
class TestLimit (line 403) | class TestLimit(unittest.TestCase):
method test_limit (line 404) | def test_limit(self):
class TestNSum (line 411) | class TestNSum(unittest.TestCase):
method test_n_sum (line 412) | def test_n_sum(self):
FILE: tests/test_backtracking.py
class TestAddOperator (line 28) | class TestAddOperator(unittest.TestCase):
method test_add_operators (line 29) | def test_add_operators(self):
class TestPermuteAndAnagram (line 58) | class TestPermuteAndAnagram(unittest.TestCase):
method test_permute (line 59) | def test_permute(self):
method test_permute_iter (line 63) | def test_permute_iter(self):
method test_angram (line 69) | def test_angram(self):
class TestArrayCombinationSum (line 74) | class TestArrayCombinationSum(unittest.TestCase):
method test_array_sum_combinations (line 75) | def test_array_sum_combinations(self):
method test_unique_array_sum_combinations (line 97) | def test_unique_array_sum_combinations(self):
class TestCombinationSum (line 109) | class TestCombinationSum(unittest.TestCase):
method check_sum (line 110) | def check_sum(self, nums, target):
method test_combination_sum (line 116) | def test_combination_sum(self):
class TestFactorCombinations (line 128) | class TestFactorCombinations(unittest.TestCase):
method test_get_factors (line 129) | def test_get_factors(self):
method test_recursive_get_factors (line 140) | def test_recursive_get_factors(self):
class TestFindWords (line 152) | class TestFindWords(unittest.TestCase):
method test_normal (line 153) | def test_normal(self):
method test_none (line 166) | def test_none(self):
method test_empty (line 177) | def test_empty(self):
method test_uneven (line 182) | def test_uneven(self):
method test_repeat (line 187) | def test_repeat(self):
class TestGenerateAbbreviations (line 193) | class TestGenerateAbbreviations(unittest.TestCase):
method test_generate_abbreviations (line 194) | def test_generate_abbreviations(self):
class TestPatternMatch (line 254) | class TestPatternMatch(unittest.TestCase):
method test_pattern_match (line 255) | def test_pattern_match(self):
class TestGenerateParenthesis (line 268) | class TestGenerateParenthesis(unittest.TestCase):
method test_generate_parenthesis (line 269) | def test_generate_parenthesis(self):
class TestLetterCombinations (line 282) | class TestLetterCombinations(unittest.TestCase):
method test_letter_combinations (line 283) | def test_letter_combinations(self):
class TestPalindromicSubstrings (line 293) | class TestPalindromicSubstrings(unittest.TestCase):
method test_palindromic_substrings (line 294) | def test_palindromic_substrings(self):
class TestPermuteUnique (line 315) | class TestPermuteUnique(unittest.TestCase):
method test_permute_unique (line 316) | def test_permute_unique(self):
class TestPermute (line 343) | class TestPermute(unittest.TestCase):
method test_permute (line 344) | def test_permute(self):
method test_permute_recursive (line 378) | def test_permute_recursive(self):
class TestSubsetsUnique (line 413) | class TestSubsetsUnique(unittest.TestCase):
method test_subsets_unique (line 414) | def test_subsets_unique(self):
class TestSubsets (line 441) | class TestSubsets(unittest.TestCase):
method test_subsets (line 442) | def test_subsets(self):
method test_subsets_v2 (line 468) | def test_subsets_v2(self):
FILE: tests/test_bit_manipulation.py
class TestSuite (line 37) | class TestSuite(unittest.TestCase):
method setUp (line 38) | def setUp(self):
method test_add_bitwise_operator (line 42) | def test_add_bitwise_operator(self):
method test_count_ones_recur (line 48) | def test_count_ones_recur(self):
method test_count_ones_iter (line 62) | def test_count_ones_iter(self):
method test_count_flips_to_convert (line 76) | def test_count_flips_to_convert(self):
method test_find_missing_number (line 86) | def test_find_missing_number(self):
method test_find_missing_number2 (line 96) | def test_find_missing_number2(self):
method test_flip_bit_longest_seq (line 106) | def test_flip_bit_longest_seq(self):
method test_is_power_of_two (line 116) | def test_is_power_of_two(self):
method test_reverse_bits (line 124) | def test_reverse_bits(self):
method test_single_number (line 136) | def test_single_number(self):
method test_single_number2 (line 151) | def test_single_number2(self):
method test_single_number3 (line 161) | def test_single_number3(self):
method test_subsets (line 165) | def test_subsets(self):
method test_get_bit (line 194) | def test_get_bit(self):
method test_set_bit (line 199) | def test_set_bit(self):
method test_clear_bit (line 203) | def test_clear_bit(self):
method test_update_bit (line 207) | def test_update_bit(self):
method test_int_to_bytes_big_endian (line 215) | def test_int_to_bytes_big_endian(self):
method test_int_to_bytes_little_endian (line 218) | def test_int_to_bytes_little_endian(self):
method test_bytes_big_endian_to_int (line 221) | def test_bytes_big_endian_to_int(self):
method test_bytes_little_endian_to_int (line 224) | def test_bytes_little_endian_to_int(self):
method test_swap_pair (line 227) | def test_swap_pair(self):
method test_find_difference (line 233) | def test_find_difference(self):
method test_has_alternative_bit (line 236) | def test_has_alternative_bit(self):
method test_has_alternative_bit_fast (line 242) | def test_has_alternative_bit_fast(self):
method test_insert_one_bit (line 248) | def test_insert_one_bit(self):
method test_insert_mult_bits (line 261) | def test_insert_mult_bits(self):
method test_remove_bit (line 272) | def test_remove_bit(self):
method test_binary_gap (line 283) | def test_binary_gap(self):
FILE: tests/test_community_algorithms.py
class TestManacher (line 32) | class TestManacher(unittest.TestCase):
method test_odd_palindrome (line 33) | def test_odd_palindrome(self):
method test_even_palindrome (line 37) | def test_even_palindrome(self):
method test_single_char (line 40) | def test_single_char(self):
method test_full_palindrome (line 43) | def test_full_palindrome(self):
method test_empty (line 46) | def test_empty(self):
method test_all_same (line 49) | def test_all_same(self):
class TestZAlgorithm (line 53) | class TestZAlgorithm(unittest.TestCase):
method test_z_array_basic (line 54) | def test_z_array_basic(self):
method test_z_search_found (line 60) | def test_z_search_found(self):
method test_z_search_multiple (line 63) | def test_z_search_multiple(self):
method test_z_search_not_found (line 66) | def test_z_search_not_found(self):
method test_z_search_empty (line 69) | def test_z_search_empty(self):
method test_z_array_empty (line 73) | def test_z_array_empty(self):
class TestGrayCode (line 77) | class TestGrayCode(unittest.TestCase):
method test_2bit (line 78) | def test_2bit(self):
method test_3bit (line 81) | def test_3bit(self):
method test_1bit (line 84) | def test_1bit(self):
method test_0bit (line 87) | def test_0bit(self):
method test_successive_differ_by_one_bit (line 90) | def test_successive_differ_by_one_bit(self):
method test_gray_to_binary_roundtrip (line 96) | def test_gray_to_binary_roundtrip(self):
class TestKdTree (line 102) | class TestKdTree(unittest.TestCase):
method test_nearest_basic (line 103) | def test_nearest_basic(self):
method test_nearest_exact (line 108) | def test_nearest_exact(self):
method test_nearest_3d (line 113) | def test_nearest_3d(self):
method test_single_point (line 118) | def test_single_point(self):
class TestExponentialSearch (line 123) | class TestExponentialSearch(unittest.TestCase):
method test_found (line 124) | def test_found(self):
method test_first_element (line 128) | def test_first_element(self):
method test_last_element (line 131) | def test_last_element(self):
method test_not_found (line 134) | def test_not_found(self):
method test_empty (line 137) | def test_empty(self):
method test_single_element_found (line 140) | def test_single_element_found(self):
method test_single_element_not_found (line 143) | def test_single_element_not_found(self):
class TestSentinelSearch (line 147) | class TestSentinelSearch(unittest.TestCase):
method test_found (line 148) | def test_found(self):
method test_last_element (line 152) | def test_last_element(self):
method test_not_found (line 156) | def test_not_found(self):
method test_empty (line 160) | def test_empty(self):
method test_restores_array (line 163) | def test_restores_array(self):
class TestManhattanDistance (line 169) | class TestManhattanDistance(unittest.TestCase):
method test_2d (line 170) | def test_2d(self):
method test_3d (line 173) | def test_3d(self):
method test_same_point (line 176) | def test_same_point(self):
method test_negative (line 179) | def test_negative(self):
class TestLinearRegression (line 183) | class TestLinearRegression(unittest.TestCase):
method test_basic_fit (line 184) | def test_basic_fit(self):
method test_perfect_line (line 191) | def test_perfect_line(self):
method test_r_squared_perfect (line 198) | def test_r_squared_perfect(self):
method test_rmse_perfect (line 203) | def test_rmse_perfect(self):
method test_rmse_nonperfect (line 208) | def test_rmse_nonperfect(self):
method test_too_few_points (line 213) | def test_too_few_points(self):
class TestPolynomialDivision (line 218) | class TestPolynomialDivision(unittest.TestCase):
method test_basic (line 219) | def test_basic(self):
method test_with_remainder (line 225) | def test_with_remainder(self):
method test_divide_by_zero (line 232) | def test_divide_by_zero(self):
class TestAlphabetBoardPath (line 237) | class TestAlphabetBoardPath(unittest.TestCase):
method test_leet (line 238) | def test_leet(self):
method test_code (line 244) | def test_code(self):
method test_z (line 248) | def test_z(self):
method test_za (line 253) | def test_za(self):
class TestSwapCharacters (line 258) | class TestSwapCharacters(unittest.TestCase):
method test_can_swap (line 259) | def test_can_swap(self):
method test_identical (line 262) | def test_identical(self):
method test_too_many_diffs (line 266) | def test_too_many_diffs(self):
method test_different_lengths (line 269) | def test_different_lengths(self):
method test_one_diff (line 272) | def test_one_diff(self):
class TestMinimax (line 276) | class TestMinimax(unittest.TestCase):
method test_depth_2 (line 277) | def test_depth_2(self):
method test_depth_3 (line 281) | def test_depth_3(self):
method test_single_leaf (line 284) | def test_single_leaf(self):
method test_minimizing (line 287) | def test_minimizing(self):
class TestTsp (line 291) | class TestTsp(unittest.TestCase):
method test_4_cities (line 292) | def test_4_cities(self):
method test_3_cities (line 301) | def test_3_cities(self):
class TestCountPathsDp (line 310) | class TestCountPathsDp(unittest.TestCase):
method test_3x7 (line 311) | def test_3x7(self):
method test_3x3 (line 316) | def test_3x3(self):
method test_1x1 (line 319) | def test_1x1(self):
method test_2x2 (line 322) | def test_2x2(self):
class TestBlossom (line 326) | class TestBlossom(unittest.TestCase):
method test_path_graph (line 327) | def test_path_graph(self):
method test_triangle (line 332) | def test_triangle(self):
method test_empty_graph (line 337) | def test_empty_graph(self):
method test_complete_4 (line 341) | def test_complete_4(self):
FILE: tests/test_compression.py
class TestHuffmanCoding (line 8) | class TestHuffmanCoding(unittest.TestCase):
method setUpClass (line 10) | def setUpClass(cls):
method setUp (line 15) | def setUp(self):
method test_huffman_coding (line 23) | def test_huffman_coding(self):
method tearDown (line 36) | def tearDown(self):
class TestRLECompression (line 44) | class TestRLECompression(unittest.TestCase):
method test_encode_rle (line 45) | def test_encode_rle(self):
method test_decode_rle (line 53) | def test_decode_rle(self):
class TestEliasCoding (line 60) | class TestEliasCoding(unittest.TestCase):
method test_elias_gamma (line 61) | def test_elias_gamma(self):
method test_elias_delta (line 82) | def test_elias_delta(self):
FILE: tests/test_data_structures.py
class TestRBTree (line 16) | class TestRBTree(unittest.TestCase):
method _make_tree (line 17) | def _make_tree(self, values):
method test_insert_single (line 23) | def test_insert_single(self):
method test_insert_multiple_sorted (line 29) | def test_insert_multiple_sorted(self):
method test_root_is_black (line 36) | def test_root_is_black(self):
method test_empty_tree (line 40) | def test_empty_tree(self):
method test_insert_duplicates_order (line 45) | def test_insert_duplicates_order(self):
class TestAvlTree (line 52) | class TestAvlTree(unittest.TestCase):
method test_insert_single (line 53) | def test_insert_single(self):
method test_insert_multiple_root_exists (line 59) | def test_insert_multiple_root_exists(self):
method test_balanced_after_insert (line 65) | def test_balanced_after_insert(self):
method test_empty_tree (line 72) | def test_empty_tree(self):
method test_in_order_traverse_populated (line 77) | def test_in_order_traverse_populated(self):
method test_insert_balance_factor (line 83) | def test_insert_balance_factor(self):
class TestTrie (line 91) | class TestTrie(unittest.TestCase):
method test_insert_and_search (line 92) | def test_insert_and_search(self):
method test_search_missing (line 97) | def test_search_missing(self):
method test_starts_with (line 102) | def test_starts_with(self):
method test_empty_trie (line 108) | def test_empty_trie(self):
method test_multiple_words (line 113) | def test_multiple_words(self):
method test_insert_single_char (line 121) | def test_insert_single_char(self):
class TestUnionFind (line 128) | class TestUnionFind(unittest.TestCase):
method test_add_and_root (line 129) | def test_add_and_root(self):
method test_unite_connects (line 134) | def test_unite_connects(self):
method test_not_connected (line 141) | def test_not_connected(self):
method test_count_decrements_on_unite (line 147) | def test_count_decrements_on_unite(self):
method test_unite_same_element (line 156) | def test_unite_same_element(self):
method test_transitive_connectivity (line 162) | def test_transitive_connectivity(self):
class TestSegmentTree (line 171) | class TestSegmentTree(unittest.TestCase):
method test_max_query (line 172) | def test_max_query(self):
method test_sum_query (line 176) | def test_sum_query(self):
method test_single_element_query (line 180) | def test_single_element_query(self):
method test_full_range_max (line 185) | def test_full_range_max(self):
class TestHashTable (line 191) | class TestHashTable(unittest.TestCase):
method test_put_and_get (line 192) | def test_put_and_get(self):
method test_get_missing (line 197) | def test_get_missing(self):
method test_delete (line 201) | def test_delete(self):
method test_update_existing (line 207) | def test_update_existing(self):
method test_len (line 213) | def test_len(self):
method test_bracket_operators (line 219) | def test_bracket_operators(self):
class TestResizableHashTable (line 227) | class TestResizableHashTable(unittest.TestCase):
method test_put_and_get (line 228) | def test_put_and_get(self):
method test_resizes_automatically (line 233) | def test_resizes_automatically(self):
class TestSeparateChainingHashTable (line 241) | class TestSeparateChainingHashTable(unittest.TestCase):
method test_put_and_get (line 242) | def test_put_and_get(self):
method test_get_missing (line 247) | def test_get_missing(self):
method test_delete (line 251) | def test_delete(self):
method test_len (line 257) | def test_len(self):
method test_collision_handling (line 263) | def test_collision_handling(self):
method test_bracket_operators (line 271) | def test_bracket_operators(self):
FILE: tests/test_dynamic_programming.py
class TestBuySellStock (line 30) | class TestBuySellStock(unittest.TestCase):
method test_max_profit_naive (line 31) | def test_max_profit_naive(self):
method test_max_profit_optimized (line 35) | def test_max_profit_optimized(self):
class TestClimbingStairs (line 40) | class TestClimbingStairs(unittest.TestCase):
method test_climb_stairs (line 41) | def test_climb_stairs(self):
method test_climb_stairs_optimized (line 45) | def test_climb_stairs_optimized(self):
class TestCoinChange (line 50) | class TestCoinChange(unittest.TestCase):
method test_count (line 51) | def test_count(self):
class TestCombinationSum (line 56) | class TestCombinationSum(unittest.TestCase):
method test_combination_sum_topdown (line 57) | def test_combination_sum_topdown(self):
method test_combination_sum_bottom_up (line 60) | def test_combination_sum_bottom_up(self):
class TestEditDistance (line 64) | class TestEditDistance(unittest.TestCase):
method test_edit_distance (line 65) | def test_edit_distance(self):
class TestEggDrop (line 70) | class TestEggDrop(unittest.TestCase):
method test_egg_drop (line 71) | def test_egg_drop(self):
class TestFib (line 77) | class TestFib(unittest.TestCase):
method test_fib_recursive (line 78) | def test_fib_recursive(self):
method test_fib_list (line 82) | def test_fib_list(self):
method test_fib_iter (line 86) | def test_fib_iter(self):
class TestHosoyaTriangle (line 91) | class TestHosoyaTriangle(unittest.TestCase):
method test_hosoya (line 99) | def test_hosoya(self):
class TestHouseRobber (line 167) | class TestHouseRobber(unittest.TestCase):
method test_house_robber (line 168) | def test_house_robber(self):
class TestJobScheduling (line 172) | class TestJobScheduling(unittest.TestCase):
method test_job_scheduling (line 173) | def test_job_scheduling(self):
class TestKnapsack (line 178) | class TestKnapsack(unittest.TestCase):
method test_get_maximum_value (line 179) | def test_get_maximum_value(self):
class TestLongestIncreasingSubsequence (line 187) | class TestLongestIncreasingSubsequence(unittest.TestCase):
method test_longest_increasing_subsequence (line 188) | def test_longest_increasing_subsequence(self):
class TestLongestIncreasingSubsequenceOptimized (line 193) | class TestLongestIncreasingSubsequenceOptimized(unittest.TestCase):
method test_longest_increasing_subsequence_optimized (line 194) | def test_longest_increasing_subsequence_optimized(self):
class TestLongestIncreasingSubsequenceOptimized2 (line 199) | class TestLongestIncreasingSubsequenceOptimized2(unittest.TestCase):
method test_longest_increasing_subsequence_optimized2 (line 200) | def test_longest_increasing_subsequence_optimized2(self):
class TestIntDivide (line 205) | class TestIntDivide(unittest.TestCase):
method test_int_divide (line 206) | def test_int_divide(self):
class TestDpKFactor (line 212) | class TestDpKFactor(unittest.TestCase):
method test_kfactor (line 213) | def test_kfactor(self):
class TestPlantingTrees (line 240) | class TestPlantingTrees(unittest.TestCase):
method test_simple (line 241) | def test_simple(self):
method test_simple2 (line 253) | def test_simple2(self):
class TestRegexMatching (line 266) | class TestRegexMatching(unittest.TestCase):
method test_none_0 (line 267) | def test_none_0(self):
method test_none_1 (line 272) | def test_none_1(self):
method test_no_symbol_equal (line 277) | def test_no_symbol_equal(self):
method test_no_symbol_not_equal_0 (line 282) | def test_no_symbol_not_equal_0(self):
method test_no_symbol_not_equal_1 (line 287) | def test_no_symbol_not_equal_1(self):
method test_symbol_0 (line 292) | def test_symbol_0(self):
method test_symbol_1 (line 297) | def test_symbol_1(self):
method test_symbol_2 (line 302) | def test_symbol_2(self):
FILE: tests/test_graph.py
class TestTarjan (line 38) | class TestTarjan(unittest.TestCase):
method test_tarjan_example_1 (line 46) | def test_tarjan_example_1(self):
method test_tarjan_example_2 (line 62) | def test_tarjan_example_2(self):
class TestCheckBipartite (line 79) | class TestCheckBipartite(unittest.TestCase):
method test_check_bipartite (line 80) | def test_check_bipartite(self):
class TestDijkstra (line 89) | class TestDijkstra(unittest.TestCase):
method test_dijkstra (line 90) | def test_dijkstra(self):
class TestMaximumFlow (line 107) | class TestMaximumFlow(unittest.TestCase):
method test_ford_fulkerson (line 115) | def test_ford_fulkerson(self):
method test_edmonds_karp (line 127) | def test_edmonds_karp(self):
method dinic (line 139) | def dinic(self):
class TestMaximumFlowBfs (line 152) | class TestMaximumFlowBfs(unittest.TestCase):
method test_maximum_flow_bfs (line 159) | def test_maximum_flow_bfs(self):
class TestMaximumFlowDfs (line 173) | class TestMaximumFlowDfs(unittest.TestCase):
method test_maximum_flow_dfs (line 180) | def test_maximum_flow_dfs(self):
class TestAllPairsShortestPath (line 194) | class TestAllPairsShortestPath(unittest.TestCase):
method test_all_pairs_shortest_path (line 195) | def test_all_pairs_shortest_path(self):
class TestBellmanFord (line 217) | class TestBellmanFord(unittest.TestCase):
method test_bellman_ford (line 218) | def test_bellman_ford(self):
class TestConnectedComponentInGraph (line 237) | class TestConnectedComponentInGraph(unittest.TestCase):
method test_count_connected_components (line 242) | def test_count_connected_components(self):
method test_connected_components_with_empty_graph (line 260) | def test_connected_components_with_empty_graph(self):
method test_connected_components_without_edges_graph (line 271) | def test_connected_components_without_edges_graph(self):
class PrimsMinimumSpanning (line 283) | class PrimsMinimumSpanning(unittest.TestCase):
method test_prim_spanning (line 284) | def test_prim_spanning(self):
class TestDigraphStronglyConnected (line 302) | class TestDigraphStronglyConnected(unittest.TestCase):
method test_digraph_strongly_connected (line 303) | def test_digraph_strongly_connected(self):
class TestCycleDetection (line 320) | class TestCycleDetection(unittest.TestCase):
method test_cycle_detection_with_cycle (line 321) | def test_cycle_detection_with_cycle(self):
method test_cycle_detection_with_no_cycle (line 332) | def test_cycle_detection_with_no_cycle(self):
class TestFindPath (line 344) | class TestFindPath(unittest.TestCase):
method test_find_all_paths (line 345) | def test_find_all_paths(self):
class TestPathBetweenTwoVertices (line 369) | class TestPathBetweenTwoVertices(unittest.TestCase):
method test_node_is_reachable (line 370) | def test_node_is_reachable(self):
class TestStronglyConnectedComponentsKosaraju (line 383) | class TestStronglyConnectedComponentsKosaraju(unittest.TestCase):
method test_kosaraju_algorithm (line 384) | def test_kosaraju_algorithm(self):
class TestCountIslandsBfs (line 400) | class TestCountIslandsBfs(unittest.TestCase):
method test_count_islands (line 401) | def test_count_islands(self):
class TestMazeSearchBfs (line 423) | class TestMazeSearchBfs(unittest.TestCase):
method test_maze_search (line 424) | def test_maze_search(self):
class TestWordLadder (line 436) | class TestWordLadder(unittest.TestCase):
method test_ladder_length (line 437) | def test_ladder_length(self):
class TestAllFactors (line 462) | class TestAllFactors(unittest.TestCase):
method test_get_factors (line 463) | def test_get_factors(self):
method test_get_factors_iterative1 (line 469) | def test_get_factors_iterative1(self):
method test_get_factors_iterative2 (line 475) | def test_get_factors_iterative2(self):
class TestCountIslandsDfs (line 482) | class TestCountIslandsDfs(unittest.TestCase):
method test_num_islands (line 483) | def test_num_islands(self):
class TestPacificAtlantic (line 498) | class TestPacificAtlantic(unittest.TestCase):
method test_pacific_atlantic (line 499) | def test_pacific_atlantic(self):
class TestSudoku (line 514) | class TestSudoku(unittest.TestCase):
method test_sudoku_solver (line 515) | def test_sudoku_solver(self):
class TestWallsAndGates (line 524) | class TestWallsAndGates(unittest.TestCase):
method test_walls_and_gates (line 525) | def test_walls_and_gates(self):
class TestMazeSearchDfs (line 538) | class TestMazeSearchDfs(unittest.TestCase):
method test_maze_search (line 539) | def test_maze_search(self):
class TestTopSort (line 559) | class TestTopSort(unittest.TestCase):
method setUp (line 560) | def setUp(self):
method test_topsort (line 571) | def test_topsort(self):
class TestTopologicalSort (line 578) | class TestTopologicalSort(unittest.TestCase):
method test_simple_dag (line 579) | def test_simple_dag(self):
method test_single_vertex (line 593) | def test_single_vertex(self):
method test_disconnected_graph (line 600) | def test_disconnected_graph(self):
method test_no_edges (line 612) | def test_no_edges(self):
method test_cycle_detection (line 621) | def test_cycle_detection(self):
method test_self_loop_cycle (line 628) | def test_self_loop_cycle(self):
FILE: tests/test_greedy.py
class TestMaxContiguousSubsequenceSum (line 8) | class TestMaxContiguousSubsequenceSum(unittest.TestCase):
method test_max_contiguous_subsequence_sum (line 9) | def test_max_contiguous_subsequence_sum(self):
FILE: tests/test_heap.py
class TestBinaryHeap (line 6) | class TestBinaryHeap(unittest.TestCase):
method setUp (line 11) | def setUp(self):
method test_insert (line 20) | def test_insert(self):
method test_remove_min (line 27) | def test_remove_min(self):
class TestSuite (line 37) | class TestSuite(unittest.TestCase):
method test_get_skyline (line 38) | def test_get_skyline(self):
method test_max_sliding_window (line 44) | def test_max_sliding_window(self):
method test_k_closest_points (line 48) | def test_k_closest_points(self):
FILE: tests/test_issue_fixes.py
class TestDijkstraHeapq (line 21) | class TestDijkstraHeapq(unittest.TestCase):
method setUp (line 24) | def setUp(self):
method test_shortest_path (line 34) | def test_shortest_path(self):
method test_same_source_and_target (line 39) | def test_same_source_and_target(self):
method test_direct_neighbor (line 44) | def test_direct_neighbor(self):
method test_unreachable_target (line 49) | def test_unreachable_target(self):
method test_single_node (line 55) | def test_single_node(self):
method test_triangle (line 61) | def test_triangle(self):
class TestGoldbach (line 71) | class TestGoldbach(unittest.TestCase):
method test_small_even (line 74) | def test_small_even(self):
method test_goldbach_28 (line 77) | def test_goldbach_28(self):
method test_goldbach_100 (line 82) | def test_goldbach_100(self):
method test_goldbach_large (line 86) | def test_goldbach_large(self):
method test_odd_raises (line 90) | def test_odd_raises(self):
method test_two_raises (line 94) | def test_two_raises(self):
method test_negative_raises (line 98) | def test_negative_raises(self):
method test_verify_range (line 102) | def test_verify_range(self):
class TestBinaryTreeViews (line 109) | class TestBinaryTreeViews(unittest.TestCase):
method setUp (line 112) | def setUp(self):
method test_left_view (line 126) | def test_left_view(self):
method test_right_view (line 129) | def test_right_view(self):
method test_top_view (line 132) | def test_top_view(self):
method test_bottom_view (line 135) | def test_bottom_view(self):
method test_empty_tree (line 138) | def test_empty_tree(self):
method test_single_node (line 144) | def test_single_node(self):
method test_left_skewed (line 151) | def test_left_skewed(self):
method test_right_skewed (line 163) | def test_right_skewed(self):
class TestSqrtDecomposition (line 179) | class TestSqrtDecomposition(unittest.TestCase):
method test_full_range_sum (line 182) | def test_full_range_sum(self):
method test_partial_range (line 186) | def test_partial_range(self):
method test_single_element (line 190) | def test_single_element(self):
method test_update (line 194) | def test_update(self):
method test_update_full_range (line 199) | def test_update_full_range(self):
method test_multiple_updates (line 204) | def test_multiple_updates(self):
method test_out_of_range_update (line 210) | def test_out_of_range_update(self):
method test_invalid_query (line 215) | def test_invalid_query(self):
method test_small_array (line 220) | def test_small_array(self):
method test_larger_array (line 226) | def test_larger_array(self):
FILE: tests/test_iterative_segment_tree.py
function gcd (line 7) | def gcd(a, b):
class TestSegmentTree (line 13) | class TestSegmentTree(unittest.TestCase):
method test_segment_tree_creation (line 18) | def test_segment_tree_creation(self):
method test_max_segment_tree (line 37) | def test_max_segment_tree(self):
method test_min_segment_tree (line 41) | def test_min_segment_tree(self):
method test_sum_segment_tree (line 45) | def test_sum_segment_tree(self):
method test_gcd_segment_tree (line 49) | def test_gcd_segment_tree(self):
method test_max_segment_tree_with_updates (line 53) | def test_max_segment_tree_with_updates(self):
method test_min_segment_tree_with_updates (line 71) | def test_min_segment_tree_with_updates(self):
method test_sum_segment_tree_with_updates (line 89) | def test_sum_segment_tree_with_updates(self):
method test_gcd_segment_tree_with_updates (line 107) | def test_gcd_segment_tree_with_updates(self):
method __test_all_segments (line 126) | def __test_all_segments(self, arr, fnc):
method __test_all_segments_with_updates (line 135) | def __test_all_segments_with_updates(self, arr, fnc, upd):
method __test_segments_helper (line 148) | def __test_segments_helper(self, seg_tree, fnc, arr):
FILE: tests/test_linked_list.py
class Node (line 22) | class Node:
method __init__ (line 23) | def __init__(self, x):
function convert (line 29) | def convert(head):
class TestSuite (line 39) | class TestSuite(unittest.TestCase):
method setUp (line 40) | def setUp(self):
method test_reverse_list (line 53) | def test_reverse_list(self):
method test_is_sorted (line 65) | def test_is_sorted(self):
method test_remove_range (line 81) | def test_remove_range(self):
method test_swap_in_pairs (line 108) | def test_swap_in_pairs(self):
method test_rotate_right (line 116) | def test_rotate_right(self):
method test_is_cyclic (line 126) | def test_is_cyclic(self):
method test_merge_two_list (line 149) | def test_merge_two_list(self):
method test_is_palindrome (line 172) | def test_is_palindrome(self):
method test_is_palindrome_stack (line 176) | def test_is_palindrome_stack(self):
method test_is_palindrome_dict (line 180) | def test_is_palindrome_dict(self):
method test_solution_0 (line 184) | def test_solution_0(self):
method test_solution_1 (line 189) | def test_solution_1(self):
method _assert_is_a_copy (line 194) | def _assert_is_a_copy(self, result):
method _init_random_list_nodes (line 206) | def _init_random_list_nodes(self):
FILE: tests/test_map.py
class TestHashTable (line 14) | class TestHashTable(unittest.TestCase):
method test_one_entry (line 15) | def test_one_entry(self):
method test_add_entry_bigger_than_table_size (line 20) | def test_add_entry_bigger_than_table_size(self):
method test_get_none_if_key_missing_and_hash_collision (line 25) | def test_get_none_if_key_missing_and_hash_collision(self):
method test_two_entries_with_same_hash (line 30) | def test_two_entries_with_same_hash(self):
method test_get_on_full_table_does_halts (line 37) | def test_get_on_full_table_does_halts(self):
method test_delete_key (line 44) | def test_delete_key(self):
method test_delete_key_and_reassign (line 52) | def test_delete_key_and_reassign(self):
method test_assigning_to_full_table_throws_error (line 59) | def test_assigning_to_full_table_throws_error(self):
method test_len_trivial (line 67) | def test_len_trivial(self):
method test_len_after_deletions (line 74) | def test_len_after_deletions(self):
method test_resizable_hash_table (line 83) | def test_resizable_hash_table(self):
method test_fill_up_the_limit (line 93) | def test_fill_up_the_limit(self):
class TestSeparateChainingHashTable (line 101) | class TestSeparateChainingHashTable(unittest.TestCase):
method test_one_entry (line 102) | def test_one_entry(self):
method test_two_entries_with_same_hash (line 107) | def test_two_entries_with_same_hash(self):
method test_len_trivial (line 114) | def test_len_trivial(self):
method test_len_after_deletions (line 121) | def test_len_after_deletions(self):
method test_delete_key (line 130) | def test_delete_key(self):
method test_delete_key_and_reassign (line 138) | def test_delete_key_and_reassign(self):
method test_add_entry_bigger_than_table_size (line 145) | def test_add_entry_bigger_than_table_size(self):
method test_get_none_if_key_missing_and_hash_collision (line 150) | def test_get_none_if_key_missing_and_hash_collision(self):
class TestWordPattern (line 156) | class TestWordPattern(unittest.TestCase):
method test_word_pattern (line 157) | def test_word_pattern(self):
class TestIsSomorphic (line 164) | class TestIsSomorphic(unittest.TestCase):
method test_is_isomorphic (line 165) | def test_is_isomorphic(self):
class TestLongestPalindromicSubsequence (line 171) | class TestLongestPalindromicSubsequence(unittest.TestCase):
method test_longest_palindromic_subsequence_is_correct (line 172) | def test_longest_palindromic_subsequence_is_correct(self):
method test_longest_palindromic_subsequence_is_incorrect (line 178) | def test_longest_palindromic_subsequence_is_incorrect(self):
class TestIsAnagram (line 185) | class TestIsAnagram(unittest.TestCase):
method test_is_anagram (line 186) | def test_is_anagram(self):
FILE: tests/test_math.py
class TestPower (line 49) | class TestPower(unittest.TestCase):
method test_power (line 57) | def test_power(self):
method test_power_recur (line 63) | def test_power_recur(self):
class TestBaseConversion (line 70) | class TestBaseConversion(unittest.TestCase):
method test_int_to_base (line 78) | def test_int_to_base(self):
method test_base_to_int (line 83) | def test_base_to_int(self):
class TestDecimalToBinaryIP (line 89) | class TestDecimalToBinaryIP(unittest.TestCase):
method test_decimal_to_binary_ip (line 97) | def test_decimal_to_binary_ip(self):
class TestEulerTotient (line 110) | class TestEulerTotient(unittest.TestCase):
method test_euler_totient (line 118) | def test_euler_totient(self):
class TestExtendedGcd (line 125) | class TestExtendedGcd(unittest.TestCase):
method test_extended_gcd (line 133) | def test_extended_gcd(self):
class TestGcd (line 138) | class TestGcd(unittest.TestCase):
method test_gcd (line 146) | def test_gcd(self):
method test_gcd_non_integer_input (line 150) | def test_gcd_non_integer_input(self):
method test_gcd_zero_input (line 156) | def test_gcd_zero_input(self):
method test_gcd_negative_input (line 164) | def test_gcd_negative_input(self):
method test_lcm (line 169) | def test_lcm(self):
method test_lcm_negative_numbers (line 173) | def test_lcm_negative_numbers(self):
method test_lcm_zero_input (line 178) | def test_lcm_zero_input(self):
method test_trailing_zero (line 186) | def test_trailing_zero(self):
method test_gcd_bit (line 190) | def test_gcd_bit(self):
class TestGenerateStroboGrammatic (line 195) | class TestGenerateStroboGrammatic(unittest.TestCase):
method test_gen_strobomatic (line 203) | def test_gen_strobomatic(self):
method test_strobogrammatic_in_range (line 206) | def test_strobogrammatic_in_range(self):
class TestIsStrobogrammatic (line 210) | class TestIsStrobogrammatic(unittest.TestCase):
method test_is_strobogrammatic (line 218) | def test_is_strobogrammatic(self):
method test_is_strobogrammatic2 (line 222) | def test_is_strobogrammatic2(self):
class TestModularInverse (line 227) | class TestModularInverse(unittest.TestCase):
method test_modular_inverse (line 235) | def test_modular_inverse(self):
class TestModularExponential (line 245) | class TestModularExponential(unittest.TestCase):
method test_modular_exponential (line 253) | def test_modular_exponential(self):
class TestNextPerfectSquare (line 262) | class TestNextPerfectSquare(unittest.TestCase):
method test_find_next_square (line 270) | def test_find_next_square(self):
method test_find_next_square2 (line 274) | def test_find_next_square2(self):
class TestPrimesSieveOfEratosthenes (line 279) | class TestPrimesSieveOfEratosthenes(unittest.TestCase):
method test_primes (line 287) | def test_primes(self):
class TestPrimeTest (line 292) | class TestPrimeTest(unittest.TestCase):
method test_prime_test (line 300) | def test_prime_test(self):
class TestPythagoras (line 312) | class TestPythagoras(unittest.TestCase):
method test_pythagoras (line 320) | def test_pythagoras(self):
class TestRabinMiller (line 324) | class TestRabinMiller(unittest.TestCase):
method test_is_prime (line 332) | def test_is_prime(self):
class TestRSA (line 338) | class TestRSA(unittest.TestCase):
method test_encrypt_decrypt (line 346) | def test_encrypt_decrypt(self):
class TestCombination (line 359) | class TestCombination(unittest.TestCase):
method test_combination (line 367) | def test_combination(self):
method test_combination_memo (line 371) | def test_combination_memo(self):
class TestFactorial (line 376) | class TestFactorial(unittest.TestCase):
method test_factorial (line 384) | def test_factorial(self):
method test_factorial_recur (line 392) | def test_factorial_recur(self):
class TestHailstone (line 401) | class TestHailstone(unittest.TestCase):
method test_hailstone (line 409) | def test_hailstone(self):
class TestCosineSimilarity (line 414) | class TestCosineSimilarity(unittest.TestCase):
method test_cosine_similarity (line 422) | def test_cosine_similarity(self):
class TestFindPrimitiveRoot (line 431) | class TestFindPrimitiveRoot(unittest.TestCase):
method test_find_primitive_root_simple (line 439) | def test_find_primitive_root_simple(self):
class TestFindOrder (line 448) | class TestFindOrder(unittest.TestCase):
method test_find_order_simple (line 456) | def test_find_order_simple(self):
class TestKrishnamurthyNumber (line 463) | class TestKrishnamurthyNumber(unittest.TestCase):
method test_krishnamurthy_number (line 471) | def test_krishnamurthy_number(self):
class TestMagicNumber (line 479) | class TestMagicNumber(unittest.TestCase):
method test_magic_number (line 487) | def test_magic_number(self):
class TestDiffieHellmanKeyExchange (line 496) | class TestDiffieHellmanKeyExchange(unittest.TestCase):
method test_find_order_simple (line 504) | def test_find_order_simple(self):
class TestNumberOfDigits (line 511) | class TestNumberOfDigits(unittest.TestCase):
method test_num_digits (line 519) | def test_num_digits(self):
class TestNumberOfPerfectSquares (line 528) | class TestNumberOfPerfectSquares(unittest.TestCase):
method test_num_perfect_squares (line 536) | def test_num_perfect_squares(self):
class TestChineseRemainderSolver (line 547) | class TestChineseRemainderSolver(unittest.TestCase):
method test_k_three (line 548) | def test_k_three(self):
method test_k_five (line 558) | def test_k_five(self):
method test_exception_non_coprime (line 568) | def test_exception_non_coprime(self):
method test_empty_lists (line 576) | def test_empty_lists(self):
class TestFFT (line 583) | class TestFFT(unittest.TestCase):
method test_real_numbers (line 591) | def test_real_numbers(self):
method test_all_zero (line 598) | def test_all_zero(self):
method test_all_ones (line 604) | def test_all_ones(self):
method test_complex_numbers (line 610) | def test_complex_numbers(self):
FILE: tests/test_matrix.py
class TestBombEnemy (line 20) | class TestBombEnemy(unittest.TestCase):
method test_3x4 (line 21) | def test_3x4(self):
class TestCopyTransform (line 41) | class TestCopyTransform(unittest.TestCase):
method test_copy_transform (line 49) | def test_copy_transform(self):
class TestCroutMatrixDecomposition (line 71) | class TestCroutMatrixDecomposition(unittest.TestCase):
method test_crout_matrix_decomposition (line 79) | def test_crout_matrix_decomposition(self):
class TestCholeskyMatrixDecomposition (line 116) | class TestCholeskyMatrixDecomposition(unittest.TestCase):
method test_cholesky_matrix_decomposition (line 124) | def test_cholesky_matrix_decomposition(self):
class TestInversion (line 170) | class TestInversion(unittest.TestCase):
method test_inversion (line 178) | def test_inversion(self):
class TestMatrixExponentiation (line 207) | class TestMatrixExponentiation(unittest.TestCase):
method test_matrix_exponentiation (line 215) | def test_matrix_exponentiation(self):
class TestMultiply (line 239) | class TestMultiply(unittest.TestCase):
method test_multiply (line 247) | def test_multiply(self):
class TestRotateImage (line 253) | class TestRotateImage(unittest.TestCase):
method test_rotate_image (line 261) | def test_rotate_image(self):
class TestSparseDotVector (line 268) | class TestSparseDotVector(unittest.TestCase):
method test_sparse_dot_vector (line 276) | def test_sparse_dot_vector(self):
class TestSpiralTraversal (line 286) | class TestSpiralTraversal(unittest.TestCase):
method test_spiral_traversal (line 294) | def test_spiral_traversal(self):
class TestSudokuValidator (line 301) | class TestSudokuValidator(unittest.TestCase):
method test_sudoku_validator (line 309) | def test_sudoku_validator(self):
class TestSumSubSquares (line 407) | class TestSumSubSquares(unittest.TestCase):
method test_sum_sub_squares (line 415) | def test_sum_sub_squares(self):
class TestSortMatrixDiagonally (line 429) | class TestSortMatrixDiagonally(unittest.TestCase):
method test_sort_diagonally (line 430) | def test_sort_diagonally(self):
FILE: tests/test_monomial.py
class TestSuite (line 8) | class TestSuite(unittest.TestCase):
method setUp (line 9) | def setUp(self):
method test_monomial_addition (line 28) | def test_monomial_addition(self):
method test_monomial_subtraction (line 65) | def test_monomial_subtraction(self):
method test_monomial_multiplication (line 103) | def test_monomial_multiplication(self):
method test_monomial_inverse (line 123) | def test_monomial_inverse(self):
method test_monomial_division (line 143) | def test_monomial_division(self):
method test_monomial_substitution (line 155) | def test_monomial_substitution(self):
method test_monomial_all_variables (line 189) | def test_monomial_all_variables(self):
method test_monomial_clone (line 201) | def test_monomial_clone(self):
FILE: tests/test_polynomial.py
class TestSuite (line 8) | class TestSuite(unittest.TestCase):
method setUp (line 9) | def setUp(self):
method test_polynomial_addition (line 36) | def test_polynomial_addition(self):
method test_polynomial_subtraction (line 78) | def test_polynomial_subtraction(self):
method test_polynomial_multiplication (line 88) | def test_polynomial_multiplication(self):
method test_polynomial_variables (line 98) | def test_polynomial_variables(self):
method test_polynomial_subs (line 112) | def test_polynomial_subs(self):
method test_polynomial_clone (line 134) | def test_polynomial_clone(self):
method test_polynomial_long_division (line 150) | def test_polynomial_long_division(self):
FILE: tests/test_queue.py
class TestQueue (line 12) | class TestQueue(unittest.TestCase):
method test_array_queue (line 17) | def test_array_queue(self):
method test_linked_list_queue (line 46) | def test_linked_list_queue(self):
class TestSuite (line 76) | class TestSuite(unittest.TestCase):
method test_max_sliding_window (line 77) | def test_max_sliding_window(self):
method test_reconstruct_queue (line 90) | def test_reconstruct_queue(self):
class TestPriorityQueue (line 97) | class TestPriorityQueue(unittest.TestCase):
method test_priority_queue (line 100) | def test_priority_queue(self):
FILE: tests/test_searching.py
class TestSuite (line 27) | class TestSuite(unittest.TestCase):
method test_first_occurrence (line 28) | def test_first_occurrence(self):
method test_binary_search (line 41) | def test_binary_search(self):
method test_ternary_search (line 53) | def test_ternary_search(self):
method test_last_occurrence (line 61) | def test_last_occurrence(self):
method test_linear_search (line 69) | def test_linear_search(self):
method test_search_insert (line 76) | def test_search_insert(self):
method test_two_sum (line 83) | def test_two_sum(self):
method test_search_range (line 95) | def test_search_range(self):
method test_find_min_rotate (line 106) | def test_find_min_rotate(self):
method test_search_rotate (line 117) | def test_search_rotate(self):
method test_jump_search (line 124) | def test_jump_search(self):
method test_next_greatest_letter (line 131) | def test_next_greatest_letter(self):
method test_interpolation_search (line 148) | def test_interpolation_search(self):
FILE: tests/test_set.py
class TestFindKeyboardRow (line 6) | class TestFindKeyboardRow(unittest.TestCase):
method test_find_keyboard_row (line 7) | def test_find_keyboard_row(self):
FILE: tests/test_sorting.py
function is_sorted (line 27) | def is_sorted(array):
class TestSuite (line 36) | class TestSuite(unittest.TestCase):
method test_bogo_sort (line 37) | def test_bogo_sort(self):
method test_bitonic_sort (line 40) | def test_bitonic_sort(self):
method test_bubble_sort (line 43) | def test_bubble_sort(self):
method test_comb_sort (line 46) | def test_comb_sort(self):
method test_counting_sort (line 49) | def test_counting_sort(self):
method test_cycle_sort (line 52) | def test_cycle_sort(self):
method test_exchange_sort (line 55) | def test_exchange_sort(self):
method test_heap_sort (line 58) | def test_heap_sort(self):
method test_insertion_sort (line 63) | def test_insertion_sort(self):
method test_merge_sort (line 66) | def test_merge_sort(self):
method test_pancake_sort (line 69) | def test_pancake_sort(self):
method test_pigeonhole_sort (line 72) | def test_pigeonhole_sort(self):
method test_quick_sort (line 75) | def test_quick_sort(self):
method test_selection_sort (line 78) | def test_selection_sort(self):
method test_bucket_sort (line 81) | def test_bucket_sort(self):
method test_shell_sort (line 84) | def test_shell_sort(self):
method test_radix_sort (line 87) | def test_radix_sort(self):
method test_gnome_sort (line 90) | def test_gnome_sort(self):
method test_cocktail_shaker_sort (line 93) | def test_cocktail_shaker_sort(self):
FILE: tests/test_stack.py
class TestSuite (line 20) | class TestSuite(unittest.TestCase):
method test_is_consecutive (line 21) | def test_is_consecutive(self):
method test_is_sorted (line 30) | def test_is_sorted(self):
method test_remove_min (line 36) | def test_remove_min(self):
method test_stutter (line 42) | def test_stutter(self):
method test_switch_pairs (line 51) | def test_switch_pairs(self):
method test_is_valid_parenthesis (line 63) | def test_is_valid_parenthesis(self):
method test_simplify_path (line 71) | def test_simplify_path(self):
class TestStack (line 76) | class TestStack(unittest.TestCase):
method test_array_stack (line 77) | def test_array_stack(self):
method test_linked_list_stack (line 109) | def test_linked_list_stack(self):
class TestOrderedStack (line 143) | class TestOrderedStack(unittest.TestCase):
method test_ordered_stack (line 144) | def test_ordered_stack(self):
FILE: tests/test_streaming.py
class TestMisraGreis (line 9) | class TestMisraGreis(unittest.TestCase):
method test_misra_correct (line 10) | def test_misra_correct(self):
method test_misra_incorrect (line 15) | def test_misra_incorrect(self):
class TestOneSparse (line 21) | class TestOneSparse(unittest.TestCase):
method test_one_sparse_correct (line 22) | def test_one_sparse_correct(self):
method test_one_sparse_incorrect (line 33) | def test_one_sparse_incorrect(self):
FILE: tests/test_string.py
class TestAddBinary (line 70) | class TestAddBinary(unittest.TestCase):
method test_add_binary (line 78) | def test_add_binary(self):
class TestBreakingBad (line 84) | class TestBreakingBad(unittest.TestCase):
method setUp (line 92) | def setUp(self):
method test_match_symbol (line 97) | def test_match_symbol(self):
method test_match_symbol_1 (line 100) | def test_match_symbol_1(self):
method test_bracket (line 106) | def test_bracket(self):
class TestDecodeString (line 119) | class TestDecodeString(unittest.TestCase):
method test_decode_string (line 127) | def test_decode_string(self):
class TestDeleteReoccurring (line 132) | class TestDeleteReoccurring(unittest.TestCase):
method test_delete_reoccurring_characters (line 140) | def test_delete_reoccurring_characters(self):
class TestDomainExtractor (line 144) | class TestDomainExtractor(unittest.TestCase):
method test_valid (line 152) | def test_valid(self):
method test_invalid (line 155) | def test_invalid(self):
class TestEncodeDecode (line 159) | class TestEncodeDecode(unittest.TestCase):
method test_encode (line 167) | def test_encode(self):
method test_decode (line 170) | def test_decode(self):
class TestGroupAnagrams (line 174) | class TestGroupAnagrams(unittest.TestCase):
method test_group_anagrams (line 182) | def test_group_anagrams(self):
class TestIntToRoman (line 189) | class TestIntToRoman(unittest.TestCase):
method test_int_to_roman (line 197) | def test_int_to_roman(self):
class TestIsPalindrome (line 203) | class TestIsPalindrome(unittest.TestCase):
method test_is_palindrome (line 211) | def test_is_palindrome(self):
method test_is_palindrome_reverse (line 216) | def test_is_palindrome_reverse(self):
method test_is_palindrome_two_pointer (line 221) | def test_is_palindrome_two_pointer(self):
method test_is_palindrome_stack (line 226) | def test_is_palindrome_stack(self):
method test_is_palindrome_deque (line 231) | def test_is_palindrome_deque(self):
class TestIsRotated (line 237) | class TestIsRotated(unittest.TestCase):
method test_is_rotated (line 245) | def test_is_rotated(self):
method test_is_rotated_v1 (line 252) | def test_is_rotated_v1(self):
class TestRotated (line 260) | class TestRotated(unittest.TestCase):
method test_rotate (line 261) | def test_rotate(self):
method test_rotate_alt (line 267) | def test_rotate_alt(self):
class TestLicenseNumber (line 274) | class TestLicenseNumber(unittest.TestCase):
method test_license_number (line 282) | def test_license_number(self):
class TestMakeSentence (line 290) | class TestMakeSentence(unittest.TestCase):
method test_make_sentence (line 298) | def test_make_sentence(self):
class TestMergeStringChecker (line 304) | class TestMergeStringChecker(unittest.TestCase):
method test_is_merge_recursive (line 312) | def test_is_merge_recursive(self):
method test_is_merge_iterative (line 315) | def test_is_merge_iterative(self):
class TestMultiplyStrings (line 319) | class TestMultiplyStrings(unittest.TestCase):
method test_multiply (line 327) | def test_multiply(self):
class TestOneEditDistance (line 334) | class TestOneEditDistance(unittest.TestCase):
method test_is_one_edit (line 342) | def test_is_one_edit(self):
method test_is_one_edit2 (line 347) | def test_is_one_edit2(self):
class TestRabinKarp (line 353) | class TestRabinKarp(unittest.TestCase):
method test_rabin_karp (line 361) | def test_rabin_karp(self):
class TestReverseString (line 366) | class TestReverseString(unittest.TestCase):
method test_recursive (line 374) | def test_recursive(self):
method test_iterative (line 377) | def test_iterative(self):
method test_pythonic (line 380) | def test_pythonic(self):
method test_ultra_pythonic (line 383) | def test_ultra_pythonic(self):
class TestReverseVowel (line 387) | class TestReverseVowel(unittest.TestCase):
method test_reverse_vowel (line 395) | def test_reverse_vowel(self):
class TestReverseWords (line 399) | class TestReverseWords(unittest.TestCase):
method test_reverse_words (line 407) | def test_reverse_words(self):
class TestRomanToInt (line 414) | class TestRomanToInt(unittest.TestCase):
method test_roman_to_int (line 422) | def test_roman_to_int(self):
class TestStripUrlParams (line 428) | class TestStripUrlParams(unittest.TestCase):
method test_strip_url_params1 (line 431) | def test_strip_url_params1(self):
method test_strip_url_params2 (line 441) | def test_strip_url_params2(self):
method test_strip_url_params3 (line 451) | def test_strip_url_params3(self):
class TestValidateCoordinates (line 462) | class TestValidateCoordinates(unittest.TestCase):
method test_valid (line 470) | def test_valid(self):
method test_invalid (line 475) | def test_invalid(self):
class TestWordSquares (line 487) | class TestWordSquares(unittest.TestCase):
method test_word_squares (line 495) | def test_word_squares(self):
class TestUniqueMorse (line 502) | class TestUniqueMorse(unittest.TestCase):
method test_convert_morse_word (line 503) | def test_convert_morse_word(self):
method test_unique_morse (line 507) | def test_unique_morse(self):
class TestJudgeCircle (line 511) | class TestJudgeCircle(unittest.TestCase):
method test_judge_circle (line 512) | def test_judge_circle(self):
class TestStrongPassword (line 517) | class TestStrongPassword(unittest.TestCase):
method test_strong_password (line 518) | def test_strong_password(self):
class TestCaesarCipher (line 523) | class TestCaesarCipher(unittest.TestCase):
method test_caesar_cipher (line 524) | def test_caesar_cipher(self):
class TestCheckPangram (line 529) | class TestCheckPangram(unittest.TestCase):
method test_check_pangram (line 530) | def test_check_pangram(self):
class TestContainString (line 535) | class TestContainString(unittest.TestCase):
method test_contain_string (line 536) | def test_contain_string(self):
class TestCountBinarySubstring (line 542) | class TestCountBinarySubstring(unittest.TestCase):
method test_count_binary_substring (line 543) | def test_count_binary_substring(self):
class TestRepeatString (line 549) | class TestRepeatString(unittest.TestCase):
method test_repeat_string (line 550) | def test_repeat_string(self):
class TestTextJustification (line 555) | class TestTextJustification(unittest.TestCase):
method test_text_justification (line 556) | def test_text_justification(self):
class TestMinDistance (line 572) | class TestMinDistance(unittest.TestCase):
method test_min_distance (line 573) | def test_min_distance(self):
class TestMinDistanceDP (line 579) | class TestMinDistanceDP(unittest.TestCase):
method test_min_distance (line 580) | def test_min_distance(self):
class TestLongestCommonPrefix (line 586) | class TestLongestCommonPrefix(unittest.TestCase):
method test_longest_common_prefix (line 587) | def test_longest_common_prefix(self):
class TestFirstUniqueChar (line 599) | class TestFirstUniqueChar(unittest.TestCase):
method test_first_unique_char (line 600) | def test_first_unique_char(self):
class TestRepeatSubstring (line 605) | class TestRepeatSubstring(unittest.TestCase):
method test_repeat_substring (line 606) | def test_repeat_substring(self):
class TestAtbashCipher (line 612) | class TestAtbashCipher(unittest.TestCase):
method test_atbash_cipher (line 620) | def test_atbash_cipher(self):
class TestLongestPalindromicSubstring (line 627) | class TestLongestPalindromicSubstring(unittest.TestCase):
method test_longest_palindromic_substring (line 634) | def test_longest_palindromic_substring(self):
class TestKnuthMorrisPratt (line 641) | class TestKnuthMorrisPratt(unittest.TestCase):
method test_knuth_morris_pratt (line 650) | def test_knuth_morris_pratt(self):
class TestPanagram (line 657) | class TestPanagram(unittest.TestCase):
method test_empty_string (line 665) | def test_empty_string(self):
method test_single_word_non_panagram (line 675) | def test_single_word_non_panagram(self):
method test_fox_panagram_no_spaces (line 685) | def test_fox_panagram_no_spaces(self):
method test_fox_panagram_mixed_case (line 695) | def test_fox_panagram_mixed_case(self):
method test_whitespace_punctuation (line 705) | def test_whitespace_punctuation(self):
method test_fox_panagram (line 715) | def test_fox_panagram(self):
method test_swedish_panagram (line 725) | def test_swedish_panagram(self):
class TestFizzbuzz (line 736) | class TestFizzbuzz(unittest.TestCase):
method test_fizzbuzz (line 741) | def test_fizzbuzz(self):
FILE: tests/test_tree.py
class Node (line 11) | class Node:
method __init__ (line 12) | def __init__(self, val, left=None, right=None):
class TestTraversal (line 18) | class TestTraversal(unittest.TestCase):
method test_preorder (line 19) | def test_preorder(self):
method test_postorder (line 24) | def test_postorder(self):
method test_inorder (line 29) | def test_inorder(self):
function create_tree (line 35) | def create_tree():
class TestBTree (line 49) | class TestBTree(unittest.TestCase):
method setUpClass (line 51) | def setUpClass(cls):
method setUp (line 58) | def setUp(self):
method test_insertion_and_find_even_degree (line 63) | def test_insertion_and_find_even_degree(self):
method test_insertion_and_find_odd_degree (line 72) | def test_insertion_and_find_odd_degree(self):
method test_deletion_even_degree (line 81) | def test_deletion_even_degree(self):
method test_deletion_odd_degree (line 94) | def test_deletion_odd_degree(self):
class TestConstructTreePreorderPostorder (line 108) | class TestConstructTreePreorderPostorder(unittest.TestCase):
method test_construct_tree (line 109) | def test_construct_tree(self):
class TestFenwickTree (line 140) | class TestFenwickTree(unittest.TestCase):
method test_construct_tree_with_update_1 (line 141) | def test_construct_tree_with_update_1(self):
method test_construct_tree_with_update_2 (line 151) | def test_construct_tree_with_update_2(self):
method test_construct_tree_with_update_3 (line 161) | def test_construct_tree_with_update_3(self):
FILE: tests/test_veb_tree.py
class TestVEBTree (line 6) | class TestVEBTree(unittest.TestCase):
method setUp (line 7) | def setUp(self):
method test_insert_and_member (line 10) | def test_insert_and_member(self):
method test_min_max (line 20) | def test_min_max(self):
method test_successor (line 28) | def test_successor(self):
method test_delete (line 36) | def test_delete(self):
method test_invalid_universe (line 44) | def test_invalid_universe(self):
Condensed preview — 440 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,126K chars).
[
{
"path": ".github/workflows/publish.yml",
"chars": 1118,
"preview": "name: Publish to PyPI\n\non:\n release:\n types: [published]\n\njobs:\n build:\n runs-on: ubuntu-latest\n steps:\n "
},
{
"path": ".github/workflows/python-app.yml",
"chars": 703,
"preview": "name: Tests\n\non:\n push:\n branches: [master, main]\n pull_request:\n branches: [master, main]\n\njobs:\n test:\n ru"
},
{
"path": ".gitignore",
"chars": 310,
"preview": "__pycache__/\n*.py[cod]\n*.iml\n*.xml\n.idea/\n.cache/\n.pytest_cache/\n.coverage\n# Setuptools distribution folder.\n/dist/\n# Py"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 3213,
"preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
},
{
"path": "CONTRIBUTING.md",
"chars": 2818,
"preview": "# Contributing\n\nWe love pull requests from everyone. By contributing to this repository, you\nagree to abide by the [Code"
},
{
"path": "LICENSE",
"chars": 1061,
"preview": "MIT License\n\nCopyright (c) 2017 Keon\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof th"
},
{
"path": "MANIFEST.in",
"chars": 55,
"preview": "include README.md\ninclude LICENSE\ninclude algorithms/*\n"
},
{
"path": "README.md",
"chars": 45227,
"preview": "[](https://badge.fury.io/py/algorithms)\n[. Given the\ninitial "
},
{
"path": "algorithms/array/josephus.py",
"chars": 1062,
"preview": "\"\"\"\nJosephus Problem\n\nPeople sit in a circular fashion; every k-th person is eliminated until\neveryone has been removed."
},
{
"path": "algorithms/array/limit.py",
"chars": 1049,
"preview": "\"\"\"\nLimit Array Values\n\nFilter an array to include only elements within a specified minimum and\nmaximum range (inclusive"
},
{
"path": "algorithms/array/longest_non_repeat.py",
"chars": 4208,
"preview": "\"\"\"\nLongest Substring Without Repeating Characters\n\nGiven a string, find the length of the longest substring without rep"
},
{
"path": "algorithms/array/max_ones_index.py",
"chars": 1202,
"preview": "\"\"\"\nMax Ones Index\n\nFind the index of the 0 that, when replaced with 1, produces the longest\ncontinuous sequence of 1s i"
},
{
"path": "algorithms/array/merge_intervals.py",
"chars": 3356,
"preview": "\"\"\"\nMerge Intervals\n\nGiven a collection of intervals, merge all overlapping intervals into a\nconsolidated set.\n\nReferenc"
},
{
"path": "algorithms/array/missing_ranges.py",
"chars": 1104,
"preview": "\"\"\"\nMissing Ranges\n\nFind the ranges of numbers that are missing between a given low and high\nbound, given a sorted array"
},
{
"path": "algorithms/array/move_zeros.py",
"chars": 954,
"preview": "\"\"\"\nMove Zeros\n\nMove all zeros in an array to the end while preserving the relative order\nof the non-zero (and non-integ"
},
{
"path": "algorithms/array/n_sum.py",
"chars": 3948,
"preview": "\"\"\"\nN-Sum\n\nGiven an array of integers, find all unique n-tuples that sum to a target\nvalue. Supports custom sum, compari"
},
{
"path": "algorithms/array/plus_one.py",
"chars": 2200,
"preview": "\"\"\"\nPlus One\n\nGiven a non-negative number represented as an array of digits (big-endian),\nadd one to the number and retu"
},
{
"path": "algorithms/array/remove_duplicates.py",
"chars": 1210,
"preview": "\"\"\"\nRemove Duplicates\n\nRemove duplicate elements from an array while preserving the original order.\nHandles both hashabl"
},
{
"path": "algorithms/array/rotate.py",
"chars": 2294,
"preview": "\"\"\"\nRotate Array\n\nRotate an array of n elements to the right by k steps.\nThree algorithm variants are provided with diff"
},
{
"path": "algorithms/array/summarize_ranges.py",
"chars": 1073,
"preview": "\"\"\"\nSummarize Ranges\n\nGiven a sorted integer array without duplicates, return the summary of its\nranges as a list of (st"
},
{
"path": "algorithms/array/three_sum.py",
"chars": 1413,
"preview": "\"\"\"\nThree Sum\n\nGiven an array of integers, find all unique triplets that sum to zero\nusing the two-pointer technique.\n\nR"
},
{
"path": "algorithms/array/top_1.py",
"chars": 959,
"preview": "\"\"\"\nTop 1 (Mode)\n\nFind the most frequently occurring value(s) in an array. When multiple\nvalues share the highest freque"
},
{
"path": "algorithms/array/trimmean.py",
"chars": 1140,
"preview": "\"\"\"\nTrimmed Mean\n\nCompute the mean of an array after discarding a given percentage of the\nhighest and lowest values. Use"
},
{
"path": "algorithms/array/two_sum.py",
"chars": 843,
"preview": "\"\"\"\nTwo Sum\n\nGiven an array of integers and a target sum, return the indices of the two\nnumbers that add up to the targe"
},
{
"path": "algorithms/backtracking/__init__.py",
"chars": 1440,
"preview": "from .add_operators import add_operators\nfrom .anagram import anagram\nfrom .array_sum_combinations import (\n array_su"
},
{
"path": "algorithms/backtracking/add_operators.py",
"chars": 2239,
"preview": "\"\"\"\nExpression Add Operators\n\nGiven a string of digits and a target value, return all possibilities to\ninsert binary ope"
},
{
"path": "algorithms/backtracking/anagram.py",
"chars": 1054,
"preview": "\"\"\"\nAnagram Checker\n\nGiven two strings, determine if they are anagrams of each other (i.e. one\ncan be rearranged to form"
},
{
"path": "algorithms/backtracking/array_sum_combinations.py",
"chars": 3484,
"preview": "\"\"\"\nArray Sum Combinations\n\nGiven three arrays and a target sum, find all three-element combinations\n(one element from e"
},
{
"path": "algorithms/backtracking/combination_sum.py",
"chars": 1368,
"preview": "\"\"\"\nCombination Sum\n\nGiven a set of candidate numbers (without duplicates) and a target number,\nfind all unique combinat"
},
{
"path": "algorithms/backtracking/factor_combinations.py",
"chars": 2017,
"preview": "\"\"\"\nFactor Combinations\n\nGiven an integer n, return all possible combinations of its factors.\nFactors should be greater "
},
{
"path": "algorithms/backtracking/find_words.py",
"chars": 2529,
"preview": "\"\"\"\nWord Search II\n\nGiven a board of characters and a list of words, find all words that can\nbe constructed from adjacen"
},
{
"path": "algorithms/backtracking/generate_abbreviations.py",
"chars": 1362,
"preview": "\"\"\"\nGeneralized Abbreviations\n\nGiven a word, return all possible generalized abbreviations. Each\nabbreviation replaces c"
},
{
"path": "algorithms/backtracking/generate_parenthesis.py",
"chars": 2240,
"preview": "\"\"\"\nGenerate Parentheses\n\nGiven n pairs of parentheses, generate all combinations of well-formed\nparentheses.\n\nReference"
},
{
"path": "algorithms/backtracking/letter_combination.py",
"chars": 1252,
"preview": "\"\"\"\nLetter Combinations of a Phone Number\n\nGiven a digit string, return all possible letter combinations that the\nnumber"
},
{
"path": "algorithms/backtracking/minimax.py",
"chars": 1603,
"preview": "\"\"\"Minimax — game-tree search with alpha-beta pruning.\n\nThe minimax algorithm finds the optimal move for a two-player ze"
},
{
"path": "algorithms/backtracking/palindrome_partitioning.py",
"chars": 1797,
"preview": "\"\"\"\nPalindrome Partitioning\n\nGiven a string, find all ways to partition it into palindromic substrings.\nThere is always "
},
{
"path": "algorithms/backtracking/pattern_match.py",
"chars": 1766,
"preview": "\"\"\"\nPattern Matching\n\nGiven a pattern and a string, determine if the string follows the same\npattern. A full match means"
},
{
"path": "algorithms/backtracking/permute.py",
"chars": 2214,
"preview": "\"\"\"\nPermutations\n\nGiven a collection of distinct elements, return all possible permutations.\n\nReference: https://en.wiki"
},
{
"path": "algorithms/backtracking/permute_unique.py",
"chars": 1127,
"preview": "\"\"\"\nUnique Permutations\n\nGiven a collection of numbers that might contain duplicates, return all\npossible unique permuta"
},
{
"path": "algorithms/backtracking/subsets.py",
"chars": 1717,
"preview": "\"\"\"\nSubsets\n\nGiven a set of distinct integers, return all possible subsets (the power\nset). The solution set must not co"
},
{
"path": "algorithms/backtracking/subsets_unique.py",
"chars": 1272,
"preview": "\"\"\"\nUnique Subsets\n\nGiven a collection of integers that might contain duplicates, return all\npossible unique subsets (th"
},
{
"path": "algorithms/bit_manipulation/__init__.py",
"chars": 1845,
"preview": "from .add_bitwise_operator import add_bitwise_operator\nfrom .binary_gap import binary_gap\nfrom .bit_operation import cle"
},
{
"path": "algorithms/bit_manipulation/add_bitwise_operator.py",
"chars": 864,
"preview": "\"\"\"\nAdd Bitwise Operator\n\nAdd two positive integers without using the '+' operator, using only\nbitwise operations (AND, "
},
{
"path": "algorithms/bit_manipulation/binary_gap.py",
"chars": 1079,
"preview": "\"\"\"\nBinary Gap\n\nGiven a positive integer N, find and return the longest distance between two\nconsecutive 1-bits in the b"
},
{
"path": "algorithms/bit_manipulation/bit_operation.py",
"chars": 2425,
"preview": "\"\"\"\nFundamental Bit Operations\n\nBasic bit manipulation operations: get, set, clear, and update individual\nbits at a spec"
},
{
"path": "algorithms/bit_manipulation/bytes_int_conversion.py",
"chars": 2239,
"preview": "\"\"\"\nBytes-Integer Conversion\n\nConvert between Python integers and raw byte sequences in both big-endian\nand little-endia"
},
{
"path": "algorithms/bit_manipulation/count_flips_to_convert.py",
"chars": 938,
"preview": "\"\"\"\nCount Flips to Convert\n\nDetermine the minimal number of bits you would need to flip to convert\ninteger A to integer "
},
{
"path": "algorithms/bit_manipulation/count_ones.py",
"chars": 1238,
"preview": "\"\"\"\nCount Ones (Hamming Weight)\n\nCount the number of 1-bits in the binary representation of an unsigned\ninteger using Br"
},
{
"path": "algorithms/bit_manipulation/find_difference.py",
"chars": 962,
"preview": "\"\"\"\nFind the Difference\n\nGiven two strings where the second is generated by shuffling the first and\nadding one extra let"
},
{
"path": "algorithms/bit_manipulation/find_missing_number.py",
"chars": 1558,
"preview": "\"\"\"\nFind Missing Number\n\nGiven a sequence of unique integers in the range [0..n] with one value\nmissing, find and return"
},
{
"path": "algorithms/bit_manipulation/flip_bit_longest_sequence.py",
"chars": 1284,
"preview": "\"\"\"\nFlip Bit Longest Sequence\n\nGiven an integer, find the length of the longest sequence of 1-bits you\ncan create by fli"
},
{
"path": "algorithms/bit_manipulation/gray_code.py",
"chars": 802,
"preview": "\"\"\"Gray code — generate n-bit Gray code sequences.\n\nA Gray code is an ordering of binary numbers such that successive va"
},
{
"path": "algorithms/bit_manipulation/has_alternative_bit.py",
"chars": 1644,
"preview": "\"\"\"\nHas Alternating Bits\n\nCheck whether a positive integer has alternating bits, meaning no two\nadjacent bits share the "
},
{
"path": "algorithms/bit_manipulation/insert_bit.py",
"chars": 1851,
"preview": "\"\"\"\nInsert Bit\n\nInsert one or more bits into an integer at a specific bit position.\n\nReference: https://en.wikipedia.org"
},
{
"path": "algorithms/bit_manipulation/power_of_two.py",
"chars": 764,
"preview": "\"\"\"\nPower of Two\n\nDetermine whether a given integer is a power of two using bit manipulation.\nA power of two has exactly"
},
{
"path": "algorithms/bit_manipulation/remove_bit.py",
"chars": 957,
"preview": "\"\"\"\nRemove Bit\n\nRemove a single bit at a specific position from an integer, shifting\nhigher bits down to fill the gap.\n\n"
},
{
"path": "algorithms/bit_manipulation/reverse_bits.py",
"chars": 710,
"preview": "\"\"\"\nReverse Bits\n\nReverse the bits of a 32-bit unsigned integer.\n\nReference: https://en.wikipedia.org/wiki/Bit_reversal\n"
},
{
"path": "algorithms/bit_manipulation/single_number.py",
"chars": 887,
"preview": "\"\"\"\nSingle Number\n\nGiven an array of integers where every element appears twice except for\none, find the unique element "
},
{
"path": "algorithms/bit_manipulation/single_number2.py",
"chars": 1074,
"preview": "\"\"\"\nSingle Number 2\n\nGiven an array of integers where every element appears three times except\nfor one (which appears ex"
},
{
"path": "algorithms/bit_manipulation/single_number3.py",
"chars": 1167,
"preview": "\"\"\"\nSingle Number 3\n\nGiven an array where exactly two elements appear once and all others\nappear exactly twice, find tho"
},
{
"path": "algorithms/bit_manipulation/subsets.py",
"chars": 1120,
"preview": "\"\"\"\nSubsets via Bit Manipulation\n\nGenerate all possible subsets of a set of distinct integers using bitmask\nenumeration."
},
{
"path": "algorithms/bit_manipulation/swap_pair.py",
"chars": 898,
"preview": "\"\"\"\nSwap Pair\n\nSwap odd and even bits of an integer using bitmask operations. Bit 0 is\nswapped with bit 1, bit 2 with bi"
},
{
"path": "algorithms/common/__init__.py",
"chars": 443,
"preview": "\"\"\"Shared data types used across all algorithm categories.\n\nThese types are the connective tissue of the library — every"
},
{
"path": "algorithms/common/graph.py",
"chars": 3078,
"preview": "\"\"\"Graph type shared across all graph algorithms.\n\nThis module provides the universal Graph used by every graph algorith"
},
{
"path": "algorithms/common/list_node.py",
"chars": 737,
"preview": "\"\"\"Singly linked list node shared across all linked list algorithms.\n\nThis module provides the universal ListNode used b"
},
{
"path": "algorithms/common/tree_node.py",
"chars": 779,
"preview": "\"\"\"Binary tree node shared across all tree algorithms.\n\nThis module provides the universal TreeNode used by every tree a"
},
{
"path": "algorithms/compression/__init__.py",
"chars": 248,
"preview": "from .elias import elias_delta, elias_gamma\nfrom .huffman_coding import HuffmanCoding\nfrom .rle_compression import decod"
},
{
"path": "algorithms/compression/elias.py",
"chars": 2389,
"preview": "\"\"\"\nElias Gamma and Delta Coding\n\nUniversal codes for encoding positive integers. Elias gamma code uses a unary\nprefix f"
},
{
"path": "algorithms/compression/huffman_coding.py",
"chars": 14211,
"preview": "\"\"\"\nHuffman Coding\n\nAn efficient method of lossless data compression. Symbols appearing more\nfrequently are encoded with"
},
{
"path": "algorithms/compression/rle_compression.py",
"chars": 1525,
"preview": "\"\"\"\nRun-Length Encoding (RLE)\n\nA simple lossless compression algorithm that encodes consecutive repeated\ncharacters as a"
},
{
"path": "algorithms/data_structures/__init__.py",
"chars": 2434,
"preview": "\"\"\"Reusable data structure implementations.\n\nThis package contains the core data structures used throughout the library."
},
{
"path": "algorithms/data_structures/avl_tree.py",
"chars": 3452,
"preview": "\"\"\"Imports TreeNodes\"\"\"\n\nfrom algorithms.common.tree_node import TreeNode\n\n\nclass AvlTree:\n \"\"\"\n An avl tree.\n "
},
{
"path": "algorithms/data_structures/b_tree.py",
"chars": 12271,
"preview": "\"\"\"\nB-Tree\n\nA self-balancing tree data structure optimized for disk operations. Each node\n(except root) contains at leas"
},
{
"path": "algorithms/data_structures/bst.py",
"chars": 3521,
"preview": "\"\"\"Binary Search Tree implementation.\n\nA BST is a node-based binary tree where each node's left subtree contains\nonly no"
},
{
"path": "algorithms/data_structures/fenwick_tree.py",
"chars": 2684,
"preview": "\"\"\"\nFenwick Tree / Binary Indexed Tree\n\nConsider we have an array arr[0 . . . n-1]. We would like to\n1. Compute the sum "
},
{
"path": "algorithms/data_structures/graph.py",
"chars": 3762,
"preview": "\"\"\"\nGraph Data Structures\n\nReusable classes for representing nodes, directed edges and directed graphs.\nThese can be sha"
},
{
"path": "algorithms/data_structures/hash_table.py",
"chars": 4922,
"preview": "\"\"\"\nHash Table (Open Addressing)\n\nHash map implementation using open addressing with linear probing\nfor collision resolu"
},
{
"path": "algorithms/data_structures/heap.py",
"chars": 4142,
"preview": "r\"\"\"\nBinary Heap\n\nA min heap is a complete binary tree where each node is smaller than\nits children. The root is the min"
},
{
"path": "algorithms/data_structures/iterative_segment_tree.py",
"chars": 1742,
"preview": "\"\"\"\nSegmentTree creates a segment tree with a given array and a \"commutative\" function,\nthis non-recursive version uses "
},
{
"path": "algorithms/data_structures/kd_tree.py",
"chars": 2378,
"preview": "\"\"\"KD-tree — a space-partitioning tree for k-dimensional points.\n\nSupports efficient nearest-neighbour and range queries"
},
{
"path": "algorithms/data_structures/linked_list.py",
"chars": 1070,
"preview": "\"\"\"\nLinked List Node Definitions\n\nBasic node classes for singly and doubly linked lists, serving as foundational\nbuildin"
},
{
"path": "algorithms/data_structures/priority_queue.py",
"chars": 3010,
"preview": "\"\"\"\nPriority Queue (Linear Array)\n\nA priority queue implementation using a sorted linear array. Elements\nare inserted in"
},
{
"path": "algorithms/data_structures/queue.py",
"chars": 5073,
"preview": "\"\"\"\nQueue Abstract Data Type\n\nImplementations of the queue ADT using both a fixed-size array and a\nlinked list. Both sup"
},
{
"path": "algorithms/data_structures/red_black_tree.py",
"chars": 11261,
"preview": "\"\"\"\nImplementation of Red-Black tree.\n\"\"\"\n\n\nclass RBNode:\n def __init__(self, val, is_red, parent=None, left=None, ri"
},
{
"path": "algorithms/data_structures/segment_tree.py",
"chars": 1616,
"preview": "\"\"\"\nSegment_tree creates a segment tree with a given array and function,\nallowing queries to be done later in log(N) tim"
},
{
"path": "algorithms/data_structures/separate_chaining_hash_table.py",
"chars": 3646,
"preview": "\"\"\"\nSeparate Chaining Hash Table\n\nHash table implementation using separate chaining (linked lists) for\ncollision resolut"
},
{
"path": "algorithms/data_structures/sqrt_decomposition.py",
"chars": 3584,
"preview": "\"\"\"\nSquare Root (Sqrt) Decomposition\n\nDivides an array into blocks of size √n to allow O(√n) range queries and\npoint upd"
},
{
"path": "algorithms/data_structures/stack.py",
"chars": 4642,
"preview": "\"\"\"\nStack Abstract Data Type\n\nImplementations of the stack ADT using both a fixed-size array and a\nlinked list. Both sup"
},
{
"path": "algorithms/data_structures/trie.py",
"chars": 981,
"preview": "\"\"\"\nImplement a trie with insert, search, and startsWith methods.\n\nNote:\nYou may assume that all inputs are consist of l"
},
{
"path": "algorithms/data_structures/union_find.py",
"chars": 2287,
"preview": "\"\"\"\nUnion-Find (Disjoint Set) Data Structure\n\nA Union-Find data structure supporting add, find (root), and unite operati"
},
{
"path": "algorithms/data_structures/veb_tree.py",
"chars": 7424,
"preview": "\"\"\"\nVan Emde Boas Tree (vEB Tree) / van Emde Boas priority queue\n\nReference: https://en.wikipedia.org/wiki/Van_Emde_Boas"
},
{
"path": "algorithms/dynamic_programming/__init__.py",
"chars": 2953,
"preview": "\"\"\"\nDynamic Programming Algorithms\n\nA collection of dynamic programming algorithm implementations.\n\"\"\"\n\nfrom . import re"
},
{
"path": "algorithms/dynamic_programming/bitmask.py",
"chars": 1179,
"preview": "\"\"\"Bitmask dynamic programming — Travelling Salesman Problem (TSP).\n\nUses DP with bitmask to find the minimum-cost Hamil"
},
{
"path": "algorithms/dynamic_programming/buy_sell_stock.py",
"chars": 1585,
"preview": "\"\"\"\nBest Time to Buy and Sell Stock\n\nGiven an array of stock prices, find the maximum profit from a single\nbuy-sell tran"
},
{
"path": "algorithms/dynamic_programming/climbing_stairs.py",
"chars": 1334,
"preview": "\"\"\"\nClimbing Stairs\n\nCount the number of distinct ways to climb a staircase of n steps,\nwhere each move is either 1 or 2"
},
{
"path": "algorithms/dynamic_programming/coin_change.py",
"chars": 902,
"preview": "\"\"\"\nCoin Change (Number of Ways)\n\nGiven a value and a set of coin denominations, count how many distinct\ncombinations of"
},
{
"path": "algorithms/dynamic_programming/combination_sum.py",
"chars": 2094,
"preview": "\"\"\"\nCombination Sum IV\n\nGiven an array of distinct positive integers and a target, find the number\nof possible combinati"
},
{
"path": "algorithms/dynamic_programming/count_paths_dp.py",
"chars": 1077,
"preview": "\"\"\"Count paths in a grid — recursive, memoized, and bottom-up DP.\n\nCount the number of unique paths from the top-left to"
},
{
"path": "algorithms/dynamic_programming/edit_distance.py",
"chars": 1311,
"preview": "\"\"\"\nEdit Distance (Levenshtein Distance)\n\nFind the minimum number of insertions, deletions, and substitutions\nrequired t"
},
{
"path": "algorithms/dynamic_programming/egg_drop.py",
"chars": 1237,
"preview": "\"\"\"\nEgg Drop Problem\n\nGiven K eggs and a building with N floors, determine the minimum number\nof moves needed to find th"
},
{
"path": "algorithms/dynamic_programming/fib.py",
"chars": 1861,
"preview": "\"\"\"\nFibonacci Number\n\nCompute the n-th Fibonacci number using three different approaches:\nrecursive, list-based DP, and "
},
{
"path": "algorithms/dynamic_programming/hosoya_triangle.py",
"chars": 1455,
"preview": "\"\"\"\nHosoya Triangle\n\nThe Hosoya triangle (originally Fibonacci triangle) is a triangular arrangement\nof numbers where ea"
},
{
"path": "algorithms/dynamic_programming/house_robber.py",
"chars": 740,
"preview": "\"\"\"\nHouse Robber\n\nDetermine the maximum amount of money that can be robbed from a row of\nhouses without robbing two adja"
},
{
"path": "algorithms/dynamic_programming/int_divide.py",
"chars": 1032,
"preview": "\"\"\"\nInteger Partition\n\nCount the number of ways a positive integer can be represented as a sum\nof positive integers (ord"
},
{
"path": "algorithms/dynamic_programming/job_scheduling.py",
"chars": 1866,
"preview": "\"\"\"\nWeighted Job Scheduling\n\nGiven a set of jobs with start times, finish times, and profits, find\nthe maximum profit su"
},
{
"path": "algorithms/dynamic_programming/k_factor.py",
"chars": 2503,
"preview": "\"\"\"\nK-Factor of a String\n\nThe K factor of a string is the number of times 'abba' appears as a\nsubstring. Given a length "
},
{
"path": "algorithms/dynamic_programming/knapsack.py",
"chars": 1264,
"preview": "\"\"\"\n0/1 Knapsack Problem\n\nGiven items with values and weights, and a knapsack capacity, find the\nmaximum total value tha"
},
{
"path": "algorithms/dynamic_programming/longest_common_subsequence.py",
"chars": 1019,
"preview": "\"\"\"\nLongest Common Subsequence\n\nFind the length of the longest subsequence common to two strings.\n\nReference: https://en"
},
{
"path": "algorithms/dynamic_programming/longest_increasing.py",
"chars": 4156,
"preview": "\"\"\"\nLongest Increasing Subsequence\n\nFind the length of the longest strictly increasing subsequence in an array.\n\nReferen"
},
{
"path": "algorithms/dynamic_programming/matrix_chain_order.py",
"chars": 1492,
"preview": "\"\"\"\nMatrix Chain Multiplication\n\nFind the optimal parenthesization of a chain of matrices to minimize\nthe total number o"
},
{
"path": "algorithms/dynamic_programming/max_product_subarray.py",
"chars": 2108,
"preview": "\"\"\"\nMaximum Product Subarray\n\nFind the contiguous subarray within an array that has the largest product.\n\nReference: htt"
},
{
"path": "algorithms/dynamic_programming/max_subarray.py",
"chars": 789,
"preview": "\"\"\"\nMaximum Subarray (Kadane's Algorithm)\n\nFind the contiguous subarray with the largest sum.\n\nReference: https://en.wik"
},
{
"path": "algorithms/dynamic_programming/min_cost_path.py",
"chars": 1046,
"preview": "\"\"\"\nMinimum Cost Path\n\nFind the minimum cost to travel from station 0 to station N-1 given\na cost matrix where cost[i][j"
},
{
"path": "algorithms/dynamic_programming/num_decodings.py",
"chars": 1899,
"preview": "\"\"\"\nDecode Ways\n\nGiven an encoded message of digits, count the total number of ways to\ndecode it where 'A' = 1, 'B' = 2,"
},
{
"path": "algorithms/dynamic_programming/planting_trees.py",
"chars": 1819,
"preview": "\"\"\"\nPlanting Trees\n\nGiven an even number of trees along one side of a road, calculate the\nminimum total distance to move"
},
{
"path": "algorithms/dynamic_programming/regex_matching.py",
"chars": 1395,
"preview": "\"\"\"\nRegular Expression Matching\n\nImplement regular expression matching with support for '.' (matches any\nsingle characte"
},
{
"path": "algorithms/dynamic_programming/rod_cut.py",
"chars": 926,
"preview": "\"\"\"\nRod Cutting Problem\n\nGiven a rod of length n and a list of prices for each piece length,\ndetermine the maximum reven"
},
{
"path": "algorithms/dynamic_programming/word_break.py",
"chars": 1019,
"preview": "\"\"\"\nWord Break\n\nGiven a string and a dictionary of words, determine whether the string\ncan be segmented into a sequence "
},
{
"path": "algorithms/graph/__init__.py",
"chars": 4131,
"preview": "\"\"\"\nCollection of graph algorithms.\n\"\"\"\n\nfrom __future__ import annotations\n\nfrom algorithms.data_structures.graph impor"
},
{
"path": "algorithms/graph/a_star.py",
"chars": 1677,
"preview": "\"\"\"\nA* (A-star) Search Algorithm\n\nFinds the shortest path in a weighted graph using a heuristic function.\n\nReference: ht"
},
{
"path": "algorithms/graph/all_factors.py",
"chars": 2308,
"preview": "\"\"\"\nFactor Combinations\n\nGiven an integer n, return all possible combinations of its factors\n(excluding 1 and n itself i"
},
{
"path": "algorithms/graph/all_pairs_shortest_path.py",
"chars": 1262,
"preview": "\"\"\"\nAll-Pairs Shortest Path (Floyd-Warshall)\n\nGiven an n*n adjacency matrix, computes the shortest path between every pa"
},
{
"path": "algorithms/graph/bellman_ford.py",
"chars": 2490,
"preview": "\"\"\"\nBellman-Ford Algorithm for Single-Source Shortest Path\n\nFinds the shortest paths from a source vertex to all other v"
},
{
"path": "algorithms/graph/blossom.py",
"chars": 2467,
"preview": "\"\"\"Edmonds' blossom algorithm — maximum cardinality matching.\n\nFinds a maximum matching in a general (non-bipartite) und"
},
{
"path": "algorithms/graph/check_bipartite.py",
"chars": 1332,
"preview": "\"\"\"\nCheck Bipartite Graph\n\nDetermine whether an undirected graph is bipartite using BFS colouring.\n\nReference: https://e"
},
{
"path": "algorithms/graph/check_digraph_strongly_connected.py",
"chars": 2453,
"preview": "\"\"\"\nCheck if a Directed Graph is Strongly Connected\n\nA directed graph is strongly connected if every vertex is reachable"
},
{
"path": "algorithms/graph/clone_graph.py",
"chars": 3745,
"preview": "\"\"\"\nClone an Undirected Graph\n\nEach node contains a label and a list of its neighbours. Three strategies\nare provided: "
},
{
"path": "algorithms/graph/count_connected_number_of_component.py",
"chars": 1363,
"preview": "\"\"\"\nCount Connected Components in an Undirected Graph\n\nUses DFS to count the number of connected components.\n\nReference:"
},
{
"path": "algorithms/graph/count_islands_bfs.py",
"chars": 1652,
"preview": "\"\"\"\nCount Islands (BFS)\n\nGiven a 2D grid of 1s (land) and 0s (water), count the number of islands\nusing breadth-first se"
},
{
"path": "algorithms/graph/count_islands_dfs.py",
"chars": 1277,
"preview": "\"\"\"\nCount Islands (DFS)\n\nGiven a 2D grid of 1s (land) and 0s (water), count the number of islands\nusing depth-first sear"
},
{
"path": "algorithms/graph/count_islands_unionfind.py",
"chars": 1422,
"preview": "\"\"\"\nCount Islands via Union-Find\n\nUses the Union-Find (Disjoint Set) data structure to solve the \"Number of\nIslands\" pro"
},
{
"path": "algorithms/graph/cycle_detection.py",
"chars": 1829,
"preview": "\"\"\"\nCycle Detection in a Directed Graph\n\nUses DFS with three-colour marking to determine whether a directed graph\ncontai"
},
{
"path": "algorithms/graph/dijkstra.py",
"chars": 2483,
"preview": "\"\"\"\nDijkstra's Single-Source Shortest-Path Algorithm\n\nFinds shortest distances from a source vertex to every other verte"
},
{
"path": "algorithms/graph/dijkstra_heapq.py",
"chars": 2688,
"preview": "\"\"\"\nDijkstra's Shortest-Path Algorithm (Heap-Optimised)\n\nComputes single-source shortest paths in a graph with non-negat"
},
{
"path": "algorithms/graph/find_all_cliques.py",
"chars": 1631,
"preview": "\"\"\"\nFind All Cliques (Bron-Kerbosch)\n\nFinds every maximal clique in an undirected graph.\n\nReference: Bron, Coen; Kerbosc"
},
{
"path": "algorithms/graph/find_path.py",
"chars": 3120,
"preview": "\"\"\"\nFind Paths in a Graph\n\nProvides functions to find a single path, all paths, or the shortest path\nbetween two nodes u"
},
{
"path": "algorithms/graph/graph.py",
"chars": 333,
"preview": "\"\"\"Graph Data Structures (re-export).\n\nThis module re-exports Node, DirectedEdge, and DirectedGraph from the\ncanonical l"
},
{
"path": "algorithms/graph/kahns_algorithm.py",
"chars": 1572,
"preview": "\"\"\"\nKahn's Algorithm (Topological Sort via BFS)\n\nComputes a topological ordering of a directed acyclic graph using an\nin"
},
{
"path": "algorithms/graph/markov_chain.py",
"chars": 1854,
"preview": "\"\"\"\nMarkov Chain\n\nProvides utilities for stepping through and iterating a discrete Markov chain\ndescribed as a dictionar"
},
{
"path": "algorithms/graph/maximum_flow.py",
"chars": 6420,
"preview": "\"\"\"\nMaximum Flow Algorithms\n\nImplements Ford-Fulkerson (DFS), Edmonds-Karp (BFS) and Dinic's algorithm\nfor computing max"
},
{
"path": "algorithms/graph/maximum_flow_bfs.py",
"chars": 1745,
"preview": "\"\"\"\nMaximum Flow via BFS\n\nComputes maximum flow in a network represented as an adjacency matrix,\nusing BFS to find augme"
},
{
"path": "algorithms/graph/maximum_flow_dfs.py",
"chars": 1756,
"preview": "\"\"\"\nMaximum Flow via DFS\n\nComputes maximum flow in a network represented as an adjacency matrix,\nusing DFS to find augme"
},
{
"path": "algorithms/graph/maze_search_bfs.py",
"chars": 1700,
"preview": "\"\"\"\nMaze Search (BFS)\n\nFind the minimum number of steps from the top-left corner to the\nbottom-right corner of a grid. "
},
{
"path": "algorithms/graph/maze_search_dfs.py",
"chars": 1726,
"preview": "\"\"\"\nMaze Search (DFS)\n\nFind the shortest path from the top-left corner to the bottom-right corner\nof a grid using depth-"
},
{
"path": "algorithms/graph/minimum_spanning_tree.py",
"chars": 2655,
"preview": "\"\"\"\nMinimum Spanning Tree (Kruskal's Algorithm)\n\nFinds the MST of an undirected graph using Kruskal's algorithm with a\nd"
},
{
"path": "algorithms/graph/pacific_atlantic.py",
"chars": 2030,
"preview": "\"\"\"\nPacific Atlantic Water Flow\n\nGiven an m*n matrix of heights, find all cells from which water can flow\nto both the Pa"
},
{
"path": "algorithms/graph/path_between_two_vertices_in_digraph.py",
"chars": 2166,
"preview": "\"\"\"\nPath Between Two Vertices in a Directed Graph\n\nDetermines whether there is a directed path from a source vertex to a"
},
{
"path": "algorithms/graph/prims_minimum_spanning.py",
"chars": 1216,
"preview": "\"\"\"\nPrim's Minimum Spanning Tree\n\nComputes the weight of a minimum spanning tree for a connected weighted\nundirected gra"
},
{
"path": "algorithms/graph/satisfiability.py",
"chars": 4749,
"preview": "\"\"\"\n2-SAT Satisfiability\n\nGiven a formula in conjunctive normal form (2-CNF), finds an assignment of\nTrue/False values t"
},
{
"path": "algorithms/graph/shortest_distance_from_all_buildings.py",
"chars": 2263,
"preview": "\"\"\"\nShortest Distance from All Buildings\n\nGiven a 2D grid with buildings (1), empty land (0) and obstacles (2), find\nthe"
},
{
"path": "algorithms/graph/strongly_connected_components_kosaraju.py",
"chars": 2006,
"preview": "\"\"\"\nStrongly Connected Components (Kosaraju's Algorithm)\n\nCounts the number of strongly connected components in a direct"
},
{
"path": "algorithms/graph/sudoku_solver.py",
"chars": 4135,
"preview": "\"\"\"\nSudoku Solver (DFS / Backtracking)\n\nSolves a Sudoku puzzle using constraint propagation and depth-first search\nwith "
},
{
"path": "algorithms/graph/tarjan.py",
"chars": 2014,
"preview": "\"\"\"\nTarjan's Strongly Connected Components Algorithm\n\nFinds all strongly connected components in a directed graph.\n\nRefe"
},
{
"path": "algorithms/graph/topological_sort_bfs.py",
"chars": 1637,
"preview": "\"\"\"\r\nTopological Sort (Kahn's Algorithm / BFS)\r\n\r\nComputes a topological ordering of a directed acyclic graph. Raises\r\n"
},
{
"path": "algorithms/graph/topological_sort_dfs.py",
"chars": 3114,
"preview": "\"\"\"\nTopological Sort\n\nTopological sort produces a linear ordering of vertices in a directed\nacyclic graph (DAG) such tha"
},
{
"path": "algorithms/graph/transitive_closure_dfs.py",
"chars": 1899,
"preview": "\"\"\"\nTransitive Closure via DFS\n\nComputes the transitive closure of a directed graph using depth-first\nsearch.\n\nReference"
},
{
"path": "algorithms/graph/traversal.py",
"chars": 2271,
"preview": "\"\"\"\nGraph Traversal Algorithms\n\nProvides DFS and BFS traversal of a graph represented as an adjacency\ndictionary.\n\nCompl"
},
{
"path": "algorithms/graph/walls_and_gates.py",
"chars": 1303,
"preview": "\"\"\"\nWalls and Gates\n\nFill each empty room (INF) with the distance to its nearest gate (0).\nWalls are represented by -1.\n"
},
{
"path": "algorithms/graph/word_ladder.py",
"chars": 2242,
"preview": "\"\"\"\nWord Ladder (Bidirectional BFS)\n\nGiven two words and a dictionary, find the length of the shortest\ntransformation se"
},
{
"path": "algorithms/greedy/__init__.py",
"chars": 187,
"preview": "from .gale_shapley import gale_shapley\nfrom .max_contiguous_subsequence_sum import max_contiguous_subsequence_sum\n\n__all"
},
{
"path": "algorithms/greedy/gale_shapley.py",
"chars": 1758,
"preview": "\"\"\"\nGale-Shapley Stable Matching\n\nSolves the stable matching (stable marriage) problem. Given N men and N women\nwith ran"
},
{
"path": "algorithms/greedy/max_contiguous_subsequence_sum.py",
"chars": 1183,
"preview": "\"\"\"\nMaximum Contiguous Subsequence Sum (Kadane's Algorithm)\n\nFinds the maximum sum of a contiguous sub-array within a on"
},
{
"path": "algorithms/heap/__init__.py",
"chars": 485,
"preview": "\"\"\"Heap-based algorithm implementations.\"\"\"\n\nfrom __future__ import annotations\n\nfrom algorithms.data_structures.heap im"
},
{
"path": "algorithms/heap/k_closest_points.py",
"chars": 1491,
"preview": "\"\"\"\nK Closest Points to Origin\n\nGiven a list of points, find the k closest to the origin using a max\nheap of size k. For"
},
{
"path": "algorithms/heap/merge_sorted_k_lists.py",
"chars": 1512,
"preview": "\"\"\"\nMerge K Sorted Linked Lists\n\nMerge k sorted linked lists into one sorted linked list using a heap\nfor efficient mini"
},
{
"path": "algorithms/heap/skyline.py",
"chars": 1347,
"preview": "\"\"\"\nSkyline Problem\n\nGiven building triplets [left, right, height], compute the skyline\ncontour as a list of key points "
},
{
"path": "algorithms/heap/sliding_window_max.py",
"chars": 1088,
"preview": "\"\"\"\nSliding Window Maximum (Heap-based)\n\nGiven an array and a window size k, find the maximum element in each\nsliding wi"
},
{
"path": "algorithms/linked_list/__init__.py",
"chars": 2156,
"preview": "\"\"\"Linked list algorithm implementations.\"\"\"\n\nfrom algorithms.data_structures.linked_list import (\n DoublyLinkedListN"
},
{
"path": "algorithms/linked_list/add_two_numbers.py",
"chars": 2616,
"preview": "\"\"\"\nAdd Two Numbers (Linked List)\n\nGiven two non-empty linked lists representing two non-negative integers with\ndigits s"
},
{
"path": "algorithms/linked_list/copy_random_pointer.py",
"chars": 2347,
"preview": "\"\"\"\nCopy List with Random Pointer\n\nGiven a linked list where each node contains an additional random pointer that\ncould "
},
{
"path": "algorithms/linked_list/delete_node.py",
"chars": 1140,
"preview": "\"\"\"\nDelete Node in a Linked List\n\nGiven only access to a node (not the tail) in a singly linked list, delete\nthat node b"
},
{
"path": "algorithms/linked_list/first_cyclic_node.py",
"chars": 1197,
"preview": "\"\"\"\nFirst Cyclic Node\n\nGiven a linked list, find the first node of a cycle in it using Floyd's\ncycle-finding algorithm ("
},
{
"path": "algorithms/linked_list/intersection.py",
"chars": 1728,
"preview": "\"\"\"\nIntersection of Two Linked Lists\n\nGiven two singly linked lists that converge at some node, find and return the\ninte"
},
{
"path": "algorithms/linked_list/is_cyclic.py",
"chars": 1081,
"preview": "\"\"\"\nLinked List Cycle Detection\n\nGiven a linked list, determine if it has a cycle using Floyd's Tortoise and\nHare algori"
},
{
"path": "algorithms/linked_list/is_palindrome.py",
"chars": 3060,
"preview": "\"\"\"\nPalindrome Linked List\n\nDetermine whether a singly linked list is a palindrome. Three approaches are\nprovided: rever"
},
{
"path": "algorithms/linked_list/is_sorted.py",
"chars": 819,
"preview": "\"\"\"\nIs Sorted Linked List\n\nGiven a linked list, determine whether the list is sorted in non-decreasing\norder. An empty l"
},
{
"path": "algorithms/linked_list/kth_to_last.py",
"chars": 2746,
"preview": "\"\"\"\nKth to Last Element\n\nFind the kth to last element of a singly linked list. Three approaches are\nprovided: eval-based"
},
{
"path": "algorithms/linked_list/merge_two_list.py",
"chars": 1872,
"preview": "\"\"\"\nMerge Two Sorted Lists\n\nMerge two sorted linked lists into a single sorted list by splicing together\nthe nodes of th"
},
{
"path": "algorithms/linked_list/partition.py",
"chars": 1476,
"preview": "\"\"\"\nPartition Linked List\n\nPartition a linked list around a value x so that all nodes with values less\nthan x come befor"
},
{
"path": "algorithms/linked_list/remove_duplicates.py",
"chars": 1904,
"preview": "\"\"\"\nRemove Duplicates from Linked List\n\nRemove duplicate values from an unsorted linked list. Two approaches are\nprovide"
},
{
"path": "algorithms/linked_list/remove_range.py",
"chars": 1200,
"preview": "\"\"\"\nRemove Range from Linked List\n\nGiven a linked list and a start and end index, remove the elements at those\nindexes ("
},
{
"path": "algorithms/linked_list/reverse.py",
"chars": 1336,
"preview": "\"\"\"\nReverse Linked List\n\nReverse a singly linked list. Both iterative and recursive solutions are\nprovided.\n\nReference: "
},
{
"path": "algorithms/linked_list/rotate_list.py",
"chars": 986,
"preview": "\"\"\"\nRotate List\n\nGiven a linked list, rotate the list to the right by k places, where k is\nnon-negative.\n\nReference: htt"
},
{
"path": "algorithms/linked_list/swap_in_pairs.py",
"chars": 1141,
"preview": "\"\"\"\nSwap Nodes in Pairs\n\nGiven a linked list, swap every two adjacent nodes and return the new head.\nOnly node links are"
},
{
"path": "algorithms/map/__init__.py",
"chars": 864,
"preview": "\"\"\"Map-based algorithm implementations.\"\"\"\n\nfrom __future__ import annotations\n\nfrom algorithms.data_structures.hash_tab"
},
{
"path": "algorithms/map/is_anagram.py",
"chars": 847,
"preview": "\"\"\"\nIs Anagram\n\nDetermine whether two strings are anagrams of each other by comparing\ncharacter frequency maps.\n\nReferen"
},
{
"path": "algorithms/map/is_isomorphic.py",
"chars": 1115,
"preview": "\"\"\"\nIsomorphic Strings\n\nDetermine if two strings are isomorphic. Two strings are isomorphic if\ncharacters in s can be ma"
},
{
"path": "algorithms/map/longest_common_subsequence.py",
"chars": 1313,
"preview": "\"\"\"\nLongest Common Substring\n\nGiven two strings where the second contains all distinct characters,\nfind the longest comm"
},
{
"path": "algorithms/map/longest_palindromic_subsequence.py",
"chars": 1459,
"preview": "\"\"\"\nLongest Palindromic Substring\n\nFind the length of the longest palindromic substring using dynamic\nprogramming with t"
},
{
"path": "algorithms/map/randomized_set.py",
"chars": 1903,
"preview": "\"\"\"\nRandomized Set\n\nDesign a data structure that supports insert, remove, and getRandom\nin average O(1) time. Uses a lis"
},
{
"path": "algorithms/map/valid_sudoku.py",
"chars": 942,
"preview": "\"\"\"\nValid Sudoku\n\nDetermine if a partially filled 9x9 Sudoku board is valid. A board is\nvalid if each row, column, and 3"
},
{
"path": "algorithms/map/word_pattern.py",
"chars": 1245,
"preview": "\"\"\"\nWord Pattern\n\nGiven a pattern and a string, determine if the string follows the same\npattern via a bijection between"
},
{
"path": "algorithms/math/__init__.py",
"chars": 4247,
"preview": "\"\"\"\nCollection of mathematical algorithms and functions.\n\"\"\"\n\nfrom __future__ import annotations\n\n# Module-level imports"
},
{
"path": "algorithms/math/base_conversion.py",
"chars": 1800,
"preview": "\"\"\"\nInteger Base Conversion\n\nConvert integers between arbitrary bases (2-36). Supports conversion from\ninteger to string"
},
{
"path": "algorithms/math/chinese_remainder_theorem.py",
"chars": 2111,
"preview": "\"\"\"\nChinese Remainder Theorem\n\nSolves a system of simultaneous congruences using the Chinese Remainder\nTheorem. Given pa"
}
]
// ... and 240 more files (download for full content)
About this extraction
This page contains the full source code of the keon/algorithms GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 440 files (1021.7 KB), approximately 284.8k tokens, and a symbol index with 1859 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.