diff --git a/_build/html/.buildinfo b/.buildinfo similarity index 100% rename from _build/html/.buildinfo rename to .buildinfo diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/_build/html/01. Array Hashing/1. Two Sum.html b/01. Array Hashing/1. Two Sum.html similarity index 100% rename from _build/html/01. Array Hashing/1. Two Sum.html rename to 01. Array Hashing/1. Two Sum.html diff --git a/_build/html/01. Array Hashing/128. Longest Consecutive Sequence.html b/01. Array Hashing/128. Longest Consecutive Sequence.html similarity index 100% rename from _build/html/01. Array Hashing/128. Longest Consecutive Sequence.html rename to 01. Array Hashing/128. Longest Consecutive Sequence.html diff --git a/_build/html/01. Array Hashing/217. Contains Duplicate.html b/01. Array Hashing/217. Contains Duplicate.html similarity index 100% rename from _build/html/01. Array Hashing/217. Contains Duplicate.html rename to 01. Array Hashing/217. Contains Duplicate.html diff --git a/_build/html/01. Array Hashing/238. Product of Array Except Self.html b/01. Array Hashing/238. Product of Array Except Self.html similarity index 100% rename from _build/html/01. Array Hashing/238. Product of Array Except Self.html rename to 01. Array Hashing/238. Product of Array Except Self.html diff --git a/_build/html/01. Array Hashing/242. Valid Anagram.html b/01. Array Hashing/242. Valid Anagram.html similarity index 100% rename from _build/html/01. Array Hashing/242. Valid Anagram.html rename to 01. Array Hashing/242. Valid Anagram.html diff --git a/_build/html/01. Array Hashing/347. Top K Frequent Elements.html b/01. Array Hashing/347. Top K Frequent Elements.html similarity index 100% rename from _build/html/01. Array Hashing/347. Top K Frequent Elements.html rename to 01. Array Hashing/347. Top K Frequent Elements.html diff --git a/_build/html/01. Array Hashing/49. Group Anagrams.html b/01. Array Hashing/49. Group Anagrams.html similarity index 100% rename from _build/html/01. Array Hashing/49. Group Anagrams.html rename to 01. Array Hashing/49. Group Anagrams.html diff --git a/_build/html/01. Array Hashing/659. Encode and Decode Strings.html b/01. Array Hashing/659. Encode and Decode Strings.html similarity index 100% rename from _build/html/01. Array Hashing/659. Encode and Decode Strings.html rename to 01. Array Hashing/659. Encode and Decode Strings.html diff --git a/_build/html/01. Array Hashing/README.html b/01. Array Hashing/README.html similarity index 100% rename from _build/html/01. Array Hashing/README.html rename to 01. Array Hashing/README.html diff --git a/_build/html/02. Two Pointers/11. Container With Most Water.html b/02. Two Pointers/11. Container With Most Water.html similarity index 100% rename from _build/html/02. Two Pointers/11. Container With Most Water.html rename to 02. Two Pointers/11. Container With Most Water.html diff --git a/_build/html/02. Two Pointers/125. Valid Palindrome.html b/02. Two Pointers/125. Valid Palindrome.html similarity index 100% rename from _build/html/02. Two Pointers/125. Valid Palindrome.html rename to 02. Two Pointers/125. Valid Palindrome.html diff --git a/_build/html/02. Two Pointers/15. 3Sum.html b/02. Two Pointers/15. 3Sum.html similarity index 100% rename from _build/html/02. Two Pointers/15. 3Sum.html rename to 02. Two Pointers/15. 3Sum.html diff --git a/_build/html/02. Two Pointers/README.html b/02. Two Pointers/README.html similarity index 100% rename from _build/html/02. Two Pointers/README.html rename to 02. Two Pointers/README.html diff --git a/_build/html/03. Sliding Window/121. Best Time to Buy and Sell Stock.html b/03. Sliding Window/121. Best Time to Buy and Sell Stock.html similarity index 100% rename from _build/html/03. Sliding Window/121. Best Time to Buy and Sell Stock.html rename to 03. Sliding Window/121. Best Time to Buy and Sell Stock.html diff --git a/_build/html/03. Sliding Window/3. Longest Substring Without Repeating Characters.html b/03. Sliding Window/3. Longest Substring Without Repeating Characters.html similarity index 100% rename from _build/html/03. Sliding Window/3. Longest Substring Without Repeating Characters.html rename to 03. Sliding Window/3. Longest Substring Without Repeating Characters.html diff --git a/_build/html/03. Sliding Window/424. Longest Repeating Character Replacement.html b/03. Sliding Window/424. Longest Repeating Character Replacement.html similarity index 100% rename from _build/html/03. Sliding Window/424. Longest Repeating Character Replacement.html rename to 03. Sliding Window/424. Longest Repeating Character Replacement.html diff --git a/_build/html/03. Sliding Window/76. Minimum Window Substring.html b/03. Sliding Window/76. Minimum Window Substring.html similarity index 100% rename from _build/html/03. Sliding Window/76. Minimum Window Substring.html rename to 03. Sliding Window/76. Minimum Window Substring.html diff --git a/_build/html/03. Sliding Window/README.html b/03. Sliding Window/README.html similarity index 100% rename from _build/html/03. Sliding Window/README.html rename to 03. Sliding Window/README.html diff --git a/_build/html/04. Stack/20. Valid Parentheses.html b/04. Stack/20. Valid Parentheses.html similarity index 100% rename from _build/html/04. Stack/20. Valid Parentheses.html rename to 04. Stack/20. Valid Parentheses.html diff --git a/_build/html/04. Stack/README.html b/04. Stack/README.html similarity index 100% rename from _build/html/04. Stack/README.html rename to 04. Stack/README.html diff --git a/_build/html/05. Binary Search/153. Find Minimum in Rotated Sorted Array.html b/05. Binary Search/153. Find Minimum in Rotated Sorted Array.html similarity index 100% rename from _build/html/05. Binary Search/153. Find Minimum in Rotated Sorted Array.html rename to 05. Binary Search/153. Find Minimum in Rotated Sorted Array.html diff --git a/_build/html/05. Binary Search/33. Search in Rotated Sorted Array.html b/05. Binary Search/33. Search in Rotated Sorted Array.html similarity index 100% rename from _build/html/05. Binary Search/33. Search in Rotated Sorted Array.html rename to 05. Binary Search/33. Search in Rotated Sorted Array.html diff --git a/_build/html/05. Binary Search/README.html b/05. Binary Search/README.html similarity index 100% rename from _build/html/05. Binary Search/README.html rename to 05. Binary Search/README.html diff --git a/_build/html/06. Linked List/141. Linked List Cycle.html b/06. Linked List/141. Linked List Cycle.html similarity index 100% rename from _build/html/06. Linked List/141. Linked List Cycle.html rename to 06. Linked List/141. Linked List Cycle.html diff --git a/_build/html/06. Linked List/143. Reorder List.html b/06. Linked List/143. Reorder List.html similarity index 100% rename from _build/html/06. Linked List/143. Reorder List.html rename to 06. Linked List/143. Reorder List.html diff --git a/_build/html/06. Linked List/19. Remove Nth Node From End of List.html b/06. Linked List/19. Remove Nth Node From End of List.html similarity index 100% rename from _build/html/06. Linked List/19. Remove Nth Node From End of List.html rename to 06. Linked List/19. Remove Nth Node From End of List.html diff --git a/_build/html/06. Linked List/206. Reverse Linked List.html b/06. Linked List/206. Reverse Linked List.html similarity index 100% rename from _build/html/06. Linked List/206. Reverse Linked List.html rename to 06. Linked List/206. Reverse Linked List.html diff --git a/_build/html/06. Linked List/21. Merge Two Sorted Lists.html b/06. Linked List/21. Merge Two Sorted Lists.html similarity index 100% rename from _build/html/06. Linked List/21. Merge Two Sorted Lists.html rename to 06. Linked List/21. Merge Two Sorted Lists.html diff --git a/_build/html/06. Linked List/23. Merge k Sorted Lists.html b/06. Linked List/23. Merge k Sorted Lists.html similarity index 100% rename from _build/html/06. Linked List/23. Merge k Sorted Lists.html rename to 06. Linked List/23. Merge k Sorted Lists.html diff --git a/_build/html/06. Linked List/README.html b/06. Linked List/README.html similarity index 100% rename from _build/html/06. Linked List/README.html rename to 06. Linked List/README.html diff --git a/_build/html/07. Trees/100. Same Tree.html b/07. Trees/100. Same Tree.html similarity index 100% rename from _build/html/07. Trees/100. Same Tree.html rename to 07. Trees/100. Same Tree.html diff --git a/_build/html/07. Trees/102. Binary Tree Level Order Traversal.html b/07. Trees/102. Binary Tree Level Order Traversal.html similarity index 100% rename from _build/html/07. Trees/102. Binary Tree Level Order Traversal.html rename to 07. Trees/102. Binary Tree Level Order Traversal.html diff --git a/_build/html/07. Trees/104. Maximum Depth of Binary Tree.html b/07. Trees/104. Maximum Depth of Binary Tree.html similarity index 100% rename from _build/html/07. Trees/104. Maximum Depth of Binary Tree.html rename to 07. Trees/104. Maximum Depth of Binary Tree.html diff --git a/_build/html/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.html b/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.html similarity index 100% rename from _build/html/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.html rename to 07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.html diff --git a/_build/html/07. Trees/124. Binary Tree Maximum Path Sum.html b/07. Trees/124. Binary Tree Maximum Path Sum.html similarity index 100% rename from _build/html/07. Trees/124. Binary Tree Maximum Path Sum.html rename to 07. Trees/124. Binary Tree Maximum Path Sum.html diff --git a/_build/html/07. Trees/199. Binary Tree Right Side View.html b/07. Trees/199. Binary Tree Right Side View.html similarity index 100% rename from _build/html/07. Trees/199. Binary Tree Right Side View.html rename to 07. Trees/199. Binary Tree Right Side View.html diff --git a/_build/html/07. Trees/226. Invert Binary Tree.html b/07. Trees/226. Invert Binary Tree.html similarity index 100% rename from _build/html/07. Trees/226. Invert Binary Tree.html rename to 07. Trees/226. Invert Binary Tree.html diff --git a/_build/html/07. Trees/230. Kth Smallest Element in a BST.html b/07. Trees/230. Kth Smallest Element in a BST.html similarity index 100% rename from _build/html/07. Trees/230. Kth Smallest Element in a BST.html rename to 07. Trees/230. Kth Smallest Element in a BST.html diff --git a/_build/html/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.html b/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.html similarity index 100% rename from _build/html/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.html rename to 07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.html diff --git a/_build/html/07. Trees/297. Serialize and Deserialize Binary Tree.html b/07. Trees/297. Serialize and Deserialize Binary Tree.html similarity index 100% rename from _build/html/07. Trees/297. Serialize and Deserialize Binary Tree.html rename to 07. Trees/297. Serialize and Deserialize Binary Tree.html diff --git a/_build/html/07. Trees/572. Subtree of Another Tree.html b/07. Trees/572. Subtree of Another Tree.html similarity index 100% rename from _build/html/07. Trees/572. Subtree of Another Tree.html rename to 07. Trees/572. Subtree of Another Tree.html diff --git a/_build/html/07. Trees/98. Validate Binary Search Tree.html b/07. Trees/98. Validate Binary Search Tree.html similarity index 100% rename from _build/html/07. Trees/98. Validate Binary Search Tree.html rename to 07. Trees/98. Validate Binary Search Tree.html diff --git a/_build/html/07. Trees/README.html b/07. Trees/README.html similarity index 100% rename from _build/html/07. Trees/README.html rename to 07. Trees/README.html diff --git a/_build/html/08. Tries/208. Implement Trie (Prefix Tree).html b/08. Tries/208. Implement Trie (Prefix Tree).html similarity index 100% rename from _build/html/08. Tries/208. Implement Trie (Prefix Tree).html rename to 08. Tries/208. Implement Trie (Prefix Tree).html diff --git a/_build/html/08. Tries/211. Design Add and Search Words Data Structure.html b/08. Tries/211. Design Add and Search Words Data Structure.html similarity index 100% rename from _build/html/08. Tries/211. Design Add and Search Words Data Structure.html rename to 08. Tries/211. Design Add and Search Words Data Structure.html diff --git a/_build/html/08. Tries/212. Word Search II.html b/08. Tries/212. Word Search II.html similarity index 100% rename from _build/html/08. Tries/212. Word Search II.html rename to 08. Tries/212. Word Search II.html diff --git a/_build/html/08. Tries/README.html b/08. Tries/README.html similarity index 100% rename from _build/html/08. Tries/README.html rename to 08. Tries/README.html diff --git a/_build/html/09. Heap - Priority Queue/1046. Last Stone Weight.html b/09. Heap - Priority Queue/1046. Last Stone Weight.html similarity index 100% rename from _build/html/09. Heap - Priority Queue/1046. Last Stone Weight.html rename to 09. Heap - Priority Queue/1046. Last Stone Weight.html diff --git a/_build/html/09. Heap - Priority Queue/295. Find Median from Data Stream.html b/09. Heap - Priority Queue/295. Find Median from Data Stream.html similarity index 100% rename from _build/html/09. Heap - Priority Queue/295. Find Median from Data Stream.html rename to 09. Heap - Priority Queue/295. Find Median from Data Stream.html diff --git a/_build/html/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.html b/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.html similarity index 100% rename from _build/html/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.html rename to 09. Heap - Priority Queue/703. Kth Largest Element in a Stream.html diff --git a/_build/html/09. Heap - Priority Queue/README.html b/09. Heap - Priority Queue/README.html similarity index 100% rename from _build/html/09. Heap - Priority Queue/README.html rename to 09. Heap - Priority Queue/README.html diff --git a/_build/html/10. Backtracking/39. Combination Sum.html b/10. Backtracking/39. Combination Sum.html similarity index 100% rename from _build/html/10. Backtracking/39. Combination Sum.html rename to 10. Backtracking/39. Combination Sum.html diff --git a/_build/html/10. Backtracking/79. Word Search.html b/10. Backtracking/79. Word Search.html similarity index 100% rename from _build/html/10. Backtracking/79. Word Search.html rename to 10. Backtracking/79. Word Search.html diff --git a/_build/html/10. Backtracking/README.html b/10. Backtracking/README.html similarity index 100% rename from _build/html/10. Backtracking/README.html rename to 10. Backtracking/README.html diff --git a/_build/html/11. Graphs/133. Clone Graph.html b/11. Graphs/133. Clone Graph.html similarity index 100% rename from _build/html/11. Graphs/133. Clone Graph.html rename to 11. Graphs/133. Clone Graph.html diff --git a/_build/html/11. Graphs/178. Graph Valid Tree.html b/11. Graphs/178. Graph Valid Tree.html similarity index 100% rename from _build/html/11. Graphs/178. Graph Valid Tree.html rename to 11. Graphs/178. Graph Valid Tree.html diff --git a/_build/html/11. Graphs/200. Number of Islands.html b/11. Graphs/200. Number of Islands.html similarity index 100% rename from _build/html/11. Graphs/200. Number of Islands.html rename to 11. Graphs/200. Number of Islands.html diff --git a/_build/html/11. Graphs/207. Course Schedule.html b/11. Graphs/207. Course Schedule.html similarity index 100% rename from _build/html/11. Graphs/207. Course Schedule.html rename to 11. Graphs/207. Course Schedule.html diff --git a/_build/html/11. Graphs/3651. Number of Connected Components in an Undirected Graph.html b/11. Graphs/3651. Number of Connected Components in an Undirected Graph.html similarity index 100% rename from _build/html/11. Graphs/3651. Number of Connected Components in an Undirected Graph.html rename to 11. Graphs/3651. Number of Connected Components in an Undirected Graph.html diff --git a/_build/html/11. Graphs/417. Pacific Atlantic Water Flow.html b/11. Graphs/417. Pacific Atlantic Water Flow.html similarity index 100% rename from _build/html/11. Graphs/417. Pacific Atlantic Water Flow.html rename to 11. Graphs/417. Pacific Atlantic Water Flow.html diff --git a/_build/html/11. Graphs/README.html b/11. Graphs/README.html similarity index 100% rename from _build/html/11. Graphs/README.html rename to 11. Graphs/README.html diff --git a/_build/html/12. Advanced Graphs/892. Alien Dictionary.html b/12. Advanced Graphs/892. Alien Dictionary.html similarity index 100% rename from _build/html/12. Advanced Graphs/892. Alien Dictionary.html rename to 12. Advanced Graphs/892. Alien Dictionary.html diff --git a/_build/html/12. Advanced Graphs/README.html b/12. Advanced Graphs/README.html similarity index 100% rename from _build/html/12. Advanced Graphs/README.html rename to 12. Advanced Graphs/README.html diff --git a/_build/html/13. One-D Dynamic Programming/198. House Robber.html b/13. One-D Dynamic Programming/198. House Robber.html similarity index 100% rename from _build/html/13. One-D Dynamic Programming/198. House Robber.html rename to 13. One-D Dynamic Programming/198. House Robber.html diff --git a/_build/html/13. One-D Dynamic Programming/213. House Robber II.html b/13. One-D Dynamic Programming/213. House Robber II.html similarity index 100% rename from _build/html/13. One-D Dynamic Programming/213. House Robber II.html rename to 13. One-D Dynamic Programming/213. House Robber II.html diff --git a/_build/html/13. One-D Dynamic Programming/70. Climbing Stairs.html b/13. One-D Dynamic Programming/70. Climbing Stairs.html similarity index 100% rename from _build/html/13. One-D Dynamic Programming/70. Climbing Stairs.html rename to 13. One-D Dynamic Programming/70. Climbing Stairs.html diff --git a/_build/html/13. One-D Dynamic Programming/README.html b/13. One-D Dynamic Programming/README.html similarity index 100% rename from _build/html/13. One-D Dynamic Programming/README.html rename to 13. One-D Dynamic Programming/README.html diff --git a/_build/html/14. Two-D Dynamic Programming/README.html b/14. Two-D Dynamic Programming/README.html similarity index 100% rename from _build/html/14. Two-D Dynamic Programming/README.html rename to 14. Two-D Dynamic Programming/README.html diff --git a/_build/html/15. Greedy/README.html b/15. Greedy/README.html similarity index 100% rename from _build/html/15. Greedy/README.html rename to 15. Greedy/README.html diff --git a/_build/html/16. Intervals/README.html b/16. Intervals/README.html similarity index 100% rename from _build/html/16. Intervals/README.html rename to 16. Intervals/README.html diff --git a/_build/html/17. Math Geometry/README.html b/17. Math Geometry/README.html similarity index 100% rename from _build/html/17. Math Geometry/README.html rename to 17. Math Geometry/README.html diff --git a/_build/html/18. Bit Manipulation/README.html b/18. Bit Manipulation/README.html similarity index 100% rename from _build/html/18. Bit Manipulation/README.html rename to 18. Bit Manipulation/README.html diff --git a/_build/html/Book.html b/Book.html similarity index 100% rename from _build/html/Book.html rename to Book.html diff --git a/Book.ipynb b/Book.ipynb deleted file mode 100644 index e7b4f46..0000000 --- a/Book.ipynb +++ /dev/null @@ -1,400 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "!python -m pip install --upgrade pip\n", - "%pip install jupyter-book" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions\n" - ] - } - ], - "source": [ - "%cd /workspaces/LeetCode-Solutions" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "!jupyter-book toc migrate /workspaces/LeetCode-Solutions/_toc.yml -o /workspaces/LeetCode-Solutions/_toc.yml" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[32m\u001b[1mRunning Jupyter-Book v0.15.1\u001b[0m\n", - "\u001b[34m\u001b[1mSource Folder: \u001b[0m/workspaces/LeetCode-Solutions\n", - "\u001b[34m\u001b[1mConfig Path: \u001b[0m/workspaces/LeetCode-Solutions/_config.yml\n", - "\u001b[34m\u001b[1mOutput Path: \u001b[0m/workspaces/LeetCode-Solutions/_build/html\n", - "\u001b[01mRunning Sphinx v5.0.2\u001b[39;49;00m\n", - "\u001b[01mmaking output directory... \u001b[39;49;00mdone\n", - "[etoc] Changing master_doc to 'README'\n", - "\u001b[01mmyst v0.18.1:\u001b[39;49;00m MdParserConfig(commonmark_only=False, gfm_only=False, enable_extensions=['colon_fence', 'dollarmath', 'linkify', 'substitution', 'tasklist'], disable_syntax=[], all_links_external=False, url_schemes=['mailto', 'http', 'https'], ref_domains=None, highlight_code_blocks=True, number_code_blocks=[], title_to_header=False, heading_anchors=None, heading_slug_func=None, footnote_transition=True, words_per_minute=200, sub_delimiters=('{', '}'), linkify_fuzzy_links=True, dmath_allow_labels=True, dmath_allow_space=True, dmath_allow_digits=True, dmath_double_inline=False, update_mathjax=True, mathjax_classes='tex2jax_process|mathjax_process|math|output_area')\n", - "\u001b[01mmyst-nb v0.17.2:\u001b[39;49;00m NbParserConfig(custom_formats={}, metadata_key='mystnb', cell_metadata_key='mystnb', kernel_rgx_aliases={}, execution_mode='auto', execution_cache_path='', execution_excludepatterns=[], execution_timeout=30, execution_in_temp=False, execution_allow_errors=False, execution_raise_on_error=False, execution_show_tb=False, merge_streams=False, render_plugin='default', remove_code_source=False, remove_code_outputs=False, code_prompt_show='Show code cell {type}', code_prompt_hide='Hide code cell {type}', number_source_lines=False, output_stderr='show', render_text_lexer='myst-ansi', render_error_lexer='ipythontb', render_image_options={}, render_figure_options={}, render_markdown_format='commonmark', output_folder='build', append_css=True, metadata_to_fm=False)\n", - "Using jupyter-cache at: /workspaces/LeetCode-Solutions/_build/.jupyter_cache\n", - "\u001b[01mbuilding [mo]: \u001b[39;49;00mtargets for 0 po files that are out of date\n", - "\u001b[01mbuilding [html]: \u001b[39;49;00mtargets for 77 source files that are out of date\n", - "\u001b[01mupdating environment: \u001b[39;49;00m[new config] 77 added, 0 changed, 0 removed\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/1. Two Sum.ipynb: Executing notebook using local CWD [mystnb] \n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/1. Two Sum.ipynb: Executed notebook in 1.26 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/128. Longest Consecutive Sequence.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/128. Longest Consecutive Sequence.ipynb: Executed notebook in 1.07 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/217. Contains Duplicate.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/217. Contains Duplicate.ipynb: Executed notebook in 1.05 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/238. Product of Array Except Self.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/238. Product of Array Except Self.ipynb: Executed notebook in 0.98 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/242. Valid Anagram.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/242. Valid Anagram.ipynb: Executed notebook in 0.96 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/347. Top K Frequent Elements.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/347. Top K Frequent Elements.ipynb: Executed notebook in 1.00 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/49. Group Anagrams.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/49. Group Anagrams.ipynb: Executed notebook in 1.07 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/659. Encode and Decode Strings.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/659. Encode and Decode Strings.ipynb: Executed notebook in 0.93 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/02. Two Pointers/11. Container With Most Water.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/02. Two Pointers/11. Container With Most Water.ipynb: Executed notebook in 0.88 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/02. Two Pointers/125. Valid Palindrome.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/02. Two Pointers/125. Valid Palindrome.ipynb: Executed notebook in 0.98 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/02. Two Pointers/15. 3Sum.ipynb: Executing notebook using local CWD [mystnb] \n", - "/workspaces/LeetCode-Solutions/02. Two Pointers/15. 3Sum.ipynb: Executed notebook in 1.08 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/03. Sliding Window/121. Best Time to Buy and Sell Stock.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/03. Sliding Window/121. Best Time to Buy and Sell Stock.ipynb: Executed notebook in 0.92 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/03. Sliding Window/3. Longest Substring Without Repeating Characters.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/03. Sliding Window/3. Longest Substring Without Repeating Characters.ipynb: Executed notebook in 0.90 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/03. Sliding Window/424. Longest Repeating Character Replacement.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/03. Sliding Window/424. Longest Repeating Character Replacement.ipynb: Executed notebook in 1.09 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/03. Sliding Window/76. Minimum Window Substring.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/03. Sliding Window/76. Minimum Window Substring.ipynb: Executed notebook in 1.09 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/04. Stack/20. Valid Parentheses.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/04. Stack/20. Valid Parentheses.ipynb: Executed notebook in 0.98 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/05. Binary Search/153. Find Minimum in Rotated Sorted Array.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/05. Binary Search/153. Find Minimum in Rotated Sorted Array.ipynb: Executed notebook in 1.15 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/05. Binary Search/33. Search in Rotated Sorted Array.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/05. Binary Search/33. Search in Rotated Sorted Array.ipynb: Executed notebook in 1.08 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/141. Linked List Cycle.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/141. Linked List Cycle.ipynb: Executed notebook in 1.28 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/143. Reorder List.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/143. Reorder List.ipynb: Executed notebook in 1.01 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/19. Remove Nth Node From End of List.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/19. Remove Nth Node From End of List.ipynb: Executed notebook in 1.10 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/206. Reverse Linked List.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/206. Reverse Linked List.ipynb: Executed notebook in 1.14 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/21. Merge Two Sorted Lists.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/21. Merge Two Sorted Lists.ipynb: Executed notebook in 0.91 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/23. Merge k Sorted Lists.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/23. Merge k Sorted Lists.ipynb: Executed notebook in 1.13 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/100. Same Tree.ipynb: Executing notebook using local CWD [mystnb] \n", - "/workspaces/LeetCode-Solutions/07. Trees/100. Same Tree.ipynb: Executed notebook in 1.07 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/102. Binary Tree Level Order Traversal.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/102. Binary Tree Level Order Traversal.ipynb: Executed notebook in 0.99 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/104. Maximum Depth of Binary Tree.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/104. Maximum Depth of Binary Tree.ipynb: Executed notebook in 0.91 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.ipynb: Executed notebook in 1.17 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/124. Binary Tree Maximum Path Sum.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/124. Binary Tree Maximum Path Sum.ipynb: Executed notebook in 0.99 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/199. Binary Tree Right Side View.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/199. Binary Tree Right Side View.ipynb: Executed notebook in 1.07 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/226. Invert Binary Tree.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/226. Invert Binary Tree.ipynb: Executed notebook in 0.96 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/230. Kth Smallest Element in a BST.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/230. Kth Smallest Element in a BST.ipynb: Executed notebook in 0.98 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.ipynb: Executed notebook in 1.11 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/297. Serialize and Deserialize Binary Tree.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/297. Serialize and Deserialize Binary Tree.ipynb: Executed notebook in 0.98 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/572. Subtree of Another Tree.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/572. Subtree of Another Tree.ipynb: Executed notebook in 1.16 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/98. Validate Binary Search Tree.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/98. Validate Binary Search Tree.ipynb: Executed notebook in 1.15 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/08. Tries/208. Implement Trie (Prefix Tree).ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/08. Tries/208. Implement Trie (Prefix Tree).ipynb: Executed notebook in 0.98 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/08. Tries/211. Design Add and Search Words Data Structure.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/08. Tries/211. Design Add and Search Words Data Structure.ipynb: Executed notebook in 1.05 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/08. Tries/212. Word Search II.ipynb: Executing notebook using local CWD [mystnb] \n", - "/workspaces/LeetCode-Solutions/08. Tries/212. Word Search II.ipynb: Executed notebook in 1.27 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/09. Heap - Priority Queue/1046. Last Stone Weight.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/09. Heap - Priority Queue/1046. Last Stone Weight.ipynb: Executed notebook in 0.93 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/09. Heap - Priority Queue/295. Find Median from Data Stream.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/09. Heap - Priority Queue/295. Find Median from Data Stream.ipynb: Executed notebook in 1.06 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.ipynb: Executed notebook in 0.87 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/10. Backtracking/39. Combination Sum.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/10. Backtracking/39. Combination Sum.ipynb: Executed notebook in 1.24 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/10. Backtracking/79. Word Search.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/10. Backtracking/79. Word Search.ipynb: Executed notebook in 4.03 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/133. Clone Graph.ipynb: Executing notebook using local CWD [mystnb] \n", - "/workspaces/LeetCode-Solutions/11. Graphs/133. Clone Graph.ipynb: Executed notebook in 1.08 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/178. Graph Valid Tree.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/178. Graph Valid Tree.ipynb: Executed notebook in 1.12 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/200. Number of Islands.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/200. Number of Islands.ipynb: Executed notebook in 1.08 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/207. Course Schedule.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/207. Course Schedule.ipynb: Executed notebook in 1.09 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/3651. Number of Connected Components in an Undirected Graph.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/3651. Number of Connected Components in an Undirected Graph.ipynb: Executed notebook in 4.02 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/417. Pacific Atlantic Water Flow.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/417. Pacific Atlantic Water Flow.ipynb: Executed notebook in 0.87 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/12. Advanced Graphs/892. Alien Dictionary.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/12. Advanced Graphs/892. Alien Dictionary.ipynb: Executed notebook in 1.12 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/13. One-D Dynamic Programming/198. House Robber.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/13. One-D Dynamic Programming/198. House Robber.ipynb: Executed notebook in 0.99 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/13. One-D Dynamic Programming/213. House Robber II.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/13. One-D Dynamic Programming/213. House Robber II.ipynb: Executed notebook in 1.08 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/13. One-D Dynamic Programming/70. Climbing Stairs.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/13. One-D Dynamic Programming/70. Climbing Stairs.ipynb: Executed notebook in 1.06 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/Book.ipynb: Executing notebook using local CWD [mystnb] \n", - "\u001b[01mreading sources... \u001b[39;49;00m[100%] \u001b[35mSECURITY\u001b[39;49;00m \n", - "\u001b[91m/workspaces/LeetCode-Solutions/07. Trees/572. Subtree of Another Tree.ipynb:30008: WARNING: Non-consecutive header level increase; H1 to H3 [myst.header]\u001b[39;49;00m\n", - "\u001b[91m/workspaces/LeetCode-Solutions/Book.ipynb: WARNING: Executing notebook failed: CellTimeoutError [mystnb.exec]\u001b[39;49;00m\n", - "\u001b[91m/workspaces/LeetCode-Solutions/Book.ipynb: WARNING: Notebook exception traceback saved in: /workspaces/LeetCode-Solutions/_build/html/reports/Book.err.log [mystnb.exec]\u001b[39;49;00m\n", - "\u001b[01mlooking for now-outdated files... \u001b[39;49;00mnone found\n", - "\u001b[01mpickling environment... \u001b[39;49;00mdone\n", - "\u001b[01mchecking consistency... \u001b[39;49;00m\u001b[91m/workspaces/LeetCode-Solutions/Book.ipynb: WARNING: document isn't included in any toctree\u001b[39;49;00m\n", - "\u001b[91m/workspaces/LeetCode-Solutions/CODE_OF_CONDUCT.md: WARNING: document isn't included in any toctree\u001b[39;49;00m\n", - "\u001b[91m/workspaces/LeetCode-Solutions/CONTRIBUTING.md: WARNING: document isn't included in any toctree\u001b[39;49;00m\n", - "\u001b[91m/workspaces/LeetCode-Solutions/SECURITY.md: WARNING: document isn't included in any toctree\u001b[39;49;00m\n", - "done\n", - "\u001b[01mpreparing documents... \u001b[39;49;00mdone\n", - "\u001b[01mwriting output... \u001b[39;49;00m[100%] \u001b[32mSECURITY\u001b[39;49;00m raph\u001b[39;49;00m0m\n", - "\u001b[91m/workspaces/LeetCode-Solutions/CONTRIBUTING.md:8: WARNING: 'myst' reference target not found: #ways-to-contribute\u001b[39;49;00m\n", - "\u001b[91m/workspaces/LeetCode-Solutions/CONTRIBUTING.md:9: WARNING: 'myst' reference target not found: #getting-started\u001b[39;49;00m\n", - "\u001b[91m/workspaces/LeetCode-Solutions/CONTRIBUTING.md:10: WARNING: 'myst' reference target not found: #contributing-process\u001b[39;49;00m\n", - "\u001b[91m/workspaces/LeetCode-Solutions/CONTRIBUTING.md:11: WARNING: 'myst' reference target not found: #code-of-conduct\u001b[39;49;00m\n", - "\u001b[01mgenerating indices... \u001b[39;49;00mgenindex done\n", - "\u001b[01mwriting additional pages... \u001b[39;49;00msearch done\n", - "\u001b[01mcopying static files... \u001b[39;49;00mdone\n", - "\u001b[01mcopying extra files... \u001b[39;49;00mdone\n", - "\u001b[01mdumping search index in English (code: en)... \u001b[39;49;00mdone\n", - "\u001b[01mdumping object inventory... \u001b[39;49;00mdone\n", - "[etoc] missing index.html written as redirect to 'README.html'\n", - "\u001b[01mbuild succeeded, 11 warnings.\u001b[39;49;00m\n", - "\n", - "The HTML pages are in _build/html.\n", - "\n", - "\u001b[92m===============================================================================\u001b[0m\n", - "\n", - "Finished generating HTML for book.\n", - "Your book's HTML pages are here:\n", - " _build/html/\n", - "You can look at your book by opening this file in a browser:\n", - " _build/html/index.html\n", - "Or paste this line directly into your browser bar:\n", - " file:///workspaces/LeetCode-Solutions/_build/html/index.html \n", - "\n", - "\u001b[92m===============================================================================\u001b[0m\n", - "\n" - ] - } - ], - "source": [ - "!jupyter-book build ." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "!jupyter-book build /workspaces/LeetCode-Solutions/ --builder pdfhtml" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "Click here to view your Jupyter Book" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from IPython.display import HTML\n", - "HTML('Click here to view your Jupyter Book')\n" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "\u001b[92m===============================================================================\u001b[0m\n", - "\n", - "Your book template can be found at\n", - "\n", - " mybook/\n", - "\n", - "\u001b[92m===============================================================================\u001b[0m\n", - "\n" - ] - } - ], - "source": [ - "!jupyter-book create mybook" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[32m\u001b[1mRunning Jupyter-Book v0.15.1\u001b[0m\n", - "\u001b[34m\u001b[1mSource Folder: \u001b[0m/workspaces/LeetCode-Solutions/mybook\n", - "\u001b[34m\u001b[1mConfig Path: \u001b[0m/workspaces/LeetCode-Solutions/mybook/_config.yml\n", - "\u001b[34m\u001b[1mOutput Path: \u001b[0m/workspaces/LeetCode-Solutions/mybook/_build/html\n", - "[sphinxcontrib-bibtex] Beware that docutils versions 0.18 and 0.19 (you are running 0.18.1) are known to generate invalid html for citations. If this issue affects you, please use docutils<0.18 (or >=0.20 once released) instead. For more details, see https://sourceforge.net/p/docutils/patches/195/\n", - "\u001b[01mRunning Sphinx v5.0.2\u001b[39;49;00m\n", - "[etoc] Changing master_doc to 'intro'\n", - "checking bibtex cache... out of date\n", - "parsing bibtex file /workspaces/LeetCode-Solutions/mybook/references.bib... parsed 5 entries\n", - "\u001b[01mmyst v0.18.1:\u001b[39;49;00m MdParserConfig(commonmark_only=False, gfm_only=False, enable_extensions=['colon_fence', 'dollarmath', 'linkify', 'substitution', 'tasklist'], disable_syntax=[], all_links_external=False, url_schemes=['mailto', 'http', 'https'], ref_domains=None, highlight_code_blocks=True, number_code_blocks=[], title_to_header=False, heading_anchors=None, heading_slug_func=None, footnote_transition=True, words_per_minute=200, sub_delimiters=('{', '}'), linkify_fuzzy_links=True, dmath_allow_labels=True, dmath_allow_space=True, dmath_allow_digits=True, dmath_double_inline=False, update_mathjax=True, mathjax_classes='tex2jax_process|mathjax_process|math|output_area')\n", - "\u001b[01mmyst-nb v0.17.2:\u001b[39;49;00m NbParserConfig(custom_formats={}, metadata_key='mystnb', cell_metadata_key='mystnb', kernel_rgx_aliases={}, execution_mode='force', execution_cache_path='', execution_excludepatterns=[], execution_timeout=30, execution_in_temp=False, execution_allow_errors=False, execution_raise_on_error=False, execution_show_tb=False, merge_streams=False, render_plugin='default', remove_code_source=False, remove_code_outputs=False, code_prompt_show='Show code cell {type}', code_prompt_hide='Hide code cell {type}', number_source_lines=False, output_stderr='show', render_text_lexer='myst-ansi', render_error_lexer='ipythontb', render_image_options={}, render_figure_options={}, render_markdown_format='commonmark', output_folder='build', append_css=True, metadata_to_fm=False)\n", - "Using jupyter-cache at: /workspaces/LeetCode-Solutions/mybook/_build/.jupyter_cache\n", - "\u001b[01mbuilding [mo]: \u001b[39;49;00mtargets for 0 po files that are out of date\n", - "\u001b[01mbuilding [html]: \u001b[39;49;00mtargets for 14 source files that are out of date\n", - "\u001b[01mupdating environment: \u001b[39;49;00m[new config] 14 added, 0 changed, 0 removed\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/1. Two Sum.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/1. Two Sum.ipynb: Executed notebook in 1.35 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/128. Longest Consecutive Sequence.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/128. Longest Consecutive Sequence.ipynb: Executed notebook in 1.09 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/217. Contains Duplicate.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/217. Contains Duplicate.ipynb: Executed notebook in 1.04 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/238. Product of Array Except Self.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/238. Product of Array Except Self.ipynb: Executed notebook in 4.02 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/242. Valid Anagram.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/242. Valid Anagram.ipynb: Executed notebook in 0.97 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/347. Top K Frequent Elements.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/347. Top K Frequent Elements.ipynb: Executed notebook in 1.14 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/49. Group Anagrams.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/49. Group Anagrams.ipynb: Executed notebook in 0.88 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/659. Encode and Decode Strings.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/659. Encode and Decode Strings.ipynb: Executed notebook in 1.10 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/11. Container With Most Water.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/11. Container With Most Water.ipynb: Executed notebook in 1.12 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/125. Valid Palindrome.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/125. Valid Palindrome.ipynb: Executed notebook in 0.98 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/15. 3Sum.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/15. 3Sum.ipynb: Executed notebook in 0.83 seconds [mystnb]\n", - "\u001b[01mreading sources... \u001b[39;49;00m[100%] \u001b[35mintro\u001b[39;49;00m \n", - "\u001b[01mlooking for now-outdated files... \u001b[39;49;00mnone found\n", - "\u001b[01mpickling environment... \u001b[39;49;00mdone\n", - "\u001b[01mchecking consistency... \u001b[39;49;00m\u001b[91m/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/README.md: WARNING: document isn't included in any toctree\u001b[39;49;00m\n", - "\u001b[91m/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/README.md: WARNING: document isn't included in any toctree\u001b[39;49;00m\n", - "done\n", - "\u001b[01mpreparing documents... \u001b[39;49;00mdone\n", - "\u001b[01mwriting output... \u001b[39;49;00m[100%] \u001b[32mintro\u001b[39;49;00m \n", - "\u001b[01mgenerating indices... \u001b[39;49;00mgenindex done\n", - "\u001b[01mwriting additional pages... \u001b[39;49;00msearch done\n", - "\u001b[01mcopying static files... \u001b[39;49;00mdone\n", - "\u001b[01mcopying extra files... \u001b[39;49;00mdone\n", - "\u001b[01mdumping search index in English (code: en)... \u001b[39;49;00mdone\n", - "\u001b[01mdumping object inventory... \u001b[39;49;00mdone\n", - "[etoc] missing index.html written as redirect to 'intro.html'\n", - "\u001b[01mbuild succeeded, 2 warnings.\u001b[39;49;00m\n", - "\n", - "The HTML pages are in mybook/_build/html.\n", - "\n", - "\u001b[92m===============================================================================\u001b[0m\n", - "\n", - "Finished generating HTML for book.\n", - "Your book's HTML pages are here:\n", - " mybook/_build/html/\n", - "You can look at your book by opening this file in a browser:\n", - " mybook/_build/html/index.html\n", - "Or paste this line directly into your browser bar:\n", - " file:///workspaces/LeetCode-Solutions/mybook/_build/html/index.html \n", - "\n", - "\u001b[92m===============================================================================\u001b[0m\n", - "\n" - ] - } - ], - "source": [ - "!jupyter-book build mybook" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "format: jb-book\n", - "root: intro\n", - "\n" - ] - } - ], - "source": [ - "!jupyter-book toc from-project /workspaces/LeetCode-Solutions/mybook/ -f jb-book" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/_build/html/CODE_OF_CONDUCT.html b/CODE_OF_CONDUCT.html similarity index 100% rename from _build/html/CODE_OF_CONDUCT.html rename to CODE_OF_CONDUCT.html diff --git a/_build/html/CONTRIBUTING.html b/CONTRIBUTING.html similarity index 100% rename from _build/html/CONTRIBUTING.html rename to CONTRIBUTING.html diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 8818d1f..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Mohsen Tabibian - -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. diff --git a/_build/html/README.html b/README.html similarity index 100% rename from _build/html/README.html rename to README.html diff --git a/_build/html/SECURITY.html b/SECURITY.html similarity index 100% rename from _build/html/SECURITY.html rename to SECURITY.html diff --git a/_build/.doctrees/01. Array Hashing/1. Two Sum.doctree b/_build/.doctrees/01. Array Hashing/1. Two Sum.doctree deleted file mode 100644 index 5390e09..0000000 Binary files a/_build/.doctrees/01. Array Hashing/1. Two Sum.doctree and /dev/null differ diff --git a/_build/.doctrees/01. Array Hashing/128. Longest Consecutive Sequence.doctree b/_build/.doctrees/01. Array Hashing/128. Longest Consecutive Sequence.doctree deleted file mode 100644 index 28888ec..0000000 Binary files a/_build/.doctrees/01. Array Hashing/128. Longest Consecutive Sequence.doctree and /dev/null differ diff --git a/_build/.doctrees/01. Array Hashing/217. Contains Duplicate.doctree b/_build/.doctrees/01. Array Hashing/217. Contains Duplicate.doctree deleted file mode 100644 index b30e57f..0000000 Binary files a/_build/.doctrees/01. Array Hashing/217. Contains Duplicate.doctree and /dev/null differ diff --git a/_build/.doctrees/01. Array Hashing/238. Product of Array Except Self.doctree b/_build/.doctrees/01. Array Hashing/238. Product of Array Except Self.doctree deleted file mode 100644 index d1df60d..0000000 Binary files a/_build/.doctrees/01. Array Hashing/238. Product of Array Except Self.doctree and /dev/null differ diff --git a/_build/.doctrees/01. Array Hashing/242. Valid Anagram.doctree b/_build/.doctrees/01. Array Hashing/242. Valid Anagram.doctree deleted file mode 100644 index 8187aae..0000000 Binary files a/_build/.doctrees/01. Array Hashing/242. Valid Anagram.doctree and /dev/null differ diff --git a/_build/.doctrees/01. Array Hashing/347. Top K Frequent Elements.doctree b/_build/.doctrees/01. Array Hashing/347. Top K Frequent Elements.doctree deleted file mode 100644 index 127b43b..0000000 Binary files a/_build/.doctrees/01. Array Hashing/347. Top K Frequent Elements.doctree and /dev/null differ diff --git a/_build/.doctrees/01. Array Hashing/49. Group Anagrams.doctree b/_build/.doctrees/01. Array Hashing/49. Group Anagrams.doctree deleted file mode 100644 index 13c81c2..0000000 Binary files a/_build/.doctrees/01. Array Hashing/49. Group Anagrams.doctree and /dev/null differ diff --git a/_build/.doctrees/01. Array Hashing/659. Encode and Decode Strings.doctree b/_build/.doctrees/01. Array Hashing/659. Encode and Decode Strings.doctree deleted file mode 100644 index 3b9c658..0000000 Binary files a/_build/.doctrees/01. Array Hashing/659. Encode and Decode Strings.doctree and /dev/null differ diff --git a/_build/.doctrees/01. Array Hashing/README.doctree b/_build/.doctrees/01. Array Hashing/README.doctree deleted file mode 100644 index f9bd117..0000000 Binary files a/_build/.doctrees/01. Array Hashing/README.doctree and /dev/null differ diff --git a/_build/.doctrees/02. Two Pointers/11. Container With Most Water.doctree b/_build/.doctrees/02. Two Pointers/11. Container With Most Water.doctree deleted file mode 100644 index 6939264..0000000 Binary files a/_build/.doctrees/02. Two Pointers/11. Container With Most Water.doctree and /dev/null differ diff --git a/_build/.doctrees/02. Two Pointers/125. Valid Palindrome.doctree b/_build/.doctrees/02. Two Pointers/125. Valid Palindrome.doctree deleted file mode 100644 index fab66a6..0000000 Binary files a/_build/.doctrees/02. Two Pointers/125. Valid Palindrome.doctree and /dev/null differ diff --git a/_build/.doctrees/02. Two Pointers/15. 3Sum.doctree b/_build/.doctrees/02. Two Pointers/15. 3Sum.doctree deleted file mode 100644 index db856f1..0000000 Binary files a/_build/.doctrees/02. Two Pointers/15. 3Sum.doctree and /dev/null differ diff --git a/_build/.doctrees/02. Two Pointers/README.doctree b/_build/.doctrees/02. Two Pointers/README.doctree deleted file mode 100644 index 311c6a1..0000000 Binary files a/_build/.doctrees/02. Two Pointers/README.doctree and /dev/null differ diff --git a/_build/.doctrees/03. Sliding Window/121. Best Time to Buy and Sell Stock.doctree b/_build/.doctrees/03. Sliding Window/121. Best Time to Buy and Sell Stock.doctree deleted file mode 100644 index a6bbeb3..0000000 Binary files a/_build/.doctrees/03. Sliding Window/121. Best Time to Buy and Sell Stock.doctree and /dev/null differ diff --git a/_build/.doctrees/03. Sliding Window/3. Longest Substring Without Repeating Characters.doctree b/_build/.doctrees/03. Sliding Window/3. Longest Substring Without Repeating Characters.doctree deleted file mode 100644 index 3d83c09..0000000 Binary files a/_build/.doctrees/03. Sliding Window/3. Longest Substring Without Repeating Characters.doctree and /dev/null differ diff --git a/_build/.doctrees/03. Sliding Window/424. Longest Repeating Character Replacement.doctree b/_build/.doctrees/03. Sliding Window/424. Longest Repeating Character Replacement.doctree deleted file mode 100644 index a107741..0000000 Binary files a/_build/.doctrees/03. Sliding Window/424. Longest Repeating Character Replacement.doctree and /dev/null differ diff --git a/_build/.doctrees/03. Sliding Window/76. Minimum Window Substring.doctree b/_build/.doctrees/03. Sliding Window/76. Minimum Window Substring.doctree deleted file mode 100644 index 55bd42c..0000000 Binary files a/_build/.doctrees/03. Sliding Window/76. Minimum Window Substring.doctree and /dev/null differ diff --git a/_build/.doctrees/03. Sliding Window/README.doctree b/_build/.doctrees/03. Sliding Window/README.doctree deleted file mode 100644 index 384aba6..0000000 Binary files a/_build/.doctrees/03. Sliding Window/README.doctree and /dev/null differ diff --git a/_build/.doctrees/04. Stack/20. Valid Parentheses.doctree b/_build/.doctrees/04. Stack/20. Valid Parentheses.doctree deleted file mode 100644 index e3a1f1d..0000000 Binary files a/_build/.doctrees/04. Stack/20. Valid Parentheses.doctree and /dev/null differ diff --git a/_build/.doctrees/04. Stack/README.doctree b/_build/.doctrees/04. Stack/README.doctree deleted file mode 100644 index b68b301..0000000 Binary files a/_build/.doctrees/04. Stack/README.doctree and /dev/null differ diff --git a/_build/.doctrees/05. Binary Search/153. Find Minimum in Rotated Sorted Array.doctree b/_build/.doctrees/05. Binary Search/153. Find Minimum in Rotated Sorted Array.doctree deleted file mode 100644 index f3ad3ed..0000000 Binary files a/_build/.doctrees/05. Binary Search/153. Find Minimum in Rotated Sorted Array.doctree and /dev/null differ diff --git a/_build/.doctrees/05. Binary Search/33. Search in Rotated Sorted Array.doctree b/_build/.doctrees/05. Binary Search/33. Search in Rotated Sorted Array.doctree deleted file mode 100644 index cce41ea..0000000 Binary files a/_build/.doctrees/05. Binary Search/33. Search in Rotated Sorted Array.doctree and /dev/null differ diff --git a/_build/.doctrees/05. Binary Search/README.doctree b/_build/.doctrees/05. Binary Search/README.doctree deleted file mode 100644 index e9ea47d..0000000 Binary files a/_build/.doctrees/05. Binary Search/README.doctree and /dev/null differ diff --git a/_build/.doctrees/06. Linked List/141. Linked List Cycle.doctree b/_build/.doctrees/06. Linked List/141. Linked List Cycle.doctree deleted file mode 100644 index ebdec70..0000000 Binary files a/_build/.doctrees/06. Linked List/141. Linked List Cycle.doctree and /dev/null differ diff --git a/_build/.doctrees/06. Linked List/143. Reorder List.doctree b/_build/.doctrees/06. Linked List/143. Reorder List.doctree deleted file mode 100644 index 93ebdf1..0000000 Binary files a/_build/.doctrees/06. Linked List/143. Reorder List.doctree and /dev/null differ diff --git a/_build/.doctrees/06. Linked List/19. Remove Nth Node From End of List.doctree b/_build/.doctrees/06. Linked List/19. Remove Nth Node From End of List.doctree deleted file mode 100644 index 36946e4..0000000 Binary files a/_build/.doctrees/06. Linked List/19. Remove Nth Node From End of List.doctree and /dev/null differ diff --git a/_build/.doctrees/06. Linked List/206. Reverse Linked List.doctree b/_build/.doctrees/06. Linked List/206. Reverse Linked List.doctree deleted file mode 100644 index b8ca05c..0000000 Binary files a/_build/.doctrees/06. Linked List/206. Reverse Linked List.doctree and /dev/null differ diff --git a/_build/.doctrees/06. Linked List/21. Merge Two Sorted Lists.doctree b/_build/.doctrees/06. Linked List/21. Merge Two Sorted Lists.doctree deleted file mode 100644 index c3fd916..0000000 Binary files a/_build/.doctrees/06. Linked List/21. Merge Two Sorted Lists.doctree and /dev/null differ diff --git a/_build/.doctrees/06. Linked List/23. Merge k Sorted Lists.doctree b/_build/.doctrees/06. Linked List/23. Merge k Sorted Lists.doctree deleted file mode 100644 index 3941f1c..0000000 Binary files a/_build/.doctrees/06. Linked List/23. Merge k Sorted Lists.doctree and /dev/null differ diff --git a/_build/.doctrees/06. Linked List/README.doctree b/_build/.doctrees/06. Linked List/README.doctree deleted file mode 100644 index 33630e1..0000000 Binary files a/_build/.doctrees/06. Linked List/README.doctree and /dev/null differ diff --git a/_build/.doctrees/07. Trees/100. Same Tree.doctree b/_build/.doctrees/07. Trees/100. Same Tree.doctree deleted file mode 100644 index 4f27ba5..0000000 Binary files a/_build/.doctrees/07. Trees/100. Same Tree.doctree and /dev/null differ diff --git a/_build/.doctrees/07. Trees/102. Binary Tree Level Order Traversal.doctree b/_build/.doctrees/07. Trees/102. Binary Tree Level Order Traversal.doctree deleted file mode 100644 index ad0d709..0000000 Binary files a/_build/.doctrees/07. Trees/102. Binary Tree Level Order Traversal.doctree and /dev/null differ diff --git a/_build/.doctrees/07. Trees/104. Maximum Depth of Binary Tree.doctree b/_build/.doctrees/07. Trees/104. Maximum Depth of Binary Tree.doctree deleted file mode 100644 index d337a7f..0000000 Binary files a/_build/.doctrees/07. Trees/104. Maximum Depth of Binary Tree.doctree and /dev/null differ diff --git a/_build/.doctrees/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.doctree b/_build/.doctrees/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.doctree deleted file mode 100644 index 8a0dff1..0000000 Binary files a/_build/.doctrees/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.doctree and /dev/null differ diff --git a/_build/.doctrees/07. Trees/124. Binary Tree Maximum Path Sum.doctree b/_build/.doctrees/07. Trees/124. Binary Tree Maximum Path Sum.doctree deleted file mode 100644 index b000d0f..0000000 Binary files a/_build/.doctrees/07. Trees/124. Binary Tree Maximum Path Sum.doctree and /dev/null differ diff --git a/_build/.doctrees/07. Trees/199. Binary Tree Right Side View.doctree b/_build/.doctrees/07. Trees/199. Binary Tree Right Side View.doctree deleted file mode 100644 index ac9e634..0000000 Binary files a/_build/.doctrees/07. Trees/199. Binary Tree Right Side View.doctree and /dev/null differ diff --git a/_build/.doctrees/07. Trees/226. Invert Binary Tree.doctree b/_build/.doctrees/07. Trees/226. Invert Binary Tree.doctree deleted file mode 100644 index 29b96ce..0000000 Binary files a/_build/.doctrees/07. Trees/226. Invert Binary Tree.doctree and /dev/null differ diff --git a/_build/.doctrees/07. Trees/230. Kth Smallest Element in a BST.doctree b/_build/.doctrees/07. Trees/230. Kth Smallest Element in a BST.doctree deleted file mode 100644 index 1b4dde5..0000000 Binary files a/_build/.doctrees/07. Trees/230. Kth Smallest Element in a BST.doctree and /dev/null differ diff --git a/_build/.doctrees/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.doctree b/_build/.doctrees/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.doctree deleted file mode 100644 index 88f1cab..0000000 Binary files a/_build/.doctrees/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.doctree and /dev/null differ diff --git a/_build/.doctrees/07. Trees/297. Serialize and Deserialize Binary Tree.doctree b/_build/.doctrees/07. Trees/297. Serialize and Deserialize Binary Tree.doctree deleted file mode 100644 index edab1dc..0000000 Binary files a/_build/.doctrees/07. Trees/297. Serialize and Deserialize Binary Tree.doctree and /dev/null differ diff --git a/_build/.doctrees/07. Trees/572. Subtree of Another Tree.doctree b/_build/.doctrees/07. Trees/572. Subtree of Another Tree.doctree deleted file mode 100644 index d18096f..0000000 Binary files a/_build/.doctrees/07. Trees/572. Subtree of Another Tree.doctree and /dev/null differ diff --git a/_build/.doctrees/07. Trees/98. Validate Binary Search Tree.doctree b/_build/.doctrees/07. Trees/98. Validate Binary Search Tree.doctree deleted file mode 100644 index f4e0df7..0000000 Binary files a/_build/.doctrees/07. Trees/98. Validate Binary Search Tree.doctree and /dev/null differ diff --git a/_build/.doctrees/07. Trees/README.doctree b/_build/.doctrees/07. Trees/README.doctree deleted file mode 100644 index 0ef6fdf..0000000 Binary files a/_build/.doctrees/07. Trees/README.doctree and /dev/null differ diff --git a/_build/.doctrees/08. Tries/208. Implement Trie (Prefix Tree).doctree b/_build/.doctrees/08. Tries/208. Implement Trie (Prefix Tree).doctree deleted file mode 100644 index 980cee7..0000000 Binary files a/_build/.doctrees/08. Tries/208. Implement Trie (Prefix Tree).doctree and /dev/null differ diff --git a/_build/.doctrees/08. Tries/211. Design Add and Search Words Data Structure.doctree b/_build/.doctrees/08. Tries/211. Design Add and Search Words Data Structure.doctree deleted file mode 100644 index 24494e8..0000000 Binary files a/_build/.doctrees/08. Tries/211. Design Add and Search Words Data Structure.doctree and /dev/null differ diff --git a/_build/.doctrees/08. Tries/212. Word Search II.doctree b/_build/.doctrees/08. Tries/212. Word Search II.doctree deleted file mode 100644 index d9bcd3d..0000000 Binary files a/_build/.doctrees/08. Tries/212. Word Search II.doctree and /dev/null differ diff --git a/_build/.doctrees/08. Tries/README.doctree b/_build/.doctrees/08. Tries/README.doctree deleted file mode 100644 index 71936f3..0000000 Binary files a/_build/.doctrees/08. Tries/README.doctree and /dev/null differ diff --git a/_build/.doctrees/09. Heap - Priority Queue/1046. Last Stone Weight.doctree b/_build/.doctrees/09. Heap - Priority Queue/1046. Last Stone Weight.doctree deleted file mode 100644 index 2e53f47..0000000 Binary files a/_build/.doctrees/09. Heap - Priority Queue/1046. Last Stone Weight.doctree and /dev/null differ diff --git a/_build/.doctrees/09. Heap - Priority Queue/295. Find Median from Data Stream.doctree b/_build/.doctrees/09. Heap - Priority Queue/295. Find Median from Data Stream.doctree deleted file mode 100644 index ecc8007..0000000 Binary files a/_build/.doctrees/09. Heap - Priority Queue/295. Find Median from Data Stream.doctree and /dev/null differ diff --git a/_build/.doctrees/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.doctree b/_build/.doctrees/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.doctree deleted file mode 100644 index 4c27fbe..0000000 Binary files a/_build/.doctrees/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.doctree and /dev/null differ diff --git a/_build/.doctrees/09. Heap - Priority Queue/README.doctree b/_build/.doctrees/09. Heap - Priority Queue/README.doctree deleted file mode 100644 index a1bd1e3..0000000 Binary files a/_build/.doctrees/09. Heap - Priority Queue/README.doctree and /dev/null differ diff --git a/_build/.doctrees/10. Backtracking/39. Combination Sum.doctree b/_build/.doctrees/10. Backtracking/39. Combination Sum.doctree deleted file mode 100644 index 74bd1e4..0000000 Binary files a/_build/.doctrees/10. Backtracking/39. Combination Sum.doctree and /dev/null differ diff --git a/_build/.doctrees/10. Backtracking/79. Word Search.doctree b/_build/.doctrees/10. Backtracking/79. Word Search.doctree deleted file mode 100644 index 23d6c0d..0000000 Binary files a/_build/.doctrees/10. Backtracking/79. Word Search.doctree and /dev/null differ diff --git a/_build/.doctrees/10. Backtracking/README.doctree b/_build/.doctrees/10. Backtracking/README.doctree deleted file mode 100644 index a587eb8..0000000 Binary files a/_build/.doctrees/10. Backtracking/README.doctree and /dev/null differ diff --git a/_build/.doctrees/11. Graphs/133. Clone Graph.doctree b/_build/.doctrees/11. Graphs/133. Clone Graph.doctree deleted file mode 100644 index 8b72c4b..0000000 Binary files a/_build/.doctrees/11. Graphs/133. Clone Graph.doctree and /dev/null differ diff --git a/_build/.doctrees/11. Graphs/178. Graph Valid Tree.doctree b/_build/.doctrees/11. Graphs/178. Graph Valid Tree.doctree deleted file mode 100644 index 2d47dfa..0000000 Binary files a/_build/.doctrees/11. Graphs/178. Graph Valid Tree.doctree and /dev/null differ diff --git a/_build/.doctrees/11. Graphs/200. Number of Islands.doctree b/_build/.doctrees/11. Graphs/200. Number of Islands.doctree deleted file mode 100644 index 61d79f5..0000000 Binary files a/_build/.doctrees/11. Graphs/200. Number of Islands.doctree and /dev/null differ diff --git a/_build/.doctrees/11. Graphs/207. Course Schedule.doctree b/_build/.doctrees/11. Graphs/207. Course Schedule.doctree deleted file mode 100644 index affb26f..0000000 Binary files a/_build/.doctrees/11. Graphs/207. Course Schedule.doctree and /dev/null differ diff --git a/_build/.doctrees/11. Graphs/3651. Number of Connected Components in an Undirected Graph.doctree b/_build/.doctrees/11. Graphs/3651. Number of Connected Components in an Undirected Graph.doctree deleted file mode 100644 index efb302e..0000000 Binary files a/_build/.doctrees/11. Graphs/3651. Number of Connected Components in an Undirected Graph.doctree and /dev/null differ diff --git a/_build/.doctrees/11. Graphs/417. Pacific Atlantic Water Flow.doctree b/_build/.doctrees/11. Graphs/417. Pacific Atlantic Water Flow.doctree deleted file mode 100644 index a8c58e1..0000000 Binary files a/_build/.doctrees/11. Graphs/417. Pacific Atlantic Water Flow.doctree and /dev/null differ diff --git a/_build/.doctrees/11. Graphs/README.doctree b/_build/.doctrees/11. Graphs/README.doctree deleted file mode 100644 index 2283665..0000000 Binary files a/_build/.doctrees/11. Graphs/README.doctree and /dev/null differ diff --git a/_build/.doctrees/12. Advanced Graphs/892. Alien Dictionary.doctree b/_build/.doctrees/12. Advanced Graphs/892. Alien Dictionary.doctree deleted file mode 100644 index 0798b9c..0000000 Binary files a/_build/.doctrees/12. Advanced Graphs/892. Alien Dictionary.doctree and /dev/null differ diff --git a/_build/.doctrees/12. Advanced Graphs/README.doctree b/_build/.doctrees/12. Advanced Graphs/README.doctree deleted file mode 100644 index 01b3a0c..0000000 Binary files a/_build/.doctrees/12. Advanced Graphs/README.doctree and /dev/null differ diff --git a/_build/.doctrees/13. One-D Dynamic Programming/198. House Robber.doctree b/_build/.doctrees/13. One-D Dynamic Programming/198. House Robber.doctree deleted file mode 100644 index d5117c1..0000000 Binary files a/_build/.doctrees/13. One-D Dynamic Programming/198. House Robber.doctree and /dev/null differ diff --git a/_build/.doctrees/13. One-D Dynamic Programming/213. House Robber II.doctree b/_build/.doctrees/13. One-D Dynamic Programming/213. House Robber II.doctree deleted file mode 100644 index fa72fda..0000000 Binary files a/_build/.doctrees/13. One-D Dynamic Programming/213. House Robber II.doctree and /dev/null differ diff --git a/_build/.doctrees/13. One-D Dynamic Programming/70. Climbing Stairs.doctree b/_build/.doctrees/13. One-D Dynamic Programming/70. Climbing Stairs.doctree deleted file mode 100644 index 6bc0e6b..0000000 Binary files a/_build/.doctrees/13. One-D Dynamic Programming/70. Climbing Stairs.doctree and /dev/null differ diff --git a/_build/.doctrees/13. One-D Dynamic Programming/README.doctree b/_build/.doctrees/13. One-D Dynamic Programming/README.doctree deleted file mode 100644 index 71dbab0..0000000 Binary files a/_build/.doctrees/13. One-D Dynamic Programming/README.doctree and /dev/null differ diff --git a/_build/.doctrees/14. Two-D Dynamic Programming/README.doctree b/_build/.doctrees/14. Two-D Dynamic Programming/README.doctree deleted file mode 100644 index b1a6326..0000000 Binary files a/_build/.doctrees/14. Two-D Dynamic Programming/README.doctree and /dev/null differ diff --git a/_build/.doctrees/15. Greedy/README.doctree b/_build/.doctrees/15. Greedy/README.doctree deleted file mode 100644 index d5cc623..0000000 Binary files a/_build/.doctrees/15. Greedy/README.doctree and /dev/null differ diff --git a/_build/.doctrees/16. Intervals/README.doctree b/_build/.doctrees/16. Intervals/README.doctree deleted file mode 100644 index 4c01fad..0000000 Binary files a/_build/.doctrees/16. Intervals/README.doctree and /dev/null differ diff --git a/_build/.doctrees/17. Math Geometry/README.doctree b/_build/.doctrees/17. Math Geometry/README.doctree deleted file mode 100644 index a4d593f..0000000 Binary files a/_build/.doctrees/17. Math Geometry/README.doctree and /dev/null differ diff --git a/_build/.doctrees/18. Bit Manipulation/README.doctree b/_build/.doctrees/18. Bit Manipulation/README.doctree deleted file mode 100644 index e6afd99..0000000 Binary files a/_build/.doctrees/18. Bit Manipulation/README.doctree and /dev/null differ diff --git a/_build/.doctrees/Book.doctree b/_build/.doctrees/Book.doctree deleted file mode 100644 index 3860721..0000000 Binary files a/_build/.doctrees/Book.doctree and /dev/null differ diff --git a/_build/.doctrees/CODE_OF_CONDUCT.doctree b/_build/.doctrees/CODE_OF_CONDUCT.doctree deleted file mode 100644 index 0f244a9..0000000 Binary files a/_build/.doctrees/CODE_OF_CONDUCT.doctree and /dev/null differ diff --git a/_build/.doctrees/CONTRIBUTING.doctree b/_build/.doctrees/CONTRIBUTING.doctree deleted file mode 100644 index 169d54d..0000000 Binary files a/_build/.doctrees/CONTRIBUTING.doctree and /dev/null differ diff --git a/_build/.doctrees/README.doctree b/_build/.doctrees/README.doctree deleted file mode 100644 index ba89dd9..0000000 Binary files a/_build/.doctrees/README.doctree and /dev/null differ diff --git a/_build/.doctrees/SECURITY.doctree b/_build/.doctrees/SECURITY.doctree deleted file mode 100644 index 22d9a6d..0000000 Binary files a/_build/.doctrees/SECURITY.doctree and /dev/null differ diff --git a/_build/.doctrees/environment.pickle b/_build/.doctrees/environment.pickle deleted file mode 100644 index 3703abd..0000000 Binary files a/_build/.doctrees/environment.pickle and /dev/null differ diff --git a/_build/html/_sources/01. Array Hashing/1. Two Sum.ipynb b/_build/html/_sources/01. Array Hashing/1. Two Sum.ipynb deleted file mode 100644 index b3b517f..0000000 --- a/_build/html/_sources/01. Array Hashing/1. Two Sum.ipynb +++ /dev/null @@ -1,211 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 100: Same Tree\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Same Tree problem on LeetCode, click here!](https://leetcode.com/problems/same-tree/)\n", - "\n", - "---\n", - "Given the roots of two binary trees `p` and `q`, write a function to check if they are the same or not.\n", - "\n", - "Two binary trees are considered the same if they are structurally identical, and the nodes have the same value.\n", - "\n", - "**Constraints**\n", - "\n", - "1. The number of nodes in both trees is in the range `[0, 100]`.\n", - "2. $-10^4$ <= `Node.val` <= $10^4$" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for a binary tree node.\n", - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " # Initialize a TreeNode with a value (val), left child, and right child.\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def isSameTree(p, q):\n", - " # Base case: If both p and q are None, the trees are the same.\n", - " if not p and not q:\n", - " return True\n", - " \n", - " # Base case: If either p or q is None (but not both), the trees are different.\n", - " if not p or not q:\n", - " return False\n", - " \n", - " # Check if the values of the current nodes (p.val and q.val) are equal.\n", - " if p.val != q.val:\n", - " return False\n", - " \n", - " # Recursively check the left and right subtrees of p and q.\n", - " # If both subtrees are the same, the entire trees are the same.\n", - " return isSameTree(p.left, q.left) and isSameTree(p.right, q.right)" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "In this code, we define a `TreeNode` class to represent binary tree nodes and a `isSameTree` function to check if two binary trees are the same. The function uses recursive traversal to compare the trees' structures and values.\n", - "\n", - "1. We start by defining a `TreeNode` class, which represents a node in a binary tree. Each node has a `val` (the node's value), a `left` child, and a right child. This class will help us create and work with binary trees.\n", - "2. Next, we define the `isSameTree` function, which checks if two binary trees (`p` and `q`) are the same.\n", - " + The base case for the recursion is when both `p` and `q` are `None`. In this case, they are considered the same, so we return `True`.\n", - " + If either `p` or `q` is `None` (but not both), they cannot be the same, so we return `False`.\n", - " + If the values of the current nodes `p.val` and `q.val` are not equal, we return `False` because the trees cannot be the same.\n", - " + Finally, we recursively check the left and right subtrees of `p` and `q` to see if they are the same." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "### Example 1\n", - "\n", - "#Input: `p = [1,2,3]`, `q = [1,2,3]`\n", - "\n", - "p1 = TreeNode(1, TreeNode(2), TreeNode(3))\n", - "q1 = TreeNode(1, TreeNode(2), TreeNode(3))\n", - "print(isSameTree(p1, q1)) " - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "### Example 2\n", - "\n", - "#Input: `p = [1,2]`, `q = [1,null,2]`\n", - "\n", - "p2 = TreeNode(1, TreeNode(2), None)\n", - "q2 = TreeNode(1, None, TreeNode(2))\n", - "print(isSameTree(p2, q2))" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "5897c29d-26f8-486a-878c-43c09ff25ce4", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "### Example 3\n", - "\n", - "#Input: p = [1,2,1], q = [1,1,2]\n", - "\n", - "p3 = TreeNode(1, TreeNode(2), TreeNode(1))\n", - "q3 = TreeNode(1, TreeNode(1), TreeNode(2))\n", - "print(isSameTree(p3, q3))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "**Time Complexity**\n", - "\n", - "The time complexity of the `isSameTree` function can be analyzed as follows:\n", - "\n", - "In the worst case, the function needs to visit every node in both trees once to determine if they are the same.\n", - "Since each node is visited exactly once, the time complexity is $O(n)$, where $n$ is the total number of nodes in the input trees.\n", - "\n", - "**Space Complexity**\n", - "The space complexity of the `isSameTree` function can be analyzed as follows:\n", - "\n", - "The space used by the function's call stack during recursion is proportional to the maximum depth of the binary trees.\n", - "In the worst case, when the trees are completely unbalanced (all nodes form a single branch), the maximum depth will be $n$, where $n$ is the total number of nodes in the input trees.\n", - "Therefore, the space complexity is $O(n)$ due to the recursive call stack.\n", - "In addition to the call stack, there is a small constant amount of space used for variables and comparisons within each recursive call, but this space is not significant in terms of the overall space complexity.\n", - "\n", - "**In summary:**\n", - "\n", - "+ Time Complexity: $O(n)$ where $n$ is the total number of nodes in the input trees.\n", - "+ Space Complexity: $O(n)$ due to the recursive call stack." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/01. Array Hashing/128. Longest Consecutive Sequence.ipynb b/_build/html/_sources/01. Array Hashing/128. Longest Consecutive Sequence.ipynb deleted file mode 100644 index a77a03d..0000000 --- a/_build/html/_sources/01. Array Hashing/128. Longest Consecutive Sequence.ipynb +++ /dev/null @@ -1,209 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 128. Longest Consecutive Sequence\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Longest Consecutive Sequence problem on LeetCode, click here!](https://leetcode.com/problems/longest-consecutive-sequence/)\n", - "\n", - "---\n", - "\n", - "Given an unsorted array of integers `nums`, return *the length of the longest consecutive elements sequence.*\n", - "\n", - "You must write an algorithm that runs in `O(n)` time.\n", - "\n", - "*Constraints:**\n", - "- 0 <= `nums.length` <= $10^5$\n", - "- $-10^9$ <= `nums[i]` <= $10^9$\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 58, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def longestConsecutive(nums):\n", - " if not nums:\n", - " return 0\n", - "\n", - " num_set = set(nums)\n", - " max_length = 0\n", - "\n", - " for num in num_set:\n", - " if num - 1 not in num_set:\n", - " current_num = num\n", - " current_length = 1\n", - "\n", - " while current_num + 1 in num_set:\n", - " current_num += 1\n", - " current_length += 1\n", - "\n", - " max_length = max(max_length, current_length)\n", - "\n", - " return max_length" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start by defining the `longestConsecutive` function that takes the `nums` array as input.\n", - "\n", - "2. We check if the `nums` array is empty. If it's empty, there are no consecutive elements, so we return 0.\n", - "\n", - "3. We create a Python set called `num_set` and insert all elements from the `nums` array into it. Using a set allows us to efficiently check for the existence of elements in O(1) time.\n", - "\n", - "4. We initialize a variable `max_length` to 0. This variable will keep track of the maximum length of consecutive elements sequence found.\n", - "\n", - "5. We iterate through the elements of the `num_set`. For each element `num`, we check if `num - 1` exists in the `num_set`. If it doesn't exist, it means `num` is the starting element of a potential consecutive sequence.\n", - "\n", - "6. Inside the loop, we initialize two variables: `current_num` to the current element `num` and `current_length` to 1. We start with a length of 1 because `num` itself is part of the sequence.\n", - "\n", - "7. We then enter a while loop that continues as long as `current_num + 1` exists in the `num_set`. This means we are incrementing the consecutive sequence.\n", - "\n", - "8. Inside the while loop, we increment `current_num` by 1 and also increment `current_length` by 1 to account for the next consecutive element.\n", - "\n", - "9. We compare `current_length` with the `max_length` and update `max_length` if the current sequence is longer.\n", - "\n", - "10. After the while loop, we move to the next element in the outer loop and repeat the process.\n", - "\n", - "11. Finally, we return the `max_length` as the result, which represents the length of the longest consecutive elements sequence in the `nums` array.\n", - "\n", - "The key idea here is to use a set to efficiently check for the existence of elements and to iterate through the elements, considering each element as the potential start of a consecutive sequence. By doing this, we can find the longest consecutive sequence in O(n) time complexity, where n is the number of elements in the array." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 59, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "nums1 = [100, 4, 200, 1, 3, 2]\n", - "print(longestConsecutive(nums1))" - ] - }, - { - "cell_type": "code", - "execution_count": 60, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "9\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "nums2 = [0, 3, 7, 2, 5, 8, 4, 6, 0, 1]\n", - "print(longestConsecutive(nums2)) " - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "The code is designed to run in O(n) time complexity, where n is the number of elements in the `nums` array. Here's the breakdown:\n", - "\n", - "1. Constructing the `num_set` by inserting all elements from `nums` into it takes O(n) time because we perform an insertion operation for each element in `nums`.\n", - "\n", - "2. The main loop iterates through the elements in `num_set`. In the worst case, each element is visited only once, so the loop itself takes O(n) time.\n", - "\n", - "3. Within the loop, we have a while loop that may also take O(n) time in the worst case. However, this while loop is nested inside the main loop, so its overall time complexity remains O(n).\n", - "\n", - "Therefore, the overall time complexity of the code is O(n).\n", - "\n", - "**Space Complexity:**\n", - "The space complexity of the code is determined by the space used by the `num_set` and a few additional variables. Here's the breakdown:\n", - "\n", - "1. `num_set` is a set that stores the unique elements from `nums`. In the worst case, it can store all n elements from `nums`, so the space complexity is O(n).\n", - "\n", - "2. The additional variables used, such as `max_length`, `current_num`, and `current_length`, have constant space requirements and do not depend on the size of the input array.\n", - "\n", - "Therefore, the overall space complexity of the code is O(n) due to the space used by the `num_set`." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. Write an algorithm that not only returns the length of the longest consecutive elements sequence but also returns the actual consecutive sequence itself.\n", - "\n", - "2. Extend the problem to allow elements to be considered consecutive if they are within a certain absolute difference (e.g., less than or equal to k) instead of exactly 1. Write an algorithm that finds the longest such sequence and runs in O(n) time." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/01. Array Hashing/217. Contains Duplicate.ipynb b/_build/html/_sources/01. Array Hashing/217. Contains Duplicate.ipynb deleted file mode 100644 index 57bb55d..0000000 --- a/_build/html/_sources/01. Array Hashing/217. Contains Duplicate.ipynb +++ /dev/null @@ -1,218 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 217. Contains Duplicate\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Contains Duplicate problem on LeetCode, click here!](https://leetcode.com/problems/contains-duplicate/)\n", - "\n", - "---\n", - "\n", - "Given an integer array `nums`, return `true` if any value appears **at least twice** in the array, and return `false` if every element is distinct.\n", - "\n", - "**Constraints:**\n", - "- 1 <= `nums.length` <= $10^5$\n", - "- $-10^9$ <= `nums[i]` <= $10^9$\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def containsDuplicate(nums):\n", - " # Create an empty set to store unique elements\n", - " unique_elements = set()\n", - " \n", - " # Iterate through the array\n", - " for num in nums:\n", - " # If the element is already in the set, return True\n", - " if num in unique_elements:\n", - " return True\n", - " # Otherwise, add it to the set\n", - " else:\n", - " unique_elements.add(num)\n", - " \n", - " # If the loop completes without finding duplicates, return False\n", - " return False" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. The `containsDuplicate` function takes a single argument, `nums`, which is the input integer array.\n", - "\n", - "2. Inside the function, an empty set called `unique_elements` is created. This set will be used to keep track of unique elements in the input array.\n", - "\n", - "3. The function then iterates through the input array `nums` using a `for` loop.\n", - "\n", - "4. For each element `num` in the array, it checks whether `num` is already in the `unique_elements` set using the `if num in unique_elements:` condition.\n", - "\n", - "5. If `num` is already in the set, it means there is a duplicate element in the array, and the function immediately returns `True`.\n", - "\n", - "6. If `num` is not in the set, it is added to the `unique_elements` set using `unique_elements.add(num)`.\n", - "\n", - "7. The loop continues to the next element, and the process repeats.\n", - "\n", - "8. If the loop completes without finding any duplicates, it means that all elements in the array are distinct, and the function returns `False`.\n", - "\n", - "The code efficiently utilizes a set data structure to keep track of unique elements while iterating through the array, allowing it to quickly detect duplicate elements. This code meets the problem's requirements and constraints, as explained earlier." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "nums1 = [1, 2, 3, 1]\n", - "print(containsDuplicate(nums1))" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 2\n", - "nums2 = [1, 2, 3, 4]\n", - "print(containsDuplicate(nums2))" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "e191cf7e-95f9-4e5c-a99b-146c2a779c0b", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 3\n", - "nums3 = [1, 1, 1, 3, 3, 4, 3, 2, 4, 2]\n", - "print(containsDuplicate(nums3))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code for the \"Contains Duplicate\" problem:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The primary operation that affects the time complexity is the `for` loop that iterates through the input array `nums`. In the worst case, the loop will iterate through all `n` elements of the array, where `n` is the length of the input array.\n", - "\n", - "- Iterating through the array: O(n)\n", - "\n", - "Inside the loop, we perform two operations:\n", - "\n", - "1. Checking whether an element exists in the `unique_elements` set (`if num in unique_elements`). This operation has an average time complexity of O(1) for a set.\n", - "2. Adding an element to the `unique_elements` set (`unique_elements.add(num)`), which also has an average time complexity of O(1) for a set.\n", - "\n", - "Since these operations are performed for each element in the array, the overall time complexity remains O(n).\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity is determined by the additional data structures used in the code, which are the `unique_elements` set.\n", - "\n", - "- `unique_elements` set: This set stores unique elements from the input array. In the worst case, if all elements in the input array are distinct, the set will store all `n` elements.\n", - "\n", - "Therefore, the space complexity is O(n) because, in the worst case, the set's size will grow linearly with the input array's size.\n", - "\n", - "**In summary**, the time complexity of the code is O(n), where `n` is the length of the input array, and the space complexity is also O(n) in the worst case. This code is efficient and meets the constraints of the problem." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **K Duplicates:** Modify the problem to return `true` if there are exactly K duplicate elements in the array. Write a function that takes an additional integer parameter K and returns `true` if there are exactly K duplicates.\n", - "2. **Frequency Count:** Write a function that returns a list of all the elements that appear more than once in the array, along with their frequencies." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/01. Array Hashing/238. Product of Array Except Self.ipynb b/_build/html/_sources/01. Array Hashing/238. Product of Array Except Self.ipynb deleted file mode 100644 index 1ff9a9c..0000000 --- a/_build/html/_sources/01. Array Hashing/238. Product of Array Except Self.ipynb +++ /dev/null @@ -1,197 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 238. Product of Array Except Self\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Product of Array Except Self problem on LeetCode, click here!](https://leetcode.com/problems/product-of-array-except-self/)\n", - "\n", - "---\n", - "Given an integer array `nums`, return *an array `answer` such that `answer[i]` is equal to the product of all the elements of `nums` except `nums[i]`.*\n", - "\n", - "The product of any prefix or suffix of `nums` is **guaranteed** to fit in a **32-bit** integer.\n", - "\n", - "You must write an algorithm that runs in O(n) time and without using the division operation.\n", - "\n", - "Constraints:\n", - "- 2 <= `nums.length` <= $10^5$\n", - "- `-30 <= nums[i] <= 30`\n", - "- The product of any prefix or suffix of `nums` is **guaranteed** to fit in a **32-bit** integer.\n", - "\n", - "**Follow-up:** Can you solve the problem in O(1) extra space complexity? (The output array **does not** count as extra space for space complexity analysis.)\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def productExceptSelf(nums):\n", - " n = len(nums)\n", - " \n", - " # Initialize two arrays to store products to the left and right of each element\n", - " left_products = [1] * n\n", - " right_products = [1] * n\n", - " \n", - " # Calculate products to the left of each element\n", - " left_product = 1\n", - " for i in range(n):\n", - " left_products[i] = left_product\n", - " left_product *= nums[i]\n", - " \n", - " # Calculate products to the right of each element\n", - " right_product = 1\n", - " for i in range(n - 1, -1, -1):\n", - " right_products[i] = right_product\n", - " right_product *= nums[i]\n", - " \n", - " # Calculate the final answer using left and right products\n", - " answer = [left_products[i] * right_products[i] for i in range(n)]\n", - " \n", - " return answer" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. `n` is initialized as the length of the `nums` array.\n", - "2. Two arrays, `left_products` and `right_products`, are created, each with a length of `n` and filled with ones initially.\n", - "3. `left_product` is initialized to 1.\n", - "4. A loop iterates through the `nums` array, from left to right. For each element at index `i`, it stores the product of all elements to its left (including itself) in the `left_products` array and updates `left_product` accordingly.\n", - "5. `right_product` is initialized to 1.\n", - "6. Another loop iterates through the `nums` array in reverse order, from right to left. For each element at index `i`, it stores the product of all elements to its right (including itself) in the `right_products` array and updates `right_product`.\n", - "7. The final `answer` list is constructed by multiplying corresponding elements from the `left_products` and `right_products` arrays for each index `i`.\n", - "8. The function returns the `answer` list, which contains the desired results.\n", - "\n", - "Overall, this algorithm efficiently computes the product of all elements except the current element, as required. It runs in O(n) time complexity and uses O(n) extra space, which is within the problem's constraints." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[24, 12, 8, 6]\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "nums = [1,2,3,4]\n", - "result1 = productExceptSelf(nums)\n", - "print(result1)" - ] - }, - { - "cell_type": "code", - "execution_count": 53, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[0, 0, 9, 0, 0]\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "nums = [-1,1,0,-3,3]\n", - "result2 = productExceptSelf(nums)\n", - "print(result2)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "1. The first loop iterates through the `nums` array to calculate the products to the left of each element. This loop runs in O(n) time, where n is the length of the `nums` array.\n", - "2. The second loop also iterates through the `nums` array in reverse order to calculate the products to the right of each element. This loop also runs in O(n) time.\n", - "3. The final loop constructs the `answer` list by multiplying elements from the `left_products` and `right_products` arrays. This loop runs in O(n) time.\n", - "\n", - "Since all the loops are independent and sequential, the overall time complexity is O(n).\n", - "\n", - "**Space Complexity:**\n", - "1. Two additional arrays, `left_products` and `right_products`, are created with a length of `n`, where `n` is the length of the `nums` array. Therefore, these arrays consume O(n) extra space.\n", - "2. The `left_product` and `right_product` variables are used to keep track of the product to the left and right of each element, respectively. These variables occupy O(1) extra space.\n", - "3. The `answer` list, which contains the final results, also consumes O(n) space, but it's not counted toward the extra space complexity analysis as per the problem's constraints.\n", - "\n", - "Overall, the space complexity is O(n) for this solution." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Handle Zeros in the Input**: Modify the solution to handle cases where the input array contains zeros. For example, if `nums = [0, 1, 2, 3, 0]`, the output should be `[0, 0, 0, 0, 0]` because any element multiplied by zero results in zero.\n", - "\n", - "2. **In-Place Modification**: Attempt to solve the problem with in-place modification of the `nums` array, where the output is stored directly in the input array without using any additional space." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/01. Array Hashing/242. Valid Anagram.ipynb b/_build/html/_sources/01. Array Hashing/242. Valid Anagram.ipynb deleted file mode 100644 index d165899..0000000 --- a/_build/html/_sources/01. Array Hashing/242. Valid Anagram.ipynb +++ /dev/null @@ -1,198 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 242. Valid Anagram\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Valid Anagram problem on LeetCode, click here!](https://leetcode.com/problems/valid-anagram/)\n", - "\n", - "---\n", - "Given two strings `s` and `t`, return `true` if `t` is an anagram of `s`, and `false` otherwise.\n", - "\n", - "An **Anagram** is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.\n", - "\n", - "**Constraints:**\n", - "- 1 <= `s.length`, `t.length` <= $5 * 10^4$\n", - "- `s` and `t` consist of lowercase English letters.\n", - "\n", - "**Follow-up:** What if the inputs contain Unicode characters? How would you adapt your solution to such a case?\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def isAnagram(s: str, t: str) -> bool:\n", - " # Check if the lengths of s and t are not equal\n", - " if len(s) != len(t):\n", - " return False\n", - "\n", - " # Create dictionaries to store character frequencies for s and t\n", - " countS, countT = {}, {}\n", - "\n", - " # Count character frequencies in s\n", - " for i in range(len(s)):\n", - " countS[s[i]] = 1 + countS.get(s[i], 0)\n", - "\n", - " # Count character frequencies in t\n", - " for i in range(len(t)):\n", - " countT[t[i]] = 1 + countT.get(t[i], 0)\n", - "\n", - " # Check if the character frequencies in s and t are the same\n", - " return countS == countT" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. The code defines a class called `Solution` with a method `isAnagram` that takes two input strings, `s` and `t`, and returns a boolean (`True` or `False`) based on whether `t` is an anagram of `s`.\n", - "\n", - "2. The first check performed in the method is whether the lengths of `s` and `t` are equal. If they are not equal, it immediately returns `False` because strings of different lengths cannot be anagrams of each other.\n", - "\n", - "3. Two dictionaries, `countS` and `countT`, are created to store the frequency of characters in `s` and `t`, respectively. These dictionaries will be used to count the occurrences of each character in the strings.\n", - "\n", - "4. The code then enters a loop to iterate through each character in string `s` using a `for` loop. Inside the loop, it updates the `countS` dictionary. The line `countS[s[i]] = 1 + countS.get(s[i], 0)` increments the count of character `s[i]` in `countS` by 1. If the character is not already in the dictionary, it initializes the count to 1.\n", - "\n", - "5. Similarly, the code iterates through each character in string `t` and updates the `countT` dictionary in the same way.\n", - "\n", - "6. After counting the character frequencies in both strings, the code compares the two dictionaries using `countS == countT`. If the dictionaries are equal, it means that both strings have the same character frequencies, and therefore, `t` is an anagram of `s`. In this case, the method returns `True`.\n", - "\n", - "7. If the dictionaries are not equal, the method returns `False`, indicating that `t` is not an anagram of `s`.\n", - "\n", - "In summary, this code efficiently determines whether two input strings are anagrams by counting the character frequencies in each string using dictionaries and then comparing these counts. If the character frequencies match, the strings are considered anagrams, and the method returns `True`; otherwise, it returns `False`." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "s = \"anagram\"\n", - "t = \"nagaram\"\n", - "print(isAnagram(s, t))" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 2\n", - "s = \"rat\"\n", - "t = \"car\"\n", - "print(isAnagram(s, t))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. The code first checks whether the lengths of the input strings `s` and `t` are equal, which takes constant time. This check has a time complexity of O(1).\n", - "\n", - "2. The code then iterates through both strings, `s` and `t`, once to count the character frequencies. Since both strings have a maximum length of 5 * 10^4, the worst-case scenario is that the code iterates through 5 * 10^4 characters in each string. This results in a linear time complexity of O(n), where n is the length of the longer of the two input strings (`s` or `t`).\n", - "\n", - "3. Finally, the code compares the two dictionaries `countS` and `countT` to check if the character frequencies match. This comparison takes O(n) time in the worst case, where n is the length of the longer string.\n", - "\n", - "Overall, the time complexity of the code is O(n), where n is the length of the longer input string.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. The code uses two dictionaries, `countS` and `countT`, to store the character frequencies of the input strings `s` and `t`. In the worst case, both dictionaries can contain all unique characters from the input strings. Since the input strings can have a maximum length of 5 * 10^4, the space complexity for these dictionaries is O(5 * 10^4) or simply O(n), where n is the length of the longer input string.\n", - "\n", - "2. The code uses a few additional variables for bookkeeping, but these variables have constant space requirements and do not depend on the input size. Therefore, they do not significantly impact the overall space complexity.\n", - "\n", - "**In summary**, the space complexity of the code is O(n), where n is the length of the longer input string." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Anagram Chains**: Given a list of words, find the longest chain of anagrams, where each word in the chain is an anagram of the previous word. For example, given [\"bat\", \"tab\", \"cat\", \"tac\", \"dog\"], the longest anagram chain is [\"bat\", \"tab\", \"cat\", \"tac\"].\n", - "\n", - "2. **Minimum Deletions to Make Anagrams**: Given two strings `s` and `t`, find the minimum number of character deletions required in both strings to make them anagrams of each other. For example, if `s = \"hello\"` and `t = \"billion\"`, you can remove the characters \"heo\" from `s` and \"billi\" from `t` to make them anagrams (\"lo\" and \"on\" are left in the two strings)." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/01. Array Hashing/347. Top K Frequent Elements.ipynb b/_build/html/_sources/01. Array Hashing/347. Top K Frequent Elements.ipynb deleted file mode 100644 index ecfa494..0000000 --- a/_build/html/_sources/01. Array Hashing/347. Top K Frequent Elements.ipynb +++ /dev/null @@ -1,215 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 347. Top K Frequent Elements\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Top K Frequent Elements problem on LeetCode, click here!](https://leetcode.com/problems/top-k-frequent-elements/)\n", - "\n", - "---\n", - "Given an integer array `nums` and an integer `k`, return the `k` most frequent elements. You may return the answer in **any order**.\n", - "\n", - "Constraints:\n", - "- 1 <= `nums.length` <= $10^5$\n", - "- $-10^4$ <= `nums[i]` <= $10^4$\n", - "- `k` is in the range `[1, the number of unique elements in the array]`.\n", - "- It is **guaranteed** that the answer is **unique**.\n", - "\n", - "**Follow-up:** Your algorithm's time complexity must be better than $O(n\\ log\\ n)$, where n is the array's size.\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def topKFrequent(nums, k):\n", - " # Create a dictionary to store the frequency of each element\n", - " count = {}\n", - " # Create a list of lists to store elements with the same frequency\n", - " frequency = [[] for i in range(len(nums) + 1)]\n", - "\n", - " # Count the frequency of each element in nums\n", - " for n in nums:\n", - " count[n] = 1 + count.get(n, 0)\n", - "\n", - " # Place elements in the freq list according to their frequency\n", - " for n, c in count.items():\n", - " frequency[c].append(n)\n", - "\n", - " res = []\n", - " # Traverse freq list from the end (higher frequencies)\n", - " for i in range(len(frequency) - 1, 0, -1):\n", - " for n in frequency[i]:\n", - " res.append(n)\n", - " if len(res) == k:\n", - " return res" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. `def topKFrequent(nums, k):`: This is a function that takes two arguments: `nums`, which is the input array of integers, and `k`, which is the number of most frequent elements to return.\n", - "\n", - "2. `count = {}`: This dictionary `count` will be used to store the frequency of each unique element in the `nums` array. The keys are elements from the input array, and the values are their corresponding frequencies.\n", - "\n", - "3. `frequency = [[] for i in range(len(nums) + 1)]`: This creates a list of empty lists called `frequency`. It's used to store elements based on their frequencies, similar to the `freq` list in the previous code. The size of this list is set to be one greater than the length of the input `nums`.\n", - "\n", - "4. `for n in nums:`: This loop iterates through each element `n` in the input `nums` array.\n", - "\n", - "5. `count[n] = 1 + count.get(n, 0)`: This line counts the frequency of each element `n` in the `nums` array. It uses the `count.get(n, 0)` method to retrieve the current count of `n` from the `count` dictionary. If `n` is not in the dictionary, it defaults to 0. It then increments the count by 1.\n", - "\n", - "6. After the above loop, the `count` dictionary will contain counts of each unique element in the `nums` array.\n", - "\n", - "7. `for n, c in count.items():`: This loop iterates through the items (key-value pairs) of the `count` dictionary. `n` represents the element, and `c` represents its frequency.\n", - "\n", - "8. `frequency[c].append(n)`: This line places the element `n` into the bucket corresponding to its frequency `c`. Buckets are represented by the `frequency` list. For example, if an element `n` has a frequency of 3, it will be added to `frequency[3]`.\n", - "\n", - "9. After this loop, the `frequency` list will contain buckets of elements grouped by their frequencies.\n", - "\n", - "10. `res = []`: This list `res` will be used to store the k most frequent elements.\n", - "\n", - "11. `for i in range(len(freq) - 1, 0, -1):`: This loop iterates in reverse order through the `frequency` list, starting from the highest frequency and going down to 1. Note that there is a typo here; it should be `frequency` instead of `freq`.\n", - "\n", - "12. `for n in frequency[i]:`: For each element `n` in the current bucket (i.e., elements with frequency `i`), it appends `n` to the result list `res`.\n", - "\n", - "13. `if len(res) == k:`: Once `res` contains k elements, the code exits and returns the result.\n", - "\n", - "The code efficiently finds the k most frequent elements in the input array without using sorting, similar to the previous explanation, with the only difference being the variable names (e.g., `frequency` instead of `freq`)." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 48, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 2]\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "nums = [1,1,1,2,2,3]\n", - "k = 2\n", - "result1 = topKFrequent(nums, k)\n", - "print(result1)" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1]\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "nums = [1]\n", - "k = 1\n", - "result2 = topKFrequent(nums, k)\n", - "print(result2)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "1. The first loop that counts the frequency of elements by iterating through `nums` has a time complexity of O(n), where n is the number of elements in the input array `nums`.\n", - "\n", - "2. The second loop iterates through the keys in the `count` dictionary, which has at most `k` unique elements (as per the constraints). Therefore, the second loop also has a time complexity of O(k).\n", - "\n", - "3. The third loop iterates through the `frequency` list, which has a length equal to the maximum frequency of elements in `nums`. In the worst case, this loop can have a time complexity of O(n), where n is the number of elements in `nums`.\n", - "\n", - "Overall, the dominant factor in terms of time complexity is the loop that iterates through the `count` dictionary. So, the total time complexity of the code is O(n + k).\n", - "\n", - "**Space Complexity:**\n", - "1. The `count` dictionary stores the frequency of each unique element in `nums`. In the worst case, it can have at most `k` unique elements, so the space complexity for `count` is O(k).\n", - "\n", - "2. The `frequency` list is used to store elements grouped by their frequencies. It has a length of `len(nums) + 1`, which can be at most 105 based on the constraints. Therefore, the space complexity for `frequency` is O(105).\n", - "\n", - "3. The `res` list stores the k most frequent elements, which can be at most `k` elements, so the space complexity for `res` is O(k).\n", - "\n", - "**In summary**, the space complexity is dominated by the `count` dictionary and the `frequency` list, both of which have a space complexity of O(k + 105)." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Optimized k Most Frequent Elements:** Modify the code to find the k most frequent elements in an array while ensuring that the time complexity is O(n + klogk). You can use a priority queue (heap) to achieve this.\n", - "\n", - "2. **Handling Duplicate Frequencies:** Extend the code to handle cases where multiple elements have the same frequency and are among the k most frequent elements. Ensure that the output contains exactly k elements." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/01. Array Hashing/49. Group Anagrams.ipynb b/_build/html/_sources/01. Array Hashing/49. Group Anagrams.ipynb deleted file mode 100644 index afe89ec..0000000 --- a/_build/html/_sources/01. Array Hashing/49. Group Anagrams.ipynb +++ /dev/null @@ -1,229 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 49. Group Anagrams\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Group Anagrams problem on LeetCode, click here!](https://leetcode.com/problems/group-anagrams/)\n", - "\n", - "---\n", - "Given an array of strings `strs`, group **the anagrams** together. You can return the answer in **any order**.\n", - "\n", - "An **Anagram** is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.\n", - "\n", - "**Constraints:**\n", - "- 1 <= `strs.length <= $10^4$\n", - "- `0 <= strs[i].length <= 100`\n", - "- `strs[i]` consists of lowercase English letters.\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "from collections import defaultdict\n", - "\n", - "\n", - "def groupAnagrams(strs):\n", - " ans = defaultdict(list)\n", - "\n", - " # Iterate through the list of input strings\n", - " for s in strs:\n", - " # Initialize a list to represent character counts for each character (a-z)\n", - " count = [0] * 26\n", - "\n", - " # Count the occurrences of each character in the current word\n", - " for c in s:\n", - " count[ord(c) - ord(\"a\")] += 1\n", - "\n", - " # Use a tuple of character counts as the key and append the word to the anagram group\n", - " ans[tuple(count)].append(s)\n", - "\n", - " # Convert the values (lists of anagrams) to a list of lists\n", - " return list(ans.values())" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. Inside the method, a `defaultdict` called `ans` is created to store anagram groups. This dictionary will have a list as its default value, meaning that each key in the dictionary will be associated with an empty list by default.\n", - "\n", - "2. The code then iterates through the list of input strings, `strs`, using a `for` loop. For each word `s` in `strs`, it performs the following steps:\n", - "\n", - " - It initializes a list `count` of length 26, where each element represents the count of a specific character (a-z) in the word `s`.\n", - "\n", - " - The code then iterates through the characters of `s`. For each character `c`, it increments the corresponding count in the `count` list based on its ASCII value.\n", - "\n", - " - After counting the characters in `s`, it converts the `count` list into a tuple `tuple(count)` to use as a key for the `ans` dictionary.\n", - "\n", - " - It appends the word `s` to the list associated with the key (tuple) in the `ans` dictionary. This groups all anagrams of the same word together under the same key.\n", - "\n", - "3. After processing all words in `strs`, the code converts the values of the `ans` dictionary (which are lists of anagrams) to a list of lists using the `list()` constructor.\n", - "\n", - "4. Finally, the code returns the list of anagram groups, which is the result of grouping the anagrams in the input list.\n", - "\n", - "In summary, the code efficiently groups anagrams together by counting the characters in each word and using a dictionary to store them under the same key. The result is a list of lists, where each inner list represents a group of anagrams." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[['eat', 'tea', 'ate'], ['tan', 'nat'], ['bat']]\n" - ] - } - ], - "source": [ - "# Example 1: Group anagrams from a list of words\n", - "strs1 = [\"eat\", \"tea\", \"tan\", \"ate\", \"nat\", \"bat\"]\n", - "result1 = groupAnagrams(strs1)\n", - "print(result1)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[['']]\n" - ] - } - ], - "source": [ - "# Example 2: Group anagrams from a list with an empty string\n", - "strs2 = [\"\"]\n", - "result2 = groupAnagrams(strs2)\n", - "print(result2)" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "id": "c8367e2a-e7d5-4e18-8235-2870e341a04b", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[['a']]\n" - ] - } - ], - "source": [ - "# Example 3: Group anagrams from a list with a single word\n", - "strs3 = [\"a\"]\n", - "result3 = groupAnagrams(strs3)\n", - "print(result3)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `groupAnagrams` method:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. First, we create an instance of the `Solution` class, which is an O(1) operation.\n", - "\n", - "2. Inside the `groupAnagrams` method, we iterate through the list of input strings `strs` once in a loop:\n", - " - For each word in `strs`, we perform character counting, which is done in O(K) time, where K is the maximum length of a word in the list.\n", - "\n", - "3. The overall time complexity of the method is O(N * K), where N is the number of words in the input list `strs`, and K is the maximum length of a word in `strs`.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. We use a `defaultdict` called `ans` to store the anagram groups. In the worst case, each word belongs to a distinct anagram group, so the space complexity for `ans` is O(N).\n", - "\n", - "2. Within the loop, we create a `count` list of length 26 to store character counts for each word. This is a fixed-size list and does not depend on the input size, so it has a constant space complexity of O(26), which is effectively O(1).\n", - "\n", - "3. The space used for other variables is also constant and does not depend on the input size.\n", - "\n", - "4. The final result, `result`, is a list of lists that contains the grouped anagrams. In the worst case, each word is a distinct anagram group, so the space complexity for `result` is O(N).\n", - "\n", - "5. The overall space complexity of the method is O(N) due to the space used by `ans` and `result`. The space used by the `count` list and other variables is constant and does not significantly affect the overall space complexity.\n", - "\n", - "**In summary,** the time complexity of the `groupAnagrams` method is O(N * K), and the space complexity is O(N), where N is the number of words in the input list `strs`, and K is the maximum length of a word in `strs`." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Anagramic Palindromes**: Given a list of strings, find all the groups of anagrams where each group contains words that can be rearranged into a palindrome. For example, in the list [\"bat\", \"tab\", \"act\", \"tac\", \"dog\"], there are two groups: [\"bat\", \"tab\", \"act\", \"tac\"] and [\"dog\"].\n", - "\n", - "2. **Largest Anagram Group**: Given a list of strings, find the largest group of anagrams. Return the list of anagrams in that group. If there are multiple largest groups, return all of them." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/01. Array Hashing/659. Encode and Decode Strings.ipynb b/_build/html/_sources/01. Array Hashing/659. Encode and Decode Strings.ipynb deleted file mode 100644 index 037c476..0000000 --- a/_build/html/_sources/01. Array Hashing/659. Encode and Decode Strings.ipynb +++ /dev/null @@ -1,204 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 659· Encode and Decode Strings\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Encode and Decode Strings problem on LintCode, click here!](https://www.lintcode.com/problem/659/)\n", - "\n", - "---\n", - "Design an algorithm to encode a list of strings to a string. The encoded string is then sent over the network and is decoded back to the original list of strings.\n", - "\n", - "Please implement `encode` and `decode`.\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class Codec:\n", - "\n", - " def encode(self, strs):\n", - " \"\"\"Encodes a list of strings to a single string.\n", - " \n", - " :type strs: List[str]\n", - " :rtype: str\n", - " \"\"\"\n", - " encoded = \"\"\n", - " for s in strs:\n", - " encoded += s.replace(':', '::') + ':;'\n", - " return encoded\n", - "\n", - " def decode(self, s):\n", - " \"\"\"Decodes a single string to a list of strings.\n", - " \n", - " :type s: str\n", - " :rtype: List[str]\n", - " \"\"\"\n", - " decoded = []\n", - " i = 0\n", - " while i < len(s):\n", - " end = s.find(':;', i)\n", - " if end == -1:\n", - " end = len(s)\n", - " decoded.append(s[i:end].replace('::', ':'))\n", - " i = end + 2\n", - " return decoded" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We define a class called `Codec` to encapsulate the encoding and decoding operations for a list of strings.\n", - "\n", - "2. In the `encode` method, we take a list of strings (`strs`) as input and return a single encoded string. The encoding process involves concatenating the strings together with a delimiter `:;`. We iterate through each string in the input list, replace any occurrence of `:` with `::` (to avoid conflicts with the delimiter), and then append `:;` to indicate the end of that string.\n", - "\n", - "3. In the `decode` method, we take an encoded string (`s`) as input and return a list of strings. The decoding process involves splitting the encoded string using the `:;` delimiter. We start from the beginning of the encoded string (`i = 0`) and repeatedly find the next occurrence of `:;`. We extract the substring between the current position (`i`) and the next delimiter (`end`). Before adding it to the result list, we replace any `::` with `:` to revert the encoding. We then update the current position `i` to be after the delimiter, so we can find the next substring in the next iteration.\n", - "\n", - "4. Finally, we create an instance of the `Codec` class and test it with two examples:\n", - "\n", - "By using the `:;` delimiter and handling the `::` escaping, this code can encode and decode lists of strings, preserving the original content even if it contains colons or the delimiter itself." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 55, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['lint', 'code', 'love', 'you']\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "codec = Codec()\n", - "\n", - "input1 = [\"lint\", \"code\", \"love\", \"you\"]\n", - "encoded1 = codec.encode(input1)\n", - "decoded1 = codec.decode(encoded1)\n", - "print(decoded1)" - ] - }, - { - "cell_type": "code", - "execution_count": 57, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['we', 'say', ':', 'yes']\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "codec = Codec() \n", - "\n", - "input2 = [\"we\", \"say\", \":\", \"yes\"]\n", - "encoded2 = codec.encode(input2)\n", - "decoded2 = codec.decode(encoded2)\n", - "print(decoded2) " - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `encode` and `decode` methods in the provided code.\n", - "\n", - "**Encode Method (`encode`):**\n", - "\n", - "- Time Complexity: O(n * m)\n", - " - Here, `n` is the number of strings in the input list `strs`, and `m` is the average length of these strings.\n", - " - In the worst case, for each string in the list, we iterate over its characters once to replace any colons (`:`) with double colons (`::`) and then append `:;`. This is done for each string in the list.\n", - "\n", - "- Space Complexity: O(n * m)\n", - " - The space complexity is also O(n * m) because we build the encoded string by concatenating the modified strings. In the worst case, the encoded string can be of the same length as the original strings.\n", - "\n", - "**Decode Method (`decode`):**\n", - "\n", - "- Time Complexity: O(n * m)\n", - " - Similar to the encode method, we iterate through the encoded string in the decode method. In the worst case, we may have to scan each character in the encoded string to find the `:;` delimiter.\n", - "\n", - "- Space Complexity: O(n * m)\n", - " - The space complexity of the decode method is also O(n * m) because we build the list of decoded strings, which can be of the same length as the encoded string.\n", - "\n", - "Overall, both the `encode` and `decode` methods have time and space complexities of O(n * m), where `n` is the number of strings in the input list, and `m` is the average length of these strings. The space complexity arises from storing the encoded or decoded strings, and the time complexity arises from iterating through the characters in these strings." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Multiple Delimiters**: Modify the code to allow for multiple delimiters, not just one. Each string could have its own delimiter, and the code should be able to handle this complexity.\n", - "\n", - "2. **Optimize Encoding**: Modify the `encode` method to achieve a more efficient encoding algorithm. Try to minimize the length of the encoded string while ensuring that it can be correctly decoded." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/01. Array Hashing/README.md b/_build/html/_sources/01. Array Hashing/README.md deleted file mode 100644 index a331dab..0000000 --- a/_build/html/_sources/01. Array Hashing/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# Array & Hashing Solutions - Blind 75 LeetCode Problems -![Array & Hashing Solutions](https://img.shields.io/badge/Array_&_Hashing_Solutions-blue)![Blind 75 LeetCode](https://img.shields.io/badge/Blind_75_LeetCode-Problems-blue?labelColor=red) - -This repository contains my solutions to Array & Hashing Problems from Blind 75 LeetCode problems. I've organized the solutions by categories for easier navigation and reference. Each problem solution is presented in Jupyter Notebook format (`.ipynb`). - - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [217. Contains Duplicate](https://github.com/mohsentabibian/LeetCode-Solutions/blob/main/01.%20Array%20Hashing/217.%20Contains%20Duplicate.ipynb) | Easy | -| [242. Valid Anagram](https://github.com/mohsentabibian/LeetCode-Solutions/blob/main/01.%20Array%20Hashing/242.%20Valid%20Anagram.ipynb) | Easy | -| [1. Two Sum](https://github.com/mohsentabibian/LeetCode-Solutions/blob/main/01.%20Array%20Hashing/1.%20Two%20Sum.ipynb) | Easy | -| [49. Group Anagrams](https://github.com/mohsentabibian/LeetCode-Solutions/blob/main/01.%20Array%20Hashing/49.%20Group%20Anagrams.ipynb) | Medium | -| [347. Top K Frequent Elements](https://github.com/mohsentabibian/LeetCode-Solutions/blob/main/01.%20Array%20Hashing/347.%20Top%20K%20Frequent%20Elements.ipynb) | Medium | -| [238. Product of Array Except Self](https://github.com/mohsentabibian/LeetCode-Solutions/blob/main/01.%20Array%20Hashing/238.%20Product%20of%20Array%20Except%20Self.ipynb) | Medium | -| [659. Encode and Decode Strings](https://github.com/mohsentabibian/LeetCode-Solutions/blob/main/01.%20Array%20Hashing/659.%20Encode%20and%20Decode%20Strings.ipynb) | Medium | -| [128. Longest Consecutive Sequence](https://github.com/mohsentabibian/LeetCode-Solutions/blob/main/01.%20Array%20Hashing/128.%20Longest%20Consecutive%20Sequence.ipynb) | Hard | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! diff --git a/_build/html/_sources/02. Two Pointers/11. Container With Most Water.ipynb b/_build/html/_sources/02. Two Pointers/11. Container With Most Water.ipynb deleted file mode 100644 index 284c832..0000000 --- a/_build/html/_sources/02. Two Pointers/11. Container With Most Water.ipynb +++ /dev/null @@ -1,220 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 11. Container With Most Water\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Container With Most Water problem on LeetCode, click here!](https://leetcode.com/problems/container-with-most-water/)\n", - "\n", - "---\n", - "You are given an integer array `height` of length `n`. There are `n` vertical lines drawn such that the two endpoints of the $i^{th}$ line are `(i, 0)` and `(i, height[i])`.\n", - "\n", - "Find two lines that together with the x-axis form a container, such that the container contains the most water.\n", - "\n", - "Return *the maximum amount of water a container can store.*\n", - "\n", - "**Notice** that you may not slant the container.\n", - "\n", - "**Constraints:**\n", - "- `n == height.length`\n", - "- 2 <= `n` <= $10^5$\n", - "- 0 <= `height[i]` <= $10^4$\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def maxArea(height):\n", - " # Initialize the maximum area to 0.\n", - " max_area = 0\n", - " # Initialize two pointers, one at the beginning (left) and one at the end (right) of the array.\n", - " left = 0\n", - " right = len(height) - 1\n", - "\n", - " # Iterate until the left pointer is less than the right pointer.\n", - " while left < right:\n", - " # Calculate the height of the container, which is the minimum height of the two lines.\n", - " h = min(height[left], height[right])\n", - " # Calculate the width of the container, which is the distance between the two pointers.\n", - " width = right - left\n", - " # Calculate the area of the container using height and width and update max_area if it's greater.\n", - " max_area = max(max_area, h * width)\n", - "\n", - " # Move the pointer with the shorter line inward.\n", - " if height[left] < height[right]:\n", - " left += 1\n", - " else:\n", - " right -= 1\n", - "\n", - " # Continue this process until left < right, and then return the maximum area.\n", - " return max_area" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start with initializing `max_area` to 0, which will store the maximum area of water that can be contained by the lines.\n", - "\n", - "2. Two pointers, `left` and `right`, are initialized to the beginning and end of the input `height` array.\n", - "\n", - "3. The main loop runs while `left` is less than `right`. This ensures that we are checking all possible pairs of lines in a systematic way.\n", - "\n", - "4. Inside the loop:\n", - " - We calculate the height of the container `h` as the minimum of the heights at the `left` and `right` pointers. This represents the height of the water the container can hold.\n", - " - We calculate the width of the container as the difference between `right` and `left`. This represents the distance between the two lines.\n", - " - We calculate the area of the container using `h * width` and update `max_area` if the calculated area is greater than the current `max_area`.\n", - "\n", - "5. After calculating the area and updating `max_area`, we move one of the pointers. We move the pointer pointing to the shorter line inward because moving the pointer pointing to the taller line won't increase the height and will only decrease the width, which will result in a smaller area.\n", - "\n", - "6. We continue this process until `left` is no longer less than `right`, indicating that we have checked all possible pairs of lines.\n", - "\n", - "7. Finally, we return the `max_area` which contains the maximum area of water that can be contained by two lines from the input array." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Output: 49\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "height1 = [1, 8, 6, 2, 5, 4, 8, 3, 7]\n", - "result1 = maxArea(height1)\n", - "print(\"Output:\", result1)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Output: 1\n" - ] - } - ], - "source": [ - "# Example 2\n", - "height2 = [1, 1]\n", - "result2 = maxArea(height2)\n", - "print(\"Output:\", result2)" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "e191cf7e-95f9-4e5c-a99b-146c2a779c0b", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Output: 45\n" - ] - } - ], - "source": [ - "# Additional Example\n", - "height3 = [3, 9, 3, 4, 7, 2, 12, 6]\n", - "result3 = maxArea(height3)\n", - "print(\"Output:\", result3)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `maxArea` function:\n", - "\n", - "**Time Complexity:**\n", - "The function uses a two-pointer approach to find the maximum area of water. In the worst case, both the left and right pointers traverse the entire input array once. Therefore, the time complexity is O(n), where n is the number of elements in the `height` array.\n", - "\n", - "**Space Complexity:**\n", - "The function uses a constant amount of extra space for variables like `max_area`, `left`, `right`, `h`, and `width`. It does not use any data structures whose space consumption depends on the input size. As a result, the space complexity is O(1), which means it has constant space complexity.\n", - "\n", - "**In summary,** the `maxArea` function has a time complexity of O(n) and a space complexity of O(1), making it an efficient algorithm for finding the maximum area of water that can be contained by two lines in the input array." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Optimization Challenge:** Modify the maxArea function to not only return the maximum area but also the indices of the two lines that form the container with the maximum area.\n", - "2. **Variant Problem:** Instead of finding the maximum area of water, find the minimum amount of water required to fill all the gaps between the lines. You'll need to return the total water volume needed." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/02. Two Pointers/125. Valid Palindrome.ipynb b/_build/html/_sources/02. Two Pointers/125. Valid Palindrome.ipynb deleted file mode 100644 index 8520b3b..0000000 --- a/_build/html/_sources/02. Two Pointers/125. Valid Palindrome.ipynb +++ /dev/null @@ -1,218 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 125. Valid Palindrome\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Valid Palindrome problem on LeetCode, click here!](https://leetcode.com/problems/valid-palindrome/)\n", - "\n", - "---\n", - "\n", - "A phrase is a **palindrome** if, after converting all uppercase letters into lowercase letters and removing all non-alphanumeric characters, it reads the same forward and backward. Alphanumeric characters include letters and numbers.\n", - "\n", - "Given a string `s`, *return `true` if it is a **palindrome**, or `false` otherwise.*\n", - "\n", - "**Constraints:**\n", - "\n", - "- 1 <= `s.length` <= $2*10^5$\n", - "- `s` consists only of printable ASCII characters.\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def isPalindrome(s):\n", - " # Step 1: Convert the input string to lowercase\n", - " s = s.lower()\n", - " \n", - " # Step 2: Remove all non-alphanumeric characters from the string\n", - " cleaned_s = ''.join(c for c in s if c.isalnum())\n", - " \n", - " # Step 3: Initialize two pointers, one at the beginning and one at the end of the cleaned string\n", - " left, right = 0, len(cleaned_s) - 1\n", - " \n", - " # Step 4: Compare characters using the two pointers while moving them towards each other\n", - " while left < right:\n", - " if cleaned_s[left] != cleaned_s[right]:\n", - " return False # If characters don't match, it's not a palindrome\n", - " left += 1\n", - " right -= 1\n", - " \n", - " # Step 5: If the loop completes without returning False, it's a palindrome\n", - " return True" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. The `isPalindrome` function takes an input string `s`.\n", - "\n", - "2. It starts by converting the input string to lowercase using `s.lower()`. This step ensures that the function is case-insensitive when checking for palindromes.\n", - "\n", - "3. Next, it removes all non-alphanumeric characters from the string and stores the result in the `cleaned_s` variable. It does this by iterating through each character in the input string and only keeping characters that are alphanumeric (letters and digits). This step removes spaces, punctuation, and other non-alphanumeric characters.\n", - "\n", - "4. The function then initializes two pointers, `left` and `right`, which will be used to compare characters from the beginning and end of the cleaned string.\n", - "\n", - "5. In a while loop, it compares characters using the two pointers while moving them towards each other. The loop continues until the `left` pointer is less than the `right` pointer. This is done to check all characters in the cleaned string.\n", - "\n", - "6. Inside the loop, it checks if the characters at the `left` and `right` pointers don't match. If they don't match, it means the input is not a palindrome, so the function returns `False`.\n", - "\n", - "7. If the characters at the `left` and `right` pointers match, the pointers are moved closer to each other by incrementing `left` and decrementing `right`.\n", - "\n", - "8. The loop continues to compare characters until it either finds a mismatch (returning `False`) or until the `left` pointer is greater than or equal to the `right` pointer. If the loop completes without finding a mismatch, it means the input is a palindrome, so the function returns `True`.\n", - "\n", - "In summary, the code converts the input string to lowercase, removes non-alphanumeric characters, and then uses two pointers to compare characters from the cleaned string's beginning and end. If all characters match during the comparison, the function returns `True`, indicating that the input is a palindrome. If any characters do not match, it returns `False`." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "input1 = \"A man, a plan, a canal: Panama\"\n", - "output1 = isPalindrome(input1)\n", - "print(output1)" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 2\n", - "input2 = \"race a car\"\n", - "output2 = isPalindrome(input2)\n", - "print(output2)" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "e191cf7e-95f9-4e5c-a99b-146c2a779c0b", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 3\n", - "input3 = \"\"\n", - "output3 = isPalindrome(input3)\n", - "print(output3)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `isPalindrome` function that uses two pointers:\n", - "\n", - "1. **Time Complexity:**\n", - " - Converting the input string to lowercase using `s.lower()` takes O(n) time, where 'n' is the length of the input string.\n", - " - Removing non-alphanumeric characters using the list comprehension `''.join(c for c in s if c.isalnum())` also takes O(n) time because it iterates through each character in the string once.\n", - " - The comparison of characters using the two pointers (`left` and `right`) is done in a loop that runs until `left` is less than `right`. In the worst case, the loop iterates through half of the string, so it takes O(n/2) time, which is still considered O(n).\n", - "\n", - " Therefore, the overall time complexity of the `isPalindrome` function is O(n), where 'n' is the length of the input string.\n", - "\n", - "2. **Space Complexity:**\n", - " - The space complexity is primarily determined by the additional string `cleaned_s` created to store the cleaned version of the input string. In the worst case, if all characters in the input string are alphanumeric, this cleaned string can be as large as the original input string.\n", - " - Additionally, the function uses two pointers, `left` and `right`, which consume constant space and do not depend on the size of the input.\n", - "\n", - "**In summary,** the overall space complexity of the `isPalindrome` function is O(n) in the worst case, where 'n' is the length of the input string. The space complexity is dominated by the space required for `cleaned_s`." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Longest Palindromic Substring:** Given a string `s`, find and return the longest palindromic substring within `s`. For example, if `s = \"babad\"`, the function should return `\"bab\"` or `\"aba\"`.\n", - "2. **Palindrome with Limited Characters:** Given a string `s` and a list of characters `allowed_chars`, check if `s` is a palindrome considering only the characters from `allowed_chars`. Ignore all other characters. For example, if `s = \"A man, a plan, a canal: Panama\"` and `allowed_chars = ['a', 'm', 'n', 'p']`, the function should return `True`." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/02. Two Pointers/15. 3Sum.ipynb b/_build/html/_sources/02. Two Pointers/15. 3Sum.ipynb deleted file mode 100644 index 06de549..0000000 --- a/_build/html/_sources/02. Two Pointers/15. 3Sum.ipynb +++ /dev/null @@ -1,250 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 15. 3Sum\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the 3Sum problem on LeetCode, click here!](https://leetcode.com/problems/3sum/)\n", - "\n", - "---\n", - "Given an integer array nums, *return all the triplets `[nums[i], nums[j], nums[k]]` such that `i != j`, `i != k`, and `j != k`, and `nums[i] + nums[j] + nums[k] == 0`.*\n", - "\n", - "**Notice** that the solution set must not contain duplicate triplets.\n", - "\n", - "**Constraints:**\n", - "\n", - "- `3 <= nums.length <= 3000`\n", - "- $-10^5$ <= `nums[i]` <= $10^5$\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def threeSum(nums):\n", - " # Sort the input array in ascending order\n", - " nums.sort()\n", - " triplets = []\n", - " \n", - " for i in range(len(nums) - 2):\n", - " # Skip duplicates to avoid duplicate triplets\n", - " if i > 0 and nums[i] == nums[i - 1]:\n", - " continue\n", - " \n", - " left, right = i + 1, len(nums) - 1\n", - " \n", - " while left < right:\n", - " # Calculate the total sum of the current triplet\n", - " total = nums[i] + nums[left] + nums[right]\n", - " \n", - " if total == 0:\n", - " # If the total is zero, we found a valid triplet\n", - " triplets.append([nums[i], nums[left], nums[right]])\n", - " \n", - " # Skip duplicates of left and right pointers\n", - " while left < right and nums[left] == nums[left + 1]:\n", - " left += 1\n", - " while left < right and nums[right] == nums[right - 1]:\n", - " right -= 1\n", - " \n", - " # Move the pointers to the next unique elements\n", - " left += 1\n", - " right -= 1\n", - " elif total < 0:\n", - " # If the total is negative, we need to increase the sum by moving the left pointer to the right\n", - " left += 1\n", - " else:\n", - " # If the total is positive, we need to decrease the sum by moving the right pointer to the left\n", - " right -= 1\n", - " \n", - " return triplets" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. It starts by sorting the input array `nums` in ascending order. Sorting helps in efficiently finding triplets that sum up to zero.\n", - "\n", - "2. It initializes an empty list `triplets` to store the unique triplets that meet the given conditions.\n", - "\n", - "3. The code then iterates through the `nums` array using a loop with index `i`. This loop will consider each element of the array as a potential starting point for a triplet.\n", - "\n", - "4. Inside the loop, it checks for duplicates and skips them. This is done to ensure that the solution set does not contain duplicate triplets. If `nums[i]` is the same as the previous element `nums[i-1]`, it continues to the next iteration of the loop.\n", - "\n", - "5. Two pointers, `left` and `right`, are initialized. `left` starts just after the current element `nums[i]`, and `right` starts at the end of the array.\n", - "\n", - "6. The code enters another loop with `left` and `right` pointers, trying to find a triplet that sums up to zero.\n", - "\n", - "7. It calculates the `total` sum of the current triplet as `nums[i] + nums[left] + nums[right]`.\n", - "\n", - "8. If `total` is zero, it means a valid triplet is found, so it appends `[nums[i], nums[left], nums[right]]` to the `triplets` list. Then, it moves both the `left` and `right` pointers to their next unique elements while skipping duplicates.\n", - "\n", - "9. If `total` is less than zero, it means the sum is negative, so it increments the `left` pointer to move towards a larger sum.\n", - "\n", - "10. If `total` is greater than zero, it means the sum is positive, so it decrements the `right` pointer to move towards a smaller sum.\n", - "\n", - "11. This process continues until all possible triplets have been considered.\n", - "\n", - "12. Finally, the function returns the `triplets` list, which contains all the unique triplets that sum up to zero in the sorted `nums` array." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[-1, -1, 2], [-1, 0, 1]]\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "nums = [-1, 0, 1, 2, -1, -4]\n", - "result = threeSum(nums)\n", - "print(result)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[]\n" - ] - } - ], - "source": [ - "# Example 2\n", - "nums = [0, 1, 1]\n", - "result = threeSum(nums)\n", - "print(result)" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "e191cf7e-95f9-4e5c-a99b-146c2a779c0b", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[0, 0, 0]]\n" - ] - } - ], - "source": [ - "# Example 3\n", - "nums = [0, 0, 0]\n", - "result = threeSum(nums)\n", - "print(result)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `threeSum` function:\n", - "\n", - "**Time Complexity:**\n", - "1. Sorting the input array `nums` takes O(n log n) time, where n is the length of the array.\n", - "\n", - "2. The outer loop runs for each element of the array, so it iterates O(n) times.\n", - "\n", - "3. Inside the outer loop, we have a while loop with two pointers (`left` and `right`). In the worst case, the while loop can iterate O(n) times (when all elements are unique).\n", - "\n", - "4. Inside the while loop, we have constant time operations (additions, comparisons, and list appends).\n", - "\n", - "Overall, the time complexity of the `threeSum` function is dominated by the sorting step, so it is O(n log n) due to the sorting. The other operations inside the loops contribute linearly but are dominated by the sorting step.\n", - "\n", - "**Space Complexity:**\n", - "1. The space used by the `triplets` list to store the output triplets is O(k), where k is the number of unique triplets that sum up to zero. In the worst case, this can be O(n^2/3) because there can be roughly O(n^2) possible triplets, and many of them may sum up to zero.\n", - "\n", - "2. Other than the `triplets` list, the function uses only a constant amount of additional space for variables like `i`, `left`, `right`, and `total`.\n", - "\n", - "Overall, the space complexity of the `threeSum` function is O(k), where k is the number of unique triplets that meet the criteria. It's important to note that the space complexity does not depend on the size of the input array but rather on the number of valid triplets found.\n", - "\n", - "**In summary:**\n", - "- Time Complexity: O(n log n) due to sorting (dominant factor) and O(n^2) in the worst case for the nested loops.\n", - "- Space Complexity: O(k) for storing the output triplets, where k is the number of unique triplets that meet the criteria." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **K-Sum Problem:** Generalize the problem to the K-Sum problem, where instead of finding triplets that sum to zero, you need to find K elements that sum to a target value. Implement a function for this generalization.\n", - "2. **Count the Number of Unique Triplets:** Modify the algorithm to count the number of unique triplets that satisfy the conditions instead of returning the triplets themselves. This will require some modifications to handle duplicates efficiently." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/02. Two Pointers/README.md b/_build/html/_sources/02. Two Pointers/README.md deleted file mode 100644 index 0d4c7cf..0000000 --- a/_build/html/_sources/02. Two Pointers/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# Two Pointers Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [125. Valid Palindrome](https://leetcode.com/problems/valid-palindrome/) | Easy | -| [15. 3Sum](https://leetcode.com/problems/3sum/) | Medium | -| [11. Container With Most Water](https://leetcode.com/problems/container-with-most-water/) | Medium | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! \ No newline at end of file diff --git a/_build/html/_sources/03. Sliding Window/121. Best Time to Buy and Sell Stock.ipynb b/_build/html/_sources/03. Sliding Window/121. Best Time to Buy and Sell Stock.ipynb deleted file mode 100644 index 554c940..0000000 --- a/_build/html/_sources/03. Sliding Window/121. Best Time to Buy and Sell Stock.ipynb +++ /dev/null @@ -1,191 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 121. Best Time to Buy and Sell Stock\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Best Time to Buy and Sell Stock problem on LeetCode, click here!](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/)\n", - "\n", - "---\n", - "\n", - "You are given an array `prices` where `prices[i]` is the price of a given stock on the $i^{th}$ day.\n", - "\n", - "You want to maximize your profit by choosing a **single day** to buy one stock and choosing a **different day in the future** to sell that stock.\n", - "\n", - "*Return the maximum profit you can achieve from this transaction. If you cannot achieve any profit, return `0`.*\n", - "\n", - "**Constraints:**\n", - "\n", - "- 1 <= `prices.length` <= $10^5$\n", - "- 0 <= `prices[i]` <= $10^4$\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 65, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def maxProfit(prices):\n", - " if not prices:\n", - " return 0\n", - " \n", - " min_price = prices[0]\n", - " max_profit = 0\n", - " \n", - " for price in prices:\n", - " # Update the minimum price if a lower price is encountered\n", - " min_price = min(min_price, price)\n", - " # Calculate the profit if selling at the current price\n", - " max_profit = max(max_profit, price - min_price)\n", - " \n", - " return max_profit" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "- The `maxProfit` function takes a single argument, `prices`, which is a list of stock prices.\n", - "- The first line of the function checks if the `prices` list is empty. If it's empty, there are no prices to analyze, so the function returns 0 (no profit can be made).\n", - "\n", - "- Then, we initialize two variables:\n", - " - `min_price`: This variable will keep track of the minimum price seen so far. We initialize it with the price of the first day in the list (`prices[0]`).\n", - " - `max_profit`: This variable will keep track of the maximum profit we can achieve. We initialize it to 0 because initially, we haven't made any profit.\n", - "\n", - "- We start iterating through the `prices` list, where `price` represents the stock price for the current day.\n", - "\n", - "- In each iteration, we check if the current `price` is lower than the `min_price` we've seen so far. If it is, we update `min_price` to the current `price`. This is because we want to buy the stock at the lowest possible price.\n", - "\n", - "- Next, we calculate the profit we would make if we sold the stock at the current `price` (assuming we bought it at `min_price`). We do this by subtracting `min_price` from the current `price`. This represents the profit for the current day.\n", - "\n", - "- We also use the `max` function to keep track of the maximum profit seen so far. If the profit calculated for the current day is greater than the `max_profit` we've seen previously, we update `max_profit` with this higher value.\n", - "\n", - "- Finally, after iterating through all the days in the `prices` list, we return `max_profit`, which represents the maximum profit that can be achieved by buying and selling a single stock." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 66, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "5\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "prices1 = [7, 1, 5, 3, 6, 4]\n", - "print(maxProfit(prices1))" - ] - }, - { - "cell_type": "code", - "execution_count": 67, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "prices2 = [7, 6, 4, 3, 1]\n", - "print(maxProfit(prices2))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "- The code iterates through the `prices` array once, examining each price exactly once.\n", - "- Within the loop, there are constant-time operations such as comparisons, additions, and subtractions.\n", - "- Therefore, the time complexity of this code is O(n), where n is the length of the `prices` array. It performs a linear number of operations relative to the size of the input.\n", - "\n", - "**Space Complexity:**\n", - "- The space complexity of the code is constant, O(1).\n", - "- Regardless of the size of the input `prices` array, the code only uses a fixed amount of additional memory to store two variables (`min_price` and `max_profit`) and a few loop variables.\n", - "- The memory usage does not depend on the size of the input, so it is considered constant space complexity.\n", - "\n", - "**In summary:**\n", - "- Time Complexity: O(n) where n is the length of the `prices` array.\n", - "- Space Complexity: O(1) (constant space usage)." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Multiple Transactions Allowed:** Modify the problem to allow multiple transactions (buy and sell multiple times), but you must sell before buying again. Find the maximum profit in this scenario.\n", - "2. **K Transactions Allowed:** Extend the problem to allow at most k transactions. Find the maximum profit considering this constraint.\n", - "3. **With Transaction Fee:** Introduce a transaction fee for each buy/sell operation. Modify the code to maximize profit while considering the transaction fee." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/03. Sliding Window/3. Longest Substring Without Repeating Characters.ipynb b/_build/html/_sources/03. Sliding Window/3. Longest Substring Without Repeating Characters.ipynb deleted file mode 100644 index 4a516de..0000000 --- a/_build/html/_sources/03. Sliding Window/3. Longest Substring Without Repeating Characters.ipynb +++ /dev/null @@ -1,214 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 3. Longest Substring Without Repeating Characters\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Longest Substring Without Repeating Characters problem on LeetCode, click here!](https://leetcode.com/problems/longest-substring-without-repeating-characters/)\n", - "\n", - "---\n", - "Given a string `s`, find the length of the **longest substring** without repeating characters.\n", - "\n", - "**Constraints:**\n", - "\n", - "- 0 <= `s.length` <= $5 * 10^4$\n", - "- `s` consists of English letters, digits, symbols and spaces.\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 61, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def length_of_longest_substring(s):\n", - " # Create a dictionary to store the index of each character's last occurrence.\n", - " char_index = {}\n", - " \n", - " # Initialize variables to keep track of the start and end of the current substring.\n", - " start = 0\n", - " max_length = 0\n", - " \n", - " for end in range(len(s)):\n", - " # If the character is in the dictionary and its last occurrence is after the start of the current substring,\n", - " # update the start of the substring to the next character after its last occurrence.\n", - " if s[end] in char_index and char_index[s[end]] >= start:\n", - " start = char_index[s[end]] + 1\n", - " \n", - " # Update the last occurrence index of the current character.\n", - " char_index[s[end]] = end\n", - " \n", - " # Calculate the length of the current substring and update the maximum length if necessary.\n", - " current_length = end - start + 1\n", - " max_length = max(max_length, current_length)\n", - " \n", - " return max_length" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start by defining a function called `length_of_longest_substring` that takes a single argument `s`, which is the input string for which we want to find the length of the longest substring without repeating characters.\n", - "\n", - "2. We create a dictionary called `char_index` to store the index of the last occurrence of each character in the input string. This dictionary will help us keep track of where each character was last seen.\n", - "\n", - "3. We initialize two variables, `start` and `max_length`. \n", - " - `start` represents the start index of the current substring without repeating characters. It starts at 0.\n", - " - `max_length` is used to keep track of the maximum length found so far and is initially set to 0.\n", - "\n", - "4. We then iterate through the input string `s` using a for loop, where the loop variable `end` represents the current end index of the substring we are considering.\n", - "\n", - "5. Inside the loop:\n", - " - We check if the character `s[end]` is already in the `char_index` dictionary and if its last occurrence is within or after the current substring. If so, it means that we've encountered a repeating character, and we need to update the `start` of the substring to the next character after the last occurrence of `s[end]`. This ensures that we have a new valid substring without repeating characters.\n", - " - We then update the `char_index` dictionary by storing the current index `end` as the last occurrence index of the character `s[end]`.\n", - "\n", - "6. Next, we calculate the length of the current substring without repeating characters, which is `current_length = end - start + 1`. We add 1 to account for the fact that the indices are zero-based.\n", - "\n", - "7. We update the `max_length` with the maximum of its current value and the `current_length`. This step ensures that we keep track of the longest valid substring we have encountered so far.\n", - "\n", - "8. The loop continues to iterate through the input string, and at the end, we return the `max_length`, which represents the length of the longest substring without repeating characters." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 62, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "print(length_of_longest_substring(\"abcabcbb\"))" - ] - }, - { - "cell_type": "code", - "execution_count": 63, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "print(length_of_longest_substring(\"bbbbb\"))" - ] - }, - { - "cell_type": "code", - "execution_count": 64, - "id": "cf04eba0-0ead-4e8b-ba33-4316ea64a9d3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "print(length_of_longest_substring(\"pwwkew\"))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "Let's analyze the time and space complexity of the `length_of_longest_substring` function:\n", - "\n", - "**Time Complexity:**\n", - "- The function iterates through the input string `s` using a single for loop. The loop runs from the beginning of the string to the end once.\n", - "- Inside the loop, we perform constant-time operations such as dictionary lookups and updates, comparisons, and arithmetic operations.\n", - "- Therefore, the time complexity of the function is O(n), where n is the length of the input string `s`.\n", - "\n", - "**Space Complexity:**\n", - "- The primary data structure that consumes space in this function is the `char_index` dictionary.\n", - "- In the worst case, if there are no repeating characters in the input string, the dictionary can store all unique characters in the string.\n", - "- Therefore, the space complexity is O(min(n, m)), where n is the length of the input string `s`, and m is the number of unique characters in the string. In the worst case, when all characters are unique, m is equal to n, so the space complexity is O(n).\n", - "- Additionally, there are a few integer variables used for indices and lengths, which consume constant space.\n", - "- Overall, the space complexity of the function is O(min(n, m)) or simply O(n) in the worst case.\n", - "\n", - "**In summary,** the time complexity of the `length_of_longest_substring` function is O(n), and the space complexity is O(n) in the worst case due to the `char_index` dictionary. This algorithm provides an efficient way to find the length of the longest substring without repeating characters in linear time." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Longest Substring with K Distinct Characters:** Modify the problem to find the length of the longest substring with exactly K distinct characters. For example, given the input string \"abcabcbb\" and K = 2, the answer would be 4 because the longest substring with two distinct characters is \"abca.\"\n", - "2. **Longest Substring with Unique Characters:** Write a function to find the length of the longest substring in a given string where all characters are unique. For example, given the input string \"abcabcbb,\" the answer would be 4 because \"abcd\" is the longest substring with unique characters." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/03. Sliding Window/424. Longest Repeating Character Replacement.ipynb b/_build/html/_sources/03. Sliding Window/424. Longest Repeating Character Replacement.ipynb deleted file mode 100644 index 07e96a2..0000000 --- a/_build/html/_sources/03. Sliding Window/424. Longest Repeating Character Replacement.ipynb +++ /dev/null @@ -1,195 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 424. Longest Repeating Character Replacement\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Longest Repeating Character Replacement problem on LeetCode, click here!](https://leetcode.com/problems/longest-repeating-character-replacement/)\n", - "\n", - "---\n", - "You are given a string `s` and an integer `k`. You can choose any character of the string and change it to any other uppercase English character. You can perform this operation at most `k` times.\n", - "\n", - "*Return the length of the longest substring containing the same letter you can get after performing the above operations.*\n", - "\n", - "**Constraints:**\n", - "\n", - "- 1 <= `s.length` <= $10^5$\n", - "- `s` consists of only uppercase English letters.\n", - "- `0 <= k <= s.length`" - ] - }, - { - "cell_type": "code", - "execution_count": 58, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def characterReplacement(s, k):\n", - " max_length = 0 # Initialize the maximum length\n", - " max_count = 0 # Initialize the maximum count of repeating characters\n", - " start = 0 # Initialize the start of the sliding window\n", - " char_count = {} # Dictionary to store the count of each character\n", - "\n", - " for end in range(len(s)):\n", - " # Update the count of the current character in the dictionary\n", - " char_count[s[end]] = char_count.get(s[end], 0) + 1\n", - " \n", - " # Update the maximum count of repeating characters\n", - " max_count = max(max_count, char_count[s[end]])\n", - " \n", - " # Check if the current window size is greater than k\n", - " if (end - start + 1) - max_count > k:\n", - " # Move the start of the window to the right\n", - " char_count[s[start]] -= 1\n", - " start += 1\n", - " \n", - " # Update the maximum length\n", - " max_length = max(max_length, end - start + 1)\n", - "\n", - " return max_length" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We initialize some variables:\n", - " - `max_length` to keep track of the maximum length of the substring containing the same letter.\n", - " - `max_count` to keep track of the maximum count of repeating characters within the current window.\n", - " - `start` to represent the start index of the sliding window.\n", - " - `char_count` is a dictionary that will store the count of each character within the current window.\n", - "\n", - "2. We use a `for` loop to iterate through the characters of the string `s`.\n", - "\n", - "3. Inside the loop, we do the following for each character at position `end`:\n", - " - Update the count of the current character in the `char_count` dictionary.\n", - " - Update the `max_count` to be the maximum of the current `max_count` and the count of the current character. This keeps track of the maximum count of repeating characters within the current window.\n", - "\n", - "4. We check if the current window size (the difference between `end` and `start` plus one) minus the `max_count` is greater than `k`. This condition checks whether we have exceeded the allowed number of replacements (`k`) within the current window.\n", - "\n", - " - If we have exceeded the allowed replacements, it means we need to shrink the window from the left side. We do this by moving the `start` of the window to the right and decrementing the count of the character at `s[start]` in the `char_count` dictionary. This effectively removes characters from the left side of the window until we have a valid window again.\n", - "\n", - " - By doing this, we ensure that the difference between the current window size and the `max_count` is always less than or equal to `k`.\n", - "\n", - "5. After each character, we update the `max_length` to be the maximum of the current `max_length` and the size of the current window (`end - start + 1`).\n", - "\n", - "6. Finally, we return `max_length`, which holds the length of the longest substring containing the same letter with at most `k` replacements." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 59, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "s1 = \"ABAB\"\n", - "k1 = 2\n", - "print(characterReplacement(s1, k1))" - ] - }, - { - "cell_type": "code", - "execution_count": 60, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "s2 = \"AABABBA\"\n", - "k2 = 1\n", - "print(characterReplacement(s2, k2))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "- The code uses a single `for` loop to iterate through the characters of the input string `s`. The loop runs from the beginning to the end of the string.\n", - "- Inside the loop, we perform constant-time operations such as updating the `char_count` dictionary and updating variables like `max_count` and `max_length`.\n", - "- The code's time complexity is primarily determined by the loop, which iterates through each character in the string once. Therefore, the time complexity is O(n), where n is the length of the input string `s`.\n", - "\n", - "**Space Complexity:**\n", - "- The code uses several variables to store information, but the space they consume is constant and does not depend on the size of the input string. These variables include `max_length`, `max_count`, `start`, and `char_count`. Therefore, the space complexity is O(1) or constant space.\n", - "\n", - "**In summary**, the time complexity of the code is O(n), where n is the length of the input string, and the space complexity is O(1), as it uses a constant amount of additional space regardless of the input size. This algorithm efficiently solves the problem with a linear time complexity." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Optimization Challenge:** Modify the code to find the longest substring containing the same letter with at most k replacements in O(n) time complexity and O(1) space complexity. Hint: You may need to update the approach to achieve this.\n", - "2. **Variation with Lowercase Letters:** Extend the problem to include both uppercase and lowercase English letters in the input string s. Write a function that can handle this extended input and still find the longest substring with at most k replacements efficiently." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/03. Sliding Window/76. Minimum Window Substring.ipynb b/_build/html/_sources/03. Sliding Window/76. Minimum Window Substring.ipynb deleted file mode 100644 index 33c2a44..0000000 --- a/_build/html/_sources/03. Sliding Window/76. Minimum Window Substring.ipynb +++ /dev/null @@ -1,273 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 76. Minimum Window Substring\n", - "\n", - "**Difficulty:** Hard\n", - "\n", - "**Link to Problem:** [To see the Minimum Window Substring problem on LeetCode, click here!](https://leetcode.com/problems/minimum-window-substring/)\n", - "\n", - "---\n", - "Given two strings `s` and `t` of lengths `m` and `n` respectively, return *the **minimum window substring** of `s` such that every character in `t` (**including duplicates**) is included in the window. If there is no such substring, return the empty string `\"\"`.*\n", - "\n", - "The testcases will be generated such that the answer is **unique**.\n", - "\n", - "**Constraints:**\n", - "\n", - "- `m == s.length`\n", - "- `n == t.length`\n", - "- 1 <= `m, n` <= $10^5$\n", - "- `s` and `t` consist of uppercase and lowercase English letters.\n", - "\n", - "**Follow up**: Could you find an algorithm that runs in $O(m + n)$ time?" - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def min_window_substring(s, t):\n", - " if not s or not t:\n", - " return \"\"\n", - "\n", - " # Initialize dictionaries to keep track of character counts for t and the current window in s.\n", - " t_dict = {}\n", - " current_window_dict = {}\n", - " \n", - " # Populate t_dict with character counts for string t.\n", - " for char in t:\n", - " t_dict[char] = t_dict.get(char, 0) + 1\n", - "\n", - " # Initialize pointers for the sliding window.\n", - " left = 0\n", - " min_len = float('inf')\n", - " min_window = \"\"\n", - " required_chars = len(t_dict)\n", - "\n", - " # Initialize a variable to keep track of how many required characters have been found in the current window.\n", - " found_chars = 0\n", - "\n", - " # Iterate over the string s using the right pointer.\n", - " for right in range(len(s)):\n", - " char = s[right]\n", - "\n", - " # Update the current_window_dict.\n", - " current_window_dict[char] = current_window_dict.get(char, 0) + 1\n", - "\n", - " # Check if the current character is a required character and if its count matches the required count.\n", - " if char in t_dict and current_window_dict[char] == t_dict[char]:\n", - " found_chars += 1\n", - "\n", - " # Try to minimize the window by moving the left pointer.\n", - " while left <= right and found_chars == required_chars:\n", - " # Calculate the current window size.\n", - " window_size = right - left + 1\n", - "\n", - " # If the current window is smaller than the minimum found so far, update min_len and min_window.\n", - " if window_size < min_len:\n", - " min_len = window_size\n", - " min_window = s[left:right+1]\n", - "\n", - " # Move the left pointer to the right to shrink the window.\n", - " left_char = s[left]\n", - " current_window_dict[left_char] -= 1\n", - "\n", - " # Check if the character removed from the window was a required character.\n", - " if left_char in t_dict and current_window_dict[left_char] < t_dict[left_char]:\n", - " found_chars -= 1\n", - "\n", - " # Move the left pointer further to continue shrinking the window.\n", - " left += 1\n", - "\n", - " return min_window" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start by checking if either of the input strings `s` or `t` is empty. If either of them is empty, we return an empty string since there can't be any valid substring in this case.\n", - "\n", - "2. We initialize two dictionaries: `t_dict` and `current_window_dict`. These dictionaries will be used to keep track of character counts in the string `t` and the current window in string `s`, respectively.\n", - "\n", - "3. We populate the `t_dict` dictionary by iterating through string `t`. For each character, we increment its count in the dictionary using `t_dict.get(char, 0) + 1`. This allows us to count the occurrences of each character in `t`.\n", - "\n", - "4. We initialize two pointers: `left` and `right`. The `left` pointer will represent the start of the current window, and the `right` pointer will represent the end of the current window. We also initialize `min_len` to store the length of the minimum window found so far, and `min_window` to store the actual minimum window substring.\n", - "\n", - "5. We determine the number of required characters in `t` (i.e., the number of distinct characters in `t`) and store it in the variable `required_chars`.\n", - "\n", - "6. We initialize a variable `found_chars` to keep track of how many required characters have been found in the current window. Initially, it is set to 0.\n", - "\n", - "7. We iterate over the string `s` using the `right` pointer. In each iteration, we do the following:\n", - "\n", - " - Update the `current_window_dict` by incrementing the count of the current character.\n", - " \n", - " - Check if the current character is a required character (present in `t_dict`) and if its count in the `current_window_dict` matches the required count from `t_dict`. If so, we increment `found_chars`.\n", - "\n", - "8. After updating the window, we attempt to minimize the window size by moving the `left` pointer to the right. In this step, we:\n", - "\n", - " - Calculate the size of the current window.\n", - " \n", - " - If the current window size is smaller than the minimum found so far (`min_len`), we update `min_len` and `min_window` to store the current window substring.\n", - " \n", - " - Move the `left` pointer to the right to shrink the window.\n", - " \n", - " - Check if the character being removed from the window was a required character. If it was, we decrement `found_chars`.\n", - " \n", - " - Continue moving the `left` pointer further to continue shrinking the window if the window still contains all required characters.\n", - "\n", - "9. Finally, we return `min_window`, which will contain the minimum window substring that contains all characters from `t`." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 55, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "BANC\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "print(min_window_substring(\"ADOBECODEBANC\", \"ABC\"))" - ] - }, - { - "cell_type": "code", - "execution_count": 56, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "a\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "print(min_window_substring(\"a\", \"a\")) " - ] - }, - { - "cell_type": "code", - "execution_count": 57, - "id": "6c69a707-02af-4212-b2e7-1881d62a62d2", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "print(min_window_substring(\"a\", \"aa\")) " - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the `min_window_substring` function:\n", - "\n", - "**Time Complexity:**\n", - "- The main loop iterates through the string `s` from left to right using the `right` pointer. This loop runs in O(m) time, where 'm' is the length of string `s`.\n", - "\n", - "- Inside the loop, we have a while loop that moves the `left` pointer to the right to shrink the window as needed. In the worst case, this while loop can also run in O(m) time because in the worst case, we may have to move the `left` pointer all the way to the end of the string.\n", - "\n", - "- Within each iteration of the while loop, we perform constant time operations, such as updating dictionaries and comparing character counts.\n", - "\n", - "- The initialization of the `t_dict` dictionary takes O(n) time, where 'n' is the length of string `t`.\n", - "\n", - "Therefore, the overall time complexity of the function is O(m + n) because the dominant factor is the length of string `s`, and the length of string `t` has a smaller impact.\n", - "\n", - "**Space Complexity:**\n", - "- The space complexity is determined by the space used by the `t_dict` dictionary, the `current_window_dict` dictionary, and a few variables.\n", - "\n", - "- The `t_dict` dictionary stores character counts for string `t`. In the worst case, when all characters in `t` are distinct, this dictionary can have a maximum of 'n' key-value pairs. So, the space complexity for `t_dict` is O(n).\n", - "\n", - "- The `current_window_dict` dictionary stores character counts for the current window. In the worst case, it can have a maximum of 'm' key-value pairs. So, the space complexity for `current_window_dict` is also O(m).\n", - "\n", - "- Other variables used in the function, such as `left`, `right`, `min_len`, `min_window`, `required_chars`, and `found_chars`, are all of constant size and do not depend on the input sizes.\n", - "\n", - "**In summary**, the overall space complexity of the function is O(max(m, n)), which means it is determined by the larger of the two input strings' lengths. This is because the space used for `t_dict` and `current_window_dict` dominates the space complexity." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Smallest Distinct Substring:** Instead of finding the minimum window substring containing all characters, find the smallest distinct (unique) substring of s that contains all characters from t. This variation adds complexity because you must find a substring with distinct characters.\n", - "2. **No Extra Space:** Solve the problem without using any extra space, such as dictionaries or arrays, other than a constant amount of space. This is a significant optimization challenge." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/03. Sliding Window/README.md b/_build/html/_sources/03. Sliding Window/README.md deleted file mode 100644 index e1294ff..0000000 --- a/_build/html/_sources/03. Sliding Window/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# Sliding Window Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [121. Best Time to Buy And Sell Stock](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/) | Easy | -| [3. Longest Substring Without Repeating Characters](https://leetcode.com/problems/longest-substring-without-repeating-characters/) | Medium | -| [424. Longest Repeating Character Replacement](https://leetcode.com/problems/longest-repeating-character-replacement/) | Medium | -| [76. Minimum Window Substring](https://leetcode.com/problems/minimum-window-substring/) | Hard | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! \ No newline at end of file diff --git a/_build/html/_sources/04. Stack/20. Valid Parentheses.ipynb b/_build/html/_sources/04. Stack/20. Valid Parentheses.ipynb deleted file mode 100644 index c47292f..0000000 --- a/_build/html/_sources/04. Stack/20. Valid Parentheses.ipynb +++ /dev/null @@ -1,220 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 20. Valid Parentheses\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Valid Parentheses problem on LeetCode, click here!](https://leetcode.com/problems/valid-parentheses/)\n", - "\n", - "---\n", - "\n", - "Given a string s containing just the characters `'('`, `')'`, `'{'`, `'}'`, `'['` and `']'`, determine if the input string is valid.\n", - "\n", - "An input string is valid if:\n", - "\n", - "1. Open brackets must be closed by the same type of brackets.\n", - "2. Open brackets must be closed in the correct order.\n", - "3. Every close bracket has a corresponding open bracket of the same type.\n", - "\n", - "**Constraints:**\n", - "\n", - "- 1 <= `s.length` <= $10^4$\n", - "- `s` consists of parentheses only `'()[]{}'`." - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def isValid(s):\n", - " # Create an empty stack to store opening brackets\n", - " stack = []\n", - " \n", - " # Define a mapping for matching brackets\n", - " bracket_mapping = {')': '(', '}': '{', ']': '['}\n", - " \n", - " # Iterate through the characters in the input string\n", - " for char in s:\n", - " # If the character is an opening bracket, push it onto the stack\n", - " if char in bracket_mapping.values():\n", - " stack.append(char)\n", - " # If the character is a closing bracket\n", - " elif char in bracket_mapping.keys():\n", - " # Pop the top element from the stack if it exists, or use a dummy value '#'\n", - " top_element = stack.pop() if stack else '#'\n", - " # If the popped element does not match the corresponding opening bracket, return False\n", - " if bracket_mapping[char] != top_element:\n", - " return False\n", - " # If the character is not a bracket, ignore it\n", - " \n", - " # After processing the entire string, if there are any unmatched opening brackets left in the stack, return False\n", - " return len(stack) == 0" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start by defining the `isValid` function that takes a single argument `s`, which is the input string containing parentheses and brackets.\n", - "\n", - "2. Inside the function, we create an empty stack, which is a list in Python, to store opening brackets as we encounter them in the input string. The stack will help us keep track of the brackets and their order.\n", - "\n", - "3. We define a `bracket_mapping` dictionary that maps each closing bracket to its corresponding opening bracket. This mapping will be used to check if a closing bracket matches the most recent opening bracket in the stack.\n", - "\n", - "4. We iterate through each character `char` in the input string `s` using a `for` loop.\n", - "\n", - "5. If the character `char` is an opening bracket (i.e., it exists in the `values()` of `bracket_mapping`), we push it onto the stack using the `append()` method.\n", - "\n", - "6. If the character `char` is a closing bracket (i.e., it exists in the `keys()` of `bracket_mapping`), we need to check if it matches the corresponding opening bracket. To do this, we pop the top element from the stack (if it exists) and store it in `top_element`. We use a dummy value `'#'` if the stack is empty to avoid errors.\n", - "\n", - "7. We then compare `top_element` with the corresponding opening bracket using `bracket_mapping[char]`. If they do not match, it means the string is not valid, and we return `False`.\n", - "\n", - "8. If the character `char` is not a bracket, we simply ignore it and continue the loop.\n", - "\n", - "9. After processing the entire string, we check if there are any unmatched opening brackets left in the stack. If the stack is empty, it means all opening brackets have been properly matched and closed, and we return `True`. Otherwise, we return `False`.\n", - "\n", - "10. Finally, we provide some test cases at the bottom of the code to demonstrate how the function works for different input strings." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "print(isValid(\"()\")) " - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "print(isValid(\"()[]{}\")) " - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "id": "6c69a707-02af-4212-b2e7-1881d62a62d2", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "print(isValid(\"(]\")) " - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the `isValid` function:\n", - "\n", - "**Time Complexity:**\n", - "- The function iterates through each character in the input string `s` once, performing constant-time operations for each character.\n", - "- Pushing and popping elements from the stack (list) also takes constant time in most cases.\n", - "- Therefore, the overall time complexity of the function is $O(n)$, where $n$ is the length of the input string `s`.\n", - "\n", - "**Space Complexity:**\n", - "- The space complexity of the function is determined by the space used by the stack and the `bracket_mapping` dictionary.\n", - "- In the worst case, if the input string `s` consists entirely of opening brackets, the stack can potentially contain all of these opening brackets, resulting in a space complexity of $O(n)$ in terms of the stack.\n", - "- The `bracket_mapping` dictionary has a constant number of key-value pairs (3 pairs in this case).\n", - "- Therefore, the overall space complexity of the function is $O(n)$, where $n$ is the length of the input string `s`, mainly due to the stack space.\n", - "\n", - "**In summary:**\n", - "- The time complexity is $O(n)$ because we iterate through the string once.\n", - "- The space complexity is $O(n)$ due to the stack used to keep track of opening brackets." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Valid Expressions:** Modify the problem to validate not only brackets but also arithmetic expressions containing parentheses, such as \"$2 * (3 + 5) / (4 - 2)$\".\n", - "2. **Valid Parentheses Combinations:**\n", - "Write a function to generate all valid combinations of n pairs of parentheses, where $n$ is a positive integer. For example, for $n = 3$, the valid combinations are [\"((()))\", \"(()())\", \"(())()\", \"()(())\", \"()()()\"]." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/04. Stack/README.md b/_build/html/_sources/04. Stack/README.md deleted file mode 100644 index 2ed115b..0000000 --- a/_build/html/_sources/04. Stack/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# Stack Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [20. Valid Parentheses](https://leetcode.com/problems/valid-parentheses/) | Easy | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! \ No newline at end of file diff --git a/_build/html/_sources/05. Binary Search/153. Find Minimum in Rotated Sorted Array.ipynb b/_build/html/_sources/05. Binary Search/153. Find Minimum in Rotated Sorted Array.ipynb deleted file mode 100644 index 98f2331..0000000 --- a/_build/html/_sources/05. Binary Search/153. Find Minimum in Rotated Sorted Array.ipynb +++ /dev/null @@ -1,228 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 153. Find Minimum in Rotated Sorted Array\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Find Minimum in Rotated Sorted Array problem on LeetCode, click here!](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/)\n", - "\n", - "---\n", - "\n", - "Suppose an array of length `n` sorted in ascending order is **rotated** between `1` and `n` times. For example, the array `nums = [0,1,2,4,5,6,7]` might become:\n", - "\n", - "- `[4,5,6,7,0,1,2]` if it was rotated `4` times.\n", - "- `[0,1,2,4,5,6,7]` if it was rotated `7` times.\n", - "\n", - "Notice that **rotating** an array `[a[0], a[1], a[2], ..., a[n-1]]` 1 time results in the array `[a[n-1], a[0], a[1], a[2], ..., a[n-2]]`.\n", - "\n", - "Given the sorted rotated array `nums` of **unique** elements, return *the minimum element of this array.*\n", - "\n", - "You must write an algorithm that runs in $O(log\\ n)$ time.\n", - " \n", - "\n", - "**Constraints:**\n", - "\n", - "- `n == nums.length`\n", - "- `1 <= n <= 5000`\n", - "- `-5000 <= nums[i] <= 5000`\n", - "- All the integers of `nums` are **unique**.\n", - "- `nums` is sorted and rotated between `1` and `n` times." - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def findMin(nums):\n", - " left, right = 0, len(nums) - 1\n", - " \n", - " while left < right:\n", - " mid = left + (right - left) // 2\n", - " \n", - " # If the mid element is greater than the rightmost element,\n", - " # it means the minimum element is in the right half.\n", - " if nums[mid] > nums[right]:\n", - " left = mid + 1\n", - " # If the mid element is less than or equal to the rightmost element,\n", - " # it means the minimum element is in the left half or at the mid itself.\n", - " else:\n", - " right = mid\n", - " \n", - " # The loop will break when left and right converge to the minimum element.\n", - " # At this point, left (or right) will be pointing to the minimum element.\n", - " return nums[left]" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. The function `findMin(nums)` takes an input list `nums`, which represents the rotated sorted array.\n", - "\n", - "2. Initialize two pointers `left` and `right` to track the current search range. Initially, `left` is set to 0 (the beginning of the array), and `right` is set to `len(nums) - 1` (the end of the array).\n", - "\n", - "3. Enter a `while` loop with the condition `left < right`. This loop continues until `left` and `right` converge to a single element, which will be the minimum element in the rotated array.\n", - "\n", - "4. Inside the loop, calculate the middle index `mid` using integer division. This helps in finding the middle element of the current search range.\n", - "\n", - "5. Check if the element at the middle index (`nums[mid]`) is greater than the element at the rightmost index (`nums[right]`). If this condition is true, it means that the minimum element must be in the right half of the current search range. So, update `left` to `mid + 1`, effectively eliminating the left half of the search range.\n", - "\n", - "6. If the condition from step 5 is not met, it implies that the minimum element can be in the left half of the current search range or could be the element at the `mid` index itself. In this case, update `right` to `mid`, effectively eliminating the right half of the search range.\n", - "\n", - "7. Repeat steps 4-6 until `left` and `right` converge to the minimum element.\n", - "\n", - "8. When the loop exits, it means that `left` (or `right`) points to the minimum element in the array.\n", - "\n", - "9. Return `nums[left]` (or `nums[right]`) as the result, which is the minimum element in the rotated sorted array." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n" - ] - } - ], - "source": [ - "### Example 1:\n", - "nums1 = [3, 4, 5, 1, 2]\n", - "print(findMin(nums1))" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "nums2 = [4, 5, 6, 7, 0, 1, 2]\n", - "print(findMin(nums2))" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "id": "6c69a707-02af-4212-b2e7-1881d62a62d2", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "11\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "nums3 = [11, 13, 15, 17]\n", - "print(findMin(nums3))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "The time complexity of this code is $O(log\\ n)$, where '$n$' is the length of the input array `nums`. This is because the binary search algorithm is employed, which continually divides the search range in half with each iteration.\n", - "\n", - "In each iteration of the `while` loop, the search range is halved, and this process continues until the `left` and `right` pointers converge to the minimum element. In the worst case, it will take logarithmic time to reduce the search range to a single element.\n", - "\n", - "Therefore, the binary search used in this code runs in $O(log\\ n)$ time complexity.\n", - "\n", - "**Space Complexity:**\n", - "The space complexity of this code is $O(1)$, which means it uses a constant amount of additional space that does not depend on the size of the input array.\n", - "\n", - "The algorithm uses a fixed number of variables (`left`, `right`, `mid`) to keep track of the search range and indices, but the number of these variables does not grow with the size of the input array. Hence, the space complexity is constant.\n", - "\n", - "**In summary:**\n", - "- Time Complexity: $O(log\\ n)$\n", - "- Space Complexity: $O(1)$" - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. Solve the problem with a variation where the input array may contain duplicates.\n", - "\n", - "2. Modify the problem to return the index of the minimum element in the rotated sorted array, rather than the element itself. The algorithm should still run in $O(log\\ n)$ time.\n", - "\n", - "3. Implement a function that finds the maximum element in a rotated sorted array. How would you adapt the binary search algorithm to solve this problem efficiently in $O(log\\ n)$ time?\n", - "\n", - "4. Implement a function that can find the kth smallest element in a rotated sorted array. This is an extension of the original problem, and the algorithm should still run in $O(log\\ n)$ time." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/05. Binary Search/33. Search in Rotated Sorted Array.ipynb b/_build/html/_sources/05. Binary Search/33. Search in Rotated Sorted Array.ipynb deleted file mode 100644 index d8d4202..0000000 --- a/_build/html/_sources/05. Binary Search/33. Search in Rotated Sorted Array.ipynb +++ /dev/null @@ -1,245 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 33. Search in Rotated Sorted Array\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Search in Rotated Sorted Array problem on LeetCode, click here!](https://leetcode.com/problems/search-in-rotated-sorted-array/)\n", - "\n", - "---\n", - "\n", - "There is an integer array `nums` sorted in ascending order (with **distinct** values).\n", - "\n", - "Prior to being passed to your function, `nums` is **possibly rotated** at an unknown pivot index `k (1 <= k < nums.length)` such that the resulting array is `[nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]]` (**0-indexed**). For example, `[0,1,2,4,5,6,7]` might be rotated at pivot index 3 and become `[4,5,6,7,0,1,2]`.\n", - "\n", - "Given the array `nums` **after** the possible rotation and an integer `target`, return *the index of `target` if it is in `nums`, or `-1` if it is not in `nums`.*\n", - "\n", - "You must write an algorithm with $O(log\\ n)$ runtime complexity.\n", - " \n", - "\n", - "**Constraints:**\n", - "\n", - "- `1 <= nums.length <= 5000`\n", - "- $-10^4$ <= `nums[i]` <= $10^4$\n", - "- All values of `nums` are **unique**.\n", - "- `nums` is an ascending array that is possibly rotated.\n", - "- $-10^4$ <= `target` <= $10^4$" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def search(nums, target):\n", - " left, right = 0, len(nums) - 1\n", - "\n", - " # Find the pivot index using binary search\n", - " while left < right:\n", - " mid = left + (right - left) // 2\n", - "\n", - " if nums[mid] > nums[right]:\n", - " left = mid + 1\n", - " else:\n", - " right = mid\n", - "\n", - " pivot = left\n", - " left, right = 0, len(nums) - 1\n", - "\n", - " # Determine which part of the array to search in\n", - " if target >= nums[pivot] and target <= nums[right]:\n", - " left = pivot\n", - " else:\n", - " right = pivot\n", - "\n", - " # Perform binary search to find the target\n", - " while left <= right:\n", - " mid = left + (right - left) // 2\n", - "\n", - " if nums[mid] == target:\n", - " return mid\n", - " elif nums[mid] < target:\n", - " left = mid + 1\n", - " else:\n", - " right = mid - 1\n", - "\n", - " return -1" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. The `search` function takes two arguments: `nums`, which is the rotated sorted array, and `target`, which is the value we want to find in the array.\n", - "\n", - "2. We initialize two pointers, `left` and `right`, which represent the range in which we are going to perform binary search. Initially, `left` is set to 0, and `right` is set to the index of the last element in the array (`len(nums) - 1`).\n", - "\n", - "3. We start by finding the pivot index using binary search. The pivot index is the index at which the array is rotated. We use a `while` loop to continue the search until `left` is less than `right`.\n", - "\n", - "4. Inside the loop, we calculate the middle index `mid` using integer division. We then compare the value at `mid` with the value at `right`. If `nums[mid]` is greater than `nums[right]`, it means the pivot point lies to the right of `mid`, so we update `left` to `mid + 1`. Otherwise, the pivot point lies to the left of `mid`, so we update `right` to `mid`. This process continues until we find the pivot index.\n", - "\n", - "5. After finding the pivot index, we have divided the array into two parts: one part is sorted in ascending order, and the other part is also sorted in ascending order but rotated. We need to determine which part of the array contains the target value.\n", - "\n", - "6. We reset `left` and `right` pointers. If the target value is within the range `[nums[pivot], nums[right]]`, we set `left` to `pivot` (the start of the rotated part), indicating that we should search in the rotated part. Otherwise, we set `right` to `pivot` (the end of the sorted part), indicating that we should search in the sorted part.\n", - "\n", - "7. We then perform binary search again within the chosen range (`left` to `right`) to find the target element. The binary search continues until `left` is less than or equal to `right`.\n", - "\n", - "8. Inside the binary search loop, we calculate the middle index `mid` and compare `nums[mid]` with the target value. If they are equal, we return `mid` as the index of the target element. If `nums[mid]` is less than the target, we update `left` to `mid + 1` to search in the right half. If `nums[mid]` is greater than the target, we update `right` to `mid - 1` to search in the left half.\n", - "\n", - "9. If we exit the binary search loop without finding the target, we return -1 to indicate that the target is not present in the array." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n" - ] - } - ], - "source": [ - "nums1 = [4, 5, 6, 7, 0, 1, 2]\n", - "target1 = 0\n", - "result1 = search(nums1, target1)\n", - "print(result1) " - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "-1\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "nums2 = [4, 5, 6, 7, 0, 1, 2]\n", - "target2 = 3\n", - "result2 = search(nums2, target2)\n", - "print(result2) " - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "id": "6c69a707-02af-4212-b2e7-1881d62a62d2", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "-1\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "nums3 = [1]\n", - "target3 = 0\n", - "result3 = search(nums3, target3)\n", - "print(result3) " - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. Finding the pivot index using binary search takes $O(log\\ n)$ time, where '$n$' is the number of elements in the array.\n", - "2. After finding the pivot index, performing binary search to find the target element also takes $O(log\\ n)$ time in the worst case.\n", - "\n", - "The dominant factor in the time complexity is the binary search, and since we perform two binary searches sequentially, the overall time complexity of the code is $O(log\\ n)$.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity of the code is very minimal:\n", - "\n", - "1. We use a constant amount of additional space for variables such as `left`, `right`, `pivot`, and `mid`. These variables do not depend on the input size, so they contribute $O(1)$ space complexity.\n", - "2. The function does not use any additional data structures that scale with the input size.\n", - "\n", - "Therefore, the space complexity of the code is $O(1)$, which means it has a constant space complexity and does not depend on the size of the input array.\n", - "\n", - "**In summary:**\n", - "- Time Complexity: $O(log\\ n)$\n", - "- Space Complexity: $O(1)$" - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Find Minimum Element in Rotated Sorted Array**: Write an algorithm to find the minimum element in a rotated sorted array. This is a variation of the problem where you don't need to search for a target value but instead find the smallest element.\n", - "\n", - "2. **Search in a Circularly Sorted Array**: Consider an array that is sorted in a circular manner (e.g., [4, 5, 6, 7, 0, 1, 2, 3]). Adapt the search algorithm to work for circularly sorted arrays while maintaining $O(log\\ n)$ complexity." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/05. Binary Search/README.md b/_build/html/_sources/05. Binary Search/README.md deleted file mode 100644 index 6086b9b..0000000 --- a/_build/html/_sources/05. Binary Search/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Binary search Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [153. Find Minimum In Rotated Sorted Array](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/) | Medium | -| [33. Search In Rotated Sorted Array](https://leetcode.com/problems/search-in-rotated-sorted-array/) | Medium | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! diff --git a/_build/html/_sources/06. Linked List/141. Linked List Cycle.ipynb b/_build/html/_sources/06. Linked List/141. Linked List Cycle.ipynb deleted file mode 100644 index 0336bc8..0000000 --- a/_build/html/_sources/06. Linked List/141. Linked List Cycle.ipynb +++ /dev/null @@ -1,271 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 141. Linked List Cycle\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Linked List Cycle problem on LeetCode, click here!](https://leetcode.com/problems/linked-list-cycle/)\n", - "\n", - "---\n", - "\n", - "Given `head`, the head of a linked list, determine if the linked list has a cycle in it.\n", - "\n", - "There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the `next` pointer. Internally, `pos` is used to denote the index of the node that tail's `next` pointer is connected to. **Note that `pos` is not passed as a parameter.**\n", - "\n", - "Return `true` if there is a cycle in the linked list. Otherwise, return `false`.\n", - "\n", - " \n", - "\n", - "**Constraints:**\n", - "\n", - "- The number of the nodes in the list is in the range $[0, 10^4]$.\n", - "- $-10^5$ <= Node.val <= $10^5$\n", - "- `pos` is `-1` or a **valid index** in the linked-list.\n", - "\n", - "**Follow up:** Can you solve it using $O(1)$ (i.e. constant) memory?" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for singly-linked list.\n", - "class ListNode:\n", - " def __init__(self, val=0):\n", - " self.val = val\n", - " self.next = None\n", - "\n", - "class Solution:\n", - " def hasCycle(self, head: ListNode) -> bool:\n", - " if not head:\n", - " return False\n", - " \n", - " slow = head\n", - " fast = head\n", - " \n", - " while fast and fast.next:\n", - " slow = slow.next\n", - " fast = fast.next.next\n", - " \n", - " if slow == fast:\n", - " return True\n", - " \n", - " return False" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The given code defines a class `Solution` with a method `hasCycle` for determining if a linked list has a cycle.\n", - "\n", - "The `ListNode` class represents nodes in the linked list, where each node has a `val` (a value associated with the node) and a `next` attribute (a reference to the next node in the list).\n", - "\n", - "The `hasCycle` method takes the `head` of a linked list as input and returns `True` if there is a cycle in the linked list, and `False` otherwise. It uses two pointers, `slow` and `fast`, to traverse the linked list. If there is a cycle, the `fast` pointer will eventually catch up to the `slow` pointer.\n", - "\n", - "The algorithm works as follows:\n", - "1. It checks if the input `head` is `None` (an empty list). If it is, the method returns `False` because an empty list can't have a cycle.\n", - "2. Two pointers, `slow` and `fast`, initially point to the `head` of the list.\n", - "3. The code enters a `while` loop where `fast` moves two steps at a time, and `slow` moves one step at a time.\n", - "4. If there is a cycle, `fast` will eventually catch up to `slow`, and the method returns `True`.\n", - "5. If the loop completes without finding a cycle, the method returns `False`." - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "01849ced-1bbf-4956-8e54-451b358cb4fe", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Helper function to create a linked list with a cycle\n", - "def create_linked_list_with_cycle(values, pos):\n", - " dummy = ListNode()\n", - " current = dummy\n", - " cycle_node = None\n", - " \n", - " for i, val in enumerate(values):\n", - " current.next = ListNode(val)\n", - " current = current.next\n", - " \n", - " if i == pos:\n", - " cycle_node = current\n", - " \n", - " if cycle_node:\n", - " current.next = cycle_node\n", - " \n", - " return dummy.next" - ] - }, - { - "cell_type": "markdown", - "id": "f7490d01-d64e-4f20-b178-e14490d6dd6f", - "metadata": {}, - "source": [ - "This helper function is designed to create a linked list with a cycle for testing purposes. It takes two arguments:\n", - "\n", - "1. `values`: A list of values representing the nodes in the linked list.\n", - "2. `pos`: An integer representing the index of the node where the cycle begins.\n", - "\n", - "Here's how the function works:\n", - "\n", - "- It starts by creating an empty `ListNode` called `dummy`. This `dummy` node is used to simplify the creation of the linked list.\n", - "- It initializes a `current` pointer to the `dummy` node. This pointer will be used to traverse the linked list.\n", - "- It initializes a `cycle_node` variable to `None`. This variable will hold the reference to the node where the cycle begins, if any.\n", - "- It then iterates through the `values` list, creating a new `ListNode` for each value and appending it to the linked list.\n", - "- Inside the loop, it checks if the current index `i` is equal to the specified `pos`. If they match, it sets `cycle_node` to the current node. This simulates the creation of a cycle in the linked list.\n", - "- After the loop, if `cycle_node` is not `None` (indicating a cycle should be created), it connects the last node in the linked list to `cycle_node`, effectively creating a cycle.\n", - "- Finally, it returns the reference to the first node of the linked list (not the `dummy` node).\n", - "\n", - "This helper function allows you to easily create test cases where you can specify the values for the linked list and the position where the cycle starts. It's particularly useful for testing the code's ability to detect cycles in linked lists." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "### Example 1\n", - "head = [3,2,0,-4]\n", - "pos = 1\n", - "\n", - "head = create_linked_list_with_cycle(head, pos)\n", - "solution = Solution()\n", - "result = solution.hasCycle(head)\n", - "print(result)" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "### Example 2\n", - "head = [1,2]\n", - "pos = 0\n", - "\n", - "head = create_linked_list_with_cycle(head, pos)\n", - "solution = Solution()\n", - "result = solution.hasCycle(head)\n", - "print(result)" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "e140b956-7b3d-40d5-b6b0-9615860af67e", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "### Example 3\n", - "head = [1]\n", - "pos = -1\n", - "\n", - "head = create_linked_list_with_cycle(head, pos)\n", - "solution = Solution()\n", - "result = solution.hasCycle(head)\n", - "print(result)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's discuss the time and space complexity of the code for detecting a cycle in a linked list:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The time complexity of this code is $O(n)$, where \"$n$\" is the number of nodes in the linked list.\n", - "\n", - "The reason for this is that both the `slow` and `fast` pointers traverse the linked list, and they move at different speeds. In the worst case, when there is no cycle, the `fast` pointer will reach the end of the list after going through approximately $n/2$ nodes. In the case of a cycle, it may take some extra iterations for the `fast` pointer to catch up to the `slow` pointer. However, the total number of iterations is still proportional to the number of nodes in the linked list, making it $O(n)$.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity of this code is $O(1)$, which means it uses constant space.\n", - "\n", - "The reason for this is that regardless of the size of the linked list, the code only uses two additional pointers (`slow` and `fast`) to traverse the list. These pointers do not depend on the size of the input linked list, so the space complexity remains constant.\n", - "\n", - "**In summary**, this code efficiently detects cycles in a linked list with a time complexity of $O(n)$ and a space complexity of $O(1)$. It is an example of an algorithm that solves a complex problem with minimal memory usage." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/06. Linked List/143. Reorder List.ipynb b/_build/html/_sources/06. Linked List/143. Reorder List.ipynb deleted file mode 100644 index a83545b..0000000 --- a/_build/html/_sources/06. Linked List/143. Reorder List.ipynb +++ /dev/null @@ -1,285 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 143. Reorder List\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Reorder List problem on LeetCode, click here!](https://leetcode.com/problems/reorder-list/)\n", - "\n", - "---\n", - "\n", - "You are given the head of a singly linked-list. The list can be represented as:\n", - "\n", - "$L_0 → L_1 → … → L_{n - 1} → L_n$\n", - "\n", - "Reorder the list to be on the following form:\n", - "\n", - "$L_0 → L_n → L_1 → L_{n - 1} → L_2 → L_{n - 2} → …$\n", - "\n", - "You may not modify the values in the list's nodes. Only nodes themselves may be changed.\n", - " \n", - "\n", - "**Constraints:**\n", - "\n", - "- The number of nodes in the list is in the range $[1, 5 * 10^4]$.\n", - "- `1 <= Node.val <= 1000`" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class ListNode:\n", - " def __init__(self, val=0, next=None):\n", - " self.val = val\n", - " self.next = next\n", - "\n", - "def reorderList(head):\n", - " if not head or not head.next:\n", - " return head\n", - "\n", - " # Step 1: Find the middle of the linked list\n", - " slow, fast = head, head\n", - " while fast.next and fast.next.next:\n", - " slow = slow.next\n", - " fast = fast.next.next\n", - "\n", - " # Split the list into two halves\n", - " first_half = head\n", - " second_half = slow.next\n", - " slow.next = None\n", - "\n", - " # Step 2: Reverse the second half of the linked list\n", - " prev = None\n", - " current = second_half\n", - " while current:\n", - " next_node = current.next\n", - " current.next = prev\n", - " prev = current\n", - " current = next_node\n", - " second_half = prev\n", - "\n", - " # Step 3: Merge the first and reversed second halves alternately\n", - " p1, p2 = first_half, second_half\n", - " while p2:\n", - " next_p1 = p1.next\n", - " next_p2 = p2.next\n", - " p1.next = p2\n", - " p2.next = next_p1\n", - " p1 = next_p1\n", - " p2 = next_p2\n", - "\n", - " return head" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The `reorderList` function is designed to reorder a singly linked list following the specific pattern described in the problem statement. Here's a detailed explanation of how the function works:\n", - "\n", - "1. **Base Cases Handling**:\n", - " - The function first checks if the input linked list is empty (`not head`) or contains only one element (`not head.next`). If either of these conditions is met, the list cannot be reordered, so the function returns the original list as-is.\n", - "\n", - "2. **Finding the Middle of the Linked List**:\n", - " - To reorder the list, we first need to find the middle point so that we can split the list into two halves. This is done using two pointers, `slow` and `fast`, initialized to the head of the list.\n", - " - `slow` moves one step at a time while `fast` moves two steps at a time. When `fast` reaches the end of the list or the second-to-last node, `slow` will be at the middle node.\n", - "\n", - "3. **Splitting the List**:\n", - " - After finding the middle node, we split the list into two halves:\n", - " - The first half, `first_half`, contains nodes from the beginning up to the middle.\n", - " - The second half, `second_half`, contains nodes from the middle to the end.\n", - " - To split the list, we set the `next` pointer of the node before the middle node to `None`.\n", - "\n", - "4. **Reversing the Second Half**:\n", - " - We reverse the second half of the linked list using the `prev`, `current`, and `next_node` pointers.\n", - " - `prev` is initially `None`, and we iterate through the second half. For each node, we:\n", - " - Set the `next` of the current node to `prev`, effectively reversing the next pointer direction.\n", - " - Update `prev` to the current node.\n", - " - Move to the next node using the `next_node`.\n", - "\n", - "5. **Merging the Two Halves Alternately**:\n", - " - We now have two linked lists: `first_half` and the reversed `second_half`.\n", - " - We merge these two lists alternately by adjusting the `next` pointers of the nodes.\n", - " - `p1` and `p2` are pointers to the current nodes in `first_half` and `second_half`, respectively.\n", - " - We iterate through both lists while reordering nodes:\n", - " - Set the `next` of `p1` to `p2` to link a node from the first half to a node from the reversed second half.\n", - " - Update `p1` and `p2` to their respective next nodes.\n", - " - Repeat this process until we have processed all nodes in both halves.\n", - "\n", - "6. **Returning the Reordered List**:\n", - " - After the merging process is complete, the linked list is reordered as specified.\n", - " - The function returns the `head` of the reordered list.\n", - "\n", - "The overall result is a singly linked list that has been reordered according to the given pattern. The time complexity of this algorithm is O(N), where N is the number of nodes in the linked list, as we traverse the list once to find the middle, once to reverse the second half, and once to merge the two halves." - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "id": "01849ced-1bbf-4956-8e54-451b358cb4fe", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Helper function to print the linked list\n", - "def printLinkedList(head):\n", - " result = []\n", - " while head:\n", - " result.append(head.val)\n", - " head = head.next\n", - " return result" - ] - }, - { - "cell_type": "markdown", - "id": "f7490d01-d64e-4f20-b178-e14490d6dd6f", - "metadata": {}, - "source": [ - "Let's explain the helper functions:\n", - "**printLinkedList Function**:\n", - " - The `printLinkedList` function takes the `head` of a linked list as input and returns a list of values representing the nodes in the linked list.\n", - " - Inside the function, a `result` list is initialized to store the values of the linked list nodes.\n", - " - The function then iterates through the linked list starting from the `head` node and appends the `val` attribute of each node to the `result` list.\n", - " - As it iterates through the list, it moves to the next node using the `next` attribute of each node.\n", - " - Finally, the function returns the `result` list containing the values of the linked list nodes in the order they appear in the linked list.\n", - "\n", - " This function is useful for debugging and displaying the contents of a linked list. It allows you to easily convert a linked list into a regular Python list for visualization and testing purposes." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 4, 2, 3]\n" - ] - } - ], - "source": [ - "# Example 1\n", - "head1 = ListNode(1, ListNode(2, ListNode(3, ListNode(4))))\n", - "reorderList(head1)\n", - "print(printLinkedList(head1))" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 5, 2, 4, 3]\n" - ] - } - ], - "source": [ - "# Example 2\n", - "head2 = ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5)))))\n", - "reorderList(head2)\n", - "print(printLinkedList(head2))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the `reorderList` function:\n", - "\n", - "**Time Complexity**:\n", - "1. **Finding the Middle of the Linked List**: In this step, we use two pointers, one moving one step at a time (`slow`) and the other moving two steps at a time (`fast`). This process takes $O(N/2)$ time, where $N$ is the number of nodes in the linked list.\n", - "\n", - "2. **Splitting the List**: After finding the middle, we split the list into two halves by setting the `next` pointer of the node before the middle node to `None`. This step takes $O(1)$ time.\n", - "\n", - "3. **Reversing the Second Half**: We reverse the second half of the linked list using a while loop that iterates through the second half of the list once. Therefore, this step also takes $O(N/2)$ time.\n", - "\n", - "4. **Merging the Two Halves Alternately**: In this step, we merge the two halves alternately by adjusting the `next` pointers of the nodes. We iterate through both halves once, so this step takes $O(N/2)$ time.\n", - "\n", - "Overall, the time complexity of the `reorderList` function is dominated by the steps involving reversing and merging the two halves, both of which take $O(N/2)$ time. Therefore, the total time complexity is $O(N)$.\n", - "\n", - "**Space Complexity**:\n", - "The space complexity of the `reorderList` function is primarily determined by the variables and data structures used within the function. Let's break down the space complexity components:\n", - "\n", - "1. **Constant Space Variables**: The variables `slow`, `fast`, `prev`, `current`, `next_node`, `p1`, and `p2` are used to traverse and manipulate the linked list. These variables occupy constant space, regardless of the input size. Therefore, they contribute $O(1)$ to the space complexity.\n", - "\n", - "2. **Split Linked Lists**: In the splitting step, we create two new linked list segments (`first_half` and `second_half`) that store references to nodes from the original linked list. These segments occupy space proportional to half of the input list, $O(N/2)$. \n", - "\n", - "3. **Reversed Second Half**: During the reversal step, we reverse the second half of the linked list in-place without creating any additional data structures. Therefore, it doesn't contribute to additional space complexity.\n", - "\n", - "4. **Overall**: Combining the above components, the total space complexity is $O(N/2)$, which simplifies to $O(N)$ in terms of space complexity.\n", - "\n", - "**In summary**, the `reorderList` function has a time complexity of $O(N)$ and a space complexity of $O(N)$ due to the creation of two new linked list segments while splitting the list. The constant space variables used for traversal do not significantly impact the overall space complexity." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Reorder by K Elements:** Generalize the reorderList function to reorder the list in a different pattern, where you reorder the list by $K$ elements at a time. For example, for $K=3$, you would reorder it as ($L_0 → L_1 → L_2 → L_n → L_{n-1} → L_{n-2} → ...$).\n", - "You may need to handle cases where the number of nodes is not a multiple of $K$.\n", - "\n", - "2. **Reorder by Odd and Even Nodes:** Modify the reorderList function to reorder the list in a pattern where odd-indexed nodes (1-based index) come before even-indexed nodes. For example, ($L_0 → L_n → L_1 → L_{n-1} → L_2 → L_{n-2} → ...$)." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/06. Linked List/19. Remove Nth Node From End of List.ipynb b/_build/html/_sources/06. Linked List/19. Remove Nth Node From End of List.ipynb deleted file mode 100644 index 263124e..0000000 --- a/_build/html/_sources/06. Linked List/19. Remove Nth Node From End of List.ipynb +++ /dev/null @@ -1,278 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 19. Remove Nth Node From End of List\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Remove Nth Node From End of List problem on LeetCode, click here!](https://leetcode.com/problems/remove-nth-node-from-end-of-list/)\n", - "\n", - "---\n", - "\n", - "Given the head of a linked list, remove the $n^{th}$ node from the end of the list and return its head.\n", - " \n", - "\n", - "**Constraints:**\n", - "\n", - "- The number of nodes in the list is `sz`.\n", - "- `1 <= sz <= 30`\n", - "- `0 <= Node.val <= 100`\n", - "- `1 <= n <= sz`\n", - "\n", - "**Follow up:** Could you do this in one pass?" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class ListNode:\n", - " def __init__(self, val=0, next=None):\n", - " self.val = val\n", - " self.next = next\n", - "\n", - "def removeNthFromEnd(head, n):\n", - " # Create a dummy node to handle the case of removing the head node.\n", - " dummy = ListNode(0)\n", - " dummy.next = head\n", - " first = dummy\n", - " second = dummy\n", - " \n", - " # Advance the first pointer by n+1 nodes.\n", - " for _ in range(n + 1):\n", - " first = first.next\n", - " \n", - " # Move both pointers simultaneously until first reaches the end.\n", - " while first is not None:\n", - " first = first.next\n", - " second = second.next\n", - " \n", - " # Remove the nth node by updating the next pointer of the previous node.\n", - " second.next = second.next.next\n", - " \n", - " return dummy.next # Return the modified head of the linked list" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start by defining a `ListNode` class to represent individual nodes in a linked list. Each node has two attributes: `val` (the value of the node) and `next` (a reference to the next node in the list).\n", - "\n", - "2. The `removeNthFromEnd` function takes the head of a linked list (`head`) and the value `n`, which represents the position from the end of the list of the node to be removed. It returns the modified head of the linked list after the removal.\n", - "\n", - "3. We create a dummy node (`dummy`) at the beginning of the list. This dummy node simplifies the code by handling cases where the head of the list needs to be removed.\n", - "\n", - "4. We initialize two pointers, `first` and `second`, both initially pointing to the dummy node.\n", - "\n", - "5. To advance the `first` pointer by `n+1` nodes, we use a `for` loop. This positions the `first` pointer `n` nodes ahead of the `second` pointer.\n", - "\n", - "6. We then move both `first` and `second` pointers simultaneously until `first` reaches the end of the list. This ensures that the `second` pointer ends up pointing to the node that needs to be removed.\n", - "\n", - "7. To remove the nth node from the end, we update the `next` pointer of the node pointed to by the `second` pointer to skip over the node to be removed.\n", - "\n", - "8. Finally, we return `dummy.next`, which is the modified head of the linked list without the removed node.\n", - "\n", - "9. Additionally, there are two helper functions:\n", - " - `createLinkedList(values)` creates a linked list from a list of values.\n", - " - `convertToList(head)` converts a linked list back into a list of values." - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "id": "01849ced-1bbf-4956-8e54-451b358cb4fe", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Helper function to create a linked list from a list of values.\n", - "def createLinkedList(values):\n", - " if not values:\n", - " return None\n", - " head = ListNode(values[0])\n", - " current = head\n", - " for val in values[1:]:\n", - " current.next = ListNode(val)\n", - " current = current.next\n", - " return head\n", - "\n", - "# Helper function to convert a linked list to a list of values.\n", - "def convertToList(head):\n", - " result = []\n", - " current = head\n", - " while current:\n", - " result.append(current.val)\n", - " current = current.next\n", - " return result" - ] - }, - { - "cell_type": "markdown", - "id": "f7490d01-d64e-4f20-b178-e14490d6dd6f", - "metadata": {}, - "source": [ - "Let's explain the two helper functions:\n", - "\n", - "1. `createLinkedList(values)`: This function creates a linked list from a list of values.\n", - "\n", - " - Input: `values` is a list containing values that you want to insert into the linked list.\n", - " - Output: The function returns the head of the created linked list.\n", - "\n", - " Explanation:\n", - " - The function starts by checking if the `values` list is empty. If it is, it returns `None` to indicate an empty linked list.\n", - " - If the `values` list is not empty, it creates the first node of the linked list with the value from the first element of `values`.\n", - " - It then iterates through the remaining elements of `values` and creates new nodes for each value, connecting them together using the `next` attribute to form a linked list.\n", - " - Finally, it returns the head of the linked list, which is the first node created.\n", - " \n", - "\n", - "2. `convertToList(head)`: This function converts a linked list into a list of values.\n", - "\n", - " - Input: `head` is the head node of the linked list that you want to convert.\n", - " - Output: The function returns a list containing the values of the nodes in the linked list in order.\n", - "\n", - " Explanation:\n", - " - The function starts by initializing an empty list, `result`, to store the values of the linked list nodes.\n", - " - It then iterates through the linked list starting from the `head` node and appends the `val` attribute of each node to the `result` list.\n", - " - The iteration continues until it reaches the end of the linked list (i.e., the `next` attribute of the current node becomes `None`).\n", - " - After the iteration is complete, the function returns the `result` list, which now contains the values of all the nodes in the linked list in the same order as they appear in the linked list.\n", - "\n", - "These helper functions are useful for creating linked lists from lists of values and converting linked lists back into lists of values, making it easier to work with linked list examples and test cases in a more familiar list format." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 2, 3, 5]\n" - ] - } - ], - "source": [ - "# Example 1\n", - "head1 = createLinkedList([1, 2, 3, 4, 5])\n", - "n1 = 2\n", - "new_head1 = removeNthFromEnd(head1, n1)\n", - "print(convertToList(new_head1))" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[]\n" - ] - } - ], - "source": [ - "# Example 2\n", - "head2 = createLinkedList([1])\n", - "n2 = 1\n", - "new_head2 = removeNthFromEnd(head2, n2)\n", - "print(convertToList(new_head2))" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "id": "e140b956-7b3d-40d5-b6b0-9615860af67e", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1]\n" - ] - } - ], - "source": [ - "# Example 3\n", - "head3 = createLinkedList([1, 2])\n", - "n3 = 1\n", - "new_head3 = removeNthFromEnd(head3, n3)\n", - "print(convertToList(new_head3))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Certainly! Let's analyze the time and space complexity of the `removeNthFromEnd` function in isolation:\n", - "\n", - "**Time Complexity:**\n", - "- The `removeNthFromEnd` function performs two passes through the linked list. In the worst case, it needs to traverse the entire linked list of length $N$.\n", - "- The first pass positions the `first` pointer $n$ nodes ahead of the `second` pointer. This pass takes $O(N)$ time because it involves iterating through all N nodes.\n", - "- The second pass moves both `first` and `second` pointers simultaneously until `first` reaches the end of the list. This also takes $O(N)$ time in the worst case.\n", - "- Therefore, the overall time complexity of the `removeNthFromEnd` function is $O(N)$.\n", - "\n", - "**Space Complexity:**\n", - "- The `removeNthFromEnd` function uses a constant amount of extra space for its variables (e.g., `first`, `second`, and `dummy`). This space usage does not depend on the size of the linked list.\n", - "- The space complexity is $O(1)$, indicating that the space used by the function is constant and independent of the size of the input linked list.\n", - "\n", - "**In summary**, the `removeNthFromEnd` function has a time complexity of $O(N)$ and a space complexity of $O(1)$. It efficiently removes the nth node from the end of the linked list with a single pass through the list and constant extra space usage." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/06. Linked List/206. Reverse Linked List.ipynb b/_build/html/_sources/06. Linked List/206. Reverse Linked List.ipynb deleted file mode 100644 index c97de2d..0000000 --- a/_build/html/_sources/06. Linked List/206. Reverse Linked List.ipynb +++ /dev/null @@ -1,316 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 206. Reverse Linked List\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Reverse Linked List problem on LeetCode, click here!](https://leetcode.com/problems/reverse-linked-list/)\n", - "\n", - "---\n", - "\n", - "Given the `head` of a singly linked list, reverse the list, and return the reversed list.\n", - " \n", - "\n", - "**Constraints:**\n", - "\n", - "- The number of nodes in the list is the range `[0, 5000]`.\n", - "- `-5000 <= Node.val <= 5000`\n", - "\n", - "**Follow up:** A linked list can be reversed either iteratively or recursively. Could you implement both?" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for singly-linked list.\n", - "class ListNode:\n", - " def __init__(self, val=0, next=None):\n", - " self.val = val\n", - " self.next = next\n", - "\n", - "# Function to reverse a linked list iteratively\n", - "def reverseListIterative(head):\n", - " prev = None\n", - " current = head\n", - " \n", - " while current:\n", - " next_node = current.next\n", - " current.next = prev\n", - " prev = current\n", - " current = next_node\n", - " \n", - " return prev\n", - "\n", - "# Function to reverse a linked list recursively\n", - "def reverseListRecursive(head):\n", - " if not head or not head.next:\n", - " return head\n", - "\n", - " new_head = reverseListRecursive(head.next)\n", - " head.next.next = head\n", - " head.next = None\n", - "\n", - " return new_head" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. `reverseListIterative(head)`: This function reverses a linked list iteratively using a loop. Here's a step-by-step explanation:\n", - "\n", - " - It takes the `head` of the input linked list as a parameter.\n", - " - It initializes two pointers, `prev` and `current`, initially set to `None` and the `head` of the list, respectively.\n", - " - It enters a `while` loop that continues until `current` reaches the end of the list (i.e., becomes `None`).\n", - " - Inside the loop:\n", - " - It stores the `next_node` which is the next node after `current`.\n", - " - It updates the `next` pointer of `current` to point to the `prev` node. This effectively reverses the link direction.\n", - " - It moves `prev` to `current` and `current` to `next_node`, advancing the pointers one step further in the list.\n", - " - Once the loop completes, `prev` will be pointing to the new head of the reversed list (which was the last node of the original list), so it returns `prev`.\n", - "\n", - "2. `reverseListRecursive(head)`: This function reverses a linked list recursively. Here's how it works:\n", - "\n", - " - It takes the `head` of the input linked list as a parameter.\n", - " - The base case is checked: if `head` is `None` or `head.next` is `None`, meaning the list is empty or has only one node, it returns `head` as there's no need to reverse a list with zero or one element.\n", - " - In the recursive case:\n", - " - It calls itself with `head.next`, effectively moving down the list until it reaches the end.\n", - " - Once it reaches the end, it starts reversing the links:\n", - " - `head.next.next` is set to `head`, reversing the link between `head` and the next node.\n", - " - `head.next` is set to `None` to avoid cycles.\n", - " - Finally, it returns the new head of the reversed list, which will be the last node of the original list.\n", - "\n", - "**In summary,** `reverseListIterative` reverses the linked list by iterating through it and changing the next pointers, while `reverseListRecursive` reverses the linked list by recursively reaching the end and then reversing the links on the way back up the recursion stack. Both functions achieve the same result: reversing the linked list." - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "id": "01849ced-1bbf-4956-8e54-451b358cb4fe", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Helper function to create a linked list from a list of values\n", - "def createLinkedList(values):\n", - " if not values:\n", - " return None\n", - " head = ListNode(values[0])\n", - " current = head\n", - " for val in values[1:]:\n", - " current.next = ListNode(val)\n", - " current = current.next\n", - " return head\n", - "\n", - "# Helper function to convert a linked list to a list for testing\n", - "def linkedListToList(head):\n", - " result = []\n", - " current = head\n", - " while current:\n", - " result.append(current.val)\n", - " current = current.next\n", - " return result\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "f7490d01-d64e-4f20-b178-e14490d6dd6f", - "metadata": {}, - "source": [ - "Let's explain the two helper functions used in the provided code:\n", - "\n", - "1. `createLinkedList(values)`:\n", - "\n", - " - Purpose: This function is used to create a linked list from a list of values. It takes a list of values as input and returns the head of the linked list.\n", - "\n", - " - How it works:\n", - " - It first checks if the input list `values` is empty. If it's empty, it returns `None` to indicate an empty linked list.\n", - " - If `values` is not empty, it initializes a `head` node with the value of the first element in `values`.\n", - " - It then iterates through the remaining values in `values`, creating new nodes for each value and linking them together to form a linked list.\n", - " - Finally, it returns the `head` node of the newly created linked list.\n", - "\n", - "2. `linkedListToList(head)`:\n", - "\n", - " - Purpose: This function is used to convert a linked list back into a Python list for testing and output purposes.\n", - "\n", - " - How it works:\n", - " - It takes the `head` of the linked list as input.\n", - " - It initializes an empty list called `result`.\n", - " - It then iterates through the linked list, starting from `head`, and appends each node's `val` (value) to the `result` list.\n", - " - This process continues until the end of the linked list is reached.\n", - " - Finally, it returns the `result` list, which contains the values from the linked list in the same order.\n", - "\n", - "These helper functions are used to simplify the process of creating linked lists from lists of values and converting linked lists back into lists, making it easier to work with linked lists in the provided examples and test cases." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "[1, 1, 2, 3, 4, 4]" - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Example 1: Iterative\n", - "head1 = [1,2,3,4,5]\n", - "head1 = createLinkedList(head1)\n", - "reversed_head1 = reverseListIterative(head1)\n", - "print(linkedListToList(reversed_head1))" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 37, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Example 2: Recursive\n", - "head2 = [1,2]\n", - "head2 = createLinkedList(head2)\n", - "reversed_head2 = reverseListRecursive(head2)\n", - "print(linkedListToList(reversed_head2))" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "id": "6c69a707-02af-4212-b2e7-1881d62a62d2", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "[0]" - ] - }, - "execution_count": 38, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Example 3: Empty list\n", - "head3 = []\n", - "head3 = createLinkedList(head3)\n", - "reversed_head3 = reverseListIterative(head3)\n", - "print(linkedListToList(reversed_head3))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the two functions:\n", - "\n", - "1. `reverseListIterative(head)`:\n", - "\n", - " - Time Complexity: $O(n)$\n", - " - The iterative function visits each node in the linked list exactly once in a single pass, where \"$n$\" is the number of nodes in the list. Therefore, the time complexity is linear in the number of nodes.\n", - "\n", - " - Space Complexity: $O(1)$\n", - " - This function uses a constant amount of extra space for the `prev`, `current`, and `next_node` pointers. Regardless of the size of the input list, the amount of additional memory used remains the same, so the space complexity is constant.\n", - "\n", - "2. `reverseListRecursive(head)`:\n", - "\n", - " - Time Complexity: $O(n)$\n", - " - The recursive function also visits each node in the linked list exactly once. It recursively traverses the list from the head to the tail, reversing the links on the way back. Therefore, like the iterative approach, the time complexity is $O(n)$, where \"$n$\" is the number of nodes.\n", - "\n", - " - Space Complexity: $O(n)$\n", - " - The recursive function uses space on the call stack for each recursive call. In the worst case, when the list has \"$n$\" nodes, it will create \"$n$\" recursive function calls on the stack, resulting in a space complexity of $O(n)$. This is because each function call stores information about its state, including the `head` pointer, until it reaches the base case and starts returning.\n", - "\n", - "**In summary:**\n", - "\n", - "- The time complexity of both functions is $O(n)$ because they both visit each node once.\n", - "- The space complexity of `reverseListIterative` is $O(1)$ because it uses a constant amount of extra space.\n", - "- The space complexity of `reverseListRecursive` is $O(n)$ due to the recursive function calls and the associated call stack space.\n", - "\n", - "Both functions are efficient in terms of time complexity, but `reverseListIterative` is more memory-efficient because it uses a constant amount of additional space, while `reverseListRecursive` uses space on the call stack proportional to the number of nodes in the list." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **K-Group Reverse:** Modify the reverseListIterative function to reverse the linked list in groups of $K$ elements. For example, if the input linked list is [1, 2, 3, 4, 5, 6], and $K$ is 3, the output should be [3, 2, 1, 6, 5, 4].\n", - "\n", - "2. **Rotate Linked List:** Write a function to rotate a linked list to the right by $K$ places. For example, if the input is [1, 2, 3, 4, 5] and $K$ is 2, the output should be [4, 5, 1, 2, 3]." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/06. Linked List/21. Merge Two Sorted Lists.ipynb b/_build/html/_sources/06. Linked List/21. Merge Two Sorted Lists.ipynb deleted file mode 100644 index 876d633..0000000 --- a/_build/html/_sources/06. Linked List/21. Merge Two Sorted Lists.ipynb +++ /dev/null @@ -1,249 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 21. Merge Two Sorted Lists\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Merge Two Sorted Lists problem on LeetCode, click here!](https://leetcode.com/problems/merge-two-sorted-lists/)\n", - "\n", - "---\n", - "\n", - "You are given the heads of two sorted linked lists `list1` and `list2`.\n", - "\n", - "Merge the two lists into one **sorted** list. The list should be made by splicing together the nodes of the first two lists.\n", - "\n", - "*Return the head of the merged linked list.*\n", - " \n", - "\n", - "**Constraints:**\n", - "\n", - "- The number of nodes in both lists is in the range `[0, 50]`.\n", - "- `-100 <= Node.val <= 100`\n", - "- Both `list1` and `list2` are sorted in non-decreasing order." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class ListNode:\n", - " def __init__(self, val=0, next=None):\n", - " self.val = val\n", - " self.next = next\n", - "\n", - "def mergeTwoLists(list1, list2):\n", - " # Create a dummy node to simplify the code.\n", - " dummy = ListNode()\n", - " current = dummy\n", - "\n", - " while list1 and list2:\n", - " if list1.val < list2.val:\n", - " current.next = list1\n", - " list1 = list1.next\n", - " else:\n", - " current.next = list2\n", - " list2 = list2.next\n", - " current = current.next\n", - "\n", - " # Append the remaining elements from either list.\n", - " if list1:\n", - " current.next = list1\n", - " else:\n", - " current.next = list2\n", - "\n", - " return dummy.next" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We define a class `ListNode` to represent the nodes of a singly-linked list. Each node has a `val` attribute to store the value of the node and a `next` attribute to point to the next node in the list.\n", - "\n", - "2. We define the `mergeTwoLists` function that takes two linked list heads, `list1` and `list2`, as input.\n", - "\n", - "3. We create a `dummy` node at the beginning of the merged list. The `dummy` node simplifies the code by serving as a placeholder, and its `next` attribute will point to the actual merged list.\n", - "\n", - "4. We initialize a `current` pointer to point to the `dummy` node initially. This `current` pointer helps us traverse and build the merged list.\n", - "\n", - "5. We enter a `while` loop that continues until either `list1` or `list2` becomes empty. Inside the loop, we compare the values of the nodes at the current positions of `list1` and `list2`.\n", - "\n", - "6. If the `val` of the node in `list1` is smaller than the `val` of the node in `list2`, we attach the node from `list1` to the merged list by updating the `next` attribute of the `current` node to point to the node in `list1`. We then move the `list1` pointer to the next node.\n", - "\n", - "7. If the `val` of the node in `list2` is smaller than or equal to the `val` of the node in `list1`, we attach the node from `list2` to the merged list in a similar manner. We move the `list2` pointer to the next node.\n", - "\n", - "8. After attaching a node to the merged list, we move the `current` pointer to the newly added node. This step is essential for keeping track of the end of the merged list.\n", - "\n", - "9. The loop continues until either `list1` or `list2` becomes empty.\n", - "\n", - "10. Once the loop exits, we check if there are any remaining elements in `list1` or `list2`. If `list1` is not empty, we attach the remaining elements of `list1` to the merged list. If `list2` is not empty, we attach the remaining elements of `list2`.\n", - "\n", - "11. Finally, we return the `next` attribute of the `dummy` node as the head of the merged list, which represents the sorted merged list." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "01849ced-1bbf-4956-8e54-451b358cb4fe", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Helper function to print the linked list\n", - "def printLinkedList(head):\n", - " result = []\n", - " while head:\n", - " result.append(head.val)\n", - " head = head.next\n", - " return result" - ] - }, - { - "cell_type": "markdown", - "id": "f7490d01-d64e-4f20-b178-e14490d6dd6f", - "metadata": {}, - "source": [ - "Let's explain the helper functions:\n", - "**printLinkedList Function**:\n", - " - The `printLinkedList` function takes the `head` of a linked list as input and returns a list of values representing the nodes in the linked list.\n", - " - Inside the function, a `result` list is initialized to store the values of the linked list nodes.\n", - " - The function then iterates through the linked list starting from the `head` node and appends the `val` attribute of each node to the `result` list.\n", - " - As it iterates through the list, it moves to the next node using the `next` attribute of each node.\n", - " - Finally, the function returns the `result` list containing the values of the linked list nodes in the order they appear in the linked list.\n", - "\n", - " This function is useful for debugging and displaying the contents of a linked list. It allows you to easily convert a linked list into a regular Python list for visualization and testing purposes." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Example 1:\n", - "# Input: list1 = [1,2,4], list2 = [1,3,4]\n", - "list1 = ListNode(1, ListNode(2, ListNode(4)))\n", - "list2 = ListNode(1, ListNode(3, ListNode(4)))\n", - "merged_list = mergeTwoLists(list1, list2)\n", - "printLinkedList(merged_list)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Example 2:\n", - "# Input: list1 = [], list2 = []\n", - "list1 = None\n", - "list2 = None\n", - "merged_list = mergeTwoLists(list1, list2)\n", - "printLinkedList(merged_list)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6c69a707-02af-4212-b2e7-1881d62a62d2", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Example 3:\n", - "# list1 = [], list2 = [0]\n", - "list1 = None\n", - "list2 = ListNode(0)\n", - "merged_list = mergeTwoLists(list1, list2)\n", - "printLinkedList(merged_list)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the `mergeTwoLists` function.\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The time complexity of this function is $O(N + M$), where $N$ and $M$ are the lengths of `list1` and `list2`, respectively. Here's why:\n", - "\n", - "1. In the worst case, we need to traverse both `list1` and `list2` completely. This involves iterating through all the nodes in both lists once.\n", - "\n", - "2. The while loop runs until either `list1` or `list2` becomes empty. The number of iterations depends on the total number of nodes in both lists, which is N + M in the worst case.\n", - "\n", - "3. Inside the loop, we perform constant-time operations for each iteration, such as comparisons and updating pointers.\n", - "\n", - "Therefore, the dominant factor in the time complexity is the combined length of both input lists, resulting in a linear time complexity of $O(N + M)$.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity of this function is $O(1)$, which means it uses a constant amount of extra space regardless of the input sizes. Here's why:\n", - "\n", - "1. We create a few extra pointers (`dummy`, `current`) and temporary variables (`val`) to manage the merging process. These consume a fixed amount of memory, regardless of the input sizes. The number of these extra variables is independent of the lengths of `list1` and `list2`.\n", - "\n", - "2. We do not create a new data structure or allocate memory for the merged list. Instead, we rearrange the existing nodes from `list1` and `list2` to form the merged list. This operation does not consume additional memory proportional to the input sizes.\n", - "\n", - "**In summary**, the `mergeTwoLists` function has a time complexity of $O(N + M)$ and a space complexity of $O(1)$, making it an efficient solution for merging two sorted linked lists." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Merge K Sorted Lists:** Extend the problem to merge $K$ sorted linked lists instead of just two. You need to efficiently merge $K$ lists into one sorted list.\n", - "\n", - "2. **Merge Lists in a Zigzag Pattern:** Merge two sorted lists in a zigzag pattern. For example, given [1, 2, 4] and [1, 3, 5], the merged list should be [1, 1, 2, 3, 4, 5]." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": "sql", - "file_extension": "", - "mimetype": "", - "name": "sql", - "version": "3.32.3" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/06. Linked List/23. Merge k Sorted Lists.ipynb b/_build/html/_sources/06. Linked List/23. Merge k Sorted Lists.ipynb deleted file mode 100644 index a850734..0000000 --- a/_build/html/_sources/06. Linked List/23. Merge k Sorted Lists.ipynb +++ /dev/null @@ -1,285 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 23. Merge k Sorted Lists\n", - "\n", - "**Difficulty:** Hard\n", - "\n", - "**Link to Problem:** [To see the Merge k Sorted Lists problem on LeetCode, click here!](https://leetcode.com/problems/merge-k-sorted-lists/)\n", - "\n", - "---\n", - "\n", - "You are given an array of $k$ linked-lists lists, each linked-list is sorted in ascending order.\n", - "\n", - "Merge all the linked-lists into one sorted linked-list and return it.\n", - "\n", - "**Constraints:**\n", - "\n", - "- `k == lists.length`\n", - "- 0 <= k <= $10^4$\n", - "- `0 <= lists[i].length <= 500`\n", - "- $-10^4$ <= lists[i][j] <= $10^4$\n", - "- `lists[i]` is sorted in ascending order.\n", - "- The sum of `lists[i].length` will not exceed $10^4$.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for singly-linked list.\n", - "class ListNode:\n", - " def __init__(self, val=0, next=None):\n", - " self.val = val\n", - " self.next = next\n", - "\n", - "class Solution:\n", - " def mergeKLists(self, lists: [[ListNode]]) -> ListNode:\n", - " # Check if the input list of linked lists is empty\n", - " if not lists or len(lists) == 0:\n", - " return None\n", - "\n", - " # Loop until there is only one merged list left\n", - " while len(lists) > 1:\n", - " mergedLists = []\n", - "\n", - " # Merge pairs of lists\n", - " for i in range(0, len(lists), 2):\n", - " l1 = lists[i]\n", - " l2 = lists[i + 1] if (i + 1) < len(lists) else None\n", - " mergedLists.append(self.mergeList(l1, l2))\n", - "\n", - " # Update the list of lists with merged results\n", - " lists = mergedLists\n", - " \n", - " # Return the final merged list\n", - " return lists[0]\n", - "\n", - " def mergeList(self, l1, l2):\n", - " # Create a dummy node to simplify merging\n", - " dummy = ListNode()\n", - " tail = dummy\n", - "\n", - " # Merge the two sorted lists\n", - " while l1 and l2:\n", - " if l1.val < l2.val:\n", - " tail.next = l1\n", - " l1 = l1.next\n", - " else:\n", - " tail.next = l2\n", - " l2 = l2.next\n", - " tail = tail.next\n", - "\n", - " # Append any remaining elements from l1 or l2 (if any)\n", - " if l1:\n", - " tail.next = l1\n", - " if l2:\n", - " tail.next = l2\n", - "\n", - " # Return the merged result starting from the next of the dummy node\n", - " return dummy.next\n" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The provided code defines a Python class `Solution` with two methods for merging k sorted linked lists:\n", - "\n", - "1. `mergeKLists(self, lists: List[ListNode]) -> ListNode`: This method takes a list of k sorted linked lists as input and returns a single merged sorted linked list. It uses a divide-and-conquer approach to repeatedly merge pairs of lists until only one merged list remains.\n", - "\n", - "2. `mergeList(self, l1, l2)`: This method takes two sorted linked lists, `l1` and `l2`, as input and merges them into a single sorted linked list. It uses a dummy node to simplify the merging process.\n", - "\n", - "Here's a high-level overview of how the code works:\n", - "\n", - "- The `mergeKLists` method checks if the input list of linked lists is empty or contains no lists. If there are no lists, it returns `None`.\n", - "\n", - "- Inside a `while` loop, the code repeatedly merges pairs of linked lists until only one merged list remains in the `lists` array. It does this by iterating through the input lists in pairs and calling the `mergeList` method to merge each pair.\n", - "\n", - "- The `mergeList` method takes two sorted linked lists, `l1` and `l2`, and merges them into a single sorted linked list. It uses a dummy node (`dummy`) and a `tail` pointer to keep track of the merged list while comparing and merging elements from `l1` and `l2`.\n", - "\n", - "- After merging all pairs of lists and updating the `lists` array with the merged results, the loop continues until only one merged list remains in the `lists` array.\n", - "\n", - "- Finally, the `mergeKLists` method returns the merged list.\n", - "\n", - "Overall, this code efficiently merges k sorted linked lists using a divide-and-conquer strategy, resulting in a single merged sorted linked list as the output." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1 -> 1 -> 2 -> 3 -> 4 -> 4 -> 5 -> 6 -> " - ] - } - ], - "source": [ - "### Example 1\n", - "# Input: lists = [[1,4,5],[1,3,4],[2,6]]\n", - "\n", - "lists1 = [\n", - " ListNode(1, ListNode(4, ListNode(5))),\n", - " ListNode(1, ListNode(3, ListNode(4))),\n", - " ListNode(2, ListNode(6))\n", - "]\n", - "solution = Solution()\n", - "result1 = solution.mergeKLists(lists1)\n", - "\n", - "# Print the result\n", - "if result1:\n", - " current = result1\n", - " while current:\n", - " print(current.val, end=\" -> \")\n", - " current = current.next\n", - "else:\n", - " print(\"None\") # Print \"None\" for input with a single None element" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "None\n" - ] - } - ], - "source": [ - "### Example 2\n", - "# Input: lists = []\n", - "\n", - "lists2 = []\n", - "solution = Solution()\n", - "result2 = solution.mergeKLists(lists2)\n", - "\n", - "# Print the result\n", - "if result2:\n", - " current = result2\n", - " while current:\n", - " print(current.val, end=\" -> \")\n", - " current = current.next\n", - "else:\n", - " print(\"None\") # Print \"None\" for input with a single None element" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "e140b956-7b3d-40d5-b6b0-9615860af67e", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "None\n" - ] - } - ], - "source": [ - "### Example 3\n", - "# Input: lists = [[]]\n", - "\n", - "lists3 = [None]\n", - "solution = Solution()\n", - "result3 = solution.mergeKLists(lists3)\n", - "\n", - "# Print the result\n", - "if result3:\n", - " current = result3\n", - " while current:\n", - " print(current.val, end=\" -> \")\n", - " current = current.next\n", - "else:\n", - " print(\"None\") # Print \"None\" for input with a single None element" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. **Heap Initialization:** The code does not use a heap. Instead, it uses a divide-and-conquer approach. The initial check for empty input lists takes $O(1)$ time.\n", - "\n", - "2. **Merging:** The merging operation is performed in a divide-and-conquer fashion. In each iteration of the `while` loop, we merge pairs of linked lists, and the number of comparisons made is proportional to the total number of nodes across all the linked lists ($n$). In each merge step, we effectively process each node once. The number of iterations required to reduce k lists to 1 is $O(log\\ k)$.\n", - "\n", - " Therefore, the overall time complexity of the code is $O(n * log\\ k)$, where n is the total number of nodes across all lists, and $k$ is the number of linked lists.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. **Heap Space:** The code doesn't use a heap data structure, so there's no additional space complexity due to a heap.\n", - "\n", - "2. **Merged Lists:** In the `mergeList` method, we create a new merged list. However, this list is not stored in memory for all lists; it's replaced with each merged pair. The space used for these merged lists is proportional to the size of the largest merged list, which is $O(n)$ in the worst case.\n", - "\n", - "3. **Additional Variables:** The code uses a few additional variables, such as `dummy` and `tail`, but these occupy a constant amount of space and don't depend on the input size.\n", - "\n", - " Therefore, the overall space complexity of the code is $O(n)$, where n is the total number of nodes across all lists.\n", - "\n", - "In summary, the code's time complexity is $O(n * log(k))$, and its space complexity is $O(n)$. This code efficiently merges $k$ sorted linked lists using a divide-and-conquer approach with a relatively low space overhead." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/06. Linked List/README.md b/_build/html/_sources/06. Linked List/README.md deleted file mode 100644 index fb7b3ee..0000000 --- a/_build/html/_sources/06. Linked List/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Linked List Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [206. Reverse Linked List](https://leetcode.com/problems/reverse-linked-list/) | Easy | -| [21. Merge Two Sorted Lists](https://leetcode.com/problems/merge-two-sorted-lists/) | Easy | -| [143. Reorder List](https://leetcode.com/problems/reorder-list/) | Medium | -| [19. Remove Nth Node From End of List](https://leetcode.com/problems/remove-nth-node-from-end-of-list/) | Medium | -| [141. Linked List Cycle](https://leetcode.com/problems/linked-list-cycle/) | Medium | -| [23. Merge K Sorted Lists](https://leetcode.com/problems/merge-k-sorted-lists/) | Hard | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! diff --git a/_build/html/_sources/07. Trees/100. Same Tree.ipynb b/_build/html/_sources/07. Trees/100. Same Tree.ipynb deleted file mode 100644 index a270fab..0000000 --- a/_build/html/_sources/07. Trees/100. Same Tree.ipynb +++ /dev/null @@ -1,211 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 100: Same Tree\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Same Tree problem on LeetCode, click here!](https://leetcode.com/problems/same-tree/)\n", - "\n", - "---\n", - "\n", - "Given the roots of two binary trees `p` and `q`, write a function to check if they are the same or not.\n", - "\n", - "Two binary trees are considered the same if they are structurally identical, and the nodes have the same value.\n", - "\n", - "**Constraints**\n", - "\n", - "1. The number of nodes in both trees is in the range `[0, 100]`.\n", - "2. $-10^4$ <= Node.val <= $10^4$\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for a binary tree node.\n", - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " # Initialize a TreeNode with a value (val), left child, and right child.\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def isSameTree(p, q):\n", - " # Base case: If both p and q are None, the trees are the same.\n", - " if not p and not q:\n", - " return True\n", - " \n", - " # Base case: If either p or q is None (but not both), the trees are different.\n", - " if not p or not q:\n", - " return False\n", - " \n", - " # Check if the values of the current nodes (p.val and q.val) are equal.\n", - " if p.val != q.val:\n", - " return False\n", - " \n", - " # Recursively check the left and right subtrees of p and q.\n", - " # If both subtrees are the same, the entire trees are the same.\n", - " return isSameTree(p.left, q.left) and isSameTree(p.right, q.right)" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "In this code, we define a `TreeNode` class to represent binary tree nodes and a `isSameTree` function to check if two binary trees are the same. The function uses recursive traversal to compare the trees' structures and values.\n", - "\n", - "1. We start by defining a `TreeNode` class, which represents a node in a binary tree. Each node has a `val` (the node's value), a `left` child, and a right child. This class will help us create and work with binary trees.\n", - "2. Next, we define the `isSameTree` function, which checks if two binary trees (`p` and `q`) are the same.\n", - " + The base case for the recursion is when both `p` and `q` are `None`. In this case, they are considered the same, so we return `True`.\n", - " + If either `p` or `q` is `None` (but not both), they cannot be the same, so we return `False`.\n", - " + If the values of the current nodes `p.val` and `q.val` are not equal, we return `False` because the trees cannot be the same.\n", - " + Finally, we recursively check the left and right subtrees of `p` and `q` to see if they are the same." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "### Example 1\n", - "\n", - "#Input: `p = [1,2,3]`, `q = [1,2,3]`\n", - "\n", - "p1 = TreeNode(1, TreeNode(2), TreeNode(3))\n", - "q1 = TreeNode(1, TreeNode(2), TreeNode(3))\n", - "print(isSameTree(p1, q1)) " - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "### Example 2\n", - "\n", - "#Input: `p = [1,2]`, `q = [1,null,2]`\n", - "\n", - "p2 = TreeNode(1, TreeNode(2), None)\n", - "q2 = TreeNode(1, None, TreeNode(2))\n", - "print(isSameTree(p2, q2))" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "5897c29d-26f8-486a-878c-43c09ff25ce4", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "### Example 3\n", - "\n", - "#Input: p = [1,2,1], q = [1,1,2]\n", - "\n", - "p3 = TreeNode(1, TreeNode(2), TreeNode(1))\n", - "q3 = TreeNode(1, TreeNode(1), TreeNode(2))\n", - "print(isSameTree(p3, q3))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time Complexity\n", - "\n", - "The time complexity of the `isSameTree` function can be analyzed as follows:\n", - "\n", - "In the worst case, the function needs to visit every node in both trees once to determine if they are the same.\n", - "Since each node is visited exactly once, the time complexity is $O(n)$, where $n$ is the total number of nodes in the input trees.\n", - "\n", - "## Space Complexity\n", - "The space complexity of the `isSameTree` function can be analyzed as follows:\n", - "\n", - "The space used by the function's call stack during recursion is proportional to the maximum depth of the binary trees.\n", - "In the worst case, when the trees are completely unbalanced (all nodes form a single branch), the maximum depth will be $n$, where $n$ is the total number of nodes in the input trees.\n", - "Therefore, the space complexity is $O(n)$ due to the recursive call stack.\n", - "In addition to the call stack, there is a small constant amount of space used for variables and comparisons within each recursive call, but this space is not significant in terms of the overall space complexity.\n", - "\n", - "## In summary:\n", - "\n", - "+ **Time Complexity:** $O(n)$ where $n$ is the total number of nodes in the input trees.\n", - "+ **Space Complexity:** $O(n)$ due to the recursive call stack." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/07. Trees/102. Binary Tree Level Order Traversal.ipynb b/_build/html/_sources/07. Trees/102. Binary Tree Level Order Traversal.ipynb deleted file mode 100644 index 8cb08b7..0000000 --- a/_build/html/_sources/07. Trees/102. Binary Tree Level Order Traversal.ipynb +++ /dev/null @@ -1,271 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 102. Binary Tree Level Order Traversal\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Binary Tree Level Order Traversal problem on LeetCode, click here!](https://leetcode.com/problems/binary-tree-level-order-traversal/)\n", - "\n", - "---\n", - "Given the `root` of a binary tree, return *the level order traversal of its nodes' values*. (i.e., from left to right, level by level).\n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the tree is in the range `[0, 2000]`.\n", - "- `-1000 <= Node.val <= 1000`\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def levelOrder(root):\n", - " # Check if the tree is empty, if so, return an empty list.\n", - " if not root:\n", - " return []\n", - "\n", - " # Initialize an empty list to store the result.\n", - " result = []\n", - " \n", - " # Initialize a queue with the root node to perform BFS.\n", - " queue = [root]\n", - "\n", - " while queue:\n", - " # Initialize an empty list to store the values of nodes at the current level.\n", - " level_values = []\n", - " \n", - " # Get the number of nodes at the current level.\n", - " level_size = len(queue)\n", - "\n", - " # Iterate through the nodes at the current level.\n", - " for _ in range(level_size):\n", - " # Dequeue the front node from the queue.\n", - " node = queue.pop(0)\n", - " \n", - " # Append the value of the current node to the level_values list.\n", - " level_values.append(node.val)\n", - "\n", - " # Enqueue the left and right children of the current node if they exist.\n", - " if node.left:\n", - " queue.append(node.left)\n", - " if node.right:\n", - " queue.append(node.right)\n", - "\n", - " # Append the level_values list (values at the current level) to the result list.\n", - " result.append(level_values)\n", - "\n", - " # Return the final result, which is a list of lists representing level order traversal.\n", - " return result" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We define a `TreeNode` class that represents a node in the binary tree. Each `TreeNode` object has a value (`val`) and two child nodes: `left` and `right`.\n", - "\n", - "2. The `levelOrder` function takes the root of the binary tree as its input and returns the level order traversal of the tree as a list of lists.\n", - "\n", - "3. We start by checking if the input `root` is `None`, which indicates an empty tree. If the tree is empty, we return an empty list because there are no nodes to traverse.\n", - "\n", - "4. We initialize an empty list called `result` to store the final result, which will be a list of lists containing node values at each level.\n", - "\n", - "5. We initialize a queue called `queue` with the root node. This queue will be used for breadth-first traversal of the tree.\n", - "\n", - "6. We enter a while loop that continues until the `queue` is empty. Inside the loop, we perform the following steps:\n", - "\n", - " - We initialize an empty list called `level_values` to store the values of nodes at the current level.\n", - "\n", - " - We determine the number of nodes at the current level by getting the length of the `queue`. This is done to process nodes level by level.\n", - "\n", - " - We iterate through the nodes at the current level using a for loop. For each node in the current level:\n", - "\n", - " - We dequeue (remove) the front node from the `queue`.\n", - "\n", - " - We append the value of the dequeued node to the `level_values` list, effectively collecting the values of nodes at the current level.\n", - "\n", - " - If the dequeued node has a left child, we enqueue the left child to the `queue`.\n", - "\n", - " - If the dequeued node has a right child, we enqueue the right child to the `queue`.\n", - "\n", - " - After processing all nodes at the current level, we append the `level_values` list to the `result` list. This represents the values at the current level.\n", - "\n", - "7. The loop continues until all levels have been traversed, and the `queue` becomes empty.\n", - "\n", - "8. Finally, we return the `result` list, which contains lists of node values at each level, representing the level order traversal of the binary tree.\n", - "\n", - "The code effectively performs a breadth-first traversal of the binary tree, processing nodes level by level, and constructs the result list that represents the level order traversal." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[3], [9, 20], [15, 7]]\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Construct the tree\n", - "root = TreeNode(3)\n", - "root.left = TreeNode(9)\n", - "root.right = TreeNode(20)\n", - "root.right.left = TreeNode(15)\n", - "root.right.right = TreeNode(7)\n", - "\n", - "result = levelOrder(root)\n", - "print(result)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[1]]\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "# Using the same tree as before\n", - "root = TreeNode(1)\n", - "result = levelOrder(root)\n", - "print(result)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "7fc71180-e586-4c37-9fcf-2f574cb2b9d6", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[]\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "# Creating a new tree for this example\n", - "root = None\n", - "result = levelOrder(root)\n", - "print(result)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `levelOrder` function:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The time complexity of this function is O(N), where N is the number of nodes in the binary tree. This is because we visit each node exactly once during the breadth-first traversal.\n", - "\n", - "In the worst case, we have to enqueue and dequeue all nodes in the binary tree, which is proportional to the number of nodes (N). In each level, we process all nodes in that level, and since there are a total of log(N) levels in a balanced binary tree, the time complexity can also be approximated as O(N) for unbalanced trees.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity of this function is O(N), where N is the number of nodes in the binary tree. Here's how the space complexity breaks down:\n", - "\n", - "1. The `result` list stores the level order traversal, and in the worst case, it contains N/2 levels (for a completely unbalanced binary tree). So, the space used by `result` is O(N).\n", - "\n", - "2. The `queue` data structure is used for BFS traversal. In the worst case, it can store all nodes at the last level of the tree. In a balanced binary tree, the maximum number of nodes at any level is 2^(log(N)), which is still O(N). In the case of an unbalanced tree, it can be even worse. So, the space used by `queue` is O(N).\n", - "\n", - "Overall, the dominant factor in terms of space complexity is the `queue`, and the space complexity is O(N).\n", - "\n", - "In summary, the function's time complexity is O(N), and its space complexity is also O(N). It is an efficient and optimal solution for performing a level order traversal of a binary tree." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Reverse Level Order Traversal:** Modify the `levelOrder` function to return the level order traversal in reverse order (from bottom to top). For example, if the input tree is `[3, 9, 20, null, null, 15, 7]`, the output should be `[[15, 7], [9, 20], [3]]`.\n", - "\n", - "2. **Zigzag Level Order Traversal:** Write a function that performs a level order traversal of a binary tree in a zigzag pattern. In a zigzag traversal, the nodes at even levels are traversed from left to right, and nodes at odd levels are traversed from right to left. For example, if the input tree is `[3, 9, 20, null, null, 15, 7]`, the output should be `[[3], [20, 9], [15, 7]]`." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/07. Trees/104. Maximum Depth of Binary Tree.ipynb b/_build/html/_sources/07. Trees/104. Maximum Depth of Binary Tree.ipynb deleted file mode 100644 index 213989d..0000000 --- a/_build/html/_sources/07. Trees/104. Maximum Depth of Binary Tree.ipynb +++ /dev/null @@ -1,209 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 104. Maximum Depth of Binary Tree\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Invert Binary Tree problem on LeetCode, click here!](https://leetcode.com/problems/invert-binary-tree/)\n", - "\n", - "---\n", - "\n", - "Given the `root` of a binary tree, return its maximum depth.\n", - "\n", - "A binary tree's **maximum depth** is the number of nodes along the longest path from the root node down to the farthest leaf node.\n", - "\n", - "**Constraints:**\n", - "\n", - "- The number of nodes in the tree is in the range $[0, 10^4]$.\n", - "- `-100 <= Node.val <= 100`\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for a binary tree node.\n", - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def maxDepth(root):\n", - " # Base case: If the root is None, the depth is 0.\n", - " if root is None:\n", - " return 0\n", - " \n", - " # Recursively calculate the maximum depth of the left and right subtrees.\n", - " left_depth = maxDepth(root.left)\n", - " right_depth = maxDepth(root.right)\n", - " \n", - " # Return the maximum depth of the tree by adding 1 to the maximum depth of the subtrees.\n", - " return max(left_depth, right_depth) + 1" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "Let's go through the code step by step to understand how it works:\n", - "\n", - "1. We start by defining a `TreeNode` class to represent the nodes of the binary tree. Each node has three attributes:\n", - " - `val`: the value stored in the node.\n", - " - `left`: a reference to the left child node.\n", - " - `right`: a reference to the right child node.\n", - "\n", - "2. The `maxDepth` function is the main function that calculates the maximum depth of the binary tree. It takes a single argument, `root`, which is the root node of the binary tree.\n", - "\n", - "3. In the `maxDepth` function, we have a base case:\n", - " - If the `root` is `None`, it means we have reached the end of a branch of the tree (a leaf node or an empty subtree). In this case, the depth is 0 because there are no nodes to count.\n", - "\n", - "4. If the `root` is not `None`, we recursively calculate the maximum depth of the left and right subtrees:\n", - " - We call `maxDepth` on the `root.left` to calculate the maximum depth of the left subtree and store it in the variable `left_depth`.\n", - " - We call `maxDepth` on the `root.right` to calculate the maximum depth of the right subtree and store it in the variable `right_depth`.\n", - "\n", - "5. Finally, we return the maximum depth of the tree by taking the maximum of `left_depth` and `right_depth` and adding 1 to it. This is because we are counting the current level as well." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3\n" - ] - } - ], - "source": [ - "### Example 1\n", - "# Input: root = [3,9,20,null,null,15,7]\n", - "\n", - "root = TreeNode(3)\n", - "root.left = TreeNode(9)\n", - "root.right = TreeNode(20)\n", - "root.right.left = TreeNode(15)\n", - "root.right.right = TreeNode(7)\n", - "\n", - "print(maxDepth(root))" - ] - }, - { - "cell_type": "markdown", - "id": "a230be4f-1f47-4919-87e3-62fc3f072d97", - "metadata": {}, - "source": [ - "In this example, we create a binary tree based on the given input `[3,9,20,null,null,15,7]` and calculate its maximum depth, which is `3`. The tree structure is as follows:\n", - " ```\n", - " 3\n", - " / \\\n", - " 9 20\n", - " / \\\n", - " 15 7\n", - " ```\n", - "\n", - "So, the maximum depth is the length of the longest path from the root to a leaf node, which is 3 in this case." - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2\n" - ] - } - ], - "source": [ - "### Example 2\n", - "# Input: root = [1,null,2]\n", - "\n", - "root = TreeNode(1)\n", - "root.right = TreeNode(2)\n", - "\n", - "# Calculate the maximum depth of the tree and print the result\n", - "print(maxDepth(root))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "- The time complexity of the `maxDepth` function is $O(N)$, where $N$ is the number of nodes in the binary tree.\n", - "- This is because in the worst case, the function visits every node exactly once in a depth-first manner.\n", - "- The recursion explores all nodes of the tree, so the time complexity is linear with respect to the number of nodes.\n", - "\n", - "**Space Complexity:**\n", - "- The space complexity of the `maxDepth` function is $O(H)$, where H is the height of the binary tree.\n", - "- In the worst case, if the binary tree is completely unbalanced (skewed), the recursion stack can go as deep as the height of the tree.\n", - "- In the best case, if the binary tree is perfectly balanced, the height is $O(log\\ N)$, where $N$ is the number of nodes.\n", - "- Therefore, the space complexity can vary from $O(log\\ N)$ to $O(N)$ depending on the shape of the tree.\n", - "- In addition to the recursion stack, there is a small constant amount of space used for variables and function call overhead.\n", - "\n", - "**In summary:**\n", - "- The time complexity of the code is $O(N)$ as it visits each node once.\n", - "- The space complexity is $O(H)$, where H is the height of the tree, which can vary from $O(log\\ N)$ to $O(N)$ depending on the tree's shape." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.ipynb b/_build/html/_sources/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.ipynb deleted file mode 100644 index 31c9e69..0000000 --- a/_build/html/_sources/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.ipynb +++ /dev/null @@ -1,313 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 105. Construct Binary Tree from Preorder and Inorder Traversal\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Construct Binary Tree from Preorder and Inorder Traversal problem on LeetCode, click here!](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/)\n", - "\n", - "---\n", - "Given two integer arrays `preorder` and `inorder` where `preorder` is the preorder traversal of a binary tree and `inorder` is the inorder traversal of the same tree, construct and return *the binary tree.*\n", - "\n", - "**Constraints:**\n", - "- `1 <= preorder.length <= 3000`\n", - "- `inorder.length == preorder.length`\n", - "- `-3000 <= preorder[i], inorder[i] <= 3000`\n", - "- `preorder` and `inorder` consist of **unique** values.\n", - "- Each value of `inorder` also appears in `preorder`.\n", - "- `preorder` is **guaranteed** to be the preorder traversal of the tree.\n", - "- `inorder` is **guaranteed** to be the inorder traversal of the tree.\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def buildTree(preorder, inorder):\n", - " if not preorder:\n", - " return None\n", - "\n", - " # The first element in the preorder traversal is the root of the current subtree\n", - " root_val = preorder[0]\n", - " root = TreeNode(root_val)\n", - "\n", - " # Find the index of the root value in the inorder traversal\n", - " root_idx_inorder = inorder.index(root_val)\n", - "\n", - " # Recursively build left and right subtrees\n", - " root.left = buildTree(preorder[1:1 + root_idx_inorder], inorder[:root_idx_inorder])\n", - " root.right = buildTree(preorder[1 + root_idx_inorder:], inorder[root_idx_inorder + 1:])\n", - "\n", - " return root" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. `class TreeNode:`: This is a class definition for a binary tree node. It has three attributes:\n", - " - `val`: The value of the node.\n", - " - `left`: A reference to the left child node.\n", - " - `right`: A reference to the right child node.\n", - "\n", - " This class is used to create instances of binary tree nodes, which will be used to build the binary tree.\n", - "\n", - "2. `def buildTree(preorder, inorder):`: This is the main function that constructs a binary tree from its preorder and inorder traversals.\n", - "\n", - " - `preorder`: A list representing the preorder traversal of the binary tree.\n", - " - `inorder`: A list representing the inorder traversal of the binary tree.\n", - "\n", - "3. `if not preorder: return None`: This line checks if the `preorder` list is empty. If it is, it means there are no nodes to construct, so the function returns `None`.\n", - "\n", - "4. `root_val = preorder[0]`: The value of the root node is extracted from the first element of the `preorder` list.\n", - "\n", - "5. `root = TreeNode(root_val)`: A new `TreeNode` object is created with the `root_val` as its value. This represents the root of the current subtree.\n", - "\n", - "6. `root_idx_inorder = inorder.index(root_val)`: The index of the `root_val` in the `inorder` list is found. This index indicates the position of the root node in the inorder traversal.\n", - "\n", - "7. `root.left`: The left subtree is constructed recursively by calling the `buildTree` function with the appropriate sublists of `preorder` and `inorder`. The left subtree's preorder and inorder traversals are the slices of `preorder` and `inorder` lists up to the `root_idx_inorder`.\n", - "\n", - "8. `root.right`: The right subtree is constructed recursively by calling the `buildTree` function with the appropriate sublists of `preorder` and `inorder`. The right subtree's preorder and inorder traversals are the slices of `preorder` and `inorder` lists starting from `root_idx_inorder + 1`.\n", - "\n", - "9. Finally, the function returns the `root` of the subtree it just constructed.\n", - "\n", - "The recursive approach used here divides the problem of constructing the entire binary tree into smaller subproblems, starting with the root node and then recursively building the left and right subtrees until the entire tree is constructed." - ] - }, - { - "cell_type": "markdown", - "id": "2d82857b-4fbe-474f-bf33-17b55c20147b", - "metadata": {}, - "source": [ - "## Helper Function \n", - "\n", - "Here is a helper function to represent the binary tree elements." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "13e6f3e1-659d-479d-9521-75629b8c782f", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def treeToList(root):\n", - " # Initialize an empty list to store the elements of the binary tree\n", - " result = []\n", - " \n", - " # Initialize a queue for level-order traversal starting with the root\n", - " queue = [root]\n", - "\n", - " while queue:\n", - " # Pop the front node from the queue\n", - " node = queue.pop(0)\n", - " \n", - " # If the node is not None (i.e., a valid node), add its value to the result list\n", - " if node:\n", - " result.append(node.val)\n", - " \n", - " # Add the left and right children of the node to the queue\n", - " queue.append(node.left)\n", - " queue.append(node.right)\n", - " else:\n", - " # If the node is None, add None to the result to represent an empty node\n", - " result.append(None)\n", - "\n", - " # Remove any trailing None values from the result list\n", - " while result and result[-1] is None:\n", - " result.pop()\n", - "\n", - " # Return the resulting list representing the binary tree elements\n", - " return result" - ] - }, - { - "cell_type": "markdown", - "id": "86cd4c9d-a120-4dd1-a1bd-530436012574", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "Let's break down the `treeToList` helper function step by step:\n", - "\n", - "1. `def treeToList(root):`: This function takes the root of a binary tree as input and converts it into a list.\n", - "\n", - "2. `result = []`: Initialize an empty list called `result` to store the elements of the binary tree in list format.\n", - "\n", - "3. `queue = [root]`: Initialize a queue data structure for a level-order traversal, starting with the root node.\n", - "\n", - "4. `while queue:`: This starts a loop that continues until the queue is empty, indicating that all nodes have been processed.\n", - "\n", - "5. `node = queue.pop(0)`: Dequeue the first node from the queue, effectively processing it.\n", - "\n", - "6. `if node:`: Check if the `node` is not None, which means it's a valid node in the binary tree.\n", - "\n", - " a. `result.append(node.val)`: If the node is valid, append its value (`node.val`) to the `result` list. This represents the value of the current node in the binary tree.\n", - "\n", - " b. `queue.append(node.left)`: Enqueue the left child of the current node if it exists. This adds the left child to the queue for processing in the next iteration.\n", - "\n", - " c. `queue.append(node.right)`: Enqueue the right child of the current node if it exists. This adds the right child to the queue for processing in the next iteration.\n", - "\n", - "7. `else:`: If the `node` is None, it represents an empty node in the binary tree.\n", - "\n", - " a. `result.append(None)`: Append `None` to the `result` list to indicate an empty node.\n", - "\n", - "8. `while result and result[-1] is None:`: After the traversal is complete, there might be trailing `None` values in the `result` list. This loop removes any such trailing `None` values to ensure a clean representation of the tree's elements.\n", - "\n", - "9. `return result`: Return the `result` list, which now contains the elements of the binary tree in a format where `None` represents empty nodes and the order of elements reflects a level-order traversal of the tree.\n", - "\n", - "In summary, the `treeToList` function performs a level-order traversal of the binary tree using a queue, constructing a list where each element corresponds to a node's value or represents an empty node with `None`. This list represents the binary tree's elements in a structured format." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[3, 9, 20, None, None, 15, 7]\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "preorder = [3, 9, 20, 15, 7]\n", - "inorder = [9, 3, 15, 20, 7]\n", - "result = buildTree(preorder, inorder)\n", - "\n", - "print(treeToList(result))" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[-1]\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "preorder = [-1]\n", - "inorder = [-1]\n", - "result = buildTree(preorder, inorder)\n", - "\n", - "print(treeToList(result))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `buildTree` function:\n", - "\n", - "**Time Complexity:**\n", - "The time complexity of the `buildTree` function can be analyzed in terms of the number of nodes in the binary tree. Let's assume there are `n` nodes in the binary tree.\n", - "\n", - "1. Finding the root value in the `preorder` traversal takes O(1) time as it's just extracting the first element from the list.\n", - "2. Finding the index of the root value in the `inorder` traversal using `inorder.index(root_val)` takes O(n) time in the worst case because in the worst case, it might have to search through all `n` elements in the `inorder` list to find the index.\n", - "3. The recursive calls to `buildTree` for the left and right subtrees are made once for each node in the tree. Therefore, the recursive calls have a combined time complexity of O(n) as they process each node once.\n", - "\n", - "The total time complexity of the `buildTree` function is O(n) due to the recursive calls and finding the root's index in the `inorder` list.\n", - "\n", - "**Space Complexity:**\n", - "The space complexity is determined by the space used by the function's call stack during recursion and any additional data structures used. \n", - "\n", - "1. The space used by the function call stack during recursion depends on the height of the binary tree. In the worst case, where the tree is highly unbalanced (e.g., a skewed tree), the space complexity for the call stack is O(n) as it can go as deep as the number of nodes in the tree.\n", - "\n", - "2. Additionally, the function creates TreeNode objects for each node in the binary tree. Therefore, the space complexity for these objects is also O(n).\n", - "\n", - "Overall, the space complexity of the `buildTree` function is O(n) due to the space used by the call stack and the TreeNode objects.\n", - "\n", - "In summary, the time complexity of `buildTree` is O(n), and the space complexity is O(n), where 'n' is the number of nodes in the binary tree." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Construct Binary Tree from Postorder and Inorder Traversal:**\n", - " Modify the problem to construct a binary tree from its postorder and inorder traversals. Implement a function similar to `buildTree` but for postorder and inorder traversals.\n", - "\n", - "2. **Reconstruct Binary Tree with Duplicate Values:**\n", - " Extend the problem to handle binary trees with duplicate values. Ensure that your solution correctly handles scenarios where there are duplicate values in the preorder and inorder traversals." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/07. Trees/124. Binary Tree Maximum Path Sum.ipynb b/_build/html/_sources/07. Trees/124. Binary Tree Maximum Path Sum.ipynb deleted file mode 100644 index 59d8e7d..0000000 --- a/_build/html/_sources/07. Trees/124. Binary Tree Maximum Path Sum.ipynb +++ /dev/null @@ -1,249 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 124. Binary Tree Maximum Path Sum\n", - "\n", - "**Difficulty:** Hard\n", - "\n", - "**Link to Problem:** [To see the Binary Tree Maximum Path Sum problem on LeetCode, click here!](https://leetcode.com/problems/binary-tree-maximum-path-sum/)\n", - "\n", - "---\n", - "A **path** in a binary tree is a sequence of nodes where each pair of adjacent nodes in the sequence has an edge connecting them. A node can only appear in the sequence **at most once**. Note that the path does not need to pass through the root.\n", - "\n", - "The **path sum** of a path is the sum of the node's values in the path.\n", - "\n", - "Given the `root` of a binary tree, return *the maximum **path sum** of any **non-empty** path*.\n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the tree is in the range $[1, 3*10^4]$.\n", - "- `-1000 <= Node.val <= 1000`" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is to find the maximum path sum in a binary tree. A path in a binary tree is a sequence of nodes where each pair of adjacent nodes in the sequence has an edge connecting them. The path sum of a path is the sum of the node values in that path.\n", - "\n", - "In this problem, you are given the root of a binary tree, and you need to find the maximum path sum among all possible paths in the tree. Note that the path does not need to start at the root node or end at a leaf node; it can start and end at any nodes in the tree.\n", - "\n", - "To find the maximum path sum, you need to consider both left and right subtrees of each node while traversing the tree. At each node, you have two choices:\n", - "\n", - "1. Include the current node in the path: In this case, you add the value of the current node to the sum and continue exploring both the left and right subtrees for possible extensions of the path.\n", - "\n", - "2. Start a new path from the current node: In this case, you do not include the current node in the path sum, and you choose either the left subtree or the right subtree to start a new path.\n", - "\n", - "To solve this problem, you can use a recursive approach to traverse the binary tree. For each node, you calculate the maximum path sum that can pass through that node (option 1) and also return the maximum path sum that can be extended from that node (option 2). You keep track of the global maximum path sum encountered during the traversal.\n", - "\n", - "Ultimately, the maximum path sum among all paths in the tree will be the maximum of the global maximum path sum and the maximum path sum calculated for each node.\n", - "\n", - "The constraints for this problem include:\n", - "\n", - "- The number of nodes in the tree is in the range $[1, 3 * 10^4]$.\n", - "- Node values are in the range [-1000, 1000].\n", - "\n", - "By considering all possible paths through the tree, the algorithm aims to find the most significant sum of node values in any path in the binary tree.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "class Solution:\n", - " def maxPathSum(self, root):\n", - " def max_path_sum_helper(node):\n", - " if not node:\n", - " return 0\n", - " \n", - " # Recursively calculate the maximum path sum for left and right subtrees\n", - " left_max = max(0, max_path_sum_helper(node.left))\n", - " right_max = max(0, max_path_sum_helper(node.right))\n", - " \n", - " # Update the global maximum path sum\n", - " self.max_sum = max(self.max_sum, left_max + right_max + node.val)\n", - " \n", - " # Return the maximum path sum starting from the current node\n", - " return max(left_max, right_max) + node.val\n", - " \n", - " self.max_sum = float('-inf') # Initialize the global maximum to negative infinity\n", - " max_path_sum_helper(root) # Start the recursive traversal from the root\n", - " return self.max_sum" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. The code starts by defining a `TreeNode` class to represent nodes in the binary tree. Each `TreeNode` has a `val` attribute representing its value, a `left` attribute pointing to the left child, and a `right` attribute pointing to the right child.\n", - "\n", - "2. Next, a `Solution` class is defined to contain the `maxPathSum` method, which will be used to find the maximum path sum in the binary tree.\n", - "\n", - "3. Within the `maxPathSum` method, a helper function called `max_path_sum_helper` is defined. This recursive function takes a single argument, `node`, which is the current node being considered during traversal.\n", - "\n", - "4. Inside the `max_path_sum_helper` function:\n", - " - If `node` is `None` (i.e., the current node is a null node), it returns 0. This is the base case of the recursion.\n", - " - It calculates the maximum path sum starting from the left subtree (`left_max`) and the right subtree (`right_max`). Importantly, it uses `max(0, ...)` to ensure that negative values (which would make the path sum smaller) are not considered. If a subtree's path sum is negative, it's better to not include it in the path.\n", - " - The code then updates the global maximum path sum (`self.max_sum`) by checking if the sum of `left_max`, `right_max`, and the current node's value is greater than the current maximum.\n", - " - Finally, it returns the maximum path sum starting from the current node, which is the maximum of `left_max` and `right_max` plus the current node's value.\n", - "\n", - "5. Before calling the `max_path_sum_helper` function, the `max_sum` attribute of the `Solution` class is initialized to negative infinity (`float('-inf')`). This is done to ensure that any valid path sum encountered during traversal will be greater than the initial value of `max_sum`.\n", - "\n", - "6. The `max_path_sum_helper` function is called with the root of the binary tree, effectively starting the traversal from the root node.\n", - "\n", - "7. Once the traversal is complete, the method returns the value of `self.max_sum`, which contains the maximum path sum found in the binary tree.\n", - "\n", - "8. Example usage at the bottom of the code demonstrates how to create binary trees and use the `maxPathSum` method to find the maximum path sum for two different tree structures.\n", - "\n", - "In summary, the code uses a recursive approach to explore all possible paths in the binary tree, ensuring that negative path sums are not considered. It keeps track of the maximum path sum encountered and returns that maximum value as the result." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "6\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "root1 = TreeNode(1)\n", - "root1.left = TreeNode(2)\n", - "root1.right = TreeNode(3)\n", - "solution = Solution()\n", - "print(solution.maxPathSum(root1))" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "42\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "root2 = TreeNode(-10)\n", - "root2.left = TreeNode(9)\n", - "root2.right = TreeNode(20)\n", - "root2.right.left = TreeNode(15)\n", - "root2.right.right = TreeNode(7)\n", - "print(solution.maxPathSum(root2))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the given code:\n", - "\n", - "Time Complexity:\n", - "- The code uses a recursive depth-first traversal to explore each node in the binary tree exactly once.\n", - "- During the traversal, for each node, we perform constant time operations, such as updating the `max_sum` variable and calculating the maximum path sum starting from that node.\n", - "- Therefore, the time complexity of the code is O(N), where N is the number of nodes in the binary tree.\n", - "\n", - "Space Complexity:\n", - "- The space complexity of the code is determined by the space used in the call stack during the recursive traversal.\n", - "- In the worst case, the depth of the call stack can be equal to the height of the binary tree. In an unbalanced tree, this could be O(N), but in a balanced binary tree, the height is O(log N).\n", - "- Additionally, the code uses a constant amount of space for variables like `left_max`, `right_max`, and `max_sum`.\n", - "- Therefore, the overall space complexity is O(H), where H is the height of the binary tree. In the worst case, it's O(N), and in the best case (a balanced binary tree), it's O(log N).\n", - "\n", - "In summary:\n", - "- Time Complexity: O(N)\n", - "- Space Complexity: O(H), where H is the height of the binary tree, ranging from O(log N) to O(N) depending on the tree's balance." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Print the Maximum Path:**\n", - " Modify the code to not only find the maximum path sum but also print the nodes involved in the maximum path. You can print the nodes in the correct order from the root to the leaf.\n", - "\n", - "2. **Path Sum Count:**\n", - " Instead of finding the maximum path sum, find the count of unique paths that sum to a given target value. Each path can start and end anywhere in the tree." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/07. Trees/199. Binary Tree Right Side View.ipynb b/_build/html/_sources/07. Trees/199. Binary Tree Right Side View.ipynb deleted file mode 100644 index 55dc944..0000000 --- a/_build/html/_sources/07. Trees/199. Binary Tree Right Side View.ipynb +++ /dev/null @@ -1,257 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 199. Binary Tree Right Side View\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Binary Tree Right Side View problem on LeetCode, click here!](https://leetcode.com/problems/binary-tree-right-side-view/)\n", - "\n", - "---\n", - "Given the `root` of a binary tree, imagine yourself standing on the **right side** of it, return *the values of the nodes you can see ordered from top to bottom*.\n", - "\n", - " \n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the tree is in the range `[0, 2000]`.\n", - "- `-100 <= Node.val <= 100`\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def rightSideView(root):\n", - " if not root:\n", - " return [] # If the tree is empty, return an empty list.\n", - "\n", - " result = [] # Initialize a list to store the right side view values.\n", - " queue = [root] # Initialize a queue for level-order traversal with the root node.\n", - "\n", - " while queue:\n", - " # Get the number of nodes at the current level.\n", - " level_size = len(queue)\n", - "\n", - " # Traverse all nodes at the current level and add the rightmost node to the result.\n", - " for i in range(level_size):\n", - " node = queue.pop(0) # Dequeue the first node from the queue.\n", - "\n", - " # If it's the rightmost node at this level, add its value to the result.\n", - " if i == level_size - 1:\n", - " result.append(node.val)\n", - "\n", - " # Add the children of the current node to the queue.\n", - " if node.left:\n", - " queue.append(node.left)\n", - " if node.right:\n", - " queue.append(node.right)\n", - "\n", - " return result # Return the list of right side view values.\n" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start with a binary tree represented using a TreeNode class. Each node has a value (`val`) and can have a left child (`left`) and a right child (`right`).\n", - "\n", - "2. The `rightSideView` function takes the root node of the binary tree as input and returns a list of values representing the nodes you can see when standing on the right side of the tree.\n", - "\n", - "3. We check if the `root` is `None`, which means the tree is empty. If it's empty, we return an empty list because there are no nodes to see.\n", - "\n", - "4. We initialize an empty list called `result` to store the right side view values.\n", - "\n", - "5. We initialize a queue called `queue` with the root node. This queue is used for a level-order traversal of the tree.\n", - "\n", - "6. We enter a while loop that continues until the `queue` is empty. Inside this loop, we perform the following steps for each level of the tree:\n", - "\n", - " a. We determine the number of nodes at the current level by getting the length of the `queue`. This is important for processing nodes at the same level together.\n", - "\n", - " b. We then iterate through the nodes at the current level using a for loop. For each node in the level, we dequeue it from the `queue` using `queue.pop(0)`.\n", - "\n", - " c. If the node we dequeue is the rightmost node at the current level (determined by `i == level_size - 1`), we add its `val` to the `result` list. This is because, when standing on the right side of the tree, you can see the rightmost node at each level.\n", - "\n", - " d. We enqueue the left and right children of the current node (if they exist) to the `queue`. This ensures that we process the next level in the subsequent iterations of the while loop.\n", - "\n", - "7. After processing all levels of the tree, the `result` list contains the values of the rightmost nodes in each level, ordered from top to bottom.\n", - "\n", - "8. Finally, we return the `result` list as the output of the function, which represents the right side view of the binary tree.\n", - "\n", - "The code effectively performs a level-order traversal of the binary tree while keeping track of the rightmost nodes at each level and adding them to the result list. This ensures that we obtain the correct order of nodes visible from the right side of the tree." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 3, 4]\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Construct the tree\n", - "root1 = TreeNode(1)\n", - "root1.left = TreeNode(2)\n", - "root1.right = TreeNode(3)\n", - "root1.left.right = TreeNode(5)\n", - "root1.right.right = TreeNode(4)\n", - "print(rightSideView(root1))" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 3]\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "root2 = TreeNode(1)\n", - "root2.right = TreeNode(3)\n", - "print(rightSideView(root2))" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "7fc71180-e586-4c37-9fcf-2f574cb2b9d6", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[]\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "# Creating a new tree for this example\n", - "root = None\n", - "result = rightSideView(root)\n", - "print(result)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the given code:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The time complexity of the code is O(N), where N is the number of nodes in the binary tree. Here's why:\n", - "\n", - "1. We perform a level-order traversal of the tree using a queue. In the worst case, we visit all nodes once, which takes O(N) time since we visit each node exactly once.\n", - "\n", - "2. For each node, we perform constant-time operations like dequeuing it from the queue, checking if it's the rightmost node at the current level, and enqueuing its children (if they exist). These operations do not depend on the size of the tree, so they do not contribute to the overall time complexity.\n", - "\n", - "Therefore, the dominant factor in the time complexity is the level-order traversal, making it O(N).\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity of the code is also O(N). Here's why:\n", - "\n", - "1. We use a queue to perform level-order traversal. In the worst case, the queue can contain all nodes at the maximum width of the tree, which can be up to N/2 nodes for a completely unbalanced tree. Therefore, the space required for the queue is O(N).\n", - "\n", - "2. The `result` list stores the values of the rightmost nodes. In the worst case, when the binary tree is a complete binary tree, it can have roughly N/2 rightmost nodes. Therefore, the space required for the `result` list is also O(N).\n", - "\n", - "3. Other auxiliary variables like `level_size`, `i`, and `node` require only constant space and do not depend on the size of the tree.\n", - "\n", - "Combining the space used by the queue and the `result` list, we get a space complexity of O(N).\n", - "\n", - "In summary, the code has a time complexity of O(N) and a space complexity of O(N), where N is the number of nodes in the binary tree. These complexities are efficient and scale linearly with the size of the input tree." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Variant with Left Side View**: Modify the code to find and return the values of nodes visible from the left side of the binary tree instead of the right side.\n", - "\n", - "2. **Zigzag Right Side View**: Extend the code to return the right side view values in a zigzag order. In a zigzag order, you alternate between starting from the rightmost node at level 0, then the leftmost at level 1, rightmost at level 2, and so on." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/07. Trees/226. Invert Binary Tree.ipynb b/_build/html/_sources/07. Trees/226. Invert Binary Tree.ipynb deleted file mode 100644 index 8ea4609..0000000 --- a/_build/html/_sources/07. Trees/226. Invert Binary Tree.ipynb +++ /dev/null @@ -1,223 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 226: Invert Binary Tree\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Invert Binary Tree problem on LeetCode, click here!](https://leetcode.com/problems/invert-binary-tree/)\n", - "\n", - "---\n", - "\n", - "Given the root of a binary tree, invert the tree, and return its root.\n", - "\n", - "**Constraints:**\n", - "\n", - "- The number of nodes in the tree is in the range `[0, 100]`.\n", - "- `-100 <= Node.val <= 100`\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for a binary tree node.\n", - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def invertTree(root):\n", - " # Base case: If the root is None or the tree is empty, return None.\n", - " if not root:\n", - " return None\n", - "\n", - " # Swap the left and right subtrees of the current node.\n", - " root.left, root.right = root.right, root.left\n", - "\n", - " # Recursively invert the left and right subtrees.\n", - " invertTree(root.left)\n", - " invertTree(root.right)\n", - "\n", - " return root" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start by defining a TreeNode class, which represents a node in a binary tree. Each node has a value (`val`), a left child (`left`), and a right child (`right`).\n", - "\n", - "2. The `invertTree` function is defined to invert the binary tree. It takes the root node of the tree as an argument.\n", - "\n", - "3. In the `invertTree` function, we have a base case to handle the scenario when the root is `None` (empty tree). In such cases, we return `None` because there's nothing to invert.\n", - "\n", - "4. For non-empty trees, we swap the left and right subtrees of the current node. This effectively inverts the tree at the current node.\n", - "\n", - "5. We then recursively call `invertTree` on the left and right subtrees to invert them.\n", - "\n", - "6. Finally, we return the root of the inverted tree." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Inverted Tree (Example 1): <__main__.TreeNode object at 0x270c9c0>\n" - ] - } - ], - "source": [ - "### Example 1\n", - "# Input: root = [4,2,7,1,3,6,9]\n", - "\n", - "root1 = TreeNode(4)\n", - "root1.left = TreeNode(2)\n", - "root1.right = TreeNode(7)\n", - "root1.left.left = TreeNode(1)\n", - "root1.left.right = TreeNode(3)\n", - "root1.right.left = TreeNode(6)\n", - "root1.right.right = TreeNode(9)\n", - "\n", - "inverted_root1 = invertTree(root1)\n", - "print(\"Inverted Tree (Example 1):\", inverted_root1)" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Inorder Traversal of Inverted Tree (Example 2): <__main__.TreeNode object at 0x2255fc0>\n" - ] - } - ], - "source": [ - "### Example 2\n", - "# Input: root = [2,1,3]\n", - "\n", - "root2 = TreeNode(2)\n", - "root2.left = TreeNode(1)\n", - "root2.right = TreeNode(3)\n", - "\n", - "inverted_root2 = invertTree(root2)\n", - "print(\"Inverted Tree (Example 2):\", inverted_root2)" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "5897c29d-26f8-486a-878c-43c09ff25ce4", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Inverted Tree (Example 3): None\n" - ] - } - ], - "source": [ - "### Example 3\n", - "# Input: root = []\n", - "\n", - "root3 = None # Empty tree\n", - "\n", - "inverted_root3 = invertTree(root3)\n", - "print(\"Inverted Tree (Example 3):\", inverted_root3)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's discuss the time and space complexity of the provided Python code to invert a binary tree.\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The time complexity of the `invertTree` function is $O(n)$, where $n$ is the number of nodes in the binary tree. This is because we visit each node exactly once during the traversal of the tree. In the worst case, we have to visit all nodes in the tree.\n", - "\n", - "The reason for this time complexity is the depth-first traversal of the tree, where we recursively process the left and right subtrees of each node.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity of the code is determined by the function call stack during the recursion. In the worst case, the space complexity is $O(h)$, where $h$ is the height of the binary tree. \n", - "\n", - "In a completely unbalanced binary tree (essentially a linked list), the height $h$ is equal to the number of nodes $n$, resulting in a space complexity of $O(n)$. This occurs when the tree is skewed to one side.\n", - "\n", - "In a balanced binary tree, such as a full binary tree, the height $h$ is $O(log\\ n)$, and the space complexity is $O(log\\ n)$.\n", - "\n", - "The space complexity depends on how balanced the tree is. In practical scenarios, binary trees are often approximately balanced, so the space complexity is typically closer to $O(log\\ n)$.\n", - "\n", - "**In summary:**\n", - "\n", - "- Time Complexity: $O(n)$ where $n$ is the number of nodes.\n", - "- Space Complexity: $O(h)$, where $h$ is the height of the binary tree. In the worst case, it can be $O(n)$, and in a balanced tree, it is $O(log\\ n)$.\n", - "\n", - "Keep in mind that these complexities are based on the recursive implementation provided. Iterative solutions can achieve the same task with $O(1)$ space complexity, using auxiliary data structures like stacks or queues to mimic the recursion stack." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/07. Trees/230. Kth Smallest Element in a BST.ipynb b/_build/html/_sources/07. Trees/230. Kth Smallest Element in a BST.ipynb deleted file mode 100644 index 673ced2..0000000 --- a/_build/html/_sources/07. Trees/230. Kth Smallest Element in a BST.ipynb +++ /dev/null @@ -1,221 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 230. Kth Smallest Element in a BST\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Kth Smallest Element in a BST problem on LeetCode, click here!](https://leetcode.com/problems/kth-smallest-element-in-a-bst/)\n", - "\n", - "---\n", - "Given the `root` of a binary search tree, and an integer `k`, return *the $k^{th}$ smallest value (**1-indexed**) of all the values of the nodes in the tree.*\n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the tree is `n`.\n", - "- 1 <= `k <= n` <= $10^4$\n", - "- 0 <= `Node.val` <= $10^4$\n", - "\n", - "**Follow up**: If the BST is modified often (i.e., we can do insert and delete operations) and you need to find the kth smallest frequently, how would you optimize?\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def kthSmallest(root, k):\n", - " stack = [] # Initialize an empty stack to simulate the traversal\n", - " while root or stack:\n", - " while root:\n", - " stack.append(root) # Push the current node onto the stack\n", - " root = root.left # Move to the left child\n", - " root = stack.pop() # Pop a node from the stack\n", - " k -= 1 # Decrement k since we've visited a node\n", - " if k == 0:\n", - " return root.val # If k becomes 0, return the current node's value as the kth smallest\n", - " root = root.right # Move to the right child to continue the traversal" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start by defining a `TreeNode` class, which represents a node in the binary search tree (BST). Each node has a value (`val`), a left child (`left`), and a right child (`right`).\n", - "\n", - "2. The `kthSmallest` function takes two parameters: `root`, which is the root of the BST, and `k`, which represents the kth smallest element we want to find.\n", - "\n", - "3. We initialize an empty stack (`stack`) to simulate the traversal of the BST. The stack will be used to keep track of nodes as we traverse the tree in an iterative manner.\n", - "\n", - "4. We enter a while loop that continues until either `root` becomes `None` (indicating we have traversed the entire tree) or the `stack` is empty.\n", - "\n", - "5. Within the loop, we start another while loop to traverse as far left as possible in the BST. We repeatedly push nodes onto the `stack` and move to their left children until we reach the leftmost leaf node. This is the smallest node in the BST.\n", - "\n", - "6. Once we have reached the leftmost leaf node (the smallest node), we pop nodes from the `stack` one by one. As we pop each node, we decrement `k` by 1 to keep track of the number of nodes we have visited.\n", - "\n", - "7. If `k` becomes 0 after decrementing, it means we have found the kth smallest element. In this case, we return the `val` of the current node as the result.\n", - "\n", - "8. If `k` is still greater than 0, it means we haven't found the kth smallest element yet. In this case, we move to the right child of the current node to continue the traversal, as the kth smallest element, if it exists, will be in the right subtree of the current node.\n", - "\n", - "9. The process continues until we find the kth smallest element or traverse the entire tree.\n", - "\n", - "10. Finally, we return the kth smallest element found.\n", - "\n", - "The key idea in this code is to perform an in-order traversal of the BST while keeping track of the kth smallest element. By visiting nodes in ascending order, we can efficiently find the kth smallest element in O(h + k) time, where h is the height of the BST and k is the desired kth element. This approach is both concise and efficient for this problem." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "# Create the tree for the first example: root = [3,1,4,null,2], k = 1\n", - "root1 = TreeNode(3)\n", - "root1.left = TreeNode(1)\n", - "root1.right = TreeNode(4)\n", - "root1.left.right = TreeNode(2)\n", - "k1 = 1\n", - "print(kthSmallest(root1, k1)) " - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "# Create the tree for the second example: root = [5,3,6,2,4,null,null,1], k = 3\n", - "root2 = TreeNode(5)\n", - "root2.left = TreeNode(3)\n", - "root2.right = TreeNode(6)\n", - "root2.left.left = TreeNode(2)\n", - "root2.left.right = TreeNode(4)\n", - "root2.left.left.left = TreeNode(1)\n", - "k2 = 3\n", - "print(kthSmallest(root2, k2))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the given code:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The time complexity of this code is O(h + k), where:\n", - "- h is the height of the binary search tree (BST).\n", - "- k is the desired kth smallest element we want to find.\n", - "\n", - "1. In the worst case, where the BST is highly unbalanced and resembles a linked list, the height (h) of the tree can be equal to the number of nodes (n) in the tree. In this case, the time complexity is O(n + k).\n", - "\n", - "2. In the best case, where the BST is perfectly balanced, the height (h) is log(n), where n is the number of nodes in the tree. In this case, the time complexity is O(log(n) + k).\n", - "\n", - "So, the time complexity can vary from O(log(n) + k) in the best-case scenario to O(n + k) in the worst-case scenario. Typically, for balanced BSTs, the time complexity is closer to O(log(n) + k).\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity of this code is O(h) due to the stack used for the iterative in-order traversal, where h is the height of the BST.\n", - "\n", - "1. In the worst case, when the BST is highly unbalanced and resembles a linked list, the height (h) of the tree can be equal to the number of nodes (n) in the tree. In this case, the space complexity is O(n) because the stack can potentially store all n nodes.\n", - "\n", - "2. In the best case, when the BST is perfectly balanced, the height (h) is log(n), where n is the number of nodes in the tree. In this case, the space complexity is O(log(n)) because the stack will have at most log(n) nodes.\n", - "\n", - "So, the space complexity depends on the height of the BST and can vary from O(log(n)) in the best-case scenario to O(n) in the worst-case scenario.\n", - "\n", - "In practical terms, for balanced BSTs or moderately unbalanced BSTs, the space complexity is usually close to O(log(n)), and the code is efficient in terms of space usage." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Kth Largest Element**: Modify the code to find the kth largest element in the BST instead of the kth smallest element.\n", - "\n", - "2. **Kth Smallest Element in Two BSTs**: Given two BSTs, find the kth smallest element when considering both BSTs as a single sorted list. This involves merging the two BSTs while finding the kth element efficiently." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.ipynb b/_build/html/_sources/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.ipynb deleted file mode 100644 index 666bcd9..0000000 --- a/_build/html/_sources/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.ipynb +++ /dev/null @@ -1,245 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 235. Lowest Common Ancestor of a Binary Search Tree\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Lowest Common Ancestor of a Binary Search Tree problem on LeetCode, click here!](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/)\n", - "\n", - "---\n", - "Given a binary search tree (BST), find the lowest common ancestor (LCA) node of two given nodes in the BST.\n", - "\n", - "According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes `p` and `q` as the lowest node in `T` that has both `p` and `q` as descendants (where we allow **a node to be a descendant of itself**).”\n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the tree is in the range $[2, 10^5]$.\n", - "- $-10^9$ <= `Node.val` <= $10^9$\n", - "- All `Node.val` are **unique**.\n", - "- `p != q`\n", - "- `p` and `q` will exist in the BST.\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def lowestCommonAncestor(root, p, q):\n", - " # Ensure p is less than q\n", - " if p.val > q.val:\n", - " p, q = q, p\n", - "\n", - " while root:\n", - " # If the current node value is greater than both p and q, move left\n", - " if root.val > q.val:\n", - " root = root.left\n", - " # If the current node value is less than both p and q, move right\n", - " elif root.val < p.val:\n", - " root = root.right\n", - " # If the current node value is between p and q (inclusive), or it matches either p or q, it's the LCA\n", - " else:\n", - " return root" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. `class TreeNode:` defines a simple class for representing nodes in a binary tree. Each `TreeNode` has three attributes:\n", - " - `val`: The value of the node.\n", - " - `left`: A reference to the left child node.\n", - " - `right`: A reference to the right child node.\n", - "\n", - "2. `def lowestCommonAncestor(root, p, q):` is a function that takes three arguments:\n", - " - `root`: The root node of the BST.\n", - " - `p`: A TreeNode representing one of the nodes for which we want to find the LCA.\n", - " - `q`: A TreeNode representing the other node for which we want to find the LCA.\n", - "\n", - "3. `if p.val > q.val:` checks if the value of `p` is greater than the value of `q`. In a BST, it's essential to ensure that `p` represents the smaller value, and `q` represents the larger value. If `p` is greater than `q`, the code swaps their values.\n", - "\n", - "4. The main logic is inside the `while` loop, which runs until `root` becomes `None`. It performs the following steps to find the LCA:\n", - " - If the current `root` node's value is greater than the value of `q`, it means both `p` and `q` are on the left subtree of the current node. So, we move to the left child of the current node by setting `root = root.left`.\n", - " - If the current `root` node's value is less than the value of `p`, it means both `p` and `q` are on the right subtree of the current node. So, we move to the right child of the current node by setting `root = root.right`.\n", - " - If neither of the above conditions is met, it means the current `root` node's value is between `p` and `q`, or it matches either `p` or `q`. In this case, the current node is the lowest common ancestor (LCA), so we return `root`.\n", - "\n", - "The algorithm is efficient because it takes advantage of the properties of a BST. It eliminates subtrees that cannot contain the LCA by comparing the values of `p`, `q`, and the current `root` node. Eventually, it reaches the LCA node, and that node is returned as the result." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "6\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Construct the tree\n", - "root = TreeNode(6)\n", - "root.left = TreeNode(2)\n", - "root.right = TreeNode(8)\n", - "root.left.left = TreeNode(0)\n", - "root.left.right = TreeNode(4)\n", - "root.right.left = TreeNode(7)\n", - "root.right.right = TreeNode(9)\n", - "root.left.right.left = TreeNode(3)\n", - "root.left.right.right = TreeNode(5)\n", - "\n", - "p = root.left # Node 2\n", - "q = root.right # Node 8\n", - "\n", - "result = lowestCommonAncestor(root, p, q)\n", - "print(result.val)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "# Using the same tree as before\n", - "p = root.left # Node 2\n", - "q = root.left.right # Node 4\n", - "\n", - "result = lowestCommonAncestor(root, p, q)\n", - "print(result.val) " - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "7fc71180-e586-4c37-9fcf-2f574cb2b9d6", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "# Creating a new tree for this example\n", - "root2 = TreeNode(2)\n", - "root2.left = TreeNode(1)\n", - "\n", - "p = root2 # Node 2\n", - "q = root2.left # Node 1\n", - "\n", - "result = lowestCommonAncestor(root2, p, q)\n", - "print(result.val)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided algorithm for finding the lowest common ancestor (LCA) in a Binary Search Tree (BST).\n", - "\n", - "**Time Complexity:**\n", - "The time complexity of this algorithm is O(h), where \"h\" is the height of the BST. In the worst case, where the tree is completely unbalanced (essentially a linked list), the height of the tree is O(n), where \"n\" is the number of nodes in the tree. However, in a well-balanced BST, the height is logarithmic, which is O(log n).\n", - "\n", - "The reason for this time complexity is that the algorithm efficiently narrows down the search space by traversing either left or right subtrees based on the values of the target nodes `p` and `q`. It eliminates entire subtrees that cannot contain the LCA, leading to a relatively quick search.\n", - "\n", - "**Space Complexity:**\n", - "The space complexity of the algorithm is O(1). This is because it uses a constant amount of extra space, regardless of the size of the input BST. The only variables used are `root`, `p`, and `q`, and there are no data structures like stacks or queues used for additional space. The algorithm performs a simple traversal without recursion, so it does not consume extra memory as the tree depth increases.\n", - "\n", - "**In summary**, the provided algorithm for finding the LCA in a BST is both time and space-efficient. Its time complexity is O(h), where \"h\" is the height of the tree, and its space complexity is O(1), making it suitable for practical use even in large BSTs." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "### Challenging Exercises:\n", - "\n", - "1. **Multiple LCAs:** Extend the algorithm to find all the lowest common ancestors of two given nodes `p` and `q` in a BST. In some cases, there can be multiple LCAs.\n", - "\n", - "2. **LCA with k Nodes:** Given a BST and k nodes, find the lowest common ancestor of these k nodes. This is an extension of the problem where you must find the LCA of more than two nodes." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/07. Trees/297. Serialize and Deserialize Binary Tree.ipynb b/_build/html/_sources/07. Trees/297. Serialize and Deserialize Binary Tree.ipynb deleted file mode 100644 index 75c48ea..0000000 --- a/_build/html/_sources/07. Trees/297. Serialize and Deserialize Binary Tree.ipynb +++ /dev/null @@ -1,297 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 297. Serialize and Deserialize Binary Tree\n", - "\n", - "**Difficulty:** Hard\n", - "\n", - "**Link to Problem:** [To see the Serialize and Deserialize Binary Tree problem on LeetCode, click here!](https://leetcode.com/problems/serialize-and-deserialize-binary-tree/)\n", - "\n", - "---\n", - "Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.\n", - "\n", - "Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure.\n", - "\n", - "**Clarification:** The input/output format is the same as how LeetCode serializes a binary tree. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself.\n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the tree is in the range $[0, 10^4]$.\n", - "- `-1000 <= Node.val <= 1000`" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "TThe problem is to design an algorithm to serialize and deserialize a binary tree. Serialization is the process of converting a data structure or object into a sequence of characters or bytes so that it can be easily stored in a file, transmitted over a network, or otherwise persisted. Deserialization is the reverse process of converting the serialized data back into the original data structure.\n", - "\n", - "In the context of this problem:\n", - "\n", - "1. **Serialization**: You are given a binary tree, and your task is to convert it into a string representation such that you can later recreate the same binary tree from this string. The format of serialization is flexible, but it should allow you to reconstruct the original binary tree accurately.\n", - "\n", - "2. **Deserialization**: Given a serialized string, you need to reconstruct the binary tree it represents, ensuring that it is identical to the original tree.\n", - "\n", - "Here are some key points to consider in solving this problem:\n", - "\n", - "- The input can include any valid binary tree, including trees with nodes having integer values within the range [-1000, 1000].\n", - "- You don't necessarily need to follow a specific format for serialization, but it should be designed in a way that allows unambiguous deserialization.\n", - "- The goal is to serialize the tree structure and its values and then deserialize it back into the same structure and values.\n", - "\n", - "A common approach for serialization is to use a traversal method like preorder traversal, where you visit nodes in the order: root, left subtree, right subtree. This way, you can serialize the tree into a string, and during deserialization, you can reconstruct the tree by parsing the string in the same order.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for a binary tree node.\n", - "class TreeNode(object):\n", - " def __init__(self, x):\n", - " self.val = x\n", - " self.left = None\n", - " self.right = None\n", - "\n", - "class Codec:\n", - " def serialize(self, root):\n", - " serialized = []\n", - "\n", - " def dfs(node):\n", - " if not node:\n", - " # If the node is None, represent it as \"Null\" in the serialized string\n", - " serialized .append(\"Null\")\n", - " return\n", - " # Convert the node's value to a string and add it to the serialized string\n", - " serialized .append(str(node.val))\n", - " dfs(node.left)\n", - " dfs(node.right)\n", - "\n", - " dfs(root)\n", - " # Join the serialized values with \",\"\n", - " return \",\".join(serialized )\n", - "\n", - " def deserialize(self, data):\n", - " vals = data.split(\",\")\n", - " self.i = 0\n", - "\n", - " def dfs():\n", - " if vals[self.i] == \"Null\":\n", - " self.i += 1\n", - " return None\n", - " # Convert the value to an integer to create a new node\n", - " node = TreeNode(int(vals[self.i]))\n", - " self.i += 1\n", - " node.left = dfs()\n", - " node.right = dfs()\n", - " return node\n", - "\n", - " return dfs()" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "Here's a step-by-step explanation of the code:\n", - "\n", - "1. **Definition of TreeNode**:\n", - " - The code defines a simple `TreeNode` class that represents a node in a binary tree. Each `TreeNode` has three attributes:\n", - " - `val`: The integer value stored in the node.\n", - " - `left`: A reference to the left child node (or None if there is no left child).\n", - " - `right`: A reference to the right child node (or None if there is no right child).\n", - " - This class allows you to create binary tree nodes with integer values and left and right child references.\n", - "\n", - "2. **Serialization (serialize method)**:\n", - " - The `serialize` method takes a `root` node as input, which is the root of the binary tree that needs to be serialized.\n", - " - It initializes an empty list `serialized` to store the serialized elements.\n", - " - The `dfs` (depth-first search) function is defined within the `serialize` method to perform a preorder traversal of the binary tree.\n", - " - In the `dfs` function:\n", - " - If the current `node` is `None` (i.e., a leaf node or a child of a leaf node), it appends the string \"Null\" to the `serialized` list to represent the absence of a node.\n", - " - If the current `node` is not `None`, it appends the string representation of the `node.val` to the `serialized` list and then recursively calls `dfs` on the left and right children.\n", - " - After the `dfs` traversal, the `serialized` list contains the serialized binary tree elements.\n", - " - The method returns a string obtained by joining the elements in the `serialized` list with commas.\n", - "\n", - "3. **Deserialization (deserialize method)**:\n", - " - The `deserialize` method takes a serialized string `data` as input, which represents a binary tree in the custom format.\n", - " - It splits the `data` string by commas to obtain a list of elements called `vals`.\n", - " - The method initializes an index `self.i` to 0. This index keeps track of the current position in the `vals` list during deserialization.\n", - " - The `dfs` function is defined within the `deserialize` method to perform the deserialization process using a recursive approach.\n", - " - In the `dfs` function:\n", - " - If the current element in `vals` is \"Null,\" it means there is no node at this position in the binary tree, so it returns `None`.\n", - " - If the current element is not \"Null,\" it converts the element to an integer to create a new `TreeNode` with that value.\n", - " - It then recursively calls `dfs` to set the left and right children of the current node.\n", - " - The method returns the root node of the reconstructed binary tree.\n", - "\n", - "Overall, this code demonstrates a way to serialize a binary tree into a string format and then deserialize it back into the original tree structure, allowing for the representation of both the tree structure and the values stored in the nodes." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1,2,Null,Null,3,4,Null,Null,5,Null,Null\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "# Serialize a binary tree\n", - "root = TreeNode(1)\n", - "root.left = TreeNode(2)\n", - "root.right = TreeNode(3)\n", - "root.right.left = TreeNode(4)\n", - "root.right.right = TreeNode(5)\n", - "\n", - "codec = Codec()\n", - "serialized_tree = codec.serialize(root)\n", - "print(serialized_tree)\n", - "\n", - "# Deserialize the serialized tree\n", - "new_root = codec.deserialize(serialized_tree)" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Null\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "# Example usage:\n", - "# Serialize a binary tree\n", - "root = None\n", - "\n", - "codec = Codec()\n", - "serialized_tree = codec.serialize(root)\n", - "print(serialized_tree)\n", - "\n", - "# Deserialize the serialized tree\n", - "new_root = codec.deserialize(serialized_tree)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code for serializing and deserializing a binary tree:\n", - "\n", - "1. **Serialization (serialize method)**:\n", - "\n", - " - Time Complexity:\n", - " - The `serialize` method uses a depth-first traversal (preorder) of the binary tree.\n", - " - It visits each node exactly once.\n", - " - At each node, it performs constant-time operations (string conversion and list append).\n", - " - Therefore, the time complexity for serialization is O(N), where N is the number of nodes in the binary tree.\n", - "\n", - " - Space Complexity:\n", - " - The space complexity for serialization includes the space used by the `serialized` list and the recursive call stack.\n", - " - The `serialized` list stores the serialized elements, and its space is proportional to the number of nodes.\n", - " - The recursive call stack depth is determined by the height of the binary tree, and in the worst case (completely unbalanced tree), it can be O(N).\n", - " - Therefore, the space complexity for serialization is O(N) due to the list and O(H) due to the recursive call stack, where H is the height of the tree. In most cases, the dominant factor is O(N).\n", - "\n", - "2. **Deserialization (deserialize method)**:\n", - "\n", - " - Time Complexity:\n", - " - The `deserialize` method splits the serialized string into a list of elements, which takes O(N) time.\n", - " - The `dfs` function is a recursive function that visits each element in the list exactly once.\n", - " - At each element, it performs constant-time operations (string comparison, integer conversion, and recursive function calls).\n", - " - Therefore, the time complexity for deserialization is O(N).\n", - "\n", - " - Space Complexity:\n", - " - The space complexity for deserialization includes the space used by the `vals` list and the recursive call stack.\n", - " - The `vals` list stores the elements from the serialized string, and its space is proportional to the number of nodes.\n", - " - The recursive call stack depth is determined by the height of the binary tree, and in the worst case (completely unbalanced tree), it can be O(N).\n", - " - Therefore, the space complexity for deserialization is O(N) due to the list and O(H) due to the recursive call stack, where H is the height of the tree. In most cases, the dominant factor is O(N).\n", - "\n", - "Overall, the provided code has a time complexity of O(N) for both serialization and deserialization and a space complexity of O(N) in the majority of cases (unless the tree is severely unbalanced, in which case the height H dominates the space complexity). It efficiently serializes and deserializes a binary tree while using a linear amount of memory." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Efficient Serialization**:\n", - " Optimize the serialization process to minimize the length of the serialized string. Consider using techniques like binary encoding to represent node values more efficiently.\n", - "\n", - "2. **Custom Serialization Format**:\n", - " Modify the serialization and deserialization methods to use a custom format different from the one provided. Ensure that the new format allows for accurate reconstruction of the original binary tree." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/07. Trees/572. Subtree of Another Tree.ipynb b/_build/html/_sources/07. Trees/572. Subtree of Another Tree.ipynb deleted file mode 100644 index 8a41c3b..0000000 --- a/_build/html/_sources/07. Trees/572. Subtree of Another Tree.ipynb +++ /dev/null @@ -1,265 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 572: Subtree of Another Tree\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Subtree of Another Tree problem on LeetCode, click here!](https://leetcode.com/problems/subtree-of-another-tree/)\n", - "\n", - "---\n", - "\n", - "**Problem Description:**\n", - "\n", - "Given the roots of two binary trees `root` and `subRoot`, return `True` if there is a subtree of `root` with the same structure and node values as `subRoot`, and `False` otherwise.\n", - "\n", - "A subtree of a binary tree `tree` is a tree that consists of a node in `tree` and all of this node's descendants. The tree `tree` could also be considered as a subtree of itself.\n", - "\n", - "**Constraints:**\n", - "\n", - "1. The number of nodes in the `root` tree is in the range $[1, 2000]$.\n", - "2. The number of nodes in the `subRoot` tree is in the range $[1, 1000]$.\n", - "3. $-10^4$ <= root.val <= $10^4$\n", - "4. $-10^4$ <= subRoot.val <= $10^4$\n" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for a binary tree node.\n", - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "class Solution:\n", - " def isSubtree(self, root, subRoot):\n", - " if not root:\n", - " return False\n", - " \n", - " # Check if the current subtree is equal to the subRoot\n", - " if self.isSameTree(root, subRoot):\n", - " return True\n", - " \n", - " # Recursively check the left and right subtrees\n", - " return self.isSubtree(root.left, subRoot) or self.isSubtree(root.right, subRoot)\n", - " \n", - " def isSameTree(self, tree1, tree2):\n", - " if not tree1 and not tree2:\n", - " return True\n", - " if not tree1 or not tree2:\n", - " return False\n", - " \n", - " return (\n", - " tree1.val == tree2.val and\n", - " self.isSameTree(tree1.left, tree2.left) and\n", - " self.isSameTree(tree1.right, tree2.right)\n", - " )" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "This code defines a TreeNode class for the binary tree nodes and a Solution class with two methods:\n", - "\n", - "1. `isSubtree`: This method checks if there is a subtree of the `root` tree with the same structure and node values as the `subRoot` tree. It uses a helper function `isSameTree` to compare two trees for equality.\n", - "\n", - "2. `isSameTree`: This helper method recursively compares two trees to check if they are the same in structure and node values.\n", - "\n", - "### Here's a detailed explanation of the code:\n", - "\n", - "1. **TreeNode Class:**\n", - "\n", - "The `TreeNode` class is defined to represent nodes in a binary tree. Each node has a `val` (the node's value) and may have a `left` and `right` child.\n", - "\n", - "2. **Solution Class:**\n", - "\n", - " + The `Solution` class contains the solution for the problem and defines two important methods:\n", - "\n", - " + `isSubtree(self, root, subRoot)`:\n", - "\n", - " - This method checks whether `subRoot` is a subtree of `root`. It takes two tree nodes, `root` and `subRoot`, as input arguments.\n", - " - If `root` is `None`, it returns `False` because there is no subtree to search.\n", - " - It then checks if the current subtree with `root` as its root is equal to `subRoot` using the `isSameTree` method. If they are the same, it returns `True`.\n", - " - If the current subtree is not the same as `subRoot`, it recursively checks the left and right subtrees of `root` to see if `subRoot` is a subtree of any of them.\n", - " - It returns `True` if `subRoot` is found in either the left or right subtree; otherwise, it returns `False`.\n", - "\n", - " + `isSameTree(self, tree1, tree2)`:\n", - "\n", - " - This method checks whether two trees, `tree1` and `tree2`, are the same.\n", - " - If both `tree1` and `tree2` are `None`, they are considered the same tree, so it returns `True`.\n", - " - If only one of them is `None` (but not both), they are different trees, so it returns `False`.\n", - " - If both `tree1` and `tree2` have values, it checks if their values are equal and recursively checks if their left and right subtrees are the same.\n", - " - It returns `True` if the trees are the same; otherwise, it returns `False`.\n", - "\n", - "The code effectively uses recursion to traverse the binary trees and check for subtree equality. The `isSubtree` method starts the recursive search, and the `isSameTree` method is used to compare individual subtrees. The approach is efficient and avoids unnecessary checks when possible.\n", - "\n", - "This solution allows you to determine if there exists a subtree within the `root` tree that matches the structure and node values of `subRoot`." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Is subRoot a subtree of root? True\n" - ] - } - ], - "source": [ - "#root = [3,4,5,1,2]\n", - "#subRoot = [4,1,2]\n", - "\n", - "# Example input\n", - "root = TreeNode(3)\n", - "root.left = TreeNode(4)\n", - "root.right = TreeNode(5)\n", - "root.left.left = TreeNode(1)\n", - "root.left.right = TreeNode(2)\n", - "\n", - "subRoot = TreeNode(4)\n", - "subRoot.left = TreeNode(1)\n", - "subRoot.right = TreeNode(2)\n", - "\n", - "# Create an instance of the Solution class\n", - "solution = Solution()\n", - "\n", - "# Test the isSubtree method\n", - "result = solution.isSubtree(root, subRoot)\n", - "print(\"Is subRoot a subtree of root?\", result)" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Is subRoot a subtree of root? False\n" - ] - } - ], - "source": [ - "#root = [3,4,5,1,2,null,null,null,null,0] \n", - "#subRoot = [4,1,2]\n", - "\n", - "\n", - "# Example input\n", - "root = TreeNode(3)\n", - "root.left = TreeNode(4)\n", - "root.right = TreeNode(5)\n", - "root.left.left = TreeNode(1)\n", - "root.left.right = TreeNode(2)\n", - "root.left.right.left = TreeNode(0)\n", - "\n", - "subRoot = TreeNode(4)\n", - "subRoot.left = TreeNode(1)\n", - "subRoot.right = TreeNode(2)\n", - "\n", - "# Create an instance of the Solution class\n", - "solution = Solution()\n", - "\n", - "# Test the isSubtree method\n", - "result = solution.isSubtree(root, subRoot)\n", - "print(\"Is subRoot a subtree of root?\", result)" - ] - }, - { - "cell_type": "markdown", - "id": "86a34f0d-0789-498c-818c-2d30f84754d0", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the provided code for the \"Subtree of Another Tree\" problem:\n", - "\n", - "**Time Complexity**\n", - "\n", - "The time complexity of the code primarily depends on the recursive traversal of the binary tree. In both the `isSubtree` and `isSameTree` functions, we visit each node in the binary trees once. Let's break down the time complexity:\n", - "\n", - "1. The `isSubtree` function:\n", - " - In the worst case, we need to visit every node in the `root` tree.\n", - " - For each node in the `root` tree, we call the `isSameTree` function, which has its own traversal.\n", - " - So, the total time complexity is $O(n * m)$, where $n$ is the number of nodes in the `root` tree, and $m$ is the number of nodes in the `subRoot` tree.\n", - "\n", - "2. The `isSameTree` function:\n", - " - In the worst case, we visit every node in both `tree1` and `tree2`.\n", - " - The number of recursive calls made is proportional to the number of nodes in the trees.\n", - " - So, the time complexity of this function is $O(max(n, m))$, where $n$ and $m$ are the numbers of nodes in `tree1` and `tree2`, respectively.\n", - "\n", - "Overall, the time complexity of the entire code is $O(n * m)$, where $n$ is the number of nodes in the `root` tree, and $m$ is the number of nodes in the `subRoot` tree. In practice, it may be less than $O(n * m)$ if a subtree mismatch is detected early during the traversal.\n", - "\n", - "**Space Complexity**\n", - "\n", - "The space complexity of the code is determined by the function call stack during recursion and the space used by the recursive functions. Let's analyze the space complexity:\n", - "\n", - "1. The `isSubtree` function:\n", - " - It uses the call stack for recursion.\n", - " - The maximum depth of the recursion is equal to the height of the `root` tree, which can be $O(n)$ in the worst case (unbalanced tree).\n", - " - Additionally, the function doesn't use any significant extra space other than the recursion stack.\n", - "\n", - "2. The `isSameTree` function:\n", - " - It also uses the call stack for recursion.\n", - " - The maximum depth of the recursion is equal to the height of the `tree1` or `tree2`, whichever is greater.\n", - " - So, the maximum space used for the call stack is $O(max(n, m))$.\n", - "\n", - "In summary, the space complexity of the code is $O(max(n, m))$ due to the function call stack. It scales with the maximum height of the trees being compared.\n", - "\n", - "Overall, the code is efficient and works well for trees with moderate sizes. However, it's important to keep in mind that the worst-case time complexity is $O(n * m)$, so for very large trees, the performance may degrade." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/07. Trees/98. Validate Binary Search Tree.ipynb b/_build/html/_sources/07. Trees/98. Validate Binary Search Tree.ipynb deleted file mode 100644 index ad86882..0000000 --- a/_build/html/_sources/07. Trees/98. Validate Binary Search Tree.ipynb +++ /dev/null @@ -1,221 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 98. Validate Binary Search Tree\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Validate Binary Search Tree problem on LeetCode, click here!](https://leetcode.com/problems/validate-binary-search-tree/)\n", - "\n", - "---\n", - "Given the `root` of a binary tree, *determine if it is a valid binary search tree (BST)*.\n", - "\n", - "A **valid BST** is defined as follows:\n", - "\n", - "- The left subtree of a node contains only nodes with keys **less than** the node's key.\n", - "- The right subtree of a node contains only nodes with keys **greater than** the node's key.\n", - "- Both the left and right subtrees must also be binary search trees. \n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the tree is in the range $[1, 10^4]$.\n", - "- $-2^{31}$ <= `Node.val` <= $2^{31} - 1$\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def is_valid_BST(root):\n", - " def is_valid(node, min_val, max_val):\n", - " # Base case: If the node is None, it's a valid BST.\n", - " if node is None:\n", - " return True\n", - " \n", - " # Check if the current node's value is within the valid range.\n", - " if not (min_val < node.val < max_val):\n", - " return False\n", - " \n", - " # Recursively check the left and right subtrees with updated ranges.\n", - " return (is_valid(node.left, min_val, node.val) and\n", - " is_valid(node.right, node.val, max_val))\n", - " \n", - " # Call the helper function starting with a wide range for root node.\n", - " return is_valid(root, float('-inf'), float('inf'))" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "- It defines a `TreeNode` class to represent nodes in the binary tree.\n", - "\n", - "- The `is_valid_BST` function takes the root node of the binary tree as input and returns `True` if the tree is a valid BST, and `False` otherwise.\n", - "\n", - "- Inside the `is_valid_BST` function, there is a helper function called `is_valid` that performs the actual validation using a recursive approach.\n", - "\n", - "- The `is_valid` function checks each node in the tree to ensure that it satisfies the properties of a BST:\n", - " - The value of the current node must be within a valid range defined by `min_val` and `max_val`.\n", - " - The left subtree of the current node should contain values less than the current node's value.\n", - " - The right subtree of the current node should contain values greater than the current node's value.\n", - "\n", - "- If any of these conditions are violated, the function returns `False`, indicating that the tree is not a valid BST.\n", - "\n", - "- If all nodes satisfy these conditions, the function returns `True`, indicating that the tree is a valid BST.\n", - "\n", - "- The code calls the `is_valid` function with the root node and initial range values of negative infinity to positive infinity to start the validation.\n", - "\n", - "- The time complexity of the code is O(N), where N is the number of nodes in the tree, as it traverses each node once.\n", - "\n", - "- The space complexity depends on the height of the tree. In the average case for a balanced BST, the space complexity is O(log N), but in the worst case (skewed tree), it can be O(N) due to the recursive call stack.\n", - "\n", - "In summary, this code checks whether a given binary tree is a valid BST by recursively validating each node's value and its left and right subtrees while maintaining valid value ranges. If all nodes satisfy the BST properties, the tree is considered a valid BST." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "# Create the tree for the first example: [2, 1, 3]\n", - "root1 = TreeNode(2)\n", - "root1.left = TreeNode(1)\n", - "root1.right = TreeNode(3)\n", - "print(is_valid_BST(root1))" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "# Create the tree for the second example: [5, 1, 4, None, None, 3, 6]\n", - "root2 = TreeNode(5)\n", - "root2.left = TreeNode(1)\n", - "root2.right = TreeNode(4)\n", - "root2.right.left = TreeNode(3)\n", - "root2.right.right = TreeNode(6)\n", - "print(is_valid_BST(root2))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `is_valid_BST` function:\n", - "\n", - "**Time Complexity:**\n", - "- The time complexity of the function primarily depends on the number of nodes in the binary tree.\n", - "- In the worst case, we may have to visit every node in the tree once to validate whether it's part of a valid BST.\n", - "- Since we are performing a depth-first search (DFS) traversal of the tree, the time complexity is O(N), where N is the number of nodes in the tree.\n", - "\n", - "**Space Complexity:**\n", - "- The space complexity is determined by the space used by the recursive call stack during the DFS traversal.\n", - "- In the worst case, if the tree is completely unbalanced (a skewed tree), the maximum depth of the call stack would be equal to the height of the tree.\n", - "- In a balanced BST, the height is approximately log2(N), where N is the number of nodes.\n", - "- Therefore, the space complexity of the call stack is O(log N) for a balanced BST.\n", - "- In the worst case (skewed tree), the space complexity can be O(N) as the height of the tree can be equal to N.\n", - "\n", - "**Overall:**\n", - "- Time Complexity: O(N)\n", - "- Space Complexity: O(log N) on average for a balanced BST, and O(N) in the worst case for a skewed tree.\n", - "\n", - "The space complexity is typically dominated by the recursive call stack, and it varies depending on the shape of the binary tree. In practice, for balanced binary trees, the space complexity is often close to O(log N), which is quite efficient." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Complex Constraints**: Modify the problem to have more complex constraints on the tree. For example, consider a binary tree with constraints like \"The left subtree of a node contains only nodes with keys less than or equal to the node's key,\" and \"The right subtree of a node contains only nodes with keys greater than or equal to the node's key.\" How would you adapt the code to handle these constraints?\n", - "\n", - "2. **Handling Duplicates**: Modify the code to handle binary search trees that allow duplicate values. In a standard BST, each value is unique, but in this case, multiple nodes can have the same value. The tree should still be considered valid if it follows the BST property." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/07. Trees/README.md b/_build/html/_sources/07. Trees/README.md deleted file mode 100644 index 1eba5d4..0000000 --- a/_build/html/_sources/07. Trees/README.md +++ /dev/null @@ -1,26 +0,0 @@ -# Trees Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [226. Invert Binary Tree](https://leetcode.com/problems/invert-binary-tree/) | Easy | -| [104. Maximum Depth of Binary Tree](https://leetcode.com/problems/maximum-depth-of-binary-tree/) | Easy | -| [100. Same Tree](https://leetcode.com/problems/same-tree/) | Easy | -| [572. Subtree of Another Tree](https://leetcode.com/problems/subtree-of-another-tree/) | Easy | -| [235. Lowest Common Ancestor of a Binary Search Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/) | Easy | -| [102. Binary Tree Level Order Traversal](https://leetcode.com/problems/binary-tree-level-order-traversal/) | Medium | -| [98. Validate Binary Search Tree](https://leetcode.com/problems/validate-binary-search-tree/) | Medium | -| [230. Kth Smallest Element In a BST](https://leetcode.com/problems/kth-smallest-element-in-a-bst/) | Medium | -| [105. Construct Binary Tree From Preorder And Inorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/) | Medium | -| [124. Binary Tree Maximum Path Sum](https://leetcode.com/problems/binary-tree-maximum-path-sum/) | Hard | -| [297. Serialize And Deserialize Binary Tree](https://leetcode.com/problems/serialize-and-deserialize-binary-tree/) | Hard | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! diff --git a/_build/html/_sources/08. Tries/208. Implement Trie (Prefix Tree).ipynb b/_build/html/_sources/08. Tries/208. Implement Trie (Prefix Tree).ipynb deleted file mode 100644 index 9da2a17..0000000 --- a/_build/html/_sources/08. Tries/208. Implement Trie (Prefix Tree).ipynb +++ /dev/null @@ -1,249 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 208. Implement Trie (Prefix Tree)\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Implement Trie problem on LeetCode, click here!](https://leetcode.com/problems/implement-trie-prefix-tree/)\n", - "\n", - "---\n", - "A **trie** (pronounced as \"try\") or **prefix tree** is a tree data structure used to efficiently store and retrieve keys in a dataset of strings. There are various applications of this data structure, such as autocomplete and spellchecker.\n", - "\n", - "Implement the Trie class:\n", - "\n", - "- `Trie()` Initializes the trie object.\n", - "- `void insert(String word)` Inserts the string `word` into the trie.\n", - "- `boolean search(String word)` Returns `true` if the string `word` is in the trie (i.e., was inserted before), and `false` otherwise.\n", - "- `boolean startsWith(String prefix)` Returns `true` if there is a previously inserted string `word` that has the prefix `prefix`, and `false` otherwise.\n", - "\n", - "\n", - "**Constraints:**\n", - "- `1 <= word.length, prefix.length <= 2000`\n", - "- `word` and `prefix` consist only of lowercase English letters.\n", - "- At most $3 * 10^4$ calls in total will be made to `insert`, `search`, and `startsWith`." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem at hand is to implement a data structure known as a Trie (pronounced \"try\") or Prefix Tree. A Trie is a tree-like data structure that is used to efficiently store and retrieve a set of strings or words. It's particularly useful for tasks involving string manipulation, such as autocomplete and spell-checking. The problem statement defines the following operations for implementing the Trie class:\n", - "\n", - "1. `Trie()`: This is the constructor that initializes the Trie object.\n", - "\n", - "2. `void insert(String word)`: This method inserts the given string `word` into the Trie. It effectively adds the characters of the word to the Trie's structure, creating nodes for each character if they don't already exist. At the end of the word, a special flag is set to indicate that this node represents the end of a valid word.\n", - "\n", - "3. `boolean search(String word)`: This method checks if the given string `word` is present in the Trie. It starts from the root of the Trie and traverses the Trie by following the characters in the word. If it successfully traverses the Trie and reaches the end of the word, it returns `true`, indicating that the word exists in the Trie; otherwise, it returns `false`.\n", - "\n", - "4. `boolean startsWith(String prefix)`: This method checks if there is any previously inserted word in the Trie that has the given `prefix`. It's similar to the `search` method but does not require that the prefix be a complete word. If there is any word in the Trie that starts with the given prefix, it returns `true`; otherwise, it returns `false`.\n", - "\n", - "The problem also provides an example scenario where these operations are called, demonstrating the expected output for each operation.\n", - "\n", - "In summary, the goal is to create a data structure (Trie) that efficiently stores a set of strings and provides methods to insert new strings, search for complete words, and check if a given prefix exists in the stored set of strings.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class TrieNode:\n", - " def __init__(self):\n", - " self.children = {} # A dictionary to store child nodes\n", - " self.is_end_of_word = False # Indicates if a word ends at this node\n", - "\n", - "class Trie:\n", - " def __init__(self):\n", - " self.root = TrieNode() # Initialize the Trie with a root node\n", - "\n", - " def insert(self, word):\n", - " node = self.root # Start from the root\n", - " for char in word:\n", - " if char not in node.children:\n", - " node.children[char] = TrieNode() # Create a new node if the character is not present\n", - " node = node.children[char] # Move to the child node\n", - " node.is_end_of_word = True # Mark the end of the inserted word\n", - "\n", - " def search(self, word):\n", - " node = self.root # Start from the root\n", - " for char in word:\n", - " if char not in node.children:\n", - " return False # If the character is not found, the word is not in the Trie\n", - " node = node.children[char] # Move to the child node\n", - " return node.is_end_of_word # Check if the node represents the end of a valid word\n", - "\n", - " def startsWith(self, prefix):\n", - " node = self.root # Start from the root\n", - " for char in prefix:\n", - " if char not in node.children:\n", - " return False # If the character is not found, no word starts with the prefix\n", - " node = node.children[char] # Move to the child node\n", - " return True # Prefix found in the Trie" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "Let's explain how the code works step by step:\n", - "\n", - "1. `TrieNode` Class:\n", - " - `TrieNode` is a class that represents nodes in the Trie. Each node has two attributes:\n", - " - `children`: This is a dictionary that stores child nodes. Each key in the dictionary represents a character, and the corresponding value is the child node for that character.\n", - " - `is_end_of_word`: This boolean flag indicates whether the node represents the end of a complete word. Initially, it's set to `False` for all nodes.\n", - "\n", - "2. `Trie` Class:\n", - " - `Trie` is the main class that implements the Trie data structure. It has the following methods:\n", - "\n", - " - `__init__(self)`: The constructor initializes the Trie object by creating a root node, which serves as the starting point for all Trie operations.\n", - "\n", - " - `insert(self, word)`: This method inserts a string `word` into the Trie. It starts from the root node and iterates through each character in the word.\n", - " - If a character is not present as a child node, it creates a new node for that character.\n", - " - It then moves to the child node and continues the process until the entire word is inserted.\n", - " - Finally, it sets the `is_end_of_word` flag to `True` for the last node to mark the end of the inserted word.\n", - "\n", - " - `search(self, word)`: This method checks if a complete word (string) exists in the Trie. It starts from the root node and iterates through each character in the word.\n", - " - If a character is not found as a child node, it immediately returns `False` because the word is not in the Trie.\n", - " - It continues to move to the child node for each character.\n", - " - After reaching the end of the word, it checks if the `is_end_of_word` flag is `True` for the last node to confirm the presence of the word.\n", - "\n", - " - `startsWith(self, prefix)`: This method checks if there is any previously inserted word in the Trie that starts with a given `prefix`. It follows the same logic as the `search` method but does not require the entire word to be present.\n", - " - If the prefix is found in the Trie, it returns `True`; otherwise, it returns `False`.\n", - "\n", - "3. Example Usage:\n", - " - The code demonstrates how to create a Trie object, insert words (\"apple\" and \"app\"), and perform operations on the Trie:\n", - " - It inserts the word \"apple\" into the Trie.\n", - " - It checks if \"apple\" is in the Trie, which returns `True`.\n", - " - It checks if \"app\" is in the Trie, which returns `False`.\n", - " - It checks if there is any word in the Trie that starts with \"app,\" which returns `True`.\n", - " - It inserts the word \"app\" into the Trie.\n", - " - It checks if \"app\" is in the Trie again, which now returns `True`.\n", - "\n", - "In summary, the code efficiently implements a Trie data structure with the ability to insert words, search for complete words, and check for the existence of words with a given prefix. The Trie is organized as a tree of nodes, with each node representing a character in the words being stored." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n", - "False\n", - "True\n", - "True\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "\n", - "trie = Trie()\n", - "trie.insert(\"apple\")\n", - "print(trie.search(\"apple\")) # Output: True\n", - "print(trie.search(\"app\")) # Output: False\n", - "print(trie.startsWith(\"app\")) # Output: True\n", - "trie.insert(\"app\")\n", - "print(trie.search(\"app\")) # Output: True" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the Trie implementation:\n", - "\n", - "1. Time Complexity:\n", - " - Insertion (`insert` method): The time complexity of inserting a word into the Trie is O(m), where m is the length of the word. In the worst case, you may need to traverse the entire word to insert it into the Trie.\n", - " - Search (`search` method): The time complexity of searching for a word in the Trie is also O(m), where m is the length of the word. In the worst case, you may need to traverse the entire word to determine if it exists in the Trie.\n", - " - Starts with (`startsWith` method): The time complexity of checking if a prefix exists in the Trie is O(p), where p is the length of the prefix. In the worst case, you may need to traverse the entire prefix to determine its presence.\n", - "\n", - " Therefore, for each operation (insertion, search, or starts with), the time complexity is O(m) or O(p), where m is the length of the word being operated on, and p is the length of the prefix.\n", - "\n", - "2. Space Complexity:\n", - " - The space complexity of the Trie is determined by the number of nodes and characters stored in it. In the worst case, where none of the inserted words share common prefixes, the space complexity is O(N), where N is the total number of characters across all inserted words.\n", - " - Each node in the Trie represents a character, and the number of nodes is directly related to the total number of characters.\n", - "\n", - " In practice, the space complexity can be less than O(N) because common prefixes are shared among words in the Trie, leading to space optimization.\n", - "\n", - "In summary:\n", - "- Time complexity for each operation (insertion, search, starts with) is O(m) or O(p), where m is the length of the word and p is the length of the prefix.\n", - "- Space complexity is O(N) in the worst case, where N is the total number of characters across all inserted words. However, space optimization occurs due to common prefix sharing in practice, potentially reducing the actual space used." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Count Prefixes**:\n", - " Implement a method to count the number of words in the Trie that have a specific prefix. This exercise requires you to maintain additional data in the Trie nodes to keep track of the count.\n", - "\n", - "2. **Auto-Complete Suggestions**:\n", - " Implement an auto-complete feature using the Trie. Given a prefix, the program should return a list of suggested words based on the words previously inserted into the Trie." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/08. Tries/211. Design Add and Search Words Data Structure.ipynb b/_build/html/_sources/08. Tries/211. Design Add and Search Words Data Structure.ipynb deleted file mode 100644 index 2de472c..0000000 --- a/_build/html/_sources/08. Tries/211. Design Add and Search Words Data Structure.ipynb +++ /dev/null @@ -1,275 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 211. Design Add and Search Words Data Structure\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Design Add and Search Words Data Structure problem on LeetCode, click here!](https://leetcode.com/problems/design-add-and-search-words-data-structure/)\n", - "\n", - "---\n", - "Design a data structure that supports adding new words and finding if a string matches any previously added string.\n", - "\n", - "Implement the `WordDictionary` class:\n", - "\n", - "- `WordDictionary()` Initializes the object.\n", - "- `void addWord(word)` Adds `word` to the data structure, it can be matched later.\n", - "- `bool search(word)` Returns `true` if there is any string in the data structure that matches `word` or `false` otherwise. `word` may contain dots `'.'` where dots can be matched with any letter.\n", - "\n", - "**Constraints:**\n", - "- `1 <= word.length <= 25`\n", - "- `word` in `addWord` consists of lowercase English letters.\n", - "- `word` in `search` consist of `'.'` or lowercase English letters.\n", - "- There will be at most `2` dots in `word` for `search` queries.\n", - "- At most $10^4$ calls will be made to `addWord` and `search`." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is to design a data structure called `WordDictionary` that allows you to add words and search for words efficiently. The key feature of this data structure is that it should support wildcard search, where a dot ('.') can match any letter.\n", - "\n", - "Here are the specific requirements and explanations for the problem:\n", - "\n", - "1. Initialize the `WordDictionary` object using the constructor `WordDictionary()`.\n", - "\n", - "2. The `addWord(word)` method allows you to add a word to the data structure. Once added, you should be able to search for this word later. The words consist of lowercase English letters, and each word has a length between 1 and 25 characters.\n", - "\n", - "3. The `search(word)` method allows you to search for a word in the data structure. This method returns `True` if there is any string in the data structure that matches the given word or `False` otherwise. The word you are searching for may contain dots ('.'), where each dot can match any letter.\n", - "\n", - "4. The wildcard character ('.') in the `search` method allows for partial or fuzzy searching. For example, if the word dictionary contains the words \"bad,\" \"dad,\" and \"mad,\" then:\n", - " - Searching for \"pad\" should return `False` because there is no exact match.\n", - " - Searching for \"bad\" should return `True` because \"bad\" is in the dictionary.\n", - " - Searching for \".ad\" should return `True` because it can match \"bad,\" \"dad,\" or \"mad.\"\n", - " - Searching for \"b..\" should return `True` because it can match \"bad,\" \"bed,\" \"bet,\" etc.\n", - "\n", - "5. The problem specifies that there will be at most two dots ('.') in search queries, and there will be at most 10^4 calls to both `addWord` and `search`.\n", - "\n", - "In summary, you need to implement the `WordDictionary` class that efficiently supports adding words and searching for words, where the search can include wildcard characters ('.') that match any letter.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class TrieNode:\n", - " def __init__(self):\n", - " # Initialize a TrieNode with children and a flag to indicate the end of a word.\n", - " self.children = {}\n", - " self.is_end_of_word = False\n", - "\n", - "class WordDictionary:\n", - "\n", - " def __init__(self):\n", - " # Initialize the WordDictionary with a root node.\n", - " self.root = TrieNode()\n", - "\n", - " def addWord(self, word: str) -> None:\n", - " node = self.root\n", - " # Iterate through the characters in the word.\n", - " for char in word:\n", - " if char not in node.children:\n", - " # Create a new node for the character if it doesn't exist.\n", - " node.children[char] = TrieNode()\n", - " # Move to the next node.\n", - " node = node.children[char]\n", - " # Mark the end of the word by setting the flag to True.\n", - " node.is_end_of_word = True\n", - "\n", - " def search_helper(self, node: TrieNode, word: str) -> bool:\n", - " if not word:\n", - " # If there are no characters left in the word, check if we reached the end of a word in the trie.\n", - " return node.is_end_of_word\n", - " \n", - " char = word[0]\n", - " if char == '.':\n", - " # If the character is a dot, explore all possible child nodes.\n", - " for child in node.children.values():\n", - " if self.search_helper(child, word[1:]):\n", - " return True\n", - " elif char in node.children:\n", - " # If the character is in the children of the current node, move to the next node.\n", - " return self.search_helper(node.children[char], word[1:])\n", - " \n", - " # If the character is not found and is not a dot, the word is not in the trie.\n", - " return False\n", - "\n", - " def search(self, word: str) -> bool:\n", - " # Start the search from the root of the trie.\n", - " return self.search_helper(self.root, word)" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "This code defines a `WordDictionary` class that uses a Trie data structure to efficiently store and search for words. Here's a step-by-step explanation:\n", - "\n", - "1. `TrieNode` class: This class represents nodes in the Trie data structure. Each node has two attributes: `children` (a dictionary to store child nodes) and `is_end_of_word` (a flag to indicate whether the node marks the end of a word).\n", - "\n", - "2. `WordDictionary` class: This class initializes with an empty Trie by creating a root node.\n", - "\n", - "3. `addWord` method: This method adds a word to the Trie. It iterates through each character in the word and creates Trie nodes as necessary. It sets the `is_end_of_word` flag to `True` for the final character of the word to mark the end of the word.\n", - "\n", - "4. `search_helper` method: This is a recursive helper function for searching words in the Trie. It takes a Trie node (`node`) and a word to search (`word`) as input. If there are no characters left in the word (`not word`), it checks if the current node marks the end of a word. If it does, it returns `True`.\n", - "\n", - "5. If the first character of the word is a dot ('.'), the function explores all possible child nodes by iterating through `node.children.values()` and recursively calls `search_helper` for each child with the remaining part of the word (`word[1:]`).\n", - "\n", - "6. If the first character of the word is not a dot and is found in the children of the current node, the function recursively moves to the next node by calling `search_helper` on the child node and the remaining part of the word.\n", - "\n", - "7. If the character is not found in the children and is not a dot, the word is not in the Trie, so the function returns `False`.\n", - "\n", - "8. `search` method: This is the public method for searching words. It initiates the search process by calling `search_helper` starting from the root node of the Trie.\n", - "\n", - "Overall, this code efficiently implements a Trie-based data structure that allows adding and searching for words, including support for wildcard characters represented by dots ('.')." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n", - "True\n", - "True\n", - "True\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "\n", - "wordDictionary = WordDictionary()\n", - "wordDictionary.addWord(\"bad\")\n", - "wordDictionary.addWord(\"dad\")\n", - "wordDictionary.addWord(\"mad\")\n", - "print(wordDictionary.search(\"pad\")) # Output: False\n", - "print(wordDictionary.search(\"bad\")) # Output: True\n", - "print(wordDictionary.search(\".ad\")) # Output: True\n", - "print(wordDictionary.search(\"b..\")) # Output: True" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `WordDictionary` class methods:\n", - "\n", - "1. `addWord` Method:\n", - "\n", - " - Time Complexity: O(L)\n", - " - L is the length of the word being added.\n", - " - In the worst case, we need to iterate through each character in the word and create nodes in the Trie. This takes O(L) time.\n", - "\n", - " - Space Complexity: O(L)\n", - " - The space complexity for storing the word in the Trie is also O(L) because we create nodes for each character in the word.\n", - "\n", - "2. `search_helper` Method (called by `search`):\n", - "\n", - " - Time Complexity: O(2^M * L)\n", - " - M is the maximum number of dots ('.') in the search word.\n", - " - In the worst case, when there are M dots in the search word, we may explore all possible child nodes at each dot. This results in a branching factor of 26 (for lowercase letters) at each dot.\n", - " - So, the time complexity is exponential in the number of dots and linear in the length of the word being searched (L).\n", - "\n", - " - Space Complexity: O(L)\n", - " - The space complexity for the recursive call stack is O(L) in the worst case because we may have to recurse to a depth equal to the length of the search word.\n", - "\n", - "3. `search` Method:\n", - "\n", - " - Time Complexity: O(2^M * L)\n", - " - The `search` method calls the `search_helper` method, which has the same time complexity explained above.\n", - "\n", - " - Space Complexity: O(L)\n", - " - The space complexity for the recursive call stack is O(L) in the worst case, as explained earlier.\n", - "\n", - "Overall, the time complexity of the `search` method is mainly affected by the number of dots ('.') in the search word. In the worst case, when there are multiple dots and many possibilities to explore at each dot, the time complexity can be exponential. However, for most practical cases, it performs reasonably well.\n", - "\n", - "The space complexity primarily depends on the space required to store the words in the Trie. It is proportional to the total number of characters in all added words and is linear with respect to the length of the words added.\n", - "\n", - "In summary:\n", - "\n", - "- Time Complexity for `addWord`: O(L)\n", - "- Time Complexity for `search`: O(2^M * L)\n", - "- Space Complexity: O(L) for storing words in the Trie, O(L) for the recursive call stack during search.\n", - "\n", - "Note: The space complexity analysis assumes that the dictionary contains a reasonable number of words and does not account for the overhead of Python objects or system-level memory allocation." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Dictionary Auto-Completion**: Extend the `WordDictionary` class to provide auto-completion suggestions based on the prefix of a word. Implement a method that returns a list of words that match the given prefix.\n", - "\n", - "2. **Support Word Deletion**: Extend the `WordDictionary` class to support word deletion. Add a method `deleteWord(word)` that removes a word from the data structure. Ensure that the search operation still works correctly after deletion." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/08. Tries/212. Word Search II.ipynb b/_build/html/_sources/08. Tries/212. Word Search II.ipynb deleted file mode 100644 index 71597b8..0000000 --- a/_build/html/_sources/08. Tries/212. Word Search II.ipynb +++ /dev/null @@ -1,316 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 212. Word Search II\n", - "\n", - "**Difficulty:** Hard\n", - "\n", - "**Link to Problem:** [To see the Word Search II problem on LeetCode, click here!](https://leetcode.com/problems/word-search-ii/)\n", - "\n", - "---\n", - "Given an `m x n` `board` of characters and a list of strings `words`, the task is to return *all words on the board*.\n", - "\n", - "Each word must be constructed from letters of sequentially **adjacent cells**, where adjacent cells are horizontally or vertically neighboring. The same letter cell may not be used more than once in a word.\n", - "\n", - "\n", - "**Constraints:**\n", - "- `m == board.length`\n", - "- `n == board[i].length`\n", - "- `1 <= m, n <= 12`\n", - "- `board[i][j]` is a lowercase English letter.\n", - "- 1 <= `words.length` <= $3 * 10^4$\n", - "- `1 <= words[i].length <= 10`\n", - "- `words[i]` consists of lowercase English letters.\n", - "- All the strings of `words` are unique." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "To solve the \"Word Search II\" problem, you can use a Trie data structure and perform a depth-first search (DFS) on the board. Here's a step-by-step approach to solve the problem:\n", - "\n", - "1. Build a Trie from the given list of words:\n", - " - Create a Trie data structure to store all the words from the input list.\n", - " - For each word in the input list, insert it into the Trie, character by character. Make sure to mark the end of each word in the Trie.\n", - "\n", - "2. Perform DFS on the board:\n", - " - Iterate through each cell (i, j) on the board.\n", - " - For each cell, start a DFS traversal from that cell to search for words.\n", - " - During the DFS traversal, maintain a current path string.\n", - " - At each cell, check if the current path string, concatenated with the character in the cell, matches any word prefix in the Trie. If it does, continue the DFS.\n", - " - If the current path string matches a word in the Trie, add it to the result.\n", - "\n", - "3. Implement DFS with backtracking:\n", - " - During the DFS traversal, you will explore neighboring cells (horizontally and vertically) if they are within bounds and haven't been visited before.\n", - " - To prevent revisiting the same cell within the same word, mark the cell as visited (e.g., change its character to a special character like '#') before exploring it and restore its original character after the DFS traversal.\n", - "\n", - "4. Return the result:\n", - " - After completing the DFS traversal for all cells on the board, you will have collected all the valid words in the result set.\n", - " - Convert the result set to a list and return it as the final output.\n", - "\n", - "This approach efficiently finds all words on the board by utilizing the Trie data structure to prune unnecessary DFS paths and avoiding duplicate visits to the same cell within the same word. It ensures that each word is constructed from letters of sequentially adjacent cells without using the same letter cell more than once in a word.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Define a TrieNode class to represent nodes in the Trie.\n", - "class TrieNode:\n", - " def __init__(self):\n", - " self.children = {} # Dictionary to store child nodes.\n", - " self.is_end_of_word = False # Flag to mark the end of a word.\n", - "\n", - "# Main function to find words on the board.\n", - "def findWords(board, words):\n", - " # DFS function to search for words starting from a given cell.\n", - " def dfs(node, i, j, path):\n", - " char = board[i][j] # Get the character at the current cell.\n", - " curr_node = node.children.get(char) # Find the corresponding Trie node.\n", - "\n", - " if not curr_node:\n", - " return # If no matching Trie node, stop the search.\n", - "\n", - " path += char # Add the character to the current path.\n", - "\n", - " if curr_node.is_end_of_word:\n", - " result.add(path) # If the path matches a word, add it to the result.\n", - "\n", - " temp, board[i][j] = board[i][j], \"#\" # Mark the cell as visited.\n", - "\n", - " # Explore neighboring cells (up, down, left, right).\n", - " if i > 0:\n", - " dfs(curr_node, i - 1, j, path)\n", - " if i < m - 1:\n", - " dfs(curr_node, i + 1, j, path)\n", - " if j > 0:\n", - " dfs(curr_node, i, j - 1, path)\n", - " if j < n - 1:\n", - " dfs(curr_node, i, j + 1, path)\n", - "\n", - " board[i][j] = temp # Restore the cell's original character.\n", - "\n", - " # Function to build a Trie from the list of words.\n", - " def buildTrie():\n", - " root = TrieNode() # Create a root node.\n", - " for word in words:\n", - " node = root\n", - " for char in word:\n", - " if char not in node.children:\n", - " node.children[char] = TrieNode() # Create a new node if needed.\n", - " node = node.children[char]\n", - " node.is_end_of_word = True # Mark the end of the word.\n", - " return root\n", - "\n", - " m, n = len(board), len(board[0]) # Get the dimensions of the board.\n", - " root = buildTrie() # Build the Trie from the list of words.\n", - " result = set() # Use a set to store unique words found on the board.\n", - "\n", - " # Iterate through each cell on the board and start DFS from there.\n", - " for i in range(m):\n", - " for j in range(n):\n", - " dfs(root, i, j, \"\") # Start DFS from each cell on the board.\n", - "\n", - " return list(result) # Convert the set to a list and return the result." - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The code solves the \"Word Search II\" problem, where you have a grid of characters and a list of words. The goal is to find all words from the list that can be constructed by traversing adjacent cells (horizontally or vertically) in the grid, without using the same cell more than once for a single word.\n", - "\n", - "The code does the following:\n", - "\n", - "1. Defines a `TrieNode` class to represent nodes in a Trie data structure. Each node has children (other characters in the word) and a flag to mark the end of a word.\n", - "\n", - "2. Defines the `findWords` function, which takes the grid (`board`) and a list of words (`words`) as input.\n", - "\n", - "3. Inside the `findWords` function, there is a `dfs` (depth-first search) function. This function is used to explore the grid starting from a specific cell. It checks if the current path matches any word in the Trie and adds it to the result if found.\n", - "\n", - "4. The code also includes a `buildTrie` function that constructs a Trie data structure from the list of words. It iterates through each word, creating nodes for each character in the Trie and marking the end of words.\n", - "\n", - "5. The dimensions of the grid are obtained (m x n).\n", - "\n", - "6. A Trie is built using the `buildTrie` function.\n", - "\n", - "7. A set called `result` is used to store unique words found in the grid.\n", - "\n", - "8. The code iterates through each cell on the grid (using nested loops) and starts a DFS search from each cell.\n", - "\n", - "9. During the DFS, it explores neighboring cells (up, down, left, right) if they haven't been visited before and if the current path matches a prefix in the Trie.\n", - "\n", - "10. When a word is found during the DFS traversal, it is added to the `result` set.\n", - "\n", - "11. The grid cell is marked as visited during the DFS by changing its character to \"#\", and it is restored to its original character after the DFS traversal.\n", - "\n", - "12. Finally, the set of unique words found is converted to a list and returned as the output.\n", - "\n", - "The code effectively uses a Trie data structure to optimize the search and ensures that each word is constructed from adjacent cells without reusing the same cell for the same word." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['eat', 'oath']\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "board1 = [[\"o\",\"a\",\"a\",\"n\"],[\"e\",\"t\",\"a\",\"e\"],[\"i\",\"h\",\"k\",\"r\"],[\"i\",\"f\",\"l\",\"v\"]]\n", - "words1 = [\"oath\",\"pea\",\"eat\",\"rain\"]\n", - "print(findWords(board1, words1)) # Output: [\"eat\", \"oath\"]" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "c748b879-a2d8-4298-a42c-c7f61f9c7fc6", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[]\n" - ] - } - ], - "source": [ - "# Example 2\n", - "\n", - "board2 = [[\"a\",\"b\"],[\"c\",\"d\"]]\n", - "words2 = [\"abcb\"]\n", - "print(findWords(board2, words2)) # Output: []" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. **Building the Trie (`buildTrie` function):** \n", - " - Suppose there are `N` words in the input list, and the average length of a word is `L`.\n", - " - Building the Trie takes O(N * L) time, as we iterate through each word and insert each character into the Trie.\n", - "\n", - "2. **DFS Traversal (`dfs` function):** \n", - " - In the worst case, the DFS function explores all possible paths in the grid.\n", - " - The maximum number of recursive calls for each cell is 4 (up, down, left, right).\n", - " - The maximum depth of the DFS is limited by the length of the longest word in the Trie, which is at most `L`.\n", - " - Therefore, the DFS traversal for each cell takes $O(4^L)$ time.\n", - "\n", - "3. **Iterating Through the Grid (`findWords` function):**\n", - " - In the worst case, we iterate through all `m` rows and `n` columns in the grid.\n", - " - For each cell, we start a DFS traversal.\n", - " - Therefore, iterating through the entire grid takes $O(m * n * 4^L)$ time.\n", - "\n", - "Overall, the time complexity of the code is $O(N * L + m * n * 4^L)$.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. **Trie Data Structure:**\n", - " - The space required to store the Trie depends on the number of unique characters in all the words.\n", - " - In the worst case, where all words are unique and have no common prefixes, the space complexity of the Trie is O(N * L).\n", - " - In practice, it may be less if there are common prefixes among words.\n", - "\n", - "2. **DFS Stack (Recursive Calls):**\n", - " - The depth of the recursive call stack during DFS is at most `L`, where `L` is the length of the longest word in the Trie.\n", - " - Therefore, the space complexity for the recursive call stack is O(L).\n", - "\n", - "3. **Result Set (`result` set):**\n", - " - The space used to store the result set depends on the number of valid words found in the grid.\n", - " - In the worst case, when all words are found, the space complexity of the result set is O(N * L).\n", - "\n", - "Overall, the space complexity of the code is O(N * L) for the Trie and O(L) for the recursive call stack.\n", - "\n", - "In summary, the time complexity is dominated by the DFS traversal and is influenced by the number of words, their lengths, and the size of the grid. The space complexity is mainly determined by the Trie structure and the recursive call stack depth during DFS." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Word Search Paths:**\n", - " Extend the basic word search exercise to find all possible paths (sequences of cells) that spell out a given word on the board. Return a list of paths if the word can be formed, otherwise an empty list.\n", - "\n", - "\n", - "2. **Reverse Word Search:**\n", - " Modify the code to search for words in reverse order on the board. Given a 2D grid of characters and a list of words, find all words from the list that can be formed by traversing the board in reverse (right to left, bottom to top, etc.)." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/08. Tries/README.md b/_build/html/_sources/08. Tries/README.md deleted file mode 100644 index 22c3bcd..0000000 --- a/_build/html/_sources/08. Tries/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# Trie Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [208. Implement Trie Prefix Tree](https://leetcode.com/problems/implement-trie-prefix-tree/) | Medium | -| [211. Design Add And Search Words Data Structure](https://leetcode.com/problems/design-add-and-search-words-data-structure/) | Medium | -| [212. Word Search II](https://leetcode.com/problems/word-search-ii/) | Hard | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! diff --git a/_build/html/_sources/09. Heap - Priority Queue/1046. Last Stone Weight.ipynb b/_build/html/_sources/09. Heap - Priority Queue/1046. Last Stone Weight.ipynb deleted file mode 100644 index cb66b6a..0000000 --- a/_build/html/_sources/09. Heap - Priority Queue/1046. Last Stone Weight.ipynb +++ /dev/null @@ -1,254 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 1046. Last Stone Weight\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Last Stone Weight problem on LeetCode, click here!](https://leetcode.com/problems/last-stone-weight/)\n", - "\n", - "---\n", - "You are given an array of integers `stones` where `stones[i]` is the weight of the `i`th stone.\n", - "\n", - "We are playing a game with the stones. On each turn, you choose the **heaviest two stones** and smash them together. Suppose the heaviest two stones have weights `x` and `y` with `x <= y`. The result of this smash is:\n", - "\n", - "1. If `x == y`, both stones are destroyed.\n", - "2. If `x != y`, the stone of weight `x` is destroyed, and the stone of weight `y` has new weight `y - x`.\n", - "\n", - "At the end of the game, there is **at most one** stone left.\n", - "\n", - "Return *the weight of the last remaining stone*. If there are no stones left, return `0`.\n", - "\n", - "**Constraints:**\n", - "- `1 <= stones.length <= 30`\n", - "- `1 <= stones[i] <= 1000`" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The \"Last Stone Weight\" problem involves a game played with a collection of stones, each stone having a certain weight. The goal is to find the weight of the last remaining stone after applying a specific set of rules.\n", - "\n", - "Here's how the game works:\n", - "\n", - "1. You start with an array of stones, where each stone is represented by its weight. The weights of the stones are given in the input as an array.\n", - "\n", - "2. In each turn of the game, you select the two heaviest stones from the remaining stones. If there is only one stone left, you've found the answer.\n", - "\n", - "3. If there are two stones with weights `x` and `y`, where `x` is less than or equal to `y`, the following happens:\n", - " - If `x` is equal to `y`, both stones are completely destroyed, and they are removed from the array of stones.\n", - " - If `x` is not equal to `y`, the stone with weight `x` is destroyed, and the stone with weight `y` now has a new weight of `y - x`. The stone with weight `x` is removed from the array, and the modified stone with weight `y - x` remains in the array.\n", - "\n", - "4. The game continues with the modified array of stones until there is at most one stone left.\n", - "\n", - "5. The goal is to find the weight of the last remaining stone, or if there are no stones left, return `0`.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "import heapq\n", - "\n", - "def lastStoneWeight(stones):\n", - " # Convert the input list to a max heap (negate the values to simulate a max heap)\n", - " max_heap = [-stone for stone in stones]\n", - " heapq.heapify(max_heap)\n", - "\n", - " # Continue as long as there are more than 1 stone in the heap\n", - " while len(max_heap) > 1:\n", - " # Get the two heaviest stones\n", - " y = -heapq.heappop(max_heap) # Get the heaviest stone and negate it back to positive\n", - " x = -heapq.heappop(max_heap) # Get the second heaviest stone and negate it back to positive\n", - "\n", - " # Calculate the new stone's weight after smashing\n", - " if x != y:\n", - " new_stone = y - x\n", - " heapq.heappush(max_heap, -new_stone) # Negate the value and push it back to the heap\n", - "\n", - " # If there is one stone left, return its weight (negate it back to positive)\n", - " if max_heap:\n", - " return -max_heap[0]\n", - " else:\n", - " return 0" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The code defines a Python function called `lastStoneWeight` that takes a list of stone weights as input. It aims to find the weight of the last remaining stone after playing the stone smashing game described in the problem statement.\n", - "\n", - "Here's a step-by-step explanation of the code:\n", - "\n", - "1. We import the `heapq` library, which allows us to create and manipulate a heap (priority queue).\n", - "\n", - "2. Inside the `lastStoneWeight` function:\n", - " - We create a max heap (negating stone weights to simulate a max heap) using the `heapq.heapify` function. This heap will keep track of the heaviest stones.\n", - " \n", - " - We enter a loop that continues as long as there are more than 1 stone in the heap.\n", - " \n", - " - Inside the loop, we:\n", - " - Retrieve and negate the heaviest stone (`y`) from the heap.\n", - " - Retrieve and negate the second heaviest stone (`x`) from the heap.\n", - " \n", - " - Calculate the new stone's weight after smashing (`y - x`), and negate it back to simulate a max heap.\n", - " - Add the new stone back to the heap using `heapq.heappush`.\n", - " \n", - "3. After the loop, if there is one stone left in the heap, we retrieve and negate it to get its actual weight, and return it as the result.\n", - " \n", - "4. If there are no stones left (the heap is empty), we return `0`, indicating that no stones remain.\n", - "\n", - "5. Finally, we provide two test cases to demonstrate the function's usage and correctness.\n", - "\n", - "In summary, the code efficiently implements the stone smashing game by maintaining a max heap, selecting the heaviest stones in each turn, smashing them, and updating the heap until there is at most one stone left. It then returns the weight of the last remaining stone or 0 if there are no stones left." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "stones1 = [2, 7, 4, 1, 8, 1]\n", - "print(lastStoneWeight(stones1)) # Output: 1" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "b7e79514-4821-48d0-bb9d-0f2de8150945", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n" - ] - } - ], - "source": [ - "# Example 2: \n", - "\n", - "stones2 = [1]\n", - "print(lastStoneWeight(stones2)) # Output: 1" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided Python code for the \"Last Stone Weight\" problem:\n", - "\n", - "**Time Complexity:**\n", - "1. The `heapq.heapify` operation to create the max heap from the input stone weights has a time complexity of O(n), where n is the number of stones.\n", - "\n", - "2. The loop that continues until there are more than 1 stone in the heap performs the following operations in each iteration:\n", - " - Retrieving and negating the heaviest stone (`y`) from the heap, which takes O(log n) time.\n", - " - Retrieving and negating the second heaviest stone (`x`) from the heap, also taking O(log n) time.\n", - " - Calculating the new stone's weight and pushing it back into the heap using `heapq.heappush`, which takes O(log n) time.\n", - "\n", - "3. In the worst case, the loop runs until there is only one stone left, which requires approximately (n-1) iterations.\n", - "\n", - "Overall, the dominant time complexity is O(n) for the initial heap creation, and within the loop, each iteration takes O(log n) time. Therefore, the overall time complexity of the algorithm is O(n log n).\n", - "\n", - "**Space Complexity:**\n", - "1. The space complexity is primarily determined by the space required for the max heap. In the worst case, this heap can contain all the stones, so the space complexity for the heap is O(n).\n", - "\n", - "2. The rest of the variables used in the function (e.g., `x`, `y`, `new_stone`) require only constant space, so they do not significantly contribute to the space complexity.\n", - "\n", - "Therefore, the overall space complexity of the algorithm is O(n) due to the space used for the max heap.\n", - "\n", - "In summary:\n", - "- Time Complexity: $O(n\\ log\\ n)$\n", - "- Space Complexity: $O(n)$\n", - "\n", - "The algorithm is efficient enough to handle the problem's constraints, as the worst-case time and space complexities are both linearithmic in terms of the number of stones." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Kth Last Stone Weight**: Modify the problem to find the weight of the Kth last remaining stone, where K is an integer input. Your function should work efficiently for large values of K.\n", - "\n", - "\n", - "2. **Multiple Stones Smash**: Modify the problem so that instead of smashing two stones at a time, you can smash up to K stones at each turn, where K is an integer input. Determine the weight of the last remaining stone in this variation." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/09. Heap - Priority Queue/295. Find Median from Data Stream.ipynb b/_build/html/_sources/09. Heap - Priority Queue/295. Find Median from Data Stream.ipynb deleted file mode 100644 index 847dd60..0000000 --- a/_build/html/_sources/09. Heap - Priority Queue/295. Find Median from Data Stream.ipynb +++ /dev/null @@ -1,242 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 295. Find Median from Data Stream\n", - "\n", - "**Difficulty:** Hard\n", - "\n", - "**Link to Problem:** [To see the Find Median from Data Stream problem on LeetCode, click here!](https://leetcode.com/problems/find-median-from-data-stream/)\n", - "\n", - "---\n", - "\n", - "The **median** is the middle value in an ordered integer list. If the size of the list is even, there is no middle value, and the median is the mean of the two middle values.\n", - "\n", - "Implement the MedianFinder class:\n", - "\n", - "- `MedianFinder()` initializes the `MedianFinder` object.\n", - "- `void addNum(int num)` adds the integer `num` from the data stream to the data structure.\n", - "- `double findMedian()` returns the median of all elements so far. Answers within $10^{-5}$ of the actual answer will be accepted.\n", - "\n", - "**Constraints:**\n", - "\n", - "- $-10^{5}$ <= `num` <= $10^{5}$\n", - "- There will be at least one element in the data structure before calling `findMedian`.\n", - "- At most $5 * 10^4$ calls will be made to `addNum` and `findMedian`.\n", - "\n", - "**Follow-up:**\n", - "\n", - "1. If all integer numbers from the stream are in the range `[0, 100]`, how would you optimize your solution?\n", - "2. If `99%` of all integer numbers from the stream are in the range `[0, 100]`, how would you optimize your solution?" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem, \"Find Median from Data Stream,\" deals with efficiently computing the median of a sequence of numbers as they are incrementally provided. The median is the middle value in an ordered list of numbers. When the list has an even number of elements, the median is the average of the two middle values.\n", - "\n", - "Here's a breakdown of the problem:\n", - "\n", - "1. **Initialization**: You are asked to implement a `MedianFinder` class that supports the following operations:\n", - "\n", - " - `MedianFinder()`: Initializes the MedianFinder object.\n", - " - `addNum(int num)`: Adds an integer `num` from the data stream to the data structure.\n", - " - `findMedian()`: Returns the median of all elements added to the data structure.\n", - "\n", - "2. **Median Calculation**: The `findMedian` operation should efficiently compute the median, and the result should have a precision of at least $10^{-5}$ (i.e., answers within this range will be considered correct).\n", - "\n", - "3. **Examples**:\n", - " \n", - " - If you add numbers [1, 2], the median should be 1.5 because (1 + 2) / 2 = 1.5.\n", - " - If you add numbers [1, 2, 3], the median should be 2 because it's the middle value.\n", - " \n", - "4. **Constraints**:\n", - "\n", - " - The integers provided in the data stream are in the range from $-10^5$ to $10^5$.\n", - " - There will be at least one element in the data structure before calling `findMedian`.\n", - " - At most, $5 * 10^4$ calls will be made to `addNum` and `findMedian`.\n", - "\n", - "The problem can be solved by using two priority queues (heaps): one max-heap to store the smaller half of the numbers and one min-heap to store the larger half of the numbers. The max-heap ensures that the largest number in the smaller half is at the top, and the min-heap ensures that the smallest number in the larger half is at the top. These heaps are balanced to efficiently find the median when requested.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "import heapq\n", - "\n", - "class MedianFinder:\n", - "\n", - " def __init__(self):\n", - " # Initialize two heaps: a max-heap (small_half) for the smaller half of numbers,\n", - " # and a min-heap (large_half) for the larger half of numbers.\n", - " self.small_half = [] # Max-heap for the smaller half of the numbers\n", - " self.large_half = [] # Min-heap for the larger half of the numbers\n", - "\n", - " def addNum(self, num: int) -> None:\n", - " # Add the number to the appropriate heap based on its value\n", - " if not self.small_half or num <= -self.small_half[0]:\n", - " # If the number is less than or equal to the current maximum in the smaller half,\n", - " # add it to the smaller half (max-heap)\n", - " heapq.heappush(self.small_half, -num)\n", - " else:\n", - " # Otherwise, add it to the larger half (min-heap)\n", - " heapq.heappush(self.large_half, num)\n", - "\n", - " # Balance the heaps if necessary to ensure the size difference is at most 1\n", - " if len(self.small_half) > len(self.large_half) + 1:\n", - " # If the size of the smaller half is more than one greater than the size of the larger half,\n", - " # move the maximum from the smaller half to the larger half to balance them.\n", - " heapq.heappush(self.large_half, -heapq.heappop(self.small_half))\n", - " elif len(self.large_half) > len(self.small_half):\n", - " # If the size of the larger half is greater than the size of the smaller half,\n", - " # move the minimum from the larger half to the smaller half to balance them.\n", - " heapq.heappush(self.small_half, -heapq.heappop(self.large_half))\n", - "\n", - " def findMedian(self) -> float:\n", - " if len(self.small_half) == len(self.large_half):\n", - " # If both halves have the same size, there's an even number of elements,\n", - " # so the median is the average of the top elements in both heaps.\n", - " return (-self.small_half[0] + self.large_half[0]) / 2.0\n", - " else:\n", - " # If the smaller half has more elements, it contains the median (odd number of elements).\n", - " return -self.small_half[0]" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The code defines a `MedianFinder` class for efficiently finding the median of a stream of numbers. It uses two heaps: a max-heap (`small_half`) to store the smaller half of the numbers and a min-heap (`large_half`) to store the larger half. Here's how the code works:\n", - "\n", - "1. The `__init__` method initializes the two heaps.\n", - "\n", - "2. The `addNum` method adds a number to the appropriate heap, ensuring that the heaps remain balanced. It does this by comparing the number to the current maximum in the smaller half and adding it to the appropriate heap. Then, it checks the sizes of the two heaps and rebalances them if necessary.\n", - "\n", - "3. The `findMedian` method calculates and returns the median. If both halves have the same size (even number of elements), it computes the average of the tops of both heaps. If the smaller half has more elements (odd number of elements), it returns the top of the max-heap, which is the median.\n", - "\n", - "In summary, this code efficiently maintains two heaps to divide the elements into smaller and larger halves, allowing for quick median retrieval. It offers a time complexity of O(log N) for adding elements and O(1) for finding the median, where N is the total number of elements processed. The space complexity is O(1) as the space used by the two heaps is independent of the input size." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1.5\n", - "2\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "medianFinder = MedianFinder()\n", - "medianFinder.addNum(1)\n", - "medianFinder.addNum(2)\n", - "print(medianFinder.findMedian()) # Output: 1.5\n", - "medianFinder.addNum(3)\n", - "print(medianFinder.findMedian()) # Output: 2.0\n" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `MedianFinder` class:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. `MedianFinder()` Initialization: This operation has a time complexity of O(1). It simply initializes the two heaps.\n", - "\n", - "2. `addNum(int num)`: The time complexity for adding a number is O(log N), where N is the total number of elements processed so far. This is because, in the worst case, you might need to perform logarithmic operations on the heaps to maintain their balance.\n", - "\n", - "3. `findMedian()`: Finding the median has a time complexity of O(1). It simply involves accessing the tops of the two heaps, which takes constant time.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. `MedianFinder()` Initialization: The space complexity for initialization is O(1). It involves creating two empty heaps, which do not depend on the size of the data stream.\n", - "\n", - "2. `addNum(int num)`: The space complexity for adding a number is also O(1). It involves adding the number to one of the two heaps, which do not significantly affect the overall space complexity.\n", - "\n", - "3. `findMedian()`: The space complexity for finding the median is O(1). It doesn't require any additional data structures that grow with the input size.\n", - "\n", - "In summary, the time complexity of the `addNum` operation is O(log N), and the time complexity of the `findMedian` operation is O(1). The space complexity is O(1) as well, as the space used by the two heaps is independent of the size of the data stream. This solution efficiently maintains and retrieves the median, making it suitable for the given problem constraints." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Generalized kth Element**: Extend the `MedianFinder` class to support finding the kth element in the data stream efficiently. This means finding the kth smallest or kth largest element in the stream.\n", - "\n", - "2. **Sliding Window Median**: Given an array and a sliding window size, find the median within the window as it slides over the array. This is an extension of the problem to a moving window scenario." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.ipynb b/_build/html/_sources/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.ipynb deleted file mode 100644 index 2e1522d..0000000 --- a/_build/html/_sources/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.ipynb +++ /dev/null @@ -1,239 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 703. Kth Largest Element in a Stream\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Kth Largest Element in a Stream problem on LeetCode, click here!](https://leetcode.com/problems/kth-largest-element-in-a-stream/)\n", - "\n", - "---\n", - "Design a class to find the `kth` largest element in a stream. Note that it is the `kth` largest element in the sorted order, not the `kth` distinct element.\n", - "\n", - "Implement the `KthLargest` class with the following methods:\n", - "\n", - "- `KthLargest(int k, int[] nums)`: Initializes the object with the integer `k` and the stream of integers `nums`.\n", - "- `int add(int val)`: Appends the integer `val` to the stream and returns the element representing the `kth` largest element in the stream.\n", - "\n", - "\n", - "**Constraints:**\n", - "\n", - "- 1 <= `k` <= $10^4$\n", - "- 0 <= `nums.length` <= $10^4$\n", - "- $-10^4$ <= `nums[i]` <= $10^4$\n", - "- $-10^4$ <= `val` <= $10^4$\n", - "- At most $10^4$ calls will be made to `add`.\n", - "- It is guaranteed that there will be at least `k` elements in the array when you search for the `kth` element." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem you're trying to solve is to design a class called `KthLargest` that can efficiently find the kth largest element in a stream of integers. You need to support two main operations:\n", - "\n", - "To solve this problem efficiently, you can use a min-heap data structure. Here's how the approach works:\n", - "\n", - "1. Initialize a min-heap to store the k largest elements. Initially, it's empty.\n", - "\n", - "2. In the `__init__` method, populate the min-heap with the first `k` elements from `nums`. This ensures that you have the k largest elements seen so far.\n", - "\n", - "3. Whenever you add a new element to the stream using the `add` method, follow these steps:\n", - " - Add the new element to the min-heap.\n", - " - If the size of the min-heap exceeds `k`, remove the smallest element from the min-heap. This ensures that you always have the k largest elements in the min-heap.\n", - " - The smallest element in the min-heap (the root) will always represent the kth largest element in the stream.\n", - "\n", - "Here's why this approach works efficiently:\n", - "\n", - "- By using a min-heap, you can quickly maintain the k largest elements, and finding the smallest element in the heap (the root) takes constant time.\n", - "\n", - "- When you add a new element, the min-heap's size is kept at most `k`, which ensures that you only track the k largest elements and discard the smaller ones.\n", - "\n", - "- The time complexity for adding an element is O(log k), which is very efficient compared to sorting the entire stream, which would be O(n log n).\n", - "\n", - "- This approach meets the constraints of the problem, including handling large streams and having a low time complexity for both initialization and adding elements.\n", - "\n", - "In summary, the min-heap approach efficiently tracks the kth largest element in the stream by maintaining a heap of the k largest elements seen so far, updating it as new elements are added. This approach provides a fast and scalable solution to the problem.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "import heapq\n", - "from typing import List # Import the List type from the typing module\n", - "\n", - "class KthLargest:\n", - "\n", - " def __init__(self, k: int, nums: List[int]):\n", - " # Initialize the KthLargest object with k and nums.\n", - " self.k = k\n", - " # Create a min-heap to store the k largest elements.\n", - " self.min_heap = []\n", - " # Populate the min-heap with the first k elements from nums.\n", - " for num in nums:\n", - " self.add(num)\n", - "\n", - " def add(self, val: int) -> int:\n", - " # Add val to the min-heap.\n", - " heapq.heappush(self.min_heap, val)\n", - " # If the size of the min-heap exceeds k, remove the smallest element.\n", - " if len(self.min_heap) > self.k:\n", - " heapq.heappop(self.min_heap)\n", - " # The root of the min-heap is the kth largest element.\n", - " return self.min_heap[0]" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "- We start by importing the necessary modules:\n", - " - `heapq`: This module provides functions to create and manipulate heaps.\n", - " - `List` from the `typing` module: This is used to specify the type of the `nums` parameter.\n", - "\n", - "- We define the `KthLargest` class:\n", - " - The `__init__` method initializes the object with the integer `k` and the list of integers `nums`.\n", - " - It also creates an empty min-heap called `self.min_heap` to store the k largest elements.\n", - " - It populates the min-heap with the first `k` elements from `nums` by calling the `add` method.\n", - "\n", - "- The `add` method:\n", - " - Adds the new integer `val` to the min-heap using `heapq.heappush`. This maintains the min-heap property.\n", - " - Checks if the size of the min-heap exceeds `k`. If it does, it removes the smallest element (the k+1th largest) using `heapq.heappop`.\n", - " - Finally, it returns the smallest element in the min-heap, which is always the kth largest element.\n", - "\n", - "Overall, this code implements a class that efficiently finds the kth largest element in a stream of integers by maintaining a min-heap of the k largest elements seen so far.\n" - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n", - "5\n", - "5\n", - "8\n", - "8\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "kthLargest = KthLargest(3, [4, 5, 8, 2])\n", - "print(kthLargest.add(3)) # Output: 4\n", - "print(kthLargest.add(5)) # Output: 5\n", - "print(kthLargest.add(10)) # Output: 5\n", - "print(kthLargest.add(9)) # Output: 8\n", - "print(kthLargest.add(4)) # Output: 8" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `KthLargest` class using the min-heap approach:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. `__init__` method:\n", - " - In the `__init__` method, you iterate over the first `k` elements in `nums` and add them to the min-heap. Each `heapq.heappush` operation takes O(log k) time.\n", - " - Therefore, the time complexity of the `__init__` method is O(k * log k).\n", - "\n", - "2. `add` method:\n", - " - In the `add` method, you perform the following operations:\n", - " - `heapq.heappush`: O(log k) to add the new element to the min-heap.\n", - " - If the size of the min-heap exceeds `k`, you perform `heapq.heappop`, which is also O(log k).\n", - " - Finally, you return the smallest element from the min-heap, which is O(1) because it's always the root.\n", - " - Overall, the time complexity of the `add` method is O(log k).\n", - "\n", - "3. Overall, if you make `n` calls to the `add` method, the total time complexity is O(n * log k), where `n` is the total number of elements added to the stream.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. The space complexity is determined by the space used to store the min-heap and the instance variables.\n", - "2. The min-heap stores at most `k` elements at any given time, so its space complexity is O(k).\n", - "3. The instance variables (such as `self.k` and `self.min_heap`) have constant space requirements.\n", - "4. Therefore, the overall space complexity of the `KthLargest` class is O(k).\n", - "\n", - "In summary, the time complexity of the `KthLargest` class is O(n * log k) for `n` add operations, and the space complexity is O(k), where `k` is the parameter passed during initialization. This implementation efficiently maintains the kth largest element in the stream while meeting the problem's constraints." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Dynamic k:** Modify the `KthLargest` class to support dynamic changes in the value of `k`. Implement a method `update_k` that allows changing the value of `k` during the lifetime of the object. Ensure that the object can still correctly find the kth largest element based on the updated value of `k`.\n", - "\n", - "\n", - "2. **Implement kth Smallest:** Create a new class called `KthSmallest` that finds the kth smallest element in a stream instead of the kth largest. You may need to modify the data structure used in the implementation." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/09. Heap - Priority Queue/README.md b/_build/html/_sources/09. Heap - Priority Queue/README.md deleted file mode 100644 index 2eac70c..0000000 --- a/_build/html/_sources/09. Heap - Priority Queue/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# Heap / Priority Queue Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [703. Kth Largest Element in a Stream](https://leetcode.com/problems/kth-largest-element-in-a-stream/) | Easy | -| [1046. Last Stone Weight](https://leetcode.com/problems/last-stone-weight/) | Easy | -| [295. Find Median From Data Stream](https://leetcode.com/problems/find-median-from-data-stream/) | Hard | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! diff --git a/_build/html/_sources/10. Backtracking/39. Combination Sum.ipynb b/_build/html/_sources/10. Backtracking/39. Combination Sum.ipynb deleted file mode 100644 index 228a62e..0000000 --- a/_build/html/_sources/10. Backtracking/39. Combination Sum.ipynb +++ /dev/null @@ -1,282 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 39. Combination Sum\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Combination Sum problem on LeetCode, click here!](https://leetcode.com/problems/combination-sum/)\n", - "\n", - "---\n", - "Given an array of **distinct** integers `candidates` and a target integer `target`, return *a list of all **unique combinations** of `candidates` where the chosen numbers sum to the `target`*. You may return the combinations in **any order**. \n", - "\n", - "The **same** number may be chosen from `candidates` an **unlimited number** of times. Two combinations are unique if the **frequency** of at least one of the chosen numbers is different.\n", - "\n", - "The test cases are generated such that the number of unique combinations that sum up to `target` is less than `150` combinations for the given input.\n", - "\n", - "**Constraints:**\n", - "- `1 <= candidates.length <= 30`\n", - "- `2 <= candidates[i] <= 40`\n", - "- All elements of `candidates` are **distinct**.\n", - "- `1 <= target <= 40`" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is to find all unique combinations of numbers from a given array (candidates) such that their sum equals a target number. Here are the details of the problem:\n", - "\n", - "- You are given an array of distinct integers called \"candidates.\"\n", - "- You are also given a target integer called \"target.\"\n", - "\n", - "The goal is to find all unique combinations of numbers from the candidates array where the sum of the selected numbers is equal to the target. You can use the same number from the candidates array an unlimited number of times. A combination is considered unique if it has a different frequency (i.e., a different number of occurrences) of at least one chosen number compared to other combinations.\n", - "\n", - "For example:\n", - "\n", - "**Example 1:**\n", - "```python\n", - "Input: candidates = [2, 3, 6, 7], target = 7\n", - "Output: [[2, 2, 3], [7]]\n", - "```\n", - "In this example, there are two unique combinations that sum up to the target:\n", - "- 2 + 2 + 3 = 7\n", - "- 7 = 7\n", - "\n", - "**Example 2:**\n", - "```python\n", - "Input: candidates = [2, 3, 5], target = 8\n", - "Output: [[2, 2, 2, 2], [2, 3, 3], [3, 5]]\n", - "```\n", - "Here, there are three unique combinations that sum up to the target.\n", - "\n", - "**Example 3:**\n", - "```python\n", - "Input: candidates = [2], target = 1\n", - "Output: []\n", - "```\n", - "In this case, there are no combinations that can be formed from the candidates to reach the target of 1, so the output is an empty list.\n", - "\n", - "The problem asks you to find and return these combinations in any order.\n", - "\n", - "The constraints for this problem include the length of the candidates array, the values of candidates, and the target value.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def combinationSum(candidates, target):\n", - " # Define a recursive DFS function to find combinations\n", - " def dfs(remaining, start, path):\n", - " # If the remaining target is 0, we found a valid combination\n", - " if remaining == 0:\n", - " result.append(path)\n", - " return\n", - " # If the remaining target is negative, this path is invalid\n", - " if remaining < 0:\n", - " return\n", - " # Iterate through candidates starting from 'start' to avoid duplicates\n", - " for i in range(start, len(candidates)):\n", - " # Explore the current candidate by subtracting it from the remaining target\n", - " # Add the current candidate to the path\n", - " dfs(remaining - candidates[i], i, path + [candidates[i]])\n", - "\n", - " result = [] # Initialize an empty list to store the result\n", - " candidates.sort() # Sort the candidates for deduplication and early stopping\n", - " dfs(target, 0, []) # Start the DFS from the target value with an empty path\n", - " return result # Return the list of unique combinations" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The `combinationSum` function takes an array of distinct integers `candidates` and a target integer `target`. It returns a list of all unique combinations of `candidates` where the chosen numbers sum to the `target`. Each number in the `candidates` array can be used an unlimited number of times.\n", - "\n", - "Here's an overview of how the code works:\n", - "\n", - "1. The `combinationSum` function is defined, and it takes two arguments: `candidates` and `target`.\n", - "\n", - "2. Inside the function, there is a nested helper function called `backtrack`. This function is responsible for the actual combination generation using a recursive approach.\n", - "\n", - "3. The `backtrack` function is called with three arguments: `start`, `target`, and `path`. The `start` variable helps keep track of the current index in the `candidates` array, `target` keeps track of the remaining sum to be achieved, and `path` is a list that stores the current combination.\n", - "\n", - "4. Within the `backtrack` function, there are three main conditional statements:\n", - " - If `target` becomes zero, it means we have found a combination that sums up to the target, so we add `path` to the `result` list.\n", - " - If `target` becomes negative, it means the current combination doesn't work, so we return without doing anything.\n", - " - Otherwise, we enter a loop that iterates over the `candidates` array, starting from the current index `start`.\n", - "\n", - "5. In the loop, the `backtrack` function is called recursively with the updated `target` and `path` after including the current candidate. This process explores different combinations by considering the current candidate or moving to the next candidate.\n", - "\n", - "6. After the loop completes, the `result` list contains all unique combinations that sum to the target.\n", - "\n", - "7. The `candidates` array is sorted to optimize the search. Sorting helps in avoiding unnecessary recursive branches and reduces the number of explored combinations.\n", - "\n", - "8. Finally, the `backtrack` function is initially called from the `combinationSum` function with `start` set to 0, `target` set to the original target value, and an empty `path`. The result is returned as a list of unique combinations.\n", - "\n", - "The code includes a few example cases to demonstrate how the function works with different inputs." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[2, 2, 3], [7]]\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example 1\n", - "candidates1 = [2, 3, 6, 7]\n", - "target1 = 7\n", - "print(combinationSum(candidates1, target1)) # Output: [[2, 2, 3], [7]]" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[2, 2, 2, 2], [2, 3, 3], [3, 5]]\n" - ] - } - ], - "source": [ - "# Example 2\n", - "candidates2 = [2, 3, 5]\n", - "target2 = 8\n", - "print(combinationSum(candidates2, target2)) # Output: [[2, 2, 2, 2], [2, 3, 3], [3, 5]]" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "b5fca8ab-8c98-45b1-b44b-0503309121c9", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[]\n" - ] - } - ], - "source": [ - "# Example 3\n", - "candidates3 = [2]\n", - "target3 = 1\n", - "print(combinationSum(candidates3, target3)) # Output: []" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `combinationSum` function.\n", - "\n", - "**Time Complexity:**\n", - "The time complexity of this function is influenced by the number of recursive calls made by the `backtrack` function and the amount of work done within each call. In the worst case, the function will explore all possible combinations.\n", - "\n", - "The worst-case scenario occurs when we have many combinations to reach the target. The time complexity can be expressed as $O(2^n)$, where 'n' is the maximum number of recursive calls. In this context, 'n' corresponds to the number of elements in the `candidates` list, and it may be up to 30 (as per the constraints). However, the actual number of combinations explored is generally much smaller because we eliminate branches when the target becomes negative, and we skip over candidates that cannot lead to a solution. The sorting step also helps to optimize the search.\n", - "\n", - "**Space Complexity:**\n", - "The space complexity is determined by the auxiliary space used for storing the results and the stack space for the recursive calls.\n", - "\n", - "1. The space required for the `result` list can be up to $O(2^n)$ in the worst case because each combination is stored.\n", - "\n", - "2. The stack space for the recursive calls can also be up to O(n) in the worst case, where 'n' is the number of elements in the `candidates` list.\n", - "\n", - "Therefore, the overall space complexity of the function is $O(2^n + n)$. However, in practice, the space used for the results list is often the dominant factor, and the actual space used may be much smaller than 2^n because not all combinations are explored.\n", - "\n", - "In summary, the time complexity is exponential but typically smaller in practice due to optimization, and the space complexity is influenced by the number of results and the depth of the recursion." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Find the Number of Unique Combinations:** Instead of listing all unique combinations, modify the function to return the count of unique combinations that sum to the target.\n", - "\n", - "2. **Combinations with a Maximum Value:** Add a maximum value constraint for each combination, so they cannot exceed a certain value. Modify the code to find combinations respecting this constraint." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/10. Backtracking/79. Word Search.ipynb b/_build/html/_sources/10. Backtracking/79. Word Search.ipynb deleted file mode 100644 index cee509b..0000000 --- a/_build/html/_sources/10. Backtracking/79. Word Search.ipynb +++ /dev/null @@ -1,298 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 79. Word Search\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Word Search problem on LeetCode, click here!](https://leetcode.com/problems/word-search/)\n", - "\n", - "---\n", - "Given an `m x n` grid of characters `board` and a string `word`, return *`true` if `word` exists in the grid.*\n", - "\n", - "The word can be constructed from letters of sequentially adjacent cells, where adjacent cells are horizontally or vertically neighboring. The same letter cell may not be used more than once.\n", - "\n", - "**Constraints:**\n", - "- `m == board.length`\n", - "- `n = board[i].length`\n", - "- `1 <= m, n <= 6`\n", - "- `1 <= word.length <= 15`\n", - "- `board` and `word` consists of only lowercase and uppercase English letters.\n", - "\n", - "**Follow up:** Could you use search pruning to make your solution faster with a larger `board`?" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is to determine whether a given word can be constructed from characters in an `m x n` grid of characters. The word can be formed by moving sequentially through horizontally or vertically neighboring cells in the grid, and you cannot use the same cell more than once.\n", - "\n", - "Here are the specifics of the problem:\n", - "\n", - "- You are given an `m x n` grid, which is a 2D board of characters.\n", - "- You are also given a string `word` consisting of lowercase and uppercase English letters.\n", - "- Your task is to determine if the word can be found in the grid by moving from one cell to an adjacent cell (horizontally or vertically) and collecting the characters sequentially to form the word.\n", - "- You can't use the same cell more than once when forming the word.\n", - "- If it's possible to form the word in the grid, return `True`; otherwise, return `False`.\n", - "\n", - "For example, consider the following grid and word:\n", - "\n", - "```python\n", - "board = [[\"A\", \"B\", \"C\", \"E\"],\n", - " [\"S\", \"F\", \"C\", \"S\"],\n", - " [\"A\", \"D\", \"E\", \"E\"]] \n", - "word = \"ABCCED\"\n", - "```\n", - "\n", - "In this case, the word \"ABCCED\" can be formed by moving through the cells (0,0) -> (0,1) -> (0,2) -> (1,2) -> (2,2) -> (2,3) in the grid. Therefore, the function should return `True`.\n", - "\n", - "Conversely, if the word is impossible to construct, such as in the case of the word \"ABCB\" for the same grid, where there's no valid path that forms the word, the function should return `False`.\n", - "\n", - "The problem involves searching for a path through the grid that matches the characters in the word while respecting the constraints mentioned. It can be solved using depth-first search (DFS) or backtracking.\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "from typing import List\n", - "\n", - "class Solution:\n", - " def exist(self, board: List[List[str]], word: str) -> bool:\n", - " def dfs(i, j, k):\n", - " # Check if the current position is out of bounds or doesn't match the character in the word.\n", - " if not (0 <= i < len(board)) or not (0 <= j < len(board[0])) or board[i][j] != word[k]:\n", - " return False\n", - " \n", - " # If we have matched all characters in the word, return True.\n", - " if k == len(word) - 1:\n", - " return True\n", - "\n", - " # Temporarily mark the current cell to prevent revisiting.\n", - " tmp, board[i][j] = board[i][j], \"/\"\n", - "\n", - " # Explore adjacent cells by making recursive calls in all four directions.\n", - " found = dfs(i + 1, j, k + 1) or dfs(i - 1, j, k + 1) or dfs(i, j + 1, k + 1) or dfs(i, j - 1, k + 1)\n", - "\n", - " # Restore the original character in the cell.\n", - " board[i][j] = tmp\n", - "\n", - " return found\n", - "\n", - " # Iterate through all cells in the board.\n", - " for i in range(len(board)):\n", - " for j in range(len(board[0])):\n", - " # Check if the 'dfs' function starting from this cell returns True.\n", - " if dfs(i, j, 0):\n", - " return True\n", - "\n", - " # If no match is found after exploring all cells, return False.\n", - " return False" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. Import the necessary module:\n", - " - `from typing import List`: This line imports the `List` type from the `typing` module, which is used to specify the type of the `board` parameter in the method signature.\n", - "\n", - "2. Define the `Solution` class:\n", - " - `class Solution:`: This line defines a class called `Solution` to encapsulate the solution for the word search problem.\n", - "\n", - "3. Define the `exist` method:\n", - " - `def exist(self, board: List[List[str]], word: str) -> bool:`: This method is a member of the `Solution` class and takes two parameters: `board`, which is a 2D list of characters, and `word`, which is a string. It returns a boolean value, indicating whether the word exists in the board.\n", - "\n", - "4. Implement the inner `dfs` function:\n", - " - `def dfs(i, j, k):`: This is a helper function used for depth-first search (DFS). It is called recursively to explore the board and search for the word. It takes three parameters: `i` and `j` representing the current position on the board, and `k` representing the current index in the `word` string.\n", - "\n", - " - Inside `dfs`, it checks if the current position is out of bounds or if the character at the current position on the board does not match the character at the current index in the `word`. If either of these conditions is met, it returns `False`.\n", - "\n", - " - If `k` is equal to the length of the `word` minus one, it means we have successfully matched all characters in the `word`, so it returns `True`.\n", - "\n", - " - The function then temporarily replaces the character at the current position with a marker, \"/\", to prevent revisiting the same cell. It then explores adjacent cells by making recursive calls in all four directions: up, down, left, and right. If any of these recursive calls return `True`, it propagates the `True` result up the call stack. After the exploration is complete, it restores the original character in the cell.\n", - "\n", - "5. Iterate through the board:\n", - " - The outer loop iterates through all cells in the `board` using two nested loops. For each cell, it checks if the `dfs` function starting from that cell (with `k` initially set to 0) returns `True`. If it does, it means the word exists, so the method returns `True`.\n", - "\n", - "6. Return `False`:\n", - " - If the loop completes without finding the word in the board, the method returns `False`.\n", - "\n", - "To use this code, you can create an instance of the `Solution` class and call the `exist` method on that instance, passing the `board` and the `word` as arguments to check if the word exists in the board." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Create an instance of the Solution class\n", - "solution = Solution()\n", - "\n", - "# Test case 1: Word \"ABCCED\" can be found in the grid\n", - "board1 = [[\"A\",\"B\",\"C\",\"E\"],\n", - " [\"S\",\"F\",\"C\",\"S\"],\n", - " [\"A\",\"D\",\"E\",\"E\"]]\n", - "word1 = \"ABCCED\"\n", - "print(solution.exist(board1, word1)) # Expected output: True" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 2\n", - "\n", - "# Test case 2: Word \"SEE\" can be found in the grid\n", - "word2 = \"SEE\"\n", - "print(solution.exist(board1, word2)) # Expected output: True" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "b5fca8ab-8c98-45b1-b44b-0503309121c9", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 3\n", - "\n", - "# Test case 3: Word \"ABCB\" cannot be found in the grid\n", - "word3 = \"ABCB\"\n", - "print(solution.exist(board1, word3)) # Expected output: False" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `exist` method in the given code.\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The primary work in this code is done by the `dfs` function, which performs a depth-first search through the grid. The time complexity of the `dfs` function is $O(4^(n))$, where \"n\" is the length of the `word`. This is because, in the worst case, the function explores all possible directions (up, down, left, right) for each character in the `word`.\n", - "\n", - "The outer loops iterate through all cells in the `board`, which has dimensions `m x n`. So, the total number of iterations of `dfs` is O(m * n). However, since the `dfs` function has a higher time complexity, the overall time complexity is still dominated by the `dfs` function.\n", - "\n", - "Therefore, the overall time complexity of the `exist` method is $O(m * n * 4^n)$, where \"m\" and \"n\" are the dimensions of the board, and \"n\" is the length of the word.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. The primary space usage comes from the recursive calls in the `dfs` function. The depth of the recursion can be at most equal to the length of the `word`, which is O(n).\n", - "\n", - "2. Additionally, the `tmp` variable and the recursive calls on the call stack consume a small amount of additional memory.\n", - "\n", - "3. The marking of visited cells with the \"/\" character temporarily modifies the `board` in-place but doesn't significantly contribute to the space complexity.\n", - "\n", - "Therefore, the overall space complexity is O(n) due to the recursive call stack.\n", - "\n", - "In summary, the time complexity is $O(m * n * 4^n)$, and the space complexity is O(n), where \"m\" and \"n\" are the dimensions of the board, and \"n\" is the length of the word. The time complexity is exponential in the worst case due to the depth-first search through all possible paths in the grid." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Optimization Challenge:** Modify the code to find all unique words that can be constructed from the grid. Instead of returning `True` or `False`, return a list of words found. Ensure that the same cell is not used more than once in constructing each word.\n", - "\n", - "2. **Board Generation:** Create a function to generate random grids of characters and then use the `exist` method to solve them. Test the efficiency and correctness of your code by generating larger boards and words." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/10. Backtracking/README.md b/_build/html/_sources/10. Backtracking/README.md deleted file mode 100644 index 0d1ea13..0000000 --- a/_build/html/_sources/10. Backtracking/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Backtracking Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [39. Combination Sum](https://leetcode.com/problems/combination-sum/) | Medium | -| [79. Word Search](https://leetcode.com/problems/word-search/) | Medium | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! \ No newline at end of file diff --git a/_build/html/_sources/11. Graphs/133. Clone Graph.ipynb b/_build/html/_sources/11. Graphs/133. Clone Graph.ipynb deleted file mode 100644 index 07351b6..0000000 --- a/_build/html/_sources/11. Graphs/133. Clone Graph.ipynb +++ /dev/null @@ -1,317 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 133. Clone Graph\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Clone Graph problem on LeetCode, click here!](https://leetcode.com/problems/clone-graph/)\n", - "\n", - "---\n", - "Given a reference of a node in a **connected** undirected graph.\n", - "\n", - "Return a **deep copy** (clone) of the graph.\n", - "\n", - "Each node in the graph contains a value (`int`) and a list (`List[Node]`) of its neighbors.\n", - "\n", - "```\n", - "class Node {\n", - " public int val;\n", - " public List neighbors;\n", - "}\n", - "```\n", - "\n", - "**Test case format:**\n", - "\n", - "For simplicity, each node's value is the same as the node's index (1-indexed). For example, the first node with `val == 1`, the second node with `val == 2`, and so on. The graph is represented in the test case using an adjacency list.\n", - "\n", - "**An adjacency list** is a collection of unordered **lists** used to represent a finite graph. Each list describes the set of neighbors of a node in the graph.\n", - "\n", - "The given node will always be the first node with `val = 1`. You must return the **copy of the given node** as a reference to the cloned graph.\n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the graph is in the range `[0, 100]`.\n", - "- `1 <= Node.val <= 100`\n", - "- `Node.val` is unique for each node.\n", - "- There are no repeated edges and no self-loops in the graph.\n", - "- The Graph is connected and all nodes can be visited starting from the given node." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem at hand is to clone a connected undirected graph, which means we need to create a deep copy of the original graph while preserving its structure and relationships between nodes. The graph is represented using adjacency lists, where each node has a value (an integer) and a list of its neighbors.\n", - "\n", - "Here are the key aspects of the problem:\n", - "\n", - "1. **Input**: You are given a reference to one of the nodes in the original graph. This reference node serves as the entry point to the graph. The entire graph can be explored starting from this node.\n", - "\n", - "2. **Output**: The goal is to create a deep copy of the graph and return a reference to the cloned graph. The cloned graph should have the same structure and relationships as the original one but should be a separate instance in memory.\n", - "\n", - "3. **Graph Structure**: The graph is composed of nodes (vertices) and edges. Nodes have values (integers) and are connected to other nodes through edges (undirected connections). Each node has a list of neighbors, which are other nodes it is connected to.\n", - "\n", - "4. **Connected Graph**: The problem assumes that the graph is connected, meaning that you can start from the reference node provided and traverse the entire graph by following the edges. This ensures that there are no isolated components in the graph.\n", - "\n", - "To solve this problem, you typically need to perform a graph traversal (e.g., depth-first search or breadth-first search) to visit all the nodes in the original graph, create corresponding nodes in the clone, and establish the same connections between nodes in the cloned graph as in the original one. To avoid duplication of nodes, you also need to keep track of visited nodes to ensure that the cloning process is efficient and that nodes are not duplicated in the clone.\n", - "\n", - "The problem can be challenging because you need to create a deep copy of the graph while handling cyclic dependencies between nodes and ensuring that the structure and relationships of the original graph are preserved in the clone. The solution requires recursion or a data structure to maintain the mapping between original nodes and their clones to achieve an efficient and accurate cloning process.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for a Node.\n", - "class Node:\n", - " def __init__(self, val=0, neighbors=None):\n", - " self.val = val\n", - " self.neighbors = neighbors if neighbors is not None else []\n", - "\n", - "class Solution:\n", - " def cloneGraph(self, node: 'Node') -> 'Node':\n", - " if not node:\n", - " return None\n", - "\n", - " visited = {} # Dictionary to keep track of visited nodes\n", - "\n", - " def dfs(original_node):\n", - " if original_node in visited:\n", - " return visited[original_node]\n", - "\n", - " # Create a copy of the original node\n", - " copy_node = Node(original_node.val)\n", - " visited[original_node] = copy_node\n", - "\n", - " # Recursively clone the neighbors of the original node\n", - " for neighbor in original_node.neighbors:\n", - " copy_node.neighbors.append(dfs(neighbor))\n", - "\n", - " return copy_node\n", - "\n", - " return dfs(node)" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The given code defines a Python class, `Node`, and a solution class, `Solution`, to clone a connected undirected graph represented by nodes and their neighbors. Here's an explanation of the code:\n", - "\n", - "1. The `Node` class defines a node in the graph. Each node has a value (`val`) which is an integer and a list of neighbors (`neighbors`) that are other nodes in the graph.\n", - "\n", - "2. The `Solution` class contains the method `cloneGraph`, which takes a reference to the first node of the graph (`node`) as input and returns a deep copy of the entire graph, preserving the structure and relationships between nodes.\n", - "\n", - "3. Inside the `cloneGraph` method:\n", - " - It first checks if the input `node` is `None`. If it's `None`, it means there is no graph to clone, and the method returns `None`.\n", - "\n", - " - It initializes a `visited` dictionary to keep track of visited nodes. This dictionary is used to ensure that each node is cloned only once to avoid duplication.\n", - "\n", - " - The `dfs` (depth-first search) function is defined within the `cloneGraph` method. It takes an original node as input and returns its corresponding clone. This function performs the actual cloning of the graph.\n", - "\n", - " - Inside the `dfs` function:\n", - " - It checks if the original node has been visited before by looking it up in the `visited` dictionary. If it has been visited, it returns the corresponding clone from the `visited` dictionary.\n", - "\n", - " - If the original node is not visited, it creates a new node, `copy_node`, with the same value as the original node. This is the first step in creating the clone of the original node.\n", - "\n", - " - It then recursively clones the neighbors of the original node by iterating through the `neighbors` list of the original node and appending the corresponding cloned neighbors to the `neighbors` list of the `copy_node`. This step ensures that the relationships between nodes are preserved in the clone.\n", - "\n", - " - The `copy_node` is added to the `visited` dictionary with the original node as the key and the clone as the value.\n", - "\n", - " - Finally, the `copy_node` is returned as the result of the DFS for the original node.\n", - "\n", - "4. The `cloneGraph` method returns the result of the DFS on the input `node`, which is the clone of the entire graph with its structure and relationships intact.\n", - "\n", - "In summary, the code uses depth-first search (DFS) to traverse the original graph, creating a clone for each node and its neighbors. It ensures that each node is cloned only once to avoid duplication and returns a reference to the cloned graph." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "f12c5a63-b811-4be7-83c2-34ee396b546c", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[1, 2, 4]]\n" - ] - } - ], - "source": [ - "def get_adjacency_list(node):\n", - " visited = {} # Dictionary to keep track of visited nodes\n", - "\n", - " def dfs(node):\n", - " if not node:\n", - " return []\n", - "\n", - " if node in visited:\n", - " return visited[node]\n", - "\n", - " neighbors = [n.val for n in node.neighbors]\n", - " visited[node] = neighbors\n", - "\n", - " for neighbor in node.neighbors:\n", - " dfs(neighbor)\n", - "\n", - " dfs(node)\n", - " result = []\n", - "\n", - " def get_node_and_neighbors(node):\n", - " result.append([node.val] + visited[node])\n", - "\n", - " get_node_and_neighbors(node)\n", - " return result\n", - "\n", - "\n", - "# Testing the code with the provided examples\n", - "adjList1 = [[2, 4], [1, 3], [2, 4], [1, 3]]\n", - "solution = Solution()\n", - "\n", - "# Create the graph from adjList\n", - "nodes = [Node(i) for i in range(1, len(adjList1) + 1)]\n", - "for i, adj in enumerate(adjList1):\n", - " nodes[i].neighbors = [nodes[j - 1] for j in adj]\n", - "\n", - "# Clone the graph and get its adjacency list\n", - "cloned_node1 = solution.cloneGraph(nodes[0])\n", - "cloned_adjList1 = get_adjacency_list(cloned_node1)\n", - "\n", - "# Print the cloned graph as an adjacency list\n", - "print(cloned_adjList1)\n", - "\n", - "# Output should match adjList1\n" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[1]]\n" - ] - } - ], - "source": [ - "# Example 2\n", - "# Input: adjList = [[]]\n", - "\n", - "adjList2 = [[]]\n", - "solution = Solution()\n", - "\n", - "# Create the graph from adjList\n", - "node1 = Node(1)\n", - "\n", - "# Clone the graph and get its adjacency list\n", - "cloned_node1 = solution.cloneGraph(node1)\n", - "cloned_adjList2 = get_adjacency_list(cloned_node1)\n", - "\n", - "# Print the cloned graph as an adjacency list\n", - "print(cloned_adjList2)\n", - "\n", - "# Output should be [[]], which represents an empty graph" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code for cloning a graph using depth-first search (DFS).\n", - "\n", - "Time Complexity:\n", - "1. Creating the graph: The time complexity to create the original graph from `adjList` is O(V + E), where V is the number of vertices (nodes) and E is the number of edges. We iterate through each node and its neighbors in `adjList`.\n", - "\n", - "2. Cloning the graph (DFS): The depth-first search (DFS) is used to traverse the original graph and create a clone. The time complexity of DFS is O(V + E), as we visit each node and each edge once.\n", - "\n", - "Overall, the time complexity is O(V + E) for both creating the original graph and cloning it.\n", - "\n", - "Space Complexity:\n", - "1. Storage for the original graph: We need to store the original graph, which includes all nodes and their adjacency lists. In the worst case, this requires O(V + E) space, where V is the number of nodes, and E is the number of edges.\n", - "\n", - "2. Storage for the visited dictionary: The `visited` dictionary stores mappings from original nodes to their corresponding clones. In the worst case, this requires O(V) space because each node is visited once.\n", - "\n", - "3. Recursive stack for DFS: The space used for the recursive call stack during DFS can be up to O(V) in the worst case, where V is the number of nodes.\n", - "\n", - "Overall, the space complexity is O(V + E) for storing the original graph, and O(V) for auxiliary data structures, including the `visited` dictionary and the DFS call stack. Therefore, the overall space complexity is O(V + E).\n", - "\n", - "In summary, the time and space complexities of the provided code for cloning a graph are both O(V + E), where V is the number of nodes, and E is the number of edges in the graph." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Cyclic Graph**: Design a graph with cycles (nodes connected in a cycle). Test if the code can correctly clone graphs with cycles and doesn't fall into an infinite loop during traversal.\n", - "\n", - "\n", - "2. **Partial Graph Cloning**: Modify the code to clone only a subset of the graph starting from a given reference node, rather than the entire graph. Implement this as an extension to the problem." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/11. Graphs/178. Graph Valid Tree.ipynb b/_build/html/_sources/11. Graphs/178. Graph Valid Tree.ipynb deleted file mode 100644 index e0235d6..0000000 --- a/_build/html/_sources/11. Graphs/178. Graph Valid Tree.ipynb +++ /dev/null @@ -1,248 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 178. Graph Valid Tree\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Graph Valid Tree problem on LintCode, click here!](https://www.lintcode.com/problem/178/)\n", - "\n", - "---\n", - "Given `n` nodes labeled from `0` to `n - 1` and a list of `undirected` edges (each edge is a pair of nodes), write a function to check whether these edges make up a valid tree.\n", - "\n", - "**Constraints:**\n", - "- You can assume that no duplicate edges will appear in edges. Since all edges are `undirected`, `[0, 1]` is the same as `[1, 0]` and thus will not appear together in edges." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is to determine whether a given set of undirected edges can form a valid tree. In this context, a \"tree\" is a specific type of graph with the following properties:\n", - "\n", - "1. It is a connected graph, meaning there is a path between any pair of nodes in the graph.\n", - "2. It has no cycles, which means there are no closed loops or circuits in the graph.\n", - "3. It has exactly `n - 1` edges, where `n` is the number of nodes in the tree.\n", - "\n", - "The problem is typically given with two pieces of information:\n", - "\n", - "1. The number of nodes (`n`), which are usually labeled from 0 to `n-1`.\n", - "2. A list of undirected edges, where each edge is represented as a pair of nodes.\n", - "\n", - "The task is to write a function or algorithm to determine whether the provided set of edges can be arranged to form a valid tree based on the properties mentioned above.\n", - "\n", - "To solve this problem, you need to check the following conditions:\n", - "\n", - "1. There should be exactly `n - 1` edges to ensure that the graph is connected and tree-like.\n", - "2. There should be no cycles in the graph. If there are any cycles, the set of edges cannot form a tree.\n", - "3. The graph should be connected, which means you can reach any node from any other node through a series of edges.\n", - "\n", - "The solution typically involves using graph traversal algorithms like Depth-First Search (DFS) or Breadth-First Search (BFS) to explore the graph and check these conditions. If all conditions are met, the given edges form a valid tree; otherwise, they do not.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def validTree(n, edges):\n", - " if len(edges) != n - 1:\n", - " return False # A tree with n nodes must have n-1 edges.\n", - "\n", - " # Create an adjacency list to represent the graph.\n", - " adj_list = {i: [] for i in range(n)}\n", - " for u, v in edges:\n", - " adj_list[u].append(v)\n", - " adj_list[v].append(u)\n", - "\n", - " visited = set()\n", - "\n", - " # Define a recursive DFS function.\n", - " def dfs(node, parent):\n", - " if node in visited:\n", - " return False # If we encounter a visited node, there's a cycle.\n", - " visited.add(node)\n", - "\n", - " for neighbor in adj_list[node]:\n", - " if neighbor != parent:\n", - " if not dfs(neighbor, node):\n", - " return False\n", - "\n", - " return True\n", - "\n", - " # Start DFS from any node (e.g., node 0).\n", - " if not dfs(0, -1):\n", - " return False # If there's a cycle, it's not a valid tree.\n", - "\n", - " return len(visited) == n" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The `validTree` function checks if a given set of undirected edges forms a valid tree. A valid tree must satisfy these conditions:\n", - "\n", - "1. It has exactly `n - 1` edges, where `n` is the number of nodes.\n", - "2. There are no cycles in the graph.\n", - "3. The graph is connected, meaning all nodes are reachable from any starting node.\n", - "\n", - "The code accomplishes this as follows:\n", - "\n", - "- It first checks if the number of edges is equal to `n - 1`. If not, it immediately returns `False` since a tree with `n` nodes must have `n - 1` edges to be connected.\n", - "\n", - "- It then constructs an adjacency list (`adj_list`) to represent the graph efficiently. This data structure stores the neighbors of each node.\n", - "\n", - "- The code uses a `visited` set to keep track of nodes visited during depth-first search (DFS).\n", - "\n", - "- The `dfs` function is a recursive function that checks for cycles in the graph. It does this by visiting nodes and marking them as visited. If it encounters a node that has already been visited (indicating a cycle), it returns `False`.\n", - "\n", - "- The DFS function explores the neighbors of each node, avoiding revisiting the parent node to prevent cycles.\n", - "\n", - "- After the DFS is complete, the code checks if the number of visited nodes is equal to `n`, ensuring the graph is connected.\n", - "\n", - "- Finally, if all conditions are met, the code returns `True`, indicating that the given edges form a valid tree. Otherwise, it returns `False`.\n", - "\n", - "The code provides examples to demonstrate how to use the `validTree` function to check whether a set of edges forms a valid tree or not." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1\n", - "n1 = 5\n", - "edges1 = [[0, 1], [0, 2], [0, 3], [1, 4]]\n", - "print(validTree(n1, edges1)) # Output: true" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 2\n", - "n2 = 5\n", - "edges2 = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]]\n", - "print(validTree(n2, edges2)) # Output: false" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexities of the `validTree` function:\n", - "\n", - "**Time Complexity:**\n", - "1. Constructing the adjacency list (`adj_list`) takes O(E) time, where E is the number of edges in the input graph (|edges|).\n", - "\n", - "2. The DFS function, when considering all nodes, has a time complexity of O(V + E), where V is the number of nodes in the graph. This is because, in the worst case, the DFS function visits each node and each edge once.\n", - "\n", - "3. Checking if the number of visited nodes is equal to `n` takes O(1) time.\n", - "\n", - "Overall, the time complexity of the `validTree` function is O(E + V) in the worst case.\n", - "\n", - "**Space Complexity:**\n", - "1. The adjacency list (`adj_list`) consumes additional space to store the graph structure, taking O(V + E) space. This is because it stores information about each node and its adjacent nodes.\n", - "\n", - "2. The `visited` set keeps track of visited nodes, and its space complexity is O(V) in the worst case, as there can be at most V unique nodes in the set.\n", - "\n", - "3. The depth of the function call stack during DFS can be at most V, which contributes O(V) space to the space complexity.\n", - "\n", - "Overall, the space complexity of the `validTree` function is O(V + E) due to the adjacency list and O(V) due to the `visited` set and DFS call stack.\n", - "\n", - "In summary, the time complexity is O(E + V), and the space complexity is O(V + E). These complexities are based on the worst-case scenario, where all nodes and edges are considered. In practical cases, the actual complexities may be smaller, depending on the specific structure of the graph." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Minimum Spanning Tree (MST)**: Implement an algorithm to find the minimum spanning tree of a connected graph using either Kruskal's or Prim's algorithm. Compare the MST to the original graph to determine if the original graph is a tree. This exercise reinforces the concept of tree properties.\n", - "\n", - "2. **Detecting Cycles**: Modify the code to not only check if the input forms a tree but also to identify and print out any cycles present in the graph if it's not a tree. This exercise enhances your ability to detect and visualize cycles in a graph." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/11. Graphs/200. Number of Islands.ipynb b/_build/html/_sources/11. Graphs/200. Number of Islands.ipynb deleted file mode 100644 index a8a7727..0000000 --- a/_build/html/_sources/11. Graphs/200. Number of Islands.ipynb +++ /dev/null @@ -1,242 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 200. Number of Islands\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Number of Islands problem on LeetCode, click here!](https://leetcode.com/problems/number-of-islands/)\n", - "\n", - "---\n", - "\n", - "Given an `m x n` 2D binary grid `grid` which represents a map of `'1'`s (land) and `'0'`s (water), return *the number of islands*. \n", - "\n", - "An **island** is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.\n", - "\n", - "**Constraints:**\n", - "- `m == grid.length`\n", - "- `n == grid[i].length`\n", - "- `1 <= m, n <= 300`\n", - "- `grid[i][j]` is `'0'` or `'1'`." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is about counting the number of islands in a 2D binary grid. In this grid, '1' represents land, and '0' represents water. An island is defined as a group of '1' cells that are adjacent to each other either horizontally or vertically. It's important to note that diagonal connections do not count. Additionally, it's assumed that all four edges of the grid are surrounded by water, meaning the grid is finite and doesn't \"wrap around.\"\n", - "\n", - "The objective is to determine how many distinct islands exist in the grid. To clarify, an island consists of connected '1' cells, and these connections can only occur horizontally or vertically. If there are no '1' cells in the grid, the number of islands would be zero.\n", - "\n", - "The problem often involves using graph traversal techniques like Depth-First Search (DFS) or Breadth-First Search (BFS) to identify and count these islands. You start at one '1' cell and explore its adjacent cells to determine the extent of the island. Once you've visited all the '1' cells in an island, you move on to the next unvisited '1' cell and repeat the process until you've counted all the islands in the grid.\n", - "\n", - "In essence, the problem asks you to analyze the grid to find groups of connected '1' cells and count them as individual islands. The goal is to return the total count of islands in the given grid.\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "from typing import List\n", - "\n", - "class Solution:\n", - " def numIslands(self, grid: List[List[str]]) -> int:\n", - " if not grid:\n", - " return 0\n", - "\n", - " m, n = len(grid), len(grid[0]) # Get the dimensions of the grid\n", - " num_islands = 0 # Initialize the count of islands\n", - "\n", - " def dfs(row, col):\n", - " if row < 0 or row >= m or col < 0 or col >= n or grid[row][col] == '0':\n", - " return\n", - "\n", - " grid[row][col] = '0' # Mark the current cell as visited by changing it to '0'\n", - " directions = [(1, 0), (-1, 0), (0, 1), (0, -1)] # Define four possible directions to move\n", - "\n", - " for dr, dc in directions:\n", - " # Explore adjacent cells\n", - " dfs(row + dr, col + dc)\n", - "\n", - " for i in range(m):\n", - " for j in range(n):\n", - " if grid[i][j] == '1':\n", - " num_islands += 1 # Increment the island count\n", - " dfs(i, j) # Start a DFS from the current '1' cell to explore the entire island\n", - "\n", - " return num_islands\n" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The provided code defines a Python class called `Solution` with a method called `numIslands`. This class is designed to count the number of islands in a 2D binary grid.\n", - "\n", - "The `numIslands` method takes a 2D grid as input, where '1' represents land, and '0' represents water. It uses a depth-first search (DFS) approach to identify and count islands. The key steps in the code include:\n", - "\n", - "1. Checking if the input grid is empty, and if so, returning 0 (indicating there are no islands).\n", - "\n", - "2. Determining the dimensions of the grid (number of rows and columns).\n", - "\n", - "3. Initializing a variable `num_islands` to keep track of the count of islands.\n", - "\n", - "4. Defining a nested function `dfs` to perform depth-first search. This function recursively explores adjacent land cells connected to the current cell and marks them as visited by changing '1' to '0'.\n", - "\n", - "5. In the `dfs` function, it checks for boundary conditions and whether the current cell is '0'. If these conditions are met, it returns without further exploration.\n", - "\n", - "6. The `dfs` function explores neighboring cells in all four directions (up, down, left, right) using a loop.\n", - "\n", - "7. The main loop iterates through each cell of the grid. When a '1' cell is encountered, it increments the `num_islands` count and starts a DFS from that cell to explore the entire island.\n", - "\n", - "8. Finally, the method returns the total count of islands found in the grid.\n", - "\n", - "This code encapsulates the solution in a class, allowing you to create an instance of the `Solution` class and call the `numIslands` method on it to count the number of islands in a given grid." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Example 1 Output: 1\n" - ] - } - ], - "source": [ - "grid1 = [\n", - " [\"1\", \"1\", \"1\", \"1\", \"0\"],\n", - " [\"1\", \"1\", \"0\", \"1\", \"0\"],\n", - " [\"1\", \"1\", \"0\", \"0\", \"0\"],\n", - " [\"0\", \"0\", \"0\", \"0\", \"0\"]\n", - "]\n", - "\n", - "solution = Solution()\n", - "result1 = solution.numIslands(grid1)\n", - "print(\"Example 1 Output:\", result1) # Expected output: 1\n" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Example 2 Output: 3\n" - ] - } - ], - "source": [ - "grid2 = [\n", - " [\"1\", \"1\", \"0\", \"0\", \"0\"],\n", - " [\"1\", \"1\", \"0\", \"0\", \"0\"],\n", - " [\"0\", \"0\", \"1\", \"0\", \"0\"],\n", - " [\"0\", \"0\", \"0\", \"1\", \"1\"]\n", - "]\n", - "\n", - "result2 = solution.numIslands(grid2)\n", - "print(\"Example 2 Output:\", result2) # Expected output: 3\n" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "Time Complexity:\n", - "- The code uses a depth-first search (DFS) to explore the grid and count the number of islands.\n", - "- In the worst case, it visits every cell in the grid exactly once.\n", - "- The DFS function explores neighboring cells in four directions (up, down, left, right), so it has a time complexity of $O(4^{max(m, n)})$, where m is the number of rows and n is the number of columns.\n", - "- Therefore, the overall time complexity of the code is O(m * n), where m is the number of rows, and n is the number of columns.\n", - "\n", - "Space Complexity:\n", - "- The space complexity is determined by the recursive calls and the depth of the DFS stack.\n", - "- In the worst case, when the entire grid consists of '1's, the depth of the DFS recursion can be as deep as max(m, n).\n", - "- Therefore, the space complexity of the code is O(max(m, n)), representing the maximum depth of the DFS stack.\n", - "\n", - "In practical terms, for reasonably sized grids, the time and space complexity is linear, and the code should perform well. However, it's important to keep in mind that the worst-case time complexity is O(m * n), and the space complexity can be O(max(m, n))." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Identify Largest Island:** In addition to counting the number of islands, modify the code to identify the largest island in the grid and return its size.\n", - "\n", - "2. **Optimize for Space:** Modify the solution to reduce its space complexity to O(1) without modifying the input grid. This is a more memory-efficient version of the problem." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/11. Graphs/207. Course Schedule.ipynb b/_build/html/_sources/11. Graphs/207. Course Schedule.ipynb deleted file mode 100644 index 37624f6..0000000 --- a/_build/html/_sources/11. Graphs/207. Course Schedule.ipynb +++ /dev/null @@ -1,249 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 207. Course Schedule\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Course Schedule problem on LeetCode, click here!](https://leetcode.com/problems/course-schedule/)\n", - "\n", - "---\n", - "There are a total of `numCourses` courses to take, labeled from 0 to `numCourses - 1`. You are given an array `prerequisites` where `prerequisites[i] = [ai, bi]` indicates that you **must** take course `bi` first if you want to take course `ai`. \n", - "\n", - "- For example, the pair `[0, 1]`, indicates that to take course `0` you have to first take course `1`.\n", - "\n", - "Return `true` if you can finish all courses. Otherwise, return `false`.\n", - "\n", - "**Constraints:**\n", - "- 1 <= `numCourses` <= 2000\n", - "- 0 <= `prerequisites.length` <= 5000\n", - "- `prerequisites[i].length` == 2\n", - "- 0 <= `ai`, `bi` < `numCourses`\n", - "- All the pairs `prerequisites[i]` are **unique**." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is to determine whether it's possible to complete a set of courses given a list of prerequisites. You are given the following:\n", - "\n", - "- `numCourses`: The total number of courses to be taken, labeled from 0 to `numCourses - 1`.\n", - "- `prerequisites`: A list of prerequisite courses, where each element `prerequisites[i]` is a pair `[ai, bi]`, indicating that you must take course `bi` before you can take course `ai`.\n", - "\n", - "The goal is to check whether it's possible to complete all the courses while respecting the prerequisite requirements. In other words, you need to determine if there are any circular dependencies in the course prerequisites that would prevent you from taking all the courses.\n", - "\n", - "For example:\n", - "\n", - "- If `numCourses` is 2, and `prerequisites` is `[[1, 0]]`, it means you have two courses, and you must finish course 0 before you can take course 1. In this case, it's possible to complete all courses, so the function should return `True`.\n", - "\n", - "- If `numCourses` is 2, and `prerequisites` is `[[1, 0], [0, 1]]`, it means you have two courses, but there's a circular dependency where course 1 requires course 0 and course 0 requires course 1. In this case, it's impossible to complete all courses, so the function should return `False`.\n", - "\n", - "The problem is essentially about checking for the presence of cycles in a directed graph, where the courses are nodes, and the prerequisites represent directed edges between them. If there are no cycles, it's possible to complete all courses; otherwise, it's not possible.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "from collections import defaultdict, deque\n", - "from typing import List\n", - "\n", - "class Solution:\n", - " def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:\n", - " # Create a graph using an adjacency list to represent the courses and their prerequisites.\n", - " graph = defaultdict(list) # Initialize an empty adjacency list.\n", - " in_degree = [0] * numCourses # Initialize an array to store in-degrees of courses.\n", - "\n", - " # Populate the graph and calculate in-degrees.\n", - " for course, prerequisite in prerequisites:\n", - " graph[prerequisite].append(course) # Add the course as a neighbor to its prerequisite.\n", - " in_degree[course] += 1 # Increment the in-degree of the course.\n", - "\n", - " # Initialize a queue with courses that have no prerequisites.\n", - " queue = deque()\n", - " for course in range(numCourses):\n", - " if in_degree[course] == 0:\n", - " queue.append(course)\n", - "\n", - " # Perform topological sorting.\n", - " while queue:\n", - " course = queue.popleft() # Take a course with no prerequisites.\n", - " numCourses -= 1 # Decrement the count of remaining courses.\n", - "\n", - " for neighbor in graph[course]:\n", - " in_degree[neighbor] -= 1 # Remove the prerequisite relationship.\n", - " if in_degree[neighbor] == 0:\n", - " queue.append(neighbor) # If no more prerequisites, add to the queue.\n", - "\n", - " # If all courses were successfully taken (numCourses becomes 0), return True.\n", - " return numCourses == 0" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "This Python code is designed to determine whether it is possible to complete all the required courses given a set of prerequisites. It uses a topological sorting algorithm to accomplish this. Here's a brief explanation of the code:\n", - "\n", - "1. The code defines a `Solution` class with a `canFinish` method that takes two parameters: `numCourses` (the total number of courses) and `prerequisites` (a list of pairs indicating which course must be taken before another).\n", - "\n", - "2. It initializes an empty graph as an adjacency list using a `defaultdict` to represent the courses and their prerequisites. It also initializes a list called `in_degree` to keep track of the in-degrees of courses, which is used in the topological sorting process.\n", - "\n", - "3. The code then populates the graph by iterating through the `prerequisites` list. For each pair `(ai, bi)`, it adds course `ai` as a neighbor to its prerequisite course `bi` in the graph and increments the in-degree of course `ai`.\n", - "\n", - "4. Next, it initializes a queue with courses that have no prerequisites. It does this by iterating through all the courses and adding those with an in-degree of 0 to the queue.\n", - "\n", - "5. The code performs a topological sorting of the courses using a while loop. In each iteration of the loop, it dequeues a course from the front of the queue (a course with no prerequisites).\n", - "\n", - "6. For each neighbor (course that depends on the dequeued course), it decrements the in-degree of the neighbor. If the neighbor's in-degree becomes 0, it means all of its prerequisites have been taken, so the neighbor is added to the queue.\n", - "\n", - "7. The loop continues until there are no more courses with no prerequisites to dequeue, and the in-degrees are updated accordingly.\n", - "\n", - "8. After the loop, if all courses were successfully taken (i.e., `numCourses` becomes 0), it means that there were no circular dependencies, and it's possible to finish all courses. In this case, the method returns `True`. Otherwise, if there are remaining courses (indicating a circular dependency), it returns `False`." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1\n", - "numCourses1 = 2\n", - "prerequisites1 = [[1, 0]]\n", - "sol = Solution()\n", - "print(sol.canFinish(numCourses1, prerequisites1)) # Output: True" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 2\n", - "numCourses2 = 2\n", - "prerequisites2 = [[1, 0], [0, 1]]\n", - "print(sol.canFinish(numCourses2, prerequisites2)) # Output: False" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `canFinish` method:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. Constructing the graph: In the first loop where we iterate through the `prerequisites` list, we populate the graph with prerequisites. This loop has a time complexity of O(E), where E is the number of prerequisites (edges).\n", - "\n", - "2. Initializing in-degrees and finding courses with no prerequisites: In the worst case, we iterate through all `numCourses` courses to initialize in-degrees and find the courses with no prerequisites. This has a time complexity of O(V), where V is the number of courses (vertices).\n", - "\n", - "3. Topological Sorting: In the while loop, we perform topological sorting, processing each course once and its outgoing edges. In the worst case, each course is processed once. This has a time complexity of O(V + E).\n", - "\n", - "The overall time complexity is O(V + E), where V is the number of courses, and E is the number of prerequisites.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. Graph Representation: The space complexity for storing the graph as an adjacency list is O(E), where E is the number of prerequisites.\n", - "\n", - "2. In-Degree Array: The space complexity for storing the in-degrees of courses is O(V), where V is the number of courses.\n", - "\n", - "3. Queue: The space complexity for the queue is O(V), as it may contain all the courses.\n", - "\n", - "The overall space complexity is O(V + E), where V is the number of courses, and E is the number of prerequisites.\n", - "\n", - "In most practical cases, the number of prerequisites (E) is much smaller than the number of courses (V), so the time and space complexity can often be considered as O(V)." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Optimizing Course Scheduling**: Given a list of courses with their durations and prerequisites, find the most efficient way to schedule these courses to minimize the time it takes to complete all of them.\n", - "\n", - "2. **Detecting Cycles in Course Dependencies**: Modify the original problem to not just determine if you can finish all courses but also to identify the specific courses that form a cycle in the prerequisite dependencies." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/11. Graphs/3651. Number of Connected Components in an Undirected Graph.ipynb b/_build/html/_sources/11. Graphs/3651. Number of Connected Components in an Undirected Graph.ipynb deleted file mode 100644 index fb186f2..0000000 --- a/_build/html/_sources/11. Graphs/3651. Number of Connected Components in an Undirected Graph.ipynb +++ /dev/null @@ -1,236 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 3651. Number of Connected Components in an Undirected Graph\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Number of Connected Components in an Undirected Graph problem on LintCode, click here!](https://www.lintcode.com/problem/3651/)\n", - "\n", - "---\n", - "In this problem, there is an undirected graph with `n` nodes. There is also an `edges` array. Where `edges[i] = [a, b]` means that there is an edge between *node a* and *node b* in the graph.\n", - "\n", - "You need to return *the number of connected components in that graph*." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem at hand is to determine the number of connected components in an undirected graph. Here's a more detailed explanation of the problem:\n", - "\n", - "- You are given an undirected graph, which consists of nodes and edges. The graph may have multiple distinct connected components.\n", - "\n", - "- A connected component is a group of nodes within the graph where each node can be reached from every other node in the same component. In other words, there is a path between any two nodes in the same connected component, but there are no paths connecting nodes from different components.\n", - "\n", - "- Your task is to write a function that takes as input the number of nodes `n` and a list of edges `edges`, where each edge is represented as a pair of nodes `[a, b]` indicating an edge between node `a` and node `b`.\n", - "\n", - "- The goal is to determine the number of distinct connected components in the graph.\n", - "\n", - "- You need to implement an algorithm that can identify these connected components and count how many there are in the given graph.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def countConnectedComponents(n, edges):\n", - " # Define a helper function for depth-first search (DFS).\n", - " def dfs(node):\n", - " if not visited[node]: # If the node has not been visited yet:\n", - " visited[node] = True # Mark it as visited.\n", - " for neighbor in graph[node]: # Explore all neighbors of the current node.\n", - " dfs(neighbor) # Recursively call DFS on the neighbor.\n", - "\n", - " # Create an empty adjacency list to represent the graph.\n", - " graph = [[] for _ in range(n)]\n", - "\n", - " # Initialize a boolean list to keep track of visited nodes.\n", - " visited = [False] * n\n", - "\n", - " # Populate the adjacency list with edges from the input.\n", - " for a, b in edges:\n", - " graph[a].append(b)\n", - " graph[b].append(a) # Since the graph is undirected, we add edges in both directions.\n", - "\n", - " # Initialize a counter to keep track of the number of connected components.\n", - " count = 0\n", - "\n", - " # Iterate through all nodes in the graph.\n", - " for i in range(n):\n", - " if not visited[i]: # If the node has not been visited:\n", - " count += 1 # Increment the count since we've found a new connected component.\n", - " dfs(i) # Start a depth-first search from the unvisited node to explore the component.\n", - "\n", - " return count" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The provided Python code calculates the number of connected components in an undirected graph. Here's a high-level explanation of how the code works:\n", - "\n", - "1. The `countConnectedComponents` function takes two arguments: `n` (the number of nodes in the graph) and `edges` (a list of edge pairs representing connections between nodes).\n", - "\n", - "2. Inside the function, there is a helper function called `dfs` (depth-first search), which is used to explore and mark nodes as visited.\n", - "\n", - "3. An empty adjacency list called `graph` is created to represent the graph. The `graph` is a list of lists where each element represents a node, and the list associated with each node contains its neighboring nodes.\n", - "\n", - "4. Another list called `visited` is created to keep track of visited nodes. Initially, all nodes are marked as not visited (`False`).\n", - "\n", - "5. The code populates the `graph` by iterating through the `edges` list and adding each edge to the adjacency list. Since the graph is undirected, both directions of each edge are added.\n", - "\n", - "6. A counter variable called `count` is initialized to keep track of the number of connected components.\n", - "\n", - "7. The code iterates through all nodes from `0` to `n-1`. For each node, it checks whether it has been visited yet. If it hasn't been visited, it means a new connected component is found. The counter `count` is incremented, and a depth-first search (DFS) is initiated from this unvisited node to explore the connected component.\n", - "\n", - "8. The `dfs` function recursively visits all nodes in the connected component, marking them as visited. It does this by checking each neighbor of the current node and recursively calling `dfs` on unvisited neighbors.\n", - "\n", - "9. After the loop through all nodes, the `count` variable contains the total number of connected components in the graph.\n", - "\n", - "10. The function returns the value of `count`, which represents the number of connected components.\n", - "\n", - "11. Two examples are provided at the end to demonstrate how to use the function with different inputs." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n" - ] - } - ], - "source": [ - "# Example 1\n", - "n1 = 3\n", - "edges1 = [[0, 1], [0, 2]]\n", - "print(countConnectedComponents(n1, edges1)) # Output: 1" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2\n" - ] - } - ], - "source": [ - "# Example 2\n", - "n2 = 6\n", - "edges2 = [[0, 1], [1, 2], [2, 3], [4, 5]]\n", - "print(countConnectedComponents(n2, edges2)) # Output: 2" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the code for counting the number of connected components in an undirected graph using depth-first search (DFS).\n", - "\n", - "**Time Complexity:**\n", - "- The code iterates through all nodes in the graph (from 0 to `n-1`).\n", - "- For each unvisited node, it initiates a depth-first search (DFS) from that node to explore the connected component.\n", - "- In the worst case, every node may belong to a separate connected component, and you perform a DFS for each node.\n", - "- The time complexity of the DFS for a single connected component is O(V + E), where V is the number of nodes in the component, and E is the number of edges.\n", - "- In the worst case, you perform O(n) DFS calls, each with its own O(V + E) complexity.\n", - "\n", - "So, the overall time complexity of the code is O(n * (V + E)). In the worst case, if the graph is connected (a single connected component), this simplifies to O(n * (n + m)), where m is the number of edges.\n", - "\n", - "**Space Complexity:**\n", - "- The main data structures used are the `graph` (adjacency list), `visited` (boolean array), and the recursive call stack for DFS.\n", - "- The `graph` has a space complexity of O(n + m), where n is the number of nodes, and m is the number of edges.\n", - "- The `visited` boolean array also has a space complexity of O(n) to keep track of whether nodes have been visited.\n", - "- The depth of the recursive call stack for DFS can go up to O(n) in the worst case, when all nodes are part of a single connected component.\n", - "\n", - "So, the overall space complexity of the code is O(n + m) for data structures and O(n) for the call stack. In the worst case, this simplifies to O(n + m).\n", - "\n", - "In summary, the time complexity is O(n * (V + E)), and the space complexity is O(n + m)." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Disconnected Components with Multiple Queries:** You are given an undirected graph with `n` nodes and `m` edges. Initially, the graph is disconnected, and you need to process `q` queries. Each query consists of adding an edge to connect two nodes. After each query, you need to output the number of connected components in the updated graph.\n", - "\n", - "2. **Maximum Size of Connected Components:** Given an undirected graph with `n` nodes and `m` edges, find the size of the largest connected component in the graph. Additionally, identify the nodes that belong to this largest component. You can assume there is at least one connected component in the graph.\n" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/11. Graphs/417. Pacific Atlantic Water Flow.ipynb b/_build/html/_sources/11. Graphs/417. Pacific Atlantic Water Flow.ipynb deleted file mode 100644 index eb34497..0000000 --- a/_build/html/_sources/11. Graphs/417. Pacific Atlantic Water Flow.ipynb +++ /dev/null @@ -1,261 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 417. Pacific Atlantic Water Flow\n", - "\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Pacific Atlantic Water Flow problem on LeetCode, click here!](https://leetcode.com/problems/pacific-atlantic-water-flow/)\n", - "\n", - "---\n", - "There is an `m x n` rectangular island that borders both the **Pacific Ocean** and **Atlantic Ocean**. The **Pacific Ocea**n touches the island's left and top edges, and the **Atlantic Ocean** touches the island's right and bottom edges.\n", - "\n", - "The island is partitioned into a grid of square cells. You are given an `m x n` integer matrix `heights` where `heights[r][c]` represents the **height above sea level** of the cell at coordinate `(r, c)`.\n", - "\n", - "The island receives a lot of rain, and the rain water can flow to neighboring cells directly north, south, east, and west if the neighboring cell's height is **less than or equal to** the current cell's height. Water can flow from any cell adjacent to an ocean into the ocean.\n", - "\n", - "Return *a **2D list** of grid coordinates `result` where $result[i] = [r_i, c_i]$ denotes that rain water can flow from cell $(r_i, c_i)$ to **both** the Pacific and Atlantic oceans*.\n", - "\n", - "**Constraints:**\n", - "- `m == heights.length`\n", - "- `n == heights[r].length`\n", - "- `1 <= m, n <= 200`\n", - "- 0 <= `heights[r][c]` <= $10^5$" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem at hand involves a scenario with a rectangular island surrounded by both the Pacific Ocean and the Atlantic Ocean. The Pacific Ocean is in contact with the island's left and top edges, while the Atlantic Ocean is in contact with the island's right and bottom edges. The goal is to determine which cells on the island can allow rainwater to flow to both the Pacific and Atlantic Oceans.\n", - "\n", - "Here are the key details and constraints of the problem:\n", - "\n", - "1. The island is divided into a grid of square cells.\n", - "\n", - "2. Each cell is represented by an integer value in a matrix `heights`. The value at `heights[r][c]` represents the height above sea level of the cell at coordinates `(r, c)` on the island.\n", - "\n", - "3. Rainwater can flow from a cell to neighboring cells directly north, south, east, or west only if the neighboring cell's height is less than or equal to the current cell's height.\n", - "\n", - "4. Water can flow from any cell adjacent to the ocean into the ocean. This means water can flow from cells on the edge of the island to the Pacific Ocean and the Atlantic Ocean.\n", - "\n", - "The task is to find and return a 2D list of grid coordinates where rainwater can flow from a cell to both the Pacific and Atlantic Oceans. In other words, you need to identify the cells that can send water to both the left and top edges (Pacific) and the right and bottom edges (Atlantic) of the island.\n", - "\n", - "The problem is solved by performing a depth-first search (DFS) starting from the ocean edges and marking the cells that can flow to each ocean. Then, the algorithm identifies cells that are reachable from both oceans and returns their coordinates as the result.\n", - "\n", - "The problem involves both traversal of the island and backtracking to find the solution, which makes it a classic graph traversal problem.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "from typing import List\n", - "\n", - "class Solution:\n", - " def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]:\n", - " # Check if the input matrix is empty\n", - " if not heights:\n", - " return []\n", - " \n", - " m, n = len(heights), len(heights[0])\n", - " \n", - " # Initialize boolean matrices to keep track of cells reachable from each ocean\n", - " pacific_reachable = [[False] * n for _ in range(m)]\n", - " atlantic_reachable = [[False] * n for _ in range(m)]\n", - " \n", - " # Depth-First Search (DFS) function to mark cells that can be reached from an ocean\n", - " def dfs(x, y, reachable):\n", - " if reachable[x][y]:\n", - " return\n", - " reachable[x][y] = True\n", - " for dx, dy in [(0, 1), (0, -1), (1, 0), (-1, 0)]:\n", - " new_x, new_y = x + dx, y + dy\n", - " if 0 <= new_x < m and 0 <= new_y < n and heights[new_x][new_y] >= heights[x][y]:\n", - " dfs(new_x, new_y, reachable)\n", - " \n", - " # Start DFS from the Pacific Ocean (left and top edges)\n", - " for i in range(m):\n", - " dfs(i, 0, pacific_reachable)\n", - " dfs(i, n - 1, atlantic_reachable)\n", - " \n", - " for j in range(n):\n", - " dfs(0, j, pacific_reachable)\n", - " dfs(m - 1, j, atlantic_reachable)\n", - " \n", - " result = []\n", - " \n", - " # Find cells that can flow to both the Pacific and Atlantic oceans\n", - " for i in range(m):\n", - " for j in range(n):\n", - " if pacific_reachable[i][j] and atlantic_reachable[i][j]:\n", - " result.append([i, j])\n", - " \n", - " return result" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The code defines a class called `Solution` with a method named `pacificAtlantic`. This method takes a 2D matrix `heights`, where each element represents the height above sea level of a cell on a rectangular island. The goal of the method is to find and return a list of grid coordinates (cells) from which rainwater can flow into both the Pacific and Atlantic Oceans.\n", - "\n", - "The code uses a Depth-First Search (DFS) algorithm to traverse the island, starting from the ocean edges, and marks cells that are reachable from either the Pacific or Atlantic Ocean. It does this by creating two boolean matrices, `pacific_reachable` and `atlantic_reachable`, to keep track of cells that can be reached from each ocean.\n", - "\n", - "The code iterates through the entire island, initiating DFS searches from the edges of the island. If a cell is reachable from an ocean (either Pacific or Atlantic), it is marked as reachable in the corresponding boolean matrix. The DFS function ensures that the traversal follows the rule that water can flow to a neighboring cell if the neighboring cell's height is less than or equal to the current cell's height.\n", - "\n", - "After marking all reachable cells from both oceans, the code then looks for cells that are reachable from both the Pacific and Atlantic Oceans. If a cell satisfies this condition, it is added to the `result` list.\n", - "\n", - "Finally, the code returns the `result` list, which contains the grid coordinates of cells from which rainwater can flow into both the Pacific and Atlantic Oceans.\n", - "\n", - "The code provides a solution to the problem of finding cells on the island where water can reach both oceans, demonstrating a traversal algorithm that explores the connectivity of cells on the island." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]]\n" - ] - } - ], - "source": [ - "# Example 1\n", - "heights1 = [\n", - " [1,2,2,3,5],\n", - " [3,2,3,4,4],\n", - " [2,4,5,3,1],\n", - " [6,7,1,4,5],\n", - " [5,1,1,2,4]\n", - "]\n", - "\n", - "solution = Solution()\n", - "print(solution.pacificAtlantic(heights1)) # Expected Output: [[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]]" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[0, 0]]\n" - ] - } - ], - "source": [ - "# Example 2\n", - "heights2 = [[1]]\n", - "print(solution.pacificAtlantic(heights2)) # Expected Output: [[0, 0]]" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Time Complexity:\n", - "The time complexity of this solution is O(m * n), where 'm' is the number of rows in the input matrix and 'n' is the number of columns. Here's a breakdown of the time complexity:\n", - "\n", - "1. Creating the `pacific_reachable` and `atlantic_reachable` matrices with dimensions m x n takes O(m * n) time.\n", - "\n", - "2. Initiating Depth-First Search (DFS) from the edges of the island takes O(m * n) time because it processes each cell once.\n", - "\n", - "3. The DFS function visits each cell at most once, and its time complexity is O(1) for each cell. The number of cells visited by the DFS in the worst case is m * n.\n", - "\n", - "4. The final step of identifying and appending cells to the result list takes O(m * n) time in the worst case.\n", - "\n", - "Overall, the time complexity is dominated by the DFS and is O(m * n).\n", - "\n", - "Space Complexity:\n", - "The space complexity of this solution is also O(m * n). Here's how the space is used:\n", - "\n", - "1. Two boolean matrices, `pacific_reachable` and `atlantic_reachable`, are created with dimensions m x n. Each matrix takes O(m * n) space, resulting in O(2 * m * n) space usage.\n", - "\n", - "2. The depth-first search (DFS) stack space during the recursive calls can go as deep as the diagonal of the grid, which is at most min(m, n). This additional space for the call stack is relatively small compared to the boolean matrices and can be considered O(min(m, n)).\n", - "\n", - "3. The `result` list stores the grid coordinates, and its size is determined by the number of cells that can flow to both oceans. In the worst case, this list can contain all m * n cells, so it takes O(m * n) space.\n", - "\n", - "The overall space complexity is the sum of these components, which is O(m * n) + O(min(m, n)) + O(m * n). In big O notation, we can simplify this to O(m * n)." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Optimization Challenge:** Modify the algorithm to find the maximum flow of water from any cell to both the Pacific and Atlantic Oceans. In other words, find the cell(s) that can send the most water to both oceans.\n", - "\n", - "2. **Efficiency Challenge:** Optimize the time and space complexity of the algorithm while maintaining correctness. Aim to reduce both time and space complexity as much as possible." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/11. Graphs/README.md b/_build/html/_sources/11. Graphs/README.md deleted file mode 100644 index aad262c..0000000 --- a/_build/html/_sources/11. Graphs/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# Graphs Problems - Blind 75 LeetCode - - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [200. Number of Islands](https://leetcode.com/problems/number-of-islands/) | Medium | -| [133. Clone Graph](https://leetcode.com/problems/clone-graph/) | Medium | -| [417. Pacific Atlantic Water Flow](https://leetcode.com/problems/pacific-atlantic-water-flow/) | Medium | -| [207. Course Schedule](https://leetcode.com/problems/course-schedule/) | Medium | -| [323. Number of Connected Components In An Undirected Graph](https://leetcode.com/problems/number-of-connected-components-in-an-undirected-graph/) | Medium | -| [261. Graph Valid Tree](https://leetcode.com/problems/graph-valid-tree/) | Medium | - - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! \ No newline at end of file diff --git a/_build/html/_sources/12. Advanced Graphs/892. Alien Dictionary.ipynb b/_build/html/_sources/12. Advanced Graphs/892. Alien Dictionary.ipynb deleted file mode 100644 index 81f0e5b..0000000 --- a/_build/html/_sources/12. Advanced Graphs/892. Alien Dictionary.ipynb +++ /dev/null @@ -1,256 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 892. Alien Dictionary\n", - "\n", - "**Difficulty:** Hard\n", - "\n", - "**Link to Problem:** [To see the Alien Dictionary problem on LintCode, click here!](https://www.lintcode.com/problem/892/)\n", - "\n", - "---\n", - "\n", - "There is a new alien language which uses the latin alphabet. However, the order among letters are unknown to you. You receive a list of **non-empty** words from the dictionary, where words are **sorted lexicographically by the rules of this new language**. Derive the order of letters in this language.\n", - "\n", - "**Constraints:**\n", - "- You may assume all letters are in lowercase.\n", - "- The dictionary is invalid, if string a is prefix of string b and b is appear before a.\n", - "- If the order is invalid, return an empty string.\n", - "- There may be multiple valid order of letters, return the smallest in normal lexicographical order.\n", - "- The letters in **one** string are of the same rank by default and are sorted in Human dictionary order." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem at hand involves determining the order of letters in a new alien language that uses the Latin alphabet. However, the order of letters in this alien language is unknown. To solve this problem, we are given a list of non-empty words from the dictionary, where the words are sorted lexicographically based on the rules of the alien language. The goal is to derive the correct order of letters in this new language.\n", - "\n", - "Here's a more detailed explanation of the problem:\n", - "\n", - "1. The alphabet: The new alien language uses the Latin alphabet, which consists of lowercase letters.\n", - "\n", - "2. Dictionary: We are provided with a list of non-empty words. These words are sorted in lexicographical order based on the rules of the alien language. The order of letters in the words reflects the correct order in the new language.\n", - "\n", - "3. Invalid order: The problem specifies that the dictionary is considered invalid if there exists a situation where one string 'a' is a prefix of another string 'b,' and 'b' appears before 'a' in the dictionary. This condition ensures that there are no inconsistencies in the order of letters.\n", - "\n", - "4. Multiple valid orders: It's possible that there are multiple valid orders of letters that satisfy the provided dictionary. However, we are instructed to return the smallest valid order in normal lexicographical order.\n", - "\n", - "To solve this problem, you need to analyze the given list of words and determine the correct order of letters in the alien language while adhering to the specified constraints. You should return the order as a string in lexicographical order if it's valid, and an empty string if the order is invalid.\n", - "\n", - "The key to solving this problem is to construct a directed graph of letter relationships based on the order information provided by the words in the dictionary. Then, perform a topological sort on this graph to derive the order of letters, ensuring that the order is consistent and valid according to the given constraints.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "from collections import defaultdict, deque\n", - "\n", - "def alienOrder(words):\n", - " # Create an adjacency list to represent the graph\n", - " graph = defaultdict(list)\n", - " \n", - " # Create a dictionary to store the in-degrees of each letter\n", - " in_degree = {}\n", - " \n", - " # Initialize in-degrees to 0 for all letters\n", - " for word in words:\n", - " for char in word:\n", - " if char not in in_degree:\n", - " in_degree[char] = 0\n", - " \n", - " # Build the graph and update in-degrees\n", - " for i in range(1, len(words)):\n", - " word1, word2 = words[i-1], words[i]\n", - " min_length = min(len(word1), len(word2))\n", - " \n", - " # Compare characters in the two words\n", - " j = 0\n", - " while j < min_length and word1[j] == word2[j]:\n", - " j += 1\n", - " \n", - " if j < min_length:\n", - " # If word1[j] is lexicographically before word2[j], add an edge\n", - " graph[word1[j]].append(word2[j])\n", - " in_degree[word2[j]] += 1\n", - " \n", - " # Break the loop to avoid further comparisons\n", - " break\n", - " \n", - " # Perform topological sorting using Kahn's algorithm\n", - " result = []\n", - " queue = deque([char for char in in_degree if in_degree[char] == 0])\n", - " \n", - " while queue:\n", - " char = queue.popleft()\n", - " result.append(char)\n", - " \n", - " for neighbor in graph[char]:\n", - " in_degree[neighbor] -= 1\n", - " if in_degree[neighbor] == 0:\n", - " queue.append(neighbor)\n", - " \n", - " # Check if there is a valid order\n", - " if len(result) < len(in_degree):\n", - " return \"\"\n", - " \n", - " return \"\".join(result)" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The code is designed to determine the order of letters in an unknown alien language that uses the Latin alphabet. It takes a list of non-empty words from a dictionary as input, where the words are sorted lexicographically based on the rules of this alien language.\n", - "\n", - "The code follows these main steps:\n", - "\n", - "1. Create a data structure to represent the graph of letters and their relationships in the alien language. It uses a defaultdict to store a list of letters that come after each letter. Additionally, it uses a dictionary called `in_degree` to keep track of the in-degrees (the number of letters that precede a letter) for each letter.\n", - "\n", - "2. Initialize the in-degrees of all letters to 0. This is done by iterating through all the words and characters in the words, adding each character to the `in_degree` dictionary with an initial in-degree of 0.\n", - "\n", - "3. Build the graph by comparing adjacent words in the dictionary. For each pair of adjacent words, the code finds the first differing character between the two words. If such a character exists, it means there's an order relationship between the letters represented by these characters. The code updates the graph and in-degrees accordingly.\n", - "\n", - "4. After constructing the graph, the code performs a topological sorting of the letters using Kahn's algorithm. It starts by initializing an empty result list and a queue containing letters with in-degrees of 0. The algorithm repeatedly removes a letter with an in-degree of 0 from the queue, adds it to the result list, and updates the in-degrees of its neighbors. This process continues until the queue is empty.\n", - "\n", - "5. Finally, the code checks if the topological sorting was successful by comparing the length of the result list with the number of unique letters in the input. If the lengths differ, it means there's a cycle in the graph, and the order is invalid. In such a case, an empty string is returned. Otherwise, the result list is joined together to form the smallest order of letters in normal lexicographical order, and it is returned as the output.\n", - "\n", - "The code provides a way to determine the order of letters in the alien language while handling various edge cases, including checking for invalid order conditions." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "wrtef\n" - ] - } - ], - "source": [ - "# Example 1\n", - "words1 = [\"wrt\", \"wrf\", \"er\", \"ett\", \"rftt\"]\n", - "print(alienOrder(words1)) # Output: \"wertf\"" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "zx\n" - ] - } - ], - "source": [ - "# Example 2\n", - "words2 = [\"z\", \"x\"]\n", - "print(alienOrder(words2)) # Output: \"zx\"" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code for determining the order of letters in an alien language.\n", - "\n", - "Time Complexity:\n", - "1. Building the graph: The code iterates through the list of words and compares adjacent words. In the worst case, where all words have the same prefix, it takes O(N) time to build the graph, where N is the total number of characters in all the words.\n", - "2. Topological sorting: Performing a topological sort on the graph takes O(V + E) time, where V is the number of unique letters (vertices) and E is the number of relationships between letters (edges) in the graph.\n", - "\n", - "Overall, the time complexity is O(N + V + E), where N is the total number of characters in the words, V is the number of unique letters, and E is the number of order relationships between letters.\n", - "\n", - "Space Complexity:\n", - "1. Graph and In-degrees: The code uses data structures to represent the graph and in-degrees. The space complexity for these data structures is O(V + E), where V is the number of unique letters, and E is the number of order relationships between letters in the words.\n", - "2. Result List: The result list stores the order of letters, which can have a maximum size of V, where V is the number of unique letters.\n", - "3. Queue: The space used by the queue during topological sorting is also O(V).\n", - "\n", - "Overall, the space complexity is O(V + E) due to the data structures used for graph representation and the space needed for storing the result and the queue.\n", - "\n", - "In the worst case, where there are many unique letters and many order relationships, the space complexity is dominated by the number of unique letters and their relationships.\n", - "\n", - "In summary, the time complexity of the code is O(N + V + E), and the space complexity is O(V + E). The actual performance will depend on the specific input data, such as the number of unique letters and the relationships between them in the alien language." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Multiple Valid Orders**: Extend the problem to handle cases where there are multiple valid orders of letters in the alien language. Modify the code to return all valid orders instead of just one. Be mindful of performance.\n", - "\n", - "2. **Detect Invalid Dictionary**: Given a dictionary of words, write a function to detect whether the dictionary is valid or not based on the constraints mentioned in the problem statement." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/12. Advanced Graphs/README.md b/_build/html/_sources/12. Advanced Graphs/README.md deleted file mode 100644 index f362de7..0000000 --- a/_build/html/_sources/12. Advanced Graphs/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# Advanced Graphs Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [269. Alien Dictionary](https://leetcode.com/problems/alien-dictionary/) | Hard | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! \ No newline at end of file diff --git a/_build/html/_sources/13. One-D Dynamic Programming/198. House Robber.ipynb b/_build/html/_sources/13. One-D Dynamic Programming/198. House Robber.ipynb deleted file mode 100644 index 8d32e21..0000000 --- a/_build/html/_sources/13. One-D Dynamic Programming/198. House Robber.ipynb +++ /dev/null @@ -1,103 +0,0 @@ -{ - "metadata": { - "kernelspec": { - "name": "python", - "display_name": "Python (Pyodide)", - "language": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat_minor": 5, - "nbformat": 4, - "cells": [ - { - "cell_type": "markdown", - "source": "# House Robber\n**Difficulty:** Medium\n\n---\nYou are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security systems connected and **it will automatically contact the police if two adjacent houses were broken into on the same night.**\n\nGiven an integer array `nums` representing the amount of money of each house, return *the maximum amount of money you can rob tonight **without alerting the police**.*\n\n**Constraints:**\n- `1 <= nums.length <= 100`\n- `0 <= nums[i] <= 400`", - "metadata": {}, - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49" - }, - { - "cell_type": "markdown", - "source": "## Probelm Explanation:\n\nThe problem is a classic dynamic programming challenge known as the \"House Robber\" problem. The scenario is that you are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, but the constraint is that adjacent houses have security systems connected. If two adjacent houses are broken into on the same night, the security systems will automatically contact the police.\n\nThe goal is to determine the maximum amount of money you can rob tonight without alerting the police. You need to find a strategy to maximize your earnings while avoiding robbing two adjacent houses.\n\nThe input to the problem is an array `nums`, where `nums[i]` represents the amount of money in the `i`-th house. The task is to return the maximum amount of money that can be robbed without triggering the security system.\n\nFor example:\n```\nInput: nums = [1,2,3,1]\nOutput: 4\nExplanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).\nTotal amount you can rob = 1 + 3 = 4.\n\nInput: nums = [2,7,9,3,1]\nOutput: 12\nExplanation: Rob house 1 (money = 2), rob house 3 (money = 9), and rob house 5 (money = 1).\nTotal amount you can rob = 2 + 9 + 1 = 12.\n```\n\nThe challenge involves designing an algorithm to efficiently solve this problem and find the optimal strategy for robbing houses to maximize the stolen money while adhering to the constraint of not robbing adjacent houses. The provided solution utilizes dynamic programming to achieve this.\n\n## Solution:\nHere's a Python function to implement this algorithm:", - "metadata": {}, - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76" - }, - { - "cell_type": "code", - "source": "from typing import List\n\nclass Solution:\n def rob(self, nums: List[int]) -> int:\n # Initialize variables to keep track of the maximum amount of money robbed at the previous and current houses\n prev, curr = 0, 0\n\n # Iterate through the houses\n for n in nums:\n # Calculate the maximum amount of money that can be robbed at the current house\n # It is the maximum of either robbing the current house and the money robbed at the house before the previous one (prev),\n # or skipping the current house and taking the maximum amount from the previous house (curr)\n temp = max(n + prev, curr)\n\n # Update the variables for the next iteration\n prev, curr = curr, temp\n\n # The final result is the maximum amount of money that can be robbed at the last house\n return curr", - "metadata": { - "trusted": true - }, - "execution_count": 4, - "outputs": [], - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5" - }, - { - "cell_type": "markdown", - "source": "## Explanation:\n\nThe provided code is a Python implementation of the \"House Robber\" problem using a dynamic programming approach. It's part of a class `Solution` and includes a method `rob` that takes a list of integers `nums` as input and returns the maximum amount of money that can be robbed without alerting the police.\n\nThe key idea of the algorithm is to maintain two variables, `prev` and `curr`, which represent the maximum amount of money that can be robbed up to the previous house and the current house, respectively. The algorithm iterates through the houses, updating these variables based on the maximum amount that can be robbed at the current house, considering the constraint of not robbing adjacent houses.\n\nThe loop calculates a temporary variable `temp` that represents the maximum amount of money that can be robbed at the current house. It considers two scenarios: either robbing the current house and adding the money robbed at the house before the previous one (`n + prev`), or skipping the current house and taking the maximum amount from the previous house (`curr`). The maximum of these two scenarios is assigned to `temp`.\n\nThe `prev` and `curr` variables are then updated for the next iteration. `prev` is set to the previous value of `curr`, and `curr` is set to the calculated `temp`.\n\nThe final result is the value stored in the `curr` variable, representing the maximum amount of money that can be robbed at the last house. This value is returned as the result of the `rob` method.\n\nThe provided test cases at the end demonstrate the usage of the `rob` method with different input arrays.", - "metadata": {}, - "id": "ece39324-cd9e-47d7-8677-a001878494d9" - }, - { - "cell_type": "markdown", - "source": "## Test cases:\n\nHere's how you can use this solution:", - "metadata": {}, - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244" - }, - { - "cell_type": "code", - "source": "# Example 1:\nsol = Solution()\n\nnums1 = [1, 2, 3, 1]\nprint(sol.rob(nums1)) # Output: 4", - "metadata": { - "trusted": true - }, - "execution_count": 5, - "outputs": [ - { - "name": "stdout", - "text": "4\n", - "output_type": "stream" - } - ], - "id": "f12c5a63-b811-4be7-83c2-34ee396b546c" - }, - { - "cell_type": "code", - "source": "# Example 2:\nnums2 = [2, 7, 9, 3, 1]\nprint(sol.rob(nums2)) # Output: 12", - "metadata": { - "trusted": true - }, - "execution_count": 6, - "outputs": [ - { - "name": "stdout", - "text": "12\n", - "output_type": "stream" - } - ], - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3" - }, - { - "cell_type": "markdown", - "source": "## Time and Space Complexity Analysis\n\nLet's analyze the time and space complexity of the provided code.\n\n### Time Complexity:\n\nThe time complexity of the code is O(n), where n is the number of houses. The algorithm iterates through the array once, and in each iteration, it performs constant time operations. The loop runs for each house, and the number of operations inside the loop is independent of the input size. Therefore, the overall time complexity is linear, O(n).\n\n### Space Complexity:\n\nThe space complexity is O(1), constant space. The algorithm uses only a constant amount of extra space regardless of the input size. The variables `prev`, `curr`, and `temp` are the only additional variables used, and they do not depend on the size of the input array. Thus, the space complexity is constant, O(1).\n\nIn summary:\n- Time Complexity: O(n)\n- Space Complexity: O(1)", - "metadata": {}, - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2" - }, - { - "cell_type": "markdown", - "source": "## Challenging Exercises:\n\n1. **Variation with Maximum Number of Houses to Rob:** Modify the problem to include an additional constraint: you are allowed to rob at most 'k' houses without triggering the alarm. Find the maximum amount you can rob under this new constraint.\n\n2. **Robbing in a Circular Street:** Extend the problem to a circular street where the first and last houses are adjacent. You cannot rob both the first and last houses simultaneously. Find the maximum amount you can rob in this circular setting.\n\n\n**Link to Problem:** [To see the House Robber problem on LeetCode, click here!](https://leetcode.com/problems/house-robber/description/)\n", - "metadata": {}, - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6" - } - ] -} \ No newline at end of file diff --git a/_build/html/_sources/13. One-D Dynamic Programming/213. House Robber II.ipynb b/_build/html/_sources/13. One-D Dynamic Programming/213. House Robber II.ipynb deleted file mode 100644 index b1080e8..0000000 --- a/_build/html/_sources/13. One-D Dynamic Programming/213. House Robber II.ipynb +++ /dev/null @@ -1,119 +0,0 @@ -{ - "metadata": { - "kernelspec": { - "name": "python", - "display_name": "Python (Pyodide)", - "language": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat_minor": 5, - "nbformat": 4, - "cells": [ - { - "cell_type": "markdown", - "source": "# House Robber II\n**Difficulty:** Medium\n\n---\nYou are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. All houses at this place are **arranged in a circle**. That means the first house is the neighbor of the last one. Meanwhile, adjacent houses have a security system connected, and **it will automatically contact the police if two adjacent houses were broken into on the same night**.\n\nGiven an integer array `nums` representing the amount of money of each house, return *the maximum amount of money you can rob tonight without alerting the police*.\n\n**Constraints:**\n- `1 <= nums.length <= 100`\n- `0 <= nums[i] <= 1000`", - "metadata": {}, - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49" - }, - { - "cell_type": "markdown", - "source": "## Probelm Explanation:\n\nCertainly! The problem statement describes a scenario where you are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. However, there is a security system in place: adjacent houses have a security system connected, and it will automatically contact the police if two adjacent houses are broken into on the same night.\n\nThe twist in this problem is that the houses are arranged in a circle. That means the first house is the neighbor of the last one. So, robbing the first house has implications for the last house, and vice versa.\n\nThe goal is to find the maximum amount of money you can rob tonight without alerting the police. You need to implement a function that takes an integer array `nums` representing the amount of money in each house and returns the maximum amount of money that can be robbed without triggering the security system.\n\nHere are a few examples to illustrate the problem:\n\n1. **Example 1:**\n ```python\n Input: nums = [2, 3, 2]\n Output: 3\n Explanation: You cannot rob house 1 (money = 2) and then rob house 3 (money = 2) because they are adjacent houses. The optimal strategy is to rob house 2 (money = 3).\n ```\n\n2. **Example 2:**\n ```python\n Input: nums = [1, 2, 3, 1]\n Output: 4\n Explanation: Robbing house 1 (money = 1) and then robbing house 3 (money = 3) results in a total amount of 4. Robbing house 2 is skipped to avoid alerting the police.\n ```\n\n3. **Example 3:**\n ```python\n Input: nums = [1, 2, 3]\n Output: 3\n Explanation: Since the houses are in a circle, you can choose either house 1, 2, or 3. The optimal strategy is to rob house 3 for a total amount of 3.\n ```\n\nThe constraints for the problem are that the length of the `nums` array is between 1 and 100, and the amount of money in each house (`nums[i]`) is between 0 and 1000.\n\n## Solution:\nHere's a Python function to implement this algorithm:", - "metadata": {}, - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76" - }, - { - "cell_type": "code", - "source": "from typing import List\n\nclass Solution:\n def rob(self, nums: List[int]) -> int:\n def simple_rob(nums):\n # Helper function for basic house robbery problem\n prev, curr = 0, 0\n for num in nums:\n # Calculate the maximum amount of money that can be robbed\n # without alerting the police for each house\n prev, curr = curr, max(prev + num, curr)\n return curr\n\n # Check the base cases where the length of nums is 1 or 2\n if len(nums) == 1:\n return nums[0]\n elif len(nums) == 2:\n return max(nums[0], nums[1])\n\n # Case 1: First house is robbed, last house is not\n case1 = simple_rob(nums[:-1])\n\n # Case 2: First house is not robbed, last house is\n case2 = simple_rob(nums[1:])\n\n # Maximum of the two cases\n return max(case1, case2)", - "metadata": { - "trusted": true - }, - "execution_count": 7, - "outputs": [], - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5" - }, - { - "cell_type": "markdown", - "source": "## Explanation:\n\nThe provided code defines a class `Solution` with a method `rob`, which aims to determine the maximum amount of money a professional robber can steal from houses arranged in a circle without alerting the police. Each house contains a certain amount of money, and adjacent houses have a security system that triggers if both are robbed on the same night.\n\nThe code uses dynamic programming to solve the problem efficiently. It contains a helper function `simple_rob` that computes the maximum amount of money that can be robbed from a linear arrangement of houses. The main method `rob` handles the circular arrangement by considering two cases: robbing the first house and not robbing the last, and not robbing the first house and robbing the last. The result is the maximum of these two cases.\n\nThe class is instantiated as `solution`, and the `rob` method is applied to three different scenarios (test cases) to demonstrate its functionality. The final output represents the maximum amount of money the robber can steal without triggering the security system.", - "metadata": {}, - "id": "ece39324-cd9e-47d7-8677-a001878494d9" - }, - { - "cell_type": "markdown", - "source": "## Test cases:\n\nHere's how you can use this solution:", - "metadata": {}, - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244" - }, - { - "cell_type": "code", - "source": "# Example 1:\n\n# Create an instance of the Solution class\nsolution = Solution()\n\nnums1 = [2, 3, 2]\nprint(solution.rob(nums1)) # Output: 3", - "metadata": { - "trusted": true - }, - "execution_count": 8, - "outputs": [ - { - "name": "stdout", - "text": "3\n", - "output_type": "stream" - } - ], - "id": "f12c5a63-b811-4be7-83c2-34ee396b546c" - }, - { - "cell_type": "code", - "source": "# Example 2:\nnums2 = [1, 2, 3, 1]\nprint(solution.rob(nums2)) # Output: 4", - "metadata": { - "trusted": true - }, - "execution_count": 9, - "outputs": [ - { - "name": "stdout", - "text": "4\n", - "output_type": "stream" - } - ], - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3" - }, - { - "cell_type": "code", - "source": "# Example 2:\nnums3 = [1, 2, 3]\nprint(solution.rob(nums3)) # Output: 3", - "metadata": { - "trusted": true - }, - "execution_count": 10, - "outputs": [ - { - "name": "stdout", - "text": "3\n", - "output_type": "stream" - } - ], - "id": "e6e1554f-ae77-410c-8af2-e59e5428166c" - }, - { - "cell_type": "markdown", - "source": "## Time and Space Complexity Analysis\n\nLet's analyze the time and space complexity of the provided code:\n\n### Time Complexity:\nThe time complexity is primarily determined by the `simple_rob` helper function, which has a time complexity of O(N), where N is the number of houses in the input array. The main `rob` function calls `simple_rob` twice, once for the case of robbing the first house and not robbing the last, and once for the case of not robbing the first house and robbing the last. Therefore, the overall time complexity is O(N).\n\n### Space Complexity:\nThe space complexity is O(1) because the space used by the algorithm is constant, regardless of the size of the input array. The only variables used are `prev` and `curr` in the `simple_rob` function, which represent the previous and current maximum amounts of money that can be robbed without alerting the police. These variables are updated iteratively, and no additional data structures are used that scale with the input size. Therefore, the space complexity is constant, or O(1).\n\nIn summary:\n- Time Complexity: O(N)\n- Space Complexity: O(1)", - "metadata": {}, - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2" - }, - { - "cell_type": "markdown", - "source": "## Challenging Exercises:\n\n1. **Optimization Challenge:** Optimize the space complexity of the solution. Can you solve the problem with O(1) space complexity without sacrificing the time complexity?\n\n2. **Circular Robbery Variations:** Consider variations of the circular house robbery problem, such as allowing the robber to skip a certain number of houses or restricting the number of consecutive houses that can be robbed. Modify the solution to accommodate these variations.\n\n**Link to Problem:** [To see the House Robber II problem on LeetCode, click here!](https://leetcode.com/problems/house-robber-ii/)", - "metadata": {}, - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6" - } - ] -} \ No newline at end of file diff --git a/_build/html/_sources/13. One-D Dynamic Programming/70. Climbing Stairs.ipynb b/_build/html/_sources/13. One-D Dynamic Programming/70. Climbing Stairs.ipynb deleted file mode 100644 index b727489..0000000 --- a/_build/html/_sources/13. One-D Dynamic Programming/70. Climbing Stairs.ipynb +++ /dev/null @@ -1,210 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 70. Climbing Stairs\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Climbing Stairs problem on LeetCode, click here!](https://leetcode.com/problems/climbing-stairs/)\n", - "\n", - "---\n", - "You are climbing a staircase. It takes `n` steps to reach the top.\n", - "\n", - "Each time you can either climb `1` or `2` steps. In how many distinct ways can you climb to the top?\n", - "\n", - "**Constraints:**\n", - "- `1 <= n <= 45`" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The \"Climbing Stairs\" problem is a classic algorithmic problem that asks you to find the number of distinct ways to climb a staircase with a given number of steps. Here's the problem statement:\n", - "\n", - "You are given a staircase with 'n' steps. Each time you can either climb 1 step or 2 steps. You need to find out how many distinct ways there are to reach the top of the staircase.\n", - "\n", - "For example, if 'n' is 2, there are two ways to climb to the top:\n", - "\n", - "1. Climbing two steps at once.\n", - "2. Climbing one step, and then another step.\n", - "\n", - "If 'n' is 3, there are three ways:\n", - "\n", - "1. Climbing one step, then one step, and finally one step.\n", - "2. Climbing one step, then two steps.\n", - "3. Climbing two steps, then one step.\n", - "\n", - "The problem essentially asks you to find a solution that counts the possible combinations of 1-step and 2-step climbs that can be taken to reach the top of the staircase. It's a classic example of a dynamic programming problem where you can break it down into smaller subproblems and build a solution incrementally, as shown in the code I provided earlier.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class Solution:\n", - " def climbStairs(self, n: int) -> int:\n", - " # If there are 1 or 2 steps, there are exactly n ways to reach the top.\n", - " if n <= 2:\n", - " return n\n", - "\n", - " # Create an array to store the number of ways to reach each step.\n", - " dp = [0] * (n + 1)\n", - "\n", - " # There is one way to reach the first step (base case).\n", - " dp[1] = 1\n", - "\n", - " # There are two ways to reach the second step (base case).\n", - " dp[2] = 2\n", - "\n", - " # Calculate the number of ways to reach each step from the previous steps.\n", - " for i in range(3, n + 1):\n", - " # The number of ways to reach step 'i' is the sum of the ways to reach\n", - " # the previous two steps, as you can take 1 or 2 steps at a time.\n", - " dp[i] = dp[i - 1] + dp[i - 2]\n", - "\n", - " # The result is the number of ways to reach the top, which is stored in dp[n].\n", - " return dp[n]" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The code defines a class `Solution` with a method `climbStairs` that takes an integer `n` as input and returns the number of distinct ways to climb a staircase with `n` steps.\n", - "\n", - "1. If `n` is 1 or 2, the function returns `n` directly because there are only 1 or 2 distinct ways to reach the top in those cases.\n", - "\n", - "2. For `n` greater than 2, the code uses dynamic programming to calculate the number of ways to reach each step. It creates an array `dp` of length `n + 1` to store these values.\n", - "\n", - "3. The `dp[1]` and `dp[2]` are initialized to 1 and 2, respectively. This is because there is only one way to reach the first step (by taking 1 step), and there are two ways to reach the second step (by taking 2 steps or two 1-step climbs).\n", - "\n", - "4. The code then uses a loop to fill in the `dp` array for steps 3 and above. For each step `i` from 3 to `n`, it calculates the number of ways to reach that step by adding the number of ways to reach the previous two steps, as you can either take 1 step or 2 steps at a time.\n", - "\n", - "5. Finally, the function returns the value stored in `dp[n]`, which represents the total number of distinct ways to climb the staircase with `n` steps." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "f12c5a63-b811-4be7-83c2-34ee396b546c", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Example 1 - Input: n = 2, Output: 2\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "n = 2\n", - "solution = Solution()\n", - "print(f\"Example 1 - Input: n = {n}, Output: {solution.climbStairs(n)}\") # Output should be 2" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Example 2 - Input: n = 3, Output: 3\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "n = 3\n", - "print(f\"Example 2 - Input: n = {n}, Output: {solution.climbStairs(n)}\") # Output should be 3\n" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Time Complexity:\n", - "The time complexity of the solution is O(n) because we use a single for loop that iterates from 3 to n to fill the `dp` array. In each iteration, we perform constant time operations (addition and assignment). Therefore, the time complexity is linear with respect to the input value `n`.\n", - "\n", - "Space Complexity:\n", - "The space complexity of the solution is O(n) as well. We use an array `dp` of length `n + 1` to store the number of ways to reach each step. The size of this array is directly proportional to the input value `n`, which makes the space complexity linear in terms of `n`. The rest of the variables used in the function (e.g., `i`) occupy constant space and do not contribute significantly to the overall space complexity.\n", - "\n", - "In summary, the time complexity is O(n), and the space complexity is O(n) for this dynamic programming solution to the \"Climbing Stairs\" problem." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Generalized Step Sizes**: Instead of being limited to 1 step or 2 steps, consider a scenario where you can take steps of sizes `[1, 2, 3]`. Implement a function that calculates the number of ways to climb the staircase with these different step sizes.\n", - "\n", - "2. **Minimize Steps**: Given an integer `n`, find the minimum number of steps required to reach the top of the staircase. Return both the minimum number of steps and the specific sequence of steps taken." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/_build/html/_sources/13. One-D Dynamic Programming/README.md b/_build/html/_sources/13. One-D Dynamic Programming/README.md deleted file mode 100644 index 73f4de3..0000000 --- a/_build/html/_sources/13. One-D Dynamic Programming/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# 1-D Dynamic Programming Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [70. Climbing Stairs](https://leetcode.com/problems/climbing-stairs/) | Easy | -| [198. House Robber](https://leetcode.com/problems/house-robber/) | Medium | -| [213. House Robber II](https://leetcode.com/problems/house-robber-ii/) | Medium | -| [5. Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/) | Medium | -| [647. Palindromic Substrings](https://leetcode.com/problems/palindromic-substrings/) | Medium | -| [91. Decode Ways](https://leetcode.com/problems/decode-ways/) | Medium | -| [322. Coin Change](https://leetcode.com/problems/coin-change/) | Medium | -| [152. Maximum Product Subarray](https://leetcode.com/problems/maximum-product-subarray/) | Medium | -| [139. Word Break](https://leetcode.com/problems/word-break/) | Medium | -| [300. Longest Increasing Subsequence](https://leetcode.com/problems/longest-increasing-subsequence/) | Medium | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! \ No newline at end of file diff --git a/_build/html/_sources/14. Two-D Dynamic Programming/README.md b/_build/html/_sources/14. Two-D Dynamic Programming/README.md deleted file mode 100644 index 8bab876..0000000 --- a/_build/html/_sources/14. Two-D Dynamic Programming/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# Blind 75 LeetCode Problems - -This repository contains a curated list of 75 LeetCode problems that are commonly known as the "Blind 75." These problems cover a wide range of data structures and algorithms and are frequently asked in technical interviews. Solving these problems can help you build a strong foundation in algorithmic problem-solving. - -## Problem List - -### 2-D Dynamic Programming - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [62. Unique Paths](https://leetcode.com/problems/unique-paths/) | Medium | -| [1143. Longest Common Subsequence](https://leetcode.com/problems/longest-common-subsequence/) | Medium | - -## How to Use - -1. Clone or download this repository to your local machine. - -```bash -git clone https://github.com/mohsentabibian/LeetCode-Solutions/Blind-75-LeetCode.git -``` - -2. Navigate to the directory of the specific problem you want to solve. - -```bash -cd Blind-75-LeetCode/Problem-Directory -``` - -3. Open the problem's directory to find its description, code template, and solution(s). - -4. Solve the problem using your preferred programming language. - -5. Check the solution(s) provided in the directory for reference and to compare your solution. - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -## Disclaimer - -This repository is meant for educational purposes and to help individuals prepare for technical interviews. Please respect LeetCode's terms of use and guidelines when using this repository. - -Happy coding! \ No newline at end of file diff --git a/_build/html/_sources/15. Greedy/README.md b/_build/html/_sources/15. Greedy/README.md deleted file mode 100644 index 82b6543..0000000 --- a/_build/html/_sources/15. Greedy/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# Blind 75 LeetCode Problems - -This repository contains a curated list of 75 LeetCode problems that are commonly known as the "Blind 75." These problems cover a wide range of data structures and algorithms and are frequently asked in technical interviews. Solving these problems can help you build a strong foundation in algorithmic problem-solving. - -## Problem List - -### Greedy - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [53. Maximum Subarray](https://leetcode.com/problems/maximum-subarray/) | Easy | -| [55. Jump Game](https://leetcode.com/problems/jump-game/) | Medium | - -## How to Use - -1. Clone or download this repository to your local machine. - -```bash -git clone https://github.com/mohsentabibian/LeetCode-Solutions/Blind-75-LeetCode.git -``` - -2. Navigate to the directory of the specific problem you want to solve. - -```bash -cd Blind-75-LeetCode/Problem-Directory -``` - -3. Open the problem's directory to find its description, code template, and solution(s). - -4. Solve the problem using your preferred programming language. - -5. Check the solution(s) provided in the directory for reference and to compare your solution. - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -## Disclaimer - -This repository is meant for educational purposes and to help individuals prepare for technical interviews. Please respect LeetCode's terms of use and guidelines when using this repository. - -Happy coding! \ No newline at end of file diff --git a/_build/html/_sources/16. Intervals/README.md b/_build/html/_sources/16. Intervals/README.md deleted file mode 100644 index a57713e..0000000 --- a/_build/html/_sources/16. Intervals/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# Blind 75 LeetCode Problems - -This repository contains a curated list of 75 LeetCode problems that are commonly known as the "Blind 75." These problems cover a wide range of data structures and algorithms and are frequently asked in technical interviews. Solving these problems can help you build a strong foundation in algorithmic problem-solving. - -## Problem List - -### Intervals - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [57. Insert Interval](https://leetcode.com/problems/insert-interval/) | Hard | -| [56. Merge Intervals](https://leetcode.com/problems/merge-intervals/) | Medium | -| [435. Non Overlapping Intervals](https://leetcode.com/problems/non-overlapping-intervals/) | Medium | -| [252. Meeting Rooms](https://leetcode.com/problems/meeting-rooms/) | Easy | -| [253. Meeting Rooms II](https://leetcode.com/problems/meeting-rooms-ii/) | Medium | - -## How to Use - -1. Clone or download this repository to your local machine. - -```bash -git clone https://github.com/mohsentabibian/LeetCode-Solutions/Blind-75-LeetCode.git -``` - -2. Navigate to the directory of the specific problem you want to solve. - -```bash -cd Blind-75-LeetCode/Problem-Directory -``` - -3. Open the problem's directory to find its description, code template, and solution(s). - -4. Solve the problem using your preferred programming language. - -5. Check the solution(s) provided in the directory for reference and to compare your solution. - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -## Disclaimer - -This repository is meant for educational purposes and to help individuals prepare for technical interviews. Please respect LeetCode's terms of use and guidelines when using this repository. - -Happy coding! \ No newline at end of file diff --git a/_build/html/_sources/17. Math Geometry/README.md b/_build/html/_sources/17. Math Geometry/README.md deleted file mode 100644 index 8b2f180..0000000 --- a/_build/html/_sources/17. Math Geometry/README.md +++ /dev/null @@ -1,48 +0,0 @@ -# Blind 75 LeetCode Problems - -This repository contains a curated list of 75 LeetCode problems that are commonly known as the "Blind 75." These problems cover a wide range of data structures and algorithms and are frequently asked in technical interviews. Solving these problems can help you build a strong foundation in algorithmic problem-solving. - -## Problem List - -### Math & Geometry - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [48. Rotate Image](https://leetcode.com/problems/rotate-image/) | Medium | -| [54. Spiral Matrix](https://leetcode.com/problems/spiral-matrix/) | Medium | -| [73. Set Matrix Zeroes](https://leetcode.com/problems/set-matrix-zeroes/) | Medium | - -## How to Use - -1. Clone or download this repository to your local machine. - -```bash -git clone https://github.com/mohsentabibian/LeetCode-Solutions/Blind-75-LeetCode.git -``` - -2. Navigate to the directory of the specific problem you want to solve. - -```bash -cd Blind-75-LeetCode/Problem-Directory -``` - -3. Open the problem's directory to find its description, code template, and solution(s). - -4. Solve the problem using your preferred programming language. - -5. Check the solution(s) provided in the directory for reference and to compare your solution. - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -## Disclaimer - -This repository is meant for educational purposes and to help individuals prepare for technical interviews. Please respect LeetCode's terms of use and guidelines when using this repository. - -Happy coding! \ No newline at end of file diff --git a/_build/html/_sources/18. Bit Manipulation/README.md b/_build/html/_sources/18. Bit Manipulation/README.md deleted file mode 100644 index 05b2fef..0000000 --- a/_build/html/_sources/18. Bit Manipulation/README.md +++ /dev/null @@ -1,51 +0,0 @@ -# Blind 75 LeetCode Problems - -This repository contains a curated list of 75 LeetCode problems that are commonly known as the "Blind 75." These problems cover a wide range of data structures and algorithms and are frequently asked in technical interviews. Solving these problems can help you build a strong foundation in algorithmic problem-solving. - -## Problem List - -### Bit Manupulation - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [191. Number of 1 Bits](https://leetcode.com/problems/number-of-1-bits/) | Easy | -| [338. Counting Bits](https://leetcode.com/problems/counting-bits/) | Medium | -| [190. Reverse Bits](https://leetcode.com/problems/reverse-bits/) | Easy | -| [268. Missing Number](https://leetcode.com/problems/missing-number/) | Easy | -| [371. Sum of Two Integers](https://leetcode.com/problems/sum-of-two-integers/) | Medium | - - -## How to Use - -1. Clone or download this repository to your local machine. - -```bash -git clone https://github.com/mohsentabibian/LeetCode-Solutions/Blind-75-LeetCode.git -``` - -2. Navigate to the directory of the specific problem you want to solve. - -```bash -cd Blind-75-LeetCode/Problem-Directory -``` - -3. Open the problem's directory to find its description, code template, and solution(s). - -4. Solve the problem using your preferred programming language. - -5. Check the solution(s) provided in the directory for reference and to compare your solution. - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -## Disclaimer - -This repository is meant for educational purposes and to help individuals prepare for technical interviews. Please respect LeetCode's terms of use and guidelines when using this repository. - -Happy coding! \ No newline at end of file diff --git a/_build/html/_sources/CODE_OF_CONDUCT.md b/_build/html/_sources/CODE_OF_CONDUCT.md deleted file mode 100644 index 5fe5041..0000000 --- a/_build/html/_sources/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,128 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -We as members, contributors, and leaders pledge to make participation in our -community a harassment-free experience for everyone, regardless of age, body -size, visible or invisible disability, ethnicity, sex characteristics, gender -identity and expression, level of experience, education, socio-economic status, -nationality, personal appearance, race, religion, or sexual identity -and orientation. - -We pledge to act and interact in ways that contribute to an open, welcoming, -diverse, inclusive, and healthy community. - -## Our Standards - -Examples of behavior that contributes to a positive environment for our -community include: - -* Demonstrating empathy and kindness toward other people -* Being respectful of differing opinions, viewpoints, and experiences -* Giving and gracefully accepting constructive feedback -* Accepting responsibility and apologizing to those affected by our mistakes, - and learning from the experience -* Focusing on what is best not just for us as individuals, but for the - overall community - -Examples of unacceptable behavior include: - -* The use of sexualized language or imagery, and sexual attention or - advances of any kind -* Trolling, insulting or derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or email - address, without their explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Enforcement Responsibilities - -Community leaders are responsible for clarifying and enforcing our standards of -acceptable behavior and will take appropriate and fair corrective action in -response to any behavior that they deem inappropriate, threatening, offensive, -or harmful. - -Community leaders 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, and will communicate reasons for moderation -decisions when appropriate. - -## Scope - -This Code of Conduct applies within all community spaces, and also applies when -an individual is officially representing the community in public spaces. -Examples of representing our community include using an official e-mail address, -posting via an official social media account, or acting as an appointed -representative at an online or offline event. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported to the community leaders responsible for enforcement at -Email. -All complaints will be reviewed and investigated promptly and fairly. - -All community leaders are obligated to respect the privacy and security of the -reporter of any incident. - -## Enforcement Guidelines - -Community leaders will follow these Community Impact Guidelines in determining -the consequences for any action they deem in violation of this Code of Conduct: - -### 1. Correction - -**Community Impact**: Use of inappropriate language or other behavior deemed -unprofessional or unwelcome in the community. - -**Consequence**: A private, written warning from community leaders, providing -clarity around the nature of the violation and an explanation of why the -behavior was inappropriate. A public apology may be requested. - -### 2. Warning - -**Community Impact**: A violation through a single incident or series -of actions. - -**Consequence**: A warning with consequences for continued behavior. No -interaction with the people involved, including unsolicited interaction with -those enforcing the Code of Conduct, for a specified period of time. This -includes avoiding interactions in community spaces as well as external channels -like social media. Violating these terms may lead to a temporary or -permanent ban. - -### 3. Temporary Ban - -**Community Impact**: A serious violation of community standards, including -sustained inappropriate behavior. - -**Consequence**: A temporary ban from any sort of interaction or public -communication with the community for a specified period of time. No public or -private interaction with the people involved, including unsolicited interaction -with those enforcing the Code of Conduct, is allowed during this period. -Violating these terms may lead to a permanent ban. - -### 4. Permanent Ban - -**Community Impact**: Demonstrating a pattern of violation of community -standards, including sustained inappropriate behavior, harassment of an -individual, or aggression toward or disparagement of classes of individuals. - -**Consequence**: A permanent ban from any sort of public interaction within -the community. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], -version 2.0, available at -https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. - -Community Impact Guidelines were inspired by [Mozilla's code of conduct -enforcement ladder](https://github.com/mozilla/diversity). - -[homepage]: https://www.contributor-covenant.org - -For answers to common questions about this code of conduct, see the FAQ at -https://www.contributor-covenant.org/faq. Translations are available at -https://www.contributor-covenant.org/translations. diff --git a/_build/html/_sources/CONTRIBUTING.md b/_build/html/_sources/CONTRIBUTING.md deleted file mode 100644 index ca794ef..0000000 --- a/_build/html/_sources/CONTRIBUTING.md +++ /dev/null @@ -1,79 +0,0 @@ -# Contributing Guidelines - -Thank you for considering contributing to the Blind 75 LeetCode repository! We welcome contributions from the community to help improve this resource and make it even more valuable. - -Please take a moment to review this document to understand how you can contribute. - -## Table of Contents -- [Ways to Contribute](#ways-to-contribute) -- [Getting Started](#getting-started) -- [Contributing Process](#contributing-process) -- [Code of Conduct](#code-of-conduct) - -## Ways to Contribute - -There are several ways you can contribute to this repository: - -1. **Suggest Improvements**: If you have ideas for making the Blind 75 LeetCode repository better, please open an issue to discuss your suggestions. - -2. **Report Issues**: If you encounter any issues with the existing content or code, please open an issue and provide as much detail as possible. - -3. **Contribute Solutions**: You can contribute solutions to the problems listed in the repository. Please follow the guidelines mentioned below when submitting your solutions. - -4. **Enhance Documentation**: Improve documentation, including explanations and time/space complexity analysis, for existing solutions. - -5. **Fix Bugs**: If you find and fix any bugs in the existing code or documentation, you are welcome to submit a pull request. - -## Getting Started - -Before you start contributing, please ensure you have the following prerequisites: - -- A GitHub account. -- Familiarity with Git and GitHub. -- Code editor or IDE for making changes. - -## Contributing Process - -Here's the general process for contributing: - -1. **Fork the Repository**: Click the "Fork" button at the top of this repository to create your copy. - -2. **Clone Your Fork**: Clone your fork to your local machine. - - ``` - git clone https://github.com/your-username/Blind-75-LeetCode.git - ``` - -3. **Create a Branch**: Create a new branch for your contribution. - - ``` - git checkout -b feature/your-feature-name - ``` - -4. **Make Changes**: Implement your changes, following the guidelines provided. - -5. **Test Your Changes**: Ensure that your changes do not introduce new issues and are consistent with the repository's style and structure. - -6. **Commit Changes**: Commit your changes with a meaningful commit message. - - ``` - git commit -m "Add solution to problem X" - ``` - -7. **Push Changes**: Push your changes to your fork on GitHub. - - ``` - git push origin feature/your-feature-name - ``` - -8. **Create a Pull Request**: Go to the original repository and create a pull request. Please provide a detailed description of your changes. - -9. **Review and Collaboration**: Your pull request will be reviewed, and you may need to make further changes. Be responsive to comments and feedback. - -10. **Merge**: Once your pull request is approved, it will be merged into the main branch. - -## Code of Conduct - -Please note that we have a [Code of Conduct](CODE_OF_CONDUCT.md) that we expect all contributors to adhere to. By participating in this project, you agree to follow this code. - -We appreciate your contributions to the Blind 75 LeetCode repository and look forward to working together to make it an even better resource for the community! diff --git a/_build/html/_sources/README.md b/_build/html/_sources/README.md deleted file mode 100644 index a9b8b2e..0000000 --- a/_build/html/_sources/README.md +++ /dev/null @@ -1,216 +0,0 @@ -# Blind 75 LeetCode Solutions - -![Blind 75 LeetCode](https://img.shields.io/badge/Blind_75_LeetCode-Solutions-blue?labelColor=red) - -This repository contains a curated list of 75 LeetCode problems that are commonly known as the "Blind 75." These problems cover a wide range of data structures and algorithms and are frequently asked in technical interviews. Solving these problems can help you build a strong foundation in algorithmic problem-solving. - -## Problem List - -### Array & Hashing -![Array & Hashing](https://img.shields.io/badge/Array_&_Hashing-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [217. Contains Duplicate](https://leetcode.com/problems/contains-duplicate/) | Easy | -| [242. Valid Anagram](https://leetcode.com/problems/valid-anagram/) | Easy | -| [1. Two Sum](https://leetcode.com/problems/two-sum/) | Easy | -| [49. Group Anagrams](https://leetcode.com/problems/group-anagrams/) | Medium | -| [347. Top K Frequent Elements](https://leetcode.com/problems/top-k-frequent-elements/) | Medium | -| [238. Product of Array Except Self](https://leetcode.com/problems/product-of-array-except-self/) | Medium | -| [659. Encode and Decode Strings](https://leetcode.com/problems/encode-and-decode-strings/) | Medium | -| [128. Longest Consecutive Sequence](https://leetcode.com/problems/longest-consecutive-sequence/) | Hard | - -### Two Pointers -![Array & Hashing](https://img.shields.io/badge/Two_Pointers-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [125. Valid Palindrome](https://leetcode.com/problems/valid-palindrome/) | Easy | -| [15. 3Sum](https://leetcode.com/problems/3sum/) | Medium | -| [11. Container With Most Water](https://leetcode.com/problems/container-with-most-water/) | Medium | - -### Sliding Window -![Array & Hashing](https://img.shields.io/badge/Sliding_Window-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [121. Best Time to Buy And Sell Stock](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/) | Easy | -| [3. Longest Substring Without Repeating Characters](https://leetcode.com/problems/longest-substring-without-repeating-characters/) | Medium | -| [424. Longest Repeating Character Replacement](https://leetcode.com/problems/longest-repeating-character-replacement/) | Medium | -| [76. Minimum Window Substring](https://leetcode.com/problems/minimum-window-substring/) | Hard | - -### Stack -![Array & Hashing](https://img.shields.io/badge/Stack-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [20. Valid Parentheses](https://leetcode.com/problems/valid-parentheses/) | Easy | - -### Binary Search -![Array & Hashing](https://img.shields.io/badge/Binary_Search-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [153. Find Minimum In Rotated Sorted Array](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/) | Medium | -| [33. Search In Rotated Sorted Array](https://leetcode.com/problems/search-in-rotated-sorted-array/) | Medium | - -### Linked List -![Array & Hashing](https://img.shields.io/badge/Linked_List-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [206. Reverse Linked List](https://leetcode.com/problems/reverse-linked-list/) | Easy | -| [21. Merge Two Sorted Lists](https://leetcode.com/problems/merge-two-sorted-lists/) | Easy | -| [143. Reorder List](https://leetcode.com/problems/reorder-list/) | Medium | -| [19. Remove Nth Node From End of List](https://leetcode.com/problems/remove-nth-node-from-end-of-list/) | Medium | -| [141. Linked List Cycle](https://leetcode.com/problems/linked-list-cycle/) | Medium | -| [23. Merge K Sorted Lists](https://leetcode.com/problems/merge-k-sorted-lists/) | Hard | - -### Trees -![Array & Hashing](https://img.shields.io/badge/Trees-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [226. Invert Binary Tree](https://leetcode.com/problems/invert-binary-tree/) | Easy | -| [104. Maximum Depth of Binary Tree](https://leetcode.com/problems/maximum-depth-of-binary-tree/) | Easy | -| [100. Same Tree](https://leetcode.com/problems/same-tree/) | Easy | -| [572. Subtree of Another Tree](https://leetcode.com/problems/subtree-of-another-tree/) | Easy | -| [235. Lowest Common Ancestor of a Binary Search Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/) | Easy | -| [102. Binary Tree Level Order Traversal](https://leetcode.com/problems/binary-tree-level-order-traversal/) | Medium | -| [98. Validate Binary Search Tree](https://leetcode.com/problems/validate-binary-search-tree/) | Medium | -| [230. Kth Smallest Element In a BST](https://leetcode.com/problems/kth-smallest-element-in-a-bst/) | Medium | -| [105. Construct Binary Tree From Preorder And Inorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/) | Medium | -| [124. Binary Tree Maximum Path Sum](https://leetcode.com/problems/binary-tree-maximum-path-sum/) | Hard | -| [297. Serialize And Deserialize Binary Tree](https://leetcode.com/problems/serialize-and-deserialize-binary-tree/) | Hard | - -### Tries -![Array & Hashing](https://img.shields.io/badge/Tries-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [208. Implement Trie Prefix Tree](https://leetcode.com/problems/implement-trie-prefix-tree/) | Medium | -| [211. Design Add And Search Words Data Structure](https://leetcode.com/problems/design-add-and-search-words-data-structure/) | Medium | -| [212. Word Search II](https://leetcode.com/problems/word-search-ii/) | Hard | - -### Heap / Priority Queue -![Array & Hashing](https://img.shields.io/badge/Heap_/_Priority_Queue-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [295. Find Median From Data Stream](https://leetcode.com/problems/find-median-from-data-stream/) | Hard | - -### Backtracking -![Array & Hashing](https://img.shields.io/badge/Backtracking-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [39. Combination Sum](https://leetcode.com/problems/combination-sum/) | Medium | -| [79. Word Search](https://leetcode.com/problems/word-search/) | Medium | - -### Graphs -![Array & Hashing](https://img.shields.io/badge/Graphs-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [200. Number of Islands](https://leetcode.com/problems/number-of-islands/) | Medium | -| [133. Clone Graph](https://leetcode.com/problems/clone-graph/) | Medium | -| [417. Pacific Atlantic Water Flow](https://leetcode.com/problems/pacific-atlantic-water-flow/) | Medium | -| [207. Course Schedule](https://leetcode.com/problems/course-schedule/) | Medium | -| [323. Number of Connected Components In An Undirected Graph](https://leetcode.com/problems/number-of-connected-components-in-an-undirected-graph/) | Medium | -| [261. Graph Valid Tree](https://leetcode.com/problems/graph-valid-tree/) | Medium | - -### Advanced Graphs -![Array & Hashing](https://img.shields.io/badge/Advanced_Graphs-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [269. Alien Dictionary](https://leetcode.com/problems/alien-dictionary/) | Hard | - -### 1-D Dynamic Programming -![Array & Hashing](https://img.shields.io/badge/1_D_Dynamic_Programming-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [70. Climbing Stairs](https://leetcode.com/problems/climbing-stairs/) | Easy | -| [198. House Robber](https://leetcode.com/problems/house-robber/) | Easy | -| [213. House Robber II](https://leetcode.com/problems/house-robber-ii/) | Medium | -| [5. Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/) | Medium | -| [647. Palindromic Substrings](https://leetcode.com/problems/palindromic-substrings/) | Medium | -| [91. Decode Ways](https://leetcode.com/problems/decode-ways/) | Medium | -| [322. Coin Change](https://leetcode.com/problems/coin-change/) | Medium | -| [152. Maximum Product Subarray](https://leetcode.com/problems/maximum-product-subarray/) | Medium | -| [139. Word Break](https://leetcode.com/problems/word-break/) | Medium | -| [300. Longest Increasing Subsequence](https://leetcode.com/problems/longest-increasing-subsequence/) | Medium | - -### 2-D Dynamic Programming -![Array & Hashing](https://img.shields.io/badge/2_D_Dynamic_Programming-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [62. Unique Paths](https://leetcode.com/problems/unique-paths/) | Medium | -| [1143. Longest Common Subsequence](https://leetcode.com/problems/longest-common-subsequence/) | Medium | - -### Greedy -![Array & Hashing](https://img.shields.io/badge/Greedy-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [53. Maximum Subarray](https://leetcode.com/problems/maximum-subarray/) | Easy | -| [55. Jump Game](https://leetcode.com/problems/jump-game/) | Medium | - -### Intervals -![Array & Hashing](https://img.shields.io/badge/Intervals-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [57. Insert Interval](https://leetcode.com/problems/insert-interval/) | Hard | -| [56. Merge Intervals](https://leetcode.com/problems/merge-intervals/) | Medium | -| [435. Non Overlapping Intervals](https://leetcode.com/problems/non-overlapping-intervals/) | Medium | -| [252. Meeting Rooms](https://leetcode.com/problems/meeting-rooms/) | Easy | -| [253. Meeting Rooms II](https://leetcode.com/problems/meeting-rooms-ii/) | Medium | - -### Math & Geometry -![Array & Hashing](https://img.shields.io/badge/Math_&_Geometry-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [48. Rotate Image](https://leetcode.com/problems/rotate-image/) | Medium | -| [54. Spiral Matrix](https://leetcode.com/problems/spiral-matrix/) | Medium | -| [73. Set Matrix Zeroes](https://leetcode.com/problems/set-matrix-zeroes/) | Medium | - -### Bit Manipulation -![Array & Hashing](https://img.shields.io/badge/Bit_Manipulation-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [191. Number of 1 Bits](https://leetcode.com/problems/number-of-1-bits/) | Easy | -| [338. Counting Bits](https://leetcode.com/problems/counting-bits/) | Medium | -| [190. Reverse Bits](https://leetcode.com/problems/reverse-bits/) | Easy | -| [268. Missing Number](https://leetcode.com/problems/missing-number/) | Easy | -| [371. Sum of Two Integers](https://leetcode.com/problems/sum-of-two-integers/) | Medium | - - -## How to Use - -1. Clone or download this repository to your local machine. - -```bash -git clone https://github.com/mohsentabibian/LeetCode-Solutions/Blind-75-LeetCode.git -``` - -2. Navigate to the directory of the specific problem you want to solve. - -```bash -cd Blind-75-LeetCode/Problem-Directory -``` - -3. Open the problem's directory to find its description, code template, and solution(s). - -4. Solve the problem using your preferred programming language. - -5. Check the solution(s) provided in the directory for reference and to compare your solution. - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -## Disclaimer - -This repository is meant for educational purposes and to help individuals prepare for technical interviews. Please respect LeetCode's terms of use and guidelines when using this repository. - -## Code of Conduct - -We have a [Code of Conduct](CODE_OF_CONDUCT.md) that we expect all contributors to adhere to. By participating in this project, you agree to follow this code. - -## Security Policy - -We take security seriously. Please review our [Security Policy](SECURITY.md) for information on reporting security vulnerabilities. - -Happy coding! diff --git a/_build/html/_sources/SECURITY.md b/_build/html/_sources/SECURITY.md deleted file mode 100644 index 7c19993..0000000 --- a/_build/html/_sources/SECURITY.md +++ /dev/null @@ -1,42 +0,0 @@ -# Security Policy - -## Reporting a Vulnerability - -We take the security of the Blind 75 LeetCode repository seriously. If you believe you have found a security vulnerability, please help us by following these steps: - -1. **Do Not Disclose Publicly**: Please do not disclose the issue publicly until it has been addressed by our team. - -2. **Report Privately**: Create a GitHub issue with the title "Security Vulnerability Report" and provide a detailed description of the vulnerability. You can use a sample report template as follows: - - ``` - **Description** - A clear and concise description of the security vulnerability. - - **Steps to Reproduce** - Provide detailed steps on how to reproduce the vulnerability. - - **Expected Behavior** - Describe what you expected to happen. - - **Actual Behavior** - Describe what actually happened. - - **Additional Information** - Any additional information that can help us understand and reproduce the issue, such as environment details, configuration, or screenshots. - ``` - -3. **Secure Communication**: If the vulnerability involves sensitive data, please encrypt your communication with our PGP key. Contact us for our PGP key information. - -4. **Response**: We will acknowledge your report within 5 business days and provide an estimated timeline for the resolution. - -5. **Fix and Disclosure**: We will work to fix the issue promptly and privately. Once resolved, we will provide a security advisory and give credit to the reporter if desired. - -6. **Responsible Disclosure**: We encourage responsible disclosure. Please do not take advantage of the vulnerability or attempt to exploit it for malicious purposes. - -## Security Updates - -We are committed to promptly addressing and resolving any security issues. We recommend that you stay up-to-date with the latest releases of this repository, as they may include security updates and fixes. - -## Contact - -If you have any questions or need further assistance regarding security, you can contact us at mohsentabibian@gmail.com. diff --git a/_build/jupyter_execute/01. Array Hashing/1. Two Sum.ipynb b/_build/jupyter_execute/01. Array Hashing/1. Two Sum.ipynb deleted file mode 100644 index 5d55ca7..0000000 --- a/_build/jupyter_execute/01. Array Hashing/1. Two Sum.ipynb +++ /dev/null @@ -1,203 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 100: Same Tree\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Same Tree problem on LeetCode, click here!](https://leetcode.com/problems/same-tree/)\n", - "\n", - "---\n", - "Given the roots of two binary trees `p` and `q`, write a function to check if they are the same or not.\n", - "\n", - "Two binary trees are considered the same if they are structurally identical, and the nodes have the same value.\n", - "\n", - "**Constraints**\n", - "\n", - "1. The number of nodes in both trees is in the range `[0, 100]`.\n", - "2. $-10^4$ <= `Node.val` <= $10^4$" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "# Definition for a binary tree node.\n", - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " # Initialize a TreeNode with a value (val), left child, and right child.\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def isSameTree(p, q):\n", - " # Base case: If both p and q are None, the trees are the same.\n", - " if not p and not q:\n", - " return True\n", - " \n", - " # Base case: If either p or q is None (but not both), the trees are different.\n", - " if not p or not q:\n", - " return False\n", - " \n", - " # Check if the values of the current nodes (p.val and q.val) are equal.\n", - " if p.val != q.val:\n", - " return False\n", - " \n", - " # Recursively check the left and right subtrees of p and q.\n", - " # If both subtrees are the same, the entire trees are the same.\n", - " return isSameTree(p.left, q.left) and isSameTree(p.right, q.right)" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "In this code, we define a `TreeNode` class to represent binary tree nodes and a `isSameTree` function to check if two binary trees are the same. The function uses recursive traversal to compare the trees' structures and values.\n", - "\n", - "1. We start by defining a `TreeNode` class, which represents a node in a binary tree. Each node has a `val` (the node's value), a `left` child, and a right child. This class will help us create and work with binary trees.\n", - "2. Next, we define the `isSameTree` function, which checks if two binary trees (`p` and `q`) are the same.\n", - " + The base case for the recursion is when both `p` and `q` are `None`. In this case, they are considered the same, so we return `True`.\n", - " + If either `p` or `q` is `None` (but not both), they cannot be the same, so we return `False`.\n", - " + If the values of the current nodes `p.val` and `q.val` are not equal, we return `False` because the trees cannot be the same.\n", - " + Finally, we recursively check the left and right subtrees of `p` and `q` to see if they are the same." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "### Example 1\n", - "\n", - "#Input: `p = [1,2,3]`, `q = [1,2,3]`\n", - "\n", - "p1 = TreeNode(1, TreeNode(2), TreeNode(3))\n", - "q1 = TreeNode(1, TreeNode(2), TreeNode(3))\n", - "print(isSameTree(p1, q1)) " - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "### Example 2\n", - "\n", - "#Input: `p = [1,2]`, `q = [1,null,2]`\n", - "\n", - "p2 = TreeNode(1, TreeNode(2), None)\n", - "q2 = TreeNode(1, None, TreeNode(2))\n", - "print(isSameTree(p2, q2))" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "5897c29d-26f8-486a-878c-43c09ff25ce4", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "### Example 3\n", - "\n", - "#Input: p = [1,2,1], q = [1,1,2]\n", - "\n", - "p3 = TreeNode(1, TreeNode(2), TreeNode(1))\n", - "q3 = TreeNode(1, TreeNode(1), TreeNode(2))\n", - "print(isSameTree(p3, q3))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "**Time Complexity**\n", - "\n", - "The time complexity of the `isSameTree` function can be analyzed as follows:\n", - "\n", - "In the worst case, the function needs to visit every node in both trees once to determine if they are the same.\n", - "Since each node is visited exactly once, the time complexity is $O(n)$, where $n$ is the total number of nodes in the input trees.\n", - "\n", - "**Space Complexity**\n", - "The space complexity of the `isSameTree` function can be analyzed as follows:\n", - "\n", - "The space used by the function's call stack during recursion is proportional to the maximum depth of the binary trees.\n", - "In the worst case, when the trees are completely unbalanced (all nodes form a single branch), the maximum depth will be $n$, where $n$ is the total number of nodes in the input trees.\n", - "Therefore, the space complexity is $O(n)$ due to the recursive call stack.\n", - "In addition to the call stack, there is a small constant amount of space used for variables and comparisons within each recursive call, but this space is not significant in terms of the overall space complexity.\n", - "\n", - "**In summary:**\n", - "\n", - "+ Time Complexity: $O(n)$ where $n$ is the total number of nodes in the input trees.\n", - "+ Space Complexity: $O(n)$ due to the recursive call stack." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/01. Array Hashing/128. Longest Consecutive Sequence.ipynb b/_build/jupyter_execute/01. Array Hashing/128. Longest Consecutive Sequence.ipynb deleted file mode 100644 index 9256d0e..0000000 --- a/_build/jupyter_execute/01. Array Hashing/128. Longest Consecutive Sequence.ipynb +++ /dev/null @@ -1,203 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 128. Longest Consecutive Sequence\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Longest Consecutive Sequence problem on LeetCode, click here!](https://leetcode.com/problems/longest-consecutive-sequence/)\n", - "\n", - "---\n", - "\n", - "Given an unsorted array of integers `nums`, return *the length of the longest consecutive elements sequence.*\n", - "\n", - "You must write an algorithm that runs in `O(n)` time.\n", - "\n", - "*Constraints:**\n", - "- 0 <= `nums.length` <= $10^5$\n", - "- $-10^9$ <= `nums[i]` <= $10^9$\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "def longestConsecutive(nums):\n", - " if not nums:\n", - " return 0\n", - "\n", - " num_set = set(nums)\n", - " max_length = 0\n", - "\n", - " for num in num_set:\n", - " if num - 1 not in num_set:\n", - " current_num = num\n", - " current_length = 1\n", - "\n", - " while current_num + 1 in num_set:\n", - " current_num += 1\n", - " current_length += 1\n", - "\n", - " max_length = max(max_length, current_length)\n", - "\n", - " return max_length" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start by defining the `longestConsecutive` function that takes the `nums` array as input.\n", - "\n", - "2. We check if the `nums` array is empty. If it's empty, there are no consecutive elements, so we return 0.\n", - "\n", - "3. We create a Python set called `num_set` and insert all elements from the `nums` array into it. Using a set allows us to efficiently check for the existence of elements in O(1) time.\n", - "\n", - "4. We initialize a variable `max_length` to 0. This variable will keep track of the maximum length of consecutive elements sequence found.\n", - "\n", - "5. We iterate through the elements of the `num_set`. For each element `num`, we check if `num - 1` exists in the `num_set`. If it doesn't exist, it means `num` is the starting element of a potential consecutive sequence.\n", - "\n", - "6. Inside the loop, we initialize two variables: `current_num` to the current element `num` and `current_length` to 1. We start with a length of 1 because `num` itself is part of the sequence.\n", - "\n", - "7. We then enter a while loop that continues as long as `current_num + 1` exists in the `num_set`. This means we are incrementing the consecutive sequence.\n", - "\n", - "8. Inside the while loop, we increment `current_num` by 1 and also increment `current_length` by 1 to account for the next consecutive element.\n", - "\n", - "9. We compare `current_length` with the `max_length` and update `max_length` if the current sequence is longer.\n", - "\n", - "10. After the while loop, we move to the next element in the outer loop and repeat the process.\n", - "\n", - "11. Finally, we return the `max_length` as the result, which represents the length of the longest consecutive elements sequence in the `nums` array.\n", - "\n", - "The key idea here is to use a set to efficiently check for the existence of elements and to iterate through the elements, considering each element as the potential start of a consecutive sequence. By doing this, we can find the longest consecutive sequence in O(n) time complexity, where n is the number of elements in the array." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "nums1 = [100, 4, 200, 1, 3, 2]\n", - "print(longestConsecutive(nums1))" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "9\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "nums2 = [0, 3, 7, 2, 5, 8, 4, 6, 0, 1]\n", - "print(longestConsecutive(nums2)) " - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "The code is designed to run in O(n) time complexity, where n is the number of elements in the `nums` array. Here's the breakdown:\n", - "\n", - "1. Constructing the `num_set` by inserting all elements from `nums` into it takes O(n) time because we perform an insertion operation for each element in `nums`.\n", - "\n", - "2. The main loop iterates through the elements in `num_set`. In the worst case, each element is visited only once, so the loop itself takes O(n) time.\n", - "\n", - "3. Within the loop, we have a while loop that may also take O(n) time in the worst case. However, this while loop is nested inside the main loop, so its overall time complexity remains O(n).\n", - "\n", - "Therefore, the overall time complexity of the code is O(n).\n", - "\n", - "**Space Complexity:**\n", - "The space complexity of the code is determined by the space used by the `num_set` and a few additional variables. Here's the breakdown:\n", - "\n", - "1. `num_set` is a set that stores the unique elements from `nums`. In the worst case, it can store all n elements from `nums`, so the space complexity is O(n).\n", - "\n", - "2. The additional variables used, such as `max_length`, `current_num`, and `current_length`, have constant space requirements and do not depend on the size of the input array.\n", - "\n", - "Therefore, the overall space complexity of the code is O(n) due to the space used by the `num_set`." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. Write an algorithm that not only returns the length of the longest consecutive elements sequence but also returns the actual consecutive sequence itself.\n", - "\n", - "2. Extend the problem to allow elements to be considered consecutive if they are within a certain absolute difference (e.g., less than or equal to k) instead of exactly 1. Write an algorithm that finds the longest such sequence and runs in O(n) time." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/01. Array Hashing/217. Contains Duplicate.ipynb b/_build/jupyter_execute/01. Array Hashing/217. Contains Duplicate.ipynb deleted file mode 100644 index f7dbbe9..0000000 --- a/_build/jupyter_execute/01. Array Hashing/217. Contains Duplicate.ipynb +++ /dev/null @@ -1,210 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 217. Contains Duplicate\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Contains Duplicate problem on LeetCode, click here!](https://leetcode.com/problems/contains-duplicate/)\n", - "\n", - "---\n", - "\n", - "Given an integer array `nums`, return `true` if any value appears **at least twice** in the array, and return `false` if every element is distinct.\n", - "\n", - "**Constraints:**\n", - "- 1 <= `nums.length` <= $10^5$\n", - "- $-10^9$ <= `nums[i]` <= $10^9$\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "def containsDuplicate(nums):\n", - " # Create an empty set to store unique elements\n", - " unique_elements = set()\n", - " \n", - " # Iterate through the array\n", - " for num in nums:\n", - " # If the element is already in the set, return True\n", - " if num in unique_elements:\n", - " return True\n", - " # Otherwise, add it to the set\n", - " else:\n", - " unique_elements.add(num)\n", - " \n", - " # If the loop completes without finding duplicates, return False\n", - " return False" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. The `containsDuplicate` function takes a single argument, `nums`, which is the input integer array.\n", - "\n", - "2. Inside the function, an empty set called `unique_elements` is created. This set will be used to keep track of unique elements in the input array.\n", - "\n", - "3. The function then iterates through the input array `nums` using a `for` loop.\n", - "\n", - "4. For each element `num` in the array, it checks whether `num` is already in the `unique_elements` set using the `if num in unique_elements:` condition.\n", - "\n", - "5. If `num` is already in the set, it means there is a duplicate element in the array, and the function immediately returns `True`.\n", - "\n", - "6. If `num` is not in the set, it is added to the `unique_elements` set using `unique_elements.add(num)`.\n", - "\n", - "7. The loop continues to the next element, and the process repeats.\n", - "\n", - "8. If the loop completes without finding any duplicates, it means that all elements in the array are distinct, and the function returns `False`.\n", - "\n", - "The code efficiently utilizes a set data structure to keep track of unique elements while iterating through the array, allowing it to quickly detect duplicate elements. This code meets the problem's requirements and constraints, as explained earlier." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "nums1 = [1, 2, 3, 1]\n", - "print(containsDuplicate(nums1))" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 2\n", - "nums2 = [1, 2, 3, 4]\n", - "print(containsDuplicate(nums2))" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "e191cf7e-95f9-4e5c-a99b-146c2a779c0b", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 3\n", - "nums3 = [1, 1, 1, 3, 3, 4, 3, 2, 4, 2]\n", - "print(containsDuplicate(nums3))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code for the \"Contains Duplicate\" problem:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The primary operation that affects the time complexity is the `for` loop that iterates through the input array `nums`. In the worst case, the loop will iterate through all `n` elements of the array, where `n` is the length of the input array.\n", - "\n", - "- Iterating through the array: O(n)\n", - "\n", - "Inside the loop, we perform two operations:\n", - "\n", - "1. Checking whether an element exists in the `unique_elements` set (`if num in unique_elements`). This operation has an average time complexity of O(1) for a set.\n", - "2. Adding an element to the `unique_elements` set (`unique_elements.add(num)`), which also has an average time complexity of O(1) for a set.\n", - "\n", - "Since these operations are performed for each element in the array, the overall time complexity remains O(n).\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity is determined by the additional data structures used in the code, which are the `unique_elements` set.\n", - "\n", - "- `unique_elements` set: This set stores unique elements from the input array. In the worst case, if all elements in the input array are distinct, the set will store all `n` elements.\n", - "\n", - "Therefore, the space complexity is O(n) because, in the worst case, the set's size will grow linearly with the input array's size.\n", - "\n", - "**In summary**, the time complexity of the code is O(n), where `n` is the length of the input array, and the space complexity is also O(n) in the worst case. This code is efficient and meets the constraints of the problem." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **K Duplicates:** Modify the problem to return `true` if there are exactly K duplicate elements in the array. Write a function that takes an additional integer parameter K and returns `true` if there are exactly K duplicates.\n", - "2. **Frequency Count:** Write a function that returns a list of all the elements that appear more than once in the array, along with their frequencies." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/01. Array Hashing/238. Product of Array Except Self.ipynb b/_build/jupyter_execute/01. Array Hashing/238. Product of Array Except Self.ipynb deleted file mode 100644 index c5a69c0..0000000 --- a/_build/jupyter_execute/01. Array Hashing/238. Product of Array Except Self.ipynb +++ /dev/null @@ -1,191 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 238. Product of Array Except Self\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Product of Array Except Self problem on LeetCode, click here!](https://leetcode.com/problems/product-of-array-except-self/)\n", - "\n", - "---\n", - "Given an integer array `nums`, return *an array `answer` such that `answer[i]` is equal to the product of all the elements of `nums` except `nums[i]`.*\n", - "\n", - "The product of any prefix or suffix of `nums` is **guaranteed** to fit in a **32-bit** integer.\n", - "\n", - "You must write an algorithm that runs in O(n) time and without using the division operation.\n", - "\n", - "Constraints:\n", - "- 2 <= `nums.length` <= $10^5$\n", - "- `-30 <= nums[i] <= 30`\n", - "- The product of any prefix or suffix of `nums` is **guaranteed** to fit in a **32-bit** integer.\n", - "\n", - "**Follow-up:** Can you solve the problem in O(1) extra space complexity? (The output array **does not** count as extra space for space complexity analysis.)\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "def productExceptSelf(nums):\n", - " n = len(nums)\n", - " \n", - " # Initialize two arrays to store products to the left and right of each element\n", - " left_products = [1] * n\n", - " right_products = [1] * n\n", - " \n", - " # Calculate products to the left of each element\n", - " left_product = 1\n", - " for i in range(n):\n", - " left_products[i] = left_product\n", - " left_product *= nums[i]\n", - " \n", - " # Calculate products to the right of each element\n", - " right_product = 1\n", - " for i in range(n - 1, -1, -1):\n", - " right_products[i] = right_product\n", - " right_product *= nums[i]\n", - " \n", - " # Calculate the final answer using left and right products\n", - " answer = [left_products[i] * right_products[i] for i in range(n)]\n", - " \n", - " return answer" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. `n` is initialized as the length of the `nums` array.\n", - "2. Two arrays, `left_products` and `right_products`, are created, each with a length of `n` and filled with ones initially.\n", - "3. `left_product` is initialized to 1.\n", - "4. A loop iterates through the `nums` array, from left to right. For each element at index `i`, it stores the product of all elements to its left (including itself) in the `left_products` array and updates `left_product` accordingly.\n", - "5. `right_product` is initialized to 1.\n", - "6. Another loop iterates through the `nums` array in reverse order, from right to left. For each element at index `i`, it stores the product of all elements to its right (including itself) in the `right_products` array and updates `right_product`.\n", - "7. The final `answer` list is constructed by multiplying corresponding elements from the `left_products` and `right_products` arrays for each index `i`.\n", - "8. The function returns the `answer` list, which contains the desired results.\n", - "\n", - "Overall, this algorithm efficiently computes the product of all elements except the current element, as required. It runs in O(n) time complexity and uses O(n) extra space, which is within the problem's constraints." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[24, 12, 8, 6]\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "nums = [1,2,3,4]\n", - "result1 = productExceptSelf(nums)\n", - "print(result1)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[0, 0, 9, 0, 0]\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "nums = [-1,1,0,-3,3]\n", - "result2 = productExceptSelf(nums)\n", - "print(result2)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "1. The first loop iterates through the `nums` array to calculate the products to the left of each element. This loop runs in O(n) time, where n is the length of the `nums` array.\n", - "2. The second loop also iterates through the `nums` array in reverse order to calculate the products to the right of each element. This loop also runs in O(n) time.\n", - "3. The final loop constructs the `answer` list by multiplying elements from the `left_products` and `right_products` arrays. This loop runs in O(n) time.\n", - "\n", - "Since all the loops are independent and sequential, the overall time complexity is O(n).\n", - "\n", - "**Space Complexity:**\n", - "1. Two additional arrays, `left_products` and `right_products`, are created with a length of `n`, where `n` is the length of the `nums` array. Therefore, these arrays consume O(n) extra space.\n", - "2. The `left_product` and `right_product` variables are used to keep track of the product to the left and right of each element, respectively. These variables occupy O(1) extra space.\n", - "3. The `answer` list, which contains the final results, also consumes O(n) space, but it's not counted toward the extra space complexity analysis as per the problem's constraints.\n", - "\n", - "Overall, the space complexity is O(n) for this solution." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Handle Zeros in the Input**: Modify the solution to handle cases where the input array contains zeros. For example, if `nums = [0, 1, 2, 3, 0]`, the output should be `[0, 0, 0, 0, 0]` because any element multiplied by zero results in zero.\n", - "\n", - "2. **In-Place Modification**: Attempt to solve the problem with in-place modification of the `nums` array, where the output is stored directly in the input array without using any additional space." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/01. Array Hashing/242. Valid Anagram.ipynb b/_build/jupyter_execute/01. Array Hashing/242. Valid Anagram.ipynb deleted file mode 100644 index 5649123..0000000 --- a/_build/jupyter_execute/01. Array Hashing/242. Valid Anagram.ipynb +++ /dev/null @@ -1,192 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 242. Valid Anagram\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Valid Anagram problem on LeetCode, click here!](https://leetcode.com/problems/valid-anagram/)\n", - "\n", - "---\n", - "Given two strings `s` and `t`, return `true` if `t` is an anagram of `s`, and `false` otherwise.\n", - "\n", - "An **Anagram** is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.\n", - "\n", - "**Constraints:**\n", - "- 1 <= `s.length`, `t.length` <= $5 * 10^4$\n", - "- `s` and `t` consist of lowercase English letters.\n", - "\n", - "**Follow-up:** What if the inputs contain Unicode characters? How would you adapt your solution to such a case?\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "def isAnagram(s: str, t: str) -> bool:\n", - " # Check if the lengths of s and t are not equal\n", - " if len(s) != len(t):\n", - " return False\n", - "\n", - " # Create dictionaries to store character frequencies for s and t\n", - " countS, countT = {}, {}\n", - "\n", - " # Count character frequencies in s\n", - " for i in range(len(s)):\n", - " countS[s[i]] = 1 + countS.get(s[i], 0)\n", - "\n", - " # Count character frequencies in t\n", - " for i in range(len(t)):\n", - " countT[t[i]] = 1 + countT.get(t[i], 0)\n", - "\n", - " # Check if the character frequencies in s and t are the same\n", - " return countS == countT" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. The code defines a class called `Solution` with a method `isAnagram` that takes two input strings, `s` and `t`, and returns a boolean (`True` or `False`) based on whether `t` is an anagram of `s`.\n", - "\n", - "2. The first check performed in the method is whether the lengths of `s` and `t` are equal. If they are not equal, it immediately returns `False` because strings of different lengths cannot be anagrams of each other.\n", - "\n", - "3. Two dictionaries, `countS` and `countT`, are created to store the frequency of characters in `s` and `t`, respectively. These dictionaries will be used to count the occurrences of each character in the strings.\n", - "\n", - "4. The code then enters a loop to iterate through each character in string `s` using a `for` loop. Inside the loop, it updates the `countS` dictionary. The line `countS[s[i]] = 1 + countS.get(s[i], 0)` increments the count of character `s[i]` in `countS` by 1. If the character is not already in the dictionary, it initializes the count to 1.\n", - "\n", - "5. Similarly, the code iterates through each character in string `t` and updates the `countT` dictionary in the same way.\n", - "\n", - "6. After counting the character frequencies in both strings, the code compares the two dictionaries using `countS == countT`. If the dictionaries are equal, it means that both strings have the same character frequencies, and therefore, `t` is an anagram of `s`. In this case, the method returns `True`.\n", - "\n", - "7. If the dictionaries are not equal, the method returns `False`, indicating that `t` is not an anagram of `s`.\n", - "\n", - "In summary, this code efficiently determines whether two input strings are anagrams by counting the character frequencies in each string using dictionaries and then comparing these counts. If the character frequencies match, the strings are considered anagrams, and the method returns `True`; otherwise, it returns `False`." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "s = \"anagram\"\n", - "t = \"nagaram\"\n", - "print(isAnagram(s, t))" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 2\n", - "s = \"rat\"\n", - "t = \"car\"\n", - "print(isAnagram(s, t))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. The code first checks whether the lengths of the input strings `s` and `t` are equal, which takes constant time. This check has a time complexity of O(1).\n", - "\n", - "2. The code then iterates through both strings, `s` and `t`, once to count the character frequencies. Since both strings have a maximum length of 5 * 10^4, the worst-case scenario is that the code iterates through 5 * 10^4 characters in each string. This results in a linear time complexity of O(n), where n is the length of the longer of the two input strings (`s` or `t`).\n", - "\n", - "3. Finally, the code compares the two dictionaries `countS` and `countT` to check if the character frequencies match. This comparison takes O(n) time in the worst case, where n is the length of the longer string.\n", - "\n", - "Overall, the time complexity of the code is O(n), where n is the length of the longer input string.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. The code uses two dictionaries, `countS` and `countT`, to store the character frequencies of the input strings `s` and `t`. In the worst case, both dictionaries can contain all unique characters from the input strings. Since the input strings can have a maximum length of 5 * 10^4, the space complexity for these dictionaries is O(5 * 10^4) or simply O(n), where n is the length of the longer input string.\n", - "\n", - "2. The code uses a few additional variables for bookkeeping, but these variables have constant space requirements and do not depend on the input size. Therefore, they do not significantly impact the overall space complexity.\n", - "\n", - "**In summary**, the space complexity of the code is O(n), where n is the length of the longer input string." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Anagram Chains**: Given a list of words, find the longest chain of anagrams, where each word in the chain is an anagram of the previous word. For example, given [\"bat\", \"tab\", \"cat\", \"tac\", \"dog\"], the longest anagram chain is [\"bat\", \"tab\", \"cat\", \"tac\"].\n", - "\n", - "2. **Minimum Deletions to Make Anagrams**: Given two strings `s` and `t`, find the minimum number of character deletions required in both strings to make them anagrams of each other. For example, if `s = \"hello\"` and `t = \"billion\"`, you can remove the characters \"heo\" from `s` and \"billi\" from `t` to make them anagrams (\"lo\" and \"on\" are left in the two strings)." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/01. Array Hashing/347. Top K Frequent Elements.ipynb b/_build/jupyter_execute/01. Array Hashing/347. Top K Frequent Elements.ipynb deleted file mode 100644 index 1b11faf..0000000 --- a/_build/jupyter_execute/01. Array Hashing/347. Top K Frequent Elements.ipynb +++ /dev/null @@ -1,209 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 347. Top K Frequent Elements\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Top K Frequent Elements problem on LeetCode, click here!](https://leetcode.com/problems/top-k-frequent-elements/)\n", - "\n", - "---\n", - "Given an integer array `nums` and an integer `k`, return the `k` most frequent elements. You may return the answer in **any order**.\n", - "\n", - "Constraints:\n", - "- 1 <= `nums.length` <= $10^5$\n", - "- $-10^4$ <= `nums[i]` <= $10^4$\n", - "- `k` is in the range `[1, the number of unique elements in the array]`.\n", - "- It is **guaranteed** that the answer is **unique**.\n", - "\n", - "**Follow-up:** Your algorithm's time complexity must be better than $O(n\\ log\\ n)$, where n is the array's size.\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "def topKFrequent(nums, k):\n", - " # Create a dictionary to store the frequency of each element\n", - " count = {}\n", - " # Create a list of lists to store elements with the same frequency\n", - " frequency = [[] for i in range(len(nums) + 1)]\n", - "\n", - " # Count the frequency of each element in nums\n", - " for n in nums:\n", - " count[n] = 1 + count.get(n, 0)\n", - "\n", - " # Place elements in the freq list according to their frequency\n", - " for n, c in count.items():\n", - " frequency[c].append(n)\n", - "\n", - " res = []\n", - " # Traverse freq list from the end (higher frequencies)\n", - " for i in range(len(frequency) - 1, 0, -1):\n", - " for n in frequency[i]:\n", - " res.append(n)\n", - " if len(res) == k:\n", - " return res" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. `def topKFrequent(nums, k):`: This is a function that takes two arguments: `nums`, which is the input array of integers, and `k`, which is the number of most frequent elements to return.\n", - "\n", - "2. `count = {}`: This dictionary `count` will be used to store the frequency of each unique element in the `nums` array. The keys are elements from the input array, and the values are their corresponding frequencies.\n", - "\n", - "3. `frequency = [[] for i in range(len(nums) + 1)]`: This creates a list of empty lists called `frequency`. It's used to store elements based on their frequencies, similar to the `freq` list in the previous code. The size of this list is set to be one greater than the length of the input `nums`.\n", - "\n", - "4. `for n in nums:`: This loop iterates through each element `n` in the input `nums` array.\n", - "\n", - "5. `count[n] = 1 + count.get(n, 0)`: This line counts the frequency of each element `n` in the `nums` array. It uses the `count.get(n, 0)` method to retrieve the current count of `n` from the `count` dictionary. If `n` is not in the dictionary, it defaults to 0. It then increments the count by 1.\n", - "\n", - "6. After the above loop, the `count` dictionary will contain counts of each unique element in the `nums` array.\n", - "\n", - "7. `for n, c in count.items():`: This loop iterates through the items (key-value pairs) of the `count` dictionary. `n` represents the element, and `c` represents its frequency.\n", - "\n", - "8. `frequency[c].append(n)`: This line places the element `n` into the bucket corresponding to its frequency `c`. Buckets are represented by the `frequency` list. For example, if an element `n` has a frequency of 3, it will be added to `frequency[3]`.\n", - "\n", - "9. After this loop, the `frequency` list will contain buckets of elements grouped by their frequencies.\n", - "\n", - "10. `res = []`: This list `res` will be used to store the k most frequent elements.\n", - "\n", - "11. `for i in range(len(freq) - 1, 0, -1):`: This loop iterates in reverse order through the `frequency` list, starting from the highest frequency and going down to 1. Note that there is a typo here; it should be `frequency` instead of `freq`.\n", - "\n", - "12. `for n in frequency[i]:`: For each element `n` in the current bucket (i.e., elements with frequency `i`), it appends `n` to the result list `res`.\n", - "\n", - "13. `if len(res) == k:`: Once `res` contains k elements, the code exits and returns the result.\n", - "\n", - "The code efficiently finds the k most frequent elements in the input array without using sorting, similar to the previous explanation, with the only difference being the variable names (e.g., `frequency` instead of `freq`)." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 2]\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "nums = [1,1,1,2,2,3]\n", - "k = 2\n", - "result1 = topKFrequent(nums, k)\n", - "print(result1)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1]\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "nums = [1]\n", - "k = 1\n", - "result2 = topKFrequent(nums, k)\n", - "print(result2)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "1. The first loop that counts the frequency of elements by iterating through `nums` has a time complexity of O(n), where n is the number of elements in the input array `nums`.\n", - "\n", - "2. The second loop iterates through the keys in the `count` dictionary, which has at most `k` unique elements (as per the constraints). Therefore, the second loop also has a time complexity of O(k).\n", - "\n", - "3. The third loop iterates through the `frequency` list, which has a length equal to the maximum frequency of elements in `nums`. In the worst case, this loop can have a time complexity of O(n), where n is the number of elements in `nums`.\n", - "\n", - "Overall, the dominant factor in terms of time complexity is the loop that iterates through the `count` dictionary. So, the total time complexity of the code is O(n + k).\n", - "\n", - "**Space Complexity:**\n", - "1. The `count` dictionary stores the frequency of each unique element in `nums`. In the worst case, it can have at most `k` unique elements, so the space complexity for `count` is O(k).\n", - "\n", - "2. The `frequency` list is used to store elements grouped by their frequencies. It has a length of `len(nums) + 1`, which can be at most 105 based on the constraints. Therefore, the space complexity for `frequency` is O(105).\n", - "\n", - "3. The `res` list stores the k most frequent elements, which can be at most `k` elements, so the space complexity for `res` is O(k).\n", - "\n", - "**In summary**, the space complexity is dominated by the `count` dictionary and the `frequency` list, both of which have a space complexity of O(k + 105)." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Optimized k Most Frequent Elements:** Modify the code to find the k most frequent elements in an array while ensuring that the time complexity is O(n + klogk). You can use a priority queue (heap) to achieve this.\n", - "\n", - "2. **Handling Duplicate Frequencies:** Extend the code to handle cases where multiple elements have the same frequency and are among the k most frequent elements. Ensure that the output contains exactly k elements." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/01. Array Hashing/49. Group Anagrams.ipynb b/_build/jupyter_execute/01. Array Hashing/49. Group Anagrams.ipynb deleted file mode 100644 index 256e8f7..0000000 --- a/_build/jupyter_execute/01. Array Hashing/49. Group Anagrams.ipynb +++ /dev/null @@ -1,221 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 49. Group Anagrams\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Group Anagrams problem on LeetCode, click here!](https://leetcode.com/problems/group-anagrams/)\n", - "\n", - "---\n", - "Given an array of strings `strs`, group **the anagrams** together. You can return the answer in **any order**.\n", - "\n", - "An **Anagram** is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.\n", - "\n", - "**Constraints:**\n", - "- 1 <= `strs.length <= $10^4$\n", - "- `0 <= strs[i].length <= 100`\n", - "- `strs[i]` consists of lowercase English letters.\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "from collections import defaultdict\n", - "\n", - "\n", - "def groupAnagrams(strs):\n", - " ans = defaultdict(list)\n", - "\n", - " # Iterate through the list of input strings\n", - " for s in strs:\n", - " # Initialize a list to represent character counts for each character (a-z)\n", - " count = [0] * 26\n", - "\n", - " # Count the occurrences of each character in the current word\n", - " for c in s:\n", - " count[ord(c) - ord(\"a\")] += 1\n", - "\n", - " # Use a tuple of character counts as the key and append the word to the anagram group\n", - " ans[tuple(count)].append(s)\n", - "\n", - " # Convert the values (lists of anagrams) to a list of lists\n", - " return list(ans.values())" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. Inside the method, a `defaultdict` called `ans` is created to store anagram groups. This dictionary will have a list as its default value, meaning that each key in the dictionary will be associated with an empty list by default.\n", - "\n", - "2. The code then iterates through the list of input strings, `strs`, using a `for` loop. For each word `s` in `strs`, it performs the following steps:\n", - "\n", - " - It initializes a list `count` of length 26, where each element represents the count of a specific character (a-z) in the word `s`.\n", - "\n", - " - The code then iterates through the characters of `s`. For each character `c`, it increments the corresponding count in the `count` list based on its ASCII value.\n", - "\n", - " - After counting the characters in `s`, it converts the `count` list into a tuple `tuple(count)` to use as a key for the `ans` dictionary.\n", - "\n", - " - It appends the word `s` to the list associated with the key (tuple) in the `ans` dictionary. This groups all anagrams of the same word together under the same key.\n", - "\n", - "3. After processing all words in `strs`, the code converts the values of the `ans` dictionary (which are lists of anagrams) to a list of lists using the `list()` constructor.\n", - "\n", - "4. Finally, the code returns the list of anagram groups, which is the result of grouping the anagrams in the input list.\n", - "\n", - "In summary, the code efficiently groups anagrams together by counting the characters in each word and using a dictionary to store them under the same key. The result is a list of lists, where each inner list represents a group of anagrams." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[['eat', 'tea', 'ate'], ['tan', 'nat'], ['bat']]\n" - ] - } - ], - "source": [ - "# Example 1: Group anagrams from a list of words\n", - "strs1 = [\"eat\", \"tea\", \"tan\", \"ate\", \"nat\", \"bat\"]\n", - "result1 = groupAnagrams(strs1)\n", - "print(result1)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[['']]\n" - ] - } - ], - "source": [ - "# Example 2: Group anagrams from a list with an empty string\n", - "strs2 = [\"\"]\n", - "result2 = groupAnagrams(strs2)\n", - "print(result2)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "c8367e2a-e7d5-4e18-8235-2870e341a04b", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[['a']]\n" - ] - } - ], - "source": [ - "# Example 3: Group anagrams from a list with a single word\n", - "strs3 = [\"a\"]\n", - "result3 = groupAnagrams(strs3)\n", - "print(result3)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `groupAnagrams` method:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. First, we create an instance of the `Solution` class, which is an O(1) operation.\n", - "\n", - "2. Inside the `groupAnagrams` method, we iterate through the list of input strings `strs` once in a loop:\n", - " - For each word in `strs`, we perform character counting, which is done in O(K) time, where K is the maximum length of a word in the list.\n", - "\n", - "3. The overall time complexity of the method is O(N * K), where N is the number of words in the input list `strs`, and K is the maximum length of a word in `strs`.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. We use a `defaultdict` called `ans` to store the anagram groups. In the worst case, each word belongs to a distinct anagram group, so the space complexity for `ans` is O(N).\n", - "\n", - "2. Within the loop, we create a `count` list of length 26 to store character counts for each word. This is a fixed-size list and does not depend on the input size, so it has a constant space complexity of O(26), which is effectively O(1).\n", - "\n", - "3. The space used for other variables is also constant and does not depend on the input size.\n", - "\n", - "4. The final result, `result`, is a list of lists that contains the grouped anagrams. In the worst case, each word is a distinct anagram group, so the space complexity for `result` is O(N).\n", - "\n", - "5. The overall space complexity of the method is O(N) due to the space used by `ans` and `result`. The space used by the `count` list and other variables is constant and does not significantly affect the overall space complexity.\n", - "\n", - "**In summary,** the time complexity of the `groupAnagrams` method is O(N * K), and the space complexity is O(N), where N is the number of words in the input list `strs`, and K is the maximum length of a word in `strs`." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Anagramic Palindromes**: Given a list of strings, find all the groups of anagrams where each group contains words that can be rearranged into a palindrome. For example, in the list [\"bat\", \"tab\", \"act\", \"tac\", \"dog\"], there are two groups: [\"bat\", \"tab\", \"act\", \"tac\"] and [\"dog\"].\n", - "\n", - "2. **Largest Anagram Group**: Given a list of strings, find the largest group of anagrams. Return the list of anagrams in that group. If there are multiple largest groups, return all of them." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/01. Array Hashing/659. Encode and Decode Strings.ipynb b/_build/jupyter_execute/01. Array Hashing/659. Encode and Decode Strings.ipynb deleted file mode 100644 index 2fae2a5..0000000 --- a/_build/jupyter_execute/01. Array Hashing/659. Encode and Decode Strings.ipynb +++ /dev/null @@ -1,198 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 659· Encode and Decode Strings\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Encode and Decode Strings problem on LintCode, click here!](https://www.lintcode.com/problem/659/)\n", - "\n", - "---\n", - "Design an algorithm to encode a list of strings to a string. The encoded string is then sent over the network and is decoded back to the original list of strings.\n", - "\n", - "Please implement `encode` and `decode`.\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "class Codec:\n", - "\n", - " def encode(self, strs):\n", - " \"\"\"Encodes a list of strings to a single string.\n", - " \n", - " :type strs: List[str]\n", - " :rtype: str\n", - " \"\"\"\n", - " encoded = \"\"\n", - " for s in strs:\n", - " encoded += s.replace(':', '::') + ':;'\n", - " return encoded\n", - "\n", - " def decode(self, s):\n", - " \"\"\"Decodes a single string to a list of strings.\n", - " \n", - " :type s: str\n", - " :rtype: List[str]\n", - " \"\"\"\n", - " decoded = []\n", - " i = 0\n", - " while i < len(s):\n", - " end = s.find(':;', i)\n", - " if end == -1:\n", - " end = len(s)\n", - " decoded.append(s[i:end].replace('::', ':'))\n", - " i = end + 2\n", - " return decoded" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We define a class called `Codec` to encapsulate the encoding and decoding operations for a list of strings.\n", - "\n", - "2. In the `encode` method, we take a list of strings (`strs`) as input and return a single encoded string. The encoding process involves concatenating the strings together with a delimiter `:;`. We iterate through each string in the input list, replace any occurrence of `:` with `::` (to avoid conflicts with the delimiter), and then append `:;` to indicate the end of that string.\n", - "\n", - "3. In the `decode` method, we take an encoded string (`s`) as input and return a list of strings. The decoding process involves splitting the encoded string using the `:;` delimiter. We start from the beginning of the encoded string (`i = 0`) and repeatedly find the next occurrence of `:;`. We extract the substring between the current position (`i`) and the next delimiter (`end`). Before adding it to the result list, we replace any `::` with `:` to revert the encoding. We then update the current position `i` to be after the delimiter, so we can find the next substring in the next iteration.\n", - "\n", - "4. Finally, we create an instance of the `Codec` class and test it with two examples:\n", - "\n", - "By using the `:;` delimiter and handling the `::` escaping, this code can encode and decode lists of strings, preserving the original content even if it contains colons or the delimiter itself." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['lint', 'code', 'love', 'you']\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "codec = Codec()\n", - "\n", - "input1 = [\"lint\", \"code\", \"love\", \"you\"]\n", - "encoded1 = codec.encode(input1)\n", - "decoded1 = codec.decode(encoded1)\n", - "print(decoded1)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['we', 'say', ':', 'yes']\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "codec = Codec() \n", - "\n", - "input2 = [\"we\", \"say\", \":\", \"yes\"]\n", - "encoded2 = codec.encode(input2)\n", - "decoded2 = codec.decode(encoded2)\n", - "print(decoded2) " - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `encode` and `decode` methods in the provided code.\n", - "\n", - "**Encode Method (`encode`):**\n", - "\n", - "- Time Complexity: O(n * m)\n", - " - Here, `n` is the number of strings in the input list `strs`, and `m` is the average length of these strings.\n", - " - In the worst case, for each string in the list, we iterate over its characters once to replace any colons (`:`) with double colons (`::`) and then append `:;`. This is done for each string in the list.\n", - "\n", - "- Space Complexity: O(n * m)\n", - " - The space complexity is also O(n * m) because we build the encoded string by concatenating the modified strings. In the worst case, the encoded string can be of the same length as the original strings.\n", - "\n", - "**Decode Method (`decode`):**\n", - "\n", - "- Time Complexity: O(n * m)\n", - " - Similar to the encode method, we iterate through the encoded string in the decode method. In the worst case, we may have to scan each character in the encoded string to find the `:;` delimiter.\n", - "\n", - "- Space Complexity: O(n * m)\n", - " - The space complexity of the decode method is also O(n * m) because we build the list of decoded strings, which can be of the same length as the encoded string.\n", - "\n", - "Overall, both the `encode` and `decode` methods have time and space complexities of O(n * m), where `n` is the number of strings in the input list, and `m` is the average length of these strings. The space complexity arises from storing the encoded or decoded strings, and the time complexity arises from iterating through the characters in these strings." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Multiple Delimiters**: Modify the code to allow for multiple delimiters, not just one. Each string could have its own delimiter, and the code should be able to handle this complexity.\n", - "\n", - "2. **Optimize Encoding**: Modify the `encode` method to achieve a more efficient encoding algorithm. Try to minimize the length of the encoded string while ensuring that it can be correctly decoded." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/02. Two Pointers/11. Container With Most Water.ipynb b/_build/jupyter_execute/02. Two Pointers/11. Container With Most Water.ipynb deleted file mode 100644 index e330eb0..0000000 --- a/_build/jupyter_execute/02. Two Pointers/11. Container With Most Water.ipynb +++ /dev/null @@ -1,212 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 11. Container With Most Water\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Container With Most Water problem on LeetCode, click here!](https://leetcode.com/problems/container-with-most-water/)\n", - "\n", - "---\n", - "You are given an integer array `height` of length `n`. There are `n` vertical lines drawn such that the two endpoints of the $i^{th}$ line are `(i, 0)` and `(i, height[i])`.\n", - "\n", - "Find two lines that together with the x-axis form a container, such that the container contains the most water.\n", - "\n", - "Return *the maximum amount of water a container can store.*\n", - "\n", - "**Notice** that you may not slant the container.\n", - "\n", - "**Constraints:**\n", - "- `n == height.length`\n", - "- 2 <= `n` <= $10^5$\n", - "- 0 <= `height[i]` <= $10^4$\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "def maxArea(height):\n", - " # Initialize the maximum area to 0.\n", - " max_area = 0\n", - " # Initialize two pointers, one at the beginning (left) and one at the end (right) of the array.\n", - " left = 0\n", - " right = len(height) - 1\n", - "\n", - " # Iterate until the left pointer is less than the right pointer.\n", - " while left < right:\n", - " # Calculate the height of the container, which is the minimum height of the two lines.\n", - " h = min(height[left], height[right])\n", - " # Calculate the width of the container, which is the distance between the two pointers.\n", - " width = right - left\n", - " # Calculate the area of the container using height and width and update max_area if it's greater.\n", - " max_area = max(max_area, h * width)\n", - "\n", - " # Move the pointer with the shorter line inward.\n", - " if height[left] < height[right]:\n", - " left += 1\n", - " else:\n", - " right -= 1\n", - "\n", - " # Continue this process until left < right, and then return the maximum area.\n", - " return max_area" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start with initializing `max_area` to 0, which will store the maximum area of water that can be contained by the lines.\n", - "\n", - "2. Two pointers, `left` and `right`, are initialized to the beginning and end of the input `height` array.\n", - "\n", - "3. The main loop runs while `left` is less than `right`. This ensures that we are checking all possible pairs of lines in a systematic way.\n", - "\n", - "4. Inside the loop:\n", - " - We calculate the height of the container `h` as the minimum of the heights at the `left` and `right` pointers. This represents the height of the water the container can hold.\n", - " - We calculate the width of the container as the difference between `right` and `left`. This represents the distance between the two lines.\n", - " - We calculate the area of the container using `h * width` and update `max_area` if the calculated area is greater than the current `max_area`.\n", - "\n", - "5. After calculating the area and updating `max_area`, we move one of the pointers. We move the pointer pointing to the shorter line inward because moving the pointer pointing to the taller line won't increase the height and will only decrease the width, which will result in a smaller area.\n", - "\n", - "6. We continue this process until `left` is no longer less than `right`, indicating that we have checked all possible pairs of lines.\n", - "\n", - "7. Finally, we return the `max_area` which contains the maximum area of water that can be contained by two lines from the input array." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Output: 49\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "height1 = [1, 8, 6, 2, 5, 4, 8, 3, 7]\n", - "result1 = maxArea(height1)\n", - "print(\"Output:\", result1)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Output: 1\n" - ] - } - ], - "source": [ - "# Example 2\n", - "height2 = [1, 1]\n", - "result2 = maxArea(height2)\n", - "print(\"Output:\", result2)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "e191cf7e-95f9-4e5c-a99b-146c2a779c0b", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Output: 45\n" - ] - } - ], - "source": [ - "# Additional Example\n", - "height3 = [3, 9, 3, 4, 7, 2, 12, 6]\n", - "result3 = maxArea(height3)\n", - "print(\"Output:\", result3)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `maxArea` function:\n", - "\n", - "**Time Complexity:**\n", - "The function uses a two-pointer approach to find the maximum area of water. In the worst case, both the left and right pointers traverse the entire input array once. Therefore, the time complexity is O(n), where n is the number of elements in the `height` array.\n", - "\n", - "**Space Complexity:**\n", - "The function uses a constant amount of extra space for variables like `max_area`, `left`, `right`, `h`, and `width`. It does not use any data structures whose space consumption depends on the input size. As a result, the space complexity is O(1), which means it has constant space complexity.\n", - "\n", - "**In summary,** the `maxArea` function has a time complexity of O(n) and a space complexity of O(1), making it an efficient algorithm for finding the maximum area of water that can be contained by two lines in the input array." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Optimization Challenge:** Modify the maxArea function to not only return the maximum area but also the indices of the two lines that form the container with the maximum area.\n", - "2. **Variant Problem:** Instead of finding the maximum area of water, find the minimum amount of water required to fill all the gaps between the lines. You'll need to return the total water volume needed." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/02. Two Pointers/125. Valid Palindrome.ipynb b/_build/jupyter_execute/02. Two Pointers/125. Valid Palindrome.ipynb deleted file mode 100644 index 12c7daa..0000000 --- a/_build/jupyter_execute/02. Two Pointers/125. Valid Palindrome.ipynb +++ /dev/null @@ -1,210 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 125. Valid Palindrome\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Valid Palindrome problem on LeetCode, click here!](https://leetcode.com/problems/valid-palindrome/)\n", - "\n", - "---\n", - "\n", - "A phrase is a **palindrome** if, after converting all uppercase letters into lowercase letters and removing all non-alphanumeric characters, it reads the same forward and backward. Alphanumeric characters include letters and numbers.\n", - "\n", - "Given a string `s`, *return `true` if it is a **palindrome**, or `false` otherwise.*\n", - "\n", - "**Constraints:**\n", - "\n", - "- 1 <= `s.length` <= $2*10^5$\n", - "- `s` consists only of printable ASCII characters.\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "def isPalindrome(s):\n", - " # Step 1: Convert the input string to lowercase\n", - " s = s.lower()\n", - " \n", - " # Step 2: Remove all non-alphanumeric characters from the string\n", - " cleaned_s = ''.join(c for c in s if c.isalnum())\n", - " \n", - " # Step 3: Initialize two pointers, one at the beginning and one at the end of the cleaned string\n", - " left, right = 0, len(cleaned_s) - 1\n", - " \n", - " # Step 4: Compare characters using the two pointers while moving them towards each other\n", - " while left < right:\n", - " if cleaned_s[left] != cleaned_s[right]:\n", - " return False # If characters don't match, it's not a palindrome\n", - " left += 1\n", - " right -= 1\n", - " \n", - " # Step 5: If the loop completes without returning False, it's a palindrome\n", - " return True" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. The `isPalindrome` function takes an input string `s`.\n", - "\n", - "2. It starts by converting the input string to lowercase using `s.lower()`. This step ensures that the function is case-insensitive when checking for palindromes.\n", - "\n", - "3. Next, it removes all non-alphanumeric characters from the string and stores the result in the `cleaned_s` variable. It does this by iterating through each character in the input string and only keeping characters that are alphanumeric (letters and digits). This step removes spaces, punctuation, and other non-alphanumeric characters.\n", - "\n", - "4. The function then initializes two pointers, `left` and `right`, which will be used to compare characters from the beginning and end of the cleaned string.\n", - "\n", - "5. In a while loop, it compares characters using the two pointers while moving them towards each other. The loop continues until the `left` pointer is less than the `right` pointer. This is done to check all characters in the cleaned string.\n", - "\n", - "6. Inside the loop, it checks if the characters at the `left` and `right` pointers don't match. If they don't match, it means the input is not a palindrome, so the function returns `False`.\n", - "\n", - "7. If the characters at the `left` and `right` pointers match, the pointers are moved closer to each other by incrementing `left` and decrementing `right`.\n", - "\n", - "8. The loop continues to compare characters until it either finds a mismatch (returning `False`) or until the `left` pointer is greater than or equal to the `right` pointer. If the loop completes without finding a mismatch, it means the input is a palindrome, so the function returns `True`.\n", - "\n", - "In summary, the code converts the input string to lowercase, removes non-alphanumeric characters, and then uses two pointers to compare characters from the cleaned string's beginning and end. If all characters match during the comparison, the function returns `True`, indicating that the input is a palindrome. If any characters do not match, it returns `False`." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "input1 = \"A man, a plan, a canal: Panama\"\n", - "output1 = isPalindrome(input1)\n", - "print(output1)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 2\n", - "input2 = \"race a car\"\n", - "output2 = isPalindrome(input2)\n", - "print(output2)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "e191cf7e-95f9-4e5c-a99b-146c2a779c0b", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 3\n", - "input3 = \"\"\n", - "output3 = isPalindrome(input3)\n", - "print(output3)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `isPalindrome` function that uses two pointers:\n", - "\n", - "1. **Time Complexity:**\n", - " - Converting the input string to lowercase using `s.lower()` takes O(n) time, where 'n' is the length of the input string.\n", - " - Removing non-alphanumeric characters using the list comprehension `''.join(c for c in s if c.isalnum())` also takes O(n) time because it iterates through each character in the string once.\n", - " - The comparison of characters using the two pointers (`left` and `right`) is done in a loop that runs until `left` is less than `right`. In the worst case, the loop iterates through half of the string, so it takes O(n/2) time, which is still considered O(n).\n", - "\n", - " Therefore, the overall time complexity of the `isPalindrome` function is O(n), where 'n' is the length of the input string.\n", - "\n", - "2. **Space Complexity:**\n", - " - The space complexity is primarily determined by the additional string `cleaned_s` created to store the cleaned version of the input string. In the worst case, if all characters in the input string are alphanumeric, this cleaned string can be as large as the original input string.\n", - " - Additionally, the function uses two pointers, `left` and `right`, which consume constant space and do not depend on the size of the input.\n", - "\n", - "**In summary,** the overall space complexity of the `isPalindrome` function is O(n) in the worst case, where 'n' is the length of the input string. The space complexity is dominated by the space required for `cleaned_s`." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Longest Palindromic Substring:** Given a string `s`, find and return the longest palindromic substring within `s`. For example, if `s = \"babad\"`, the function should return `\"bab\"` or `\"aba\"`.\n", - "2. **Palindrome with Limited Characters:** Given a string `s` and a list of characters `allowed_chars`, check if `s` is a palindrome considering only the characters from `allowed_chars`. Ignore all other characters. For example, if `s = \"A man, a plan, a canal: Panama\"` and `allowed_chars = ['a', 'm', 'n', 'p']`, the function should return `True`." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/02. Two Pointers/15. 3Sum.ipynb b/_build/jupyter_execute/02. Two Pointers/15. 3Sum.ipynb deleted file mode 100644 index 15d189a..0000000 --- a/_build/jupyter_execute/02. Two Pointers/15. 3Sum.ipynb +++ /dev/null @@ -1,242 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 15. 3Sum\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the 3Sum problem on LeetCode, click here!](https://leetcode.com/problems/3sum/)\n", - "\n", - "---\n", - "Given an integer array nums, *return all the triplets `[nums[i], nums[j], nums[k]]` such that `i != j`, `i != k`, and `j != k`, and `nums[i] + nums[j] + nums[k] == 0`.*\n", - "\n", - "**Notice** that the solution set must not contain duplicate triplets.\n", - "\n", - "**Constraints:**\n", - "\n", - "- `3 <= nums.length <= 3000`\n", - "- $-10^5$ <= `nums[i]` <= $10^5$\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "def threeSum(nums):\n", - " # Sort the input array in ascending order\n", - " nums.sort()\n", - " triplets = []\n", - " \n", - " for i in range(len(nums) - 2):\n", - " # Skip duplicates to avoid duplicate triplets\n", - " if i > 0 and nums[i] == nums[i - 1]:\n", - " continue\n", - " \n", - " left, right = i + 1, len(nums) - 1\n", - " \n", - " while left < right:\n", - " # Calculate the total sum of the current triplet\n", - " total = nums[i] + nums[left] + nums[right]\n", - " \n", - " if total == 0:\n", - " # If the total is zero, we found a valid triplet\n", - " triplets.append([nums[i], nums[left], nums[right]])\n", - " \n", - " # Skip duplicates of left and right pointers\n", - " while left < right and nums[left] == nums[left + 1]:\n", - " left += 1\n", - " while left < right and nums[right] == nums[right - 1]:\n", - " right -= 1\n", - " \n", - " # Move the pointers to the next unique elements\n", - " left += 1\n", - " right -= 1\n", - " elif total < 0:\n", - " # If the total is negative, we need to increase the sum by moving the left pointer to the right\n", - " left += 1\n", - " else:\n", - " # If the total is positive, we need to decrease the sum by moving the right pointer to the left\n", - " right -= 1\n", - " \n", - " return triplets" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. It starts by sorting the input array `nums` in ascending order. Sorting helps in efficiently finding triplets that sum up to zero.\n", - "\n", - "2. It initializes an empty list `triplets` to store the unique triplets that meet the given conditions.\n", - "\n", - "3. The code then iterates through the `nums` array using a loop with index `i`. This loop will consider each element of the array as a potential starting point for a triplet.\n", - "\n", - "4. Inside the loop, it checks for duplicates and skips them. This is done to ensure that the solution set does not contain duplicate triplets. If `nums[i]` is the same as the previous element `nums[i-1]`, it continues to the next iteration of the loop.\n", - "\n", - "5. Two pointers, `left` and `right`, are initialized. `left` starts just after the current element `nums[i]`, and `right` starts at the end of the array.\n", - "\n", - "6. The code enters another loop with `left` and `right` pointers, trying to find a triplet that sums up to zero.\n", - "\n", - "7. It calculates the `total` sum of the current triplet as `nums[i] + nums[left] + nums[right]`.\n", - "\n", - "8. If `total` is zero, it means a valid triplet is found, so it appends `[nums[i], nums[left], nums[right]]` to the `triplets` list. Then, it moves both the `left` and `right` pointers to their next unique elements while skipping duplicates.\n", - "\n", - "9. If `total` is less than zero, it means the sum is negative, so it increments the `left` pointer to move towards a larger sum.\n", - "\n", - "10. If `total` is greater than zero, it means the sum is positive, so it decrements the `right` pointer to move towards a smaller sum.\n", - "\n", - "11. This process continues until all possible triplets have been considered.\n", - "\n", - "12. Finally, the function returns the `triplets` list, which contains all the unique triplets that sum up to zero in the sorted `nums` array." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[-1, -1, 2], [-1, 0, 1]]\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "nums = [-1, 0, 1, 2, -1, -4]\n", - "result = threeSum(nums)\n", - "print(result)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[]\n" - ] - } - ], - "source": [ - "# Example 2\n", - "nums = [0, 1, 1]\n", - "result = threeSum(nums)\n", - "print(result)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "e191cf7e-95f9-4e5c-a99b-146c2a779c0b", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[0, 0, 0]]\n" - ] - } - ], - "source": [ - "# Example 3\n", - "nums = [0, 0, 0]\n", - "result = threeSum(nums)\n", - "print(result)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `threeSum` function:\n", - "\n", - "**Time Complexity:**\n", - "1. Sorting the input array `nums` takes O(n log n) time, where n is the length of the array.\n", - "\n", - "2. The outer loop runs for each element of the array, so it iterates O(n) times.\n", - "\n", - "3. Inside the outer loop, we have a while loop with two pointers (`left` and `right`). In the worst case, the while loop can iterate O(n) times (when all elements are unique).\n", - "\n", - "4. Inside the while loop, we have constant time operations (additions, comparisons, and list appends).\n", - "\n", - "Overall, the time complexity of the `threeSum` function is dominated by the sorting step, so it is O(n log n) due to the sorting. The other operations inside the loops contribute linearly but are dominated by the sorting step.\n", - "\n", - "**Space Complexity:**\n", - "1. The space used by the `triplets` list to store the output triplets is O(k), where k is the number of unique triplets that sum up to zero. In the worst case, this can be O(n^2/3) because there can be roughly O(n^2) possible triplets, and many of them may sum up to zero.\n", - "\n", - "2. Other than the `triplets` list, the function uses only a constant amount of additional space for variables like `i`, `left`, `right`, and `total`.\n", - "\n", - "Overall, the space complexity of the `threeSum` function is O(k), where k is the number of unique triplets that meet the criteria. It's important to note that the space complexity does not depend on the size of the input array but rather on the number of valid triplets found.\n", - "\n", - "**In summary:**\n", - "- Time Complexity: O(n log n) due to sorting (dominant factor) and O(n^2) in the worst case for the nested loops.\n", - "- Space Complexity: O(k) for storing the output triplets, where k is the number of unique triplets that meet the criteria." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **K-Sum Problem:** Generalize the problem to the K-Sum problem, where instead of finding triplets that sum to zero, you need to find K elements that sum to a target value. Implement a function for this generalization.\n", - "2. **Count the Number of Unique Triplets:** Modify the algorithm to count the number of unique triplets that satisfy the conditions instead of returning the triplets themselves. This will require some modifications to handle duplicates efficiently." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/03. Sliding Window/121. Best Time to Buy and Sell Stock.ipynb b/_build/jupyter_execute/03. Sliding Window/121. Best Time to Buy and Sell Stock.ipynb deleted file mode 100644 index 451a21d..0000000 --- a/_build/jupyter_execute/03. Sliding Window/121. Best Time to Buy and Sell Stock.ipynb +++ /dev/null @@ -1,185 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 121. Best Time to Buy and Sell Stock\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Best Time to Buy and Sell Stock problem on LeetCode, click here!](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/)\n", - "\n", - "---\n", - "\n", - "You are given an array `prices` where `prices[i]` is the price of a given stock on the $i^{th}$ day.\n", - "\n", - "You want to maximize your profit by choosing a **single day** to buy one stock and choosing a **different day in the future** to sell that stock.\n", - "\n", - "*Return the maximum profit you can achieve from this transaction. If you cannot achieve any profit, return `0`.*\n", - "\n", - "**Constraints:**\n", - "\n", - "- 1 <= `prices.length` <= $10^5$\n", - "- 0 <= `prices[i]` <= $10^4$\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "def maxProfit(prices):\n", - " if not prices:\n", - " return 0\n", - " \n", - " min_price = prices[0]\n", - " max_profit = 0\n", - " \n", - " for price in prices:\n", - " # Update the minimum price if a lower price is encountered\n", - " min_price = min(min_price, price)\n", - " # Calculate the profit if selling at the current price\n", - " max_profit = max(max_profit, price - min_price)\n", - " \n", - " return max_profit" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "- The `maxProfit` function takes a single argument, `prices`, which is a list of stock prices.\n", - "- The first line of the function checks if the `prices` list is empty. If it's empty, there are no prices to analyze, so the function returns 0 (no profit can be made).\n", - "\n", - "- Then, we initialize two variables:\n", - " - `min_price`: This variable will keep track of the minimum price seen so far. We initialize it with the price of the first day in the list (`prices[0]`).\n", - " - `max_profit`: This variable will keep track of the maximum profit we can achieve. We initialize it to 0 because initially, we haven't made any profit.\n", - "\n", - "- We start iterating through the `prices` list, where `price` represents the stock price for the current day.\n", - "\n", - "- In each iteration, we check if the current `price` is lower than the `min_price` we've seen so far. If it is, we update `min_price` to the current `price`. This is because we want to buy the stock at the lowest possible price.\n", - "\n", - "- Next, we calculate the profit we would make if we sold the stock at the current `price` (assuming we bought it at `min_price`). We do this by subtracting `min_price` from the current `price`. This represents the profit for the current day.\n", - "\n", - "- We also use the `max` function to keep track of the maximum profit seen so far. If the profit calculated for the current day is greater than the `max_profit` we've seen previously, we update `max_profit` with this higher value.\n", - "\n", - "- Finally, after iterating through all the days in the `prices` list, we return `max_profit`, which represents the maximum profit that can be achieved by buying and selling a single stock." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "5\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "prices1 = [7, 1, 5, 3, 6, 4]\n", - "print(maxProfit(prices1))" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "prices2 = [7, 6, 4, 3, 1]\n", - "print(maxProfit(prices2))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "- The code iterates through the `prices` array once, examining each price exactly once.\n", - "- Within the loop, there are constant-time operations such as comparisons, additions, and subtractions.\n", - "- Therefore, the time complexity of this code is O(n), where n is the length of the `prices` array. It performs a linear number of operations relative to the size of the input.\n", - "\n", - "**Space Complexity:**\n", - "- The space complexity of the code is constant, O(1).\n", - "- Regardless of the size of the input `prices` array, the code only uses a fixed amount of additional memory to store two variables (`min_price` and `max_profit`) and a few loop variables.\n", - "- The memory usage does not depend on the size of the input, so it is considered constant space complexity.\n", - "\n", - "**In summary:**\n", - "- Time Complexity: O(n) where n is the length of the `prices` array.\n", - "- Space Complexity: O(1) (constant space usage)." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Multiple Transactions Allowed:** Modify the problem to allow multiple transactions (buy and sell multiple times), but you must sell before buying again. Find the maximum profit in this scenario.\n", - "2. **K Transactions Allowed:** Extend the problem to allow at most k transactions. Find the maximum profit considering this constraint.\n", - "3. **With Transaction Fee:** Introduce a transaction fee for each buy/sell operation. Modify the code to maximize profit while considering the transaction fee." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/03. Sliding Window/3. Longest Substring Without Repeating Characters.ipynb b/_build/jupyter_execute/03. Sliding Window/3. Longest Substring Without Repeating Characters.ipynb deleted file mode 100644 index ded03f3..0000000 --- a/_build/jupyter_execute/03. Sliding Window/3. Longest Substring Without Repeating Characters.ipynb +++ /dev/null @@ -1,206 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 3. Longest Substring Without Repeating Characters\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Longest Substring Without Repeating Characters problem on LeetCode, click here!](https://leetcode.com/problems/longest-substring-without-repeating-characters/)\n", - "\n", - "---\n", - "Given a string `s`, find the length of the **longest substring** without repeating characters.\n", - "\n", - "**Constraints:**\n", - "\n", - "- 0 <= `s.length` <= $5 * 10^4$\n", - "- `s` consists of English letters, digits, symbols and spaces.\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "def length_of_longest_substring(s):\n", - " # Create a dictionary to store the index of each character's last occurrence.\n", - " char_index = {}\n", - " \n", - " # Initialize variables to keep track of the start and end of the current substring.\n", - " start = 0\n", - " max_length = 0\n", - " \n", - " for end in range(len(s)):\n", - " # If the character is in the dictionary and its last occurrence is after the start of the current substring,\n", - " # update the start of the substring to the next character after its last occurrence.\n", - " if s[end] in char_index and char_index[s[end]] >= start:\n", - " start = char_index[s[end]] + 1\n", - " \n", - " # Update the last occurrence index of the current character.\n", - " char_index[s[end]] = end\n", - " \n", - " # Calculate the length of the current substring and update the maximum length if necessary.\n", - " current_length = end - start + 1\n", - " max_length = max(max_length, current_length)\n", - " \n", - " return max_length" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start by defining a function called `length_of_longest_substring` that takes a single argument `s`, which is the input string for which we want to find the length of the longest substring without repeating characters.\n", - "\n", - "2. We create a dictionary called `char_index` to store the index of the last occurrence of each character in the input string. This dictionary will help us keep track of where each character was last seen.\n", - "\n", - "3. We initialize two variables, `start` and `max_length`. \n", - " - `start` represents the start index of the current substring without repeating characters. It starts at 0.\n", - " - `max_length` is used to keep track of the maximum length found so far and is initially set to 0.\n", - "\n", - "4. We then iterate through the input string `s` using a for loop, where the loop variable `end` represents the current end index of the substring we are considering.\n", - "\n", - "5. Inside the loop:\n", - " - We check if the character `s[end]` is already in the `char_index` dictionary and if its last occurrence is within or after the current substring. If so, it means that we've encountered a repeating character, and we need to update the `start` of the substring to the next character after the last occurrence of `s[end]`. This ensures that we have a new valid substring without repeating characters.\n", - " - We then update the `char_index` dictionary by storing the current index `end` as the last occurrence index of the character `s[end]`.\n", - "\n", - "6. Next, we calculate the length of the current substring without repeating characters, which is `current_length = end - start + 1`. We add 1 to account for the fact that the indices are zero-based.\n", - "\n", - "7. We update the `max_length` with the maximum of its current value and the `current_length`. This step ensures that we keep track of the longest valid substring we have encountered so far.\n", - "\n", - "8. The loop continues to iterate through the input string, and at the end, we return the `max_length`, which represents the length of the longest substring without repeating characters." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "print(length_of_longest_substring(\"abcabcbb\"))" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "print(length_of_longest_substring(\"bbbbb\"))" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "cf04eba0-0ead-4e8b-ba33-4316ea64a9d3", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "print(length_of_longest_substring(\"pwwkew\"))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "Let's analyze the time and space complexity of the `length_of_longest_substring` function:\n", - "\n", - "**Time Complexity:**\n", - "- The function iterates through the input string `s` using a single for loop. The loop runs from the beginning of the string to the end once.\n", - "- Inside the loop, we perform constant-time operations such as dictionary lookups and updates, comparisons, and arithmetic operations.\n", - "- Therefore, the time complexity of the function is O(n), where n is the length of the input string `s`.\n", - "\n", - "**Space Complexity:**\n", - "- The primary data structure that consumes space in this function is the `char_index` dictionary.\n", - "- In the worst case, if there are no repeating characters in the input string, the dictionary can store all unique characters in the string.\n", - "- Therefore, the space complexity is O(min(n, m)), where n is the length of the input string `s`, and m is the number of unique characters in the string. In the worst case, when all characters are unique, m is equal to n, so the space complexity is O(n).\n", - "- Additionally, there are a few integer variables used for indices and lengths, which consume constant space.\n", - "- Overall, the space complexity of the function is O(min(n, m)) or simply O(n) in the worst case.\n", - "\n", - "**In summary,** the time complexity of the `length_of_longest_substring` function is O(n), and the space complexity is O(n) in the worst case due to the `char_index` dictionary. This algorithm provides an efficient way to find the length of the longest substring without repeating characters in linear time." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Longest Substring with K Distinct Characters:** Modify the problem to find the length of the longest substring with exactly K distinct characters. For example, given the input string \"abcabcbb\" and K = 2, the answer would be 4 because the longest substring with two distinct characters is \"abca.\"\n", - "2. **Longest Substring with Unique Characters:** Write a function to find the length of the longest substring in a given string where all characters are unique. For example, given the input string \"abcabcbb,\" the answer would be 4 because \"abcd\" is the longest substring with unique characters." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/03. Sliding Window/424. Longest Repeating Character Replacement.ipynb b/_build/jupyter_execute/03. Sliding Window/424. Longest Repeating Character Replacement.ipynb deleted file mode 100644 index df4b0d3..0000000 --- a/_build/jupyter_execute/03. Sliding Window/424. Longest Repeating Character Replacement.ipynb +++ /dev/null @@ -1,189 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 424. Longest Repeating Character Replacement\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Longest Repeating Character Replacement problem on LeetCode, click here!](https://leetcode.com/problems/longest-repeating-character-replacement/)\n", - "\n", - "---\n", - "You are given a string `s` and an integer `k`. You can choose any character of the string and change it to any other uppercase English character. You can perform this operation at most `k` times.\n", - "\n", - "*Return the length of the longest substring containing the same letter you can get after performing the above operations.*\n", - "\n", - "**Constraints:**\n", - "\n", - "- 1 <= `s.length` <= $10^5$\n", - "- `s` consists of only uppercase English letters.\n", - "- `0 <= k <= s.length`" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "def characterReplacement(s, k):\n", - " max_length = 0 # Initialize the maximum length\n", - " max_count = 0 # Initialize the maximum count of repeating characters\n", - " start = 0 # Initialize the start of the sliding window\n", - " char_count = {} # Dictionary to store the count of each character\n", - "\n", - " for end in range(len(s)):\n", - " # Update the count of the current character in the dictionary\n", - " char_count[s[end]] = char_count.get(s[end], 0) + 1\n", - " \n", - " # Update the maximum count of repeating characters\n", - " max_count = max(max_count, char_count[s[end]])\n", - " \n", - " # Check if the current window size is greater than k\n", - " if (end - start + 1) - max_count > k:\n", - " # Move the start of the window to the right\n", - " char_count[s[start]] -= 1\n", - " start += 1\n", - " \n", - " # Update the maximum length\n", - " max_length = max(max_length, end - start + 1)\n", - "\n", - " return max_length" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We initialize some variables:\n", - " - `max_length` to keep track of the maximum length of the substring containing the same letter.\n", - " - `max_count` to keep track of the maximum count of repeating characters within the current window.\n", - " - `start` to represent the start index of the sliding window.\n", - " - `char_count` is a dictionary that will store the count of each character within the current window.\n", - "\n", - "2. We use a `for` loop to iterate through the characters of the string `s`.\n", - "\n", - "3. Inside the loop, we do the following for each character at position `end`:\n", - " - Update the count of the current character in the `char_count` dictionary.\n", - " - Update the `max_count` to be the maximum of the current `max_count` and the count of the current character. This keeps track of the maximum count of repeating characters within the current window.\n", - "\n", - "4. We check if the current window size (the difference between `end` and `start` plus one) minus the `max_count` is greater than `k`. This condition checks whether we have exceeded the allowed number of replacements (`k`) within the current window.\n", - "\n", - " - If we have exceeded the allowed replacements, it means we need to shrink the window from the left side. We do this by moving the `start` of the window to the right and decrementing the count of the character at `s[start]` in the `char_count` dictionary. This effectively removes characters from the left side of the window until we have a valid window again.\n", - "\n", - " - By doing this, we ensure that the difference between the current window size and the `max_count` is always less than or equal to `k`.\n", - "\n", - "5. After each character, we update the `max_length` to be the maximum of the current `max_length` and the size of the current window (`end - start + 1`).\n", - "\n", - "6. Finally, we return `max_length`, which holds the length of the longest substring containing the same letter with at most `k` replacements." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "s1 = \"ABAB\"\n", - "k1 = 2\n", - "print(characterReplacement(s1, k1))" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "s2 = \"AABABBA\"\n", - "k2 = 1\n", - "print(characterReplacement(s2, k2))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "- The code uses a single `for` loop to iterate through the characters of the input string `s`. The loop runs from the beginning to the end of the string.\n", - "- Inside the loop, we perform constant-time operations such as updating the `char_count` dictionary and updating variables like `max_count` and `max_length`.\n", - "- The code's time complexity is primarily determined by the loop, which iterates through each character in the string once. Therefore, the time complexity is O(n), where n is the length of the input string `s`.\n", - "\n", - "**Space Complexity:**\n", - "- The code uses several variables to store information, but the space they consume is constant and does not depend on the size of the input string. These variables include `max_length`, `max_count`, `start`, and `char_count`. Therefore, the space complexity is O(1) or constant space.\n", - "\n", - "**In summary**, the time complexity of the code is O(n), where n is the length of the input string, and the space complexity is O(1), as it uses a constant amount of additional space regardless of the input size. This algorithm efficiently solves the problem with a linear time complexity." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Optimization Challenge:** Modify the code to find the longest substring containing the same letter with at most k replacements in O(n) time complexity and O(1) space complexity. Hint: You may need to update the approach to achieve this.\n", - "2. **Variation with Lowercase Letters:** Extend the problem to include both uppercase and lowercase English letters in the input string s. Write a function that can handle this extended input and still find the longest substring with at most k replacements efficiently." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/03. Sliding Window/76. Minimum Window Substring.ipynb b/_build/jupyter_execute/03. Sliding Window/76. Minimum Window Substring.ipynb deleted file mode 100644 index cf22c86..0000000 --- a/_build/jupyter_execute/03. Sliding Window/76. Minimum Window Substring.ipynb +++ /dev/null @@ -1,260 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 76. Minimum Window Substring\n", - "\n", - "**Difficulty:** Hard\n", - "\n", - "**Link to Problem:** [To see the Minimum Window Substring problem on LeetCode, click here!](https://leetcode.com/problems/minimum-window-substring/)\n", - "\n", - "---\n", - "Given two strings `s` and `t` of lengths `m` and `n` respectively, return *the **minimum window substring** of `s` such that every character in `t` (**including duplicates**) is included in the window. If there is no such substring, return the empty string `\"\"`.*\n", - "\n", - "The testcases will be generated such that the answer is **unique**.\n", - "\n", - "**Constraints:**\n", - "\n", - "- `m == s.length`\n", - "- `n == t.length`\n", - "- 1 <= `m, n` <= $10^5$\n", - "- `s` and `t` consist of uppercase and lowercase English letters.\n", - "\n", - "**Follow up**: Could you find an algorithm that runs in $O(m + n)$ time?" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "def min_window_substring(s, t):\n", - " if not s or not t:\n", - " return \"\"\n", - "\n", - " # Initialize dictionaries to keep track of character counts for t and the current window in s.\n", - " t_dict = {}\n", - " current_window_dict = {}\n", - " \n", - " # Populate t_dict with character counts for string t.\n", - " for char in t:\n", - " t_dict[char] = t_dict.get(char, 0) + 1\n", - "\n", - " # Initialize pointers for the sliding window.\n", - " left = 0\n", - " min_len = float('inf')\n", - " min_window = \"\"\n", - " required_chars = len(t_dict)\n", - "\n", - " # Initialize a variable to keep track of how many required characters have been found in the current window.\n", - " found_chars = 0\n", - "\n", - " # Iterate over the string s using the right pointer.\n", - " for right in range(len(s)):\n", - " char = s[right]\n", - "\n", - " # Update the current_window_dict.\n", - " current_window_dict[char] = current_window_dict.get(char, 0) + 1\n", - "\n", - " # Check if the current character is a required character and if its count matches the required count.\n", - " if char in t_dict and current_window_dict[char] == t_dict[char]:\n", - " found_chars += 1\n", - "\n", - " # Try to minimize the window by moving the left pointer.\n", - " while left <= right and found_chars == required_chars:\n", - " # Calculate the current window size.\n", - " window_size = right - left + 1\n", - "\n", - " # If the current window is smaller than the minimum found so far, update min_len and min_window.\n", - " if window_size < min_len:\n", - " min_len = window_size\n", - " min_window = s[left:right+1]\n", - "\n", - " # Move the left pointer to the right to shrink the window.\n", - " left_char = s[left]\n", - " current_window_dict[left_char] -= 1\n", - "\n", - " # Check if the character removed from the window was a required character.\n", - " if left_char in t_dict and current_window_dict[left_char] < t_dict[left_char]:\n", - " found_chars -= 1\n", - "\n", - " # Move the left pointer further to continue shrinking the window.\n", - " left += 1\n", - "\n", - " return min_window" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start by checking if either of the input strings `s` or `t` is empty. If either of them is empty, we return an empty string since there can't be any valid substring in this case.\n", - "\n", - "2. We initialize two dictionaries: `t_dict` and `current_window_dict`. These dictionaries will be used to keep track of character counts in the string `t` and the current window in string `s`, respectively.\n", - "\n", - "3. We populate the `t_dict` dictionary by iterating through string `t`. For each character, we increment its count in the dictionary using `t_dict.get(char, 0) + 1`. This allows us to count the occurrences of each character in `t`.\n", - "\n", - "4. We initialize two pointers: `left` and `right`. The `left` pointer will represent the start of the current window, and the `right` pointer will represent the end of the current window. We also initialize `min_len` to store the length of the minimum window found so far, and `min_window` to store the actual minimum window substring.\n", - "\n", - "5. We determine the number of required characters in `t` (i.e., the number of distinct characters in `t`) and store it in the variable `required_chars`.\n", - "\n", - "6. We initialize a variable `found_chars` to keep track of how many required characters have been found in the current window. Initially, it is set to 0.\n", - "\n", - "7. We iterate over the string `s` using the `right` pointer. In each iteration, we do the following:\n", - "\n", - " - Update the `current_window_dict` by incrementing the count of the current character.\n", - " \n", - " - Check if the current character is a required character (present in `t_dict`) and if its count in the `current_window_dict` matches the required count from `t_dict`. If so, we increment `found_chars`.\n", - "\n", - "8. After updating the window, we attempt to minimize the window size by moving the `left` pointer to the right. In this step, we:\n", - "\n", - " - Calculate the size of the current window.\n", - " \n", - " - If the current window size is smaller than the minimum found so far (`min_len`), we update `min_len` and `min_window` to store the current window substring.\n", - " \n", - " - Move the `left` pointer to the right to shrink the window.\n", - " \n", - " - Check if the character being removed from the window was a required character. If it was, we decrement `found_chars`.\n", - " \n", - " - Continue moving the `left` pointer further to continue shrinking the window if the window still contains all required characters.\n", - "\n", - "9. Finally, we return `min_window`, which will contain the minimum window substring that contains all characters from `t`." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "BANC\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "print(min_window_substring(\"ADOBECODEBANC\", \"ABC\"))" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "a\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "print(min_window_substring(\"a\", \"a\")) " - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "6c69a707-02af-4212-b2e7-1881d62a62d2", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "print(min_window_substring(\"a\", \"aa\")) " - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the `min_window_substring` function:\n", - "\n", - "**Time Complexity:**\n", - "- The main loop iterates through the string `s` from left to right using the `right` pointer. This loop runs in O(m) time, where 'm' is the length of string `s`.\n", - "\n", - "- Inside the loop, we have a while loop that moves the `left` pointer to the right to shrink the window as needed. In the worst case, this while loop can also run in O(m) time because in the worst case, we may have to move the `left` pointer all the way to the end of the string.\n", - "\n", - "- Within each iteration of the while loop, we perform constant time operations, such as updating dictionaries and comparing character counts.\n", - "\n", - "- The initialization of the `t_dict` dictionary takes O(n) time, where 'n' is the length of string `t`.\n", - "\n", - "Therefore, the overall time complexity of the function is O(m + n) because the dominant factor is the length of string `s`, and the length of string `t` has a smaller impact.\n", - "\n", - "**Space Complexity:**\n", - "- The space complexity is determined by the space used by the `t_dict` dictionary, the `current_window_dict` dictionary, and a few variables.\n", - "\n", - "- The `t_dict` dictionary stores character counts for string `t`. In the worst case, when all characters in `t` are distinct, this dictionary can have a maximum of 'n' key-value pairs. So, the space complexity for `t_dict` is O(n).\n", - "\n", - "- The `current_window_dict` dictionary stores character counts for the current window. In the worst case, it can have a maximum of 'm' key-value pairs. So, the space complexity for `current_window_dict` is also O(m).\n", - "\n", - "- Other variables used in the function, such as `left`, `right`, `min_len`, `min_window`, `required_chars`, and `found_chars`, are all of constant size and do not depend on the input sizes.\n", - "\n", - "**In summary**, the overall space complexity of the function is O(max(m, n)), which means it is determined by the larger of the two input strings' lengths. This is because the space used for `t_dict` and `current_window_dict` dominates the space complexity." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Smallest Distinct Substring:** Instead of finding the minimum window substring containing all characters, find the smallest distinct (unique) substring of s that contains all characters from t. This variation adds complexity because you must find a substring with distinct characters.\n", - "2. **No Extra Space:** Solve the problem without using any extra space, such as dictionaries or arrays, other than a constant amount of space. This is a significant optimization challenge." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/04. Stack/20. Valid Parentheses.ipynb b/_build/jupyter_execute/04. Stack/20. Valid Parentheses.ipynb deleted file mode 100644 index 04c0280..0000000 --- a/_build/jupyter_execute/04. Stack/20. Valid Parentheses.ipynb +++ /dev/null @@ -1,212 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 20. Valid Parentheses\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Valid Parentheses problem on LeetCode, click here!](https://leetcode.com/problems/valid-parentheses/)\n", - "\n", - "---\n", - "\n", - "Given a string s containing just the characters `'('`, `')'`, `'{'`, `'}'`, `'['` and `']'`, determine if the input string is valid.\n", - "\n", - "An input string is valid if:\n", - "\n", - "1. Open brackets must be closed by the same type of brackets.\n", - "2. Open brackets must be closed in the correct order.\n", - "3. Every close bracket has a corresponding open bracket of the same type.\n", - "\n", - "**Constraints:**\n", - "\n", - "- 1 <= `s.length` <= $10^4$\n", - "- `s` consists of parentheses only `'()[]{}'`." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "def isValid(s):\n", - " # Create an empty stack to store opening brackets\n", - " stack = []\n", - " \n", - " # Define a mapping for matching brackets\n", - " bracket_mapping = {')': '(', '}': '{', ']': '['}\n", - " \n", - " # Iterate through the characters in the input string\n", - " for char in s:\n", - " # If the character is an opening bracket, push it onto the stack\n", - " if char in bracket_mapping.values():\n", - " stack.append(char)\n", - " # If the character is a closing bracket\n", - " elif char in bracket_mapping.keys():\n", - " # Pop the top element from the stack if it exists, or use a dummy value '#'\n", - " top_element = stack.pop() if stack else '#'\n", - " # If the popped element does not match the corresponding opening bracket, return False\n", - " if bracket_mapping[char] != top_element:\n", - " return False\n", - " # If the character is not a bracket, ignore it\n", - " \n", - " # After processing the entire string, if there are any unmatched opening brackets left in the stack, return False\n", - " return len(stack) == 0" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start by defining the `isValid` function that takes a single argument `s`, which is the input string containing parentheses and brackets.\n", - "\n", - "2. Inside the function, we create an empty stack, which is a list in Python, to store opening brackets as we encounter them in the input string. The stack will help us keep track of the brackets and their order.\n", - "\n", - "3. We define a `bracket_mapping` dictionary that maps each closing bracket to its corresponding opening bracket. This mapping will be used to check if a closing bracket matches the most recent opening bracket in the stack.\n", - "\n", - "4. We iterate through each character `char` in the input string `s` using a `for` loop.\n", - "\n", - "5. If the character `char` is an opening bracket (i.e., it exists in the `values()` of `bracket_mapping`), we push it onto the stack using the `append()` method.\n", - "\n", - "6. If the character `char` is a closing bracket (i.e., it exists in the `keys()` of `bracket_mapping`), we need to check if it matches the corresponding opening bracket. To do this, we pop the top element from the stack (if it exists) and store it in `top_element`. We use a dummy value `'#'` if the stack is empty to avoid errors.\n", - "\n", - "7. We then compare `top_element` with the corresponding opening bracket using `bracket_mapping[char]`. If they do not match, it means the string is not valid, and we return `False`.\n", - "\n", - "8. If the character `char` is not a bracket, we simply ignore it and continue the loop.\n", - "\n", - "9. After processing the entire string, we check if there are any unmatched opening brackets left in the stack. If the stack is empty, it means all opening brackets have been properly matched and closed, and we return `True`. Otherwise, we return `False`.\n", - "\n", - "10. Finally, we provide some test cases at the bottom of the code to demonstrate how the function works for different input strings." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "print(isValid(\"()\")) " - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "print(isValid(\"()[]{}\")) " - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "6c69a707-02af-4212-b2e7-1881d62a62d2", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "print(isValid(\"(]\")) " - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the `isValid` function:\n", - "\n", - "**Time Complexity:**\n", - "- The function iterates through each character in the input string `s` once, performing constant-time operations for each character.\n", - "- Pushing and popping elements from the stack (list) also takes constant time in most cases.\n", - "- Therefore, the overall time complexity of the function is $O(n)$, where $n$ is the length of the input string `s`.\n", - "\n", - "**Space Complexity:**\n", - "- The space complexity of the function is determined by the space used by the stack and the `bracket_mapping` dictionary.\n", - "- In the worst case, if the input string `s` consists entirely of opening brackets, the stack can potentially contain all of these opening brackets, resulting in a space complexity of $O(n)$ in terms of the stack.\n", - "- The `bracket_mapping` dictionary has a constant number of key-value pairs (3 pairs in this case).\n", - "- Therefore, the overall space complexity of the function is $O(n)$, where $n$ is the length of the input string `s`, mainly due to the stack space.\n", - "\n", - "**In summary:**\n", - "- The time complexity is $O(n)$ because we iterate through the string once.\n", - "- The space complexity is $O(n)$ due to the stack used to keep track of opening brackets." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Valid Expressions:** Modify the problem to validate not only brackets but also arithmetic expressions containing parentheses, such as \"$2 * (3 + 5) / (4 - 2)$\".\n", - "2. **Valid Parentheses Combinations:**\n", - "Write a function to generate all valid combinations of n pairs of parentheses, where $n$ is a positive integer. For example, for $n = 3$, the valid combinations are [\"((()))\", \"(()())\", \"(())()\", \"()(())\", \"()()()\"]." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/05. Binary Search/153. Find Minimum in Rotated Sorted Array.ipynb b/_build/jupyter_execute/05. Binary Search/153. Find Minimum in Rotated Sorted Array.ipynb deleted file mode 100644 index eb4858b..0000000 --- a/_build/jupyter_execute/05. Binary Search/153. Find Minimum in Rotated Sorted Array.ipynb +++ /dev/null @@ -1,220 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 153. Find Minimum in Rotated Sorted Array\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Find Minimum in Rotated Sorted Array problem on LeetCode, click here!](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/)\n", - "\n", - "---\n", - "\n", - "Suppose an array of length `n` sorted in ascending order is **rotated** between `1` and `n` times. For example, the array `nums = [0,1,2,4,5,6,7]` might become:\n", - "\n", - "- `[4,5,6,7,0,1,2]` if it was rotated `4` times.\n", - "- `[0,1,2,4,5,6,7]` if it was rotated `7` times.\n", - "\n", - "Notice that **rotating** an array `[a[0], a[1], a[2], ..., a[n-1]]` 1 time results in the array `[a[n-1], a[0], a[1], a[2], ..., a[n-2]]`.\n", - "\n", - "Given the sorted rotated array `nums` of **unique** elements, return *the minimum element of this array.*\n", - "\n", - "You must write an algorithm that runs in $O(log\\ n)$ time.\n", - " \n", - "\n", - "**Constraints:**\n", - "\n", - "- `n == nums.length`\n", - "- `1 <= n <= 5000`\n", - "- `-5000 <= nums[i] <= 5000`\n", - "- All the integers of `nums` are **unique**.\n", - "- `nums` is sorted and rotated between `1` and `n` times." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "def findMin(nums):\n", - " left, right = 0, len(nums) - 1\n", - " \n", - " while left < right:\n", - " mid = left + (right - left) // 2\n", - " \n", - " # If the mid element is greater than the rightmost element,\n", - " # it means the minimum element is in the right half.\n", - " if nums[mid] > nums[right]:\n", - " left = mid + 1\n", - " # If the mid element is less than or equal to the rightmost element,\n", - " # it means the minimum element is in the left half or at the mid itself.\n", - " else:\n", - " right = mid\n", - " \n", - " # The loop will break when left and right converge to the minimum element.\n", - " # At this point, left (or right) will be pointing to the minimum element.\n", - " return nums[left]" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. The function `findMin(nums)` takes an input list `nums`, which represents the rotated sorted array.\n", - "\n", - "2. Initialize two pointers `left` and `right` to track the current search range. Initially, `left` is set to 0 (the beginning of the array), and `right` is set to `len(nums) - 1` (the end of the array).\n", - "\n", - "3. Enter a `while` loop with the condition `left < right`. This loop continues until `left` and `right` converge to a single element, which will be the minimum element in the rotated array.\n", - "\n", - "4. Inside the loop, calculate the middle index `mid` using integer division. This helps in finding the middle element of the current search range.\n", - "\n", - "5. Check if the element at the middle index (`nums[mid]`) is greater than the element at the rightmost index (`nums[right]`). If this condition is true, it means that the minimum element must be in the right half of the current search range. So, update `left` to `mid + 1`, effectively eliminating the left half of the search range.\n", - "\n", - "6. If the condition from step 5 is not met, it implies that the minimum element can be in the left half of the current search range or could be the element at the `mid` index itself. In this case, update `right` to `mid`, effectively eliminating the right half of the search range.\n", - "\n", - "7. Repeat steps 4-6 until `left` and `right` converge to the minimum element.\n", - "\n", - "8. When the loop exits, it means that `left` (or `right`) points to the minimum element in the array.\n", - "\n", - "9. Return `nums[left]` (or `nums[right]`) as the result, which is the minimum element in the rotated sorted array." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n" - ] - } - ], - "source": [ - "### Example 1:\n", - "nums1 = [3, 4, 5, 1, 2]\n", - "print(findMin(nums1))" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "nums2 = [4, 5, 6, 7, 0, 1, 2]\n", - "print(findMin(nums2))" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "6c69a707-02af-4212-b2e7-1881d62a62d2", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "11\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "nums3 = [11, 13, 15, 17]\n", - "print(findMin(nums3))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "The time complexity of this code is $O(log\\ n)$, where '$n$' is the length of the input array `nums`. This is because the binary search algorithm is employed, which continually divides the search range in half with each iteration.\n", - "\n", - "In each iteration of the `while` loop, the search range is halved, and this process continues until the `left` and `right` pointers converge to the minimum element. In the worst case, it will take logarithmic time to reduce the search range to a single element.\n", - "\n", - "Therefore, the binary search used in this code runs in $O(log\\ n)$ time complexity.\n", - "\n", - "**Space Complexity:**\n", - "The space complexity of this code is $O(1)$, which means it uses a constant amount of additional space that does not depend on the size of the input array.\n", - "\n", - "The algorithm uses a fixed number of variables (`left`, `right`, `mid`) to keep track of the search range and indices, but the number of these variables does not grow with the size of the input array. Hence, the space complexity is constant.\n", - "\n", - "**In summary:**\n", - "- Time Complexity: $O(log\\ n)$\n", - "- Space Complexity: $O(1)$" - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. Solve the problem with a variation where the input array may contain duplicates.\n", - "\n", - "2. Modify the problem to return the index of the minimum element in the rotated sorted array, rather than the element itself. The algorithm should still run in $O(log\\ n)$ time.\n", - "\n", - "3. Implement a function that finds the maximum element in a rotated sorted array. How would you adapt the binary search algorithm to solve this problem efficiently in $O(log\\ n)$ time?\n", - "\n", - "4. Implement a function that can find the kth smallest element in a rotated sorted array. This is an extension of the original problem, and the algorithm should still run in $O(log\\ n)$ time." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/05. Binary Search/33. Search in Rotated Sorted Array.ipynb b/_build/jupyter_execute/05. Binary Search/33. Search in Rotated Sorted Array.ipynb deleted file mode 100644 index 7b3139d..0000000 --- a/_build/jupyter_execute/05. Binary Search/33. Search in Rotated Sorted Array.ipynb +++ /dev/null @@ -1,237 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 33. Search in Rotated Sorted Array\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Search in Rotated Sorted Array problem on LeetCode, click here!](https://leetcode.com/problems/search-in-rotated-sorted-array/)\n", - "\n", - "---\n", - "\n", - "There is an integer array `nums` sorted in ascending order (with **distinct** values).\n", - "\n", - "Prior to being passed to your function, `nums` is **possibly rotated** at an unknown pivot index `k (1 <= k < nums.length)` such that the resulting array is `[nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]]` (**0-indexed**). For example, `[0,1,2,4,5,6,7]` might be rotated at pivot index 3 and become `[4,5,6,7,0,1,2]`.\n", - "\n", - "Given the array `nums` **after** the possible rotation and an integer `target`, return *the index of `target` if it is in `nums`, or `-1` if it is not in `nums`.*\n", - "\n", - "You must write an algorithm with $O(log\\ n)$ runtime complexity.\n", - " \n", - "\n", - "**Constraints:**\n", - "\n", - "- `1 <= nums.length <= 5000`\n", - "- $-10^4$ <= `nums[i]` <= $10^4$\n", - "- All values of `nums` are **unique**.\n", - "- `nums` is an ascending array that is possibly rotated.\n", - "- $-10^4$ <= `target` <= $10^4$" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "def search(nums, target):\n", - " left, right = 0, len(nums) - 1\n", - "\n", - " # Find the pivot index using binary search\n", - " while left < right:\n", - " mid = left + (right - left) // 2\n", - "\n", - " if nums[mid] > nums[right]:\n", - " left = mid + 1\n", - " else:\n", - " right = mid\n", - "\n", - " pivot = left\n", - " left, right = 0, len(nums) - 1\n", - "\n", - " # Determine which part of the array to search in\n", - " if target >= nums[pivot] and target <= nums[right]:\n", - " left = pivot\n", - " else:\n", - " right = pivot\n", - "\n", - " # Perform binary search to find the target\n", - " while left <= right:\n", - " mid = left + (right - left) // 2\n", - "\n", - " if nums[mid] == target:\n", - " return mid\n", - " elif nums[mid] < target:\n", - " left = mid + 1\n", - " else:\n", - " right = mid - 1\n", - "\n", - " return -1" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. The `search` function takes two arguments: `nums`, which is the rotated sorted array, and `target`, which is the value we want to find in the array.\n", - "\n", - "2. We initialize two pointers, `left` and `right`, which represent the range in which we are going to perform binary search. Initially, `left` is set to 0, and `right` is set to the index of the last element in the array (`len(nums) - 1`).\n", - "\n", - "3. We start by finding the pivot index using binary search. The pivot index is the index at which the array is rotated. We use a `while` loop to continue the search until `left` is less than `right`.\n", - "\n", - "4. Inside the loop, we calculate the middle index `mid` using integer division. We then compare the value at `mid` with the value at `right`. If `nums[mid]` is greater than `nums[right]`, it means the pivot point lies to the right of `mid`, so we update `left` to `mid + 1`. Otherwise, the pivot point lies to the left of `mid`, so we update `right` to `mid`. This process continues until we find the pivot index.\n", - "\n", - "5. After finding the pivot index, we have divided the array into two parts: one part is sorted in ascending order, and the other part is also sorted in ascending order but rotated. We need to determine which part of the array contains the target value.\n", - "\n", - "6. We reset `left` and `right` pointers. If the target value is within the range `[nums[pivot], nums[right]]`, we set `left` to `pivot` (the start of the rotated part), indicating that we should search in the rotated part. Otherwise, we set `right` to `pivot` (the end of the sorted part), indicating that we should search in the sorted part.\n", - "\n", - "7. We then perform binary search again within the chosen range (`left` to `right`) to find the target element. The binary search continues until `left` is less than or equal to `right`.\n", - "\n", - "8. Inside the binary search loop, we calculate the middle index `mid` and compare `nums[mid]` with the target value. If they are equal, we return `mid` as the index of the target element. If `nums[mid]` is less than the target, we update `left` to `mid + 1` to search in the right half. If `nums[mid]` is greater than the target, we update `right` to `mid - 1` to search in the left half.\n", - "\n", - "9. If we exit the binary search loop without finding the target, we return -1 to indicate that the target is not present in the array." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n" - ] - } - ], - "source": [ - "nums1 = [4, 5, 6, 7, 0, 1, 2]\n", - "target1 = 0\n", - "result1 = search(nums1, target1)\n", - "print(result1) " - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "-1\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "nums2 = [4, 5, 6, 7, 0, 1, 2]\n", - "target2 = 3\n", - "result2 = search(nums2, target2)\n", - "print(result2) " - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "6c69a707-02af-4212-b2e7-1881d62a62d2", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "-1\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "nums3 = [1]\n", - "target3 = 0\n", - "result3 = search(nums3, target3)\n", - "print(result3) " - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. Finding the pivot index using binary search takes $O(log\\ n)$ time, where '$n$' is the number of elements in the array.\n", - "2. After finding the pivot index, performing binary search to find the target element also takes $O(log\\ n)$ time in the worst case.\n", - "\n", - "The dominant factor in the time complexity is the binary search, and since we perform two binary searches sequentially, the overall time complexity of the code is $O(log\\ n)$.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity of the code is very minimal:\n", - "\n", - "1. We use a constant amount of additional space for variables such as `left`, `right`, `pivot`, and `mid`. These variables do not depend on the input size, so they contribute $O(1)$ space complexity.\n", - "2. The function does not use any additional data structures that scale with the input size.\n", - "\n", - "Therefore, the space complexity of the code is $O(1)$, which means it has a constant space complexity and does not depend on the size of the input array.\n", - "\n", - "**In summary:**\n", - "- Time Complexity: $O(log\\ n)$\n", - "- Space Complexity: $O(1)$" - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Find Minimum Element in Rotated Sorted Array**: Write an algorithm to find the minimum element in a rotated sorted array. This is a variation of the problem where you don't need to search for a target value but instead find the smallest element.\n", - "\n", - "2. **Search in a Circularly Sorted Array**: Consider an array that is sorted in a circular manner (e.g., [4, 5, 6, 7, 0, 1, 2, 3]). Adapt the search algorithm to work for circularly sorted arrays while maintaining $O(log\\ n)$ complexity." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/06. Linked List/141. Linked List Cycle.ipynb b/_build/jupyter_execute/06. Linked List/141. Linked List Cycle.ipynb deleted file mode 100644 index c428c9f..0000000 --- a/_build/jupyter_execute/06. Linked List/141. Linked List Cycle.ipynb +++ /dev/null @@ -1,261 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 141. Linked List Cycle\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Linked List Cycle problem on LeetCode, click here!](https://leetcode.com/problems/linked-list-cycle/)\n", - "\n", - "---\n", - "\n", - "Given `head`, the head of a linked list, determine if the linked list has a cycle in it.\n", - "\n", - "There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the `next` pointer. Internally, `pos` is used to denote the index of the node that tail's `next` pointer is connected to. **Note that `pos` is not passed as a parameter.**\n", - "\n", - "Return `true` if there is a cycle in the linked list. Otherwise, return `false`.\n", - "\n", - " \n", - "\n", - "**Constraints:**\n", - "\n", - "- The number of the nodes in the list is in the range $[0, 10^4]$.\n", - "- $-10^5$ <= Node.val <= $10^5$\n", - "- `pos` is `-1` or a **valid index** in the linked-list.\n", - "\n", - "**Follow up:** Can you solve it using $O(1)$ (i.e. constant) memory?" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "# Definition for singly-linked list.\n", - "class ListNode:\n", - " def __init__(self, val=0):\n", - " self.val = val\n", - " self.next = None\n", - "\n", - "class Solution:\n", - " def hasCycle(self, head: ListNode) -> bool:\n", - " if not head:\n", - " return False\n", - " \n", - " slow = head\n", - " fast = head\n", - " \n", - " while fast and fast.next:\n", - " slow = slow.next\n", - " fast = fast.next.next\n", - " \n", - " if slow == fast:\n", - " return True\n", - " \n", - " return False" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The given code defines a class `Solution` with a method `hasCycle` for determining if a linked list has a cycle.\n", - "\n", - "The `ListNode` class represents nodes in the linked list, where each node has a `val` (a value associated with the node) and a `next` attribute (a reference to the next node in the list).\n", - "\n", - "The `hasCycle` method takes the `head` of a linked list as input and returns `True` if there is a cycle in the linked list, and `False` otherwise. It uses two pointers, `slow` and `fast`, to traverse the linked list. If there is a cycle, the `fast` pointer will eventually catch up to the `slow` pointer.\n", - "\n", - "The algorithm works as follows:\n", - "1. It checks if the input `head` is `None` (an empty list). If it is, the method returns `False` because an empty list can't have a cycle.\n", - "2. Two pointers, `slow` and `fast`, initially point to the `head` of the list.\n", - "3. The code enters a `while` loop where `fast` moves two steps at a time, and `slow` moves one step at a time.\n", - "4. If there is a cycle, `fast` will eventually catch up to `slow`, and the method returns `True`.\n", - "5. If the loop completes without finding a cycle, the method returns `False`." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "01849ced-1bbf-4956-8e54-451b358cb4fe", - "metadata": {}, - "outputs": [], - "source": [ - "# Helper function to create a linked list with a cycle\n", - "def create_linked_list_with_cycle(values, pos):\n", - " dummy = ListNode()\n", - " current = dummy\n", - " cycle_node = None\n", - " \n", - " for i, val in enumerate(values):\n", - " current.next = ListNode(val)\n", - " current = current.next\n", - " \n", - " if i == pos:\n", - " cycle_node = current\n", - " \n", - " if cycle_node:\n", - " current.next = cycle_node\n", - " \n", - " return dummy.next" - ] - }, - { - "cell_type": "markdown", - "id": "f7490d01-d64e-4f20-b178-e14490d6dd6f", - "metadata": {}, - "source": [ - "This helper function is designed to create a linked list with a cycle for testing purposes. It takes two arguments:\n", - "\n", - "1. `values`: A list of values representing the nodes in the linked list.\n", - "2. `pos`: An integer representing the index of the node where the cycle begins.\n", - "\n", - "Here's how the function works:\n", - "\n", - "- It starts by creating an empty `ListNode` called `dummy`. This `dummy` node is used to simplify the creation of the linked list.\n", - "- It initializes a `current` pointer to the `dummy` node. This pointer will be used to traverse the linked list.\n", - "- It initializes a `cycle_node` variable to `None`. This variable will hold the reference to the node where the cycle begins, if any.\n", - "- It then iterates through the `values` list, creating a new `ListNode` for each value and appending it to the linked list.\n", - "- Inside the loop, it checks if the current index `i` is equal to the specified `pos`. If they match, it sets `cycle_node` to the current node. This simulates the creation of a cycle in the linked list.\n", - "- After the loop, if `cycle_node` is not `None` (indicating a cycle should be created), it connects the last node in the linked list to `cycle_node`, effectively creating a cycle.\n", - "- Finally, it returns the reference to the first node of the linked list (not the `dummy` node).\n", - "\n", - "This helper function allows you to easily create test cases where you can specify the values for the linked list and the position where the cycle starts. It's particularly useful for testing the code's ability to detect cycles in linked lists." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "### Example 1\n", - "head = [3,2,0,-4]\n", - "pos = 1\n", - "\n", - "head = create_linked_list_with_cycle(head, pos)\n", - "solution = Solution()\n", - "result = solution.hasCycle(head)\n", - "print(result)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "### Example 2\n", - "head = [1,2]\n", - "pos = 0\n", - "\n", - "head = create_linked_list_with_cycle(head, pos)\n", - "solution = Solution()\n", - "result = solution.hasCycle(head)\n", - "print(result)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "e140b956-7b3d-40d5-b6b0-9615860af67e", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "### Example 3\n", - "head = [1]\n", - "pos = -1\n", - "\n", - "head = create_linked_list_with_cycle(head, pos)\n", - "solution = Solution()\n", - "result = solution.hasCycle(head)\n", - "print(result)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's discuss the time and space complexity of the code for detecting a cycle in a linked list:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The time complexity of this code is $O(n)$, where \"$n$\" is the number of nodes in the linked list.\n", - "\n", - "The reason for this is that both the `slow` and `fast` pointers traverse the linked list, and they move at different speeds. In the worst case, when there is no cycle, the `fast` pointer will reach the end of the list after going through approximately $n/2$ nodes. In the case of a cycle, it may take some extra iterations for the `fast` pointer to catch up to the `slow` pointer. However, the total number of iterations is still proportional to the number of nodes in the linked list, making it $O(n)$.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity of this code is $O(1)$, which means it uses constant space.\n", - "\n", - "The reason for this is that regardless of the size of the linked list, the code only uses two additional pointers (`slow` and `fast`) to traverse the list. These pointers do not depend on the size of the input linked list, so the space complexity remains constant.\n", - "\n", - "**In summary**, this code efficiently detects cycles in a linked list with a time complexity of $O(n)$ and a space complexity of $O(1)$. It is an example of an algorithm that solves a complex problem with minimal memory usage." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/06. Linked List/143. Reorder List.ipynb b/_build/jupyter_execute/06. Linked List/143. Reorder List.ipynb deleted file mode 100644 index 4ec3f3b..0000000 --- a/_build/jupyter_execute/06. Linked List/143. Reorder List.ipynb +++ /dev/null @@ -1,277 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 143. Reorder List\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Reorder List problem on LeetCode, click here!](https://leetcode.com/problems/reorder-list/)\n", - "\n", - "---\n", - "\n", - "You are given the head of a singly linked-list. The list can be represented as:\n", - "\n", - "$L_0 → L_1 → … → L_{n - 1} → L_n$\n", - "\n", - "Reorder the list to be on the following form:\n", - "\n", - "$L_0 → L_n → L_1 → L_{n - 1} → L_2 → L_{n - 2} → …$\n", - "\n", - "You may not modify the values in the list's nodes. Only nodes themselves may be changed.\n", - " \n", - "\n", - "**Constraints:**\n", - "\n", - "- The number of nodes in the list is in the range $[1, 5 * 10^4]$.\n", - "- `1 <= Node.val <= 1000`" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "class ListNode:\n", - " def __init__(self, val=0, next=None):\n", - " self.val = val\n", - " self.next = next\n", - "\n", - "def reorderList(head):\n", - " if not head or not head.next:\n", - " return head\n", - "\n", - " # Step 1: Find the middle of the linked list\n", - " slow, fast = head, head\n", - " while fast.next and fast.next.next:\n", - " slow = slow.next\n", - " fast = fast.next.next\n", - "\n", - " # Split the list into two halves\n", - " first_half = head\n", - " second_half = slow.next\n", - " slow.next = None\n", - "\n", - " # Step 2: Reverse the second half of the linked list\n", - " prev = None\n", - " current = second_half\n", - " while current:\n", - " next_node = current.next\n", - " current.next = prev\n", - " prev = current\n", - " current = next_node\n", - " second_half = prev\n", - "\n", - " # Step 3: Merge the first and reversed second halves alternately\n", - " p1, p2 = first_half, second_half\n", - " while p2:\n", - " next_p1 = p1.next\n", - " next_p2 = p2.next\n", - " p1.next = p2\n", - " p2.next = next_p1\n", - " p1 = next_p1\n", - " p2 = next_p2\n", - "\n", - " return head" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The `reorderList` function is designed to reorder a singly linked list following the specific pattern described in the problem statement. Here's a detailed explanation of how the function works:\n", - "\n", - "1. **Base Cases Handling**:\n", - " - The function first checks if the input linked list is empty (`not head`) or contains only one element (`not head.next`). If either of these conditions is met, the list cannot be reordered, so the function returns the original list as-is.\n", - "\n", - "2. **Finding the Middle of the Linked List**:\n", - " - To reorder the list, we first need to find the middle point so that we can split the list into two halves. This is done using two pointers, `slow` and `fast`, initialized to the head of the list.\n", - " - `slow` moves one step at a time while `fast` moves two steps at a time. When `fast` reaches the end of the list or the second-to-last node, `slow` will be at the middle node.\n", - "\n", - "3. **Splitting the List**:\n", - " - After finding the middle node, we split the list into two halves:\n", - " - The first half, `first_half`, contains nodes from the beginning up to the middle.\n", - " - The second half, `second_half`, contains nodes from the middle to the end.\n", - " - To split the list, we set the `next` pointer of the node before the middle node to `None`.\n", - "\n", - "4. **Reversing the Second Half**:\n", - " - We reverse the second half of the linked list using the `prev`, `current`, and `next_node` pointers.\n", - " - `prev` is initially `None`, and we iterate through the second half. For each node, we:\n", - " - Set the `next` of the current node to `prev`, effectively reversing the next pointer direction.\n", - " - Update `prev` to the current node.\n", - " - Move to the next node using the `next_node`.\n", - "\n", - "5. **Merging the Two Halves Alternately**:\n", - " - We now have two linked lists: `first_half` and the reversed `second_half`.\n", - " - We merge these two lists alternately by adjusting the `next` pointers of the nodes.\n", - " - `p1` and `p2` are pointers to the current nodes in `first_half` and `second_half`, respectively.\n", - " - We iterate through both lists while reordering nodes:\n", - " - Set the `next` of `p1` to `p2` to link a node from the first half to a node from the reversed second half.\n", - " - Update `p1` and `p2` to their respective next nodes.\n", - " - Repeat this process until we have processed all nodes in both halves.\n", - "\n", - "6. **Returning the Reordered List**:\n", - " - After the merging process is complete, the linked list is reordered as specified.\n", - " - The function returns the `head` of the reordered list.\n", - "\n", - "The overall result is a singly linked list that has been reordered according to the given pattern. The time complexity of this algorithm is O(N), where N is the number of nodes in the linked list, as we traverse the list once to find the middle, once to reverse the second half, and once to merge the two halves." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "01849ced-1bbf-4956-8e54-451b358cb4fe", - "metadata": {}, - "outputs": [], - "source": [ - "# Helper function to print the linked list\n", - "def printLinkedList(head):\n", - " result = []\n", - " while head:\n", - " result.append(head.val)\n", - " head = head.next\n", - " return result" - ] - }, - { - "cell_type": "markdown", - "id": "f7490d01-d64e-4f20-b178-e14490d6dd6f", - "metadata": {}, - "source": [ - "Let's explain the helper functions:\n", - "**printLinkedList Function**:\n", - " - The `printLinkedList` function takes the `head` of a linked list as input and returns a list of values representing the nodes in the linked list.\n", - " - Inside the function, a `result` list is initialized to store the values of the linked list nodes.\n", - " - The function then iterates through the linked list starting from the `head` node and appends the `val` attribute of each node to the `result` list.\n", - " - As it iterates through the list, it moves to the next node using the `next` attribute of each node.\n", - " - Finally, the function returns the `result` list containing the values of the linked list nodes in the order they appear in the linked list.\n", - "\n", - " This function is useful for debugging and displaying the contents of a linked list. It allows you to easily convert a linked list into a regular Python list for visualization and testing purposes." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 4, 2, 3]\n" - ] - } - ], - "source": [ - "# Example 1\n", - "head1 = ListNode(1, ListNode(2, ListNode(3, ListNode(4))))\n", - "reorderList(head1)\n", - "print(printLinkedList(head1))" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 5, 2, 4, 3]\n" - ] - } - ], - "source": [ - "# Example 2\n", - "head2 = ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5)))))\n", - "reorderList(head2)\n", - "print(printLinkedList(head2))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the `reorderList` function:\n", - "\n", - "**Time Complexity**:\n", - "1. **Finding the Middle of the Linked List**: In this step, we use two pointers, one moving one step at a time (`slow`) and the other moving two steps at a time (`fast`). This process takes $O(N/2)$ time, where $N$ is the number of nodes in the linked list.\n", - "\n", - "2. **Splitting the List**: After finding the middle, we split the list into two halves by setting the `next` pointer of the node before the middle node to `None`. This step takes $O(1)$ time.\n", - "\n", - "3. **Reversing the Second Half**: We reverse the second half of the linked list using a while loop that iterates through the second half of the list once. Therefore, this step also takes $O(N/2)$ time.\n", - "\n", - "4. **Merging the Two Halves Alternately**: In this step, we merge the two halves alternately by adjusting the `next` pointers of the nodes. We iterate through both halves once, so this step takes $O(N/2)$ time.\n", - "\n", - "Overall, the time complexity of the `reorderList` function is dominated by the steps involving reversing and merging the two halves, both of which take $O(N/2)$ time. Therefore, the total time complexity is $O(N)$.\n", - "\n", - "**Space Complexity**:\n", - "The space complexity of the `reorderList` function is primarily determined by the variables and data structures used within the function. Let's break down the space complexity components:\n", - "\n", - "1. **Constant Space Variables**: The variables `slow`, `fast`, `prev`, `current`, `next_node`, `p1`, and `p2` are used to traverse and manipulate the linked list. These variables occupy constant space, regardless of the input size. Therefore, they contribute $O(1)$ to the space complexity.\n", - "\n", - "2. **Split Linked Lists**: In the splitting step, we create two new linked list segments (`first_half` and `second_half`) that store references to nodes from the original linked list. These segments occupy space proportional to half of the input list, $O(N/2)$. \n", - "\n", - "3. **Reversed Second Half**: During the reversal step, we reverse the second half of the linked list in-place without creating any additional data structures. Therefore, it doesn't contribute to additional space complexity.\n", - "\n", - "4. **Overall**: Combining the above components, the total space complexity is $O(N/2)$, which simplifies to $O(N)$ in terms of space complexity.\n", - "\n", - "**In summary**, the `reorderList` function has a time complexity of $O(N)$ and a space complexity of $O(N)$ due to the creation of two new linked list segments while splitting the list. The constant space variables used for traversal do not significantly impact the overall space complexity." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Reorder by K Elements:** Generalize the reorderList function to reorder the list in a different pattern, where you reorder the list by $K$ elements at a time. For example, for $K=3$, you would reorder it as ($L_0 → L_1 → L_2 → L_n → L_{n-1} → L_{n-2} → ...$).\n", - "You may need to handle cases where the number of nodes is not a multiple of $K$.\n", - "\n", - "2. **Reorder by Odd and Even Nodes:** Modify the reorderList function to reorder the list in a pattern where odd-indexed nodes (1-based index) come before even-indexed nodes. For example, ($L_0 → L_n → L_1 → L_{n-1} → L_2 → L_{n-2} → ...$)." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/06. Linked List/19. Remove Nth Node From End of List.ipynb b/_build/jupyter_execute/06. Linked List/19. Remove Nth Node From End of List.ipynb deleted file mode 100644 index 73dbf66..0000000 --- a/_build/jupyter_execute/06. Linked List/19. Remove Nth Node From End of List.ipynb +++ /dev/null @@ -1,268 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 19. Remove Nth Node From End of List\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Remove Nth Node From End of List problem on LeetCode, click here!](https://leetcode.com/problems/remove-nth-node-from-end-of-list/)\n", - "\n", - "---\n", - "\n", - "Given the head of a linked list, remove the $n^{th}$ node from the end of the list and return its head.\n", - " \n", - "\n", - "**Constraints:**\n", - "\n", - "- The number of nodes in the list is `sz`.\n", - "- `1 <= sz <= 30`\n", - "- `0 <= Node.val <= 100`\n", - "- `1 <= n <= sz`\n", - "\n", - "**Follow up:** Could you do this in one pass?" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "class ListNode:\n", - " def __init__(self, val=0, next=None):\n", - " self.val = val\n", - " self.next = next\n", - "\n", - "def removeNthFromEnd(head, n):\n", - " # Create a dummy node to handle the case of removing the head node.\n", - " dummy = ListNode(0)\n", - " dummy.next = head\n", - " first = dummy\n", - " second = dummy\n", - " \n", - " # Advance the first pointer by n+1 nodes.\n", - " for _ in range(n + 1):\n", - " first = first.next\n", - " \n", - " # Move both pointers simultaneously until first reaches the end.\n", - " while first is not None:\n", - " first = first.next\n", - " second = second.next\n", - " \n", - " # Remove the nth node by updating the next pointer of the previous node.\n", - " second.next = second.next.next\n", - " \n", - " return dummy.next # Return the modified head of the linked list" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start by defining a `ListNode` class to represent individual nodes in a linked list. Each node has two attributes: `val` (the value of the node) and `next` (a reference to the next node in the list).\n", - "\n", - "2. The `removeNthFromEnd` function takes the head of a linked list (`head`) and the value `n`, which represents the position from the end of the list of the node to be removed. It returns the modified head of the linked list after the removal.\n", - "\n", - "3. We create a dummy node (`dummy`) at the beginning of the list. This dummy node simplifies the code by handling cases where the head of the list needs to be removed.\n", - "\n", - "4. We initialize two pointers, `first` and `second`, both initially pointing to the dummy node.\n", - "\n", - "5. To advance the `first` pointer by `n+1` nodes, we use a `for` loop. This positions the `first` pointer `n` nodes ahead of the `second` pointer.\n", - "\n", - "6. We then move both `first` and `second` pointers simultaneously until `first` reaches the end of the list. This ensures that the `second` pointer ends up pointing to the node that needs to be removed.\n", - "\n", - "7. To remove the nth node from the end, we update the `next` pointer of the node pointed to by the `second` pointer to skip over the node to be removed.\n", - "\n", - "8. Finally, we return `dummy.next`, which is the modified head of the linked list without the removed node.\n", - "\n", - "9. Additionally, there are two helper functions:\n", - " - `createLinkedList(values)` creates a linked list from a list of values.\n", - " - `convertToList(head)` converts a linked list back into a list of values." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "01849ced-1bbf-4956-8e54-451b358cb4fe", - "metadata": {}, - "outputs": [], - "source": [ - "# Helper function to create a linked list from a list of values.\n", - "def createLinkedList(values):\n", - " if not values:\n", - " return None\n", - " head = ListNode(values[0])\n", - " current = head\n", - " for val in values[1:]:\n", - " current.next = ListNode(val)\n", - " current = current.next\n", - " return head\n", - "\n", - "# Helper function to convert a linked list to a list of values.\n", - "def convertToList(head):\n", - " result = []\n", - " current = head\n", - " while current:\n", - " result.append(current.val)\n", - " current = current.next\n", - " return result" - ] - }, - { - "cell_type": "markdown", - "id": "f7490d01-d64e-4f20-b178-e14490d6dd6f", - "metadata": {}, - "source": [ - "Let's explain the two helper functions:\n", - "\n", - "1. `createLinkedList(values)`: This function creates a linked list from a list of values.\n", - "\n", - " - Input: `values` is a list containing values that you want to insert into the linked list.\n", - " - Output: The function returns the head of the created linked list.\n", - "\n", - " Explanation:\n", - " - The function starts by checking if the `values` list is empty. If it is, it returns `None` to indicate an empty linked list.\n", - " - If the `values` list is not empty, it creates the first node of the linked list with the value from the first element of `values`.\n", - " - It then iterates through the remaining elements of `values` and creates new nodes for each value, connecting them together using the `next` attribute to form a linked list.\n", - " - Finally, it returns the head of the linked list, which is the first node created.\n", - " \n", - "\n", - "2. `convertToList(head)`: This function converts a linked list into a list of values.\n", - "\n", - " - Input: `head` is the head node of the linked list that you want to convert.\n", - " - Output: The function returns a list containing the values of the nodes in the linked list in order.\n", - "\n", - " Explanation:\n", - " - The function starts by initializing an empty list, `result`, to store the values of the linked list nodes.\n", - " - It then iterates through the linked list starting from the `head` node and appends the `val` attribute of each node to the `result` list.\n", - " - The iteration continues until it reaches the end of the linked list (i.e., the `next` attribute of the current node becomes `None`).\n", - " - After the iteration is complete, the function returns the `result` list, which now contains the values of all the nodes in the linked list in the same order as they appear in the linked list.\n", - "\n", - "These helper functions are useful for creating linked lists from lists of values and converting linked lists back into lists of values, making it easier to work with linked list examples and test cases in a more familiar list format." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 2, 3, 5]\n" - ] - } - ], - "source": [ - "# Example 1\n", - "head1 = createLinkedList([1, 2, 3, 4, 5])\n", - "n1 = 2\n", - "new_head1 = removeNthFromEnd(head1, n1)\n", - "print(convertToList(new_head1))" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[]\n" - ] - } - ], - "source": [ - "# Example 2\n", - "head2 = createLinkedList([1])\n", - "n2 = 1\n", - "new_head2 = removeNthFromEnd(head2, n2)\n", - "print(convertToList(new_head2))" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "e140b956-7b3d-40d5-b6b0-9615860af67e", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1]\n" - ] - } - ], - "source": [ - "# Example 3\n", - "head3 = createLinkedList([1, 2])\n", - "n3 = 1\n", - "new_head3 = removeNthFromEnd(head3, n3)\n", - "print(convertToList(new_head3))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Certainly! Let's analyze the time and space complexity of the `removeNthFromEnd` function in isolation:\n", - "\n", - "**Time Complexity:**\n", - "- The `removeNthFromEnd` function performs two passes through the linked list. In the worst case, it needs to traverse the entire linked list of length $N$.\n", - "- The first pass positions the `first` pointer $n$ nodes ahead of the `second` pointer. This pass takes $O(N)$ time because it involves iterating through all N nodes.\n", - "- The second pass moves both `first` and `second` pointers simultaneously until `first` reaches the end of the list. This also takes $O(N)$ time in the worst case.\n", - "- Therefore, the overall time complexity of the `removeNthFromEnd` function is $O(N)$.\n", - "\n", - "**Space Complexity:**\n", - "- The `removeNthFromEnd` function uses a constant amount of extra space for its variables (e.g., `first`, `second`, and `dummy`). This space usage does not depend on the size of the linked list.\n", - "- The space complexity is $O(1)$, indicating that the space used by the function is constant and independent of the size of the input linked list.\n", - "\n", - "**In summary**, the `removeNthFromEnd` function has a time complexity of $O(N)$ and a space complexity of $O(1)$. It efficiently removes the nth node from the end of the linked list with a single pass through the list and constant extra space usage." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/06. Linked List/206. Reverse Linked List.ipynb b/_build/jupyter_execute/06. Linked List/206. Reverse Linked List.ipynb deleted file mode 100644 index 09de0a3..0000000 --- a/_build/jupyter_execute/06. Linked List/206. Reverse Linked List.ipynb +++ /dev/null @@ -1,297 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 206. Reverse Linked List\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Reverse Linked List problem on LeetCode, click here!](https://leetcode.com/problems/reverse-linked-list/)\n", - "\n", - "---\n", - "\n", - "Given the `head` of a singly linked list, reverse the list, and return the reversed list.\n", - " \n", - "\n", - "**Constraints:**\n", - "\n", - "- The number of nodes in the list is the range `[0, 5000]`.\n", - "- `-5000 <= Node.val <= 5000`\n", - "\n", - "**Follow up:** A linked list can be reversed either iteratively or recursively. Could you implement both?" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "# Definition for singly-linked list.\n", - "class ListNode:\n", - " def __init__(self, val=0, next=None):\n", - " self.val = val\n", - " self.next = next\n", - "\n", - "# Function to reverse a linked list iteratively\n", - "def reverseListIterative(head):\n", - " prev = None\n", - " current = head\n", - " \n", - " while current:\n", - " next_node = current.next\n", - " current.next = prev\n", - " prev = current\n", - " current = next_node\n", - " \n", - " return prev\n", - "\n", - "# Function to reverse a linked list recursively\n", - "def reverseListRecursive(head):\n", - " if not head or not head.next:\n", - " return head\n", - "\n", - " new_head = reverseListRecursive(head.next)\n", - " head.next.next = head\n", - " head.next = None\n", - "\n", - " return new_head" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. `reverseListIterative(head)`: This function reverses a linked list iteratively using a loop. Here's a step-by-step explanation:\n", - "\n", - " - It takes the `head` of the input linked list as a parameter.\n", - " - It initializes two pointers, `prev` and `current`, initially set to `None` and the `head` of the list, respectively.\n", - " - It enters a `while` loop that continues until `current` reaches the end of the list (i.e., becomes `None`).\n", - " - Inside the loop:\n", - " - It stores the `next_node` which is the next node after `current`.\n", - " - It updates the `next` pointer of `current` to point to the `prev` node. This effectively reverses the link direction.\n", - " - It moves `prev` to `current` and `current` to `next_node`, advancing the pointers one step further in the list.\n", - " - Once the loop completes, `prev` will be pointing to the new head of the reversed list (which was the last node of the original list), so it returns `prev`.\n", - "\n", - "2. `reverseListRecursive(head)`: This function reverses a linked list recursively. Here's how it works:\n", - "\n", - " - It takes the `head` of the input linked list as a parameter.\n", - " - The base case is checked: if `head` is `None` or `head.next` is `None`, meaning the list is empty or has only one node, it returns `head` as there's no need to reverse a list with zero or one element.\n", - " - In the recursive case:\n", - " - It calls itself with `head.next`, effectively moving down the list until it reaches the end.\n", - " - Once it reaches the end, it starts reversing the links:\n", - " - `head.next.next` is set to `head`, reversing the link between `head` and the next node.\n", - " - `head.next` is set to `None` to avoid cycles.\n", - " - Finally, it returns the new head of the reversed list, which will be the last node of the original list.\n", - "\n", - "**In summary,** `reverseListIterative` reverses the linked list by iterating through it and changing the next pointers, while `reverseListRecursive` reverses the linked list by recursively reaching the end and then reversing the links on the way back up the recursion stack. Both functions achieve the same result: reversing the linked list." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "01849ced-1bbf-4956-8e54-451b358cb4fe", - "metadata": {}, - "outputs": [], - "source": [ - "# Helper function to create a linked list from a list of values\n", - "def createLinkedList(values):\n", - " if not values:\n", - " return None\n", - " head = ListNode(values[0])\n", - " current = head\n", - " for val in values[1:]:\n", - " current.next = ListNode(val)\n", - " current = current.next\n", - " return head\n", - "\n", - "# Helper function to convert a linked list to a list for testing\n", - "def linkedListToList(head):\n", - " result = []\n", - " current = head\n", - " while current:\n", - " result.append(current.val)\n", - " current = current.next\n", - " return result\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "f7490d01-d64e-4f20-b178-e14490d6dd6f", - "metadata": {}, - "source": [ - "Let's explain the two helper functions used in the provided code:\n", - "\n", - "1. `createLinkedList(values)`:\n", - "\n", - " - Purpose: This function is used to create a linked list from a list of values. It takes a list of values as input and returns the head of the linked list.\n", - "\n", - " - How it works:\n", - " - It first checks if the input list `values` is empty. If it's empty, it returns `None` to indicate an empty linked list.\n", - " - If `values` is not empty, it initializes a `head` node with the value of the first element in `values`.\n", - " - It then iterates through the remaining values in `values`, creating new nodes for each value and linking them together to form a linked list.\n", - " - Finally, it returns the `head` node of the newly created linked list.\n", - "\n", - "2. `linkedListToList(head)`:\n", - "\n", - " - Purpose: This function is used to convert a linked list back into a Python list for testing and output purposes.\n", - "\n", - " - How it works:\n", - " - It takes the `head` of the linked list as input.\n", - " - It initializes an empty list called `result`.\n", - " - It then iterates through the linked list, starting from `head`, and appends each node's `val` (value) to the `result` list.\n", - " - This process continues until the end of the linked list is reached.\n", - " - Finally, it returns the `result` list, which contains the values from the linked list in the same order.\n", - "\n", - "These helper functions are used to simplify the process of creating linked lists from lists of values and converting linked lists back into lists, making it easier to work with linked lists in the provided examples and test cases." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[5, 4, 3, 2, 1]\n" - ] - } - ], - "source": [ - "# Example 1: Iterative\n", - "head1 = [1,2,3,4,5]\n", - "head1 = createLinkedList(head1)\n", - "reversed_head1 = reverseListIterative(head1)\n", - "print(linkedListToList(reversed_head1))" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[2, 1]\n" - ] - } - ], - "source": [ - "# Example 2: Recursive\n", - "head2 = [1,2]\n", - "head2 = createLinkedList(head2)\n", - "reversed_head2 = reverseListRecursive(head2)\n", - "print(linkedListToList(reversed_head2))" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "6c69a707-02af-4212-b2e7-1881d62a62d2", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[]\n" - ] - } - ], - "source": [ - "# Example 3: Empty list\n", - "head3 = []\n", - "head3 = createLinkedList(head3)\n", - "reversed_head3 = reverseListIterative(head3)\n", - "print(linkedListToList(reversed_head3))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the two functions:\n", - "\n", - "1. `reverseListIterative(head)`:\n", - "\n", - " - Time Complexity: $O(n)$\n", - " - The iterative function visits each node in the linked list exactly once in a single pass, where \"$n$\" is the number of nodes in the list. Therefore, the time complexity is linear in the number of nodes.\n", - "\n", - " - Space Complexity: $O(1)$\n", - " - This function uses a constant amount of extra space for the `prev`, `current`, and `next_node` pointers. Regardless of the size of the input list, the amount of additional memory used remains the same, so the space complexity is constant.\n", - "\n", - "2. `reverseListRecursive(head)`:\n", - "\n", - " - Time Complexity: $O(n)$\n", - " - The recursive function also visits each node in the linked list exactly once. It recursively traverses the list from the head to the tail, reversing the links on the way back. Therefore, like the iterative approach, the time complexity is $O(n)$, where \"$n$\" is the number of nodes.\n", - "\n", - " - Space Complexity: $O(n)$\n", - " - The recursive function uses space on the call stack for each recursive call. In the worst case, when the list has \"$n$\" nodes, it will create \"$n$\" recursive function calls on the stack, resulting in a space complexity of $O(n)$. This is because each function call stores information about its state, including the `head` pointer, until it reaches the base case and starts returning.\n", - "\n", - "**In summary:**\n", - "\n", - "- The time complexity of both functions is $O(n)$ because they both visit each node once.\n", - "- The space complexity of `reverseListIterative` is $O(1)$ because it uses a constant amount of extra space.\n", - "- The space complexity of `reverseListRecursive` is $O(n)$ due to the recursive function calls and the associated call stack space.\n", - "\n", - "Both functions are efficient in terms of time complexity, but `reverseListIterative` is more memory-efficient because it uses a constant amount of additional space, while `reverseListRecursive` uses space on the call stack proportional to the number of nodes in the list." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **K-Group Reverse:** Modify the reverseListIterative function to reverse the linked list in groups of $K$ elements. For example, if the input linked list is [1, 2, 3, 4, 5, 6], and $K$ is 3, the output should be [3, 2, 1, 6, 5, 4].\n", - "\n", - "2. **Rotate Linked List:** Write a function to rotate a linked list to the right by $K$ places. For example, if the input is [1, 2, 3, 4, 5] and $K$ is 2, the output should be [4, 5, 1, 2, 3]." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/06. Linked List/21. Merge Two Sorted Lists.ipynb b/_build/jupyter_execute/06. Linked List/21. Merge Two Sorted Lists.ipynb deleted file mode 100644 index b433cf3..0000000 --- a/_build/jupyter_execute/06. Linked List/21. Merge Two Sorted Lists.ipynb +++ /dev/null @@ -1,277 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 21. Merge Two Sorted Lists\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Merge Two Sorted Lists problem on LeetCode, click here!](https://leetcode.com/problems/merge-two-sorted-lists/)\n", - "\n", - "---\n", - "\n", - "You are given the heads of two sorted linked lists `list1` and `list2`.\n", - "\n", - "Merge the two lists into one **sorted** list. The list should be made by splicing together the nodes of the first two lists.\n", - "\n", - "*Return the head of the merged linked list.*\n", - " \n", - "\n", - "**Constraints:**\n", - "\n", - "- The number of nodes in both lists is in the range `[0, 50]`.\n", - "- `-100 <= Node.val <= 100`\n", - "- Both `list1` and `list2` are sorted in non-decreasing order." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "class ListNode:\n", - " def __init__(self, val=0, next=None):\n", - " self.val = val\n", - " self.next = next\n", - "\n", - "def mergeTwoLists(list1, list2):\n", - " # Create a dummy node to simplify the code.\n", - " dummy = ListNode()\n", - " current = dummy\n", - "\n", - " while list1 and list2:\n", - " if list1.val < list2.val:\n", - " current.next = list1\n", - " list1 = list1.next\n", - " else:\n", - " current.next = list2\n", - " list2 = list2.next\n", - " current = current.next\n", - "\n", - " # Append the remaining elements from either list.\n", - " if list1:\n", - " current.next = list1\n", - " else:\n", - " current.next = list2\n", - "\n", - " return dummy.next" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We define a class `ListNode` to represent the nodes of a singly-linked list. Each node has a `val` attribute to store the value of the node and a `next` attribute to point to the next node in the list.\n", - "\n", - "2. We define the `mergeTwoLists` function that takes two linked list heads, `list1` and `list2`, as input.\n", - "\n", - "3. We create a `dummy` node at the beginning of the merged list. The `dummy` node simplifies the code by serving as a placeholder, and its `next` attribute will point to the actual merged list.\n", - "\n", - "4. We initialize a `current` pointer to point to the `dummy` node initially. This `current` pointer helps us traverse and build the merged list.\n", - "\n", - "5. We enter a `while` loop that continues until either `list1` or `list2` becomes empty. Inside the loop, we compare the values of the nodes at the current positions of `list1` and `list2`.\n", - "\n", - "6. If the `val` of the node in `list1` is smaller than the `val` of the node in `list2`, we attach the node from `list1` to the merged list by updating the `next` attribute of the `current` node to point to the node in `list1`. We then move the `list1` pointer to the next node.\n", - "\n", - "7. If the `val` of the node in `list2` is smaller than or equal to the `val` of the node in `list1`, we attach the node from `list2` to the merged list in a similar manner. We move the `list2` pointer to the next node.\n", - "\n", - "8. After attaching a node to the merged list, we move the `current` pointer to the newly added node. This step is essential for keeping track of the end of the merged list.\n", - "\n", - "9. The loop continues until either `list1` or `list2` becomes empty.\n", - "\n", - "10. Once the loop exits, we check if there are any remaining elements in `list1` or `list2`. If `list1` is not empty, we attach the remaining elements of `list1` to the merged list. If `list2` is not empty, we attach the remaining elements of `list2`.\n", - "\n", - "11. Finally, we return the `next` attribute of the `dummy` node as the head of the merged list, which represents the sorted merged list." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "01849ced-1bbf-4956-8e54-451b358cb4fe", - "metadata": {}, - "outputs": [], - "source": [ - "# Helper function to print the linked list\n", - "def printLinkedList(head):\n", - " result = []\n", - " while head:\n", - " result.append(head.val)\n", - " head = head.next\n", - " return result" - ] - }, - { - "cell_type": "markdown", - "id": "f7490d01-d64e-4f20-b178-e14490d6dd6f", - "metadata": {}, - "source": [ - "Let's explain the helper functions:\n", - "**printLinkedList Function**:\n", - " - The `printLinkedList` function takes the `head` of a linked list as input and returns a list of values representing the nodes in the linked list.\n", - " - Inside the function, a `result` list is initialized to store the values of the linked list nodes.\n", - " - The function then iterates through the linked list starting from the `head` node and appends the `val` attribute of each node to the `result` list.\n", - " - As it iterates through the list, it moves to the next node using the `next` attribute of each node.\n", - " - Finally, the function returns the `result` list containing the values of the linked list nodes in the order they appear in the linked list.\n", - "\n", - " This function is useful for debugging and displaying the contents of a linked list. It allows you to easily convert a linked list into a regular Python list for visualization and testing purposes." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[1, 1, 2, 3, 4, 4]" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Example 1:\n", - "# Input: list1 = [1,2,4], list2 = [1,3,4]\n", - "list1 = ListNode(1, ListNode(2, ListNode(4)))\n", - "list2 = ListNode(1, ListNode(3, ListNode(4)))\n", - "merged_list = mergeTwoLists(list1, list2)\n", - "printLinkedList(merged_list)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Example 2:\n", - "# Input: list1 = [], list2 = []\n", - "list1 = None\n", - "list2 = None\n", - "merged_list = mergeTwoLists(list1, list2)\n", - "printLinkedList(merged_list)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "6c69a707-02af-4212-b2e7-1881d62a62d2", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[0]" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Example 3:\n", - "# list1 = [], list2 = [0]\n", - "list1 = None\n", - "list2 = ListNode(0)\n", - "merged_list = mergeTwoLists(list1, list2)\n", - "printLinkedList(merged_list)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the `mergeTwoLists` function.\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The time complexity of this function is $O(N + M$), where $N$ and $M$ are the lengths of `list1` and `list2`, respectively. Here's why:\n", - "\n", - "1. In the worst case, we need to traverse both `list1` and `list2` completely. This involves iterating through all the nodes in both lists once.\n", - "\n", - "2. The while loop runs until either `list1` or `list2` becomes empty. The number of iterations depends on the total number of nodes in both lists, which is N + M in the worst case.\n", - "\n", - "3. Inside the loop, we perform constant-time operations for each iteration, such as comparisons and updating pointers.\n", - "\n", - "Therefore, the dominant factor in the time complexity is the combined length of both input lists, resulting in a linear time complexity of $O(N + M)$.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity of this function is $O(1)$, which means it uses a constant amount of extra space regardless of the input sizes. Here's why:\n", - "\n", - "1. We create a few extra pointers (`dummy`, `current`) and temporary variables (`val`) to manage the merging process. These consume a fixed amount of memory, regardless of the input sizes. The number of these extra variables is independent of the lengths of `list1` and `list2`.\n", - "\n", - "2. We do not create a new data structure or allocate memory for the merged list. Instead, we rearrange the existing nodes from `list1` and `list2` to form the merged list. This operation does not consume additional memory proportional to the input sizes.\n", - "\n", - "**In summary**, the `mergeTwoLists` function has a time complexity of $O(N + M)$ and a space complexity of $O(1)$, making it an efficient solution for merging two sorted linked lists." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Merge K Sorted Lists:** Extend the problem to merge $K$ sorted linked lists instead of just two. You need to efficiently merge $K$ lists into one sorted list.\n", - "\n", - "2. **Merge Lists in a Zigzag Pattern:** Merge two sorted lists in a zigzag pattern. For example, given [1, 2, 4] and [1, 3, 5], the merged list should be [1, 1, 2, 3, 4, 5]." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/06. Linked List/23. Merge k Sorted Lists.ipynb b/_build/jupyter_execute/06. Linked List/23. Merge k Sorted Lists.ipynb deleted file mode 100644 index 0568867..0000000 --- a/_build/jupyter_execute/06. Linked List/23. Merge k Sorted Lists.ipynb +++ /dev/null @@ -1,277 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 23. Merge k Sorted Lists\n", - "\n", - "**Difficulty:** Hard\n", - "\n", - "**Link to Problem:** [To see the Merge k Sorted Lists problem on LeetCode, click here!](https://leetcode.com/problems/merge-k-sorted-lists/)\n", - "\n", - "---\n", - "\n", - "You are given an array of $k$ linked-lists lists, each linked-list is sorted in ascending order.\n", - "\n", - "Merge all the linked-lists into one sorted linked-list and return it.\n", - "\n", - "**Constraints:**\n", - "\n", - "- `k == lists.length`\n", - "- 0 <= k <= $10^4$\n", - "- `0 <= lists[i].length <= 500`\n", - "- $-10^4$ <= lists[i][j] <= $10^4$\n", - "- `lists[i]` is sorted in ascending order.\n", - "- The sum of `lists[i].length` will not exceed $10^4$.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "# Definition for singly-linked list.\n", - "class ListNode:\n", - " def __init__(self, val=0, next=None):\n", - " self.val = val\n", - " self.next = next\n", - "\n", - "class Solution:\n", - " def mergeKLists(self, lists: [[ListNode]]) -> ListNode:\n", - " # Check if the input list of linked lists is empty\n", - " if not lists or len(lists) == 0:\n", - " return None\n", - "\n", - " # Loop until there is only one merged list left\n", - " while len(lists) > 1:\n", - " mergedLists = []\n", - "\n", - " # Merge pairs of lists\n", - " for i in range(0, len(lists), 2):\n", - " l1 = lists[i]\n", - " l2 = lists[i + 1] if (i + 1) < len(lists) else None\n", - " mergedLists.append(self.mergeList(l1, l2))\n", - "\n", - " # Update the list of lists with merged results\n", - " lists = mergedLists\n", - " \n", - " # Return the final merged list\n", - " return lists[0]\n", - "\n", - " def mergeList(self, l1, l2):\n", - " # Create a dummy node to simplify merging\n", - " dummy = ListNode()\n", - " tail = dummy\n", - "\n", - " # Merge the two sorted lists\n", - " while l1 and l2:\n", - " if l1.val < l2.val:\n", - " tail.next = l1\n", - " l1 = l1.next\n", - " else:\n", - " tail.next = l2\n", - " l2 = l2.next\n", - " tail = tail.next\n", - "\n", - " # Append any remaining elements from l1 or l2 (if any)\n", - " if l1:\n", - " tail.next = l1\n", - " if l2:\n", - " tail.next = l2\n", - "\n", - " # Return the merged result starting from the next of the dummy node\n", - " return dummy.next\n" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The provided code defines a Python class `Solution` with two methods for merging k sorted linked lists:\n", - "\n", - "1. `mergeKLists(self, lists: List[ListNode]) -> ListNode`: This method takes a list of k sorted linked lists as input and returns a single merged sorted linked list. It uses a divide-and-conquer approach to repeatedly merge pairs of lists until only one merged list remains.\n", - "\n", - "2. `mergeList(self, l1, l2)`: This method takes two sorted linked lists, `l1` and `l2`, as input and merges them into a single sorted linked list. It uses a dummy node to simplify the merging process.\n", - "\n", - "Here's a high-level overview of how the code works:\n", - "\n", - "- The `mergeKLists` method checks if the input list of linked lists is empty or contains no lists. If there are no lists, it returns `None`.\n", - "\n", - "- Inside a `while` loop, the code repeatedly merges pairs of linked lists until only one merged list remains in the `lists` array. It does this by iterating through the input lists in pairs and calling the `mergeList` method to merge each pair.\n", - "\n", - "- The `mergeList` method takes two sorted linked lists, `l1` and `l2`, and merges them into a single sorted linked list. It uses a dummy node (`dummy`) and a `tail` pointer to keep track of the merged list while comparing and merging elements from `l1` and `l2`.\n", - "\n", - "- After merging all pairs of lists and updating the `lists` array with the merged results, the loop continues until only one merged list remains in the `lists` array.\n", - "\n", - "- Finally, the `mergeKLists` method returns the merged list.\n", - "\n", - "Overall, this code efficiently merges k sorted linked lists using a divide-and-conquer strategy, resulting in a single merged sorted linked list as the output." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1 -> 1 -> 2 -> 3 -> 4 -> 4 -> 5 -> 6 -> " - ] - } - ], - "source": [ - "### Example 1\n", - "# Input: lists = [[1,4,5],[1,3,4],[2,6]]\n", - "\n", - "lists1 = [\n", - " ListNode(1, ListNode(4, ListNode(5))),\n", - " ListNode(1, ListNode(3, ListNode(4))),\n", - " ListNode(2, ListNode(6))\n", - "]\n", - "solution = Solution()\n", - "result1 = solution.mergeKLists(lists1)\n", - "\n", - "# Print the result\n", - "if result1:\n", - " current = result1\n", - " while current:\n", - " print(current.val, end=\" -> \")\n", - " current = current.next\n", - "else:\n", - " print(\"None\") # Print \"None\" for input with a single None element" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "None\n" - ] - } - ], - "source": [ - "### Example 2\n", - "# Input: lists = []\n", - "\n", - "lists2 = []\n", - "solution = Solution()\n", - "result2 = solution.mergeKLists(lists2)\n", - "\n", - "# Print the result\n", - "if result2:\n", - " current = result2\n", - " while current:\n", - " print(current.val, end=\" -> \")\n", - " current = current.next\n", - "else:\n", - " print(\"None\") # Print \"None\" for input with a single None element" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "e140b956-7b3d-40d5-b6b0-9615860af67e", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "None\n" - ] - } - ], - "source": [ - "### Example 3\n", - "# Input: lists = [[]]\n", - "\n", - "lists3 = [None]\n", - "solution = Solution()\n", - "result3 = solution.mergeKLists(lists3)\n", - "\n", - "# Print the result\n", - "if result3:\n", - " current = result3\n", - " while current:\n", - " print(current.val, end=\" -> \")\n", - " current = current.next\n", - "else:\n", - " print(\"None\") # Print \"None\" for input with a single None element" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. **Heap Initialization:** The code does not use a heap. Instead, it uses a divide-and-conquer approach. The initial check for empty input lists takes $O(1)$ time.\n", - "\n", - "2. **Merging:** The merging operation is performed in a divide-and-conquer fashion. In each iteration of the `while` loop, we merge pairs of linked lists, and the number of comparisons made is proportional to the total number of nodes across all the linked lists ($n$). In each merge step, we effectively process each node once. The number of iterations required to reduce k lists to 1 is $O(log\\ k)$.\n", - "\n", - " Therefore, the overall time complexity of the code is $O(n * log\\ k)$, where n is the total number of nodes across all lists, and $k$ is the number of linked lists.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. **Heap Space:** The code doesn't use a heap data structure, so there's no additional space complexity due to a heap.\n", - "\n", - "2. **Merged Lists:** In the `mergeList` method, we create a new merged list. However, this list is not stored in memory for all lists; it's replaced with each merged pair. The space used for these merged lists is proportional to the size of the largest merged list, which is $O(n)$ in the worst case.\n", - "\n", - "3. **Additional Variables:** The code uses a few additional variables, such as `dummy` and `tail`, but these occupy a constant amount of space and don't depend on the input size.\n", - "\n", - " Therefore, the overall space complexity of the code is $O(n)$, where n is the total number of nodes across all lists.\n", - "\n", - "In summary, the code's time complexity is $O(n * log(k))$, and its space complexity is $O(n)$. This code efficiently merges $k$ sorted linked lists using a divide-and-conquer approach with a relatively low space overhead." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/07. Trees/100. Same Tree.ipynb b/_build/jupyter_execute/07. Trees/100. Same Tree.ipynb deleted file mode 100644 index 2238b48..0000000 --- a/_build/jupyter_execute/07. Trees/100. Same Tree.ipynb +++ /dev/null @@ -1,203 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 100: Same Tree\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Same Tree problem on LeetCode, click here!](https://leetcode.com/problems/same-tree/)\n", - "\n", - "---\n", - "\n", - "Given the roots of two binary trees `p` and `q`, write a function to check if they are the same or not.\n", - "\n", - "Two binary trees are considered the same if they are structurally identical, and the nodes have the same value.\n", - "\n", - "**Constraints**\n", - "\n", - "1. The number of nodes in both trees is in the range `[0, 100]`.\n", - "2. $-10^4$ <= Node.val <= $10^4$\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "# Definition for a binary tree node.\n", - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " # Initialize a TreeNode with a value (val), left child, and right child.\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def isSameTree(p, q):\n", - " # Base case: If both p and q are None, the trees are the same.\n", - " if not p and not q:\n", - " return True\n", - " \n", - " # Base case: If either p or q is None (but not both), the trees are different.\n", - " if not p or not q:\n", - " return False\n", - " \n", - " # Check if the values of the current nodes (p.val and q.val) are equal.\n", - " if p.val != q.val:\n", - " return False\n", - " \n", - " # Recursively check the left and right subtrees of p and q.\n", - " # If both subtrees are the same, the entire trees are the same.\n", - " return isSameTree(p.left, q.left) and isSameTree(p.right, q.right)" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "In this code, we define a `TreeNode` class to represent binary tree nodes and a `isSameTree` function to check if two binary trees are the same. The function uses recursive traversal to compare the trees' structures and values.\n", - "\n", - "1. We start by defining a `TreeNode` class, which represents a node in a binary tree. Each node has a `val` (the node's value), a `left` child, and a right child. This class will help us create and work with binary trees.\n", - "2. Next, we define the `isSameTree` function, which checks if two binary trees (`p` and `q`) are the same.\n", - " + The base case for the recursion is when both `p` and `q` are `None`. In this case, they are considered the same, so we return `True`.\n", - " + If either `p` or `q` is `None` (but not both), they cannot be the same, so we return `False`.\n", - " + If the values of the current nodes `p.val` and `q.val` are not equal, we return `False` because the trees cannot be the same.\n", - " + Finally, we recursively check the left and right subtrees of `p` and `q` to see if they are the same." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "### Example 1\n", - "\n", - "#Input: `p = [1,2,3]`, `q = [1,2,3]`\n", - "\n", - "p1 = TreeNode(1, TreeNode(2), TreeNode(3))\n", - "q1 = TreeNode(1, TreeNode(2), TreeNode(3))\n", - "print(isSameTree(p1, q1)) " - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "### Example 2\n", - "\n", - "#Input: `p = [1,2]`, `q = [1,null,2]`\n", - "\n", - "p2 = TreeNode(1, TreeNode(2), None)\n", - "q2 = TreeNode(1, None, TreeNode(2))\n", - "print(isSameTree(p2, q2))" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "5897c29d-26f8-486a-878c-43c09ff25ce4", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "### Example 3\n", - "\n", - "#Input: p = [1,2,1], q = [1,1,2]\n", - "\n", - "p3 = TreeNode(1, TreeNode(2), TreeNode(1))\n", - "q3 = TreeNode(1, TreeNode(1), TreeNode(2))\n", - "print(isSameTree(p3, q3))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time Complexity\n", - "\n", - "The time complexity of the `isSameTree` function can be analyzed as follows:\n", - "\n", - "In the worst case, the function needs to visit every node in both trees once to determine if they are the same.\n", - "Since each node is visited exactly once, the time complexity is $O(n)$, where $n$ is the total number of nodes in the input trees.\n", - "\n", - "## Space Complexity\n", - "The space complexity of the `isSameTree` function can be analyzed as follows:\n", - "\n", - "The space used by the function's call stack during recursion is proportional to the maximum depth of the binary trees.\n", - "In the worst case, when the trees are completely unbalanced (all nodes form a single branch), the maximum depth will be $n$, where $n$ is the total number of nodes in the input trees.\n", - "Therefore, the space complexity is $O(n)$ due to the recursive call stack.\n", - "In addition to the call stack, there is a small constant amount of space used for variables and comparisons within each recursive call, but this space is not significant in terms of the overall space complexity.\n", - "\n", - "## In summary:\n", - "\n", - "+ **Time Complexity:** $O(n)$ where $n$ is the total number of nodes in the input trees.\n", - "+ **Space Complexity:** $O(n)$ due to the recursive call stack." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/07. Trees/102. Binary Tree Level Order Traversal.ipynb b/_build/jupyter_execute/07. Trees/102. Binary Tree Level Order Traversal.ipynb deleted file mode 100644 index 9d2cc7f..0000000 --- a/_build/jupyter_execute/07. Trees/102. Binary Tree Level Order Traversal.ipynb +++ /dev/null @@ -1,263 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 102. Binary Tree Level Order Traversal\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Binary Tree Level Order Traversal problem on LeetCode, click here!](https://leetcode.com/problems/binary-tree-level-order-traversal/)\n", - "\n", - "---\n", - "Given the `root` of a binary tree, return *the level order traversal of its nodes' values*. (i.e., from left to right, level by level).\n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the tree is in the range `[0, 2000]`.\n", - "- `-1000 <= Node.val <= 1000`\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def levelOrder(root):\n", - " # Check if the tree is empty, if so, return an empty list.\n", - " if not root:\n", - " return []\n", - "\n", - " # Initialize an empty list to store the result.\n", - " result = []\n", - " \n", - " # Initialize a queue with the root node to perform BFS.\n", - " queue = [root]\n", - "\n", - " while queue:\n", - " # Initialize an empty list to store the values of nodes at the current level.\n", - " level_values = []\n", - " \n", - " # Get the number of nodes at the current level.\n", - " level_size = len(queue)\n", - "\n", - " # Iterate through the nodes at the current level.\n", - " for _ in range(level_size):\n", - " # Dequeue the front node from the queue.\n", - " node = queue.pop(0)\n", - " \n", - " # Append the value of the current node to the level_values list.\n", - " level_values.append(node.val)\n", - "\n", - " # Enqueue the left and right children of the current node if they exist.\n", - " if node.left:\n", - " queue.append(node.left)\n", - " if node.right:\n", - " queue.append(node.right)\n", - "\n", - " # Append the level_values list (values at the current level) to the result list.\n", - " result.append(level_values)\n", - "\n", - " # Return the final result, which is a list of lists representing level order traversal.\n", - " return result" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We define a `TreeNode` class that represents a node in the binary tree. Each `TreeNode` object has a value (`val`) and two child nodes: `left` and `right`.\n", - "\n", - "2. The `levelOrder` function takes the root of the binary tree as its input and returns the level order traversal of the tree as a list of lists.\n", - "\n", - "3. We start by checking if the input `root` is `None`, which indicates an empty tree. If the tree is empty, we return an empty list because there are no nodes to traverse.\n", - "\n", - "4. We initialize an empty list called `result` to store the final result, which will be a list of lists containing node values at each level.\n", - "\n", - "5. We initialize a queue called `queue` with the root node. This queue will be used for breadth-first traversal of the tree.\n", - "\n", - "6. We enter a while loop that continues until the `queue` is empty. Inside the loop, we perform the following steps:\n", - "\n", - " - We initialize an empty list called `level_values` to store the values of nodes at the current level.\n", - "\n", - " - We determine the number of nodes at the current level by getting the length of the `queue`. This is done to process nodes level by level.\n", - "\n", - " - We iterate through the nodes at the current level using a for loop. For each node in the current level:\n", - "\n", - " - We dequeue (remove) the front node from the `queue`.\n", - "\n", - " - We append the value of the dequeued node to the `level_values` list, effectively collecting the values of nodes at the current level.\n", - "\n", - " - If the dequeued node has a left child, we enqueue the left child to the `queue`.\n", - "\n", - " - If the dequeued node has a right child, we enqueue the right child to the `queue`.\n", - "\n", - " - After processing all nodes at the current level, we append the `level_values` list to the `result` list. This represents the values at the current level.\n", - "\n", - "7. The loop continues until all levels have been traversed, and the `queue` becomes empty.\n", - "\n", - "8. Finally, we return the `result` list, which contains lists of node values at each level, representing the level order traversal of the binary tree.\n", - "\n", - "The code effectively performs a breadth-first traversal of the binary tree, processing nodes level by level, and constructs the result list that represents the level order traversal." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[3], [9, 20], [15, 7]]\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Construct the tree\n", - "root = TreeNode(3)\n", - "root.left = TreeNode(9)\n", - "root.right = TreeNode(20)\n", - "root.right.left = TreeNode(15)\n", - "root.right.right = TreeNode(7)\n", - "\n", - "result = levelOrder(root)\n", - "print(result)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[1]]\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "# Using the same tree as before\n", - "root = TreeNode(1)\n", - "result = levelOrder(root)\n", - "print(result)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "7fc71180-e586-4c37-9fcf-2f574cb2b9d6", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[]\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "# Creating a new tree for this example\n", - "root = None\n", - "result = levelOrder(root)\n", - "print(result)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `levelOrder` function:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The time complexity of this function is O(N), where N is the number of nodes in the binary tree. This is because we visit each node exactly once during the breadth-first traversal.\n", - "\n", - "In the worst case, we have to enqueue and dequeue all nodes in the binary tree, which is proportional to the number of nodes (N). In each level, we process all nodes in that level, and since there are a total of log(N) levels in a balanced binary tree, the time complexity can also be approximated as O(N) for unbalanced trees.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity of this function is O(N), where N is the number of nodes in the binary tree. Here's how the space complexity breaks down:\n", - "\n", - "1. The `result` list stores the level order traversal, and in the worst case, it contains N/2 levels (for a completely unbalanced binary tree). So, the space used by `result` is O(N).\n", - "\n", - "2. The `queue` data structure is used for BFS traversal. In the worst case, it can store all nodes at the last level of the tree. In a balanced binary tree, the maximum number of nodes at any level is 2^(log(N)), which is still O(N). In the case of an unbalanced tree, it can be even worse. So, the space used by `queue` is O(N).\n", - "\n", - "Overall, the dominant factor in terms of space complexity is the `queue`, and the space complexity is O(N).\n", - "\n", - "In summary, the function's time complexity is O(N), and its space complexity is also O(N). It is an efficient and optimal solution for performing a level order traversal of a binary tree." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Reverse Level Order Traversal:** Modify the `levelOrder` function to return the level order traversal in reverse order (from bottom to top). For example, if the input tree is `[3, 9, 20, null, null, 15, 7]`, the output should be `[[15, 7], [9, 20], [3]]`.\n", - "\n", - "2. **Zigzag Level Order Traversal:** Write a function that performs a level order traversal of a binary tree in a zigzag pattern. In a zigzag traversal, the nodes at even levels are traversed from left to right, and nodes at odd levels are traversed from right to left. For example, if the input tree is `[3, 9, 20, null, null, 15, 7]`, the output should be `[[3], [20, 9], [15, 7]]`." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/07. Trees/104. Maximum Depth of Binary Tree.ipynb b/_build/jupyter_execute/07. Trees/104. Maximum Depth of Binary Tree.ipynb deleted file mode 100644 index 87c5eaa..0000000 --- a/_build/jupyter_execute/07. Trees/104. Maximum Depth of Binary Tree.ipynb +++ /dev/null @@ -1,203 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 104. Maximum Depth of Binary Tree\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Invert Binary Tree problem on LeetCode, click here!](https://leetcode.com/problems/invert-binary-tree/)\n", - "\n", - "---\n", - "\n", - "Given the `root` of a binary tree, return its maximum depth.\n", - "\n", - "A binary tree's **maximum depth** is the number of nodes along the longest path from the root node down to the farthest leaf node.\n", - "\n", - "**Constraints:**\n", - "\n", - "- The number of nodes in the tree is in the range $[0, 10^4]$.\n", - "- `-100 <= Node.val <= 100`\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "# Definition for a binary tree node.\n", - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def maxDepth(root):\n", - " # Base case: If the root is None, the depth is 0.\n", - " if root is None:\n", - " return 0\n", - " \n", - " # Recursively calculate the maximum depth of the left and right subtrees.\n", - " left_depth = maxDepth(root.left)\n", - " right_depth = maxDepth(root.right)\n", - " \n", - " # Return the maximum depth of the tree by adding 1 to the maximum depth of the subtrees.\n", - " return max(left_depth, right_depth) + 1" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "Let's go through the code step by step to understand how it works:\n", - "\n", - "1. We start by defining a `TreeNode` class to represent the nodes of the binary tree. Each node has three attributes:\n", - " - `val`: the value stored in the node.\n", - " - `left`: a reference to the left child node.\n", - " - `right`: a reference to the right child node.\n", - "\n", - "2. The `maxDepth` function is the main function that calculates the maximum depth of the binary tree. It takes a single argument, `root`, which is the root node of the binary tree.\n", - "\n", - "3. In the `maxDepth` function, we have a base case:\n", - " - If the `root` is `None`, it means we have reached the end of a branch of the tree (a leaf node or an empty subtree). In this case, the depth is 0 because there are no nodes to count.\n", - "\n", - "4. If the `root` is not `None`, we recursively calculate the maximum depth of the left and right subtrees:\n", - " - We call `maxDepth` on the `root.left` to calculate the maximum depth of the left subtree and store it in the variable `left_depth`.\n", - " - We call `maxDepth` on the `root.right` to calculate the maximum depth of the right subtree and store it in the variable `right_depth`.\n", - "\n", - "5. Finally, we return the maximum depth of the tree by taking the maximum of `left_depth` and `right_depth` and adding 1 to it. This is because we are counting the current level as well." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3\n" - ] - } - ], - "source": [ - "### Example 1\n", - "# Input: root = [3,9,20,null,null,15,7]\n", - "\n", - "root = TreeNode(3)\n", - "root.left = TreeNode(9)\n", - "root.right = TreeNode(20)\n", - "root.right.left = TreeNode(15)\n", - "root.right.right = TreeNode(7)\n", - "\n", - "print(maxDepth(root))" - ] - }, - { - "cell_type": "markdown", - "id": "a230be4f-1f47-4919-87e3-62fc3f072d97", - "metadata": {}, - "source": [ - "In this example, we create a binary tree based on the given input `[3,9,20,null,null,15,7]` and calculate its maximum depth, which is `3`. The tree structure is as follows:\n", - " ```\n", - " 3\n", - " / \\\n", - " 9 20\n", - " / \\\n", - " 15 7\n", - " ```\n", - "\n", - "So, the maximum depth is the length of the longest path from the root to a leaf node, which is 3 in this case." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2\n" - ] - } - ], - "source": [ - "### Example 2\n", - "# Input: root = [1,null,2]\n", - "\n", - "root = TreeNode(1)\n", - "root.right = TreeNode(2)\n", - "\n", - "# Calculate the maximum depth of the tree and print the result\n", - "print(maxDepth(root))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "- The time complexity of the `maxDepth` function is $O(N)$, where $N$ is the number of nodes in the binary tree.\n", - "- This is because in the worst case, the function visits every node exactly once in a depth-first manner.\n", - "- The recursion explores all nodes of the tree, so the time complexity is linear with respect to the number of nodes.\n", - "\n", - "**Space Complexity:**\n", - "- The space complexity of the `maxDepth` function is $O(H)$, where H is the height of the binary tree.\n", - "- In the worst case, if the binary tree is completely unbalanced (skewed), the recursion stack can go as deep as the height of the tree.\n", - "- In the best case, if the binary tree is perfectly balanced, the height is $O(log\\ N)$, where $N$ is the number of nodes.\n", - "- Therefore, the space complexity can vary from $O(log\\ N)$ to $O(N)$ depending on the shape of the tree.\n", - "- In addition to the recursion stack, there is a small constant amount of space used for variables and function call overhead.\n", - "\n", - "**In summary:**\n", - "- The time complexity of the code is $O(N)$ as it visits each node once.\n", - "- The space complexity is $O(H)$, where H is the height of the tree, which can vary from $O(log\\ N)$ to $O(N)$ depending on the tree's shape." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.ipynb b/_build/jupyter_execute/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.ipynb deleted file mode 100644 index 0d5bbd6..0000000 --- a/_build/jupyter_execute/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.ipynb +++ /dev/null @@ -1,305 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 105. Construct Binary Tree from Preorder and Inorder Traversal\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Construct Binary Tree from Preorder and Inorder Traversal problem on LeetCode, click here!](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/)\n", - "\n", - "---\n", - "Given two integer arrays `preorder` and `inorder` where `preorder` is the preorder traversal of a binary tree and `inorder` is the inorder traversal of the same tree, construct and return *the binary tree.*\n", - "\n", - "**Constraints:**\n", - "- `1 <= preorder.length <= 3000`\n", - "- `inorder.length == preorder.length`\n", - "- `-3000 <= preorder[i], inorder[i] <= 3000`\n", - "- `preorder` and `inorder` consist of **unique** values.\n", - "- Each value of `inorder` also appears in `preorder`.\n", - "- `preorder` is **guaranteed** to be the preorder traversal of the tree.\n", - "- `inorder` is **guaranteed** to be the inorder traversal of the tree.\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def buildTree(preorder, inorder):\n", - " if not preorder:\n", - " return None\n", - "\n", - " # The first element in the preorder traversal is the root of the current subtree\n", - " root_val = preorder[0]\n", - " root = TreeNode(root_val)\n", - "\n", - " # Find the index of the root value in the inorder traversal\n", - " root_idx_inorder = inorder.index(root_val)\n", - "\n", - " # Recursively build left and right subtrees\n", - " root.left = buildTree(preorder[1:1 + root_idx_inorder], inorder[:root_idx_inorder])\n", - " root.right = buildTree(preorder[1 + root_idx_inorder:], inorder[root_idx_inorder + 1:])\n", - "\n", - " return root" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. `class TreeNode:`: This is a class definition for a binary tree node. It has three attributes:\n", - " - `val`: The value of the node.\n", - " - `left`: A reference to the left child node.\n", - " - `right`: A reference to the right child node.\n", - "\n", - " This class is used to create instances of binary tree nodes, which will be used to build the binary tree.\n", - "\n", - "2. `def buildTree(preorder, inorder):`: This is the main function that constructs a binary tree from its preorder and inorder traversals.\n", - "\n", - " - `preorder`: A list representing the preorder traversal of the binary tree.\n", - " - `inorder`: A list representing the inorder traversal of the binary tree.\n", - "\n", - "3. `if not preorder: return None`: This line checks if the `preorder` list is empty. If it is, it means there are no nodes to construct, so the function returns `None`.\n", - "\n", - "4. `root_val = preorder[0]`: The value of the root node is extracted from the first element of the `preorder` list.\n", - "\n", - "5. `root = TreeNode(root_val)`: A new `TreeNode` object is created with the `root_val` as its value. This represents the root of the current subtree.\n", - "\n", - "6. `root_idx_inorder = inorder.index(root_val)`: The index of the `root_val` in the `inorder` list is found. This index indicates the position of the root node in the inorder traversal.\n", - "\n", - "7. `root.left`: The left subtree is constructed recursively by calling the `buildTree` function with the appropriate sublists of `preorder` and `inorder`. The left subtree's preorder and inorder traversals are the slices of `preorder` and `inorder` lists up to the `root_idx_inorder`.\n", - "\n", - "8. `root.right`: The right subtree is constructed recursively by calling the `buildTree` function with the appropriate sublists of `preorder` and `inorder`. The right subtree's preorder and inorder traversals are the slices of `preorder` and `inorder` lists starting from `root_idx_inorder + 1`.\n", - "\n", - "9. Finally, the function returns the `root` of the subtree it just constructed.\n", - "\n", - "The recursive approach used here divides the problem of constructing the entire binary tree into smaller subproblems, starting with the root node and then recursively building the left and right subtrees until the entire tree is constructed." - ] - }, - { - "cell_type": "markdown", - "id": "2d82857b-4fbe-474f-bf33-17b55c20147b", - "metadata": {}, - "source": [ - "## Helper Function \n", - "\n", - "Here is a helper function to represent the binary tree elements." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "13e6f3e1-659d-479d-9521-75629b8c782f", - "metadata": {}, - "outputs": [], - "source": [ - "def treeToList(root):\n", - " # Initialize an empty list to store the elements of the binary tree\n", - " result = []\n", - " \n", - " # Initialize a queue for level-order traversal starting with the root\n", - " queue = [root]\n", - "\n", - " while queue:\n", - " # Pop the front node from the queue\n", - " node = queue.pop(0)\n", - " \n", - " # If the node is not None (i.e., a valid node), add its value to the result list\n", - " if node:\n", - " result.append(node.val)\n", - " \n", - " # Add the left and right children of the node to the queue\n", - " queue.append(node.left)\n", - " queue.append(node.right)\n", - " else:\n", - " # If the node is None, add None to the result to represent an empty node\n", - " result.append(None)\n", - "\n", - " # Remove any trailing None values from the result list\n", - " while result and result[-1] is None:\n", - " result.pop()\n", - "\n", - " # Return the resulting list representing the binary tree elements\n", - " return result" - ] - }, - { - "cell_type": "markdown", - "id": "86cd4c9d-a120-4dd1-a1bd-530436012574", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "Let's break down the `treeToList` helper function step by step:\n", - "\n", - "1. `def treeToList(root):`: This function takes the root of a binary tree as input and converts it into a list.\n", - "\n", - "2. `result = []`: Initialize an empty list called `result` to store the elements of the binary tree in list format.\n", - "\n", - "3. `queue = [root]`: Initialize a queue data structure for a level-order traversal, starting with the root node.\n", - "\n", - "4. `while queue:`: This starts a loop that continues until the queue is empty, indicating that all nodes have been processed.\n", - "\n", - "5. `node = queue.pop(0)`: Dequeue the first node from the queue, effectively processing it.\n", - "\n", - "6. `if node:`: Check if the `node` is not None, which means it's a valid node in the binary tree.\n", - "\n", - " a. `result.append(node.val)`: If the node is valid, append its value (`node.val`) to the `result` list. This represents the value of the current node in the binary tree.\n", - "\n", - " b. `queue.append(node.left)`: Enqueue the left child of the current node if it exists. This adds the left child to the queue for processing in the next iteration.\n", - "\n", - " c. `queue.append(node.right)`: Enqueue the right child of the current node if it exists. This adds the right child to the queue for processing in the next iteration.\n", - "\n", - "7. `else:`: If the `node` is None, it represents an empty node in the binary tree.\n", - "\n", - " a. `result.append(None)`: Append `None` to the `result` list to indicate an empty node.\n", - "\n", - "8. `while result and result[-1] is None:`: After the traversal is complete, there might be trailing `None` values in the `result` list. This loop removes any such trailing `None` values to ensure a clean representation of the tree's elements.\n", - "\n", - "9. `return result`: Return the `result` list, which now contains the elements of the binary tree in a format where `None` represents empty nodes and the order of elements reflects a level-order traversal of the tree.\n", - "\n", - "In summary, the `treeToList` function performs a level-order traversal of the binary tree using a queue, constructing a list where each element corresponds to a node's value or represents an empty node with `None`. This list represents the binary tree's elements in a structured format." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[3, 9, 20, None, None, 15, 7]\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "preorder = [3, 9, 20, 15, 7]\n", - "inorder = [9, 3, 15, 20, 7]\n", - "result = buildTree(preorder, inorder)\n", - "\n", - "print(treeToList(result))" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[-1]\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "preorder = [-1]\n", - "inorder = [-1]\n", - "result = buildTree(preorder, inorder)\n", - "\n", - "print(treeToList(result))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `buildTree` function:\n", - "\n", - "**Time Complexity:**\n", - "The time complexity of the `buildTree` function can be analyzed in terms of the number of nodes in the binary tree. Let's assume there are `n` nodes in the binary tree.\n", - "\n", - "1. Finding the root value in the `preorder` traversal takes O(1) time as it's just extracting the first element from the list.\n", - "2. Finding the index of the root value in the `inorder` traversal using `inorder.index(root_val)` takes O(n) time in the worst case because in the worst case, it might have to search through all `n` elements in the `inorder` list to find the index.\n", - "3. The recursive calls to `buildTree` for the left and right subtrees are made once for each node in the tree. Therefore, the recursive calls have a combined time complexity of O(n) as they process each node once.\n", - "\n", - "The total time complexity of the `buildTree` function is O(n) due to the recursive calls and finding the root's index in the `inorder` list.\n", - "\n", - "**Space Complexity:**\n", - "The space complexity is determined by the space used by the function's call stack during recursion and any additional data structures used. \n", - "\n", - "1. The space used by the function call stack during recursion depends on the height of the binary tree. In the worst case, where the tree is highly unbalanced (e.g., a skewed tree), the space complexity for the call stack is O(n) as it can go as deep as the number of nodes in the tree.\n", - "\n", - "2. Additionally, the function creates TreeNode objects for each node in the binary tree. Therefore, the space complexity for these objects is also O(n).\n", - "\n", - "Overall, the space complexity of the `buildTree` function is O(n) due to the space used by the call stack and the TreeNode objects.\n", - "\n", - "In summary, the time complexity of `buildTree` is O(n), and the space complexity is O(n), where 'n' is the number of nodes in the binary tree." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Construct Binary Tree from Postorder and Inorder Traversal:**\n", - " Modify the problem to construct a binary tree from its postorder and inorder traversals. Implement a function similar to `buildTree` but for postorder and inorder traversals.\n", - "\n", - "2. **Reconstruct Binary Tree with Duplicate Values:**\n", - " Extend the problem to handle binary trees with duplicate values. Ensure that your solution correctly handles scenarios where there are duplicate values in the preorder and inorder traversals." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/07. Trees/124. Binary Tree Maximum Path Sum.ipynb b/_build/jupyter_execute/07. Trees/124. Binary Tree Maximum Path Sum.ipynb deleted file mode 100644 index b661fa1..0000000 --- a/_build/jupyter_execute/07. Trees/124. Binary Tree Maximum Path Sum.ipynb +++ /dev/null @@ -1,243 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 124. Binary Tree Maximum Path Sum\n", - "\n", - "**Difficulty:** Hard\n", - "\n", - "**Link to Problem:** [To see the Binary Tree Maximum Path Sum problem on LeetCode, click here!](https://leetcode.com/problems/binary-tree-maximum-path-sum/)\n", - "\n", - "---\n", - "A **path** in a binary tree is a sequence of nodes where each pair of adjacent nodes in the sequence has an edge connecting them. A node can only appear in the sequence **at most once**. Note that the path does not need to pass through the root.\n", - "\n", - "The **path sum** of a path is the sum of the node's values in the path.\n", - "\n", - "Given the `root` of a binary tree, return *the maximum **path sum** of any **non-empty** path*.\n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the tree is in the range $[1, 3*10^4]$.\n", - "- `-1000 <= Node.val <= 1000`" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is to find the maximum path sum in a binary tree. A path in a binary tree is a sequence of nodes where each pair of adjacent nodes in the sequence has an edge connecting them. The path sum of a path is the sum of the node values in that path.\n", - "\n", - "In this problem, you are given the root of a binary tree, and you need to find the maximum path sum among all possible paths in the tree. Note that the path does not need to start at the root node or end at a leaf node; it can start and end at any nodes in the tree.\n", - "\n", - "To find the maximum path sum, you need to consider both left and right subtrees of each node while traversing the tree. At each node, you have two choices:\n", - "\n", - "1. Include the current node in the path: In this case, you add the value of the current node to the sum and continue exploring both the left and right subtrees for possible extensions of the path.\n", - "\n", - "2. Start a new path from the current node: In this case, you do not include the current node in the path sum, and you choose either the left subtree or the right subtree to start a new path.\n", - "\n", - "To solve this problem, you can use a recursive approach to traverse the binary tree. For each node, you calculate the maximum path sum that can pass through that node (option 1) and also return the maximum path sum that can be extended from that node (option 2). You keep track of the global maximum path sum encountered during the traversal.\n", - "\n", - "Ultimately, the maximum path sum among all paths in the tree will be the maximum of the global maximum path sum and the maximum path sum calculated for each node.\n", - "\n", - "The constraints for this problem include:\n", - "\n", - "- The number of nodes in the tree is in the range $[1, 3 * 10^4]$.\n", - "- Node values are in the range [-1000, 1000].\n", - "\n", - "By considering all possible paths through the tree, the algorithm aims to find the most significant sum of node values in any path in the binary tree.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "class Solution:\n", - " def maxPathSum(self, root):\n", - " def max_path_sum_helper(node):\n", - " if not node:\n", - " return 0\n", - " \n", - " # Recursively calculate the maximum path sum for left and right subtrees\n", - " left_max = max(0, max_path_sum_helper(node.left))\n", - " right_max = max(0, max_path_sum_helper(node.right))\n", - " \n", - " # Update the global maximum path sum\n", - " self.max_sum = max(self.max_sum, left_max + right_max + node.val)\n", - " \n", - " # Return the maximum path sum starting from the current node\n", - " return max(left_max, right_max) + node.val\n", - " \n", - " self.max_sum = float('-inf') # Initialize the global maximum to negative infinity\n", - " max_path_sum_helper(root) # Start the recursive traversal from the root\n", - " return self.max_sum" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. The code starts by defining a `TreeNode` class to represent nodes in the binary tree. Each `TreeNode` has a `val` attribute representing its value, a `left` attribute pointing to the left child, and a `right` attribute pointing to the right child.\n", - "\n", - "2. Next, a `Solution` class is defined to contain the `maxPathSum` method, which will be used to find the maximum path sum in the binary tree.\n", - "\n", - "3. Within the `maxPathSum` method, a helper function called `max_path_sum_helper` is defined. This recursive function takes a single argument, `node`, which is the current node being considered during traversal.\n", - "\n", - "4. Inside the `max_path_sum_helper` function:\n", - " - If `node` is `None` (i.e., the current node is a null node), it returns 0. This is the base case of the recursion.\n", - " - It calculates the maximum path sum starting from the left subtree (`left_max`) and the right subtree (`right_max`). Importantly, it uses `max(0, ...)` to ensure that negative values (which would make the path sum smaller) are not considered. If a subtree's path sum is negative, it's better to not include it in the path.\n", - " - The code then updates the global maximum path sum (`self.max_sum`) by checking if the sum of `left_max`, `right_max`, and the current node's value is greater than the current maximum.\n", - " - Finally, it returns the maximum path sum starting from the current node, which is the maximum of `left_max` and `right_max` plus the current node's value.\n", - "\n", - "5. Before calling the `max_path_sum_helper` function, the `max_sum` attribute of the `Solution` class is initialized to negative infinity (`float('-inf')`). This is done to ensure that any valid path sum encountered during traversal will be greater than the initial value of `max_sum`.\n", - "\n", - "6. The `max_path_sum_helper` function is called with the root of the binary tree, effectively starting the traversal from the root node.\n", - "\n", - "7. Once the traversal is complete, the method returns the value of `self.max_sum`, which contains the maximum path sum found in the binary tree.\n", - "\n", - "8. Example usage at the bottom of the code demonstrates how to create binary trees and use the `maxPathSum` method to find the maximum path sum for two different tree structures.\n", - "\n", - "In summary, the code uses a recursive approach to explore all possible paths in the binary tree, ensuring that negative path sums are not considered. It keeps track of the maximum path sum encountered and returns that maximum value as the result." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "6\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "root1 = TreeNode(1)\n", - "root1.left = TreeNode(2)\n", - "root1.right = TreeNode(3)\n", - "solution = Solution()\n", - "print(solution.maxPathSum(root1))" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "42\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "root2 = TreeNode(-10)\n", - "root2.left = TreeNode(9)\n", - "root2.right = TreeNode(20)\n", - "root2.right.left = TreeNode(15)\n", - "root2.right.right = TreeNode(7)\n", - "print(solution.maxPathSum(root2))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the given code:\n", - "\n", - "Time Complexity:\n", - "- The code uses a recursive depth-first traversal to explore each node in the binary tree exactly once.\n", - "- During the traversal, for each node, we perform constant time operations, such as updating the `max_sum` variable and calculating the maximum path sum starting from that node.\n", - "- Therefore, the time complexity of the code is O(N), where N is the number of nodes in the binary tree.\n", - "\n", - "Space Complexity:\n", - "- The space complexity of the code is determined by the space used in the call stack during the recursive traversal.\n", - "- In the worst case, the depth of the call stack can be equal to the height of the binary tree. In an unbalanced tree, this could be O(N), but in a balanced binary tree, the height is O(log N).\n", - "- Additionally, the code uses a constant amount of space for variables like `left_max`, `right_max`, and `max_sum`.\n", - "- Therefore, the overall space complexity is O(H), where H is the height of the binary tree. In the worst case, it's O(N), and in the best case (a balanced binary tree), it's O(log N).\n", - "\n", - "In summary:\n", - "- Time Complexity: O(N)\n", - "- Space Complexity: O(H), where H is the height of the binary tree, ranging from O(log N) to O(N) depending on the tree's balance." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Print the Maximum Path:**\n", - " Modify the code to not only find the maximum path sum but also print the nodes involved in the maximum path. You can print the nodes in the correct order from the root to the leaf.\n", - "\n", - "2. **Path Sum Count:**\n", - " Instead of finding the maximum path sum, find the count of unique paths that sum to a given target value. Each path can start and end anywhere in the tree." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/07. Trees/199. Binary Tree Right Side View.ipynb b/_build/jupyter_execute/07. Trees/199. Binary Tree Right Side View.ipynb deleted file mode 100644 index 5bbdf42..0000000 --- a/_build/jupyter_execute/07. Trees/199. Binary Tree Right Side View.ipynb +++ /dev/null @@ -1,249 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 199. Binary Tree Right Side View\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Binary Tree Right Side View problem on LeetCode, click here!](https://leetcode.com/problems/binary-tree-right-side-view/)\n", - "\n", - "---\n", - "Given the `root` of a binary tree, imagine yourself standing on the **right side** of it, return *the values of the nodes you can see ordered from top to bottom*.\n", - "\n", - " \n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the tree is in the range `[0, 2000]`.\n", - "- `-100 <= Node.val <= 100`\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def rightSideView(root):\n", - " if not root:\n", - " return [] # If the tree is empty, return an empty list.\n", - "\n", - " result = [] # Initialize a list to store the right side view values.\n", - " queue = [root] # Initialize a queue for level-order traversal with the root node.\n", - "\n", - " while queue:\n", - " # Get the number of nodes at the current level.\n", - " level_size = len(queue)\n", - "\n", - " # Traverse all nodes at the current level and add the rightmost node to the result.\n", - " for i in range(level_size):\n", - " node = queue.pop(0) # Dequeue the first node from the queue.\n", - "\n", - " # If it's the rightmost node at this level, add its value to the result.\n", - " if i == level_size - 1:\n", - " result.append(node.val)\n", - "\n", - " # Add the children of the current node to the queue.\n", - " if node.left:\n", - " queue.append(node.left)\n", - " if node.right:\n", - " queue.append(node.right)\n", - "\n", - " return result # Return the list of right side view values.\n" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start with a binary tree represented using a TreeNode class. Each node has a value (`val`) and can have a left child (`left`) and a right child (`right`).\n", - "\n", - "2. The `rightSideView` function takes the root node of the binary tree as input and returns a list of values representing the nodes you can see when standing on the right side of the tree.\n", - "\n", - "3. We check if the `root` is `None`, which means the tree is empty. If it's empty, we return an empty list because there are no nodes to see.\n", - "\n", - "4. We initialize an empty list called `result` to store the right side view values.\n", - "\n", - "5. We initialize a queue called `queue` with the root node. This queue is used for a level-order traversal of the tree.\n", - "\n", - "6. We enter a while loop that continues until the `queue` is empty. Inside this loop, we perform the following steps for each level of the tree:\n", - "\n", - " a. We determine the number of nodes at the current level by getting the length of the `queue`. This is important for processing nodes at the same level together.\n", - "\n", - " b. We then iterate through the nodes at the current level using a for loop. For each node in the level, we dequeue it from the `queue` using `queue.pop(0)`.\n", - "\n", - " c. If the node we dequeue is the rightmost node at the current level (determined by `i == level_size - 1`), we add its `val` to the `result` list. This is because, when standing on the right side of the tree, you can see the rightmost node at each level.\n", - "\n", - " d. We enqueue the left and right children of the current node (if they exist) to the `queue`. This ensures that we process the next level in the subsequent iterations of the while loop.\n", - "\n", - "7. After processing all levels of the tree, the `result` list contains the values of the rightmost nodes in each level, ordered from top to bottom.\n", - "\n", - "8. Finally, we return the `result` list as the output of the function, which represents the right side view of the binary tree.\n", - "\n", - "The code effectively performs a level-order traversal of the binary tree while keeping track of the rightmost nodes at each level and adding them to the result list. This ensures that we obtain the correct order of nodes visible from the right side of the tree." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 3, 4]\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Construct the tree\n", - "root1 = TreeNode(1)\n", - "root1.left = TreeNode(2)\n", - "root1.right = TreeNode(3)\n", - "root1.left.right = TreeNode(5)\n", - "root1.right.right = TreeNode(4)\n", - "print(rightSideView(root1))" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 3]\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "root2 = TreeNode(1)\n", - "root2.right = TreeNode(3)\n", - "print(rightSideView(root2))" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "7fc71180-e586-4c37-9fcf-2f574cb2b9d6", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[]\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "# Creating a new tree for this example\n", - "root = None\n", - "result = rightSideView(root)\n", - "print(result)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the given code:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The time complexity of the code is O(N), where N is the number of nodes in the binary tree. Here's why:\n", - "\n", - "1. We perform a level-order traversal of the tree using a queue. In the worst case, we visit all nodes once, which takes O(N) time since we visit each node exactly once.\n", - "\n", - "2. For each node, we perform constant-time operations like dequeuing it from the queue, checking if it's the rightmost node at the current level, and enqueuing its children (if they exist). These operations do not depend on the size of the tree, so they do not contribute to the overall time complexity.\n", - "\n", - "Therefore, the dominant factor in the time complexity is the level-order traversal, making it O(N).\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity of the code is also O(N). Here's why:\n", - "\n", - "1. We use a queue to perform level-order traversal. In the worst case, the queue can contain all nodes at the maximum width of the tree, which can be up to N/2 nodes for a completely unbalanced tree. Therefore, the space required for the queue is O(N).\n", - "\n", - "2. The `result` list stores the values of the rightmost nodes. In the worst case, when the binary tree is a complete binary tree, it can have roughly N/2 rightmost nodes. Therefore, the space required for the `result` list is also O(N).\n", - "\n", - "3. Other auxiliary variables like `level_size`, `i`, and `node` require only constant space and do not depend on the size of the tree.\n", - "\n", - "Combining the space used by the queue and the `result` list, we get a space complexity of O(N).\n", - "\n", - "In summary, the code has a time complexity of O(N) and a space complexity of O(N), where N is the number of nodes in the binary tree. These complexities are efficient and scale linearly with the size of the input tree." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Variant with Left Side View**: Modify the code to find and return the values of nodes visible from the left side of the binary tree instead of the right side.\n", - "\n", - "2. **Zigzag Right Side View**: Extend the code to return the right side view values in a zigzag order. In a zigzag order, you alternate between starting from the rightmost node at level 0, then the leftmost at level 1, rightmost at level 2, and so on." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/07. Trees/226. Invert Binary Tree.ipynb b/_build/jupyter_execute/07. Trees/226. Invert Binary Tree.ipynb deleted file mode 100644 index 3e542c9..0000000 --- a/_build/jupyter_execute/07. Trees/226. Invert Binary Tree.ipynb +++ /dev/null @@ -1,215 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 226: Invert Binary Tree\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Invert Binary Tree problem on LeetCode, click here!](https://leetcode.com/problems/invert-binary-tree/)\n", - "\n", - "---\n", - "\n", - "Given the root of a binary tree, invert the tree, and return its root.\n", - "\n", - "**Constraints:**\n", - "\n", - "- The number of nodes in the tree is in the range `[0, 100]`.\n", - "- `-100 <= Node.val <= 100`\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "# Definition for a binary tree node.\n", - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def invertTree(root):\n", - " # Base case: If the root is None or the tree is empty, return None.\n", - " if not root:\n", - " return None\n", - "\n", - " # Swap the left and right subtrees of the current node.\n", - " root.left, root.right = root.right, root.left\n", - "\n", - " # Recursively invert the left and right subtrees.\n", - " invertTree(root.left)\n", - " invertTree(root.right)\n", - "\n", - " return root" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start by defining a TreeNode class, which represents a node in a binary tree. Each node has a value (`val`), a left child (`left`), and a right child (`right`).\n", - "\n", - "2. The `invertTree` function is defined to invert the binary tree. It takes the root node of the tree as an argument.\n", - "\n", - "3. In the `invertTree` function, we have a base case to handle the scenario when the root is `None` (empty tree). In such cases, we return `None` because there's nothing to invert.\n", - "\n", - "4. For non-empty trees, we swap the left and right subtrees of the current node. This effectively inverts the tree at the current node.\n", - "\n", - "5. We then recursively call `invertTree` on the left and right subtrees to invert them.\n", - "\n", - "6. Finally, we return the root of the inverted tree." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Inverted Tree (Example 1): <__main__.TreeNode object at 0x7faa5c445ab0>\n" - ] - } - ], - "source": [ - "### Example 1\n", - "# Input: root = [4,2,7,1,3,6,9]\n", - "\n", - "root1 = TreeNode(4)\n", - "root1.left = TreeNode(2)\n", - "root1.right = TreeNode(7)\n", - "root1.left.left = TreeNode(1)\n", - "root1.left.right = TreeNode(3)\n", - "root1.right.left = TreeNode(6)\n", - "root1.right.right = TreeNode(9)\n", - "\n", - "inverted_root1 = invertTree(root1)\n", - "print(\"Inverted Tree (Example 1):\", inverted_root1)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Inverted Tree (Example 2): <__main__.TreeNode object at 0x7faa5c444310>\n" - ] - } - ], - "source": [ - "### Example 2\n", - "# Input: root = [2,1,3]\n", - "\n", - "root2 = TreeNode(2)\n", - "root2.left = TreeNode(1)\n", - "root2.right = TreeNode(3)\n", - "\n", - "inverted_root2 = invertTree(root2)\n", - "print(\"Inverted Tree (Example 2):\", inverted_root2)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "5897c29d-26f8-486a-878c-43c09ff25ce4", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Inverted Tree (Example 3): None\n" - ] - } - ], - "source": [ - "### Example 3\n", - "# Input: root = []\n", - "\n", - "root3 = None # Empty tree\n", - "\n", - "inverted_root3 = invertTree(root3)\n", - "print(\"Inverted Tree (Example 3):\", inverted_root3)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's discuss the time and space complexity of the provided Python code to invert a binary tree.\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The time complexity of the `invertTree` function is $O(n)$, where $n$ is the number of nodes in the binary tree. This is because we visit each node exactly once during the traversal of the tree. In the worst case, we have to visit all nodes in the tree.\n", - "\n", - "The reason for this time complexity is the depth-first traversal of the tree, where we recursively process the left and right subtrees of each node.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity of the code is determined by the function call stack during the recursion. In the worst case, the space complexity is $O(h)$, where $h$ is the height of the binary tree. \n", - "\n", - "In a completely unbalanced binary tree (essentially a linked list), the height $h$ is equal to the number of nodes $n$, resulting in a space complexity of $O(n)$. This occurs when the tree is skewed to one side.\n", - "\n", - "In a balanced binary tree, such as a full binary tree, the height $h$ is $O(log\\ n)$, and the space complexity is $O(log\\ n)$.\n", - "\n", - "The space complexity depends on how balanced the tree is. In practical scenarios, binary trees are often approximately balanced, so the space complexity is typically closer to $O(log\\ n)$.\n", - "\n", - "**In summary:**\n", - "\n", - "- Time Complexity: $O(n)$ where $n$ is the number of nodes.\n", - "- Space Complexity: $O(h)$, where $h$ is the height of the binary tree. In the worst case, it can be $O(n)$, and in a balanced tree, it is $O(log\\ n)$.\n", - "\n", - "Keep in mind that these complexities are based on the recursive implementation provided. Iterative solutions can achieve the same task with $O(1)$ space complexity, using auxiliary data structures like stacks or queues to mimic the recursion stack." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/07. Trees/230. Kth Smallest Element in a BST.ipynb b/_build/jupyter_execute/07. Trees/230. Kth Smallest Element in a BST.ipynb deleted file mode 100644 index fdad9ba..0000000 --- a/_build/jupyter_execute/07. Trees/230. Kth Smallest Element in a BST.ipynb +++ /dev/null @@ -1,215 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 230. Kth Smallest Element in a BST\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Kth Smallest Element in a BST problem on LeetCode, click here!](https://leetcode.com/problems/kth-smallest-element-in-a-bst/)\n", - "\n", - "---\n", - "Given the `root` of a binary search tree, and an integer `k`, return *the $k^{th}$ smallest value (**1-indexed**) of all the values of the nodes in the tree.*\n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the tree is `n`.\n", - "- 1 <= `k <= n` <= $10^4$\n", - "- 0 <= `Node.val` <= $10^4$\n", - "\n", - "**Follow up**: If the BST is modified often (i.e., we can do insert and delete operations) and you need to find the kth smallest frequently, how would you optimize?\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def kthSmallest(root, k):\n", - " stack = [] # Initialize an empty stack to simulate the traversal\n", - " while root or stack:\n", - " while root:\n", - " stack.append(root) # Push the current node onto the stack\n", - " root = root.left # Move to the left child\n", - " root = stack.pop() # Pop a node from the stack\n", - " k -= 1 # Decrement k since we've visited a node\n", - " if k == 0:\n", - " return root.val # If k becomes 0, return the current node's value as the kth smallest\n", - " root = root.right # Move to the right child to continue the traversal" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start by defining a `TreeNode` class, which represents a node in the binary search tree (BST). Each node has a value (`val`), a left child (`left`), and a right child (`right`).\n", - "\n", - "2. The `kthSmallest` function takes two parameters: `root`, which is the root of the BST, and `k`, which represents the kth smallest element we want to find.\n", - "\n", - "3. We initialize an empty stack (`stack`) to simulate the traversal of the BST. The stack will be used to keep track of nodes as we traverse the tree in an iterative manner.\n", - "\n", - "4. We enter a while loop that continues until either `root` becomes `None` (indicating we have traversed the entire tree) or the `stack` is empty.\n", - "\n", - "5. Within the loop, we start another while loop to traverse as far left as possible in the BST. We repeatedly push nodes onto the `stack` and move to their left children until we reach the leftmost leaf node. This is the smallest node in the BST.\n", - "\n", - "6. Once we have reached the leftmost leaf node (the smallest node), we pop nodes from the `stack` one by one. As we pop each node, we decrement `k` by 1 to keep track of the number of nodes we have visited.\n", - "\n", - "7. If `k` becomes 0 after decrementing, it means we have found the kth smallest element. In this case, we return the `val` of the current node as the result.\n", - "\n", - "8. If `k` is still greater than 0, it means we haven't found the kth smallest element yet. In this case, we move to the right child of the current node to continue the traversal, as the kth smallest element, if it exists, will be in the right subtree of the current node.\n", - "\n", - "9. The process continues until we find the kth smallest element or traverse the entire tree.\n", - "\n", - "10. Finally, we return the kth smallest element found.\n", - "\n", - "The key idea in this code is to perform an in-order traversal of the BST while keeping track of the kth smallest element. By visiting nodes in ascending order, we can efficiently find the kth smallest element in O(h + k) time, where h is the height of the BST and k is the desired kth element. This approach is both concise and efficient for this problem." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "# Create the tree for the first example: root = [3,1,4,null,2], k = 1\n", - "root1 = TreeNode(3)\n", - "root1.left = TreeNode(1)\n", - "root1.right = TreeNode(4)\n", - "root1.left.right = TreeNode(2)\n", - "k1 = 1\n", - "print(kthSmallest(root1, k1)) " - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "# Create the tree for the second example: root = [5,3,6,2,4,null,null,1], k = 3\n", - "root2 = TreeNode(5)\n", - "root2.left = TreeNode(3)\n", - "root2.right = TreeNode(6)\n", - "root2.left.left = TreeNode(2)\n", - "root2.left.right = TreeNode(4)\n", - "root2.left.left.left = TreeNode(1)\n", - "k2 = 3\n", - "print(kthSmallest(root2, k2))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the given code:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The time complexity of this code is O(h + k), where:\n", - "- h is the height of the binary search tree (BST).\n", - "- k is the desired kth smallest element we want to find.\n", - "\n", - "1. In the worst case, where the BST is highly unbalanced and resembles a linked list, the height (h) of the tree can be equal to the number of nodes (n) in the tree. In this case, the time complexity is O(n + k).\n", - "\n", - "2. In the best case, where the BST is perfectly balanced, the height (h) is log(n), where n is the number of nodes in the tree. In this case, the time complexity is O(log(n) + k).\n", - "\n", - "So, the time complexity can vary from O(log(n) + k) in the best-case scenario to O(n + k) in the worst-case scenario. Typically, for balanced BSTs, the time complexity is closer to O(log(n) + k).\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity of this code is O(h) due to the stack used for the iterative in-order traversal, where h is the height of the BST.\n", - "\n", - "1. In the worst case, when the BST is highly unbalanced and resembles a linked list, the height (h) of the tree can be equal to the number of nodes (n) in the tree. In this case, the space complexity is O(n) because the stack can potentially store all n nodes.\n", - "\n", - "2. In the best case, when the BST is perfectly balanced, the height (h) is log(n), where n is the number of nodes in the tree. In this case, the space complexity is O(log(n)) because the stack will have at most log(n) nodes.\n", - "\n", - "So, the space complexity depends on the height of the BST and can vary from O(log(n)) in the best-case scenario to O(n) in the worst-case scenario.\n", - "\n", - "In practical terms, for balanced BSTs or moderately unbalanced BSTs, the space complexity is usually close to O(log(n)), and the code is efficient in terms of space usage." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Kth Largest Element**: Modify the code to find the kth largest element in the BST instead of the kth smallest element.\n", - "\n", - "2. **Kth Smallest Element in Two BSTs**: Given two BSTs, find the kth smallest element when considering both BSTs as a single sorted list. This involves merging the two BSTs while finding the kth element efficiently." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.ipynb b/_build/jupyter_execute/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.ipynb deleted file mode 100644 index 0179ca4..0000000 --- a/_build/jupyter_execute/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.ipynb +++ /dev/null @@ -1,237 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 235. Lowest Common Ancestor of a Binary Search Tree\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Lowest Common Ancestor of a Binary Search Tree problem on LeetCode, click here!](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/)\n", - "\n", - "---\n", - "Given a binary search tree (BST), find the lowest common ancestor (LCA) node of two given nodes in the BST.\n", - "\n", - "According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes `p` and `q` as the lowest node in `T` that has both `p` and `q` as descendants (where we allow **a node to be a descendant of itself**).”\n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the tree is in the range $[2, 10^5]$.\n", - "- $-10^9$ <= `Node.val` <= $10^9$\n", - "- All `Node.val` are **unique**.\n", - "- `p != q`\n", - "- `p` and `q` will exist in the BST.\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def lowestCommonAncestor(root, p, q):\n", - " # Ensure p is less than q\n", - " if p.val > q.val:\n", - " p, q = q, p\n", - "\n", - " while root:\n", - " # If the current node value is greater than both p and q, move left\n", - " if root.val > q.val:\n", - " root = root.left\n", - " # If the current node value is less than both p and q, move right\n", - " elif root.val < p.val:\n", - " root = root.right\n", - " # If the current node value is between p and q (inclusive), or it matches either p or q, it's the LCA\n", - " else:\n", - " return root" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. `class TreeNode:` defines a simple class for representing nodes in a binary tree. Each `TreeNode` has three attributes:\n", - " - `val`: The value of the node.\n", - " - `left`: A reference to the left child node.\n", - " - `right`: A reference to the right child node.\n", - "\n", - "2. `def lowestCommonAncestor(root, p, q):` is a function that takes three arguments:\n", - " - `root`: The root node of the BST.\n", - " - `p`: A TreeNode representing one of the nodes for which we want to find the LCA.\n", - " - `q`: A TreeNode representing the other node for which we want to find the LCA.\n", - "\n", - "3. `if p.val > q.val:` checks if the value of `p` is greater than the value of `q`. In a BST, it's essential to ensure that `p` represents the smaller value, and `q` represents the larger value. If `p` is greater than `q`, the code swaps their values.\n", - "\n", - "4. The main logic is inside the `while` loop, which runs until `root` becomes `None`. It performs the following steps to find the LCA:\n", - " - If the current `root` node's value is greater than the value of `q`, it means both `p` and `q` are on the left subtree of the current node. So, we move to the left child of the current node by setting `root = root.left`.\n", - " - If the current `root` node's value is less than the value of `p`, it means both `p` and `q` are on the right subtree of the current node. So, we move to the right child of the current node by setting `root = root.right`.\n", - " - If neither of the above conditions is met, it means the current `root` node's value is between `p` and `q`, or it matches either `p` or `q`. In this case, the current node is the lowest common ancestor (LCA), so we return `root`.\n", - "\n", - "The algorithm is efficient because it takes advantage of the properties of a BST. It eliminates subtrees that cannot contain the LCA by comparing the values of `p`, `q`, and the current `root` node. Eventually, it reaches the LCA node, and that node is returned as the result." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "6\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Construct the tree\n", - "root = TreeNode(6)\n", - "root.left = TreeNode(2)\n", - "root.right = TreeNode(8)\n", - "root.left.left = TreeNode(0)\n", - "root.left.right = TreeNode(4)\n", - "root.right.left = TreeNode(7)\n", - "root.right.right = TreeNode(9)\n", - "root.left.right.left = TreeNode(3)\n", - "root.left.right.right = TreeNode(5)\n", - "\n", - "p = root.left # Node 2\n", - "q = root.right # Node 8\n", - "\n", - "result = lowestCommonAncestor(root, p, q)\n", - "print(result.val)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "# Using the same tree as before\n", - "p = root.left # Node 2\n", - "q = root.left.right # Node 4\n", - "\n", - "result = lowestCommonAncestor(root, p, q)\n", - "print(result.val) " - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "7fc71180-e586-4c37-9fcf-2f574cb2b9d6", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "# Creating a new tree for this example\n", - "root2 = TreeNode(2)\n", - "root2.left = TreeNode(1)\n", - "\n", - "p = root2 # Node 2\n", - "q = root2.left # Node 1\n", - "\n", - "result = lowestCommonAncestor(root2, p, q)\n", - "print(result.val)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided algorithm for finding the lowest common ancestor (LCA) in a Binary Search Tree (BST).\n", - "\n", - "**Time Complexity:**\n", - "The time complexity of this algorithm is O(h), where \"h\" is the height of the BST. In the worst case, where the tree is completely unbalanced (essentially a linked list), the height of the tree is O(n), where \"n\" is the number of nodes in the tree. However, in a well-balanced BST, the height is logarithmic, which is O(log n).\n", - "\n", - "The reason for this time complexity is that the algorithm efficiently narrows down the search space by traversing either left or right subtrees based on the values of the target nodes `p` and `q`. It eliminates entire subtrees that cannot contain the LCA, leading to a relatively quick search.\n", - "\n", - "**Space Complexity:**\n", - "The space complexity of the algorithm is O(1). This is because it uses a constant amount of extra space, regardless of the size of the input BST. The only variables used are `root`, `p`, and `q`, and there are no data structures like stacks or queues used for additional space. The algorithm performs a simple traversal without recursion, so it does not consume extra memory as the tree depth increases.\n", - "\n", - "**In summary**, the provided algorithm for finding the LCA in a BST is both time and space-efficient. Its time complexity is O(h), where \"h\" is the height of the tree, and its space complexity is O(1), making it suitable for practical use even in large BSTs." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "### Challenging Exercises:\n", - "\n", - "1. **Multiple LCAs:** Extend the algorithm to find all the lowest common ancestors of two given nodes `p` and `q` in a BST. In some cases, there can be multiple LCAs.\n", - "\n", - "2. **LCA with k Nodes:** Given a BST and k nodes, find the lowest common ancestor of these k nodes. This is an extension of the problem where you must find the LCA of more than two nodes." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/07. Trees/297. Serialize and Deserialize Binary Tree.ipynb b/_build/jupyter_execute/07. Trees/297. Serialize and Deserialize Binary Tree.ipynb deleted file mode 100644 index 78a78b5..0000000 --- a/_build/jupyter_execute/07. Trees/297. Serialize and Deserialize Binary Tree.ipynb +++ /dev/null @@ -1,291 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 297. Serialize and Deserialize Binary Tree\n", - "\n", - "**Difficulty:** Hard\n", - "\n", - "**Link to Problem:** [To see the Serialize and Deserialize Binary Tree problem on LeetCode, click here!](https://leetcode.com/problems/serialize-and-deserialize-binary-tree/)\n", - "\n", - "---\n", - "Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.\n", - "\n", - "Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure.\n", - "\n", - "**Clarification:** The input/output format is the same as how LeetCode serializes a binary tree. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself.\n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the tree is in the range $[0, 10^4]$.\n", - "- `-1000 <= Node.val <= 1000`" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "TThe problem is to design an algorithm to serialize and deserialize a binary tree. Serialization is the process of converting a data structure or object into a sequence of characters or bytes so that it can be easily stored in a file, transmitted over a network, or otherwise persisted. Deserialization is the reverse process of converting the serialized data back into the original data structure.\n", - "\n", - "In the context of this problem:\n", - "\n", - "1. **Serialization**: You are given a binary tree, and your task is to convert it into a string representation such that you can later recreate the same binary tree from this string. The format of serialization is flexible, but it should allow you to reconstruct the original binary tree accurately.\n", - "\n", - "2. **Deserialization**: Given a serialized string, you need to reconstruct the binary tree it represents, ensuring that it is identical to the original tree.\n", - "\n", - "Here are some key points to consider in solving this problem:\n", - "\n", - "- The input can include any valid binary tree, including trees with nodes having integer values within the range [-1000, 1000].\n", - "- You don't necessarily need to follow a specific format for serialization, but it should be designed in a way that allows unambiguous deserialization.\n", - "- The goal is to serialize the tree structure and its values and then deserialize it back into the same structure and values.\n", - "\n", - "A common approach for serialization is to use a traversal method like preorder traversal, where you visit nodes in the order: root, left subtree, right subtree. This way, you can serialize the tree into a string, and during deserialization, you can reconstruct the tree by parsing the string in the same order.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "# Definition for a binary tree node.\n", - "class TreeNode(object):\n", - " def __init__(self, x):\n", - " self.val = x\n", - " self.left = None\n", - " self.right = None\n", - "\n", - "class Codec:\n", - " def serialize(self, root):\n", - " serialized = []\n", - "\n", - " def dfs(node):\n", - " if not node:\n", - " # If the node is None, represent it as \"Null\" in the serialized string\n", - " serialized .append(\"Null\")\n", - " return\n", - " # Convert the node's value to a string and add it to the serialized string\n", - " serialized .append(str(node.val))\n", - " dfs(node.left)\n", - " dfs(node.right)\n", - "\n", - " dfs(root)\n", - " # Join the serialized values with \",\"\n", - " return \",\".join(serialized )\n", - "\n", - " def deserialize(self, data):\n", - " vals = data.split(\",\")\n", - " self.i = 0\n", - "\n", - " def dfs():\n", - " if vals[self.i] == \"Null\":\n", - " self.i += 1\n", - " return None\n", - " # Convert the value to an integer to create a new node\n", - " node = TreeNode(int(vals[self.i]))\n", - " self.i += 1\n", - " node.left = dfs()\n", - " node.right = dfs()\n", - " return node\n", - "\n", - " return dfs()" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "Here's a step-by-step explanation of the code:\n", - "\n", - "1. **Definition of TreeNode**:\n", - " - The code defines a simple `TreeNode` class that represents a node in a binary tree. Each `TreeNode` has three attributes:\n", - " - `val`: The integer value stored in the node.\n", - " - `left`: A reference to the left child node (or None if there is no left child).\n", - " - `right`: A reference to the right child node (or None if there is no right child).\n", - " - This class allows you to create binary tree nodes with integer values and left and right child references.\n", - "\n", - "2. **Serialization (serialize method)**:\n", - " - The `serialize` method takes a `root` node as input, which is the root of the binary tree that needs to be serialized.\n", - " - It initializes an empty list `serialized` to store the serialized elements.\n", - " - The `dfs` (depth-first search) function is defined within the `serialize` method to perform a preorder traversal of the binary tree.\n", - " - In the `dfs` function:\n", - " - If the current `node` is `None` (i.e., a leaf node or a child of a leaf node), it appends the string \"Null\" to the `serialized` list to represent the absence of a node.\n", - " - If the current `node` is not `None`, it appends the string representation of the `node.val` to the `serialized` list and then recursively calls `dfs` on the left and right children.\n", - " - After the `dfs` traversal, the `serialized` list contains the serialized binary tree elements.\n", - " - The method returns a string obtained by joining the elements in the `serialized` list with commas.\n", - "\n", - "3. **Deserialization (deserialize method)**:\n", - " - The `deserialize` method takes a serialized string `data` as input, which represents a binary tree in the custom format.\n", - " - It splits the `data` string by commas to obtain a list of elements called `vals`.\n", - " - The method initializes an index `self.i` to 0. This index keeps track of the current position in the `vals` list during deserialization.\n", - " - The `dfs` function is defined within the `deserialize` method to perform the deserialization process using a recursive approach.\n", - " - In the `dfs` function:\n", - " - If the current element in `vals` is \"Null,\" it means there is no node at this position in the binary tree, so it returns `None`.\n", - " - If the current element is not \"Null,\" it converts the element to an integer to create a new `TreeNode` with that value.\n", - " - It then recursively calls `dfs` to set the left and right children of the current node.\n", - " - The method returns the root node of the reconstructed binary tree.\n", - "\n", - "Overall, this code demonstrates a way to serialize a binary tree into a string format and then deserialize it back into the original tree structure, allowing for the representation of both the tree structure and the values stored in the nodes." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1,2,Null,Null,3,4,Null,Null,5,Null,Null\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "# Serialize a binary tree\n", - "root = TreeNode(1)\n", - "root.left = TreeNode(2)\n", - "root.right = TreeNode(3)\n", - "root.right.left = TreeNode(4)\n", - "root.right.right = TreeNode(5)\n", - "\n", - "codec = Codec()\n", - "serialized_tree = codec.serialize(root)\n", - "print(serialized_tree)\n", - "\n", - "# Deserialize the serialized tree\n", - "new_root = codec.deserialize(serialized_tree)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Null\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "# Example usage:\n", - "# Serialize a binary tree\n", - "root = None\n", - "\n", - "codec = Codec()\n", - "serialized_tree = codec.serialize(root)\n", - "print(serialized_tree)\n", - "\n", - "# Deserialize the serialized tree\n", - "new_root = codec.deserialize(serialized_tree)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code for serializing and deserializing a binary tree:\n", - "\n", - "1. **Serialization (serialize method)**:\n", - "\n", - " - Time Complexity:\n", - " - The `serialize` method uses a depth-first traversal (preorder) of the binary tree.\n", - " - It visits each node exactly once.\n", - " - At each node, it performs constant-time operations (string conversion and list append).\n", - " - Therefore, the time complexity for serialization is O(N), where N is the number of nodes in the binary tree.\n", - "\n", - " - Space Complexity:\n", - " - The space complexity for serialization includes the space used by the `serialized` list and the recursive call stack.\n", - " - The `serialized` list stores the serialized elements, and its space is proportional to the number of nodes.\n", - " - The recursive call stack depth is determined by the height of the binary tree, and in the worst case (completely unbalanced tree), it can be O(N).\n", - " - Therefore, the space complexity for serialization is O(N) due to the list and O(H) due to the recursive call stack, where H is the height of the tree. In most cases, the dominant factor is O(N).\n", - "\n", - "2. **Deserialization (deserialize method)**:\n", - "\n", - " - Time Complexity:\n", - " - The `deserialize` method splits the serialized string into a list of elements, which takes O(N) time.\n", - " - The `dfs` function is a recursive function that visits each element in the list exactly once.\n", - " - At each element, it performs constant-time operations (string comparison, integer conversion, and recursive function calls).\n", - " - Therefore, the time complexity for deserialization is O(N).\n", - "\n", - " - Space Complexity:\n", - " - The space complexity for deserialization includes the space used by the `vals` list and the recursive call stack.\n", - " - The `vals` list stores the elements from the serialized string, and its space is proportional to the number of nodes.\n", - " - The recursive call stack depth is determined by the height of the binary tree, and in the worst case (completely unbalanced tree), it can be O(N).\n", - " - Therefore, the space complexity for deserialization is O(N) due to the list and O(H) due to the recursive call stack, where H is the height of the tree. In most cases, the dominant factor is O(N).\n", - "\n", - "Overall, the provided code has a time complexity of O(N) for both serialization and deserialization and a space complexity of O(N) in the majority of cases (unless the tree is severely unbalanced, in which case the height H dominates the space complexity). It efficiently serializes and deserializes a binary tree while using a linear amount of memory." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Efficient Serialization**:\n", - " Optimize the serialization process to minimize the length of the serialized string. Consider using techniques like binary encoding to represent node values more efficiently.\n", - "\n", - "2. **Custom Serialization Format**:\n", - " Modify the serialization and deserialization methods to use a custom format different from the one provided. Ensure that the new format allows for accurate reconstruction of the original binary tree." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/07. Trees/572. Subtree of Another Tree.ipynb b/_build/jupyter_execute/07. Trees/572. Subtree of Another Tree.ipynb deleted file mode 100644 index 425f22d..0000000 --- a/_build/jupyter_execute/07. Trees/572. Subtree of Another Tree.ipynb +++ /dev/null @@ -1,259 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 572: Subtree of Another Tree\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Subtree of Another Tree problem on LeetCode, click here!](https://leetcode.com/problems/subtree-of-another-tree/)\n", - "\n", - "---\n", - "\n", - "**Problem Description:**\n", - "\n", - "Given the roots of two binary trees `root` and `subRoot`, return `True` if there is a subtree of `root` with the same structure and node values as `subRoot`, and `False` otherwise.\n", - "\n", - "A subtree of a binary tree `tree` is a tree that consists of a node in `tree` and all of this node's descendants. The tree `tree` could also be considered as a subtree of itself.\n", - "\n", - "**Constraints:**\n", - "\n", - "1. The number of nodes in the `root` tree is in the range $[1, 2000]$.\n", - "2. The number of nodes in the `subRoot` tree is in the range $[1, 1000]$.\n", - "3. $-10^4$ <= root.val <= $10^4$\n", - "4. $-10^4$ <= subRoot.val <= $10^4$\n" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "# Definition for a binary tree node.\n", - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "class Solution:\n", - " def isSubtree(self, root, subRoot):\n", - " if not root:\n", - " return False\n", - " \n", - " # Check if the current subtree is equal to the subRoot\n", - " if self.isSameTree(root, subRoot):\n", - " return True\n", - " \n", - " # Recursively check the left and right subtrees\n", - " return self.isSubtree(root.left, subRoot) or self.isSubtree(root.right, subRoot)\n", - " \n", - " def isSameTree(self, tree1, tree2):\n", - " if not tree1 and not tree2:\n", - " return True\n", - " if not tree1 or not tree2:\n", - " return False\n", - " \n", - " return (\n", - " tree1.val == tree2.val and\n", - " self.isSameTree(tree1.left, tree2.left) and\n", - " self.isSameTree(tree1.right, tree2.right)\n", - " )" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "This code defines a TreeNode class for the binary tree nodes and a Solution class with two methods:\n", - "\n", - "1. `isSubtree`: This method checks if there is a subtree of the `root` tree with the same structure and node values as the `subRoot` tree. It uses a helper function `isSameTree` to compare two trees for equality.\n", - "\n", - "2. `isSameTree`: This helper method recursively compares two trees to check if they are the same in structure and node values.\n", - "\n", - "### Here's a detailed explanation of the code:\n", - "\n", - "1. **TreeNode Class:**\n", - "\n", - "The `TreeNode` class is defined to represent nodes in a binary tree. Each node has a `val` (the node's value) and may have a `left` and `right` child.\n", - "\n", - "2. **Solution Class:**\n", - "\n", - " + The `Solution` class contains the solution for the problem and defines two important methods:\n", - "\n", - " + `isSubtree(self, root, subRoot)`:\n", - "\n", - " - This method checks whether `subRoot` is a subtree of `root`. It takes two tree nodes, `root` and `subRoot`, as input arguments.\n", - " - If `root` is `None`, it returns `False` because there is no subtree to search.\n", - " - It then checks if the current subtree with `root` as its root is equal to `subRoot` using the `isSameTree` method. If they are the same, it returns `True`.\n", - " - If the current subtree is not the same as `subRoot`, it recursively checks the left and right subtrees of `root` to see if `subRoot` is a subtree of any of them.\n", - " - It returns `True` if `subRoot` is found in either the left or right subtree; otherwise, it returns `False`.\n", - "\n", - " + `isSameTree(self, tree1, tree2)`:\n", - "\n", - " - This method checks whether two trees, `tree1` and `tree2`, are the same.\n", - " - If both `tree1` and `tree2` are `None`, they are considered the same tree, so it returns `True`.\n", - " - If only one of them is `None` (but not both), they are different trees, so it returns `False`.\n", - " - If both `tree1` and `tree2` have values, it checks if their values are equal and recursively checks if their left and right subtrees are the same.\n", - " - It returns `True` if the trees are the same; otherwise, it returns `False`.\n", - "\n", - "The code effectively uses recursion to traverse the binary trees and check for subtree equality. The `isSubtree` method starts the recursive search, and the `isSameTree` method is used to compare individual subtrees. The approach is efficient and avoids unnecessary checks when possible.\n", - "\n", - "This solution allows you to determine if there exists a subtree within the `root` tree that matches the structure and node values of `subRoot`." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Is subRoot a subtree of root? True\n" - ] - } - ], - "source": [ - "#root = [3,4,5,1,2]\n", - "#subRoot = [4,1,2]\n", - "\n", - "# Example input\n", - "root = TreeNode(3)\n", - "root.left = TreeNode(4)\n", - "root.right = TreeNode(5)\n", - "root.left.left = TreeNode(1)\n", - "root.left.right = TreeNode(2)\n", - "\n", - "subRoot = TreeNode(4)\n", - "subRoot.left = TreeNode(1)\n", - "subRoot.right = TreeNode(2)\n", - "\n", - "# Create an instance of the Solution class\n", - "solution = Solution()\n", - "\n", - "# Test the isSubtree method\n", - "result = solution.isSubtree(root, subRoot)\n", - "print(\"Is subRoot a subtree of root?\", result)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Is subRoot a subtree of root? False\n" - ] - } - ], - "source": [ - "#root = [3,4,5,1,2,null,null,null,null,0] \n", - "#subRoot = [4,1,2]\n", - "\n", - "\n", - "# Example input\n", - "root = TreeNode(3)\n", - "root.left = TreeNode(4)\n", - "root.right = TreeNode(5)\n", - "root.left.left = TreeNode(1)\n", - "root.left.right = TreeNode(2)\n", - "root.left.right.left = TreeNode(0)\n", - "\n", - "subRoot = TreeNode(4)\n", - "subRoot.left = TreeNode(1)\n", - "subRoot.right = TreeNode(2)\n", - "\n", - "# Create an instance of the Solution class\n", - "solution = Solution()\n", - "\n", - "# Test the isSubtree method\n", - "result = solution.isSubtree(root, subRoot)\n", - "print(\"Is subRoot a subtree of root?\", result)" - ] - }, - { - "cell_type": "markdown", - "id": "86a34f0d-0789-498c-818c-2d30f84754d0", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the provided code for the \"Subtree of Another Tree\" problem:\n", - "\n", - "**Time Complexity**\n", - "\n", - "The time complexity of the code primarily depends on the recursive traversal of the binary tree. In both the `isSubtree` and `isSameTree` functions, we visit each node in the binary trees once. Let's break down the time complexity:\n", - "\n", - "1. The `isSubtree` function:\n", - " - In the worst case, we need to visit every node in the `root` tree.\n", - " - For each node in the `root` tree, we call the `isSameTree` function, which has its own traversal.\n", - " - So, the total time complexity is $O(n * m)$, where $n$ is the number of nodes in the `root` tree, and $m$ is the number of nodes in the `subRoot` tree.\n", - "\n", - "2. The `isSameTree` function:\n", - " - In the worst case, we visit every node in both `tree1` and `tree2`.\n", - " - The number of recursive calls made is proportional to the number of nodes in the trees.\n", - " - So, the time complexity of this function is $O(max(n, m))$, where $n$ and $m$ are the numbers of nodes in `tree1` and `tree2`, respectively.\n", - "\n", - "Overall, the time complexity of the entire code is $O(n * m)$, where $n$ is the number of nodes in the `root` tree, and $m$ is the number of nodes in the `subRoot` tree. In practice, it may be less than $O(n * m)$ if a subtree mismatch is detected early during the traversal.\n", - "\n", - "**Space Complexity**\n", - "\n", - "The space complexity of the code is determined by the function call stack during recursion and the space used by the recursive functions. Let's analyze the space complexity:\n", - "\n", - "1. The `isSubtree` function:\n", - " - It uses the call stack for recursion.\n", - " - The maximum depth of the recursion is equal to the height of the `root` tree, which can be $O(n)$ in the worst case (unbalanced tree).\n", - " - Additionally, the function doesn't use any significant extra space other than the recursion stack.\n", - "\n", - "2. The `isSameTree` function:\n", - " - It also uses the call stack for recursion.\n", - " - The maximum depth of the recursion is equal to the height of the `tree1` or `tree2`, whichever is greater.\n", - " - So, the maximum space used for the call stack is $O(max(n, m))$.\n", - "\n", - "In summary, the space complexity of the code is $O(max(n, m))$ due to the function call stack. It scales with the maximum height of the trees being compared.\n", - "\n", - "Overall, the code is efficient and works well for trees with moderate sizes. However, it's important to keep in mind that the worst-case time complexity is $O(n * m)$, so for very large trees, the performance may degrade." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/07. Trees/98. Validate Binary Search Tree.ipynb b/_build/jupyter_execute/07. Trees/98. Validate Binary Search Tree.ipynb deleted file mode 100644 index 0cbe2fc..0000000 --- a/_build/jupyter_execute/07. Trees/98. Validate Binary Search Tree.ipynb +++ /dev/null @@ -1,215 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 98. Validate Binary Search Tree\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Validate Binary Search Tree problem on LeetCode, click here!](https://leetcode.com/problems/validate-binary-search-tree/)\n", - "\n", - "---\n", - "Given the `root` of a binary tree, *determine if it is a valid binary search tree (BST)*.\n", - "\n", - "A **valid BST** is defined as follows:\n", - "\n", - "- The left subtree of a node contains only nodes with keys **less than** the node's key.\n", - "- The right subtree of a node contains only nodes with keys **greater than** the node's key.\n", - "- Both the left and right subtrees must also be binary search trees. \n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the tree is in the range $[1, 10^4]$.\n", - "- $-2^{31}$ <= `Node.val` <= $2^{31} - 1$\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def is_valid_BST(root):\n", - " def is_valid(node, min_val, max_val):\n", - " # Base case: If the node is None, it's a valid BST.\n", - " if node is None:\n", - " return True\n", - " \n", - " # Check if the current node's value is within the valid range.\n", - " if not (min_val < node.val < max_val):\n", - " return False\n", - " \n", - " # Recursively check the left and right subtrees with updated ranges.\n", - " return (is_valid(node.left, min_val, node.val) and\n", - " is_valid(node.right, node.val, max_val))\n", - " \n", - " # Call the helper function starting with a wide range for root node.\n", - " return is_valid(root, float('-inf'), float('inf'))" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "- It defines a `TreeNode` class to represent nodes in the binary tree.\n", - "\n", - "- The `is_valid_BST` function takes the root node of the binary tree as input and returns `True` if the tree is a valid BST, and `False` otherwise.\n", - "\n", - "- Inside the `is_valid_BST` function, there is a helper function called `is_valid` that performs the actual validation using a recursive approach.\n", - "\n", - "- The `is_valid` function checks each node in the tree to ensure that it satisfies the properties of a BST:\n", - " - The value of the current node must be within a valid range defined by `min_val` and `max_val`.\n", - " - The left subtree of the current node should contain values less than the current node's value.\n", - " - The right subtree of the current node should contain values greater than the current node's value.\n", - "\n", - "- If any of these conditions are violated, the function returns `False`, indicating that the tree is not a valid BST.\n", - "\n", - "- If all nodes satisfy these conditions, the function returns `True`, indicating that the tree is a valid BST.\n", - "\n", - "- The code calls the `is_valid` function with the root node and initial range values of negative infinity to positive infinity to start the validation.\n", - "\n", - "- The time complexity of the code is O(N), where N is the number of nodes in the tree, as it traverses each node once.\n", - "\n", - "- The space complexity depends on the height of the tree. In the average case for a balanced BST, the space complexity is O(log N), but in the worst case (skewed tree), it can be O(N) due to the recursive call stack.\n", - "\n", - "In summary, this code checks whether a given binary tree is a valid BST by recursively validating each node's value and its left and right subtrees while maintaining valid value ranges. If all nodes satisfy the BST properties, the tree is considered a valid BST." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "# Create the tree for the first example: [2, 1, 3]\n", - "root1 = TreeNode(2)\n", - "root1.left = TreeNode(1)\n", - "root1.right = TreeNode(3)\n", - "print(is_valid_BST(root1))" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "# Create the tree for the second example: [5, 1, 4, None, None, 3, 6]\n", - "root2 = TreeNode(5)\n", - "root2.left = TreeNode(1)\n", - "root2.right = TreeNode(4)\n", - "root2.right.left = TreeNode(3)\n", - "root2.right.right = TreeNode(6)\n", - "print(is_valid_BST(root2))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `is_valid_BST` function:\n", - "\n", - "**Time Complexity:**\n", - "- The time complexity of the function primarily depends on the number of nodes in the binary tree.\n", - "- In the worst case, we may have to visit every node in the tree once to validate whether it's part of a valid BST.\n", - "- Since we are performing a depth-first search (DFS) traversal of the tree, the time complexity is O(N), where N is the number of nodes in the tree.\n", - "\n", - "**Space Complexity:**\n", - "- The space complexity is determined by the space used by the recursive call stack during the DFS traversal.\n", - "- In the worst case, if the tree is completely unbalanced (a skewed tree), the maximum depth of the call stack would be equal to the height of the tree.\n", - "- In a balanced BST, the height is approximately log2(N), where N is the number of nodes.\n", - "- Therefore, the space complexity of the call stack is O(log N) for a balanced BST.\n", - "- In the worst case (skewed tree), the space complexity can be O(N) as the height of the tree can be equal to N.\n", - "\n", - "**Overall:**\n", - "- Time Complexity: O(N)\n", - "- Space Complexity: O(log N) on average for a balanced BST, and O(N) in the worst case for a skewed tree.\n", - "\n", - "The space complexity is typically dominated by the recursive call stack, and it varies depending on the shape of the binary tree. In practice, for balanced binary trees, the space complexity is often close to O(log N), which is quite efficient." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Complex Constraints**: Modify the problem to have more complex constraints on the tree. For example, consider a binary tree with constraints like \"The left subtree of a node contains only nodes with keys less than or equal to the node's key,\" and \"The right subtree of a node contains only nodes with keys greater than or equal to the node's key.\" How would you adapt the code to handle these constraints?\n", - "\n", - "2. **Handling Duplicates**: Modify the code to handle binary search trees that allow duplicate values. In a standard BST, each value is unique, but in this case, multiple nodes can have the same value. The tree should still be considered valid if it follows the BST property." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/08. Tries/208. Implement Trie (Prefix Tree).ipynb b/_build/jupyter_execute/08. Tries/208. Implement Trie (Prefix Tree).ipynb deleted file mode 100644 index 5c54c25..0000000 --- a/_build/jupyter_execute/08. Tries/208. Implement Trie (Prefix Tree).ipynb +++ /dev/null @@ -1,245 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 208. Implement Trie (Prefix Tree)\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Implement Trie problem on LeetCode, click here!](https://leetcode.com/problems/implement-trie-prefix-tree/)\n", - "\n", - "---\n", - "A **trie** (pronounced as \"try\") or **prefix tree** is a tree data structure used to efficiently store and retrieve keys in a dataset of strings. There are various applications of this data structure, such as autocomplete and spellchecker.\n", - "\n", - "Implement the Trie class:\n", - "\n", - "- `Trie()` Initializes the trie object.\n", - "- `void insert(String word)` Inserts the string `word` into the trie.\n", - "- `boolean search(String word)` Returns `true` if the string `word` is in the trie (i.e., was inserted before), and `false` otherwise.\n", - "- `boolean startsWith(String prefix)` Returns `true` if there is a previously inserted string `word` that has the prefix `prefix`, and `false` otherwise.\n", - "\n", - "\n", - "**Constraints:**\n", - "- `1 <= word.length, prefix.length <= 2000`\n", - "- `word` and `prefix` consist only of lowercase English letters.\n", - "- At most $3 * 10^4$ calls in total will be made to `insert`, `search`, and `startsWith`." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem at hand is to implement a data structure known as a Trie (pronounced \"try\") or Prefix Tree. A Trie is a tree-like data structure that is used to efficiently store and retrieve a set of strings or words. It's particularly useful for tasks involving string manipulation, such as autocomplete and spell-checking. The problem statement defines the following operations for implementing the Trie class:\n", - "\n", - "1. `Trie()`: This is the constructor that initializes the Trie object.\n", - "\n", - "2. `void insert(String word)`: This method inserts the given string `word` into the Trie. It effectively adds the characters of the word to the Trie's structure, creating nodes for each character if they don't already exist. At the end of the word, a special flag is set to indicate that this node represents the end of a valid word.\n", - "\n", - "3. `boolean search(String word)`: This method checks if the given string `word` is present in the Trie. It starts from the root of the Trie and traverses the Trie by following the characters in the word. If it successfully traverses the Trie and reaches the end of the word, it returns `true`, indicating that the word exists in the Trie; otherwise, it returns `false`.\n", - "\n", - "4. `boolean startsWith(String prefix)`: This method checks if there is any previously inserted word in the Trie that has the given `prefix`. It's similar to the `search` method but does not require that the prefix be a complete word. If there is any word in the Trie that starts with the given prefix, it returns `true`; otherwise, it returns `false`.\n", - "\n", - "The problem also provides an example scenario where these operations are called, demonstrating the expected output for each operation.\n", - "\n", - "In summary, the goal is to create a data structure (Trie) that efficiently stores a set of strings and provides methods to insert new strings, search for complete words, and check if a given prefix exists in the stored set of strings.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "class TrieNode:\n", - " def __init__(self):\n", - " self.children = {} # A dictionary to store child nodes\n", - " self.is_end_of_word = False # Indicates if a word ends at this node\n", - "\n", - "class Trie:\n", - " def __init__(self):\n", - " self.root = TrieNode() # Initialize the Trie with a root node\n", - "\n", - " def insert(self, word):\n", - " node = self.root # Start from the root\n", - " for char in word:\n", - " if char not in node.children:\n", - " node.children[char] = TrieNode() # Create a new node if the character is not present\n", - " node = node.children[char] # Move to the child node\n", - " node.is_end_of_word = True # Mark the end of the inserted word\n", - "\n", - " def search(self, word):\n", - " node = self.root # Start from the root\n", - " for char in word:\n", - " if char not in node.children:\n", - " return False # If the character is not found, the word is not in the Trie\n", - " node = node.children[char] # Move to the child node\n", - " return node.is_end_of_word # Check if the node represents the end of a valid word\n", - "\n", - " def startsWith(self, prefix):\n", - " node = self.root # Start from the root\n", - " for char in prefix:\n", - " if char not in node.children:\n", - " return False # If the character is not found, no word starts with the prefix\n", - " node = node.children[char] # Move to the child node\n", - " return True # Prefix found in the Trie" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "Let's explain how the code works step by step:\n", - "\n", - "1. `TrieNode` Class:\n", - " - `TrieNode` is a class that represents nodes in the Trie. Each node has two attributes:\n", - " - `children`: This is a dictionary that stores child nodes. Each key in the dictionary represents a character, and the corresponding value is the child node for that character.\n", - " - `is_end_of_word`: This boolean flag indicates whether the node represents the end of a complete word. Initially, it's set to `False` for all nodes.\n", - "\n", - "2. `Trie` Class:\n", - " - `Trie` is the main class that implements the Trie data structure. It has the following methods:\n", - "\n", - " - `__init__(self)`: The constructor initializes the Trie object by creating a root node, which serves as the starting point for all Trie operations.\n", - "\n", - " - `insert(self, word)`: This method inserts a string `word` into the Trie. It starts from the root node and iterates through each character in the word.\n", - " - If a character is not present as a child node, it creates a new node for that character.\n", - " - It then moves to the child node and continues the process until the entire word is inserted.\n", - " - Finally, it sets the `is_end_of_word` flag to `True` for the last node to mark the end of the inserted word.\n", - "\n", - " - `search(self, word)`: This method checks if a complete word (string) exists in the Trie. It starts from the root node and iterates through each character in the word.\n", - " - If a character is not found as a child node, it immediately returns `False` because the word is not in the Trie.\n", - " - It continues to move to the child node for each character.\n", - " - After reaching the end of the word, it checks if the `is_end_of_word` flag is `True` for the last node to confirm the presence of the word.\n", - "\n", - " - `startsWith(self, prefix)`: This method checks if there is any previously inserted word in the Trie that starts with a given `prefix`. It follows the same logic as the `search` method but does not require the entire word to be present.\n", - " - If the prefix is found in the Trie, it returns `True`; otherwise, it returns `False`.\n", - "\n", - "3. Example Usage:\n", - " - The code demonstrates how to create a Trie object, insert words (\"apple\" and \"app\"), and perform operations on the Trie:\n", - " - It inserts the word \"apple\" into the Trie.\n", - " - It checks if \"apple\" is in the Trie, which returns `True`.\n", - " - It checks if \"app\" is in the Trie, which returns `False`.\n", - " - It checks if there is any word in the Trie that starts with \"app,\" which returns `True`.\n", - " - It inserts the word \"app\" into the Trie.\n", - " - It checks if \"app\" is in the Trie again, which now returns `True`.\n", - "\n", - "In summary, the code efficiently implements a Trie data structure with the ability to insert words, search for complete words, and check for the existence of words with a given prefix. The Trie is organized as a tree of nodes, with each node representing a character in the words being stored." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n", - "False\n", - "True\n", - "True\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "\n", - "trie = Trie()\n", - "trie.insert(\"apple\")\n", - "print(trie.search(\"apple\")) # Output: True\n", - "print(trie.search(\"app\")) # Output: False\n", - "print(trie.startsWith(\"app\")) # Output: True\n", - "trie.insert(\"app\")\n", - "print(trie.search(\"app\")) # Output: True" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the Trie implementation:\n", - "\n", - "1. Time Complexity:\n", - " - Insertion (`insert` method): The time complexity of inserting a word into the Trie is O(m), where m is the length of the word. In the worst case, you may need to traverse the entire word to insert it into the Trie.\n", - " - Search (`search` method): The time complexity of searching for a word in the Trie is also O(m), where m is the length of the word. In the worst case, you may need to traverse the entire word to determine if it exists in the Trie.\n", - " - Starts with (`startsWith` method): The time complexity of checking if a prefix exists in the Trie is O(p), where p is the length of the prefix. In the worst case, you may need to traverse the entire prefix to determine its presence.\n", - "\n", - " Therefore, for each operation (insertion, search, or starts with), the time complexity is O(m) or O(p), where m is the length of the word being operated on, and p is the length of the prefix.\n", - "\n", - "2. Space Complexity:\n", - " - The space complexity of the Trie is determined by the number of nodes and characters stored in it. In the worst case, where none of the inserted words share common prefixes, the space complexity is O(N), where N is the total number of characters across all inserted words.\n", - " - Each node in the Trie represents a character, and the number of nodes is directly related to the total number of characters.\n", - "\n", - " In practice, the space complexity can be less than O(N) because common prefixes are shared among words in the Trie, leading to space optimization.\n", - "\n", - "In summary:\n", - "- Time complexity for each operation (insertion, search, starts with) is O(m) or O(p), where m is the length of the word and p is the length of the prefix.\n", - "- Space complexity is O(N) in the worst case, where N is the total number of characters across all inserted words. However, space optimization occurs due to common prefix sharing in practice, potentially reducing the actual space used." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Count Prefixes**:\n", - " Implement a method to count the number of words in the Trie that have a specific prefix. This exercise requires you to maintain additional data in the Trie nodes to keep track of the count.\n", - "\n", - "2. **Auto-Complete Suggestions**:\n", - " Implement an auto-complete feature using the Trie. Given a prefix, the program should return a list of suggested words based on the words previously inserted into the Trie." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/08. Tries/211. Design Add and Search Words Data Structure.ipynb b/_build/jupyter_execute/08. Tries/211. Design Add and Search Words Data Structure.ipynb deleted file mode 100644 index bdd867c..0000000 --- a/_build/jupyter_execute/08. Tries/211. Design Add and Search Words Data Structure.ipynb +++ /dev/null @@ -1,271 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 211. Design Add and Search Words Data Structure\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Design Add and Search Words Data Structure problem on LeetCode, click here!](https://leetcode.com/problems/design-add-and-search-words-data-structure/)\n", - "\n", - "---\n", - "Design a data structure that supports adding new words and finding if a string matches any previously added string.\n", - "\n", - "Implement the `WordDictionary` class:\n", - "\n", - "- `WordDictionary()` Initializes the object.\n", - "- `void addWord(word)` Adds `word` to the data structure, it can be matched later.\n", - "- `bool search(word)` Returns `true` if there is any string in the data structure that matches `word` or `false` otherwise. `word` may contain dots `'.'` where dots can be matched with any letter.\n", - "\n", - "**Constraints:**\n", - "- `1 <= word.length <= 25`\n", - "- `word` in `addWord` consists of lowercase English letters.\n", - "- `word` in `search` consist of `'.'` or lowercase English letters.\n", - "- There will be at most `2` dots in `word` for `search` queries.\n", - "- At most $10^4$ calls will be made to `addWord` and `search`." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is to design a data structure called `WordDictionary` that allows you to add words and search for words efficiently. The key feature of this data structure is that it should support wildcard search, where a dot ('.') can match any letter.\n", - "\n", - "Here are the specific requirements and explanations for the problem:\n", - "\n", - "1. Initialize the `WordDictionary` object using the constructor `WordDictionary()`.\n", - "\n", - "2. The `addWord(word)` method allows you to add a word to the data structure. Once added, you should be able to search for this word later. The words consist of lowercase English letters, and each word has a length between 1 and 25 characters.\n", - "\n", - "3. The `search(word)` method allows you to search for a word in the data structure. This method returns `True` if there is any string in the data structure that matches the given word or `False` otherwise. The word you are searching for may contain dots ('.'), where each dot can match any letter.\n", - "\n", - "4. The wildcard character ('.') in the `search` method allows for partial or fuzzy searching. For example, if the word dictionary contains the words \"bad,\" \"dad,\" and \"mad,\" then:\n", - " - Searching for \"pad\" should return `False` because there is no exact match.\n", - " - Searching for \"bad\" should return `True` because \"bad\" is in the dictionary.\n", - " - Searching for \".ad\" should return `True` because it can match \"bad,\" \"dad,\" or \"mad.\"\n", - " - Searching for \"b..\" should return `True` because it can match \"bad,\" \"bed,\" \"bet,\" etc.\n", - "\n", - "5. The problem specifies that there will be at most two dots ('.') in search queries, and there will be at most 10^4 calls to both `addWord` and `search`.\n", - "\n", - "In summary, you need to implement the `WordDictionary` class that efficiently supports adding words and searching for words, where the search can include wildcard characters ('.') that match any letter.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "class TrieNode:\n", - " def __init__(self):\n", - " # Initialize a TrieNode with children and a flag to indicate the end of a word.\n", - " self.children = {}\n", - " self.is_end_of_word = False\n", - "\n", - "class WordDictionary:\n", - "\n", - " def __init__(self):\n", - " # Initialize the WordDictionary with a root node.\n", - " self.root = TrieNode()\n", - "\n", - " def addWord(self, word: str) -> None:\n", - " node = self.root\n", - " # Iterate through the characters in the word.\n", - " for char in word:\n", - " if char not in node.children:\n", - " # Create a new node for the character if it doesn't exist.\n", - " node.children[char] = TrieNode()\n", - " # Move to the next node.\n", - " node = node.children[char]\n", - " # Mark the end of the word by setting the flag to True.\n", - " node.is_end_of_word = True\n", - "\n", - " def search_helper(self, node: TrieNode, word: str) -> bool:\n", - " if not word:\n", - " # If there are no characters left in the word, check if we reached the end of a word in the trie.\n", - " return node.is_end_of_word\n", - " \n", - " char = word[0]\n", - " if char == '.':\n", - " # If the character is a dot, explore all possible child nodes.\n", - " for child in node.children.values():\n", - " if self.search_helper(child, word[1:]):\n", - " return True\n", - " elif char in node.children:\n", - " # If the character is in the children of the current node, move to the next node.\n", - " return self.search_helper(node.children[char], word[1:])\n", - " \n", - " # If the character is not found and is not a dot, the word is not in the trie.\n", - " return False\n", - "\n", - " def search(self, word: str) -> bool:\n", - " # Start the search from the root of the trie.\n", - " return self.search_helper(self.root, word)" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "This code defines a `WordDictionary` class that uses a Trie data structure to efficiently store and search for words. Here's a step-by-step explanation:\n", - "\n", - "1. `TrieNode` class: This class represents nodes in the Trie data structure. Each node has two attributes: `children` (a dictionary to store child nodes) and `is_end_of_word` (a flag to indicate whether the node marks the end of a word).\n", - "\n", - "2. `WordDictionary` class: This class initializes with an empty Trie by creating a root node.\n", - "\n", - "3. `addWord` method: This method adds a word to the Trie. It iterates through each character in the word and creates Trie nodes as necessary. It sets the `is_end_of_word` flag to `True` for the final character of the word to mark the end of the word.\n", - "\n", - "4. `search_helper` method: This is a recursive helper function for searching words in the Trie. It takes a Trie node (`node`) and a word to search (`word`) as input. If there are no characters left in the word (`not word`), it checks if the current node marks the end of a word. If it does, it returns `True`.\n", - "\n", - "5. If the first character of the word is a dot ('.'), the function explores all possible child nodes by iterating through `node.children.values()` and recursively calls `search_helper` for each child with the remaining part of the word (`word[1:]`).\n", - "\n", - "6. If the first character of the word is not a dot and is found in the children of the current node, the function recursively moves to the next node by calling `search_helper` on the child node and the remaining part of the word.\n", - "\n", - "7. If the character is not found in the children and is not a dot, the word is not in the Trie, so the function returns `False`.\n", - "\n", - "8. `search` method: This is the public method for searching words. It initiates the search process by calling `search_helper` starting from the root node of the Trie.\n", - "\n", - "Overall, this code efficiently implements a Trie-based data structure that allows adding and searching for words, including support for wildcard characters represented by dots ('.')." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n", - "True\n", - "True\n", - "True\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "\n", - "wordDictionary = WordDictionary()\n", - "wordDictionary.addWord(\"bad\")\n", - "wordDictionary.addWord(\"dad\")\n", - "wordDictionary.addWord(\"mad\")\n", - "print(wordDictionary.search(\"pad\")) # Output: False\n", - "print(wordDictionary.search(\"bad\")) # Output: True\n", - "print(wordDictionary.search(\".ad\")) # Output: True\n", - "print(wordDictionary.search(\"b..\")) # Output: True" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `WordDictionary` class methods:\n", - "\n", - "1. `addWord` Method:\n", - "\n", - " - Time Complexity: O(L)\n", - " - L is the length of the word being added.\n", - " - In the worst case, we need to iterate through each character in the word and create nodes in the Trie. This takes O(L) time.\n", - "\n", - " - Space Complexity: O(L)\n", - " - The space complexity for storing the word in the Trie is also O(L) because we create nodes for each character in the word.\n", - "\n", - "2. `search_helper` Method (called by `search`):\n", - "\n", - " - Time Complexity: O(2^M * L)\n", - " - M is the maximum number of dots ('.') in the search word.\n", - " - In the worst case, when there are M dots in the search word, we may explore all possible child nodes at each dot. This results in a branching factor of 26 (for lowercase letters) at each dot.\n", - " - So, the time complexity is exponential in the number of dots and linear in the length of the word being searched (L).\n", - "\n", - " - Space Complexity: O(L)\n", - " - The space complexity for the recursive call stack is O(L) in the worst case because we may have to recurse to a depth equal to the length of the search word.\n", - "\n", - "3. `search` Method:\n", - "\n", - " - Time Complexity: O(2^M * L)\n", - " - The `search` method calls the `search_helper` method, which has the same time complexity explained above.\n", - "\n", - " - Space Complexity: O(L)\n", - " - The space complexity for the recursive call stack is O(L) in the worst case, as explained earlier.\n", - "\n", - "Overall, the time complexity of the `search` method is mainly affected by the number of dots ('.') in the search word. In the worst case, when there are multiple dots and many possibilities to explore at each dot, the time complexity can be exponential. However, for most practical cases, it performs reasonably well.\n", - "\n", - "The space complexity primarily depends on the space required to store the words in the Trie. It is proportional to the total number of characters in all added words and is linear with respect to the length of the words added.\n", - "\n", - "In summary:\n", - "\n", - "- Time Complexity for `addWord`: O(L)\n", - "- Time Complexity for `search`: O(2^M * L)\n", - "- Space Complexity: O(L) for storing words in the Trie, O(L) for the recursive call stack during search.\n", - "\n", - "Note: The space complexity analysis assumes that the dictionary contains a reasonable number of words and does not account for the overhead of Python objects or system-level memory allocation." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Dictionary Auto-Completion**: Extend the `WordDictionary` class to provide auto-completion suggestions based on the prefix of a word. Implement a method that returns a list of words that match the given prefix.\n", - "\n", - "2. **Support Word Deletion**: Extend the `WordDictionary` class to support word deletion. Add a method `deleteWord(word)` that removes a word from the data structure. Ensure that the search operation still works correctly after deletion." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/08. Tries/212. Word Search II.ipynb b/_build/jupyter_execute/08. Tries/212. Word Search II.ipynb deleted file mode 100644 index e582b9d..0000000 --- a/_build/jupyter_execute/08. Tries/212. Word Search II.ipynb +++ /dev/null @@ -1,310 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 212. Word Search II\n", - "\n", - "**Difficulty:** Hard\n", - "\n", - "**Link to Problem:** [To see the Word Search II problem on LeetCode, click here!](https://leetcode.com/problems/word-search-ii/)\n", - "\n", - "---\n", - "Given an `m x n` `board` of characters and a list of strings `words`, the task is to return *all words on the board*.\n", - "\n", - "Each word must be constructed from letters of sequentially **adjacent cells**, where adjacent cells are horizontally or vertically neighboring. The same letter cell may not be used more than once in a word.\n", - "\n", - "\n", - "**Constraints:**\n", - "- `m == board.length`\n", - "- `n == board[i].length`\n", - "- `1 <= m, n <= 12`\n", - "- `board[i][j]` is a lowercase English letter.\n", - "- 1 <= `words.length` <= $3 * 10^4$\n", - "- `1 <= words[i].length <= 10`\n", - "- `words[i]` consists of lowercase English letters.\n", - "- All the strings of `words` are unique." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "To solve the \"Word Search II\" problem, you can use a Trie data structure and perform a depth-first search (DFS) on the board. Here's a step-by-step approach to solve the problem:\n", - "\n", - "1. Build a Trie from the given list of words:\n", - " - Create a Trie data structure to store all the words from the input list.\n", - " - For each word in the input list, insert it into the Trie, character by character. Make sure to mark the end of each word in the Trie.\n", - "\n", - "2. Perform DFS on the board:\n", - " - Iterate through each cell (i, j) on the board.\n", - " - For each cell, start a DFS traversal from that cell to search for words.\n", - " - During the DFS traversal, maintain a current path string.\n", - " - At each cell, check if the current path string, concatenated with the character in the cell, matches any word prefix in the Trie. If it does, continue the DFS.\n", - " - If the current path string matches a word in the Trie, add it to the result.\n", - "\n", - "3. Implement DFS with backtracking:\n", - " - During the DFS traversal, you will explore neighboring cells (horizontally and vertically) if they are within bounds and haven't been visited before.\n", - " - To prevent revisiting the same cell within the same word, mark the cell as visited (e.g., change its character to a special character like '#') before exploring it and restore its original character after the DFS traversal.\n", - "\n", - "4. Return the result:\n", - " - After completing the DFS traversal for all cells on the board, you will have collected all the valid words in the result set.\n", - " - Convert the result set to a list and return it as the final output.\n", - "\n", - "This approach efficiently finds all words on the board by utilizing the Trie data structure to prune unnecessary DFS paths and avoiding duplicate visits to the same cell within the same word. It ensures that each word is constructed from letters of sequentially adjacent cells without using the same letter cell more than once in a word.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "# Define a TrieNode class to represent nodes in the Trie.\n", - "class TrieNode:\n", - " def __init__(self):\n", - " self.children = {} # Dictionary to store child nodes.\n", - " self.is_end_of_word = False # Flag to mark the end of a word.\n", - "\n", - "# Main function to find words on the board.\n", - "def findWords(board, words):\n", - " # DFS function to search for words starting from a given cell.\n", - " def dfs(node, i, j, path):\n", - " char = board[i][j] # Get the character at the current cell.\n", - " curr_node = node.children.get(char) # Find the corresponding Trie node.\n", - "\n", - " if not curr_node:\n", - " return # If no matching Trie node, stop the search.\n", - "\n", - " path += char # Add the character to the current path.\n", - "\n", - " if curr_node.is_end_of_word:\n", - " result.add(path) # If the path matches a word, add it to the result.\n", - "\n", - " temp, board[i][j] = board[i][j], \"#\" # Mark the cell as visited.\n", - "\n", - " # Explore neighboring cells (up, down, left, right).\n", - " if i > 0:\n", - " dfs(curr_node, i - 1, j, path)\n", - " if i < m - 1:\n", - " dfs(curr_node, i + 1, j, path)\n", - " if j > 0:\n", - " dfs(curr_node, i, j - 1, path)\n", - " if j < n - 1:\n", - " dfs(curr_node, i, j + 1, path)\n", - "\n", - " board[i][j] = temp # Restore the cell's original character.\n", - "\n", - " # Function to build a Trie from the list of words.\n", - " def buildTrie():\n", - " root = TrieNode() # Create a root node.\n", - " for word in words:\n", - " node = root\n", - " for char in word:\n", - " if char not in node.children:\n", - " node.children[char] = TrieNode() # Create a new node if needed.\n", - " node = node.children[char]\n", - " node.is_end_of_word = True # Mark the end of the word.\n", - " return root\n", - "\n", - " m, n = len(board), len(board[0]) # Get the dimensions of the board.\n", - " root = buildTrie() # Build the Trie from the list of words.\n", - " result = set() # Use a set to store unique words found on the board.\n", - "\n", - " # Iterate through each cell on the board and start DFS from there.\n", - " for i in range(m):\n", - " for j in range(n):\n", - " dfs(root, i, j, \"\") # Start DFS from each cell on the board.\n", - "\n", - " return list(result) # Convert the set to a list and return the result." - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The code solves the \"Word Search II\" problem, where you have a grid of characters and a list of words. The goal is to find all words from the list that can be constructed by traversing adjacent cells (horizontally or vertically) in the grid, without using the same cell more than once for a single word.\n", - "\n", - "The code does the following:\n", - "\n", - "1. Defines a `TrieNode` class to represent nodes in a Trie data structure. Each node has children (other characters in the word) and a flag to mark the end of a word.\n", - "\n", - "2. Defines the `findWords` function, which takes the grid (`board`) and a list of words (`words`) as input.\n", - "\n", - "3. Inside the `findWords` function, there is a `dfs` (depth-first search) function. This function is used to explore the grid starting from a specific cell. It checks if the current path matches any word in the Trie and adds it to the result if found.\n", - "\n", - "4. The code also includes a `buildTrie` function that constructs a Trie data structure from the list of words. It iterates through each word, creating nodes for each character in the Trie and marking the end of words.\n", - "\n", - "5. The dimensions of the grid are obtained (m x n).\n", - "\n", - "6. A Trie is built using the `buildTrie` function.\n", - "\n", - "7. A set called `result` is used to store unique words found in the grid.\n", - "\n", - "8. The code iterates through each cell on the grid (using nested loops) and starts a DFS search from each cell.\n", - "\n", - "9. During the DFS, it explores neighboring cells (up, down, left, right) if they haven't been visited before and if the current path matches a prefix in the Trie.\n", - "\n", - "10. When a word is found during the DFS traversal, it is added to the `result` set.\n", - "\n", - "11. The grid cell is marked as visited during the DFS by changing its character to \"#\", and it is restored to its original character after the DFS traversal.\n", - "\n", - "12. Finally, the set of unique words found is converted to a list and returned as the output.\n", - "\n", - "The code effectively uses a Trie data structure to optimize the search and ensures that each word is constructed from adjacent cells without reusing the same cell for the same word." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['eat', 'oath']\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "board1 = [[\"o\",\"a\",\"a\",\"n\"],[\"e\",\"t\",\"a\",\"e\"],[\"i\",\"h\",\"k\",\"r\"],[\"i\",\"f\",\"l\",\"v\"]]\n", - "words1 = [\"oath\",\"pea\",\"eat\",\"rain\"]\n", - "print(findWords(board1, words1)) # Output: [\"eat\", \"oath\"]" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "c748b879-a2d8-4298-a42c-c7f61f9c7fc6", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[]\n" - ] - } - ], - "source": [ - "# Example 2\n", - "\n", - "board2 = [[\"a\",\"b\"],[\"c\",\"d\"]]\n", - "words2 = [\"abcb\"]\n", - "print(findWords(board2, words2)) # Output: []" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. **Building the Trie (`buildTrie` function):** \n", - " - Suppose there are `N` words in the input list, and the average length of a word is `L`.\n", - " - Building the Trie takes O(N * L) time, as we iterate through each word and insert each character into the Trie.\n", - "\n", - "2. **DFS Traversal (`dfs` function):** \n", - " - In the worst case, the DFS function explores all possible paths in the grid.\n", - " - The maximum number of recursive calls for each cell is 4 (up, down, left, right).\n", - " - The maximum depth of the DFS is limited by the length of the longest word in the Trie, which is at most `L`.\n", - " - Therefore, the DFS traversal for each cell takes $O(4^L)$ time.\n", - "\n", - "3. **Iterating Through the Grid (`findWords` function):**\n", - " - In the worst case, we iterate through all `m` rows and `n` columns in the grid.\n", - " - For each cell, we start a DFS traversal.\n", - " - Therefore, iterating through the entire grid takes $O(m * n * 4^L)$ time.\n", - "\n", - "Overall, the time complexity of the code is $O(N * L + m * n * 4^L)$.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. **Trie Data Structure:**\n", - " - The space required to store the Trie depends on the number of unique characters in all the words.\n", - " - In the worst case, where all words are unique and have no common prefixes, the space complexity of the Trie is O(N * L).\n", - " - In practice, it may be less if there are common prefixes among words.\n", - "\n", - "2. **DFS Stack (Recursive Calls):**\n", - " - The depth of the recursive call stack during DFS is at most `L`, where `L` is the length of the longest word in the Trie.\n", - " - Therefore, the space complexity for the recursive call stack is O(L).\n", - "\n", - "3. **Result Set (`result` set):**\n", - " - The space used to store the result set depends on the number of valid words found in the grid.\n", - " - In the worst case, when all words are found, the space complexity of the result set is O(N * L).\n", - "\n", - "Overall, the space complexity of the code is O(N * L) for the Trie and O(L) for the recursive call stack.\n", - "\n", - "In summary, the time complexity is dominated by the DFS traversal and is influenced by the number of words, their lengths, and the size of the grid. The space complexity is mainly determined by the Trie structure and the recursive call stack depth during DFS." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Word Search Paths:**\n", - " Extend the basic word search exercise to find all possible paths (sequences of cells) that spell out a given word on the board. Return a list of paths if the word can be formed, otherwise an empty list.\n", - "\n", - "\n", - "2. **Reverse Word Search:**\n", - " Modify the code to search for words in reverse order on the board. Given a 2D grid of characters and a list of words, find all words from the list that can be formed by traversing the board in reverse (right to left, bottom to top, etc.)." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/09. Heap - Priority Queue/1046. Last Stone Weight.ipynb b/_build/jupyter_execute/09. Heap - Priority Queue/1046. Last Stone Weight.ipynb deleted file mode 100644 index f82ad98..0000000 --- a/_build/jupyter_execute/09. Heap - Priority Queue/1046. Last Stone Weight.ipynb +++ /dev/null @@ -1,248 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 1046. Last Stone Weight\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Last Stone Weight problem on LeetCode, click here!](https://leetcode.com/problems/last-stone-weight/)\n", - "\n", - "---\n", - "You are given an array of integers `stones` where `stones[i]` is the weight of the `i`th stone.\n", - "\n", - "We are playing a game with the stones. On each turn, you choose the **heaviest two stones** and smash them together. Suppose the heaviest two stones have weights `x` and `y` with `x <= y`. The result of this smash is:\n", - "\n", - "1. If `x == y`, both stones are destroyed.\n", - "2. If `x != y`, the stone of weight `x` is destroyed, and the stone of weight `y` has new weight `y - x`.\n", - "\n", - "At the end of the game, there is **at most one** stone left.\n", - "\n", - "Return *the weight of the last remaining stone*. If there are no stones left, return `0`.\n", - "\n", - "**Constraints:**\n", - "- `1 <= stones.length <= 30`\n", - "- `1 <= stones[i] <= 1000`" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The \"Last Stone Weight\" problem involves a game played with a collection of stones, each stone having a certain weight. The goal is to find the weight of the last remaining stone after applying a specific set of rules.\n", - "\n", - "Here's how the game works:\n", - "\n", - "1. You start with an array of stones, where each stone is represented by its weight. The weights of the stones are given in the input as an array.\n", - "\n", - "2. In each turn of the game, you select the two heaviest stones from the remaining stones. If there is only one stone left, you've found the answer.\n", - "\n", - "3. If there are two stones with weights `x` and `y`, where `x` is less than or equal to `y`, the following happens:\n", - " - If `x` is equal to `y`, both stones are completely destroyed, and they are removed from the array of stones.\n", - " - If `x` is not equal to `y`, the stone with weight `x` is destroyed, and the stone with weight `y` now has a new weight of `y - x`. The stone with weight `x` is removed from the array, and the modified stone with weight `y - x` remains in the array.\n", - "\n", - "4. The game continues with the modified array of stones until there is at most one stone left.\n", - "\n", - "5. The goal is to find the weight of the last remaining stone, or if there are no stones left, return `0`.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "import heapq\n", - "\n", - "def lastStoneWeight(stones):\n", - " # Convert the input list to a max heap (negate the values to simulate a max heap)\n", - " max_heap = [-stone for stone in stones]\n", - " heapq.heapify(max_heap)\n", - "\n", - " # Continue as long as there are more than 1 stone in the heap\n", - " while len(max_heap) > 1:\n", - " # Get the two heaviest stones\n", - " y = -heapq.heappop(max_heap) # Get the heaviest stone and negate it back to positive\n", - " x = -heapq.heappop(max_heap) # Get the second heaviest stone and negate it back to positive\n", - "\n", - " # Calculate the new stone's weight after smashing\n", - " if x != y:\n", - " new_stone = y - x\n", - " heapq.heappush(max_heap, -new_stone) # Negate the value and push it back to the heap\n", - "\n", - " # If there is one stone left, return its weight (negate it back to positive)\n", - " if max_heap:\n", - " return -max_heap[0]\n", - " else:\n", - " return 0" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The code defines a Python function called `lastStoneWeight` that takes a list of stone weights as input. It aims to find the weight of the last remaining stone after playing the stone smashing game described in the problem statement.\n", - "\n", - "Here's a step-by-step explanation of the code:\n", - "\n", - "1. We import the `heapq` library, which allows us to create and manipulate a heap (priority queue).\n", - "\n", - "2. Inside the `lastStoneWeight` function:\n", - " - We create a max heap (negating stone weights to simulate a max heap) using the `heapq.heapify` function. This heap will keep track of the heaviest stones.\n", - " \n", - " - We enter a loop that continues as long as there are more than 1 stone in the heap.\n", - " \n", - " - Inside the loop, we:\n", - " - Retrieve and negate the heaviest stone (`y`) from the heap.\n", - " - Retrieve and negate the second heaviest stone (`x`) from the heap.\n", - " \n", - " - Calculate the new stone's weight after smashing (`y - x`), and negate it back to simulate a max heap.\n", - " - Add the new stone back to the heap using `heapq.heappush`.\n", - " \n", - "3. After the loop, if there is one stone left in the heap, we retrieve and negate it to get its actual weight, and return it as the result.\n", - " \n", - "4. If there are no stones left (the heap is empty), we return `0`, indicating that no stones remain.\n", - "\n", - "5. Finally, we provide two test cases to demonstrate the function's usage and correctness.\n", - "\n", - "In summary, the code efficiently implements the stone smashing game by maintaining a max heap, selecting the heaviest stones in each turn, smashing them, and updating the heap until there is at most one stone left. It then returns the weight of the last remaining stone or 0 if there are no stones left." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "stones1 = [2, 7, 4, 1, 8, 1]\n", - "print(lastStoneWeight(stones1)) # Output: 1" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "b7e79514-4821-48d0-bb9d-0f2de8150945", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n" - ] - } - ], - "source": [ - "# Example 2: \n", - "\n", - "stones2 = [1]\n", - "print(lastStoneWeight(stones2)) # Output: 1" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided Python code for the \"Last Stone Weight\" problem:\n", - "\n", - "**Time Complexity:**\n", - "1. The `heapq.heapify` operation to create the max heap from the input stone weights has a time complexity of O(n), where n is the number of stones.\n", - "\n", - "2. The loop that continues until there are more than 1 stone in the heap performs the following operations in each iteration:\n", - " - Retrieving and negating the heaviest stone (`y`) from the heap, which takes O(log n) time.\n", - " - Retrieving and negating the second heaviest stone (`x`) from the heap, also taking O(log n) time.\n", - " - Calculating the new stone's weight and pushing it back into the heap using `heapq.heappush`, which takes O(log n) time.\n", - "\n", - "3. In the worst case, the loop runs until there is only one stone left, which requires approximately (n-1) iterations.\n", - "\n", - "Overall, the dominant time complexity is O(n) for the initial heap creation, and within the loop, each iteration takes O(log n) time. Therefore, the overall time complexity of the algorithm is O(n log n).\n", - "\n", - "**Space Complexity:**\n", - "1. The space complexity is primarily determined by the space required for the max heap. In the worst case, this heap can contain all the stones, so the space complexity for the heap is O(n).\n", - "\n", - "2. The rest of the variables used in the function (e.g., `x`, `y`, `new_stone`) require only constant space, so they do not significantly contribute to the space complexity.\n", - "\n", - "Therefore, the overall space complexity of the algorithm is O(n) due to the space used for the max heap.\n", - "\n", - "In summary:\n", - "- Time Complexity: $O(n\\ log\\ n)$\n", - "- Space Complexity: $O(n)$\n", - "\n", - "The algorithm is efficient enough to handle the problem's constraints, as the worst-case time and space complexities are both linearithmic in terms of the number of stones." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Kth Last Stone Weight**: Modify the problem to find the weight of the Kth last remaining stone, where K is an integer input. Your function should work efficiently for large values of K.\n", - "\n", - "\n", - "2. **Multiple Stones Smash**: Modify the problem so that instead of smashing two stones at a time, you can smash up to K stones at each turn, where K is an integer input. Determine the weight of the last remaining stone in this variation." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/09. Heap - Priority Queue/295. Find Median from Data Stream.ipynb b/_build/jupyter_execute/09. Heap - Priority Queue/295. Find Median from Data Stream.ipynb deleted file mode 100644 index 6c43a8d..0000000 --- a/_build/jupyter_execute/09. Heap - Priority Queue/295. Find Median from Data Stream.ipynb +++ /dev/null @@ -1,238 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 295. Find Median from Data Stream\n", - "\n", - "**Difficulty:** Hard\n", - "\n", - "**Link to Problem:** [To see the Find Median from Data Stream problem on LeetCode, click here!](https://leetcode.com/problems/find-median-from-data-stream/)\n", - "\n", - "---\n", - "\n", - "The **median** is the middle value in an ordered integer list. If the size of the list is even, there is no middle value, and the median is the mean of the two middle values.\n", - "\n", - "Implement the MedianFinder class:\n", - "\n", - "- `MedianFinder()` initializes the `MedianFinder` object.\n", - "- `void addNum(int num)` adds the integer `num` from the data stream to the data structure.\n", - "- `double findMedian()` returns the median of all elements so far. Answers within $10^{-5}$ of the actual answer will be accepted.\n", - "\n", - "**Constraints:**\n", - "\n", - "- $-10^{5}$ <= `num` <= $10^{5}$\n", - "- There will be at least one element in the data structure before calling `findMedian`.\n", - "- At most $5 * 10^4$ calls will be made to `addNum` and `findMedian`.\n", - "\n", - "**Follow-up:**\n", - "\n", - "1. If all integer numbers from the stream are in the range `[0, 100]`, how would you optimize your solution?\n", - "2. If `99%` of all integer numbers from the stream are in the range `[0, 100]`, how would you optimize your solution?" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem, \"Find Median from Data Stream,\" deals with efficiently computing the median of a sequence of numbers as they are incrementally provided. The median is the middle value in an ordered list of numbers. When the list has an even number of elements, the median is the average of the two middle values.\n", - "\n", - "Here's a breakdown of the problem:\n", - "\n", - "1. **Initialization**: You are asked to implement a `MedianFinder` class that supports the following operations:\n", - "\n", - " - `MedianFinder()`: Initializes the MedianFinder object.\n", - " - `addNum(int num)`: Adds an integer `num` from the data stream to the data structure.\n", - " - `findMedian()`: Returns the median of all elements added to the data structure.\n", - "\n", - "2. **Median Calculation**: The `findMedian` operation should efficiently compute the median, and the result should have a precision of at least $10^{-5}$ (i.e., answers within this range will be considered correct).\n", - "\n", - "3. **Examples**:\n", - " \n", - " - If you add numbers [1, 2], the median should be 1.5 because (1 + 2) / 2 = 1.5.\n", - " - If you add numbers [1, 2, 3], the median should be 2 because it's the middle value.\n", - " \n", - "4. **Constraints**:\n", - "\n", - " - The integers provided in the data stream are in the range from $-10^5$ to $10^5$.\n", - " - There will be at least one element in the data structure before calling `findMedian`.\n", - " - At most, $5 * 10^4$ calls will be made to `addNum` and `findMedian`.\n", - "\n", - "The problem can be solved by using two priority queues (heaps): one max-heap to store the smaller half of the numbers and one min-heap to store the larger half of the numbers. The max-heap ensures that the largest number in the smaller half is at the top, and the min-heap ensures that the smallest number in the larger half is at the top. These heaps are balanced to efficiently find the median when requested.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "import heapq\n", - "\n", - "class MedianFinder:\n", - "\n", - " def __init__(self):\n", - " # Initialize two heaps: a max-heap (small_half) for the smaller half of numbers,\n", - " # and a min-heap (large_half) for the larger half of numbers.\n", - " self.small_half = [] # Max-heap for the smaller half of the numbers\n", - " self.large_half = [] # Min-heap for the larger half of the numbers\n", - "\n", - " def addNum(self, num: int) -> None:\n", - " # Add the number to the appropriate heap based on its value\n", - " if not self.small_half or num <= -self.small_half[0]:\n", - " # If the number is less than or equal to the current maximum in the smaller half,\n", - " # add it to the smaller half (max-heap)\n", - " heapq.heappush(self.small_half, -num)\n", - " else:\n", - " # Otherwise, add it to the larger half (min-heap)\n", - " heapq.heappush(self.large_half, num)\n", - "\n", - " # Balance the heaps if necessary to ensure the size difference is at most 1\n", - " if len(self.small_half) > len(self.large_half) + 1:\n", - " # If the size of the smaller half is more than one greater than the size of the larger half,\n", - " # move the maximum from the smaller half to the larger half to balance them.\n", - " heapq.heappush(self.large_half, -heapq.heappop(self.small_half))\n", - " elif len(self.large_half) > len(self.small_half):\n", - " # If the size of the larger half is greater than the size of the smaller half,\n", - " # move the minimum from the larger half to the smaller half to balance them.\n", - " heapq.heappush(self.small_half, -heapq.heappop(self.large_half))\n", - "\n", - " def findMedian(self) -> float:\n", - " if len(self.small_half) == len(self.large_half):\n", - " # If both halves have the same size, there's an even number of elements,\n", - " # so the median is the average of the top elements in both heaps.\n", - " return (-self.small_half[0] + self.large_half[0]) / 2.0\n", - " else:\n", - " # If the smaller half has more elements, it contains the median (odd number of elements).\n", - " return -self.small_half[0]" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The code defines a `MedianFinder` class for efficiently finding the median of a stream of numbers. It uses two heaps: a max-heap (`small_half`) to store the smaller half of the numbers and a min-heap (`large_half`) to store the larger half. Here's how the code works:\n", - "\n", - "1. The `__init__` method initializes the two heaps.\n", - "\n", - "2. The `addNum` method adds a number to the appropriate heap, ensuring that the heaps remain balanced. It does this by comparing the number to the current maximum in the smaller half and adding it to the appropriate heap. Then, it checks the sizes of the two heaps and rebalances them if necessary.\n", - "\n", - "3. The `findMedian` method calculates and returns the median. If both halves have the same size (even number of elements), it computes the average of the tops of both heaps. If the smaller half has more elements (odd number of elements), it returns the top of the max-heap, which is the median.\n", - "\n", - "In summary, this code efficiently maintains two heaps to divide the elements into smaller and larger halves, allowing for quick median retrieval. It offers a time complexity of O(log N) for adding elements and O(1) for finding the median, where N is the total number of elements processed. The space complexity is O(1) as the space used by the two heaps is independent of the input size." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1.5\n", - "2\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "medianFinder = MedianFinder()\n", - "medianFinder.addNum(1)\n", - "medianFinder.addNum(2)\n", - "print(medianFinder.findMedian()) # Output: 1.5\n", - "medianFinder.addNum(3)\n", - "print(medianFinder.findMedian()) # Output: 2.0\n" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `MedianFinder` class:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. `MedianFinder()` Initialization: This operation has a time complexity of O(1). It simply initializes the two heaps.\n", - "\n", - "2. `addNum(int num)`: The time complexity for adding a number is O(log N), where N is the total number of elements processed so far. This is because, in the worst case, you might need to perform logarithmic operations on the heaps to maintain their balance.\n", - "\n", - "3. `findMedian()`: Finding the median has a time complexity of O(1). It simply involves accessing the tops of the two heaps, which takes constant time.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. `MedianFinder()` Initialization: The space complexity for initialization is O(1). It involves creating two empty heaps, which do not depend on the size of the data stream.\n", - "\n", - "2. `addNum(int num)`: The space complexity for adding a number is also O(1). It involves adding the number to one of the two heaps, which do not significantly affect the overall space complexity.\n", - "\n", - "3. `findMedian()`: The space complexity for finding the median is O(1). It doesn't require any additional data structures that grow with the input size.\n", - "\n", - "In summary, the time complexity of the `addNum` operation is O(log N), and the time complexity of the `findMedian` operation is O(1). The space complexity is O(1) as well, as the space used by the two heaps is independent of the size of the data stream. This solution efficiently maintains and retrieves the median, making it suitable for the given problem constraints." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Generalized kth Element**: Extend the `MedianFinder` class to support finding the kth element in the data stream efficiently. This means finding the kth smallest or kth largest element in the stream.\n", - "\n", - "2. **Sliding Window Median**: Given an array and a sliding window size, find the median within the window as it slides over the array. This is an extension of the problem to a moving window scenario." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.ipynb b/_build/jupyter_execute/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.ipynb deleted file mode 100644 index e6ab9e3..0000000 --- a/_build/jupyter_execute/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.ipynb +++ /dev/null @@ -1,235 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 703. Kth Largest Element in a Stream\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Kth Largest Element in a Stream problem on LeetCode, click here!](https://leetcode.com/problems/kth-largest-element-in-a-stream/)\n", - "\n", - "---\n", - "Design a class to find the `kth` largest element in a stream. Note that it is the `kth` largest element in the sorted order, not the `kth` distinct element.\n", - "\n", - "Implement the `KthLargest` class with the following methods:\n", - "\n", - "- `KthLargest(int k, int[] nums)`: Initializes the object with the integer `k` and the stream of integers `nums`.\n", - "- `int add(int val)`: Appends the integer `val` to the stream and returns the element representing the `kth` largest element in the stream.\n", - "\n", - "\n", - "**Constraints:**\n", - "\n", - "- 1 <= `k` <= $10^4$\n", - "- 0 <= `nums.length` <= $10^4$\n", - "- $-10^4$ <= `nums[i]` <= $10^4$\n", - "- $-10^4$ <= `val` <= $10^4$\n", - "- At most $10^4$ calls will be made to `add`.\n", - "- It is guaranteed that there will be at least `k` elements in the array when you search for the `kth` element." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem you're trying to solve is to design a class called `KthLargest` that can efficiently find the kth largest element in a stream of integers. You need to support two main operations:\n", - "\n", - "To solve this problem efficiently, you can use a min-heap data structure. Here's how the approach works:\n", - "\n", - "1. Initialize a min-heap to store the k largest elements. Initially, it's empty.\n", - "\n", - "2. In the `__init__` method, populate the min-heap with the first `k` elements from `nums`. This ensures that you have the k largest elements seen so far.\n", - "\n", - "3. Whenever you add a new element to the stream using the `add` method, follow these steps:\n", - " - Add the new element to the min-heap.\n", - " - If the size of the min-heap exceeds `k`, remove the smallest element from the min-heap. This ensures that you always have the k largest elements in the min-heap.\n", - " - The smallest element in the min-heap (the root) will always represent the kth largest element in the stream.\n", - "\n", - "Here's why this approach works efficiently:\n", - "\n", - "- By using a min-heap, you can quickly maintain the k largest elements, and finding the smallest element in the heap (the root) takes constant time.\n", - "\n", - "- When you add a new element, the min-heap's size is kept at most `k`, which ensures that you only track the k largest elements and discard the smaller ones.\n", - "\n", - "- The time complexity for adding an element is O(log k), which is very efficient compared to sorting the entire stream, which would be O(n log n).\n", - "\n", - "- This approach meets the constraints of the problem, including handling large streams and having a low time complexity for both initialization and adding elements.\n", - "\n", - "In summary, the min-heap approach efficiently tracks the kth largest element in the stream by maintaining a heap of the k largest elements seen so far, updating it as new elements are added. This approach provides a fast and scalable solution to the problem.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "import heapq\n", - "from typing import List # Import the List type from the typing module\n", - "\n", - "class KthLargest:\n", - "\n", - " def __init__(self, k: int, nums: List[int]):\n", - " # Initialize the KthLargest object with k and nums.\n", - " self.k = k\n", - " # Create a min-heap to store the k largest elements.\n", - " self.min_heap = []\n", - " # Populate the min-heap with the first k elements from nums.\n", - " for num in nums:\n", - " self.add(num)\n", - "\n", - " def add(self, val: int) -> int:\n", - " # Add val to the min-heap.\n", - " heapq.heappush(self.min_heap, val)\n", - " # If the size of the min-heap exceeds k, remove the smallest element.\n", - " if len(self.min_heap) > self.k:\n", - " heapq.heappop(self.min_heap)\n", - " # The root of the min-heap is the kth largest element.\n", - " return self.min_heap[0]" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "- We start by importing the necessary modules:\n", - " - `heapq`: This module provides functions to create and manipulate heaps.\n", - " - `List` from the `typing` module: This is used to specify the type of the `nums` parameter.\n", - "\n", - "- We define the `KthLargest` class:\n", - " - The `__init__` method initializes the object with the integer `k` and the list of integers `nums`.\n", - " - It also creates an empty min-heap called `self.min_heap` to store the k largest elements.\n", - " - It populates the min-heap with the first `k` elements from `nums` by calling the `add` method.\n", - "\n", - "- The `add` method:\n", - " - Adds the new integer `val` to the min-heap using `heapq.heappush`. This maintains the min-heap property.\n", - " - Checks if the size of the min-heap exceeds `k`. If it does, it removes the smallest element (the k+1th largest) using `heapq.heappop`.\n", - " - Finally, it returns the smallest element in the min-heap, which is always the kth largest element.\n", - "\n", - "Overall, this code implements a class that efficiently finds the kth largest element in a stream of integers by maintaining a min-heap of the k largest elements seen so far.\n" - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n", - "5\n", - "5\n", - "8\n", - "8\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "kthLargest = KthLargest(3, [4, 5, 8, 2])\n", - "print(kthLargest.add(3)) # Output: 4\n", - "print(kthLargest.add(5)) # Output: 5\n", - "print(kthLargest.add(10)) # Output: 5\n", - "print(kthLargest.add(9)) # Output: 8\n", - "print(kthLargest.add(4)) # Output: 8" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `KthLargest` class using the min-heap approach:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. `__init__` method:\n", - " - In the `__init__` method, you iterate over the first `k` elements in `nums` and add them to the min-heap. Each `heapq.heappush` operation takes O(log k) time.\n", - " - Therefore, the time complexity of the `__init__` method is O(k * log k).\n", - "\n", - "2. `add` method:\n", - " - In the `add` method, you perform the following operations:\n", - " - `heapq.heappush`: O(log k) to add the new element to the min-heap.\n", - " - If the size of the min-heap exceeds `k`, you perform `heapq.heappop`, which is also O(log k).\n", - " - Finally, you return the smallest element from the min-heap, which is O(1) because it's always the root.\n", - " - Overall, the time complexity of the `add` method is O(log k).\n", - "\n", - "3. Overall, if you make `n` calls to the `add` method, the total time complexity is O(n * log k), where `n` is the total number of elements added to the stream.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. The space complexity is determined by the space used to store the min-heap and the instance variables.\n", - "2. The min-heap stores at most `k` elements at any given time, so its space complexity is O(k).\n", - "3. The instance variables (such as `self.k` and `self.min_heap`) have constant space requirements.\n", - "4. Therefore, the overall space complexity of the `KthLargest` class is O(k).\n", - "\n", - "In summary, the time complexity of the `KthLargest` class is O(n * log k) for `n` add operations, and the space complexity is O(k), where `k` is the parameter passed during initialization. This implementation efficiently maintains the kth largest element in the stream while meeting the problem's constraints." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Dynamic k:** Modify the `KthLargest` class to support dynamic changes in the value of `k`. Implement a method `update_k` that allows changing the value of `k` during the lifetime of the object. Ensure that the object can still correctly find the kth largest element based on the updated value of `k`.\n", - "\n", - "\n", - "2. **Implement kth Smallest:** Create a new class called `KthSmallest` that finds the kth smallest element in a stream instead of the kth largest. You may need to modify the data structure used in the implementation." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/10. Backtracking/39. Combination Sum.ipynb b/_build/jupyter_execute/10. Backtracking/39. Combination Sum.ipynb deleted file mode 100644 index 85d59ac..0000000 --- a/_build/jupyter_execute/10. Backtracking/39. Combination Sum.ipynb +++ /dev/null @@ -1,274 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 39. Combination Sum\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Combination Sum problem on LeetCode, click here!](https://leetcode.com/problems/combination-sum/)\n", - "\n", - "---\n", - "Given an array of **distinct** integers `candidates` and a target integer `target`, return *a list of all **unique combinations** of `candidates` where the chosen numbers sum to the `target`*. You may return the combinations in **any order**. \n", - "\n", - "The **same** number may be chosen from `candidates` an **unlimited number** of times. Two combinations are unique if the **frequency** of at least one of the chosen numbers is different.\n", - "\n", - "The test cases are generated such that the number of unique combinations that sum up to `target` is less than `150` combinations for the given input.\n", - "\n", - "**Constraints:**\n", - "- `1 <= candidates.length <= 30`\n", - "- `2 <= candidates[i] <= 40`\n", - "- All elements of `candidates` are **distinct**.\n", - "- `1 <= target <= 40`" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is to find all unique combinations of numbers from a given array (candidates) such that their sum equals a target number. Here are the details of the problem:\n", - "\n", - "- You are given an array of distinct integers called \"candidates.\"\n", - "- You are also given a target integer called \"target.\"\n", - "\n", - "The goal is to find all unique combinations of numbers from the candidates array where the sum of the selected numbers is equal to the target. You can use the same number from the candidates array an unlimited number of times. A combination is considered unique if it has a different frequency (i.e., a different number of occurrences) of at least one chosen number compared to other combinations.\n", - "\n", - "For example:\n", - "\n", - "**Example 1:**\n", - "```python\n", - "Input: candidates = [2, 3, 6, 7], target = 7\n", - "Output: [[2, 2, 3], [7]]\n", - "```\n", - "In this example, there are two unique combinations that sum up to the target:\n", - "- 2 + 2 + 3 = 7\n", - "- 7 = 7\n", - "\n", - "**Example 2:**\n", - "```python\n", - "Input: candidates = [2, 3, 5], target = 8\n", - "Output: [[2, 2, 2, 2], [2, 3, 3], [3, 5]]\n", - "```\n", - "Here, there are three unique combinations that sum up to the target.\n", - "\n", - "**Example 3:**\n", - "```python\n", - "Input: candidates = [2], target = 1\n", - "Output: []\n", - "```\n", - "In this case, there are no combinations that can be formed from the candidates to reach the target of 1, so the output is an empty list.\n", - "\n", - "The problem asks you to find and return these combinations in any order.\n", - "\n", - "The constraints for this problem include the length of the candidates array, the values of candidates, and the target value.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "def combinationSum(candidates, target):\n", - " # Define a recursive DFS function to find combinations\n", - " def dfs(remaining, start, path):\n", - " # If the remaining target is 0, we found a valid combination\n", - " if remaining == 0:\n", - " result.append(path)\n", - " return\n", - " # If the remaining target is negative, this path is invalid\n", - " if remaining < 0:\n", - " return\n", - " # Iterate through candidates starting from 'start' to avoid duplicates\n", - " for i in range(start, len(candidates)):\n", - " # Explore the current candidate by subtracting it from the remaining target\n", - " # Add the current candidate to the path\n", - " dfs(remaining - candidates[i], i, path + [candidates[i]])\n", - "\n", - " result = [] # Initialize an empty list to store the result\n", - " candidates.sort() # Sort the candidates for deduplication and early stopping\n", - " dfs(target, 0, []) # Start the DFS from the target value with an empty path\n", - " return result # Return the list of unique combinations" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The `combinationSum` function takes an array of distinct integers `candidates` and a target integer `target`. It returns a list of all unique combinations of `candidates` where the chosen numbers sum to the `target`. Each number in the `candidates` array can be used an unlimited number of times.\n", - "\n", - "Here's an overview of how the code works:\n", - "\n", - "1. The `combinationSum` function is defined, and it takes two arguments: `candidates` and `target`.\n", - "\n", - "2. Inside the function, there is a nested helper function called `backtrack`. This function is responsible for the actual combination generation using a recursive approach.\n", - "\n", - "3. The `backtrack` function is called with three arguments: `start`, `target`, and `path`. The `start` variable helps keep track of the current index in the `candidates` array, `target` keeps track of the remaining sum to be achieved, and `path` is a list that stores the current combination.\n", - "\n", - "4. Within the `backtrack` function, there are three main conditional statements:\n", - " - If `target` becomes zero, it means we have found a combination that sums up to the target, so we add `path` to the `result` list.\n", - " - If `target` becomes negative, it means the current combination doesn't work, so we return without doing anything.\n", - " - Otherwise, we enter a loop that iterates over the `candidates` array, starting from the current index `start`.\n", - "\n", - "5. In the loop, the `backtrack` function is called recursively with the updated `target` and `path` after including the current candidate. This process explores different combinations by considering the current candidate or moving to the next candidate.\n", - "\n", - "6. After the loop completes, the `result` list contains all unique combinations that sum to the target.\n", - "\n", - "7. The `candidates` array is sorted to optimize the search. Sorting helps in avoiding unnecessary recursive branches and reduces the number of explored combinations.\n", - "\n", - "8. Finally, the `backtrack` function is initially called from the `combinationSum` function with `start` set to 0, `target` set to the original target value, and an empty `path`. The result is returned as a list of unique combinations.\n", - "\n", - "The code includes a few example cases to demonstrate how the function works with different inputs." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[2, 2, 3], [7]]\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example 1\n", - "candidates1 = [2, 3, 6, 7]\n", - "target1 = 7\n", - "print(combinationSum(candidates1, target1)) # Output: [[2, 2, 3], [7]]" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[2, 2, 2, 2], [2, 3, 3], [3, 5]]\n" - ] - } - ], - "source": [ - "# Example 2\n", - "candidates2 = [2, 3, 5]\n", - "target2 = 8\n", - "print(combinationSum(candidates2, target2)) # Output: [[2, 2, 2, 2], [2, 3, 3], [3, 5]]" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "b5fca8ab-8c98-45b1-b44b-0503309121c9", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[]\n" - ] - } - ], - "source": [ - "# Example 3\n", - "candidates3 = [2]\n", - "target3 = 1\n", - "print(combinationSum(candidates3, target3)) # Output: []" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `combinationSum` function.\n", - "\n", - "**Time Complexity:**\n", - "The time complexity of this function is influenced by the number of recursive calls made by the `backtrack` function and the amount of work done within each call. In the worst case, the function will explore all possible combinations.\n", - "\n", - "The worst-case scenario occurs when we have many combinations to reach the target. The time complexity can be expressed as $O(2^n)$, where 'n' is the maximum number of recursive calls. In this context, 'n' corresponds to the number of elements in the `candidates` list, and it may be up to 30 (as per the constraints). However, the actual number of combinations explored is generally much smaller because we eliminate branches when the target becomes negative, and we skip over candidates that cannot lead to a solution. The sorting step also helps to optimize the search.\n", - "\n", - "**Space Complexity:**\n", - "The space complexity is determined by the auxiliary space used for storing the results and the stack space for the recursive calls.\n", - "\n", - "1. The space required for the `result` list can be up to $O(2^n)$ in the worst case because each combination is stored.\n", - "\n", - "2. The stack space for the recursive calls can also be up to O(n) in the worst case, where 'n' is the number of elements in the `candidates` list.\n", - "\n", - "Therefore, the overall space complexity of the function is $O(2^n + n)$. However, in practice, the space used for the results list is often the dominant factor, and the actual space used may be much smaller than 2^n because not all combinations are explored.\n", - "\n", - "In summary, the time complexity is exponential but typically smaller in practice due to optimization, and the space complexity is influenced by the number of results and the depth of the recursion." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Find the Number of Unique Combinations:** Instead of listing all unique combinations, modify the function to return the count of unique combinations that sum to the target.\n", - "\n", - "2. **Combinations with a Maximum Value:** Add a maximum value constraint for each combination, so they cannot exceed a certain value. Modify the code to find combinations respecting this constraint." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/10. Backtracking/79. Word Search.ipynb b/_build/jupyter_execute/10. Backtracking/79. Word Search.ipynb deleted file mode 100644 index 8d97d20..0000000 --- a/_build/jupyter_execute/10. Backtracking/79. Word Search.ipynb +++ /dev/null @@ -1,290 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 79. Word Search\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Word Search problem on LeetCode, click here!](https://leetcode.com/problems/word-search/)\n", - "\n", - "---\n", - "Given an `m x n` grid of characters `board` and a string `word`, return *`true` if `word` exists in the grid.*\n", - "\n", - "The word can be constructed from letters of sequentially adjacent cells, where adjacent cells are horizontally or vertically neighboring. The same letter cell may not be used more than once.\n", - "\n", - "**Constraints:**\n", - "- `m == board.length`\n", - "- `n = board[i].length`\n", - "- `1 <= m, n <= 6`\n", - "- `1 <= word.length <= 15`\n", - "- `board` and `word` consists of only lowercase and uppercase English letters.\n", - "\n", - "**Follow up:** Could you use search pruning to make your solution faster with a larger `board`?" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is to determine whether a given word can be constructed from characters in an `m x n` grid of characters. The word can be formed by moving sequentially through horizontally or vertically neighboring cells in the grid, and you cannot use the same cell more than once.\n", - "\n", - "Here are the specifics of the problem:\n", - "\n", - "- You are given an `m x n` grid, which is a 2D board of characters.\n", - "- You are also given a string `word` consisting of lowercase and uppercase English letters.\n", - "- Your task is to determine if the word can be found in the grid by moving from one cell to an adjacent cell (horizontally or vertically) and collecting the characters sequentially to form the word.\n", - "- You can't use the same cell more than once when forming the word.\n", - "- If it's possible to form the word in the grid, return `True`; otherwise, return `False`.\n", - "\n", - "For example, consider the following grid and word:\n", - "\n", - "```python\n", - "board = [[\"A\", \"B\", \"C\", \"E\"],\n", - " [\"S\", \"F\", \"C\", \"S\"],\n", - " [\"A\", \"D\", \"E\", \"E\"]] \n", - "word = \"ABCCED\"\n", - "```\n", - "\n", - "In this case, the word \"ABCCED\" can be formed by moving through the cells (0,0) -> (0,1) -> (0,2) -> (1,2) -> (2,2) -> (2,3) in the grid. Therefore, the function should return `True`.\n", - "\n", - "Conversely, if the word is impossible to construct, such as in the case of the word \"ABCB\" for the same grid, where there's no valid path that forms the word, the function should return `False`.\n", - "\n", - "The problem involves searching for a path through the grid that matches the characters in the word while respecting the constraints mentioned. It can be solved using depth-first search (DFS) or backtracking.\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "from typing import List\n", - "\n", - "class Solution:\n", - " def exist(self, board: List[List[str]], word: str) -> bool:\n", - " def dfs(i, j, k):\n", - " # Check if the current position is out of bounds or doesn't match the character in the word.\n", - " if not (0 <= i < len(board)) or not (0 <= j < len(board[0])) or board[i][j] != word[k]:\n", - " return False\n", - " \n", - " # If we have matched all characters in the word, return True.\n", - " if k == len(word) - 1:\n", - " return True\n", - "\n", - " # Temporarily mark the current cell to prevent revisiting.\n", - " tmp, board[i][j] = board[i][j], \"/\"\n", - "\n", - " # Explore adjacent cells by making recursive calls in all four directions.\n", - " found = dfs(i + 1, j, k + 1) or dfs(i - 1, j, k + 1) or dfs(i, j + 1, k + 1) or dfs(i, j - 1, k + 1)\n", - "\n", - " # Restore the original character in the cell.\n", - " board[i][j] = tmp\n", - "\n", - " return found\n", - "\n", - " # Iterate through all cells in the board.\n", - " for i in range(len(board)):\n", - " for j in range(len(board[0])):\n", - " # Check if the 'dfs' function starting from this cell returns True.\n", - " if dfs(i, j, 0):\n", - " return True\n", - "\n", - " # If no match is found after exploring all cells, return False.\n", - " return False" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. Import the necessary module:\n", - " - `from typing import List`: This line imports the `List` type from the `typing` module, which is used to specify the type of the `board` parameter in the method signature.\n", - "\n", - "2. Define the `Solution` class:\n", - " - `class Solution:`: This line defines a class called `Solution` to encapsulate the solution for the word search problem.\n", - "\n", - "3. Define the `exist` method:\n", - " - `def exist(self, board: List[List[str]], word: str) -> bool:`: This method is a member of the `Solution` class and takes two parameters: `board`, which is a 2D list of characters, and `word`, which is a string. It returns a boolean value, indicating whether the word exists in the board.\n", - "\n", - "4. Implement the inner `dfs` function:\n", - " - `def dfs(i, j, k):`: This is a helper function used for depth-first search (DFS). It is called recursively to explore the board and search for the word. It takes three parameters: `i` and `j` representing the current position on the board, and `k` representing the current index in the `word` string.\n", - "\n", - " - Inside `dfs`, it checks if the current position is out of bounds or if the character at the current position on the board does not match the character at the current index in the `word`. If either of these conditions is met, it returns `False`.\n", - "\n", - " - If `k` is equal to the length of the `word` minus one, it means we have successfully matched all characters in the `word`, so it returns `True`.\n", - "\n", - " - The function then temporarily replaces the character at the current position with a marker, \"/\", to prevent revisiting the same cell. It then explores adjacent cells by making recursive calls in all four directions: up, down, left, and right. If any of these recursive calls return `True`, it propagates the `True` result up the call stack. After the exploration is complete, it restores the original character in the cell.\n", - "\n", - "5. Iterate through the board:\n", - " - The outer loop iterates through all cells in the `board` using two nested loops. For each cell, it checks if the `dfs` function starting from that cell (with `k` initially set to 0) returns `True`. If it does, it means the word exists, so the method returns `True`.\n", - "\n", - "6. Return `False`:\n", - " - If the loop completes without finding the word in the board, the method returns `False`.\n", - "\n", - "To use this code, you can create an instance of the `Solution` class and call the `exist` method on that instance, passing the `board` and the `word` as arguments to check if the word exists in the board." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Create an instance of the Solution class\n", - "solution = Solution()\n", - "\n", - "# Test case 1: Word \"ABCCED\" can be found in the grid\n", - "board1 = [[\"A\",\"B\",\"C\",\"E\"],\n", - " [\"S\",\"F\",\"C\",\"S\"],\n", - " [\"A\",\"D\",\"E\",\"E\"]]\n", - "word1 = \"ABCCED\"\n", - "print(solution.exist(board1, word1)) # Expected output: True" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 2\n", - "\n", - "# Test case 2: Word \"SEE\" can be found in the grid\n", - "word2 = \"SEE\"\n", - "print(solution.exist(board1, word2)) # Expected output: True" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "b5fca8ab-8c98-45b1-b44b-0503309121c9", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 3\n", - "\n", - "# Test case 3: Word \"ABCB\" cannot be found in the grid\n", - "word3 = \"ABCB\"\n", - "print(solution.exist(board1, word3)) # Expected output: False" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `exist` method in the given code.\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The primary work in this code is done by the `dfs` function, which performs a depth-first search through the grid. The time complexity of the `dfs` function is $O(4^(n))$, where \"n\" is the length of the `word`. This is because, in the worst case, the function explores all possible directions (up, down, left, right) for each character in the `word`.\n", - "\n", - "The outer loops iterate through all cells in the `board`, which has dimensions `m x n`. So, the total number of iterations of `dfs` is O(m * n). However, since the `dfs` function has a higher time complexity, the overall time complexity is still dominated by the `dfs` function.\n", - "\n", - "Therefore, the overall time complexity of the `exist` method is $O(m * n * 4^n)$, where \"m\" and \"n\" are the dimensions of the board, and \"n\" is the length of the word.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. The primary space usage comes from the recursive calls in the `dfs` function. The depth of the recursion can be at most equal to the length of the `word`, which is O(n).\n", - "\n", - "2. Additionally, the `tmp` variable and the recursive calls on the call stack consume a small amount of additional memory.\n", - "\n", - "3. The marking of visited cells with the \"/\" character temporarily modifies the `board` in-place but doesn't significantly contribute to the space complexity.\n", - "\n", - "Therefore, the overall space complexity is O(n) due to the recursive call stack.\n", - "\n", - "In summary, the time complexity is $O(m * n * 4^n)$, and the space complexity is O(n), where \"m\" and \"n\" are the dimensions of the board, and \"n\" is the length of the word. The time complexity is exponential in the worst case due to the depth-first search through all possible paths in the grid." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Optimization Challenge:** Modify the code to find all unique words that can be constructed from the grid. Instead of returning `True` or `False`, return a list of words found. Ensure that the same cell is not used more than once in constructing each word.\n", - "\n", - "2. **Board Generation:** Create a function to generate random grids of characters and then use the `exist` method to solve them. Test the efficiency and correctness of your code by generating larger boards and words." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/11. Graphs/133. Clone Graph.ipynb b/_build/jupyter_execute/11. Graphs/133. Clone Graph.ipynb deleted file mode 100644 index 56b7647..0000000 --- a/_build/jupyter_execute/11. Graphs/133. Clone Graph.ipynb +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 133. Clone Graph\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Clone Graph problem on LeetCode, click here!](https://leetcode.com/problems/clone-graph/)\n", - "\n", - "---\n", - "Given a reference of a node in a **connected** undirected graph.\n", - "\n", - "Return a **deep copy** (clone) of the graph.\n", - "\n", - "Each node in the graph contains a value (`int`) and a list (`List[Node]`) of its neighbors.\n", - "\n", - "```\n", - "class Node {\n", - " public int val;\n", - " public List neighbors;\n", - "}\n", - "```\n", - "\n", - "**Test case format:**\n", - "\n", - "For simplicity, each node's value is the same as the node's index (1-indexed). For example, the first node with `val == 1`, the second node with `val == 2`, and so on. The graph is represented in the test case using an adjacency list.\n", - "\n", - "**An adjacency list** is a collection of unordered **lists** used to represent a finite graph. Each list describes the set of neighbors of a node in the graph.\n", - "\n", - "The given node will always be the first node with `val = 1`. You must return the **copy of the given node** as a reference to the cloned graph.\n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the graph is in the range `[0, 100]`.\n", - "- `1 <= Node.val <= 100`\n", - "- `Node.val` is unique for each node.\n", - "- There are no repeated edges and no self-loops in the graph.\n", - "- The Graph is connected and all nodes can be visited starting from the given node." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem at hand is to clone a connected undirected graph, which means we need to create a deep copy of the original graph while preserving its structure and relationships between nodes. The graph is represented using adjacency lists, where each node has a value (an integer) and a list of its neighbors.\n", - "\n", - "Here are the key aspects of the problem:\n", - "\n", - "1. **Input**: You are given a reference to one of the nodes in the original graph. This reference node serves as the entry point to the graph. The entire graph can be explored starting from this node.\n", - "\n", - "2. **Output**: The goal is to create a deep copy of the graph and return a reference to the cloned graph. The cloned graph should have the same structure and relationships as the original one but should be a separate instance in memory.\n", - "\n", - "3. **Graph Structure**: The graph is composed of nodes (vertices) and edges. Nodes have values (integers) and are connected to other nodes through edges (undirected connections). Each node has a list of neighbors, which are other nodes it is connected to.\n", - "\n", - "4. **Connected Graph**: The problem assumes that the graph is connected, meaning that you can start from the reference node provided and traverse the entire graph by following the edges. This ensures that there are no isolated components in the graph.\n", - "\n", - "To solve this problem, you typically need to perform a graph traversal (e.g., depth-first search or breadth-first search) to visit all the nodes in the original graph, create corresponding nodes in the clone, and establish the same connections between nodes in the cloned graph as in the original one. To avoid duplication of nodes, you also need to keep track of visited nodes to ensure that the cloning process is efficient and that nodes are not duplicated in the clone.\n", - "\n", - "The problem can be challenging because you need to create a deep copy of the graph while handling cyclic dependencies between nodes and ensuring that the structure and relationships of the original graph are preserved in the clone. The solution requires recursion or a data structure to maintain the mapping between original nodes and their clones to achieve an efficient and accurate cloning process.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "# Definition for a Node.\n", - "class Node:\n", - " def __init__(self, val=0, neighbors=None):\n", - " self.val = val\n", - " self.neighbors = neighbors if neighbors is not None else []\n", - "\n", - "class Solution:\n", - " def cloneGraph(self, node: 'Node') -> 'Node':\n", - " if not node:\n", - " return None\n", - "\n", - " visited = {} # Dictionary to keep track of visited nodes\n", - "\n", - " def dfs(original_node):\n", - " if original_node in visited:\n", - " return visited[original_node]\n", - "\n", - " # Create a copy of the original node\n", - " copy_node = Node(original_node.val)\n", - " visited[original_node] = copy_node\n", - "\n", - " # Recursively clone the neighbors of the original node\n", - " for neighbor in original_node.neighbors:\n", - " copy_node.neighbors.append(dfs(neighbor))\n", - "\n", - " return copy_node\n", - "\n", - " return dfs(node)" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The given code defines a Python class, `Node`, and a solution class, `Solution`, to clone a connected undirected graph represented by nodes and their neighbors. Here's an explanation of the code:\n", - "\n", - "1. The `Node` class defines a node in the graph. Each node has a value (`val`) which is an integer and a list of neighbors (`neighbors`) that are other nodes in the graph.\n", - "\n", - "2. The `Solution` class contains the method `cloneGraph`, which takes a reference to the first node of the graph (`node`) as input and returns a deep copy of the entire graph, preserving the structure and relationships between nodes.\n", - "\n", - "3. Inside the `cloneGraph` method:\n", - " - It first checks if the input `node` is `None`. If it's `None`, it means there is no graph to clone, and the method returns `None`.\n", - "\n", - " - It initializes a `visited` dictionary to keep track of visited nodes. This dictionary is used to ensure that each node is cloned only once to avoid duplication.\n", - "\n", - " - The `dfs` (depth-first search) function is defined within the `cloneGraph` method. It takes an original node as input and returns its corresponding clone. This function performs the actual cloning of the graph.\n", - "\n", - " - Inside the `dfs` function:\n", - " - It checks if the original node has been visited before by looking it up in the `visited` dictionary. If it has been visited, it returns the corresponding clone from the `visited` dictionary.\n", - "\n", - " - If the original node is not visited, it creates a new node, `copy_node`, with the same value as the original node. This is the first step in creating the clone of the original node.\n", - "\n", - " - It then recursively clones the neighbors of the original node by iterating through the `neighbors` list of the original node and appending the corresponding cloned neighbors to the `neighbors` list of the `copy_node`. This step ensures that the relationships between nodes are preserved in the clone.\n", - "\n", - " - The `copy_node` is added to the `visited` dictionary with the original node as the key and the clone as the value.\n", - "\n", - " - Finally, the `copy_node` is returned as the result of the DFS for the original node.\n", - "\n", - "4. The `cloneGraph` method returns the result of the DFS on the input `node`, which is the clone of the entire graph with its structure and relationships intact.\n", - "\n", - "In summary, the code uses depth-first search (DFS) to traverse the original graph, creating a clone for each node and its neighbors. It ensures that each node is cloned only once to avoid duplication and returns a reference to the cloned graph." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "f12c5a63-b811-4be7-83c2-34ee396b546c", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[1, 2, 4]]\n" - ] - } - ], - "source": [ - "def get_adjacency_list(node):\n", - " visited = {} # Dictionary to keep track of visited nodes\n", - "\n", - " def dfs(node):\n", - " if not node:\n", - " return []\n", - "\n", - " if node in visited:\n", - " return visited[node]\n", - "\n", - " neighbors = [n.val for n in node.neighbors]\n", - " visited[node] = neighbors\n", - "\n", - " for neighbor in node.neighbors:\n", - " dfs(neighbor)\n", - "\n", - " dfs(node)\n", - " result = []\n", - "\n", - " def get_node_and_neighbors(node):\n", - " result.append([node.val] + visited[node])\n", - "\n", - " get_node_and_neighbors(node)\n", - " return result\n", - "\n", - "\n", - "# Testing the code with the provided examples\n", - "adjList1 = [[2, 4], [1, 3], [2, 4], [1, 3]]\n", - "solution = Solution()\n", - "\n", - "# Create the graph from adjList\n", - "nodes = [Node(i) for i in range(1, len(adjList1) + 1)]\n", - "for i, adj in enumerate(adjList1):\n", - " nodes[i].neighbors = [nodes[j - 1] for j in adj]\n", - "\n", - "# Clone the graph and get its adjacency list\n", - "cloned_node1 = solution.cloneGraph(nodes[0])\n", - "cloned_adjList1 = get_adjacency_list(cloned_node1)\n", - "\n", - "# Print the cloned graph as an adjacency list\n", - "print(cloned_adjList1)\n", - "\n", - "# Output should match adjList1\n" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[1]]\n" - ] - } - ], - "source": [ - "# Example 2\n", - "# Input: adjList = [[]]\n", - "\n", - "adjList2 = [[]]\n", - "solution = Solution()\n", - "\n", - "# Create the graph from adjList\n", - "node1 = Node(1)\n", - "\n", - "# Clone the graph and get its adjacency list\n", - "cloned_node1 = solution.cloneGraph(node1)\n", - "cloned_adjList2 = get_adjacency_list(cloned_node1)\n", - "\n", - "# Print the cloned graph as an adjacency list\n", - "print(cloned_adjList2)\n", - "\n", - "# Output should be [[]], which represents an empty graph" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code for cloning a graph using depth-first search (DFS).\n", - "\n", - "Time Complexity:\n", - "1. Creating the graph: The time complexity to create the original graph from `adjList` is O(V + E), where V is the number of vertices (nodes) and E is the number of edges. We iterate through each node and its neighbors in `adjList`.\n", - "\n", - "2. Cloning the graph (DFS): The depth-first search (DFS) is used to traverse the original graph and create a clone. The time complexity of DFS is O(V + E), as we visit each node and each edge once.\n", - "\n", - "Overall, the time complexity is O(V + E) for both creating the original graph and cloning it.\n", - "\n", - "Space Complexity:\n", - "1. Storage for the original graph: We need to store the original graph, which includes all nodes and their adjacency lists. In the worst case, this requires O(V + E) space, where V is the number of nodes, and E is the number of edges.\n", - "\n", - "2. Storage for the visited dictionary: The `visited` dictionary stores mappings from original nodes to their corresponding clones. In the worst case, this requires O(V) space because each node is visited once.\n", - "\n", - "3. Recursive stack for DFS: The space used for the recursive call stack during DFS can be up to O(V) in the worst case, where V is the number of nodes.\n", - "\n", - "Overall, the space complexity is O(V + E) for storing the original graph, and O(V) for auxiliary data structures, including the `visited` dictionary and the DFS call stack. Therefore, the overall space complexity is O(V + E).\n", - "\n", - "In summary, the time and space complexities of the provided code for cloning a graph are both O(V + E), where V is the number of nodes, and E is the number of edges in the graph." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Cyclic Graph**: Design a graph with cycles (nodes connected in a cycle). Test if the code can correctly clone graphs with cycles and doesn't fall into an infinite loop during traversal.\n", - "\n", - "\n", - "2. **Partial Graph Cloning**: Modify the code to clone only a subset of the graph starting from a given reference node, rather than the entire graph. Implement this as an extension to the problem." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/11. Graphs/178. Graph Valid Tree.ipynb b/_build/jupyter_execute/11. Graphs/178. Graph Valid Tree.ipynb deleted file mode 100644 index 0dd53e9..0000000 --- a/_build/jupyter_execute/11. Graphs/178. Graph Valid Tree.ipynb +++ /dev/null @@ -1,242 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 178. Graph Valid Tree\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Graph Valid Tree problem on LintCode, click here!](https://www.lintcode.com/problem/178/)\n", - "\n", - "---\n", - "Given `n` nodes labeled from `0` to `n - 1` and a list of `undirected` edges (each edge is a pair of nodes), write a function to check whether these edges make up a valid tree.\n", - "\n", - "**Constraints:**\n", - "- You can assume that no duplicate edges will appear in edges. Since all edges are `undirected`, `[0, 1]` is the same as `[1, 0]` and thus will not appear together in edges." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is to determine whether a given set of undirected edges can form a valid tree. In this context, a \"tree\" is a specific type of graph with the following properties:\n", - "\n", - "1. It is a connected graph, meaning there is a path between any pair of nodes in the graph.\n", - "2. It has no cycles, which means there are no closed loops or circuits in the graph.\n", - "3. It has exactly `n - 1` edges, where `n` is the number of nodes in the tree.\n", - "\n", - "The problem is typically given with two pieces of information:\n", - "\n", - "1. The number of nodes (`n`), which are usually labeled from 0 to `n-1`.\n", - "2. A list of undirected edges, where each edge is represented as a pair of nodes.\n", - "\n", - "The task is to write a function or algorithm to determine whether the provided set of edges can be arranged to form a valid tree based on the properties mentioned above.\n", - "\n", - "To solve this problem, you need to check the following conditions:\n", - "\n", - "1. There should be exactly `n - 1` edges to ensure that the graph is connected and tree-like.\n", - "2. There should be no cycles in the graph. If there are any cycles, the set of edges cannot form a tree.\n", - "3. The graph should be connected, which means you can reach any node from any other node through a series of edges.\n", - "\n", - "The solution typically involves using graph traversal algorithms like Depth-First Search (DFS) or Breadth-First Search (BFS) to explore the graph and check these conditions. If all conditions are met, the given edges form a valid tree; otherwise, they do not.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "def validTree(n, edges):\n", - " if len(edges) != n - 1:\n", - " return False # A tree with n nodes must have n-1 edges.\n", - "\n", - " # Create an adjacency list to represent the graph.\n", - " adj_list = {i: [] for i in range(n)}\n", - " for u, v in edges:\n", - " adj_list[u].append(v)\n", - " adj_list[v].append(u)\n", - "\n", - " visited = set()\n", - "\n", - " # Define a recursive DFS function.\n", - " def dfs(node, parent):\n", - " if node in visited:\n", - " return False # If we encounter a visited node, there's a cycle.\n", - " visited.add(node)\n", - "\n", - " for neighbor in adj_list[node]:\n", - " if neighbor != parent:\n", - " if not dfs(neighbor, node):\n", - " return False\n", - "\n", - " return True\n", - "\n", - " # Start DFS from any node (e.g., node 0).\n", - " if not dfs(0, -1):\n", - " return False # If there's a cycle, it's not a valid tree.\n", - "\n", - " return len(visited) == n" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The `validTree` function checks if a given set of undirected edges forms a valid tree. A valid tree must satisfy these conditions:\n", - "\n", - "1. It has exactly `n - 1` edges, where `n` is the number of nodes.\n", - "2. There are no cycles in the graph.\n", - "3. The graph is connected, meaning all nodes are reachable from any starting node.\n", - "\n", - "The code accomplishes this as follows:\n", - "\n", - "- It first checks if the number of edges is equal to `n - 1`. If not, it immediately returns `False` since a tree with `n` nodes must have `n - 1` edges to be connected.\n", - "\n", - "- It then constructs an adjacency list (`adj_list`) to represent the graph efficiently. This data structure stores the neighbors of each node.\n", - "\n", - "- The code uses a `visited` set to keep track of nodes visited during depth-first search (DFS).\n", - "\n", - "- The `dfs` function is a recursive function that checks for cycles in the graph. It does this by visiting nodes and marking them as visited. If it encounters a node that has already been visited (indicating a cycle), it returns `False`.\n", - "\n", - "- The DFS function explores the neighbors of each node, avoiding revisiting the parent node to prevent cycles.\n", - "\n", - "- After the DFS is complete, the code checks if the number of visited nodes is equal to `n`, ensuring the graph is connected.\n", - "\n", - "- Finally, if all conditions are met, the code returns `True`, indicating that the given edges form a valid tree. Otherwise, it returns `False`.\n", - "\n", - "The code provides examples to demonstrate how to use the `validTree` function to check whether a set of edges forms a valid tree or not." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1\n", - "n1 = 5\n", - "edges1 = [[0, 1], [0, 2], [0, 3], [1, 4]]\n", - "print(validTree(n1, edges1)) # Output: true" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 2\n", - "n2 = 5\n", - "edges2 = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]]\n", - "print(validTree(n2, edges2)) # Output: false" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexities of the `validTree` function:\n", - "\n", - "**Time Complexity:**\n", - "1. Constructing the adjacency list (`adj_list`) takes O(E) time, where E is the number of edges in the input graph (|edges|).\n", - "\n", - "2. The DFS function, when considering all nodes, has a time complexity of O(V + E), where V is the number of nodes in the graph. This is because, in the worst case, the DFS function visits each node and each edge once.\n", - "\n", - "3. Checking if the number of visited nodes is equal to `n` takes O(1) time.\n", - "\n", - "Overall, the time complexity of the `validTree` function is O(E + V) in the worst case.\n", - "\n", - "**Space Complexity:**\n", - "1. The adjacency list (`adj_list`) consumes additional space to store the graph structure, taking O(V + E) space. This is because it stores information about each node and its adjacent nodes.\n", - "\n", - "2. The `visited` set keeps track of visited nodes, and its space complexity is O(V) in the worst case, as there can be at most V unique nodes in the set.\n", - "\n", - "3. The depth of the function call stack during DFS can be at most V, which contributes O(V) space to the space complexity.\n", - "\n", - "Overall, the space complexity of the `validTree` function is O(V + E) due to the adjacency list and O(V) due to the `visited` set and DFS call stack.\n", - "\n", - "In summary, the time complexity is O(E + V), and the space complexity is O(V + E). These complexities are based on the worst-case scenario, where all nodes and edges are considered. In practical cases, the actual complexities may be smaller, depending on the specific structure of the graph." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Minimum Spanning Tree (MST)**: Implement an algorithm to find the minimum spanning tree of a connected graph using either Kruskal's or Prim's algorithm. Compare the MST to the original graph to determine if the original graph is a tree. This exercise reinforces the concept of tree properties.\n", - "\n", - "2. **Detecting Cycles**: Modify the code to not only check if the input forms a tree but also to identify and print out any cycles present in the graph if it's not a tree. This exercise enhances your ability to detect and visualize cycles in a graph." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/11. Graphs/200. Number of Islands.ipynb b/_build/jupyter_execute/11. Graphs/200. Number of Islands.ipynb deleted file mode 100644 index 5a878a4..0000000 --- a/_build/jupyter_execute/11. Graphs/200. Number of Islands.ipynb +++ /dev/null @@ -1,236 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 200. Number of Islands\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Number of Islands problem on LeetCode, click here!](https://leetcode.com/problems/number-of-islands/)\n", - "\n", - "---\n", - "\n", - "Given an `m x n` 2D binary grid `grid` which represents a map of `'1'`s (land) and `'0'`s (water), return *the number of islands*. \n", - "\n", - "An **island** is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.\n", - "\n", - "**Constraints:**\n", - "- `m == grid.length`\n", - "- `n == grid[i].length`\n", - "- `1 <= m, n <= 300`\n", - "- `grid[i][j]` is `'0'` or `'1'`." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is about counting the number of islands in a 2D binary grid. In this grid, '1' represents land, and '0' represents water. An island is defined as a group of '1' cells that are adjacent to each other either horizontally or vertically. It's important to note that diagonal connections do not count. Additionally, it's assumed that all four edges of the grid are surrounded by water, meaning the grid is finite and doesn't \"wrap around.\"\n", - "\n", - "The objective is to determine how many distinct islands exist in the grid. To clarify, an island consists of connected '1' cells, and these connections can only occur horizontally or vertically. If there are no '1' cells in the grid, the number of islands would be zero.\n", - "\n", - "The problem often involves using graph traversal techniques like Depth-First Search (DFS) or Breadth-First Search (BFS) to identify and count these islands. You start at one '1' cell and explore its adjacent cells to determine the extent of the island. Once you've visited all the '1' cells in an island, you move on to the next unvisited '1' cell and repeat the process until you've counted all the islands in the grid.\n", - "\n", - "In essence, the problem asks you to analyze the grid to find groups of connected '1' cells and count them as individual islands. The goal is to return the total count of islands in the given grid.\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "from typing import List\n", - "\n", - "class Solution:\n", - " def numIslands(self, grid: List[List[str]]) -> int:\n", - " if not grid:\n", - " return 0\n", - "\n", - " m, n = len(grid), len(grid[0]) # Get the dimensions of the grid\n", - " num_islands = 0 # Initialize the count of islands\n", - "\n", - " def dfs(row, col):\n", - " if row < 0 or row >= m or col < 0 or col >= n or grid[row][col] == '0':\n", - " return\n", - "\n", - " grid[row][col] = '0' # Mark the current cell as visited by changing it to '0'\n", - " directions = [(1, 0), (-1, 0), (0, 1), (0, -1)] # Define four possible directions to move\n", - "\n", - " for dr, dc in directions:\n", - " # Explore adjacent cells\n", - " dfs(row + dr, col + dc)\n", - "\n", - " for i in range(m):\n", - " for j in range(n):\n", - " if grid[i][j] == '1':\n", - " num_islands += 1 # Increment the island count\n", - " dfs(i, j) # Start a DFS from the current '1' cell to explore the entire island\n", - "\n", - " return num_islands\n" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The provided code defines a Python class called `Solution` with a method called `numIslands`. This class is designed to count the number of islands in a 2D binary grid.\n", - "\n", - "The `numIslands` method takes a 2D grid as input, where '1' represents land, and '0' represents water. It uses a depth-first search (DFS) approach to identify and count islands. The key steps in the code include:\n", - "\n", - "1. Checking if the input grid is empty, and if so, returning 0 (indicating there are no islands).\n", - "\n", - "2. Determining the dimensions of the grid (number of rows and columns).\n", - "\n", - "3. Initializing a variable `num_islands` to keep track of the count of islands.\n", - "\n", - "4. Defining a nested function `dfs` to perform depth-first search. This function recursively explores adjacent land cells connected to the current cell and marks them as visited by changing '1' to '0'.\n", - "\n", - "5. In the `dfs` function, it checks for boundary conditions and whether the current cell is '0'. If these conditions are met, it returns without further exploration.\n", - "\n", - "6. The `dfs` function explores neighboring cells in all four directions (up, down, left, right) using a loop.\n", - "\n", - "7. The main loop iterates through each cell of the grid. When a '1' cell is encountered, it increments the `num_islands` count and starts a DFS from that cell to explore the entire island.\n", - "\n", - "8. Finally, the method returns the total count of islands found in the grid.\n", - "\n", - "This code encapsulates the solution in a class, allowing you to create an instance of the `Solution` class and call the `numIslands` method on it to count the number of islands in a given grid." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Example 1 Output: 1\n" - ] - } - ], - "source": [ - "grid1 = [\n", - " [\"1\", \"1\", \"1\", \"1\", \"0\"],\n", - " [\"1\", \"1\", \"0\", \"1\", \"0\"],\n", - " [\"1\", \"1\", \"0\", \"0\", \"0\"],\n", - " [\"0\", \"0\", \"0\", \"0\", \"0\"]\n", - "]\n", - "\n", - "solution = Solution()\n", - "result1 = solution.numIslands(grid1)\n", - "print(\"Example 1 Output:\", result1) # Expected output: 1\n" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Example 2 Output: 3\n" - ] - } - ], - "source": [ - "grid2 = [\n", - " [\"1\", \"1\", \"0\", \"0\", \"0\"],\n", - " [\"1\", \"1\", \"0\", \"0\", \"0\"],\n", - " [\"0\", \"0\", \"1\", \"0\", \"0\"],\n", - " [\"0\", \"0\", \"0\", \"1\", \"1\"]\n", - "]\n", - "\n", - "result2 = solution.numIslands(grid2)\n", - "print(\"Example 2 Output:\", result2) # Expected output: 3\n" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "Time Complexity:\n", - "- The code uses a depth-first search (DFS) to explore the grid and count the number of islands.\n", - "- In the worst case, it visits every cell in the grid exactly once.\n", - "- The DFS function explores neighboring cells in four directions (up, down, left, right), so it has a time complexity of $O(4^{max(m, n)})$, where m is the number of rows and n is the number of columns.\n", - "- Therefore, the overall time complexity of the code is O(m * n), where m is the number of rows, and n is the number of columns.\n", - "\n", - "Space Complexity:\n", - "- The space complexity is determined by the recursive calls and the depth of the DFS stack.\n", - "- In the worst case, when the entire grid consists of '1's, the depth of the DFS recursion can be as deep as max(m, n).\n", - "- Therefore, the space complexity of the code is O(max(m, n)), representing the maximum depth of the DFS stack.\n", - "\n", - "In practical terms, for reasonably sized grids, the time and space complexity is linear, and the code should perform well. However, it's important to keep in mind that the worst-case time complexity is O(m * n), and the space complexity can be O(max(m, n))." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Identify Largest Island:** In addition to counting the number of islands, modify the code to identify the largest island in the grid and return its size.\n", - "\n", - "2. **Optimize for Space:** Modify the solution to reduce its space complexity to O(1) without modifying the input grid. This is a more memory-efficient version of the problem." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/11. Graphs/207. Course Schedule.ipynb b/_build/jupyter_execute/11. Graphs/207. Course Schedule.ipynb deleted file mode 100644 index 4176cab..0000000 --- a/_build/jupyter_execute/11. Graphs/207. Course Schedule.ipynb +++ /dev/null @@ -1,243 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 207. Course Schedule\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Course Schedule problem on LeetCode, click here!](https://leetcode.com/problems/course-schedule/)\n", - "\n", - "---\n", - "There are a total of `numCourses` courses to take, labeled from 0 to `numCourses - 1`. You are given an array `prerequisites` where `prerequisites[i] = [ai, bi]` indicates that you **must** take course `bi` first if you want to take course `ai`. \n", - "\n", - "- For example, the pair `[0, 1]`, indicates that to take course `0` you have to first take course `1`.\n", - "\n", - "Return `true` if you can finish all courses. Otherwise, return `false`.\n", - "\n", - "**Constraints:**\n", - "- 1 <= `numCourses` <= 2000\n", - "- 0 <= `prerequisites.length` <= 5000\n", - "- `prerequisites[i].length` == 2\n", - "- 0 <= `ai`, `bi` < `numCourses`\n", - "- All the pairs `prerequisites[i]` are **unique**." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is to determine whether it's possible to complete a set of courses given a list of prerequisites. You are given the following:\n", - "\n", - "- `numCourses`: The total number of courses to be taken, labeled from 0 to `numCourses - 1`.\n", - "- `prerequisites`: A list of prerequisite courses, where each element `prerequisites[i]` is a pair `[ai, bi]`, indicating that you must take course `bi` before you can take course `ai`.\n", - "\n", - "The goal is to check whether it's possible to complete all the courses while respecting the prerequisite requirements. In other words, you need to determine if there are any circular dependencies in the course prerequisites that would prevent you from taking all the courses.\n", - "\n", - "For example:\n", - "\n", - "- If `numCourses` is 2, and `prerequisites` is `[[1, 0]]`, it means you have two courses, and you must finish course 0 before you can take course 1. In this case, it's possible to complete all courses, so the function should return `True`.\n", - "\n", - "- If `numCourses` is 2, and `prerequisites` is `[[1, 0], [0, 1]]`, it means you have two courses, but there's a circular dependency where course 1 requires course 0 and course 0 requires course 1. In this case, it's impossible to complete all courses, so the function should return `False`.\n", - "\n", - "The problem is essentially about checking for the presence of cycles in a directed graph, where the courses are nodes, and the prerequisites represent directed edges between them. If there are no cycles, it's possible to complete all courses; otherwise, it's not possible.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "from collections import defaultdict, deque\n", - "from typing import List\n", - "\n", - "class Solution:\n", - " def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:\n", - " # Create a graph using an adjacency list to represent the courses and their prerequisites.\n", - " graph = defaultdict(list) # Initialize an empty adjacency list.\n", - " in_degree = [0] * numCourses # Initialize an array to store in-degrees of courses.\n", - "\n", - " # Populate the graph and calculate in-degrees.\n", - " for course, prerequisite in prerequisites:\n", - " graph[prerequisite].append(course) # Add the course as a neighbor to its prerequisite.\n", - " in_degree[course] += 1 # Increment the in-degree of the course.\n", - "\n", - " # Initialize a queue with courses that have no prerequisites.\n", - " queue = deque()\n", - " for course in range(numCourses):\n", - " if in_degree[course] == 0:\n", - " queue.append(course)\n", - "\n", - " # Perform topological sorting.\n", - " while queue:\n", - " course = queue.popleft() # Take a course with no prerequisites.\n", - " numCourses -= 1 # Decrement the count of remaining courses.\n", - "\n", - " for neighbor in graph[course]:\n", - " in_degree[neighbor] -= 1 # Remove the prerequisite relationship.\n", - " if in_degree[neighbor] == 0:\n", - " queue.append(neighbor) # If no more prerequisites, add to the queue.\n", - "\n", - " # If all courses were successfully taken (numCourses becomes 0), return True.\n", - " return numCourses == 0" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "This Python code is designed to determine whether it is possible to complete all the required courses given a set of prerequisites. It uses a topological sorting algorithm to accomplish this. Here's a brief explanation of the code:\n", - "\n", - "1. The code defines a `Solution` class with a `canFinish` method that takes two parameters: `numCourses` (the total number of courses) and `prerequisites` (a list of pairs indicating which course must be taken before another).\n", - "\n", - "2. It initializes an empty graph as an adjacency list using a `defaultdict` to represent the courses and their prerequisites. It also initializes a list called `in_degree` to keep track of the in-degrees of courses, which is used in the topological sorting process.\n", - "\n", - "3. The code then populates the graph by iterating through the `prerequisites` list. For each pair `(ai, bi)`, it adds course `ai` as a neighbor to its prerequisite course `bi` in the graph and increments the in-degree of course `ai`.\n", - "\n", - "4. Next, it initializes a queue with courses that have no prerequisites. It does this by iterating through all the courses and adding those with an in-degree of 0 to the queue.\n", - "\n", - "5. The code performs a topological sorting of the courses using a while loop. In each iteration of the loop, it dequeues a course from the front of the queue (a course with no prerequisites).\n", - "\n", - "6. For each neighbor (course that depends on the dequeued course), it decrements the in-degree of the neighbor. If the neighbor's in-degree becomes 0, it means all of its prerequisites have been taken, so the neighbor is added to the queue.\n", - "\n", - "7. The loop continues until there are no more courses with no prerequisites to dequeue, and the in-degrees are updated accordingly.\n", - "\n", - "8. After the loop, if all courses were successfully taken (i.e., `numCourses` becomes 0), it means that there were no circular dependencies, and it's possible to finish all courses. In this case, the method returns `True`. Otherwise, if there are remaining courses (indicating a circular dependency), it returns `False`." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1\n", - "numCourses1 = 2\n", - "prerequisites1 = [[1, 0]]\n", - "sol = Solution()\n", - "print(sol.canFinish(numCourses1, prerequisites1)) # Output: True" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 2\n", - "numCourses2 = 2\n", - "prerequisites2 = [[1, 0], [0, 1]]\n", - "print(sol.canFinish(numCourses2, prerequisites2)) # Output: False" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `canFinish` method:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. Constructing the graph: In the first loop where we iterate through the `prerequisites` list, we populate the graph with prerequisites. This loop has a time complexity of O(E), where E is the number of prerequisites (edges).\n", - "\n", - "2. Initializing in-degrees and finding courses with no prerequisites: In the worst case, we iterate through all `numCourses` courses to initialize in-degrees and find the courses with no prerequisites. This has a time complexity of O(V), where V is the number of courses (vertices).\n", - "\n", - "3. Topological Sorting: In the while loop, we perform topological sorting, processing each course once and its outgoing edges. In the worst case, each course is processed once. This has a time complexity of O(V + E).\n", - "\n", - "The overall time complexity is O(V + E), where V is the number of courses, and E is the number of prerequisites.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. Graph Representation: The space complexity for storing the graph as an adjacency list is O(E), where E is the number of prerequisites.\n", - "\n", - "2. In-Degree Array: The space complexity for storing the in-degrees of courses is O(V), where V is the number of courses.\n", - "\n", - "3. Queue: The space complexity for the queue is O(V), as it may contain all the courses.\n", - "\n", - "The overall space complexity is O(V + E), where V is the number of courses, and E is the number of prerequisites.\n", - "\n", - "In most practical cases, the number of prerequisites (E) is much smaller than the number of courses (V), so the time and space complexity can often be considered as O(V)." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Optimizing Course Scheduling**: Given a list of courses with their durations and prerequisites, find the most efficient way to schedule these courses to minimize the time it takes to complete all of them.\n", - "\n", - "2. **Detecting Cycles in Course Dependencies**: Modify the original problem to not just determine if you can finish all courses but also to identify the specific courses that form a cycle in the prerequisite dependencies." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/11. Graphs/3651. Number of Connected Components in an Undirected Graph.ipynb b/_build/jupyter_execute/11. Graphs/3651. Number of Connected Components in an Undirected Graph.ipynb deleted file mode 100644 index a2789c4..0000000 --- a/_build/jupyter_execute/11. Graphs/3651. Number of Connected Components in an Undirected Graph.ipynb +++ /dev/null @@ -1,230 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 3651. Number of Connected Components in an Undirected Graph\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Number of Connected Components in an Undirected Graph problem on LintCode, click here!](https://www.lintcode.com/problem/3651/)\n", - "\n", - "---\n", - "In this problem, there is an undirected graph with `n` nodes. There is also an `edges` array. Where `edges[i] = [a, b]` means that there is an edge between *node a* and *node b* in the graph.\n", - "\n", - "You need to return *the number of connected components in that graph*." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem at hand is to determine the number of connected components in an undirected graph. Here's a more detailed explanation of the problem:\n", - "\n", - "- You are given an undirected graph, which consists of nodes and edges. The graph may have multiple distinct connected components.\n", - "\n", - "- A connected component is a group of nodes within the graph where each node can be reached from every other node in the same component. In other words, there is a path between any two nodes in the same connected component, but there are no paths connecting nodes from different components.\n", - "\n", - "- Your task is to write a function that takes as input the number of nodes `n` and a list of edges `edges`, where each edge is represented as a pair of nodes `[a, b]` indicating an edge between node `a` and node `b`.\n", - "\n", - "- The goal is to determine the number of distinct connected components in the graph.\n", - "\n", - "- You need to implement an algorithm that can identify these connected components and count how many there are in the given graph.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "def countConnectedComponents(n, edges):\n", - " # Define a helper function for depth-first search (DFS).\n", - " def dfs(node):\n", - " if not visited[node]: # If the node has not been visited yet:\n", - " visited[node] = True # Mark it as visited.\n", - " for neighbor in graph[node]: # Explore all neighbors of the current node.\n", - " dfs(neighbor) # Recursively call DFS on the neighbor.\n", - "\n", - " # Create an empty adjacency list to represent the graph.\n", - " graph = [[] for _ in range(n)]\n", - "\n", - " # Initialize a boolean list to keep track of visited nodes.\n", - " visited = [False] * n\n", - "\n", - " # Populate the adjacency list with edges from the input.\n", - " for a, b in edges:\n", - " graph[a].append(b)\n", - " graph[b].append(a) # Since the graph is undirected, we add edges in both directions.\n", - "\n", - " # Initialize a counter to keep track of the number of connected components.\n", - " count = 0\n", - "\n", - " # Iterate through all nodes in the graph.\n", - " for i in range(n):\n", - " if not visited[i]: # If the node has not been visited:\n", - " count += 1 # Increment the count since we've found a new connected component.\n", - " dfs(i) # Start a depth-first search from the unvisited node to explore the component.\n", - "\n", - " return count" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The provided Python code calculates the number of connected components in an undirected graph. Here's a high-level explanation of how the code works:\n", - "\n", - "1. The `countConnectedComponents` function takes two arguments: `n` (the number of nodes in the graph) and `edges` (a list of edge pairs representing connections between nodes).\n", - "\n", - "2. Inside the function, there is a helper function called `dfs` (depth-first search), which is used to explore and mark nodes as visited.\n", - "\n", - "3. An empty adjacency list called `graph` is created to represent the graph. The `graph` is a list of lists where each element represents a node, and the list associated with each node contains its neighboring nodes.\n", - "\n", - "4. Another list called `visited` is created to keep track of visited nodes. Initially, all nodes are marked as not visited (`False`).\n", - "\n", - "5. The code populates the `graph` by iterating through the `edges` list and adding each edge to the adjacency list. Since the graph is undirected, both directions of each edge are added.\n", - "\n", - "6. A counter variable called `count` is initialized to keep track of the number of connected components.\n", - "\n", - "7. The code iterates through all nodes from `0` to `n-1`. For each node, it checks whether it has been visited yet. If it hasn't been visited, it means a new connected component is found. The counter `count` is incremented, and a depth-first search (DFS) is initiated from this unvisited node to explore the connected component.\n", - "\n", - "8. The `dfs` function recursively visits all nodes in the connected component, marking them as visited. It does this by checking each neighbor of the current node and recursively calling `dfs` on unvisited neighbors.\n", - "\n", - "9. After the loop through all nodes, the `count` variable contains the total number of connected components in the graph.\n", - "\n", - "10. The function returns the value of `count`, which represents the number of connected components.\n", - "\n", - "11. Two examples are provided at the end to demonstrate how to use the function with different inputs." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n" - ] - } - ], - "source": [ - "# Example 1\n", - "n1 = 3\n", - "edges1 = [[0, 1], [0, 2]]\n", - "print(countConnectedComponents(n1, edges1)) # Output: 1" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2\n" - ] - } - ], - "source": [ - "# Example 2\n", - "n2 = 6\n", - "edges2 = [[0, 1], [1, 2], [2, 3], [4, 5]]\n", - "print(countConnectedComponents(n2, edges2)) # Output: 2" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the code for counting the number of connected components in an undirected graph using depth-first search (DFS).\n", - "\n", - "**Time Complexity:**\n", - "- The code iterates through all nodes in the graph (from 0 to `n-1`).\n", - "- For each unvisited node, it initiates a depth-first search (DFS) from that node to explore the connected component.\n", - "- In the worst case, every node may belong to a separate connected component, and you perform a DFS for each node.\n", - "- The time complexity of the DFS for a single connected component is O(V + E), where V is the number of nodes in the component, and E is the number of edges.\n", - "- In the worst case, you perform O(n) DFS calls, each with its own O(V + E) complexity.\n", - "\n", - "So, the overall time complexity of the code is O(n * (V + E)). In the worst case, if the graph is connected (a single connected component), this simplifies to O(n * (n + m)), where m is the number of edges.\n", - "\n", - "**Space Complexity:**\n", - "- The main data structures used are the `graph` (adjacency list), `visited` (boolean array), and the recursive call stack for DFS.\n", - "- The `graph` has a space complexity of O(n + m), where n is the number of nodes, and m is the number of edges.\n", - "- The `visited` boolean array also has a space complexity of O(n) to keep track of whether nodes have been visited.\n", - "- The depth of the recursive call stack for DFS can go up to O(n) in the worst case, when all nodes are part of a single connected component.\n", - "\n", - "So, the overall space complexity of the code is O(n + m) for data structures and O(n) for the call stack. In the worst case, this simplifies to O(n + m).\n", - "\n", - "In summary, the time complexity is O(n * (V + E)), and the space complexity is O(n + m)." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Disconnected Components with Multiple Queries:** You are given an undirected graph with `n` nodes and `m` edges. Initially, the graph is disconnected, and you need to process `q` queries. Each query consists of adding an edge to connect two nodes. After each query, you need to output the number of connected components in the updated graph.\n", - "\n", - "2. **Maximum Size of Connected Components:** Given an undirected graph with `n` nodes and `m` edges, find the size of the largest connected component in the graph. Additionally, identify the nodes that belong to this largest component. You can assume there is at least one connected component in the graph.\n" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/11. Graphs/417. Pacific Atlantic Water Flow.ipynb b/_build/jupyter_execute/11. Graphs/417. Pacific Atlantic Water Flow.ipynb deleted file mode 100644 index c685b23..0000000 --- a/_build/jupyter_execute/11. Graphs/417. Pacific Atlantic Water Flow.ipynb +++ /dev/null @@ -1,255 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 417. Pacific Atlantic Water Flow\n", - "\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Pacific Atlantic Water Flow problem on LeetCode, click here!](https://leetcode.com/problems/pacific-atlantic-water-flow/)\n", - "\n", - "---\n", - "There is an `m x n` rectangular island that borders both the **Pacific Ocean** and **Atlantic Ocean**. The **Pacific Ocea**n touches the island's left and top edges, and the **Atlantic Ocean** touches the island's right and bottom edges.\n", - "\n", - "The island is partitioned into a grid of square cells. You are given an `m x n` integer matrix `heights` where `heights[r][c]` represents the **height above sea level** of the cell at coordinate `(r, c)`.\n", - "\n", - "The island receives a lot of rain, and the rain water can flow to neighboring cells directly north, south, east, and west if the neighboring cell's height is **less than or equal to** the current cell's height. Water can flow from any cell adjacent to an ocean into the ocean.\n", - "\n", - "Return *a **2D list** of grid coordinates `result` where $result[i] = [r_i, c_i]$ denotes that rain water can flow from cell $(r_i, c_i)$ to **both** the Pacific and Atlantic oceans*.\n", - "\n", - "**Constraints:**\n", - "- `m == heights.length`\n", - "- `n == heights[r].length`\n", - "- `1 <= m, n <= 200`\n", - "- 0 <= `heights[r][c]` <= $10^5$" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem at hand involves a scenario with a rectangular island surrounded by both the Pacific Ocean and the Atlantic Ocean. The Pacific Ocean is in contact with the island's left and top edges, while the Atlantic Ocean is in contact with the island's right and bottom edges. The goal is to determine which cells on the island can allow rainwater to flow to both the Pacific and Atlantic Oceans.\n", - "\n", - "Here are the key details and constraints of the problem:\n", - "\n", - "1. The island is divided into a grid of square cells.\n", - "\n", - "2. Each cell is represented by an integer value in a matrix `heights`. The value at `heights[r][c]` represents the height above sea level of the cell at coordinates `(r, c)` on the island.\n", - "\n", - "3. Rainwater can flow from a cell to neighboring cells directly north, south, east, or west only if the neighboring cell's height is less than or equal to the current cell's height.\n", - "\n", - "4. Water can flow from any cell adjacent to the ocean into the ocean. This means water can flow from cells on the edge of the island to the Pacific Ocean and the Atlantic Ocean.\n", - "\n", - "The task is to find and return a 2D list of grid coordinates where rainwater can flow from a cell to both the Pacific and Atlantic Oceans. In other words, you need to identify the cells that can send water to both the left and top edges (Pacific) and the right and bottom edges (Atlantic) of the island.\n", - "\n", - "The problem is solved by performing a depth-first search (DFS) starting from the ocean edges and marking the cells that can flow to each ocean. Then, the algorithm identifies cells that are reachable from both oceans and returns their coordinates as the result.\n", - "\n", - "The problem involves both traversal of the island and backtracking to find the solution, which makes it a classic graph traversal problem.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "from typing import List\n", - "\n", - "class Solution:\n", - " def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]:\n", - " # Check if the input matrix is empty\n", - " if not heights:\n", - " return []\n", - " \n", - " m, n = len(heights), len(heights[0])\n", - " \n", - " # Initialize boolean matrices to keep track of cells reachable from each ocean\n", - " pacific_reachable = [[False] * n for _ in range(m)]\n", - " atlantic_reachable = [[False] * n for _ in range(m)]\n", - " \n", - " # Depth-First Search (DFS) function to mark cells that can be reached from an ocean\n", - " def dfs(x, y, reachable):\n", - " if reachable[x][y]:\n", - " return\n", - " reachable[x][y] = True\n", - " for dx, dy in [(0, 1), (0, -1), (1, 0), (-1, 0)]:\n", - " new_x, new_y = x + dx, y + dy\n", - " if 0 <= new_x < m and 0 <= new_y < n and heights[new_x][new_y] >= heights[x][y]:\n", - " dfs(new_x, new_y, reachable)\n", - " \n", - " # Start DFS from the Pacific Ocean (left and top edges)\n", - " for i in range(m):\n", - " dfs(i, 0, pacific_reachable)\n", - " dfs(i, n - 1, atlantic_reachable)\n", - " \n", - " for j in range(n):\n", - " dfs(0, j, pacific_reachable)\n", - " dfs(m - 1, j, atlantic_reachable)\n", - " \n", - " result = []\n", - " \n", - " # Find cells that can flow to both the Pacific and Atlantic oceans\n", - " for i in range(m):\n", - " for j in range(n):\n", - " if pacific_reachable[i][j] and atlantic_reachable[i][j]:\n", - " result.append([i, j])\n", - " \n", - " return result" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The code defines a class called `Solution` with a method named `pacificAtlantic`. This method takes a 2D matrix `heights`, where each element represents the height above sea level of a cell on a rectangular island. The goal of the method is to find and return a list of grid coordinates (cells) from which rainwater can flow into both the Pacific and Atlantic Oceans.\n", - "\n", - "The code uses a Depth-First Search (DFS) algorithm to traverse the island, starting from the ocean edges, and marks cells that are reachable from either the Pacific or Atlantic Ocean. It does this by creating two boolean matrices, `pacific_reachable` and `atlantic_reachable`, to keep track of cells that can be reached from each ocean.\n", - "\n", - "The code iterates through the entire island, initiating DFS searches from the edges of the island. If a cell is reachable from an ocean (either Pacific or Atlantic), it is marked as reachable in the corresponding boolean matrix. The DFS function ensures that the traversal follows the rule that water can flow to a neighboring cell if the neighboring cell's height is less than or equal to the current cell's height.\n", - "\n", - "After marking all reachable cells from both oceans, the code then looks for cells that are reachable from both the Pacific and Atlantic Oceans. If a cell satisfies this condition, it is added to the `result` list.\n", - "\n", - "Finally, the code returns the `result` list, which contains the grid coordinates of cells from which rainwater can flow into both the Pacific and Atlantic Oceans.\n", - "\n", - "The code provides a solution to the problem of finding cells on the island where water can reach both oceans, demonstrating a traversal algorithm that explores the connectivity of cells on the island." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]]\n" - ] - } - ], - "source": [ - "# Example 1\n", - "heights1 = [\n", - " [1,2,2,3,5],\n", - " [3,2,3,4,4],\n", - " [2,4,5,3,1],\n", - " [6,7,1,4,5],\n", - " [5,1,1,2,4]\n", - "]\n", - "\n", - "solution = Solution()\n", - "print(solution.pacificAtlantic(heights1)) # Expected Output: [[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]]" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[0, 0]]\n" - ] - } - ], - "source": [ - "# Example 2\n", - "heights2 = [[1]]\n", - "print(solution.pacificAtlantic(heights2)) # Expected Output: [[0, 0]]" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Time Complexity:\n", - "The time complexity of this solution is O(m * n), where 'm' is the number of rows in the input matrix and 'n' is the number of columns. Here's a breakdown of the time complexity:\n", - "\n", - "1. Creating the `pacific_reachable` and `atlantic_reachable` matrices with dimensions m x n takes O(m * n) time.\n", - "\n", - "2. Initiating Depth-First Search (DFS) from the edges of the island takes O(m * n) time because it processes each cell once.\n", - "\n", - "3. The DFS function visits each cell at most once, and its time complexity is O(1) for each cell. The number of cells visited by the DFS in the worst case is m * n.\n", - "\n", - "4. The final step of identifying and appending cells to the result list takes O(m * n) time in the worst case.\n", - "\n", - "Overall, the time complexity is dominated by the DFS and is O(m * n).\n", - "\n", - "Space Complexity:\n", - "The space complexity of this solution is also O(m * n). Here's how the space is used:\n", - "\n", - "1. Two boolean matrices, `pacific_reachable` and `atlantic_reachable`, are created with dimensions m x n. Each matrix takes O(m * n) space, resulting in O(2 * m * n) space usage.\n", - "\n", - "2. The depth-first search (DFS) stack space during the recursive calls can go as deep as the diagonal of the grid, which is at most min(m, n). This additional space for the call stack is relatively small compared to the boolean matrices and can be considered O(min(m, n)).\n", - "\n", - "3. The `result` list stores the grid coordinates, and its size is determined by the number of cells that can flow to both oceans. In the worst case, this list can contain all m * n cells, so it takes O(m * n) space.\n", - "\n", - "The overall space complexity is the sum of these components, which is O(m * n) + O(min(m, n)) + O(m * n). In big O notation, we can simplify this to O(m * n)." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Optimization Challenge:** Modify the algorithm to find the maximum flow of water from any cell to both the Pacific and Atlantic Oceans. In other words, find the cell(s) that can send the most water to both oceans.\n", - "\n", - "2. **Efficiency Challenge:** Optimize the time and space complexity of the algorithm while maintaining correctness. Aim to reduce both time and space complexity as much as possible." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/12. Advanced Graphs/892. Alien Dictionary.ipynb b/_build/jupyter_execute/12. Advanced Graphs/892. Alien Dictionary.ipynb deleted file mode 100644 index 19db846..0000000 --- a/_build/jupyter_execute/12. Advanced Graphs/892. Alien Dictionary.ipynb +++ /dev/null @@ -1,250 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 892. Alien Dictionary\n", - "\n", - "**Difficulty:** Hard\n", - "\n", - "**Link to Problem:** [To see the Alien Dictionary problem on LintCode, click here!](https://www.lintcode.com/problem/892/)\n", - "\n", - "---\n", - "\n", - "There is a new alien language which uses the latin alphabet. However, the order among letters are unknown to you. You receive a list of **non-empty** words from the dictionary, where words are **sorted lexicographically by the rules of this new language**. Derive the order of letters in this language.\n", - "\n", - "**Constraints:**\n", - "- You may assume all letters are in lowercase.\n", - "- The dictionary is invalid, if string a is prefix of string b and b is appear before a.\n", - "- If the order is invalid, return an empty string.\n", - "- There may be multiple valid order of letters, return the smallest in normal lexicographical order.\n", - "- The letters in **one** string are of the same rank by default and are sorted in Human dictionary order." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem at hand involves determining the order of letters in a new alien language that uses the Latin alphabet. However, the order of letters in this alien language is unknown. To solve this problem, we are given a list of non-empty words from the dictionary, where the words are sorted lexicographically based on the rules of the alien language. The goal is to derive the correct order of letters in this new language.\n", - "\n", - "Here's a more detailed explanation of the problem:\n", - "\n", - "1. The alphabet: The new alien language uses the Latin alphabet, which consists of lowercase letters.\n", - "\n", - "2. Dictionary: We are provided with a list of non-empty words. These words are sorted in lexicographical order based on the rules of the alien language. The order of letters in the words reflects the correct order in the new language.\n", - "\n", - "3. Invalid order: The problem specifies that the dictionary is considered invalid if there exists a situation where one string 'a' is a prefix of another string 'b,' and 'b' appears before 'a' in the dictionary. This condition ensures that there are no inconsistencies in the order of letters.\n", - "\n", - "4. Multiple valid orders: It's possible that there are multiple valid orders of letters that satisfy the provided dictionary. However, we are instructed to return the smallest valid order in normal lexicographical order.\n", - "\n", - "To solve this problem, you need to analyze the given list of words and determine the correct order of letters in the alien language while adhering to the specified constraints. You should return the order as a string in lexicographical order if it's valid, and an empty string if the order is invalid.\n", - "\n", - "The key to solving this problem is to construct a directed graph of letter relationships based on the order information provided by the words in the dictionary. Then, perform a topological sort on this graph to derive the order of letters, ensuring that the order is consistent and valid according to the given constraints.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "from collections import defaultdict, deque\n", - "\n", - "def alienOrder(words):\n", - " # Create an adjacency list to represent the graph\n", - " graph = defaultdict(list)\n", - " \n", - " # Create a dictionary to store the in-degrees of each letter\n", - " in_degree = {}\n", - " \n", - " # Initialize in-degrees to 0 for all letters\n", - " for word in words:\n", - " for char in word:\n", - " if char not in in_degree:\n", - " in_degree[char] = 0\n", - " \n", - " # Build the graph and update in-degrees\n", - " for i in range(1, len(words)):\n", - " word1, word2 = words[i-1], words[i]\n", - " min_length = min(len(word1), len(word2))\n", - " \n", - " # Compare characters in the two words\n", - " j = 0\n", - " while j < min_length and word1[j] == word2[j]:\n", - " j += 1\n", - " \n", - " if j < min_length:\n", - " # If word1[j] is lexicographically before word2[j], add an edge\n", - " graph[word1[j]].append(word2[j])\n", - " in_degree[word2[j]] += 1\n", - " \n", - " # Break the loop to avoid further comparisons\n", - " break\n", - " \n", - " # Perform topological sorting using Kahn's algorithm\n", - " result = []\n", - " queue = deque([char for char in in_degree if in_degree[char] == 0])\n", - " \n", - " while queue:\n", - " char = queue.popleft()\n", - " result.append(char)\n", - " \n", - " for neighbor in graph[char]:\n", - " in_degree[neighbor] -= 1\n", - " if in_degree[neighbor] == 0:\n", - " queue.append(neighbor)\n", - " \n", - " # Check if there is a valid order\n", - " if len(result) < len(in_degree):\n", - " return \"\"\n", - " \n", - " return \"\".join(result)" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The code is designed to determine the order of letters in an unknown alien language that uses the Latin alphabet. It takes a list of non-empty words from a dictionary as input, where the words are sorted lexicographically based on the rules of this alien language.\n", - "\n", - "The code follows these main steps:\n", - "\n", - "1. Create a data structure to represent the graph of letters and their relationships in the alien language. It uses a defaultdict to store a list of letters that come after each letter. Additionally, it uses a dictionary called `in_degree` to keep track of the in-degrees (the number of letters that precede a letter) for each letter.\n", - "\n", - "2. Initialize the in-degrees of all letters to 0. This is done by iterating through all the words and characters in the words, adding each character to the `in_degree` dictionary with an initial in-degree of 0.\n", - "\n", - "3. Build the graph by comparing adjacent words in the dictionary. For each pair of adjacent words, the code finds the first differing character between the two words. If such a character exists, it means there's an order relationship between the letters represented by these characters. The code updates the graph and in-degrees accordingly.\n", - "\n", - "4. After constructing the graph, the code performs a topological sorting of the letters using Kahn's algorithm. It starts by initializing an empty result list and a queue containing letters with in-degrees of 0. The algorithm repeatedly removes a letter with an in-degree of 0 from the queue, adds it to the result list, and updates the in-degrees of its neighbors. This process continues until the queue is empty.\n", - "\n", - "5. Finally, the code checks if the topological sorting was successful by comparing the length of the result list with the number of unique letters in the input. If the lengths differ, it means there's a cycle in the graph, and the order is invalid. In such a case, an empty string is returned. Otherwise, the result list is joined together to form the smallest order of letters in normal lexicographical order, and it is returned as the output.\n", - "\n", - "The code provides a way to determine the order of letters in the alien language while handling various edge cases, including checking for invalid order conditions." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "wrtef\n" - ] - } - ], - "source": [ - "# Example 1\n", - "words1 = [\"wrt\", \"wrf\", \"er\", \"ett\", \"rftt\"]\n", - "print(alienOrder(words1)) # Output: \"wertf\"" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "zx\n" - ] - } - ], - "source": [ - "# Example 2\n", - "words2 = [\"z\", \"x\"]\n", - "print(alienOrder(words2)) # Output: \"zx\"" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code for determining the order of letters in an alien language.\n", - "\n", - "Time Complexity:\n", - "1. Building the graph: The code iterates through the list of words and compares adjacent words. In the worst case, where all words have the same prefix, it takes O(N) time to build the graph, where N is the total number of characters in all the words.\n", - "2. Topological sorting: Performing a topological sort on the graph takes O(V + E) time, where V is the number of unique letters (vertices) and E is the number of relationships between letters (edges) in the graph.\n", - "\n", - "Overall, the time complexity is O(N + V + E), where N is the total number of characters in the words, V is the number of unique letters, and E is the number of order relationships between letters.\n", - "\n", - "Space Complexity:\n", - "1. Graph and In-degrees: The code uses data structures to represent the graph and in-degrees. The space complexity for these data structures is O(V + E), where V is the number of unique letters, and E is the number of order relationships between letters in the words.\n", - "2. Result List: The result list stores the order of letters, which can have a maximum size of V, where V is the number of unique letters.\n", - "3. Queue: The space used by the queue during topological sorting is also O(V).\n", - "\n", - "Overall, the space complexity is O(V + E) due to the data structures used for graph representation and the space needed for storing the result and the queue.\n", - "\n", - "In the worst case, where there are many unique letters and many order relationships, the space complexity is dominated by the number of unique letters and their relationships.\n", - "\n", - "In summary, the time complexity of the code is O(N + V + E), and the space complexity is O(V + E). The actual performance will depend on the specific input data, such as the number of unique letters and the relationships between them in the alien language." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Multiple Valid Orders**: Extend the problem to handle cases where there are multiple valid orders of letters in the alien language. Modify the code to return all valid orders instead of just one. Be mindful of performance.\n", - "\n", - "2. **Detect Invalid Dictionary**: Given a dictionary of words, write a function to detect whether the dictionary is valid or not based on the constraints mentioned in the problem statement." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/13. One-D Dynamic Programming/198. House Robber.ipynb b/_build/jupyter_execute/13. One-D Dynamic Programming/198. House Robber.ipynb deleted file mode 100644 index 9539363..0000000 --- a/_build/jupyter_execute/13. One-D Dynamic Programming/198. House Robber.ipynb +++ /dev/null @@ -1,212 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# House Robber\n", - "**Difficulty:** Medium\n", - "\n", - "---\n", - "You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security systems connected and **it will automatically contact the police if two adjacent houses were broken into on the same night.**\n", - "\n", - "Given an integer array `nums` representing the amount of money of each house, return *the maximum amount of money you can rob tonight **without alerting the police**.*\n", - "\n", - "**Constraints:**\n", - "- `1 <= nums.length <= 100`\n", - "- `0 <= nums[i] <= 400`" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is a classic dynamic programming challenge known as the \"House Robber\" problem. The scenario is that you are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, but the constraint is that adjacent houses have security systems connected. If two adjacent houses are broken into on the same night, the security systems will automatically contact the police.\n", - "\n", - "The goal is to determine the maximum amount of money you can rob tonight without alerting the police. You need to find a strategy to maximize your earnings while avoiding robbing two adjacent houses.\n", - "\n", - "The input to the problem is an array `nums`, where `nums[i]` represents the amount of money in the `i`-th house. The task is to return the maximum amount of money that can be robbed without triggering the security system.\n", - "\n", - "For example:\n", - "```\n", - "Input: nums = [1,2,3,1]\n", - "Output: 4\n", - "Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).\n", - "Total amount you can rob = 1 + 3 = 4.\n", - "\n", - "Input: nums = [2,7,9,3,1]\n", - "Output: 12\n", - "Explanation: Rob house 1 (money = 2), rob house 3 (money = 9), and rob house 5 (money = 1).\n", - "Total amount you can rob = 2 + 9 + 1 = 12.\n", - "```\n", - "\n", - "The challenge involves designing an algorithm to efficiently solve this problem and find the optimal strategy for robbing houses to maximize the stolen money while adhering to the constraint of not robbing adjacent houses. The provided solution utilizes dynamic programming to achieve this.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "from typing import List\n", - "\n", - "class Solution:\n", - " def rob(self, nums: List[int]) -> int:\n", - " # Initialize variables to keep track of the maximum amount of money robbed at the previous and current houses\n", - " prev, curr = 0, 0\n", - "\n", - " # Iterate through the houses\n", - " for n in nums:\n", - " # Calculate the maximum amount of money that can be robbed at the current house\n", - " # It is the maximum of either robbing the current house and the money robbed at the house before the previous one (prev),\n", - " # or skipping the current house and taking the maximum amount from the previous house (curr)\n", - " temp = max(n + prev, curr)\n", - "\n", - " # Update the variables for the next iteration\n", - " prev, curr = curr, temp\n", - "\n", - " # The final result is the maximum amount of money that can be robbed at the last house\n", - " return curr" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The provided code is a Python implementation of the \"House Robber\" problem using a dynamic programming approach. It's part of a class `Solution` and includes a method `rob` that takes a list of integers `nums` as input and returns the maximum amount of money that can be robbed without alerting the police.\n", - "\n", - "The key idea of the algorithm is to maintain two variables, `prev` and `curr`, which represent the maximum amount of money that can be robbed up to the previous house and the current house, respectively. The algorithm iterates through the houses, updating these variables based on the maximum amount that can be robbed at the current house, considering the constraint of not robbing adjacent houses.\n", - "\n", - "The loop calculates a temporary variable `temp` that represents the maximum amount of money that can be robbed at the current house. It considers two scenarios: either robbing the current house and adding the money robbed at the house before the previous one (`n + prev`), or skipping the current house and taking the maximum amount from the previous house (`curr`). The maximum of these two scenarios is assigned to `temp`.\n", - "\n", - "The `prev` and `curr` variables are then updated for the next iteration. `prev` is set to the previous value of `curr`, and `curr` is set to the calculated `temp`.\n", - "\n", - "The final result is the value stored in the `curr` variable, representing the maximum amount of money that can be robbed at the last house. This value is returned as the result of the `rob` method.\n", - "\n", - "The provided test cases at the end demonstrate the usage of the `rob` method with different input arrays." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "f12c5a63-b811-4be7-83c2-34ee396b546c", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "sol = Solution()\n", - "\n", - "nums1 = [1, 2, 3, 1]\n", - "print(sol.rob(nums1)) # Output: 4" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "12\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "nums2 = [2, 7, 9, 3, 1]\n", - "print(sol.rob(nums2)) # Output: 12" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code.\n", - "\n", - "### Time Complexity:\n", - "\n", - "The time complexity of the code is O(n), where n is the number of houses. The algorithm iterates through the array once, and in each iteration, it performs constant time operations. The loop runs for each house, and the number of operations inside the loop is independent of the input size. Therefore, the overall time complexity is linear, O(n).\n", - "\n", - "### Space Complexity:\n", - "\n", - "The space complexity is O(1), constant space. The algorithm uses only a constant amount of extra space regardless of the input size. The variables `prev`, `curr`, and `temp` are the only additional variables used, and they do not depend on the size of the input array. Thus, the space complexity is constant, O(1).\n", - "\n", - "In summary:\n", - "- Time Complexity: O(n)\n", - "- Space Complexity: O(1)" - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Variation with Maximum Number of Houses to Rob:** Modify the problem to include an additional constraint: you are allowed to rob at most 'k' houses without triggering the alarm. Find the maximum amount you can rob under this new constraint.\n", - "\n", - "2. **Robbing in a Circular Street:** Extend the problem to a circular street where the first and last houses are adjacent. You cannot rob both the first and last houses simultaneously. Find the maximum amount you can rob in this circular setting.\n", - "\n", - "\n", - "**Link to Problem:** [To see the House Robber problem on LeetCode, click here!](https://leetcode.com/problems/house-robber/description/)\n" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/13. One-D Dynamic Programming/213. House Robber II.ipynb b/_build/jupyter_execute/13. One-D Dynamic Programming/213. House Robber II.ipynb deleted file mode 100644 index d210017..0000000 --- a/_build/jupyter_execute/13. One-D Dynamic Programming/213. House Robber II.ipynb +++ /dev/null @@ -1,243 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# House Robber II\n", - "**Difficulty:** Medium\n", - "\n", - "---\n", - "You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. All houses at this place are **arranged in a circle**. That means the first house is the neighbor of the last one. Meanwhile, adjacent houses have a security system connected, and **it will automatically contact the police if two adjacent houses were broken into on the same night**.\n", - "\n", - "Given an integer array `nums` representing the amount of money of each house, return *the maximum amount of money you can rob tonight without alerting the police*.\n", - "\n", - "**Constraints:**\n", - "- `1 <= nums.length <= 100`\n", - "- `0 <= nums[i] <= 1000`" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "Certainly! The problem statement describes a scenario where you are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. However, there is a security system in place: adjacent houses have a security system connected, and it will automatically contact the police if two adjacent houses are broken into on the same night.\n", - "\n", - "The twist in this problem is that the houses are arranged in a circle. That means the first house is the neighbor of the last one. So, robbing the first house has implications for the last house, and vice versa.\n", - "\n", - "The goal is to find the maximum amount of money you can rob tonight without alerting the police. You need to implement a function that takes an integer array `nums` representing the amount of money in each house and returns the maximum amount of money that can be robbed without triggering the security system.\n", - "\n", - "Here are a few examples to illustrate the problem:\n", - "\n", - "1. **Example 1:**\n", - " ```python\n", - " Input: nums = [2, 3, 2]\n", - " Output: 3\n", - " Explanation: You cannot rob house 1 (money = 2) and then rob house 3 (money = 2) because they are adjacent houses. The optimal strategy is to rob house 2 (money = 3).\n", - " ```\n", - "\n", - "2. **Example 2:**\n", - " ```python\n", - " Input: nums = [1, 2, 3, 1]\n", - " Output: 4\n", - " Explanation: Robbing house 1 (money = 1) and then robbing house 3 (money = 3) results in a total amount of 4. Robbing house 2 is skipped to avoid alerting the police.\n", - " ```\n", - "\n", - "3. **Example 3:**\n", - " ```python\n", - " Input: nums = [1, 2, 3]\n", - " Output: 3\n", - " Explanation: Since the houses are in a circle, you can choose either house 1, 2, or 3. The optimal strategy is to rob house 3 for a total amount of 3.\n", - " ```\n", - "\n", - "The constraints for the problem are that the length of the `nums` array is between 1 and 100, and the amount of money in each house (`nums[i]`) is between 0 and 1000.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "from typing import List\n", - "\n", - "class Solution:\n", - " def rob(self, nums: List[int]) -> int:\n", - " def simple_rob(nums):\n", - " # Helper function for basic house robbery problem\n", - " prev, curr = 0, 0\n", - " for num in nums:\n", - " # Calculate the maximum amount of money that can be robbed\n", - " # without alerting the police for each house\n", - " prev, curr = curr, max(prev + num, curr)\n", - " return curr\n", - "\n", - " # Check the base cases where the length of nums is 1 or 2\n", - " if len(nums) == 1:\n", - " return nums[0]\n", - " elif len(nums) == 2:\n", - " return max(nums[0], nums[1])\n", - "\n", - " # Case 1: First house is robbed, last house is not\n", - " case1 = simple_rob(nums[:-1])\n", - "\n", - " # Case 2: First house is not robbed, last house is\n", - " case2 = simple_rob(nums[1:])\n", - "\n", - " # Maximum of the two cases\n", - " return max(case1, case2)" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The provided code defines a class `Solution` with a method `rob`, which aims to determine the maximum amount of money a professional robber can steal from houses arranged in a circle without alerting the police. Each house contains a certain amount of money, and adjacent houses have a security system that triggers if both are robbed on the same night.\n", - "\n", - "The code uses dynamic programming to solve the problem efficiently. It contains a helper function `simple_rob` that computes the maximum amount of money that can be robbed from a linear arrangement of houses. The main method `rob` handles the circular arrangement by considering two cases: robbing the first house and not robbing the last, and not robbing the first house and robbing the last. The result is the maximum of these two cases.\n", - "\n", - "The class is instantiated as `solution`, and the `rob` method is applied to three different scenarios (test cases) to demonstrate its functionality. The final output represents the maximum amount of money the robber can steal without triggering the security system." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "f12c5a63-b811-4be7-83c2-34ee396b546c", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "\n", - "# Create an instance of the Solution class\n", - "solution = Solution()\n", - "\n", - "nums1 = [2, 3, 2]\n", - "print(solution.rob(nums1)) # Output: 3" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "nums2 = [1, 2, 3, 1]\n", - "print(solution.rob(nums2)) # Output: 4" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "e6e1554f-ae77-410c-8af2-e59e5428166c", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "nums3 = [1, 2, 3]\n", - "print(solution.rob(nums3)) # Output: 3" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "### Time Complexity:\n", - "The time complexity is primarily determined by the `simple_rob` helper function, which has a time complexity of O(N), where N is the number of houses in the input array. The main `rob` function calls `simple_rob` twice, once for the case of robbing the first house and not robbing the last, and once for the case of not robbing the first house and robbing the last. Therefore, the overall time complexity is O(N).\n", - "\n", - "### Space Complexity:\n", - "The space complexity is O(1) because the space used by the algorithm is constant, regardless of the size of the input array. The only variables used are `prev` and `curr` in the `simple_rob` function, which represent the previous and current maximum amounts of money that can be robbed without alerting the police. These variables are updated iteratively, and no additional data structures are used that scale with the input size. Therefore, the space complexity is constant, or O(1).\n", - "\n", - "In summary:\n", - "- Time Complexity: O(N)\n", - "- Space Complexity: O(1)" - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Optimization Challenge:** Optimize the space complexity of the solution. Can you solve the problem with O(1) space complexity without sacrificing the time complexity?\n", - "\n", - "2. **Circular Robbery Variations:** Consider variations of the circular house robbery problem, such as allowing the robber to skip a certain number of houses or restricting the number of consecutive houses that can be robbed. Modify the solution to accommodate these variations.\n", - "\n", - "**Link to Problem:** [To see the House Robber II problem on LeetCode, click here!](https://leetcode.com/problems/house-robber-ii/)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/13. One-D Dynamic Programming/70. Climbing Stairs.ipynb b/_build/jupyter_execute/13. One-D Dynamic Programming/70. Climbing Stairs.ipynb deleted file mode 100644 index 32c5da3..0000000 --- a/_build/jupyter_execute/13. One-D Dynamic Programming/70. Climbing Stairs.ipynb +++ /dev/null @@ -1,204 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 70. Climbing Stairs\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Climbing Stairs problem on LeetCode, click here!](https://leetcode.com/problems/climbing-stairs/)\n", - "\n", - "---\n", - "You are climbing a staircase. It takes `n` steps to reach the top.\n", - "\n", - "Each time you can either climb `1` or `2` steps. In how many distinct ways can you climb to the top?\n", - "\n", - "**Constraints:**\n", - "- `1 <= n <= 45`" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The \"Climbing Stairs\" problem is a classic algorithmic problem that asks you to find the number of distinct ways to climb a staircase with a given number of steps. Here's the problem statement:\n", - "\n", - "You are given a staircase with 'n' steps. Each time you can either climb 1 step or 2 steps. You need to find out how many distinct ways there are to reach the top of the staircase.\n", - "\n", - "For example, if 'n' is 2, there are two ways to climb to the top:\n", - "\n", - "1. Climbing two steps at once.\n", - "2. Climbing one step, and then another step.\n", - "\n", - "If 'n' is 3, there are three ways:\n", - "\n", - "1. Climbing one step, then one step, and finally one step.\n", - "2. Climbing one step, then two steps.\n", - "3. Climbing two steps, then one step.\n", - "\n", - "The problem essentially asks you to find a solution that counts the possible combinations of 1-step and 2-step climbs that can be taken to reach the top of the staircase. It's a classic example of a dynamic programming problem where you can break it down into smaller subproblems and build a solution incrementally, as shown in the code I provided earlier.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": {}, - "outputs": [], - "source": [ - "class Solution:\n", - " def climbStairs(self, n: int) -> int:\n", - " # If there are 1 or 2 steps, there are exactly n ways to reach the top.\n", - " if n <= 2:\n", - " return n\n", - "\n", - " # Create an array to store the number of ways to reach each step.\n", - " dp = [0] * (n + 1)\n", - "\n", - " # There is one way to reach the first step (base case).\n", - " dp[1] = 1\n", - "\n", - " # There are two ways to reach the second step (base case).\n", - " dp[2] = 2\n", - "\n", - " # Calculate the number of ways to reach each step from the previous steps.\n", - " for i in range(3, n + 1):\n", - " # The number of ways to reach step 'i' is the sum of the ways to reach\n", - " # the previous two steps, as you can take 1 or 2 steps at a time.\n", - " dp[i] = dp[i - 1] + dp[i - 2]\n", - "\n", - " # The result is the number of ways to reach the top, which is stored in dp[n].\n", - " return dp[n]" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The code defines a class `Solution` with a method `climbStairs` that takes an integer `n` as input and returns the number of distinct ways to climb a staircase with `n` steps.\n", - "\n", - "1. If `n` is 1 or 2, the function returns `n` directly because there are only 1 or 2 distinct ways to reach the top in those cases.\n", - "\n", - "2. For `n` greater than 2, the code uses dynamic programming to calculate the number of ways to reach each step. It creates an array `dp` of length `n + 1` to store these values.\n", - "\n", - "3. The `dp[1]` and `dp[2]` are initialized to 1 and 2, respectively. This is because there is only one way to reach the first step (by taking 1 step), and there are two ways to reach the second step (by taking 2 steps or two 1-step climbs).\n", - "\n", - "4. The code then uses a loop to fill in the `dp` array for steps 3 and above. For each step `i` from 3 to `n`, it calculates the number of ways to reach that step by adding the number of ways to reach the previous two steps, as you can either take 1 step or 2 steps at a time.\n", - "\n", - "5. Finally, the function returns the value stored in `dp[n]`, which represents the total number of distinct ways to climb the staircase with `n` steps." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "f12c5a63-b811-4be7-83c2-34ee396b546c", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Example 1 - Input: n = 2, Output: 2\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "n = 2\n", - "solution = Solution()\n", - "print(f\"Example 1 - Input: n = {n}, Output: {solution.climbStairs(n)}\") # Output should be 2" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Example 2 - Input: n = 3, Output: 3\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "n = 3\n", - "print(f\"Example 2 - Input: n = {n}, Output: {solution.climbStairs(n)}\") # Output should be 3\n" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Time Complexity:\n", - "The time complexity of the solution is O(n) because we use a single for loop that iterates from 3 to n to fill the `dp` array. In each iteration, we perform constant time operations (addition and assignment). Therefore, the time complexity is linear with respect to the input value `n`.\n", - "\n", - "Space Complexity:\n", - "The space complexity of the solution is O(n) as well. We use an array `dp` of length `n + 1` to store the number of ways to reach each step. The size of this array is directly proportional to the input value `n`, which makes the space complexity linear in terms of `n`. The rest of the variables used in the function (e.g., `i`) occupy constant space and do not contribute significantly to the overall space complexity.\n", - "\n", - "In summary, the time complexity is O(n), and the space complexity is O(n) for this dynamic programming solution to the \"Climbing Stairs\" problem." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Generalized Step Sizes**: Instead of being limited to 1 step or 2 steps, consider a scenario where you can take steps of sizes `[1, 2, 3]`. Implement a function that calculates the number of ways to climb the staircase with these different step sizes.\n", - "\n", - "2. **Minimize Steps**: Given an integer `n`, find the minimum number of steps required to reach the top of the staircase. Return both the minimum number of steps and the specific sequence of steps taken." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/_build/jupyter_execute/Book.ipynb b/_build/jupyter_execute/Book.ipynb deleted file mode 100644 index 6c891d7..0000000 --- a/_build/jupyter_execute/Book.ipynb +++ /dev/null @@ -1,914 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: pip in /usr/local/python/3.10.8/lib/python3.10/site-packages (23.3.1)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: jupyter-book in /usr/local/python/3.10.8/lib/python3.10/site-packages (0.15.1)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: click<9,>=7.1 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (8.1.7)\r\n", - "Requirement already satisfied: docutils<0.19,>=0.15 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (0.18.1)\r\n", - "Requirement already satisfied: Jinja2 in /home/codespace/.local/lib/python3.10/site-packages (from jupyter-book) (3.1.2)\r\n", - "Requirement already satisfied: jsonschema<5 in /home/codespace/.local/lib/python3.10/site-packages (from jupyter-book) (4.19.1)\r\n", - "Requirement already satisfied: linkify-it-py~=2.0.0 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (2.0.2)\r\n", - "Requirement already satisfied: myst-nb~=0.17.1 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (0.17.2)\r\n", - "Requirement already satisfied: pyyaml in /home/codespace/.local/lib/python3.10/site-packages (from jupyter-book) (6.0.1)\r\n", - "Requirement already satisfied: sphinx<6,>=4 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (5.0.2)\r\n", - "Requirement already satisfied: sphinx-comments in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (0.0.3)\r\n", - "Requirement already satisfied: sphinx-copybutton in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (0.5.2)\r\n", - "Requirement already satisfied: sphinx-external-toc~=0.3.1 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (0.3.1)\r\n", - "Requirement already satisfied: sphinx-jupyterbook-latex~=0.5.2 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (0.5.2)\r\n", - "Requirement already satisfied: sphinx-design~=0.3.0 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (0.3.0)\r\n", - "Requirement already satisfied: sphinx-thebe~=0.2.0 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (0.2.1)\r\n", - "Requirement already satisfied: sphinx-book-theme~=1.0.0 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (1.0.1)\r\n", - "Requirement already satisfied: sphinx_togglebutton in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (0.3.2)\r\n", - "Requirement already satisfied: sphinxcontrib-bibtex<=2.5.0,>=2.2.0 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (2.5.0)\r\n", - "Requirement already satisfied: sphinx-multitoc-numbering~=0.1.3 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (0.1.3)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: attrs>=22.2.0 in /home/codespace/.local/lib/python3.10/site-packages (from jsonschema<5->jupyter-book) (23.1.0)\r\n", - "Requirement already satisfied: jsonschema-specifications>=2023.03.6 in /home/codespace/.local/lib/python3.10/site-packages (from jsonschema<5->jupyter-book) (2023.7.1)\r\n", - "Requirement already satisfied: referencing>=0.28.4 in /home/codespace/.local/lib/python3.10/site-packages (from jsonschema<5->jupyter-book) (0.30.2)\r\n", - "Requirement already satisfied: rpds-py>=0.7.1 in /home/codespace/.local/lib/python3.10/site-packages (from jsonschema<5->jupyter-book) (0.10.6)\r\n", - "Requirement already satisfied: uc-micro-py in /usr/local/python/3.10.8/lib/python3.10/site-packages (from linkify-it-py~=2.0.0->jupyter-book) (1.0.2)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: importlib_metadata in /usr/local/python/3.10.8/lib/python3.10/site-packages (from myst-nb~=0.17.1->jupyter-book) (6.8.0)\r\n", - "Requirement already satisfied: ipython in /home/codespace/.local/lib/python3.10/site-packages (from myst-nb~=0.17.1->jupyter-book) (8.16.1)\r\n", - "Requirement already satisfied: jupyter-cache<0.7,>=0.5 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from myst-nb~=0.17.1->jupyter-book) (0.6.1)\r\n", - "Requirement already satisfied: nbclient in /usr/local/python/3.10.8/lib/python3.10/site-packages (from myst-nb~=0.17.1->jupyter-book) (0.7.4)\r\n", - "Requirement already satisfied: myst-parser~=0.18.0 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from myst-nb~=0.17.1->jupyter-book) (0.18.1)\r\n", - "Requirement already satisfied: nbformat~=5.0 in /home/codespace/.local/lib/python3.10/site-packages (from myst-nb~=0.17.1->jupyter-book) (5.9.2)\r\n", - "Requirement already satisfied: typing-extensions in /home/codespace/.local/lib/python3.10/site-packages (from myst-nb~=0.17.1->jupyter-book) (4.8.0)\r\n", - "Requirement already satisfied: ipykernel in /home/codespace/.local/lib/python3.10/site-packages (from myst-nb~=0.17.1->jupyter-book) (6.25.2)\r\n", - "Requirement already satisfied: sphinxcontrib-applehelp in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sphinx<6,>=4->jupyter-book) (1.0.7)\r\n", - "Requirement already satisfied: sphinxcontrib-devhelp in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sphinx<6,>=4->jupyter-book) (1.0.5)\r\n", - "Requirement already satisfied: sphinxcontrib-jsmath in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sphinx<6,>=4->jupyter-book) (1.0.1)\r\n", - "Requirement already satisfied: sphinxcontrib-htmlhelp>=2.0.0 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sphinx<6,>=4->jupyter-book) (2.0.4)\r\n", - "Requirement already satisfied: sphinxcontrib-serializinghtml>=1.1.5 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sphinx<6,>=4->jupyter-book) (1.1.9)\r\n", - "Requirement already satisfied: sphinxcontrib-qthelp in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sphinx<6,>=4->jupyter-book) (1.0.6)\r\n", - "Requirement already satisfied: Pygments>=2.0 in /home/codespace/.local/lib/python3.10/site-packages (from sphinx<6,>=4->jupyter-book) (2.16.1)\r\n", - "Requirement already satisfied: snowballstemmer>=1.1 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sphinx<6,>=4->jupyter-book) (2.2.0)\r\n", - "Requirement already satisfied: babel>=1.3 in /home/codespace/.local/lib/python3.10/site-packages (from sphinx<6,>=4->jupyter-book) (2.13.0)\r\n", - "Requirement already satisfied: alabaster<0.8,>=0.7 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sphinx<6,>=4->jupyter-book) (0.7.13)\r\n", - "Requirement already satisfied: imagesize in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sphinx<6,>=4->jupyter-book) (1.4.1)\r\n", - "Requirement already satisfied: requests>=2.5.0 in /home/codespace/.local/lib/python3.10/site-packages (from sphinx<6,>=4->jupyter-book) (2.31.0)\r\n", - "Requirement already satisfied: packaging in /home/codespace/.local/lib/python3.10/site-packages (from sphinx<6,>=4->jupyter-book) (23.2)\r\n", - "Requirement already satisfied: MarkupSafe>=2.0 in /home/codespace/.local/lib/python3.10/site-packages (from Jinja2->jupyter-book) (2.1.3)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: pydata-sphinx-theme>=0.13.3 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sphinx-book-theme~=1.0.0->jupyter-book) (0.14.3)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: pybtex>=0.24 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sphinxcontrib-bibtex<=2.5.0,>=2.2.0->jupyter-book) (0.24.0)\r\n", - "Requirement already satisfied: pybtex-docutils>=1.0.0 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sphinxcontrib-bibtex<=2.5.0,>=2.2.0->jupyter-book) (1.0.3)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: setuptools in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sphinx_togglebutton->jupyter-book) (68.0.0)\r\n", - "Requirement already satisfied: wheel in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sphinx_togglebutton->jupyter-book) (0.41.3)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: sqlalchemy<3,>=1.3.12 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-cache<0.7,>=0.5->myst-nb~=0.17.1->jupyter-book) (2.0.23)\r\n", - "Requirement already satisfied: tabulate in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-cache<0.7,>=0.5->myst-nb~=0.17.1->jupyter-book) (0.9.0)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: markdown-it-py<3.0.0,>=1.0.0 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from myst-parser~=0.18.0->myst-nb~=0.17.1->jupyter-book) (2.2.0)\r\n", - "Requirement already satisfied: mdit-py-plugins~=0.3.1 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from myst-parser~=0.18.0->myst-nb~=0.17.1->jupyter-book) (0.3.5)\r\n", - "Requirement already satisfied: jupyter-client>=6.1.12 in /home/codespace/.local/lib/python3.10/site-packages (from nbclient->myst-nb~=0.17.1->jupyter-book) (8.4.0)\r\n", - "Requirement already satisfied: jupyter-core!=5.0.*,>=4.12 in /home/codespace/.local/lib/python3.10/site-packages (from nbclient->myst-nb~=0.17.1->jupyter-book) (5.4.0)\r\n", - "Requirement already satisfied: traitlets>=5.3 in /home/codespace/.local/lib/python3.10/site-packages (from nbclient->myst-nb~=0.17.1->jupyter-book) (5.11.2)\r\n", - "Requirement already satisfied: fastjsonschema in /home/codespace/.local/lib/python3.10/site-packages (from nbformat~=5.0->myst-nb~=0.17.1->jupyter-book) (2.18.1)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: latexcodec>=1.0.4 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from pybtex>=0.24->sphinxcontrib-bibtex<=2.5.0,>=2.2.0->jupyter-book) (2.0.1)\r\n", - "Requirement already satisfied: six in /home/codespace/.local/lib/python3.10/site-packages (from pybtex>=0.24->sphinxcontrib-bibtex<=2.5.0,>=2.2.0->jupyter-book) (1.16.0)\r\n", - "Requirement already satisfied: beautifulsoup4 in /home/codespace/.local/lib/python3.10/site-packages (from pydata-sphinx-theme>=0.13.3->sphinx-book-theme~=1.0.0->jupyter-book) (4.12.2)\r\n", - "Requirement already satisfied: accessible-pygments in /usr/local/python/3.10.8/lib/python3.10/site-packages (from pydata-sphinx-theme>=0.13.3->sphinx-book-theme~=1.0.0->jupyter-book) (0.0.4)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: charset-normalizer<4,>=2 in /home/codespace/.local/lib/python3.10/site-packages (from requests>=2.5.0->sphinx<6,>=4->jupyter-book) (3.3.0)\r\n", - "Requirement already satisfied: idna<4,>=2.5 in /home/codespace/.local/lib/python3.10/site-packages (from requests>=2.5.0->sphinx<6,>=4->jupyter-book) (3.4)\r\n", - "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from requests>=2.5.0->sphinx<6,>=4->jupyter-book) (1.26.18)\r\n", - "Requirement already satisfied: certifi>=2017.4.17 in /home/codespace/.local/lib/python3.10/site-packages (from requests>=2.5.0->sphinx<6,>=4->jupyter-book) (2023.7.22)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: zipp>=0.5 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from importlib_metadata->myst-nb~=0.17.1->jupyter-book) (3.17.0)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: comm>=0.1.1 in /home/codespace/.local/lib/python3.10/site-packages (from ipykernel->myst-nb~=0.17.1->jupyter-book) (0.1.4)\r\n", - "Requirement already satisfied: debugpy>=1.6.5 in /home/codespace/.local/lib/python3.10/site-packages (from ipykernel->myst-nb~=0.17.1->jupyter-book) (1.8.0)\r\n", - "Requirement already satisfied: matplotlib-inline>=0.1 in /home/codespace/.local/lib/python3.10/site-packages (from ipykernel->myst-nb~=0.17.1->jupyter-book) (0.1.6)\r\n", - "Requirement already satisfied: nest-asyncio in /home/codespace/.local/lib/python3.10/site-packages (from ipykernel->myst-nb~=0.17.1->jupyter-book) (1.5.8)\r\n", - "Requirement already satisfied: psutil in /home/codespace/.local/lib/python3.10/site-packages (from ipykernel->myst-nb~=0.17.1->jupyter-book) (5.9.6)\r\n", - "Requirement already satisfied: pyzmq>=20 in /home/codespace/.local/lib/python3.10/site-packages (from ipykernel->myst-nb~=0.17.1->jupyter-book) (25.1.1)\r\n", - "Requirement already satisfied: tornado>=6.1 in /home/codespace/.local/lib/python3.10/site-packages (from ipykernel->myst-nb~=0.17.1->jupyter-book) (6.3.3)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: backcall in /home/codespace/.local/lib/python3.10/site-packages (from ipython->myst-nb~=0.17.1->jupyter-book) (0.2.0)\r\n", - "Requirement already satisfied: decorator in /home/codespace/.local/lib/python3.10/site-packages (from ipython->myst-nb~=0.17.1->jupyter-book) (5.1.1)\r\n", - "Requirement already satisfied: jedi>=0.16 in /home/codespace/.local/lib/python3.10/site-packages (from ipython->myst-nb~=0.17.1->jupyter-book) (0.19.1)\r\n", - "Requirement already satisfied: pickleshare in /home/codespace/.local/lib/python3.10/site-packages (from ipython->myst-nb~=0.17.1->jupyter-book) (0.7.5)\r\n", - "Requirement already satisfied: prompt-toolkit!=3.0.37,<3.1.0,>=3.0.30 in /home/codespace/.local/lib/python3.10/site-packages (from ipython->myst-nb~=0.17.1->jupyter-book) (3.0.39)\r\n", - "Requirement already satisfied: stack-data in /home/codespace/.local/lib/python3.10/site-packages (from ipython->myst-nb~=0.17.1->jupyter-book) (0.6.3)\r\n", - "Requirement already satisfied: exceptiongroup in /home/codespace/.local/lib/python3.10/site-packages (from ipython->myst-nb~=0.17.1->jupyter-book) (1.1.3)\r\n", - "Requirement already satisfied: pexpect>4.3 in /home/codespace/.local/lib/python3.10/site-packages (from ipython->myst-nb~=0.17.1->jupyter-book) (4.8.0)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: parso<0.9.0,>=0.8.3 in /home/codespace/.local/lib/python3.10/site-packages (from jedi>=0.16->ipython->myst-nb~=0.17.1->jupyter-book) (0.8.3)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: python-dateutil>=2.8.2 in /home/codespace/.local/lib/python3.10/site-packages (from jupyter-client>=6.1.12->nbclient->myst-nb~=0.17.1->jupyter-book) (2.8.2)\r\n", - "Requirement already satisfied: platformdirs>=2.5 in /home/codespace/.local/lib/python3.10/site-packages (from jupyter-core!=5.0.*,>=4.12->nbclient->myst-nb~=0.17.1->jupyter-book) (3.11.0)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: mdurl~=0.1 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from markdown-it-py<3.0.0,>=1.0.0->myst-parser~=0.18.0->myst-nb~=0.17.1->jupyter-book) (0.1.2)\r\n", - "Requirement already satisfied: ptyprocess>=0.5 in /home/codespace/.local/lib/python3.10/site-packages (from pexpect>4.3->ipython->myst-nb~=0.17.1->jupyter-book) (0.7.0)\r\n", - "Requirement already satisfied: wcwidth in /home/codespace/.local/lib/python3.10/site-packages (from prompt-toolkit!=3.0.37,<3.1.0,>=3.0.30->ipython->myst-nb~=0.17.1->jupyter-book) (0.2.8)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: greenlet!=0.4.17 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sqlalchemy<3,>=1.3.12->jupyter-cache<0.7,>=0.5->myst-nb~=0.17.1->jupyter-book) (3.0.1)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: soupsieve>1.2 in /home/codespace/.local/lib/python3.10/site-packages (from beautifulsoup4->pydata-sphinx-theme>=0.13.3->sphinx-book-theme~=1.0.0->jupyter-book) (2.5)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: executing>=1.2.0 in /home/codespace/.local/lib/python3.10/site-packages (from stack-data->ipython->myst-nb~=0.17.1->jupyter-book) (2.0.0)\r\n", - "Requirement already satisfied: asttokens>=2.1.0 in /home/codespace/.local/lib/python3.10/site-packages (from stack-data->ipython->myst-nb~=0.17.1->jupyter-book) (2.4.0)\r\n", - "Requirement already satisfied: pure-eval in /home/codespace/.local/lib/python3.10/site-packages (from stack-data->ipython->myst-nb~=0.17.1->jupyter-book) (0.2.2)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Note: you may need to restart the kernel to use updated packages.\n" - ] - } - ], - "source": [ - "!python -m pip install --upgrade pip\n", - "%pip install jupyter-book" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions\n" - ] - } - ], - "source": [ - "%cd /workspaces/LeetCode-Solutions" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Traceback (most recent call last):\r\n", - " File \"/home/codespace/.python/current/bin/jupyter-book\", line 8, in \r\n", - " sys.exit(main())\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/click/core.py\", line 1157, in __call__\r\n", - " return self.main(*args, **kwargs)\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/click/core.py\", line 1078, in main\r\n", - " rv = self.invoke(ctx)\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/click/core.py\", line 1688, in invoke\r\n", - " return _process_result(sub_ctx.command.invoke(sub_ctx))\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/click/core.py\", line 1688, in invoke\r\n", - " return _process_result(sub_ctx.command.invoke(sub_ctx))\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/click/core.py\", line 1434, in invoke\r\n", - " return ctx.invoke(self.callback, **ctx.params)\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/click/core.py\", line 783, in invoke\r\n", - " return __callback(*args, **kwargs)\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/sphinx_external_toc/cli.py\", line 139, in migrate_toc\r\n", - " toc = migrate_jupyter_book(Path(toc_file))\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/sphinx_external_toc/tools.py\", line 327, in migrate_jupyter_book\r\n", - " raise MalformedError(\"no top-level 'file' key found\")\r\n", - "sphinx_external_toc.parsing.MalformedError: no top-level 'file' key found\r\n" - ] - } - ], - "source": [ - "!jupyter-book toc migrate /workspaces/LeetCode-Solutions/_toc.yml -o /workspaces/LeetCode-Solutions/_toc.yml" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[32m\u001b[1mRunning Jupyter-Book v0.15.1\u001b[0m\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[34m\u001b[1mSource Folder: \u001b[0m/workspaces/LeetCode-Solutions\r\n", - "\u001b[34m\u001b[1mConfig Path: \u001b[0m/workspaces/LeetCode-Solutions/_config.yml\r\n", - "\u001b[34m\u001b[1mOutput Path: \u001b[0m/workspaces/LeetCode-Solutions/_build/html\r\n", - "\u001b[01mRunning Sphinx v5.0.2\u001b[39;49;00m\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[etoc] Changing master_doc to 'README'\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[01mmyst v0.18.1:\u001b[39;49;00m MdParserConfig(commonmark_only=False, gfm_only=False, enable_extensions=['colon_fence', 'dollarmath', 'linkify', 'substitution', 'tasklist'], disable_syntax=[], all_links_external=False, url_schemes=['mailto', 'http', 'https'], ref_domains=None, highlight_code_blocks=True, number_code_blocks=[], title_to_header=False, heading_anchors=None, heading_slug_func=None, footnote_transition=True, words_per_minute=200, sub_delimiters=('{', '}'), linkify_fuzzy_links=True, dmath_allow_labels=True, dmath_allow_space=True, dmath_allow_digits=True, dmath_double_inline=False, update_mathjax=True, mathjax_classes='tex2jax_process|mathjax_process|math|output_area')\r\n", - "\u001b[01mmyst-nb v0.17.2:\u001b[39;49;00m NbParserConfig(custom_formats={}, metadata_key='mystnb', cell_metadata_key='mystnb', kernel_rgx_aliases={}, execution_mode='auto', execution_cache_path='', execution_excludepatterns=[], execution_timeout=30, execution_in_temp=False, execution_allow_errors=False, execution_raise_on_error=False, execution_show_tb=False, merge_streams=False, render_plugin='default', remove_code_source=False, remove_code_outputs=False, code_prompt_show='Show code cell {type}', code_prompt_hide='Hide code cell {type}', number_source_lines=False, output_stderr='show', render_text_lexer='myst-ansi', render_error_lexer='ipythontb', render_image_options={}, render_figure_options={}, render_markdown_format='commonmark', output_folder='build', append_css=True, metadata_to_fm=False)\r\n", - "Using jupyter-cache at: /workspaces/LeetCode-Solutions/_build/.jupyter_cache\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[01mbuilding [mo]: \u001b[39;49;00mtargets for 0 po files that are out of date\r\n", - "\u001b[01mbuilding [html]: \u001b[39;49;00mtargets for 77 source files that are out of date\r\n", - "\u001b[01mupdating environment: \u001b[39;49;00m[new config] 77 added, 0 changed, 0 removed\r\n", - "\u001b[01mreading sources... \u001b[39;49;00m[ 1%] \u001b[35m01. Array Hashing/1. Two Sum\u001b[39;49;00m \r" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions/01. Array Hashing/1. Two Sum.ipynb: Executing notebook using local CWD [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions/01. Array Hashing/1. Two Sum.ipynb: Executed notebook in 1.07 seconds [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[01mreading sources... \u001b[39;49;00m[ 2%] \u001b[35m01. Array Hashing/128. Longest Consecutive Sequence\u001b[39;49;00m \r", - "/workspaces/LeetCode-Solutions/01. Array Hashing/128. Longest Consecutive Sequence.ipynb: Executing notebook using local CWD [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions/01. Array Hashing/128. Longest Consecutive Sequence.ipynb: Executed notebook in 1.17 seconds [mystnb]\r\n", - "\u001b[01mreading sources... \u001b[39;49;00m[ 3%] \u001b[35m01. Array Hashing/217. Contains Duplicate\u001b[39;49;00m \r", - "/workspaces/LeetCode-Solutions/01. Array Hashing/217. Contains Duplicate.ipynb: Executing notebook using local CWD [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions/01. Array Hashing/217. Contains Duplicate.ipynb: Executed notebook in 1.19 seconds [mystnb]\r\n", - "\u001b[01mreading sources... \u001b[39;49;00m[ 5%] \u001b[35m01. Array Hashing/238. Product of Array Except Self\u001b[39;49;00m \r", - "/workspaces/LeetCode-Solutions/01. Array Hashing/238. Product of Array Except Self.ipynb: Executing notebook using local CWD [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions/01. Array Hashing/238. Product of Array Except Self.ipynb: Executed notebook in 1.26 seconds [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[01mreading sources... \u001b[39;49;00m[ 6%] \u001b[35m01. Array Hashing/242. Valid Anagram\u001b[39;49;00m \r", - "/workspaces/LeetCode-Solutions/01. Array Hashing/242. Valid Anagram.ipynb: Executing notebook using local CWD [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions/01. Array Hashing/242. Valid Anagram.ipynb: Executed notebook in 1.18 seconds [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[01mreading sources... \u001b[39;49;00m[ 7%] \u001b[35m01. Array Hashing/347. Top K Frequent Elements\u001b[39;49;00m \r", - "/workspaces/LeetCode-Solutions/01. Array Hashing/347. Top K Frequent Elements.ipynb: Executing notebook using local CWD [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions/01. Array Hashing/347. Top K Frequent Elements.ipynb: Executed notebook in 1.13 seconds [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[01mreading sources... \u001b[39;49;00m[ 9%] \u001b[35m01. Array Hashing/49. Group Anagrams\u001b[39;49;00m \r", - "/workspaces/LeetCode-Solutions/01. Array Hashing/49. Group Anagrams.ipynb: Executing notebook using local CWD [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions/01. Array Hashing/49. Group Anagrams.ipynb: Executed notebook in 4.02 seconds [mystnb]\r\n", - "\u001b[01mreading sources... \u001b[39;49;00m[ 10%] \u001b[35m01. Array Hashing/659. Encode and Decode Strings\u001b[39;49;00m \r" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions/01. Array Hashing/659. Encode and Decode Strings.ipynb: Executing notebook using local CWD [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions/01. Array Hashing/659. Encode and Decode Strings.ipynb: Executed notebook in 1.05 seconds [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[01mreading sources... \u001b[39;49;00m[ 11%] \u001b[35m01. Array Hashing/README\u001b[39;49;00m \r", - "\u001b[01mreading sources... \u001b[39;49;00m[ 12%] \u001b[35m02. Two Pointers/11. Container With Most Water\u001b[39;49;00m \r", - "/workspaces/LeetCode-Solutions/02. Two Pointers/11. Container With Most Water.ipynb: Executing notebook using local CWD [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions/02. Two Pointers/11. Container With Most Water.ipynb: Executed notebook in 1.26 seconds [mystnb]\r\n", - "\u001b[01mreading sources... \u001b[39;49;00m[ 14%] \u001b[35m02. Two Pointers/125. Valid Palindrome\u001b[39;49;00m \r", - "/workspaces/LeetCode-Solutions/02. Two Pointers/125. Valid Palindrome.ipynb: Executing notebook using local CWD [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions/02. Two Pointers/125. Valid Palindrome.ipynb: Executed notebook in 1.07 seconds [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[01mreading sources... \u001b[39;49;00m[ 15%] \u001b[35m02. Two Pointers/15. 3Sum\u001b[39;49;00m \r", - "/workspaces/LeetCode-Solutions/02. Two Pointers/15. 3Sum.ipynb: Executing notebook using local CWD [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions/02. Two Pointers/15. 3Sum.ipynb: Executed notebook in 1.00 seconds [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[01mreading sources... \u001b[39;49;00m[ 16%] \u001b[35m02. Two Pointers/README\u001b[39;49;00m \r", - "\u001b[01mreading sources... \u001b[39;49;00m[ 18%] \u001b[35m03. Sliding Window/121. Best Time to Buy and Sell Stock\u001b[39;49;00m\r" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions/03. Sliding Window/121. Best Time to Buy and Sell Stock.ipynb: Executing notebook using local CWD [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions/03. Sliding Window/121. Best Time to Buy and Sell Stock.ipynb: Executed notebook in 0.89 seconds [mystnb]\r\n", - "\u001b[01mreading sources... \u001b[39;49;00m[ 19%] \u001b[35m03. Sliding Window/3. Longest Substring Without Repeating Characters\u001b[39;49;00m\r" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions/03. Sliding Window/3. Longest Substring Without Repeating Characters.ipynb: Executing notebook using local CWD [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions/03. Sliding Window/3. Longest Substring Without Repeating Characters.ipynb: Executed notebook in 1.16 seconds [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[01mreading sources... \u001b[39;49;00m[ 20%] \u001b[35m03. Sliding Window/424. Longest Repeating Character Replacement\u001b[39;49;00m\r", - "/workspaces/LeetCode-Solutions/03. Sliding Window/424. Longest Repeating Character Replacement.ipynb: Executing notebook using local CWD [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions/03. Sliding Window/424. Longest Repeating Character Replacement.ipynb: Executed notebook in 1.05 seconds [mystnb]\r\n", - "\u001b[01mreading sources... \u001b[39;49;00m[ 22%] \u001b[35m03. Sliding Window/76. Minimum Window Substring\u001b[39;49;00m \r", - "/workspaces/LeetCode-Solutions/03. Sliding Window/76. Minimum Window Substring.ipynb: Executing notebook using local CWD [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions/03. Sliding Window/76. Minimum Window Substring.ipynb: Executed notebook in 0.87 seconds [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[01mreading sources... \u001b[39;49;00m[ 23%] \u001b[35m03. Sliding Window/README\u001b[39;49;00m \r", - "\u001b[01mreading sources... \u001b[39;49;00m[ 24%] \u001b[35m04. Stack/20. Valid Parentheses\u001b[39;49;00m \r", - "/workspaces/LeetCode-Solutions/04. Stack/20. Valid Parentheses.ipynb: Executing notebook using local CWD [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions/04. Stack/20. Valid Parentheses.ipynb: Executed notebook in 4.02 seconds [mystnb]\r\n", - "\u001b[01mreading sources... \u001b[39;49;00m[ 25%] \u001b[35m04. Stack/README\u001b[39;49;00m \r", - "\u001b[01mreading sources... \u001b[39;49;00m[ 27%] \u001b[35m05. Binary Search/153. Find Minimum in Rotated Sorted Array\u001b[39;49;00m\r" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions/05. Binary Search/153. Find Minimum in Rotated Sorted Array.ipynb: Executing notebook using local CWD [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions/05. Binary Search/153. Find Minimum in Rotated Sorted Array.ipynb: Executed notebook in 0.98 seconds [mystnb]\r\n", - "\u001b[01mreading sources... \u001b[39;49;00m[ 28%] \u001b[35m05. Binary Search/33. Search in Rotated Sorted Array\u001b[39;49;00m \r" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions/05. Binary Search/33. Search in Rotated Sorted Array.ipynb: Executing notebook using local CWD [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions/05. Binary Search/33. Search in Rotated Sorted Array.ipynb: Executed notebook in 1.05 seconds [mystnb]\r\n", - "\u001b[01mreading sources... \u001b[39;49;00m[ 29%] \u001b[35m05. Binary Search/README\u001b[39;49;00m \r" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[01mreading sources... \u001b[39;49;00m[ 31%] \u001b[35m06. Linked List/141. Linked List Cycle\u001b[39;49;00m \r", - "/workspaces/LeetCode-Solutions/06. Linked List/141. Linked List Cycle.ipynb: Executing notebook using local CWD [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions/06. Linked List/141. Linked List Cycle.ipynb: Executed notebook in 0.96 seconds [mystnb]\r\n", - "\u001b[01mreading sources... \u001b[39;49;00m[ 32%] \u001b[35m06. Linked List/143. Reorder List\u001b[39;49;00m \r" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions/06. Linked List/143. Reorder List.ipynb: Executing notebook using local CWD [mystnb]\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "^C\r\n", - "\r\n", - "\u001b[91mException occurred:\u001b[39;49;00m\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/nbclient/client.py\", line 512, in _async_cleanup_kernel\r\n", - " await ensure_async(self.km.cleanup_resources())\r\n", - "AttributeError: 'NoneType' object has no attribute 'cleanup_resources'\r\n", - "\u001b[91mThe full traceback has been saved in /tmp/sphinx-err-tl19fjln.log, if you want to report the issue to the developers.\u001b[39;49;00m\r\n", - "Please also report this if it was a user error, so that a better error message can be provided next time.\r\n", - "A bug report can be filed in the tracker at . Thanks!\r\n", - "Traceback (most recent call last):\r\n", - " File \"/home/codespace/.local/lib/python3.10/site-packages/jupyter_client/manager.py\", line 89, in wrapper\r\n", - " self._ready.set_result(None)\r\n", - "asyncio.exceptions.InvalidStateError: invalid state\r\n", - "\r\n", - "During handling of the above exception, another exception occurred:\r\n", - "\r\n", - "Traceback (most recent call last):\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/nbclient/client.py\", line 505, in _async_cleanup_kernel\r\n", - " await ensure_async(self.km.shutdown_kernel(now=now))\r\n", - " File \"/home/codespace/.local/lib/python3.10/site-packages/jupyter_core/utils/__init__.py\", line 189, in ensure_async\r\n", - " result = await obj\r\n", - " File \"/home/codespace/.local/lib/python3.10/site-packages/jupyter_client/manager.py\", line 92, in wrapper\r\n", - " self._ready.set_exception(e)\r\n", - "asyncio.exceptions.InvalidStateError: invalid state\r\n", - "\r\n", - "During handling of the above exception, another exception occurred:\r\n", - "\r\n", - "Traceback (most recent call last):\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/jupyter_book/sphinx.py\", line 171, in build_sphinx\r\n", - " app.build(force_all, filenames)\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/sphinx/application.py\", line 329, in build\r\n", - " self.builder.build_update()\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/sphinx/builders/__init__.py\", line 288, in build_update\r\n", - " self.build(to_build,\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/sphinx/builders/__init__.py\", line 302, in build\r\n", - " updated_docnames = set(self.read())\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/sphinx/builders/__init__.py\", line 409, in read\r\n", - " self._read_serial(docnames)\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/sphinx/builders/__init__.py\", line 430, in _read_serial\r\n", - " self.read_doc(docname)\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/sphinx/builders/__init__.py\", line 483, in read_doc\r\n", - " publisher.publish()\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/docutils/core.py\", line 217, in publish\r\n", - " self.document = self.reader.read(self.source, self.parser,\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/sphinx/io.py\", line 103, in read\r\n", - " self.parse()\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/docutils/readers/__init__.py\", line 78, in parse\r\n", - " self.parser.parse(self.input, document)\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/myst_nb/sphinx_.py\", line 150, in parse\r\n", - " with create_client(\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/myst_nb/core/execute/base.py\", line 83, in __enter__\r\n", - " self.start_client()\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/myst_nb/core/execute/direct.py\", line 40, in start_client\r\n", - " result = single_nb_execution(\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/jupyter_cache/executors/utils.py\", line 58, in single_nb_execution\r\n", - " executenb(\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/nbclient/client.py\", line 1305, in execute\r\n", - " return NotebookClient(nb=nb, resources=resources, km=km, **kwargs).execute()\r\n", - " File \"/home/codespace/.local/lib/python3.10/site-packages/jupyter_core/utils/__init__.py\", line 173, in wrapped\r\n", - " return loop.run_until_complete(inner)\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/asyncio/base_events.py\", line 649, in run_until_complete\r\n", - " return future.result()\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/nbclient/client.py\", line 689, in async_execute\r\n", - " async with self.async_setup_kernel(**kwargs):\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/contextlib.py\", line 206, in __aexit__\r\n", - " await anext(self.gen)\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/nbclient/client.py\", line 656, in async_setup_kernel\r\n", - " await self._async_cleanup_kernel()\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/nbclient/client.py\", line 512, in _async_cleanup_kernel\r\n", - " await ensure_async(self.km.cleanup_resources())\r\n", - "AttributeError: 'NoneType' object has no attribute 'cleanup_resources'\r\n", - "\r\n", - "The above exception was the direct cause of the following exception:\r\n", - "\r\n", - "Traceback (most recent call last):\r\n", - " File \"/home/codespace/.python/current/bin/jupyter-book\", line 8, in \r\n", - " sys.exit(main())\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/click/core.py\", line 1157, in __call__\r\n", - " return self.main(*args, **kwargs)\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/click/core.py\", line 1078, in main\r\n", - " rv = self.invoke(ctx)\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/click/core.py\", line 1688, in invoke\r\n", - " return _process_result(sub_ctx.command.invoke(sub_ctx))\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/click/core.py\", line 1434, in invoke\r\n", - " return ctx.invoke(self.callback, **ctx.params)\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/click/core.py\", line 783, in invoke\r\n", - " return __callback(*args, **kwargs)\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/jupyter_book/cli/main.py\", line 317, in build\r\n", - " builder_specific_actions(\r\n", - " File \"/usr/local/python/3.10.8/lib/python3.10/site-packages/jupyter_book/cli/main.py\", line 525, in builder_specific_actions\r\n", - " raise RuntimeError(_message_box(msg, color=\"red\", doprint=False)) from result\r\n", - "RuntimeError: \r\n", - "\u001b[91m===============================================================================\u001b[0m\r\n", - "\r\n", - "There was an error in building your book. Look above for the cause.\r\n", - "\r\n", - "\u001b[91m===============================================================================\u001b[0m\r\n", - "\r\n" - ] - } - ], - "source": [ - "!jupyter-book build ." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "!jupyter-book build /workspaces/LeetCode-Solutions/ --builder pdfhtml" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "Click here to view your Jupyter Book" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from IPython.display import HTML\n", - "HTML('Click here to view your Jupyter Book')\n" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "\u001b[92m===============================================================================\u001b[0m\n", - "\n", - "Your book template can be found at\n", - "\n", - " mybook/\n", - "\n", - "\u001b[92m===============================================================================\u001b[0m\n", - "\n" - ] - } - ], - "source": [ - "!jupyter-book create mybook" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[32m\u001b[1mRunning Jupyter-Book v0.15.1\u001b[0m\n", - "\u001b[34m\u001b[1mSource Folder: \u001b[0m/workspaces/LeetCode-Solutions/mybook\n", - "\u001b[34m\u001b[1mConfig Path: \u001b[0m/workspaces/LeetCode-Solutions/mybook/_config.yml\n", - "\u001b[34m\u001b[1mOutput Path: \u001b[0m/workspaces/LeetCode-Solutions/mybook/_build/html\n", - "[sphinxcontrib-bibtex] Beware that docutils versions 0.18 and 0.19 (you are running 0.18.1) are known to generate invalid html for citations. If this issue affects you, please use docutils<0.18 (or >=0.20 once released) instead. For more details, see https://sourceforge.net/p/docutils/patches/195/\n", - "\u001b[01mRunning Sphinx v5.0.2\u001b[39;49;00m\n", - "[etoc] Changing master_doc to 'intro'\n", - "checking bibtex cache... out of date\n", - "parsing bibtex file /workspaces/LeetCode-Solutions/mybook/references.bib... parsed 5 entries\n", - "\u001b[01mmyst v0.18.1:\u001b[39;49;00m MdParserConfig(commonmark_only=False, gfm_only=False, enable_extensions=['colon_fence', 'dollarmath', 'linkify', 'substitution', 'tasklist'], disable_syntax=[], all_links_external=False, url_schemes=['mailto', 'http', 'https'], ref_domains=None, highlight_code_blocks=True, number_code_blocks=[], title_to_header=False, heading_anchors=None, heading_slug_func=None, footnote_transition=True, words_per_minute=200, sub_delimiters=('{', '}'), linkify_fuzzy_links=True, dmath_allow_labels=True, dmath_allow_space=True, dmath_allow_digits=True, dmath_double_inline=False, update_mathjax=True, mathjax_classes='tex2jax_process|mathjax_process|math|output_area')\n", - "\u001b[01mmyst-nb v0.17.2:\u001b[39;49;00m NbParserConfig(custom_formats={}, metadata_key='mystnb', cell_metadata_key='mystnb', kernel_rgx_aliases={}, execution_mode='force', execution_cache_path='', execution_excludepatterns=[], execution_timeout=30, execution_in_temp=False, execution_allow_errors=False, execution_raise_on_error=False, execution_show_tb=False, merge_streams=False, render_plugin='default', remove_code_source=False, remove_code_outputs=False, code_prompt_show='Show code cell {type}', code_prompt_hide='Hide code cell {type}', number_source_lines=False, output_stderr='show', render_text_lexer='myst-ansi', render_error_lexer='ipythontb', render_image_options={}, render_figure_options={}, render_markdown_format='commonmark', output_folder='build', append_css=True, metadata_to_fm=False)\n", - "Using jupyter-cache at: /workspaces/LeetCode-Solutions/mybook/_build/.jupyter_cache\n", - "\u001b[01mbuilding [mo]: \u001b[39;49;00mtargets for 0 po files that are out of date\n", - "\u001b[01mbuilding [html]: \u001b[39;49;00mtargets for 14 source files that are out of date\n", - "\u001b[01mupdating environment: \u001b[39;49;00m[new config] 14 added, 0 changed, 0 removed\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/1. Two Sum.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/1. Two Sum.ipynb: Executed notebook in 1.35 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/128. Longest Consecutive Sequence.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/128. Longest Consecutive Sequence.ipynb: Executed notebook in 1.09 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/217. Contains Duplicate.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/217. Contains Duplicate.ipynb: Executed notebook in 1.04 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/238. Product of Array Except Self.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/238. Product of Array Except Self.ipynb: Executed notebook in 4.02 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/242. Valid Anagram.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/242. Valid Anagram.ipynb: Executed notebook in 0.97 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/347. Top K Frequent Elements.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/347. Top K Frequent Elements.ipynb: Executed notebook in 1.14 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/49. Group Anagrams.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/49. Group Anagrams.ipynb: Executed notebook in 0.88 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/659. Encode and Decode Strings.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/659. Encode and Decode Strings.ipynb: Executed notebook in 1.10 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/11. Container With Most Water.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/11. Container With Most Water.ipynb: Executed notebook in 1.12 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/125. Valid Palindrome.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/125. Valid Palindrome.ipynb: Executed notebook in 0.98 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/15. 3Sum.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/15. 3Sum.ipynb: Executed notebook in 0.83 seconds [mystnb]\n", - "\u001b[01mreading sources... \u001b[39;49;00m[100%] \u001b[35mintro\u001b[39;49;00m \n", - "\u001b[01mlooking for now-outdated files... \u001b[39;49;00mnone found\n", - "\u001b[01mpickling environment... \u001b[39;49;00mdone\n", - "\u001b[01mchecking consistency... \u001b[39;49;00m\u001b[91m/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/README.md: WARNING: document isn't included in any toctree\u001b[39;49;00m\n", - "\u001b[91m/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/README.md: WARNING: document isn't included in any toctree\u001b[39;49;00m\n", - "done\n", - "\u001b[01mpreparing documents... \u001b[39;49;00mdone\n", - "\u001b[01mwriting output... \u001b[39;49;00m[100%] \u001b[32mintro\u001b[39;49;00m \n", - "\u001b[01mgenerating indices... \u001b[39;49;00mgenindex done\n", - "\u001b[01mwriting additional pages... \u001b[39;49;00msearch done\n", - "\u001b[01mcopying static files... \u001b[39;49;00mdone\n", - "\u001b[01mcopying extra files... \u001b[39;49;00mdone\n", - "\u001b[01mdumping search index in English (code: en)... \u001b[39;49;00mdone\n", - "\u001b[01mdumping object inventory... \u001b[39;49;00mdone\n", - "[etoc] missing index.html written as redirect to 'intro.html'\n", - "\u001b[01mbuild succeeded, 2 warnings.\u001b[39;49;00m\n", - "\n", - "The HTML pages are in mybook/_build/html.\n", - "\n", - "\u001b[92m===============================================================================\u001b[0m\n", - "\n", - "Finished generating HTML for book.\n", - "Your book's HTML pages are here:\n", - " mybook/_build/html/\n", - "You can look at your book by opening this file in a browser:\n", - " mybook/_build/html/index.html\n", - "Or paste this line directly into your browser bar:\n", - " file:///workspaces/LeetCode-Solutions/mybook/_build/html/index.html \n", - "\n", - "\u001b[92m===============================================================================\u001b[0m\n", - "\n" - ] - } - ], - "source": [ - "!jupyter-book build mybook" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "format: jb-book\n", - "root: intro\n", - "\n" - ] - } - ], - "source": [ - "!jupyter-book toc from-project /workspaces/LeetCode-Solutions/mybook/ -f jb-book" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/_config.yml b/_config.yml deleted file mode 100644 index 3def3c7..0000000 --- a/_config.yml +++ /dev/null @@ -1,31 +0,0 @@ -# Jupyter Book configuration - -# Project information -title: "Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges" # Python Problem-Solving Pro: Conquering the Blind 75 LeetCode Challenges -author: Mohsen Tabibian and Saeed Samadidana -email: mohsentabibian@gmail.com -description: Explore 75 essential problems frequently asked in tech interviews. Each solution includes detailed explanations and time/space complexity analysis. Boost your coding skills and interview preparedness! - -repository: - url: https://github.com/mohsentabibian/LeetCode-Solutions - path: docs #LeetCode-Solutions/ - branch: main - -# Execute notebooks when building (set to false if you don't want to run the code) -execute: - execute_notebooks: auto - -# HTML settings -html: - theme: jekyll-theme-Architect #jupyter - logo: logo.png - toc: - display: true - use_issues_button: true - use_repository_button: true - -#Build settings -#repository_url: https://github.com/mohsentabibian/LeetCode-Solutions # URL to the GitHub repository - -# Add GitHub buttons to the book -# See https://jupyterbook.org/customize/config.html #add-a-link-to-your-repository \ No newline at end of file diff --git a/01. Array Hashing/1. Two Sum.ipynb b/_sources/01. Array Hashing/1. Two Sum.ipynb similarity index 100% rename from 01. Array Hashing/1. Two Sum.ipynb rename to _sources/01. Array Hashing/1. Two Sum.ipynb diff --git a/01. Array Hashing/128. Longest Consecutive Sequence.ipynb b/_sources/01. Array Hashing/128. Longest Consecutive Sequence.ipynb similarity index 100% rename from 01. Array Hashing/128. Longest Consecutive Sequence.ipynb rename to _sources/01. Array Hashing/128. Longest Consecutive Sequence.ipynb diff --git a/01. Array Hashing/217. Contains Duplicate.ipynb b/_sources/01. Array Hashing/217. Contains Duplicate.ipynb similarity index 100% rename from 01. Array Hashing/217. Contains Duplicate.ipynb rename to _sources/01. Array Hashing/217. Contains Duplicate.ipynb diff --git a/01. Array Hashing/238. Product of Array Except Self.ipynb b/_sources/01. Array Hashing/238. Product of Array Except Self.ipynb similarity index 100% rename from 01. Array Hashing/238. Product of Array Except Self.ipynb rename to _sources/01. Array Hashing/238. Product of Array Except Self.ipynb diff --git a/01. Array Hashing/242. Valid Anagram.ipynb b/_sources/01. Array Hashing/242. Valid Anagram.ipynb similarity index 100% rename from 01. Array Hashing/242. Valid Anagram.ipynb rename to _sources/01. Array Hashing/242. Valid Anagram.ipynb diff --git a/01. Array Hashing/347. Top K Frequent Elements.ipynb b/_sources/01. Array Hashing/347. Top K Frequent Elements.ipynb similarity index 100% rename from 01. Array Hashing/347. Top K Frequent Elements.ipynb rename to _sources/01. Array Hashing/347. Top K Frequent Elements.ipynb diff --git a/01. Array Hashing/49. Group Anagrams.ipynb b/_sources/01. Array Hashing/49. Group Anagrams.ipynb similarity index 100% rename from 01. Array Hashing/49. Group Anagrams.ipynb rename to _sources/01. Array Hashing/49. Group Anagrams.ipynb diff --git a/01. Array Hashing/659. Encode and Decode Strings.ipynb b/_sources/01. Array Hashing/659. Encode and Decode Strings.ipynb similarity index 100% rename from 01. Array Hashing/659. Encode and Decode Strings.ipynb rename to _sources/01. Array Hashing/659. Encode and Decode Strings.ipynb diff --git a/01. Array Hashing/README.md b/_sources/01. Array Hashing/README.md similarity index 100% rename from 01. Array Hashing/README.md rename to _sources/01. Array Hashing/README.md diff --git a/02. Two Pointers/11. Container With Most Water.ipynb b/_sources/02. Two Pointers/11. Container With Most Water.ipynb similarity index 100% rename from 02. Two Pointers/11. Container With Most Water.ipynb rename to _sources/02. Two Pointers/11. Container With Most Water.ipynb diff --git a/02. Two Pointers/125. Valid Palindrome.ipynb b/_sources/02. Two Pointers/125. Valid Palindrome.ipynb similarity index 100% rename from 02. Two Pointers/125. Valid Palindrome.ipynb rename to _sources/02. Two Pointers/125. Valid Palindrome.ipynb diff --git a/02. Two Pointers/15. 3Sum.ipynb b/_sources/02. Two Pointers/15. 3Sum.ipynb similarity index 100% rename from 02. Two Pointers/15. 3Sum.ipynb rename to _sources/02. Two Pointers/15. 3Sum.ipynb diff --git a/02. Two Pointers/README.md b/_sources/02. Two Pointers/README.md similarity index 100% rename from 02. Two Pointers/README.md rename to _sources/02. Two Pointers/README.md diff --git a/03. Sliding Window/121. Best Time to Buy and Sell Stock.ipynb b/_sources/03. Sliding Window/121. Best Time to Buy and Sell Stock.ipynb similarity index 100% rename from 03. Sliding Window/121. Best Time to Buy and Sell Stock.ipynb rename to _sources/03. Sliding Window/121. Best Time to Buy and Sell Stock.ipynb diff --git a/03. Sliding Window/3. Longest Substring Without Repeating Characters.ipynb b/_sources/03. Sliding Window/3. Longest Substring Without Repeating Characters.ipynb similarity index 100% rename from 03. Sliding Window/3. Longest Substring Without Repeating Characters.ipynb rename to _sources/03. Sliding Window/3. Longest Substring Without Repeating Characters.ipynb diff --git a/03. Sliding Window/424. Longest Repeating Character Replacement.ipynb b/_sources/03. Sliding Window/424. Longest Repeating Character Replacement.ipynb similarity index 100% rename from 03. Sliding Window/424. Longest Repeating Character Replacement.ipynb rename to _sources/03. Sliding Window/424. Longest Repeating Character Replacement.ipynb diff --git a/03. Sliding Window/76. Minimum Window Substring.ipynb b/_sources/03. Sliding Window/76. Minimum Window Substring.ipynb similarity index 100% rename from 03. Sliding Window/76. Minimum Window Substring.ipynb rename to _sources/03. Sliding Window/76. Minimum Window Substring.ipynb diff --git a/03. Sliding Window/README.md b/_sources/03. Sliding Window/README.md similarity index 100% rename from 03. Sliding Window/README.md rename to _sources/03. Sliding Window/README.md diff --git a/04. Stack/20. Valid Parentheses.ipynb b/_sources/04. Stack/20. Valid Parentheses.ipynb similarity index 100% rename from 04. Stack/20. Valid Parentheses.ipynb rename to _sources/04. Stack/20. Valid Parentheses.ipynb diff --git a/04. Stack/README.md b/_sources/04. Stack/README.md similarity index 100% rename from 04. Stack/README.md rename to _sources/04. Stack/README.md diff --git a/05. Binary Search/153. Find Minimum in Rotated Sorted Array.ipynb b/_sources/05. Binary Search/153. Find Minimum in Rotated Sorted Array.ipynb similarity index 100% rename from 05. Binary Search/153. Find Minimum in Rotated Sorted Array.ipynb rename to _sources/05. Binary Search/153. Find Minimum in Rotated Sorted Array.ipynb diff --git a/05. Binary Search/33. Search in Rotated Sorted Array.ipynb b/_sources/05. Binary Search/33. Search in Rotated Sorted Array.ipynb similarity index 100% rename from 05. Binary Search/33. Search in Rotated Sorted Array.ipynb rename to _sources/05. Binary Search/33. Search in Rotated Sorted Array.ipynb diff --git a/05. Binary Search/README.md b/_sources/05. Binary Search/README.md similarity index 100% rename from 05. Binary Search/README.md rename to _sources/05. Binary Search/README.md diff --git a/06. Linked List/141. Linked List Cycle.ipynb b/_sources/06. Linked List/141. Linked List Cycle.ipynb similarity index 100% rename from 06. Linked List/141. Linked List Cycle.ipynb rename to _sources/06. Linked List/141. Linked List Cycle.ipynb diff --git a/06. Linked List/143. Reorder List.ipynb b/_sources/06. Linked List/143. Reorder List.ipynb similarity index 100% rename from 06. Linked List/143. Reorder List.ipynb rename to _sources/06. Linked List/143. Reorder List.ipynb diff --git a/06. Linked List/19. Remove Nth Node From End of List.ipynb b/_sources/06. Linked List/19. Remove Nth Node From End of List.ipynb similarity index 100% rename from 06. Linked List/19. Remove Nth Node From End of List.ipynb rename to _sources/06. Linked List/19. Remove Nth Node From End of List.ipynb diff --git a/06. Linked List/206. Reverse Linked List.ipynb b/_sources/06. Linked List/206. Reverse Linked List.ipynb similarity index 100% rename from 06. Linked List/206. Reverse Linked List.ipynb rename to _sources/06. Linked List/206. Reverse Linked List.ipynb diff --git a/06. Linked List/21. Merge Two Sorted Lists.ipynb b/_sources/06. Linked List/21. Merge Two Sorted Lists.ipynb similarity index 100% rename from 06. Linked List/21. Merge Two Sorted Lists.ipynb rename to _sources/06. Linked List/21. Merge Two Sorted Lists.ipynb diff --git a/06. Linked List/23. Merge k Sorted Lists.ipynb b/_sources/06. Linked List/23. Merge k Sorted Lists.ipynb similarity index 100% rename from 06. Linked List/23. Merge k Sorted Lists.ipynb rename to _sources/06. Linked List/23. Merge k Sorted Lists.ipynb diff --git a/06. Linked List/README.md b/_sources/06. Linked List/README.md similarity index 100% rename from 06. Linked List/README.md rename to _sources/06. Linked List/README.md diff --git a/07. Trees/100. Same Tree.ipynb b/_sources/07. Trees/100. Same Tree.ipynb similarity index 100% rename from 07. Trees/100. Same Tree.ipynb rename to _sources/07. Trees/100. Same Tree.ipynb diff --git a/07. Trees/102. Binary Tree Level Order Traversal.ipynb b/_sources/07. Trees/102. Binary Tree Level Order Traversal.ipynb similarity index 100% rename from 07. Trees/102. Binary Tree Level Order Traversal.ipynb rename to _sources/07. Trees/102. Binary Tree Level Order Traversal.ipynb diff --git a/07. Trees/104. Maximum Depth of Binary Tree.ipynb b/_sources/07. Trees/104. Maximum Depth of Binary Tree.ipynb similarity index 100% rename from 07. Trees/104. Maximum Depth of Binary Tree.ipynb rename to _sources/07. Trees/104. Maximum Depth of Binary Tree.ipynb diff --git a/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.ipynb b/_sources/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.ipynb similarity index 100% rename from 07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.ipynb rename to _sources/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.ipynb diff --git a/07. Trees/124. Binary Tree Maximum Path Sum.ipynb b/_sources/07. Trees/124. Binary Tree Maximum Path Sum.ipynb similarity index 100% rename from 07. Trees/124. Binary Tree Maximum Path Sum.ipynb rename to _sources/07. Trees/124. Binary Tree Maximum Path Sum.ipynb diff --git a/07. Trees/199. Binary Tree Right Side View.ipynb b/_sources/07. Trees/199. Binary Tree Right Side View.ipynb similarity index 100% rename from 07. Trees/199. Binary Tree Right Side View.ipynb rename to _sources/07. Trees/199. Binary Tree Right Side View.ipynb diff --git a/07. Trees/226. Invert Binary Tree.ipynb b/_sources/07. Trees/226. Invert Binary Tree.ipynb similarity index 100% rename from 07. Trees/226. Invert Binary Tree.ipynb rename to _sources/07. Trees/226. Invert Binary Tree.ipynb diff --git a/07. Trees/230. Kth Smallest Element in a BST.ipynb b/_sources/07. Trees/230. Kth Smallest Element in a BST.ipynb similarity index 100% rename from 07. Trees/230. Kth Smallest Element in a BST.ipynb rename to _sources/07. Trees/230. Kth Smallest Element in a BST.ipynb diff --git a/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.ipynb b/_sources/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.ipynb similarity index 100% rename from 07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.ipynb rename to _sources/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.ipynb diff --git a/07. Trees/297. Serialize and Deserialize Binary Tree.ipynb b/_sources/07. Trees/297. Serialize and Deserialize Binary Tree.ipynb similarity index 100% rename from 07. Trees/297. Serialize and Deserialize Binary Tree.ipynb rename to _sources/07. Trees/297. Serialize and Deserialize Binary Tree.ipynb diff --git a/07. Trees/572. Subtree of Another Tree.ipynb b/_sources/07. Trees/572. Subtree of Another Tree.ipynb similarity index 100% rename from 07. Trees/572. Subtree of Another Tree.ipynb rename to _sources/07. Trees/572. Subtree of Another Tree.ipynb diff --git a/07. Trees/98. Validate Binary Search Tree.ipynb b/_sources/07. Trees/98. Validate Binary Search Tree.ipynb similarity index 100% rename from 07. Trees/98. Validate Binary Search Tree.ipynb rename to _sources/07. Trees/98. Validate Binary Search Tree.ipynb diff --git a/07. Trees/README.md b/_sources/07. Trees/README.md similarity index 100% rename from 07. Trees/README.md rename to _sources/07. Trees/README.md diff --git a/08. Tries/208. Implement Trie (Prefix Tree).ipynb b/_sources/08. Tries/208. Implement Trie (Prefix Tree).ipynb similarity index 100% rename from 08. Tries/208. Implement Trie (Prefix Tree).ipynb rename to _sources/08. Tries/208. Implement Trie (Prefix Tree).ipynb diff --git a/08. Tries/211. Design Add and Search Words Data Structure.ipynb b/_sources/08. Tries/211. Design Add and Search Words Data Structure.ipynb similarity index 100% rename from 08. Tries/211. Design Add and Search Words Data Structure.ipynb rename to _sources/08. Tries/211. Design Add and Search Words Data Structure.ipynb diff --git a/08. Tries/212. Word Search II.ipynb b/_sources/08. Tries/212. Word Search II.ipynb similarity index 100% rename from 08. Tries/212. Word Search II.ipynb rename to _sources/08. Tries/212. Word Search II.ipynb diff --git a/08. Tries/README.md b/_sources/08. Tries/README.md similarity index 100% rename from 08. Tries/README.md rename to _sources/08. Tries/README.md diff --git a/09. Heap - Priority Queue/1046. Last Stone Weight.ipynb b/_sources/09. Heap - Priority Queue/1046. Last Stone Weight.ipynb similarity index 100% rename from 09. Heap - Priority Queue/1046. Last Stone Weight.ipynb rename to _sources/09. Heap - Priority Queue/1046. Last Stone Weight.ipynb diff --git a/09. Heap - Priority Queue/295. Find Median from Data Stream.ipynb b/_sources/09. Heap - Priority Queue/295. Find Median from Data Stream.ipynb similarity index 100% rename from 09. Heap - Priority Queue/295. Find Median from Data Stream.ipynb rename to _sources/09. Heap - Priority Queue/295. Find Median from Data Stream.ipynb diff --git a/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.ipynb b/_sources/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.ipynb similarity index 100% rename from 09. Heap - Priority Queue/703. Kth Largest Element in a Stream.ipynb rename to _sources/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.ipynb diff --git a/09. Heap - Priority Queue/README.md b/_sources/09. Heap - Priority Queue/README.md similarity index 100% rename from 09. Heap - Priority Queue/README.md rename to _sources/09. Heap - Priority Queue/README.md diff --git a/10. Backtracking/39. Combination Sum.ipynb b/_sources/10. Backtracking/39. Combination Sum.ipynb similarity index 100% rename from 10. Backtracking/39. Combination Sum.ipynb rename to _sources/10. Backtracking/39. Combination Sum.ipynb diff --git a/10. Backtracking/79. Word Search.ipynb b/_sources/10. Backtracking/79. Word Search.ipynb similarity index 100% rename from 10. Backtracking/79. Word Search.ipynb rename to _sources/10. Backtracking/79. Word Search.ipynb diff --git a/10. Backtracking/README.md b/_sources/10. Backtracking/README.md similarity index 100% rename from 10. Backtracking/README.md rename to _sources/10. Backtracking/README.md diff --git a/11. Graphs/133. Clone Graph.ipynb b/_sources/11. Graphs/133. Clone Graph.ipynb similarity index 100% rename from 11. Graphs/133. Clone Graph.ipynb rename to _sources/11. Graphs/133. Clone Graph.ipynb diff --git a/11. Graphs/178. Graph Valid Tree.ipynb b/_sources/11. Graphs/178. Graph Valid Tree.ipynb similarity index 100% rename from 11. Graphs/178. Graph Valid Tree.ipynb rename to _sources/11. Graphs/178. Graph Valid Tree.ipynb diff --git a/11. Graphs/200. Number of Islands.ipynb b/_sources/11. Graphs/200. Number of Islands.ipynb similarity index 100% rename from 11. Graphs/200. Number of Islands.ipynb rename to _sources/11. Graphs/200. Number of Islands.ipynb diff --git a/11. Graphs/207. Course Schedule.ipynb b/_sources/11. Graphs/207. Course Schedule.ipynb similarity index 100% rename from 11. Graphs/207. Course Schedule.ipynb rename to _sources/11. Graphs/207. Course Schedule.ipynb diff --git a/11. Graphs/3651. Number of Connected Components in an Undirected Graph.ipynb b/_sources/11. Graphs/3651. Number of Connected Components in an Undirected Graph.ipynb similarity index 100% rename from 11. Graphs/3651. Number of Connected Components in an Undirected Graph.ipynb rename to _sources/11. Graphs/3651. Number of Connected Components in an Undirected Graph.ipynb diff --git a/11. Graphs/417. Pacific Atlantic Water Flow.ipynb b/_sources/11. Graphs/417. Pacific Atlantic Water Flow.ipynb similarity index 100% rename from 11. Graphs/417. Pacific Atlantic Water Flow.ipynb rename to _sources/11. Graphs/417. Pacific Atlantic Water Flow.ipynb diff --git a/11. Graphs/README.md b/_sources/11. Graphs/README.md similarity index 100% rename from 11. Graphs/README.md rename to _sources/11. Graphs/README.md diff --git a/12. Advanced Graphs/892. Alien Dictionary.ipynb b/_sources/12. Advanced Graphs/892. Alien Dictionary.ipynb similarity index 100% rename from 12. Advanced Graphs/892. Alien Dictionary.ipynb rename to _sources/12. Advanced Graphs/892. Alien Dictionary.ipynb diff --git a/12. Advanced Graphs/README.md b/_sources/12. Advanced Graphs/README.md similarity index 100% rename from 12. Advanced Graphs/README.md rename to _sources/12. Advanced Graphs/README.md diff --git a/13. One-D Dynamic Programming/198. House Robber.ipynb b/_sources/13. One-D Dynamic Programming/198. House Robber.ipynb similarity index 100% rename from 13. One-D Dynamic Programming/198. House Robber.ipynb rename to _sources/13. One-D Dynamic Programming/198. House Robber.ipynb diff --git a/13. One-D Dynamic Programming/213. House Robber II.ipynb b/_sources/13. One-D Dynamic Programming/213. House Robber II.ipynb similarity index 100% rename from 13. One-D Dynamic Programming/213. House Robber II.ipynb rename to _sources/13. One-D Dynamic Programming/213. House Robber II.ipynb diff --git a/13. One-D Dynamic Programming/70. Climbing Stairs.ipynb b/_sources/13. One-D Dynamic Programming/70. Climbing Stairs.ipynb similarity index 100% rename from 13. One-D Dynamic Programming/70. Climbing Stairs.ipynb rename to _sources/13. One-D Dynamic Programming/70. Climbing Stairs.ipynb diff --git a/13. One-D Dynamic Programming/README.md b/_sources/13. One-D Dynamic Programming/README.md similarity index 100% rename from 13. One-D Dynamic Programming/README.md rename to _sources/13. One-D Dynamic Programming/README.md diff --git a/14. Two-D Dynamic Programming/README.md b/_sources/14. Two-D Dynamic Programming/README.md similarity index 100% rename from 14. Two-D Dynamic Programming/README.md rename to _sources/14. Two-D Dynamic Programming/README.md diff --git a/15. Greedy/README.md b/_sources/15. Greedy/README.md similarity index 100% rename from 15. Greedy/README.md rename to _sources/15. Greedy/README.md diff --git a/16. Intervals/README.md b/_sources/16. Intervals/README.md similarity index 100% rename from 16. Intervals/README.md rename to _sources/16. Intervals/README.md diff --git a/17. Math Geometry/README.md b/_sources/17. Math Geometry/README.md similarity index 100% rename from 17. Math Geometry/README.md rename to _sources/17. Math Geometry/README.md diff --git a/18. Bit Manipulation/README.md b/_sources/18. Bit Manipulation/README.md similarity index 100% rename from 18. Bit Manipulation/README.md rename to _sources/18. Bit Manipulation/README.md diff --git a/_build/html/_sources/Book.ipynb b/_sources/Book.ipynb similarity index 100% rename from _build/html/_sources/Book.ipynb rename to _sources/Book.ipynb diff --git a/CODE_OF_CONDUCT.md b/_sources/CODE_OF_CONDUCT.md similarity index 100% rename from CODE_OF_CONDUCT.md rename to _sources/CODE_OF_CONDUCT.md diff --git a/CONTRIBUTING.md b/_sources/CONTRIBUTING.md similarity index 100% rename from CONTRIBUTING.md rename to _sources/CONTRIBUTING.md diff --git a/README.md b/_sources/README.md similarity index 100% rename from README.md rename to _sources/README.md diff --git a/SECURITY.md b/_sources/SECURITY.md similarity index 100% rename from SECURITY.md rename to _sources/SECURITY.md diff --git a/_build/html/_sphinx_design_static/design-style.4045f2051d55cab465a707391d5b2007.min.css b/_sphinx_design_static/design-style.4045f2051d55cab465a707391d5b2007.min.css similarity index 100% rename from _build/html/_sphinx_design_static/design-style.4045f2051d55cab465a707391d5b2007.min.css rename to _sphinx_design_static/design-style.4045f2051d55cab465a707391d5b2007.min.css diff --git a/_build/html/_sphinx_design_static/design-tabs.js b/_sphinx_design_static/design-tabs.js similarity index 100% rename from _build/html/_sphinx_design_static/design-tabs.js rename to _sphinx_design_static/design-tabs.js diff --git a/_build/html/_static/_sphinx_javascript_frameworks_compat.js b/_static/_sphinx_javascript_frameworks_compat.js similarity index 100% rename from _build/html/_static/_sphinx_javascript_frameworks_compat.js rename to _static/_sphinx_javascript_frameworks_compat.js diff --git a/_build/html/_static/basic.css b/_static/basic.css similarity index 100% rename from _build/html/_static/basic.css rename to _static/basic.css diff --git a/_build/html/_static/check-solid.svg b/_static/check-solid.svg similarity index 100% rename from _build/html/_static/check-solid.svg rename to _static/check-solid.svg diff --git a/_build/html/_static/clipboard.min.js b/_static/clipboard.min.js similarity index 100% rename from _build/html/_static/clipboard.min.js rename to _static/clipboard.min.js diff --git a/_build/html/_static/copy-button.svg b/_static/copy-button.svg similarity index 100% rename from _build/html/_static/copy-button.svg rename to _static/copy-button.svg diff --git a/_build/html/_static/copybutton.css b/_static/copybutton.css similarity index 100% rename from _build/html/_static/copybutton.css rename to _static/copybutton.css diff --git a/_build/html/_static/copybutton.js b/_static/copybutton.js similarity index 100% rename from _build/html/_static/copybutton.js rename to _static/copybutton.js diff --git a/_build/html/_static/copybutton_funcs.js b/_static/copybutton_funcs.js similarity index 100% rename from _build/html/_static/copybutton_funcs.js rename to _static/copybutton_funcs.js diff --git a/_build/html/_static/design-style.4045f2051d55cab465a707391d5b2007.min.css b/_static/design-style.4045f2051d55cab465a707391d5b2007.min.css similarity index 100% rename from _build/html/_static/design-style.4045f2051d55cab465a707391d5b2007.min.css rename to _static/design-style.4045f2051d55cab465a707391d5b2007.min.css diff --git a/_build/html/_static/design-tabs.js b/_static/design-tabs.js similarity index 100% rename from _build/html/_static/design-tabs.js rename to _static/design-tabs.js diff --git a/_build/html/_static/doctools.js b/_static/doctools.js similarity index 100% rename from _build/html/_static/doctools.js rename to _static/doctools.js diff --git a/_build/html/_static/documentation_options.js b/_static/documentation_options.js similarity index 100% rename from _build/html/_static/documentation_options.js rename to _static/documentation_options.js diff --git a/_build/html/_static/file.png b/_static/file.png similarity index 100% rename from _build/html/_static/file.png rename to _static/file.png diff --git a/_build/html/_static/images/logo_binder.svg b/_static/images/logo_binder.svg similarity index 100% rename from _build/html/_static/images/logo_binder.svg rename to _static/images/logo_binder.svg diff --git a/_build/html/_static/images/logo_colab.png b/_static/images/logo_colab.png similarity index 100% rename from _build/html/_static/images/logo_colab.png rename to _static/images/logo_colab.png diff --git a/_build/html/_static/images/logo_deepnote.svg b/_static/images/logo_deepnote.svg similarity index 100% rename from _build/html/_static/images/logo_deepnote.svg rename to _static/images/logo_deepnote.svg diff --git a/_build/html/_static/images/logo_jupyterhub.svg b/_static/images/logo_jupyterhub.svg similarity index 100% rename from _build/html/_static/images/logo_jupyterhub.svg rename to _static/images/logo_jupyterhub.svg diff --git a/_build/html/_static/jquery-3.6.0.js b/_static/jquery-3.6.0.js similarity index 100% rename from _build/html/_static/jquery-3.6.0.js rename to _static/jquery-3.6.0.js diff --git a/_build/html/_static/jquery.js b/_static/jquery.js similarity index 100% rename from _build/html/_static/jquery.js rename to _static/jquery.js diff --git a/_build/html/_static/language_data.js b/_static/language_data.js similarity index 100% rename from _build/html/_static/language_data.js rename to _static/language_data.js diff --git a/_build/html/_static/locales/ar/LC_MESSAGES/booktheme.mo b/_static/locales/ar/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/ar/LC_MESSAGES/booktheme.mo rename to _static/locales/ar/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/ar/LC_MESSAGES/booktheme.po b/_static/locales/ar/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/ar/LC_MESSAGES/booktheme.po rename to _static/locales/ar/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/bg/LC_MESSAGES/booktheme.mo b/_static/locales/bg/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/bg/LC_MESSAGES/booktheme.mo rename to _static/locales/bg/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/bg/LC_MESSAGES/booktheme.po b/_static/locales/bg/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/bg/LC_MESSAGES/booktheme.po rename to _static/locales/bg/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/bn/LC_MESSAGES/booktheme.mo b/_static/locales/bn/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/bn/LC_MESSAGES/booktheme.mo rename to _static/locales/bn/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/bn/LC_MESSAGES/booktheme.po b/_static/locales/bn/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/bn/LC_MESSAGES/booktheme.po rename to _static/locales/bn/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/ca/LC_MESSAGES/booktheme.mo b/_static/locales/ca/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/ca/LC_MESSAGES/booktheme.mo rename to _static/locales/ca/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/ca/LC_MESSAGES/booktheme.po b/_static/locales/ca/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/ca/LC_MESSAGES/booktheme.po rename to _static/locales/ca/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/cs/LC_MESSAGES/booktheme.mo b/_static/locales/cs/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/cs/LC_MESSAGES/booktheme.mo rename to _static/locales/cs/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/cs/LC_MESSAGES/booktheme.po b/_static/locales/cs/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/cs/LC_MESSAGES/booktheme.po rename to _static/locales/cs/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/da/LC_MESSAGES/booktheme.mo b/_static/locales/da/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/da/LC_MESSAGES/booktheme.mo rename to _static/locales/da/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/da/LC_MESSAGES/booktheme.po b/_static/locales/da/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/da/LC_MESSAGES/booktheme.po rename to _static/locales/da/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/de/LC_MESSAGES/booktheme.mo b/_static/locales/de/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/de/LC_MESSAGES/booktheme.mo rename to _static/locales/de/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/de/LC_MESSAGES/booktheme.po b/_static/locales/de/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/de/LC_MESSAGES/booktheme.po rename to _static/locales/de/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/el/LC_MESSAGES/booktheme.mo b/_static/locales/el/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/el/LC_MESSAGES/booktheme.mo rename to _static/locales/el/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/el/LC_MESSAGES/booktheme.po b/_static/locales/el/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/el/LC_MESSAGES/booktheme.po rename to _static/locales/el/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/eo/LC_MESSAGES/booktheme.mo b/_static/locales/eo/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/eo/LC_MESSAGES/booktheme.mo rename to _static/locales/eo/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/eo/LC_MESSAGES/booktheme.po b/_static/locales/eo/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/eo/LC_MESSAGES/booktheme.po rename to _static/locales/eo/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/es/LC_MESSAGES/booktheme.mo b/_static/locales/es/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/es/LC_MESSAGES/booktheme.mo rename to _static/locales/es/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/es/LC_MESSAGES/booktheme.po b/_static/locales/es/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/es/LC_MESSAGES/booktheme.po rename to _static/locales/es/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/et/LC_MESSAGES/booktheme.mo b/_static/locales/et/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/et/LC_MESSAGES/booktheme.mo rename to _static/locales/et/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/et/LC_MESSAGES/booktheme.po b/_static/locales/et/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/et/LC_MESSAGES/booktheme.po rename to _static/locales/et/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/fi/LC_MESSAGES/booktheme.mo b/_static/locales/fi/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/fi/LC_MESSAGES/booktheme.mo rename to _static/locales/fi/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/fi/LC_MESSAGES/booktheme.po b/_static/locales/fi/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/fi/LC_MESSAGES/booktheme.po rename to _static/locales/fi/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/fr/LC_MESSAGES/booktheme.mo b/_static/locales/fr/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/fr/LC_MESSAGES/booktheme.mo rename to _static/locales/fr/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/fr/LC_MESSAGES/booktheme.po b/_static/locales/fr/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/fr/LC_MESSAGES/booktheme.po rename to _static/locales/fr/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/hr/LC_MESSAGES/booktheme.mo b/_static/locales/hr/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/hr/LC_MESSAGES/booktheme.mo rename to _static/locales/hr/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/hr/LC_MESSAGES/booktheme.po b/_static/locales/hr/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/hr/LC_MESSAGES/booktheme.po rename to _static/locales/hr/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/id/LC_MESSAGES/booktheme.mo b/_static/locales/id/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/id/LC_MESSAGES/booktheme.mo rename to _static/locales/id/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/id/LC_MESSAGES/booktheme.po b/_static/locales/id/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/id/LC_MESSAGES/booktheme.po rename to _static/locales/id/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/it/LC_MESSAGES/booktheme.mo b/_static/locales/it/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/it/LC_MESSAGES/booktheme.mo rename to _static/locales/it/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/it/LC_MESSAGES/booktheme.po b/_static/locales/it/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/it/LC_MESSAGES/booktheme.po rename to _static/locales/it/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/iw/LC_MESSAGES/booktheme.mo b/_static/locales/iw/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/iw/LC_MESSAGES/booktheme.mo rename to _static/locales/iw/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/iw/LC_MESSAGES/booktheme.po b/_static/locales/iw/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/iw/LC_MESSAGES/booktheme.po rename to _static/locales/iw/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/ja/LC_MESSAGES/booktheme.mo b/_static/locales/ja/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/ja/LC_MESSAGES/booktheme.mo rename to _static/locales/ja/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/ja/LC_MESSAGES/booktheme.po b/_static/locales/ja/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/ja/LC_MESSAGES/booktheme.po rename to _static/locales/ja/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/ko/LC_MESSAGES/booktheme.mo b/_static/locales/ko/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/ko/LC_MESSAGES/booktheme.mo rename to _static/locales/ko/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/ko/LC_MESSAGES/booktheme.po b/_static/locales/ko/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/ko/LC_MESSAGES/booktheme.po rename to _static/locales/ko/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/lt/LC_MESSAGES/booktheme.mo b/_static/locales/lt/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/lt/LC_MESSAGES/booktheme.mo rename to _static/locales/lt/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/lt/LC_MESSAGES/booktheme.po b/_static/locales/lt/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/lt/LC_MESSAGES/booktheme.po rename to _static/locales/lt/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/lv/LC_MESSAGES/booktheme.mo b/_static/locales/lv/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/lv/LC_MESSAGES/booktheme.mo rename to _static/locales/lv/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/lv/LC_MESSAGES/booktheme.po b/_static/locales/lv/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/lv/LC_MESSAGES/booktheme.po rename to _static/locales/lv/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/ml/LC_MESSAGES/booktheme.mo b/_static/locales/ml/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/ml/LC_MESSAGES/booktheme.mo rename to _static/locales/ml/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/ml/LC_MESSAGES/booktheme.po b/_static/locales/ml/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/ml/LC_MESSAGES/booktheme.po rename to _static/locales/ml/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/mr/LC_MESSAGES/booktheme.mo b/_static/locales/mr/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/mr/LC_MESSAGES/booktheme.mo rename to _static/locales/mr/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/mr/LC_MESSAGES/booktheme.po b/_static/locales/mr/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/mr/LC_MESSAGES/booktheme.po rename to _static/locales/mr/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/ms/LC_MESSAGES/booktheme.mo b/_static/locales/ms/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/ms/LC_MESSAGES/booktheme.mo rename to _static/locales/ms/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/ms/LC_MESSAGES/booktheme.po b/_static/locales/ms/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/ms/LC_MESSAGES/booktheme.po rename to _static/locales/ms/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/nl/LC_MESSAGES/booktheme.mo b/_static/locales/nl/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/nl/LC_MESSAGES/booktheme.mo rename to _static/locales/nl/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/nl/LC_MESSAGES/booktheme.po b/_static/locales/nl/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/nl/LC_MESSAGES/booktheme.po rename to _static/locales/nl/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/no/LC_MESSAGES/booktheme.mo b/_static/locales/no/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/no/LC_MESSAGES/booktheme.mo rename to _static/locales/no/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/no/LC_MESSAGES/booktheme.po b/_static/locales/no/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/no/LC_MESSAGES/booktheme.po rename to _static/locales/no/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/pl/LC_MESSAGES/booktheme.mo b/_static/locales/pl/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/pl/LC_MESSAGES/booktheme.mo rename to _static/locales/pl/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/pl/LC_MESSAGES/booktheme.po b/_static/locales/pl/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/pl/LC_MESSAGES/booktheme.po rename to _static/locales/pl/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/pt/LC_MESSAGES/booktheme.mo b/_static/locales/pt/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/pt/LC_MESSAGES/booktheme.mo rename to _static/locales/pt/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/pt/LC_MESSAGES/booktheme.po b/_static/locales/pt/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/pt/LC_MESSAGES/booktheme.po rename to _static/locales/pt/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/ro/LC_MESSAGES/booktheme.mo b/_static/locales/ro/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/ro/LC_MESSAGES/booktheme.mo rename to _static/locales/ro/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/ro/LC_MESSAGES/booktheme.po b/_static/locales/ro/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/ro/LC_MESSAGES/booktheme.po rename to _static/locales/ro/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/ru/LC_MESSAGES/booktheme.mo b/_static/locales/ru/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/ru/LC_MESSAGES/booktheme.mo rename to _static/locales/ru/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/ru/LC_MESSAGES/booktheme.po b/_static/locales/ru/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/ru/LC_MESSAGES/booktheme.po rename to _static/locales/ru/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/sk/LC_MESSAGES/booktheme.mo b/_static/locales/sk/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/sk/LC_MESSAGES/booktheme.mo rename to _static/locales/sk/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/sk/LC_MESSAGES/booktheme.po b/_static/locales/sk/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/sk/LC_MESSAGES/booktheme.po rename to _static/locales/sk/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/sl/LC_MESSAGES/booktheme.mo b/_static/locales/sl/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/sl/LC_MESSAGES/booktheme.mo rename to _static/locales/sl/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/sl/LC_MESSAGES/booktheme.po b/_static/locales/sl/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/sl/LC_MESSAGES/booktheme.po rename to _static/locales/sl/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/sr/LC_MESSAGES/booktheme.mo b/_static/locales/sr/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/sr/LC_MESSAGES/booktheme.mo rename to _static/locales/sr/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/sr/LC_MESSAGES/booktheme.po b/_static/locales/sr/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/sr/LC_MESSAGES/booktheme.po rename to _static/locales/sr/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/sv/LC_MESSAGES/booktheme.mo b/_static/locales/sv/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/sv/LC_MESSAGES/booktheme.mo rename to _static/locales/sv/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/sv/LC_MESSAGES/booktheme.po b/_static/locales/sv/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/sv/LC_MESSAGES/booktheme.po rename to _static/locales/sv/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/ta/LC_MESSAGES/booktheme.mo b/_static/locales/ta/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/ta/LC_MESSAGES/booktheme.mo rename to _static/locales/ta/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/ta/LC_MESSAGES/booktheme.po b/_static/locales/ta/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/ta/LC_MESSAGES/booktheme.po rename to _static/locales/ta/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/te/LC_MESSAGES/booktheme.mo b/_static/locales/te/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/te/LC_MESSAGES/booktheme.mo rename to _static/locales/te/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/te/LC_MESSAGES/booktheme.po b/_static/locales/te/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/te/LC_MESSAGES/booktheme.po rename to _static/locales/te/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/tg/LC_MESSAGES/booktheme.mo b/_static/locales/tg/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/tg/LC_MESSAGES/booktheme.mo rename to _static/locales/tg/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/tg/LC_MESSAGES/booktheme.po b/_static/locales/tg/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/tg/LC_MESSAGES/booktheme.po rename to _static/locales/tg/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/th/LC_MESSAGES/booktheme.mo b/_static/locales/th/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/th/LC_MESSAGES/booktheme.mo rename to _static/locales/th/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/th/LC_MESSAGES/booktheme.po b/_static/locales/th/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/th/LC_MESSAGES/booktheme.po rename to _static/locales/th/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/tl/LC_MESSAGES/booktheme.mo b/_static/locales/tl/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/tl/LC_MESSAGES/booktheme.mo rename to _static/locales/tl/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/tl/LC_MESSAGES/booktheme.po b/_static/locales/tl/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/tl/LC_MESSAGES/booktheme.po rename to _static/locales/tl/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/tr/LC_MESSAGES/booktheme.mo b/_static/locales/tr/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/tr/LC_MESSAGES/booktheme.mo rename to _static/locales/tr/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/tr/LC_MESSAGES/booktheme.po b/_static/locales/tr/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/tr/LC_MESSAGES/booktheme.po rename to _static/locales/tr/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/uk/LC_MESSAGES/booktheme.mo b/_static/locales/uk/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/uk/LC_MESSAGES/booktheme.mo rename to _static/locales/uk/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/uk/LC_MESSAGES/booktheme.po b/_static/locales/uk/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/uk/LC_MESSAGES/booktheme.po rename to _static/locales/uk/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/ur/LC_MESSAGES/booktheme.mo b/_static/locales/ur/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/ur/LC_MESSAGES/booktheme.mo rename to _static/locales/ur/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/ur/LC_MESSAGES/booktheme.po b/_static/locales/ur/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/ur/LC_MESSAGES/booktheme.po rename to _static/locales/ur/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/vi/LC_MESSAGES/booktheme.mo b/_static/locales/vi/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/vi/LC_MESSAGES/booktheme.mo rename to _static/locales/vi/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/vi/LC_MESSAGES/booktheme.po b/_static/locales/vi/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/vi/LC_MESSAGES/booktheme.po rename to _static/locales/vi/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/zh_CN/LC_MESSAGES/booktheme.mo b/_static/locales/zh_CN/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/zh_CN/LC_MESSAGES/booktheme.mo rename to _static/locales/zh_CN/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/zh_CN/LC_MESSAGES/booktheme.po b/_static/locales/zh_CN/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/zh_CN/LC_MESSAGES/booktheme.po rename to _static/locales/zh_CN/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/locales/zh_TW/LC_MESSAGES/booktheme.mo b/_static/locales/zh_TW/LC_MESSAGES/booktheme.mo similarity index 100% rename from _build/html/_static/locales/zh_TW/LC_MESSAGES/booktheme.mo rename to _static/locales/zh_TW/LC_MESSAGES/booktheme.mo diff --git a/_build/html/_static/locales/zh_TW/LC_MESSAGES/booktheme.po b/_static/locales/zh_TW/LC_MESSAGES/booktheme.po similarity index 100% rename from _build/html/_static/locales/zh_TW/LC_MESSAGES/booktheme.po rename to _static/locales/zh_TW/LC_MESSAGES/booktheme.po diff --git a/_build/html/_static/minus.png b/_static/minus.png similarity index 100% rename from _build/html/_static/minus.png rename to _static/minus.png diff --git a/_build/html/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css b/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css similarity index 100% rename from _build/html/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css rename to _static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css diff --git a/_build/html/_static/plus.png b/_static/plus.png similarity index 100% rename from _build/html/_static/plus.png rename to _static/plus.png diff --git a/_build/html/_static/pygments.css b/_static/pygments.css similarity index 100% rename from _build/html/_static/pygments.css rename to _static/pygments.css diff --git a/_build/html/_static/sbt-webpack-macros.html b/_static/sbt-webpack-macros.html similarity index 100% rename from _build/html/_static/sbt-webpack-macros.html rename to _static/sbt-webpack-macros.html diff --git a/_build/html/_static/scripts/bootstrap.js b/_static/scripts/bootstrap.js similarity index 100% rename from _build/html/_static/scripts/bootstrap.js rename to _static/scripts/bootstrap.js diff --git a/_build/html/_static/scripts/bootstrap.js.LICENSE.txt b/_static/scripts/bootstrap.js.LICENSE.txt similarity index 100% rename from _build/html/_static/scripts/bootstrap.js.LICENSE.txt rename to _static/scripts/bootstrap.js.LICENSE.txt diff --git a/_build/html/_static/scripts/bootstrap.js.map b/_static/scripts/bootstrap.js.map similarity index 100% rename from _build/html/_static/scripts/bootstrap.js.map rename to _static/scripts/bootstrap.js.map diff --git a/_build/html/_static/scripts/pydata-sphinx-theme.js b/_static/scripts/pydata-sphinx-theme.js similarity index 100% rename from _build/html/_static/scripts/pydata-sphinx-theme.js rename to _static/scripts/pydata-sphinx-theme.js diff --git a/_build/html/_static/scripts/pydata-sphinx-theme.js.map b/_static/scripts/pydata-sphinx-theme.js.map similarity index 100% rename from _build/html/_static/scripts/pydata-sphinx-theme.js.map rename to _static/scripts/pydata-sphinx-theme.js.map diff --git a/_build/html/_static/scripts/sphinx-book-theme.js b/_static/scripts/sphinx-book-theme.js similarity index 100% rename from _build/html/_static/scripts/sphinx-book-theme.js rename to _static/scripts/sphinx-book-theme.js diff --git a/_build/html/_static/scripts/sphinx-book-theme.js.map b/_static/scripts/sphinx-book-theme.js.map similarity index 100% rename from _build/html/_static/scripts/sphinx-book-theme.js.map rename to _static/scripts/sphinx-book-theme.js.map diff --git a/_build/html/_static/searchtools.js b/_static/searchtools.js similarity index 100% rename from _build/html/_static/searchtools.js rename to _static/searchtools.js diff --git a/_build/html/_static/sphinx-thebe.css b/_static/sphinx-thebe.css similarity index 100% rename from _build/html/_static/sphinx-thebe.css rename to _static/sphinx-thebe.css diff --git a/_build/html/_static/sphinx-thebe.js b/_static/sphinx-thebe.js similarity index 100% rename from _build/html/_static/sphinx-thebe.js rename to _static/sphinx-thebe.js diff --git a/_build/html/_static/styles/bootstrap.css b/_static/styles/bootstrap.css similarity index 100% rename from _build/html/_static/styles/bootstrap.css rename to _static/styles/bootstrap.css diff --git a/_build/html/_static/styles/bootstrap.css.map b/_static/styles/bootstrap.css.map similarity index 100% rename from _build/html/_static/styles/bootstrap.css.map rename to _static/styles/bootstrap.css.map diff --git a/_build/html/_static/styles/pydata-sphinx-theme.css b/_static/styles/pydata-sphinx-theme.css similarity index 100% rename from _build/html/_static/styles/pydata-sphinx-theme.css rename to _static/styles/pydata-sphinx-theme.css diff --git a/_build/html/_static/styles/pydata-sphinx-theme.css.map b/_static/styles/pydata-sphinx-theme.css.map similarity index 100% rename from _build/html/_static/styles/pydata-sphinx-theme.css.map rename to _static/styles/pydata-sphinx-theme.css.map diff --git a/_build/html/_static/styles/sphinx-book-theme.css b/_static/styles/sphinx-book-theme.css similarity index 100% rename from _build/html/_static/styles/sphinx-book-theme.css rename to _static/styles/sphinx-book-theme.css diff --git a/_build/html/_static/styles/theme.css b/_static/styles/theme.css similarity index 100% rename from _build/html/_static/styles/theme.css rename to _static/styles/theme.css diff --git a/_build/html/_static/togglebutton.css b/_static/togglebutton.css similarity index 100% rename from _build/html/_static/togglebutton.css rename to _static/togglebutton.css diff --git a/_build/html/_static/togglebutton.js b/_static/togglebutton.js similarity index 100% rename from _build/html/_static/togglebutton.js rename to _static/togglebutton.js diff --git a/_build/html/_static/underscore-1.13.1.js b/_static/underscore-1.13.1.js similarity index 100% rename from _build/html/_static/underscore-1.13.1.js rename to _static/underscore-1.13.1.js diff --git a/_build/html/_static/underscore.js b/_static/underscore.js similarity index 100% rename from _build/html/_static/underscore.js rename to _static/underscore.js diff --git a/_build/html/_static/vendor/fontawesome/6.1.2/LICENSE.txt b/_static/vendor/fontawesome/6.1.2/LICENSE.txt similarity index 100% rename from _build/html/_static/vendor/fontawesome/6.1.2/LICENSE.txt rename to _static/vendor/fontawesome/6.1.2/LICENSE.txt diff --git a/_build/html/_static/vendor/fontawesome/6.1.2/css/all.min.css b/_static/vendor/fontawesome/6.1.2/css/all.min.css similarity index 100% rename from _build/html/_static/vendor/fontawesome/6.1.2/css/all.min.css rename to _static/vendor/fontawesome/6.1.2/css/all.min.css diff --git a/_build/html/_static/vendor/fontawesome/6.1.2/js/all.min.js b/_static/vendor/fontawesome/6.1.2/js/all.min.js similarity index 100% rename from _build/html/_static/vendor/fontawesome/6.1.2/js/all.min.js rename to _static/vendor/fontawesome/6.1.2/js/all.min.js diff --git a/_build/html/_static/vendor/fontawesome/6.1.2/js/all.min.js.LICENSE.txt b/_static/vendor/fontawesome/6.1.2/js/all.min.js.LICENSE.txt similarity index 100% rename from _build/html/_static/vendor/fontawesome/6.1.2/js/all.min.js.LICENSE.txt rename to _static/vendor/fontawesome/6.1.2/js/all.min.js.LICENSE.txt diff --git a/_build/html/_static/vendor/fontawesome/6.1.2/webfonts/fa-brands-400.ttf b/_static/vendor/fontawesome/6.1.2/webfonts/fa-brands-400.ttf similarity index 100% rename from _build/html/_static/vendor/fontawesome/6.1.2/webfonts/fa-brands-400.ttf rename to _static/vendor/fontawesome/6.1.2/webfonts/fa-brands-400.ttf diff --git a/_build/html/_static/vendor/fontawesome/6.1.2/webfonts/fa-brands-400.woff2 b/_static/vendor/fontawesome/6.1.2/webfonts/fa-brands-400.woff2 similarity index 100% rename from _build/html/_static/vendor/fontawesome/6.1.2/webfonts/fa-brands-400.woff2 rename to _static/vendor/fontawesome/6.1.2/webfonts/fa-brands-400.woff2 diff --git a/_build/html/_static/vendor/fontawesome/6.1.2/webfonts/fa-regular-400.ttf b/_static/vendor/fontawesome/6.1.2/webfonts/fa-regular-400.ttf similarity index 100% rename from _build/html/_static/vendor/fontawesome/6.1.2/webfonts/fa-regular-400.ttf rename to _static/vendor/fontawesome/6.1.2/webfonts/fa-regular-400.ttf diff --git a/_build/html/_static/vendor/fontawesome/6.1.2/webfonts/fa-regular-400.woff2 b/_static/vendor/fontawesome/6.1.2/webfonts/fa-regular-400.woff2 similarity index 100% rename from _build/html/_static/vendor/fontawesome/6.1.2/webfonts/fa-regular-400.woff2 rename to _static/vendor/fontawesome/6.1.2/webfonts/fa-regular-400.woff2 diff --git a/_build/html/_static/vendor/fontawesome/6.1.2/webfonts/fa-solid-900.ttf b/_static/vendor/fontawesome/6.1.2/webfonts/fa-solid-900.ttf similarity index 100% rename from _build/html/_static/vendor/fontawesome/6.1.2/webfonts/fa-solid-900.ttf rename to _static/vendor/fontawesome/6.1.2/webfonts/fa-solid-900.ttf diff --git a/_build/html/_static/vendor/fontawesome/6.1.2/webfonts/fa-solid-900.woff2 b/_static/vendor/fontawesome/6.1.2/webfonts/fa-solid-900.woff2 similarity index 100% rename from _build/html/_static/vendor/fontawesome/6.1.2/webfonts/fa-solid-900.woff2 rename to _static/vendor/fontawesome/6.1.2/webfonts/fa-solid-900.woff2 diff --git a/_build/html/_static/vendor/fontawesome/6.1.2/webfonts/fa-v4compatibility.ttf b/_static/vendor/fontawesome/6.1.2/webfonts/fa-v4compatibility.ttf similarity index 100% rename from _build/html/_static/vendor/fontawesome/6.1.2/webfonts/fa-v4compatibility.ttf rename to _static/vendor/fontawesome/6.1.2/webfonts/fa-v4compatibility.ttf diff --git a/_build/html/_static/vendor/fontawesome/6.1.2/webfonts/fa-v4compatibility.woff2 b/_static/vendor/fontawesome/6.1.2/webfonts/fa-v4compatibility.woff2 similarity index 100% rename from _build/html/_static/vendor/fontawesome/6.1.2/webfonts/fa-v4compatibility.woff2 rename to _static/vendor/fontawesome/6.1.2/webfonts/fa-v4compatibility.woff2 diff --git a/_build/html/_static/webpack-macros.html b/_static/webpack-macros.html similarity index 100% rename from _build/html/_static/webpack-macros.html rename to _static/webpack-macros.html diff --git a/_toc.yml b/_toc.yml deleted file mode 100644 index 0e4e1db..0000000 --- a/_toc.yml +++ /dev/null @@ -1,88 +0,0 @@ -format: jb-book -root: README -chapters: - - file: 01. Array Hashing/README - sections: - - file: 01. Array Hashing/1. Two Sum - - file: 01. Array Hashing/128. Longest Consecutive Sequence - - file: 01. Array Hashing/217. Contains Duplicate - - file: 01. Array Hashing/238. Product of Array Except Self - - file: 01. Array Hashing/242. Valid Anagram - - file: 01. Array Hashing/347. Top K Frequent Elements - - file: 01. Array Hashing/49. Group Anagrams - - file: 01. Array Hashing/659. Encode and Decode Strings - - file: 02. Two Pointers/README - sections: - - file: 02. Two Pointers/11. Container With Most Water - - file: 02. Two Pointers/125. Valid Palindrome - - file: 02. Two Pointers/15. 3Sum - - file: 03. Sliding Window/README - sections: - - file: 03. Sliding Window/121. Best Time to Buy and Sell Stock - - file: 03. Sliding Window/3. Longest Substring Without Repeating Characters - - file: 03. Sliding Window/424. Longest Repeating Character Replacement - - file: 03. Sliding Window/76. Minimum Window Substring - - file: 04. Stack/README - sections: - - file: 04. Stack/20. Valid Parentheses - - file: 05. Binary Search/README - sections: - - file: 05. Binary Search/153. Find Minimum in Rotated Sorted Array - - file: 05. Binary Search/33. Search in Rotated Sorted Array - - file: 06. Linked List/README - sections: - - file: 06. Linked List/141. Linked List Cycle - - file: 06. Linked List/143. Reorder List - - file: 06. Linked List/19. Remove Nth Node From End of List - - file: 06. Linked List/206. Reverse Linked List - - file: 06. Linked List/21. Merge Two Sorted Lists - - file: 06. Linked List/23. Merge k Sorted Lists - - file: 07. Trees/README - sections: - - file: 07. Trees/100. Same Tree - - file: 07. Trees/102. Binary Tree Level Order Traversal - - file: 07. Trees/104. Maximum Depth of Binary Tree - - file: 07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal - - file: 07. Trees/124. Binary Tree Maximum Path Sum - - file: 07. Trees/199. Binary Tree Right Side View - - file: 07. Trees/226. Invert Binary Tree - - file: 07. Trees/230. Kth Smallest Element in a BST - - file: 07. Trees/235. Lowest Common Ancestor of a Binary Search Tree - - file: 07. Trees/297. Serialize and Deserialize Binary Tree - - file: 07. Trees/572. Subtree of Another Tree - - file: 07. Trees/98. Validate Binary Search Tree - - file: 08. Tries/README - sections: - - file: 08. Tries/208. Implement Trie (Prefix Tree) - - file: 08. Tries/211. Design Add and Search Words Data Structure - - file: 08. Tries/212. Word Search II - - file: 09. Heap - Priority Queue/README - sections: - - file: 09. Heap - Priority Queue/1046. Last Stone Weight - - file: 09. Heap - Priority Queue/295. Find Median from Data Stream - - file: 09. Heap - Priority Queue/703. Kth Largest Element in a Stream - - file: 10. Backtracking/README - sections: - - file: 10. Backtracking/39. Combination Sum - - file: 10. Backtracking/79. Word Search - - file: 11. Graphs/README - sections: - - file: 11. Graphs/133. Clone Graph - - file: 11. Graphs/178. Graph Valid Tree - - file: 11. Graphs/200. Number of Islands - - file: 11. Graphs/207. Course Schedule - - file: 11. Graphs/3651. Number of Connected Components in an Undirected Graph - - file: 11. Graphs/417. Pacific Atlantic Water Flow - - file: 12. Advanced Graphs/README - sections: - - file: 12. Advanced Graphs/892. Alien Dictionary - - file: 13. One-D Dynamic Programming/README - sections: - - file: 13. One-D Dynamic Programming/70. Climbing Stairs - - file: 13. One-D Dynamic Programming/198. House Robber - - file: 13. One-D Dynamic Programming/213. House Robber II - - file: 14. Two-D Dynamic Programming/README - - file: 15. Greedy/README - - file: 16. Intervals/README - - file: 17. Math Geometry/README - - file: 18. Bit Manipulation/README \ No newline at end of file diff --git a/docs/01. Array Hashing/1. Two Sum.ipynb b/docs/01. Array Hashing/1. Two Sum.ipynb deleted file mode 100644 index b3b517f..0000000 --- a/docs/01. Array Hashing/1. Two Sum.ipynb +++ /dev/null @@ -1,211 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 100: Same Tree\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Same Tree problem on LeetCode, click here!](https://leetcode.com/problems/same-tree/)\n", - "\n", - "---\n", - "Given the roots of two binary trees `p` and `q`, write a function to check if they are the same or not.\n", - "\n", - "Two binary trees are considered the same if they are structurally identical, and the nodes have the same value.\n", - "\n", - "**Constraints**\n", - "\n", - "1. The number of nodes in both trees is in the range `[0, 100]`.\n", - "2. $-10^4$ <= `Node.val` <= $10^4$" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for a binary tree node.\n", - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " # Initialize a TreeNode with a value (val), left child, and right child.\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def isSameTree(p, q):\n", - " # Base case: If both p and q are None, the trees are the same.\n", - " if not p and not q:\n", - " return True\n", - " \n", - " # Base case: If either p or q is None (but not both), the trees are different.\n", - " if not p or not q:\n", - " return False\n", - " \n", - " # Check if the values of the current nodes (p.val and q.val) are equal.\n", - " if p.val != q.val:\n", - " return False\n", - " \n", - " # Recursively check the left and right subtrees of p and q.\n", - " # If both subtrees are the same, the entire trees are the same.\n", - " return isSameTree(p.left, q.left) and isSameTree(p.right, q.right)" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "In this code, we define a `TreeNode` class to represent binary tree nodes and a `isSameTree` function to check if two binary trees are the same. The function uses recursive traversal to compare the trees' structures and values.\n", - "\n", - "1. We start by defining a `TreeNode` class, which represents a node in a binary tree. Each node has a `val` (the node's value), a `left` child, and a right child. This class will help us create and work with binary trees.\n", - "2. Next, we define the `isSameTree` function, which checks if two binary trees (`p` and `q`) are the same.\n", - " + The base case for the recursion is when both `p` and `q` are `None`. In this case, they are considered the same, so we return `True`.\n", - " + If either `p` or `q` is `None` (but not both), they cannot be the same, so we return `False`.\n", - " + If the values of the current nodes `p.val` and `q.val` are not equal, we return `False` because the trees cannot be the same.\n", - " + Finally, we recursively check the left and right subtrees of `p` and `q` to see if they are the same." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "### Example 1\n", - "\n", - "#Input: `p = [1,2,3]`, `q = [1,2,3]`\n", - "\n", - "p1 = TreeNode(1, TreeNode(2), TreeNode(3))\n", - "q1 = TreeNode(1, TreeNode(2), TreeNode(3))\n", - "print(isSameTree(p1, q1)) " - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "### Example 2\n", - "\n", - "#Input: `p = [1,2]`, `q = [1,null,2]`\n", - "\n", - "p2 = TreeNode(1, TreeNode(2), None)\n", - "q2 = TreeNode(1, None, TreeNode(2))\n", - "print(isSameTree(p2, q2))" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "5897c29d-26f8-486a-878c-43c09ff25ce4", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "### Example 3\n", - "\n", - "#Input: p = [1,2,1], q = [1,1,2]\n", - "\n", - "p3 = TreeNode(1, TreeNode(2), TreeNode(1))\n", - "q3 = TreeNode(1, TreeNode(1), TreeNode(2))\n", - "print(isSameTree(p3, q3))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "**Time Complexity**\n", - "\n", - "The time complexity of the `isSameTree` function can be analyzed as follows:\n", - "\n", - "In the worst case, the function needs to visit every node in both trees once to determine if they are the same.\n", - "Since each node is visited exactly once, the time complexity is $O(n)$, where $n$ is the total number of nodes in the input trees.\n", - "\n", - "**Space Complexity**\n", - "The space complexity of the `isSameTree` function can be analyzed as follows:\n", - "\n", - "The space used by the function's call stack during recursion is proportional to the maximum depth of the binary trees.\n", - "In the worst case, when the trees are completely unbalanced (all nodes form a single branch), the maximum depth will be $n$, where $n$ is the total number of nodes in the input trees.\n", - "Therefore, the space complexity is $O(n)$ due to the recursive call stack.\n", - "In addition to the call stack, there is a small constant amount of space used for variables and comparisons within each recursive call, but this space is not significant in terms of the overall space complexity.\n", - "\n", - "**In summary:**\n", - "\n", - "+ Time Complexity: $O(n)$ where $n$ is the total number of nodes in the input trees.\n", - "+ Space Complexity: $O(n)$ due to the recursive call stack." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/01. Array Hashing/128. Longest Consecutive Sequence.ipynb b/docs/01. Array Hashing/128. Longest Consecutive Sequence.ipynb deleted file mode 100644 index a77a03d..0000000 --- a/docs/01. Array Hashing/128. Longest Consecutive Sequence.ipynb +++ /dev/null @@ -1,209 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 128. Longest Consecutive Sequence\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Longest Consecutive Sequence problem on LeetCode, click here!](https://leetcode.com/problems/longest-consecutive-sequence/)\n", - "\n", - "---\n", - "\n", - "Given an unsorted array of integers `nums`, return *the length of the longest consecutive elements sequence.*\n", - "\n", - "You must write an algorithm that runs in `O(n)` time.\n", - "\n", - "*Constraints:**\n", - "- 0 <= `nums.length` <= $10^5$\n", - "- $-10^9$ <= `nums[i]` <= $10^9$\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 58, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def longestConsecutive(nums):\n", - " if not nums:\n", - " return 0\n", - "\n", - " num_set = set(nums)\n", - " max_length = 0\n", - "\n", - " for num in num_set:\n", - " if num - 1 not in num_set:\n", - " current_num = num\n", - " current_length = 1\n", - "\n", - " while current_num + 1 in num_set:\n", - " current_num += 1\n", - " current_length += 1\n", - "\n", - " max_length = max(max_length, current_length)\n", - "\n", - " return max_length" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start by defining the `longestConsecutive` function that takes the `nums` array as input.\n", - "\n", - "2. We check if the `nums` array is empty. If it's empty, there are no consecutive elements, so we return 0.\n", - "\n", - "3. We create a Python set called `num_set` and insert all elements from the `nums` array into it. Using a set allows us to efficiently check for the existence of elements in O(1) time.\n", - "\n", - "4. We initialize a variable `max_length` to 0. This variable will keep track of the maximum length of consecutive elements sequence found.\n", - "\n", - "5. We iterate through the elements of the `num_set`. For each element `num`, we check if `num - 1` exists in the `num_set`. If it doesn't exist, it means `num` is the starting element of a potential consecutive sequence.\n", - "\n", - "6. Inside the loop, we initialize two variables: `current_num` to the current element `num` and `current_length` to 1. We start with a length of 1 because `num` itself is part of the sequence.\n", - "\n", - "7. We then enter a while loop that continues as long as `current_num + 1` exists in the `num_set`. This means we are incrementing the consecutive sequence.\n", - "\n", - "8. Inside the while loop, we increment `current_num` by 1 and also increment `current_length` by 1 to account for the next consecutive element.\n", - "\n", - "9. We compare `current_length` with the `max_length` and update `max_length` if the current sequence is longer.\n", - "\n", - "10. After the while loop, we move to the next element in the outer loop and repeat the process.\n", - "\n", - "11. Finally, we return the `max_length` as the result, which represents the length of the longest consecutive elements sequence in the `nums` array.\n", - "\n", - "The key idea here is to use a set to efficiently check for the existence of elements and to iterate through the elements, considering each element as the potential start of a consecutive sequence. By doing this, we can find the longest consecutive sequence in O(n) time complexity, where n is the number of elements in the array." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 59, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "nums1 = [100, 4, 200, 1, 3, 2]\n", - "print(longestConsecutive(nums1))" - ] - }, - { - "cell_type": "code", - "execution_count": 60, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "9\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "nums2 = [0, 3, 7, 2, 5, 8, 4, 6, 0, 1]\n", - "print(longestConsecutive(nums2)) " - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "The code is designed to run in O(n) time complexity, where n is the number of elements in the `nums` array. Here's the breakdown:\n", - "\n", - "1. Constructing the `num_set` by inserting all elements from `nums` into it takes O(n) time because we perform an insertion operation for each element in `nums`.\n", - "\n", - "2. The main loop iterates through the elements in `num_set`. In the worst case, each element is visited only once, so the loop itself takes O(n) time.\n", - "\n", - "3. Within the loop, we have a while loop that may also take O(n) time in the worst case. However, this while loop is nested inside the main loop, so its overall time complexity remains O(n).\n", - "\n", - "Therefore, the overall time complexity of the code is O(n).\n", - "\n", - "**Space Complexity:**\n", - "The space complexity of the code is determined by the space used by the `num_set` and a few additional variables. Here's the breakdown:\n", - "\n", - "1. `num_set` is a set that stores the unique elements from `nums`. In the worst case, it can store all n elements from `nums`, so the space complexity is O(n).\n", - "\n", - "2. The additional variables used, such as `max_length`, `current_num`, and `current_length`, have constant space requirements and do not depend on the size of the input array.\n", - "\n", - "Therefore, the overall space complexity of the code is O(n) due to the space used by the `num_set`." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. Write an algorithm that not only returns the length of the longest consecutive elements sequence but also returns the actual consecutive sequence itself.\n", - "\n", - "2. Extend the problem to allow elements to be considered consecutive if they are within a certain absolute difference (e.g., less than or equal to k) instead of exactly 1. Write an algorithm that finds the longest such sequence and runs in O(n) time." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/01. Array Hashing/217. Contains Duplicate.ipynb b/docs/01. Array Hashing/217. Contains Duplicate.ipynb deleted file mode 100644 index 57bb55d..0000000 --- a/docs/01. Array Hashing/217. Contains Duplicate.ipynb +++ /dev/null @@ -1,218 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 217. Contains Duplicate\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Contains Duplicate problem on LeetCode, click here!](https://leetcode.com/problems/contains-duplicate/)\n", - "\n", - "---\n", - "\n", - "Given an integer array `nums`, return `true` if any value appears **at least twice** in the array, and return `false` if every element is distinct.\n", - "\n", - "**Constraints:**\n", - "- 1 <= `nums.length` <= $10^5$\n", - "- $-10^9$ <= `nums[i]` <= $10^9$\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def containsDuplicate(nums):\n", - " # Create an empty set to store unique elements\n", - " unique_elements = set()\n", - " \n", - " # Iterate through the array\n", - " for num in nums:\n", - " # If the element is already in the set, return True\n", - " if num in unique_elements:\n", - " return True\n", - " # Otherwise, add it to the set\n", - " else:\n", - " unique_elements.add(num)\n", - " \n", - " # If the loop completes without finding duplicates, return False\n", - " return False" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. The `containsDuplicate` function takes a single argument, `nums`, which is the input integer array.\n", - "\n", - "2. Inside the function, an empty set called `unique_elements` is created. This set will be used to keep track of unique elements in the input array.\n", - "\n", - "3. The function then iterates through the input array `nums` using a `for` loop.\n", - "\n", - "4. For each element `num` in the array, it checks whether `num` is already in the `unique_elements` set using the `if num in unique_elements:` condition.\n", - "\n", - "5. If `num` is already in the set, it means there is a duplicate element in the array, and the function immediately returns `True`.\n", - "\n", - "6. If `num` is not in the set, it is added to the `unique_elements` set using `unique_elements.add(num)`.\n", - "\n", - "7. The loop continues to the next element, and the process repeats.\n", - "\n", - "8. If the loop completes without finding any duplicates, it means that all elements in the array are distinct, and the function returns `False`.\n", - "\n", - "The code efficiently utilizes a set data structure to keep track of unique elements while iterating through the array, allowing it to quickly detect duplicate elements. This code meets the problem's requirements and constraints, as explained earlier." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "nums1 = [1, 2, 3, 1]\n", - "print(containsDuplicate(nums1))" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 2\n", - "nums2 = [1, 2, 3, 4]\n", - "print(containsDuplicate(nums2))" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "e191cf7e-95f9-4e5c-a99b-146c2a779c0b", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 3\n", - "nums3 = [1, 1, 1, 3, 3, 4, 3, 2, 4, 2]\n", - "print(containsDuplicate(nums3))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code for the \"Contains Duplicate\" problem:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The primary operation that affects the time complexity is the `for` loop that iterates through the input array `nums`. In the worst case, the loop will iterate through all `n` elements of the array, where `n` is the length of the input array.\n", - "\n", - "- Iterating through the array: O(n)\n", - "\n", - "Inside the loop, we perform two operations:\n", - "\n", - "1. Checking whether an element exists in the `unique_elements` set (`if num in unique_elements`). This operation has an average time complexity of O(1) for a set.\n", - "2. Adding an element to the `unique_elements` set (`unique_elements.add(num)`), which also has an average time complexity of O(1) for a set.\n", - "\n", - "Since these operations are performed for each element in the array, the overall time complexity remains O(n).\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity is determined by the additional data structures used in the code, which are the `unique_elements` set.\n", - "\n", - "- `unique_elements` set: This set stores unique elements from the input array. In the worst case, if all elements in the input array are distinct, the set will store all `n` elements.\n", - "\n", - "Therefore, the space complexity is O(n) because, in the worst case, the set's size will grow linearly with the input array's size.\n", - "\n", - "**In summary**, the time complexity of the code is O(n), where `n` is the length of the input array, and the space complexity is also O(n) in the worst case. This code is efficient and meets the constraints of the problem." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **K Duplicates:** Modify the problem to return `true` if there are exactly K duplicate elements in the array. Write a function that takes an additional integer parameter K and returns `true` if there are exactly K duplicates.\n", - "2. **Frequency Count:** Write a function that returns a list of all the elements that appear more than once in the array, along with their frequencies." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/01. Array Hashing/238. Product of Array Except Self.ipynb b/docs/01. Array Hashing/238. Product of Array Except Self.ipynb deleted file mode 100644 index 1ff9a9c..0000000 --- a/docs/01. Array Hashing/238. Product of Array Except Self.ipynb +++ /dev/null @@ -1,197 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 238. Product of Array Except Self\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Product of Array Except Self problem on LeetCode, click here!](https://leetcode.com/problems/product-of-array-except-self/)\n", - "\n", - "---\n", - "Given an integer array `nums`, return *an array `answer` such that `answer[i]` is equal to the product of all the elements of `nums` except `nums[i]`.*\n", - "\n", - "The product of any prefix or suffix of `nums` is **guaranteed** to fit in a **32-bit** integer.\n", - "\n", - "You must write an algorithm that runs in O(n) time and without using the division operation.\n", - "\n", - "Constraints:\n", - "- 2 <= `nums.length` <= $10^5$\n", - "- `-30 <= nums[i] <= 30`\n", - "- The product of any prefix or suffix of `nums` is **guaranteed** to fit in a **32-bit** integer.\n", - "\n", - "**Follow-up:** Can you solve the problem in O(1) extra space complexity? (The output array **does not** count as extra space for space complexity analysis.)\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def productExceptSelf(nums):\n", - " n = len(nums)\n", - " \n", - " # Initialize two arrays to store products to the left and right of each element\n", - " left_products = [1] * n\n", - " right_products = [1] * n\n", - " \n", - " # Calculate products to the left of each element\n", - " left_product = 1\n", - " for i in range(n):\n", - " left_products[i] = left_product\n", - " left_product *= nums[i]\n", - " \n", - " # Calculate products to the right of each element\n", - " right_product = 1\n", - " for i in range(n - 1, -1, -1):\n", - " right_products[i] = right_product\n", - " right_product *= nums[i]\n", - " \n", - " # Calculate the final answer using left and right products\n", - " answer = [left_products[i] * right_products[i] for i in range(n)]\n", - " \n", - " return answer" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. `n` is initialized as the length of the `nums` array.\n", - "2. Two arrays, `left_products` and `right_products`, are created, each with a length of `n` and filled with ones initially.\n", - "3. `left_product` is initialized to 1.\n", - "4. A loop iterates through the `nums` array, from left to right. For each element at index `i`, it stores the product of all elements to its left (including itself) in the `left_products` array and updates `left_product` accordingly.\n", - "5. `right_product` is initialized to 1.\n", - "6. Another loop iterates through the `nums` array in reverse order, from right to left. For each element at index `i`, it stores the product of all elements to its right (including itself) in the `right_products` array and updates `right_product`.\n", - "7. The final `answer` list is constructed by multiplying corresponding elements from the `left_products` and `right_products` arrays for each index `i`.\n", - "8. The function returns the `answer` list, which contains the desired results.\n", - "\n", - "Overall, this algorithm efficiently computes the product of all elements except the current element, as required. It runs in O(n) time complexity and uses O(n) extra space, which is within the problem's constraints." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[24, 12, 8, 6]\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "nums = [1,2,3,4]\n", - "result1 = productExceptSelf(nums)\n", - "print(result1)" - ] - }, - { - "cell_type": "code", - "execution_count": 53, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[0, 0, 9, 0, 0]\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "nums = [-1,1,0,-3,3]\n", - "result2 = productExceptSelf(nums)\n", - "print(result2)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "1. The first loop iterates through the `nums` array to calculate the products to the left of each element. This loop runs in O(n) time, where n is the length of the `nums` array.\n", - "2. The second loop also iterates through the `nums` array in reverse order to calculate the products to the right of each element. This loop also runs in O(n) time.\n", - "3. The final loop constructs the `answer` list by multiplying elements from the `left_products` and `right_products` arrays. This loop runs in O(n) time.\n", - "\n", - "Since all the loops are independent and sequential, the overall time complexity is O(n).\n", - "\n", - "**Space Complexity:**\n", - "1. Two additional arrays, `left_products` and `right_products`, are created with a length of `n`, where `n` is the length of the `nums` array. Therefore, these arrays consume O(n) extra space.\n", - "2. The `left_product` and `right_product` variables are used to keep track of the product to the left and right of each element, respectively. These variables occupy O(1) extra space.\n", - "3. The `answer` list, which contains the final results, also consumes O(n) space, but it's not counted toward the extra space complexity analysis as per the problem's constraints.\n", - "\n", - "Overall, the space complexity is O(n) for this solution." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Handle Zeros in the Input**: Modify the solution to handle cases where the input array contains zeros. For example, if `nums = [0, 1, 2, 3, 0]`, the output should be `[0, 0, 0, 0, 0]` because any element multiplied by zero results in zero.\n", - "\n", - "2. **In-Place Modification**: Attempt to solve the problem with in-place modification of the `nums` array, where the output is stored directly in the input array without using any additional space." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/01. Array Hashing/242. Valid Anagram.ipynb b/docs/01. Array Hashing/242. Valid Anagram.ipynb deleted file mode 100644 index d165899..0000000 --- a/docs/01. Array Hashing/242. Valid Anagram.ipynb +++ /dev/null @@ -1,198 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 242. Valid Anagram\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Valid Anagram problem on LeetCode, click here!](https://leetcode.com/problems/valid-anagram/)\n", - "\n", - "---\n", - "Given two strings `s` and `t`, return `true` if `t` is an anagram of `s`, and `false` otherwise.\n", - "\n", - "An **Anagram** is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.\n", - "\n", - "**Constraints:**\n", - "- 1 <= `s.length`, `t.length` <= $5 * 10^4$\n", - "- `s` and `t` consist of lowercase English letters.\n", - "\n", - "**Follow-up:** What if the inputs contain Unicode characters? How would you adapt your solution to such a case?\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def isAnagram(s: str, t: str) -> bool:\n", - " # Check if the lengths of s and t are not equal\n", - " if len(s) != len(t):\n", - " return False\n", - "\n", - " # Create dictionaries to store character frequencies for s and t\n", - " countS, countT = {}, {}\n", - "\n", - " # Count character frequencies in s\n", - " for i in range(len(s)):\n", - " countS[s[i]] = 1 + countS.get(s[i], 0)\n", - "\n", - " # Count character frequencies in t\n", - " for i in range(len(t)):\n", - " countT[t[i]] = 1 + countT.get(t[i], 0)\n", - "\n", - " # Check if the character frequencies in s and t are the same\n", - " return countS == countT" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. The code defines a class called `Solution` with a method `isAnagram` that takes two input strings, `s` and `t`, and returns a boolean (`True` or `False`) based on whether `t` is an anagram of `s`.\n", - "\n", - "2. The first check performed in the method is whether the lengths of `s` and `t` are equal. If they are not equal, it immediately returns `False` because strings of different lengths cannot be anagrams of each other.\n", - "\n", - "3. Two dictionaries, `countS` and `countT`, are created to store the frequency of characters in `s` and `t`, respectively. These dictionaries will be used to count the occurrences of each character in the strings.\n", - "\n", - "4. The code then enters a loop to iterate through each character in string `s` using a `for` loop. Inside the loop, it updates the `countS` dictionary. The line `countS[s[i]] = 1 + countS.get(s[i], 0)` increments the count of character `s[i]` in `countS` by 1. If the character is not already in the dictionary, it initializes the count to 1.\n", - "\n", - "5. Similarly, the code iterates through each character in string `t` and updates the `countT` dictionary in the same way.\n", - "\n", - "6. After counting the character frequencies in both strings, the code compares the two dictionaries using `countS == countT`. If the dictionaries are equal, it means that both strings have the same character frequencies, and therefore, `t` is an anagram of `s`. In this case, the method returns `True`.\n", - "\n", - "7. If the dictionaries are not equal, the method returns `False`, indicating that `t` is not an anagram of `s`.\n", - "\n", - "In summary, this code efficiently determines whether two input strings are anagrams by counting the character frequencies in each string using dictionaries and then comparing these counts. If the character frequencies match, the strings are considered anagrams, and the method returns `True`; otherwise, it returns `False`." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "s = \"anagram\"\n", - "t = \"nagaram\"\n", - "print(isAnagram(s, t))" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 2\n", - "s = \"rat\"\n", - "t = \"car\"\n", - "print(isAnagram(s, t))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. The code first checks whether the lengths of the input strings `s` and `t` are equal, which takes constant time. This check has a time complexity of O(1).\n", - "\n", - "2. The code then iterates through both strings, `s` and `t`, once to count the character frequencies. Since both strings have a maximum length of 5 * 10^4, the worst-case scenario is that the code iterates through 5 * 10^4 characters in each string. This results in a linear time complexity of O(n), where n is the length of the longer of the two input strings (`s` or `t`).\n", - "\n", - "3. Finally, the code compares the two dictionaries `countS` and `countT` to check if the character frequencies match. This comparison takes O(n) time in the worst case, where n is the length of the longer string.\n", - "\n", - "Overall, the time complexity of the code is O(n), where n is the length of the longer input string.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. The code uses two dictionaries, `countS` and `countT`, to store the character frequencies of the input strings `s` and `t`. In the worst case, both dictionaries can contain all unique characters from the input strings. Since the input strings can have a maximum length of 5 * 10^4, the space complexity for these dictionaries is O(5 * 10^4) or simply O(n), where n is the length of the longer input string.\n", - "\n", - "2. The code uses a few additional variables for bookkeeping, but these variables have constant space requirements and do not depend on the input size. Therefore, they do not significantly impact the overall space complexity.\n", - "\n", - "**In summary**, the space complexity of the code is O(n), where n is the length of the longer input string." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Anagram Chains**: Given a list of words, find the longest chain of anagrams, where each word in the chain is an anagram of the previous word. For example, given [\"bat\", \"tab\", \"cat\", \"tac\", \"dog\"], the longest anagram chain is [\"bat\", \"tab\", \"cat\", \"tac\"].\n", - "\n", - "2. **Minimum Deletions to Make Anagrams**: Given two strings `s` and `t`, find the minimum number of character deletions required in both strings to make them anagrams of each other. For example, if `s = \"hello\"` and `t = \"billion\"`, you can remove the characters \"heo\" from `s` and \"billi\" from `t` to make them anagrams (\"lo\" and \"on\" are left in the two strings)." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/01. Array Hashing/347. Top K Frequent Elements.ipynb b/docs/01. Array Hashing/347. Top K Frequent Elements.ipynb deleted file mode 100644 index ecfa494..0000000 --- a/docs/01. Array Hashing/347. Top K Frequent Elements.ipynb +++ /dev/null @@ -1,215 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 347. Top K Frequent Elements\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Top K Frequent Elements problem on LeetCode, click here!](https://leetcode.com/problems/top-k-frequent-elements/)\n", - "\n", - "---\n", - "Given an integer array `nums` and an integer `k`, return the `k` most frequent elements. You may return the answer in **any order**.\n", - "\n", - "Constraints:\n", - "- 1 <= `nums.length` <= $10^5$\n", - "- $-10^4$ <= `nums[i]` <= $10^4$\n", - "- `k` is in the range `[1, the number of unique elements in the array]`.\n", - "- It is **guaranteed** that the answer is **unique**.\n", - "\n", - "**Follow-up:** Your algorithm's time complexity must be better than $O(n\\ log\\ n)$, where n is the array's size.\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def topKFrequent(nums, k):\n", - " # Create a dictionary to store the frequency of each element\n", - " count = {}\n", - " # Create a list of lists to store elements with the same frequency\n", - " frequency = [[] for i in range(len(nums) + 1)]\n", - "\n", - " # Count the frequency of each element in nums\n", - " for n in nums:\n", - " count[n] = 1 + count.get(n, 0)\n", - "\n", - " # Place elements in the freq list according to their frequency\n", - " for n, c in count.items():\n", - " frequency[c].append(n)\n", - "\n", - " res = []\n", - " # Traverse freq list from the end (higher frequencies)\n", - " for i in range(len(frequency) - 1, 0, -1):\n", - " for n in frequency[i]:\n", - " res.append(n)\n", - " if len(res) == k:\n", - " return res" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. `def topKFrequent(nums, k):`: This is a function that takes two arguments: `nums`, which is the input array of integers, and `k`, which is the number of most frequent elements to return.\n", - "\n", - "2. `count = {}`: This dictionary `count` will be used to store the frequency of each unique element in the `nums` array. The keys are elements from the input array, and the values are their corresponding frequencies.\n", - "\n", - "3. `frequency = [[] for i in range(len(nums) + 1)]`: This creates a list of empty lists called `frequency`. It's used to store elements based on their frequencies, similar to the `freq` list in the previous code. The size of this list is set to be one greater than the length of the input `nums`.\n", - "\n", - "4. `for n in nums:`: This loop iterates through each element `n` in the input `nums` array.\n", - "\n", - "5. `count[n] = 1 + count.get(n, 0)`: This line counts the frequency of each element `n` in the `nums` array. It uses the `count.get(n, 0)` method to retrieve the current count of `n` from the `count` dictionary. If `n` is not in the dictionary, it defaults to 0. It then increments the count by 1.\n", - "\n", - "6. After the above loop, the `count` dictionary will contain counts of each unique element in the `nums` array.\n", - "\n", - "7. `for n, c in count.items():`: This loop iterates through the items (key-value pairs) of the `count` dictionary. `n` represents the element, and `c` represents its frequency.\n", - "\n", - "8. `frequency[c].append(n)`: This line places the element `n` into the bucket corresponding to its frequency `c`. Buckets are represented by the `frequency` list. For example, if an element `n` has a frequency of 3, it will be added to `frequency[3]`.\n", - "\n", - "9. After this loop, the `frequency` list will contain buckets of elements grouped by their frequencies.\n", - "\n", - "10. `res = []`: This list `res` will be used to store the k most frequent elements.\n", - "\n", - "11. `for i in range(len(freq) - 1, 0, -1):`: This loop iterates in reverse order through the `frequency` list, starting from the highest frequency and going down to 1. Note that there is a typo here; it should be `frequency` instead of `freq`.\n", - "\n", - "12. `for n in frequency[i]:`: For each element `n` in the current bucket (i.e., elements with frequency `i`), it appends `n` to the result list `res`.\n", - "\n", - "13. `if len(res) == k:`: Once `res` contains k elements, the code exits and returns the result.\n", - "\n", - "The code efficiently finds the k most frequent elements in the input array without using sorting, similar to the previous explanation, with the only difference being the variable names (e.g., `frequency` instead of `freq`)." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 48, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 2]\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "nums = [1,1,1,2,2,3]\n", - "k = 2\n", - "result1 = topKFrequent(nums, k)\n", - "print(result1)" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1]\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "nums = [1]\n", - "k = 1\n", - "result2 = topKFrequent(nums, k)\n", - "print(result2)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "1. The first loop that counts the frequency of elements by iterating through `nums` has a time complexity of O(n), where n is the number of elements in the input array `nums`.\n", - "\n", - "2. The second loop iterates through the keys in the `count` dictionary, which has at most `k` unique elements (as per the constraints). Therefore, the second loop also has a time complexity of O(k).\n", - "\n", - "3. The third loop iterates through the `frequency` list, which has a length equal to the maximum frequency of elements in `nums`. In the worst case, this loop can have a time complexity of O(n), where n is the number of elements in `nums`.\n", - "\n", - "Overall, the dominant factor in terms of time complexity is the loop that iterates through the `count` dictionary. So, the total time complexity of the code is O(n + k).\n", - "\n", - "**Space Complexity:**\n", - "1. The `count` dictionary stores the frequency of each unique element in `nums`. In the worst case, it can have at most `k` unique elements, so the space complexity for `count` is O(k).\n", - "\n", - "2. The `frequency` list is used to store elements grouped by their frequencies. It has a length of `len(nums) + 1`, which can be at most 105 based on the constraints. Therefore, the space complexity for `frequency` is O(105).\n", - "\n", - "3. The `res` list stores the k most frequent elements, which can be at most `k` elements, so the space complexity for `res` is O(k).\n", - "\n", - "**In summary**, the space complexity is dominated by the `count` dictionary and the `frequency` list, both of which have a space complexity of O(k + 105)." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Optimized k Most Frequent Elements:** Modify the code to find the k most frequent elements in an array while ensuring that the time complexity is O(n + klogk). You can use a priority queue (heap) to achieve this.\n", - "\n", - "2. **Handling Duplicate Frequencies:** Extend the code to handle cases where multiple elements have the same frequency and are among the k most frequent elements. Ensure that the output contains exactly k elements." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/01. Array Hashing/49. Group Anagrams.ipynb b/docs/01. Array Hashing/49. Group Anagrams.ipynb deleted file mode 100644 index afe89ec..0000000 --- a/docs/01. Array Hashing/49. Group Anagrams.ipynb +++ /dev/null @@ -1,229 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 49. Group Anagrams\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Group Anagrams problem on LeetCode, click here!](https://leetcode.com/problems/group-anagrams/)\n", - "\n", - "---\n", - "Given an array of strings `strs`, group **the anagrams** together. You can return the answer in **any order**.\n", - "\n", - "An **Anagram** is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.\n", - "\n", - "**Constraints:**\n", - "- 1 <= `strs.length <= $10^4$\n", - "- `0 <= strs[i].length <= 100`\n", - "- `strs[i]` consists of lowercase English letters.\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "from collections import defaultdict\n", - "\n", - "\n", - "def groupAnagrams(strs):\n", - " ans = defaultdict(list)\n", - "\n", - " # Iterate through the list of input strings\n", - " for s in strs:\n", - " # Initialize a list to represent character counts for each character (a-z)\n", - " count = [0] * 26\n", - "\n", - " # Count the occurrences of each character in the current word\n", - " for c in s:\n", - " count[ord(c) - ord(\"a\")] += 1\n", - "\n", - " # Use a tuple of character counts as the key and append the word to the anagram group\n", - " ans[tuple(count)].append(s)\n", - "\n", - " # Convert the values (lists of anagrams) to a list of lists\n", - " return list(ans.values())" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. Inside the method, a `defaultdict` called `ans` is created to store anagram groups. This dictionary will have a list as its default value, meaning that each key in the dictionary will be associated with an empty list by default.\n", - "\n", - "2. The code then iterates through the list of input strings, `strs`, using a `for` loop. For each word `s` in `strs`, it performs the following steps:\n", - "\n", - " - It initializes a list `count` of length 26, where each element represents the count of a specific character (a-z) in the word `s`.\n", - "\n", - " - The code then iterates through the characters of `s`. For each character `c`, it increments the corresponding count in the `count` list based on its ASCII value.\n", - "\n", - " - After counting the characters in `s`, it converts the `count` list into a tuple `tuple(count)` to use as a key for the `ans` dictionary.\n", - "\n", - " - It appends the word `s` to the list associated with the key (tuple) in the `ans` dictionary. This groups all anagrams of the same word together under the same key.\n", - "\n", - "3. After processing all words in `strs`, the code converts the values of the `ans` dictionary (which are lists of anagrams) to a list of lists using the `list()` constructor.\n", - "\n", - "4. Finally, the code returns the list of anagram groups, which is the result of grouping the anagrams in the input list.\n", - "\n", - "In summary, the code efficiently groups anagrams together by counting the characters in each word and using a dictionary to store them under the same key. The result is a list of lists, where each inner list represents a group of anagrams." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[['eat', 'tea', 'ate'], ['tan', 'nat'], ['bat']]\n" - ] - } - ], - "source": [ - "# Example 1: Group anagrams from a list of words\n", - "strs1 = [\"eat\", \"tea\", \"tan\", \"ate\", \"nat\", \"bat\"]\n", - "result1 = groupAnagrams(strs1)\n", - "print(result1)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[['']]\n" - ] - } - ], - "source": [ - "# Example 2: Group anagrams from a list with an empty string\n", - "strs2 = [\"\"]\n", - "result2 = groupAnagrams(strs2)\n", - "print(result2)" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "id": "c8367e2a-e7d5-4e18-8235-2870e341a04b", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[['a']]\n" - ] - } - ], - "source": [ - "# Example 3: Group anagrams from a list with a single word\n", - "strs3 = [\"a\"]\n", - "result3 = groupAnagrams(strs3)\n", - "print(result3)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `groupAnagrams` method:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. First, we create an instance of the `Solution` class, which is an O(1) operation.\n", - "\n", - "2. Inside the `groupAnagrams` method, we iterate through the list of input strings `strs` once in a loop:\n", - " - For each word in `strs`, we perform character counting, which is done in O(K) time, where K is the maximum length of a word in the list.\n", - "\n", - "3. The overall time complexity of the method is O(N * K), where N is the number of words in the input list `strs`, and K is the maximum length of a word in `strs`.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. We use a `defaultdict` called `ans` to store the anagram groups. In the worst case, each word belongs to a distinct anagram group, so the space complexity for `ans` is O(N).\n", - "\n", - "2. Within the loop, we create a `count` list of length 26 to store character counts for each word. This is a fixed-size list and does not depend on the input size, so it has a constant space complexity of O(26), which is effectively O(1).\n", - "\n", - "3. The space used for other variables is also constant and does not depend on the input size.\n", - "\n", - "4. The final result, `result`, is a list of lists that contains the grouped anagrams. In the worst case, each word is a distinct anagram group, so the space complexity for `result` is O(N).\n", - "\n", - "5. The overall space complexity of the method is O(N) due to the space used by `ans` and `result`. The space used by the `count` list and other variables is constant and does not significantly affect the overall space complexity.\n", - "\n", - "**In summary,** the time complexity of the `groupAnagrams` method is O(N * K), and the space complexity is O(N), where N is the number of words in the input list `strs`, and K is the maximum length of a word in `strs`." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Anagramic Palindromes**: Given a list of strings, find all the groups of anagrams where each group contains words that can be rearranged into a palindrome. For example, in the list [\"bat\", \"tab\", \"act\", \"tac\", \"dog\"], there are two groups: [\"bat\", \"tab\", \"act\", \"tac\"] and [\"dog\"].\n", - "\n", - "2. **Largest Anagram Group**: Given a list of strings, find the largest group of anagrams. Return the list of anagrams in that group. If there are multiple largest groups, return all of them." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/01. Array Hashing/659. Encode and Decode Strings.ipynb b/docs/01. Array Hashing/659. Encode and Decode Strings.ipynb deleted file mode 100644 index 037c476..0000000 --- a/docs/01. Array Hashing/659. Encode and Decode Strings.ipynb +++ /dev/null @@ -1,204 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 659· Encode and Decode Strings\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Encode and Decode Strings problem on LintCode, click here!](https://www.lintcode.com/problem/659/)\n", - "\n", - "---\n", - "Design an algorithm to encode a list of strings to a string. The encoded string is then sent over the network and is decoded back to the original list of strings.\n", - "\n", - "Please implement `encode` and `decode`.\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class Codec:\n", - "\n", - " def encode(self, strs):\n", - " \"\"\"Encodes a list of strings to a single string.\n", - " \n", - " :type strs: List[str]\n", - " :rtype: str\n", - " \"\"\"\n", - " encoded = \"\"\n", - " for s in strs:\n", - " encoded += s.replace(':', '::') + ':;'\n", - " return encoded\n", - "\n", - " def decode(self, s):\n", - " \"\"\"Decodes a single string to a list of strings.\n", - " \n", - " :type s: str\n", - " :rtype: List[str]\n", - " \"\"\"\n", - " decoded = []\n", - " i = 0\n", - " while i < len(s):\n", - " end = s.find(':;', i)\n", - " if end == -1:\n", - " end = len(s)\n", - " decoded.append(s[i:end].replace('::', ':'))\n", - " i = end + 2\n", - " return decoded" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We define a class called `Codec` to encapsulate the encoding and decoding operations for a list of strings.\n", - "\n", - "2. In the `encode` method, we take a list of strings (`strs`) as input and return a single encoded string. The encoding process involves concatenating the strings together with a delimiter `:;`. We iterate through each string in the input list, replace any occurrence of `:` with `::` (to avoid conflicts with the delimiter), and then append `:;` to indicate the end of that string.\n", - "\n", - "3. In the `decode` method, we take an encoded string (`s`) as input and return a list of strings. The decoding process involves splitting the encoded string using the `:;` delimiter. We start from the beginning of the encoded string (`i = 0`) and repeatedly find the next occurrence of `:;`. We extract the substring between the current position (`i`) and the next delimiter (`end`). Before adding it to the result list, we replace any `::` with `:` to revert the encoding. We then update the current position `i` to be after the delimiter, so we can find the next substring in the next iteration.\n", - "\n", - "4. Finally, we create an instance of the `Codec` class and test it with two examples:\n", - "\n", - "By using the `:;` delimiter and handling the `::` escaping, this code can encode and decode lists of strings, preserving the original content even if it contains colons or the delimiter itself." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 55, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['lint', 'code', 'love', 'you']\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "codec = Codec()\n", - "\n", - "input1 = [\"lint\", \"code\", \"love\", \"you\"]\n", - "encoded1 = codec.encode(input1)\n", - "decoded1 = codec.decode(encoded1)\n", - "print(decoded1)" - ] - }, - { - "cell_type": "code", - "execution_count": 57, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['we', 'say', ':', 'yes']\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "codec = Codec() \n", - "\n", - "input2 = [\"we\", \"say\", \":\", \"yes\"]\n", - "encoded2 = codec.encode(input2)\n", - "decoded2 = codec.decode(encoded2)\n", - "print(decoded2) " - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `encode` and `decode` methods in the provided code.\n", - "\n", - "**Encode Method (`encode`):**\n", - "\n", - "- Time Complexity: O(n * m)\n", - " - Here, `n` is the number of strings in the input list `strs`, and `m` is the average length of these strings.\n", - " - In the worst case, for each string in the list, we iterate over its characters once to replace any colons (`:`) with double colons (`::`) and then append `:;`. This is done for each string in the list.\n", - "\n", - "- Space Complexity: O(n * m)\n", - " - The space complexity is also O(n * m) because we build the encoded string by concatenating the modified strings. In the worst case, the encoded string can be of the same length as the original strings.\n", - "\n", - "**Decode Method (`decode`):**\n", - "\n", - "- Time Complexity: O(n * m)\n", - " - Similar to the encode method, we iterate through the encoded string in the decode method. In the worst case, we may have to scan each character in the encoded string to find the `:;` delimiter.\n", - "\n", - "- Space Complexity: O(n * m)\n", - " - The space complexity of the decode method is also O(n * m) because we build the list of decoded strings, which can be of the same length as the encoded string.\n", - "\n", - "Overall, both the `encode` and `decode` methods have time and space complexities of O(n * m), where `n` is the number of strings in the input list, and `m` is the average length of these strings. The space complexity arises from storing the encoded or decoded strings, and the time complexity arises from iterating through the characters in these strings." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Multiple Delimiters**: Modify the code to allow for multiple delimiters, not just one. Each string could have its own delimiter, and the code should be able to handle this complexity.\n", - "\n", - "2. **Optimize Encoding**: Modify the `encode` method to achieve a more efficient encoding algorithm. Try to minimize the length of the encoded string while ensuring that it can be correctly decoded." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/01. Array Hashing/README.md b/docs/01. Array Hashing/README.md deleted file mode 100644 index a331dab..0000000 --- a/docs/01. Array Hashing/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# Array & Hashing Solutions - Blind 75 LeetCode Problems -![Array & Hashing Solutions](https://img.shields.io/badge/Array_&_Hashing_Solutions-blue)![Blind 75 LeetCode](https://img.shields.io/badge/Blind_75_LeetCode-Problems-blue?labelColor=red) - -This repository contains my solutions to Array & Hashing Problems from Blind 75 LeetCode problems. I've organized the solutions by categories for easier navigation and reference. Each problem solution is presented in Jupyter Notebook format (`.ipynb`). - - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [217. Contains Duplicate](https://github.com/mohsentabibian/LeetCode-Solutions/blob/main/01.%20Array%20Hashing/217.%20Contains%20Duplicate.ipynb) | Easy | -| [242. Valid Anagram](https://github.com/mohsentabibian/LeetCode-Solutions/blob/main/01.%20Array%20Hashing/242.%20Valid%20Anagram.ipynb) | Easy | -| [1. Two Sum](https://github.com/mohsentabibian/LeetCode-Solutions/blob/main/01.%20Array%20Hashing/1.%20Two%20Sum.ipynb) | Easy | -| [49. Group Anagrams](https://github.com/mohsentabibian/LeetCode-Solutions/blob/main/01.%20Array%20Hashing/49.%20Group%20Anagrams.ipynb) | Medium | -| [347. Top K Frequent Elements](https://github.com/mohsentabibian/LeetCode-Solutions/blob/main/01.%20Array%20Hashing/347.%20Top%20K%20Frequent%20Elements.ipynb) | Medium | -| [238. Product of Array Except Self](https://github.com/mohsentabibian/LeetCode-Solutions/blob/main/01.%20Array%20Hashing/238.%20Product%20of%20Array%20Except%20Self.ipynb) | Medium | -| [659. Encode and Decode Strings](https://github.com/mohsentabibian/LeetCode-Solutions/blob/main/01.%20Array%20Hashing/659.%20Encode%20and%20Decode%20Strings.ipynb) | Medium | -| [128. Longest Consecutive Sequence](https://github.com/mohsentabibian/LeetCode-Solutions/blob/main/01.%20Array%20Hashing/128.%20Longest%20Consecutive%20Sequence.ipynb) | Hard | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! diff --git a/docs/02. Two Pointers/11. Container With Most Water.ipynb b/docs/02. Two Pointers/11. Container With Most Water.ipynb deleted file mode 100644 index 284c832..0000000 --- a/docs/02. Two Pointers/11. Container With Most Water.ipynb +++ /dev/null @@ -1,220 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 11. Container With Most Water\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Container With Most Water problem on LeetCode, click here!](https://leetcode.com/problems/container-with-most-water/)\n", - "\n", - "---\n", - "You are given an integer array `height` of length `n`. There are `n` vertical lines drawn such that the two endpoints of the $i^{th}$ line are `(i, 0)` and `(i, height[i])`.\n", - "\n", - "Find two lines that together with the x-axis form a container, such that the container contains the most water.\n", - "\n", - "Return *the maximum amount of water a container can store.*\n", - "\n", - "**Notice** that you may not slant the container.\n", - "\n", - "**Constraints:**\n", - "- `n == height.length`\n", - "- 2 <= `n` <= $10^5$\n", - "- 0 <= `height[i]` <= $10^4$\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def maxArea(height):\n", - " # Initialize the maximum area to 0.\n", - " max_area = 0\n", - " # Initialize two pointers, one at the beginning (left) and one at the end (right) of the array.\n", - " left = 0\n", - " right = len(height) - 1\n", - "\n", - " # Iterate until the left pointer is less than the right pointer.\n", - " while left < right:\n", - " # Calculate the height of the container, which is the minimum height of the two lines.\n", - " h = min(height[left], height[right])\n", - " # Calculate the width of the container, which is the distance between the two pointers.\n", - " width = right - left\n", - " # Calculate the area of the container using height and width and update max_area if it's greater.\n", - " max_area = max(max_area, h * width)\n", - "\n", - " # Move the pointer with the shorter line inward.\n", - " if height[left] < height[right]:\n", - " left += 1\n", - " else:\n", - " right -= 1\n", - "\n", - " # Continue this process until left < right, and then return the maximum area.\n", - " return max_area" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start with initializing `max_area` to 0, which will store the maximum area of water that can be contained by the lines.\n", - "\n", - "2. Two pointers, `left` and `right`, are initialized to the beginning and end of the input `height` array.\n", - "\n", - "3. The main loop runs while `left` is less than `right`. This ensures that we are checking all possible pairs of lines in a systematic way.\n", - "\n", - "4. Inside the loop:\n", - " - We calculate the height of the container `h` as the minimum of the heights at the `left` and `right` pointers. This represents the height of the water the container can hold.\n", - " - We calculate the width of the container as the difference between `right` and `left`. This represents the distance between the two lines.\n", - " - We calculate the area of the container using `h * width` and update `max_area` if the calculated area is greater than the current `max_area`.\n", - "\n", - "5. After calculating the area and updating `max_area`, we move one of the pointers. We move the pointer pointing to the shorter line inward because moving the pointer pointing to the taller line won't increase the height and will only decrease the width, which will result in a smaller area.\n", - "\n", - "6. We continue this process until `left` is no longer less than `right`, indicating that we have checked all possible pairs of lines.\n", - "\n", - "7. Finally, we return the `max_area` which contains the maximum area of water that can be contained by two lines from the input array." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Output: 49\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "height1 = [1, 8, 6, 2, 5, 4, 8, 3, 7]\n", - "result1 = maxArea(height1)\n", - "print(\"Output:\", result1)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Output: 1\n" - ] - } - ], - "source": [ - "# Example 2\n", - "height2 = [1, 1]\n", - "result2 = maxArea(height2)\n", - "print(\"Output:\", result2)" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "e191cf7e-95f9-4e5c-a99b-146c2a779c0b", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Output: 45\n" - ] - } - ], - "source": [ - "# Additional Example\n", - "height3 = [3, 9, 3, 4, 7, 2, 12, 6]\n", - "result3 = maxArea(height3)\n", - "print(\"Output:\", result3)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `maxArea` function:\n", - "\n", - "**Time Complexity:**\n", - "The function uses a two-pointer approach to find the maximum area of water. In the worst case, both the left and right pointers traverse the entire input array once. Therefore, the time complexity is O(n), where n is the number of elements in the `height` array.\n", - "\n", - "**Space Complexity:**\n", - "The function uses a constant amount of extra space for variables like `max_area`, `left`, `right`, `h`, and `width`. It does not use any data structures whose space consumption depends on the input size. As a result, the space complexity is O(1), which means it has constant space complexity.\n", - "\n", - "**In summary,** the `maxArea` function has a time complexity of O(n) and a space complexity of O(1), making it an efficient algorithm for finding the maximum area of water that can be contained by two lines in the input array." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Optimization Challenge:** Modify the maxArea function to not only return the maximum area but also the indices of the two lines that form the container with the maximum area.\n", - "2. **Variant Problem:** Instead of finding the maximum area of water, find the minimum amount of water required to fill all the gaps between the lines. You'll need to return the total water volume needed." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/02. Two Pointers/125. Valid Palindrome.ipynb b/docs/02. Two Pointers/125. Valid Palindrome.ipynb deleted file mode 100644 index 8520b3b..0000000 --- a/docs/02. Two Pointers/125. Valid Palindrome.ipynb +++ /dev/null @@ -1,218 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 125. Valid Palindrome\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Valid Palindrome problem on LeetCode, click here!](https://leetcode.com/problems/valid-palindrome/)\n", - "\n", - "---\n", - "\n", - "A phrase is a **palindrome** if, after converting all uppercase letters into lowercase letters and removing all non-alphanumeric characters, it reads the same forward and backward. Alphanumeric characters include letters and numbers.\n", - "\n", - "Given a string `s`, *return `true` if it is a **palindrome**, or `false` otherwise.*\n", - "\n", - "**Constraints:**\n", - "\n", - "- 1 <= `s.length` <= $2*10^5$\n", - "- `s` consists only of printable ASCII characters.\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def isPalindrome(s):\n", - " # Step 1: Convert the input string to lowercase\n", - " s = s.lower()\n", - " \n", - " # Step 2: Remove all non-alphanumeric characters from the string\n", - " cleaned_s = ''.join(c for c in s if c.isalnum())\n", - " \n", - " # Step 3: Initialize two pointers, one at the beginning and one at the end of the cleaned string\n", - " left, right = 0, len(cleaned_s) - 1\n", - " \n", - " # Step 4: Compare characters using the two pointers while moving them towards each other\n", - " while left < right:\n", - " if cleaned_s[left] != cleaned_s[right]:\n", - " return False # If characters don't match, it's not a palindrome\n", - " left += 1\n", - " right -= 1\n", - " \n", - " # Step 5: If the loop completes without returning False, it's a palindrome\n", - " return True" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. The `isPalindrome` function takes an input string `s`.\n", - "\n", - "2. It starts by converting the input string to lowercase using `s.lower()`. This step ensures that the function is case-insensitive when checking for palindromes.\n", - "\n", - "3. Next, it removes all non-alphanumeric characters from the string and stores the result in the `cleaned_s` variable. It does this by iterating through each character in the input string and only keeping characters that are alphanumeric (letters and digits). This step removes spaces, punctuation, and other non-alphanumeric characters.\n", - "\n", - "4. The function then initializes two pointers, `left` and `right`, which will be used to compare characters from the beginning and end of the cleaned string.\n", - "\n", - "5. In a while loop, it compares characters using the two pointers while moving them towards each other. The loop continues until the `left` pointer is less than the `right` pointer. This is done to check all characters in the cleaned string.\n", - "\n", - "6. Inside the loop, it checks if the characters at the `left` and `right` pointers don't match. If they don't match, it means the input is not a palindrome, so the function returns `False`.\n", - "\n", - "7. If the characters at the `left` and `right` pointers match, the pointers are moved closer to each other by incrementing `left` and decrementing `right`.\n", - "\n", - "8. The loop continues to compare characters until it either finds a mismatch (returning `False`) or until the `left` pointer is greater than or equal to the `right` pointer. If the loop completes without finding a mismatch, it means the input is a palindrome, so the function returns `True`.\n", - "\n", - "In summary, the code converts the input string to lowercase, removes non-alphanumeric characters, and then uses two pointers to compare characters from the cleaned string's beginning and end. If all characters match during the comparison, the function returns `True`, indicating that the input is a palindrome. If any characters do not match, it returns `False`." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "input1 = \"A man, a plan, a canal: Panama\"\n", - "output1 = isPalindrome(input1)\n", - "print(output1)" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 2\n", - "input2 = \"race a car\"\n", - "output2 = isPalindrome(input2)\n", - "print(output2)" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "e191cf7e-95f9-4e5c-a99b-146c2a779c0b", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 3\n", - "input3 = \"\"\n", - "output3 = isPalindrome(input3)\n", - "print(output3)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `isPalindrome` function that uses two pointers:\n", - "\n", - "1. **Time Complexity:**\n", - " - Converting the input string to lowercase using `s.lower()` takes O(n) time, where 'n' is the length of the input string.\n", - " - Removing non-alphanumeric characters using the list comprehension `''.join(c for c in s if c.isalnum())` also takes O(n) time because it iterates through each character in the string once.\n", - " - The comparison of characters using the two pointers (`left` and `right`) is done in a loop that runs until `left` is less than `right`. In the worst case, the loop iterates through half of the string, so it takes O(n/2) time, which is still considered O(n).\n", - "\n", - " Therefore, the overall time complexity of the `isPalindrome` function is O(n), where 'n' is the length of the input string.\n", - "\n", - "2. **Space Complexity:**\n", - " - The space complexity is primarily determined by the additional string `cleaned_s` created to store the cleaned version of the input string. In the worst case, if all characters in the input string are alphanumeric, this cleaned string can be as large as the original input string.\n", - " - Additionally, the function uses two pointers, `left` and `right`, which consume constant space and do not depend on the size of the input.\n", - "\n", - "**In summary,** the overall space complexity of the `isPalindrome` function is O(n) in the worst case, where 'n' is the length of the input string. The space complexity is dominated by the space required for `cleaned_s`." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Longest Palindromic Substring:** Given a string `s`, find and return the longest palindromic substring within `s`. For example, if `s = \"babad\"`, the function should return `\"bab\"` or `\"aba\"`.\n", - "2. **Palindrome with Limited Characters:** Given a string `s` and a list of characters `allowed_chars`, check if `s` is a palindrome considering only the characters from `allowed_chars`. Ignore all other characters. For example, if `s = \"A man, a plan, a canal: Panama\"` and `allowed_chars = ['a', 'm', 'n', 'p']`, the function should return `True`." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/02. Two Pointers/15. 3Sum.ipynb b/docs/02. Two Pointers/15. 3Sum.ipynb deleted file mode 100644 index 06de549..0000000 --- a/docs/02. Two Pointers/15. 3Sum.ipynb +++ /dev/null @@ -1,250 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 15. 3Sum\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the 3Sum problem on LeetCode, click here!](https://leetcode.com/problems/3sum/)\n", - "\n", - "---\n", - "Given an integer array nums, *return all the triplets `[nums[i], nums[j], nums[k]]` such that `i != j`, `i != k`, and `j != k`, and `nums[i] + nums[j] + nums[k] == 0`.*\n", - "\n", - "**Notice** that the solution set must not contain duplicate triplets.\n", - "\n", - "**Constraints:**\n", - "\n", - "- `3 <= nums.length <= 3000`\n", - "- $-10^5$ <= `nums[i]` <= $10^5$\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def threeSum(nums):\n", - " # Sort the input array in ascending order\n", - " nums.sort()\n", - " triplets = []\n", - " \n", - " for i in range(len(nums) - 2):\n", - " # Skip duplicates to avoid duplicate triplets\n", - " if i > 0 and nums[i] == nums[i - 1]:\n", - " continue\n", - " \n", - " left, right = i + 1, len(nums) - 1\n", - " \n", - " while left < right:\n", - " # Calculate the total sum of the current triplet\n", - " total = nums[i] + nums[left] + nums[right]\n", - " \n", - " if total == 0:\n", - " # If the total is zero, we found a valid triplet\n", - " triplets.append([nums[i], nums[left], nums[right]])\n", - " \n", - " # Skip duplicates of left and right pointers\n", - " while left < right and nums[left] == nums[left + 1]:\n", - " left += 1\n", - " while left < right and nums[right] == nums[right - 1]:\n", - " right -= 1\n", - " \n", - " # Move the pointers to the next unique elements\n", - " left += 1\n", - " right -= 1\n", - " elif total < 0:\n", - " # If the total is negative, we need to increase the sum by moving the left pointer to the right\n", - " left += 1\n", - " else:\n", - " # If the total is positive, we need to decrease the sum by moving the right pointer to the left\n", - " right -= 1\n", - " \n", - " return triplets" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. It starts by sorting the input array `nums` in ascending order. Sorting helps in efficiently finding triplets that sum up to zero.\n", - "\n", - "2. It initializes an empty list `triplets` to store the unique triplets that meet the given conditions.\n", - "\n", - "3. The code then iterates through the `nums` array using a loop with index `i`. This loop will consider each element of the array as a potential starting point for a triplet.\n", - "\n", - "4. Inside the loop, it checks for duplicates and skips them. This is done to ensure that the solution set does not contain duplicate triplets. If `nums[i]` is the same as the previous element `nums[i-1]`, it continues to the next iteration of the loop.\n", - "\n", - "5. Two pointers, `left` and `right`, are initialized. `left` starts just after the current element `nums[i]`, and `right` starts at the end of the array.\n", - "\n", - "6. The code enters another loop with `left` and `right` pointers, trying to find a triplet that sums up to zero.\n", - "\n", - "7. It calculates the `total` sum of the current triplet as `nums[i] + nums[left] + nums[right]`.\n", - "\n", - "8. If `total` is zero, it means a valid triplet is found, so it appends `[nums[i], nums[left], nums[right]]` to the `triplets` list. Then, it moves both the `left` and `right` pointers to their next unique elements while skipping duplicates.\n", - "\n", - "9. If `total` is less than zero, it means the sum is negative, so it increments the `left` pointer to move towards a larger sum.\n", - "\n", - "10. If `total` is greater than zero, it means the sum is positive, so it decrements the `right` pointer to move towards a smaller sum.\n", - "\n", - "11. This process continues until all possible triplets have been considered.\n", - "\n", - "12. Finally, the function returns the `triplets` list, which contains all the unique triplets that sum up to zero in the sorted `nums` array." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[-1, -1, 2], [-1, 0, 1]]\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "nums = [-1, 0, 1, 2, -1, -4]\n", - "result = threeSum(nums)\n", - "print(result)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[]\n" - ] - } - ], - "source": [ - "# Example 2\n", - "nums = [0, 1, 1]\n", - "result = threeSum(nums)\n", - "print(result)" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "e191cf7e-95f9-4e5c-a99b-146c2a779c0b", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[0, 0, 0]]\n" - ] - } - ], - "source": [ - "# Example 3\n", - "nums = [0, 0, 0]\n", - "result = threeSum(nums)\n", - "print(result)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `threeSum` function:\n", - "\n", - "**Time Complexity:**\n", - "1. Sorting the input array `nums` takes O(n log n) time, where n is the length of the array.\n", - "\n", - "2. The outer loop runs for each element of the array, so it iterates O(n) times.\n", - "\n", - "3. Inside the outer loop, we have a while loop with two pointers (`left` and `right`). In the worst case, the while loop can iterate O(n) times (when all elements are unique).\n", - "\n", - "4. Inside the while loop, we have constant time operations (additions, comparisons, and list appends).\n", - "\n", - "Overall, the time complexity of the `threeSum` function is dominated by the sorting step, so it is O(n log n) due to the sorting. The other operations inside the loops contribute linearly but are dominated by the sorting step.\n", - "\n", - "**Space Complexity:**\n", - "1. The space used by the `triplets` list to store the output triplets is O(k), where k is the number of unique triplets that sum up to zero. In the worst case, this can be O(n^2/3) because there can be roughly O(n^2) possible triplets, and many of them may sum up to zero.\n", - "\n", - "2. Other than the `triplets` list, the function uses only a constant amount of additional space for variables like `i`, `left`, `right`, and `total`.\n", - "\n", - "Overall, the space complexity of the `threeSum` function is O(k), where k is the number of unique triplets that meet the criteria. It's important to note that the space complexity does not depend on the size of the input array but rather on the number of valid triplets found.\n", - "\n", - "**In summary:**\n", - "- Time Complexity: O(n log n) due to sorting (dominant factor) and O(n^2) in the worst case for the nested loops.\n", - "- Space Complexity: O(k) for storing the output triplets, where k is the number of unique triplets that meet the criteria." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **K-Sum Problem:** Generalize the problem to the K-Sum problem, where instead of finding triplets that sum to zero, you need to find K elements that sum to a target value. Implement a function for this generalization.\n", - "2. **Count the Number of Unique Triplets:** Modify the algorithm to count the number of unique triplets that satisfy the conditions instead of returning the triplets themselves. This will require some modifications to handle duplicates efficiently." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/02. Two Pointers/README.md b/docs/02. Two Pointers/README.md deleted file mode 100644 index 0d4c7cf..0000000 --- a/docs/02. Two Pointers/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# Two Pointers Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [125. Valid Palindrome](https://leetcode.com/problems/valid-palindrome/) | Easy | -| [15. 3Sum](https://leetcode.com/problems/3sum/) | Medium | -| [11. Container With Most Water](https://leetcode.com/problems/container-with-most-water/) | Medium | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! \ No newline at end of file diff --git a/docs/03. Sliding Window/121. Best Time to Buy and Sell Stock.ipynb b/docs/03. Sliding Window/121. Best Time to Buy and Sell Stock.ipynb deleted file mode 100644 index 554c940..0000000 --- a/docs/03. Sliding Window/121. Best Time to Buy and Sell Stock.ipynb +++ /dev/null @@ -1,191 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 121. Best Time to Buy and Sell Stock\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Best Time to Buy and Sell Stock problem on LeetCode, click here!](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/)\n", - "\n", - "---\n", - "\n", - "You are given an array `prices` where `prices[i]` is the price of a given stock on the $i^{th}$ day.\n", - "\n", - "You want to maximize your profit by choosing a **single day** to buy one stock and choosing a **different day in the future** to sell that stock.\n", - "\n", - "*Return the maximum profit you can achieve from this transaction. If you cannot achieve any profit, return `0`.*\n", - "\n", - "**Constraints:**\n", - "\n", - "- 1 <= `prices.length` <= $10^5$\n", - "- 0 <= `prices[i]` <= $10^4$\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 65, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def maxProfit(prices):\n", - " if not prices:\n", - " return 0\n", - " \n", - " min_price = prices[0]\n", - " max_profit = 0\n", - " \n", - " for price in prices:\n", - " # Update the minimum price if a lower price is encountered\n", - " min_price = min(min_price, price)\n", - " # Calculate the profit if selling at the current price\n", - " max_profit = max(max_profit, price - min_price)\n", - " \n", - " return max_profit" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "- The `maxProfit` function takes a single argument, `prices`, which is a list of stock prices.\n", - "- The first line of the function checks if the `prices` list is empty. If it's empty, there are no prices to analyze, so the function returns 0 (no profit can be made).\n", - "\n", - "- Then, we initialize two variables:\n", - " - `min_price`: This variable will keep track of the minimum price seen so far. We initialize it with the price of the first day in the list (`prices[0]`).\n", - " - `max_profit`: This variable will keep track of the maximum profit we can achieve. We initialize it to 0 because initially, we haven't made any profit.\n", - "\n", - "- We start iterating through the `prices` list, where `price` represents the stock price for the current day.\n", - "\n", - "- In each iteration, we check if the current `price` is lower than the `min_price` we've seen so far. If it is, we update `min_price` to the current `price`. This is because we want to buy the stock at the lowest possible price.\n", - "\n", - "- Next, we calculate the profit we would make if we sold the stock at the current `price` (assuming we bought it at `min_price`). We do this by subtracting `min_price` from the current `price`. This represents the profit for the current day.\n", - "\n", - "- We also use the `max` function to keep track of the maximum profit seen so far. If the profit calculated for the current day is greater than the `max_profit` we've seen previously, we update `max_profit` with this higher value.\n", - "\n", - "- Finally, after iterating through all the days in the `prices` list, we return `max_profit`, which represents the maximum profit that can be achieved by buying and selling a single stock." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 66, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "5\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "prices1 = [7, 1, 5, 3, 6, 4]\n", - "print(maxProfit(prices1))" - ] - }, - { - "cell_type": "code", - "execution_count": 67, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "prices2 = [7, 6, 4, 3, 1]\n", - "print(maxProfit(prices2))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "- The code iterates through the `prices` array once, examining each price exactly once.\n", - "- Within the loop, there are constant-time operations such as comparisons, additions, and subtractions.\n", - "- Therefore, the time complexity of this code is O(n), where n is the length of the `prices` array. It performs a linear number of operations relative to the size of the input.\n", - "\n", - "**Space Complexity:**\n", - "- The space complexity of the code is constant, O(1).\n", - "- Regardless of the size of the input `prices` array, the code only uses a fixed amount of additional memory to store two variables (`min_price` and `max_profit`) and a few loop variables.\n", - "- The memory usage does not depend on the size of the input, so it is considered constant space complexity.\n", - "\n", - "**In summary:**\n", - "- Time Complexity: O(n) where n is the length of the `prices` array.\n", - "- Space Complexity: O(1) (constant space usage)." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Multiple Transactions Allowed:** Modify the problem to allow multiple transactions (buy and sell multiple times), but you must sell before buying again. Find the maximum profit in this scenario.\n", - "2. **K Transactions Allowed:** Extend the problem to allow at most k transactions. Find the maximum profit considering this constraint.\n", - "3. **With Transaction Fee:** Introduce a transaction fee for each buy/sell operation. Modify the code to maximize profit while considering the transaction fee." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/03. Sliding Window/3. Longest Substring Without Repeating Characters.ipynb b/docs/03. Sliding Window/3. Longest Substring Without Repeating Characters.ipynb deleted file mode 100644 index 4a516de..0000000 --- a/docs/03. Sliding Window/3. Longest Substring Without Repeating Characters.ipynb +++ /dev/null @@ -1,214 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 3. Longest Substring Without Repeating Characters\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Longest Substring Without Repeating Characters problem on LeetCode, click here!](https://leetcode.com/problems/longest-substring-without-repeating-characters/)\n", - "\n", - "---\n", - "Given a string `s`, find the length of the **longest substring** without repeating characters.\n", - "\n", - "**Constraints:**\n", - "\n", - "- 0 <= `s.length` <= $5 * 10^4$\n", - "- `s` consists of English letters, digits, symbols and spaces.\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 61, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def length_of_longest_substring(s):\n", - " # Create a dictionary to store the index of each character's last occurrence.\n", - " char_index = {}\n", - " \n", - " # Initialize variables to keep track of the start and end of the current substring.\n", - " start = 0\n", - " max_length = 0\n", - " \n", - " for end in range(len(s)):\n", - " # If the character is in the dictionary and its last occurrence is after the start of the current substring,\n", - " # update the start of the substring to the next character after its last occurrence.\n", - " if s[end] in char_index and char_index[s[end]] >= start:\n", - " start = char_index[s[end]] + 1\n", - " \n", - " # Update the last occurrence index of the current character.\n", - " char_index[s[end]] = end\n", - " \n", - " # Calculate the length of the current substring and update the maximum length if necessary.\n", - " current_length = end - start + 1\n", - " max_length = max(max_length, current_length)\n", - " \n", - " return max_length" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start by defining a function called `length_of_longest_substring` that takes a single argument `s`, which is the input string for which we want to find the length of the longest substring without repeating characters.\n", - "\n", - "2. We create a dictionary called `char_index` to store the index of the last occurrence of each character in the input string. This dictionary will help us keep track of where each character was last seen.\n", - "\n", - "3. We initialize two variables, `start` and `max_length`. \n", - " - `start` represents the start index of the current substring without repeating characters. It starts at 0.\n", - " - `max_length` is used to keep track of the maximum length found so far and is initially set to 0.\n", - "\n", - "4. We then iterate through the input string `s` using a for loop, where the loop variable `end` represents the current end index of the substring we are considering.\n", - "\n", - "5. Inside the loop:\n", - " - We check if the character `s[end]` is already in the `char_index` dictionary and if its last occurrence is within or after the current substring. If so, it means that we've encountered a repeating character, and we need to update the `start` of the substring to the next character after the last occurrence of `s[end]`. This ensures that we have a new valid substring without repeating characters.\n", - " - We then update the `char_index` dictionary by storing the current index `end` as the last occurrence index of the character `s[end]`.\n", - "\n", - "6. Next, we calculate the length of the current substring without repeating characters, which is `current_length = end - start + 1`. We add 1 to account for the fact that the indices are zero-based.\n", - "\n", - "7. We update the `max_length` with the maximum of its current value and the `current_length`. This step ensures that we keep track of the longest valid substring we have encountered so far.\n", - "\n", - "8. The loop continues to iterate through the input string, and at the end, we return the `max_length`, which represents the length of the longest substring without repeating characters." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 62, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "print(length_of_longest_substring(\"abcabcbb\"))" - ] - }, - { - "cell_type": "code", - "execution_count": 63, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "print(length_of_longest_substring(\"bbbbb\"))" - ] - }, - { - "cell_type": "code", - "execution_count": 64, - "id": "cf04eba0-0ead-4e8b-ba33-4316ea64a9d3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "print(length_of_longest_substring(\"pwwkew\"))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "Let's analyze the time and space complexity of the `length_of_longest_substring` function:\n", - "\n", - "**Time Complexity:**\n", - "- The function iterates through the input string `s` using a single for loop. The loop runs from the beginning of the string to the end once.\n", - "- Inside the loop, we perform constant-time operations such as dictionary lookups and updates, comparisons, and arithmetic operations.\n", - "- Therefore, the time complexity of the function is O(n), where n is the length of the input string `s`.\n", - "\n", - "**Space Complexity:**\n", - "- The primary data structure that consumes space in this function is the `char_index` dictionary.\n", - "- In the worst case, if there are no repeating characters in the input string, the dictionary can store all unique characters in the string.\n", - "- Therefore, the space complexity is O(min(n, m)), where n is the length of the input string `s`, and m is the number of unique characters in the string. In the worst case, when all characters are unique, m is equal to n, so the space complexity is O(n).\n", - "- Additionally, there are a few integer variables used for indices and lengths, which consume constant space.\n", - "- Overall, the space complexity of the function is O(min(n, m)) or simply O(n) in the worst case.\n", - "\n", - "**In summary,** the time complexity of the `length_of_longest_substring` function is O(n), and the space complexity is O(n) in the worst case due to the `char_index` dictionary. This algorithm provides an efficient way to find the length of the longest substring without repeating characters in linear time." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Longest Substring with K Distinct Characters:** Modify the problem to find the length of the longest substring with exactly K distinct characters. For example, given the input string \"abcabcbb\" and K = 2, the answer would be 4 because the longest substring with two distinct characters is \"abca.\"\n", - "2. **Longest Substring with Unique Characters:** Write a function to find the length of the longest substring in a given string where all characters are unique. For example, given the input string \"abcabcbb,\" the answer would be 4 because \"abcd\" is the longest substring with unique characters." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/03. Sliding Window/424. Longest Repeating Character Replacement.ipynb b/docs/03. Sliding Window/424. Longest Repeating Character Replacement.ipynb deleted file mode 100644 index 07e96a2..0000000 --- a/docs/03. Sliding Window/424. Longest Repeating Character Replacement.ipynb +++ /dev/null @@ -1,195 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 424. Longest Repeating Character Replacement\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Longest Repeating Character Replacement problem on LeetCode, click here!](https://leetcode.com/problems/longest-repeating-character-replacement/)\n", - "\n", - "---\n", - "You are given a string `s` and an integer `k`. You can choose any character of the string and change it to any other uppercase English character. You can perform this operation at most `k` times.\n", - "\n", - "*Return the length of the longest substring containing the same letter you can get after performing the above operations.*\n", - "\n", - "**Constraints:**\n", - "\n", - "- 1 <= `s.length` <= $10^5$\n", - "- `s` consists of only uppercase English letters.\n", - "- `0 <= k <= s.length`" - ] - }, - { - "cell_type": "code", - "execution_count": 58, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def characterReplacement(s, k):\n", - " max_length = 0 # Initialize the maximum length\n", - " max_count = 0 # Initialize the maximum count of repeating characters\n", - " start = 0 # Initialize the start of the sliding window\n", - " char_count = {} # Dictionary to store the count of each character\n", - "\n", - " for end in range(len(s)):\n", - " # Update the count of the current character in the dictionary\n", - " char_count[s[end]] = char_count.get(s[end], 0) + 1\n", - " \n", - " # Update the maximum count of repeating characters\n", - " max_count = max(max_count, char_count[s[end]])\n", - " \n", - " # Check if the current window size is greater than k\n", - " if (end - start + 1) - max_count > k:\n", - " # Move the start of the window to the right\n", - " char_count[s[start]] -= 1\n", - " start += 1\n", - " \n", - " # Update the maximum length\n", - " max_length = max(max_length, end - start + 1)\n", - "\n", - " return max_length" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We initialize some variables:\n", - " - `max_length` to keep track of the maximum length of the substring containing the same letter.\n", - " - `max_count` to keep track of the maximum count of repeating characters within the current window.\n", - " - `start` to represent the start index of the sliding window.\n", - " - `char_count` is a dictionary that will store the count of each character within the current window.\n", - "\n", - "2. We use a `for` loop to iterate through the characters of the string `s`.\n", - "\n", - "3. Inside the loop, we do the following for each character at position `end`:\n", - " - Update the count of the current character in the `char_count` dictionary.\n", - " - Update the `max_count` to be the maximum of the current `max_count` and the count of the current character. This keeps track of the maximum count of repeating characters within the current window.\n", - "\n", - "4. We check if the current window size (the difference between `end` and `start` plus one) minus the `max_count` is greater than `k`. This condition checks whether we have exceeded the allowed number of replacements (`k`) within the current window.\n", - "\n", - " - If we have exceeded the allowed replacements, it means we need to shrink the window from the left side. We do this by moving the `start` of the window to the right and decrementing the count of the character at `s[start]` in the `char_count` dictionary. This effectively removes characters from the left side of the window until we have a valid window again.\n", - "\n", - " - By doing this, we ensure that the difference between the current window size and the `max_count` is always less than or equal to `k`.\n", - "\n", - "5. After each character, we update the `max_length` to be the maximum of the current `max_length` and the size of the current window (`end - start + 1`).\n", - "\n", - "6. Finally, we return `max_length`, which holds the length of the longest substring containing the same letter with at most `k` replacements." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 59, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "s1 = \"ABAB\"\n", - "k1 = 2\n", - "print(characterReplacement(s1, k1))" - ] - }, - { - "cell_type": "code", - "execution_count": 60, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "s2 = \"AABABBA\"\n", - "k2 = 1\n", - "print(characterReplacement(s2, k2))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "- The code uses a single `for` loop to iterate through the characters of the input string `s`. The loop runs from the beginning to the end of the string.\n", - "- Inside the loop, we perform constant-time operations such as updating the `char_count` dictionary and updating variables like `max_count` and `max_length`.\n", - "- The code's time complexity is primarily determined by the loop, which iterates through each character in the string once. Therefore, the time complexity is O(n), where n is the length of the input string `s`.\n", - "\n", - "**Space Complexity:**\n", - "- The code uses several variables to store information, but the space they consume is constant and does not depend on the size of the input string. These variables include `max_length`, `max_count`, `start`, and `char_count`. Therefore, the space complexity is O(1) or constant space.\n", - "\n", - "**In summary**, the time complexity of the code is O(n), where n is the length of the input string, and the space complexity is O(1), as it uses a constant amount of additional space regardless of the input size. This algorithm efficiently solves the problem with a linear time complexity." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Optimization Challenge:** Modify the code to find the longest substring containing the same letter with at most k replacements in O(n) time complexity and O(1) space complexity. Hint: You may need to update the approach to achieve this.\n", - "2. **Variation with Lowercase Letters:** Extend the problem to include both uppercase and lowercase English letters in the input string s. Write a function that can handle this extended input and still find the longest substring with at most k replacements efficiently." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/03. Sliding Window/76. Minimum Window Substring.ipynb b/docs/03. Sliding Window/76. Minimum Window Substring.ipynb deleted file mode 100644 index 33c2a44..0000000 --- a/docs/03. Sliding Window/76. Minimum Window Substring.ipynb +++ /dev/null @@ -1,273 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 76. Minimum Window Substring\n", - "\n", - "**Difficulty:** Hard\n", - "\n", - "**Link to Problem:** [To see the Minimum Window Substring problem on LeetCode, click here!](https://leetcode.com/problems/minimum-window-substring/)\n", - "\n", - "---\n", - "Given two strings `s` and `t` of lengths `m` and `n` respectively, return *the **minimum window substring** of `s` such that every character in `t` (**including duplicates**) is included in the window. If there is no such substring, return the empty string `\"\"`.*\n", - "\n", - "The testcases will be generated such that the answer is **unique**.\n", - "\n", - "**Constraints:**\n", - "\n", - "- `m == s.length`\n", - "- `n == t.length`\n", - "- 1 <= `m, n` <= $10^5$\n", - "- `s` and `t` consist of uppercase and lowercase English letters.\n", - "\n", - "**Follow up**: Could you find an algorithm that runs in $O(m + n)$ time?" - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def min_window_substring(s, t):\n", - " if not s or not t:\n", - " return \"\"\n", - "\n", - " # Initialize dictionaries to keep track of character counts for t and the current window in s.\n", - " t_dict = {}\n", - " current_window_dict = {}\n", - " \n", - " # Populate t_dict with character counts for string t.\n", - " for char in t:\n", - " t_dict[char] = t_dict.get(char, 0) + 1\n", - "\n", - " # Initialize pointers for the sliding window.\n", - " left = 0\n", - " min_len = float('inf')\n", - " min_window = \"\"\n", - " required_chars = len(t_dict)\n", - "\n", - " # Initialize a variable to keep track of how many required characters have been found in the current window.\n", - " found_chars = 0\n", - "\n", - " # Iterate over the string s using the right pointer.\n", - " for right in range(len(s)):\n", - " char = s[right]\n", - "\n", - " # Update the current_window_dict.\n", - " current_window_dict[char] = current_window_dict.get(char, 0) + 1\n", - "\n", - " # Check if the current character is a required character and if its count matches the required count.\n", - " if char in t_dict and current_window_dict[char] == t_dict[char]:\n", - " found_chars += 1\n", - "\n", - " # Try to minimize the window by moving the left pointer.\n", - " while left <= right and found_chars == required_chars:\n", - " # Calculate the current window size.\n", - " window_size = right - left + 1\n", - "\n", - " # If the current window is smaller than the minimum found so far, update min_len and min_window.\n", - " if window_size < min_len:\n", - " min_len = window_size\n", - " min_window = s[left:right+1]\n", - "\n", - " # Move the left pointer to the right to shrink the window.\n", - " left_char = s[left]\n", - " current_window_dict[left_char] -= 1\n", - "\n", - " # Check if the character removed from the window was a required character.\n", - " if left_char in t_dict and current_window_dict[left_char] < t_dict[left_char]:\n", - " found_chars -= 1\n", - "\n", - " # Move the left pointer further to continue shrinking the window.\n", - " left += 1\n", - "\n", - " return min_window" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start by checking if either of the input strings `s` or `t` is empty. If either of them is empty, we return an empty string since there can't be any valid substring in this case.\n", - "\n", - "2. We initialize two dictionaries: `t_dict` and `current_window_dict`. These dictionaries will be used to keep track of character counts in the string `t` and the current window in string `s`, respectively.\n", - "\n", - "3. We populate the `t_dict` dictionary by iterating through string `t`. For each character, we increment its count in the dictionary using `t_dict.get(char, 0) + 1`. This allows us to count the occurrences of each character in `t`.\n", - "\n", - "4. We initialize two pointers: `left` and `right`. The `left` pointer will represent the start of the current window, and the `right` pointer will represent the end of the current window. We also initialize `min_len` to store the length of the minimum window found so far, and `min_window` to store the actual minimum window substring.\n", - "\n", - "5. We determine the number of required characters in `t` (i.e., the number of distinct characters in `t`) and store it in the variable `required_chars`.\n", - "\n", - "6. We initialize a variable `found_chars` to keep track of how many required characters have been found in the current window. Initially, it is set to 0.\n", - "\n", - "7. We iterate over the string `s` using the `right` pointer. In each iteration, we do the following:\n", - "\n", - " - Update the `current_window_dict` by incrementing the count of the current character.\n", - " \n", - " - Check if the current character is a required character (present in `t_dict`) and if its count in the `current_window_dict` matches the required count from `t_dict`. If so, we increment `found_chars`.\n", - "\n", - "8. After updating the window, we attempt to minimize the window size by moving the `left` pointer to the right. In this step, we:\n", - "\n", - " - Calculate the size of the current window.\n", - " \n", - " - If the current window size is smaller than the minimum found so far (`min_len`), we update `min_len` and `min_window` to store the current window substring.\n", - " \n", - " - Move the `left` pointer to the right to shrink the window.\n", - " \n", - " - Check if the character being removed from the window was a required character. If it was, we decrement `found_chars`.\n", - " \n", - " - Continue moving the `left` pointer further to continue shrinking the window if the window still contains all required characters.\n", - "\n", - "9. Finally, we return `min_window`, which will contain the minimum window substring that contains all characters from `t`." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 55, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "BANC\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "print(min_window_substring(\"ADOBECODEBANC\", \"ABC\"))" - ] - }, - { - "cell_type": "code", - "execution_count": 56, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "a\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "print(min_window_substring(\"a\", \"a\")) " - ] - }, - { - "cell_type": "code", - "execution_count": 57, - "id": "6c69a707-02af-4212-b2e7-1881d62a62d2", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "print(min_window_substring(\"a\", \"aa\")) " - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the `min_window_substring` function:\n", - "\n", - "**Time Complexity:**\n", - "- The main loop iterates through the string `s` from left to right using the `right` pointer. This loop runs in O(m) time, where 'm' is the length of string `s`.\n", - "\n", - "- Inside the loop, we have a while loop that moves the `left` pointer to the right to shrink the window as needed. In the worst case, this while loop can also run in O(m) time because in the worst case, we may have to move the `left` pointer all the way to the end of the string.\n", - "\n", - "- Within each iteration of the while loop, we perform constant time operations, such as updating dictionaries and comparing character counts.\n", - "\n", - "- The initialization of the `t_dict` dictionary takes O(n) time, where 'n' is the length of string `t`.\n", - "\n", - "Therefore, the overall time complexity of the function is O(m + n) because the dominant factor is the length of string `s`, and the length of string `t` has a smaller impact.\n", - "\n", - "**Space Complexity:**\n", - "- The space complexity is determined by the space used by the `t_dict` dictionary, the `current_window_dict` dictionary, and a few variables.\n", - "\n", - "- The `t_dict` dictionary stores character counts for string `t`. In the worst case, when all characters in `t` are distinct, this dictionary can have a maximum of 'n' key-value pairs. So, the space complexity for `t_dict` is O(n).\n", - "\n", - "- The `current_window_dict` dictionary stores character counts for the current window. In the worst case, it can have a maximum of 'm' key-value pairs. So, the space complexity for `current_window_dict` is also O(m).\n", - "\n", - "- Other variables used in the function, such as `left`, `right`, `min_len`, `min_window`, `required_chars`, and `found_chars`, are all of constant size and do not depend on the input sizes.\n", - "\n", - "**In summary**, the overall space complexity of the function is O(max(m, n)), which means it is determined by the larger of the two input strings' lengths. This is because the space used for `t_dict` and `current_window_dict` dominates the space complexity." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Smallest Distinct Substring:** Instead of finding the minimum window substring containing all characters, find the smallest distinct (unique) substring of s that contains all characters from t. This variation adds complexity because you must find a substring with distinct characters.\n", - "2. **No Extra Space:** Solve the problem without using any extra space, such as dictionaries or arrays, other than a constant amount of space. This is a significant optimization challenge." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/03. Sliding Window/README.md b/docs/03. Sliding Window/README.md deleted file mode 100644 index e1294ff..0000000 --- a/docs/03. Sliding Window/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# Sliding Window Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [121. Best Time to Buy And Sell Stock](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/) | Easy | -| [3. Longest Substring Without Repeating Characters](https://leetcode.com/problems/longest-substring-without-repeating-characters/) | Medium | -| [424. Longest Repeating Character Replacement](https://leetcode.com/problems/longest-repeating-character-replacement/) | Medium | -| [76. Minimum Window Substring](https://leetcode.com/problems/minimum-window-substring/) | Hard | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! \ No newline at end of file diff --git a/docs/04. Stack/20. Valid Parentheses.ipynb b/docs/04. Stack/20. Valid Parentheses.ipynb deleted file mode 100644 index c47292f..0000000 --- a/docs/04. Stack/20. Valid Parentheses.ipynb +++ /dev/null @@ -1,220 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 20. Valid Parentheses\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Valid Parentheses problem on LeetCode, click here!](https://leetcode.com/problems/valid-parentheses/)\n", - "\n", - "---\n", - "\n", - "Given a string s containing just the characters `'('`, `')'`, `'{'`, `'}'`, `'['` and `']'`, determine if the input string is valid.\n", - "\n", - "An input string is valid if:\n", - "\n", - "1. Open brackets must be closed by the same type of brackets.\n", - "2. Open brackets must be closed in the correct order.\n", - "3. Every close bracket has a corresponding open bracket of the same type.\n", - "\n", - "**Constraints:**\n", - "\n", - "- 1 <= `s.length` <= $10^4$\n", - "- `s` consists of parentheses only `'()[]{}'`." - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def isValid(s):\n", - " # Create an empty stack to store opening brackets\n", - " stack = []\n", - " \n", - " # Define a mapping for matching brackets\n", - " bracket_mapping = {')': '(', '}': '{', ']': '['}\n", - " \n", - " # Iterate through the characters in the input string\n", - " for char in s:\n", - " # If the character is an opening bracket, push it onto the stack\n", - " if char in bracket_mapping.values():\n", - " stack.append(char)\n", - " # If the character is a closing bracket\n", - " elif char in bracket_mapping.keys():\n", - " # Pop the top element from the stack if it exists, or use a dummy value '#'\n", - " top_element = stack.pop() if stack else '#'\n", - " # If the popped element does not match the corresponding opening bracket, return False\n", - " if bracket_mapping[char] != top_element:\n", - " return False\n", - " # If the character is not a bracket, ignore it\n", - " \n", - " # After processing the entire string, if there are any unmatched opening brackets left in the stack, return False\n", - " return len(stack) == 0" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start by defining the `isValid` function that takes a single argument `s`, which is the input string containing parentheses and brackets.\n", - "\n", - "2. Inside the function, we create an empty stack, which is a list in Python, to store opening brackets as we encounter them in the input string. The stack will help us keep track of the brackets and their order.\n", - "\n", - "3. We define a `bracket_mapping` dictionary that maps each closing bracket to its corresponding opening bracket. This mapping will be used to check if a closing bracket matches the most recent opening bracket in the stack.\n", - "\n", - "4. We iterate through each character `char` in the input string `s` using a `for` loop.\n", - "\n", - "5. If the character `char` is an opening bracket (i.e., it exists in the `values()` of `bracket_mapping`), we push it onto the stack using the `append()` method.\n", - "\n", - "6. If the character `char` is a closing bracket (i.e., it exists in the `keys()` of `bracket_mapping`), we need to check if it matches the corresponding opening bracket. To do this, we pop the top element from the stack (if it exists) and store it in `top_element`. We use a dummy value `'#'` if the stack is empty to avoid errors.\n", - "\n", - "7. We then compare `top_element` with the corresponding opening bracket using `bracket_mapping[char]`. If they do not match, it means the string is not valid, and we return `False`.\n", - "\n", - "8. If the character `char` is not a bracket, we simply ignore it and continue the loop.\n", - "\n", - "9. After processing the entire string, we check if there are any unmatched opening brackets left in the stack. If the stack is empty, it means all opening brackets have been properly matched and closed, and we return `True`. Otherwise, we return `False`.\n", - "\n", - "10. Finally, we provide some test cases at the bottom of the code to demonstrate how the function works for different input strings." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "print(isValid(\"()\")) " - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "print(isValid(\"()[]{}\")) " - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "id": "6c69a707-02af-4212-b2e7-1881d62a62d2", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "print(isValid(\"(]\")) " - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the `isValid` function:\n", - "\n", - "**Time Complexity:**\n", - "- The function iterates through each character in the input string `s` once, performing constant-time operations for each character.\n", - "- Pushing and popping elements from the stack (list) also takes constant time in most cases.\n", - "- Therefore, the overall time complexity of the function is $O(n)$, where $n$ is the length of the input string `s`.\n", - "\n", - "**Space Complexity:**\n", - "- The space complexity of the function is determined by the space used by the stack and the `bracket_mapping` dictionary.\n", - "- In the worst case, if the input string `s` consists entirely of opening brackets, the stack can potentially contain all of these opening brackets, resulting in a space complexity of $O(n)$ in terms of the stack.\n", - "- The `bracket_mapping` dictionary has a constant number of key-value pairs (3 pairs in this case).\n", - "- Therefore, the overall space complexity of the function is $O(n)$, where $n$ is the length of the input string `s`, mainly due to the stack space.\n", - "\n", - "**In summary:**\n", - "- The time complexity is $O(n)$ because we iterate through the string once.\n", - "- The space complexity is $O(n)$ due to the stack used to keep track of opening brackets." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Valid Expressions:** Modify the problem to validate not only brackets but also arithmetic expressions containing parentheses, such as \"$2 * (3 + 5) / (4 - 2)$\".\n", - "2. **Valid Parentheses Combinations:**\n", - "Write a function to generate all valid combinations of n pairs of parentheses, where $n$ is a positive integer. For example, for $n = 3$, the valid combinations are [\"((()))\", \"(()())\", \"(())()\", \"()(())\", \"()()()\"]." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/04. Stack/README.md b/docs/04. Stack/README.md deleted file mode 100644 index 2ed115b..0000000 --- a/docs/04. Stack/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# Stack Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [20. Valid Parentheses](https://leetcode.com/problems/valid-parentheses/) | Easy | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! \ No newline at end of file diff --git a/docs/05. Binary Search/153. Find Minimum in Rotated Sorted Array.ipynb b/docs/05. Binary Search/153. Find Minimum in Rotated Sorted Array.ipynb deleted file mode 100644 index 98f2331..0000000 --- a/docs/05. Binary Search/153. Find Minimum in Rotated Sorted Array.ipynb +++ /dev/null @@ -1,228 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 153. Find Minimum in Rotated Sorted Array\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Find Minimum in Rotated Sorted Array problem on LeetCode, click here!](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/)\n", - "\n", - "---\n", - "\n", - "Suppose an array of length `n` sorted in ascending order is **rotated** between `1` and `n` times. For example, the array `nums = [0,1,2,4,5,6,7]` might become:\n", - "\n", - "- `[4,5,6,7,0,1,2]` if it was rotated `4` times.\n", - "- `[0,1,2,4,5,6,7]` if it was rotated `7` times.\n", - "\n", - "Notice that **rotating** an array `[a[0], a[1], a[2], ..., a[n-1]]` 1 time results in the array `[a[n-1], a[0], a[1], a[2], ..., a[n-2]]`.\n", - "\n", - "Given the sorted rotated array `nums` of **unique** elements, return *the minimum element of this array.*\n", - "\n", - "You must write an algorithm that runs in $O(log\\ n)$ time.\n", - " \n", - "\n", - "**Constraints:**\n", - "\n", - "- `n == nums.length`\n", - "- `1 <= n <= 5000`\n", - "- `-5000 <= nums[i] <= 5000`\n", - "- All the integers of `nums` are **unique**.\n", - "- `nums` is sorted and rotated between `1` and `n` times." - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def findMin(nums):\n", - " left, right = 0, len(nums) - 1\n", - " \n", - " while left < right:\n", - " mid = left + (right - left) // 2\n", - " \n", - " # If the mid element is greater than the rightmost element,\n", - " # it means the minimum element is in the right half.\n", - " if nums[mid] > nums[right]:\n", - " left = mid + 1\n", - " # If the mid element is less than or equal to the rightmost element,\n", - " # it means the minimum element is in the left half or at the mid itself.\n", - " else:\n", - " right = mid\n", - " \n", - " # The loop will break when left and right converge to the minimum element.\n", - " # At this point, left (or right) will be pointing to the minimum element.\n", - " return nums[left]" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. The function `findMin(nums)` takes an input list `nums`, which represents the rotated sorted array.\n", - "\n", - "2. Initialize two pointers `left` and `right` to track the current search range. Initially, `left` is set to 0 (the beginning of the array), and `right` is set to `len(nums) - 1` (the end of the array).\n", - "\n", - "3. Enter a `while` loop with the condition `left < right`. This loop continues until `left` and `right` converge to a single element, which will be the minimum element in the rotated array.\n", - "\n", - "4. Inside the loop, calculate the middle index `mid` using integer division. This helps in finding the middle element of the current search range.\n", - "\n", - "5. Check if the element at the middle index (`nums[mid]`) is greater than the element at the rightmost index (`nums[right]`). If this condition is true, it means that the minimum element must be in the right half of the current search range. So, update `left` to `mid + 1`, effectively eliminating the left half of the search range.\n", - "\n", - "6. If the condition from step 5 is not met, it implies that the minimum element can be in the left half of the current search range or could be the element at the `mid` index itself. In this case, update `right` to `mid`, effectively eliminating the right half of the search range.\n", - "\n", - "7. Repeat steps 4-6 until `left` and `right` converge to the minimum element.\n", - "\n", - "8. When the loop exits, it means that `left` (or `right`) points to the minimum element in the array.\n", - "\n", - "9. Return `nums[left]` (or `nums[right]`) as the result, which is the minimum element in the rotated sorted array." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n" - ] - } - ], - "source": [ - "### Example 1:\n", - "nums1 = [3, 4, 5, 1, 2]\n", - "print(findMin(nums1))" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "nums2 = [4, 5, 6, 7, 0, 1, 2]\n", - "print(findMin(nums2))" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "id": "6c69a707-02af-4212-b2e7-1881d62a62d2", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "11\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "nums3 = [11, 13, 15, 17]\n", - "print(findMin(nums3))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "The time complexity of this code is $O(log\\ n)$, where '$n$' is the length of the input array `nums`. This is because the binary search algorithm is employed, which continually divides the search range in half with each iteration.\n", - "\n", - "In each iteration of the `while` loop, the search range is halved, and this process continues until the `left` and `right` pointers converge to the minimum element. In the worst case, it will take logarithmic time to reduce the search range to a single element.\n", - "\n", - "Therefore, the binary search used in this code runs in $O(log\\ n)$ time complexity.\n", - "\n", - "**Space Complexity:**\n", - "The space complexity of this code is $O(1)$, which means it uses a constant amount of additional space that does not depend on the size of the input array.\n", - "\n", - "The algorithm uses a fixed number of variables (`left`, `right`, `mid`) to keep track of the search range and indices, but the number of these variables does not grow with the size of the input array. Hence, the space complexity is constant.\n", - "\n", - "**In summary:**\n", - "- Time Complexity: $O(log\\ n)$\n", - "- Space Complexity: $O(1)$" - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. Solve the problem with a variation where the input array may contain duplicates.\n", - "\n", - "2. Modify the problem to return the index of the minimum element in the rotated sorted array, rather than the element itself. The algorithm should still run in $O(log\\ n)$ time.\n", - "\n", - "3. Implement a function that finds the maximum element in a rotated sorted array. How would you adapt the binary search algorithm to solve this problem efficiently in $O(log\\ n)$ time?\n", - "\n", - "4. Implement a function that can find the kth smallest element in a rotated sorted array. This is an extension of the original problem, and the algorithm should still run in $O(log\\ n)$ time." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/05. Binary Search/33. Search in Rotated Sorted Array.ipynb b/docs/05. Binary Search/33. Search in Rotated Sorted Array.ipynb deleted file mode 100644 index d8d4202..0000000 --- a/docs/05. Binary Search/33. Search in Rotated Sorted Array.ipynb +++ /dev/null @@ -1,245 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 33. Search in Rotated Sorted Array\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Search in Rotated Sorted Array problem on LeetCode, click here!](https://leetcode.com/problems/search-in-rotated-sorted-array/)\n", - "\n", - "---\n", - "\n", - "There is an integer array `nums` sorted in ascending order (with **distinct** values).\n", - "\n", - "Prior to being passed to your function, `nums` is **possibly rotated** at an unknown pivot index `k (1 <= k < nums.length)` such that the resulting array is `[nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]]` (**0-indexed**). For example, `[0,1,2,4,5,6,7]` might be rotated at pivot index 3 and become `[4,5,6,7,0,1,2]`.\n", - "\n", - "Given the array `nums` **after** the possible rotation and an integer `target`, return *the index of `target` if it is in `nums`, or `-1` if it is not in `nums`.*\n", - "\n", - "You must write an algorithm with $O(log\\ n)$ runtime complexity.\n", - " \n", - "\n", - "**Constraints:**\n", - "\n", - "- `1 <= nums.length <= 5000`\n", - "- $-10^4$ <= `nums[i]` <= $10^4$\n", - "- All values of `nums` are **unique**.\n", - "- `nums` is an ascending array that is possibly rotated.\n", - "- $-10^4$ <= `target` <= $10^4$" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def search(nums, target):\n", - " left, right = 0, len(nums) - 1\n", - "\n", - " # Find the pivot index using binary search\n", - " while left < right:\n", - " mid = left + (right - left) // 2\n", - "\n", - " if nums[mid] > nums[right]:\n", - " left = mid + 1\n", - " else:\n", - " right = mid\n", - "\n", - " pivot = left\n", - " left, right = 0, len(nums) - 1\n", - "\n", - " # Determine which part of the array to search in\n", - " if target >= nums[pivot] and target <= nums[right]:\n", - " left = pivot\n", - " else:\n", - " right = pivot\n", - "\n", - " # Perform binary search to find the target\n", - " while left <= right:\n", - " mid = left + (right - left) // 2\n", - "\n", - " if nums[mid] == target:\n", - " return mid\n", - " elif nums[mid] < target:\n", - " left = mid + 1\n", - " else:\n", - " right = mid - 1\n", - "\n", - " return -1" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. The `search` function takes two arguments: `nums`, which is the rotated sorted array, and `target`, which is the value we want to find in the array.\n", - "\n", - "2. We initialize two pointers, `left` and `right`, which represent the range in which we are going to perform binary search. Initially, `left` is set to 0, and `right` is set to the index of the last element in the array (`len(nums) - 1`).\n", - "\n", - "3. We start by finding the pivot index using binary search. The pivot index is the index at which the array is rotated. We use a `while` loop to continue the search until `left` is less than `right`.\n", - "\n", - "4. Inside the loop, we calculate the middle index `mid` using integer division. We then compare the value at `mid` with the value at `right`. If `nums[mid]` is greater than `nums[right]`, it means the pivot point lies to the right of `mid`, so we update `left` to `mid + 1`. Otherwise, the pivot point lies to the left of `mid`, so we update `right` to `mid`. This process continues until we find the pivot index.\n", - "\n", - "5. After finding the pivot index, we have divided the array into two parts: one part is sorted in ascending order, and the other part is also sorted in ascending order but rotated. We need to determine which part of the array contains the target value.\n", - "\n", - "6. We reset `left` and `right` pointers. If the target value is within the range `[nums[pivot], nums[right]]`, we set `left` to `pivot` (the start of the rotated part), indicating that we should search in the rotated part. Otherwise, we set `right` to `pivot` (the end of the sorted part), indicating that we should search in the sorted part.\n", - "\n", - "7. We then perform binary search again within the chosen range (`left` to `right`) to find the target element. The binary search continues until `left` is less than or equal to `right`.\n", - "\n", - "8. Inside the binary search loop, we calculate the middle index `mid` and compare `nums[mid]` with the target value. If they are equal, we return `mid` as the index of the target element. If `nums[mid]` is less than the target, we update `left` to `mid + 1` to search in the right half. If `nums[mid]` is greater than the target, we update `right` to `mid - 1` to search in the left half.\n", - "\n", - "9. If we exit the binary search loop without finding the target, we return -1 to indicate that the target is not present in the array." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n" - ] - } - ], - "source": [ - "nums1 = [4, 5, 6, 7, 0, 1, 2]\n", - "target1 = 0\n", - "result1 = search(nums1, target1)\n", - "print(result1) " - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "-1\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "nums2 = [4, 5, 6, 7, 0, 1, 2]\n", - "target2 = 3\n", - "result2 = search(nums2, target2)\n", - "print(result2) " - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "id": "6c69a707-02af-4212-b2e7-1881d62a62d2", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "-1\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "nums3 = [1]\n", - "target3 = 0\n", - "result3 = search(nums3, target3)\n", - "print(result3) " - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. Finding the pivot index using binary search takes $O(log\\ n)$ time, where '$n$' is the number of elements in the array.\n", - "2. After finding the pivot index, performing binary search to find the target element also takes $O(log\\ n)$ time in the worst case.\n", - "\n", - "The dominant factor in the time complexity is the binary search, and since we perform two binary searches sequentially, the overall time complexity of the code is $O(log\\ n)$.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity of the code is very minimal:\n", - "\n", - "1. We use a constant amount of additional space for variables such as `left`, `right`, `pivot`, and `mid`. These variables do not depend on the input size, so they contribute $O(1)$ space complexity.\n", - "2. The function does not use any additional data structures that scale with the input size.\n", - "\n", - "Therefore, the space complexity of the code is $O(1)$, which means it has a constant space complexity and does not depend on the size of the input array.\n", - "\n", - "**In summary:**\n", - "- Time Complexity: $O(log\\ n)$\n", - "- Space Complexity: $O(1)$" - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Find Minimum Element in Rotated Sorted Array**: Write an algorithm to find the minimum element in a rotated sorted array. This is a variation of the problem where you don't need to search for a target value but instead find the smallest element.\n", - "\n", - "2. **Search in a Circularly Sorted Array**: Consider an array that is sorted in a circular manner (e.g., [4, 5, 6, 7, 0, 1, 2, 3]). Adapt the search algorithm to work for circularly sorted arrays while maintaining $O(log\\ n)$ complexity." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/05. Binary Search/README.md b/docs/05. Binary Search/README.md deleted file mode 100644 index 6086b9b..0000000 --- a/docs/05. Binary Search/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Binary search Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [153. Find Minimum In Rotated Sorted Array](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/) | Medium | -| [33. Search In Rotated Sorted Array](https://leetcode.com/problems/search-in-rotated-sorted-array/) | Medium | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! diff --git a/docs/06. Linked List/141. Linked List Cycle.ipynb b/docs/06. Linked List/141. Linked List Cycle.ipynb deleted file mode 100644 index 0336bc8..0000000 --- a/docs/06. Linked List/141. Linked List Cycle.ipynb +++ /dev/null @@ -1,271 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 141. Linked List Cycle\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Linked List Cycle problem on LeetCode, click here!](https://leetcode.com/problems/linked-list-cycle/)\n", - "\n", - "---\n", - "\n", - "Given `head`, the head of a linked list, determine if the linked list has a cycle in it.\n", - "\n", - "There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the `next` pointer. Internally, `pos` is used to denote the index of the node that tail's `next` pointer is connected to. **Note that `pos` is not passed as a parameter.**\n", - "\n", - "Return `true` if there is a cycle in the linked list. Otherwise, return `false`.\n", - "\n", - " \n", - "\n", - "**Constraints:**\n", - "\n", - "- The number of the nodes in the list is in the range $[0, 10^4]$.\n", - "- $-10^5$ <= Node.val <= $10^5$\n", - "- `pos` is `-1` or a **valid index** in the linked-list.\n", - "\n", - "**Follow up:** Can you solve it using $O(1)$ (i.e. constant) memory?" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for singly-linked list.\n", - "class ListNode:\n", - " def __init__(self, val=0):\n", - " self.val = val\n", - " self.next = None\n", - "\n", - "class Solution:\n", - " def hasCycle(self, head: ListNode) -> bool:\n", - " if not head:\n", - " return False\n", - " \n", - " slow = head\n", - " fast = head\n", - " \n", - " while fast and fast.next:\n", - " slow = slow.next\n", - " fast = fast.next.next\n", - " \n", - " if slow == fast:\n", - " return True\n", - " \n", - " return False" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The given code defines a class `Solution` with a method `hasCycle` for determining if a linked list has a cycle.\n", - "\n", - "The `ListNode` class represents nodes in the linked list, where each node has a `val` (a value associated with the node) and a `next` attribute (a reference to the next node in the list).\n", - "\n", - "The `hasCycle` method takes the `head` of a linked list as input and returns `True` if there is a cycle in the linked list, and `False` otherwise. It uses two pointers, `slow` and `fast`, to traverse the linked list. If there is a cycle, the `fast` pointer will eventually catch up to the `slow` pointer.\n", - "\n", - "The algorithm works as follows:\n", - "1. It checks if the input `head` is `None` (an empty list). If it is, the method returns `False` because an empty list can't have a cycle.\n", - "2. Two pointers, `slow` and `fast`, initially point to the `head` of the list.\n", - "3. The code enters a `while` loop where `fast` moves two steps at a time, and `slow` moves one step at a time.\n", - "4. If there is a cycle, `fast` will eventually catch up to `slow`, and the method returns `True`.\n", - "5. If the loop completes without finding a cycle, the method returns `False`." - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "01849ced-1bbf-4956-8e54-451b358cb4fe", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Helper function to create a linked list with a cycle\n", - "def create_linked_list_with_cycle(values, pos):\n", - " dummy = ListNode()\n", - " current = dummy\n", - " cycle_node = None\n", - " \n", - " for i, val in enumerate(values):\n", - " current.next = ListNode(val)\n", - " current = current.next\n", - " \n", - " if i == pos:\n", - " cycle_node = current\n", - " \n", - " if cycle_node:\n", - " current.next = cycle_node\n", - " \n", - " return dummy.next" - ] - }, - { - "cell_type": "markdown", - "id": "f7490d01-d64e-4f20-b178-e14490d6dd6f", - "metadata": {}, - "source": [ - "This helper function is designed to create a linked list with a cycle for testing purposes. It takes two arguments:\n", - "\n", - "1. `values`: A list of values representing the nodes in the linked list.\n", - "2. `pos`: An integer representing the index of the node where the cycle begins.\n", - "\n", - "Here's how the function works:\n", - "\n", - "- It starts by creating an empty `ListNode` called `dummy`. This `dummy` node is used to simplify the creation of the linked list.\n", - "- It initializes a `current` pointer to the `dummy` node. This pointer will be used to traverse the linked list.\n", - "- It initializes a `cycle_node` variable to `None`. This variable will hold the reference to the node where the cycle begins, if any.\n", - "- It then iterates through the `values` list, creating a new `ListNode` for each value and appending it to the linked list.\n", - "- Inside the loop, it checks if the current index `i` is equal to the specified `pos`. If they match, it sets `cycle_node` to the current node. This simulates the creation of a cycle in the linked list.\n", - "- After the loop, if `cycle_node` is not `None` (indicating a cycle should be created), it connects the last node in the linked list to `cycle_node`, effectively creating a cycle.\n", - "- Finally, it returns the reference to the first node of the linked list (not the `dummy` node).\n", - "\n", - "This helper function allows you to easily create test cases where you can specify the values for the linked list and the position where the cycle starts. It's particularly useful for testing the code's ability to detect cycles in linked lists." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "### Example 1\n", - "head = [3,2,0,-4]\n", - "pos = 1\n", - "\n", - "head = create_linked_list_with_cycle(head, pos)\n", - "solution = Solution()\n", - "result = solution.hasCycle(head)\n", - "print(result)" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "### Example 2\n", - "head = [1,2]\n", - "pos = 0\n", - "\n", - "head = create_linked_list_with_cycle(head, pos)\n", - "solution = Solution()\n", - "result = solution.hasCycle(head)\n", - "print(result)" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "e140b956-7b3d-40d5-b6b0-9615860af67e", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "### Example 3\n", - "head = [1]\n", - "pos = -1\n", - "\n", - "head = create_linked_list_with_cycle(head, pos)\n", - "solution = Solution()\n", - "result = solution.hasCycle(head)\n", - "print(result)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's discuss the time and space complexity of the code for detecting a cycle in a linked list:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The time complexity of this code is $O(n)$, where \"$n$\" is the number of nodes in the linked list.\n", - "\n", - "The reason for this is that both the `slow` and `fast` pointers traverse the linked list, and they move at different speeds. In the worst case, when there is no cycle, the `fast` pointer will reach the end of the list after going through approximately $n/2$ nodes. In the case of a cycle, it may take some extra iterations for the `fast` pointer to catch up to the `slow` pointer. However, the total number of iterations is still proportional to the number of nodes in the linked list, making it $O(n)$.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity of this code is $O(1)$, which means it uses constant space.\n", - "\n", - "The reason for this is that regardless of the size of the linked list, the code only uses two additional pointers (`slow` and `fast`) to traverse the list. These pointers do not depend on the size of the input linked list, so the space complexity remains constant.\n", - "\n", - "**In summary**, this code efficiently detects cycles in a linked list with a time complexity of $O(n)$ and a space complexity of $O(1)$. It is an example of an algorithm that solves a complex problem with minimal memory usage." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/06. Linked List/143. Reorder List.ipynb b/docs/06. Linked List/143. Reorder List.ipynb deleted file mode 100644 index a83545b..0000000 --- a/docs/06. Linked List/143. Reorder List.ipynb +++ /dev/null @@ -1,285 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 143. Reorder List\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Reorder List problem on LeetCode, click here!](https://leetcode.com/problems/reorder-list/)\n", - "\n", - "---\n", - "\n", - "You are given the head of a singly linked-list. The list can be represented as:\n", - "\n", - "$L_0 → L_1 → … → L_{n - 1} → L_n$\n", - "\n", - "Reorder the list to be on the following form:\n", - "\n", - "$L_0 → L_n → L_1 → L_{n - 1} → L_2 → L_{n - 2} → …$\n", - "\n", - "You may not modify the values in the list's nodes. Only nodes themselves may be changed.\n", - " \n", - "\n", - "**Constraints:**\n", - "\n", - "- The number of nodes in the list is in the range $[1, 5 * 10^4]$.\n", - "- `1 <= Node.val <= 1000`" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class ListNode:\n", - " def __init__(self, val=0, next=None):\n", - " self.val = val\n", - " self.next = next\n", - "\n", - "def reorderList(head):\n", - " if not head or not head.next:\n", - " return head\n", - "\n", - " # Step 1: Find the middle of the linked list\n", - " slow, fast = head, head\n", - " while fast.next and fast.next.next:\n", - " slow = slow.next\n", - " fast = fast.next.next\n", - "\n", - " # Split the list into two halves\n", - " first_half = head\n", - " second_half = slow.next\n", - " slow.next = None\n", - "\n", - " # Step 2: Reverse the second half of the linked list\n", - " prev = None\n", - " current = second_half\n", - " while current:\n", - " next_node = current.next\n", - " current.next = prev\n", - " prev = current\n", - " current = next_node\n", - " second_half = prev\n", - "\n", - " # Step 3: Merge the first and reversed second halves alternately\n", - " p1, p2 = first_half, second_half\n", - " while p2:\n", - " next_p1 = p1.next\n", - " next_p2 = p2.next\n", - " p1.next = p2\n", - " p2.next = next_p1\n", - " p1 = next_p1\n", - " p2 = next_p2\n", - "\n", - " return head" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The `reorderList` function is designed to reorder a singly linked list following the specific pattern described in the problem statement. Here's a detailed explanation of how the function works:\n", - "\n", - "1. **Base Cases Handling**:\n", - " - The function first checks if the input linked list is empty (`not head`) or contains only one element (`not head.next`). If either of these conditions is met, the list cannot be reordered, so the function returns the original list as-is.\n", - "\n", - "2. **Finding the Middle of the Linked List**:\n", - " - To reorder the list, we first need to find the middle point so that we can split the list into two halves. This is done using two pointers, `slow` and `fast`, initialized to the head of the list.\n", - " - `slow` moves one step at a time while `fast` moves two steps at a time. When `fast` reaches the end of the list or the second-to-last node, `slow` will be at the middle node.\n", - "\n", - "3. **Splitting the List**:\n", - " - After finding the middle node, we split the list into two halves:\n", - " - The first half, `first_half`, contains nodes from the beginning up to the middle.\n", - " - The second half, `second_half`, contains nodes from the middle to the end.\n", - " - To split the list, we set the `next` pointer of the node before the middle node to `None`.\n", - "\n", - "4. **Reversing the Second Half**:\n", - " - We reverse the second half of the linked list using the `prev`, `current`, and `next_node` pointers.\n", - " - `prev` is initially `None`, and we iterate through the second half. For each node, we:\n", - " - Set the `next` of the current node to `prev`, effectively reversing the next pointer direction.\n", - " - Update `prev` to the current node.\n", - " - Move to the next node using the `next_node`.\n", - "\n", - "5. **Merging the Two Halves Alternately**:\n", - " - We now have two linked lists: `first_half` and the reversed `second_half`.\n", - " - We merge these two lists alternately by adjusting the `next` pointers of the nodes.\n", - " - `p1` and `p2` are pointers to the current nodes in `first_half` and `second_half`, respectively.\n", - " - We iterate through both lists while reordering nodes:\n", - " - Set the `next` of `p1` to `p2` to link a node from the first half to a node from the reversed second half.\n", - " - Update `p1` and `p2` to their respective next nodes.\n", - " - Repeat this process until we have processed all nodes in both halves.\n", - "\n", - "6. **Returning the Reordered List**:\n", - " - After the merging process is complete, the linked list is reordered as specified.\n", - " - The function returns the `head` of the reordered list.\n", - "\n", - "The overall result is a singly linked list that has been reordered according to the given pattern. The time complexity of this algorithm is O(N), where N is the number of nodes in the linked list, as we traverse the list once to find the middle, once to reverse the second half, and once to merge the two halves." - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "id": "01849ced-1bbf-4956-8e54-451b358cb4fe", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Helper function to print the linked list\n", - "def printLinkedList(head):\n", - " result = []\n", - " while head:\n", - " result.append(head.val)\n", - " head = head.next\n", - " return result" - ] - }, - { - "cell_type": "markdown", - "id": "f7490d01-d64e-4f20-b178-e14490d6dd6f", - "metadata": {}, - "source": [ - "Let's explain the helper functions:\n", - "**printLinkedList Function**:\n", - " - The `printLinkedList` function takes the `head` of a linked list as input and returns a list of values representing the nodes in the linked list.\n", - " - Inside the function, a `result` list is initialized to store the values of the linked list nodes.\n", - " - The function then iterates through the linked list starting from the `head` node and appends the `val` attribute of each node to the `result` list.\n", - " - As it iterates through the list, it moves to the next node using the `next` attribute of each node.\n", - " - Finally, the function returns the `result` list containing the values of the linked list nodes in the order they appear in the linked list.\n", - "\n", - " This function is useful for debugging and displaying the contents of a linked list. It allows you to easily convert a linked list into a regular Python list for visualization and testing purposes." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 4, 2, 3]\n" - ] - } - ], - "source": [ - "# Example 1\n", - "head1 = ListNode(1, ListNode(2, ListNode(3, ListNode(4))))\n", - "reorderList(head1)\n", - "print(printLinkedList(head1))" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 5, 2, 4, 3]\n" - ] - } - ], - "source": [ - "# Example 2\n", - "head2 = ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5)))))\n", - "reorderList(head2)\n", - "print(printLinkedList(head2))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the `reorderList` function:\n", - "\n", - "**Time Complexity**:\n", - "1. **Finding the Middle of the Linked List**: In this step, we use two pointers, one moving one step at a time (`slow`) and the other moving two steps at a time (`fast`). This process takes $O(N/2)$ time, where $N$ is the number of nodes in the linked list.\n", - "\n", - "2. **Splitting the List**: After finding the middle, we split the list into two halves by setting the `next` pointer of the node before the middle node to `None`. This step takes $O(1)$ time.\n", - "\n", - "3. **Reversing the Second Half**: We reverse the second half of the linked list using a while loop that iterates through the second half of the list once. Therefore, this step also takes $O(N/2)$ time.\n", - "\n", - "4. **Merging the Two Halves Alternately**: In this step, we merge the two halves alternately by adjusting the `next` pointers of the nodes. We iterate through both halves once, so this step takes $O(N/2)$ time.\n", - "\n", - "Overall, the time complexity of the `reorderList` function is dominated by the steps involving reversing and merging the two halves, both of which take $O(N/2)$ time. Therefore, the total time complexity is $O(N)$.\n", - "\n", - "**Space Complexity**:\n", - "The space complexity of the `reorderList` function is primarily determined by the variables and data structures used within the function. Let's break down the space complexity components:\n", - "\n", - "1. **Constant Space Variables**: The variables `slow`, `fast`, `prev`, `current`, `next_node`, `p1`, and `p2` are used to traverse and manipulate the linked list. These variables occupy constant space, regardless of the input size. Therefore, they contribute $O(1)$ to the space complexity.\n", - "\n", - "2. **Split Linked Lists**: In the splitting step, we create two new linked list segments (`first_half` and `second_half`) that store references to nodes from the original linked list. These segments occupy space proportional to half of the input list, $O(N/2)$. \n", - "\n", - "3. **Reversed Second Half**: During the reversal step, we reverse the second half of the linked list in-place without creating any additional data structures. Therefore, it doesn't contribute to additional space complexity.\n", - "\n", - "4. **Overall**: Combining the above components, the total space complexity is $O(N/2)$, which simplifies to $O(N)$ in terms of space complexity.\n", - "\n", - "**In summary**, the `reorderList` function has a time complexity of $O(N)$ and a space complexity of $O(N)$ due to the creation of two new linked list segments while splitting the list. The constant space variables used for traversal do not significantly impact the overall space complexity." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Reorder by K Elements:** Generalize the reorderList function to reorder the list in a different pattern, where you reorder the list by $K$ elements at a time. For example, for $K=3$, you would reorder it as ($L_0 → L_1 → L_2 → L_n → L_{n-1} → L_{n-2} → ...$).\n", - "You may need to handle cases where the number of nodes is not a multiple of $K$.\n", - "\n", - "2. **Reorder by Odd and Even Nodes:** Modify the reorderList function to reorder the list in a pattern where odd-indexed nodes (1-based index) come before even-indexed nodes. For example, ($L_0 → L_n → L_1 → L_{n-1} → L_2 → L_{n-2} → ...$)." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/06. Linked List/19. Remove Nth Node From End of List.ipynb b/docs/06. Linked List/19. Remove Nth Node From End of List.ipynb deleted file mode 100644 index 263124e..0000000 --- a/docs/06. Linked List/19. Remove Nth Node From End of List.ipynb +++ /dev/null @@ -1,278 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 19. Remove Nth Node From End of List\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Remove Nth Node From End of List problem on LeetCode, click here!](https://leetcode.com/problems/remove-nth-node-from-end-of-list/)\n", - "\n", - "---\n", - "\n", - "Given the head of a linked list, remove the $n^{th}$ node from the end of the list and return its head.\n", - " \n", - "\n", - "**Constraints:**\n", - "\n", - "- The number of nodes in the list is `sz`.\n", - "- `1 <= sz <= 30`\n", - "- `0 <= Node.val <= 100`\n", - "- `1 <= n <= sz`\n", - "\n", - "**Follow up:** Could you do this in one pass?" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class ListNode:\n", - " def __init__(self, val=0, next=None):\n", - " self.val = val\n", - " self.next = next\n", - "\n", - "def removeNthFromEnd(head, n):\n", - " # Create a dummy node to handle the case of removing the head node.\n", - " dummy = ListNode(0)\n", - " dummy.next = head\n", - " first = dummy\n", - " second = dummy\n", - " \n", - " # Advance the first pointer by n+1 nodes.\n", - " for _ in range(n + 1):\n", - " first = first.next\n", - " \n", - " # Move both pointers simultaneously until first reaches the end.\n", - " while first is not None:\n", - " first = first.next\n", - " second = second.next\n", - " \n", - " # Remove the nth node by updating the next pointer of the previous node.\n", - " second.next = second.next.next\n", - " \n", - " return dummy.next # Return the modified head of the linked list" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start by defining a `ListNode` class to represent individual nodes in a linked list. Each node has two attributes: `val` (the value of the node) and `next` (a reference to the next node in the list).\n", - "\n", - "2. The `removeNthFromEnd` function takes the head of a linked list (`head`) and the value `n`, which represents the position from the end of the list of the node to be removed. It returns the modified head of the linked list after the removal.\n", - "\n", - "3. We create a dummy node (`dummy`) at the beginning of the list. This dummy node simplifies the code by handling cases where the head of the list needs to be removed.\n", - "\n", - "4. We initialize two pointers, `first` and `second`, both initially pointing to the dummy node.\n", - "\n", - "5. To advance the `first` pointer by `n+1` nodes, we use a `for` loop. This positions the `first` pointer `n` nodes ahead of the `second` pointer.\n", - "\n", - "6. We then move both `first` and `second` pointers simultaneously until `first` reaches the end of the list. This ensures that the `second` pointer ends up pointing to the node that needs to be removed.\n", - "\n", - "7. To remove the nth node from the end, we update the `next` pointer of the node pointed to by the `second` pointer to skip over the node to be removed.\n", - "\n", - "8. Finally, we return `dummy.next`, which is the modified head of the linked list without the removed node.\n", - "\n", - "9. Additionally, there are two helper functions:\n", - " - `createLinkedList(values)` creates a linked list from a list of values.\n", - " - `convertToList(head)` converts a linked list back into a list of values." - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "id": "01849ced-1bbf-4956-8e54-451b358cb4fe", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Helper function to create a linked list from a list of values.\n", - "def createLinkedList(values):\n", - " if not values:\n", - " return None\n", - " head = ListNode(values[0])\n", - " current = head\n", - " for val in values[1:]:\n", - " current.next = ListNode(val)\n", - " current = current.next\n", - " return head\n", - "\n", - "# Helper function to convert a linked list to a list of values.\n", - "def convertToList(head):\n", - " result = []\n", - " current = head\n", - " while current:\n", - " result.append(current.val)\n", - " current = current.next\n", - " return result" - ] - }, - { - "cell_type": "markdown", - "id": "f7490d01-d64e-4f20-b178-e14490d6dd6f", - "metadata": {}, - "source": [ - "Let's explain the two helper functions:\n", - "\n", - "1. `createLinkedList(values)`: This function creates a linked list from a list of values.\n", - "\n", - " - Input: `values` is a list containing values that you want to insert into the linked list.\n", - " - Output: The function returns the head of the created linked list.\n", - "\n", - " Explanation:\n", - " - The function starts by checking if the `values` list is empty. If it is, it returns `None` to indicate an empty linked list.\n", - " - If the `values` list is not empty, it creates the first node of the linked list with the value from the first element of `values`.\n", - " - It then iterates through the remaining elements of `values` and creates new nodes for each value, connecting them together using the `next` attribute to form a linked list.\n", - " - Finally, it returns the head of the linked list, which is the first node created.\n", - " \n", - "\n", - "2. `convertToList(head)`: This function converts a linked list into a list of values.\n", - "\n", - " - Input: `head` is the head node of the linked list that you want to convert.\n", - " - Output: The function returns a list containing the values of the nodes in the linked list in order.\n", - "\n", - " Explanation:\n", - " - The function starts by initializing an empty list, `result`, to store the values of the linked list nodes.\n", - " - It then iterates through the linked list starting from the `head` node and appends the `val` attribute of each node to the `result` list.\n", - " - The iteration continues until it reaches the end of the linked list (i.e., the `next` attribute of the current node becomes `None`).\n", - " - After the iteration is complete, the function returns the `result` list, which now contains the values of all the nodes in the linked list in the same order as they appear in the linked list.\n", - "\n", - "These helper functions are useful for creating linked lists from lists of values and converting linked lists back into lists of values, making it easier to work with linked list examples and test cases in a more familiar list format." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 2, 3, 5]\n" - ] - } - ], - "source": [ - "# Example 1\n", - "head1 = createLinkedList([1, 2, 3, 4, 5])\n", - "n1 = 2\n", - "new_head1 = removeNthFromEnd(head1, n1)\n", - "print(convertToList(new_head1))" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[]\n" - ] - } - ], - "source": [ - "# Example 2\n", - "head2 = createLinkedList([1])\n", - "n2 = 1\n", - "new_head2 = removeNthFromEnd(head2, n2)\n", - "print(convertToList(new_head2))" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "id": "e140b956-7b3d-40d5-b6b0-9615860af67e", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1]\n" - ] - } - ], - "source": [ - "# Example 3\n", - "head3 = createLinkedList([1, 2])\n", - "n3 = 1\n", - "new_head3 = removeNthFromEnd(head3, n3)\n", - "print(convertToList(new_head3))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Certainly! Let's analyze the time and space complexity of the `removeNthFromEnd` function in isolation:\n", - "\n", - "**Time Complexity:**\n", - "- The `removeNthFromEnd` function performs two passes through the linked list. In the worst case, it needs to traverse the entire linked list of length $N$.\n", - "- The first pass positions the `first` pointer $n$ nodes ahead of the `second` pointer. This pass takes $O(N)$ time because it involves iterating through all N nodes.\n", - "- The second pass moves both `first` and `second` pointers simultaneously until `first` reaches the end of the list. This also takes $O(N)$ time in the worst case.\n", - "- Therefore, the overall time complexity of the `removeNthFromEnd` function is $O(N)$.\n", - "\n", - "**Space Complexity:**\n", - "- The `removeNthFromEnd` function uses a constant amount of extra space for its variables (e.g., `first`, `second`, and `dummy`). This space usage does not depend on the size of the linked list.\n", - "- The space complexity is $O(1)$, indicating that the space used by the function is constant and independent of the size of the input linked list.\n", - "\n", - "**In summary**, the `removeNthFromEnd` function has a time complexity of $O(N)$ and a space complexity of $O(1)$. It efficiently removes the nth node from the end of the linked list with a single pass through the list and constant extra space usage." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/06. Linked List/206. Reverse Linked List.ipynb b/docs/06. Linked List/206. Reverse Linked List.ipynb deleted file mode 100644 index c97de2d..0000000 --- a/docs/06. Linked List/206. Reverse Linked List.ipynb +++ /dev/null @@ -1,316 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 206. Reverse Linked List\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Reverse Linked List problem on LeetCode, click here!](https://leetcode.com/problems/reverse-linked-list/)\n", - "\n", - "---\n", - "\n", - "Given the `head` of a singly linked list, reverse the list, and return the reversed list.\n", - " \n", - "\n", - "**Constraints:**\n", - "\n", - "- The number of nodes in the list is the range `[0, 5000]`.\n", - "- `-5000 <= Node.val <= 5000`\n", - "\n", - "**Follow up:** A linked list can be reversed either iteratively or recursively. Could you implement both?" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for singly-linked list.\n", - "class ListNode:\n", - " def __init__(self, val=0, next=None):\n", - " self.val = val\n", - " self.next = next\n", - "\n", - "# Function to reverse a linked list iteratively\n", - "def reverseListIterative(head):\n", - " prev = None\n", - " current = head\n", - " \n", - " while current:\n", - " next_node = current.next\n", - " current.next = prev\n", - " prev = current\n", - " current = next_node\n", - " \n", - " return prev\n", - "\n", - "# Function to reverse a linked list recursively\n", - "def reverseListRecursive(head):\n", - " if not head or not head.next:\n", - " return head\n", - "\n", - " new_head = reverseListRecursive(head.next)\n", - " head.next.next = head\n", - " head.next = None\n", - "\n", - " return new_head" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. `reverseListIterative(head)`: This function reverses a linked list iteratively using a loop. Here's a step-by-step explanation:\n", - "\n", - " - It takes the `head` of the input linked list as a parameter.\n", - " - It initializes two pointers, `prev` and `current`, initially set to `None` and the `head` of the list, respectively.\n", - " - It enters a `while` loop that continues until `current` reaches the end of the list (i.e., becomes `None`).\n", - " - Inside the loop:\n", - " - It stores the `next_node` which is the next node after `current`.\n", - " - It updates the `next` pointer of `current` to point to the `prev` node. This effectively reverses the link direction.\n", - " - It moves `prev` to `current` and `current` to `next_node`, advancing the pointers one step further in the list.\n", - " - Once the loop completes, `prev` will be pointing to the new head of the reversed list (which was the last node of the original list), so it returns `prev`.\n", - "\n", - "2. `reverseListRecursive(head)`: This function reverses a linked list recursively. Here's how it works:\n", - "\n", - " - It takes the `head` of the input linked list as a parameter.\n", - " - The base case is checked: if `head` is `None` or `head.next` is `None`, meaning the list is empty or has only one node, it returns `head` as there's no need to reverse a list with zero or one element.\n", - " - In the recursive case:\n", - " - It calls itself with `head.next`, effectively moving down the list until it reaches the end.\n", - " - Once it reaches the end, it starts reversing the links:\n", - " - `head.next.next` is set to `head`, reversing the link between `head` and the next node.\n", - " - `head.next` is set to `None` to avoid cycles.\n", - " - Finally, it returns the new head of the reversed list, which will be the last node of the original list.\n", - "\n", - "**In summary,** `reverseListIterative` reverses the linked list by iterating through it and changing the next pointers, while `reverseListRecursive` reverses the linked list by recursively reaching the end and then reversing the links on the way back up the recursion stack. Both functions achieve the same result: reversing the linked list." - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "id": "01849ced-1bbf-4956-8e54-451b358cb4fe", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Helper function to create a linked list from a list of values\n", - "def createLinkedList(values):\n", - " if not values:\n", - " return None\n", - " head = ListNode(values[0])\n", - " current = head\n", - " for val in values[1:]:\n", - " current.next = ListNode(val)\n", - " current = current.next\n", - " return head\n", - "\n", - "# Helper function to convert a linked list to a list for testing\n", - "def linkedListToList(head):\n", - " result = []\n", - " current = head\n", - " while current:\n", - " result.append(current.val)\n", - " current = current.next\n", - " return result\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "f7490d01-d64e-4f20-b178-e14490d6dd6f", - "metadata": {}, - "source": [ - "Let's explain the two helper functions used in the provided code:\n", - "\n", - "1. `createLinkedList(values)`:\n", - "\n", - " - Purpose: This function is used to create a linked list from a list of values. It takes a list of values as input and returns the head of the linked list.\n", - "\n", - " - How it works:\n", - " - It first checks if the input list `values` is empty. If it's empty, it returns `None` to indicate an empty linked list.\n", - " - If `values` is not empty, it initializes a `head` node with the value of the first element in `values`.\n", - " - It then iterates through the remaining values in `values`, creating new nodes for each value and linking them together to form a linked list.\n", - " - Finally, it returns the `head` node of the newly created linked list.\n", - "\n", - "2. `linkedListToList(head)`:\n", - "\n", - " - Purpose: This function is used to convert a linked list back into a Python list for testing and output purposes.\n", - "\n", - " - How it works:\n", - " - It takes the `head` of the linked list as input.\n", - " - It initializes an empty list called `result`.\n", - " - It then iterates through the linked list, starting from `head`, and appends each node's `val` (value) to the `result` list.\n", - " - This process continues until the end of the linked list is reached.\n", - " - Finally, it returns the `result` list, which contains the values from the linked list in the same order.\n", - "\n", - "These helper functions are used to simplify the process of creating linked lists from lists of values and converting linked lists back into lists, making it easier to work with linked lists in the provided examples and test cases." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "[1, 1, 2, 3, 4, 4]" - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Example 1: Iterative\n", - "head1 = [1,2,3,4,5]\n", - "head1 = createLinkedList(head1)\n", - "reversed_head1 = reverseListIterative(head1)\n", - "print(linkedListToList(reversed_head1))" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 37, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Example 2: Recursive\n", - "head2 = [1,2]\n", - "head2 = createLinkedList(head2)\n", - "reversed_head2 = reverseListRecursive(head2)\n", - "print(linkedListToList(reversed_head2))" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "id": "6c69a707-02af-4212-b2e7-1881d62a62d2", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "[0]" - ] - }, - "execution_count": 38, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Example 3: Empty list\n", - "head3 = []\n", - "head3 = createLinkedList(head3)\n", - "reversed_head3 = reverseListIterative(head3)\n", - "print(linkedListToList(reversed_head3))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the two functions:\n", - "\n", - "1. `reverseListIterative(head)`:\n", - "\n", - " - Time Complexity: $O(n)$\n", - " - The iterative function visits each node in the linked list exactly once in a single pass, where \"$n$\" is the number of nodes in the list. Therefore, the time complexity is linear in the number of nodes.\n", - "\n", - " - Space Complexity: $O(1)$\n", - " - This function uses a constant amount of extra space for the `prev`, `current`, and `next_node` pointers. Regardless of the size of the input list, the amount of additional memory used remains the same, so the space complexity is constant.\n", - "\n", - "2. `reverseListRecursive(head)`:\n", - "\n", - " - Time Complexity: $O(n)$\n", - " - The recursive function also visits each node in the linked list exactly once. It recursively traverses the list from the head to the tail, reversing the links on the way back. Therefore, like the iterative approach, the time complexity is $O(n)$, where \"$n$\" is the number of nodes.\n", - "\n", - " - Space Complexity: $O(n)$\n", - " - The recursive function uses space on the call stack for each recursive call. In the worst case, when the list has \"$n$\" nodes, it will create \"$n$\" recursive function calls on the stack, resulting in a space complexity of $O(n)$. This is because each function call stores information about its state, including the `head` pointer, until it reaches the base case and starts returning.\n", - "\n", - "**In summary:**\n", - "\n", - "- The time complexity of both functions is $O(n)$ because they both visit each node once.\n", - "- The space complexity of `reverseListIterative` is $O(1)$ because it uses a constant amount of extra space.\n", - "- The space complexity of `reverseListRecursive` is $O(n)$ due to the recursive function calls and the associated call stack space.\n", - "\n", - "Both functions are efficient in terms of time complexity, but `reverseListIterative` is more memory-efficient because it uses a constant amount of additional space, while `reverseListRecursive` uses space on the call stack proportional to the number of nodes in the list." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **K-Group Reverse:** Modify the reverseListIterative function to reverse the linked list in groups of $K$ elements. For example, if the input linked list is [1, 2, 3, 4, 5, 6], and $K$ is 3, the output should be [3, 2, 1, 6, 5, 4].\n", - "\n", - "2. **Rotate Linked List:** Write a function to rotate a linked list to the right by $K$ places. For example, if the input is [1, 2, 3, 4, 5] and $K$ is 2, the output should be [4, 5, 1, 2, 3]." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/06. Linked List/21. Merge Two Sorted Lists.ipynb b/docs/06. Linked List/21. Merge Two Sorted Lists.ipynb deleted file mode 100644 index 876d633..0000000 --- a/docs/06. Linked List/21. Merge Two Sorted Lists.ipynb +++ /dev/null @@ -1,249 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 21. Merge Two Sorted Lists\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Merge Two Sorted Lists problem on LeetCode, click here!](https://leetcode.com/problems/merge-two-sorted-lists/)\n", - "\n", - "---\n", - "\n", - "You are given the heads of two sorted linked lists `list1` and `list2`.\n", - "\n", - "Merge the two lists into one **sorted** list. The list should be made by splicing together the nodes of the first two lists.\n", - "\n", - "*Return the head of the merged linked list.*\n", - " \n", - "\n", - "**Constraints:**\n", - "\n", - "- The number of nodes in both lists is in the range `[0, 50]`.\n", - "- `-100 <= Node.val <= 100`\n", - "- Both `list1` and `list2` are sorted in non-decreasing order." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class ListNode:\n", - " def __init__(self, val=0, next=None):\n", - " self.val = val\n", - " self.next = next\n", - "\n", - "def mergeTwoLists(list1, list2):\n", - " # Create a dummy node to simplify the code.\n", - " dummy = ListNode()\n", - " current = dummy\n", - "\n", - " while list1 and list2:\n", - " if list1.val < list2.val:\n", - " current.next = list1\n", - " list1 = list1.next\n", - " else:\n", - " current.next = list2\n", - " list2 = list2.next\n", - " current = current.next\n", - "\n", - " # Append the remaining elements from either list.\n", - " if list1:\n", - " current.next = list1\n", - " else:\n", - " current.next = list2\n", - "\n", - " return dummy.next" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We define a class `ListNode` to represent the nodes of a singly-linked list. Each node has a `val` attribute to store the value of the node and a `next` attribute to point to the next node in the list.\n", - "\n", - "2. We define the `mergeTwoLists` function that takes two linked list heads, `list1` and `list2`, as input.\n", - "\n", - "3. We create a `dummy` node at the beginning of the merged list. The `dummy` node simplifies the code by serving as a placeholder, and its `next` attribute will point to the actual merged list.\n", - "\n", - "4. We initialize a `current` pointer to point to the `dummy` node initially. This `current` pointer helps us traverse and build the merged list.\n", - "\n", - "5. We enter a `while` loop that continues until either `list1` or `list2` becomes empty. Inside the loop, we compare the values of the nodes at the current positions of `list1` and `list2`.\n", - "\n", - "6. If the `val` of the node in `list1` is smaller than the `val` of the node in `list2`, we attach the node from `list1` to the merged list by updating the `next` attribute of the `current` node to point to the node in `list1`. We then move the `list1` pointer to the next node.\n", - "\n", - "7. If the `val` of the node in `list2` is smaller than or equal to the `val` of the node in `list1`, we attach the node from `list2` to the merged list in a similar manner. We move the `list2` pointer to the next node.\n", - "\n", - "8. After attaching a node to the merged list, we move the `current` pointer to the newly added node. This step is essential for keeping track of the end of the merged list.\n", - "\n", - "9. The loop continues until either `list1` or `list2` becomes empty.\n", - "\n", - "10. Once the loop exits, we check if there are any remaining elements in `list1` or `list2`. If `list1` is not empty, we attach the remaining elements of `list1` to the merged list. If `list2` is not empty, we attach the remaining elements of `list2`.\n", - "\n", - "11. Finally, we return the `next` attribute of the `dummy` node as the head of the merged list, which represents the sorted merged list." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "01849ced-1bbf-4956-8e54-451b358cb4fe", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Helper function to print the linked list\n", - "def printLinkedList(head):\n", - " result = []\n", - " while head:\n", - " result.append(head.val)\n", - " head = head.next\n", - " return result" - ] - }, - { - "cell_type": "markdown", - "id": "f7490d01-d64e-4f20-b178-e14490d6dd6f", - "metadata": {}, - "source": [ - "Let's explain the helper functions:\n", - "**printLinkedList Function**:\n", - " - The `printLinkedList` function takes the `head` of a linked list as input and returns a list of values representing the nodes in the linked list.\n", - " - Inside the function, a `result` list is initialized to store the values of the linked list nodes.\n", - " - The function then iterates through the linked list starting from the `head` node and appends the `val` attribute of each node to the `result` list.\n", - " - As it iterates through the list, it moves to the next node using the `next` attribute of each node.\n", - " - Finally, the function returns the `result` list containing the values of the linked list nodes in the order they appear in the linked list.\n", - "\n", - " This function is useful for debugging and displaying the contents of a linked list. It allows you to easily convert a linked list into a regular Python list for visualization and testing purposes." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Example 1:\n", - "# Input: list1 = [1,2,4], list2 = [1,3,4]\n", - "list1 = ListNode(1, ListNode(2, ListNode(4)))\n", - "list2 = ListNode(1, ListNode(3, ListNode(4)))\n", - "merged_list = mergeTwoLists(list1, list2)\n", - "printLinkedList(merged_list)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Example 2:\n", - "# Input: list1 = [], list2 = []\n", - "list1 = None\n", - "list2 = None\n", - "merged_list = mergeTwoLists(list1, list2)\n", - "printLinkedList(merged_list)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6c69a707-02af-4212-b2e7-1881d62a62d2", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Example 3:\n", - "# list1 = [], list2 = [0]\n", - "list1 = None\n", - "list2 = ListNode(0)\n", - "merged_list = mergeTwoLists(list1, list2)\n", - "printLinkedList(merged_list)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the `mergeTwoLists` function.\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The time complexity of this function is $O(N + M$), where $N$ and $M$ are the lengths of `list1` and `list2`, respectively. Here's why:\n", - "\n", - "1. In the worst case, we need to traverse both `list1` and `list2` completely. This involves iterating through all the nodes in both lists once.\n", - "\n", - "2. The while loop runs until either `list1` or `list2` becomes empty. The number of iterations depends on the total number of nodes in both lists, which is N + M in the worst case.\n", - "\n", - "3. Inside the loop, we perform constant-time operations for each iteration, such as comparisons and updating pointers.\n", - "\n", - "Therefore, the dominant factor in the time complexity is the combined length of both input lists, resulting in a linear time complexity of $O(N + M)$.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity of this function is $O(1)$, which means it uses a constant amount of extra space regardless of the input sizes. Here's why:\n", - "\n", - "1. We create a few extra pointers (`dummy`, `current`) and temporary variables (`val`) to manage the merging process. These consume a fixed amount of memory, regardless of the input sizes. The number of these extra variables is independent of the lengths of `list1` and `list2`.\n", - "\n", - "2. We do not create a new data structure or allocate memory for the merged list. Instead, we rearrange the existing nodes from `list1` and `list2` to form the merged list. This operation does not consume additional memory proportional to the input sizes.\n", - "\n", - "**In summary**, the `mergeTwoLists` function has a time complexity of $O(N + M)$ and a space complexity of $O(1)$, making it an efficient solution for merging two sorted linked lists." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Merge K Sorted Lists:** Extend the problem to merge $K$ sorted linked lists instead of just two. You need to efficiently merge $K$ lists into one sorted list.\n", - "\n", - "2. **Merge Lists in a Zigzag Pattern:** Merge two sorted lists in a zigzag pattern. For example, given [1, 2, 4] and [1, 3, 5], the merged list should be [1, 1, 2, 3, 4, 5]." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": "sql", - "file_extension": "", - "mimetype": "", - "name": "sql", - "version": "3.32.3" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/06. Linked List/23. Merge k Sorted Lists.ipynb b/docs/06. Linked List/23. Merge k Sorted Lists.ipynb deleted file mode 100644 index a850734..0000000 --- a/docs/06. Linked List/23. Merge k Sorted Lists.ipynb +++ /dev/null @@ -1,285 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 23. Merge k Sorted Lists\n", - "\n", - "**Difficulty:** Hard\n", - "\n", - "**Link to Problem:** [To see the Merge k Sorted Lists problem on LeetCode, click here!](https://leetcode.com/problems/merge-k-sorted-lists/)\n", - "\n", - "---\n", - "\n", - "You are given an array of $k$ linked-lists lists, each linked-list is sorted in ascending order.\n", - "\n", - "Merge all the linked-lists into one sorted linked-list and return it.\n", - "\n", - "**Constraints:**\n", - "\n", - "- `k == lists.length`\n", - "- 0 <= k <= $10^4$\n", - "- `0 <= lists[i].length <= 500`\n", - "- $-10^4$ <= lists[i][j] <= $10^4$\n", - "- `lists[i]` is sorted in ascending order.\n", - "- The sum of `lists[i].length` will not exceed $10^4$.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for singly-linked list.\n", - "class ListNode:\n", - " def __init__(self, val=0, next=None):\n", - " self.val = val\n", - " self.next = next\n", - "\n", - "class Solution:\n", - " def mergeKLists(self, lists: [[ListNode]]) -> ListNode:\n", - " # Check if the input list of linked lists is empty\n", - " if not lists or len(lists) == 0:\n", - " return None\n", - "\n", - " # Loop until there is only one merged list left\n", - " while len(lists) > 1:\n", - " mergedLists = []\n", - "\n", - " # Merge pairs of lists\n", - " for i in range(0, len(lists), 2):\n", - " l1 = lists[i]\n", - " l2 = lists[i + 1] if (i + 1) < len(lists) else None\n", - " mergedLists.append(self.mergeList(l1, l2))\n", - "\n", - " # Update the list of lists with merged results\n", - " lists = mergedLists\n", - " \n", - " # Return the final merged list\n", - " return lists[0]\n", - "\n", - " def mergeList(self, l1, l2):\n", - " # Create a dummy node to simplify merging\n", - " dummy = ListNode()\n", - " tail = dummy\n", - "\n", - " # Merge the two sorted lists\n", - " while l1 and l2:\n", - " if l1.val < l2.val:\n", - " tail.next = l1\n", - " l1 = l1.next\n", - " else:\n", - " tail.next = l2\n", - " l2 = l2.next\n", - " tail = tail.next\n", - "\n", - " # Append any remaining elements from l1 or l2 (if any)\n", - " if l1:\n", - " tail.next = l1\n", - " if l2:\n", - " tail.next = l2\n", - "\n", - " # Return the merged result starting from the next of the dummy node\n", - " return dummy.next\n" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The provided code defines a Python class `Solution` with two methods for merging k sorted linked lists:\n", - "\n", - "1. `mergeKLists(self, lists: List[ListNode]) -> ListNode`: This method takes a list of k sorted linked lists as input and returns a single merged sorted linked list. It uses a divide-and-conquer approach to repeatedly merge pairs of lists until only one merged list remains.\n", - "\n", - "2. `mergeList(self, l1, l2)`: This method takes two sorted linked lists, `l1` and `l2`, as input and merges them into a single sorted linked list. It uses a dummy node to simplify the merging process.\n", - "\n", - "Here's a high-level overview of how the code works:\n", - "\n", - "- The `mergeKLists` method checks if the input list of linked lists is empty or contains no lists. If there are no lists, it returns `None`.\n", - "\n", - "- Inside a `while` loop, the code repeatedly merges pairs of linked lists until only one merged list remains in the `lists` array. It does this by iterating through the input lists in pairs and calling the `mergeList` method to merge each pair.\n", - "\n", - "- The `mergeList` method takes two sorted linked lists, `l1` and `l2`, and merges them into a single sorted linked list. It uses a dummy node (`dummy`) and a `tail` pointer to keep track of the merged list while comparing and merging elements from `l1` and `l2`.\n", - "\n", - "- After merging all pairs of lists and updating the `lists` array with the merged results, the loop continues until only one merged list remains in the `lists` array.\n", - "\n", - "- Finally, the `mergeKLists` method returns the merged list.\n", - "\n", - "Overall, this code efficiently merges k sorted linked lists using a divide-and-conquer strategy, resulting in a single merged sorted linked list as the output." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1 -> 1 -> 2 -> 3 -> 4 -> 4 -> 5 -> 6 -> " - ] - } - ], - "source": [ - "### Example 1\n", - "# Input: lists = [[1,4,5],[1,3,4],[2,6]]\n", - "\n", - "lists1 = [\n", - " ListNode(1, ListNode(4, ListNode(5))),\n", - " ListNode(1, ListNode(3, ListNode(4))),\n", - " ListNode(2, ListNode(6))\n", - "]\n", - "solution = Solution()\n", - "result1 = solution.mergeKLists(lists1)\n", - "\n", - "# Print the result\n", - "if result1:\n", - " current = result1\n", - " while current:\n", - " print(current.val, end=\" -> \")\n", - " current = current.next\n", - "else:\n", - " print(\"None\") # Print \"None\" for input with a single None element" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "None\n" - ] - } - ], - "source": [ - "### Example 2\n", - "# Input: lists = []\n", - "\n", - "lists2 = []\n", - "solution = Solution()\n", - "result2 = solution.mergeKLists(lists2)\n", - "\n", - "# Print the result\n", - "if result2:\n", - " current = result2\n", - " while current:\n", - " print(current.val, end=\" -> \")\n", - " current = current.next\n", - "else:\n", - " print(\"None\") # Print \"None\" for input with a single None element" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "e140b956-7b3d-40d5-b6b0-9615860af67e", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "None\n" - ] - } - ], - "source": [ - "### Example 3\n", - "# Input: lists = [[]]\n", - "\n", - "lists3 = [None]\n", - "solution = Solution()\n", - "result3 = solution.mergeKLists(lists3)\n", - "\n", - "# Print the result\n", - "if result3:\n", - " current = result3\n", - " while current:\n", - " print(current.val, end=\" -> \")\n", - " current = current.next\n", - "else:\n", - " print(\"None\") # Print \"None\" for input with a single None element" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. **Heap Initialization:** The code does not use a heap. Instead, it uses a divide-and-conquer approach. The initial check for empty input lists takes $O(1)$ time.\n", - "\n", - "2. **Merging:** The merging operation is performed in a divide-and-conquer fashion. In each iteration of the `while` loop, we merge pairs of linked lists, and the number of comparisons made is proportional to the total number of nodes across all the linked lists ($n$). In each merge step, we effectively process each node once. The number of iterations required to reduce k lists to 1 is $O(log\\ k)$.\n", - "\n", - " Therefore, the overall time complexity of the code is $O(n * log\\ k)$, where n is the total number of nodes across all lists, and $k$ is the number of linked lists.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. **Heap Space:** The code doesn't use a heap data structure, so there's no additional space complexity due to a heap.\n", - "\n", - "2. **Merged Lists:** In the `mergeList` method, we create a new merged list. However, this list is not stored in memory for all lists; it's replaced with each merged pair. The space used for these merged lists is proportional to the size of the largest merged list, which is $O(n)$ in the worst case.\n", - "\n", - "3. **Additional Variables:** The code uses a few additional variables, such as `dummy` and `tail`, but these occupy a constant amount of space and don't depend on the input size.\n", - "\n", - " Therefore, the overall space complexity of the code is $O(n)$, where n is the total number of nodes across all lists.\n", - "\n", - "In summary, the code's time complexity is $O(n * log(k))$, and its space complexity is $O(n)$. This code efficiently merges $k$ sorted linked lists using a divide-and-conquer approach with a relatively low space overhead." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/06. Linked List/README.md b/docs/06. Linked List/README.md deleted file mode 100644 index fb7b3ee..0000000 --- a/docs/06. Linked List/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Linked List Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [206. Reverse Linked List](https://leetcode.com/problems/reverse-linked-list/) | Easy | -| [21. Merge Two Sorted Lists](https://leetcode.com/problems/merge-two-sorted-lists/) | Easy | -| [143. Reorder List](https://leetcode.com/problems/reorder-list/) | Medium | -| [19. Remove Nth Node From End of List](https://leetcode.com/problems/remove-nth-node-from-end-of-list/) | Medium | -| [141. Linked List Cycle](https://leetcode.com/problems/linked-list-cycle/) | Medium | -| [23. Merge K Sorted Lists](https://leetcode.com/problems/merge-k-sorted-lists/) | Hard | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! diff --git a/docs/07. Trees/100. Same Tree.ipynb b/docs/07. Trees/100. Same Tree.ipynb deleted file mode 100644 index a270fab..0000000 --- a/docs/07. Trees/100. Same Tree.ipynb +++ /dev/null @@ -1,211 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 100: Same Tree\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Same Tree problem on LeetCode, click here!](https://leetcode.com/problems/same-tree/)\n", - "\n", - "---\n", - "\n", - "Given the roots of two binary trees `p` and `q`, write a function to check if they are the same or not.\n", - "\n", - "Two binary trees are considered the same if they are structurally identical, and the nodes have the same value.\n", - "\n", - "**Constraints**\n", - "\n", - "1. The number of nodes in both trees is in the range `[0, 100]`.\n", - "2. $-10^4$ <= Node.val <= $10^4$\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for a binary tree node.\n", - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " # Initialize a TreeNode with a value (val), left child, and right child.\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def isSameTree(p, q):\n", - " # Base case: If both p and q are None, the trees are the same.\n", - " if not p and not q:\n", - " return True\n", - " \n", - " # Base case: If either p or q is None (but not both), the trees are different.\n", - " if not p or not q:\n", - " return False\n", - " \n", - " # Check if the values of the current nodes (p.val and q.val) are equal.\n", - " if p.val != q.val:\n", - " return False\n", - " \n", - " # Recursively check the left and right subtrees of p and q.\n", - " # If both subtrees are the same, the entire trees are the same.\n", - " return isSameTree(p.left, q.left) and isSameTree(p.right, q.right)" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "In this code, we define a `TreeNode` class to represent binary tree nodes and a `isSameTree` function to check if two binary trees are the same. The function uses recursive traversal to compare the trees' structures and values.\n", - "\n", - "1. We start by defining a `TreeNode` class, which represents a node in a binary tree. Each node has a `val` (the node's value), a `left` child, and a right child. This class will help us create and work with binary trees.\n", - "2. Next, we define the `isSameTree` function, which checks if two binary trees (`p` and `q`) are the same.\n", - " + The base case for the recursion is when both `p` and `q` are `None`. In this case, they are considered the same, so we return `True`.\n", - " + If either `p` or `q` is `None` (but not both), they cannot be the same, so we return `False`.\n", - " + If the values of the current nodes `p.val` and `q.val` are not equal, we return `False` because the trees cannot be the same.\n", - " + Finally, we recursively check the left and right subtrees of `p` and `q` to see if they are the same." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "### Example 1\n", - "\n", - "#Input: `p = [1,2,3]`, `q = [1,2,3]`\n", - "\n", - "p1 = TreeNode(1, TreeNode(2), TreeNode(3))\n", - "q1 = TreeNode(1, TreeNode(2), TreeNode(3))\n", - "print(isSameTree(p1, q1)) " - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "### Example 2\n", - "\n", - "#Input: `p = [1,2]`, `q = [1,null,2]`\n", - "\n", - "p2 = TreeNode(1, TreeNode(2), None)\n", - "q2 = TreeNode(1, None, TreeNode(2))\n", - "print(isSameTree(p2, q2))" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "5897c29d-26f8-486a-878c-43c09ff25ce4", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "### Example 3\n", - "\n", - "#Input: p = [1,2,1], q = [1,1,2]\n", - "\n", - "p3 = TreeNode(1, TreeNode(2), TreeNode(1))\n", - "q3 = TreeNode(1, TreeNode(1), TreeNode(2))\n", - "print(isSameTree(p3, q3))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time Complexity\n", - "\n", - "The time complexity of the `isSameTree` function can be analyzed as follows:\n", - "\n", - "In the worst case, the function needs to visit every node in both trees once to determine if they are the same.\n", - "Since each node is visited exactly once, the time complexity is $O(n)$, where $n$ is the total number of nodes in the input trees.\n", - "\n", - "## Space Complexity\n", - "The space complexity of the `isSameTree` function can be analyzed as follows:\n", - "\n", - "The space used by the function's call stack during recursion is proportional to the maximum depth of the binary trees.\n", - "In the worst case, when the trees are completely unbalanced (all nodes form a single branch), the maximum depth will be $n$, where $n$ is the total number of nodes in the input trees.\n", - "Therefore, the space complexity is $O(n)$ due to the recursive call stack.\n", - "In addition to the call stack, there is a small constant amount of space used for variables and comparisons within each recursive call, but this space is not significant in terms of the overall space complexity.\n", - "\n", - "## In summary:\n", - "\n", - "+ **Time Complexity:** $O(n)$ where $n$ is the total number of nodes in the input trees.\n", - "+ **Space Complexity:** $O(n)$ due to the recursive call stack." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/07. Trees/102. Binary Tree Level Order Traversal.ipynb b/docs/07. Trees/102. Binary Tree Level Order Traversal.ipynb deleted file mode 100644 index 8cb08b7..0000000 --- a/docs/07. Trees/102. Binary Tree Level Order Traversal.ipynb +++ /dev/null @@ -1,271 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 102. Binary Tree Level Order Traversal\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Binary Tree Level Order Traversal problem on LeetCode, click here!](https://leetcode.com/problems/binary-tree-level-order-traversal/)\n", - "\n", - "---\n", - "Given the `root` of a binary tree, return *the level order traversal of its nodes' values*. (i.e., from left to right, level by level).\n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the tree is in the range `[0, 2000]`.\n", - "- `-1000 <= Node.val <= 1000`\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def levelOrder(root):\n", - " # Check if the tree is empty, if so, return an empty list.\n", - " if not root:\n", - " return []\n", - "\n", - " # Initialize an empty list to store the result.\n", - " result = []\n", - " \n", - " # Initialize a queue with the root node to perform BFS.\n", - " queue = [root]\n", - "\n", - " while queue:\n", - " # Initialize an empty list to store the values of nodes at the current level.\n", - " level_values = []\n", - " \n", - " # Get the number of nodes at the current level.\n", - " level_size = len(queue)\n", - "\n", - " # Iterate through the nodes at the current level.\n", - " for _ in range(level_size):\n", - " # Dequeue the front node from the queue.\n", - " node = queue.pop(0)\n", - " \n", - " # Append the value of the current node to the level_values list.\n", - " level_values.append(node.val)\n", - "\n", - " # Enqueue the left and right children of the current node if they exist.\n", - " if node.left:\n", - " queue.append(node.left)\n", - " if node.right:\n", - " queue.append(node.right)\n", - "\n", - " # Append the level_values list (values at the current level) to the result list.\n", - " result.append(level_values)\n", - "\n", - " # Return the final result, which is a list of lists representing level order traversal.\n", - " return result" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We define a `TreeNode` class that represents a node in the binary tree. Each `TreeNode` object has a value (`val`) and two child nodes: `left` and `right`.\n", - "\n", - "2. The `levelOrder` function takes the root of the binary tree as its input and returns the level order traversal of the tree as a list of lists.\n", - "\n", - "3. We start by checking if the input `root` is `None`, which indicates an empty tree. If the tree is empty, we return an empty list because there are no nodes to traverse.\n", - "\n", - "4. We initialize an empty list called `result` to store the final result, which will be a list of lists containing node values at each level.\n", - "\n", - "5. We initialize a queue called `queue` with the root node. This queue will be used for breadth-first traversal of the tree.\n", - "\n", - "6. We enter a while loop that continues until the `queue` is empty. Inside the loop, we perform the following steps:\n", - "\n", - " - We initialize an empty list called `level_values` to store the values of nodes at the current level.\n", - "\n", - " - We determine the number of nodes at the current level by getting the length of the `queue`. This is done to process nodes level by level.\n", - "\n", - " - We iterate through the nodes at the current level using a for loop. For each node in the current level:\n", - "\n", - " - We dequeue (remove) the front node from the `queue`.\n", - "\n", - " - We append the value of the dequeued node to the `level_values` list, effectively collecting the values of nodes at the current level.\n", - "\n", - " - If the dequeued node has a left child, we enqueue the left child to the `queue`.\n", - "\n", - " - If the dequeued node has a right child, we enqueue the right child to the `queue`.\n", - "\n", - " - After processing all nodes at the current level, we append the `level_values` list to the `result` list. This represents the values at the current level.\n", - "\n", - "7. The loop continues until all levels have been traversed, and the `queue` becomes empty.\n", - "\n", - "8. Finally, we return the `result` list, which contains lists of node values at each level, representing the level order traversal of the binary tree.\n", - "\n", - "The code effectively performs a breadth-first traversal of the binary tree, processing nodes level by level, and constructs the result list that represents the level order traversal." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[3], [9, 20], [15, 7]]\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Construct the tree\n", - "root = TreeNode(3)\n", - "root.left = TreeNode(9)\n", - "root.right = TreeNode(20)\n", - "root.right.left = TreeNode(15)\n", - "root.right.right = TreeNode(7)\n", - "\n", - "result = levelOrder(root)\n", - "print(result)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[1]]\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "# Using the same tree as before\n", - "root = TreeNode(1)\n", - "result = levelOrder(root)\n", - "print(result)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "7fc71180-e586-4c37-9fcf-2f574cb2b9d6", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[]\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "# Creating a new tree for this example\n", - "root = None\n", - "result = levelOrder(root)\n", - "print(result)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `levelOrder` function:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The time complexity of this function is O(N), where N is the number of nodes in the binary tree. This is because we visit each node exactly once during the breadth-first traversal.\n", - "\n", - "In the worst case, we have to enqueue and dequeue all nodes in the binary tree, which is proportional to the number of nodes (N). In each level, we process all nodes in that level, and since there are a total of log(N) levels in a balanced binary tree, the time complexity can also be approximated as O(N) for unbalanced trees.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity of this function is O(N), where N is the number of nodes in the binary tree. Here's how the space complexity breaks down:\n", - "\n", - "1. The `result` list stores the level order traversal, and in the worst case, it contains N/2 levels (for a completely unbalanced binary tree). So, the space used by `result` is O(N).\n", - "\n", - "2. The `queue` data structure is used for BFS traversal. In the worst case, it can store all nodes at the last level of the tree. In a balanced binary tree, the maximum number of nodes at any level is 2^(log(N)), which is still O(N). In the case of an unbalanced tree, it can be even worse. So, the space used by `queue` is O(N).\n", - "\n", - "Overall, the dominant factor in terms of space complexity is the `queue`, and the space complexity is O(N).\n", - "\n", - "In summary, the function's time complexity is O(N), and its space complexity is also O(N). It is an efficient and optimal solution for performing a level order traversal of a binary tree." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Reverse Level Order Traversal:** Modify the `levelOrder` function to return the level order traversal in reverse order (from bottom to top). For example, if the input tree is `[3, 9, 20, null, null, 15, 7]`, the output should be `[[15, 7], [9, 20], [3]]`.\n", - "\n", - "2. **Zigzag Level Order Traversal:** Write a function that performs a level order traversal of a binary tree in a zigzag pattern. In a zigzag traversal, the nodes at even levels are traversed from left to right, and nodes at odd levels are traversed from right to left. For example, if the input tree is `[3, 9, 20, null, null, 15, 7]`, the output should be `[[3], [20, 9], [15, 7]]`." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/07. Trees/104. Maximum Depth of Binary Tree.ipynb b/docs/07. Trees/104. Maximum Depth of Binary Tree.ipynb deleted file mode 100644 index 213989d..0000000 --- a/docs/07. Trees/104. Maximum Depth of Binary Tree.ipynb +++ /dev/null @@ -1,209 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 104. Maximum Depth of Binary Tree\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Invert Binary Tree problem on LeetCode, click here!](https://leetcode.com/problems/invert-binary-tree/)\n", - "\n", - "---\n", - "\n", - "Given the `root` of a binary tree, return its maximum depth.\n", - "\n", - "A binary tree's **maximum depth** is the number of nodes along the longest path from the root node down to the farthest leaf node.\n", - "\n", - "**Constraints:**\n", - "\n", - "- The number of nodes in the tree is in the range $[0, 10^4]$.\n", - "- `-100 <= Node.val <= 100`\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for a binary tree node.\n", - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def maxDepth(root):\n", - " # Base case: If the root is None, the depth is 0.\n", - " if root is None:\n", - " return 0\n", - " \n", - " # Recursively calculate the maximum depth of the left and right subtrees.\n", - " left_depth = maxDepth(root.left)\n", - " right_depth = maxDepth(root.right)\n", - " \n", - " # Return the maximum depth of the tree by adding 1 to the maximum depth of the subtrees.\n", - " return max(left_depth, right_depth) + 1" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "Let's go through the code step by step to understand how it works:\n", - "\n", - "1. We start by defining a `TreeNode` class to represent the nodes of the binary tree. Each node has three attributes:\n", - " - `val`: the value stored in the node.\n", - " - `left`: a reference to the left child node.\n", - " - `right`: a reference to the right child node.\n", - "\n", - "2. The `maxDepth` function is the main function that calculates the maximum depth of the binary tree. It takes a single argument, `root`, which is the root node of the binary tree.\n", - "\n", - "3. In the `maxDepth` function, we have a base case:\n", - " - If the `root` is `None`, it means we have reached the end of a branch of the tree (a leaf node or an empty subtree). In this case, the depth is 0 because there are no nodes to count.\n", - "\n", - "4. If the `root` is not `None`, we recursively calculate the maximum depth of the left and right subtrees:\n", - " - We call `maxDepth` on the `root.left` to calculate the maximum depth of the left subtree and store it in the variable `left_depth`.\n", - " - We call `maxDepth` on the `root.right` to calculate the maximum depth of the right subtree and store it in the variable `right_depth`.\n", - "\n", - "5. Finally, we return the maximum depth of the tree by taking the maximum of `left_depth` and `right_depth` and adding 1 to it. This is because we are counting the current level as well." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3\n" - ] - } - ], - "source": [ - "### Example 1\n", - "# Input: root = [3,9,20,null,null,15,7]\n", - "\n", - "root = TreeNode(3)\n", - "root.left = TreeNode(9)\n", - "root.right = TreeNode(20)\n", - "root.right.left = TreeNode(15)\n", - "root.right.right = TreeNode(7)\n", - "\n", - "print(maxDepth(root))" - ] - }, - { - "cell_type": "markdown", - "id": "a230be4f-1f47-4919-87e3-62fc3f072d97", - "metadata": {}, - "source": [ - "In this example, we create a binary tree based on the given input `[3,9,20,null,null,15,7]` and calculate its maximum depth, which is `3`. The tree structure is as follows:\n", - " ```\n", - " 3\n", - " / \\\n", - " 9 20\n", - " / \\\n", - " 15 7\n", - " ```\n", - "\n", - "So, the maximum depth is the length of the longest path from the root to a leaf node, which is 3 in this case." - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2\n" - ] - } - ], - "source": [ - "### Example 2\n", - "# Input: root = [1,null,2]\n", - "\n", - "root = TreeNode(1)\n", - "root.right = TreeNode(2)\n", - "\n", - "# Calculate the maximum depth of the tree and print the result\n", - "print(maxDepth(root))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "- The time complexity of the `maxDepth` function is $O(N)$, where $N$ is the number of nodes in the binary tree.\n", - "- This is because in the worst case, the function visits every node exactly once in a depth-first manner.\n", - "- The recursion explores all nodes of the tree, so the time complexity is linear with respect to the number of nodes.\n", - "\n", - "**Space Complexity:**\n", - "- The space complexity of the `maxDepth` function is $O(H)$, where H is the height of the binary tree.\n", - "- In the worst case, if the binary tree is completely unbalanced (skewed), the recursion stack can go as deep as the height of the tree.\n", - "- In the best case, if the binary tree is perfectly balanced, the height is $O(log\\ N)$, where $N$ is the number of nodes.\n", - "- Therefore, the space complexity can vary from $O(log\\ N)$ to $O(N)$ depending on the shape of the tree.\n", - "- In addition to the recursion stack, there is a small constant amount of space used for variables and function call overhead.\n", - "\n", - "**In summary:**\n", - "- The time complexity of the code is $O(N)$ as it visits each node once.\n", - "- The space complexity is $O(H)$, where H is the height of the tree, which can vary from $O(log\\ N)$ to $O(N)$ depending on the tree's shape." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.ipynb b/docs/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.ipynb deleted file mode 100644 index 31c9e69..0000000 --- a/docs/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.ipynb +++ /dev/null @@ -1,313 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 105. Construct Binary Tree from Preorder and Inorder Traversal\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Construct Binary Tree from Preorder and Inorder Traversal problem on LeetCode, click here!](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/)\n", - "\n", - "---\n", - "Given two integer arrays `preorder` and `inorder` where `preorder` is the preorder traversal of a binary tree and `inorder` is the inorder traversal of the same tree, construct and return *the binary tree.*\n", - "\n", - "**Constraints:**\n", - "- `1 <= preorder.length <= 3000`\n", - "- `inorder.length == preorder.length`\n", - "- `-3000 <= preorder[i], inorder[i] <= 3000`\n", - "- `preorder` and `inorder` consist of **unique** values.\n", - "- Each value of `inorder` also appears in `preorder`.\n", - "- `preorder` is **guaranteed** to be the preorder traversal of the tree.\n", - "- `inorder` is **guaranteed** to be the inorder traversal of the tree.\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def buildTree(preorder, inorder):\n", - " if not preorder:\n", - " return None\n", - "\n", - " # The first element in the preorder traversal is the root of the current subtree\n", - " root_val = preorder[0]\n", - " root = TreeNode(root_val)\n", - "\n", - " # Find the index of the root value in the inorder traversal\n", - " root_idx_inorder = inorder.index(root_val)\n", - "\n", - " # Recursively build left and right subtrees\n", - " root.left = buildTree(preorder[1:1 + root_idx_inorder], inorder[:root_idx_inorder])\n", - " root.right = buildTree(preorder[1 + root_idx_inorder:], inorder[root_idx_inorder + 1:])\n", - "\n", - " return root" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. `class TreeNode:`: This is a class definition for a binary tree node. It has three attributes:\n", - " - `val`: The value of the node.\n", - " - `left`: A reference to the left child node.\n", - " - `right`: A reference to the right child node.\n", - "\n", - " This class is used to create instances of binary tree nodes, which will be used to build the binary tree.\n", - "\n", - "2. `def buildTree(preorder, inorder):`: This is the main function that constructs a binary tree from its preorder and inorder traversals.\n", - "\n", - " - `preorder`: A list representing the preorder traversal of the binary tree.\n", - " - `inorder`: A list representing the inorder traversal of the binary tree.\n", - "\n", - "3. `if not preorder: return None`: This line checks if the `preorder` list is empty. If it is, it means there are no nodes to construct, so the function returns `None`.\n", - "\n", - "4. `root_val = preorder[0]`: The value of the root node is extracted from the first element of the `preorder` list.\n", - "\n", - "5. `root = TreeNode(root_val)`: A new `TreeNode` object is created with the `root_val` as its value. This represents the root of the current subtree.\n", - "\n", - "6. `root_idx_inorder = inorder.index(root_val)`: The index of the `root_val` in the `inorder` list is found. This index indicates the position of the root node in the inorder traversal.\n", - "\n", - "7. `root.left`: The left subtree is constructed recursively by calling the `buildTree` function with the appropriate sublists of `preorder` and `inorder`. The left subtree's preorder and inorder traversals are the slices of `preorder` and `inorder` lists up to the `root_idx_inorder`.\n", - "\n", - "8. `root.right`: The right subtree is constructed recursively by calling the `buildTree` function with the appropriate sublists of `preorder` and `inorder`. The right subtree's preorder and inorder traversals are the slices of `preorder` and `inorder` lists starting from `root_idx_inorder + 1`.\n", - "\n", - "9. Finally, the function returns the `root` of the subtree it just constructed.\n", - "\n", - "The recursive approach used here divides the problem of constructing the entire binary tree into smaller subproblems, starting with the root node and then recursively building the left and right subtrees until the entire tree is constructed." - ] - }, - { - "cell_type": "markdown", - "id": "2d82857b-4fbe-474f-bf33-17b55c20147b", - "metadata": {}, - "source": [ - "## Helper Function \n", - "\n", - "Here is a helper function to represent the binary tree elements." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "13e6f3e1-659d-479d-9521-75629b8c782f", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def treeToList(root):\n", - " # Initialize an empty list to store the elements of the binary tree\n", - " result = []\n", - " \n", - " # Initialize a queue for level-order traversal starting with the root\n", - " queue = [root]\n", - "\n", - " while queue:\n", - " # Pop the front node from the queue\n", - " node = queue.pop(0)\n", - " \n", - " # If the node is not None (i.e., a valid node), add its value to the result list\n", - " if node:\n", - " result.append(node.val)\n", - " \n", - " # Add the left and right children of the node to the queue\n", - " queue.append(node.left)\n", - " queue.append(node.right)\n", - " else:\n", - " # If the node is None, add None to the result to represent an empty node\n", - " result.append(None)\n", - "\n", - " # Remove any trailing None values from the result list\n", - " while result and result[-1] is None:\n", - " result.pop()\n", - "\n", - " # Return the resulting list representing the binary tree elements\n", - " return result" - ] - }, - { - "cell_type": "markdown", - "id": "86cd4c9d-a120-4dd1-a1bd-530436012574", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "Let's break down the `treeToList` helper function step by step:\n", - "\n", - "1. `def treeToList(root):`: This function takes the root of a binary tree as input and converts it into a list.\n", - "\n", - "2. `result = []`: Initialize an empty list called `result` to store the elements of the binary tree in list format.\n", - "\n", - "3. `queue = [root]`: Initialize a queue data structure for a level-order traversal, starting with the root node.\n", - "\n", - "4. `while queue:`: This starts a loop that continues until the queue is empty, indicating that all nodes have been processed.\n", - "\n", - "5. `node = queue.pop(0)`: Dequeue the first node from the queue, effectively processing it.\n", - "\n", - "6. `if node:`: Check if the `node` is not None, which means it's a valid node in the binary tree.\n", - "\n", - " a. `result.append(node.val)`: If the node is valid, append its value (`node.val`) to the `result` list. This represents the value of the current node in the binary tree.\n", - "\n", - " b. `queue.append(node.left)`: Enqueue the left child of the current node if it exists. This adds the left child to the queue for processing in the next iteration.\n", - "\n", - " c. `queue.append(node.right)`: Enqueue the right child of the current node if it exists. This adds the right child to the queue for processing in the next iteration.\n", - "\n", - "7. `else:`: If the `node` is None, it represents an empty node in the binary tree.\n", - "\n", - " a. `result.append(None)`: Append `None` to the `result` list to indicate an empty node.\n", - "\n", - "8. `while result and result[-1] is None:`: After the traversal is complete, there might be trailing `None` values in the `result` list. This loop removes any such trailing `None` values to ensure a clean representation of the tree's elements.\n", - "\n", - "9. `return result`: Return the `result` list, which now contains the elements of the binary tree in a format where `None` represents empty nodes and the order of elements reflects a level-order traversal of the tree.\n", - "\n", - "In summary, the `treeToList` function performs a level-order traversal of the binary tree using a queue, constructing a list where each element corresponds to a node's value or represents an empty node with `None`. This list represents the binary tree's elements in a structured format." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[3, 9, 20, None, None, 15, 7]\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "preorder = [3, 9, 20, 15, 7]\n", - "inorder = [9, 3, 15, 20, 7]\n", - "result = buildTree(preorder, inorder)\n", - "\n", - "print(treeToList(result))" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[-1]\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "preorder = [-1]\n", - "inorder = [-1]\n", - "result = buildTree(preorder, inorder)\n", - "\n", - "print(treeToList(result))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `buildTree` function:\n", - "\n", - "**Time Complexity:**\n", - "The time complexity of the `buildTree` function can be analyzed in terms of the number of nodes in the binary tree. Let's assume there are `n` nodes in the binary tree.\n", - "\n", - "1. Finding the root value in the `preorder` traversal takes O(1) time as it's just extracting the first element from the list.\n", - "2. Finding the index of the root value in the `inorder` traversal using `inorder.index(root_val)` takes O(n) time in the worst case because in the worst case, it might have to search through all `n` elements in the `inorder` list to find the index.\n", - "3. The recursive calls to `buildTree` for the left and right subtrees are made once for each node in the tree. Therefore, the recursive calls have a combined time complexity of O(n) as they process each node once.\n", - "\n", - "The total time complexity of the `buildTree` function is O(n) due to the recursive calls and finding the root's index in the `inorder` list.\n", - "\n", - "**Space Complexity:**\n", - "The space complexity is determined by the space used by the function's call stack during recursion and any additional data structures used. \n", - "\n", - "1. The space used by the function call stack during recursion depends on the height of the binary tree. In the worst case, where the tree is highly unbalanced (e.g., a skewed tree), the space complexity for the call stack is O(n) as it can go as deep as the number of nodes in the tree.\n", - "\n", - "2. Additionally, the function creates TreeNode objects for each node in the binary tree. Therefore, the space complexity for these objects is also O(n).\n", - "\n", - "Overall, the space complexity of the `buildTree` function is O(n) due to the space used by the call stack and the TreeNode objects.\n", - "\n", - "In summary, the time complexity of `buildTree` is O(n), and the space complexity is O(n), where 'n' is the number of nodes in the binary tree." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Construct Binary Tree from Postorder and Inorder Traversal:**\n", - " Modify the problem to construct a binary tree from its postorder and inorder traversals. Implement a function similar to `buildTree` but for postorder and inorder traversals.\n", - "\n", - "2. **Reconstruct Binary Tree with Duplicate Values:**\n", - " Extend the problem to handle binary trees with duplicate values. Ensure that your solution correctly handles scenarios where there are duplicate values in the preorder and inorder traversals." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/07. Trees/124. Binary Tree Maximum Path Sum.ipynb b/docs/07. Trees/124. Binary Tree Maximum Path Sum.ipynb deleted file mode 100644 index 59d8e7d..0000000 --- a/docs/07. Trees/124. Binary Tree Maximum Path Sum.ipynb +++ /dev/null @@ -1,249 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 124. Binary Tree Maximum Path Sum\n", - "\n", - "**Difficulty:** Hard\n", - "\n", - "**Link to Problem:** [To see the Binary Tree Maximum Path Sum problem on LeetCode, click here!](https://leetcode.com/problems/binary-tree-maximum-path-sum/)\n", - "\n", - "---\n", - "A **path** in a binary tree is a sequence of nodes where each pair of adjacent nodes in the sequence has an edge connecting them. A node can only appear in the sequence **at most once**. Note that the path does not need to pass through the root.\n", - "\n", - "The **path sum** of a path is the sum of the node's values in the path.\n", - "\n", - "Given the `root` of a binary tree, return *the maximum **path sum** of any **non-empty** path*.\n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the tree is in the range $[1, 3*10^4]$.\n", - "- `-1000 <= Node.val <= 1000`" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is to find the maximum path sum in a binary tree. A path in a binary tree is a sequence of nodes where each pair of adjacent nodes in the sequence has an edge connecting them. The path sum of a path is the sum of the node values in that path.\n", - "\n", - "In this problem, you are given the root of a binary tree, and you need to find the maximum path sum among all possible paths in the tree. Note that the path does not need to start at the root node or end at a leaf node; it can start and end at any nodes in the tree.\n", - "\n", - "To find the maximum path sum, you need to consider both left and right subtrees of each node while traversing the tree. At each node, you have two choices:\n", - "\n", - "1. Include the current node in the path: In this case, you add the value of the current node to the sum and continue exploring both the left and right subtrees for possible extensions of the path.\n", - "\n", - "2. Start a new path from the current node: In this case, you do not include the current node in the path sum, and you choose either the left subtree or the right subtree to start a new path.\n", - "\n", - "To solve this problem, you can use a recursive approach to traverse the binary tree. For each node, you calculate the maximum path sum that can pass through that node (option 1) and also return the maximum path sum that can be extended from that node (option 2). You keep track of the global maximum path sum encountered during the traversal.\n", - "\n", - "Ultimately, the maximum path sum among all paths in the tree will be the maximum of the global maximum path sum and the maximum path sum calculated for each node.\n", - "\n", - "The constraints for this problem include:\n", - "\n", - "- The number of nodes in the tree is in the range $[1, 3 * 10^4]$.\n", - "- Node values are in the range [-1000, 1000].\n", - "\n", - "By considering all possible paths through the tree, the algorithm aims to find the most significant sum of node values in any path in the binary tree.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "class Solution:\n", - " def maxPathSum(self, root):\n", - " def max_path_sum_helper(node):\n", - " if not node:\n", - " return 0\n", - " \n", - " # Recursively calculate the maximum path sum for left and right subtrees\n", - " left_max = max(0, max_path_sum_helper(node.left))\n", - " right_max = max(0, max_path_sum_helper(node.right))\n", - " \n", - " # Update the global maximum path sum\n", - " self.max_sum = max(self.max_sum, left_max + right_max + node.val)\n", - " \n", - " # Return the maximum path sum starting from the current node\n", - " return max(left_max, right_max) + node.val\n", - " \n", - " self.max_sum = float('-inf') # Initialize the global maximum to negative infinity\n", - " max_path_sum_helper(root) # Start the recursive traversal from the root\n", - " return self.max_sum" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. The code starts by defining a `TreeNode` class to represent nodes in the binary tree. Each `TreeNode` has a `val` attribute representing its value, a `left` attribute pointing to the left child, and a `right` attribute pointing to the right child.\n", - "\n", - "2. Next, a `Solution` class is defined to contain the `maxPathSum` method, which will be used to find the maximum path sum in the binary tree.\n", - "\n", - "3. Within the `maxPathSum` method, a helper function called `max_path_sum_helper` is defined. This recursive function takes a single argument, `node`, which is the current node being considered during traversal.\n", - "\n", - "4. Inside the `max_path_sum_helper` function:\n", - " - If `node` is `None` (i.e., the current node is a null node), it returns 0. This is the base case of the recursion.\n", - " - It calculates the maximum path sum starting from the left subtree (`left_max`) and the right subtree (`right_max`). Importantly, it uses `max(0, ...)` to ensure that negative values (which would make the path sum smaller) are not considered. If a subtree's path sum is negative, it's better to not include it in the path.\n", - " - The code then updates the global maximum path sum (`self.max_sum`) by checking if the sum of `left_max`, `right_max`, and the current node's value is greater than the current maximum.\n", - " - Finally, it returns the maximum path sum starting from the current node, which is the maximum of `left_max` and `right_max` plus the current node's value.\n", - "\n", - "5. Before calling the `max_path_sum_helper` function, the `max_sum` attribute of the `Solution` class is initialized to negative infinity (`float('-inf')`). This is done to ensure that any valid path sum encountered during traversal will be greater than the initial value of `max_sum`.\n", - "\n", - "6. The `max_path_sum_helper` function is called with the root of the binary tree, effectively starting the traversal from the root node.\n", - "\n", - "7. Once the traversal is complete, the method returns the value of `self.max_sum`, which contains the maximum path sum found in the binary tree.\n", - "\n", - "8. Example usage at the bottom of the code demonstrates how to create binary trees and use the `maxPathSum` method to find the maximum path sum for two different tree structures.\n", - "\n", - "In summary, the code uses a recursive approach to explore all possible paths in the binary tree, ensuring that negative path sums are not considered. It keeps track of the maximum path sum encountered and returns that maximum value as the result." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "6\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "root1 = TreeNode(1)\n", - "root1.left = TreeNode(2)\n", - "root1.right = TreeNode(3)\n", - "solution = Solution()\n", - "print(solution.maxPathSum(root1))" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "42\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "root2 = TreeNode(-10)\n", - "root2.left = TreeNode(9)\n", - "root2.right = TreeNode(20)\n", - "root2.right.left = TreeNode(15)\n", - "root2.right.right = TreeNode(7)\n", - "print(solution.maxPathSum(root2))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the given code:\n", - "\n", - "Time Complexity:\n", - "- The code uses a recursive depth-first traversal to explore each node in the binary tree exactly once.\n", - "- During the traversal, for each node, we perform constant time operations, such as updating the `max_sum` variable and calculating the maximum path sum starting from that node.\n", - "- Therefore, the time complexity of the code is O(N), where N is the number of nodes in the binary tree.\n", - "\n", - "Space Complexity:\n", - "- The space complexity of the code is determined by the space used in the call stack during the recursive traversal.\n", - "- In the worst case, the depth of the call stack can be equal to the height of the binary tree. In an unbalanced tree, this could be O(N), but in a balanced binary tree, the height is O(log N).\n", - "- Additionally, the code uses a constant amount of space for variables like `left_max`, `right_max`, and `max_sum`.\n", - "- Therefore, the overall space complexity is O(H), where H is the height of the binary tree. In the worst case, it's O(N), and in the best case (a balanced binary tree), it's O(log N).\n", - "\n", - "In summary:\n", - "- Time Complexity: O(N)\n", - "- Space Complexity: O(H), where H is the height of the binary tree, ranging from O(log N) to O(N) depending on the tree's balance." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Print the Maximum Path:**\n", - " Modify the code to not only find the maximum path sum but also print the nodes involved in the maximum path. You can print the nodes in the correct order from the root to the leaf.\n", - "\n", - "2. **Path Sum Count:**\n", - " Instead of finding the maximum path sum, find the count of unique paths that sum to a given target value. Each path can start and end anywhere in the tree." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/07. Trees/199. Binary Tree Right Side View.ipynb b/docs/07. Trees/199. Binary Tree Right Side View.ipynb deleted file mode 100644 index 55dc944..0000000 --- a/docs/07. Trees/199. Binary Tree Right Side View.ipynb +++ /dev/null @@ -1,257 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 199. Binary Tree Right Side View\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Binary Tree Right Side View problem on LeetCode, click here!](https://leetcode.com/problems/binary-tree-right-side-view/)\n", - "\n", - "---\n", - "Given the `root` of a binary tree, imagine yourself standing on the **right side** of it, return *the values of the nodes you can see ordered from top to bottom*.\n", - "\n", - " \n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the tree is in the range `[0, 2000]`.\n", - "- `-100 <= Node.val <= 100`\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def rightSideView(root):\n", - " if not root:\n", - " return [] # If the tree is empty, return an empty list.\n", - "\n", - " result = [] # Initialize a list to store the right side view values.\n", - " queue = [root] # Initialize a queue for level-order traversal with the root node.\n", - "\n", - " while queue:\n", - " # Get the number of nodes at the current level.\n", - " level_size = len(queue)\n", - "\n", - " # Traverse all nodes at the current level and add the rightmost node to the result.\n", - " for i in range(level_size):\n", - " node = queue.pop(0) # Dequeue the first node from the queue.\n", - "\n", - " # If it's the rightmost node at this level, add its value to the result.\n", - " if i == level_size - 1:\n", - " result.append(node.val)\n", - "\n", - " # Add the children of the current node to the queue.\n", - " if node.left:\n", - " queue.append(node.left)\n", - " if node.right:\n", - " queue.append(node.right)\n", - "\n", - " return result # Return the list of right side view values.\n" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start with a binary tree represented using a TreeNode class. Each node has a value (`val`) and can have a left child (`left`) and a right child (`right`).\n", - "\n", - "2. The `rightSideView` function takes the root node of the binary tree as input and returns a list of values representing the nodes you can see when standing on the right side of the tree.\n", - "\n", - "3. We check if the `root` is `None`, which means the tree is empty. If it's empty, we return an empty list because there are no nodes to see.\n", - "\n", - "4. We initialize an empty list called `result` to store the right side view values.\n", - "\n", - "5. We initialize a queue called `queue` with the root node. This queue is used for a level-order traversal of the tree.\n", - "\n", - "6. We enter a while loop that continues until the `queue` is empty. Inside this loop, we perform the following steps for each level of the tree:\n", - "\n", - " a. We determine the number of nodes at the current level by getting the length of the `queue`. This is important for processing nodes at the same level together.\n", - "\n", - " b. We then iterate through the nodes at the current level using a for loop. For each node in the level, we dequeue it from the `queue` using `queue.pop(0)`.\n", - "\n", - " c. If the node we dequeue is the rightmost node at the current level (determined by `i == level_size - 1`), we add its `val` to the `result` list. This is because, when standing on the right side of the tree, you can see the rightmost node at each level.\n", - "\n", - " d. We enqueue the left and right children of the current node (if they exist) to the `queue`. This ensures that we process the next level in the subsequent iterations of the while loop.\n", - "\n", - "7. After processing all levels of the tree, the `result` list contains the values of the rightmost nodes in each level, ordered from top to bottom.\n", - "\n", - "8. Finally, we return the `result` list as the output of the function, which represents the right side view of the binary tree.\n", - "\n", - "The code effectively performs a level-order traversal of the binary tree while keeping track of the rightmost nodes at each level and adding them to the result list. This ensures that we obtain the correct order of nodes visible from the right side of the tree." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 3, 4]\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Construct the tree\n", - "root1 = TreeNode(1)\n", - "root1.left = TreeNode(2)\n", - "root1.right = TreeNode(3)\n", - "root1.left.right = TreeNode(5)\n", - "root1.right.right = TreeNode(4)\n", - "print(rightSideView(root1))" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 3]\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "root2 = TreeNode(1)\n", - "root2.right = TreeNode(3)\n", - "print(rightSideView(root2))" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "7fc71180-e586-4c37-9fcf-2f574cb2b9d6", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[]\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "# Creating a new tree for this example\n", - "root = None\n", - "result = rightSideView(root)\n", - "print(result)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the given code:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The time complexity of the code is O(N), where N is the number of nodes in the binary tree. Here's why:\n", - "\n", - "1. We perform a level-order traversal of the tree using a queue. In the worst case, we visit all nodes once, which takes O(N) time since we visit each node exactly once.\n", - "\n", - "2. For each node, we perform constant-time operations like dequeuing it from the queue, checking if it's the rightmost node at the current level, and enqueuing its children (if they exist). These operations do not depend on the size of the tree, so they do not contribute to the overall time complexity.\n", - "\n", - "Therefore, the dominant factor in the time complexity is the level-order traversal, making it O(N).\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity of the code is also O(N). Here's why:\n", - "\n", - "1. We use a queue to perform level-order traversal. In the worst case, the queue can contain all nodes at the maximum width of the tree, which can be up to N/2 nodes for a completely unbalanced tree. Therefore, the space required for the queue is O(N).\n", - "\n", - "2. The `result` list stores the values of the rightmost nodes. In the worst case, when the binary tree is a complete binary tree, it can have roughly N/2 rightmost nodes. Therefore, the space required for the `result` list is also O(N).\n", - "\n", - "3. Other auxiliary variables like `level_size`, `i`, and `node` require only constant space and do not depend on the size of the tree.\n", - "\n", - "Combining the space used by the queue and the `result` list, we get a space complexity of O(N).\n", - "\n", - "In summary, the code has a time complexity of O(N) and a space complexity of O(N), where N is the number of nodes in the binary tree. These complexities are efficient and scale linearly with the size of the input tree." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Variant with Left Side View**: Modify the code to find and return the values of nodes visible from the left side of the binary tree instead of the right side.\n", - "\n", - "2. **Zigzag Right Side View**: Extend the code to return the right side view values in a zigzag order. In a zigzag order, you alternate between starting from the rightmost node at level 0, then the leftmost at level 1, rightmost at level 2, and so on." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/07. Trees/226. Invert Binary Tree.ipynb b/docs/07. Trees/226. Invert Binary Tree.ipynb deleted file mode 100644 index 8ea4609..0000000 --- a/docs/07. Trees/226. Invert Binary Tree.ipynb +++ /dev/null @@ -1,223 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 226: Invert Binary Tree\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Invert Binary Tree problem on LeetCode, click here!](https://leetcode.com/problems/invert-binary-tree/)\n", - "\n", - "---\n", - "\n", - "Given the root of a binary tree, invert the tree, and return its root.\n", - "\n", - "**Constraints:**\n", - "\n", - "- The number of nodes in the tree is in the range `[0, 100]`.\n", - "- `-100 <= Node.val <= 100`\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for a binary tree node.\n", - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def invertTree(root):\n", - " # Base case: If the root is None or the tree is empty, return None.\n", - " if not root:\n", - " return None\n", - "\n", - " # Swap the left and right subtrees of the current node.\n", - " root.left, root.right = root.right, root.left\n", - "\n", - " # Recursively invert the left and right subtrees.\n", - " invertTree(root.left)\n", - " invertTree(root.right)\n", - "\n", - " return root" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start by defining a TreeNode class, which represents a node in a binary tree. Each node has a value (`val`), a left child (`left`), and a right child (`right`).\n", - "\n", - "2. The `invertTree` function is defined to invert the binary tree. It takes the root node of the tree as an argument.\n", - "\n", - "3. In the `invertTree` function, we have a base case to handle the scenario when the root is `None` (empty tree). In such cases, we return `None` because there's nothing to invert.\n", - "\n", - "4. For non-empty trees, we swap the left and right subtrees of the current node. This effectively inverts the tree at the current node.\n", - "\n", - "5. We then recursively call `invertTree` on the left and right subtrees to invert them.\n", - "\n", - "6. Finally, we return the root of the inverted tree." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Inverted Tree (Example 1): <__main__.TreeNode object at 0x270c9c0>\n" - ] - } - ], - "source": [ - "### Example 1\n", - "# Input: root = [4,2,7,1,3,6,9]\n", - "\n", - "root1 = TreeNode(4)\n", - "root1.left = TreeNode(2)\n", - "root1.right = TreeNode(7)\n", - "root1.left.left = TreeNode(1)\n", - "root1.left.right = TreeNode(3)\n", - "root1.right.left = TreeNode(6)\n", - "root1.right.right = TreeNode(9)\n", - "\n", - "inverted_root1 = invertTree(root1)\n", - "print(\"Inverted Tree (Example 1):\", inverted_root1)" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Inorder Traversal of Inverted Tree (Example 2): <__main__.TreeNode object at 0x2255fc0>\n" - ] - } - ], - "source": [ - "### Example 2\n", - "# Input: root = [2,1,3]\n", - "\n", - "root2 = TreeNode(2)\n", - "root2.left = TreeNode(1)\n", - "root2.right = TreeNode(3)\n", - "\n", - "inverted_root2 = invertTree(root2)\n", - "print(\"Inverted Tree (Example 2):\", inverted_root2)" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "5897c29d-26f8-486a-878c-43c09ff25ce4", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Inverted Tree (Example 3): None\n" - ] - } - ], - "source": [ - "### Example 3\n", - "# Input: root = []\n", - "\n", - "root3 = None # Empty tree\n", - "\n", - "inverted_root3 = invertTree(root3)\n", - "print(\"Inverted Tree (Example 3):\", inverted_root3)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's discuss the time and space complexity of the provided Python code to invert a binary tree.\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The time complexity of the `invertTree` function is $O(n)$, where $n$ is the number of nodes in the binary tree. This is because we visit each node exactly once during the traversal of the tree. In the worst case, we have to visit all nodes in the tree.\n", - "\n", - "The reason for this time complexity is the depth-first traversal of the tree, where we recursively process the left and right subtrees of each node.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity of the code is determined by the function call stack during the recursion. In the worst case, the space complexity is $O(h)$, where $h$ is the height of the binary tree. \n", - "\n", - "In a completely unbalanced binary tree (essentially a linked list), the height $h$ is equal to the number of nodes $n$, resulting in a space complexity of $O(n)$. This occurs when the tree is skewed to one side.\n", - "\n", - "In a balanced binary tree, such as a full binary tree, the height $h$ is $O(log\\ n)$, and the space complexity is $O(log\\ n)$.\n", - "\n", - "The space complexity depends on how balanced the tree is. In practical scenarios, binary trees are often approximately balanced, so the space complexity is typically closer to $O(log\\ n)$.\n", - "\n", - "**In summary:**\n", - "\n", - "- Time Complexity: $O(n)$ where $n$ is the number of nodes.\n", - "- Space Complexity: $O(h)$, where $h$ is the height of the binary tree. In the worst case, it can be $O(n)$, and in a balanced tree, it is $O(log\\ n)$.\n", - "\n", - "Keep in mind that these complexities are based on the recursive implementation provided. Iterative solutions can achieve the same task with $O(1)$ space complexity, using auxiliary data structures like stacks or queues to mimic the recursion stack." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/07. Trees/230. Kth Smallest Element in a BST.ipynb b/docs/07. Trees/230. Kth Smallest Element in a BST.ipynb deleted file mode 100644 index 673ced2..0000000 --- a/docs/07. Trees/230. Kth Smallest Element in a BST.ipynb +++ /dev/null @@ -1,221 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 230. Kth Smallest Element in a BST\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Kth Smallest Element in a BST problem on LeetCode, click here!](https://leetcode.com/problems/kth-smallest-element-in-a-bst/)\n", - "\n", - "---\n", - "Given the `root` of a binary search tree, and an integer `k`, return *the $k^{th}$ smallest value (**1-indexed**) of all the values of the nodes in the tree.*\n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the tree is `n`.\n", - "- 1 <= `k <= n` <= $10^4$\n", - "- 0 <= `Node.val` <= $10^4$\n", - "\n", - "**Follow up**: If the BST is modified often (i.e., we can do insert and delete operations) and you need to find the kth smallest frequently, how would you optimize?\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def kthSmallest(root, k):\n", - " stack = [] # Initialize an empty stack to simulate the traversal\n", - " while root or stack:\n", - " while root:\n", - " stack.append(root) # Push the current node onto the stack\n", - " root = root.left # Move to the left child\n", - " root = stack.pop() # Pop a node from the stack\n", - " k -= 1 # Decrement k since we've visited a node\n", - " if k == 0:\n", - " return root.val # If k becomes 0, return the current node's value as the kth smallest\n", - " root = root.right # Move to the right child to continue the traversal" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start by defining a `TreeNode` class, which represents a node in the binary search tree (BST). Each node has a value (`val`), a left child (`left`), and a right child (`right`).\n", - "\n", - "2. The `kthSmallest` function takes two parameters: `root`, which is the root of the BST, and `k`, which represents the kth smallest element we want to find.\n", - "\n", - "3. We initialize an empty stack (`stack`) to simulate the traversal of the BST. The stack will be used to keep track of nodes as we traverse the tree in an iterative manner.\n", - "\n", - "4. We enter a while loop that continues until either `root` becomes `None` (indicating we have traversed the entire tree) or the `stack` is empty.\n", - "\n", - "5. Within the loop, we start another while loop to traverse as far left as possible in the BST. We repeatedly push nodes onto the `stack` and move to their left children until we reach the leftmost leaf node. This is the smallest node in the BST.\n", - "\n", - "6. Once we have reached the leftmost leaf node (the smallest node), we pop nodes from the `stack` one by one. As we pop each node, we decrement `k` by 1 to keep track of the number of nodes we have visited.\n", - "\n", - "7. If `k` becomes 0 after decrementing, it means we have found the kth smallest element. In this case, we return the `val` of the current node as the result.\n", - "\n", - "8. If `k` is still greater than 0, it means we haven't found the kth smallest element yet. In this case, we move to the right child of the current node to continue the traversal, as the kth smallest element, if it exists, will be in the right subtree of the current node.\n", - "\n", - "9. The process continues until we find the kth smallest element or traverse the entire tree.\n", - "\n", - "10. Finally, we return the kth smallest element found.\n", - "\n", - "The key idea in this code is to perform an in-order traversal of the BST while keeping track of the kth smallest element. By visiting nodes in ascending order, we can efficiently find the kth smallest element in O(h + k) time, where h is the height of the BST and k is the desired kth element. This approach is both concise and efficient for this problem." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "# Create the tree for the first example: root = [3,1,4,null,2], k = 1\n", - "root1 = TreeNode(3)\n", - "root1.left = TreeNode(1)\n", - "root1.right = TreeNode(4)\n", - "root1.left.right = TreeNode(2)\n", - "k1 = 1\n", - "print(kthSmallest(root1, k1)) " - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "# Create the tree for the second example: root = [5,3,6,2,4,null,null,1], k = 3\n", - "root2 = TreeNode(5)\n", - "root2.left = TreeNode(3)\n", - "root2.right = TreeNode(6)\n", - "root2.left.left = TreeNode(2)\n", - "root2.left.right = TreeNode(4)\n", - "root2.left.left.left = TreeNode(1)\n", - "k2 = 3\n", - "print(kthSmallest(root2, k2))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the given code:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The time complexity of this code is O(h + k), where:\n", - "- h is the height of the binary search tree (BST).\n", - "- k is the desired kth smallest element we want to find.\n", - "\n", - "1. In the worst case, where the BST is highly unbalanced and resembles a linked list, the height (h) of the tree can be equal to the number of nodes (n) in the tree. In this case, the time complexity is O(n + k).\n", - "\n", - "2. In the best case, where the BST is perfectly balanced, the height (h) is log(n), where n is the number of nodes in the tree. In this case, the time complexity is O(log(n) + k).\n", - "\n", - "So, the time complexity can vary from O(log(n) + k) in the best-case scenario to O(n + k) in the worst-case scenario. Typically, for balanced BSTs, the time complexity is closer to O(log(n) + k).\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity of this code is O(h) due to the stack used for the iterative in-order traversal, where h is the height of the BST.\n", - "\n", - "1. In the worst case, when the BST is highly unbalanced and resembles a linked list, the height (h) of the tree can be equal to the number of nodes (n) in the tree. In this case, the space complexity is O(n) because the stack can potentially store all n nodes.\n", - "\n", - "2. In the best case, when the BST is perfectly balanced, the height (h) is log(n), where n is the number of nodes in the tree. In this case, the space complexity is O(log(n)) because the stack will have at most log(n) nodes.\n", - "\n", - "So, the space complexity depends on the height of the BST and can vary from O(log(n)) in the best-case scenario to O(n) in the worst-case scenario.\n", - "\n", - "In practical terms, for balanced BSTs or moderately unbalanced BSTs, the space complexity is usually close to O(log(n)), and the code is efficient in terms of space usage." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Kth Largest Element**: Modify the code to find the kth largest element in the BST instead of the kth smallest element.\n", - "\n", - "2. **Kth Smallest Element in Two BSTs**: Given two BSTs, find the kth smallest element when considering both BSTs as a single sorted list. This involves merging the two BSTs while finding the kth element efficiently." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.ipynb b/docs/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.ipynb deleted file mode 100644 index 666bcd9..0000000 --- a/docs/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.ipynb +++ /dev/null @@ -1,245 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 235. Lowest Common Ancestor of a Binary Search Tree\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Lowest Common Ancestor of a Binary Search Tree problem on LeetCode, click here!](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/)\n", - "\n", - "---\n", - "Given a binary search tree (BST), find the lowest common ancestor (LCA) node of two given nodes in the BST.\n", - "\n", - "According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes `p` and `q` as the lowest node in `T` that has both `p` and `q` as descendants (where we allow **a node to be a descendant of itself**).”\n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the tree is in the range $[2, 10^5]$.\n", - "- $-10^9$ <= `Node.val` <= $10^9$\n", - "- All `Node.val` are **unique**.\n", - "- `p != q`\n", - "- `p` and `q` will exist in the BST.\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def lowestCommonAncestor(root, p, q):\n", - " # Ensure p is less than q\n", - " if p.val > q.val:\n", - " p, q = q, p\n", - "\n", - " while root:\n", - " # If the current node value is greater than both p and q, move left\n", - " if root.val > q.val:\n", - " root = root.left\n", - " # If the current node value is less than both p and q, move right\n", - " elif root.val < p.val:\n", - " root = root.right\n", - " # If the current node value is between p and q (inclusive), or it matches either p or q, it's the LCA\n", - " else:\n", - " return root" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. `class TreeNode:` defines a simple class for representing nodes in a binary tree. Each `TreeNode` has three attributes:\n", - " - `val`: The value of the node.\n", - " - `left`: A reference to the left child node.\n", - " - `right`: A reference to the right child node.\n", - "\n", - "2. `def lowestCommonAncestor(root, p, q):` is a function that takes three arguments:\n", - " - `root`: The root node of the BST.\n", - " - `p`: A TreeNode representing one of the nodes for which we want to find the LCA.\n", - " - `q`: A TreeNode representing the other node for which we want to find the LCA.\n", - "\n", - "3. `if p.val > q.val:` checks if the value of `p` is greater than the value of `q`. In a BST, it's essential to ensure that `p` represents the smaller value, and `q` represents the larger value. If `p` is greater than `q`, the code swaps their values.\n", - "\n", - "4. The main logic is inside the `while` loop, which runs until `root` becomes `None`. It performs the following steps to find the LCA:\n", - " - If the current `root` node's value is greater than the value of `q`, it means both `p` and `q` are on the left subtree of the current node. So, we move to the left child of the current node by setting `root = root.left`.\n", - " - If the current `root` node's value is less than the value of `p`, it means both `p` and `q` are on the right subtree of the current node. So, we move to the right child of the current node by setting `root = root.right`.\n", - " - If neither of the above conditions is met, it means the current `root` node's value is between `p` and `q`, or it matches either `p` or `q`. In this case, the current node is the lowest common ancestor (LCA), so we return `root`.\n", - "\n", - "The algorithm is efficient because it takes advantage of the properties of a BST. It eliminates subtrees that cannot contain the LCA by comparing the values of `p`, `q`, and the current `root` node. Eventually, it reaches the LCA node, and that node is returned as the result." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "6\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Construct the tree\n", - "root = TreeNode(6)\n", - "root.left = TreeNode(2)\n", - "root.right = TreeNode(8)\n", - "root.left.left = TreeNode(0)\n", - "root.left.right = TreeNode(4)\n", - "root.right.left = TreeNode(7)\n", - "root.right.right = TreeNode(9)\n", - "root.left.right.left = TreeNode(3)\n", - "root.left.right.right = TreeNode(5)\n", - "\n", - "p = root.left # Node 2\n", - "q = root.right # Node 8\n", - "\n", - "result = lowestCommonAncestor(root, p, q)\n", - "print(result.val)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "# Using the same tree as before\n", - "p = root.left # Node 2\n", - "q = root.left.right # Node 4\n", - "\n", - "result = lowestCommonAncestor(root, p, q)\n", - "print(result.val) " - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "7fc71180-e586-4c37-9fcf-2f574cb2b9d6", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "# Creating a new tree for this example\n", - "root2 = TreeNode(2)\n", - "root2.left = TreeNode(1)\n", - "\n", - "p = root2 # Node 2\n", - "q = root2.left # Node 1\n", - "\n", - "result = lowestCommonAncestor(root2, p, q)\n", - "print(result.val)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided algorithm for finding the lowest common ancestor (LCA) in a Binary Search Tree (BST).\n", - "\n", - "**Time Complexity:**\n", - "The time complexity of this algorithm is O(h), where \"h\" is the height of the BST. In the worst case, where the tree is completely unbalanced (essentially a linked list), the height of the tree is O(n), where \"n\" is the number of nodes in the tree. However, in a well-balanced BST, the height is logarithmic, which is O(log n).\n", - "\n", - "The reason for this time complexity is that the algorithm efficiently narrows down the search space by traversing either left or right subtrees based on the values of the target nodes `p` and `q`. It eliminates entire subtrees that cannot contain the LCA, leading to a relatively quick search.\n", - "\n", - "**Space Complexity:**\n", - "The space complexity of the algorithm is O(1). This is because it uses a constant amount of extra space, regardless of the size of the input BST. The only variables used are `root`, `p`, and `q`, and there are no data structures like stacks or queues used for additional space. The algorithm performs a simple traversal without recursion, so it does not consume extra memory as the tree depth increases.\n", - "\n", - "**In summary**, the provided algorithm for finding the LCA in a BST is both time and space-efficient. Its time complexity is O(h), where \"h\" is the height of the tree, and its space complexity is O(1), making it suitable for practical use even in large BSTs." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "### Challenging Exercises:\n", - "\n", - "1. **Multiple LCAs:** Extend the algorithm to find all the lowest common ancestors of two given nodes `p` and `q` in a BST. In some cases, there can be multiple LCAs.\n", - "\n", - "2. **LCA with k Nodes:** Given a BST and k nodes, find the lowest common ancestor of these k nodes. This is an extension of the problem where you must find the LCA of more than two nodes." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/07. Trees/297. Serialize and Deserialize Binary Tree.ipynb b/docs/07. Trees/297. Serialize and Deserialize Binary Tree.ipynb deleted file mode 100644 index 75c48ea..0000000 --- a/docs/07. Trees/297. Serialize and Deserialize Binary Tree.ipynb +++ /dev/null @@ -1,297 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 297. Serialize and Deserialize Binary Tree\n", - "\n", - "**Difficulty:** Hard\n", - "\n", - "**Link to Problem:** [To see the Serialize and Deserialize Binary Tree problem on LeetCode, click here!](https://leetcode.com/problems/serialize-and-deserialize-binary-tree/)\n", - "\n", - "---\n", - "Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.\n", - "\n", - "Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure.\n", - "\n", - "**Clarification:** The input/output format is the same as how LeetCode serializes a binary tree. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself.\n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the tree is in the range $[0, 10^4]$.\n", - "- `-1000 <= Node.val <= 1000`" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "TThe problem is to design an algorithm to serialize and deserialize a binary tree. Serialization is the process of converting a data structure or object into a sequence of characters or bytes so that it can be easily stored in a file, transmitted over a network, or otherwise persisted. Deserialization is the reverse process of converting the serialized data back into the original data structure.\n", - "\n", - "In the context of this problem:\n", - "\n", - "1. **Serialization**: You are given a binary tree, and your task is to convert it into a string representation such that you can later recreate the same binary tree from this string. The format of serialization is flexible, but it should allow you to reconstruct the original binary tree accurately.\n", - "\n", - "2. **Deserialization**: Given a serialized string, you need to reconstruct the binary tree it represents, ensuring that it is identical to the original tree.\n", - "\n", - "Here are some key points to consider in solving this problem:\n", - "\n", - "- The input can include any valid binary tree, including trees with nodes having integer values within the range [-1000, 1000].\n", - "- You don't necessarily need to follow a specific format for serialization, but it should be designed in a way that allows unambiguous deserialization.\n", - "- The goal is to serialize the tree structure and its values and then deserialize it back into the same structure and values.\n", - "\n", - "A common approach for serialization is to use a traversal method like preorder traversal, where you visit nodes in the order: root, left subtree, right subtree. This way, you can serialize the tree into a string, and during deserialization, you can reconstruct the tree by parsing the string in the same order.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for a binary tree node.\n", - "class TreeNode(object):\n", - " def __init__(self, x):\n", - " self.val = x\n", - " self.left = None\n", - " self.right = None\n", - "\n", - "class Codec:\n", - " def serialize(self, root):\n", - " serialized = []\n", - "\n", - " def dfs(node):\n", - " if not node:\n", - " # If the node is None, represent it as \"Null\" in the serialized string\n", - " serialized .append(\"Null\")\n", - " return\n", - " # Convert the node's value to a string and add it to the serialized string\n", - " serialized .append(str(node.val))\n", - " dfs(node.left)\n", - " dfs(node.right)\n", - "\n", - " dfs(root)\n", - " # Join the serialized values with \",\"\n", - " return \",\".join(serialized )\n", - "\n", - " def deserialize(self, data):\n", - " vals = data.split(\",\")\n", - " self.i = 0\n", - "\n", - " def dfs():\n", - " if vals[self.i] == \"Null\":\n", - " self.i += 1\n", - " return None\n", - " # Convert the value to an integer to create a new node\n", - " node = TreeNode(int(vals[self.i]))\n", - " self.i += 1\n", - " node.left = dfs()\n", - " node.right = dfs()\n", - " return node\n", - "\n", - " return dfs()" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "Here's a step-by-step explanation of the code:\n", - "\n", - "1. **Definition of TreeNode**:\n", - " - The code defines a simple `TreeNode` class that represents a node in a binary tree. Each `TreeNode` has three attributes:\n", - " - `val`: The integer value stored in the node.\n", - " - `left`: A reference to the left child node (or None if there is no left child).\n", - " - `right`: A reference to the right child node (or None if there is no right child).\n", - " - This class allows you to create binary tree nodes with integer values and left and right child references.\n", - "\n", - "2. **Serialization (serialize method)**:\n", - " - The `serialize` method takes a `root` node as input, which is the root of the binary tree that needs to be serialized.\n", - " - It initializes an empty list `serialized` to store the serialized elements.\n", - " - The `dfs` (depth-first search) function is defined within the `serialize` method to perform a preorder traversal of the binary tree.\n", - " - In the `dfs` function:\n", - " - If the current `node` is `None` (i.e., a leaf node or a child of a leaf node), it appends the string \"Null\" to the `serialized` list to represent the absence of a node.\n", - " - If the current `node` is not `None`, it appends the string representation of the `node.val` to the `serialized` list and then recursively calls `dfs` on the left and right children.\n", - " - After the `dfs` traversal, the `serialized` list contains the serialized binary tree elements.\n", - " - The method returns a string obtained by joining the elements in the `serialized` list with commas.\n", - "\n", - "3. **Deserialization (deserialize method)**:\n", - " - The `deserialize` method takes a serialized string `data` as input, which represents a binary tree in the custom format.\n", - " - It splits the `data` string by commas to obtain a list of elements called `vals`.\n", - " - The method initializes an index `self.i` to 0. This index keeps track of the current position in the `vals` list during deserialization.\n", - " - The `dfs` function is defined within the `deserialize` method to perform the deserialization process using a recursive approach.\n", - " - In the `dfs` function:\n", - " - If the current element in `vals` is \"Null,\" it means there is no node at this position in the binary tree, so it returns `None`.\n", - " - If the current element is not \"Null,\" it converts the element to an integer to create a new `TreeNode` with that value.\n", - " - It then recursively calls `dfs` to set the left and right children of the current node.\n", - " - The method returns the root node of the reconstructed binary tree.\n", - "\n", - "Overall, this code demonstrates a way to serialize a binary tree into a string format and then deserialize it back into the original tree structure, allowing for the representation of both the tree structure and the values stored in the nodes." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1,2,Null,Null,3,4,Null,Null,5,Null,Null\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "# Serialize a binary tree\n", - "root = TreeNode(1)\n", - "root.left = TreeNode(2)\n", - "root.right = TreeNode(3)\n", - "root.right.left = TreeNode(4)\n", - "root.right.right = TreeNode(5)\n", - "\n", - "codec = Codec()\n", - "serialized_tree = codec.serialize(root)\n", - "print(serialized_tree)\n", - "\n", - "# Deserialize the serialized tree\n", - "new_root = codec.deserialize(serialized_tree)" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Null\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "# Example usage:\n", - "# Serialize a binary tree\n", - "root = None\n", - "\n", - "codec = Codec()\n", - "serialized_tree = codec.serialize(root)\n", - "print(serialized_tree)\n", - "\n", - "# Deserialize the serialized tree\n", - "new_root = codec.deserialize(serialized_tree)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code for serializing and deserializing a binary tree:\n", - "\n", - "1. **Serialization (serialize method)**:\n", - "\n", - " - Time Complexity:\n", - " - The `serialize` method uses a depth-first traversal (preorder) of the binary tree.\n", - " - It visits each node exactly once.\n", - " - At each node, it performs constant-time operations (string conversion and list append).\n", - " - Therefore, the time complexity for serialization is O(N), where N is the number of nodes in the binary tree.\n", - "\n", - " - Space Complexity:\n", - " - The space complexity for serialization includes the space used by the `serialized` list and the recursive call stack.\n", - " - The `serialized` list stores the serialized elements, and its space is proportional to the number of nodes.\n", - " - The recursive call stack depth is determined by the height of the binary tree, and in the worst case (completely unbalanced tree), it can be O(N).\n", - " - Therefore, the space complexity for serialization is O(N) due to the list and O(H) due to the recursive call stack, where H is the height of the tree. In most cases, the dominant factor is O(N).\n", - "\n", - "2. **Deserialization (deserialize method)**:\n", - "\n", - " - Time Complexity:\n", - " - The `deserialize` method splits the serialized string into a list of elements, which takes O(N) time.\n", - " - The `dfs` function is a recursive function that visits each element in the list exactly once.\n", - " - At each element, it performs constant-time operations (string comparison, integer conversion, and recursive function calls).\n", - " - Therefore, the time complexity for deserialization is O(N).\n", - "\n", - " - Space Complexity:\n", - " - The space complexity for deserialization includes the space used by the `vals` list and the recursive call stack.\n", - " - The `vals` list stores the elements from the serialized string, and its space is proportional to the number of nodes.\n", - " - The recursive call stack depth is determined by the height of the binary tree, and in the worst case (completely unbalanced tree), it can be O(N).\n", - " - Therefore, the space complexity for deserialization is O(N) due to the list and O(H) due to the recursive call stack, where H is the height of the tree. In most cases, the dominant factor is O(N).\n", - "\n", - "Overall, the provided code has a time complexity of O(N) for both serialization and deserialization and a space complexity of O(N) in the majority of cases (unless the tree is severely unbalanced, in which case the height H dominates the space complexity). It efficiently serializes and deserializes a binary tree while using a linear amount of memory." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Efficient Serialization**:\n", - " Optimize the serialization process to minimize the length of the serialized string. Consider using techniques like binary encoding to represent node values more efficiently.\n", - "\n", - "2. **Custom Serialization Format**:\n", - " Modify the serialization and deserialization methods to use a custom format different from the one provided. Ensure that the new format allows for accurate reconstruction of the original binary tree." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/07. Trees/572. Subtree of Another Tree.ipynb b/docs/07. Trees/572. Subtree of Another Tree.ipynb deleted file mode 100644 index 8a41c3b..0000000 --- a/docs/07. Trees/572. Subtree of Another Tree.ipynb +++ /dev/null @@ -1,265 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 572: Subtree of Another Tree\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Subtree of Another Tree problem on LeetCode, click here!](https://leetcode.com/problems/subtree-of-another-tree/)\n", - "\n", - "---\n", - "\n", - "**Problem Description:**\n", - "\n", - "Given the roots of two binary trees `root` and `subRoot`, return `True` if there is a subtree of `root` with the same structure and node values as `subRoot`, and `False` otherwise.\n", - "\n", - "A subtree of a binary tree `tree` is a tree that consists of a node in `tree` and all of this node's descendants. The tree `tree` could also be considered as a subtree of itself.\n", - "\n", - "**Constraints:**\n", - "\n", - "1. The number of nodes in the `root` tree is in the range $[1, 2000]$.\n", - "2. The number of nodes in the `subRoot` tree is in the range $[1, 1000]$.\n", - "3. $-10^4$ <= root.val <= $10^4$\n", - "4. $-10^4$ <= subRoot.val <= $10^4$\n" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for a binary tree node.\n", - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "class Solution:\n", - " def isSubtree(self, root, subRoot):\n", - " if not root:\n", - " return False\n", - " \n", - " # Check if the current subtree is equal to the subRoot\n", - " if self.isSameTree(root, subRoot):\n", - " return True\n", - " \n", - " # Recursively check the left and right subtrees\n", - " return self.isSubtree(root.left, subRoot) or self.isSubtree(root.right, subRoot)\n", - " \n", - " def isSameTree(self, tree1, tree2):\n", - " if not tree1 and not tree2:\n", - " return True\n", - " if not tree1 or not tree2:\n", - " return False\n", - " \n", - " return (\n", - " tree1.val == tree2.val and\n", - " self.isSameTree(tree1.left, tree2.left) and\n", - " self.isSameTree(tree1.right, tree2.right)\n", - " )" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "This code defines a TreeNode class for the binary tree nodes and a Solution class with two methods:\n", - "\n", - "1. `isSubtree`: This method checks if there is a subtree of the `root` tree with the same structure and node values as the `subRoot` tree. It uses a helper function `isSameTree` to compare two trees for equality.\n", - "\n", - "2. `isSameTree`: This helper method recursively compares two trees to check if they are the same in structure and node values.\n", - "\n", - "### Here's a detailed explanation of the code:\n", - "\n", - "1. **TreeNode Class:**\n", - "\n", - "The `TreeNode` class is defined to represent nodes in a binary tree. Each node has a `val` (the node's value) and may have a `left` and `right` child.\n", - "\n", - "2. **Solution Class:**\n", - "\n", - " + The `Solution` class contains the solution for the problem and defines two important methods:\n", - "\n", - " + `isSubtree(self, root, subRoot)`:\n", - "\n", - " - This method checks whether `subRoot` is a subtree of `root`. It takes two tree nodes, `root` and `subRoot`, as input arguments.\n", - " - If `root` is `None`, it returns `False` because there is no subtree to search.\n", - " - It then checks if the current subtree with `root` as its root is equal to `subRoot` using the `isSameTree` method. If they are the same, it returns `True`.\n", - " - If the current subtree is not the same as `subRoot`, it recursively checks the left and right subtrees of `root` to see if `subRoot` is a subtree of any of them.\n", - " - It returns `True` if `subRoot` is found in either the left or right subtree; otherwise, it returns `False`.\n", - "\n", - " + `isSameTree(self, tree1, tree2)`:\n", - "\n", - " - This method checks whether two trees, `tree1` and `tree2`, are the same.\n", - " - If both `tree1` and `tree2` are `None`, they are considered the same tree, so it returns `True`.\n", - " - If only one of them is `None` (but not both), they are different trees, so it returns `False`.\n", - " - If both `tree1` and `tree2` have values, it checks if their values are equal and recursively checks if their left and right subtrees are the same.\n", - " - It returns `True` if the trees are the same; otherwise, it returns `False`.\n", - "\n", - "The code effectively uses recursion to traverse the binary trees and check for subtree equality. The `isSubtree` method starts the recursive search, and the `isSameTree` method is used to compare individual subtrees. The approach is efficient and avoids unnecessary checks when possible.\n", - "\n", - "This solution allows you to determine if there exists a subtree within the `root` tree that matches the structure and node values of `subRoot`." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Is subRoot a subtree of root? True\n" - ] - } - ], - "source": [ - "#root = [3,4,5,1,2]\n", - "#subRoot = [4,1,2]\n", - "\n", - "# Example input\n", - "root = TreeNode(3)\n", - "root.left = TreeNode(4)\n", - "root.right = TreeNode(5)\n", - "root.left.left = TreeNode(1)\n", - "root.left.right = TreeNode(2)\n", - "\n", - "subRoot = TreeNode(4)\n", - "subRoot.left = TreeNode(1)\n", - "subRoot.right = TreeNode(2)\n", - "\n", - "# Create an instance of the Solution class\n", - "solution = Solution()\n", - "\n", - "# Test the isSubtree method\n", - "result = solution.isSubtree(root, subRoot)\n", - "print(\"Is subRoot a subtree of root?\", result)" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Is subRoot a subtree of root? False\n" - ] - } - ], - "source": [ - "#root = [3,4,5,1,2,null,null,null,null,0] \n", - "#subRoot = [4,1,2]\n", - "\n", - "\n", - "# Example input\n", - "root = TreeNode(3)\n", - "root.left = TreeNode(4)\n", - "root.right = TreeNode(5)\n", - "root.left.left = TreeNode(1)\n", - "root.left.right = TreeNode(2)\n", - "root.left.right.left = TreeNode(0)\n", - "\n", - "subRoot = TreeNode(4)\n", - "subRoot.left = TreeNode(1)\n", - "subRoot.right = TreeNode(2)\n", - "\n", - "# Create an instance of the Solution class\n", - "solution = Solution()\n", - "\n", - "# Test the isSubtree method\n", - "result = solution.isSubtree(root, subRoot)\n", - "print(\"Is subRoot a subtree of root?\", result)" - ] - }, - { - "cell_type": "markdown", - "id": "86a34f0d-0789-498c-818c-2d30f84754d0", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the provided code for the \"Subtree of Another Tree\" problem:\n", - "\n", - "**Time Complexity**\n", - "\n", - "The time complexity of the code primarily depends on the recursive traversal of the binary tree. In both the `isSubtree` and `isSameTree` functions, we visit each node in the binary trees once. Let's break down the time complexity:\n", - "\n", - "1. The `isSubtree` function:\n", - " - In the worst case, we need to visit every node in the `root` tree.\n", - " - For each node in the `root` tree, we call the `isSameTree` function, which has its own traversal.\n", - " - So, the total time complexity is $O(n * m)$, where $n$ is the number of nodes in the `root` tree, and $m$ is the number of nodes in the `subRoot` tree.\n", - "\n", - "2. The `isSameTree` function:\n", - " - In the worst case, we visit every node in both `tree1` and `tree2`.\n", - " - The number of recursive calls made is proportional to the number of nodes in the trees.\n", - " - So, the time complexity of this function is $O(max(n, m))$, where $n$ and $m$ are the numbers of nodes in `tree1` and `tree2`, respectively.\n", - "\n", - "Overall, the time complexity of the entire code is $O(n * m)$, where $n$ is the number of nodes in the `root` tree, and $m$ is the number of nodes in the `subRoot` tree. In practice, it may be less than $O(n * m)$ if a subtree mismatch is detected early during the traversal.\n", - "\n", - "**Space Complexity**\n", - "\n", - "The space complexity of the code is determined by the function call stack during recursion and the space used by the recursive functions. Let's analyze the space complexity:\n", - "\n", - "1. The `isSubtree` function:\n", - " - It uses the call stack for recursion.\n", - " - The maximum depth of the recursion is equal to the height of the `root` tree, which can be $O(n)$ in the worst case (unbalanced tree).\n", - " - Additionally, the function doesn't use any significant extra space other than the recursion stack.\n", - "\n", - "2. The `isSameTree` function:\n", - " - It also uses the call stack for recursion.\n", - " - The maximum depth of the recursion is equal to the height of the `tree1` or `tree2`, whichever is greater.\n", - " - So, the maximum space used for the call stack is $O(max(n, m))$.\n", - "\n", - "In summary, the space complexity of the code is $O(max(n, m))$ due to the function call stack. It scales with the maximum height of the trees being compared.\n", - "\n", - "Overall, the code is efficient and works well for trees with moderate sizes. However, it's important to keep in mind that the worst-case time complexity is $O(n * m)$, so for very large trees, the performance may degrade." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/07. Trees/98. Validate Binary Search Tree.ipynb b/docs/07. Trees/98. Validate Binary Search Tree.ipynb deleted file mode 100644 index ad86882..0000000 --- a/docs/07. Trees/98. Validate Binary Search Tree.ipynb +++ /dev/null @@ -1,221 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 98. Validate Binary Search Tree\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Validate Binary Search Tree problem on LeetCode, click here!](https://leetcode.com/problems/validate-binary-search-tree/)\n", - "\n", - "---\n", - "Given the `root` of a binary tree, *determine if it is a valid binary search tree (BST)*.\n", - "\n", - "A **valid BST** is defined as follows:\n", - "\n", - "- The left subtree of a node contains only nodes with keys **less than** the node's key.\n", - "- The right subtree of a node contains only nodes with keys **greater than** the node's key.\n", - "- Both the left and right subtrees must also be binary search trees. \n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the tree is in the range $[1, 10^4]$.\n", - "- $-2^{31}$ <= `Node.val` <= $2^{31} - 1$\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def is_valid_BST(root):\n", - " def is_valid(node, min_val, max_val):\n", - " # Base case: If the node is None, it's a valid BST.\n", - " if node is None:\n", - " return True\n", - " \n", - " # Check if the current node's value is within the valid range.\n", - " if not (min_val < node.val < max_val):\n", - " return False\n", - " \n", - " # Recursively check the left and right subtrees with updated ranges.\n", - " return (is_valid(node.left, min_val, node.val) and\n", - " is_valid(node.right, node.val, max_val))\n", - " \n", - " # Call the helper function starting with a wide range for root node.\n", - " return is_valid(root, float('-inf'), float('inf'))" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "- It defines a `TreeNode` class to represent nodes in the binary tree.\n", - "\n", - "- The `is_valid_BST` function takes the root node of the binary tree as input and returns `True` if the tree is a valid BST, and `False` otherwise.\n", - "\n", - "- Inside the `is_valid_BST` function, there is a helper function called `is_valid` that performs the actual validation using a recursive approach.\n", - "\n", - "- The `is_valid` function checks each node in the tree to ensure that it satisfies the properties of a BST:\n", - " - The value of the current node must be within a valid range defined by `min_val` and `max_val`.\n", - " - The left subtree of the current node should contain values less than the current node's value.\n", - " - The right subtree of the current node should contain values greater than the current node's value.\n", - "\n", - "- If any of these conditions are violated, the function returns `False`, indicating that the tree is not a valid BST.\n", - "\n", - "- If all nodes satisfy these conditions, the function returns `True`, indicating that the tree is a valid BST.\n", - "\n", - "- The code calls the `is_valid` function with the root node and initial range values of negative infinity to positive infinity to start the validation.\n", - "\n", - "- The time complexity of the code is O(N), where N is the number of nodes in the tree, as it traverses each node once.\n", - "\n", - "- The space complexity depends on the height of the tree. In the average case for a balanced BST, the space complexity is O(log N), but in the worst case (skewed tree), it can be O(N) due to the recursive call stack.\n", - "\n", - "In summary, this code checks whether a given binary tree is a valid BST by recursively validating each node's value and its left and right subtrees while maintaining valid value ranges. If all nodes satisfy the BST properties, the tree is considered a valid BST." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "# Create the tree for the first example: [2, 1, 3]\n", - "root1 = TreeNode(2)\n", - "root1.left = TreeNode(1)\n", - "root1.right = TreeNode(3)\n", - "print(is_valid_BST(root1))" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "# Create the tree for the second example: [5, 1, 4, None, None, 3, 6]\n", - "root2 = TreeNode(5)\n", - "root2.left = TreeNode(1)\n", - "root2.right = TreeNode(4)\n", - "root2.right.left = TreeNode(3)\n", - "root2.right.right = TreeNode(6)\n", - "print(is_valid_BST(root2))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `is_valid_BST` function:\n", - "\n", - "**Time Complexity:**\n", - "- The time complexity of the function primarily depends on the number of nodes in the binary tree.\n", - "- In the worst case, we may have to visit every node in the tree once to validate whether it's part of a valid BST.\n", - "- Since we are performing a depth-first search (DFS) traversal of the tree, the time complexity is O(N), where N is the number of nodes in the tree.\n", - "\n", - "**Space Complexity:**\n", - "- The space complexity is determined by the space used by the recursive call stack during the DFS traversal.\n", - "- In the worst case, if the tree is completely unbalanced (a skewed tree), the maximum depth of the call stack would be equal to the height of the tree.\n", - "- In a balanced BST, the height is approximately log2(N), where N is the number of nodes.\n", - "- Therefore, the space complexity of the call stack is O(log N) for a balanced BST.\n", - "- In the worst case (skewed tree), the space complexity can be O(N) as the height of the tree can be equal to N.\n", - "\n", - "**Overall:**\n", - "- Time Complexity: O(N)\n", - "- Space Complexity: O(log N) on average for a balanced BST, and O(N) in the worst case for a skewed tree.\n", - "\n", - "The space complexity is typically dominated by the recursive call stack, and it varies depending on the shape of the binary tree. In practice, for balanced binary trees, the space complexity is often close to O(log N), which is quite efficient." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Complex Constraints**: Modify the problem to have more complex constraints on the tree. For example, consider a binary tree with constraints like \"The left subtree of a node contains only nodes with keys less than or equal to the node's key,\" and \"The right subtree of a node contains only nodes with keys greater than or equal to the node's key.\" How would you adapt the code to handle these constraints?\n", - "\n", - "2. **Handling Duplicates**: Modify the code to handle binary search trees that allow duplicate values. In a standard BST, each value is unique, but in this case, multiple nodes can have the same value. The tree should still be considered valid if it follows the BST property." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/07. Trees/README.md b/docs/07. Trees/README.md deleted file mode 100644 index 1eba5d4..0000000 --- a/docs/07. Trees/README.md +++ /dev/null @@ -1,26 +0,0 @@ -# Trees Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [226. Invert Binary Tree](https://leetcode.com/problems/invert-binary-tree/) | Easy | -| [104. Maximum Depth of Binary Tree](https://leetcode.com/problems/maximum-depth-of-binary-tree/) | Easy | -| [100. Same Tree](https://leetcode.com/problems/same-tree/) | Easy | -| [572. Subtree of Another Tree](https://leetcode.com/problems/subtree-of-another-tree/) | Easy | -| [235. Lowest Common Ancestor of a Binary Search Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/) | Easy | -| [102. Binary Tree Level Order Traversal](https://leetcode.com/problems/binary-tree-level-order-traversal/) | Medium | -| [98. Validate Binary Search Tree](https://leetcode.com/problems/validate-binary-search-tree/) | Medium | -| [230. Kth Smallest Element In a BST](https://leetcode.com/problems/kth-smallest-element-in-a-bst/) | Medium | -| [105. Construct Binary Tree From Preorder And Inorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/) | Medium | -| [124. Binary Tree Maximum Path Sum](https://leetcode.com/problems/binary-tree-maximum-path-sum/) | Hard | -| [297. Serialize And Deserialize Binary Tree](https://leetcode.com/problems/serialize-and-deserialize-binary-tree/) | Hard | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! diff --git a/docs/08. Tries/208. Implement Trie (Prefix Tree).ipynb b/docs/08. Tries/208. Implement Trie (Prefix Tree).ipynb deleted file mode 100644 index 9da2a17..0000000 --- a/docs/08. Tries/208. Implement Trie (Prefix Tree).ipynb +++ /dev/null @@ -1,249 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 208. Implement Trie (Prefix Tree)\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Implement Trie problem on LeetCode, click here!](https://leetcode.com/problems/implement-trie-prefix-tree/)\n", - "\n", - "---\n", - "A **trie** (pronounced as \"try\") or **prefix tree** is a tree data structure used to efficiently store and retrieve keys in a dataset of strings. There are various applications of this data structure, such as autocomplete and spellchecker.\n", - "\n", - "Implement the Trie class:\n", - "\n", - "- `Trie()` Initializes the trie object.\n", - "- `void insert(String word)` Inserts the string `word` into the trie.\n", - "- `boolean search(String word)` Returns `true` if the string `word` is in the trie (i.e., was inserted before), and `false` otherwise.\n", - "- `boolean startsWith(String prefix)` Returns `true` if there is a previously inserted string `word` that has the prefix `prefix`, and `false` otherwise.\n", - "\n", - "\n", - "**Constraints:**\n", - "- `1 <= word.length, prefix.length <= 2000`\n", - "- `word` and `prefix` consist only of lowercase English letters.\n", - "- At most $3 * 10^4$ calls in total will be made to `insert`, `search`, and `startsWith`." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem at hand is to implement a data structure known as a Trie (pronounced \"try\") or Prefix Tree. A Trie is a tree-like data structure that is used to efficiently store and retrieve a set of strings or words. It's particularly useful for tasks involving string manipulation, such as autocomplete and spell-checking. The problem statement defines the following operations for implementing the Trie class:\n", - "\n", - "1. `Trie()`: This is the constructor that initializes the Trie object.\n", - "\n", - "2. `void insert(String word)`: This method inserts the given string `word` into the Trie. It effectively adds the characters of the word to the Trie's structure, creating nodes for each character if they don't already exist. At the end of the word, a special flag is set to indicate that this node represents the end of a valid word.\n", - "\n", - "3. `boolean search(String word)`: This method checks if the given string `word` is present in the Trie. It starts from the root of the Trie and traverses the Trie by following the characters in the word. If it successfully traverses the Trie and reaches the end of the word, it returns `true`, indicating that the word exists in the Trie; otherwise, it returns `false`.\n", - "\n", - "4. `boolean startsWith(String prefix)`: This method checks if there is any previously inserted word in the Trie that has the given `prefix`. It's similar to the `search` method but does not require that the prefix be a complete word. If there is any word in the Trie that starts with the given prefix, it returns `true`; otherwise, it returns `false`.\n", - "\n", - "The problem also provides an example scenario where these operations are called, demonstrating the expected output for each operation.\n", - "\n", - "In summary, the goal is to create a data structure (Trie) that efficiently stores a set of strings and provides methods to insert new strings, search for complete words, and check if a given prefix exists in the stored set of strings.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class TrieNode:\n", - " def __init__(self):\n", - " self.children = {} # A dictionary to store child nodes\n", - " self.is_end_of_word = False # Indicates if a word ends at this node\n", - "\n", - "class Trie:\n", - " def __init__(self):\n", - " self.root = TrieNode() # Initialize the Trie with a root node\n", - "\n", - " def insert(self, word):\n", - " node = self.root # Start from the root\n", - " for char in word:\n", - " if char not in node.children:\n", - " node.children[char] = TrieNode() # Create a new node if the character is not present\n", - " node = node.children[char] # Move to the child node\n", - " node.is_end_of_word = True # Mark the end of the inserted word\n", - "\n", - " def search(self, word):\n", - " node = self.root # Start from the root\n", - " for char in word:\n", - " if char not in node.children:\n", - " return False # If the character is not found, the word is not in the Trie\n", - " node = node.children[char] # Move to the child node\n", - " return node.is_end_of_word # Check if the node represents the end of a valid word\n", - "\n", - " def startsWith(self, prefix):\n", - " node = self.root # Start from the root\n", - " for char in prefix:\n", - " if char not in node.children:\n", - " return False # If the character is not found, no word starts with the prefix\n", - " node = node.children[char] # Move to the child node\n", - " return True # Prefix found in the Trie" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "Let's explain how the code works step by step:\n", - "\n", - "1. `TrieNode` Class:\n", - " - `TrieNode` is a class that represents nodes in the Trie. Each node has two attributes:\n", - " - `children`: This is a dictionary that stores child nodes. Each key in the dictionary represents a character, and the corresponding value is the child node for that character.\n", - " - `is_end_of_word`: This boolean flag indicates whether the node represents the end of a complete word. Initially, it's set to `False` for all nodes.\n", - "\n", - "2. `Trie` Class:\n", - " - `Trie` is the main class that implements the Trie data structure. It has the following methods:\n", - "\n", - " - `__init__(self)`: The constructor initializes the Trie object by creating a root node, which serves as the starting point for all Trie operations.\n", - "\n", - " - `insert(self, word)`: This method inserts a string `word` into the Trie. It starts from the root node and iterates through each character in the word.\n", - " - If a character is not present as a child node, it creates a new node for that character.\n", - " - It then moves to the child node and continues the process until the entire word is inserted.\n", - " - Finally, it sets the `is_end_of_word` flag to `True` for the last node to mark the end of the inserted word.\n", - "\n", - " - `search(self, word)`: This method checks if a complete word (string) exists in the Trie. It starts from the root node and iterates through each character in the word.\n", - " - If a character is not found as a child node, it immediately returns `False` because the word is not in the Trie.\n", - " - It continues to move to the child node for each character.\n", - " - After reaching the end of the word, it checks if the `is_end_of_word` flag is `True` for the last node to confirm the presence of the word.\n", - "\n", - " - `startsWith(self, prefix)`: This method checks if there is any previously inserted word in the Trie that starts with a given `prefix`. It follows the same logic as the `search` method but does not require the entire word to be present.\n", - " - If the prefix is found in the Trie, it returns `True`; otherwise, it returns `False`.\n", - "\n", - "3. Example Usage:\n", - " - The code demonstrates how to create a Trie object, insert words (\"apple\" and \"app\"), and perform operations on the Trie:\n", - " - It inserts the word \"apple\" into the Trie.\n", - " - It checks if \"apple\" is in the Trie, which returns `True`.\n", - " - It checks if \"app\" is in the Trie, which returns `False`.\n", - " - It checks if there is any word in the Trie that starts with \"app,\" which returns `True`.\n", - " - It inserts the word \"app\" into the Trie.\n", - " - It checks if \"app\" is in the Trie again, which now returns `True`.\n", - "\n", - "In summary, the code efficiently implements a Trie data structure with the ability to insert words, search for complete words, and check for the existence of words with a given prefix. The Trie is organized as a tree of nodes, with each node representing a character in the words being stored." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n", - "False\n", - "True\n", - "True\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "\n", - "trie = Trie()\n", - "trie.insert(\"apple\")\n", - "print(trie.search(\"apple\")) # Output: True\n", - "print(trie.search(\"app\")) # Output: False\n", - "print(trie.startsWith(\"app\")) # Output: True\n", - "trie.insert(\"app\")\n", - "print(trie.search(\"app\")) # Output: True" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the Trie implementation:\n", - "\n", - "1. Time Complexity:\n", - " - Insertion (`insert` method): The time complexity of inserting a word into the Trie is O(m), where m is the length of the word. In the worst case, you may need to traverse the entire word to insert it into the Trie.\n", - " - Search (`search` method): The time complexity of searching for a word in the Trie is also O(m), where m is the length of the word. In the worst case, you may need to traverse the entire word to determine if it exists in the Trie.\n", - " - Starts with (`startsWith` method): The time complexity of checking if a prefix exists in the Trie is O(p), where p is the length of the prefix. In the worst case, you may need to traverse the entire prefix to determine its presence.\n", - "\n", - " Therefore, for each operation (insertion, search, or starts with), the time complexity is O(m) or O(p), where m is the length of the word being operated on, and p is the length of the prefix.\n", - "\n", - "2. Space Complexity:\n", - " - The space complexity of the Trie is determined by the number of nodes and characters stored in it. In the worst case, where none of the inserted words share common prefixes, the space complexity is O(N), where N is the total number of characters across all inserted words.\n", - " - Each node in the Trie represents a character, and the number of nodes is directly related to the total number of characters.\n", - "\n", - " In practice, the space complexity can be less than O(N) because common prefixes are shared among words in the Trie, leading to space optimization.\n", - "\n", - "In summary:\n", - "- Time complexity for each operation (insertion, search, starts with) is O(m) or O(p), where m is the length of the word and p is the length of the prefix.\n", - "- Space complexity is O(N) in the worst case, where N is the total number of characters across all inserted words. However, space optimization occurs due to common prefix sharing in practice, potentially reducing the actual space used." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Count Prefixes**:\n", - " Implement a method to count the number of words in the Trie that have a specific prefix. This exercise requires you to maintain additional data in the Trie nodes to keep track of the count.\n", - "\n", - "2. **Auto-Complete Suggestions**:\n", - " Implement an auto-complete feature using the Trie. Given a prefix, the program should return a list of suggested words based on the words previously inserted into the Trie." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/08. Tries/211. Design Add and Search Words Data Structure.ipynb b/docs/08. Tries/211. Design Add and Search Words Data Structure.ipynb deleted file mode 100644 index 2de472c..0000000 --- a/docs/08. Tries/211. Design Add and Search Words Data Structure.ipynb +++ /dev/null @@ -1,275 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 211. Design Add and Search Words Data Structure\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Design Add and Search Words Data Structure problem on LeetCode, click here!](https://leetcode.com/problems/design-add-and-search-words-data-structure/)\n", - "\n", - "---\n", - "Design a data structure that supports adding new words and finding if a string matches any previously added string.\n", - "\n", - "Implement the `WordDictionary` class:\n", - "\n", - "- `WordDictionary()` Initializes the object.\n", - "- `void addWord(word)` Adds `word` to the data structure, it can be matched later.\n", - "- `bool search(word)` Returns `true` if there is any string in the data structure that matches `word` or `false` otherwise. `word` may contain dots `'.'` where dots can be matched with any letter.\n", - "\n", - "**Constraints:**\n", - "- `1 <= word.length <= 25`\n", - "- `word` in `addWord` consists of lowercase English letters.\n", - "- `word` in `search` consist of `'.'` or lowercase English letters.\n", - "- There will be at most `2` dots in `word` for `search` queries.\n", - "- At most $10^4$ calls will be made to `addWord` and `search`." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is to design a data structure called `WordDictionary` that allows you to add words and search for words efficiently. The key feature of this data structure is that it should support wildcard search, where a dot ('.') can match any letter.\n", - "\n", - "Here are the specific requirements and explanations for the problem:\n", - "\n", - "1. Initialize the `WordDictionary` object using the constructor `WordDictionary()`.\n", - "\n", - "2. The `addWord(word)` method allows you to add a word to the data structure. Once added, you should be able to search for this word later. The words consist of lowercase English letters, and each word has a length between 1 and 25 characters.\n", - "\n", - "3. The `search(word)` method allows you to search for a word in the data structure. This method returns `True` if there is any string in the data structure that matches the given word or `False` otherwise. The word you are searching for may contain dots ('.'), where each dot can match any letter.\n", - "\n", - "4. The wildcard character ('.') in the `search` method allows for partial or fuzzy searching. For example, if the word dictionary contains the words \"bad,\" \"dad,\" and \"mad,\" then:\n", - " - Searching for \"pad\" should return `False` because there is no exact match.\n", - " - Searching for \"bad\" should return `True` because \"bad\" is in the dictionary.\n", - " - Searching for \".ad\" should return `True` because it can match \"bad,\" \"dad,\" or \"mad.\"\n", - " - Searching for \"b..\" should return `True` because it can match \"bad,\" \"bed,\" \"bet,\" etc.\n", - "\n", - "5. The problem specifies that there will be at most two dots ('.') in search queries, and there will be at most 10^4 calls to both `addWord` and `search`.\n", - "\n", - "In summary, you need to implement the `WordDictionary` class that efficiently supports adding words and searching for words, where the search can include wildcard characters ('.') that match any letter.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class TrieNode:\n", - " def __init__(self):\n", - " # Initialize a TrieNode with children and a flag to indicate the end of a word.\n", - " self.children = {}\n", - " self.is_end_of_word = False\n", - "\n", - "class WordDictionary:\n", - "\n", - " def __init__(self):\n", - " # Initialize the WordDictionary with a root node.\n", - " self.root = TrieNode()\n", - "\n", - " def addWord(self, word: str) -> None:\n", - " node = self.root\n", - " # Iterate through the characters in the word.\n", - " for char in word:\n", - " if char not in node.children:\n", - " # Create a new node for the character if it doesn't exist.\n", - " node.children[char] = TrieNode()\n", - " # Move to the next node.\n", - " node = node.children[char]\n", - " # Mark the end of the word by setting the flag to True.\n", - " node.is_end_of_word = True\n", - "\n", - " def search_helper(self, node: TrieNode, word: str) -> bool:\n", - " if not word:\n", - " # If there are no characters left in the word, check if we reached the end of a word in the trie.\n", - " return node.is_end_of_word\n", - " \n", - " char = word[0]\n", - " if char == '.':\n", - " # If the character is a dot, explore all possible child nodes.\n", - " for child in node.children.values():\n", - " if self.search_helper(child, word[1:]):\n", - " return True\n", - " elif char in node.children:\n", - " # If the character is in the children of the current node, move to the next node.\n", - " return self.search_helper(node.children[char], word[1:])\n", - " \n", - " # If the character is not found and is not a dot, the word is not in the trie.\n", - " return False\n", - "\n", - " def search(self, word: str) -> bool:\n", - " # Start the search from the root of the trie.\n", - " return self.search_helper(self.root, word)" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "This code defines a `WordDictionary` class that uses a Trie data structure to efficiently store and search for words. Here's a step-by-step explanation:\n", - "\n", - "1. `TrieNode` class: This class represents nodes in the Trie data structure. Each node has two attributes: `children` (a dictionary to store child nodes) and `is_end_of_word` (a flag to indicate whether the node marks the end of a word).\n", - "\n", - "2. `WordDictionary` class: This class initializes with an empty Trie by creating a root node.\n", - "\n", - "3. `addWord` method: This method adds a word to the Trie. It iterates through each character in the word and creates Trie nodes as necessary. It sets the `is_end_of_word` flag to `True` for the final character of the word to mark the end of the word.\n", - "\n", - "4. `search_helper` method: This is a recursive helper function for searching words in the Trie. It takes a Trie node (`node`) and a word to search (`word`) as input. If there are no characters left in the word (`not word`), it checks if the current node marks the end of a word. If it does, it returns `True`.\n", - "\n", - "5. If the first character of the word is a dot ('.'), the function explores all possible child nodes by iterating through `node.children.values()` and recursively calls `search_helper` for each child with the remaining part of the word (`word[1:]`).\n", - "\n", - "6. If the first character of the word is not a dot and is found in the children of the current node, the function recursively moves to the next node by calling `search_helper` on the child node and the remaining part of the word.\n", - "\n", - "7. If the character is not found in the children and is not a dot, the word is not in the Trie, so the function returns `False`.\n", - "\n", - "8. `search` method: This is the public method for searching words. It initiates the search process by calling `search_helper` starting from the root node of the Trie.\n", - "\n", - "Overall, this code efficiently implements a Trie-based data structure that allows adding and searching for words, including support for wildcard characters represented by dots ('.')." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n", - "True\n", - "True\n", - "True\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "\n", - "wordDictionary = WordDictionary()\n", - "wordDictionary.addWord(\"bad\")\n", - "wordDictionary.addWord(\"dad\")\n", - "wordDictionary.addWord(\"mad\")\n", - "print(wordDictionary.search(\"pad\")) # Output: False\n", - "print(wordDictionary.search(\"bad\")) # Output: True\n", - "print(wordDictionary.search(\".ad\")) # Output: True\n", - "print(wordDictionary.search(\"b..\")) # Output: True" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `WordDictionary` class methods:\n", - "\n", - "1. `addWord` Method:\n", - "\n", - " - Time Complexity: O(L)\n", - " - L is the length of the word being added.\n", - " - In the worst case, we need to iterate through each character in the word and create nodes in the Trie. This takes O(L) time.\n", - "\n", - " - Space Complexity: O(L)\n", - " - The space complexity for storing the word in the Trie is also O(L) because we create nodes for each character in the word.\n", - "\n", - "2. `search_helper` Method (called by `search`):\n", - "\n", - " - Time Complexity: O(2^M * L)\n", - " - M is the maximum number of dots ('.') in the search word.\n", - " - In the worst case, when there are M dots in the search word, we may explore all possible child nodes at each dot. This results in a branching factor of 26 (for lowercase letters) at each dot.\n", - " - So, the time complexity is exponential in the number of dots and linear in the length of the word being searched (L).\n", - "\n", - " - Space Complexity: O(L)\n", - " - The space complexity for the recursive call stack is O(L) in the worst case because we may have to recurse to a depth equal to the length of the search word.\n", - "\n", - "3. `search` Method:\n", - "\n", - " - Time Complexity: O(2^M * L)\n", - " - The `search` method calls the `search_helper` method, which has the same time complexity explained above.\n", - "\n", - " - Space Complexity: O(L)\n", - " - The space complexity for the recursive call stack is O(L) in the worst case, as explained earlier.\n", - "\n", - "Overall, the time complexity of the `search` method is mainly affected by the number of dots ('.') in the search word. In the worst case, when there are multiple dots and many possibilities to explore at each dot, the time complexity can be exponential. However, for most practical cases, it performs reasonably well.\n", - "\n", - "The space complexity primarily depends on the space required to store the words in the Trie. It is proportional to the total number of characters in all added words and is linear with respect to the length of the words added.\n", - "\n", - "In summary:\n", - "\n", - "- Time Complexity for `addWord`: O(L)\n", - "- Time Complexity for `search`: O(2^M * L)\n", - "- Space Complexity: O(L) for storing words in the Trie, O(L) for the recursive call stack during search.\n", - "\n", - "Note: The space complexity analysis assumes that the dictionary contains a reasonable number of words and does not account for the overhead of Python objects or system-level memory allocation." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Dictionary Auto-Completion**: Extend the `WordDictionary` class to provide auto-completion suggestions based on the prefix of a word. Implement a method that returns a list of words that match the given prefix.\n", - "\n", - "2. **Support Word Deletion**: Extend the `WordDictionary` class to support word deletion. Add a method `deleteWord(word)` that removes a word from the data structure. Ensure that the search operation still works correctly after deletion." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/08. Tries/212. Word Search II.ipynb b/docs/08. Tries/212. Word Search II.ipynb deleted file mode 100644 index 71597b8..0000000 --- a/docs/08. Tries/212. Word Search II.ipynb +++ /dev/null @@ -1,316 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 212. Word Search II\n", - "\n", - "**Difficulty:** Hard\n", - "\n", - "**Link to Problem:** [To see the Word Search II problem on LeetCode, click here!](https://leetcode.com/problems/word-search-ii/)\n", - "\n", - "---\n", - "Given an `m x n` `board` of characters and a list of strings `words`, the task is to return *all words on the board*.\n", - "\n", - "Each word must be constructed from letters of sequentially **adjacent cells**, where adjacent cells are horizontally or vertically neighboring. The same letter cell may not be used more than once in a word.\n", - "\n", - "\n", - "**Constraints:**\n", - "- `m == board.length`\n", - "- `n == board[i].length`\n", - "- `1 <= m, n <= 12`\n", - "- `board[i][j]` is a lowercase English letter.\n", - "- 1 <= `words.length` <= $3 * 10^4$\n", - "- `1 <= words[i].length <= 10`\n", - "- `words[i]` consists of lowercase English letters.\n", - "- All the strings of `words` are unique." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "To solve the \"Word Search II\" problem, you can use a Trie data structure and perform a depth-first search (DFS) on the board. Here's a step-by-step approach to solve the problem:\n", - "\n", - "1. Build a Trie from the given list of words:\n", - " - Create a Trie data structure to store all the words from the input list.\n", - " - For each word in the input list, insert it into the Trie, character by character. Make sure to mark the end of each word in the Trie.\n", - "\n", - "2. Perform DFS on the board:\n", - " - Iterate through each cell (i, j) on the board.\n", - " - For each cell, start a DFS traversal from that cell to search for words.\n", - " - During the DFS traversal, maintain a current path string.\n", - " - At each cell, check if the current path string, concatenated with the character in the cell, matches any word prefix in the Trie. If it does, continue the DFS.\n", - " - If the current path string matches a word in the Trie, add it to the result.\n", - "\n", - "3. Implement DFS with backtracking:\n", - " - During the DFS traversal, you will explore neighboring cells (horizontally and vertically) if they are within bounds and haven't been visited before.\n", - " - To prevent revisiting the same cell within the same word, mark the cell as visited (e.g., change its character to a special character like '#') before exploring it and restore its original character after the DFS traversal.\n", - "\n", - "4. Return the result:\n", - " - After completing the DFS traversal for all cells on the board, you will have collected all the valid words in the result set.\n", - " - Convert the result set to a list and return it as the final output.\n", - "\n", - "This approach efficiently finds all words on the board by utilizing the Trie data structure to prune unnecessary DFS paths and avoiding duplicate visits to the same cell within the same word. It ensures that each word is constructed from letters of sequentially adjacent cells without using the same letter cell more than once in a word.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Define a TrieNode class to represent nodes in the Trie.\n", - "class TrieNode:\n", - " def __init__(self):\n", - " self.children = {} # Dictionary to store child nodes.\n", - " self.is_end_of_word = False # Flag to mark the end of a word.\n", - "\n", - "# Main function to find words on the board.\n", - "def findWords(board, words):\n", - " # DFS function to search for words starting from a given cell.\n", - " def dfs(node, i, j, path):\n", - " char = board[i][j] # Get the character at the current cell.\n", - " curr_node = node.children.get(char) # Find the corresponding Trie node.\n", - "\n", - " if not curr_node:\n", - " return # If no matching Trie node, stop the search.\n", - "\n", - " path += char # Add the character to the current path.\n", - "\n", - " if curr_node.is_end_of_word:\n", - " result.add(path) # If the path matches a word, add it to the result.\n", - "\n", - " temp, board[i][j] = board[i][j], \"#\" # Mark the cell as visited.\n", - "\n", - " # Explore neighboring cells (up, down, left, right).\n", - " if i > 0:\n", - " dfs(curr_node, i - 1, j, path)\n", - " if i < m - 1:\n", - " dfs(curr_node, i + 1, j, path)\n", - " if j > 0:\n", - " dfs(curr_node, i, j - 1, path)\n", - " if j < n - 1:\n", - " dfs(curr_node, i, j + 1, path)\n", - "\n", - " board[i][j] = temp # Restore the cell's original character.\n", - "\n", - " # Function to build a Trie from the list of words.\n", - " def buildTrie():\n", - " root = TrieNode() # Create a root node.\n", - " for word in words:\n", - " node = root\n", - " for char in word:\n", - " if char not in node.children:\n", - " node.children[char] = TrieNode() # Create a new node if needed.\n", - " node = node.children[char]\n", - " node.is_end_of_word = True # Mark the end of the word.\n", - " return root\n", - "\n", - " m, n = len(board), len(board[0]) # Get the dimensions of the board.\n", - " root = buildTrie() # Build the Trie from the list of words.\n", - " result = set() # Use a set to store unique words found on the board.\n", - "\n", - " # Iterate through each cell on the board and start DFS from there.\n", - " for i in range(m):\n", - " for j in range(n):\n", - " dfs(root, i, j, \"\") # Start DFS from each cell on the board.\n", - "\n", - " return list(result) # Convert the set to a list and return the result." - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The code solves the \"Word Search II\" problem, where you have a grid of characters and a list of words. The goal is to find all words from the list that can be constructed by traversing adjacent cells (horizontally or vertically) in the grid, without using the same cell more than once for a single word.\n", - "\n", - "The code does the following:\n", - "\n", - "1. Defines a `TrieNode` class to represent nodes in a Trie data structure. Each node has children (other characters in the word) and a flag to mark the end of a word.\n", - "\n", - "2. Defines the `findWords` function, which takes the grid (`board`) and a list of words (`words`) as input.\n", - "\n", - "3. Inside the `findWords` function, there is a `dfs` (depth-first search) function. This function is used to explore the grid starting from a specific cell. It checks if the current path matches any word in the Trie and adds it to the result if found.\n", - "\n", - "4. The code also includes a `buildTrie` function that constructs a Trie data structure from the list of words. It iterates through each word, creating nodes for each character in the Trie and marking the end of words.\n", - "\n", - "5. The dimensions of the grid are obtained (m x n).\n", - "\n", - "6. A Trie is built using the `buildTrie` function.\n", - "\n", - "7. A set called `result` is used to store unique words found in the grid.\n", - "\n", - "8. The code iterates through each cell on the grid (using nested loops) and starts a DFS search from each cell.\n", - "\n", - "9. During the DFS, it explores neighboring cells (up, down, left, right) if they haven't been visited before and if the current path matches a prefix in the Trie.\n", - "\n", - "10. When a word is found during the DFS traversal, it is added to the `result` set.\n", - "\n", - "11. The grid cell is marked as visited during the DFS by changing its character to \"#\", and it is restored to its original character after the DFS traversal.\n", - "\n", - "12. Finally, the set of unique words found is converted to a list and returned as the output.\n", - "\n", - "The code effectively uses a Trie data structure to optimize the search and ensures that each word is constructed from adjacent cells without reusing the same cell for the same word." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['eat', 'oath']\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "board1 = [[\"o\",\"a\",\"a\",\"n\"],[\"e\",\"t\",\"a\",\"e\"],[\"i\",\"h\",\"k\",\"r\"],[\"i\",\"f\",\"l\",\"v\"]]\n", - "words1 = [\"oath\",\"pea\",\"eat\",\"rain\"]\n", - "print(findWords(board1, words1)) # Output: [\"eat\", \"oath\"]" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "c748b879-a2d8-4298-a42c-c7f61f9c7fc6", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[]\n" - ] - } - ], - "source": [ - "# Example 2\n", - "\n", - "board2 = [[\"a\",\"b\"],[\"c\",\"d\"]]\n", - "words2 = [\"abcb\"]\n", - "print(findWords(board2, words2)) # Output: []" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. **Building the Trie (`buildTrie` function):** \n", - " - Suppose there are `N` words in the input list, and the average length of a word is `L`.\n", - " - Building the Trie takes O(N * L) time, as we iterate through each word and insert each character into the Trie.\n", - "\n", - "2. **DFS Traversal (`dfs` function):** \n", - " - In the worst case, the DFS function explores all possible paths in the grid.\n", - " - The maximum number of recursive calls for each cell is 4 (up, down, left, right).\n", - " - The maximum depth of the DFS is limited by the length of the longest word in the Trie, which is at most `L`.\n", - " - Therefore, the DFS traversal for each cell takes $O(4^L)$ time.\n", - "\n", - "3. **Iterating Through the Grid (`findWords` function):**\n", - " - In the worst case, we iterate through all `m` rows and `n` columns in the grid.\n", - " - For each cell, we start a DFS traversal.\n", - " - Therefore, iterating through the entire grid takes $O(m * n * 4^L)$ time.\n", - "\n", - "Overall, the time complexity of the code is $O(N * L + m * n * 4^L)$.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. **Trie Data Structure:**\n", - " - The space required to store the Trie depends on the number of unique characters in all the words.\n", - " - In the worst case, where all words are unique and have no common prefixes, the space complexity of the Trie is O(N * L).\n", - " - In practice, it may be less if there are common prefixes among words.\n", - "\n", - "2. **DFS Stack (Recursive Calls):**\n", - " - The depth of the recursive call stack during DFS is at most `L`, where `L` is the length of the longest word in the Trie.\n", - " - Therefore, the space complexity for the recursive call stack is O(L).\n", - "\n", - "3. **Result Set (`result` set):**\n", - " - The space used to store the result set depends on the number of valid words found in the grid.\n", - " - In the worst case, when all words are found, the space complexity of the result set is O(N * L).\n", - "\n", - "Overall, the space complexity of the code is O(N * L) for the Trie and O(L) for the recursive call stack.\n", - "\n", - "In summary, the time complexity is dominated by the DFS traversal and is influenced by the number of words, their lengths, and the size of the grid. The space complexity is mainly determined by the Trie structure and the recursive call stack depth during DFS." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Word Search Paths:**\n", - " Extend the basic word search exercise to find all possible paths (sequences of cells) that spell out a given word on the board. Return a list of paths if the word can be formed, otherwise an empty list.\n", - "\n", - "\n", - "2. **Reverse Word Search:**\n", - " Modify the code to search for words in reverse order on the board. Given a 2D grid of characters and a list of words, find all words from the list that can be formed by traversing the board in reverse (right to left, bottom to top, etc.)." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/08. Tries/README.md b/docs/08. Tries/README.md deleted file mode 100644 index 22c3bcd..0000000 --- a/docs/08. Tries/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# Trie Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [208. Implement Trie Prefix Tree](https://leetcode.com/problems/implement-trie-prefix-tree/) | Medium | -| [211. Design Add And Search Words Data Structure](https://leetcode.com/problems/design-add-and-search-words-data-structure/) | Medium | -| [212. Word Search II](https://leetcode.com/problems/word-search-ii/) | Hard | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! diff --git a/docs/09. Heap - Priority Queue/1046. Last Stone Weight.ipynb b/docs/09. Heap - Priority Queue/1046. Last Stone Weight.ipynb deleted file mode 100644 index cb66b6a..0000000 --- a/docs/09. Heap - Priority Queue/1046. Last Stone Weight.ipynb +++ /dev/null @@ -1,254 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 1046. Last Stone Weight\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Last Stone Weight problem on LeetCode, click here!](https://leetcode.com/problems/last-stone-weight/)\n", - "\n", - "---\n", - "You are given an array of integers `stones` where `stones[i]` is the weight of the `i`th stone.\n", - "\n", - "We are playing a game with the stones. On each turn, you choose the **heaviest two stones** and smash them together. Suppose the heaviest two stones have weights `x` and `y` with `x <= y`. The result of this smash is:\n", - "\n", - "1. If `x == y`, both stones are destroyed.\n", - "2. If `x != y`, the stone of weight `x` is destroyed, and the stone of weight `y` has new weight `y - x`.\n", - "\n", - "At the end of the game, there is **at most one** stone left.\n", - "\n", - "Return *the weight of the last remaining stone*. If there are no stones left, return `0`.\n", - "\n", - "**Constraints:**\n", - "- `1 <= stones.length <= 30`\n", - "- `1 <= stones[i] <= 1000`" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The \"Last Stone Weight\" problem involves a game played with a collection of stones, each stone having a certain weight. The goal is to find the weight of the last remaining stone after applying a specific set of rules.\n", - "\n", - "Here's how the game works:\n", - "\n", - "1. You start with an array of stones, where each stone is represented by its weight. The weights of the stones are given in the input as an array.\n", - "\n", - "2. In each turn of the game, you select the two heaviest stones from the remaining stones. If there is only one stone left, you've found the answer.\n", - "\n", - "3. If there are two stones with weights `x` and `y`, where `x` is less than or equal to `y`, the following happens:\n", - " - If `x` is equal to `y`, both stones are completely destroyed, and they are removed from the array of stones.\n", - " - If `x` is not equal to `y`, the stone with weight `x` is destroyed, and the stone with weight `y` now has a new weight of `y - x`. The stone with weight `x` is removed from the array, and the modified stone with weight `y - x` remains in the array.\n", - "\n", - "4. The game continues with the modified array of stones until there is at most one stone left.\n", - "\n", - "5. The goal is to find the weight of the last remaining stone, or if there are no stones left, return `0`.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "import heapq\n", - "\n", - "def lastStoneWeight(stones):\n", - " # Convert the input list to a max heap (negate the values to simulate a max heap)\n", - " max_heap = [-stone for stone in stones]\n", - " heapq.heapify(max_heap)\n", - "\n", - " # Continue as long as there are more than 1 stone in the heap\n", - " while len(max_heap) > 1:\n", - " # Get the two heaviest stones\n", - " y = -heapq.heappop(max_heap) # Get the heaviest stone and negate it back to positive\n", - " x = -heapq.heappop(max_heap) # Get the second heaviest stone and negate it back to positive\n", - "\n", - " # Calculate the new stone's weight after smashing\n", - " if x != y:\n", - " new_stone = y - x\n", - " heapq.heappush(max_heap, -new_stone) # Negate the value and push it back to the heap\n", - "\n", - " # If there is one stone left, return its weight (negate it back to positive)\n", - " if max_heap:\n", - " return -max_heap[0]\n", - " else:\n", - " return 0" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The code defines a Python function called `lastStoneWeight` that takes a list of stone weights as input. It aims to find the weight of the last remaining stone after playing the stone smashing game described in the problem statement.\n", - "\n", - "Here's a step-by-step explanation of the code:\n", - "\n", - "1. We import the `heapq` library, which allows us to create and manipulate a heap (priority queue).\n", - "\n", - "2. Inside the `lastStoneWeight` function:\n", - " - We create a max heap (negating stone weights to simulate a max heap) using the `heapq.heapify` function. This heap will keep track of the heaviest stones.\n", - " \n", - " - We enter a loop that continues as long as there are more than 1 stone in the heap.\n", - " \n", - " - Inside the loop, we:\n", - " - Retrieve and negate the heaviest stone (`y`) from the heap.\n", - " - Retrieve and negate the second heaviest stone (`x`) from the heap.\n", - " \n", - " - Calculate the new stone's weight after smashing (`y - x`), and negate it back to simulate a max heap.\n", - " - Add the new stone back to the heap using `heapq.heappush`.\n", - " \n", - "3. After the loop, if there is one stone left in the heap, we retrieve and negate it to get its actual weight, and return it as the result.\n", - " \n", - "4. If there are no stones left (the heap is empty), we return `0`, indicating that no stones remain.\n", - "\n", - "5. Finally, we provide two test cases to demonstrate the function's usage and correctness.\n", - "\n", - "In summary, the code efficiently implements the stone smashing game by maintaining a max heap, selecting the heaviest stones in each turn, smashing them, and updating the heap until there is at most one stone left. It then returns the weight of the last remaining stone or 0 if there are no stones left." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "stones1 = [2, 7, 4, 1, 8, 1]\n", - "print(lastStoneWeight(stones1)) # Output: 1" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "b7e79514-4821-48d0-bb9d-0f2de8150945", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n" - ] - } - ], - "source": [ - "# Example 2: \n", - "\n", - "stones2 = [1]\n", - "print(lastStoneWeight(stones2)) # Output: 1" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided Python code for the \"Last Stone Weight\" problem:\n", - "\n", - "**Time Complexity:**\n", - "1. The `heapq.heapify` operation to create the max heap from the input stone weights has a time complexity of O(n), where n is the number of stones.\n", - "\n", - "2. The loop that continues until there are more than 1 stone in the heap performs the following operations in each iteration:\n", - " - Retrieving and negating the heaviest stone (`y`) from the heap, which takes O(log n) time.\n", - " - Retrieving and negating the second heaviest stone (`x`) from the heap, also taking O(log n) time.\n", - " - Calculating the new stone's weight and pushing it back into the heap using `heapq.heappush`, which takes O(log n) time.\n", - "\n", - "3. In the worst case, the loop runs until there is only one stone left, which requires approximately (n-1) iterations.\n", - "\n", - "Overall, the dominant time complexity is O(n) for the initial heap creation, and within the loop, each iteration takes O(log n) time. Therefore, the overall time complexity of the algorithm is O(n log n).\n", - "\n", - "**Space Complexity:**\n", - "1. The space complexity is primarily determined by the space required for the max heap. In the worst case, this heap can contain all the stones, so the space complexity for the heap is O(n).\n", - "\n", - "2. The rest of the variables used in the function (e.g., `x`, `y`, `new_stone`) require only constant space, so they do not significantly contribute to the space complexity.\n", - "\n", - "Therefore, the overall space complexity of the algorithm is O(n) due to the space used for the max heap.\n", - "\n", - "In summary:\n", - "- Time Complexity: $O(n\\ log\\ n)$\n", - "- Space Complexity: $O(n)$\n", - "\n", - "The algorithm is efficient enough to handle the problem's constraints, as the worst-case time and space complexities are both linearithmic in terms of the number of stones." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Kth Last Stone Weight**: Modify the problem to find the weight of the Kth last remaining stone, where K is an integer input. Your function should work efficiently for large values of K.\n", - "\n", - "\n", - "2. **Multiple Stones Smash**: Modify the problem so that instead of smashing two stones at a time, you can smash up to K stones at each turn, where K is an integer input. Determine the weight of the last remaining stone in this variation." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/09. Heap - Priority Queue/295. Find Median from Data Stream.ipynb b/docs/09. Heap - Priority Queue/295. Find Median from Data Stream.ipynb deleted file mode 100644 index 847dd60..0000000 --- a/docs/09. Heap - Priority Queue/295. Find Median from Data Stream.ipynb +++ /dev/null @@ -1,242 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 295. Find Median from Data Stream\n", - "\n", - "**Difficulty:** Hard\n", - "\n", - "**Link to Problem:** [To see the Find Median from Data Stream problem on LeetCode, click here!](https://leetcode.com/problems/find-median-from-data-stream/)\n", - "\n", - "---\n", - "\n", - "The **median** is the middle value in an ordered integer list. If the size of the list is even, there is no middle value, and the median is the mean of the two middle values.\n", - "\n", - "Implement the MedianFinder class:\n", - "\n", - "- `MedianFinder()` initializes the `MedianFinder` object.\n", - "- `void addNum(int num)` adds the integer `num` from the data stream to the data structure.\n", - "- `double findMedian()` returns the median of all elements so far. Answers within $10^{-5}$ of the actual answer will be accepted.\n", - "\n", - "**Constraints:**\n", - "\n", - "- $-10^{5}$ <= `num` <= $10^{5}$\n", - "- There will be at least one element in the data structure before calling `findMedian`.\n", - "- At most $5 * 10^4$ calls will be made to `addNum` and `findMedian`.\n", - "\n", - "**Follow-up:**\n", - "\n", - "1. If all integer numbers from the stream are in the range `[0, 100]`, how would you optimize your solution?\n", - "2. If `99%` of all integer numbers from the stream are in the range `[0, 100]`, how would you optimize your solution?" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem, \"Find Median from Data Stream,\" deals with efficiently computing the median of a sequence of numbers as they are incrementally provided. The median is the middle value in an ordered list of numbers. When the list has an even number of elements, the median is the average of the two middle values.\n", - "\n", - "Here's a breakdown of the problem:\n", - "\n", - "1. **Initialization**: You are asked to implement a `MedianFinder` class that supports the following operations:\n", - "\n", - " - `MedianFinder()`: Initializes the MedianFinder object.\n", - " - `addNum(int num)`: Adds an integer `num` from the data stream to the data structure.\n", - " - `findMedian()`: Returns the median of all elements added to the data structure.\n", - "\n", - "2. **Median Calculation**: The `findMedian` operation should efficiently compute the median, and the result should have a precision of at least $10^{-5}$ (i.e., answers within this range will be considered correct).\n", - "\n", - "3. **Examples**:\n", - " \n", - " - If you add numbers [1, 2], the median should be 1.5 because (1 + 2) / 2 = 1.5.\n", - " - If you add numbers [1, 2, 3], the median should be 2 because it's the middle value.\n", - " \n", - "4. **Constraints**:\n", - "\n", - " - The integers provided in the data stream are in the range from $-10^5$ to $10^5$.\n", - " - There will be at least one element in the data structure before calling `findMedian`.\n", - " - At most, $5 * 10^4$ calls will be made to `addNum` and `findMedian`.\n", - "\n", - "The problem can be solved by using two priority queues (heaps): one max-heap to store the smaller half of the numbers and one min-heap to store the larger half of the numbers. The max-heap ensures that the largest number in the smaller half is at the top, and the min-heap ensures that the smallest number in the larger half is at the top. These heaps are balanced to efficiently find the median when requested.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "import heapq\n", - "\n", - "class MedianFinder:\n", - "\n", - " def __init__(self):\n", - " # Initialize two heaps: a max-heap (small_half) for the smaller half of numbers,\n", - " # and a min-heap (large_half) for the larger half of numbers.\n", - " self.small_half = [] # Max-heap for the smaller half of the numbers\n", - " self.large_half = [] # Min-heap for the larger half of the numbers\n", - "\n", - " def addNum(self, num: int) -> None:\n", - " # Add the number to the appropriate heap based on its value\n", - " if not self.small_half or num <= -self.small_half[0]:\n", - " # If the number is less than or equal to the current maximum in the smaller half,\n", - " # add it to the smaller half (max-heap)\n", - " heapq.heappush(self.small_half, -num)\n", - " else:\n", - " # Otherwise, add it to the larger half (min-heap)\n", - " heapq.heappush(self.large_half, num)\n", - "\n", - " # Balance the heaps if necessary to ensure the size difference is at most 1\n", - " if len(self.small_half) > len(self.large_half) + 1:\n", - " # If the size of the smaller half is more than one greater than the size of the larger half,\n", - " # move the maximum from the smaller half to the larger half to balance them.\n", - " heapq.heappush(self.large_half, -heapq.heappop(self.small_half))\n", - " elif len(self.large_half) > len(self.small_half):\n", - " # If the size of the larger half is greater than the size of the smaller half,\n", - " # move the minimum from the larger half to the smaller half to balance them.\n", - " heapq.heappush(self.small_half, -heapq.heappop(self.large_half))\n", - "\n", - " def findMedian(self) -> float:\n", - " if len(self.small_half) == len(self.large_half):\n", - " # If both halves have the same size, there's an even number of elements,\n", - " # so the median is the average of the top elements in both heaps.\n", - " return (-self.small_half[0] + self.large_half[0]) / 2.0\n", - " else:\n", - " # If the smaller half has more elements, it contains the median (odd number of elements).\n", - " return -self.small_half[0]" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The code defines a `MedianFinder` class for efficiently finding the median of a stream of numbers. It uses two heaps: a max-heap (`small_half`) to store the smaller half of the numbers and a min-heap (`large_half`) to store the larger half. Here's how the code works:\n", - "\n", - "1. The `__init__` method initializes the two heaps.\n", - "\n", - "2. The `addNum` method adds a number to the appropriate heap, ensuring that the heaps remain balanced. It does this by comparing the number to the current maximum in the smaller half and adding it to the appropriate heap. Then, it checks the sizes of the two heaps and rebalances them if necessary.\n", - "\n", - "3. The `findMedian` method calculates and returns the median. If both halves have the same size (even number of elements), it computes the average of the tops of both heaps. If the smaller half has more elements (odd number of elements), it returns the top of the max-heap, which is the median.\n", - "\n", - "In summary, this code efficiently maintains two heaps to divide the elements into smaller and larger halves, allowing for quick median retrieval. It offers a time complexity of O(log N) for adding elements and O(1) for finding the median, where N is the total number of elements processed. The space complexity is O(1) as the space used by the two heaps is independent of the input size." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1.5\n", - "2\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "medianFinder = MedianFinder()\n", - "medianFinder.addNum(1)\n", - "medianFinder.addNum(2)\n", - "print(medianFinder.findMedian()) # Output: 1.5\n", - "medianFinder.addNum(3)\n", - "print(medianFinder.findMedian()) # Output: 2.0\n" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `MedianFinder` class:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. `MedianFinder()` Initialization: This operation has a time complexity of O(1). It simply initializes the two heaps.\n", - "\n", - "2. `addNum(int num)`: The time complexity for adding a number is O(log N), where N is the total number of elements processed so far. This is because, in the worst case, you might need to perform logarithmic operations on the heaps to maintain their balance.\n", - "\n", - "3. `findMedian()`: Finding the median has a time complexity of O(1). It simply involves accessing the tops of the two heaps, which takes constant time.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. `MedianFinder()` Initialization: The space complexity for initialization is O(1). It involves creating two empty heaps, which do not depend on the size of the data stream.\n", - "\n", - "2. `addNum(int num)`: The space complexity for adding a number is also O(1). It involves adding the number to one of the two heaps, which do not significantly affect the overall space complexity.\n", - "\n", - "3. `findMedian()`: The space complexity for finding the median is O(1). It doesn't require any additional data structures that grow with the input size.\n", - "\n", - "In summary, the time complexity of the `addNum` operation is O(log N), and the time complexity of the `findMedian` operation is O(1). The space complexity is O(1) as well, as the space used by the two heaps is independent of the size of the data stream. This solution efficiently maintains and retrieves the median, making it suitable for the given problem constraints." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Generalized kth Element**: Extend the `MedianFinder` class to support finding the kth element in the data stream efficiently. This means finding the kth smallest or kth largest element in the stream.\n", - "\n", - "2. **Sliding Window Median**: Given an array and a sliding window size, find the median within the window as it slides over the array. This is an extension of the problem to a moving window scenario." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.ipynb b/docs/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.ipynb deleted file mode 100644 index 2e1522d..0000000 --- a/docs/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.ipynb +++ /dev/null @@ -1,239 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 703. Kth Largest Element in a Stream\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Kth Largest Element in a Stream problem on LeetCode, click here!](https://leetcode.com/problems/kth-largest-element-in-a-stream/)\n", - "\n", - "---\n", - "Design a class to find the `kth` largest element in a stream. Note that it is the `kth` largest element in the sorted order, not the `kth` distinct element.\n", - "\n", - "Implement the `KthLargest` class with the following methods:\n", - "\n", - "- `KthLargest(int k, int[] nums)`: Initializes the object with the integer `k` and the stream of integers `nums`.\n", - "- `int add(int val)`: Appends the integer `val` to the stream and returns the element representing the `kth` largest element in the stream.\n", - "\n", - "\n", - "**Constraints:**\n", - "\n", - "- 1 <= `k` <= $10^4$\n", - "- 0 <= `nums.length` <= $10^4$\n", - "- $-10^4$ <= `nums[i]` <= $10^4$\n", - "- $-10^4$ <= `val` <= $10^4$\n", - "- At most $10^4$ calls will be made to `add`.\n", - "- It is guaranteed that there will be at least `k` elements in the array when you search for the `kth` element." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem you're trying to solve is to design a class called `KthLargest` that can efficiently find the kth largest element in a stream of integers. You need to support two main operations:\n", - "\n", - "To solve this problem efficiently, you can use a min-heap data structure. Here's how the approach works:\n", - "\n", - "1. Initialize a min-heap to store the k largest elements. Initially, it's empty.\n", - "\n", - "2. In the `__init__` method, populate the min-heap with the first `k` elements from `nums`. This ensures that you have the k largest elements seen so far.\n", - "\n", - "3. Whenever you add a new element to the stream using the `add` method, follow these steps:\n", - " - Add the new element to the min-heap.\n", - " - If the size of the min-heap exceeds `k`, remove the smallest element from the min-heap. This ensures that you always have the k largest elements in the min-heap.\n", - " - The smallest element in the min-heap (the root) will always represent the kth largest element in the stream.\n", - "\n", - "Here's why this approach works efficiently:\n", - "\n", - "- By using a min-heap, you can quickly maintain the k largest elements, and finding the smallest element in the heap (the root) takes constant time.\n", - "\n", - "- When you add a new element, the min-heap's size is kept at most `k`, which ensures that you only track the k largest elements and discard the smaller ones.\n", - "\n", - "- The time complexity for adding an element is O(log k), which is very efficient compared to sorting the entire stream, which would be O(n log n).\n", - "\n", - "- This approach meets the constraints of the problem, including handling large streams and having a low time complexity for both initialization and adding elements.\n", - "\n", - "In summary, the min-heap approach efficiently tracks the kth largest element in the stream by maintaining a heap of the k largest elements seen so far, updating it as new elements are added. This approach provides a fast and scalable solution to the problem.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "import heapq\n", - "from typing import List # Import the List type from the typing module\n", - "\n", - "class KthLargest:\n", - "\n", - " def __init__(self, k: int, nums: List[int]):\n", - " # Initialize the KthLargest object with k and nums.\n", - " self.k = k\n", - " # Create a min-heap to store the k largest elements.\n", - " self.min_heap = []\n", - " # Populate the min-heap with the first k elements from nums.\n", - " for num in nums:\n", - " self.add(num)\n", - "\n", - " def add(self, val: int) -> int:\n", - " # Add val to the min-heap.\n", - " heapq.heappush(self.min_heap, val)\n", - " # If the size of the min-heap exceeds k, remove the smallest element.\n", - " if len(self.min_heap) > self.k:\n", - " heapq.heappop(self.min_heap)\n", - " # The root of the min-heap is the kth largest element.\n", - " return self.min_heap[0]" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "- We start by importing the necessary modules:\n", - " - `heapq`: This module provides functions to create and manipulate heaps.\n", - " - `List` from the `typing` module: This is used to specify the type of the `nums` parameter.\n", - "\n", - "- We define the `KthLargest` class:\n", - " - The `__init__` method initializes the object with the integer `k` and the list of integers `nums`.\n", - " - It also creates an empty min-heap called `self.min_heap` to store the k largest elements.\n", - " - It populates the min-heap with the first `k` elements from `nums` by calling the `add` method.\n", - "\n", - "- The `add` method:\n", - " - Adds the new integer `val` to the min-heap using `heapq.heappush`. This maintains the min-heap property.\n", - " - Checks if the size of the min-heap exceeds `k`. If it does, it removes the smallest element (the k+1th largest) using `heapq.heappop`.\n", - " - Finally, it returns the smallest element in the min-heap, which is always the kth largest element.\n", - "\n", - "Overall, this code implements a class that efficiently finds the kth largest element in a stream of integers by maintaining a min-heap of the k largest elements seen so far.\n" - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n", - "5\n", - "5\n", - "8\n", - "8\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "kthLargest = KthLargest(3, [4, 5, 8, 2])\n", - "print(kthLargest.add(3)) # Output: 4\n", - "print(kthLargest.add(5)) # Output: 5\n", - "print(kthLargest.add(10)) # Output: 5\n", - "print(kthLargest.add(9)) # Output: 8\n", - "print(kthLargest.add(4)) # Output: 8" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `KthLargest` class using the min-heap approach:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. `__init__` method:\n", - " - In the `__init__` method, you iterate over the first `k` elements in `nums` and add them to the min-heap. Each `heapq.heappush` operation takes O(log k) time.\n", - " - Therefore, the time complexity of the `__init__` method is O(k * log k).\n", - "\n", - "2. `add` method:\n", - " - In the `add` method, you perform the following operations:\n", - " - `heapq.heappush`: O(log k) to add the new element to the min-heap.\n", - " - If the size of the min-heap exceeds `k`, you perform `heapq.heappop`, which is also O(log k).\n", - " - Finally, you return the smallest element from the min-heap, which is O(1) because it's always the root.\n", - " - Overall, the time complexity of the `add` method is O(log k).\n", - "\n", - "3. Overall, if you make `n` calls to the `add` method, the total time complexity is O(n * log k), where `n` is the total number of elements added to the stream.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. The space complexity is determined by the space used to store the min-heap and the instance variables.\n", - "2. The min-heap stores at most `k` elements at any given time, so its space complexity is O(k).\n", - "3. The instance variables (such as `self.k` and `self.min_heap`) have constant space requirements.\n", - "4. Therefore, the overall space complexity of the `KthLargest` class is O(k).\n", - "\n", - "In summary, the time complexity of the `KthLargest` class is O(n * log k) for `n` add operations, and the space complexity is O(k), where `k` is the parameter passed during initialization. This implementation efficiently maintains the kth largest element in the stream while meeting the problem's constraints." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Dynamic k:** Modify the `KthLargest` class to support dynamic changes in the value of `k`. Implement a method `update_k` that allows changing the value of `k` during the lifetime of the object. Ensure that the object can still correctly find the kth largest element based on the updated value of `k`.\n", - "\n", - "\n", - "2. **Implement kth Smallest:** Create a new class called `KthSmallest` that finds the kth smallest element in a stream instead of the kth largest. You may need to modify the data structure used in the implementation." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/09. Heap - Priority Queue/README.md b/docs/09. Heap - Priority Queue/README.md deleted file mode 100644 index 2eac70c..0000000 --- a/docs/09. Heap - Priority Queue/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# Heap / Priority Queue Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [703. Kth Largest Element in a Stream](https://leetcode.com/problems/kth-largest-element-in-a-stream/) | Easy | -| [1046. Last Stone Weight](https://leetcode.com/problems/last-stone-weight/) | Easy | -| [295. Find Median From Data Stream](https://leetcode.com/problems/find-median-from-data-stream/) | Hard | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! diff --git a/docs/10. Backtracking/39. Combination Sum.ipynb b/docs/10. Backtracking/39. Combination Sum.ipynb deleted file mode 100644 index 228a62e..0000000 --- a/docs/10. Backtracking/39. Combination Sum.ipynb +++ /dev/null @@ -1,282 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 39. Combination Sum\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Combination Sum problem on LeetCode, click here!](https://leetcode.com/problems/combination-sum/)\n", - "\n", - "---\n", - "Given an array of **distinct** integers `candidates` and a target integer `target`, return *a list of all **unique combinations** of `candidates` where the chosen numbers sum to the `target`*. You may return the combinations in **any order**. \n", - "\n", - "The **same** number may be chosen from `candidates` an **unlimited number** of times. Two combinations are unique if the **frequency** of at least one of the chosen numbers is different.\n", - "\n", - "The test cases are generated such that the number of unique combinations that sum up to `target` is less than `150` combinations for the given input.\n", - "\n", - "**Constraints:**\n", - "- `1 <= candidates.length <= 30`\n", - "- `2 <= candidates[i] <= 40`\n", - "- All elements of `candidates` are **distinct**.\n", - "- `1 <= target <= 40`" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is to find all unique combinations of numbers from a given array (candidates) such that their sum equals a target number. Here are the details of the problem:\n", - "\n", - "- You are given an array of distinct integers called \"candidates.\"\n", - "- You are also given a target integer called \"target.\"\n", - "\n", - "The goal is to find all unique combinations of numbers from the candidates array where the sum of the selected numbers is equal to the target. You can use the same number from the candidates array an unlimited number of times. A combination is considered unique if it has a different frequency (i.e., a different number of occurrences) of at least one chosen number compared to other combinations.\n", - "\n", - "For example:\n", - "\n", - "**Example 1:**\n", - "```python\n", - "Input: candidates = [2, 3, 6, 7], target = 7\n", - "Output: [[2, 2, 3], [7]]\n", - "```\n", - "In this example, there are two unique combinations that sum up to the target:\n", - "- 2 + 2 + 3 = 7\n", - "- 7 = 7\n", - "\n", - "**Example 2:**\n", - "```python\n", - "Input: candidates = [2, 3, 5], target = 8\n", - "Output: [[2, 2, 2, 2], [2, 3, 3], [3, 5]]\n", - "```\n", - "Here, there are three unique combinations that sum up to the target.\n", - "\n", - "**Example 3:**\n", - "```python\n", - "Input: candidates = [2], target = 1\n", - "Output: []\n", - "```\n", - "In this case, there are no combinations that can be formed from the candidates to reach the target of 1, so the output is an empty list.\n", - "\n", - "The problem asks you to find and return these combinations in any order.\n", - "\n", - "The constraints for this problem include the length of the candidates array, the values of candidates, and the target value.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def combinationSum(candidates, target):\n", - " # Define a recursive DFS function to find combinations\n", - " def dfs(remaining, start, path):\n", - " # If the remaining target is 0, we found a valid combination\n", - " if remaining == 0:\n", - " result.append(path)\n", - " return\n", - " # If the remaining target is negative, this path is invalid\n", - " if remaining < 0:\n", - " return\n", - " # Iterate through candidates starting from 'start' to avoid duplicates\n", - " for i in range(start, len(candidates)):\n", - " # Explore the current candidate by subtracting it from the remaining target\n", - " # Add the current candidate to the path\n", - " dfs(remaining - candidates[i], i, path + [candidates[i]])\n", - "\n", - " result = [] # Initialize an empty list to store the result\n", - " candidates.sort() # Sort the candidates for deduplication and early stopping\n", - " dfs(target, 0, []) # Start the DFS from the target value with an empty path\n", - " return result # Return the list of unique combinations" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The `combinationSum` function takes an array of distinct integers `candidates` and a target integer `target`. It returns a list of all unique combinations of `candidates` where the chosen numbers sum to the `target`. Each number in the `candidates` array can be used an unlimited number of times.\n", - "\n", - "Here's an overview of how the code works:\n", - "\n", - "1. The `combinationSum` function is defined, and it takes two arguments: `candidates` and `target`.\n", - "\n", - "2. Inside the function, there is a nested helper function called `backtrack`. This function is responsible for the actual combination generation using a recursive approach.\n", - "\n", - "3. The `backtrack` function is called with three arguments: `start`, `target`, and `path`. The `start` variable helps keep track of the current index in the `candidates` array, `target` keeps track of the remaining sum to be achieved, and `path` is a list that stores the current combination.\n", - "\n", - "4. Within the `backtrack` function, there are three main conditional statements:\n", - " - If `target` becomes zero, it means we have found a combination that sums up to the target, so we add `path` to the `result` list.\n", - " - If `target` becomes negative, it means the current combination doesn't work, so we return without doing anything.\n", - " - Otherwise, we enter a loop that iterates over the `candidates` array, starting from the current index `start`.\n", - "\n", - "5. In the loop, the `backtrack` function is called recursively with the updated `target` and `path` after including the current candidate. This process explores different combinations by considering the current candidate or moving to the next candidate.\n", - "\n", - "6. After the loop completes, the `result` list contains all unique combinations that sum to the target.\n", - "\n", - "7. The `candidates` array is sorted to optimize the search. Sorting helps in avoiding unnecessary recursive branches and reduces the number of explored combinations.\n", - "\n", - "8. Finally, the `backtrack` function is initially called from the `combinationSum` function with `start` set to 0, `target` set to the original target value, and an empty `path`. The result is returned as a list of unique combinations.\n", - "\n", - "The code includes a few example cases to demonstrate how the function works with different inputs." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[2, 2, 3], [7]]\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example 1\n", - "candidates1 = [2, 3, 6, 7]\n", - "target1 = 7\n", - "print(combinationSum(candidates1, target1)) # Output: [[2, 2, 3], [7]]" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[2, 2, 2, 2], [2, 3, 3], [3, 5]]\n" - ] - } - ], - "source": [ - "# Example 2\n", - "candidates2 = [2, 3, 5]\n", - "target2 = 8\n", - "print(combinationSum(candidates2, target2)) # Output: [[2, 2, 2, 2], [2, 3, 3], [3, 5]]" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "b5fca8ab-8c98-45b1-b44b-0503309121c9", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[]\n" - ] - } - ], - "source": [ - "# Example 3\n", - "candidates3 = [2]\n", - "target3 = 1\n", - "print(combinationSum(candidates3, target3)) # Output: []" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `combinationSum` function.\n", - "\n", - "**Time Complexity:**\n", - "The time complexity of this function is influenced by the number of recursive calls made by the `backtrack` function and the amount of work done within each call. In the worst case, the function will explore all possible combinations.\n", - "\n", - "The worst-case scenario occurs when we have many combinations to reach the target. The time complexity can be expressed as $O(2^n)$, where 'n' is the maximum number of recursive calls. In this context, 'n' corresponds to the number of elements in the `candidates` list, and it may be up to 30 (as per the constraints). However, the actual number of combinations explored is generally much smaller because we eliminate branches when the target becomes negative, and we skip over candidates that cannot lead to a solution. The sorting step also helps to optimize the search.\n", - "\n", - "**Space Complexity:**\n", - "The space complexity is determined by the auxiliary space used for storing the results and the stack space for the recursive calls.\n", - "\n", - "1. The space required for the `result` list can be up to $O(2^n)$ in the worst case because each combination is stored.\n", - "\n", - "2. The stack space for the recursive calls can also be up to O(n) in the worst case, where 'n' is the number of elements in the `candidates` list.\n", - "\n", - "Therefore, the overall space complexity of the function is $O(2^n + n)$. However, in practice, the space used for the results list is often the dominant factor, and the actual space used may be much smaller than 2^n because not all combinations are explored.\n", - "\n", - "In summary, the time complexity is exponential but typically smaller in practice due to optimization, and the space complexity is influenced by the number of results and the depth of the recursion." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Find the Number of Unique Combinations:** Instead of listing all unique combinations, modify the function to return the count of unique combinations that sum to the target.\n", - "\n", - "2. **Combinations with a Maximum Value:** Add a maximum value constraint for each combination, so they cannot exceed a certain value. Modify the code to find combinations respecting this constraint." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/10. Backtracking/79. Word Search.ipynb b/docs/10. Backtracking/79. Word Search.ipynb deleted file mode 100644 index cee509b..0000000 --- a/docs/10. Backtracking/79. Word Search.ipynb +++ /dev/null @@ -1,298 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 79. Word Search\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Word Search problem on LeetCode, click here!](https://leetcode.com/problems/word-search/)\n", - "\n", - "---\n", - "Given an `m x n` grid of characters `board` and a string `word`, return *`true` if `word` exists in the grid.*\n", - "\n", - "The word can be constructed from letters of sequentially adjacent cells, where adjacent cells are horizontally or vertically neighboring. The same letter cell may not be used more than once.\n", - "\n", - "**Constraints:**\n", - "- `m == board.length`\n", - "- `n = board[i].length`\n", - "- `1 <= m, n <= 6`\n", - "- `1 <= word.length <= 15`\n", - "- `board` and `word` consists of only lowercase and uppercase English letters.\n", - "\n", - "**Follow up:** Could you use search pruning to make your solution faster with a larger `board`?" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is to determine whether a given word can be constructed from characters in an `m x n` grid of characters. The word can be formed by moving sequentially through horizontally or vertically neighboring cells in the grid, and you cannot use the same cell more than once.\n", - "\n", - "Here are the specifics of the problem:\n", - "\n", - "- You are given an `m x n` grid, which is a 2D board of characters.\n", - "- You are also given a string `word` consisting of lowercase and uppercase English letters.\n", - "- Your task is to determine if the word can be found in the grid by moving from one cell to an adjacent cell (horizontally or vertically) and collecting the characters sequentially to form the word.\n", - "- You can't use the same cell more than once when forming the word.\n", - "- If it's possible to form the word in the grid, return `True`; otherwise, return `False`.\n", - "\n", - "For example, consider the following grid and word:\n", - "\n", - "```python\n", - "board = [[\"A\", \"B\", \"C\", \"E\"],\n", - " [\"S\", \"F\", \"C\", \"S\"],\n", - " [\"A\", \"D\", \"E\", \"E\"]] \n", - "word = \"ABCCED\"\n", - "```\n", - "\n", - "In this case, the word \"ABCCED\" can be formed by moving through the cells (0,0) -> (0,1) -> (0,2) -> (1,2) -> (2,2) -> (2,3) in the grid. Therefore, the function should return `True`.\n", - "\n", - "Conversely, if the word is impossible to construct, such as in the case of the word \"ABCB\" for the same grid, where there's no valid path that forms the word, the function should return `False`.\n", - "\n", - "The problem involves searching for a path through the grid that matches the characters in the word while respecting the constraints mentioned. It can be solved using depth-first search (DFS) or backtracking.\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "from typing import List\n", - "\n", - "class Solution:\n", - " def exist(self, board: List[List[str]], word: str) -> bool:\n", - " def dfs(i, j, k):\n", - " # Check if the current position is out of bounds or doesn't match the character in the word.\n", - " if not (0 <= i < len(board)) or not (0 <= j < len(board[0])) or board[i][j] != word[k]:\n", - " return False\n", - " \n", - " # If we have matched all characters in the word, return True.\n", - " if k == len(word) - 1:\n", - " return True\n", - "\n", - " # Temporarily mark the current cell to prevent revisiting.\n", - " tmp, board[i][j] = board[i][j], \"/\"\n", - "\n", - " # Explore adjacent cells by making recursive calls in all four directions.\n", - " found = dfs(i + 1, j, k + 1) or dfs(i - 1, j, k + 1) or dfs(i, j + 1, k + 1) or dfs(i, j - 1, k + 1)\n", - "\n", - " # Restore the original character in the cell.\n", - " board[i][j] = tmp\n", - "\n", - " return found\n", - "\n", - " # Iterate through all cells in the board.\n", - " for i in range(len(board)):\n", - " for j in range(len(board[0])):\n", - " # Check if the 'dfs' function starting from this cell returns True.\n", - " if dfs(i, j, 0):\n", - " return True\n", - "\n", - " # If no match is found after exploring all cells, return False.\n", - " return False" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. Import the necessary module:\n", - " - `from typing import List`: This line imports the `List` type from the `typing` module, which is used to specify the type of the `board` parameter in the method signature.\n", - "\n", - "2. Define the `Solution` class:\n", - " - `class Solution:`: This line defines a class called `Solution` to encapsulate the solution for the word search problem.\n", - "\n", - "3. Define the `exist` method:\n", - " - `def exist(self, board: List[List[str]], word: str) -> bool:`: This method is a member of the `Solution` class and takes two parameters: `board`, which is a 2D list of characters, and `word`, which is a string. It returns a boolean value, indicating whether the word exists in the board.\n", - "\n", - "4. Implement the inner `dfs` function:\n", - " - `def dfs(i, j, k):`: This is a helper function used for depth-first search (DFS). It is called recursively to explore the board and search for the word. It takes three parameters: `i` and `j` representing the current position on the board, and `k` representing the current index in the `word` string.\n", - "\n", - " - Inside `dfs`, it checks if the current position is out of bounds or if the character at the current position on the board does not match the character at the current index in the `word`. If either of these conditions is met, it returns `False`.\n", - "\n", - " - If `k` is equal to the length of the `word` minus one, it means we have successfully matched all characters in the `word`, so it returns `True`.\n", - "\n", - " - The function then temporarily replaces the character at the current position with a marker, \"/\", to prevent revisiting the same cell. It then explores adjacent cells by making recursive calls in all four directions: up, down, left, and right. If any of these recursive calls return `True`, it propagates the `True` result up the call stack. After the exploration is complete, it restores the original character in the cell.\n", - "\n", - "5. Iterate through the board:\n", - " - The outer loop iterates through all cells in the `board` using two nested loops. For each cell, it checks if the `dfs` function starting from that cell (with `k` initially set to 0) returns `True`. If it does, it means the word exists, so the method returns `True`.\n", - "\n", - "6. Return `False`:\n", - " - If the loop completes without finding the word in the board, the method returns `False`.\n", - "\n", - "To use this code, you can create an instance of the `Solution` class and call the `exist` method on that instance, passing the `board` and the `word` as arguments to check if the word exists in the board." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Create an instance of the Solution class\n", - "solution = Solution()\n", - "\n", - "# Test case 1: Word \"ABCCED\" can be found in the grid\n", - "board1 = [[\"A\",\"B\",\"C\",\"E\"],\n", - " [\"S\",\"F\",\"C\",\"S\"],\n", - " [\"A\",\"D\",\"E\",\"E\"]]\n", - "word1 = \"ABCCED\"\n", - "print(solution.exist(board1, word1)) # Expected output: True" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 2\n", - "\n", - "# Test case 2: Word \"SEE\" can be found in the grid\n", - "word2 = \"SEE\"\n", - "print(solution.exist(board1, word2)) # Expected output: True" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "b5fca8ab-8c98-45b1-b44b-0503309121c9", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 3\n", - "\n", - "# Test case 3: Word \"ABCB\" cannot be found in the grid\n", - "word3 = \"ABCB\"\n", - "print(solution.exist(board1, word3)) # Expected output: False" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `exist` method in the given code.\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The primary work in this code is done by the `dfs` function, which performs a depth-first search through the grid. The time complexity of the `dfs` function is $O(4^(n))$, where \"n\" is the length of the `word`. This is because, in the worst case, the function explores all possible directions (up, down, left, right) for each character in the `word`.\n", - "\n", - "The outer loops iterate through all cells in the `board`, which has dimensions `m x n`. So, the total number of iterations of `dfs` is O(m * n). However, since the `dfs` function has a higher time complexity, the overall time complexity is still dominated by the `dfs` function.\n", - "\n", - "Therefore, the overall time complexity of the `exist` method is $O(m * n * 4^n)$, where \"m\" and \"n\" are the dimensions of the board, and \"n\" is the length of the word.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. The primary space usage comes from the recursive calls in the `dfs` function. The depth of the recursion can be at most equal to the length of the `word`, which is O(n).\n", - "\n", - "2. Additionally, the `tmp` variable and the recursive calls on the call stack consume a small amount of additional memory.\n", - "\n", - "3. The marking of visited cells with the \"/\" character temporarily modifies the `board` in-place but doesn't significantly contribute to the space complexity.\n", - "\n", - "Therefore, the overall space complexity is O(n) due to the recursive call stack.\n", - "\n", - "In summary, the time complexity is $O(m * n * 4^n)$, and the space complexity is O(n), where \"m\" and \"n\" are the dimensions of the board, and \"n\" is the length of the word. The time complexity is exponential in the worst case due to the depth-first search through all possible paths in the grid." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Optimization Challenge:** Modify the code to find all unique words that can be constructed from the grid. Instead of returning `True` or `False`, return a list of words found. Ensure that the same cell is not used more than once in constructing each word.\n", - "\n", - "2. **Board Generation:** Create a function to generate random grids of characters and then use the `exist` method to solve them. Test the efficiency and correctness of your code by generating larger boards and words." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/10. Backtracking/README.md b/docs/10. Backtracking/README.md deleted file mode 100644 index 0d1ea13..0000000 --- a/docs/10. Backtracking/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Backtracking Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [39. Combination Sum](https://leetcode.com/problems/combination-sum/) | Medium | -| [79. Word Search](https://leetcode.com/problems/word-search/) | Medium | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! \ No newline at end of file diff --git a/docs/11. Graphs/133. Clone Graph.ipynb b/docs/11. Graphs/133. Clone Graph.ipynb deleted file mode 100644 index 07351b6..0000000 --- a/docs/11. Graphs/133. Clone Graph.ipynb +++ /dev/null @@ -1,317 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 133. Clone Graph\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Clone Graph problem on LeetCode, click here!](https://leetcode.com/problems/clone-graph/)\n", - "\n", - "---\n", - "Given a reference of a node in a **connected** undirected graph.\n", - "\n", - "Return a **deep copy** (clone) of the graph.\n", - "\n", - "Each node in the graph contains a value (`int`) and a list (`List[Node]`) of its neighbors.\n", - "\n", - "```\n", - "class Node {\n", - " public int val;\n", - " public List neighbors;\n", - "}\n", - "```\n", - "\n", - "**Test case format:**\n", - "\n", - "For simplicity, each node's value is the same as the node's index (1-indexed). For example, the first node with `val == 1`, the second node with `val == 2`, and so on. The graph is represented in the test case using an adjacency list.\n", - "\n", - "**An adjacency list** is a collection of unordered **lists** used to represent a finite graph. Each list describes the set of neighbors of a node in the graph.\n", - "\n", - "The given node will always be the first node with `val = 1`. You must return the **copy of the given node** as a reference to the cloned graph.\n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the graph is in the range `[0, 100]`.\n", - "- `1 <= Node.val <= 100`\n", - "- `Node.val` is unique for each node.\n", - "- There are no repeated edges and no self-loops in the graph.\n", - "- The Graph is connected and all nodes can be visited starting from the given node." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem at hand is to clone a connected undirected graph, which means we need to create a deep copy of the original graph while preserving its structure and relationships between nodes. The graph is represented using adjacency lists, where each node has a value (an integer) and a list of its neighbors.\n", - "\n", - "Here are the key aspects of the problem:\n", - "\n", - "1. **Input**: You are given a reference to one of the nodes in the original graph. This reference node serves as the entry point to the graph. The entire graph can be explored starting from this node.\n", - "\n", - "2. **Output**: The goal is to create a deep copy of the graph and return a reference to the cloned graph. The cloned graph should have the same structure and relationships as the original one but should be a separate instance in memory.\n", - "\n", - "3. **Graph Structure**: The graph is composed of nodes (vertices) and edges. Nodes have values (integers) and are connected to other nodes through edges (undirected connections). Each node has a list of neighbors, which are other nodes it is connected to.\n", - "\n", - "4. **Connected Graph**: The problem assumes that the graph is connected, meaning that you can start from the reference node provided and traverse the entire graph by following the edges. This ensures that there are no isolated components in the graph.\n", - "\n", - "To solve this problem, you typically need to perform a graph traversal (e.g., depth-first search or breadth-first search) to visit all the nodes in the original graph, create corresponding nodes in the clone, and establish the same connections between nodes in the cloned graph as in the original one. To avoid duplication of nodes, you also need to keep track of visited nodes to ensure that the cloning process is efficient and that nodes are not duplicated in the clone.\n", - "\n", - "The problem can be challenging because you need to create a deep copy of the graph while handling cyclic dependencies between nodes and ensuring that the structure and relationships of the original graph are preserved in the clone. The solution requires recursion or a data structure to maintain the mapping between original nodes and their clones to achieve an efficient and accurate cloning process.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for a Node.\n", - "class Node:\n", - " def __init__(self, val=0, neighbors=None):\n", - " self.val = val\n", - " self.neighbors = neighbors if neighbors is not None else []\n", - "\n", - "class Solution:\n", - " def cloneGraph(self, node: 'Node') -> 'Node':\n", - " if not node:\n", - " return None\n", - "\n", - " visited = {} # Dictionary to keep track of visited nodes\n", - "\n", - " def dfs(original_node):\n", - " if original_node in visited:\n", - " return visited[original_node]\n", - "\n", - " # Create a copy of the original node\n", - " copy_node = Node(original_node.val)\n", - " visited[original_node] = copy_node\n", - "\n", - " # Recursively clone the neighbors of the original node\n", - " for neighbor in original_node.neighbors:\n", - " copy_node.neighbors.append(dfs(neighbor))\n", - "\n", - " return copy_node\n", - "\n", - " return dfs(node)" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The given code defines a Python class, `Node`, and a solution class, `Solution`, to clone a connected undirected graph represented by nodes and their neighbors. Here's an explanation of the code:\n", - "\n", - "1. The `Node` class defines a node in the graph. Each node has a value (`val`) which is an integer and a list of neighbors (`neighbors`) that are other nodes in the graph.\n", - "\n", - "2. The `Solution` class contains the method `cloneGraph`, which takes a reference to the first node of the graph (`node`) as input and returns a deep copy of the entire graph, preserving the structure and relationships between nodes.\n", - "\n", - "3. Inside the `cloneGraph` method:\n", - " - It first checks if the input `node` is `None`. If it's `None`, it means there is no graph to clone, and the method returns `None`.\n", - "\n", - " - It initializes a `visited` dictionary to keep track of visited nodes. This dictionary is used to ensure that each node is cloned only once to avoid duplication.\n", - "\n", - " - The `dfs` (depth-first search) function is defined within the `cloneGraph` method. It takes an original node as input and returns its corresponding clone. This function performs the actual cloning of the graph.\n", - "\n", - " - Inside the `dfs` function:\n", - " - It checks if the original node has been visited before by looking it up in the `visited` dictionary. If it has been visited, it returns the corresponding clone from the `visited` dictionary.\n", - "\n", - " - If the original node is not visited, it creates a new node, `copy_node`, with the same value as the original node. This is the first step in creating the clone of the original node.\n", - "\n", - " - It then recursively clones the neighbors of the original node by iterating through the `neighbors` list of the original node and appending the corresponding cloned neighbors to the `neighbors` list of the `copy_node`. This step ensures that the relationships between nodes are preserved in the clone.\n", - "\n", - " - The `copy_node` is added to the `visited` dictionary with the original node as the key and the clone as the value.\n", - "\n", - " - Finally, the `copy_node` is returned as the result of the DFS for the original node.\n", - "\n", - "4. The `cloneGraph` method returns the result of the DFS on the input `node`, which is the clone of the entire graph with its structure and relationships intact.\n", - "\n", - "In summary, the code uses depth-first search (DFS) to traverse the original graph, creating a clone for each node and its neighbors. It ensures that each node is cloned only once to avoid duplication and returns a reference to the cloned graph." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "f12c5a63-b811-4be7-83c2-34ee396b546c", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[1, 2, 4]]\n" - ] - } - ], - "source": [ - "def get_adjacency_list(node):\n", - " visited = {} # Dictionary to keep track of visited nodes\n", - "\n", - " def dfs(node):\n", - " if not node:\n", - " return []\n", - "\n", - " if node in visited:\n", - " return visited[node]\n", - "\n", - " neighbors = [n.val for n in node.neighbors]\n", - " visited[node] = neighbors\n", - "\n", - " for neighbor in node.neighbors:\n", - " dfs(neighbor)\n", - "\n", - " dfs(node)\n", - " result = []\n", - "\n", - " def get_node_and_neighbors(node):\n", - " result.append([node.val] + visited[node])\n", - "\n", - " get_node_and_neighbors(node)\n", - " return result\n", - "\n", - "\n", - "# Testing the code with the provided examples\n", - "adjList1 = [[2, 4], [1, 3], [2, 4], [1, 3]]\n", - "solution = Solution()\n", - "\n", - "# Create the graph from adjList\n", - "nodes = [Node(i) for i in range(1, len(adjList1) + 1)]\n", - "for i, adj in enumerate(adjList1):\n", - " nodes[i].neighbors = [nodes[j - 1] for j in adj]\n", - "\n", - "# Clone the graph and get its adjacency list\n", - "cloned_node1 = solution.cloneGraph(nodes[0])\n", - "cloned_adjList1 = get_adjacency_list(cloned_node1)\n", - "\n", - "# Print the cloned graph as an adjacency list\n", - "print(cloned_adjList1)\n", - "\n", - "# Output should match adjList1\n" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[1]]\n" - ] - } - ], - "source": [ - "# Example 2\n", - "# Input: adjList = [[]]\n", - "\n", - "adjList2 = [[]]\n", - "solution = Solution()\n", - "\n", - "# Create the graph from adjList\n", - "node1 = Node(1)\n", - "\n", - "# Clone the graph and get its adjacency list\n", - "cloned_node1 = solution.cloneGraph(node1)\n", - "cloned_adjList2 = get_adjacency_list(cloned_node1)\n", - "\n", - "# Print the cloned graph as an adjacency list\n", - "print(cloned_adjList2)\n", - "\n", - "# Output should be [[]], which represents an empty graph" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code for cloning a graph using depth-first search (DFS).\n", - "\n", - "Time Complexity:\n", - "1. Creating the graph: The time complexity to create the original graph from `adjList` is O(V + E), where V is the number of vertices (nodes) and E is the number of edges. We iterate through each node and its neighbors in `adjList`.\n", - "\n", - "2. Cloning the graph (DFS): The depth-first search (DFS) is used to traverse the original graph and create a clone. The time complexity of DFS is O(V + E), as we visit each node and each edge once.\n", - "\n", - "Overall, the time complexity is O(V + E) for both creating the original graph and cloning it.\n", - "\n", - "Space Complexity:\n", - "1. Storage for the original graph: We need to store the original graph, which includes all nodes and their adjacency lists. In the worst case, this requires O(V + E) space, where V is the number of nodes, and E is the number of edges.\n", - "\n", - "2. Storage for the visited dictionary: The `visited` dictionary stores mappings from original nodes to their corresponding clones. In the worst case, this requires O(V) space because each node is visited once.\n", - "\n", - "3. Recursive stack for DFS: The space used for the recursive call stack during DFS can be up to O(V) in the worst case, where V is the number of nodes.\n", - "\n", - "Overall, the space complexity is O(V + E) for storing the original graph, and O(V) for auxiliary data structures, including the `visited` dictionary and the DFS call stack. Therefore, the overall space complexity is O(V + E).\n", - "\n", - "In summary, the time and space complexities of the provided code for cloning a graph are both O(V + E), where V is the number of nodes, and E is the number of edges in the graph." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Cyclic Graph**: Design a graph with cycles (nodes connected in a cycle). Test if the code can correctly clone graphs with cycles and doesn't fall into an infinite loop during traversal.\n", - "\n", - "\n", - "2. **Partial Graph Cloning**: Modify the code to clone only a subset of the graph starting from a given reference node, rather than the entire graph. Implement this as an extension to the problem." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/11. Graphs/178. Graph Valid Tree.ipynb b/docs/11. Graphs/178. Graph Valid Tree.ipynb deleted file mode 100644 index e0235d6..0000000 --- a/docs/11. Graphs/178. Graph Valid Tree.ipynb +++ /dev/null @@ -1,248 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 178. Graph Valid Tree\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Graph Valid Tree problem on LintCode, click here!](https://www.lintcode.com/problem/178/)\n", - "\n", - "---\n", - "Given `n` nodes labeled from `0` to `n - 1` and a list of `undirected` edges (each edge is a pair of nodes), write a function to check whether these edges make up a valid tree.\n", - "\n", - "**Constraints:**\n", - "- You can assume that no duplicate edges will appear in edges. Since all edges are `undirected`, `[0, 1]` is the same as `[1, 0]` and thus will not appear together in edges." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is to determine whether a given set of undirected edges can form a valid tree. In this context, a \"tree\" is a specific type of graph with the following properties:\n", - "\n", - "1. It is a connected graph, meaning there is a path between any pair of nodes in the graph.\n", - "2. It has no cycles, which means there are no closed loops or circuits in the graph.\n", - "3. It has exactly `n - 1` edges, where `n` is the number of nodes in the tree.\n", - "\n", - "The problem is typically given with two pieces of information:\n", - "\n", - "1. The number of nodes (`n`), which are usually labeled from 0 to `n-1`.\n", - "2. A list of undirected edges, where each edge is represented as a pair of nodes.\n", - "\n", - "The task is to write a function or algorithm to determine whether the provided set of edges can be arranged to form a valid tree based on the properties mentioned above.\n", - "\n", - "To solve this problem, you need to check the following conditions:\n", - "\n", - "1. There should be exactly `n - 1` edges to ensure that the graph is connected and tree-like.\n", - "2. There should be no cycles in the graph. If there are any cycles, the set of edges cannot form a tree.\n", - "3. The graph should be connected, which means you can reach any node from any other node through a series of edges.\n", - "\n", - "The solution typically involves using graph traversal algorithms like Depth-First Search (DFS) or Breadth-First Search (BFS) to explore the graph and check these conditions. If all conditions are met, the given edges form a valid tree; otherwise, they do not.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def validTree(n, edges):\n", - " if len(edges) != n - 1:\n", - " return False # A tree with n nodes must have n-1 edges.\n", - "\n", - " # Create an adjacency list to represent the graph.\n", - " adj_list = {i: [] for i in range(n)}\n", - " for u, v in edges:\n", - " adj_list[u].append(v)\n", - " adj_list[v].append(u)\n", - "\n", - " visited = set()\n", - "\n", - " # Define a recursive DFS function.\n", - " def dfs(node, parent):\n", - " if node in visited:\n", - " return False # If we encounter a visited node, there's a cycle.\n", - " visited.add(node)\n", - "\n", - " for neighbor in adj_list[node]:\n", - " if neighbor != parent:\n", - " if not dfs(neighbor, node):\n", - " return False\n", - "\n", - " return True\n", - "\n", - " # Start DFS from any node (e.g., node 0).\n", - " if not dfs(0, -1):\n", - " return False # If there's a cycle, it's not a valid tree.\n", - "\n", - " return len(visited) == n" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The `validTree` function checks if a given set of undirected edges forms a valid tree. A valid tree must satisfy these conditions:\n", - "\n", - "1. It has exactly `n - 1` edges, where `n` is the number of nodes.\n", - "2. There are no cycles in the graph.\n", - "3. The graph is connected, meaning all nodes are reachable from any starting node.\n", - "\n", - "The code accomplishes this as follows:\n", - "\n", - "- It first checks if the number of edges is equal to `n - 1`. If not, it immediately returns `False` since a tree with `n` nodes must have `n - 1` edges to be connected.\n", - "\n", - "- It then constructs an adjacency list (`adj_list`) to represent the graph efficiently. This data structure stores the neighbors of each node.\n", - "\n", - "- The code uses a `visited` set to keep track of nodes visited during depth-first search (DFS).\n", - "\n", - "- The `dfs` function is a recursive function that checks for cycles in the graph. It does this by visiting nodes and marking them as visited. If it encounters a node that has already been visited (indicating a cycle), it returns `False`.\n", - "\n", - "- The DFS function explores the neighbors of each node, avoiding revisiting the parent node to prevent cycles.\n", - "\n", - "- After the DFS is complete, the code checks if the number of visited nodes is equal to `n`, ensuring the graph is connected.\n", - "\n", - "- Finally, if all conditions are met, the code returns `True`, indicating that the given edges form a valid tree. Otherwise, it returns `False`.\n", - "\n", - "The code provides examples to demonstrate how to use the `validTree` function to check whether a set of edges forms a valid tree or not." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1\n", - "n1 = 5\n", - "edges1 = [[0, 1], [0, 2], [0, 3], [1, 4]]\n", - "print(validTree(n1, edges1)) # Output: true" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 2\n", - "n2 = 5\n", - "edges2 = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]]\n", - "print(validTree(n2, edges2)) # Output: false" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexities of the `validTree` function:\n", - "\n", - "**Time Complexity:**\n", - "1. Constructing the adjacency list (`adj_list`) takes O(E) time, where E is the number of edges in the input graph (|edges|).\n", - "\n", - "2. The DFS function, when considering all nodes, has a time complexity of O(V + E), where V is the number of nodes in the graph. This is because, in the worst case, the DFS function visits each node and each edge once.\n", - "\n", - "3. Checking if the number of visited nodes is equal to `n` takes O(1) time.\n", - "\n", - "Overall, the time complexity of the `validTree` function is O(E + V) in the worst case.\n", - "\n", - "**Space Complexity:**\n", - "1. The adjacency list (`adj_list`) consumes additional space to store the graph structure, taking O(V + E) space. This is because it stores information about each node and its adjacent nodes.\n", - "\n", - "2. The `visited` set keeps track of visited nodes, and its space complexity is O(V) in the worst case, as there can be at most V unique nodes in the set.\n", - "\n", - "3. The depth of the function call stack during DFS can be at most V, which contributes O(V) space to the space complexity.\n", - "\n", - "Overall, the space complexity of the `validTree` function is O(V + E) due to the adjacency list and O(V) due to the `visited` set and DFS call stack.\n", - "\n", - "In summary, the time complexity is O(E + V), and the space complexity is O(V + E). These complexities are based on the worst-case scenario, where all nodes and edges are considered. In practical cases, the actual complexities may be smaller, depending on the specific structure of the graph." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Minimum Spanning Tree (MST)**: Implement an algorithm to find the minimum spanning tree of a connected graph using either Kruskal's or Prim's algorithm. Compare the MST to the original graph to determine if the original graph is a tree. This exercise reinforces the concept of tree properties.\n", - "\n", - "2. **Detecting Cycles**: Modify the code to not only check if the input forms a tree but also to identify and print out any cycles present in the graph if it's not a tree. This exercise enhances your ability to detect and visualize cycles in a graph." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/11. Graphs/200. Number of Islands.ipynb b/docs/11. Graphs/200. Number of Islands.ipynb deleted file mode 100644 index a8a7727..0000000 --- a/docs/11. Graphs/200. Number of Islands.ipynb +++ /dev/null @@ -1,242 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 200. Number of Islands\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Number of Islands problem on LeetCode, click here!](https://leetcode.com/problems/number-of-islands/)\n", - "\n", - "---\n", - "\n", - "Given an `m x n` 2D binary grid `grid` which represents a map of `'1'`s (land) and `'0'`s (water), return *the number of islands*. \n", - "\n", - "An **island** is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.\n", - "\n", - "**Constraints:**\n", - "- `m == grid.length`\n", - "- `n == grid[i].length`\n", - "- `1 <= m, n <= 300`\n", - "- `grid[i][j]` is `'0'` or `'1'`." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is about counting the number of islands in a 2D binary grid. In this grid, '1' represents land, and '0' represents water. An island is defined as a group of '1' cells that are adjacent to each other either horizontally or vertically. It's important to note that diagonal connections do not count. Additionally, it's assumed that all four edges of the grid are surrounded by water, meaning the grid is finite and doesn't \"wrap around.\"\n", - "\n", - "The objective is to determine how many distinct islands exist in the grid. To clarify, an island consists of connected '1' cells, and these connections can only occur horizontally or vertically. If there are no '1' cells in the grid, the number of islands would be zero.\n", - "\n", - "The problem often involves using graph traversal techniques like Depth-First Search (DFS) or Breadth-First Search (BFS) to identify and count these islands. You start at one '1' cell and explore its adjacent cells to determine the extent of the island. Once you've visited all the '1' cells in an island, you move on to the next unvisited '1' cell and repeat the process until you've counted all the islands in the grid.\n", - "\n", - "In essence, the problem asks you to analyze the grid to find groups of connected '1' cells and count them as individual islands. The goal is to return the total count of islands in the given grid.\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "from typing import List\n", - "\n", - "class Solution:\n", - " def numIslands(self, grid: List[List[str]]) -> int:\n", - " if not grid:\n", - " return 0\n", - "\n", - " m, n = len(grid), len(grid[0]) # Get the dimensions of the grid\n", - " num_islands = 0 # Initialize the count of islands\n", - "\n", - " def dfs(row, col):\n", - " if row < 0 or row >= m or col < 0 or col >= n or grid[row][col] == '0':\n", - " return\n", - "\n", - " grid[row][col] = '0' # Mark the current cell as visited by changing it to '0'\n", - " directions = [(1, 0), (-1, 0), (0, 1), (0, -1)] # Define four possible directions to move\n", - "\n", - " for dr, dc in directions:\n", - " # Explore adjacent cells\n", - " dfs(row + dr, col + dc)\n", - "\n", - " for i in range(m):\n", - " for j in range(n):\n", - " if grid[i][j] == '1':\n", - " num_islands += 1 # Increment the island count\n", - " dfs(i, j) # Start a DFS from the current '1' cell to explore the entire island\n", - "\n", - " return num_islands\n" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The provided code defines a Python class called `Solution` with a method called `numIslands`. This class is designed to count the number of islands in a 2D binary grid.\n", - "\n", - "The `numIslands` method takes a 2D grid as input, where '1' represents land, and '0' represents water. It uses a depth-first search (DFS) approach to identify and count islands. The key steps in the code include:\n", - "\n", - "1. Checking if the input grid is empty, and if so, returning 0 (indicating there are no islands).\n", - "\n", - "2. Determining the dimensions of the grid (number of rows and columns).\n", - "\n", - "3. Initializing a variable `num_islands` to keep track of the count of islands.\n", - "\n", - "4. Defining a nested function `dfs` to perform depth-first search. This function recursively explores adjacent land cells connected to the current cell and marks them as visited by changing '1' to '0'.\n", - "\n", - "5. In the `dfs` function, it checks for boundary conditions and whether the current cell is '0'. If these conditions are met, it returns without further exploration.\n", - "\n", - "6. The `dfs` function explores neighboring cells in all four directions (up, down, left, right) using a loop.\n", - "\n", - "7. The main loop iterates through each cell of the grid. When a '1' cell is encountered, it increments the `num_islands` count and starts a DFS from that cell to explore the entire island.\n", - "\n", - "8. Finally, the method returns the total count of islands found in the grid.\n", - "\n", - "This code encapsulates the solution in a class, allowing you to create an instance of the `Solution` class and call the `numIslands` method on it to count the number of islands in a given grid." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Example 1 Output: 1\n" - ] - } - ], - "source": [ - "grid1 = [\n", - " [\"1\", \"1\", \"1\", \"1\", \"0\"],\n", - " [\"1\", \"1\", \"0\", \"1\", \"0\"],\n", - " [\"1\", \"1\", \"0\", \"0\", \"0\"],\n", - " [\"0\", \"0\", \"0\", \"0\", \"0\"]\n", - "]\n", - "\n", - "solution = Solution()\n", - "result1 = solution.numIslands(grid1)\n", - "print(\"Example 1 Output:\", result1) # Expected output: 1\n" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Example 2 Output: 3\n" - ] - } - ], - "source": [ - "grid2 = [\n", - " [\"1\", \"1\", \"0\", \"0\", \"0\"],\n", - " [\"1\", \"1\", \"0\", \"0\", \"0\"],\n", - " [\"0\", \"0\", \"1\", \"0\", \"0\"],\n", - " [\"0\", \"0\", \"0\", \"1\", \"1\"]\n", - "]\n", - "\n", - "result2 = solution.numIslands(grid2)\n", - "print(\"Example 2 Output:\", result2) # Expected output: 3\n" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "Time Complexity:\n", - "- The code uses a depth-first search (DFS) to explore the grid and count the number of islands.\n", - "- In the worst case, it visits every cell in the grid exactly once.\n", - "- The DFS function explores neighboring cells in four directions (up, down, left, right), so it has a time complexity of $O(4^{max(m, n)})$, where m is the number of rows and n is the number of columns.\n", - "- Therefore, the overall time complexity of the code is O(m * n), where m is the number of rows, and n is the number of columns.\n", - "\n", - "Space Complexity:\n", - "- The space complexity is determined by the recursive calls and the depth of the DFS stack.\n", - "- In the worst case, when the entire grid consists of '1's, the depth of the DFS recursion can be as deep as max(m, n).\n", - "- Therefore, the space complexity of the code is O(max(m, n)), representing the maximum depth of the DFS stack.\n", - "\n", - "In practical terms, for reasonably sized grids, the time and space complexity is linear, and the code should perform well. However, it's important to keep in mind that the worst-case time complexity is O(m * n), and the space complexity can be O(max(m, n))." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Identify Largest Island:** In addition to counting the number of islands, modify the code to identify the largest island in the grid and return its size.\n", - "\n", - "2. **Optimize for Space:** Modify the solution to reduce its space complexity to O(1) without modifying the input grid. This is a more memory-efficient version of the problem." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/11. Graphs/207. Course Schedule.ipynb b/docs/11. Graphs/207. Course Schedule.ipynb deleted file mode 100644 index 37624f6..0000000 --- a/docs/11. Graphs/207. Course Schedule.ipynb +++ /dev/null @@ -1,249 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 207. Course Schedule\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Course Schedule problem on LeetCode, click here!](https://leetcode.com/problems/course-schedule/)\n", - "\n", - "---\n", - "There are a total of `numCourses` courses to take, labeled from 0 to `numCourses - 1`. You are given an array `prerequisites` where `prerequisites[i] = [ai, bi]` indicates that you **must** take course `bi` first if you want to take course `ai`. \n", - "\n", - "- For example, the pair `[0, 1]`, indicates that to take course `0` you have to first take course `1`.\n", - "\n", - "Return `true` if you can finish all courses. Otherwise, return `false`.\n", - "\n", - "**Constraints:**\n", - "- 1 <= `numCourses` <= 2000\n", - "- 0 <= `prerequisites.length` <= 5000\n", - "- `prerequisites[i].length` == 2\n", - "- 0 <= `ai`, `bi` < `numCourses`\n", - "- All the pairs `prerequisites[i]` are **unique**." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is to determine whether it's possible to complete a set of courses given a list of prerequisites. You are given the following:\n", - "\n", - "- `numCourses`: The total number of courses to be taken, labeled from 0 to `numCourses - 1`.\n", - "- `prerequisites`: A list of prerequisite courses, where each element `prerequisites[i]` is a pair `[ai, bi]`, indicating that you must take course `bi` before you can take course `ai`.\n", - "\n", - "The goal is to check whether it's possible to complete all the courses while respecting the prerequisite requirements. In other words, you need to determine if there are any circular dependencies in the course prerequisites that would prevent you from taking all the courses.\n", - "\n", - "For example:\n", - "\n", - "- If `numCourses` is 2, and `prerequisites` is `[[1, 0]]`, it means you have two courses, and you must finish course 0 before you can take course 1. In this case, it's possible to complete all courses, so the function should return `True`.\n", - "\n", - "- If `numCourses` is 2, and `prerequisites` is `[[1, 0], [0, 1]]`, it means you have two courses, but there's a circular dependency where course 1 requires course 0 and course 0 requires course 1. In this case, it's impossible to complete all courses, so the function should return `False`.\n", - "\n", - "The problem is essentially about checking for the presence of cycles in a directed graph, where the courses are nodes, and the prerequisites represent directed edges between them. If there are no cycles, it's possible to complete all courses; otherwise, it's not possible.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "from collections import defaultdict, deque\n", - "from typing import List\n", - "\n", - "class Solution:\n", - " def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:\n", - " # Create a graph using an adjacency list to represent the courses and their prerequisites.\n", - " graph = defaultdict(list) # Initialize an empty adjacency list.\n", - " in_degree = [0] * numCourses # Initialize an array to store in-degrees of courses.\n", - "\n", - " # Populate the graph and calculate in-degrees.\n", - " for course, prerequisite in prerequisites:\n", - " graph[prerequisite].append(course) # Add the course as a neighbor to its prerequisite.\n", - " in_degree[course] += 1 # Increment the in-degree of the course.\n", - "\n", - " # Initialize a queue with courses that have no prerequisites.\n", - " queue = deque()\n", - " for course in range(numCourses):\n", - " if in_degree[course] == 0:\n", - " queue.append(course)\n", - "\n", - " # Perform topological sorting.\n", - " while queue:\n", - " course = queue.popleft() # Take a course with no prerequisites.\n", - " numCourses -= 1 # Decrement the count of remaining courses.\n", - "\n", - " for neighbor in graph[course]:\n", - " in_degree[neighbor] -= 1 # Remove the prerequisite relationship.\n", - " if in_degree[neighbor] == 0:\n", - " queue.append(neighbor) # If no more prerequisites, add to the queue.\n", - "\n", - " # If all courses were successfully taken (numCourses becomes 0), return True.\n", - " return numCourses == 0" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "This Python code is designed to determine whether it is possible to complete all the required courses given a set of prerequisites. It uses a topological sorting algorithm to accomplish this. Here's a brief explanation of the code:\n", - "\n", - "1. The code defines a `Solution` class with a `canFinish` method that takes two parameters: `numCourses` (the total number of courses) and `prerequisites` (a list of pairs indicating which course must be taken before another).\n", - "\n", - "2. It initializes an empty graph as an adjacency list using a `defaultdict` to represent the courses and their prerequisites. It also initializes a list called `in_degree` to keep track of the in-degrees of courses, which is used in the topological sorting process.\n", - "\n", - "3. The code then populates the graph by iterating through the `prerequisites` list. For each pair `(ai, bi)`, it adds course `ai` as a neighbor to its prerequisite course `bi` in the graph and increments the in-degree of course `ai`.\n", - "\n", - "4. Next, it initializes a queue with courses that have no prerequisites. It does this by iterating through all the courses and adding those with an in-degree of 0 to the queue.\n", - "\n", - "5. The code performs a topological sorting of the courses using a while loop. In each iteration of the loop, it dequeues a course from the front of the queue (a course with no prerequisites).\n", - "\n", - "6. For each neighbor (course that depends on the dequeued course), it decrements the in-degree of the neighbor. If the neighbor's in-degree becomes 0, it means all of its prerequisites have been taken, so the neighbor is added to the queue.\n", - "\n", - "7. The loop continues until there are no more courses with no prerequisites to dequeue, and the in-degrees are updated accordingly.\n", - "\n", - "8. After the loop, if all courses were successfully taken (i.e., `numCourses` becomes 0), it means that there were no circular dependencies, and it's possible to finish all courses. In this case, the method returns `True`. Otherwise, if there are remaining courses (indicating a circular dependency), it returns `False`." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1\n", - "numCourses1 = 2\n", - "prerequisites1 = [[1, 0]]\n", - "sol = Solution()\n", - "print(sol.canFinish(numCourses1, prerequisites1)) # Output: True" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 2\n", - "numCourses2 = 2\n", - "prerequisites2 = [[1, 0], [0, 1]]\n", - "print(sol.canFinish(numCourses2, prerequisites2)) # Output: False" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `canFinish` method:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. Constructing the graph: In the first loop where we iterate through the `prerequisites` list, we populate the graph with prerequisites. This loop has a time complexity of O(E), where E is the number of prerequisites (edges).\n", - "\n", - "2. Initializing in-degrees and finding courses with no prerequisites: In the worst case, we iterate through all `numCourses` courses to initialize in-degrees and find the courses with no prerequisites. This has a time complexity of O(V), where V is the number of courses (vertices).\n", - "\n", - "3. Topological Sorting: In the while loop, we perform topological sorting, processing each course once and its outgoing edges. In the worst case, each course is processed once. This has a time complexity of O(V + E).\n", - "\n", - "The overall time complexity is O(V + E), where V is the number of courses, and E is the number of prerequisites.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. Graph Representation: The space complexity for storing the graph as an adjacency list is O(E), where E is the number of prerequisites.\n", - "\n", - "2. In-Degree Array: The space complexity for storing the in-degrees of courses is O(V), where V is the number of courses.\n", - "\n", - "3. Queue: The space complexity for the queue is O(V), as it may contain all the courses.\n", - "\n", - "The overall space complexity is O(V + E), where V is the number of courses, and E is the number of prerequisites.\n", - "\n", - "In most practical cases, the number of prerequisites (E) is much smaller than the number of courses (V), so the time and space complexity can often be considered as O(V)." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Optimizing Course Scheduling**: Given a list of courses with their durations and prerequisites, find the most efficient way to schedule these courses to minimize the time it takes to complete all of them.\n", - "\n", - "2. **Detecting Cycles in Course Dependencies**: Modify the original problem to not just determine if you can finish all courses but also to identify the specific courses that form a cycle in the prerequisite dependencies." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/11. Graphs/3651. Number of Connected Components in an Undirected Graph.ipynb b/docs/11. Graphs/3651. Number of Connected Components in an Undirected Graph.ipynb deleted file mode 100644 index fb186f2..0000000 --- a/docs/11. Graphs/3651. Number of Connected Components in an Undirected Graph.ipynb +++ /dev/null @@ -1,236 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 3651. Number of Connected Components in an Undirected Graph\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Number of Connected Components in an Undirected Graph problem on LintCode, click here!](https://www.lintcode.com/problem/3651/)\n", - "\n", - "---\n", - "In this problem, there is an undirected graph with `n` nodes. There is also an `edges` array. Where `edges[i] = [a, b]` means that there is an edge between *node a* and *node b* in the graph.\n", - "\n", - "You need to return *the number of connected components in that graph*." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem at hand is to determine the number of connected components in an undirected graph. Here's a more detailed explanation of the problem:\n", - "\n", - "- You are given an undirected graph, which consists of nodes and edges. The graph may have multiple distinct connected components.\n", - "\n", - "- A connected component is a group of nodes within the graph where each node can be reached from every other node in the same component. In other words, there is a path between any two nodes in the same connected component, but there are no paths connecting nodes from different components.\n", - "\n", - "- Your task is to write a function that takes as input the number of nodes `n` and a list of edges `edges`, where each edge is represented as a pair of nodes `[a, b]` indicating an edge between node `a` and node `b`.\n", - "\n", - "- The goal is to determine the number of distinct connected components in the graph.\n", - "\n", - "- You need to implement an algorithm that can identify these connected components and count how many there are in the given graph.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def countConnectedComponents(n, edges):\n", - " # Define a helper function for depth-first search (DFS).\n", - " def dfs(node):\n", - " if not visited[node]: # If the node has not been visited yet:\n", - " visited[node] = True # Mark it as visited.\n", - " for neighbor in graph[node]: # Explore all neighbors of the current node.\n", - " dfs(neighbor) # Recursively call DFS on the neighbor.\n", - "\n", - " # Create an empty adjacency list to represent the graph.\n", - " graph = [[] for _ in range(n)]\n", - "\n", - " # Initialize a boolean list to keep track of visited nodes.\n", - " visited = [False] * n\n", - "\n", - " # Populate the adjacency list with edges from the input.\n", - " for a, b in edges:\n", - " graph[a].append(b)\n", - " graph[b].append(a) # Since the graph is undirected, we add edges in both directions.\n", - "\n", - " # Initialize a counter to keep track of the number of connected components.\n", - " count = 0\n", - "\n", - " # Iterate through all nodes in the graph.\n", - " for i in range(n):\n", - " if not visited[i]: # If the node has not been visited:\n", - " count += 1 # Increment the count since we've found a new connected component.\n", - " dfs(i) # Start a depth-first search from the unvisited node to explore the component.\n", - "\n", - " return count" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The provided Python code calculates the number of connected components in an undirected graph. Here's a high-level explanation of how the code works:\n", - "\n", - "1. The `countConnectedComponents` function takes two arguments: `n` (the number of nodes in the graph) and `edges` (a list of edge pairs representing connections between nodes).\n", - "\n", - "2. Inside the function, there is a helper function called `dfs` (depth-first search), which is used to explore and mark nodes as visited.\n", - "\n", - "3. An empty adjacency list called `graph` is created to represent the graph. The `graph` is a list of lists where each element represents a node, and the list associated with each node contains its neighboring nodes.\n", - "\n", - "4. Another list called `visited` is created to keep track of visited nodes. Initially, all nodes are marked as not visited (`False`).\n", - "\n", - "5. The code populates the `graph` by iterating through the `edges` list and adding each edge to the adjacency list. Since the graph is undirected, both directions of each edge are added.\n", - "\n", - "6. A counter variable called `count` is initialized to keep track of the number of connected components.\n", - "\n", - "7. The code iterates through all nodes from `0` to `n-1`. For each node, it checks whether it has been visited yet. If it hasn't been visited, it means a new connected component is found. The counter `count` is incremented, and a depth-first search (DFS) is initiated from this unvisited node to explore the connected component.\n", - "\n", - "8. The `dfs` function recursively visits all nodes in the connected component, marking them as visited. It does this by checking each neighbor of the current node and recursively calling `dfs` on unvisited neighbors.\n", - "\n", - "9. After the loop through all nodes, the `count` variable contains the total number of connected components in the graph.\n", - "\n", - "10. The function returns the value of `count`, which represents the number of connected components.\n", - "\n", - "11. Two examples are provided at the end to demonstrate how to use the function with different inputs." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n" - ] - } - ], - "source": [ - "# Example 1\n", - "n1 = 3\n", - "edges1 = [[0, 1], [0, 2]]\n", - "print(countConnectedComponents(n1, edges1)) # Output: 1" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2\n" - ] - } - ], - "source": [ - "# Example 2\n", - "n2 = 6\n", - "edges2 = [[0, 1], [1, 2], [2, 3], [4, 5]]\n", - "print(countConnectedComponents(n2, edges2)) # Output: 2" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the code for counting the number of connected components in an undirected graph using depth-first search (DFS).\n", - "\n", - "**Time Complexity:**\n", - "- The code iterates through all nodes in the graph (from 0 to `n-1`).\n", - "- For each unvisited node, it initiates a depth-first search (DFS) from that node to explore the connected component.\n", - "- In the worst case, every node may belong to a separate connected component, and you perform a DFS for each node.\n", - "- The time complexity of the DFS for a single connected component is O(V + E), where V is the number of nodes in the component, and E is the number of edges.\n", - "- In the worst case, you perform O(n) DFS calls, each with its own O(V + E) complexity.\n", - "\n", - "So, the overall time complexity of the code is O(n * (V + E)). In the worst case, if the graph is connected (a single connected component), this simplifies to O(n * (n + m)), where m is the number of edges.\n", - "\n", - "**Space Complexity:**\n", - "- The main data structures used are the `graph` (adjacency list), `visited` (boolean array), and the recursive call stack for DFS.\n", - "- The `graph` has a space complexity of O(n + m), where n is the number of nodes, and m is the number of edges.\n", - "- The `visited` boolean array also has a space complexity of O(n) to keep track of whether nodes have been visited.\n", - "- The depth of the recursive call stack for DFS can go up to O(n) in the worst case, when all nodes are part of a single connected component.\n", - "\n", - "So, the overall space complexity of the code is O(n + m) for data structures and O(n) for the call stack. In the worst case, this simplifies to O(n + m).\n", - "\n", - "In summary, the time complexity is O(n * (V + E)), and the space complexity is O(n + m)." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Disconnected Components with Multiple Queries:** You are given an undirected graph with `n` nodes and `m` edges. Initially, the graph is disconnected, and you need to process `q` queries. Each query consists of adding an edge to connect two nodes. After each query, you need to output the number of connected components in the updated graph.\n", - "\n", - "2. **Maximum Size of Connected Components:** Given an undirected graph with `n` nodes and `m` edges, find the size of the largest connected component in the graph. Additionally, identify the nodes that belong to this largest component. You can assume there is at least one connected component in the graph.\n" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/11. Graphs/417. Pacific Atlantic Water Flow.ipynb b/docs/11. Graphs/417. Pacific Atlantic Water Flow.ipynb deleted file mode 100644 index eb34497..0000000 --- a/docs/11. Graphs/417. Pacific Atlantic Water Flow.ipynb +++ /dev/null @@ -1,261 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 417. Pacific Atlantic Water Flow\n", - "\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Pacific Atlantic Water Flow problem on LeetCode, click here!](https://leetcode.com/problems/pacific-atlantic-water-flow/)\n", - "\n", - "---\n", - "There is an `m x n` rectangular island that borders both the **Pacific Ocean** and **Atlantic Ocean**. The **Pacific Ocea**n touches the island's left and top edges, and the **Atlantic Ocean** touches the island's right and bottom edges.\n", - "\n", - "The island is partitioned into a grid of square cells. You are given an `m x n` integer matrix `heights` where `heights[r][c]` represents the **height above sea level** of the cell at coordinate `(r, c)`.\n", - "\n", - "The island receives a lot of rain, and the rain water can flow to neighboring cells directly north, south, east, and west if the neighboring cell's height is **less than or equal to** the current cell's height. Water can flow from any cell adjacent to an ocean into the ocean.\n", - "\n", - "Return *a **2D list** of grid coordinates `result` where $result[i] = [r_i, c_i]$ denotes that rain water can flow from cell $(r_i, c_i)$ to **both** the Pacific and Atlantic oceans*.\n", - "\n", - "**Constraints:**\n", - "- `m == heights.length`\n", - "- `n == heights[r].length`\n", - "- `1 <= m, n <= 200`\n", - "- 0 <= `heights[r][c]` <= $10^5$" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem at hand involves a scenario with a rectangular island surrounded by both the Pacific Ocean and the Atlantic Ocean. The Pacific Ocean is in contact with the island's left and top edges, while the Atlantic Ocean is in contact with the island's right and bottom edges. The goal is to determine which cells on the island can allow rainwater to flow to both the Pacific and Atlantic Oceans.\n", - "\n", - "Here are the key details and constraints of the problem:\n", - "\n", - "1. The island is divided into a grid of square cells.\n", - "\n", - "2. Each cell is represented by an integer value in a matrix `heights`. The value at `heights[r][c]` represents the height above sea level of the cell at coordinates `(r, c)` on the island.\n", - "\n", - "3. Rainwater can flow from a cell to neighboring cells directly north, south, east, or west only if the neighboring cell's height is less than or equal to the current cell's height.\n", - "\n", - "4. Water can flow from any cell adjacent to the ocean into the ocean. This means water can flow from cells on the edge of the island to the Pacific Ocean and the Atlantic Ocean.\n", - "\n", - "The task is to find and return a 2D list of grid coordinates where rainwater can flow from a cell to both the Pacific and Atlantic Oceans. In other words, you need to identify the cells that can send water to both the left and top edges (Pacific) and the right and bottom edges (Atlantic) of the island.\n", - "\n", - "The problem is solved by performing a depth-first search (DFS) starting from the ocean edges and marking the cells that can flow to each ocean. Then, the algorithm identifies cells that are reachable from both oceans and returns their coordinates as the result.\n", - "\n", - "The problem involves both traversal of the island and backtracking to find the solution, which makes it a classic graph traversal problem.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "from typing import List\n", - "\n", - "class Solution:\n", - " def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]:\n", - " # Check if the input matrix is empty\n", - " if not heights:\n", - " return []\n", - " \n", - " m, n = len(heights), len(heights[0])\n", - " \n", - " # Initialize boolean matrices to keep track of cells reachable from each ocean\n", - " pacific_reachable = [[False] * n for _ in range(m)]\n", - " atlantic_reachable = [[False] * n for _ in range(m)]\n", - " \n", - " # Depth-First Search (DFS) function to mark cells that can be reached from an ocean\n", - " def dfs(x, y, reachable):\n", - " if reachable[x][y]:\n", - " return\n", - " reachable[x][y] = True\n", - " for dx, dy in [(0, 1), (0, -1), (1, 0), (-1, 0)]:\n", - " new_x, new_y = x + dx, y + dy\n", - " if 0 <= new_x < m and 0 <= new_y < n and heights[new_x][new_y] >= heights[x][y]:\n", - " dfs(new_x, new_y, reachable)\n", - " \n", - " # Start DFS from the Pacific Ocean (left and top edges)\n", - " for i in range(m):\n", - " dfs(i, 0, pacific_reachable)\n", - " dfs(i, n - 1, atlantic_reachable)\n", - " \n", - " for j in range(n):\n", - " dfs(0, j, pacific_reachable)\n", - " dfs(m - 1, j, atlantic_reachable)\n", - " \n", - " result = []\n", - " \n", - " # Find cells that can flow to both the Pacific and Atlantic oceans\n", - " for i in range(m):\n", - " for j in range(n):\n", - " if pacific_reachable[i][j] and atlantic_reachable[i][j]:\n", - " result.append([i, j])\n", - " \n", - " return result" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The code defines a class called `Solution` with a method named `pacificAtlantic`. This method takes a 2D matrix `heights`, where each element represents the height above sea level of a cell on a rectangular island. The goal of the method is to find and return a list of grid coordinates (cells) from which rainwater can flow into both the Pacific and Atlantic Oceans.\n", - "\n", - "The code uses a Depth-First Search (DFS) algorithm to traverse the island, starting from the ocean edges, and marks cells that are reachable from either the Pacific or Atlantic Ocean. It does this by creating two boolean matrices, `pacific_reachable` and `atlantic_reachable`, to keep track of cells that can be reached from each ocean.\n", - "\n", - "The code iterates through the entire island, initiating DFS searches from the edges of the island. If a cell is reachable from an ocean (either Pacific or Atlantic), it is marked as reachable in the corresponding boolean matrix. The DFS function ensures that the traversal follows the rule that water can flow to a neighboring cell if the neighboring cell's height is less than or equal to the current cell's height.\n", - "\n", - "After marking all reachable cells from both oceans, the code then looks for cells that are reachable from both the Pacific and Atlantic Oceans. If a cell satisfies this condition, it is added to the `result` list.\n", - "\n", - "Finally, the code returns the `result` list, which contains the grid coordinates of cells from which rainwater can flow into both the Pacific and Atlantic Oceans.\n", - "\n", - "The code provides a solution to the problem of finding cells on the island where water can reach both oceans, demonstrating a traversal algorithm that explores the connectivity of cells on the island." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]]\n" - ] - } - ], - "source": [ - "# Example 1\n", - "heights1 = [\n", - " [1,2,2,3,5],\n", - " [3,2,3,4,4],\n", - " [2,4,5,3,1],\n", - " [6,7,1,4,5],\n", - " [5,1,1,2,4]\n", - "]\n", - "\n", - "solution = Solution()\n", - "print(solution.pacificAtlantic(heights1)) # Expected Output: [[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]]" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[0, 0]]\n" - ] - } - ], - "source": [ - "# Example 2\n", - "heights2 = [[1]]\n", - "print(solution.pacificAtlantic(heights2)) # Expected Output: [[0, 0]]" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Time Complexity:\n", - "The time complexity of this solution is O(m * n), where 'm' is the number of rows in the input matrix and 'n' is the number of columns. Here's a breakdown of the time complexity:\n", - "\n", - "1. Creating the `pacific_reachable` and `atlantic_reachable` matrices with dimensions m x n takes O(m * n) time.\n", - "\n", - "2. Initiating Depth-First Search (DFS) from the edges of the island takes O(m * n) time because it processes each cell once.\n", - "\n", - "3. The DFS function visits each cell at most once, and its time complexity is O(1) for each cell. The number of cells visited by the DFS in the worst case is m * n.\n", - "\n", - "4. The final step of identifying and appending cells to the result list takes O(m * n) time in the worst case.\n", - "\n", - "Overall, the time complexity is dominated by the DFS and is O(m * n).\n", - "\n", - "Space Complexity:\n", - "The space complexity of this solution is also O(m * n). Here's how the space is used:\n", - "\n", - "1. Two boolean matrices, `pacific_reachable` and `atlantic_reachable`, are created with dimensions m x n. Each matrix takes O(m * n) space, resulting in O(2 * m * n) space usage.\n", - "\n", - "2. The depth-first search (DFS) stack space during the recursive calls can go as deep as the diagonal of the grid, which is at most min(m, n). This additional space for the call stack is relatively small compared to the boolean matrices and can be considered O(min(m, n)).\n", - "\n", - "3. The `result` list stores the grid coordinates, and its size is determined by the number of cells that can flow to both oceans. In the worst case, this list can contain all m * n cells, so it takes O(m * n) space.\n", - "\n", - "The overall space complexity is the sum of these components, which is O(m * n) + O(min(m, n)) + O(m * n). In big O notation, we can simplify this to O(m * n)." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Optimization Challenge:** Modify the algorithm to find the maximum flow of water from any cell to both the Pacific and Atlantic Oceans. In other words, find the cell(s) that can send the most water to both oceans.\n", - "\n", - "2. **Efficiency Challenge:** Optimize the time and space complexity of the algorithm while maintaining correctness. Aim to reduce both time and space complexity as much as possible." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/11. Graphs/README.md b/docs/11. Graphs/README.md deleted file mode 100644 index aad262c..0000000 --- a/docs/11. Graphs/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# Graphs Problems - Blind 75 LeetCode - - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [200. Number of Islands](https://leetcode.com/problems/number-of-islands/) | Medium | -| [133. Clone Graph](https://leetcode.com/problems/clone-graph/) | Medium | -| [417. Pacific Atlantic Water Flow](https://leetcode.com/problems/pacific-atlantic-water-flow/) | Medium | -| [207. Course Schedule](https://leetcode.com/problems/course-schedule/) | Medium | -| [323. Number of Connected Components In An Undirected Graph](https://leetcode.com/problems/number-of-connected-components-in-an-undirected-graph/) | Medium | -| [261. Graph Valid Tree](https://leetcode.com/problems/graph-valid-tree/) | Medium | - - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! \ No newline at end of file diff --git a/docs/12. Advanced Graphs/892. Alien Dictionary.ipynb b/docs/12. Advanced Graphs/892. Alien Dictionary.ipynb deleted file mode 100644 index 81f0e5b..0000000 --- a/docs/12. Advanced Graphs/892. Alien Dictionary.ipynb +++ /dev/null @@ -1,256 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 892. Alien Dictionary\n", - "\n", - "**Difficulty:** Hard\n", - "\n", - "**Link to Problem:** [To see the Alien Dictionary problem on LintCode, click here!](https://www.lintcode.com/problem/892/)\n", - "\n", - "---\n", - "\n", - "There is a new alien language which uses the latin alphabet. However, the order among letters are unknown to you. You receive a list of **non-empty** words from the dictionary, where words are **sorted lexicographically by the rules of this new language**. Derive the order of letters in this language.\n", - "\n", - "**Constraints:**\n", - "- You may assume all letters are in lowercase.\n", - "- The dictionary is invalid, if string a is prefix of string b and b is appear before a.\n", - "- If the order is invalid, return an empty string.\n", - "- There may be multiple valid order of letters, return the smallest in normal lexicographical order.\n", - "- The letters in **one** string are of the same rank by default and are sorted in Human dictionary order." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem at hand involves determining the order of letters in a new alien language that uses the Latin alphabet. However, the order of letters in this alien language is unknown. To solve this problem, we are given a list of non-empty words from the dictionary, where the words are sorted lexicographically based on the rules of the alien language. The goal is to derive the correct order of letters in this new language.\n", - "\n", - "Here's a more detailed explanation of the problem:\n", - "\n", - "1. The alphabet: The new alien language uses the Latin alphabet, which consists of lowercase letters.\n", - "\n", - "2. Dictionary: We are provided with a list of non-empty words. These words are sorted in lexicographical order based on the rules of the alien language. The order of letters in the words reflects the correct order in the new language.\n", - "\n", - "3. Invalid order: The problem specifies that the dictionary is considered invalid if there exists a situation where one string 'a' is a prefix of another string 'b,' and 'b' appears before 'a' in the dictionary. This condition ensures that there are no inconsistencies in the order of letters.\n", - "\n", - "4. Multiple valid orders: It's possible that there are multiple valid orders of letters that satisfy the provided dictionary. However, we are instructed to return the smallest valid order in normal lexicographical order.\n", - "\n", - "To solve this problem, you need to analyze the given list of words and determine the correct order of letters in the alien language while adhering to the specified constraints. You should return the order as a string in lexicographical order if it's valid, and an empty string if the order is invalid.\n", - "\n", - "The key to solving this problem is to construct a directed graph of letter relationships based on the order information provided by the words in the dictionary. Then, perform a topological sort on this graph to derive the order of letters, ensuring that the order is consistent and valid according to the given constraints.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "from collections import defaultdict, deque\n", - "\n", - "def alienOrder(words):\n", - " # Create an adjacency list to represent the graph\n", - " graph = defaultdict(list)\n", - " \n", - " # Create a dictionary to store the in-degrees of each letter\n", - " in_degree = {}\n", - " \n", - " # Initialize in-degrees to 0 for all letters\n", - " for word in words:\n", - " for char in word:\n", - " if char not in in_degree:\n", - " in_degree[char] = 0\n", - " \n", - " # Build the graph and update in-degrees\n", - " for i in range(1, len(words)):\n", - " word1, word2 = words[i-1], words[i]\n", - " min_length = min(len(word1), len(word2))\n", - " \n", - " # Compare characters in the two words\n", - " j = 0\n", - " while j < min_length and word1[j] == word2[j]:\n", - " j += 1\n", - " \n", - " if j < min_length:\n", - " # If word1[j] is lexicographically before word2[j], add an edge\n", - " graph[word1[j]].append(word2[j])\n", - " in_degree[word2[j]] += 1\n", - " \n", - " # Break the loop to avoid further comparisons\n", - " break\n", - " \n", - " # Perform topological sorting using Kahn's algorithm\n", - " result = []\n", - " queue = deque([char for char in in_degree if in_degree[char] == 0])\n", - " \n", - " while queue:\n", - " char = queue.popleft()\n", - " result.append(char)\n", - " \n", - " for neighbor in graph[char]:\n", - " in_degree[neighbor] -= 1\n", - " if in_degree[neighbor] == 0:\n", - " queue.append(neighbor)\n", - " \n", - " # Check if there is a valid order\n", - " if len(result) < len(in_degree):\n", - " return \"\"\n", - " \n", - " return \"\".join(result)" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The code is designed to determine the order of letters in an unknown alien language that uses the Latin alphabet. It takes a list of non-empty words from a dictionary as input, where the words are sorted lexicographically based on the rules of this alien language.\n", - "\n", - "The code follows these main steps:\n", - "\n", - "1. Create a data structure to represent the graph of letters and their relationships in the alien language. It uses a defaultdict to store a list of letters that come after each letter. Additionally, it uses a dictionary called `in_degree` to keep track of the in-degrees (the number of letters that precede a letter) for each letter.\n", - "\n", - "2. Initialize the in-degrees of all letters to 0. This is done by iterating through all the words and characters in the words, adding each character to the `in_degree` dictionary with an initial in-degree of 0.\n", - "\n", - "3. Build the graph by comparing adjacent words in the dictionary. For each pair of adjacent words, the code finds the first differing character between the two words. If such a character exists, it means there's an order relationship between the letters represented by these characters. The code updates the graph and in-degrees accordingly.\n", - "\n", - "4. After constructing the graph, the code performs a topological sorting of the letters using Kahn's algorithm. It starts by initializing an empty result list and a queue containing letters with in-degrees of 0. The algorithm repeatedly removes a letter with an in-degree of 0 from the queue, adds it to the result list, and updates the in-degrees of its neighbors. This process continues until the queue is empty.\n", - "\n", - "5. Finally, the code checks if the topological sorting was successful by comparing the length of the result list with the number of unique letters in the input. If the lengths differ, it means there's a cycle in the graph, and the order is invalid. In such a case, an empty string is returned. Otherwise, the result list is joined together to form the smallest order of letters in normal lexicographical order, and it is returned as the output.\n", - "\n", - "The code provides a way to determine the order of letters in the alien language while handling various edge cases, including checking for invalid order conditions." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "wrtef\n" - ] - } - ], - "source": [ - "# Example 1\n", - "words1 = [\"wrt\", \"wrf\", \"er\", \"ett\", \"rftt\"]\n", - "print(alienOrder(words1)) # Output: \"wertf\"" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "zx\n" - ] - } - ], - "source": [ - "# Example 2\n", - "words2 = [\"z\", \"x\"]\n", - "print(alienOrder(words2)) # Output: \"zx\"" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code for determining the order of letters in an alien language.\n", - "\n", - "Time Complexity:\n", - "1. Building the graph: The code iterates through the list of words and compares adjacent words. In the worst case, where all words have the same prefix, it takes O(N) time to build the graph, where N is the total number of characters in all the words.\n", - "2. Topological sorting: Performing a topological sort on the graph takes O(V + E) time, where V is the number of unique letters (vertices) and E is the number of relationships between letters (edges) in the graph.\n", - "\n", - "Overall, the time complexity is O(N + V + E), where N is the total number of characters in the words, V is the number of unique letters, and E is the number of order relationships between letters.\n", - "\n", - "Space Complexity:\n", - "1. Graph and In-degrees: The code uses data structures to represent the graph and in-degrees. The space complexity for these data structures is O(V + E), where V is the number of unique letters, and E is the number of order relationships between letters in the words.\n", - "2. Result List: The result list stores the order of letters, which can have a maximum size of V, where V is the number of unique letters.\n", - "3. Queue: The space used by the queue during topological sorting is also O(V).\n", - "\n", - "Overall, the space complexity is O(V + E) due to the data structures used for graph representation and the space needed for storing the result and the queue.\n", - "\n", - "In the worst case, where there are many unique letters and many order relationships, the space complexity is dominated by the number of unique letters and their relationships.\n", - "\n", - "In summary, the time complexity of the code is O(N + V + E), and the space complexity is O(V + E). The actual performance will depend on the specific input data, such as the number of unique letters and the relationships between them in the alien language." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Multiple Valid Orders**: Extend the problem to handle cases where there are multiple valid orders of letters in the alien language. Modify the code to return all valid orders instead of just one. Be mindful of performance.\n", - "\n", - "2. **Detect Invalid Dictionary**: Given a dictionary of words, write a function to detect whether the dictionary is valid or not based on the constraints mentioned in the problem statement." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/12. Advanced Graphs/README.md b/docs/12. Advanced Graphs/README.md deleted file mode 100644 index f362de7..0000000 --- a/docs/12. Advanced Graphs/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# Advanced Graphs Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [269. Alien Dictionary](https://leetcode.com/problems/alien-dictionary/) | Hard | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! \ No newline at end of file diff --git a/docs/13. One-D Dynamic Programming/198. House Robber.ipynb b/docs/13. One-D Dynamic Programming/198. House Robber.ipynb deleted file mode 100644 index 8d32e21..0000000 --- a/docs/13. One-D Dynamic Programming/198. House Robber.ipynb +++ /dev/null @@ -1,103 +0,0 @@ -{ - "metadata": { - "kernelspec": { - "name": "python", - "display_name": "Python (Pyodide)", - "language": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat_minor": 5, - "nbformat": 4, - "cells": [ - { - "cell_type": "markdown", - "source": "# House Robber\n**Difficulty:** Medium\n\n---\nYou are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security systems connected and **it will automatically contact the police if two adjacent houses were broken into on the same night.**\n\nGiven an integer array `nums` representing the amount of money of each house, return *the maximum amount of money you can rob tonight **without alerting the police**.*\n\n**Constraints:**\n- `1 <= nums.length <= 100`\n- `0 <= nums[i] <= 400`", - "metadata": {}, - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49" - }, - { - "cell_type": "markdown", - "source": "## Probelm Explanation:\n\nThe problem is a classic dynamic programming challenge known as the \"House Robber\" problem. The scenario is that you are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, but the constraint is that adjacent houses have security systems connected. If two adjacent houses are broken into on the same night, the security systems will automatically contact the police.\n\nThe goal is to determine the maximum amount of money you can rob tonight without alerting the police. You need to find a strategy to maximize your earnings while avoiding robbing two adjacent houses.\n\nThe input to the problem is an array `nums`, where `nums[i]` represents the amount of money in the `i`-th house. The task is to return the maximum amount of money that can be robbed without triggering the security system.\n\nFor example:\n```\nInput: nums = [1,2,3,1]\nOutput: 4\nExplanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).\nTotal amount you can rob = 1 + 3 = 4.\n\nInput: nums = [2,7,9,3,1]\nOutput: 12\nExplanation: Rob house 1 (money = 2), rob house 3 (money = 9), and rob house 5 (money = 1).\nTotal amount you can rob = 2 + 9 + 1 = 12.\n```\n\nThe challenge involves designing an algorithm to efficiently solve this problem and find the optimal strategy for robbing houses to maximize the stolen money while adhering to the constraint of not robbing adjacent houses. The provided solution utilizes dynamic programming to achieve this.\n\n## Solution:\nHere's a Python function to implement this algorithm:", - "metadata": {}, - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76" - }, - { - "cell_type": "code", - "source": "from typing import List\n\nclass Solution:\n def rob(self, nums: List[int]) -> int:\n # Initialize variables to keep track of the maximum amount of money robbed at the previous and current houses\n prev, curr = 0, 0\n\n # Iterate through the houses\n for n in nums:\n # Calculate the maximum amount of money that can be robbed at the current house\n # It is the maximum of either robbing the current house and the money robbed at the house before the previous one (prev),\n # or skipping the current house and taking the maximum amount from the previous house (curr)\n temp = max(n + prev, curr)\n\n # Update the variables for the next iteration\n prev, curr = curr, temp\n\n # The final result is the maximum amount of money that can be robbed at the last house\n return curr", - "metadata": { - "trusted": true - }, - "execution_count": 4, - "outputs": [], - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5" - }, - { - "cell_type": "markdown", - "source": "## Explanation:\n\nThe provided code is a Python implementation of the \"House Robber\" problem using a dynamic programming approach. It's part of a class `Solution` and includes a method `rob` that takes a list of integers `nums` as input and returns the maximum amount of money that can be robbed without alerting the police.\n\nThe key idea of the algorithm is to maintain two variables, `prev` and `curr`, which represent the maximum amount of money that can be robbed up to the previous house and the current house, respectively. The algorithm iterates through the houses, updating these variables based on the maximum amount that can be robbed at the current house, considering the constraint of not robbing adjacent houses.\n\nThe loop calculates a temporary variable `temp` that represents the maximum amount of money that can be robbed at the current house. It considers two scenarios: either robbing the current house and adding the money robbed at the house before the previous one (`n + prev`), or skipping the current house and taking the maximum amount from the previous house (`curr`). The maximum of these two scenarios is assigned to `temp`.\n\nThe `prev` and `curr` variables are then updated for the next iteration. `prev` is set to the previous value of `curr`, and `curr` is set to the calculated `temp`.\n\nThe final result is the value stored in the `curr` variable, representing the maximum amount of money that can be robbed at the last house. This value is returned as the result of the `rob` method.\n\nThe provided test cases at the end demonstrate the usage of the `rob` method with different input arrays.", - "metadata": {}, - "id": "ece39324-cd9e-47d7-8677-a001878494d9" - }, - { - "cell_type": "markdown", - "source": "## Test cases:\n\nHere's how you can use this solution:", - "metadata": {}, - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244" - }, - { - "cell_type": "code", - "source": "# Example 1:\nsol = Solution()\n\nnums1 = [1, 2, 3, 1]\nprint(sol.rob(nums1)) # Output: 4", - "metadata": { - "trusted": true - }, - "execution_count": 5, - "outputs": [ - { - "name": "stdout", - "text": "4\n", - "output_type": "stream" - } - ], - "id": "f12c5a63-b811-4be7-83c2-34ee396b546c" - }, - { - "cell_type": "code", - "source": "# Example 2:\nnums2 = [2, 7, 9, 3, 1]\nprint(sol.rob(nums2)) # Output: 12", - "metadata": { - "trusted": true - }, - "execution_count": 6, - "outputs": [ - { - "name": "stdout", - "text": "12\n", - "output_type": "stream" - } - ], - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3" - }, - { - "cell_type": "markdown", - "source": "## Time and Space Complexity Analysis\n\nLet's analyze the time and space complexity of the provided code.\n\n### Time Complexity:\n\nThe time complexity of the code is O(n), where n is the number of houses. The algorithm iterates through the array once, and in each iteration, it performs constant time operations. The loop runs for each house, and the number of operations inside the loop is independent of the input size. Therefore, the overall time complexity is linear, O(n).\n\n### Space Complexity:\n\nThe space complexity is O(1), constant space. The algorithm uses only a constant amount of extra space regardless of the input size. The variables `prev`, `curr`, and `temp` are the only additional variables used, and they do not depend on the size of the input array. Thus, the space complexity is constant, O(1).\n\nIn summary:\n- Time Complexity: O(n)\n- Space Complexity: O(1)", - "metadata": {}, - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2" - }, - { - "cell_type": "markdown", - "source": "## Challenging Exercises:\n\n1. **Variation with Maximum Number of Houses to Rob:** Modify the problem to include an additional constraint: you are allowed to rob at most 'k' houses without triggering the alarm. Find the maximum amount you can rob under this new constraint.\n\n2. **Robbing in a Circular Street:** Extend the problem to a circular street where the first and last houses are adjacent. You cannot rob both the first and last houses simultaneously. Find the maximum amount you can rob in this circular setting.\n\n\n**Link to Problem:** [To see the House Robber problem on LeetCode, click here!](https://leetcode.com/problems/house-robber/description/)\n", - "metadata": {}, - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6" - } - ] -} \ No newline at end of file diff --git a/docs/13. One-D Dynamic Programming/213. House Robber II.ipynb b/docs/13. One-D Dynamic Programming/213. House Robber II.ipynb deleted file mode 100644 index b1080e8..0000000 --- a/docs/13. One-D Dynamic Programming/213. House Robber II.ipynb +++ /dev/null @@ -1,119 +0,0 @@ -{ - "metadata": { - "kernelspec": { - "name": "python", - "display_name": "Python (Pyodide)", - "language": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat_minor": 5, - "nbformat": 4, - "cells": [ - { - "cell_type": "markdown", - "source": "# House Robber II\n**Difficulty:** Medium\n\n---\nYou are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. All houses at this place are **arranged in a circle**. That means the first house is the neighbor of the last one. Meanwhile, adjacent houses have a security system connected, and **it will automatically contact the police if two adjacent houses were broken into on the same night**.\n\nGiven an integer array `nums` representing the amount of money of each house, return *the maximum amount of money you can rob tonight without alerting the police*.\n\n**Constraints:**\n- `1 <= nums.length <= 100`\n- `0 <= nums[i] <= 1000`", - "metadata": {}, - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49" - }, - { - "cell_type": "markdown", - "source": "## Probelm Explanation:\n\nCertainly! The problem statement describes a scenario where you are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. However, there is a security system in place: adjacent houses have a security system connected, and it will automatically contact the police if two adjacent houses are broken into on the same night.\n\nThe twist in this problem is that the houses are arranged in a circle. That means the first house is the neighbor of the last one. So, robbing the first house has implications for the last house, and vice versa.\n\nThe goal is to find the maximum amount of money you can rob tonight without alerting the police. You need to implement a function that takes an integer array `nums` representing the amount of money in each house and returns the maximum amount of money that can be robbed without triggering the security system.\n\nHere are a few examples to illustrate the problem:\n\n1. **Example 1:**\n ```python\n Input: nums = [2, 3, 2]\n Output: 3\n Explanation: You cannot rob house 1 (money = 2) and then rob house 3 (money = 2) because they are adjacent houses. The optimal strategy is to rob house 2 (money = 3).\n ```\n\n2. **Example 2:**\n ```python\n Input: nums = [1, 2, 3, 1]\n Output: 4\n Explanation: Robbing house 1 (money = 1) and then robbing house 3 (money = 3) results in a total amount of 4. Robbing house 2 is skipped to avoid alerting the police.\n ```\n\n3. **Example 3:**\n ```python\n Input: nums = [1, 2, 3]\n Output: 3\n Explanation: Since the houses are in a circle, you can choose either house 1, 2, or 3. The optimal strategy is to rob house 3 for a total amount of 3.\n ```\n\nThe constraints for the problem are that the length of the `nums` array is between 1 and 100, and the amount of money in each house (`nums[i]`) is between 0 and 1000.\n\n## Solution:\nHere's a Python function to implement this algorithm:", - "metadata": {}, - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76" - }, - { - "cell_type": "code", - "source": "from typing import List\n\nclass Solution:\n def rob(self, nums: List[int]) -> int:\n def simple_rob(nums):\n # Helper function for basic house robbery problem\n prev, curr = 0, 0\n for num in nums:\n # Calculate the maximum amount of money that can be robbed\n # without alerting the police for each house\n prev, curr = curr, max(prev + num, curr)\n return curr\n\n # Check the base cases where the length of nums is 1 or 2\n if len(nums) == 1:\n return nums[0]\n elif len(nums) == 2:\n return max(nums[0], nums[1])\n\n # Case 1: First house is robbed, last house is not\n case1 = simple_rob(nums[:-1])\n\n # Case 2: First house is not robbed, last house is\n case2 = simple_rob(nums[1:])\n\n # Maximum of the two cases\n return max(case1, case2)", - "metadata": { - "trusted": true - }, - "execution_count": 7, - "outputs": [], - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5" - }, - { - "cell_type": "markdown", - "source": "## Explanation:\n\nThe provided code defines a class `Solution` with a method `rob`, which aims to determine the maximum amount of money a professional robber can steal from houses arranged in a circle without alerting the police. Each house contains a certain amount of money, and adjacent houses have a security system that triggers if both are robbed on the same night.\n\nThe code uses dynamic programming to solve the problem efficiently. It contains a helper function `simple_rob` that computes the maximum amount of money that can be robbed from a linear arrangement of houses. The main method `rob` handles the circular arrangement by considering two cases: robbing the first house and not robbing the last, and not robbing the first house and robbing the last. The result is the maximum of these two cases.\n\nThe class is instantiated as `solution`, and the `rob` method is applied to three different scenarios (test cases) to demonstrate its functionality. The final output represents the maximum amount of money the robber can steal without triggering the security system.", - "metadata": {}, - "id": "ece39324-cd9e-47d7-8677-a001878494d9" - }, - { - "cell_type": "markdown", - "source": "## Test cases:\n\nHere's how you can use this solution:", - "metadata": {}, - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244" - }, - { - "cell_type": "code", - "source": "# Example 1:\n\n# Create an instance of the Solution class\nsolution = Solution()\n\nnums1 = [2, 3, 2]\nprint(solution.rob(nums1)) # Output: 3", - "metadata": { - "trusted": true - }, - "execution_count": 8, - "outputs": [ - { - "name": "stdout", - "text": "3\n", - "output_type": "stream" - } - ], - "id": "f12c5a63-b811-4be7-83c2-34ee396b546c" - }, - { - "cell_type": "code", - "source": "# Example 2:\nnums2 = [1, 2, 3, 1]\nprint(solution.rob(nums2)) # Output: 4", - "metadata": { - "trusted": true - }, - "execution_count": 9, - "outputs": [ - { - "name": "stdout", - "text": "4\n", - "output_type": "stream" - } - ], - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3" - }, - { - "cell_type": "code", - "source": "# Example 2:\nnums3 = [1, 2, 3]\nprint(solution.rob(nums3)) # Output: 3", - "metadata": { - "trusted": true - }, - "execution_count": 10, - "outputs": [ - { - "name": "stdout", - "text": "3\n", - "output_type": "stream" - } - ], - "id": "e6e1554f-ae77-410c-8af2-e59e5428166c" - }, - { - "cell_type": "markdown", - "source": "## Time and Space Complexity Analysis\n\nLet's analyze the time and space complexity of the provided code:\n\n### Time Complexity:\nThe time complexity is primarily determined by the `simple_rob` helper function, which has a time complexity of O(N), where N is the number of houses in the input array. The main `rob` function calls `simple_rob` twice, once for the case of robbing the first house and not robbing the last, and once for the case of not robbing the first house and robbing the last. Therefore, the overall time complexity is O(N).\n\n### Space Complexity:\nThe space complexity is O(1) because the space used by the algorithm is constant, regardless of the size of the input array. The only variables used are `prev` and `curr` in the `simple_rob` function, which represent the previous and current maximum amounts of money that can be robbed without alerting the police. These variables are updated iteratively, and no additional data structures are used that scale with the input size. Therefore, the space complexity is constant, or O(1).\n\nIn summary:\n- Time Complexity: O(N)\n- Space Complexity: O(1)", - "metadata": {}, - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2" - }, - { - "cell_type": "markdown", - "source": "## Challenging Exercises:\n\n1. **Optimization Challenge:** Optimize the space complexity of the solution. Can you solve the problem with O(1) space complexity without sacrificing the time complexity?\n\n2. **Circular Robbery Variations:** Consider variations of the circular house robbery problem, such as allowing the robber to skip a certain number of houses or restricting the number of consecutive houses that can be robbed. Modify the solution to accommodate these variations.\n\n**Link to Problem:** [To see the House Robber II problem on LeetCode, click here!](https://leetcode.com/problems/house-robber-ii/)", - "metadata": {}, - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6" - } - ] -} \ No newline at end of file diff --git a/docs/13. One-D Dynamic Programming/70. Climbing Stairs.ipynb b/docs/13. One-D Dynamic Programming/70. Climbing Stairs.ipynb deleted file mode 100644 index b727489..0000000 --- a/docs/13. One-D Dynamic Programming/70. Climbing Stairs.ipynb +++ /dev/null @@ -1,210 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 70. Climbing Stairs\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Climbing Stairs problem on LeetCode, click here!](https://leetcode.com/problems/climbing-stairs/)\n", - "\n", - "---\n", - "You are climbing a staircase. It takes `n` steps to reach the top.\n", - "\n", - "Each time you can either climb `1` or `2` steps. In how many distinct ways can you climb to the top?\n", - "\n", - "**Constraints:**\n", - "- `1 <= n <= 45`" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The \"Climbing Stairs\" problem is a classic algorithmic problem that asks you to find the number of distinct ways to climb a staircase with a given number of steps. Here's the problem statement:\n", - "\n", - "You are given a staircase with 'n' steps. Each time you can either climb 1 step or 2 steps. You need to find out how many distinct ways there are to reach the top of the staircase.\n", - "\n", - "For example, if 'n' is 2, there are two ways to climb to the top:\n", - "\n", - "1. Climbing two steps at once.\n", - "2. Climbing one step, and then another step.\n", - "\n", - "If 'n' is 3, there are three ways:\n", - "\n", - "1. Climbing one step, then one step, and finally one step.\n", - "2. Climbing one step, then two steps.\n", - "3. Climbing two steps, then one step.\n", - "\n", - "The problem essentially asks you to find a solution that counts the possible combinations of 1-step and 2-step climbs that can be taken to reach the top of the staircase. It's a classic example of a dynamic programming problem where you can break it down into smaller subproblems and build a solution incrementally, as shown in the code I provided earlier.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class Solution:\n", - " def climbStairs(self, n: int) -> int:\n", - " # If there are 1 or 2 steps, there are exactly n ways to reach the top.\n", - " if n <= 2:\n", - " return n\n", - "\n", - " # Create an array to store the number of ways to reach each step.\n", - " dp = [0] * (n + 1)\n", - "\n", - " # There is one way to reach the first step (base case).\n", - " dp[1] = 1\n", - "\n", - " # There are two ways to reach the second step (base case).\n", - " dp[2] = 2\n", - "\n", - " # Calculate the number of ways to reach each step from the previous steps.\n", - " for i in range(3, n + 1):\n", - " # The number of ways to reach step 'i' is the sum of the ways to reach\n", - " # the previous two steps, as you can take 1 or 2 steps at a time.\n", - " dp[i] = dp[i - 1] + dp[i - 2]\n", - "\n", - " # The result is the number of ways to reach the top, which is stored in dp[n].\n", - " return dp[n]" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The code defines a class `Solution` with a method `climbStairs` that takes an integer `n` as input and returns the number of distinct ways to climb a staircase with `n` steps.\n", - "\n", - "1. If `n` is 1 or 2, the function returns `n` directly because there are only 1 or 2 distinct ways to reach the top in those cases.\n", - "\n", - "2. For `n` greater than 2, the code uses dynamic programming to calculate the number of ways to reach each step. It creates an array `dp` of length `n + 1` to store these values.\n", - "\n", - "3. The `dp[1]` and `dp[2]` are initialized to 1 and 2, respectively. This is because there is only one way to reach the first step (by taking 1 step), and there are two ways to reach the second step (by taking 2 steps or two 1-step climbs).\n", - "\n", - "4. The code then uses a loop to fill in the `dp` array for steps 3 and above. For each step `i` from 3 to `n`, it calculates the number of ways to reach that step by adding the number of ways to reach the previous two steps, as you can either take 1 step or 2 steps at a time.\n", - "\n", - "5. Finally, the function returns the value stored in `dp[n]`, which represents the total number of distinct ways to climb the staircase with `n` steps." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "f12c5a63-b811-4be7-83c2-34ee396b546c", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Example 1 - Input: n = 2, Output: 2\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "n = 2\n", - "solution = Solution()\n", - "print(f\"Example 1 - Input: n = {n}, Output: {solution.climbStairs(n)}\") # Output should be 2" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Example 2 - Input: n = 3, Output: 3\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "n = 3\n", - "print(f\"Example 2 - Input: n = {n}, Output: {solution.climbStairs(n)}\") # Output should be 3\n" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Time Complexity:\n", - "The time complexity of the solution is O(n) because we use a single for loop that iterates from 3 to n to fill the `dp` array. In each iteration, we perform constant time operations (addition and assignment). Therefore, the time complexity is linear with respect to the input value `n`.\n", - "\n", - "Space Complexity:\n", - "The space complexity of the solution is O(n) as well. We use an array `dp` of length `n + 1` to store the number of ways to reach each step. The size of this array is directly proportional to the input value `n`, which makes the space complexity linear in terms of `n`. The rest of the variables used in the function (e.g., `i`) occupy constant space and do not contribute significantly to the overall space complexity.\n", - "\n", - "In summary, the time complexity is O(n), and the space complexity is O(n) for this dynamic programming solution to the \"Climbing Stairs\" problem." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Generalized Step Sizes**: Instead of being limited to 1 step or 2 steps, consider a scenario where you can take steps of sizes `[1, 2, 3]`. Implement a function that calculates the number of ways to climb the staircase with these different step sizes.\n", - "\n", - "2. **Minimize Steps**: Given an integer `n`, find the minimum number of steps required to reach the top of the staircase. Return both the minimum number of steps and the specific sequence of steps taken." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/13. One-D Dynamic Programming/README.md b/docs/13. One-D Dynamic Programming/README.md deleted file mode 100644 index 73f4de3..0000000 --- a/docs/13. One-D Dynamic Programming/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# 1-D Dynamic Programming Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [70. Climbing Stairs](https://leetcode.com/problems/climbing-stairs/) | Easy | -| [198. House Robber](https://leetcode.com/problems/house-robber/) | Medium | -| [213. House Robber II](https://leetcode.com/problems/house-robber-ii/) | Medium | -| [5. Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/) | Medium | -| [647. Palindromic Substrings](https://leetcode.com/problems/palindromic-substrings/) | Medium | -| [91. Decode Ways](https://leetcode.com/problems/decode-ways/) | Medium | -| [322. Coin Change](https://leetcode.com/problems/coin-change/) | Medium | -| [152. Maximum Product Subarray](https://leetcode.com/problems/maximum-product-subarray/) | Medium | -| [139. Word Break](https://leetcode.com/problems/word-break/) | Medium | -| [300. Longest Increasing Subsequence](https://leetcode.com/problems/longest-increasing-subsequence/) | Medium | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! \ No newline at end of file diff --git a/docs/14. Two-D Dynamic Programming/README.md b/docs/14. Two-D Dynamic Programming/README.md deleted file mode 100644 index 8bab876..0000000 --- a/docs/14. Two-D Dynamic Programming/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# Blind 75 LeetCode Problems - -This repository contains a curated list of 75 LeetCode problems that are commonly known as the "Blind 75." These problems cover a wide range of data structures and algorithms and are frequently asked in technical interviews. Solving these problems can help you build a strong foundation in algorithmic problem-solving. - -## Problem List - -### 2-D Dynamic Programming - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [62. Unique Paths](https://leetcode.com/problems/unique-paths/) | Medium | -| [1143. Longest Common Subsequence](https://leetcode.com/problems/longest-common-subsequence/) | Medium | - -## How to Use - -1. Clone or download this repository to your local machine. - -```bash -git clone https://github.com/mohsentabibian/LeetCode-Solutions/Blind-75-LeetCode.git -``` - -2. Navigate to the directory of the specific problem you want to solve. - -```bash -cd Blind-75-LeetCode/Problem-Directory -``` - -3. Open the problem's directory to find its description, code template, and solution(s). - -4. Solve the problem using your preferred programming language. - -5. Check the solution(s) provided in the directory for reference and to compare your solution. - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -## Disclaimer - -This repository is meant for educational purposes and to help individuals prepare for technical interviews. Please respect LeetCode's terms of use and guidelines when using this repository. - -Happy coding! \ No newline at end of file diff --git a/docs/15. Greedy/README.md b/docs/15. Greedy/README.md deleted file mode 100644 index 82b6543..0000000 --- a/docs/15. Greedy/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# Blind 75 LeetCode Problems - -This repository contains a curated list of 75 LeetCode problems that are commonly known as the "Blind 75." These problems cover a wide range of data structures and algorithms and are frequently asked in technical interviews. Solving these problems can help you build a strong foundation in algorithmic problem-solving. - -## Problem List - -### Greedy - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [53. Maximum Subarray](https://leetcode.com/problems/maximum-subarray/) | Easy | -| [55. Jump Game](https://leetcode.com/problems/jump-game/) | Medium | - -## How to Use - -1. Clone or download this repository to your local machine. - -```bash -git clone https://github.com/mohsentabibian/LeetCode-Solutions/Blind-75-LeetCode.git -``` - -2. Navigate to the directory of the specific problem you want to solve. - -```bash -cd Blind-75-LeetCode/Problem-Directory -``` - -3. Open the problem's directory to find its description, code template, and solution(s). - -4. Solve the problem using your preferred programming language. - -5. Check the solution(s) provided in the directory for reference and to compare your solution. - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -## Disclaimer - -This repository is meant for educational purposes and to help individuals prepare for technical interviews. Please respect LeetCode's terms of use and guidelines when using this repository. - -Happy coding! \ No newline at end of file diff --git a/docs/16. Intervals/README.md b/docs/16. Intervals/README.md deleted file mode 100644 index a57713e..0000000 --- a/docs/16. Intervals/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# Blind 75 LeetCode Problems - -This repository contains a curated list of 75 LeetCode problems that are commonly known as the "Blind 75." These problems cover a wide range of data structures and algorithms and are frequently asked in technical interviews. Solving these problems can help you build a strong foundation in algorithmic problem-solving. - -## Problem List - -### Intervals - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [57. Insert Interval](https://leetcode.com/problems/insert-interval/) | Hard | -| [56. Merge Intervals](https://leetcode.com/problems/merge-intervals/) | Medium | -| [435. Non Overlapping Intervals](https://leetcode.com/problems/non-overlapping-intervals/) | Medium | -| [252. Meeting Rooms](https://leetcode.com/problems/meeting-rooms/) | Easy | -| [253. Meeting Rooms II](https://leetcode.com/problems/meeting-rooms-ii/) | Medium | - -## How to Use - -1. Clone or download this repository to your local machine. - -```bash -git clone https://github.com/mohsentabibian/LeetCode-Solutions/Blind-75-LeetCode.git -``` - -2. Navigate to the directory of the specific problem you want to solve. - -```bash -cd Blind-75-LeetCode/Problem-Directory -``` - -3. Open the problem's directory to find its description, code template, and solution(s). - -4. Solve the problem using your preferred programming language. - -5. Check the solution(s) provided in the directory for reference and to compare your solution. - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -## Disclaimer - -This repository is meant for educational purposes and to help individuals prepare for technical interviews. Please respect LeetCode's terms of use and guidelines when using this repository. - -Happy coding! \ No newline at end of file diff --git a/docs/17. Math Geometry/README.md b/docs/17. Math Geometry/README.md deleted file mode 100644 index 8b2f180..0000000 --- a/docs/17. Math Geometry/README.md +++ /dev/null @@ -1,48 +0,0 @@ -# Blind 75 LeetCode Problems - -This repository contains a curated list of 75 LeetCode problems that are commonly known as the "Blind 75." These problems cover a wide range of data structures and algorithms and are frequently asked in technical interviews. Solving these problems can help you build a strong foundation in algorithmic problem-solving. - -## Problem List - -### Math & Geometry - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [48. Rotate Image](https://leetcode.com/problems/rotate-image/) | Medium | -| [54. Spiral Matrix](https://leetcode.com/problems/spiral-matrix/) | Medium | -| [73. Set Matrix Zeroes](https://leetcode.com/problems/set-matrix-zeroes/) | Medium | - -## How to Use - -1. Clone or download this repository to your local machine. - -```bash -git clone https://github.com/mohsentabibian/LeetCode-Solutions/Blind-75-LeetCode.git -``` - -2. Navigate to the directory of the specific problem you want to solve. - -```bash -cd Blind-75-LeetCode/Problem-Directory -``` - -3. Open the problem's directory to find its description, code template, and solution(s). - -4. Solve the problem using your preferred programming language. - -5. Check the solution(s) provided in the directory for reference and to compare your solution. - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -## Disclaimer - -This repository is meant for educational purposes and to help individuals prepare for technical interviews. Please respect LeetCode's terms of use and guidelines when using this repository. - -Happy coding! \ No newline at end of file diff --git a/docs/18. Bit Manipulation/README.md b/docs/18. Bit Manipulation/README.md deleted file mode 100644 index 05b2fef..0000000 --- a/docs/18. Bit Manipulation/README.md +++ /dev/null @@ -1,51 +0,0 @@ -# Blind 75 LeetCode Problems - -This repository contains a curated list of 75 LeetCode problems that are commonly known as the "Blind 75." These problems cover a wide range of data structures and algorithms and are frequently asked in technical interviews. Solving these problems can help you build a strong foundation in algorithmic problem-solving. - -## Problem List - -### Bit Manupulation - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [191. Number of 1 Bits](https://leetcode.com/problems/number-of-1-bits/) | Easy | -| [338. Counting Bits](https://leetcode.com/problems/counting-bits/) | Medium | -| [190. Reverse Bits](https://leetcode.com/problems/reverse-bits/) | Easy | -| [268. Missing Number](https://leetcode.com/problems/missing-number/) | Easy | -| [371. Sum of Two Integers](https://leetcode.com/problems/sum-of-two-integers/) | Medium | - - -## How to Use - -1. Clone or download this repository to your local machine. - -```bash -git clone https://github.com/mohsentabibian/LeetCode-Solutions/Blind-75-LeetCode.git -``` - -2. Navigate to the directory of the specific problem you want to solve. - -```bash -cd Blind-75-LeetCode/Problem-Directory -``` - -3. Open the problem's directory to find its description, code template, and solution(s). - -4. Solve the problem using your preferred programming language. - -5. Check the solution(s) provided in the directory for reference and to compare your solution. - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -## Disclaimer - -This repository is meant for educational purposes and to help individuals prepare for technical interviews. Please respect LeetCode's terms of use and guidelines when using this repository. - -Happy coding! \ No newline at end of file diff --git a/docs/Book.ipynb b/docs/Book.ipynb deleted file mode 100644 index e7b4f46..0000000 --- a/docs/Book.ipynb +++ /dev/null @@ -1,400 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "!python -m pip install --upgrade pip\n", - "%pip install jupyter-book" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions\n" - ] - } - ], - "source": [ - "%cd /workspaces/LeetCode-Solutions" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "!jupyter-book toc migrate /workspaces/LeetCode-Solutions/_toc.yml -o /workspaces/LeetCode-Solutions/_toc.yml" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[32m\u001b[1mRunning Jupyter-Book v0.15.1\u001b[0m\n", - "\u001b[34m\u001b[1mSource Folder: \u001b[0m/workspaces/LeetCode-Solutions\n", - "\u001b[34m\u001b[1mConfig Path: \u001b[0m/workspaces/LeetCode-Solutions/_config.yml\n", - "\u001b[34m\u001b[1mOutput Path: \u001b[0m/workspaces/LeetCode-Solutions/_build/html\n", - "\u001b[01mRunning Sphinx v5.0.2\u001b[39;49;00m\n", - "\u001b[01mmaking output directory... \u001b[39;49;00mdone\n", - "[etoc] Changing master_doc to 'README'\n", - "\u001b[01mmyst v0.18.1:\u001b[39;49;00m MdParserConfig(commonmark_only=False, gfm_only=False, enable_extensions=['colon_fence', 'dollarmath', 'linkify', 'substitution', 'tasklist'], disable_syntax=[], all_links_external=False, url_schemes=['mailto', 'http', 'https'], ref_domains=None, highlight_code_blocks=True, number_code_blocks=[], title_to_header=False, heading_anchors=None, heading_slug_func=None, footnote_transition=True, words_per_minute=200, sub_delimiters=('{', '}'), linkify_fuzzy_links=True, dmath_allow_labels=True, dmath_allow_space=True, dmath_allow_digits=True, dmath_double_inline=False, update_mathjax=True, mathjax_classes='tex2jax_process|mathjax_process|math|output_area')\n", - "\u001b[01mmyst-nb v0.17.2:\u001b[39;49;00m NbParserConfig(custom_formats={}, metadata_key='mystnb', cell_metadata_key='mystnb', kernel_rgx_aliases={}, execution_mode='auto', execution_cache_path='', execution_excludepatterns=[], execution_timeout=30, execution_in_temp=False, execution_allow_errors=False, execution_raise_on_error=False, execution_show_tb=False, merge_streams=False, render_plugin='default', remove_code_source=False, remove_code_outputs=False, code_prompt_show='Show code cell {type}', code_prompt_hide='Hide code cell {type}', number_source_lines=False, output_stderr='show', render_text_lexer='myst-ansi', render_error_lexer='ipythontb', render_image_options={}, render_figure_options={}, render_markdown_format='commonmark', output_folder='build', append_css=True, metadata_to_fm=False)\n", - "Using jupyter-cache at: /workspaces/LeetCode-Solutions/_build/.jupyter_cache\n", - "\u001b[01mbuilding [mo]: \u001b[39;49;00mtargets for 0 po files that are out of date\n", - "\u001b[01mbuilding [html]: \u001b[39;49;00mtargets for 77 source files that are out of date\n", - "\u001b[01mupdating environment: \u001b[39;49;00m[new config] 77 added, 0 changed, 0 removed\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/1. Two Sum.ipynb: Executing notebook using local CWD [mystnb] \n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/1. Two Sum.ipynb: Executed notebook in 1.26 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/128. Longest Consecutive Sequence.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/128. Longest Consecutive Sequence.ipynb: Executed notebook in 1.07 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/217. Contains Duplicate.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/217. Contains Duplicate.ipynb: Executed notebook in 1.05 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/238. Product of Array Except Self.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/238. Product of Array Except Self.ipynb: Executed notebook in 0.98 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/242. Valid Anagram.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/242. Valid Anagram.ipynb: Executed notebook in 0.96 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/347. Top K Frequent Elements.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/347. Top K Frequent Elements.ipynb: Executed notebook in 1.00 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/49. Group Anagrams.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/49. Group Anagrams.ipynb: Executed notebook in 1.07 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/659. Encode and Decode Strings.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/659. Encode and Decode Strings.ipynb: Executed notebook in 0.93 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/02. Two Pointers/11. Container With Most Water.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/02. Two Pointers/11. Container With Most Water.ipynb: Executed notebook in 0.88 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/02. Two Pointers/125. Valid Palindrome.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/02. Two Pointers/125. Valid Palindrome.ipynb: Executed notebook in 0.98 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/02. Two Pointers/15. 3Sum.ipynb: Executing notebook using local CWD [mystnb] \n", - "/workspaces/LeetCode-Solutions/02. Two Pointers/15. 3Sum.ipynb: Executed notebook in 1.08 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/03. Sliding Window/121. Best Time to Buy and Sell Stock.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/03. Sliding Window/121. Best Time to Buy and Sell Stock.ipynb: Executed notebook in 0.92 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/03. Sliding Window/3. Longest Substring Without Repeating Characters.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/03. Sliding Window/3. Longest Substring Without Repeating Characters.ipynb: Executed notebook in 0.90 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/03. Sliding Window/424. Longest Repeating Character Replacement.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/03. Sliding Window/424. Longest Repeating Character Replacement.ipynb: Executed notebook in 1.09 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/03. Sliding Window/76. Minimum Window Substring.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/03. Sliding Window/76. Minimum Window Substring.ipynb: Executed notebook in 1.09 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/04. Stack/20. Valid Parentheses.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/04. Stack/20. Valid Parentheses.ipynb: Executed notebook in 0.98 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/05. Binary Search/153. Find Minimum in Rotated Sorted Array.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/05. Binary Search/153. Find Minimum in Rotated Sorted Array.ipynb: Executed notebook in 1.15 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/05. Binary Search/33. Search in Rotated Sorted Array.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/05. Binary Search/33. Search in Rotated Sorted Array.ipynb: Executed notebook in 1.08 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/141. Linked List Cycle.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/141. Linked List Cycle.ipynb: Executed notebook in 1.28 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/143. Reorder List.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/143. Reorder List.ipynb: Executed notebook in 1.01 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/19. Remove Nth Node From End of List.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/19. Remove Nth Node From End of List.ipynb: Executed notebook in 1.10 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/206. Reverse Linked List.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/206. Reverse Linked List.ipynb: Executed notebook in 1.14 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/21. Merge Two Sorted Lists.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/21. Merge Two Sorted Lists.ipynb: Executed notebook in 0.91 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/23. Merge k Sorted Lists.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/23. Merge k Sorted Lists.ipynb: Executed notebook in 1.13 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/100. Same Tree.ipynb: Executing notebook using local CWD [mystnb] \n", - "/workspaces/LeetCode-Solutions/07. Trees/100. Same Tree.ipynb: Executed notebook in 1.07 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/102. Binary Tree Level Order Traversal.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/102. Binary Tree Level Order Traversal.ipynb: Executed notebook in 0.99 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/104. Maximum Depth of Binary Tree.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/104. Maximum Depth of Binary Tree.ipynb: Executed notebook in 0.91 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.ipynb: Executed notebook in 1.17 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/124. Binary Tree Maximum Path Sum.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/124. Binary Tree Maximum Path Sum.ipynb: Executed notebook in 0.99 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/199. Binary Tree Right Side View.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/199. Binary Tree Right Side View.ipynb: Executed notebook in 1.07 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/226. Invert Binary Tree.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/226. Invert Binary Tree.ipynb: Executed notebook in 0.96 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/230. Kth Smallest Element in a BST.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/230. Kth Smallest Element in a BST.ipynb: Executed notebook in 0.98 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.ipynb: Executed notebook in 1.11 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/297. Serialize and Deserialize Binary Tree.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/297. Serialize and Deserialize Binary Tree.ipynb: Executed notebook in 0.98 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/572. Subtree of Another Tree.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/572. Subtree of Another Tree.ipynb: Executed notebook in 1.16 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/98. Validate Binary Search Tree.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/98. Validate Binary Search Tree.ipynb: Executed notebook in 1.15 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/08. Tries/208. Implement Trie (Prefix Tree).ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/08. Tries/208. Implement Trie (Prefix Tree).ipynb: Executed notebook in 0.98 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/08. Tries/211. Design Add and Search Words Data Structure.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/08. Tries/211. Design Add and Search Words Data Structure.ipynb: Executed notebook in 1.05 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/08. Tries/212. Word Search II.ipynb: Executing notebook using local CWD [mystnb] \n", - "/workspaces/LeetCode-Solutions/08. Tries/212. Word Search II.ipynb: Executed notebook in 1.27 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/09. Heap - Priority Queue/1046. Last Stone Weight.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/09. Heap - Priority Queue/1046. Last Stone Weight.ipynb: Executed notebook in 0.93 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/09. Heap - Priority Queue/295. Find Median from Data Stream.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/09. Heap - Priority Queue/295. Find Median from Data Stream.ipynb: Executed notebook in 1.06 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.ipynb: Executed notebook in 0.87 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/10. Backtracking/39. Combination Sum.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/10. Backtracking/39. Combination Sum.ipynb: Executed notebook in 1.24 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/10. Backtracking/79. Word Search.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/10. Backtracking/79. Word Search.ipynb: Executed notebook in 4.03 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/133. Clone Graph.ipynb: Executing notebook using local CWD [mystnb] \n", - "/workspaces/LeetCode-Solutions/11. Graphs/133. Clone Graph.ipynb: Executed notebook in 1.08 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/178. Graph Valid Tree.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/178. Graph Valid Tree.ipynb: Executed notebook in 1.12 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/200. Number of Islands.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/200. Number of Islands.ipynb: Executed notebook in 1.08 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/207. Course Schedule.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/207. Course Schedule.ipynb: Executed notebook in 1.09 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/3651. Number of Connected Components in an Undirected Graph.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/3651. Number of Connected Components in an Undirected Graph.ipynb: Executed notebook in 4.02 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/417. Pacific Atlantic Water Flow.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/417. Pacific Atlantic Water Flow.ipynb: Executed notebook in 0.87 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/12. Advanced Graphs/892. Alien Dictionary.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/12. Advanced Graphs/892. Alien Dictionary.ipynb: Executed notebook in 1.12 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/13. One-D Dynamic Programming/198. House Robber.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/13. One-D Dynamic Programming/198. House Robber.ipynb: Executed notebook in 0.99 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/13. One-D Dynamic Programming/213. House Robber II.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/13. One-D Dynamic Programming/213. House Robber II.ipynb: Executed notebook in 1.08 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/13. One-D Dynamic Programming/70. Climbing Stairs.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/13. One-D Dynamic Programming/70. Climbing Stairs.ipynb: Executed notebook in 1.06 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/Book.ipynb: Executing notebook using local CWD [mystnb] \n", - "\u001b[01mreading sources... \u001b[39;49;00m[100%] \u001b[35mSECURITY\u001b[39;49;00m \n", - "\u001b[91m/workspaces/LeetCode-Solutions/07. Trees/572. Subtree of Another Tree.ipynb:30008: WARNING: Non-consecutive header level increase; H1 to H3 [myst.header]\u001b[39;49;00m\n", - "\u001b[91m/workspaces/LeetCode-Solutions/Book.ipynb: WARNING: Executing notebook failed: CellTimeoutError [mystnb.exec]\u001b[39;49;00m\n", - "\u001b[91m/workspaces/LeetCode-Solutions/Book.ipynb: WARNING: Notebook exception traceback saved in: /workspaces/LeetCode-Solutions/_build/html/reports/Book.err.log [mystnb.exec]\u001b[39;49;00m\n", - "\u001b[01mlooking for now-outdated files... \u001b[39;49;00mnone found\n", - "\u001b[01mpickling environment... \u001b[39;49;00mdone\n", - "\u001b[01mchecking consistency... \u001b[39;49;00m\u001b[91m/workspaces/LeetCode-Solutions/Book.ipynb: WARNING: document isn't included in any toctree\u001b[39;49;00m\n", - "\u001b[91m/workspaces/LeetCode-Solutions/CODE_OF_CONDUCT.md: WARNING: document isn't included in any toctree\u001b[39;49;00m\n", - "\u001b[91m/workspaces/LeetCode-Solutions/CONTRIBUTING.md: WARNING: document isn't included in any toctree\u001b[39;49;00m\n", - "\u001b[91m/workspaces/LeetCode-Solutions/SECURITY.md: WARNING: document isn't included in any toctree\u001b[39;49;00m\n", - "done\n", - "\u001b[01mpreparing documents... \u001b[39;49;00mdone\n", - "\u001b[01mwriting output... \u001b[39;49;00m[100%] \u001b[32mSECURITY\u001b[39;49;00m raph\u001b[39;49;00m0m\n", - "\u001b[91m/workspaces/LeetCode-Solutions/CONTRIBUTING.md:8: WARNING: 'myst' reference target not found: #ways-to-contribute\u001b[39;49;00m\n", - "\u001b[91m/workspaces/LeetCode-Solutions/CONTRIBUTING.md:9: WARNING: 'myst' reference target not found: #getting-started\u001b[39;49;00m\n", - "\u001b[91m/workspaces/LeetCode-Solutions/CONTRIBUTING.md:10: WARNING: 'myst' reference target not found: #contributing-process\u001b[39;49;00m\n", - "\u001b[91m/workspaces/LeetCode-Solutions/CONTRIBUTING.md:11: WARNING: 'myst' reference target not found: #code-of-conduct\u001b[39;49;00m\n", - "\u001b[01mgenerating indices... \u001b[39;49;00mgenindex done\n", - "\u001b[01mwriting additional pages... \u001b[39;49;00msearch done\n", - "\u001b[01mcopying static files... \u001b[39;49;00mdone\n", - "\u001b[01mcopying extra files... \u001b[39;49;00mdone\n", - "\u001b[01mdumping search index in English (code: en)... \u001b[39;49;00mdone\n", - "\u001b[01mdumping object inventory... \u001b[39;49;00mdone\n", - "[etoc] missing index.html written as redirect to 'README.html'\n", - "\u001b[01mbuild succeeded, 11 warnings.\u001b[39;49;00m\n", - "\n", - "The HTML pages are in _build/html.\n", - "\n", - "\u001b[92m===============================================================================\u001b[0m\n", - "\n", - "Finished generating HTML for book.\n", - "Your book's HTML pages are here:\n", - " _build/html/\n", - "You can look at your book by opening this file in a browser:\n", - " _build/html/index.html\n", - "Or paste this line directly into your browser bar:\n", - " file:///workspaces/LeetCode-Solutions/_build/html/index.html \n", - "\n", - "\u001b[92m===============================================================================\u001b[0m\n", - "\n" - ] - } - ], - "source": [ - "!jupyter-book build ." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "!jupyter-book build /workspaces/LeetCode-Solutions/ --builder pdfhtml" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "Click here to view your Jupyter Book" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from IPython.display import HTML\n", - "HTML('Click here to view your Jupyter Book')\n" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "\u001b[92m===============================================================================\u001b[0m\n", - "\n", - "Your book template can be found at\n", - "\n", - " mybook/\n", - "\n", - "\u001b[92m===============================================================================\u001b[0m\n", - "\n" - ] - } - ], - "source": [ - "!jupyter-book create mybook" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[32m\u001b[1mRunning Jupyter-Book v0.15.1\u001b[0m\n", - "\u001b[34m\u001b[1mSource Folder: \u001b[0m/workspaces/LeetCode-Solutions/mybook\n", - "\u001b[34m\u001b[1mConfig Path: \u001b[0m/workspaces/LeetCode-Solutions/mybook/_config.yml\n", - "\u001b[34m\u001b[1mOutput Path: \u001b[0m/workspaces/LeetCode-Solutions/mybook/_build/html\n", - "[sphinxcontrib-bibtex] Beware that docutils versions 0.18 and 0.19 (you are running 0.18.1) are known to generate invalid html for citations. If this issue affects you, please use docutils<0.18 (or >=0.20 once released) instead. For more details, see https://sourceforge.net/p/docutils/patches/195/\n", - "\u001b[01mRunning Sphinx v5.0.2\u001b[39;49;00m\n", - "[etoc] Changing master_doc to 'intro'\n", - "checking bibtex cache... out of date\n", - "parsing bibtex file /workspaces/LeetCode-Solutions/mybook/references.bib... parsed 5 entries\n", - "\u001b[01mmyst v0.18.1:\u001b[39;49;00m MdParserConfig(commonmark_only=False, gfm_only=False, enable_extensions=['colon_fence', 'dollarmath', 'linkify', 'substitution', 'tasklist'], disable_syntax=[], all_links_external=False, url_schemes=['mailto', 'http', 'https'], ref_domains=None, highlight_code_blocks=True, number_code_blocks=[], title_to_header=False, heading_anchors=None, heading_slug_func=None, footnote_transition=True, words_per_minute=200, sub_delimiters=('{', '}'), linkify_fuzzy_links=True, dmath_allow_labels=True, dmath_allow_space=True, dmath_allow_digits=True, dmath_double_inline=False, update_mathjax=True, mathjax_classes='tex2jax_process|mathjax_process|math|output_area')\n", - "\u001b[01mmyst-nb v0.17.2:\u001b[39;49;00m NbParserConfig(custom_formats={}, metadata_key='mystnb', cell_metadata_key='mystnb', kernel_rgx_aliases={}, execution_mode='force', execution_cache_path='', execution_excludepatterns=[], execution_timeout=30, execution_in_temp=False, execution_allow_errors=False, execution_raise_on_error=False, execution_show_tb=False, merge_streams=False, render_plugin='default', remove_code_source=False, remove_code_outputs=False, code_prompt_show='Show code cell {type}', code_prompt_hide='Hide code cell {type}', number_source_lines=False, output_stderr='show', render_text_lexer='myst-ansi', render_error_lexer='ipythontb', render_image_options={}, render_figure_options={}, render_markdown_format='commonmark', output_folder='build', append_css=True, metadata_to_fm=False)\n", - "Using jupyter-cache at: /workspaces/LeetCode-Solutions/mybook/_build/.jupyter_cache\n", - "\u001b[01mbuilding [mo]: \u001b[39;49;00mtargets for 0 po files that are out of date\n", - "\u001b[01mbuilding [html]: \u001b[39;49;00mtargets for 14 source files that are out of date\n", - "\u001b[01mupdating environment: \u001b[39;49;00m[new config] 14 added, 0 changed, 0 removed\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/1. Two Sum.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/1. Two Sum.ipynb: Executed notebook in 1.35 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/128. Longest Consecutive Sequence.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/128. Longest Consecutive Sequence.ipynb: Executed notebook in 1.09 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/217. Contains Duplicate.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/217. Contains Duplicate.ipynb: Executed notebook in 1.04 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/238. Product of Array Except Self.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/238. Product of Array Except Self.ipynb: Executed notebook in 4.02 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/242. Valid Anagram.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/242. Valid Anagram.ipynb: Executed notebook in 0.97 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/347. Top K Frequent Elements.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/347. Top K Frequent Elements.ipynb: Executed notebook in 1.14 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/49. Group Anagrams.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/49. Group Anagrams.ipynb: Executed notebook in 0.88 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/659. Encode and Decode Strings.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/659. Encode and Decode Strings.ipynb: Executed notebook in 1.10 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/11. Container With Most Water.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/11. Container With Most Water.ipynb: Executed notebook in 1.12 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/125. Valid Palindrome.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/125. Valid Palindrome.ipynb: Executed notebook in 0.98 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/15. 3Sum.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/15. 3Sum.ipynb: Executed notebook in 0.83 seconds [mystnb]\n", - "\u001b[01mreading sources... \u001b[39;49;00m[100%] \u001b[35mintro\u001b[39;49;00m \n", - "\u001b[01mlooking for now-outdated files... \u001b[39;49;00mnone found\n", - "\u001b[01mpickling environment... \u001b[39;49;00mdone\n", - "\u001b[01mchecking consistency... \u001b[39;49;00m\u001b[91m/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/README.md: WARNING: document isn't included in any toctree\u001b[39;49;00m\n", - "\u001b[91m/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/README.md: WARNING: document isn't included in any toctree\u001b[39;49;00m\n", - "done\n", - "\u001b[01mpreparing documents... \u001b[39;49;00mdone\n", - "\u001b[01mwriting output... \u001b[39;49;00m[100%] \u001b[32mintro\u001b[39;49;00m \n", - "\u001b[01mgenerating indices... \u001b[39;49;00mgenindex done\n", - "\u001b[01mwriting additional pages... \u001b[39;49;00msearch done\n", - "\u001b[01mcopying static files... \u001b[39;49;00mdone\n", - "\u001b[01mcopying extra files... \u001b[39;49;00mdone\n", - "\u001b[01mdumping search index in English (code: en)... \u001b[39;49;00mdone\n", - "\u001b[01mdumping object inventory... \u001b[39;49;00mdone\n", - "[etoc] missing index.html written as redirect to 'intro.html'\n", - "\u001b[01mbuild succeeded, 2 warnings.\u001b[39;49;00m\n", - "\n", - "The HTML pages are in mybook/_build/html.\n", - "\n", - "\u001b[92m===============================================================================\u001b[0m\n", - "\n", - "Finished generating HTML for book.\n", - "Your book's HTML pages are here:\n", - " mybook/_build/html/\n", - "You can look at your book by opening this file in a browser:\n", - " mybook/_build/html/index.html\n", - "Or paste this line directly into your browser bar:\n", - " file:///workspaces/LeetCode-Solutions/mybook/_build/html/index.html \n", - "\n", - "\u001b[92m===============================================================================\u001b[0m\n", - "\n" - ] - } - ], - "source": [ - "!jupyter-book build mybook" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "format: jb-book\n", - "root: intro\n", - "\n" - ] - } - ], - "source": [ - "!jupyter-book toc from-project /workspaces/LeetCode-Solutions/mybook/ -f jb-book" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/docs/CODE_OF_CONDUCT.md b/docs/CODE_OF_CONDUCT.md deleted file mode 100644 index 5fe5041..0000000 --- a/docs/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,128 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -We as members, contributors, and leaders pledge to make participation in our -community a harassment-free experience for everyone, regardless of age, body -size, visible or invisible disability, ethnicity, sex characteristics, gender -identity and expression, level of experience, education, socio-economic status, -nationality, personal appearance, race, religion, or sexual identity -and orientation. - -We pledge to act and interact in ways that contribute to an open, welcoming, -diverse, inclusive, and healthy community. - -## Our Standards - -Examples of behavior that contributes to a positive environment for our -community include: - -* Demonstrating empathy and kindness toward other people -* Being respectful of differing opinions, viewpoints, and experiences -* Giving and gracefully accepting constructive feedback -* Accepting responsibility and apologizing to those affected by our mistakes, - and learning from the experience -* Focusing on what is best not just for us as individuals, but for the - overall community - -Examples of unacceptable behavior include: - -* The use of sexualized language or imagery, and sexual attention or - advances of any kind -* Trolling, insulting or derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or email - address, without their explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Enforcement Responsibilities - -Community leaders are responsible for clarifying and enforcing our standards of -acceptable behavior and will take appropriate and fair corrective action in -response to any behavior that they deem inappropriate, threatening, offensive, -or harmful. - -Community leaders 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, and will communicate reasons for moderation -decisions when appropriate. - -## Scope - -This Code of Conduct applies within all community spaces, and also applies when -an individual is officially representing the community in public spaces. -Examples of representing our community include using an official e-mail address, -posting via an official social media account, or acting as an appointed -representative at an online or offline event. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported to the community leaders responsible for enforcement at -Email. -All complaints will be reviewed and investigated promptly and fairly. - -All community leaders are obligated to respect the privacy and security of the -reporter of any incident. - -## Enforcement Guidelines - -Community leaders will follow these Community Impact Guidelines in determining -the consequences for any action they deem in violation of this Code of Conduct: - -### 1. Correction - -**Community Impact**: Use of inappropriate language or other behavior deemed -unprofessional or unwelcome in the community. - -**Consequence**: A private, written warning from community leaders, providing -clarity around the nature of the violation and an explanation of why the -behavior was inappropriate. A public apology may be requested. - -### 2. Warning - -**Community Impact**: A violation through a single incident or series -of actions. - -**Consequence**: A warning with consequences for continued behavior. No -interaction with the people involved, including unsolicited interaction with -those enforcing the Code of Conduct, for a specified period of time. This -includes avoiding interactions in community spaces as well as external channels -like social media. Violating these terms may lead to a temporary or -permanent ban. - -### 3. Temporary Ban - -**Community Impact**: A serious violation of community standards, including -sustained inappropriate behavior. - -**Consequence**: A temporary ban from any sort of interaction or public -communication with the community for a specified period of time. No public or -private interaction with the people involved, including unsolicited interaction -with those enforcing the Code of Conduct, is allowed during this period. -Violating these terms may lead to a permanent ban. - -### 4. Permanent Ban - -**Community Impact**: Demonstrating a pattern of violation of community -standards, including sustained inappropriate behavior, harassment of an -individual, or aggression toward or disparagement of classes of individuals. - -**Consequence**: A permanent ban from any sort of public interaction within -the community. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], -version 2.0, available at -https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. - -Community Impact Guidelines were inspired by [Mozilla's code of conduct -enforcement ladder](https://github.com/mozilla/diversity). - -[homepage]: https://www.contributor-covenant.org - -For answers to common questions about this code of conduct, see the FAQ at -https://www.contributor-covenant.org/faq. Translations are available at -https://www.contributor-covenant.org/translations. diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md deleted file mode 100644 index ca794ef..0000000 --- a/docs/CONTRIBUTING.md +++ /dev/null @@ -1,79 +0,0 @@ -# Contributing Guidelines - -Thank you for considering contributing to the Blind 75 LeetCode repository! We welcome contributions from the community to help improve this resource and make it even more valuable. - -Please take a moment to review this document to understand how you can contribute. - -## Table of Contents -- [Ways to Contribute](#ways-to-contribute) -- [Getting Started](#getting-started) -- [Contributing Process](#contributing-process) -- [Code of Conduct](#code-of-conduct) - -## Ways to Contribute - -There are several ways you can contribute to this repository: - -1. **Suggest Improvements**: If you have ideas for making the Blind 75 LeetCode repository better, please open an issue to discuss your suggestions. - -2. **Report Issues**: If you encounter any issues with the existing content or code, please open an issue and provide as much detail as possible. - -3. **Contribute Solutions**: You can contribute solutions to the problems listed in the repository. Please follow the guidelines mentioned below when submitting your solutions. - -4. **Enhance Documentation**: Improve documentation, including explanations and time/space complexity analysis, for existing solutions. - -5. **Fix Bugs**: If you find and fix any bugs in the existing code or documentation, you are welcome to submit a pull request. - -## Getting Started - -Before you start contributing, please ensure you have the following prerequisites: - -- A GitHub account. -- Familiarity with Git and GitHub. -- Code editor or IDE for making changes. - -## Contributing Process - -Here's the general process for contributing: - -1. **Fork the Repository**: Click the "Fork" button at the top of this repository to create your copy. - -2. **Clone Your Fork**: Clone your fork to your local machine. - - ``` - git clone https://github.com/your-username/Blind-75-LeetCode.git - ``` - -3. **Create a Branch**: Create a new branch for your contribution. - - ``` - git checkout -b feature/your-feature-name - ``` - -4. **Make Changes**: Implement your changes, following the guidelines provided. - -5. **Test Your Changes**: Ensure that your changes do not introduce new issues and are consistent with the repository's style and structure. - -6. **Commit Changes**: Commit your changes with a meaningful commit message. - - ``` - git commit -m "Add solution to problem X" - ``` - -7. **Push Changes**: Push your changes to your fork on GitHub. - - ``` - git push origin feature/your-feature-name - ``` - -8. **Create a Pull Request**: Go to the original repository and create a pull request. Please provide a detailed description of your changes. - -9. **Review and Collaboration**: Your pull request will be reviewed, and you may need to make further changes. Be responsive to comments and feedback. - -10. **Merge**: Once your pull request is approved, it will be merged into the main branch. - -## Code of Conduct - -Please note that we have a [Code of Conduct](CODE_OF_CONDUCT.md) that we expect all contributors to adhere to. By participating in this project, you agree to follow this code. - -We appreciate your contributions to the Blind 75 LeetCode repository and look forward to working together to make it an even better resource for the community! diff --git a/docs/LICENSE b/docs/LICENSE deleted file mode 100644 index 8818d1f..0000000 --- a/docs/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Mohsen Tabibian - -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. diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index a9b8b2e..0000000 --- a/docs/README.md +++ /dev/null @@ -1,216 +0,0 @@ -# Blind 75 LeetCode Solutions - -![Blind 75 LeetCode](https://img.shields.io/badge/Blind_75_LeetCode-Solutions-blue?labelColor=red) - -This repository contains a curated list of 75 LeetCode problems that are commonly known as the "Blind 75." These problems cover a wide range of data structures and algorithms and are frequently asked in technical interviews. Solving these problems can help you build a strong foundation in algorithmic problem-solving. - -## Problem List - -### Array & Hashing -![Array & Hashing](https://img.shields.io/badge/Array_&_Hashing-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [217. Contains Duplicate](https://leetcode.com/problems/contains-duplicate/) | Easy | -| [242. Valid Anagram](https://leetcode.com/problems/valid-anagram/) | Easy | -| [1. Two Sum](https://leetcode.com/problems/two-sum/) | Easy | -| [49. Group Anagrams](https://leetcode.com/problems/group-anagrams/) | Medium | -| [347. Top K Frequent Elements](https://leetcode.com/problems/top-k-frequent-elements/) | Medium | -| [238. Product of Array Except Self](https://leetcode.com/problems/product-of-array-except-self/) | Medium | -| [659. Encode and Decode Strings](https://leetcode.com/problems/encode-and-decode-strings/) | Medium | -| [128. Longest Consecutive Sequence](https://leetcode.com/problems/longest-consecutive-sequence/) | Hard | - -### Two Pointers -![Array & Hashing](https://img.shields.io/badge/Two_Pointers-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [125. Valid Palindrome](https://leetcode.com/problems/valid-palindrome/) | Easy | -| [15. 3Sum](https://leetcode.com/problems/3sum/) | Medium | -| [11. Container With Most Water](https://leetcode.com/problems/container-with-most-water/) | Medium | - -### Sliding Window -![Array & Hashing](https://img.shields.io/badge/Sliding_Window-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [121. Best Time to Buy And Sell Stock](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/) | Easy | -| [3. Longest Substring Without Repeating Characters](https://leetcode.com/problems/longest-substring-without-repeating-characters/) | Medium | -| [424. Longest Repeating Character Replacement](https://leetcode.com/problems/longest-repeating-character-replacement/) | Medium | -| [76. Minimum Window Substring](https://leetcode.com/problems/minimum-window-substring/) | Hard | - -### Stack -![Array & Hashing](https://img.shields.io/badge/Stack-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [20. Valid Parentheses](https://leetcode.com/problems/valid-parentheses/) | Easy | - -### Binary Search -![Array & Hashing](https://img.shields.io/badge/Binary_Search-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [153. Find Minimum In Rotated Sorted Array](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/) | Medium | -| [33. Search In Rotated Sorted Array](https://leetcode.com/problems/search-in-rotated-sorted-array/) | Medium | - -### Linked List -![Array & Hashing](https://img.shields.io/badge/Linked_List-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [206. Reverse Linked List](https://leetcode.com/problems/reverse-linked-list/) | Easy | -| [21. Merge Two Sorted Lists](https://leetcode.com/problems/merge-two-sorted-lists/) | Easy | -| [143. Reorder List](https://leetcode.com/problems/reorder-list/) | Medium | -| [19. Remove Nth Node From End of List](https://leetcode.com/problems/remove-nth-node-from-end-of-list/) | Medium | -| [141. Linked List Cycle](https://leetcode.com/problems/linked-list-cycle/) | Medium | -| [23. Merge K Sorted Lists](https://leetcode.com/problems/merge-k-sorted-lists/) | Hard | - -### Trees -![Array & Hashing](https://img.shields.io/badge/Trees-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [226. Invert Binary Tree](https://leetcode.com/problems/invert-binary-tree/) | Easy | -| [104. Maximum Depth of Binary Tree](https://leetcode.com/problems/maximum-depth-of-binary-tree/) | Easy | -| [100. Same Tree](https://leetcode.com/problems/same-tree/) | Easy | -| [572. Subtree of Another Tree](https://leetcode.com/problems/subtree-of-another-tree/) | Easy | -| [235. Lowest Common Ancestor of a Binary Search Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/) | Easy | -| [102. Binary Tree Level Order Traversal](https://leetcode.com/problems/binary-tree-level-order-traversal/) | Medium | -| [98. Validate Binary Search Tree](https://leetcode.com/problems/validate-binary-search-tree/) | Medium | -| [230. Kth Smallest Element In a BST](https://leetcode.com/problems/kth-smallest-element-in-a-bst/) | Medium | -| [105. Construct Binary Tree From Preorder And Inorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/) | Medium | -| [124. Binary Tree Maximum Path Sum](https://leetcode.com/problems/binary-tree-maximum-path-sum/) | Hard | -| [297. Serialize And Deserialize Binary Tree](https://leetcode.com/problems/serialize-and-deserialize-binary-tree/) | Hard | - -### Tries -![Array & Hashing](https://img.shields.io/badge/Tries-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [208. Implement Trie Prefix Tree](https://leetcode.com/problems/implement-trie-prefix-tree/) | Medium | -| [211. Design Add And Search Words Data Structure](https://leetcode.com/problems/design-add-and-search-words-data-structure/) | Medium | -| [212. Word Search II](https://leetcode.com/problems/word-search-ii/) | Hard | - -### Heap / Priority Queue -![Array & Hashing](https://img.shields.io/badge/Heap_/_Priority_Queue-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [295. Find Median From Data Stream](https://leetcode.com/problems/find-median-from-data-stream/) | Hard | - -### Backtracking -![Array & Hashing](https://img.shields.io/badge/Backtracking-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [39. Combination Sum](https://leetcode.com/problems/combination-sum/) | Medium | -| [79. Word Search](https://leetcode.com/problems/word-search/) | Medium | - -### Graphs -![Array & Hashing](https://img.shields.io/badge/Graphs-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [200. Number of Islands](https://leetcode.com/problems/number-of-islands/) | Medium | -| [133. Clone Graph](https://leetcode.com/problems/clone-graph/) | Medium | -| [417. Pacific Atlantic Water Flow](https://leetcode.com/problems/pacific-atlantic-water-flow/) | Medium | -| [207. Course Schedule](https://leetcode.com/problems/course-schedule/) | Medium | -| [323. Number of Connected Components In An Undirected Graph](https://leetcode.com/problems/number-of-connected-components-in-an-undirected-graph/) | Medium | -| [261. Graph Valid Tree](https://leetcode.com/problems/graph-valid-tree/) | Medium | - -### Advanced Graphs -![Array & Hashing](https://img.shields.io/badge/Advanced_Graphs-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [269. Alien Dictionary](https://leetcode.com/problems/alien-dictionary/) | Hard | - -### 1-D Dynamic Programming -![Array & Hashing](https://img.shields.io/badge/1_D_Dynamic_Programming-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [70. Climbing Stairs](https://leetcode.com/problems/climbing-stairs/) | Easy | -| [198. House Robber](https://leetcode.com/problems/house-robber/) | Easy | -| [213. House Robber II](https://leetcode.com/problems/house-robber-ii/) | Medium | -| [5. Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/) | Medium | -| [647. Palindromic Substrings](https://leetcode.com/problems/palindromic-substrings/) | Medium | -| [91. Decode Ways](https://leetcode.com/problems/decode-ways/) | Medium | -| [322. Coin Change](https://leetcode.com/problems/coin-change/) | Medium | -| [152. Maximum Product Subarray](https://leetcode.com/problems/maximum-product-subarray/) | Medium | -| [139. Word Break](https://leetcode.com/problems/word-break/) | Medium | -| [300. Longest Increasing Subsequence](https://leetcode.com/problems/longest-increasing-subsequence/) | Medium | - -### 2-D Dynamic Programming -![Array & Hashing](https://img.shields.io/badge/2_D_Dynamic_Programming-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [62. Unique Paths](https://leetcode.com/problems/unique-paths/) | Medium | -| [1143. Longest Common Subsequence](https://leetcode.com/problems/longest-common-subsequence/) | Medium | - -### Greedy -![Array & Hashing](https://img.shields.io/badge/Greedy-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [53. Maximum Subarray](https://leetcode.com/problems/maximum-subarray/) | Easy | -| [55. Jump Game](https://leetcode.com/problems/jump-game/) | Medium | - -### Intervals -![Array & Hashing](https://img.shields.io/badge/Intervals-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [57. Insert Interval](https://leetcode.com/problems/insert-interval/) | Hard | -| [56. Merge Intervals](https://leetcode.com/problems/merge-intervals/) | Medium | -| [435. Non Overlapping Intervals](https://leetcode.com/problems/non-overlapping-intervals/) | Medium | -| [252. Meeting Rooms](https://leetcode.com/problems/meeting-rooms/) | Easy | -| [253. Meeting Rooms II](https://leetcode.com/problems/meeting-rooms-ii/) | Medium | - -### Math & Geometry -![Array & Hashing](https://img.shields.io/badge/Math_&_Geometry-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [48. Rotate Image](https://leetcode.com/problems/rotate-image/) | Medium | -| [54. Spiral Matrix](https://leetcode.com/problems/spiral-matrix/) | Medium | -| [73. Set Matrix Zeroes](https://leetcode.com/problems/set-matrix-zeroes/) | Medium | - -### Bit Manipulation -![Array & Hashing](https://img.shields.io/badge/Bit_Manipulation-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [191. Number of 1 Bits](https://leetcode.com/problems/number-of-1-bits/) | Easy | -| [338. Counting Bits](https://leetcode.com/problems/counting-bits/) | Medium | -| [190. Reverse Bits](https://leetcode.com/problems/reverse-bits/) | Easy | -| [268. Missing Number](https://leetcode.com/problems/missing-number/) | Easy | -| [371. Sum of Two Integers](https://leetcode.com/problems/sum-of-two-integers/) | Medium | - - -## How to Use - -1. Clone or download this repository to your local machine. - -```bash -git clone https://github.com/mohsentabibian/LeetCode-Solutions/Blind-75-LeetCode.git -``` - -2. Navigate to the directory of the specific problem you want to solve. - -```bash -cd Blind-75-LeetCode/Problem-Directory -``` - -3. Open the problem's directory to find its description, code template, and solution(s). - -4. Solve the problem using your preferred programming language. - -5. Check the solution(s) provided in the directory for reference and to compare your solution. - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -## Disclaimer - -This repository is meant for educational purposes and to help individuals prepare for technical interviews. Please respect LeetCode's terms of use and guidelines when using this repository. - -## Code of Conduct - -We have a [Code of Conduct](CODE_OF_CONDUCT.md) that we expect all contributors to adhere to. By participating in this project, you agree to follow this code. - -## Security Policy - -We take security seriously. Please review our [Security Policy](SECURITY.md) for information on reporting security vulnerabilities. - -Happy coding! diff --git a/docs/SECURITY.md b/docs/SECURITY.md deleted file mode 100644 index 7c19993..0000000 --- a/docs/SECURITY.md +++ /dev/null @@ -1,42 +0,0 @@ -# Security Policy - -## Reporting a Vulnerability - -We take the security of the Blind 75 LeetCode repository seriously. If you believe you have found a security vulnerability, please help us by following these steps: - -1. **Do Not Disclose Publicly**: Please do not disclose the issue publicly until it has been addressed by our team. - -2. **Report Privately**: Create a GitHub issue with the title "Security Vulnerability Report" and provide a detailed description of the vulnerability. You can use a sample report template as follows: - - ``` - **Description** - A clear and concise description of the security vulnerability. - - **Steps to Reproduce** - Provide detailed steps on how to reproduce the vulnerability. - - **Expected Behavior** - Describe what you expected to happen. - - **Actual Behavior** - Describe what actually happened. - - **Additional Information** - Any additional information that can help us understand and reproduce the issue, such as environment details, configuration, or screenshots. - ``` - -3. **Secure Communication**: If the vulnerability involves sensitive data, please encrypt your communication with our PGP key. Contact us for our PGP key information. - -4. **Response**: We will acknowledge your report within 5 business days and provide an estimated timeline for the resolution. - -5. **Fix and Disclosure**: We will work to fix the issue promptly and privately. Once resolved, we will provide a security advisory and give credit to the reporter if desired. - -6. **Responsible Disclosure**: We encourage responsible disclosure. Please do not take advantage of the vulnerability or attempt to exploit it for malicious purposes. - -## Security Updates - -We are committed to promptly addressing and resolving any security issues. We recommend that you stay up-to-date with the latest releases of this repository, as they may include security updates and fixes. - -## Contact - -If you have any questions or need further assistance regarding security, you can contact us at mohsentabibian@gmail.com. diff --git a/docs/_build/.doctrees/01. Array Hashing/1. Two Sum.doctree b/docs/_build/.doctrees/01. Array Hashing/1. Two Sum.doctree deleted file mode 100644 index 5390e09..0000000 Binary files a/docs/_build/.doctrees/01. Array Hashing/1. Two Sum.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/01. Array Hashing/128. Longest Consecutive Sequence.doctree b/docs/_build/.doctrees/01. Array Hashing/128. Longest Consecutive Sequence.doctree deleted file mode 100644 index 28888ec..0000000 Binary files a/docs/_build/.doctrees/01. Array Hashing/128. Longest Consecutive Sequence.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/01. Array Hashing/217. Contains Duplicate.doctree b/docs/_build/.doctrees/01. Array Hashing/217. Contains Duplicate.doctree deleted file mode 100644 index b30e57f..0000000 Binary files a/docs/_build/.doctrees/01. Array Hashing/217. Contains Duplicate.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/01. Array Hashing/238. Product of Array Except Self.doctree b/docs/_build/.doctrees/01. Array Hashing/238. Product of Array Except Self.doctree deleted file mode 100644 index d1df60d..0000000 Binary files a/docs/_build/.doctrees/01. Array Hashing/238. Product of Array Except Self.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/01. Array Hashing/242. Valid Anagram.doctree b/docs/_build/.doctrees/01. Array Hashing/242. Valid Anagram.doctree deleted file mode 100644 index 8187aae..0000000 Binary files a/docs/_build/.doctrees/01. Array Hashing/242. Valid Anagram.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/01. Array Hashing/347. Top K Frequent Elements.doctree b/docs/_build/.doctrees/01. Array Hashing/347. Top K Frequent Elements.doctree deleted file mode 100644 index 127b43b..0000000 Binary files a/docs/_build/.doctrees/01. Array Hashing/347. Top K Frequent Elements.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/01. Array Hashing/49. Group Anagrams.doctree b/docs/_build/.doctrees/01. Array Hashing/49. Group Anagrams.doctree deleted file mode 100644 index 13c81c2..0000000 Binary files a/docs/_build/.doctrees/01. Array Hashing/49. Group Anagrams.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/01. Array Hashing/659. Encode and Decode Strings.doctree b/docs/_build/.doctrees/01. Array Hashing/659. Encode and Decode Strings.doctree deleted file mode 100644 index 3b9c658..0000000 Binary files a/docs/_build/.doctrees/01. Array Hashing/659. Encode and Decode Strings.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/01. Array Hashing/README.doctree b/docs/_build/.doctrees/01. Array Hashing/README.doctree deleted file mode 100644 index f9bd117..0000000 Binary files a/docs/_build/.doctrees/01. Array Hashing/README.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/02. Two Pointers/11. Container With Most Water.doctree b/docs/_build/.doctrees/02. Two Pointers/11. Container With Most Water.doctree deleted file mode 100644 index 6939264..0000000 Binary files a/docs/_build/.doctrees/02. Two Pointers/11. Container With Most Water.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/02. Two Pointers/125. Valid Palindrome.doctree b/docs/_build/.doctrees/02. Two Pointers/125. Valid Palindrome.doctree deleted file mode 100644 index fab66a6..0000000 Binary files a/docs/_build/.doctrees/02. Two Pointers/125. Valid Palindrome.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/02. Two Pointers/15. 3Sum.doctree b/docs/_build/.doctrees/02. Two Pointers/15. 3Sum.doctree deleted file mode 100644 index db856f1..0000000 Binary files a/docs/_build/.doctrees/02. Two Pointers/15. 3Sum.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/02. Two Pointers/README.doctree b/docs/_build/.doctrees/02. Two Pointers/README.doctree deleted file mode 100644 index 311c6a1..0000000 Binary files a/docs/_build/.doctrees/02. Two Pointers/README.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/03. Sliding Window/121. Best Time to Buy and Sell Stock.doctree b/docs/_build/.doctrees/03. Sliding Window/121. Best Time to Buy and Sell Stock.doctree deleted file mode 100644 index a6bbeb3..0000000 Binary files a/docs/_build/.doctrees/03. Sliding Window/121. Best Time to Buy and Sell Stock.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/03. Sliding Window/3. Longest Substring Without Repeating Characters.doctree b/docs/_build/.doctrees/03. Sliding Window/3. Longest Substring Without Repeating Characters.doctree deleted file mode 100644 index 3d83c09..0000000 Binary files a/docs/_build/.doctrees/03. Sliding Window/3. Longest Substring Without Repeating Characters.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/03. Sliding Window/424. Longest Repeating Character Replacement.doctree b/docs/_build/.doctrees/03. Sliding Window/424. Longest Repeating Character Replacement.doctree deleted file mode 100644 index a107741..0000000 Binary files a/docs/_build/.doctrees/03. Sliding Window/424. Longest Repeating Character Replacement.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/03. Sliding Window/76. Minimum Window Substring.doctree b/docs/_build/.doctrees/03. Sliding Window/76. Minimum Window Substring.doctree deleted file mode 100644 index 55bd42c..0000000 Binary files a/docs/_build/.doctrees/03. Sliding Window/76. Minimum Window Substring.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/03. Sliding Window/README.doctree b/docs/_build/.doctrees/03. Sliding Window/README.doctree deleted file mode 100644 index 384aba6..0000000 Binary files a/docs/_build/.doctrees/03. Sliding Window/README.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/04. Stack/20. Valid Parentheses.doctree b/docs/_build/.doctrees/04. Stack/20. Valid Parentheses.doctree deleted file mode 100644 index e3a1f1d..0000000 Binary files a/docs/_build/.doctrees/04. Stack/20. Valid Parentheses.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/04. Stack/README.doctree b/docs/_build/.doctrees/04. Stack/README.doctree deleted file mode 100644 index b68b301..0000000 Binary files a/docs/_build/.doctrees/04. Stack/README.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/05. Binary Search/153. Find Minimum in Rotated Sorted Array.doctree b/docs/_build/.doctrees/05. Binary Search/153. Find Minimum in Rotated Sorted Array.doctree deleted file mode 100644 index f3ad3ed..0000000 Binary files a/docs/_build/.doctrees/05. Binary Search/153. Find Minimum in Rotated Sorted Array.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/05. Binary Search/33. Search in Rotated Sorted Array.doctree b/docs/_build/.doctrees/05. Binary Search/33. Search in Rotated Sorted Array.doctree deleted file mode 100644 index cce41ea..0000000 Binary files a/docs/_build/.doctrees/05. Binary Search/33. Search in Rotated Sorted Array.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/05. Binary Search/README.doctree b/docs/_build/.doctrees/05. Binary Search/README.doctree deleted file mode 100644 index e9ea47d..0000000 Binary files a/docs/_build/.doctrees/05. Binary Search/README.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/06. Linked List/141. Linked List Cycle.doctree b/docs/_build/.doctrees/06. Linked List/141. Linked List Cycle.doctree deleted file mode 100644 index ebdec70..0000000 Binary files a/docs/_build/.doctrees/06. Linked List/141. Linked List Cycle.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/06. Linked List/143. Reorder List.doctree b/docs/_build/.doctrees/06. Linked List/143. Reorder List.doctree deleted file mode 100644 index 93ebdf1..0000000 Binary files a/docs/_build/.doctrees/06. Linked List/143. Reorder List.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/06. Linked List/19. Remove Nth Node From End of List.doctree b/docs/_build/.doctrees/06. Linked List/19. Remove Nth Node From End of List.doctree deleted file mode 100644 index 36946e4..0000000 Binary files a/docs/_build/.doctrees/06. Linked List/19. Remove Nth Node From End of List.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/06. Linked List/206. Reverse Linked List.doctree b/docs/_build/.doctrees/06. Linked List/206. Reverse Linked List.doctree deleted file mode 100644 index b8ca05c..0000000 Binary files a/docs/_build/.doctrees/06. Linked List/206. Reverse Linked List.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/06. Linked List/21. Merge Two Sorted Lists.doctree b/docs/_build/.doctrees/06. Linked List/21. Merge Two Sorted Lists.doctree deleted file mode 100644 index c3fd916..0000000 Binary files a/docs/_build/.doctrees/06. Linked List/21. Merge Two Sorted Lists.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/06. Linked List/23. Merge k Sorted Lists.doctree b/docs/_build/.doctrees/06. Linked List/23. Merge k Sorted Lists.doctree deleted file mode 100644 index 3941f1c..0000000 Binary files a/docs/_build/.doctrees/06. Linked List/23. Merge k Sorted Lists.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/06. Linked List/README.doctree b/docs/_build/.doctrees/06. Linked List/README.doctree deleted file mode 100644 index 33630e1..0000000 Binary files a/docs/_build/.doctrees/06. Linked List/README.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/07. Trees/100. Same Tree.doctree b/docs/_build/.doctrees/07. Trees/100. Same Tree.doctree deleted file mode 100644 index 4f27ba5..0000000 Binary files a/docs/_build/.doctrees/07. Trees/100. Same Tree.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/07. Trees/102. Binary Tree Level Order Traversal.doctree b/docs/_build/.doctrees/07. Trees/102. Binary Tree Level Order Traversal.doctree deleted file mode 100644 index ad0d709..0000000 Binary files a/docs/_build/.doctrees/07. Trees/102. Binary Tree Level Order Traversal.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/07. Trees/104. Maximum Depth of Binary Tree.doctree b/docs/_build/.doctrees/07. Trees/104. Maximum Depth of Binary Tree.doctree deleted file mode 100644 index d337a7f..0000000 Binary files a/docs/_build/.doctrees/07. Trees/104. Maximum Depth of Binary Tree.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.doctree b/docs/_build/.doctrees/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.doctree deleted file mode 100644 index 8a0dff1..0000000 Binary files a/docs/_build/.doctrees/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/07. Trees/124. Binary Tree Maximum Path Sum.doctree b/docs/_build/.doctrees/07. Trees/124. Binary Tree Maximum Path Sum.doctree deleted file mode 100644 index b000d0f..0000000 Binary files a/docs/_build/.doctrees/07. Trees/124. Binary Tree Maximum Path Sum.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/07. Trees/199. Binary Tree Right Side View.doctree b/docs/_build/.doctrees/07. Trees/199. Binary Tree Right Side View.doctree deleted file mode 100644 index ac9e634..0000000 Binary files a/docs/_build/.doctrees/07. Trees/199. Binary Tree Right Side View.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/07. Trees/226. Invert Binary Tree.doctree b/docs/_build/.doctrees/07. Trees/226. Invert Binary Tree.doctree deleted file mode 100644 index 29b96ce..0000000 Binary files a/docs/_build/.doctrees/07. Trees/226. Invert Binary Tree.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/07. Trees/230. Kth Smallest Element in a BST.doctree b/docs/_build/.doctrees/07. Trees/230. Kth Smallest Element in a BST.doctree deleted file mode 100644 index 1b4dde5..0000000 Binary files a/docs/_build/.doctrees/07. Trees/230. Kth Smallest Element in a BST.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.doctree b/docs/_build/.doctrees/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.doctree deleted file mode 100644 index 88f1cab..0000000 Binary files a/docs/_build/.doctrees/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/07. Trees/297. Serialize and Deserialize Binary Tree.doctree b/docs/_build/.doctrees/07. Trees/297. Serialize and Deserialize Binary Tree.doctree deleted file mode 100644 index edab1dc..0000000 Binary files a/docs/_build/.doctrees/07. Trees/297. Serialize and Deserialize Binary Tree.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/07. Trees/572. Subtree of Another Tree.doctree b/docs/_build/.doctrees/07. Trees/572. Subtree of Another Tree.doctree deleted file mode 100644 index d18096f..0000000 Binary files a/docs/_build/.doctrees/07. Trees/572. Subtree of Another Tree.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/07. Trees/98. Validate Binary Search Tree.doctree b/docs/_build/.doctrees/07. Trees/98. Validate Binary Search Tree.doctree deleted file mode 100644 index f4e0df7..0000000 Binary files a/docs/_build/.doctrees/07. Trees/98. Validate Binary Search Tree.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/07. Trees/README.doctree b/docs/_build/.doctrees/07. Trees/README.doctree deleted file mode 100644 index 0ef6fdf..0000000 Binary files a/docs/_build/.doctrees/07. Trees/README.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/08. Tries/208. Implement Trie (Prefix Tree).doctree b/docs/_build/.doctrees/08. Tries/208. Implement Trie (Prefix Tree).doctree deleted file mode 100644 index 980cee7..0000000 Binary files a/docs/_build/.doctrees/08. Tries/208. Implement Trie (Prefix Tree).doctree and /dev/null differ diff --git a/docs/_build/.doctrees/08. Tries/211. Design Add and Search Words Data Structure.doctree b/docs/_build/.doctrees/08. Tries/211. Design Add and Search Words Data Structure.doctree deleted file mode 100644 index 24494e8..0000000 Binary files a/docs/_build/.doctrees/08. Tries/211. Design Add and Search Words Data Structure.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/08. Tries/212. Word Search II.doctree b/docs/_build/.doctrees/08. Tries/212. Word Search II.doctree deleted file mode 100644 index d9bcd3d..0000000 Binary files a/docs/_build/.doctrees/08. Tries/212. Word Search II.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/08. Tries/README.doctree b/docs/_build/.doctrees/08. Tries/README.doctree deleted file mode 100644 index 71936f3..0000000 Binary files a/docs/_build/.doctrees/08. Tries/README.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/09. Heap - Priority Queue/1046. Last Stone Weight.doctree b/docs/_build/.doctrees/09. Heap - Priority Queue/1046. Last Stone Weight.doctree deleted file mode 100644 index 2e53f47..0000000 Binary files a/docs/_build/.doctrees/09. Heap - Priority Queue/1046. Last Stone Weight.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/09. Heap - Priority Queue/295. Find Median from Data Stream.doctree b/docs/_build/.doctrees/09. Heap - Priority Queue/295. Find Median from Data Stream.doctree deleted file mode 100644 index ecc8007..0000000 Binary files a/docs/_build/.doctrees/09. Heap - Priority Queue/295. Find Median from Data Stream.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.doctree b/docs/_build/.doctrees/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.doctree deleted file mode 100644 index 4c27fbe..0000000 Binary files a/docs/_build/.doctrees/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/09. Heap - Priority Queue/README.doctree b/docs/_build/.doctrees/09. Heap - Priority Queue/README.doctree deleted file mode 100644 index a1bd1e3..0000000 Binary files a/docs/_build/.doctrees/09. Heap - Priority Queue/README.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/10. Backtracking/39. Combination Sum.doctree b/docs/_build/.doctrees/10. Backtracking/39. Combination Sum.doctree deleted file mode 100644 index 74bd1e4..0000000 Binary files a/docs/_build/.doctrees/10. Backtracking/39. Combination Sum.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/10. Backtracking/79. Word Search.doctree b/docs/_build/.doctrees/10. Backtracking/79. Word Search.doctree deleted file mode 100644 index 23d6c0d..0000000 Binary files a/docs/_build/.doctrees/10. Backtracking/79. Word Search.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/10. Backtracking/README.doctree b/docs/_build/.doctrees/10. Backtracking/README.doctree deleted file mode 100644 index a587eb8..0000000 Binary files a/docs/_build/.doctrees/10. Backtracking/README.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/11. Graphs/133. Clone Graph.doctree b/docs/_build/.doctrees/11. Graphs/133. Clone Graph.doctree deleted file mode 100644 index 8b72c4b..0000000 Binary files a/docs/_build/.doctrees/11. Graphs/133. Clone Graph.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/11. Graphs/178. Graph Valid Tree.doctree b/docs/_build/.doctrees/11. Graphs/178. Graph Valid Tree.doctree deleted file mode 100644 index 2d47dfa..0000000 Binary files a/docs/_build/.doctrees/11. Graphs/178. Graph Valid Tree.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/11. Graphs/200. Number of Islands.doctree b/docs/_build/.doctrees/11. Graphs/200. Number of Islands.doctree deleted file mode 100644 index 61d79f5..0000000 Binary files a/docs/_build/.doctrees/11. Graphs/200. Number of Islands.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/11. Graphs/207. Course Schedule.doctree b/docs/_build/.doctrees/11. Graphs/207. Course Schedule.doctree deleted file mode 100644 index affb26f..0000000 Binary files a/docs/_build/.doctrees/11. Graphs/207. Course Schedule.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/11. Graphs/3651. Number of Connected Components in an Undirected Graph.doctree b/docs/_build/.doctrees/11. Graphs/3651. Number of Connected Components in an Undirected Graph.doctree deleted file mode 100644 index efb302e..0000000 Binary files a/docs/_build/.doctrees/11. Graphs/3651. Number of Connected Components in an Undirected Graph.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/11. Graphs/417. Pacific Atlantic Water Flow.doctree b/docs/_build/.doctrees/11. Graphs/417. Pacific Atlantic Water Flow.doctree deleted file mode 100644 index a8c58e1..0000000 Binary files a/docs/_build/.doctrees/11. Graphs/417. Pacific Atlantic Water Flow.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/11. Graphs/README.doctree b/docs/_build/.doctrees/11. Graphs/README.doctree deleted file mode 100644 index 2283665..0000000 Binary files a/docs/_build/.doctrees/11. Graphs/README.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/12. Advanced Graphs/892. Alien Dictionary.doctree b/docs/_build/.doctrees/12. Advanced Graphs/892. Alien Dictionary.doctree deleted file mode 100644 index 0798b9c..0000000 Binary files a/docs/_build/.doctrees/12. Advanced Graphs/892. Alien Dictionary.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/12. Advanced Graphs/README.doctree b/docs/_build/.doctrees/12. Advanced Graphs/README.doctree deleted file mode 100644 index 01b3a0c..0000000 Binary files a/docs/_build/.doctrees/12. Advanced Graphs/README.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/13. One-D Dynamic Programming/198. House Robber.doctree b/docs/_build/.doctrees/13. One-D Dynamic Programming/198. House Robber.doctree deleted file mode 100644 index d5117c1..0000000 Binary files a/docs/_build/.doctrees/13. One-D Dynamic Programming/198. House Robber.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/13. One-D Dynamic Programming/213. House Robber II.doctree b/docs/_build/.doctrees/13. One-D Dynamic Programming/213. House Robber II.doctree deleted file mode 100644 index fa72fda..0000000 Binary files a/docs/_build/.doctrees/13. One-D Dynamic Programming/213. House Robber II.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/13. One-D Dynamic Programming/70. Climbing Stairs.doctree b/docs/_build/.doctrees/13. One-D Dynamic Programming/70. Climbing Stairs.doctree deleted file mode 100644 index 6bc0e6b..0000000 Binary files a/docs/_build/.doctrees/13. One-D Dynamic Programming/70. Climbing Stairs.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/13. One-D Dynamic Programming/README.doctree b/docs/_build/.doctrees/13. One-D Dynamic Programming/README.doctree deleted file mode 100644 index 71dbab0..0000000 Binary files a/docs/_build/.doctrees/13. One-D Dynamic Programming/README.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/14. Two-D Dynamic Programming/README.doctree b/docs/_build/.doctrees/14. Two-D Dynamic Programming/README.doctree deleted file mode 100644 index b1a6326..0000000 Binary files a/docs/_build/.doctrees/14. Two-D Dynamic Programming/README.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/15. Greedy/README.doctree b/docs/_build/.doctrees/15. Greedy/README.doctree deleted file mode 100644 index d5cc623..0000000 Binary files a/docs/_build/.doctrees/15. Greedy/README.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/16. Intervals/README.doctree b/docs/_build/.doctrees/16. Intervals/README.doctree deleted file mode 100644 index 4c01fad..0000000 Binary files a/docs/_build/.doctrees/16. Intervals/README.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/17. Math Geometry/README.doctree b/docs/_build/.doctrees/17. Math Geometry/README.doctree deleted file mode 100644 index a4d593f..0000000 Binary files a/docs/_build/.doctrees/17. Math Geometry/README.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/18. Bit Manipulation/README.doctree b/docs/_build/.doctrees/18. Bit Manipulation/README.doctree deleted file mode 100644 index e6afd99..0000000 Binary files a/docs/_build/.doctrees/18. Bit Manipulation/README.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/Book.doctree b/docs/_build/.doctrees/Book.doctree deleted file mode 100644 index 3860721..0000000 Binary files a/docs/_build/.doctrees/Book.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/CODE_OF_CONDUCT.doctree b/docs/_build/.doctrees/CODE_OF_CONDUCT.doctree deleted file mode 100644 index 0f244a9..0000000 Binary files a/docs/_build/.doctrees/CODE_OF_CONDUCT.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/CONTRIBUTING.doctree b/docs/_build/.doctrees/CONTRIBUTING.doctree deleted file mode 100644 index 169d54d..0000000 Binary files a/docs/_build/.doctrees/CONTRIBUTING.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/README.doctree b/docs/_build/.doctrees/README.doctree deleted file mode 100644 index ba89dd9..0000000 Binary files a/docs/_build/.doctrees/README.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/SECURITY.doctree b/docs/_build/.doctrees/SECURITY.doctree deleted file mode 100644 index 22d9a6d..0000000 Binary files a/docs/_build/.doctrees/SECURITY.doctree and /dev/null differ diff --git a/docs/_build/.doctrees/environment.pickle b/docs/_build/.doctrees/environment.pickle deleted file mode 100644 index 3703abd..0000000 Binary files a/docs/_build/.doctrees/environment.pickle and /dev/null differ diff --git a/docs/_build/html/.buildinfo b/docs/_build/html/.buildinfo deleted file mode 100644 index 04dfd2b..0000000 --- a/docs/_build/html/.buildinfo +++ /dev/null @@ -1,4 +0,0 @@ -# Sphinx build info version 1 -# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: 8b102b6ce68f3bc9f65a9c18adf2ae17 -tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/_build/html/01. Array Hashing/1. Two Sum.html b/docs/_build/html/01. Array Hashing/1. Two Sum.html deleted file mode 100644 index e4849aa..0000000 --- a/docs/_build/html/01. Array Hashing/1. Two Sum.html +++ /dev/null @@ -1,720 +0,0 @@ - - - - - - - - - - - - 100: Same Tree — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

100: Same Tree

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

100: Same Tree#

-

Difficulty: Easy

-

Link to Problem: To see the Same Tree problem on LeetCode, click here!

-
-

Given the roots of two binary trees p and q, write a function to check if they are the same or not.

-

Two binary trees are considered the same if they are structurally identical, and the nodes have the same value.

-

Constraints

-
    -
  1. The number of nodes in both trees is in the range [0, 100].

  2. -
  3. \(-10^4\) <= Node.val <= \(10^4\)

  4. -
-
-
-
# Definition for a binary tree node.
-class TreeNode:
-    def __init__(self, val=0, left=None, right=None):
-        # Initialize a TreeNode with a value (val), left child, and right child.
-        self.val = val
-        self.left = left
-        self.right = right
-
-def isSameTree(p, q):
-    # Base case: If both p and q are None, the trees are the same.
-    if not p and not q:
-        return True
-    
-    # Base case: If either p or q is None (but not both), the trees are different.
-    if not p or not q:
-        return False
-    
-    # Check if the values of the current nodes (p.val and q.val) are equal.
-    if p.val != q.val:
-        return False
-    
-    # Recursively check the left and right subtrees of p and q.
-    # If both subtrees are the same, the entire trees are the same.
-    return isSameTree(p.left, q.left) and isSameTree(p.right, q.right)
-
-
-
-
-

In this code, we define a TreeNode class to represent binary tree nodes and a isSameTree function to check if two binary trees are the same. The function uses recursive traversal to compare the trees’ structures and values.

-
    -
  1. We start by defining a TreeNode class, which represents a node in a binary tree. Each node has a val (the node’s value), a left child, and a right child. This class will help us create and work with binary trees.

  2. -
  3. Next, we define the isSameTree function, which checks if two binary trees (p and q) are the same.

    -
      -
    • The base case for the recursion is when both p and q are None. In this case, they are considered the same, so we return True.

    • -
    • If either p or q is None (but not both), they cannot be the same, so we return False.

    • -
    • If the values of the current nodes p.val and q.val are not equal, we return False because the trees cannot be the same.

    • -
    • Finally, we recursively check the left and right subtrees of p and q to see if they are the same.

    • -
    -
  4. -
-
-

Test cases#

-
-
-
### Example 1
-
-#Input: `p = [1,2,3]`, `q = [1,2,3]`
-
-p1 = TreeNode(1, TreeNode(2), TreeNode(3))
-q1 = TreeNode(1, TreeNode(2), TreeNode(3))
-print(isSameTree(p1, q1)) 
-
-
-
-
-
True
-
-
-
-
-
-
-
### Example 2
-
-#Input: `p = [1,2]`, `q = [1,null,2]`
-
-p2 = TreeNode(1, TreeNode(2), None)
-q2 = TreeNode(1, None, TreeNode(2))
-print(isSameTree(p2, q2))
-
-
-
-
-
False
-
-
-
-
-
-
-
### Example 3
-
-#Input: p = [1,2,1], q = [1,1,2]
-
-p3 = TreeNode(1, TreeNode(2), TreeNode(1))
-q3 = TreeNode(1, TreeNode(1), TreeNode(2))
-print(isSameTree(p3, q3))
-
-
-
-
-
False
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Time Complexity

-

The time complexity of the isSameTree function can be analyzed as follows:

-

In the worst case, the function needs to visit every node in both trees once to determine if they are the same. -Since each node is visited exactly once, the time complexity is \(O(n)\), where \(n\) is the total number of nodes in the input trees.

-

Space Complexity -The space complexity of the isSameTree function can be analyzed as follows:

-

The space used by the function’s call stack during recursion is proportional to the maximum depth of the binary trees. -In the worst case, when the trees are completely unbalanced (all nodes form a single branch), the maximum depth will be \(n\), where \(n\) is the total number of nodes in the input trees. -Therefore, the space complexity is \(O(n)\) due to the recursive call stack. -In addition to the call stack, there is a small constant amount of space used for variables and comparisons within each recursive call, but this space is not significant in terms of the overall space complexity.

-

In summary:

-
    -
  • Time Complexity: \(O(n)\) where \(n\) is the total number of nodes in the input trees.

  • -
  • Space Complexity: \(O(n)\) due to the recursive call stack.

  • -
-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/01. Array Hashing/128. Longest Consecutive Sequence.html b/docs/_build/html/01. Array Hashing/128. Longest Consecutive Sequence.html deleted file mode 100644 index 85d82fb..0000000 --- a/docs/_build/html/01. Array Hashing/128. Longest Consecutive Sequence.html +++ /dev/null @@ -1,714 +0,0 @@ - - - - - - - - - - - - 128. Longest Consecutive Sequence — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

128. Longest Consecutive Sequence

- -
- -
-
- - - - -
- -
-

128. Longest Consecutive Sequence#

-

Difficulty: Medium

-

Link to Problem: To see the Longest Consecutive Sequence problem on LeetCode, click here!

-
-

Given an unsorted array of integers nums, return the length of the longest consecutive elements sequence.

-

You must write an algorithm that runs in O(n) time.

-

Constraints:*

-
    -
  • 0 <= nums.length <= \(10^5\)

  • -
  • \(-10^9\) <= nums[i] <= \(10^9\)

  • -
-
-

Solution:#

-

Here’s a Python function to solve this problem:

-
-
-
def longestConsecutive(nums):
-    if not nums:
-        return 0
-
-    num_set = set(nums)
-    max_length = 0
-
-    for num in num_set:
-        if num - 1 not in num_set:
-            current_num = num
-            current_length = 1
-
-            while current_num + 1 in num_set:
-                current_num += 1
-                current_length += 1
-
-            max_length = max(max_length, current_length)
-
-    return max_length
-
-
-
-
-
-
-

Explanation:#

-
    -
  1. We start by defining the longestConsecutive function that takes the nums array as input.

  2. -
  3. We check if the nums array is empty. If it’s empty, there are no consecutive elements, so we return 0.

  4. -
  5. We create a Python set called num_set and insert all elements from the nums array into it. Using a set allows us to efficiently check for the existence of elements in O(1) time.

  6. -
  7. We initialize a variable max_length to 0. This variable will keep track of the maximum length of consecutive elements sequence found.

  8. -
  9. We iterate through the elements of the num_set. For each element num, we check if num - 1 exists in the num_set. If it doesn’t exist, it means num is the starting element of a potential consecutive sequence.

  10. -
  11. Inside the loop, we initialize two variables: current_num to the current element num and current_length to 1. We start with a length of 1 because num itself is part of the sequence.

  12. -
  13. We then enter a while loop that continues as long as current_num + 1 exists in the num_set. This means we are incrementing the consecutive sequence.

  14. -
  15. Inside the while loop, we increment current_num by 1 and also increment current_length by 1 to account for the next consecutive element.

  16. -
  17. We compare current_length with the max_length and update max_length if the current sequence is longer.

  18. -
  19. After the while loop, we move to the next element in the outer loop and repeat the process.

  20. -
  21. Finally, we return the max_length as the result, which represents the length of the longest consecutive elements sequence in the nums array.

  22. -
-

The key idea here is to use a set to efficiently check for the existence of elements and to iterate through the elements, considering each element as the potential start of a consecutive sequence. By doing this, we can find the longest consecutive sequence in O(n) time complexity, where n is the number of elements in the array.

-
-
-

Test cases#

-
-
-
# Example 1: 
-
-nums1 = [100, 4, 200, 1, 3, 2]
-print(longestConsecutive(nums1))
-
-
-
-
-
4
-
-
-
-
-
-
-
# Example 2:
-
-nums2 = [0, 3, 7, 2, 5, 8, 4, 6, 0, 1]
-print(longestConsecutive(nums2)) 
-
-
-
-
-
9
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the provided code:

-

Time Complexity: -The code is designed to run in O(n) time complexity, where n is the number of elements in the nums array. Here’s the breakdown:

-
    -
  1. Constructing the num_set by inserting all elements from nums into it takes O(n) time because we perform an insertion operation for each element in nums.

  2. -
  3. The main loop iterates through the elements in num_set. In the worst case, each element is visited only once, so the loop itself takes O(n) time.

  4. -
  5. Within the loop, we have a while loop that may also take O(n) time in the worst case. However, this while loop is nested inside the main loop, so its overall time complexity remains O(n).

  6. -
-

Therefore, the overall time complexity of the code is O(n).

-

Space Complexity: -The space complexity of the code is determined by the space used by the num_set and a few additional variables. Here’s the breakdown:

-
    -
  1. num_set is a set that stores the unique elements from nums. In the worst case, it can store all n elements from nums, so the space complexity is O(n).

  2. -
  3. The additional variables used, such as max_length, current_num, and current_length, have constant space requirements and do not depend on the size of the input array.

  4. -
-

Therefore, the overall space complexity of the code is O(n) due to the space used by the num_set.

-
-
-

Challenging Exercises:#

-
    -
  1. Write an algorithm that not only returns the length of the longest consecutive elements sequence but also returns the actual consecutive sequence itself.

  2. -
  3. Extend the problem to allow elements to be considered consecutive if they are within a certain absolute difference (e.g., less than or equal to k) instead of exactly 1. Write an algorithm that finds the longest such sequence and runs in O(n) time.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/01. Array Hashing/217. Contains Duplicate.html b/docs/_build/html/01. Array Hashing/217. Contains Duplicate.html deleted file mode 100644 index eb2c377..0000000 --- a/docs/_build/html/01. Array Hashing/217. Contains Duplicate.html +++ /dev/null @@ -1,721 +0,0 @@ - - - - - - - - - - - - 217. Contains Duplicate — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

217. Contains Duplicate

- -
- -
-
- - - - -
- -
-

217. Contains Duplicate#

-

Difficulty: Easy

-

Link to Problem: To see the Contains Duplicate problem on LeetCode, click here!

-
-

Given an integer array nums, return true if any value appears at least twice in the array, and return false if every element is distinct.

-

Constraints:

-
    -
  • 1 <= nums.length <= \(10^5\)

  • -
  • \(-10^9\) <= nums[i] <= \(10^9\)

  • -
-
-

Solution:#

-

Here’s a Python function to solve this problem:

-
-
-
def containsDuplicate(nums):
-    # Create an empty set to store unique elements
-    unique_elements = set()
-    
-    # Iterate through the array
-    for num in nums:
-        # If the element is already in the set, return True
-        if num in unique_elements:
-            return True
-        # Otherwise, add it to the set
-        else:
-            unique_elements.add(num)
-    
-    # If the loop completes without finding duplicates, return False
-    return False
-
-
-
-
-
-
-

Explanation:#

-
    -
  1. The containsDuplicate function takes a single argument, nums, which is the input integer array.

  2. -
  3. Inside the function, an empty set called unique_elements is created. This set will be used to keep track of unique elements in the input array.

  4. -
  5. The function then iterates through the input array nums using a for loop.

  6. -
  7. For each element num in the array, it checks whether num is already in the unique_elements set using the if num in unique_elements: condition.

  8. -
  9. If num is already in the set, it means there is a duplicate element in the array, and the function immediately returns True.

  10. -
  11. If num is not in the set, it is added to the unique_elements set using unique_elements.add(num).

  12. -
  13. The loop continues to the next element, and the process repeats.

  14. -
  15. If the loop completes without finding any duplicates, it means that all elements in the array are distinct, and the function returns False.

  16. -
-

The code efficiently utilizes a set data structure to keep track of unique elements while iterating through the array, allowing it to quickly detect duplicate elements. This code meets the problem’s requirements and constraints, as explained earlier.

-
-
-

Test cases#

-
-
-
# Example 1:
-nums1 = [1, 2, 3, 1]
-print(containsDuplicate(nums1))
-
-
-
-
-
True
-
-
-
-
-
-
-
# Example 2
-nums2 = [1, 2, 3, 4]
-print(containsDuplicate(nums2))
-
-
-
-
-
False
-
-
-
-
-
-
-
# Example 3
-nums3 = [1, 1, 1, 3, 3, 4, 3, 2, 4, 2]
-print(containsDuplicate(nums3))
-
-
-
-
-
True
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the provided code for the “Contains Duplicate” problem:

-

Time Complexity:

-

The primary operation that affects the time complexity is the for loop that iterates through the input array nums. In the worst case, the loop will iterate through all n elements of the array, where n is the length of the input array.

-
    -
  • Iterating through the array: O(n)

  • -
-

Inside the loop, we perform two operations:

-
    -
  1. Checking whether an element exists in the unique_elements set (if num in unique_elements). This operation has an average time complexity of O(1) for a set.

  2. -
  3. Adding an element to the unique_elements set (unique_elements.add(num)), which also has an average time complexity of O(1) for a set.

  4. -
-

Since these operations are performed for each element in the array, the overall time complexity remains O(n).

-

Space Complexity:

-

The space complexity is determined by the additional data structures used in the code, which are the unique_elements set.

-
    -
  • unique_elements set: This set stores unique elements from the input array. In the worst case, if all elements in the input array are distinct, the set will store all n elements.

  • -
-

Therefore, the space complexity is O(n) because, in the worst case, the set’s size will grow linearly with the input array’s size.

-

In summary, the time complexity of the code is O(n), where n is the length of the input array, and the space complexity is also O(n) in the worst case. This code is efficient and meets the constraints of the problem.

-
-
-

Challenging Exercises:#

-
    -
  1. K Duplicates: Modify the problem to return true if there are exactly K duplicate elements in the array. Write a function that takes an additional integer parameter K and returns true if there are exactly K duplicates.

  2. -
  3. Frequency Count: Write a function that returns a list of all the elements that appear more than once in the array, along with their frequencies.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/01. Array Hashing/238. Product of Array Except Self.html b/docs/_build/html/01. Array Hashing/238. Product of Array Except Self.html deleted file mode 100644 index f0fb48f..0000000 --- a/docs/_build/html/01. Array Hashing/238. Product of Array Except Self.html +++ /dev/null @@ -1,717 +0,0 @@ - - - - - - - - - - - - 238. Product of Array Except Self — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

238. Product of Array Except Self

- -
- -
-
- - - - -
- -
-

238. Product of Array Except Self#

-

Difficulty: Medium

-

Link to Problem: To see the Product of Array Except Self problem on LeetCode, click here!

-
-

Given an integer array nums, return an array answer such that answer[i] is equal to the product of all the elements of nums except nums[i].

-

The product of any prefix or suffix of nums is guaranteed to fit in a 32-bit integer.

-

You must write an algorithm that runs in O(n) time and without using the division operation.

-

Constraints:

-
    -
  • 2 <= nums.length <= \(10^5\)

  • -
  • -30 <= nums[i] <= 30

  • -
  • The product of any prefix or suffix of nums is guaranteed to fit in a 32-bit integer.

  • -
-

Follow-up: Can you solve the problem in O(1) extra space complexity? (The output array does not count as extra space for space complexity analysis.)

-
-

Solution:#

-

Here’s a Python function to solve this problem:

-
-
-
def productExceptSelf(nums):
-    n = len(nums)
-    
-    # Initialize two arrays to store products to the left and right of each element
-    left_products = [1] * n
-    right_products = [1] * n
-    
-    # Calculate products to the left of each element
-    left_product = 1
-    for i in range(n):
-        left_products[i] = left_product
-        left_product *= nums[i]
-    
-    # Calculate products to the right of each element
-    right_product = 1
-    for i in range(n - 1, -1, -1):
-        right_products[i] = right_product
-        right_product *= nums[i]
-    
-    # Calculate the final answer using left and right products
-    answer = [left_products[i] * right_products[i] for i in range(n)]
-    
-    return answer
-
-
-
-
-
-
-

Explanation:#

-
    -
  1. n is initialized as the length of the nums array.

  2. -
  3. Two arrays, left_products and right_products, are created, each with a length of n and filled with ones initially.

  4. -
  5. left_product is initialized to 1.

  6. -
  7. A loop iterates through the nums array, from left to right. For each element at index i, it stores the product of all elements to its left (including itself) in the left_products array and updates left_product accordingly.

  8. -
  9. right_product is initialized to 1.

  10. -
  11. Another loop iterates through the nums array in reverse order, from right to left. For each element at index i, it stores the product of all elements to its right (including itself) in the right_products array and updates right_product.

  12. -
  13. The final answer list is constructed by multiplying corresponding elements from the left_products and right_products arrays for each index i.

  14. -
  15. The function returns the answer list, which contains the desired results.

  16. -
-

Overall, this algorithm efficiently computes the product of all elements except the current element, as required. It runs in O(n) time complexity and uses O(n) extra space, which is within the problem’s constraints.

-
-
-

Test cases#

-
-
-
# Example 1: 
-nums = [1,2,3,4]
-result1 = productExceptSelf(nums)
-print(result1)
-
-
-
-
-
[24, 12, 8, 6]
-
-
-
-
-
-
-
# Example 2:
-nums = [-1,1,0,-3,3]
-result2 = productExceptSelf(nums)
-print(result2)
-
-
-
-
-
[0, 0, 9, 0, 0]
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the provided code:

-

Time Complexity:

-
    -
  1. The first loop iterates through the nums array to calculate the products to the left of each element. This loop runs in O(n) time, where n is the length of the nums array.

  2. -
  3. The second loop also iterates through the nums array in reverse order to calculate the products to the right of each element. This loop also runs in O(n) time.

  4. -
  5. The final loop constructs the answer list by multiplying elements from the left_products and right_products arrays. This loop runs in O(n) time.

  6. -
-

Since all the loops are independent and sequential, the overall time complexity is O(n).

-

Space Complexity:

-
    -
  1. Two additional arrays, left_products and right_products, are created with a length of n, where n is the length of the nums array. Therefore, these arrays consume O(n) extra space.

  2. -
  3. The left_product and right_product variables are used to keep track of the product to the left and right of each element, respectively. These variables occupy O(1) extra space.

  4. -
  5. The answer list, which contains the final results, also consumes O(n) space, but it’s not counted toward the extra space complexity analysis as per the problem’s constraints.

  6. -
-

Overall, the space complexity is O(n) for this solution.

-
-
-

Challenging Exercises:#

-
    -
  1. Handle Zeros in the Input: Modify the solution to handle cases where the input array contains zeros. For example, if nums = [0, 1, 2, 3, 0], the output should be [0, 0, 0, 0, 0] because any element multiplied by zero results in zero.

  2. -
  3. In-Place Modification: Attempt to solve the problem with in-place modification of the nums array, where the output is stored directly in the input array without using any additional space.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/01. Array Hashing/242. Valid Anagram.html b/docs/_build/html/01. Array Hashing/242. Valid Anagram.html deleted file mode 100644 index 46ff851..0000000 --- a/docs/_build/html/01. Array Hashing/242. Valid Anagram.html +++ /dev/null @@ -1,708 +0,0 @@ - - - - - - - - - - - - 242. Valid Anagram — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

242. Valid Anagram

- -
- -
-
- - - - -
- -
-

242. Valid Anagram#

-

Difficulty: Easy

-

Link to Problem: To see the Valid Anagram problem on LeetCode, click here!

-
-

Given two strings s and t, return true if t is an anagram of s, and false otherwise.

-

An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.

-

Constraints:

-
    -
  • 1 <= s.length, t.length <= \(5 * 10^4\)

  • -
  • s and t consist of lowercase English letters.

  • -
-

Follow-up: What if the inputs contain Unicode characters? How would you adapt your solution to such a case?

-
-

Solution:#

-

Here’s a Python function to solve this problem:

-
-
-
def isAnagram(s: str, t: str) -> bool:
-    # Check if the lengths of s and t are not equal
-    if len(s) != len(t):
-        return False
-
-    # Create dictionaries to store character frequencies for s and t
-    countS, countT = {}, {}
-
-    # Count character frequencies in s
-    for i in range(len(s)):
-        countS[s[i]] = 1 + countS.get(s[i], 0)
-
-    # Count character frequencies in t
-    for i in range(len(t)):
-        countT[t[i]] = 1 + countT.get(t[i], 0)
-
-    # Check if the character frequencies in s and t are the same
-    return countS == countT
-
-
-
-
-
-
-

Explanation:#

-
    -
  1. The code defines a class called Solution with a method isAnagram that takes two input strings, s and t, and returns a boolean (True or False) based on whether t is an anagram of s.

  2. -
  3. The first check performed in the method is whether the lengths of s and t are equal. If they are not equal, it immediately returns False because strings of different lengths cannot be anagrams of each other.

  4. -
  5. Two dictionaries, countS and countT, are created to store the frequency of characters in s and t, respectively. These dictionaries will be used to count the occurrences of each character in the strings.

  6. -
  7. The code then enters a loop to iterate through each character in string s using a for loop. Inside the loop, it updates the countS dictionary. The line countS[s[i]] = 1 + countS.get(s[i], 0) increments the count of character s[i] in countS by 1. If the character is not already in the dictionary, it initializes the count to 1.

  8. -
  9. Similarly, the code iterates through each character in string t and updates the countT dictionary in the same way.

  10. -
  11. After counting the character frequencies in both strings, the code compares the two dictionaries using countS == countT. If the dictionaries are equal, it means that both strings have the same character frequencies, and therefore, t is an anagram of s. In this case, the method returns True.

  12. -
  13. If the dictionaries are not equal, the method returns False, indicating that t is not an anagram of s.

  14. -
-

In summary, this code efficiently determines whether two input strings are anagrams by counting the character frequencies in each string using dictionaries and then comparing these counts. If the character frequencies match, the strings are considered anagrams, and the method returns True; otherwise, it returns False.

-
-
-

Test cases#

-
-
-
# Example 1:
-s = "anagram"
-t = "nagaram"
-print(isAnagram(s, t))
-
-
-
-
-
True
-
-
-
-
-
-
-
# Example 2
-s = "rat"
-t = "car"
-print(isAnagram(s, t))
-
-
-
-
-
False
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the provided code:

-

Time Complexity:

-
    -
  1. The code first checks whether the lengths of the input strings s and t are equal, which takes constant time. This check has a time complexity of O(1).

  2. -
  3. The code then iterates through both strings, s and t, once to count the character frequencies. Since both strings have a maximum length of 5 * 10^4, the worst-case scenario is that the code iterates through 5 * 10^4 characters in each string. This results in a linear time complexity of O(n), where n is the length of the longer of the two input strings (s or t).

  4. -
  5. Finally, the code compares the two dictionaries countS and countT to check if the character frequencies match. This comparison takes O(n) time in the worst case, where n is the length of the longer string.

  6. -
-

Overall, the time complexity of the code is O(n), where n is the length of the longer input string.

-

Space Complexity:

-
    -
  1. The code uses two dictionaries, countS and countT, to store the character frequencies of the input strings s and t. In the worst case, both dictionaries can contain all unique characters from the input strings. Since the input strings can have a maximum length of 5 * 10^4, the space complexity for these dictionaries is O(5 * 10^4) or simply O(n), where n is the length of the longer input string.

  2. -
  3. The code uses a few additional variables for bookkeeping, but these variables have constant space requirements and do not depend on the input size. Therefore, they do not significantly impact the overall space complexity.

  4. -
-

In summary, the space complexity of the code is O(n), where n is the length of the longer input string.

-
-
-

Challenging Exercises:#

-
    -
  1. Anagram Chains: Given a list of words, find the longest chain of anagrams, where each word in the chain is an anagram of the previous word. For example, given [“bat”, “tab”, “cat”, “tac”, “dog”], the longest anagram chain is [“bat”, “tab”, “cat”, “tac”].

  2. -
  3. Minimum Deletions to Make Anagrams: Given two strings s and t, find the minimum number of character deletions required in both strings to make them anagrams of each other. For example, if s = "hello" and t = "billion", you can remove the characters “heo” from s and “billi” from t to make them anagrams (“lo” and “on” are left in the two strings).

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/01. Array Hashing/347. Top K Frequent Elements.html b/docs/_build/html/01. Array Hashing/347. Top K Frequent Elements.html deleted file mode 100644 index 7cff15a..0000000 --- a/docs/_build/html/01. Array Hashing/347. Top K Frequent Elements.html +++ /dev/null @@ -1,721 +0,0 @@ - - - - - - - - - - - - 347. Top K Frequent Elements — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

347. Top K Frequent Elements

- -
- -
-
- - - - -
- -
-

347. Top K Frequent Elements#

-

Difficulty: Medium

-

Link to Problem: To see the Top K Frequent Elements problem on LeetCode, click here!

-
-

Given an integer array nums and an integer k, return the k most frequent elements. You may return the answer in any order.

-

Constraints:

-
    -
  • 1 <= nums.length <= \(10^5\)

  • -
  • \(-10^4\) <= nums[i] <= \(10^4\)

  • -
  • k is in the range [1, the number of unique elements in the array].

  • -
  • It is guaranteed that the answer is unique.

  • -
-

Follow-up: Your algorithm’s time complexity must be better than \(O(n\ log\ n)\), where n is the array’s size.

-
-

Solution:#

-

Here’s a Python function to solve this problem:

-
-
-
def topKFrequent(nums, k):
-    # Create a dictionary to store the frequency of each element
-    count = {}
-    # Create a list of lists to store elements with the same frequency
-    frequency = [[] for i in range(len(nums) + 1)]
-
-    # Count the frequency of each element in nums
-    for n in nums:
-        count[n] = 1 + count.get(n, 0)
-
-    # Place elements in the freq list according to their frequency
-    for n, c in count.items():
-        frequency[c].append(n)
-
-    res = []
-    # Traverse freq list from the end (higher frequencies)
-    for i in range(len(frequency) - 1, 0, -1):
-        for n in frequency[i]:
-            res.append(n)
-            if len(res) == k:
-                return res
-
-
-
-
-
-
-

Explanation:#

-
    -
  1. def topKFrequent(nums, k):: This is a function that takes two arguments: nums, which is the input array of integers, and k, which is the number of most frequent elements to return.

  2. -
  3. count = {}: This dictionary count will be used to store the frequency of each unique element in the nums array. The keys are elements from the input array, and the values are their corresponding frequencies.

  4. -
  5. frequency = [[] for i in range(len(nums) + 1)]: This creates a list of empty lists called frequency. It’s used to store elements based on their frequencies, similar to the freq list in the previous code. The size of this list is set to be one greater than the length of the input nums.

  6. -
  7. for n in nums:: This loop iterates through each element n in the input nums array.

  8. -
  9. count[n] = 1 + count.get(n, 0): This line counts the frequency of each element n in the nums array. It uses the count.get(n, 0) method to retrieve the current count of n from the count dictionary. If n is not in the dictionary, it defaults to 0. It then increments the count by 1.

  10. -
  11. After the above loop, the count dictionary will contain counts of each unique element in the nums array.

  12. -
  13. for n, c in count.items():: This loop iterates through the items (key-value pairs) of the count dictionary. n represents the element, and c represents its frequency.

  14. -
  15. frequency[c].append(n): This line places the element n into the bucket corresponding to its frequency c. Buckets are represented by the frequency list. For example, if an element n has a frequency of 3, it will be added to frequency[3].

  16. -
  17. After this loop, the frequency list will contain buckets of elements grouped by their frequencies.

  18. -
  19. res = []: This list res will be used to store the k most frequent elements.

  20. -
  21. for i in range(len(freq) - 1, 0, -1):: This loop iterates in reverse order through the frequency list, starting from the highest frequency and going down to 1. Note that there is a typo here; it should be frequency instead of freq.

  22. -
  23. for n in frequency[i]:: For each element n in the current bucket (i.e., elements with frequency i), it appends n to the result list res.

  24. -
  25. if len(res) == k:: Once res contains k elements, the code exits and returns the result.

  26. -
-

The code efficiently finds the k most frequent elements in the input array without using sorting, similar to the previous explanation, with the only difference being the variable names (e.g., frequency instead of freq).

-
-
-

Test cases#

-
-
-
# Example 1: 
-nums = [1,1,1,2,2,3]
-k = 2
-result1 = topKFrequent(nums, k)
-print(result1)
-
-
-
-
-
[1, 2]
-
-
-
-
-
-
-
# Example 2:
-nums = [1]
-k = 1
-result2 = topKFrequent(nums, k)
-print(result2)
-
-
-
-
-
[1]
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the provided code:

-

Time Complexity:

-
    -
  1. The first loop that counts the frequency of elements by iterating through nums has a time complexity of O(n), where n is the number of elements in the input array nums.

  2. -
  3. The second loop iterates through the keys in the count dictionary, which has at most k unique elements (as per the constraints). Therefore, the second loop also has a time complexity of O(k).

  4. -
  5. The third loop iterates through the frequency list, which has a length equal to the maximum frequency of elements in nums. In the worst case, this loop can have a time complexity of O(n), where n is the number of elements in nums.

  6. -
-

Overall, the dominant factor in terms of time complexity is the loop that iterates through the count dictionary. So, the total time complexity of the code is O(n + k).

-

Space Complexity:

-
    -
  1. The count dictionary stores the frequency of each unique element in nums. In the worst case, it can have at most k unique elements, so the space complexity for count is O(k).

  2. -
  3. The frequency list is used to store elements grouped by their frequencies. It has a length of len(nums) + 1, which can be at most 105 based on the constraints. Therefore, the space complexity for frequency is O(105).

  4. -
  5. The res list stores the k most frequent elements, which can be at most k elements, so the space complexity for res is O(k).

  6. -
-

In summary, the space complexity is dominated by the count dictionary and the frequency list, both of which have a space complexity of O(k + 105).

-
-
-

Challenging Exercises:#

-
    -
  1. Optimized k Most Frequent Elements: Modify the code to find the k most frequent elements in an array while ensuring that the time complexity is O(n + klogk). You can use a priority queue (heap) to achieve this.

  2. -
  3. Handling Duplicate Frequencies: Extend the code to handle cases where multiple elements have the same frequency and are among the k most frequent elements. Ensure that the output contains exactly k elements.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/01. Array Hashing/49. Group Anagrams.html b/docs/_build/html/01. Array Hashing/49. Group Anagrams.html deleted file mode 100644 index ab82f1c..0000000 --- a/docs/_build/html/01. Array Hashing/49. Group Anagrams.html +++ /dev/null @@ -1,735 +0,0 @@ - - - - - - - - - - - - 49. Group Anagrams — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

49. Group Anagrams

- -
- -
-
- - - - -
- -
-

49. Group Anagrams#

-

Difficulty: Medium

-

Link to Problem: To see the Group Anagrams problem on LeetCode, click here!

-
-

Given an array of strings strs, group the anagrams together. You can return the answer in any order.

-

An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.

-

Constraints:

-
    -
  • 1 <= `strs.length <= \(10^4\)

  • -
  • 0 <= strs[i].length <= 100

  • -
  • strs[i] consists of lowercase English letters.

  • -
-
-

Solution:#

-

Here’s a Python function to solve this problem:

-
-
-
from collections import defaultdict
-
-
-def groupAnagrams(strs):
-    ans = defaultdict(list)
-
-    # Iterate through the list of input strings
-    for s in strs:
-        # Initialize a list to represent character counts for each character (a-z)
-        count = [0] * 26
-
-        # Count the occurrences of each character in the current word
-        for c in s:
-            count[ord(c) - ord("a")] += 1
-
-        # Use a tuple of character counts as the key and append the word to the anagram group
-        ans[tuple(count)].append(s)
-
-    # Convert the values (lists of anagrams) to a list of lists
-    return list(ans.values())
-
-
-
-
-
-
-

Explanation:#

-
    -
  1. Inside the method, a defaultdict called ans is created to store anagram groups. This dictionary will have a list as its default value, meaning that each key in the dictionary will be associated with an empty list by default.

  2. -
  3. The code then iterates through the list of input strings, strs, using a for loop. For each word s in strs, it performs the following steps:

    -
      -
    • It initializes a list count of length 26, where each element represents the count of a specific character (a-z) in the word s.

    • -
    • The code then iterates through the characters of s. For each character c, it increments the corresponding count in the count list based on its ASCII value.

    • -
    • After counting the characters in s, it converts the count list into a tuple tuple(count) to use as a key for the ans dictionary.

    • -
    • It appends the word s to the list associated with the key (tuple) in the ans dictionary. This groups all anagrams of the same word together under the same key.

    • -
    -
  4. -
  5. After processing all words in strs, the code converts the values of the ans dictionary (which are lists of anagrams) to a list of lists using the list() constructor.

  6. -
  7. Finally, the code returns the list of anagram groups, which is the result of grouping the anagrams in the input list.

  8. -
-

In summary, the code efficiently groups anagrams together by counting the characters in each word and using a dictionary to store them under the same key. The result is a list of lists, where each inner list represents a group of anagrams.

-
-
-

Test cases#

-
-
-
# Example 1: Group anagrams from a list of words
-strs1 = ["eat", "tea", "tan", "ate", "nat", "bat"]
-result1 = groupAnagrams(strs1)
-print(result1)
-
-
-
-
-
[['eat', 'tea', 'ate'], ['tan', 'nat'], ['bat']]
-
-
-
-
-
-
-
# Example 2: Group anagrams from a list with an empty string
-strs2 = [""]
-result2 = groupAnagrams(strs2)
-print(result2)
-
-
-
-
-
[['']]
-
-
-
-
-
-
-
# Example 3: Group anagrams from a list with a single word
-strs3 = ["a"]
-result3 = groupAnagrams(strs3)
-print(result3)
-
-
-
-
-
[['a']]
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the groupAnagrams method:

-

Time Complexity:

-
    -
  1. First, we create an instance of the Solution class, which is an O(1) operation.

  2. -
  3. Inside the groupAnagrams method, we iterate through the list of input strings strs once in a loop:

    -
      -
    • For each word in strs, we perform character counting, which is done in O(K) time, where K is the maximum length of a word in the list.

    • -
    -
  4. -
  5. The overall time complexity of the method is O(N * K), where N is the number of words in the input list strs, and K is the maximum length of a word in strs.

  6. -
-

Space Complexity:

-
    -
  1. We use a defaultdict called ans to store the anagram groups. In the worst case, each word belongs to a distinct anagram group, so the space complexity for ans is O(N).

  2. -
  3. Within the loop, we create a count list of length 26 to store character counts for each word. This is a fixed-size list and does not depend on the input size, so it has a constant space complexity of O(26), which is effectively O(1).

  4. -
  5. The space used for other variables is also constant and does not depend on the input size.

  6. -
  7. The final result, result, is a list of lists that contains the grouped anagrams. In the worst case, each word is a distinct anagram group, so the space complexity for result is O(N).

  8. -
  9. The overall space complexity of the method is O(N) due to the space used by ans and result. The space used by the count list and other variables is constant and does not significantly affect the overall space complexity.

  10. -
-

In summary, the time complexity of the groupAnagrams method is O(N * K), and the space complexity is O(N), where N is the number of words in the input list strs, and K is the maximum length of a word in strs.

-
-
-

Challenging Exercises:#

-
    -
  1. Anagramic Palindromes: Given a list of strings, find all the groups of anagrams where each group contains words that can be rearranged into a palindrome. For example, in the list [“bat”, “tab”, “act”, “tac”, “dog”], there are two groups: [“bat”, “tab”, “act”, “tac”] and [“dog”].

  2. -
  3. Largest Anagram Group: Given a list of strings, find the largest group of anagrams. Return the list of anagrams in that group. If there are multiple largest groups, return all of them.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/01. Array Hashing/659. Encode and Decode Strings.html b/docs/_build/html/01. Array Hashing/659. Encode and Decode Strings.html deleted file mode 100644 index 64076e2..0000000 --- a/docs/_build/html/01. Array Hashing/659. Encode and Decode Strings.html +++ /dev/null @@ -1,728 +0,0 @@ - - - - - - - - - - - - 659· Encode and Decode Strings — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

659· Encode and Decode Strings

- -
- -
-
- - - - -
- -
-

659· Encode and Decode Strings#

-

Difficulty: Medium

-

Link to Problem: To see the Encode and Decode Strings problem on LintCode, click here!

-
-

Design an algorithm to encode a list of strings to a string. The encoded string is then sent over the network and is decoded back to the original list of strings.

-

Please implement encode and decode.

-
-

Solution:#

-

Here’s a Python function to solve this problem:

-
-
-
class Codec:
-
-    def encode(self, strs):
-        """Encodes a list of strings to a single string.
-        
-        :type strs: List[str]
-        :rtype: str
-        """
-        encoded = ""
-        for s in strs:
-            encoded += s.replace(':', '::') + ':;'
-        return encoded
-
-    def decode(self, s):
-        """Decodes a single string to a list of strings.
-        
-        :type s: str
-        :rtype: List[str]
-        """
-        decoded = []
-        i = 0
-        while i < len(s):
-            end = s.find(':;', i)
-            if end == -1:
-                end = len(s)
-            decoded.append(s[i:end].replace('::', ':'))
-            i = end + 2
-        return decoded
-
-
-
-
-
-
-

Explanation:#

-
    -
  1. We define a class called Codec to encapsulate the encoding and decoding operations for a list of strings.

  2. -
  3. In the encode method, we take a list of strings (strs) as input and return a single encoded string. The encoding process involves concatenating the strings together with a delimiter :;. We iterate through each string in the input list, replace any occurrence of : with :: (to avoid conflicts with the delimiter), and then append :; to indicate the end of that string.

  4. -
  5. In the decode method, we take an encoded string (s) as input and return a list of strings. The decoding process involves splitting the encoded string using the :; delimiter. We start from the beginning of the encoded string (i = 0) and repeatedly find the next occurrence of :;. We extract the substring between the current position (i) and the next delimiter (end). Before adding it to the result list, we replace any :: with : to revert the encoding. We then update the current position i to be after the delimiter, so we can find the next substring in the next iteration.

  6. -
  7. Finally, we create an instance of the Codec class and test it with two examples:

  8. -
-

By using the :; delimiter and handling the :: escaping, this code can encode and decode lists of strings, preserving the original content even if it contains colons or the delimiter itself.

-
-
-

Test cases#

-
-
-
# Example 1: 
-codec = Codec()
-
-input1 = ["lint", "code", "love", "you"]
-encoded1 = codec.encode(input1)
-decoded1 = codec.decode(encoded1)
-print(decoded1)
-
-
-
-
-
['lint', 'code', 'love', 'you']
-
-
-
-
-
-
-
# Example 2:
-codec = Codec() 
-
-input2 = ["we", "say", ":", "yes"]
-encoded2 = codec.encode(input2)
-decoded2 = codec.decode(encoded2)
-print(decoded2)  
-
-
-
-
-
['we', 'say', ':', 'yes']
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the encode and decode methods in the provided code.

-

Encode Method (encode):

-
    -
  • Time Complexity: O(n * m)

    -
      -
    • Here, n is the number of strings in the input list strs, and m is the average length of these strings.

    • -
    • In the worst case, for each string in the list, we iterate over its characters once to replace any colons (:) with double colons (::) and then append :;. This is done for each string in the list.

    • -
    -
  • -
  • Space Complexity: O(n * m)

    -
      -
    • The space complexity is also O(n * m) because we build the encoded string by concatenating the modified strings. In the worst case, the encoded string can be of the same length as the original strings.

    • -
    -
  • -
-

Decode Method (decode):

-
    -
  • Time Complexity: O(n * m)

    -
      -
    • Similar to the encode method, we iterate through the encoded string in the decode method. In the worst case, we may have to scan each character in the encoded string to find the :; delimiter.

    • -
    -
  • -
  • Space Complexity: O(n * m)

    -
      -
    • The space complexity of the decode method is also O(n * m) because we build the list of decoded strings, which can be of the same length as the encoded string.

    • -
    -
  • -
-

Overall, both the encode and decode methods have time and space complexities of O(n * m), where n is the number of strings in the input list, and m is the average length of these strings. The space complexity arises from storing the encoded or decoded strings, and the time complexity arises from iterating through the characters in these strings.

-
-
-

Challenging Exercises:#

-
    -
  1. Multiple Delimiters: Modify the code to allow for multiple delimiters, not just one. Each string could have its own delimiter, and the code should be able to handle this complexity.

  2. -
  3. Optimize Encoding: Modify the encode method to achieve a more efficient encoding algorithm. Try to minimize the length of the encoded string while ensuring that it can be correctly decoded.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/01. Array Hashing/README.html b/docs/_build/html/01. Array Hashing/README.html deleted file mode 100644 index c394455..0000000 --- a/docs/_build/html/01. Array Hashing/README.html +++ /dev/null @@ -1,640 +0,0 @@ - - - - - - - - - - - - Array & Hashing Solutions - Blind 75 LeetCode Problems — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Array & Hashing Solutions - Blind 75 LeetCode Problems

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

Array & Hashing Solutions - Blind 75 LeetCode Problems#

-

Array & Hashing SolutionsBlind 75 LeetCode

-

This repository contains my solutions to Array & Hashing Problems from Blind 75 LeetCode problems. I’ve organized the solutions by categories for easier navigation and reference. Each problem solution is presented in Jupyter Notebook format (.ipynb).

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Problem Name

Difficulty

217. Contains Duplicate

Easy

242. Valid Anagram

Easy

1. Two Sum

Easy

49. Group Anagrams

Medium

347. Top K Frequent Elements

Medium

238. Product of Array Except Self

Medium

659. Encode and Decode Strings

Medium

128. Longest Consecutive Sequence

Hard

-
-

Contribute#

-

If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements.

-
-
-

Resources#

-
    -
  • LeetCode: The official LeetCode website.

  • -
  • LeetCode Discuss: LeetCode’s discussion forum for each problem. You can find helpful hints and discussions here.

  • -
-

Happy coding!

-
-
-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/02. Two Pointers/11. Container With Most Water.html b/docs/_build/html/02. Two Pointers/11. Container With Most Water.html deleted file mode 100644 index d158b88..0000000 --- a/docs/_build/html/02. Two Pointers/11. Container With Most Water.html +++ /dev/null @@ -1,728 +0,0 @@ - - - - - - - - - - - - 11. Container With Most Water — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

11. Container With Most Water

- -
- -
-
- - - - -
- -
-

11. Container With Most Water#

-

Difficulty: Medium

-

Link to Problem: To see the Container With Most Water problem on LeetCode, click here!

-
-

You are given an integer array height of length n. There are n vertical lines drawn such that the two endpoints of the \(i^{th}\) line are (i, 0) and (i, height[i]).

-

Find two lines that together with the x-axis form a container, such that the container contains the most water.

-

Return the maximum amount of water a container can store.

-

Notice that you may not slant the container.

-

Constraints:

-
    -
  • n == height.length

  • -
  • 2 <= n <= \(10^5\)

  • -
  • 0 <= height[i] <= \(10^4\)

  • -
-
-

Solution:#

-

Here’s a Python function to solve this problem:

-
-
-
def maxArea(height):
-    # Initialize the maximum area to 0.
-    max_area = 0
-    # Initialize two pointers, one at the beginning (left) and one at the end (right) of the array.
-    left = 0
-    right = len(height) - 1
-
-    # Iterate until the left pointer is less than the right pointer.
-    while left < right:
-        # Calculate the height of the container, which is the minimum height of the two lines.
-        h = min(height[left], height[right])
-        # Calculate the width of the container, which is the distance between the two pointers.
-        width = right - left
-        # Calculate the area of the container using height and width and update max_area if it's greater.
-        max_area = max(max_area, h * width)
-
-        # Move the pointer with the shorter line inward.
-        if height[left] < height[right]:
-            left += 1
-        else:
-            right -= 1
-
-    # Continue this process until left < right, and then return the maximum area.
-    return max_area
-
-
-
-
-
-
-

Explanation:#

-
    -
  1. We start with initializing max_area to 0, which will store the maximum area of water that can be contained by the lines.

  2. -
  3. Two pointers, left and right, are initialized to the beginning and end of the input height array.

  4. -
  5. The main loop runs while left is less than right. This ensures that we are checking all possible pairs of lines in a systematic way.

  6. -
  7. Inside the loop:

    -
      -
    • We calculate the height of the container h as the minimum of the heights at the left and right pointers. This represents the height of the water the container can hold.

    • -
    • We calculate the width of the container as the difference between right and left. This represents the distance between the two lines.

    • -
    • We calculate the area of the container using h * width and update max_area if the calculated area is greater than the current max_area.

    • -
    -
  8. -
  9. After calculating the area and updating max_area, we move one of the pointers. We move the pointer pointing to the shorter line inward because moving the pointer pointing to the taller line won’t increase the height and will only decrease the width, which will result in a smaller area.

  10. -
  11. We continue this process until left is no longer less than right, indicating that we have checked all possible pairs of lines.

  12. -
  13. Finally, we return the max_area which contains the maximum area of water that can be contained by two lines from the input array.

  14. -
-
-
-

Test cases#

-
-
-
# Example 1:
-height1 = [1, 8, 6, 2, 5, 4, 8, 3, 7]
-result1 = maxArea(height1)
-print("Output:", result1)
-
-
-
-
-
Output: 49
-
-
-
-
-
-
-
# Example 2
-height2 = [1, 1]
-result2 = maxArea(height2)
-print("Output:", result2)
-
-
-
-
-
Output: 1
-
-
-
-
-
-
-
# Additional Example
-height3 = [3, 9, 3, 4, 7, 2, 12, 6]
-result3 = maxArea(height3)
-print("Output:", result3)
-
-
-
-
-
Output: 45
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the maxArea function:

-

Time Complexity: -The function uses a two-pointer approach to find the maximum area of water. In the worst case, both the left and right pointers traverse the entire input array once. Therefore, the time complexity is O(n), where n is the number of elements in the height array.

-

Space Complexity: -The function uses a constant amount of extra space for variables like max_area, left, right, h, and width. It does not use any data structures whose space consumption depends on the input size. As a result, the space complexity is O(1), which means it has constant space complexity.

-

In summary, the maxArea function has a time complexity of O(n) and a space complexity of O(1), making it an efficient algorithm for finding the maximum area of water that can be contained by two lines in the input array.

-
-
-

Challenging Exercises:#

-
    -
  1. Optimization Challenge: Modify the maxArea function to not only return the maximum area but also the indices of the two lines that form the container with the maximum area.

  2. -
  3. Variant Problem: Instead of finding the maximum area of water, find the minimum amount of water required to fill all the gaps between the lines. You’ll need to return the total water volume needed.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/02. Two Pointers/125. Valid Palindrome.html b/docs/_build/html/02. Two Pointers/125. Valid Palindrome.html deleted file mode 100644 index 419c392..0000000 --- a/docs/_build/html/02. Two Pointers/125. Valid Palindrome.html +++ /dev/null @@ -1,728 +0,0 @@ - - - - - - - - - - - - 125. Valid Palindrome — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

125. Valid Palindrome

- -
- -
-
- - - - -
- -
-

125. Valid Palindrome#

-

Difficulty: Easy

-

Link to Problem: To see the Valid Palindrome problem on LeetCode, click here!

-
-

A phrase is a palindrome if, after converting all uppercase letters into lowercase letters and removing all non-alphanumeric characters, it reads the same forward and backward. Alphanumeric characters include letters and numbers.

-

Given a string s, return true if it is a palindrome, or false otherwise.

-

Constraints:

-
    -
  • 1 <= s.length <= \(2*10^5\)

  • -
  • s consists only of printable ASCII characters.

  • -
-
-

Solution:#

-

Here’s a Python function to solve this problem:

-
-
-
def isPalindrome(s):
-    # Step 1: Convert the input string to lowercase
-    s = s.lower()
-    
-    # Step 2: Remove all non-alphanumeric characters from the string
-    cleaned_s = ''.join(c for c in s if c.isalnum())
-    
-    # Step 3: Initialize two pointers, one at the beginning and one at the end of the cleaned string
-    left, right = 0, len(cleaned_s) - 1
-    
-    # Step 4: Compare characters using the two pointers while moving them towards each other
-    while left < right:
-        if cleaned_s[left] != cleaned_s[right]:
-            return False  # If characters don't match, it's not a palindrome
-        left += 1
-        right -= 1
-    
-    # Step 5: If the loop completes without returning False, it's a palindrome
-    return True
-
-
-
-
-
-
-

Explanation:#

-
    -
  1. The isPalindrome function takes an input string s.

  2. -
  3. It starts by converting the input string to lowercase using s.lower(). This step ensures that the function is case-insensitive when checking for palindromes.

  4. -
  5. Next, it removes all non-alphanumeric characters from the string and stores the result in the cleaned_s variable. It does this by iterating through each character in the input string and only keeping characters that are alphanumeric (letters and digits). This step removes spaces, punctuation, and other non-alphanumeric characters.

  6. -
  7. The function then initializes two pointers, left and right, which will be used to compare characters from the beginning and end of the cleaned string.

  8. -
  9. In a while loop, it compares characters using the two pointers while moving them towards each other. The loop continues until the left pointer is less than the right pointer. This is done to check all characters in the cleaned string.

  10. -
  11. Inside the loop, it checks if the characters at the left and right pointers don’t match. If they don’t match, it means the input is not a palindrome, so the function returns False.

  12. -
  13. If the characters at the left and right pointers match, the pointers are moved closer to each other by incrementing left and decrementing right.

  14. -
  15. The loop continues to compare characters until it either finds a mismatch (returning False) or until the left pointer is greater than or equal to the right pointer. If the loop completes without finding a mismatch, it means the input is a palindrome, so the function returns True.

  16. -
-

In summary, the code converts the input string to lowercase, removes non-alphanumeric characters, and then uses two pointers to compare characters from the cleaned string’s beginning and end. If all characters match during the comparison, the function returns True, indicating that the input is a palindrome. If any characters do not match, it returns False.

-
-
-

Test cases#

-
-
-
# Example 1:
-input1 = "A man, a plan, a canal: Panama"
-output1 = isPalindrome(input1)
-print(output1)
-
-
-
-
-
True
-
-
-
-
-
-
-
# Example 2
-input2 = "race a car"
-output2 = isPalindrome(input2)
-print(output2)
-
-
-
-
-
False
-
-
-
-
-
-
-
# Example 3
-input3 = ""
-output3 = isPalindrome(input3)
-print(output3)
-
-
-
-
-
True
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the isPalindrome function that uses two pointers:

-
    -
  1. Time Complexity:

    -
      -
    • Converting the input string to lowercase using s.lower() takes O(n) time, where ‘n’ is the length of the input string.

    • -
    • Removing non-alphanumeric characters using the list comprehension ''.join(c for c in s if c.isalnum()) also takes O(n) time because it iterates through each character in the string once.

    • -
    • The comparison of characters using the two pointers (left and right) is done in a loop that runs until left is less than right. In the worst case, the loop iterates through half of the string, so it takes O(n/2) time, which is still considered O(n).

    • -
    -

    Therefore, the overall time complexity of the isPalindrome function is O(n), where ‘n’ is the length of the input string.

    -
  2. -
  3. Space Complexity:

    -
      -
    • The space complexity is primarily determined by the additional string cleaned_s created to store the cleaned version of the input string. In the worst case, if all characters in the input string are alphanumeric, this cleaned string can be as large as the original input string.

    • -
    • Additionally, the function uses two pointers, left and right, which consume constant space and do not depend on the size of the input.

    • -
    -
  4. -
-

In summary, the overall space complexity of the isPalindrome function is O(n) in the worst case, where ‘n’ is the length of the input string. The space complexity is dominated by the space required for cleaned_s.

-
-
-

Challenging Exercises:#

-
    -
  1. Longest Palindromic Substring: Given a string s, find and return the longest palindromic substring within s. For example, if s = "babad", the function should return "bab" or "aba".

  2. -
  3. Palindrome with Limited Characters: Given a string s and a list of characters allowed_chars, check if s is a palindrome considering only the characters from allowed_chars. Ignore all other characters. For example, if s = "A man, a plan, a canal: Panama" and allowed_chars = ['a', 'm', 'n', 'p'], the function should return True.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/02. Two Pointers/15. 3Sum.html b/docs/_build/html/02. Two Pointers/15. 3Sum.html deleted file mode 100644 index 09448fe..0000000 --- a/docs/_build/html/02. Two Pointers/15. 3Sum.html +++ /dev/null @@ -1,751 +0,0 @@ - - - - - - - - - - - - 15. 3Sum — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

15. 3Sum

- -
- -
-
- - - - -
- -
-

15. 3Sum#

-

Difficulty: Medium

-

Link to Problem: To see the 3Sum problem on LeetCode, click here!

-
-

Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0.

-

Notice that the solution set must not contain duplicate triplets.

-

Constraints:

-
    -
  • 3 <= nums.length <= 3000

  • -
  • \(-10^5\) <= nums[i] <= \(10^5\)

  • -
-
-

Solution:#

-

Here’s a Python function to solve this problem:

-
-
-
def threeSum(nums):
-    # Sort the input array in ascending order
-    nums.sort()
-    triplets = []
-    
-    for i in range(len(nums) - 2):
-        # Skip duplicates to avoid duplicate triplets
-        if i > 0 and nums[i] == nums[i - 1]:
-            continue
-        
-        left, right = i + 1, len(nums) - 1
-        
-        while left < right:
-            # Calculate the total sum of the current triplet
-            total = nums[i] + nums[left] + nums[right]
-            
-            if total == 0:
-                # If the total is zero, we found a valid triplet
-                triplets.append([nums[i], nums[left], nums[right]])
-                
-                # Skip duplicates of left and right pointers
-                while left < right and nums[left] == nums[left + 1]:
-                    left += 1
-                while left < right and nums[right] == nums[right - 1]:
-                    right -= 1
-                
-                # Move the pointers to the next unique elements
-                left += 1
-                right -= 1
-            elif total < 0:
-                # If the total is negative, we need to increase the sum by moving the left pointer to the right
-                left += 1
-            else:
-                # If the total is positive, we need to decrease the sum by moving the right pointer to the left
-                right -= 1
-    
-    return triplets
-
-
-
-
-
-
-

Explanation:#

-
    -
  1. It starts by sorting the input array nums in ascending order. Sorting helps in efficiently finding triplets that sum up to zero.

  2. -
  3. It initializes an empty list triplets to store the unique triplets that meet the given conditions.

  4. -
  5. The code then iterates through the nums array using a loop with index i. This loop will consider each element of the array as a potential starting point for a triplet.

  6. -
  7. Inside the loop, it checks for duplicates and skips them. This is done to ensure that the solution set does not contain duplicate triplets. If nums[i] is the same as the previous element nums[i-1], it continues to the next iteration of the loop.

  8. -
  9. Two pointers, left and right, are initialized. left starts just after the current element nums[i], and right starts at the end of the array.

  10. -
  11. The code enters another loop with left and right pointers, trying to find a triplet that sums up to zero.

  12. -
  13. It calculates the total sum of the current triplet as nums[i] + nums[left] + nums[right].

  14. -
  15. If total is zero, it means a valid triplet is found, so it appends [nums[i], nums[left], nums[right]] to the triplets list. Then, it moves both the left and right pointers to their next unique elements while skipping duplicates.

  16. -
  17. If total is less than zero, it means the sum is negative, so it increments the left pointer to move towards a larger sum.

  18. -
  19. If total is greater than zero, it means the sum is positive, so it decrements the right pointer to move towards a smaller sum.

  20. -
  21. This process continues until all possible triplets have been considered.

  22. -
  23. Finally, the function returns the triplets list, which contains all the unique triplets that sum up to zero in the sorted nums array.

  24. -
-
-
-

Test cases#

-
-
-
# Example 1:
-nums = [-1, 0, 1, 2, -1, -4]
-result = threeSum(nums)
-print(result)
-
-
-
-
-
[[-1, -1, 2], [-1, 0, 1]]
-
-
-
-
-
-
-
# Example 2
-nums = [0, 1, 1]
-result = threeSum(nums)
-print(result)
-
-
-
-
-
[]
-
-
-
-
-
-
-
# Example 3
-nums = [0, 0, 0]
-result = threeSum(nums)
-print(result)
-
-
-
-
-
[[0, 0, 0]]
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the threeSum function:

-

Time Complexity:

-
    -
  1. Sorting the input array nums takes O(n log n) time, where n is the length of the array.

  2. -
  3. The outer loop runs for each element of the array, so it iterates O(n) times.

  4. -
  5. Inside the outer loop, we have a while loop with two pointers (left and right). In the worst case, the while loop can iterate O(n) times (when all elements are unique).

  6. -
  7. Inside the while loop, we have constant time operations (additions, comparisons, and list appends).

  8. -
-

Overall, the time complexity of the threeSum function is dominated by the sorting step, so it is O(n log n) due to the sorting. The other operations inside the loops contribute linearly but are dominated by the sorting step.

-

Space Complexity:

-
    -
  1. The space used by the triplets list to store the output triplets is O(k), where k is the number of unique triplets that sum up to zero. In the worst case, this can be O(n^2/3) because there can be roughly O(n^2) possible triplets, and many of them may sum up to zero.

  2. -
  3. Other than the triplets list, the function uses only a constant amount of additional space for variables like i, left, right, and total.

  4. -
-

Overall, the space complexity of the threeSum function is O(k), where k is the number of unique triplets that meet the criteria. It’s important to note that the space complexity does not depend on the size of the input array but rather on the number of valid triplets found.

-

In summary:

-
    -
  • Time Complexity: O(n log n) due to sorting (dominant factor) and O(n^2) in the worst case for the nested loops.

  • -
  • Space Complexity: O(k) for storing the output triplets, where k is the number of unique triplets that meet the criteria.

  • -
-
-
-

Challenging Exercises:#

-
    -
  1. K-Sum Problem: Generalize the problem to the K-Sum problem, where instead of finding triplets that sum to zero, you need to find K elements that sum to a target value. Implement a function for this generalization.

  2. -
  3. Count the Number of Unique Triplets: Modify the algorithm to count the number of unique triplets that satisfy the conditions instead of returning the triplets themselves. This will require some modifications to handle duplicates efficiently.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/02. Two Pointers/README.html b/docs/_build/html/02. Two Pointers/README.html deleted file mode 100644 index 81083c8..0000000 --- a/docs/_build/html/02. Two Pointers/README.html +++ /dev/null @@ -1,623 +0,0 @@ - - - - - - - - - - - - Two Pointers Problems - Blind 75 LeetCode — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Two Pointers Problems - Blind 75 LeetCode

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

Two Pointers Problems - Blind 75 LeetCode#

- - - - - - - - - - - - - - - - - -

Problem Name

Difficulty

125. Valid Palindrome

Easy

15. 3Sum

Medium

11. Container With Most Water

Medium

-
-

Contribute#

-

If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements.

-
-
-

Resources#

-
    -
  • LeetCode: The official LeetCode website.

  • -
  • LeetCode Discuss: LeetCode’s discussion forum for each problem. You can find helpful hints and discussions here.

  • -
-

Happy coding!

-
-
-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/03. Sliding Window/121. Best Time to Buy and Sell Stock.html b/docs/_build/html/03. Sliding Window/121. Best Time to Buy and Sell Stock.html deleted file mode 100644 index 0cdc75b..0000000 --- a/docs/_build/html/03. Sliding Window/121. Best Time to Buy and Sell Stock.html +++ /dev/null @@ -1,712 +0,0 @@ - - - - - - - - - - - - 121. Best Time to Buy and Sell Stock — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

121. Best Time to Buy and Sell Stock

- -
- -
-
- - - - -
- -
-

121. Best Time to Buy and Sell Stock#

-

Difficulty: Easy

-

Link to Problem: To see the Best Time to Buy and Sell Stock problem on LeetCode, click here!

-
-

You are given an array prices where prices[i] is the price of a given stock on the \(i^{th}\) day.

-

You want to maximize your profit by choosing a single day to buy one stock and choosing a different day in the future to sell that stock.

-

Return the maximum profit you can achieve from this transaction. If you cannot achieve any profit, return 0.

-

Constraints:

-
    -
  • 1 <= prices.length <= \(10^5\)

  • -
  • 0 <= prices[i] <= \(10^4\)

  • -
-
-

Solution:#

-

Here’s a Python function to solve this problem:

-
-
-
def maxProfit(prices):
-    if not prices:
-        return 0
-    
-    min_price = prices[0]
-    max_profit = 0
-    
-    for price in prices:
-        # Update the minimum price if a lower price is encountered
-        min_price = min(min_price, price)
-        # Calculate the profit if selling at the current price
-        max_profit = max(max_profit, price - min_price)
-    
-    return max_profit
-
-
-
-
-
-
-

Explanation:#

-
    -
  • The maxProfit function takes a single argument, prices, which is a list of stock prices.

  • -
  • The first line of the function checks if the prices list is empty. If it’s empty, there are no prices to analyze, so the function returns 0 (no profit can be made).

  • -
  • Then, we initialize two variables:

    -
      -
    • min_price: This variable will keep track of the minimum price seen so far. We initialize it with the price of the first day in the list (prices[0]).

    • -
    • max_profit: This variable will keep track of the maximum profit we can achieve. We initialize it to 0 because initially, we haven’t made any profit.

    • -
    -
  • -
  • We start iterating through the prices list, where price represents the stock price for the current day.

  • -
  • In each iteration, we check if the current price is lower than the min_price we’ve seen so far. If it is, we update min_price to the current price. This is because we want to buy the stock at the lowest possible price.

  • -
  • Next, we calculate the profit we would make if we sold the stock at the current price (assuming we bought it at min_price). We do this by subtracting min_price from the current price. This represents the profit for the current day.

  • -
  • We also use the max function to keep track of the maximum profit seen so far. If the profit calculated for the current day is greater than the max_profit we’ve seen previously, we update max_profit with this higher value.

  • -
  • Finally, after iterating through all the days in the prices list, we return max_profit, which represents the maximum profit that can be achieved by buying and selling a single stock.

  • -
-
-
-

Test cases#

-
-
-
# Example 1:
-prices1 = [7, 1, 5, 3, 6, 4]
-print(maxProfit(prices1))
-
-
-
-
-
5
-
-
-
-
-
-
-
# Example 2:
-prices2 = [7, 6, 4, 3, 1]
-print(maxProfit(prices2))
-
-
-
-
-
0
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the provided code:

-

Time Complexity:

-
    -
  • The code iterates through the prices array once, examining each price exactly once.

  • -
  • Within the loop, there are constant-time operations such as comparisons, additions, and subtractions.

  • -
  • Therefore, the time complexity of this code is O(n), where n is the length of the prices array. It performs a linear number of operations relative to the size of the input.

  • -
-

Space Complexity:

-
    -
  • The space complexity of the code is constant, O(1).

  • -
  • Regardless of the size of the input prices array, the code only uses a fixed amount of additional memory to store two variables (min_price and max_profit) and a few loop variables.

  • -
  • The memory usage does not depend on the size of the input, so it is considered constant space complexity.

  • -
-

In summary:

-
    -
  • Time Complexity: O(n) where n is the length of the prices array.

  • -
  • Space Complexity: O(1) (constant space usage).

  • -
-
-
-

Challenging Exercises:#

-
    -
  1. Multiple Transactions Allowed: Modify the problem to allow multiple transactions (buy and sell multiple times), but you must sell before buying again. Find the maximum profit in this scenario.

  2. -
  3. K Transactions Allowed: Extend the problem to allow at most k transactions. Find the maximum profit considering this constraint.

  4. -
  5. With Transaction Fee: Introduce a transaction fee for each buy/sell operation. Modify the code to maximize profit while considering the transaction fee.

  6. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/03. Sliding Window/3. Longest Substring Without Repeating Characters.html b/docs/_build/html/03. Sliding Window/3. Longest Substring Without Repeating Characters.html deleted file mode 100644 index 491b7ec..0000000 --- a/docs/_build/html/03. Sliding Window/3. Longest Substring Without Repeating Characters.html +++ /dev/null @@ -1,731 +0,0 @@ - - - - - - - - - - - - 3. Longest Substring Without Repeating Characters — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

3. Longest Substring Without Repeating Characters

- -
- -
-
- - - - -
- -
-

3. Longest Substring Without Repeating Characters#

-

Difficulty: Medium

-

Link to Problem: To see the Longest Substring Without Repeating Characters problem on LeetCode, click here!

-
-

Given a string s, find the length of the longest substring without repeating characters.

-

Constraints:

-
    -
  • 0 <= s.length <= \(5 * 10^4\)

  • -
  • s consists of English letters, digits, symbols and spaces.

  • -
-
-

Solution:#

-

Here’s a Python function to solve this problem:

-
-
-
def length_of_longest_substring(s):
-    # Create a dictionary to store the index of each character's last occurrence.
-    char_index = {}
-    
-    # Initialize variables to keep track of the start and end of the current substring.
-    start = 0
-    max_length = 0
-    
-    for end in range(len(s)):
-        # If the character is in the dictionary and its last occurrence is after the start of the current substring,
-        # update the start of the substring to the next character after its last occurrence.
-        if s[end] in char_index and char_index[s[end]] >= start:
-            start = char_index[s[end]] + 1
-        
-        # Update the last occurrence index of the current character.
-        char_index[s[end]] = end
-        
-        # Calculate the length of the current substring and update the maximum length if necessary.
-        current_length = end - start + 1
-        max_length = max(max_length, current_length)
-    
-    return max_length
-
-
-
-
-
-
-

Explanation:#

-
    -
  1. We start by defining a function called length_of_longest_substring that takes a single argument s, which is the input string for which we want to find the length of the longest substring without repeating characters.

  2. -
  3. We create a dictionary called char_index to store the index of the last occurrence of each character in the input string. This dictionary will help us keep track of where each character was last seen.

  4. -
  5. We initialize two variables, start and max_length.

    -
      -
    • start represents the start index of the current substring without repeating characters. It starts at 0.

    • -
    • max_length is used to keep track of the maximum length found so far and is initially set to 0.

    • -
    -
  6. -
  7. We then iterate through the input string s using a for loop, where the loop variable end represents the current end index of the substring we are considering.

  8. -
  9. Inside the loop:

    -
      -
    • We check if the character s[end] is already in the char_index dictionary and if its last occurrence is within or after the current substring. If so, it means that we’ve encountered a repeating character, and we need to update the start of the substring to the next character after the last occurrence of s[end]. This ensures that we have a new valid substring without repeating characters.

    • -
    • We then update the char_index dictionary by storing the current index end as the last occurrence index of the character s[end].

    • -
    -
  10. -
  11. Next, we calculate the length of the current substring without repeating characters, which is current_length = end - start + 1. We add 1 to account for the fact that the indices are zero-based.

  12. -
  13. We update the max_length with the maximum of its current value and the current_length. This step ensures that we keep track of the longest valid substring we have encountered so far.

  14. -
  15. The loop continues to iterate through the input string, and at the end, we return the max_length, which represents the length of the longest substring without repeating characters.

  16. -
-
-
-

Test cases#

-
-
-
# Example 1:
-print(length_of_longest_substring("abcabcbb"))
-
-
-
-
-
3
-
-
-
-
-
-
-
# Example 2:
-print(length_of_longest_substring("bbbbb"))
-
-
-
-
-
1
-
-
-
-
-
-
-
# Example 3:
-print(length_of_longest_substring("pwwkew"))
-
-
-
-
-
3
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the length_of_longest_substring function:

-

Time Complexity:

-
    -
  • The function iterates through the input string s using a single for loop. The loop runs from the beginning of the string to the end once.

  • -
  • Inside the loop, we perform constant-time operations such as dictionary lookups and updates, comparisons, and arithmetic operations.

  • -
  • Therefore, the time complexity of the function is O(n), where n is the length of the input string s.

  • -
-

Space Complexity:

-
    -
  • The primary data structure that consumes space in this function is the char_index dictionary.

  • -
  • In the worst case, if there are no repeating characters in the input string, the dictionary can store all unique characters in the string.

  • -
  • Therefore, the space complexity is O(min(n, m)), where n is the length of the input string s, and m is the number of unique characters in the string. In the worst case, when all characters are unique, m is equal to n, so the space complexity is O(n).

  • -
  • Additionally, there are a few integer variables used for indices and lengths, which consume constant space.

  • -
  • Overall, the space complexity of the function is O(min(n, m)) or simply O(n) in the worst case.

  • -
-

In summary, the time complexity of the length_of_longest_substring function is O(n), and the space complexity is O(n) in the worst case due to the char_index dictionary. This algorithm provides an efficient way to find the length of the longest substring without repeating characters in linear time.

-
-
-

Challenging Exercises:#

-
    -
  1. Longest Substring with K Distinct Characters: Modify the problem to find the length of the longest substring with exactly K distinct characters. For example, given the input string “abcabcbb” and K = 2, the answer would be 4 because the longest substring with two distinct characters is “abca.”

  2. -
  3. Longest Substring with Unique Characters: Write a function to find the length of the longest substring in a given string where all characters are unique. For example, given the input string “abcabcbb,” the answer would be 4 because “abcd” is the longest substring with unique characters.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/03. Sliding Window/424. Longest Repeating Character Replacement.html b/docs/_build/html/03. Sliding Window/424. Longest Repeating Character Replacement.html deleted file mode 100644 index 0c70660..0000000 --- a/docs/_build/html/03. Sliding Window/424. Longest Repeating Character Replacement.html +++ /dev/null @@ -1,715 +0,0 @@ - - - - - - - - - - - - 424. Longest Repeating Character Replacement — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

424. Longest Repeating Character Replacement

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

424. Longest Repeating Character Replacement#

-

Difficulty: Medium

-

Link to Problem: To see the Longest Repeating Character Replacement problem on LeetCode, click here!

-
-

You are given a string s and an integer k. You can choose any character of the string and change it to any other uppercase English character. You can perform this operation at most k times.

-

Return the length of the longest substring containing the same letter you can get after performing the above operations.

-

Constraints:

-
    -
  • 1 <= s.length <= \(10^5\)

  • -
  • s consists of only uppercase English letters.

  • -
  • 0 <= k <= s.length

  • -
-
-
-
def characterReplacement(s, k):
-    max_length = 0  # Initialize the maximum length
-    max_count = 0   # Initialize the maximum count of repeating characters
-    start = 0       # Initialize the start of the sliding window
-    char_count = {} # Dictionary to store the count of each character
-
-    for end in range(len(s)):
-        # Update the count of the current character in the dictionary
-        char_count[s[end]] = char_count.get(s[end], 0) + 1
-        
-        # Update the maximum count of repeating characters
-        max_count = max(max_count, char_count[s[end]])
-        
-        # Check if the current window size is greater than k
-        if (end - start + 1) - max_count > k:
-            # Move the start of the window to the right
-            char_count[s[start]] -= 1
-            start += 1
-        
-        # Update the maximum length
-        max_length = max(max_length, end - start + 1)
-
-    return max_length
-
-
-
-
-
-

Explanation:#

-
    -
  1. We initialize some variables:

    -
      -
    • max_length to keep track of the maximum length of the substring containing the same letter.

    • -
    • max_count to keep track of the maximum count of repeating characters within the current window.

    • -
    • start to represent the start index of the sliding window.

    • -
    • char_count is a dictionary that will store the count of each character within the current window.

    • -
    -
  2. -
  3. We use a for loop to iterate through the characters of the string s.

  4. -
  5. Inside the loop, we do the following for each character at position end:

    -
      -
    • Update the count of the current character in the char_count dictionary.

    • -
    • Update the max_count to be the maximum of the current max_count and the count of the current character. This keeps track of the maximum count of repeating characters within the current window.

    • -
    -
  6. -
  7. We check if the current window size (the difference between end and start plus one) minus the max_count is greater than k. This condition checks whether we have exceeded the allowed number of replacements (k) within the current window.

    -
      -
    • If we have exceeded the allowed replacements, it means we need to shrink the window from the left side. We do this by moving the start of the window to the right and decrementing the count of the character at s[start] in the char_count dictionary. This effectively removes characters from the left side of the window until we have a valid window again.

    • -
    • By doing this, we ensure that the difference between the current window size and the max_count is always less than or equal to k.

    • -
    -
  8. -
  9. After each character, we update the max_length to be the maximum of the current max_length and the size of the current window (end - start + 1).

  10. -
  11. Finally, we return max_length, which holds the length of the longest substring containing the same letter with at most k replacements.

  12. -
-
-
-

Test cases#

-
-
-
# Example 1:
-s1 = "ABAB"
-k1 = 2
-print(characterReplacement(s1, k1))
-
-
-
-
-
4
-
-
-
-
-
-
-
# Example 2:
-s2 = "AABABBA"
-k2 = 1
-print(characterReplacement(s2, k2))
-
-
-
-
-
4
-
-
-
-
-

Let’s analyze the time and space complexity of the provided code:

-

Time Complexity:

-
    -
  • The code uses a single for loop to iterate through the characters of the input string s. The loop runs from the beginning to the end of the string.

  • -
  • Inside the loop, we perform constant-time operations such as updating the char_count dictionary and updating variables like max_count and max_length.

  • -
  • The code’s time complexity is primarily determined by the loop, which iterates through each character in the string once. Therefore, the time complexity is O(n), where n is the length of the input string s.

  • -
-

Space Complexity:

-
    -
  • The code uses several variables to store information, but the space they consume is constant and does not depend on the size of the input string. These variables include max_length, max_count, start, and char_count. Therefore, the space complexity is O(1) or constant space.

  • -
-

In summary, the time complexity of the code is O(n), where n is the length of the input string, and the space complexity is O(1), as it uses a constant amount of additional space regardless of the input size. This algorithm efficiently solves the problem with a linear time complexity.

-
-
-

Challenging Exercises:#

-
    -
  1. Optimization Challenge: Modify the code to find the longest substring containing the same letter with at most k replacements in O(n) time complexity and O(1) space complexity. Hint: You may need to update the approach to achieve this.

  2. -
  3. Variation with Lowercase Letters: Extend the problem to include both uppercase and lowercase English letters in the input string s. Write a function that can handle this extended input and still find the longest substring with at most k replacements efficiently.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/03. Sliding Window/76. Minimum Window Substring.html b/docs/_build/html/03. Sliding Window/76. Minimum Window Substring.html deleted file mode 100644 index 74efd3a..0000000 --- a/docs/_build/html/03. Sliding Window/76. Minimum Window Substring.html +++ /dev/null @@ -1,761 +0,0 @@ - - - - - - - - - - - - 76. Minimum Window Substring — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

76. Minimum Window Substring

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

76. Minimum Window Substring#

-

Difficulty: Hard

-

Link to Problem: To see the Minimum Window Substring problem on LeetCode, click here!

-
-

Given two strings s and t of lengths m and n respectively, return the minimum window substring of s such that every character in t (including duplicates) is included in the window. If there is no such substring, return the empty string "".

-

The testcases will be generated such that the answer is unique.

-

Constraints:

-
    -
  • m == s.length

  • -
  • n == t.length

  • -
  • 1 <= m, n <= \(10^5\)

  • -
  • s and t consist of uppercase and lowercase English letters.

  • -
-

Follow up: Could you find an algorithm that runs in \(O(m + n)\) time?

-
-
-
def min_window_substring(s, t):
-    if not s or not t:
-        return ""
-
-    # Initialize dictionaries to keep track of character counts for t and the current window in s.
-    t_dict = {}
-    current_window_dict = {}
-    
-    # Populate t_dict with character counts for string t.
-    for char in t:
-        t_dict[char] = t_dict.get(char, 0) + 1
-
-    # Initialize pointers for the sliding window.
-    left = 0
-    min_len = float('inf')
-    min_window = ""
-    required_chars = len(t_dict)
-
-    # Initialize a variable to keep track of how many required characters have been found in the current window.
-    found_chars = 0
-
-    # Iterate over the string s using the right pointer.
-    for right in range(len(s)):
-        char = s[right]
-
-        # Update the current_window_dict.
-        current_window_dict[char] = current_window_dict.get(char, 0) + 1
-
-        # Check if the current character is a required character and if its count matches the required count.
-        if char in t_dict and current_window_dict[char] == t_dict[char]:
-            found_chars += 1
-
-        # Try to minimize the window by moving the left pointer.
-        while left <= right and found_chars == required_chars:
-            # Calculate the current window size.
-            window_size = right - left + 1
-
-            # If the current window is smaller than the minimum found so far, update min_len and min_window.
-            if window_size < min_len:
-                min_len = window_size
-                min_window = s[left:right+1]
-
-            # Move the left pointer to the right to shrink the window.
-            left_char = s[left]
-            current_window_dict[left_char] -= 1
-
-            # Check if the character removed from the window was a required character.
-            if left_char in t_dict and current_window_dict[left_char] < t_dict[left_char]:
-                found_chars -= 1
-
-            # Move the left pointer further to continue shrinking the window.
-            left += 1
-
-    return min_window
-
-
-
-
-
-

Explanation:#

-
    -
  1. We start by checking if either of the input strings s or t is empty. If either of them is empty, we return an empty string since there can’t be any valid substring in this case.

  2. -
  3. We initialize two dictionaries: t_dict and current_window_dict. These dictionaries will be used to keep track of character counts in the string t and the current window in string s, respectively.

  4. -
  5. We populate the t_dict dictionary by iterating through string t. For each character, we increment its count in the dictionary using t_dict.get(char, 0) + 1. This allows us to count the occurrences of each character in t.

  6. -
  7. We initialize two pointers: left and right. The left pointer will represent the start of the current window, and the right pointer will represent the end of the current window. We also initialize min_len to store the length of the minimum window found so far, and min_window to store the actual minimum window substring.

  8. -
  9. We determine the number of required characters in t (i.e., the number of distinct characters in t) and store it in the variable required_chars.

  10. -
  11. We initialize a variable found_chars to keep track of how many required characters have been found in the current window. Initially, it is set to 0.

  12. -
  13. We iterate over the string s using the right pointer. In each iteration, we do the following:

    -
      -
    • Update the current_window_dict by incrementing the count of the current character.

    • -
    • Check if the current character is a required character (present in t_dict) and if its count in the current_window_dict matches the required count from t_dict. If so, we increment found_chars.

    • -
    -
  14. -
  15. After updating the window, we attempt to minimize the window size by moving the left pointer to the right. In this step, we:

    -
      -
    • Calculate the size of the current window.

    • -
    • If the current window size is smaller than the minimum found so far (min_len), we update min_len and min_window to store the current window substring.

    • -
    • Move the left pointer to the right to shrink the window.

    • -
    • Check if the character being removed from the window was a required character. If it was, we decrement found_chars.

    • -
    • Continue moving the left pointer further to continue shrinking the window if the window still contains all required characters.

    • -
    -
  16. -
  17. Finally, we return min_window, which will contain the minimum window substring that contains all characters from t.

  18. -
-
-
-

Test cases#

-
-
-
# Example 1:
-print(min_window_substring("ADOBECODEBANC", "ABC"))
-
-
-
-
-
BANC
-
-
-
-
-
-
-
# Example 2:
-print(min_window_substring("a", "a")) 
-
-
-
-
-
a
-
-
-
-
-
-
-
# Example 3:
-print(min_window_substring("a", "aa")) 
-
-
-
-
-

-
-
-
-
-

Let’s analyze the time and space complexity of the min_window_substring function:

-

Time Complexity:

-
    -
  • The main loop iterates through the string s from left to right using the right pointer. This loop runs in O(m) time, where ‘m’ is the length of string s.

  • -
  • Inside the loop, we have a while loop that moves the left pointer to the right to shrink the window as needed. In the worst case, this while loop can also run in O(m) time because in the worst case, we may have to move the left pointer all the way to the end of the string.

  • -
  • Within each iteration of the while loop, we perform constant time operations, such as updating dictionaries and comparing character counts.

  • -
  • The initialization of the t_dict dictionary takes O(n) time, where ‘n’ is the length of string t.

  • -
-

Therefore, the overall time complexity of the function is O(m + n) because the dominant factor is the length of string s, and the length of string t has a smaller impact.

-

Space Complexity:

-
    -
  • The space complexity is determined by the space used by the t_dict dictionary, the current_window_dict dictionary, and a few variables.

  • -
  • The t_dict dictionary stores character counts for string t. In the worst case, when all characters in t are distinct, this dictionary can have a maximum of ‘n’ key-value pairs. So, the space complexity for t_dict is O(n).

  • -
  • The current_window_dict dictionary stores character counts for the current window. In the worst case, it can have a maximum of ‘m’ key-value pairs. So, the space complexity for current_window_dict is also O(m).

  • -
  • Other variables used in the function, such as left, right, min_len, min_window, required_chars, and found_chars, are all of constant size and do not depend on the input sizes.

  • -
-

In summary, the overall space complexity of the function is O(max(m, n)), which means it is determined by the larger of the two input strings’ lengths. This is because the space used for t_dict and current_window_dict dominates the space complexity.

-
-
-

Challenging Exercises:#

-
    -
  1. Smallest Distinct Substring: Instead of finding the minimum window substring containing all characters, find the smallest distinct (unique) substring of s that contains all characters from t. This variation adds complexity because you must find a substring with distinct characters.

  2. -
  3. No Extra Space: Solve the problem without using any extra space, such as dictionaries or arrays, other than a constant amount of space. This is a significant optimization challenge.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/03. Sliding Window/README.html b/docs/_build/html/03. Sliding Window/README.html deleted file mode 100644 index 7dcd69b..0000000 --- a/docs/_build/html/03. Sliding Window/README.html +++ /dev/null @@ -1,626 +0,0 @@ - - - - - - - - - - - - Sliding Window Problems - Blind 75 LeetCode — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Sliding Window Problems - Blind 75 LeetCode

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

Sliding Window Problems - Blind 75 LeetCode#

- - - - - - - - - - - - - - - - - - - - -

Problem Name

Difficulty

121. Best Time to Buy And Sell Stock

Easy

3. Longest Substring Without Repeating Characters

Medium

424. Longest Repeating Character Replacement

Medium

76. Minimum Window Substring

Hard

-
-

Contribute#

-

If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements.

-
-
-

Resources#

-
    -
  • LeetCode: The official LeetCode website.

  • -
  • LeetCode Discuss: LeetCode’s discussion forum for each problem. You can find helpful hints and discussions here.

  • -
-

Happy coding!

-
-
-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/04. Stack/20. Valid Parentheses.html b/docs/_build/html/04. Stack/20. Valid Parentheses.html deleted file mode 100644 index f48f75e..0000000 --- a/docs/_build/html/04. Stack/20. Valid Parentheses.html +++ /dev/null @@ -1,723 +0,0 @@ - - - - - - - - - - - - 20. Valid Parentheses — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

20. Valid Parentheses

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

20. Valid Parentheses#

-

Difficulty: Easy

-

Link to Problem: To see the Valid Parentheses problem on LeetCode, click here!

-
-

Given a string s containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.

-

An input string is valid if:

-
    -
  1. Open brackets must be closed by the same type of brackets.

  2. -
  3. Open brackets must be closed in the correct order.

  4. -
  5. Every close bracket has a corresponding open bracket of the same type.

  6. -
-

Constraints:

-
    -
  • 1 <= s.length <= \(10^4\)

  • -
  • s consists of parentheses only '()[]{}'.

  • -
-
-
-
def isValid(s):
-    # Create an empty stack to store opening brackets
-    stack = []
-    
-    # Define a mapping for matching brackets
-    bracket_mapping = {')': '(', '}': '{', ']': '['}
-    
-    # Iterate through the characters in the input string
-    for char in s:
-        # If the character is an opening bracket, push it onto the stack
-        if char in bracket_mapping.values():
-            stack.append(char)
-        # If the character is a closing bracket
-        elif char in bracket_mapping.keys():
-            # Pop the top element from the stack if it exists, or use a dummy value '#'
-            top_element = stack.pop() if stack else '#'
-            # If the popped element does not match the corresponding opening bracket, return False
-            if bracket_mapping[char] != top_element:
-                return False
-        # If the character is not a bracket, ignore it
-        
-    # After processing the entire string, if there are any unmatched opening brackets left in the stack, return False
-    return len(stack) == 0
-
-
-
-
-
-

Explanation:#

-
    -
  1. We start by defining the isValid function that takes a single argument s, which is the input string containing parentheses and brackets.

  2. -
  3. Inside the function, we create an empty stack, which is a list in Python, to store opening brackets as we encounter them in the input string. The stack will help us keep track of the brackets and their order.

  4. -
  5. We define a bracket_mapping dictionary that maps each closing bracket to its corresponding opening bracket. This mapping will be used to check if a closing bracket matches the most recent opening bracket in the stack.

  6. -
  7. We iterate through each character char in the input string s using a for loop.

  8. -
  9. If the character char is an opening bracket (i.e., it exists in the values() of bracket_mapping), we push it onto the stack using the append() method.

  10. -
  11. If the character char is a closing bracket (i.e., it exists in the keys() of bracket_mapping), we need to check if it matches the corresponding opening bracket. To do this, we pop the top element from the stack (if it exists) and store it in top_element. We use a dummy value '#' if the stack is empty to avoid errors.

  12. -
  13. We then compare top_element with the corresponding opening bracket using bracket_mapping[char]. If they do not match, it means the string is not valid, and we return False.

  14. -
  15. If the character char is not a bracket, we simply ignore it and continue the loop.

  16. -
  17. After processing the entire string, we check if there are any unmatched opening brackets left in the stack. If the stack is empty, it means all opening brackets have been properly matched and closed, and we return True. Otherwise, we return False.

  18. -
  19. Finally, we provide some test cases at the bottom of the code to demonstrate how the function works for different input strings.

  20. -
-
-
-

Test cases#

-
-
-
# Example 1:
-print(isValid("()"))    
-
-
-
-
-
True
-
-
-
-
-
-
-
# Example 2:
-print(isValid("()[]{}")) 
-
-
-
-
-
True
-
-
-
-
-
-
-
# Example 3:
-print(isValid("(]"))     
-
-
-
-
-
False
-
-
-
-
-

Let’s analyze the time and space complexity of the isValid function:

-

Time Complexity:

-
    -
  • The function iterates through each character in the input string s once, performing constant-time operations for each character.

  • -
  • Pushing and popping elements from the stack (list) also takes constant time in most cases.

  • -
  • Therefore, the overall time complexity of the function is \(O(n)\), where \(n\) is the length of the input string s.

  • -
-

Space Complexity:

-
    -
  • The space complexity of the function is determined by the space used by the stack and the bracket_mapping dictionary.

  • -
  • In the worst case, if the input string s consists entirely of opening brackets, the stack can potentially contain all of these opening brackets, resulting in a space complexity of \(O(n)\) in terms of the stack.

  • -
  • The bracket_mapping dictionary has a constant number of key-value pairs (3 pairs in this case).

  • -
  • Therefore, the overall space complexity of the function is \(O(n)\), where \(n\) is the length of the input string s, mainly due to the stack space.

  • -
-

In summary:

-
    -
  • The time complexity is \(O(n)\) because we iterate through the string once.

  • -
  • The space complexity is \(O(n)\) due to the stack used to keep track of opening brackets.

  • -
-
-
-

Challenging Exercises:#

-
    -
  1. Valid Expressions: Modify the problem to validate not only brackets but also arithmetic expressions containing parentheses, such as “\(2 * (3 + 5) / (4 - 2)\)”.

  2. -
  3. Valid Parentheses Combinations: -Write a function to generate all valid combinations of n pairs of parentheses, where \(n\) is a positive integer. For example, for \(n = 3\), the valid combinations are [“((()))”, “(()())”, “(())()”, “()(())”, “()()()”].

  4. -
-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/04. Stack/README.html b/docs/_build/html/04. Stack/README.html deleted file mode 100644 index 9289c25..0000000 --- a/docs/_build/html/04. Stack/README.html +++ /dev/null @@ -1,617 +0,0 @@ - - - - - - - - - - - - Stack Problems - Blind 75 LeetCode — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Stack Problems - Blind 75 LeetCode

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

Stack Problems - Blind 75 LeetCode#

- - - - - - - - - - - -

Problem Name

Difficulty

20. Valid Parentheses

Easy

-
-

Contribute#

-

If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements.

-
-
-

Resources#

-
    -
  • LeetCode: The official LeetCode website.

  • -
  • LeetCode Discuss: LeetCode’s discussion forum for each problem. You can find helpful hints and discussions here.

  • -
-

Happy coding!

-
-
-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/05. Binary Search/153. Find Minimum in Rotated Sorted Array.html b/docs/_build/html/05. Binary Search/153. Find Minimum in Rotated Sorted Array.html deleted file mode 100644 index d7545de..0000000 --- a/docs/_build/html/05. Binary Search/153. Find Minimum in Rotated Sorted Array.html +++ /dev/null @@ -1,719 +0,0 @@ - - - - - - - - - - - - 153. Find Minimum in Rotated Sorted Array — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

153. Find Minimum in Rotated Sorted Array

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

153. Find Minimum in Rotated Sorted Array#

-

Difficulty: Medium

-

Link to Problem: To see the Find Minimum in Rotated Sorted Array problem on LeetCode, click here!

-
-

Suppose an array of length n sorted in ascending order is rotated between 1 and n times. For example, the array nums = [0,1,2,4,5,6,7] might become:

-
    -
  • [4,5,6,7,0,1,2] if it was rotated 4 times.

  • -
  • [0,1,2,4,5,6,7] if it was rotated 7 times.

  • -
-

Notice that rotating an array [a[0], a[1], a[2], ..., a[n-1]] 1 time results in the array [a[n-1], a[0], a[1], a[2], ..., a[n-2]].

-

Given the sorted rotated array nums of unique elements, return the minimum element of this array.

-

You must write an algorithm that runs in \(O(log\ n)\) time.

-

Constraints:

-
    -
  • n == nums.length

  • -
  • 1 <= n <= 5000

  • -
  • -5000 <= nums[i] <= 5000

  • -
  • All the integers of nums are unique.

  • -
  • nums is sorted and rotated between 1 and n times.

  • -
-
-
-
def findMin(nums):
-    left, right = 0, len(nums) - 1
-    
-    while left < right:
-        mid = left + (right - left) // 2
-        
-        # If the mid element is greater than the rightmost element,
-        # it means the minimum element is in the right half.
-        if nums[mid] > nums[right]:
-            left = mid + 1
-        # If the mid element is less than or equal to the rightmost element,
-        # it means the minimum element is in the left half or at the mid itself.
-        else:
-            right = mid
-    
-    # The loop will break when left and right converge to the minimum element.
-    # At this point, left (or right) will be pointing to the minimum element.
-    return nums[left]
-
-
-
-
-
-

Explanation:#

-
    -
  1. The function findMin(nums) takes an input list nums, which represents the rotated sorted array.

  2. -
  3. Initialize two pointers left and right to track the current search range. Initially, left is set to 0 (the beginning of the array), and right is set to len(nums) - 1 (the end of the array).

  4. -
  5. Enter a while loop with the condition left < right. This loop continues until left and right converge to a single element, which will be the minimum element in the rotated array.

  6. -
  7. Inside the loop, calculate the middle index mid using integer division. This helps in finding the middle element of the current search range.

  8. -
  9. Check if the element at the middle index (nums[mid]) is greater than the element at the rightmost index (nums[right]). If this condition is true, it means that the minimum element must be in the right half of the current search range. So, update left to mid + 1, effectively eliminating the left half of the search range.

  10. -
  11. If the condition from step 5 is not met, it implies that the minimum element can be in the left half of the current search range or could be the element at the mid index itself. In this case, update right to mid, effectively eliminating the right half of the search range.

  12. -
  13. Repeat steps 4-6 until left and right converge to the minimum element.

  14. -
  15. When the loop exits, it means that left (or right) points to the minimum element in the array.

  16. -
  17. Return nums[left] (or nums[right]) as the result, which is the minimum element in the rotated sorted array.

  18. -
-
-
-

Test cases#

-
-
-
### Example 1:
-nums1 = [3, 4, 5, 1, 2]
-print(findMin(nums1))
-
-
-
-
-
1
-
-
-
-
-
-
-
# Example 2:
-nums2 = [4, 5, 6, 7, 0, 1, 2]
-print(findMin(nums2))
-
-
-
-
-
0
-
-
-
-
-
-
-
# Example 3:
-nums3 = [11, 13, 15, 17]
-print(findMin(nums3))
-
-
-
-
-
11
-
-
-
-
-

Let’s analyze the time and space complexity of the provided code:

-

Time Complexity: -The time complexity of this code is \(O(log\ n)\), where ‘\(n\)’ is the length of the input array nums. This is because the binary search algorithm is employed, which continually divides the search range in half with each iteration.

-

In each iteration of the while loop, the search range is halved, and this process continues until the left and right pointers converge to the minimum element. In the worst case, it will take logarithmic time to reduce the search range to a single element.

-

Therefore, the binary search used in this code runs in \(O(log\ n)\) time complexity.

-

Space Complexity: -The space complexity of this code is \(O(1)\), which means it uses a constant amount of additional space that does not depend on the size of the input array.

-

The algorithm uses a fixed number of variables (left, right, mid) to keep track of the search range and indices, but the number of these variables does not grow with the size of the input array. Hence, the space complexity is constant.

-

In summary:

-
    -
  • Time Complexity: \(O(log\ n)\)

  • -
  • Space Complexity: \(O(1)\)

  • -
-
-
-

Challenging Exercises:#

-
    -
  1. Solve the problem with a variation where the input array may contain duplicates.

  2. -
  3. Modify the problem to return the index of the minimum element in the rotated sorted array, rather than the element itself. The algorithm should still run in \(O(log\ n)\) time.

  4. -
  5. Implement a function that finds the maximum element in a rotated sorted array. How would you adapt the binary search algorithm to solve this problem efficiently in \(O(log\ n)\) time?

  6. -
  7. Implement a function that can find the kth smallest element in a rotated sorted array. This is an extension of the original problem, and the algorithm should still run in \(O(log\ n)\) time.

  8. -
-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/05. Binary Search/33. Search in Rotated Sorted Array.html b/docs/_build/html/05. Binary Search/33. Search in Rotated Sorted Array.html deleted file mode 100644 index b778f6e..0000000 --- a/docs/_build/html/05. Binary Search/33. Search in Rotated Sorted Array.html +++ /dev/null @@ -1,739 +0,0 @@ - - - - - - - - - - - - 33. Search in Rotated Sorted Array — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

33. Search in Rotated Sorted Array

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

33. Search in Rotated Sorted Array#

-

Difficulty: Medium

-

Link to Problem: To see the Search in Rotated Sorted Array problem on LeetCode, click here!

-
-

There is an integer array nums sorted in ascending order (with distinct values).

-

Prior to being passed to your function, nums is possibly rotated at an unknown pivot index k (1 <= k < nums.length) such that the resulting array is [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]] (0-indexed). For example, [0,1,2,4,5,6,7] might be rotated at pivot index 3 and become [4,5,6,7,0,1,2].

-

Given the array nums after the possible rotation and an integer target, return the index of target if it is in nums, or -1 if it is not in nums.

-

You must write an algorithm with \(O(log\ n)\) runtime complexity.

-

Constraints:

-
    -
  • 1 <= nums.length <= 5000

  • -
  • \(-10^4\) <= nums[i] <= \(10^4\)

  • -
  • All values of nums are unique.

  • -
  • nums is an ascending array that is possibly rotated.

  • -
  • \(-10^4\) <= target <= \(10^4\)

  • -
-
-
-
def search(nums, target):
-    left, right = 0, len(nums) - 1
-
-    # Find the pivot index using binary search
-    while left < right:
-        mid = left + (right - left) // 2
-
-        if nums[mid] > nums[right]:
-            left = mid + 1
-        else:
-            right = mid
-
-    pivot = left
-    left, right = 0, len(nums) - 1
-
-    # Determine which part of the array to search in
-    if target >= nums[pivot] and target <= nums[right]:
-        left = pivot
-    else:
-        right = pivot
-
-    # Perform binary search to find the target
-    while left <= right:
-        mid = left + (right - left) // 2
-
-        if nums[mid] == target:
-            return mid
-        elif nums[mid] < target:
-            left = mid + 1
-        else:
-            right = mid - 1
-
-    return -1
-
-
-
-
-
-

Explanation:#

-
    -
  1. The search function takes two arguments: nums, which is the rotated sorted array, and target, which is the value we want to find in the array.

  2. -
  3. We initialize two pointers, left and right, which represent the range in which we are going to perform binary search. Initially, left is set to 0, and right is set to the index of the last element in the array (len(nums) - 1).

  4. -
  5. We start by finding the pivot index using binary search. The pivot index is the index at which the array is rotated. We use a while loop to continue the search until left is less than right.

  6. -
  7. Inside the loop, we calculate the middle index mid using integer division. We then compare the value at mid with the value at right. If nums[mid] is greater than nums[right], it means the pivot point lies to the right of mid, so we update left to mid + 1. Otherwise, the pivot point lies to the left of mid, so we update right to mid. This process continues until we find the pivot index.

  8. -
  9. After finding the pivot index, we have divided the array into two parts: one part is sorted in ascending order, and the other part is also sorted in ascending order but rotated. We need to determine which part of the array contains the target value.

  10. -
  11. We reset left and right pointers. If the target value is within the range [nums[pivot], nums[right]], we set left to pivot (the start of the rotated part), indicating that we should search in the rotated part. Otherwise, we set right to pivot (the end of the sorted part), indicating that we should search in the sorted part.

  12. -
  13. We then perform binary search again within the chosen range (left to right) to find the target element. The binary search continues until left is less than or equal to right.

  14. -
  15. Inside the binary search loop, we calculate the middle index mid and compare nums[mid] with the target value. If they are equal, we return mid as the index of the target element. If nums[mid] is less than the target, we update left to mid + 1 to search in the right half. If nums[mid] is greater than the target, we update right to mid - 1 to search in the left half.

  16. -
  17. If we exit the binary search loop without finding the target, we return -1 to indicate that the target is not present in the array.

  18. -
-
-
-

Test cases#

-
-
-
nums1 = [4, 5, 6, 7, 0, 1, 2]
-target1 = 0
-result1 = search(nums1, target1)
-print(result1) 
-
-
-
-
-
4
-
-
-
-
-
-
-
# Example 2:
-nums2 = [4, 5, 6, 7, 0, 1, 2]
-target2 = 3
-result2 = search(nums2, target2)
-print(result2) 
-
-
-
-
-
-1
-
-
-
-
-
-
-
# Example 3:
-nums3 = [1]
-target3 = 0
-result3 = search(nums3, target3)
-print(result3) 
-
-
-
-
-
-1
-
-
-
-
-

Let’s analyze the time and space complexity of the provided code:

-

Time Complexity:

-
    -
  1. Finding the pivot index using binary search takes \(O(log\ n)\) time, where ‘\(n\)’ is the number of elements in the array.

  2. -
  3. After finding the pivot index, performing binary search to find the target element also takes \(O(log\ n)\) time in the worst case.

  4. -
-

The dominant factor in the time complexity is the binary search, and since we perform two binary searches sequentially, the overall time complexity of the code is \(O(log\ n)\).

-

Space Complexity:

-

The space complexity of the code is very minimal:

-
    -
  1. We use a constant amount of additional space for variables such as left, right, pivot, and mid. These variables do not depend on the input size, so they contribute \(O(1)\) space complexity.

  2. -
  3. The function does not use any additional data structures that scale with the input size.

  4. -
-

Therefore, the space complexity of the code is \(O(1)\), which means it has a constant space complexity and does not depend on the size of the input array.

-

In summary:

-
    -
  • Time Complexity: \(O(log\ n)\)

  • -
  • Space Complexity: \(O(1)\)

  • -
-
-
-

Challenging Exercises:#

-
    -
  1. Find Minimum Element in Rotated Sorted Array: Write an algorithm to find the minimum element in a rotated sorted array. This is a variation of the problem where you don’t need to search for a target value but instead find the smallest element.

  2. -
  3. Search in a Circularly Sorted Array: Consider an array that is sorted in a circular manner (e.g., [4, 5, 6, 7, 0, 1, 2, 3]). Adapt the search algorithm to work for circularly sorted arrays while maintaining \(O(log\ n)\) complexity.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/05. Binary Search/README.html b/docs/_build/html/05. Binary Search/README.html deleted file mode 100644 index 1e6e7ec..0000000 --- a/docs/_build/html/05. Binary Search/README.html +++ /dev/null @@ -1,620 +0,0 @@ - - - - - - - - - - - - Binary search Problems - Blind 75 LeetCode — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Binary search Problems - Blind 75 LeetCode

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

Binary search Problems - Blind 75 LeetCode#

- - - - - - - - - - - - - - -

Problem Name

Difficulty

153. Find Minimum In Rotated Sorted Array

Medium

33. Search In Rotated Sorted Array

Medium

-
-

Contribute#

-

If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements.

-
-
-

Resources#

-
    -
  • LeetCode: The official LeetCode website.

  • -
  • LeetCode Discuss: LeetCode’s discussion forum for each problem. You can find helpful hints and discussions here.

  • -
-

Happy coding!

-
-
-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/06. Linked List/141. Linked List Cycle.html b/docs/_build/html/06. Linked List/141. Linked List Cycle.html deleted file mode 100644 index ddbdbff..0000000 --- a/docs/_build/html/06. Linked List/141. Linked List Cycle.html +++ /dev/null @@ -1,755 +0,0 @@ - - - - - - - - - - - - 141. Linked List Cycle — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

141. Linked List Cycle

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

141. Linked List Cycle#

-

Difficulty: Easy

-

Link to Problem: To see the Linked List Cycle problem on LeetCode, click here!

-
-

Given head, the head of a linked list, determine if the linked list has a cycle in it.

-

There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the next pointer. Internally, pos is used to denote the index of the node that tail’s next pointer is connected to. Note that pos is not passed as a parameter.

-

Return true if there is a cycle in the linked list. Otherwise, return false.

-

Constraints:

-
    -
  • The number of the nodes in the list is in the range \([0, 10^4]\).

  • -
  • \(-10^5\) <= Node.val <= \(10^5\)

  • -
  • pos is -1 or a valid index in the linked-list.

  • -
-

Follow up: Can you solve it using \(O(1)\) (i.e. constant) memory?

-
-
-
# Definition for singly-linked list.
-class ListNode:
-    def __init__(self, val=0):
-        self.val = val
-        self.next = None
-
-class Solution:
-    def hasCycle(self, head: ListNode) -> bool:
-        if not head:
-            return False
-        
-        slow = head
-        fast = head
-        
-        while fast and fast.next:
-            slow = slow.next
-            fast = fast.next.next
-            
-            if slow == fast:
-                return True
-        
-        return False
-
-
-
-
-
-

Explanation:#

-

The given code defines a class Solution with a method hasCycle for determining if a linked list has a cycle.

-

The ListNode class represents nodes in the linked list, where each node has a val (a value associated with the node) and a next attribute (a reference to the next node in the list).

-

The hasCycle method takes the head of a linked list as input and returns True if there is a cycle in the linked list, and False otherwise. It uses two pointers, slow and fast, to traverse the linked list. If there is a cycle, the fast pointer will eventually catch up to the slow pointer.

-

The algorithm works as follows:

-
    -
  1. It checks if the input head is None (an empty list). If it is, the method returns False because an empty list can’t have a cycle.

  2. -
  3. Two pointers, slow and fast, initially point to the head of the list.

  4. -
  5. The code enters a while loop where fast moves two steps at a time, and slow moves one step at a time.

  6. -
  7. If there is a cycle, fast will eventually catch up to slow, and the method returns True.

  8. -
  9. If the loop completes without finding a cycle, the method returns False.

  10. -
-
-
-
# Helper function to create a linked list with a cycle
-def create_linked_list_with_cycle(values, pos):
-    dummy = ListNode()
-    current = dummy
-    cycle_node = None
-    
-    for i, val in enumerate(values):
-        current.next = ListNode(val)
-        current = current.next
-        
-        if i == pos:
-            cycle_node = current
-    
-    if cycle_node:
-        current.next = cycle_node
-    
-    return dummy.next
-
-
-
-
-

This helper function is designed to create a linked list with a cycle for testing purposes. It takes two arguments:

-
    -
  1. values: A list of values representing the nodes in the linked list.

  2. -
  3. pos: An integer representing the index of the node where the cycle begins.

  4. -
-

Here’s how the function works:

-
    -
  • It starts by creating an empty ListNode called dummy. This dummy node is used to simplify the creation of the linked list.

  • -
  • It initializes a current pointer to the dummy node. This pointer will be used to traverse the linked list.

  • -
  • It initializes a cycle_node variable to None. This variable will hold the reference to the node where the cycle begins, if any.

  • -
  • It then iterates through the values list, creating a new ListNode for each value and appending it to the linked list.

  • -
  • Inside the loop, it checks if the current index i is equal to the specified pos. If they match, it sets cycle_node to the current node. This simulates the creation of a cycle in the linked list.

  • -
  • After the loop, if cycle_node is not None (indicating a cycle should be created), it connects the last node in the linked list to cycle_node, effectively creating a cycle.

  • -
  • Finally, it returns the reference to the first node of the linked list (not the dummy node).

  • -
-

This helper function allows you to easily create test cases where you can specify the values for the linked list and the position where the cycle starts. It’s particularly useful for testing the code’s ability to detect cycles in linked lists.

-
-
-

Test cases#

-
-
-
### Example 1
-head = [3,2,0,-4]
-pos = 1
-
-head = create_linked_list_with_cycle(head, pos)
-solution = Solution()
-result = solution.hasCycle(head)
-print(result)
-
-
-
-
-
True
-
-
-
-
-
-
-
### Example 2
-head = [1,2]
-pos = 0
-
-head = create_linked_list_with_cycle(head, pos)
-solution = Solution()
-result = solution.hasCycle(head)
-print(result)
-
-
-
-
-
True
-
-
-
-
-
-
-
### Example 3
-head = [1]
-pos = -1
-
-head = create_linked_list_with_cycle(head, pos)
-solution = Solution()
-result = solution.hasCycle(head)
-print(result)
-
-
-
-
-
False
-
-
-
-
-

Let’s discuss the time and space complexity of the code for detecting a cycle in a linked list:

-

Time Complexity:

-

The time complexity of this code is \(O(n)\), where “\(n\)” is the number of nodes in the linked list.

-

The reason for this is that both the slow and fast pointers traverse the linked list, and they move at different speeds. In the worst case, when there is no cycle, the fast pointer will reach the end of the list after going through approximately \(n/2\) nodes. In the case of a cycle, it may take some extra iterations for the fast pointer to catch up to the slow pointer. However, the total number of iterations is still proportional to the number of nodes in the linked list, making it \(O(n)\).

-

Space Complexity:

-

The space complexity of this code is \(O(1)\), which means it uses constant space.

-

The reason for this is that regardless of the size of the linked list, the code only uses two additional pointers (slow and fast) to traverse the list. These pointers do not depend on the size of the input linked list, so the space complexity remains constant.

-

In summary, this code efficiently detects cycles in a linked list with a time complexity of \(O(n)\) and a space complexity of \(O(1)\). It is an example of an algorithm that solves a complex problem with minimal memory usage.

-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/06. Linked List/143. Reorder List.html b/docs/_build/html/06. Linked List/143. Reorder List.html deleted file mode 100644 index 3447be3..0000000 --- a/docs/_build/html/06. Linked List/143. Reorder List.html +++ /dev/null @@ -1,798 +0,0 @@ - - - - - - - - - - - - 143. Reorder List — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

143. Reorder List

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

143. Reorder List#

-

Difficulty: Medium

-

Link to Problem: To see the Reorder List problem on LeetCode, click here!

-
-

You are given the head of a singly linked-list. The list can be represented as:

-

\(L_0 → L_1 → … → L_{n - 1} → L_n\)

-

Reorder the list to be on the following form:

-

\(L_0 → L_n → L_1 → L_{n - 1} → L_2 → L_{n - 2} → …\)

-

You may not modify the values in the list’s nodes. Only nodes themselves may be changed.

-

Constraints:

-
    -
  • The number of nodes in the list is in the range \([1, 5 * 10^4]\).

  • -
  • 1 <= Node.val <= 1000

  • -
-
-
-
class ListNode:
-    def __init__(self, val=0, next=None):
-        self.val = val
-        self.next = next
-
-def reorderList(head):
-    if not head or not head.next:
-        return head
-
-    # Step 1: Find the middle of the linked list
-    slow, fast = head, head
-    while fast.next and fast.next.next:
-        slow = slow.next
-        fast = fast.next.next
-
-    # Split the list into two halves
-    first_half = head
-    second_half = slow.next
-    slow.next = None
-
-    # Step 2: Reverse the second half of the linked list
-    prev = None
-    current = second_half
-    while current:
-        next_node = current.next
-        current.next = prev
-        prev = current
-        current = next_node
-    second_half = prev
-
-    # Step 3: Merge the first and reversed second halves alternately
-    p1, p2 = first_half, second_half
-    while p2:
-        next_p1 = p1.next
-        next_p2 = p2.next
-        p1.next = p2
-        p2.next = next_p1
-        p1 = next_p1
-        p2 = next_p2
-
-    return head
-
-
-
-
-
-

Explanation:#

-

The reorderList function is designed to reorder a singly linked list following the specific pattern described in the problem statement. Here’s a detailed explanation of how the function works:

-
    -
  1. Base Cases Handling:

    -
      -
    • The function first checks if the input linked list is empty (not head) or contains only one element (not head.next). If either of these conditions is met, the list cannot be reordered, so the function returns the original list as-is.

    • -
    -
  2. -
  3. Finding the Middle of the Linked List:

    -
      -
    • To reorder the list, we first need to find the middle point so that we can split the list into two halves. This is done using two pointers, slow and fast, initialized to the head of the list.

    • -
    • slow moves one step at a time while fast moves two steps at a time. When fast reaches the end of the list or the second-to-last node, slow will be at the middle node.

    • -
    -
  4. -
  5. Splitting the List:

    -
      -
    • After finding the middle node, we split the list into two halves:

      -
        -
      • The first half, first_half, contains nodes from the beginning up to the middle.

      • -
      • The second half, second_half, contains nodes from the middle to the end.

      • -
      -
    • -
    • To split the list, we set the next pointer of the node before the middle node to None.

    • -
    -
  6. -
  7. Reversing the Second Half:

    -
      -
    • We reverse the second half of the linked list using the prev, current, and next_node pointers.

    • -
    • prev is initially None, and we iterate through the second half. For each node, we:

      -
        -
      • Set the next of the current node to prev, effectively reversing the next pointer direction.

      • -
      • Update prev to the current node.

      • -
      • Move to the next node using the next_node.

      • -
      -
    • -
    -
  8. -
  9. Merging the Two Halves Alternately:

    -
      -
    • We now have two linked lists: first_half and the reversed second_half.

    • -
    • We merge these two lists alternately by adjusting the next pointers of the nodes.

    • -
    • p1 and p2 are pointers to the current nodes in first_half and second_half, respectively.

    • -
    • We iterate through both lists while reordering nodes:

      -
        -
      • Set the next of p1 to p2 to link a node from the first half to a node from the reversed second half.

      • -
      • Update p1 and p2 to their respective next nodes.

      • -
      • Repeat this process until we have processed all nodes in both halves.

      • -
      -
    • -
    -
  10. -
  11. Returning the Reordered List:

    -
      -
    • After the merging process is complete, the linked list is reordered as specified.

    • -
    • The function returns the head of the reordered list.

    • -
    -
  12. -
-

The overall result is a singly linked list that has been reordered according to the given pattern. The time complexity of this algorithm is O(N), where N is the number of nodes in the linked list, as we traverse the list once to find the middle, once to reverse the second half, and once to merge the two halves.

-
-
-
# Helper function to print the linked list
-def printLinkedList(head):
-    result = []
-    while head:
-        result.append(head.val)
-        head = head.next
-    return result
-
-
-
-
-

Let’s explain the helper functions: -printLinkedList Function:

-
    -
  • The printLinkedList function takes the head of a linked list as input and returns a list of values representing the nodes in the linked list.

  • -
  • Inside the function, a result list is initialized to store the values of the linked list nodes.

  • -
  • The function then iterates through the linked list starting from the head node and appends the val attribute of each node to the result list.

  • -
  • As it iterates through the list, it moves to the next node using the next attribute of each node.

  • -
  • Finally, the function returns the result list containing the values of the linked list nodes in the order they appear in the linked list.

  • -
-

This function is useful for debugging and displaying the contents of a linked list. It allows you to easily convert a linked list into a regular Python list for visualization and testing purposes.

-
-
-

Test cases#

-
-
-
# Example 1
-head1 = ListNode(1, ListNode(2, ListNode(3, ListNode(4))))
-reorderList(head1)
-print(printLinkedList(head1))
-
-
-
-
-
[1, 4, 2, 3]
-
-
-
-
-
-
-
# Example 2
-head2 = ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5)))))
-reorderList(head2)
-print(printLinkedList(head2))
-
-
-
-
-
[1, 5, 2, 4, 3]
-
-
-
-
-

Let’s analyze the time and space complexity of the reorderList function:

-

Time Complexity:

-
    -
  1. Finding the Middle of the Linked List: In this step, we use two pointers, one moving one step at a time (slow) and the other moving two steps at a time (fast). This process takes \(O(N/2)\) time, where \(N\) is the number of nodes in the linked list.

  2. -
  3. Splitting the List: After finding the middle, we split the list into two halves by setting the next pointer of the node before the middle node to None. This step takes \(O(1)\) time.

  4. -
  5. Reversing the Second Half: We reverse the second half of the linked list using a while loop that iterates through the second half of the list once. Therefore, this step also takes \(O(N/2)\) time.

  6. -
  7. Merging the Two Halves Alternately: In this step, we merge the two halves alternately by adjusting the next pointers of the nodes. We iterate through both halves once, so this step takes \(O(N/2)\) time.

  8. -
-

Overall, the time complexity of the reorderList function is dominated by the steps involving reversing and merging the two halves, both of which take \(O(N/2)\) time. Therefore, the total time complexity is \(O(N)\).

-

Space Complexity: -The space complexity of the reorderList function is primarily determined by the variables and data structures used within the function. Let’s break down the space complexity components:

-
    -
  1. Constant Space Variables: The variables slow, fast, prev, current, next_node, p1, and p2 are used to traverse and manipulate the linked list. These variables occupy constant space, regardless of the input size. Therefore, they contribute \(O(1)\) to the space complexity.

  2. -
  3. Split Linked Lists: In the splitting step, we create two new linked list segments (first_half and second_half) that store references to nodes from the original linked list. These segments occupy space proportional to half of the input list, \(O(N/2)\).

  4. -
  5. Reversed Second Half: During the reversal step, we reverse the second half of the linked list in-place without creating any additional data structures. Therefore, it doesn’t contribute to additional space complexity.

  6. -
  7. Overall: Combining the above components, the total space complexity is \(O(N/2)\), which simplifies to \(O(N)\) in terms of space complexity.

  8. -
-

In summary, the reorderList function has a time complexity of \(O(N)\) and a space complexity of \(O(N)\) due to the creation of two new linked list segments while splitting the list. The constant space variables used for traversal do not significantly impact the overall space complexity.

-
-
-

Challenging Exercises:#

-
    -
  1. Reorder by K Elements: Generalize the reorderList function to reorder the list in a different pattern, where you reorder the list by \(K\) elements at a time. For example, for \(K=3\), you would reorder it as (\(L_0 → L_1 → L_2 → L_n → L_{n-1} → L_{n-2} → ...\)). -You may need to handle cases where the number of nodes is not a multiple of \(K\).

  2. -
  3. Reorder by Odd and Even Nodes: Modify the reorderList function to reorder the list in a pattern where odd-indexed nodes (1-based index) come before even-indexed nodes. For example, (\(L_0 → L_n → L_1 → L_{n-1} → L_2 → L_{n-2} → ...\)).

  4. -
-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/06. Linked List/19. Remove Nth Node From End of List.html b/docs/_build/html/06. Linked List/19. Remove Nth Node From End of List.html deleted file mode 100644 index 8a7a4df..0000000 --- a/docs/_build/html/06. Linked List/19. Remove Nth Node From End of List.html +++ /dev/null @@ -1,775 +0,0 @@ - - - - - - - - - - - - 19. Remove Nth Node From End of List — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

19. Remove Nth Node From End of List

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

19. Remove Nth Node From End of List#

-

Difficulty: Medium

-

Link to Problem: To see the Remove Nth Node From End of List problem on LeetCode, click here!

-
-

Given the head of a linked list, remove the \(n^{th}\) node from the end of the list and return its head.

-

Constraints:

-
    -
  • The number of nodes in the list is sz.

  • -
  • 1 <= sz <= 30

  • -
  • 0 <= Node.val <= 100

  • -
  • 1 <= n <= sz

  • -
-

Follow up: Could you do this in one pass?

-
-
-
class ListNode:
-    def __init__(self, val=0, next=None):
-        self.val = val
-        self.next = next
-
-def removeNthFromEnd(head, n):
-    # Create a dummy node to handle the case of removing the head node.
-    dummy = ListNode(0)
-    dummy.next = head
-    first = dummy
-    second = dummy
-    
-    # Advance the first pointer by n+1 nodes.
-    for _ in range(n + 1):
-        first = first.next
-    
-    # Move both pointers simultaneously until first reaches the end.
-    while first is not None:
-        first = first.next
-        second = second.next
-    
-    # Remove the nth node by updating the next pointer of the previous node.
-    second.next = second.next.next
-    
-    return dummy.next  # Return the modified head of the linked list
-
-
-
-
-
-

Explanation:#

-
    -
  1. We start by defining a ListNode class to represent individual nodes in a linked list. Each node has two attributes: val (the value of the node) and next (a reference to the next node in the list).

  2. -
  3. The removeNthFromEnd function takes the head of a linked list (head) and the value n, which represents the position from the end of the list of the node to be removed. It returns the modified head of the linked list after the removal.

  4. -
  5. We create a dummy node (dummy) at the beginning of the list. This dummy node simplifies the code by handling cases where the head of the list needs to be removed.

  6. -
  7. We initialize two pointers, first and second, both initially pointing to the dummy node.

  8. -
  9. To advance the first pointer by n+1 nodes, we use a for loop. This positions the first pointer n nodes ahead of the second pointer.

  10. -
  11. We then move both first and second pointers simultaneously until first reaches the end of the list. This ensures that the second pointer ends up pointing to the node that needs to be removed.

  12. -
  13. To remove the nth node from the end, we update the next pointer of the node pointed to by the second pointer to skip over the node to be removed.

  14. -
  15. Finally, we return dummy.next, which is the modified head of the linked list without the removed node.

  16. -
  17. Additionally, there are two helper functions:

    -
      -
    • createLinkedList(values) creates a linked list from a list of values.

    • -
    • convertToList(head) converts a linked list back into a list of values.

    • -
    -
  18. -
-
-
-
# Helper function to create a linked list from a list of values.
-def createLinkedList(values):
-    if not values:
-        return None
-    head = ListNode(values[0])
-    current = head
-    for val in values[1:]:
-        current.next = ListNode(val)
-        current = current.next
-    return head
-
-# Helper function to convert a linked list to a list of values.
-def convertToList(head):
-    result = []
-    current = head
-    while current:
-        result.append(current.val)
-        current = current.next
-    return result
-
-
-
-
-

Let’s explain the two helper functions:

-
    -
  1. createLinkedList(values): This function creates a linked list from a list of values.

    -
      -
    • Input: values is a list containing values that you want to insert into the linked list.

    • -
    • Output: The function returns the head of the created linked list.

    • -
    -

    Explanation:

    -
      -
    • The function starts by checking if the values list is empty. If it is, it returns None to indicate an empty linked list.

    • -
    • If the values list is not empty, it creates the first node of the linked list with the value from the first element of values.

    • -
    • It then iterates through the remaining elements of values and creates new nodes for each value, connecting them together using the next attribute to form a linked list.

    • -
    • Finally, it returns the head of the linked list, which is the first node created.

    • -
    -
  2. -
  3. convertToList(head): This function converts a linked list into a list of values.

    -
      -
    • Input: head is the head node of the linked list that you want to convert.

    • -
    • Output: The function returns a list containing the values of the nodes in the linked list in order.

    • -
    -

    Explanation:

    -
      -
    • The function starts by initializing an empty list, result, to store the values of the linked list nodes.

    • -
    • It then iterates through the linked list starting from the head node and appends the val attribute of each node to the result list.

    • -
    • The iteration continues until it reaches the end of the linked list (i.e., the next attribute of the current node becomes None).

    • -
    • After the iteration is complete, the function returns the result list, which now contains the values of all the nodes in the linked list in the same order as they appear in the linked list.

    • -
    -
  4. -
-

These helper functions are useful for creating linked lists from lists of values and converting linked lists back into lists of values, making it easier to work with linked list examples and test cases in a more familiar list format.

-
-
-

Test cases#

-
-
-
# Example 1
-head1 = createLinkedList([1, 2, 3, 4, 5])
-n1 = 2
-new_head1 = removeNthFromEnd(head1, n1)
-print(convertToList(new_head1))
-
-
-
-
-
[1, 2, 3, 5]
-
-
-
-
-
-
-
# Example 2
-head2 = createLinkedList([1])
-n2 = 1
-new_head2 = removeNthFromEnd(head2, n2)
-print(convertToList(new_head2))
-
-
-
-
-
[]
-
-
-
-
-
-
-
# Example 3
-head3 = createLinkedList([1, 2])
-n3 = 1
-new_head3 = removeNthFromEnd(head3, n3)
-print(convertToList(new_head3))
-
-
-
-
-
[1]
-
-
-
-
-

Certainly! Let’s analyze the time and space complexity of the removeNthFromEnd function in isolation:

-

Time Complexity:

-
    -
  • The removeNthFromEnd function performs two passes through the linked list. In the worst case, it needs to traverse the entire linked list of length \(N\).

  • -
  • The first pass positions the first pointer \(n\) nodes ahead of the second pointer. This pass takes \(O(N)\) time because it involves iterating through all N nodes.

  • -
  • The second pass moves both first and second pointers simultaneously until first reaches the end of the list. This also takes \(O(N)\) time in the worst case.

  • -
  • Therefore, the overall time complexity of the removeNthFromEnd function is \(O(N)\).

  • -
-

Space Complexity:

-
    -
  • The removeNthFromEnd function uses a constant amount of extra space for its variables (e.g., first, second, and dummy). This space usage does not depend on the size of the linked list.

  • -
  • The space complexity is \(O(1)\), indicating that the space used by the function is constant and independent of the size of the input linked list.

  • -
-

In summary, the removeNthFromEnd function has a time complexity of \(O(N)\) and a space complexity of \(O(1)\). It efficiently removes the nth node from the end of the linked list with a single pass through the list and constant extra space usage.

-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/06. Linked List/206. Reverse Linked List.html b/docs/_build/html/06. Linked List/206. Reverse Linked List.html deleted file mode 100644 index a3b1e03..0000000 --- a/docs/_build/html/06. Linked List/206. Reverse Linked List.html +++ /dev/null @@ -1,831 +0,0 @@ - - - - - - - - - - - - 206. Reverse Linked List — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

206. Reverse Linked List

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

206. Reverse Linked List#

-

Difficulty: Easy

-

Link to Problem: To see the Reverse Linked List problem on LeetCode, click here!

-
-

Given the head of a singly linked list, reverse the list, and return the reversed list.

-

Constraints:

-
    -
  • The number of nodes in the list is the range [0, 5000].

  • -
  • -5000 <= Node.val <= 5000

  • -
-

Follow up: A linked list can be reversed either iteratively or recursively. Could you implement both?

-
-
-
# Definition for singly-linked list.
-class ListNode:
-    def __init__(self, val=0, next=None):
-        self.val = val
-        self.next = next
-
-# Function to reverse a linked list iteratively
-def reverseListIterative(head):
-    prev = None
-    current = head
-    
-    while current:
-        next_node = current.next
-        current.next = prev
-        prev = current
-        current = next_node
-    
-    return prev
-
-# Function to reverse a linked list recursively
-def reverseListRecursive(head):
-    if not head or not head.next:
-        return head
-
-    new_head = reverseListRecursive(head.next)
-    head.next.next = head
-    head.next = None
-
-    return new_head
-
-
-
-
-
-

Explanation:#

-
    -
  1. reverseListIterative(head): This function reverses a linked list iteratively using a loop. Here’s a step-by-step explanation:

    -
      -
    • It takes the head of the input linked list as a parameter.

    • -
    • It initializes two pointers, prev and current, initially set to None and the head of the list, respectively.

    • -
    • It enters a while loop that continues until current reaches the end of the list (i.e., becomes None).

    • -
    • Inside the loop:

      -
        -
      • It stores the next_node which is the next node after current.

      • -
      • It updates the next pointer of current to point to the prev node. This effectively reverses the link direction.

      • -
      • It moves prev to current and current to next_node, advancing the pointers one step further in the list.

      • -
      -
    • -
    • Once the loop completes, prev will be pointing to the new head of the reversed list (which was the last node of the original list), so it returns prev.

    • -
    -
  2. -
  3. reverseListRecursive(head): This function reverses a linked list recursively. Here’s how it works:

    -
      -
    • It takes the head of the input linked list as a parameter.

    • -
    • The base case is checked: if head is None or head.next is None, meaning the list is empty or has only one node, it returns head as there’s no need to reverse a list with zero or one element.

    • -
    • In the recursive case:

      -
        -
      • It calls itself with head.next, effectively moving down the list until it reaches the end.

      • -
      • Once it reaches the end, it starts reversing the links:

        -
          -
        • head.next.next is set to head, reversing the link between head and the next node.

        • -
        • head.next is set to None to avoid cycles.

        • -
        -
      • -
      -
    • -
    • Finally, it returns the new head of the reversed list, which will be the last node of the original list.

    • -
    -
  4. -
-

In summary, reverseListIterative reverses the linked list by iterating through it and changing the next pointers, while reverseListRecursive reverses the linked list by recursively reaching the end and then reversing the links on the way back up the recursion stack. Both functions achieve the same result: reversing the linked list.

-
-
-
# Helper function to create a linked list from a list of values
-def createLinkedList(values):
-    if not values:
-        return None
-    head = ListNode(values[0])
-    current = head
-    for val in values[1:]:
-        current.next = ListNode(val)
-        current = current.next
-    return head
-
-# Helper function to convert a linked list to a list for testing
-def linkedListToList(head):
-    result = []
-    current = head
-    while current:
-        result.append(current.val)
-        current = current.next
-    return result
-
-
-
-
-

Let’s explain the two helper functions used in the provided code:

-
    -
  1. createLinkedList(values):

    -
      -
    • Purpose: This function is used to create a linked list from a list of values. It takes a list of values as input and returns the head of the linked list.

    • -
    • How it works:

      -
        -
      • It first checks if the input list values is empty. If it’s empty, it returns None to indicate an empty linked list.

      • -
      • If values is not empty, it initializes a head node with the value of the first element in values.

      • -
      • It then iterates through the remaining values in values, creating new nodes for each value and linking them together to form a linked list.

      • -
      • Finally, it returns the head node of the newly created linked list.

      • -
      -
    • -
    -
  2. -
  3. linkedListToList(head):

    -
      -
    • Purpose: This function is used to convert a linked list back into a Python list for testing and output purposes.

    • -
    • How it works:

      -
        -
      • It takes the head of the linked list as input.

      • -
      • It initializes an empty list called result.

      • -
      • It then iterates through the linked list, starting from head, and appends each node’s val (value) to the result list.

      • -
      • This process continues until the end of the linked list is reached.

      • -
      • Finally, it returns the result list, which contains the values from the linked list in the same order.

      • -
      -
    • -
    -
  4. -
-

These helper functions are used to simplify the process of creating linked lists from lists of values and converting linked lists back into lists, making it easier to work with linked lists in the provided examples and test cases.

-
-
-

Test cases#

-
-
-
# Example 1: Iterative
-head1 = [1,2,3,4,5]
-head1 = createLinkedList(head1)
-reversed_head1 = reverseListIterative(head1)
-print(linkedListToList(reversed_head1))
-
-
-
-
-
[5, 4, 3, 2, 1]
-
-
-
-
-
-
-
# Example 2: Recursive
-head2 = [1,2]
-head2 = createLinkedList(head2)
-reversed_head2 = reverseListRecursive(head2)
-print(linkedListToList(reversed_head2))
-
-
-
-
-
[2, 1]
-
-
-
-
-
-
-
# Example 3: Empty list
-head3 = []
-head3 = createLinkedList(head3)
-reversed_head3 = reverseListIterative(head3)
-print(linkedListToList(reversed_head3))
-
-
-
-
-
[]
-
-
-
-
-

Let’s analyze the time and space complexity of the two functions:

-
    -
  1. reverseListIterative(head):

    -
      -
    • Time Complexity: \(O(n)\)

      -
        -
      • The iterative function visits each node in the linked list exactly once in a single pass, where “\(n\)” is the number of nodes in the list. Therefore, the time complexity is linear in the number of nodes.

      • -
      -
    • -
    • Space Complexity: \(O(1)\)

      -
        -
      • This function uses a constant amount of extra space for the prev, current, and next_node pointers. Regardless of the size of the input list, the amount of additional memory used remains the same, so the space complexity is constant.

      • -
      -
    • -
    -
  2. -
  3. reverseListRecursive(head):

    -
      -
    • Time Complexity: \(O(n)\)

      -
        -
      • The recursive function also visits each node in the linked list exactly once. It recursively traverses the list from the head to the tail, reversing the links on the way back. Therefore, like the iterative approach, the time complexity is \(O(n)\), where “\(n\)” is the number of nodes.

      • -
      -
    • -
    • Space Complexity: \(O(n)\)

      -
        -
      • The recursive function uses space on the call stack for each recursive call. In the worst case, when the list has “\(n\)” nodes, it will create “\(n\)” recursive function calls on the stack, resulting in a space complexity of \(O(n)\). This is because each function call stores information about its state, including the head pointer, until it reaches the base case and starts returning.

      • -
      -
    • -
    -
  4. -
-

In summary:

-
    -
  • The time complexity of both functions is \(O(n)\) because they both visit each node once.

  • -
  • The space complexity of reverseListIterative is \(O(1)\) because it uses a constant amount of extra space.

  • -
  • The space complexity of reverseListRecursive is \(O(n)\) due to the recursive function calls and the associated call stack space.

  • -
-

Both functions are efficient in terms of time complexity, but reverseListIterative is more memory-efficient because it uses a constant amount of additional space, while reverseListRecursive uses space on the call stack proportional to the number of nodes in the list.

-
-
-

Challenging Exercises:#

-
    -
  1. K-Group Reverse: Modify the reverseListIterative function to reverse the linked list in groups of \(K\) elements. For example, if the input linked list is [1, 2, 3, 4, 5, 6], and \(K\) is 3, the output should be [3, 2, 1, 6, 5, 4].

  2. -
  3. Rotate Linked List: Write a function to rotate a linked list to the right by \(K\) places. For example, if the input is [1, 2, 3, 4, 5] and \(K\) is 2, the output should be [4, 5, 1, 2, 3].

  4. -
-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/06. Linked List/21. Merge Two Sorted Lists.html b/docs/_build/html/06. Linked List/21. Merge Two Sorted Lists.html deleted file mode 100644 index d075160..0000000 --- a/docs/_build/html/06. Linked List/21. Merge Two Sorted Lists.html +++ /dev/null @@ -1,755 +0,0 @@ - - - - - - - - - - - - 21. Merge Two Sorted Lists — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

21. Merge Two Sorted Lists

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

21. Merge Two Sorted Lists#

-

Difficulty: Easy

-

Link to Problem: To see the Merge Two Sorted Lists problem on LeetCode, click here!

-
-

You are given the heads of two sorted linked lists list1 and list2.

-

Merge the two lists into one sorted list. The list should be made by splicing together the nodes of the first two lists.

-

Return the head of the merged linked list.

-

Constraints:

-
    -
  • The number of nodes in both lists is in the range [0, 50].

  • -
  • -100 <= Node.val <= 100

  • -
  • Both list1 and list2 are sorted in non-decreasing order.

  • -
-
-
-
class ListNode:
-    def __init__(self, val=0, next=None):
-        self.val = val
-        self.next = next
-
-def mergeTwoLists(list1, list2):
-    # Create a dummy node to simplify the code.
-    dummy = ListNode()
-    current = dummy
-
-    while list1 and list2:
-        if list1.val < list2.val:
-            current.next = list1
-            list1 = list1.next
-        else:
-            current.next = list2
-            list2 = list2.next
-        current = current.next
-
-    # Append the remaining elements from either list.
-    if list1:
-        current.next = list1
-    else:
-        current.next = list2
-
-    return dummy.next
-
-
-
-
-
-

Explanation:#

-
    -
  1. We define a class ListNode to represent the nodes of a singly-linked list. Each node has a val attribute to store the value of the node and a next attribute to point to the next node in the list.

  2. -
  3. We define the mergeTwoLists function that takes two linked list heads, list1 and list2, as input.

  4. -
  5. We create a dummy node at the beginning of the merged list. The dummy node simplifies the code by serving as a placeholder, and its next attribute will point to the actual merged list.

  6. -
  7. We initialize a current pointer to point to the dummy node initially. This current pointer helps us traverse and build the merged list.

  8. -
  9. We enter a while loop that continues until either list1 or list2 becomes empty. Inside the loop, we compare the values of the nodes at the current positions of list1 and list2.

  10. -
  11. If the val of the node in list1 is smaller than the val of the node in list2, we attach the node from list1 to the merged list by updating the next attribute of the current node to point to the node in list1. We then move the list1 pointer to the next node.

  12. -
  13. If the val of the node in list2 is smaller than or equal to the val of the node in list1, we attach the node from list2 to the merged list in a similar manner. We move the list2 pointer to the next node.

  14. -
  15. After attaching a node to the merged list, we move the current pointer to the newly added node. This step is essential for keeping track of the end of the merged list.

  16. -
  17. The loop continues until either list1 or list2 becomes empty.

  18. -
  19. Once the loop exits, we check if there are any remaining elements in list1 or list2. If list1 is not empty, we attach the remaining elements of list1 to the merged list. If list2 is not empty, we attach the remaining elements of list2.

  20. -
  21. Finally, we return the next attribute of the dummy node as the head of the merged list, which represents the sorted merged list.

  22. -
-
-
-
# Helper function to print the linked list
-def printLinkedList(head):
-    result = []
-    while head:
-        result.append(head.val)
-        head = head.next
-    return result
-
-
-
-
-

Let’s explain the helper functions: -printLinkedList Function:

-
    -
  • The printLinkedList function takes the head of a linked list as input and returns a list of values representing the nodes in the linked list.

  • -
  • Inside the function, a result list is initialized to store the values of the linked list nodes.

  • -
  • The function then iterates through the linked list starting from the head node and appends the val attribute of each node to the result list.

  • -
  • As it iterates through the list, it moves to the next node using the next attribute of each node.

  • -
  • Finally, the function returns the result list containing the values of the linked list nodes in the order they appear in the linked list.

  • -
-

This function is useful for debugging and displaying the contents of a linked list. It allows you to easily convert a linked list into a regular Python list for visualization and testing purposes.

-
-
-

Test cases#

-
-
-
# Example 1:
-# Input: list1 = [1,2,4], list2 = [1,3,4]
-list1 = ListNode(1, ListNode(2, ListNode(4)))
-list2 = ListNode(1, ListNode(3, ListNode(4)))
-merged_list = mergeTwoLists(list1, list2)
-printLinkedList(merged_list)
-
-
-
-
-
[1, 1, 2, 3, 4, 4]
-
-
-
-
-
-
-
# Example 2:
-# Input: list1 = [], list2 = []
-list1 = None
-list2 = None
-merged_list = mergeTwoLists(list1, list2)
-printLinkedList(merged_list)
-
-
-
-
-
[]
-
-
-
-
-
-
-
# Example 3:
-# list1 = [], list2 = [0]
-list1 = None
-list2 = ListNode(0)
-merged_list = mergeTwoLists(list1, list2)
-printLinkedList(merged_list)
-
-
-
-
-
[0]
-
-
-
-
-

Let’s analyze the time and space complexity of the mergeTwoLists function.

-

Time Complexity:

-

The time complexity of this function is \(O(N + M\)), where \(N\) and \(M\) are the lengths of list1 and list2, respectively. Here’s why:

-
    -
  1. In the worst case, we need to traverse both list1 and list2 completely. This involves iterating through all the nodes in both lists once.

  2. -
  3. The while loop runs until either list1 or list2 becomes empty. The number of iterations depends on the total number of nodes in both lists, which is N + M in the worst case.

  4. -
  5. Inside the loop, we perform constant-time operations for each iteration, such as comparisons and updating pointers.

  6. -
-

Therefore, the dominant factor in the time complexity is the combined length of both input lists, resulting in a linear time complexity of \(O(N + M)\).

-

Space Complexity:

-

The space complexity of this function is \(O(1)\), which means it uses a constant amount of extra space regardless of the input sizes. Here’s why:

-
    -
  1. We create a few extra pointers (dummy, current) and temporary variables (val) to manage the merging process. These consume a fixed amount of memory, regardless of the input sizes. The number of these extra variables is independent of the lengths of list1 and list2.

  2. -
  3. We do not create a new data structure or allocate memory for the merged list. Instead, we rearrange the existing nodes from list1 and list2 to form the merged list. This operation does not consume additional memory proportional to the input sizes.

  4. -
-

In summary, the mergeTwoLists function has a time complexity of \(O(N + M)\) and a space complexity of \(O(1)\), making it an efficient solution for merging two sorted linked lists.

-
-
-

Challenging Exercises:#

-
    -
  1. Merge K Sorted Lists: Extend the problem to merge \(K\) sorted linked lists instead of just two. You need to efficiently merge \(K\) lists into one sorted list.

  2. -
  3. Merge Lists in a Zigzag Pattern: Merge two sorted lists in a zigzag pattern. For example, given [1, 2, 4] and [1, 3, 5], the merged list should be [1, 1, 2, 3, 4, 5].

  4. -
-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/06. Linked List/23. Merge k Sorted Lists.html b/docs/_build/html/06. Linked List/23. Merge k Sorted Lists.html deleted file mode 100644 index d49d6f0..0000000 --- a/docs/_build/html/06. Linked List/23. Merge k Sorted Lists.html +++ /dev/null @@ -1,783 +0,0 @@ - - - - - - - - - - - - 23. Merge k Sorted Lists — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

23. Merge k Sorted Lists

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

23. Merge k Sorted Lists#

-

Difficulty: Hard

-

Link to Problem: To see the Merge k Sorted Lists problem on LeetCode, click here!

-
-

You are given an array of \(k\) linked-lists lists, each linked-list is sorted in ascending order.

-

Merge all the linked-lists into one sorted linked-list and return it.

-

Constraints:

-
    -
  • k == lists.length

  • -
  • 0 <= k <= \(10^4\)

  • -
  • 0 <= lists[i].length <= 500

  • -
  • \(-10^4\) <= lists[i][j] <= \(10^4\)

  • -
  • lists[i] is sorted in ascending order.

  • -
  • The sum of lists[i].length will not exceed \(10^4\).

  • -
-
-
-
# Definition for singly-linked list.
-class ListNode:
-     def __init__(self, val=0, next=None):
-         self.val = val
-         self.next = next
-
-class Solution:
-    def mergeKLists(self, lists: [[ListNode]]) -> ListNode:
-        # Check if the input list of linked lists is empty
-        if not lists or len(lists) == 0:
-            return None
-
-        # Loop until there is only one merged list left
-        while len(lists) > 1:
-            mergedLists = []
-
-            # Merge pairs of lists
-            for i in range(0, len(lists), 2):
-                l1 = lists[i]
-                l2 = lists[i + 1] if (i + 1) < len(lists) else None
-                mergedLists.append(self.mergeList(l1, l2))
-
-            # Update the list of lists with merged results
-            lists = mergedLists
-        
-        # Return the final merged list
-        return lists[0]
-
-    def mergeList(self, l1, l2):
-        # Create a dummy node to simplify merging
-        dummy = ListNode()
-        tail = dummy
-
-        # Merge the two sorted lists
-        while l1 and l2:
-            if l1.val < l2.val:
-                tail.next = l1
-                l1 = l1.next
-            else:
-                tail.next = l2
-                l2 = l2.next
-            tail = tail.next
-
-        # Append any remaining elements from l1 or l2 (if any)
-        if l1:
-            tail.next = l1
-        if l2:
-            tail.next = l2
-
-        # Return the merged result starting from the next of the dummy node
-        return dummy.next
-
-
-
-
-
-

Explanation:#

-

The provided code defines a Python class Solution with two methods for merging k sorted linked lists:

-
    -
  1. mergeKLists(self, lists: List[ListNode]) -> ListNode: This method takes a list of k sorted linked lists as input and returns a single merged sorted linked list. It uses a divide-and-conquer approach to repeatedly merge pairs of lists until only one merged list remains.

  2. -
  3. mergeList(self, l1, l2): This method takes two sorted linked lists, l1 and l2, as input and merges them into a single sorted linked list. It uses a dummy node to simplify the merging process.

  4. -
-

Here’s a high-level overview of how the code works:

-
    -
  • The mergeKLists method checks if the input list of linked lists is empty or contains no lists. If there are no lists, it returns None.

  • -
  • Inside a while loop, the code repeatedly merges pairs of linked lists until only one merged list remains in the lists array. It does this by iterating through the input lists in pairs and calling the mergeList method to merge each pair.

  • -
  • The mergeList method takes two sorted linked lists, l1 and l2, and merges them into a single sorted linked list. It uses a dummy node (dummy) and a tail pointer to keep track of the merged list while comparing and merging elements from l1 and l2.

  • -
  • After merging all pairs of lists and updating the lists array with the merged results, the loop continues until only one merged list remains in the lists array.

  • -
  • Finally, the mergeKLists method returns the merged list.

  • -
-

Overall, this code efficiently merges k sorted linked lists using a divide-and-conquer strategy, resulting in a single merged sorted linked list as the output.

-
-
-

Test cases#

-
-
-
### Example 1
-# Input: lists = [[1,4,5],[1,3,4],[2,6]]
-
-lists1 = [
-    ListNode(1, ListNode(4, ListNode(5))),
-    ListNode(1, ListNode(3, ListNode(4))),
-    ListNode(2, ListNode(6))
-]
-solution = Solution()
-result1 = solution.mergeKLists(lists1)
-
-# Print the result
-if result1:
-    current = result1
-    while current:
-        print(current.val, end=" -> ")
-        current = current.next
-else:
-    print("None")  # Print "None" for input with a single None element
-
-
-
-
-
1 -> 1 -> 2 -> 3 -> 4 -> 4 -> 5 -> 6 -> 
-
-
-
-
-
-
-
### Example 2
-# Input: lists = []
-
-lists2 = []
-solution = Solution()
-result2 = solution.mergeKLists(lists2)
-
-# Print the result
-if result2:
-    current = result2
-    while current:
-        print(current.val, end=" -> ")
-        current = current.next
-else:
-    print("None")  # Print "None" for input with a single None element
-
-
-
-
-
None
-
-
-
-
-
-
-
### Example 3
-# Input: lists = [[]]
-
-lists3 = [None]
-solution = Solution()
-result3 = solution.mergeKLists(lists3)
-
-# Print the result
-if result3:
-    current = result3
-    while current:
-        print(current.val, end=" -> ")
-        current = current.next
-else:
-    print("None")  # Print "None" for input with a single None element
-
-
-
-
-
None
-
-
-
-
-

Let’s analyze the time and space complexity of the provided code:

-

Time Complexity:

-
    -
  1. Heap Initialization: The code does not use a heap. Instead, it uses a divide-and-conquer approach. The initial check for empty input lists takes \(O(1)\) time.

  2. -
  3. Merging: The merging operation is performed in a divide-and-conquer fashion. In each iteration of the while loop, we merge pairs of linked lists, and the number of comparisons made is proportional to the total number of nodes across all the linked lists (\(n\)). In each merge step, we effectively process each node once. The number of iterations required to reduce k lists to 1 is \(O(log\ k)\).

    -

    Therefore, the overall time complexity of the code is \(O(n * log\ k)\), where n is the total number of nodes across all lists, and \(k\) is the number of linked lists.

    -
  4. -
-

Space Complexity:

-
    -
  1. Heap Space: The code doesn’t use a heap data structure, so there’s no additional space complexity due to a heap.

  2. -
  3. Merged Lists: In the mergeList method, we create a new merged list. However, this list is not stored in memory for all lists; it’s replaced with each merged pair. The space used for these merged lists is proportional to the size of the largest merged list, which is \(O(n)\) in the worst case.

  4. -
  5. Additional Variables: The code uses a few additional variables, such as dummy and tail, but these occupy a constant amount of space and don’t depend on the input size.

    -

    Therefore, the overall space complexity of the code is \(O(n)\), where n is the total number of nodes across all lists.

    -
  6. -
-

In summary, the code’s time complexity is \(O(n * log(k))\), and its space complexity is \(O(n)\). This code efficiently merges \(k\) sorted linked lists using a divide-and-conquer approach with a relatively low space overhead.

-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/06. Linked List/README.html b/docs/_build/html/06. Linked List/README.html deleted file mode 100644 index f615d60..0000000 --- a/docs/_build/html/06. Linked List/README.html +++ /dev/null @@ -1,632 +0,0 @@ - - - - - - - - - - - - Linked List Problems - Blind 75 LeetCode — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Linked List Problems - Blind 75 LeetCode

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

Linked List Problems - Blind 75 LeetCode#

- - - - - - - - - - - - - - - - - - - - - - - - - - -

Problem Name

Difficulty

206. Reverse Linked List

Easy

21. Merge Two Sorted Lists

Easy

143. Reorder List

Medium

19. Remove Nth Node From End of List

Medium

141. Linked List Cycle

Medium

23. Merge K Sorted Lists

Hard

-
-

Contribute#

-

If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements.

-
-
-

Resources#

-
    -
  • LeetCode: The official LeetCode website.

  • -
  • LeetCode Discuss: LeetCode’s discussion forum for each problem. You can find helpful hints and discussions here.

  • -
-

Happy coding!

-
-
-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/07. Trees/100. Same Tree.html b/docs/_build/html/07. Trees/100. Same Tree.html deleted file mode 100644 index 66a8f9d..0000000 --- a/docs/_build/html/07. Trees/100. Same Tree.html +++ /dev/null @@ -1,727 +0,0 @@ - - - - - - - - - - - - 100: Same Tree — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

100: Same Tree

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

100: Same Tree#

-

Difficulty: Easy

-

Link to Problem: To see the Same Tree problem on LeetCode, click here!

-
-

Given the roots of two binary trees p and q, write a function to check if they are the same or not.

-

Two binary trees are considered the same if they are structurally identical, and the nodes have the same value.

-

Constraints

-
    -
  1. The number of nodes in both trees is in the range [0, 100].

  2. -
  3. \(-10^4\) <= Node.val <= \(10^4\)

  4. -
-
-
-
# Definition for a binary tree node.
-class TreeNode:
-    def __init__(self, val=0, left=None, right=None):
-        # Initialize a TreeNode with a value (val), left child, and right child.
-        self.val = val
-        self.left = left
-        self.right = right
-
-def isSameTree(p, q):
-    # Base case: If both p and q are None, the trees are the same.
-    if not p and not q:
-        return True
-    
-    # Base case: If either p or q is None (but not both), the trees are different.
-    if not p or not q:
-        return False
-    
-    # Check if the values of the current nodes (p.val and q.val) are equal.
-    if p.val != q.val:
-        return False
-    
-    # Recursively check the left and right subtrees of p and q.
-    # If both subtrees are the same, the entire trees are the same.
-    return isSameTree(p.left, q.left) and isSameTree(p.right, q.right)
-
-
-
-
-

In this code, we define a TreeNode class to represent binary tree nodes and a isSameTree function to check if two binary trees are the same. The function uses recursive traversal to compare the trees’ structures and values.

-
    -
  1. We start by defining a TreeNode class, which represents a node in a binary tree. Each node has a val (the node’s value), a left child, and a right child. This class will help us create and work with binary trees.

  2. -
  3. Next, we define the isSameTree function, which checks if two binary trees (p and q) are the same.

    -
      -
    • The base case for the recursion is when both p and q are None. In this case, they are considered the same, so we return True.

    • -
    • If either p or q is None (but not both), they cannot be the same, so we return False.

    • -
    • If the values of the current nodes p.val and q.val are not equal, we return False because the trees cannot be the same.

    • -
    • Finally, we recursively check the left and right subtrees of p and q to see if they are the same.

    • -
    -
  4. -
-
-

Test cases#

-
-
-
### Example 1
-
-#Input: `p = [1,2,3]`, `q = [1,2,3]`
-
-p1 = TreeNode(1, TreeNode(2), TreeNode(3))
-q1 = TreeNode(1, TreeNode(2), TreeNode(3))
-print(isSameTree(p1, q1)) 
-
-
-
-
-
True
-
-
-
-
-
-
-
### Example 2
-
-#Input: `p = [1,2]`, `q = [1,null,2]`
-
-p2 = TreeNode(1, TreeNode(2), None)
-q2 = TreeNode(1, None, TreeNode(2))
-print(isSameTree(p2, q2))
-
-
-
-
-
False
-
-
-
-
-
-
-
### Example 3
-
-#Input: p = [1,2,1], q = [1,1,2]
-
-p3 = TreeNode(1, TreeNode(2), TreeNode(1))
-q3 = TreeNode(1, TreeNode(1), TreeNode(2))
-print(isSameTree(p3, q3))
-
-
-
-
-
False
-
-
-
-
-
-
-

Time Complexity#

-

The time complexity of the isSameTree function can be analyzed as follows:

-

In the worst case, the function needs to visit every node in both trees once to determine if they are the same. -Since each node is visited exactly once, the time complexity is \(O(n)\), where \(n\) is the total number of nodes in the input trees.

-
-
-

Space Complexity#

-

The space complexity of the isSameTree function can be analyzed as follows:

-

The space used by the function’s call stack during recursion is proportional to the maximum depth of the binary trees. -In the worst case, when the trees are completely unbalanced (all nodes form a single branch), the maximum depth will be \(n\), where \(n\) is the total number of nodes in the input trees. -Therefore, the space complexity is \(O(n)\) due to the recursive call stack. -In addition to the call stack, there is a small constant amount of space used for variables and comparisons within each recursive call, but this space is not significant in terms of the overall space complexity.

-
-
-

In summary:#

-
    -
  • Time Complexity: \(O(n)\) where \(n\) is the total number of nodes in the input trees.

  • -
  • Space Complexity: \(O(n)\) due to the recursive call stack.

  • -
-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/07. Trees/102. Binary Tree Level Order Traversal.html b/docs/_build/html/07. Trees/102. Binary Tree Level Order Traversal.html deleted file mode 100644 index cd6a1fe..0000000 --- a/docs/_build/html/07. Trees/102. Binary Tree Level Order Traversal.html +++ /dev/null @@ -1,767 +0,0 @@ - - - - - - - - - - - - 102. Binary Tree Level Order Traversal — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

102. Binary Tree Level Order Traversal

- -
- -
-
- - - - -
- -
-

102. Binary Tree Level Order Traversal#

-

Difficulty: Medium

-

Link to Problem: To see the Binary Tree Level Order Traversal problem on LeetCode, click here!

-
-

Given the root of a binary tree, return the level order traversal of its nodes’ values. (i.e., from left to right, level by level).

-

Constraints:

-
    -
  • The number of nodes in the tree is in the range [0, 2000].

  • -
  • -1000 <= Node.val <= 1000

  • -
-
-

Solution:#

-

Here’s a Python function to solve this problem:

-
-
-
class TreeNode:
-    def __init__(self, val=0, left=None, right=None):
-        self.val = val
-        self.left = left
-        self.right = right
-
-def levelOrder(root):
-    # Check if the tree is empty, if so, return an empty list.
-    if not root:
-        return []
-
-    # Initialize an empty list to store the result.
-    result = []
-    
-    # Initialize a queue with the root node to perform BFS.
-    queue = [root]
-
-    while queue:
-        # Initialize an empty list to store the values of nodes at the current level.
-        level_values = []
-        
-        # Get the number of nodes at the current level.
-        level_size = len(queue)
-
-        # Iterate through the nodes at the current level.
-        for _ in range(level_size):
-            # Dequeue the front node from the queue.
-            node = queue.pop(0)
-            
-            # Append the value of the current node to the level_values list.
-            level_values.append(node.val)
-
-            # Enqueue the left and right children of the current node if they exist.
-            if node.left:
-                queue.append(node.left)
-            if node.right:
-                queue.append(node.right)
-
-        # Append the level_values list (values at the current level) to the result list.
-        result.append(level_values)
-
-    # Return the final result, which is a list of lists representing level order traversal.
-    return result
-
-
-
-
-
-
-

Explanation:#

-
    -
  1. We define a TreeNode class that represents a node in the binary tree. Each TreeNode object has a value (val) and two child nodes: left and right.

  2. -
  3. The levelOrder function takes the root of the binary tree as its input and returns the level order traversal of the tree as a list of lists.

  4. -
  5. We start by checking if the input root is None, which indicates an empty tree. If the tree is empty, we return an empty list because there are no nodes to traverse.

  6. -
  7. We initialize an empty list called result to store the final result, which will be a list of lists containing node values at each level.

  8. -
  9. We initialize a queue called queue with the root node. This queue will be used for breadth-first traversal of the tree.

  10. -
  11. We enter a while loop that continues until the queue is empty. Inside the loop, we perform the following steps:

    -
      -
    • We initialize an empty list called level_values to store the values of nodes at the current level.

    • -
    • We determine the number of nodes at the current level by getting the length of the queue. This is done to process nodes level by level.

    • -
    • We iterate through the nodes at the current level using a for loop. For each node in the current level:

      -
        -
      • We dequeue (remove) the front node from the queue.

      • -
      • We append the value of the dequeued node to the level_values list, effectively collecting the values of nodes at the current level.

      • -
      • If the dequeued node has a left child, we enqueue the left child to the queue.

      • -
      • If the dequeued node has a right child, we enqueue the right child to the queue.

      • -
      -
    • -
    • After processing all nodes at the current level, we append the level_values list to the result list. This represents the values at the current level.

    • -
    -
  12. -
  13. The loop continues until all levels have been traversed, and the queue becomes empty.

  14. -
  15. Finally, we return the result list, which contains lists of node values at each level, representing the level order traversal of the binary tree.

  16. -
-

The code effectively performs a breadth-first traversal of the binary tree, processing nodes level by level, and constructs the result list that represents the level order traversal.

-
-
-

Test cases#

-
-
-
# Example 1: 
-
-# Construct the tree
-root = TreeNode(3)
-root.left = TreeNode(9)
-root.right = TreeNode(20)
-root.right.left = TreeNode(15)
-root.right.right = TreeNode(7)
-
-result = levelOrder(root)
-print(result)
-
-
-
-
-
[[3], [9, 20], [15, 7]]
-
-
-
-
-
-
-
# Example 2:
-
-# Using the same tree as before
-root = TreeNode(1)
-result = levelOrder(root)
-print(result)
-
-
-
-
-
[[1]]
-
-
-
-
-
-
-
# Example 3:
-# Creating a new tree for this example
-root = None
-result = levelOrder(root)
-print(result)
-
-
-
-
-
[]
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the levelOrder function:

-

Time Complexity:

-

The time complexity of this function is O(N), where N is the number of nodes in the binary tree. This is because we visit each node exactly once during the breadth-first traversal.

-

In the worst case, we have to enqueue and dequeue all nodes in the binary tree, which is proportional to the number of nodes (N). In each level, we process all nodes in that level, and since there are a total of log(N) levels in a balanced binary tree, the time complexity can also be approximated as O(N) for unbalanced trees.

-

Space Complexity:

-

The space complexity of this function is O(N), where N is the number of nodes in the binary tree. Here’s how the space complexity breaks down:

-
    -
  1. The result list stores the level order traversal, and in the worst case, it contains N/2 levels (for a completely unbalanced binary tree). So, the space used by result is O(N).

  2. -
  3. The queue data structure is used for BFS traversal. In the worst case, it can store all nodes at the last level of the tree. In a balanced binary tree, the maximum number of nodes at any level is 2^(log(N)), which is still O(N). In the case of an unbalanced tree, it can be even worse. So, the space used by queue is O(N).

  4. -
-

Overall, the dominant factor in terms of space complexity is the queue, and the space complexity is O(N).

-

In summary, the function’s time complexity is O(N), and its space complexity is also O(N). It is an efficient and optimal solution for performing a level order traversal of a binary tree.

-
-
-

Challenging Exercises:#

-
    -
  1. Reverse Level Order Traversal: Modify the levelOrder function to return the level order traversal in reverse order (from bottom to top). For example, if the input tree is [3, 9, 20, null, null, 15, 7], the output should be [[15, 7], [9, 20], [3]].

  2. -
  3. Zigzag Level Order Traversal: Write a function that performs a level order traversal of a binary tree in a zigzag pattern. In a zigzag traversal, the nodes at even levels are traversed from left to right, and nodes at odd levels are traversed from right to left. For example, if the input tree is [3, 9, 20, null, null, 15, 7], the output should be [[3], [20, 9], [15, 7]].

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/07. Trees/104. Maximum Depth of Binary Tree.html b/docs/_build/html/07. Trees/104. Maximum Depth of Binary Tree.html deleted file mode 100644 index 37fcb2e..0000000 --- a/docs/_build/html/07. Trees/104. Maximum Depth of Binary Tree.html +++ /dev/null @@ -1,725 +0,0 @@ - - - - - - - - - - - - 104. Maximum Depth of Binary Tree — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

104. Maximum Depth of Binary Tree

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

104. Maximum Depth of Binary Tree#

-

Difficulty: Easy

-

Link to Problem: To see the Invert Binary Tree problem on LeetCode, click here!

-
-

Given the root of a binary tree, return its maximum depth.

-

A binary tree’s maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.

-

Constraints:

-
    -
  • The number of nodes in the tree is in the range \([0, 10^4]\).

  • -
  • -100 <= Node.val <= 100

  • -
-
-
-
# Definition for a binary tree node.
-class TreeNode:
-    def __init__(self, val=0, left=None, right=None):
-        self.val = val
-        self.left = left
-        self.right = right
-
-def maxDepth(root):
-    # Base case: If the root is None, the depth is 0.
-    if root is None:
-        return 0
-    
-    # Recursively calculate the maximum depth of the left and right subtrees.
-    left_depth = maxDepth(root.left)
-    right_depth = maxDepth(root.right)
-    
-    # Return the maximum depth of the tree by adding 1 to the maximum depth of the subtrees.
-    return max(left_depth, right_depth) + 1
-
-
-
-
-
-

Explanation:#

-

Let’s go through the code step by step to understand how it works:

-
    -
  1. We start by defining a TreeNode class to represent the nodes of the binary tree. Each node has three attributes:

    -
      -
    • val: the value stored in the node.

    • -
    • left: a reference to the left child node.

    • -
    • right: a reference to the right child node.

    • -
    -
  2. -
  3. The maxDepth function is the main function that calculates the maximum depth of the binary tree. It takes a single argument, root, which is the root node of the binary tree.

  4. -
  5. In the maxDepth function, we have a base case:

    -
      -
    • If the root is None, it means we have reached the end of a branch of the tree (a leaf node or an empty subtree). In this case, the depth is 0 because there are no nodes to count.

    • -
    -
  6. -
  7. If the root is not None, we recursively calculate the maximum depth of the left and right subtrees:

    -
      -
    • We call maxDepth on the root.left to calculate the maximum depth of the left subtree and store it in the variable left_depth.

    • -
    • We call maxDepth on the root.right to calculate the maximum depth of the right subtree and store it in the variable right_depth.

    • -
    -
  8. -
  9. Finally, we return the maximum depth of the tree by taking the maximum of left_depth and right_depth and adding 1 to it. This is because we are counting the current level as well.

  10. -
-
-
-

Test cases#

-
-
-
### Example 1
-# Input: root = [3,9,20,null,null,15,7]
-
-root = TreeNode(3)
-root.left = TreeNode(9)
-root.right = TreeNode(20)
-root.right.left = TreeNode(15)
-root.right.right = TreeNode(7)
-
-print(maxDepth(root))
-
-
-
-
-
3
-
-
-
-
-

In this example, we create a binary tree based on the given input [3,9,20,null,null,15,7] and calculate its maximum depth, which is 3. The tree structure is as follows:

-
    3
-   / \
-  9  20
-    /  \
-   15   7
-
-
-

So, the maximum depth is the length of the longest path from the root to a leaf node, which is 3 in this case.

-
-
-
### Example 2
-# Input: root = [1,null,2]
-
-root = TreeNode(1)
-root.right = TreeNode(2)
-
-# Calculate the maximum depth of the tree and print the result
-print(maxDepth(root))
-
-
-
-
-
2
-
-
-
-
-

Let’s analyze the time and space complexity of the provided code:

-

Time Complexity:

-
    -
  • The time complexity of the maxDepth function is \(O(N)\), where \(N\) is the number of nodes in the binary tree.

  • -
  • This is because in the worst case, the function visits every node exactly once in a depth-first manner.

  • -
  • The recursion explores all nodes of the tree, so the time complexity is linear with respect to the number of nodes.

  • -
-

Space Complexity:

-
    -
  • The space complexity of the maxDepth function is \(O(H)\), where H is the height of the binary tree.

  • -
  • In the worst case, if the binary tree is completely unbalanced (skewed), the recursion stack can go as deep as the height of the tree.

  • -
  • In the best case, if the binary tree is perfectly balanced, the height is \(O(log\ N)\), where \(N\) is the number of nodes.

  • -
  • Therefore, the space complexity can vary from \(O(log\ N)\) to \(O(N)\) depending on the shape of the tree.

  • -
  • In addition to the recursion stack, there is a small constant amount of space used for variables and function call overhead.

  • -
-

In summary:

-
    -
  • The time complexity of the code is \(O(N)\) as it visits each node once.

  • -
  • The space complexity is \(O(H)\), where H is the height of the tree, which can vary from \(O(log\ N)\) to \(O(N)\) depending on the tree’s shape.

  • -
-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.html b/docs/_build/html/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.html deleted file mode 100644 index cc9832c..0000000 --- a/docs/_build/html/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.html +++ /dev/null @@ -1,803 +0,0 @@ - - - - - - - - - - - - 105. Construct Binary Tree from Preorder and Inorder Traversal — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

105. Construct Binary Tree from Preorder and Inorder Traversal

- -
- -
-
- - - - -
- -
-

105. Construct Binary Tree from Preorder and Inorder Traversal#

-

Difficulty: Medium

-

Link to Problem: To see the Construct Binary Tree from Preorder and Inorder Traversal problem on LeetCode, click here!

-
-

Given two integer arrays preorder and inorder where preorder is the preorder traversal of a binary tree and inorder is the inorder traversal of the same tree, construct and return the binary tree.

-

Constraints:

-
    -
  • 1 <= preorder.length <= 3000

  • -
  • inorder.length == preorder.length

  • -
  • -3000 <= preorder[i], inorder[i] <= 3000

  • -
  • preorder and inorder consist of unique values.

  • -
  • Each value of inorder also appears in preorder.

  • -
  • preorder is guaranteed to be the preorder traversal of the tree.

  • -
  • inorder is guaranteed to be the inorder traversal of the tree.

  • -
-
-

Solution:#

-

Here’s a Python function to solve this problem:

-
-
-
class TreeNode:
-    def __init__(self, val=0, left=None, right=None):
-        self.val = val
-        self.left = left
-        self.right = right
-
-def buildTree(preorder, inorder):
-    if not preorder:
-        return None
-
-    # The first element in the preorder traversal is the root of the current subtree
-    root_val = preorder[0]
-    root = TreeNode(root_val)
-
-    # Find the index of the root value in the inorder traversal
-    root_idx_inorder = inorder.index(root_val)
-
-    # Recursively build left and right subtrees
-    root.left = buildTree(preorder[1:1 + root_idx_inorder], inorder[:root_idx_inorder])
-    root.right = buildTree(preorder[1 + root_idx_inorder:], inorder[root_idx_inorder + 1:])
-
-    return root
-
-
-
-
-
-
-

Explanation:#

-
    -
  1. class TreeNode:: This is a class definition for a binary tree node. It has three attributes:

    -
      -
    • val: The value of the node.

    • -
    • left: A reference to the left child node.

    • -
    • right: A reference to the right child node.

    • -
    -

    This class is used to create instances of binary tree nodes, which will be used to build the binary tree.

    -
  2. -
  3. def buildTree(preorder, inorder):: This is the main function that constructs a binary tree from its preorder and inorder traversals.

    -
      -
    • preorder: A list representing the preorder traversal of the binary tree.

    • -
    • inorder: A list representing the inorder traversal of the binary tree.

    • -
    -
  4. -
  5. if not preorder: return None: This line checks if the preorder list is empty. If it is, it means there are no nodes to construct, so the function returns None.

  6. -
  7. root_val = preorder[0]: The value of the root node is extracted from the first element of the preorder list.

  8. -
  9. root = TreeNode(root_val): A new TreeNode object is created with the root_val as its value. This represents the root of the current subtree.

  10. -
  11. root_idx_inorder = inorder.index(root_val): The index of the root_val in the inorder list is found. This index indicates the position of the root node in the inorder traversal.

  12. -
  13. root.left: The left subtree is constructed recursively by calling the buildTree function with the appropriate sublists of preorder and inorder. The left subtree’s preorder and inorder traversals are the slices of preorder and inorder lists up to the root_idx_inorder.

  14. -
  15. root.right: The right subtree is constructed recursively by calling the buildTree function with the appropriate sublists of preorder and inorder. The right subtree’s preorder and inorder traversals are the slices of preorder and inorder lists starting from root_idx_inorder + 1.

  16. -
  17. Finally, the function returns the root of the subtree it just constructed.

  18. -
-

The recursive approach used here divides the problem of constructing the entire binary tree into smaller subproblems, starting with the root node and then recursively building the left and right subtrees until the entire tree is constructed.

-
-
-

Helper Function#

-

Here is a helper function to represent the binary tree elements.

-
-
-
def treeToList(root):
-    # Initialize an empty list to store the elements of the binary tree
-    result = []
-    
-    # Initialize a queue for level-order traversal starting with the root
-    queue = [root]
-
-    while queue:
-        # Pop the front node from the queue
-        node = queue.pop(0)
-        
-        # If the node is not None (i.e., a valid node), add its value to the result list
-        if node:
-            result.append(node.val)
-            
-            # Add the left and right children of the node to the queue
-            queue.append(node.left)
-            queue.append(node.right)
-        else:
-            # If the node is None, add None to the result to represent an empty node
-            result.append(None)
-
-    # Remove any trailing None values from the result list
-    while result and result[-1] is None:
-        result.pop()
-
-    # Return the resulting list representing the binary tree elements
-    return result
-
-
-
-
-
-
-

Explanation:#

-

Let’s break down the treeToList helper function step by step:

-
    -
  1. def treeToList(root):: This function takes the root of a binary tree as input and converts it into a list.

  2. -
  3. result = []: Initialize an empty list called result to store the elements of the binary tree in list format.

  4. -
  5. queue = [root]: Initialize a queue data structure for a level-order traversal, starting with the root node.

  6. -
  7. while queue:: This starts a loop that continues until the queue is empty, indicating that all nodes have been processed.

  8. -
  9. node = queue.pop(0): Dequeue the first node from the queue, effectively processing it.

  10. -
  11. if node:: Check if the node is not None, which means it’s a valid node in the binary tree.

    -

    a. result.append(node.val): If the node is valid, append its value (node.val) to the result list. This represents the value of the current node in the binary tree.

    -

    b. queue.append(node.left): Enqueue the left child of the current node if it exists. This adds the left child to the queue for processing in the next iteration.

    -

    c. queue.append(node.right): Enqueue the right child of the current node if it exists. This adds the right child to the queue for processing in the next iteration.

    -
  12. -
  13. else:: If the node is None, it represents an empty node in the binary tree.

    -

    a. result.append(None): Append None to the result list to indicate an empty node.

    -
  14. -
  15. while result and result[-1] is None:: After the traversal is complete, there might be trailing None values in the result list. This loop removes any such trailing None values to ensure a clean representation of the tree’s elements.

  16. -
  17. return result: Return the result list, which now contains the elements of the binary tree in a format where None represents empty nodes and the order of elements reflects a level-order traversal of the tree.

  18. -
-

In summary, the treeToList function performs a level-order traversal of the binary tree using a queue, constructing a list where each element corresponds to a node’s value or represents an empty node with None. This list represents the binary tree’s elements in a structured format.

-
-
-

Test cases#

-
-
-
# Example 1: 
-
-# Example usage:
-preorder = [3, 9, 20, 15, 7]
-inorder = [9, 3, 15, 20, 7]
-result = buildTree(preorder, inorder)
-
-print(treeToList(result))
-
-
-
-
-
[3, 9, 20, None, None, 15, 7]
-
-
-
-
-
-
-
# Example 2:
-
-preorder = [-1]
-inorder = [-1]
-result = buildTree(preorder, inorder)
-
-print(treeToList(result))
-
-
-
-
-
[-1]
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the buildTree function:

-

Time Complexity: -The time complexity of the buildTree function can be analyzed in terms of the number of nodes in the binary tree. Let’s assume there are n nodes in the binary tree.

-
    -
  1. Finding the root value in the preorder traversal takes O(1) time as it’s just extracting the first element from the list.

  2. -
  3. Finding the index of the root value in the inorder traversal using inorder.index(root_val) takes O(n) time in the worst case because in the worst case, it might have to search through all n elements in the inorder list to find the index.

  4. -
  5. The recursive calls to buildTree for the left and right subtrees are made once for each node in the tree. Therefore, the recursive calls have a combined time complexity of O(n) as they process each node once.

  6. -
-

The total time complexity of the buildTree function is O(n) due to the recursive calls and finding the root’s index in the inorder list.

-

Space Complexity: -The space complexity is determined by the space used by the function’s call stack during recursion and any additional data structures used.

-
    -
  1. The space used by the function call stack during recursion depends on the height of the binary tree. In the worst case, where the tree is highly unbalanced (e.g., a skewed tree), the space complexity for the call stack is O(n) as it can go as deep as the number of nodes in the tree.

  2. -
  3. Additionally, the function creates TreeNode objects for each node in the binary tree. Therefore, the space complexity for these objects is also O(n).

  4. -
-

Overall, the space complexity of the buildTree function is O(n) due to the space used by the call stack and the TreeNode objects.

-

In summary, the time complexity of buildTree is O(n), and the space complexity is O(n), where ‘n’ is the number of nodes in the binary tree.

-
-
-

Challenging Exercises:#

-
    -
  1. Construct Binary Tree from Postorder and Inorder Traversal: -Modify the problem to construct a binary tree from its postorder and inorder traversals. Implement a function similar to buildTree but for postorder and inorder traversals.

  2. -
  3. Reconstruct Binary Tree with Duplicate Values: -Extend the problem to handle binary trees with duplicate values. Ensure that your solution correctly handles scenarios where there are duplicate values in the preorder and inorder traversals.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/07. Trees/124. Binary Tree Maximum Path Sum.html b/docs/_build/html/07. Trees/124. Binary Tree Maximum Path Sum.html deleted file mode 100644 index b77d871..0000000 --- a/docs/_build/html/07. Trees/124. Binary Tree Maximum Path Sum.html +++ /dev/null @@ -1,759 +0,0 @@ - - - - - - - - - - - - 124. Binary Tree Maximum Path Sum — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

124. Binary Tree Maximum Path Sum

- -
- -
-
- - - - -
- -
-

124. Binary Tree Maximum Path Sum#

-

Difficulty: Hard

-

Link to Problem: To see the Binary Tree Maximum Path Sum problem on LeetCode, click here!

-
-

A path in a binary tree is a sequence of nodes where each pair of adjacent nodes in the sequence has an edge connecting them. A node can only appear in the sequence at most once. Note that the path does not need to pass through the root.

-

The path sum of a path is the sum of the node’s values in the path.

-

Given the root of a binary tree, return the maximum path sum of any non-empty path.

-

Constraints:

-
    -
  • The number of nodes in the tree is in the range \([1, 3*10^4]\).

  • -
  • -1000 <= Node.val <= 1000

  • -
-
-

Probelm Explanation:#

-

The problem is to find the maximum path sum in a binary tree. A path in a binary tree is a sequence of nodes where each pair of adjacent nodes in the sequence has an edge connecting them. The path sum of a path is the sum of the node values in that path.

-

In this problem, you are given the root of a binary tree, and you need to find the maximum path sum among all possible paths in the tree. Note that the path does not need to start at the root node or end at a leaf node; it can start and end at any nodes in the tree.

-

To find the maximum path sum, you need to consider both left and right subtrees of each node while traversing the tree. At each node, you have two choices:

-
    -
  1. Include the current node in the path: In this case, you add the value of the current node to the sum and continue exploring both the left and right subtrees for possible extensions of the path.

  2. -
  3. Start a new path from the current node: In this case, you do not include the current node in the path sum, and you choose either the left subtree or the right subtree to start a new path.

  4. -
-

To solve this problem, you can use a recursive approach to traverse the binary tree. For each node, you calculate the maximum path sum that can pass through that node (option 1) and also return the maximum path sum that can be extended from that node (option 2). You keep track of the global maximum path sum encountered during the traversal.

-

Ultimately, the maximum path sum among all paths in the tree will be the maximum of the global maximum path sum and the maximum path sum calculated for each node.

-

The constraints for this problem include:

-
    -
  • The number of nodes in the tree is in the range \([1, 3 * 10^4]\).

  • -
  • Node values are in the range [-1000, 1000].

  • -
-

By considering all possible paths through the tree, the algorithm aims to find the most significant sum of node values in any path in the binary tree.

-
-
-

Solution:#

-

Here’s a Python function to implement this algorithm:

-
-
-
class TreeNode:
-    def __init__(self, val=0, left=None, right=None):
-        self.val = val
-        self.left = left
-        self.right = right
-
-class Solution:
-    def maxPathSum(self, root):
-        def max_path_sum_helper(node):
-            if not node:
-                return 0
-            
-            # Recursively calculate the maximum path sum for left and right subtrees
-            left_max = max(0, max_path_sum_helper(node.left))
-            right_max = max(0, max_path_sum_helper(node.right))
-            
-            # Update the global maximum path sum
-            self.max_sum = max(self.max_sum, left_max + right_max + node.val)
-            
-            # Return the maximum path sum starting from the current node
-            return max(left_max, right_max) + node.val
-        
-        self.max_sum = float('-inf')  # Initialize the global maximum to negative infinity
-        max_path_sum_helper(root)  # Start the recursive traversal from the root
-        return self.max_sum
-
-
-
-
-
-
-

Explanation:#

-
    -
  1. The code starts by defining a TreeNode class to represent nodes in the binary tree. Each TreeNode has a val attribute representing its value, a left attribute pointing to the left child, and a right attribute pointing to the right child.

  2. -
  3. Next, a Solution class is defined to contain the maxPathSum method, which will be used to find the maximum path sum in the binary tree.

  4. -
  5. Within the maxPathSum method, a helper function called max_path_sum_helper is defined. This recursive function takes a single argument, node, which is the current node being considered during traversal.

  6. -
  7. Inside the max_path_sum_helper function:

    -
      -
    • If node is None (i.e., the current node is a null node), it returns 0. This is the base case of the recursion.

    • -
    • It calculates the maximum path sum starting from the left subtree (left_max) and the right subtree (right_max). Importantly, it uses max(0, ...) to ensure that negative values (which would make the path sum smaller) are not considered. If a subtree’s path sum is negative, it’s better to not include it in the path.

    • -
    • The code then updates the global maximum path sum (self.max_sum) by checking if the sum of left_max, right_max, and the current node’s value is greater than the current maximum.

    • -
    • Finally, it returns the maximum path sum starting from the current node, which is the maximum of left_max and right_max plus the current node’s value.

    • -
    -
  8. -
  9. Before calling the max_path_sum_helper function, the max_sum attribute of the Solution class is initialized to negative infinity (float('-inf')). This is done to ensure that any valid path sum encountered during traversal will be greater than the initial value of max_sum.

  10. -
  11. The max_path_sum_helper function is called with the root of the binary tree, effectively starting the traversal from the root node.

  12. -
  13. Once the traversal is complete, the method returns the value of self.max_sum, which contains the maximum path sum found in the binary tree.

  14. -
  15. Example usage at the bottom of the code demonstrates how to create binary trees and use the maxPathSum method to find the maximum path sum for two different tree structures.

  16. -
-

In summary, the code uses a recursive approach to explore all possible paths in the binary tree, ensuring that negative path sums are not considered. It keeps track of the maximum path sum encountered and returns that maximum value as the result.

-
-
-

Test cases:#

-

Here’s how you can use this solution:

-
-
-
# Example 1: 
-
-# Example usage:
-root1 = TreeNode(1)
-root1.left = TreeNode(2)
-root1.right = TreeNode(3)
-solution = Solution()
-print(solution.maxPathSum(root1))
-
-
-
-
-
6
-
-
-
-
-
-
-
# Example 2:
-
-root2 = TreeNode(-10)
-root2.left = TreeNode(9)
-root2.right = TreeNode(20)
-root2.right.left = TreeNode(15)
-root2.right.right = TreeNode(7)
-print(solution.maxPathSum(root2))
-
-
-
-
-
42
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the given code:

-

Time Complexity:

-
    -
  • The code uses a recursive depth-first traversal to explore each node in the binary tree exactly once.

  • -
  • During the traversal, for each node, we perform constant time operations, such as updating the max_sum variable and calculating the maximum path sum starting from that node.

  • -
  • Therefore, the time complexity of the code is O(N), where N is the number of nodes in the binary tree.

  • -
-

Space Complexity:

-
    -
  • The space complexity of the code is determined by the space used in the call stack during the recursive traversal.

  • -
  • In the worst case, the depth of the call stack can be equal to the height of the binary tree. In an unbalanced tree, this could be O(N), but in a balanced binary tree, the height is O(log N).

  • -
  • Additionally, the code uses a constant amount of space for variables like left_max, right_max, and max_sum.

  • -
  • Therefore, the overall space complexity is O(H), where H is the height of the binary tree. In the worst case, it’s O(N), and in the best case (a balanced binary tree), it’s O(log N).

  • -
-

In summary:

-
    -
  • Time Complexity: O(N)

  • -
  • Space Complexity: O(H), where H is the height of the binary tree, ranging from O(log N) to O(N) depending on the tree’s balance.

  • -
-
-
-

Challenging Exercises:#

-
    -
  1. Print the Maximum Path: -Modify the code to not only find the maximum path sum but also print the nodes involved in the maximum path. You can print the nodes in the correct order from the root to the leaf.

  2. -
  3. Path Sum Count: -Instead of finding the maximum path sum, find the count of unique paths that sum to a given target value. Each path can start and end anywhere in the tree.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/07. Trees/199. Binary Tree Right Side View.html b/docs/_build/html/07. Trees/199. Binary Tree Right Side View.html deleted file mode 100644 index 278eeb0..0000000 --- a/docs/_build/html/07. Trees/199. Binary Tree Right Side View.html +++ /dev/null @@ -1,749 +0,0 @@ - - - - - - - - - - - - 199. Binary Tree Right Side View — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

199. Binary Tree Right Side View

- -
- -
-
- - - - -
- -
-

199. Binary Tree Right Side View#

-

Difficulty: Medium

-

Link to Problem: To see the Binary Tree Right Side View problem on LeetCode, click here!

-
-

Given the root of a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom.

-

Constraints:

-
    -
  • The number of nodes in the tree is in the range [0, 2000].

  • -
  • -100 <= Node.val <= 100

  • -
-
-

Solution:#

-

Here’s a Python function to solve this problem:

-
-
-
class TreeNode:
-    def __init__(self, val=0, left=None, right=None):
-        self.val = val
-        self.left = left
-        self.right = right
-
-def rightSideView(root):
-    if not root:
-        return []  # If the tree is empty, return an empty list.
-
-    result = []  # Initialize a list to store the right side view values.
-    queue = [root]  # Initialize a queue for level-order traversal with the root node.
-
-    while queue:
-        # Get the number of nodes at the current level.
-        level_size = len(queue)
-
-        # Traverse all nodes at the current level and add the rightmost node to the result.
-        for i in range(level_size):
-            node = queue.pop(0)  # Dequeue the first node from the queue.
-
-            # If it's the rightmost node at this level, add its value to the result.
-            if i == level_size - 1:
-                result.append(node.val)
-
-            # Add the children of the current node to the queue.
-            if node.left:
-                queue.append(node.left)
-            if node.right:
-                queue.append(node.right)
-
-    return result  # Return the list of right side view values.
-
-
-
-
-
-
-

Explanation:#

-
    -
  1. We start with a binary tree represented using a TreeNode class. Each node has a value (val) and can have a left child (left) and a right child (right).

  2. -
  3. The rightSideView function takes the root node of the binary tree as input and returns a list of values representing the nodes you can see when standing on the right side of the tree.

  4. -
  5. We check if the root is None, which means the tree is empty. If it’s empty, we return an empty list because there are no nodes to see.

  6. -
  7. We initialize an empty list called result to store the right side view values.

  8. -
  9. We initialize a queue called queue with the root node. This queue is used for a level-order traversal of the tree.

  10. -
  11. We enter a while loop that continues until the queue is empty. Inside this loop, we perform the following steps for each level of the tree:

    -

    a. We determine the number of nodes at the current level by getting the length of the queue. This is important for processing nodes at the same level together.

    -

    b. We then iterate through the nodes at the current level using a for loop. For each node in the level, we dequeue it from the queue using queue.pop(0).

    -

    c. If the node we dequeue is the rightmost node at the current level (determined by i == level_size - 1), we add its val to the result list. This is because, when standing on the right side of the tree, you can see the rightmost node at each level.

    -

    d. We enqueue the left and right children of the current node (if they exist) to the queue. This ensures that we process the next level in the subsequent iterations of the while loop.

    -
  12. -
  13. After processing all levels of the tree, the result list contains the values of the rightmost nodes in each level, ordered from top to bottom.

  14. -
  15. Finally, we return the result list as the output of the function, which represents the right side view of the binary tree.

  16. -
-

The code effectively performs a level-order traversal of the binary tree while keeping track of the rightmost nodes at each level and adding them to the result list. This ensures that we obtain the correct order of nodes visible from the right side of the tree.

-
-
-

Test cases#

-
-
-
# Example 1: 
-
-# Construct the tree
-root1 = TreeNode(1)
-root1.left = TreeNode(2)
-root1.right = TreeNode(3)
-root1.left.right = TreeNode(5)
-root1.right.right = TreeNode(4)
-print(rightSideView(root1))
-
-
-
-
-
[1, 3, 4]
-
-
-
-
-
-
-
# Example 2:
-
-root2 = TreeNode(1)
-root2.right = TreeNode(3)
-print(rightSideView(root2))
-
-
-
-
-
[1, 3]
-
-
-
-
-
-
-
# Example 3:
-# Creating a new tree for this example
-root = None
-result = rightSideView(root)
-print(result)
-
-
-
-
-
[]
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the given code:

-

Time Complexity:

-

The time complexity of the code is O(N), where N is the number of nodes in the binary tree. Here’s why:

-
    -
  1. We perform a level-order traversal of the tree using a queue. In the worst case, we visit all nodes once, which takes O(N) time since we visit each node exactly once.

  2. -
  3. For each node, we perform constant-time operations like dequeuing it from the queue, checking if it’s the rightmost node at the current level, and enqueuing its children (if they exist). These operations do not depend on the size of the tree, so they do not contribute to the overall time complexity.

  4. -
-

Therefore, the dominant factor in the time complexity is the level-order traversal, making it O(N).

-

Space Complexity:

-

The space complexity of the code is also O(N). Here’s why:

-
    -
  1. We use a queue to perform level-order traversal. In the worst case, the queue can contain all nodes at the maximum width of the tree, which can be up to N/2 nodes for a completely unbalanced tree. Therefore, the space required for the queue is O(N).

  2. -
  3. The result list stores the values of the rightmost nodes. In the worst case, when the binary tree is a complete binary tree, it can have roughly N/2 rightmost nodes. Therefore, the space required for the result list is also O(N).

  4. -
  5. Other auxiliary variables like level_size, i, and node require only constant space and do not depend on the size of the tree.

  6. -
-

Combining the space used by the queue and the result list, we get a space complexity of O(N).

-

In summary, the code has a time complexity of O(N) and a space complexity of O(N), where N is the number of nodes in the binary tree. These complexities are efficient and scale linearly with the size of the input tree.

-
-
-

Challenging Exercises:#

-
    -
  1. Variant with Left Side View: Modify the code to find and return the values of nodes visible from the left side of the binary tree instead of the right side.

  2. -
  3. Zigzag Right Side View: Extend the code to return the right side view values in a zigzag order. In a zigzag order, you alternate between starting from the rightmost node at level 0, then the leftmost at level 1, rightmost at level 2, and so on.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/07. Trees/226. Invert Binary Tree.html b/docs/_build/html/07. Trees/226. Invert Binary Tree.html deleted file mode 100644 index 8eda822..0000000 --- a/docs/_build/html/07. Trees/226. Invert Binary Tree.html +++ /dev/null @@ -1,719 +0,0 @@ - - - - - - - - - - - - 226: Invert Binary Tree — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

226: Invert Binary Tree

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

226: Invert Binary Tree#

-

Difficulty: Easy

-

Link to Problem: To see the Invert Binary Tree problem on LeetCode, click here!

-
-

Given the root of a binary tree, invert the tree, and return its root.

-

Constraints:

-
    -
  • The number of nodes in the tree is in the range [0, 100].

  • -
  • -100 <= Node.val <= 100

  • -
-
-
-
# Definition for a binary tree node.
-class TreeNode:
-    def __init__(self, val=0, left=None, right=None):
-        self.val = val
-        self.left = left
-        self.right = right
-
-def invertTree(root):
-    # Base case: If the root is None or the tree is empty, return None.
-    if not root:
-        return None
-
-    # Swap the left and right subtrees of the current node.
-    root.left, root.right = root.right, root.left
-
-    # Recursively invert the left and right subtrees.
-    invertTree(root.left)
-    invertTree(root.right)
-
-    return root
-
-
-
-
-
-

Explanation:#

-
    -
  1. We start by defining a TreeNode class, which represents a node in a binary tree. Each node has a value (val), a left child (left), and a right child (right).

  2. -
  3. The invertTree function is defined to invert the binary tree. It takes the root node of the tree as an argument.

  4. -
  5. In the invertTree function, we have a base case to handle the scenario when the root is None (empty tree). In such cases, we return None because there’s nothing to invert.

  6. -
  7. For non-empty trees, we swap the left and right subtrees of the current node. This effectively inverts the tree at the current node.

  8. -
  9. We then recursively call invertTree on the left and right subtrees to invert them.

  10. -
  11. Finally, we return the root of the inverted tree.

  12. -
-
-
-

Test cases#

-
-
-
### Example 1
-# Input: root = [4,2,7,1,3,6,9]
-
-root1 = TreeNode(4)
-root1.left = TreeNode(2)
-root1.right = TreeNode(7)
-root1.left.left = TreeNode(1)
-root1.left.right = TreeNode(3)
-root1.right.left = TreeNode(6)
-root1.right.right = TreeNode(9)
-
-inverted_root1 = invertTree(root1)
-print("Inverted Tree (Example 1):", inverted_root1)
-
-
-
-
-
Inverted Tree (Example 1): <__main__.TreeNode object at 0x7faa5c445ab0>
-
-
-
-
-
-
-
### Example 2
-# Input: root = [2,1,3]
-
-root2 = TreeNode(2)
-root2.left = TreeNode(1)
-root2.right = TreeNode(3)
-
-inverted_root2 = invertTree(root2)
-print("Inverted Tree (Example 2):", inverted_root2)
-
-
-
-
-
Inverted Tree (Example 2): <__main__.TreeNode object at 0x7faa5c444310>
-
-
-
-
-
-
-
### Example 3
-# Input: root = []
-
-root3 = None  # Empty tree
-
-inverted_root3 = invertTree(root3)
-print("Inverted Tree (Example 3):", inverted_root3)
-
-
-
-
-
Inverted Tree (Example 3): None
-
-
-
-
-

Let’s discuss the time and space complexity of the provided Python code to invert a binary tree.

-

Time Complexity:

-

The time complexity of the invertTree function is \(O(n)\), where \(n\) is the number of nodes in the binary tree. This is because we visit each node exactly once during the traversal of the tree. In the worst case, we have to visit all nodes in the tree.

-

The reason for this time complexity is the depth-first traversal of the tree, where we recursively process the left and right subtrees of each node.

-

Space Complexity:

-

The space complexity of the code is determined by the function call stack during the recursion. In the worst case, the space complexity is \(O(h)\), where \(h\) is the height of the binary tree.

-

In a completely unbalanced binary tree (essentially a linked list), the height \(h\) is equal to the number of nodes \(n\), resulting in a space complexity of \(O(n)\). This occurs when the tree is skewed to one side.

-

In a balanced binary tree, such as a full binary tree, the height \(h\) is \(O(log\ n)\), and the space complexity is \(O(log\ n)\).

-

The space complexity depends on how balanced the tree is. In practical scenarios, binary trees are often approximately balanced, so the space complexity is typically closer to \(O(log\ n)\).

-

In summary:

-
    -
  • Time Complexity: \(O(n)\) where \(n\) is the number of nodes.

  • -
  • Space Complexity: \(O(h)\), where \(h\) is the height of the binary tree. In the worst case, it can be \(O(n)\), and in a balanced tree, it is \(O(log\ n)\).

  • -
-

Keep in mind that these complexities are based on the recursive implementation provided. Iterative solutions can achieve the same task with \(O(1)\) space complexity, using auxiliary data structures like stacks or queues to mimic the recursion stack.

-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/07. Trees/230. Kth Smallest Element in a BST.html b/docs/_build/html/07. Trees/230. Kth Smallest Element in a BST.html deleted file mode 100644 index fef5b0d..0000000 --- a/docs/_build/html/07. Trees/230. Kth Smallest Element in a BST.html +++ /dev/null @@ -1,729 +0,0 @@ - - - - - - - - - - - - 230. Kth Smallest Element in a BST — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

230. Kth Smallest Element in a BST

- -
- -
-
- - - - -
- -
-

230. Kth Smallest Element in a BST#

-

Difficulty: Medium

-

Link to Problem: To see the Kth Smallest Element in a BST problem on LeetCode, click here!

-
-

Given the root of a binary search tree, and an integer k, return the \(k^{th}\) smallest value (1-indexed) of all the values of the nodes in the tree.

-

Constraints:

-
    -
  • The number of nodes in the tree is n.

  • -
  • 1 <= k <= n <= \(10^4\)

  • -
  • 0 <= Node.val <= \(10^4\)

  • -
-

Follow up: If the BST is modified often (i.e., we can do insert and delete operations) and you need to find the kth smallest frequently, how would you optimize?

-
-

Solution:#

-

Here’s a Python function to solve this problem:

-
-
-
class TreeNode:
-    def __init__(self, val=0, left=None, right=None):
-        self.val = val
-        self.left = left
-        self.right = right
-
-def kthSmallest(root, k):
-    stack = []  # Initialize an empty stack to simulate the traversal
-    while root or stack:
-        while root:
-            stack.append(root)  # Push the current node onto the stack
-            root = root.left  # Move to the left child
-        root = stack.pop()  # Pop a node from the stack
-        k -= 1  # Decrement k since we've visited a node
-        if k == 0:
-            return root.val  # If k becomes 0, return the current node's value as the kth smallest
-        root = root.right  # Move to the right child to continue the traversal
-
-
-
-
-
-
-

Explanation:#

-
    -
  1. We start by defining a TreeNode class, which represents a node in the binary search tree (BST). Each node has a value (val), a left child (left), and a right child (right).

  2. -
  3. The kthSmallest function takes two parameters: root, which is the root of the BST, and k, which represents the kth smallest element we want to find.

  4. -
  5. We initialize an empty stack (stack) to simulate the traversal of the BST. The stack will be used to keep track of nodes as we traverse the tree in an iterative manner.

  6. -
  7. We enter a while loop that continues until either root becomes None (indicating we have traversed the entire tree) or the stack is empty.

  8. -
  9. Within the loop, we start another while loop to traverse as far left as possible in the BST. We repeatedly push nodes onto the stack and move to their left children until we reach the leftmost leaf node. This is the smallest node in the BST.

  10. -
  11. Once we have reached the leftmost leaf node (the smallest node), we pop nodes from the stack one by one. As we pop each node, we decrement k by 1 to keep track of the number of nodes we have visited.

  12. -
  13. If k becomes 0 after decrementing, it means we have found the kth smallest element. In this case, we return the val of the current node as the result.

  14. -
  15. If k is still greater than 0, it means we haven’t found the kth smallest element yet. In this case, we move to the right child of the current node to continue the traversal, as the kth smallest element, if it exists, will be in the right subtree of the current node.

  16. -
  17. The process continues until we find the kth smallest element or traverse the entire tree.

  18. -
  19. Finally, we return the kth smallest element found.

  20. -
-

The key idea in this code is to perform an in-order traversal of the BST while keeping track of the kth smallest element. By visiting nodes in ascending order, we can efficiently find the kth smallest element in O(h + k) time, where h is the height of the BST and k is the desired kth element. This approach is both concise and efficient for this problem.

-
-
-

Test cases#

-
-
-
# Example 1: 
-
-# Example usage:
-# Create the tree for the first example: root = [3,1,4,null,2], k = 1
-root1 = TreeNode(3)
-root1.left = TreeNode(1)
-root1.right = TreeNode(4)
-root1.left.right = TreeNode(2)
-k1 = 1
-print(kthSmallest(root1, k1)) 
-
-
-
-
-
1
-
-
-
-
-
-
-
# Example 2:
-
-# Create the tree for the second example: root = [5,3,6,2,4,null,null,1], k = 3
-root2 = TreeNode(5)
-root2.left = TreeNode(3)
-root2.right = TreeNode(6)
-root2.left.left = TreeNode(2)
-root2.left.right = TreeNode(4)
-root2.left.left.left = TreeNode(1)
-k2 = 3
-print(kthSmallest(root2, k2))
-
-
-
-
-
3
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the given code:

-

Time Complexity:

-

The time complexity of this code is O(h + k), where:

-
    -
  • h is the height of the binary search tree (BST).

  • -
  • k is the desired kth smallest element we want to find.

  • -
-
    -
  1. In the worst case, where the BST is highly unbalanced and resembles a linked list, the height (h) of the tree can be equal to the number of nodes (n) in the tree. In this case, the time complexity is O(n + k).

  2. -
  3. In the best case, where the BST is perfectly balanced, the height (h) is log(n), where n is the number of nodes in the tree. In this case, the time complexity is O(log(n) + k).

  4. -
-

So, the time complexity can vary from O(log(n) + k) in the best-case scenario to O(n + k) in the worst-case scenario. Typically, for balanced BSTs, the time complexity is closer to O(log(n) + k).

-

Space Complexity:

-

The space complexity of this code is O(h) due to the stack used for the iterative in-order traversal, where h is the height of the BST.

-
    -
  1. In the worst case, when the BST is highly unbalanced and resembles a linked list, the height (h) of the tree can be equal to the number of nodes (n) in the tree. In this case, the space complexity is O(n) because the stack can potentially store all n nodes.

  2. -
  3. In the best case, when the BST is perfectly balanced, the height (h) is log(n), where n is the number of nodes in the tree. In this case, the space complexity is O(log(n)) because the stack will have at most log(n) nodes.

  4. -
-

So, the space complexity depends on the height of the BST and can vary from O(log(n)) in the best-case scenario to O(n) in the worst-case scenario.

-

In practical terms, for balanced BSTs or moderately unbalanced BSTs, the space complexity is usually close to O(log(n)), and the code is efficient in terms of space usage.

-
-
-

Challenging Exercises:#

-
    -
  1. Kth Largest Element: Modify the code to find the kth largest element in the BST instead of the kth smallest element.

  2. -
  3. Kth Smallest Element in Two BSTs: Given two BSTs, find the kth smallest element when considering both BSTs as a single sorted list. This involves merging the two BSTs while finding the kth element efficiently.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.html b/docs/_build/html/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.html deleted file mode 100644 index 8098932..0000000 --- a/docs/_build/html/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.html +++ /dev/null @@ -1,764 +0,0 @@ - - - - - - - - - - - - 235. Lowest Common Ancestor of a Binary Search Tree — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

235. Lowest Common Ancestor of a Binary Search Tree

- -
- -
-
- - - - -
- -
-

235. Lowest Common Ancestor of a Binary Search Tree#

-

Difficulty: Medium

-

Link to Problem: To see the Lowest Common Ancestor of a Binary Search Tree problem on LeetCode, click here!

-
-

Given a binary search tree (BST), find the lowest common ancestor (LCA) node of two given nodes in the BST.

-

According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”

-

Constraints:

-
    -
  • The number of nodes in the tree is in the range \([2, 10^5]\).

  • -
  • \(-10^9\) <= Node.val <= \(10^9\)

  • -
  • All Node.val are unique.

  • -
  • p != q

  • -
  • p and q will exist in the BST.

  • -
-
-

Solution:#

-

Here’s a Python function to solve this problem:

-
-
-
class TreeNode:
-    def __init__(self, val=0, left=None, right=None):
-        self.val = val
-        self.left = left
-        self.right = right
-
-def lowestCommonAncestor(root, p, q):
-    # Ensure p is less than q
-    if p.val > q.val:
-        p, q = q, p
-
-    while root:
-        # If the current node value is greater than both p and q, move left
-        if root.val > q.val:
-            root = root.left
-        # If the current node value is less than both p and q, move right
-        elif root.val < p.val:
-            root = root.right
-        # If the current node value is between p and q (inclusive), or it matches either p or q, it's the LCA
-        else:
-            return root
-
-
-
-
-
-
-

Explanation:#

-
    -
  1. class TreeNode: defines a simple class for representing nodes in a binary tree. Each TreeNode has three attributes:

    -
      -
    • val: The value of the node.

    • -
    • left: A reference to the left child node.

    • -
    • right: A reference to the right child node.

    • -
    -
  2. -
  3. def lowestCommonAncestor(root, p, q): is a function that takes three arguments:

    -
      -
    • root: The root node of the BST.

    • -
    • p: A TreeNode representing one of the nodes for which we want to find the LCA.

    • -
    • q: A TreeNode representing the other node for which we want to find the LCA.

    • -
    -
  4. -
  5. if p.val > q.val: checks if the value of p is greater than the value of q. In a BST, it’s essential to ensure that p represents the smaller value, and q represents the larger value. If p is greater than q, the code swaps their values.

  6. -
  7. The main logic is inside the while loop, which runs until root becomes None. It performs the following steps to find the LCA:

    -
      -
    • If the current root node’s value is greater than the value of q, it means both p and q are on the left subtree of the current node. So, we move to the left child of the current node by setting root = root.left.

    • -
    • If the current root node’s value is less than the value of p, it means both p and q are on the right subtree of the current node. So, we move to the right child of the current node by setting root = root.right.

    • -
    • If neither of the above conditions is met, it means the current root node’s value is between p and q, or it matches either p or q. In this case, the current node is the lowest common ancestor (LCA), so we return root.

    • -
    -
  8. -
-

The algorithm is efficient because it takes advantage of the properties of a BST. It eliminates subtrees that cannot contain the LCA by comparing the values of p, q, and the current root node. Eventually, it reaches the LCA node, and that node is returned as the result.

-
-
-

Test cases#

-
-
-
# Example 1: 
-
-# Construct the tree
-root = TreeNode(6)
-root.left = TreeNode(2)
-root.right = TreeNode(8)
-root.left.left = TreeNode(0)
-root.left.right = TreeNode(4)
-root.right.left = TreeNode(7)
-root.right.right = TreeNode(9)
-root.left.right.left = TreeNode(3)
-root.left.right.right = TreeNode(5)
-
-p = root.left  # Node 2
-q = root.right  # Node 8
-
-result = lowestCommonAncestor(root, p, q)
-print(result.val)
-
-
-
-
-
6
-
-
-
-
-
-
-
# Example 2:
-
-# Using the same tree as before
-p = root.left  # Node 2
-q = root.left.right  # Node 4
-
-result = lowestCommonAncestor(root, p, q)
-print(result.val) 
-
-
-
-
-
2
-
-
-
-
-
-
-
# Example 3:
-# Creating a new tree for this example
-root2 = TreeNode(2)
-root2.left = TreeNode(1)
-
-p = root2  # Node 2
-q = root2.left  # Node 1
-
-result = lowestCommonAncestor(root2, p, q)
-print(result.val)
-
-
-
-
-
2
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the provided algorithm for finding the lowest common ancestor (LCA) in a Binary Search Tree (BST).

-

Time Complexity: -The time complexity of this algorithm is O(h), where “h” is the height of the BST. In the worst case, where the tree is completely unbalanced (essentially a linked list), the height of the tree is O(n), where “n” is the number of nodes in the tree. However, in a well-balanced BST, the height is logarithmic, which is O(log n).

-

The reason for this time complexity is that the algorithm efficiently narrows down the search space by traversing either left or right subtrees based on the values of the target nodes p and q. It eliminates entire subtrees that cannot contain the LCA, leading to a relatively quick search.

-

Space Complexity: -The space complexity of the algorithm is O(1). This is because it uses a constant amount of extra space, regardless of the size of the input BST. The only variables used are root, p, and q, and there are no data structures like stacks or queues used for additional space. The algorithm performs a simple traversal without recursion, so it does not consume extra memory as the tree depth increases.

-

In summary, the provided algorithm for finding the LCA in a BST is both time and space-efficient. Its time complexity is O(h), where “h” is the height of the tree, and its space complexity is O(1), making it suitable for practical use even in large BSTs.

-
-

Challenging Exercises:#

-
    -
  1. Multiple LCAs: Extend the algorithm to find all the lowest common ancestors of two given nodes p and q in a BST. In some cases, there can be multiple LCAs.

  2. -
  3. LCA with k Nodes: Given a BST and k nodes, find the lowest common ancestor of these k nodes. This is an extension of the problem where you must find the LCA of more than two nodes.

  4. -
-
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/07. Trees/297. Serialize and Deserialize Binary Tree.html b/docs/_build/html/07. Trees/297. Serialize and Deserialize Binary Tree.html deleted file mode 100644 index 17b2bce..0000000 --- a/docs/_build/html/07. Trees/297. Serialize and Deserialize Binary Tree.html +++ /dev/null @@ -1,839 +0,0 @@ - - - - - - - - - - - - 297. Serialize and Deserialize Binary Tree — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

297. Serialize and Deserialize Binary Tree

- -
- -
-
- - - - -
- -
-

297. Serialize and Deserialize Binary Tree#

-

Difficulty: Hard

-

Link to Problem: To see the Serialize and Deserialize Binary Tree problem on LeetCode, click here!

-
-

Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.

-

Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure.

-

Clarification: The input/output format is the same as how LeetCode serializes a binary tree. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself.

-

Constraints:

-
    -
  • The number of nodes in the tree is in the range \([0, 10^4]\).

  • -
  • -1000 <= Node.val <= 1000

  • -
-
-

Probelm Explanation:#

-

TThe problem is to design an algorithm to serialize and deserialize a binary tree. Serialization is the process of converting a data structure or object into a sequence of characters or bytes so that it can be easily stored in a file, transmitted over a network, or otherwise persisted. Deserialization is the reverse process of converting the serialized data back into the original data structure.

-

In the context of this problem:

-
    -
  1. Serialization: You are given a binary tree, and your task is to convert it into a string representation such that you can later recreate the same binary tree from this string. The format of serialization is flexible, but it should allow you to reconstruct the original binary tree accurately.

  2. -
  3. Deserialization: Given a serialized string, you need to reconstruct the binary tree it represents, ensuring that it is identical to the original tree.

  4. -
-

Here are some key points to consider in solving this problem:

-
    -
  • The input can include any valid binary tree, including trees with nodes having integer values within the range [-1000, 1000].

  • -
  • You don’t necessarily need to follow a specific format for serialization, but it should be designed in a way that allows unambiguous deserialization.

  • -
  • The goal is to serialize the tree structure and its values and then deserialize it back into the same structure and values.

  • -
-

A common approach for serialization is to use a traversal method like preorder traversal, where you visit nodes in the order: root, left subtree, right subtree. This way, you can serialize the tree into a string, and during deserialization, you can reconstruct the tree by parsing the string in the same order.

-
-
-

Solution:#

-

Here’s a Python function to implement this algorithm:

-
-
-
# Definition for a binary tree node.
-class TreeNode(object):
-    def __init__(self, x):
-        self.val = x
-        self.left = None
-        self.right = None
-
-class Codec:
-    def serialize(self, root):
-        serialized  = []
-
-        def dfs(node):
-            if not node:
-                # If the node is None, represent it as "Null" in the serialized string
-                serialized .append("Null")
-                return
-            # Convert the node's value to a string and add it to the serialized string
-            serialized .append(str(node.val))
-            dfs(node.left)
-            dfs(node.right)
-
-        dfs(root)
-        # Join the serialized values with ","
-        return ",".join(serialized )
-
-    def deserialize(self, data):
-        vals = data.split(",")
-        self.i = 0
-
-        def dfs():
-            if vals[self.i] == "Null":
-                self.i += 1
-                return None
-            # Convert the value to an integer to create a new node
-            node = TreeNode(int(vals[self.i]))
-            self.i += 1
-            node.left = dfs()
-            node.right = dfs()
-            return node
-
-        return dfs()
-
-
-
-
-
-
-

Explanation:#

-

Here’s a step-by-step explanation of the code:

-
    -
  1. Definition of TreeNode:

    -
      -
    • The code defines a simple TreeNode class that represents a node in a binary tree. Each TreeNode has three attributes:

      -
        -
      • val: The integer value stored in the node.

      • -
      • left: A reference to the left child node (or None if there is no left child).

      • -
      • right: A reference to the right child node (or None if there is no right child).

      • -
      -
    • -
    • This class allows you to create binary tree nodes with integer values and left and right child references.

    • -
    -
  2. -
  3. Serialization (serialize method):

    -
      -
    • The serialize method takes a root node as input, which is the root of the binary tree that needs to be serialized.

    • -
    • It initializes an empty list serialized to store the serialized elements.

    • -
    • The dfs (depth-first search) function is defined within the serialize method to perform a preorder traversal of the binary tree.

    • -
    • In the dfs function:

      -
        -
      • If the current node is None (i.e., a leaf node or a child of a leaf node), it appends the string “Null” to the serialized list to represent the absence of a node.

      • -
      • If the current node is not None, it appends the string representation of the node.val to the serialized list and then recursively calls dfs on the left and right children.

      • -
      -
    • -
    • After the dfs traversal, the serialized list contains the serialized binary tree elements.

    • -
    • The method returns a string obtained by joining the elements in the serialized list with commas.

    • -
    -
  4. -
  5. Deserialization (deserialize method):

    -
      -
    • The deserialize method takes a serialized string data as input, which represents a binary tree in the custom format.

    • -
    • It splits the data string by commas to obtain a list of elements called vals.

    • -
    • The method initializes an index self.i to 0. This index keeps track of the current position in the vals list during deserialization.

    • -
    • The dfs function is defined within the deserialize method to perform the deserialization process using a recursive approach.

    • -
    • In the dfs function:

      -
        -
      • If the current element in vals is “Null,” it means there is no node at this position in the binary tree, so it returns None.

      • -
      • If the current element is not “Null,” it converts the element to an integer to create a new TreeNode with that value.

      • -
      • It then recursively calls dfs to set the left and right children of the current node.

      • -
      -
    • -
    • The method returns the root node of the reconstructed binary tree.

    • -
    -
  6. -
-

Overall, this code demonstrates a way to serialize a binary tree into a string format and then deserialize it back into the original tree structure, allowing for the representation of both the tree structure and the values stored in the nodes.

-
-
-

Test cases:#

-

Here’s how you can use this solution:

-
-
-
# Example 1: 
-
-# Example usage:
-# Serialize a binary tree
-root = TreeNode(1)
-root.left = TreeNode(2)
-root.right = TreeNode(3)
-root.right.left = TreeNode(4)
-root.right.right = TreeNode(5)
-
-codec = Codec()
-serialized_tree = codec.serialize(root)
-print(serialized_tree)
-
-# Deserialize the serialized tree
-new_root = codec.deserialize(serialized_tree)
-
-
-
-
-
1,2,Null,Null,3,4,Null,Null,5,Null,Null
-
-
-
-
-
-
-
# Example 2:
-
-# Example usage:
-# Serialize a binary tree
-root = None
-
-codec = Codec()
-serialized_tree = codec.serialize(root)
-print(serialized_tree)
-
-# Deserialize the serialized tree
-new_root = codec.deserialize(serialized_tree)
-
-
-
-
-
Null
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the provided code for serializing and deserializing a binary tree:

-
    -
  1. Serialization (serialize method):

    -
      -
    • Time Complexity:

      -
        -
      • The serialize method uses a depth-first traversal (preorder) of the binary tree.

      • -
      • It visits each node exactly once.

      • -
      • At each node, it performs constant-time operations (string conversion and list append).

      • -
      • Therefore, the time complexity for serialization is O(N), where N is the number of nodes in the binary tree.

      • -
      -
    • -
    • Space Complexity:

      -
        -
      • The space complexity for serialization includes the space used by the serialized list and the recursive call stack.

      • -
      • The serialized list stores the serialized elements, and its space is proportional to the number of nodes.

      • -
      • The recursive call stack depth is determined by the height of the binary tree, and in the worst case (completely unbalanced tree), it can be O(N).

      • -
      • Therefore, the space complexity for serialization is O(N) due to the list and O(H) due to the recursive call stack, where H is the height of the tree. In most cases, the dominant factor is O(N).

      • -
      -
    • -
    -
  2. -
  3. Deserialization (deserialize method):

    -
      -
    • Time Complexity:

      -
        -
      • The deserialize method splits the serialized string into a list of elements, which takes O(N) time.

      • -
      • The dfs function is a recursive function that visits each element in the list exactly once.

      • -
      • At each element, it performs constant-time operations (string comparison, integer conversion, and recursive function calls).

      • -
      • Therefore, the time complexity for deserialization is O(N).

      • -
      -
    • -
    • Space Complexity:

      -
        -
      • The space complexity for deserialization includes the space used by the vals list and the recursive call stack.

      • -
      • The vals list stores the elements from the serialized string, and its space is proportional to the number of nodes.

      • -
      • The recursive call stack depth is determined by the height of the binary tree, and in the worst case (completely unbalanced tree), it can be O(N).

      • -
      • Therefore, the space complexity for deserialization is O(N) due to the list and O(H) due to the recursive call stack, where H is the height of the tree. In most cases, the dominant factor is O(N).

      • -
      -
    • -
    -
  4. -
-

Overall, the provided code has a time complexity of O(N) for both serialization and deserialization and a space complexity of O(N) in the majority of cases (unless the tree is severely unbalanced, in which case the height H dominates the space complexity). It efficiently serializes and deserializes a binary tree while using a linear amount of memory.

-
-
-

Challenging Exercises:#

-
    -
  1. Efficient Serialization: -Optimize the serialization process to minimize the length of the serialized string. Consider using techniques like binary encoding to represent node values more efficiently.

  2. -
  3. Custom Serialization Format: -Modify the serialization and deserialization methods to use a custom format different from the one provided. Ensure that the new format allows for accurate reconstruction of the original binary tree.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/07. Trees/572. Subtree of Another Tree.html b/docs/_build/html/07. Trees/572. Subtree of Another Tree.html deleted file mode 100644 index eb976fe..0000000 --- a/docs/_build/html/07. Trees/572. Subtree of Another Tree.html +++ /dev/null @@ -1,788 +0,0 @@ - - - - - - - - - - - - 572: Subtree of Another Tree — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

572: Subtree of Another Tree

- -
- -
-
- - - - -
- -
-

572: Subtree of Another Tree#

-

Difficulty: Easy

-

Link to Problem: To see the Subtree of Another Tree problem on LeetCode, click here!

-
-

Problem Description:

-

Given the roots of two binary trees root and subRoot, return True if there is a subtree of root with the same structure and node values as subRoot, and False otherwise.

-

A subtree of a binary tree tree is a tree that consists of a node in tree and all of this node’s descendants. The tree tree could also be considered as a subtree of itself.

-

Constraints:

-
    -
  1. The number of nodes in the root tree is in the range \([1, 2000]\).

  2. -
  3. The number of nodes in the subRoot tree is in the range \([1, 1000]\).

  4. -
  5. \(-10^4\) <= root.val <= \(10^4\)

  6. -
  7. \(-10^4\) <= subRoot.val <= \(10^4\)

  8. -
-
-
-
# Definition for a binary tree node.
-class TreeNode:
-    def __init__(self, val=0, left=None, right=None):
-        self.val = val
-        self.left = left
-        self.right = right
-
-class Solution:
-    def isSubtree(self, root, subRoot):
-        if not root:
-            return False
-        
-        # Check if the current subtree is equal to the subRoot
-        if self.isSameTree(root, subRoot):
-            return True
-        
-        # Recursively check the left and right subtrees
-        return self.isSubtree(root.left, subRoot) or self.isSubtree(root.right, subRoot)
-    
-    def isSameTree(self, tree1, tree2):
-        if not tree1 and not tree2:
-            return True
-        if not tree1 or not tree2:
-            return False
-        
-        return (
-            tree1.val == tree2.val and
-            self.isSameTree(tree1.left, tree2.left) and
-            self.isSameTree(tree1.right, tree2.right)
-        )
-
-
-
-
-

This code defines a TreeNode class for the binary tree nodes and a Solution class with two methods:

-
    -
  1. isSubtree: This method checks if there is a subtree of the root tree with the same structure and node values as the subRoot tree. It uses a helper function isSameTree to compare two trees for equality.

  2. -
  3. isSameTree: This helper method recursively compares two trees to check if they are the same in structure and node values.

  4. -
-
-

Here’s a detailed explanation of the code:#

-
    -
  1. TreeNode Class:

  2. -
-

The TreeNode class is defined to represent nodes in a binary tree. Each node has a val (the node’s value) and may have a left and right child.

-
    -
  1. Solution Class:

    -
      -
    • The Solution class contains the solution for the problem and defines two important methods:

    • -
    • isSubtree(self, root, subRoot):

      -
        -
      • This method checks whether subRoot is a subtree of root. It takes two tree nodes, root and subRoot, as input arguments.

      • -
      • If root is None, it returns False because there is no subtree to search.

      • -
      • It then checks if the current subtree with root as its root is equal to subRoot using the isSameTree method. If they are the same, it returns True.

      • -
      • If the current subtree is not the same as subRoot, it recursively checks the left and right subtrees of root to see if subRoot is a subtree of any of them.

      • -
      • It returns True if subRoot is found in either the left or right subtree; otherwise, it returns False.

      • -
      -
    • -
    • isSameTree(self, tree1, tree2):

      -
        -
      • This method checks whether two trees, tree1 and tree2, are the same.

      • -
      • If both tree1 and tree2 are None, they are considered the same tree, so it returns True.

      • -
      • If only one of them is None (but not both), they are different trees, so it returns False.

      • -
      • If both tree1 and tree2 have values, it checks if their values are equal and recursively checks if their left and right subtrees are the same.

      • -
      • It returns True if the trees are the same; otherwise, it returns False.

      • -
      -
    • -
    -
  2. -
-

The code effectively uses recursion to traverse the binary trees and check for subtree equality. The isSubtree method starts the recursive search, and the isSameTree method is used to compare individual subtrees. The approach is efficient and avoids unnecessary checks when possible.

-

This solution allows you to determine if there exists a subtree within the root tree that matches the structure and node values of subRoot.

-
-
-

Test cases#

-
-
-
#root = [3,4,5,1,2]
-#subRoot = [4,1,2]
-
-# Example input
-root = TreeNode(3)
-root.left = TreeNode(4)
-root.right = TreeNode(5)
-root.left.left = TreeNode(1)
-root.left.right = TreeNode(2)
-
-subRoot = TreeNode(4)
-subRoot.left = TreeNode(1)
-subRoot.right = TreeNode(2)
-
-# Create an instance of the Solution class
-solution = Solution()
-
-# Test the isSubtree method
-result = solution.isSubtree(root, subRoot)
-print("Is subRoot a subtree of root?", result)
-
-
-
-
-
Is subRoot a subtree of root? True
-
-
-
-
-
-
-
#root = [3,4,5,1,2,null,null,null,null,0] 
-#subRoot = [4,1,2]
-
-
-# Example input
-root = TreeNode(3)
-root.left = TreeNode(4)
-root.right = TreeNode(5)
-root.left.left = TreeNode(1)
-root.left.right = TreeNode(2)
-root.left.right.left = TreeNode(0)
-
-subRoot = TreeNode(4)
-subRoot.left = TreeNode(1)
-subRoot.right = TreeNode(2)
-
-# Create an instance of the Solution class
-solution = Solution()
-
-# Test the isSubtree method
-result = solution.isSubtree(root, subRoot)
-print("Is subRoot a subtree of root?", result)
-
-
-
-
-
Is subRoot a subtree of root? False
-
-
-
-
-

Let’s analyze the time and space complexity of the provided code for the “Subtree of Another Tree” problem:

-

Time Complexity

-

The time complexity of the code primarily depends on the recursive traversal of the binary tree. In both the isSubtree and isSameTree functions, we visit each node in the binary trees once. Let’s break down the time complexity:

-
    -
  1. The isSubtree function:

    -
      -
    • In the worst case, we need to visit every node in the root tree.

    • -
    • For each node in the root tree, we call the isSameTree function, which has its own traversal.

    • -
    • So, the total time complexity is \(O(n * m)\), where \(n\) is the number of nodes in the root tree, and \(m\) is the number of nodes in the subRoot tree.

    • -
    -
  2. -
  3. The isSameTree function:

    -
      -
    • In the worst case, we visit every node in both tree1 and tree2.

    • -
    • The number of recursive calls made is proportional to the number of nodes in the trees.

    • -
    • So, the time complexity of this function is \(O(max(n, m))\), where \(n\) and \(m\) are the numbers of nodes in tree1 and tree2, respectively.

    • -
    -
  4. -
-

Overall, the time complexity of the entire code is \(O(n * m)\), where \(n\) is the number of nodes in the root tree, and \(m\) is the number of nodes in the subRoot tree. In practice, it may be less than \(O(n * m)\) if a subtree mismatch is detected early during the traversal.

-

Space Complexity

-

The space complexity of the code is determined by the function call stack during recursion and the space used by the recursive functions. Let’s analyze the space complexity:

-
    -
  1. The isSubtree function:

    -
      -
    • It uses the call stack for recursion.

    • -
    • The maximum depth of the recursion is equal to the height of the root tree, which can be \(O(n)\) in the worst case (unbalanced tree).

    • -
    • Additionally, the function doesn’t use any significant extra space other than the recursion stack.

    • -
    -
  2. -
  3. The isSameTree function:

    -
      -
    • It also uses the call stack for recursion.

    • -
    • The maximum depth of the recursion is equal to the height of the tree1 or tree2, whichever is greater.

    • -
    • So, the maximum space used for the call stack is \(O(max(n, m))\).

    • -
    -
  4. -
-

In summary, the space complexity of the code is \(O(max(n, m))\) due to the function call stack. It scales with the maximum height of the trees being compared.

-

Overall, the code is efficient and works well for trees with moderate sizes. However, it’s important to keep in mind that the worst-case time complexity is \(O(n * m)\), so for very large trees, the performance may degrade.

-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/07. Trees/98. Validate Binary Search Tree.html b/docs/_build/html/07. Trees/98. Validate Binary Search Tree.html deleted file mode 100644 index 0d90f35..0000000 --- a/docs/_build/html/07. Trees/98. Validate Binary Search Tree.html +++ /dev/null @@ -1,740 +0,0 @@ - - - - - - - - - - - - 98. Validate Binary Search Tree — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

98. Validate Binary Search Tree

- -
- -
-
- - - - -
- -
-

98. Validate Binary Search Tree#

-

Difficulty: Medium

-

Link to Problem: To see the Validate Binary Search Tree problem on LeetCode, click here!

-
-

Given the root of a binary tree, determine if it is a valid binary search tree (BST).

-

A valid BST is defined as follows:

-
    -
  • The left subtree of a node contains only nodes with keys less than the node’s key.

  • -
  • The right subtree of a node contains only nodes with keys greater than the node’s key.

  • -
  • Both the left and right subtrees must also be binary search trees.

  • -
-

Constraints:

-
    -
  • The number of nodes in the tree is in the range \([1, 10^4]\).

  • -
  • \(-2^{31}\) <= Node.val <= \(2^{31} - 1\)

  • -
-
-

Solution:#

-

Here’s a Python function to solve this problem:

-
-
-
class TreeNode:
-    def __init__(self, val=0, left=None, right=None):
-        self.val = val
-        self.left = left
-        self.right = right
-
-def is_valid_BST(root):
-    def is_valid(node, min_val, max_val):
-        # Base case: If the node is None, it's a valid BST.
-        if node is None:
-            return True
-        
-        # Check if the current node's value is within the valid range.
-        if not (min_val < node.val < max_val):
-            return False
-        
-        # Recursively check the left and right subtrees with updated ranges.
-        return (is_valid(node.left, min_val, node.val) and
-                is_valid(node.right, node.val, max_val))
-    
-    # Call the helper function starting with a wide range for root node.
-    return is_valid(root, float('-inf'), float('inf'))
-
-
-
-
-
-
-

Explanation:#

-
    -
  • It defines a TreeNode class to represent nodes in the binary tree.

  • -
  • The is_valid_BST function takes the root node of the binary tree as input and returns True if the tree is a valid BST, and False otherwise.

  • -
  • Inside the is_valid_BST function, there is a helper function called is_valid that performs the actual validation using a recursive approach.

  • -
  • The is_valid function checks each node in the tree to ensure that it satisfies the properties of a BST:

    -
      -
    • The value of the current node must be within a valid range defined by min_val and max_val.

    • -
    • The left subtree of the current node should contain values less than the current node’s value.

    • -
    • The right subtree of the current node should contain values greater than the current node’s value.

    • -
    -
  • -
  • If any of these conditions are violated, the function returns False, indicating that the tree is not a valid BST.

  • -
  • If all nodes satisfy these conditions, the function returns True, indicating that the tree is a valid BST.

  • -
  • The code calls the is_valid function with the root node and initial range values of negative infinity to positive infinity to start the validation.

  • -
  • The time complexity of the code is O(N), where N is the number of nodes in the tree, as it traverses each node once.

  • -
  • The space complexity depends on the height of the tree. In the average case for a balanced BST, the space complexity is O(log N), but in the worst case (skewed tree), it can be O(N) due to the recursive call stack.

  • -
-

In summary, this code checks whether a given binary tree is a valid BST by recursively validating each node’s value and its left and right subtrees while maintaining valid value ranges. If all nodes satisfy the BST properties, the tree is considered a valid BST.

-
-
-

Test cases#

-
-
-
# Example 1: 
-
-# Example usage:
-# Create the tree for the first example: [2, 1, 3]
-root1 = TreeNode(2)
-root1.left = TreeNode(1)
-root1.right = TreeNode(3)
-print(is_valid_BST(root1))
-
-
-
-
-
True
-
-
-
-
-
-
-
# Example 2:
-
-# Create the tree for the second example: [5, 1, 4, None, None, 3, 6]
-root2 = TreeNode(5)
-root2.left = TreeNode(1)
-root2.right = TreeNode(4)
-root2.right.left = TreeNode(3)
-root2.right.right = TreeNode(6)
-print(is_valid_BST(root2))
-
-
-
-
-
False
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the is_valid_BST function:

-

Time Complexity:

-
    -
  • The time complexity of the function primarily depends on the number of nodes in the binary tree.

  • -
  • In the worst case, we may have to visit every node in the tree once to validate whether it’s part of a valid BST.

  • -
  • Since we are performing a depth-first search (DFS) traversal of the tree, the time complexity is O(N), where N is the number of nodes in the tree.

  • -
-

Space Complexity:

-
    -
  • The space complexity is determined by the space used by the recursive call stack during the DFS traversal.

  • -
  • In the worst case, if the tree is completely unbalanced (a skewed tree), the maximum depth of the call stack would be equal to the height of the tree.

  • -
  • In a balanced BST, the height is approximately log2(N), where N is the number of nodes.

  • -
  • Therefore, the space complexity of the call stack is O(log N) for a balanced BST.

  • -
  • In the worst case (skewed tree), the space complexity can be O(N) as the height of the tree can be equal to N.

  • -
-

Overall:

-
    -
  • Time Complexity: O(N)

  • -
  • Space Complexity: O(log N) on average for a balanced BST, and O(N) in the worst case for a skewed tree.

  • -
-

The space complexity is typically dominated by the recursive call stack, and it varies depending on the shape of the binary tree. In practice, for balanced binary trees, the space complexity is often close to O(log N), which is quite efficient.

-
-
-

Challenging Exercises:#

-
    -
  1. Complex Constraints: Modify the problem to have more complex constraints on the tree. For example, consider a binary tree with constraints like “The left subtree of a node contains only nodes with keys less than or equal to the node’s key,” and “The right subtree of a node contains only nodes with keys greater than or equal to the node’s key.” How would you adapt the code to handle these constraints?

  2. -
  3. Handling Duplicates: Modify the code to handle binary search trees that allow duplicate values. In a standard BST, each value is unique, but in this case, multiple nodes can have the same value. The tree should still be considered valid if it follows the BST property.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/07. Trees/README.html b/docs/_build/html/07. Trees/README.html deleted file mode 100644 index 1f27432..0000000 --- a/docs/_build/html/07. Trees/README.html +++ /dev/null @@ -1,647 +0,0 @@ - - - - - - - - - - - - Trees Problems - Blind 75 LeetCode — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Trees Problems - Blind 75 LeetCode

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

Trees Problems - Blind 75 LeetCode#

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Problem Name

Difficulty

226. Invert Binary Tree

Easy

104. Maximum Depth of Binary Tree

Easy

100. Same Tree

Easy

572. Subtree of Another Tree

Easy

235. Lowest Common Ancestor of a Binary Search Tree

Easy

102. Binary Tree Level Order Traversal

Medium

98. Validate Binary Search Tree

Medium

230. Kth Smallest Element In a BST

Medium

105. Construct Binary Tree From Preorder And Inorder Traversal

Medium

124. Binary Tree Maximum Path Sum

Hard

297. Serialize And Deserialize Binary Tree

Hard

-
-

Contribute#

-

If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements.

-
-
-

Resources#

-
    -
  • LeetCode: The official LeetCode website.

  • -
  • LeetCode Discuss: LeetCode’s discussion forum for each problem. You can find helpful hints and discussions here.

  • -
-

Happy coding!

-
-
-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/08. Tries/208. Implement Trie (Prefix Tree).html b/docs/_build/html/08. Tries/208. Implement Trie (Prefix Tree).html deleted file mode 100644 index 24b2af0..0000000 --- a/docs/_build/html/08. Tries/208. Implement Trie (Prefix Tree).html +++ /dev/null @@ -1,792 +0,0 @@ - - - - - - - - - - - - 208. Implement Trie (Prefix Tree) — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

208. Implement Trie (Prefix Tree)

- -
- -
-
- - - - -
- -
-

208. Implement Trie (Prefix Tree)#

-

Difficulty: Medium

-

Link to Problem: To see the Implement Trie problem on LeetCode, click here!

-
-

A trie (pronounced as “try”) or prefix tree is a tree data structure used to efficiently store and retrieve keys in a dataset of strings. There are various applications of this data structure, such as autocomplete and spellchecker.

-

Implement the Trie class:

-
    -
  • Trie() Initializes the trie object.

  • -
  • void insert(String word) Inserts the string word into the trie.

  • -
  • boolean search(String word) Returns true if the string word is in the trie (i.e., was inserted before), and false otherwise.

  • -
  • boolean startsWith(String prefix) Returns true if there is a previously inserted string word that has the prefix prefix, and false otherwise.

  • -
-

Constraints:

-
    -
  • 1 <= word.length, prefix.length <= 2000

  • -
  • word and prefix consist only of lowercase English letters.

  • -
  • At most \(3 * 10^4\) calls in total will be made to insert, search, and startsWith.

  • -
-
-

Probelm Explanation:#

-

The problem at hand is to implement a data structure known as a Trie (pronounced “try”) or Prefix Tree. A Trie is a tree-like data structure that is used to efficiently store and retrieve a set of strings or words. It’s particularly useful for tasks involving string manipulation, such as autocomplete and spell-checking. The problem statement defines the following operations for implementing the Trie class:

-
    -
  1. Trie(): This is the constructor that initializes the Trie object.

  2. -
  3. void insert(String word): This method inserts the given string word into the Trie. It effectively adds the characters of the word to the Trie’s structure, creating nodes for each character if they don’t already exist. At the end of the word, a special flag is set to indicate that this node represents the end of a valid word.

  4. -
  5. boolean search(String word): This method checks if the given string word is present in the Trie. It starts from the root of the Trie and traverses the Trie by following the characters in the word. If it successfully traverses the Trie and reaches the end of the word, it returns true, indicating that the word exists in the Trie; otherwise, it returns false.

  6. -
  7. boolean startsWith(String prefix): This method checks if there is any previously inserted word in the Trie that has the given prefix. It’s similar to the search method but does not require that the prefix be a complete word. If there is any word in the Trie that starts with the given prefix, it returns true; otherwise, it returns false.

  8. -
-

The problem also provides an example scenario where these operations are called, demonstrating the expected output for each operation.

-

In summary, the goal is to create a data structure (Trie) that efficiently stores a set of strings and provides methods to insert new strings, search for complete words, and check if a given prefix exists in the stored set of strings.

-
-
-

Solution:#

-

Here’s a Python function to implement this algorithm:

-
-
-
class TrieNode:
-    def __init__(self):
-        self.children = {}           # A dictionary to store child nodes
-        self.is_end_of_word = False  # Indicates if a word ends at this node
-
-class Trie:
-    def __init__(self):
-        self.root = TrieNode()       # Initialize the Trie with a root node
-
-    def insert(self, word):
-        node = self.root             # Start from the root
-        for char in word:
-            if char not in node.children:
-                node.children[char] = TrieNode()  # Create a new node if the character is not present
-            node = node.children[char]           # Move to the child node
-        node.is_end_of_word = True                # Mark the end of the inserted word
-
-    def search(self, word):
-        node = self.root             # Start from the root
-        for char in word:
-            if char not in node.children:
-                return False         # If the character is not found, the word is not in the Trie
-            node = node.children[char]  # Move to the child node
-        return node.is_end_of_word    # Check if the node represents the end of a valid word
-
-    def startsWith(self, prefix):
-        node = self.root             # Start from the root
-        for char in prefix:
-            if char not in node.children:
-                return False         # If the character is not found, no word starts with the prefix
-            node = node.children[char]  # Move to the child node
-        return True                  # Prefix found in the Trie
-
-
-
-
-
-
-

Explanation:#

-

Let’s explain how the code works step by step:

-
    -
  1. TrieNode Class:

    -
      -
    • TrieNode is a class that represents nodes in the Trie. Each node has two attributes:

      -
        -
      • children: This is a dictionary that stores child nodes. Each key in the dictionary represents a character, and the corresponding value is the child node for that character.

      • -
      • is_end_of_word: This boolean flag indicates whether the node represents the end of a complete word. Initially, it’s set to False for all nodes.

      • -
      -
    • -
    -
  2. -
  3. Trie Class:

    -
      -
    • Trie is the main class that implements the Trie data structure. It has the following methods:

    • -
    • __init__(self): The constructor initializes the Trie object by creating a root node, which serves as the starting point for all Trie operations.

    • -
    • insert(self, word): This method inserts a string word into the Trie. It starts from the root node and iterates through each character in the word.

      -
        -
      • If a character is not present as a child node, it creates a new node for that character.

      • -
      • It then moves to the child node and continues the process until the entire word is inserted.

      • -
      • Finally, it sets the is_end_of_word flag to True for the last node to mark the end of the inserted word.

      • -
      -
    • -
    • search(self, word): This method checks if a complete word (string) exists in the Trie. It starts from the root node and iterates through each character in the word.

      -
        -
      • If a character is not found as a child node, it immediately returns False because the word is not in the Trie.

      • -
      • It continues to move to the child node for each character.

      • -
      • After reaching the end of the word, it checks if the is_end_of_word flag is True for the last node to confirm the presence of the word.

      • -
      -
    • -
    • startsWith(self, prefix): This method checks if there is any previously inserted word in the Trie that starts with a given prefix. It follows the same logic as the search method but does not require the entire word to be present.

      -
        -
      • If the prefix is found in the Trie, it returns True; otherwise, it returns False.

      • -
      -
    • -
    -
  4. -
  5. Example Usage:

    -
      -
    • The code demonstrates how to create a Trie object, insert words (“apple” and “app”), and perform operations on the Trie:

      -
        -
      • It inserts the word “apple” into the Trie.

      • -
      • It checks if “apple” is in the Trie, which returns True.

      • -
      • It checks if “app” is in the Trie, which returns False.

      • -
      • It checks if there is any word in the Trie that starts with “app,” which returns True.

      • -
      • It inserts the word “app” into the Trie.

      • -
      • It checks if “app” is in the Trie again, which now returns True.

      • -
      -
    • -
    -
  6. -
-

In summary, the code efficiently implements a Trie data structure with the ability to insert words, search for complete words, and check for the existence of words with a given prefix. The Trie is organized as a tree of nodes, with each node representing a character in the words being stored.

-
-
-

Test cases:#

-

Here’s how you can use this solution:

-
-
-
# Example 1: 
-
-# Example usage:
-
-trie = Trie()
-trie.insert("apple")
-print(trie.search("apple"))   # Output: True
-print(trie.search("app"))     # Output: False
-print(trie.startsWith("app")) # Output: True
-trie.insert("app")
-print(trie.search("app"))     # Output: True
-
-
-
-
-
True
-False
-True
-True
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the Trie implementation:

-
    -
  1. Time Complexity:

    -
      -
    • Insertion (insert method): The time complexity of inserting a word into the Trie is O(m), where m is the length of the word. In the worst case, you may need to traverse the entire word to insert it into the Trie.

    • -
    • Search (search method): The time complexity of searching for a word in the Trie is also O(m), where m is the length of the word. In the worst case, you may need to traverse the entire word to determine if it exists in the Trie.

    • -
    • Starts with (startsWith method): The time complexity of checking if a prefix exists in the Trie is O(p), where p is the length of the prefix. In the worst case, you may need to traverse the entire prefix to determine its presence.

    • -
    -

    Therefore, for each operation (insertion, search, or starts with), the time complexity is O(m) or O(p), where m is the length of the word being operated on, and p is the length of the prefix.

    -
  2. -
  3. Space Complexity:

    -
      -
    • The space complexity of the Trie is determined by the number of nodes and characters stored in it. In the worst case, where none of the inserted words share common prefixes, the space complexity is O(N), where N is the total number of characters across all inserted words.

    • -
    • Each node in the Trie represents a character, and the number of nodes is directly related to the total number of characters.

    • -
    -

    In practice, the space complexity can be less than O(N) because common prefixes are shared among words in the Trie, leading to space optimization.

    -
  4. -
-

In summary:

-
    -
  • Time complexity for each operation (insertion, search, starts with) is O(m) or O(p), where m is the length of the word and p is the length of the prefix.

  • -
  • Space complexity is O(N) in the worst case, where N is the total number of characters across all inserted words. However, space optimization occurs due to common prefix sharing in practice, potentially reducing the actual space used.

  • -
-
-
-

Challenging Exercises:#

-
    -
  1. Count Prefixes: -Implement a method to count the number of words in the Trie that have a specific prefix. This exercise requires you to maintain additional data in the Trie nodes to keep track of the count.

  2. -
  3. Auto-Complete Suggestions: -Implement an auto-complete feature using the Trie. Given a prefix, the program should return a list of suggested words based on the words previously inserted into the Trie.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/08. Tries/211. Design Add and Search Words Data Structure.html b/docs/_build/html/08. Tries/211. Design Add and Search Words Data Structure.html deleted file mode 100644 index 395ec33..0000000 --- a/docs/_build/html/08. Tries/211. Design Add and Search Words Data Structure.html +++ /dev/null @@ -1,806 +0,0 @@ - - - - - - - - - - - - 211. Design Add and Search Words Data Structure — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

211. Design Add and Search Words Data Structure

- -
- -
-
- - - - -
- -
-

211. Design Add and Search Words Data Structure#

-

Difficulty: Medium

-

Link to Problem: To see the Design Add and Search Words Data Structure problem on LeetCode, click here!

-
-

Design a data structure that supports adding new words and finding if a string matches any previously added string.

-

Implement the WordDictionary class:

-
    -
  • WordDictionary() Initializes the object.

  • -
  • void addWord(word) Adds word to the data structure, it can be matched later.

  • -
  • bool search(word) Returns true if there is any string in the data structure that matches word or false otherwise. word may contain dots '.' where dots can be matched with any letter.

  • -
-

Constraints:

-
    -
  • 1 <= word.length <= 25

  • -
  • word in addWord consists of lowercase English letters.

  • -
  • word in search consist of '.' or lowercase English letters.

  • -
  • There will be at most 2 dots in word for search queries.

  • -
  • At most \(10^4\) calls will be made to addWord and search.

  • -
-
-

Probelm Explanation:#

-

The problem is to design a data structure called WordDictionary that allows you to add words and search for words efficiently. The key feature of this data structure is that it should support wildcard search, where a dot (‘.’) can match any letter.

-

Here are the specific requirements and explanations for the problem:

-
    -
  1. Initialize the WordDictionary object using the constructor WordDictionary().

  2. -
  3. The addWord(word) method allows you to add a word to the data structure. Once added, you should be able to search for this word later. The words consist of lowercase English letters, and each word has a length between 1 and 25 characters.

  4. -
  5. The search(word) method allows you to search for a word in the data structure. This method returns True if there is any string in the data structure that matches the given word or False otherwise. The word you are searching for may contain dots (‘.’), where each dot can match any letter.

  6. -
  7. The wildcard character (‘.’) in the search method allows for partial or fuzzy searching. For example, if the word dictionary contains the words “bad,” “dad,” and “mad,” then:

    -
      -
    • Searching for “pad” should return False because there is no exact match.

    • -
    • Searching for “bad” should return True because “bad” is in the dictionary.

    • -
    • Searching for “.ad” should return True because it can match “bad,” “dad,” or “mad.”

    • -
    • Searching for “b..” should return True because it can match “bad,” “bed,” “bet,” etc.

    • -
    -
  8. -
  9. The problem specifies that there will be at most two dots (‘.’) in search queries, and there will be at most 10^4 calls to both addWord and search.

  10. -
-

In summary, you need to implement the WordDictionary class that efficiently supports adding words and searching for words, where the search can include wildcard characters (‘.’) that match any letter.

-
-
-

Solution:#

-

Here’s a Python function to implement this algorithm:

-
-
-
class TrieNode:
-    def __init__(self):
-        # Initialize a TrieNode with children and a flag to indicate the end of a word.
-        self.children = {}
-        self.is_end_of_word = False
-
-class WordDictionary:
-
-    def __init__(self):
-        # Initialize the WordDictionary with a root node.
-        self.root = TrieNode()
-
-    def addWord(self, word: str) -> None:
-        node = self.root
-        # Iterate through the characters in the word.
-        for char in word:
-            if char not in node.children:
-                # Create a new node for the character if it doesn't exist.
-                node.children[char] = TrieNode()
-            # Move to the next node.
-            node = node.children[char]
-        # Mark the end of the word by setting the flag to True.
-        node.is_end_of_word = True
-
-    def search_helper(self, node: TrieNode, word: str) -> bool:
-        if not word:
-            # If there are no characters left in the word, check if we reached the end of a word in the trie.
-            return node.is_end_of_word
-        
-        char = word[0]
-        if char == '.':
-            # If the character is a dot, explore all possible child nodes.
-            for child in node.children.values():
-                if self.search_helper(child, word[1:]):
-                    return True
-        elif char in node.children:
-            # If the character is in the children of the current node, move to the next node.
-            return self.search_helper(node.children[char], word[1:])
-        
-        # If the character is not found and is not a dot, the word is not in the trie.
-        return False
-
-    def search(self, word: str) -> bool:
-        # Start the search from the root of the trie.
-        return self.search_helper(self.root, word)
-
-
-
-
-
-
-

Explanation:#

-

This code defines a WordDictionary class that uses a Trie data structure to efficiently store and search for words. Here’s a step-by-step explanation:

-
    -
  1. TrieNode class: This class represents nodes in the Trie data structure. Each node has two attributes: children (a dictionary to store child nodes) and is_end_of_word (a flag to indicate whether the node marks the end of a word).

  2. -
  3. WordDictionary class: This class initializes with an empty Trie by creating a root node.

  4. -
  5. addWord method: This method adds a word to the Trie. It iterates through each character in the word and creates Trie nodes as necessary. It sets the is_end_of_word flag to True for the final character of the word to mark the end of the word.

  6. -
  7. search_helper method: This is a recursive helper function for searching words in the Trie. It takes a Trie node (node) and a word to search (word) as input. If there are no characters left in the word (not word), it checks if the current node marks the end of a word. If it does, it returns True.

  8. -
  9. If the first character of the word is a dot (‘.’), the function explores all possible child nodes by iterating through node.children.values() and recursively calls search_helper for each child with the remaining part of the word (word[1:]).

  10. -
  11. If the first character of the word is not a dot and is found in the children of the current node, the function recursively moves to the next node by calling search_helper on the child node and the remaining part of the word.

  12. -
  13. If the character is not found in the children and is not a dot, the word is not in the Trie, so the function returns False.

  14. -
  15. search method: This is the public method for searching words. It initiates the search process by calling search_helper starting from the root node of the Trie.

  16. -
-

Overall, this code efficiently implements a Trie-based data structure that allows adding and searching for words, including support for wildcard characters represented by dots (‘.’).

-
-
-

Test cases:#

-

Here’s how you can use this solution:

-
-
-
# Example 1: 
-
-# Example usage:
-
-wordDictionary = WordDictionary()
-wordDictionary.addWord("bad")
-wordDictionary.addWord("dad")
-wordDictionary.addWord("mad")
-print(wordDictionary.search("pad"))  # Output: False
-print(wordDictionary.search("bad"))  # Output: True
-print(wordDictionary.search(".ad"))  # Output: True
-print(wordDictionary.search("b.."))  # Output: True
-
-
-
-
-
False
-True
-True
-True
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the WordDictionary class methods:

-
    -
  1. addWord Method:

    -
      -
    • Time Complexity: O(L)

      -
        -
      • L is the length of the word being added.

      • -
      • In the worst case, we need to iterate through each character in the word and create nodes in the Trie. This takes O(L) time.

      • -
      -
    • -
    • Space Complexity: O(L)

      -
        -
      • The space complexity for storing the word in the Trie is also O(L) because we create nodes for each character in the word.

      • -
      -
    • -
    -
  2. -
  3. search_helper Method (called by search):

    -
      -
    • Time Complexity: O(2^M * L)

      -
        -
      • M is the maximum number of dots (‘.’) in the search word.

      • -
      • In the worst case, when there are M dots in the search word, we may explore all possible child nodes at each dot. This results in a branching factor of 26 (for lowercase letters) at each dot.

      • -
      • So, the time complexity is exponential in the number of dots and linear in the length of the word being searched (L).

      • -
      -
    • -
    • Space Complexity: O(L)

      -
        -
      • The space complexity for the recursive call stack is O(L) in the worst case because we may have to recurse to a depth equal to the length of the search word.

      • -
      -
    • -
    -
  4. -
  5. search Method:

    -
      -
    • Time Complexity: O(2^M * L)

      -
        -
      • The search method calls the search_helper method, which has the same time complexity explained above.

      • -
      -
    • -
    • Space Complexity: O(L)

      -
        -
      • The space complexity for the recursive call stack is O(L) in the worst case, as explained earlier.

      • -
      -
    • -
    -
  6. -
-

Overall, the time complexity of the search method is mainly affected by the number of dots (‘.’) in the search word. In the worst case, when there are multiple dots and many possibilities to explore at each dot, the time complexity can be exponential. However, for most practical cases, it performs reasonably well.

-

The space complexity primarily depends on the space required to store the words in the Trie. It is proportional to the total number of characters in all added words and is linear with respect to the length of the words added.

-

In summary:

-
    -
  • Time Complexity for addWord: O(L)

  • -
  • Time Complexity for search: O(2^M * L)

  • -
  • Space Complexity: O(L) for storing words in the Trie, O(L) for the recursive call stack during search.

  • -
-

Note: The space complexity analysis assumes that the dictionary contains a reasonable number of words and does not account for the overhead of Python objects or system-level memory allocation.

-
-
-

Challenging Exercises:#

-
    -
  1. Dictionary Auto-Completion: Extend the WordDictionary class to provide auto-completion suggestions based on the prefix of a word. Implement a method that returns a list of words that match the given prefix.

  2. -
  3. Support Word Deletion: Extend the WordDictionary class to support word deletion. Add a method deleteWord(word) that removes a word from the data structure. Ensure that the search operation still works correctly after deletion.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/08. Tries/212. Word Search II.html b/docs/_build/html/08. Tries/212. Word Search II.html deleted file mode 100644 index c29a4c9..0000000 --- a/docs/_build/html/08. Tries/212. Word Search II.html +++ /dev/null @@ -1,836 +0,0 @@ - - - - - - - - - - - - 212. Word Search II — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

212. Word Search II#

-

Difficulty: Hard

-

Link to Problem: To see the Word Search II problem on LeetCode, click here!

-
-

Given an m x n board of characters and a list of strings words, the task is to return all words on the board.

-

Each word must be constructed from letters of sequentially adjacent cells, where adjacent cells are horizontally or vertically neighboring. The same letter cell may not be used more than once in a word.

-

Constraints:

-
    -
  • m == board.length

  • -
  • n == board[i].length

  • -
  • 1 <= m, n <= 12

  • -
  • board[i][j] is a lowercase English letter.

  • -
  • 1 <= words.length <= \(3 * 10^4\)

  • -
  • 1 <= words[i].length <= 10

  • -
  • words[i] consists of lowercase English letters.

  • -
  • All the strings of words are unique.

  • -
-
-

Probelm Explanation:#

-

To solve the “Word Search II” problem, you can use a Trie data structure and perform a depth-first search (DFS) on the board. Here’s a step-by-step approach to solve the problem:

-
    -
  1. Build a Trie from the given list of words:

    -
      -
    • Create a Trie data structure to store all the words from the input list.

    • -
    • For each word in the input list, insert it into the Trie, character by character. Make sure to mark the end of each word in the Trie.

    • -
    -
  2. -
  3. Perform DFS on the board:

    -
      -
    • Iterate through each cell (i, j) on the board.

    • -
    • For each cell, start a DFS traversal from that cell to search for words.

    • -
    • During the DFS traversal, maintain a current path string.

    • -
    • At each cell, check if the current path string, concatenated with the character in the cell, matches any word prefix in the Trie. If it does, continue the DFS.

    • -
    • If the current path string matches a word in the Trie, add it to the result.

    • -
    -
  4. -
  5. Implement DFS with backtracking:

    -
      -
    • During the DFS traversal, you will explore neighboring cells (horizontally and vertically) if they are within bounds and haven’t been visited before.

    • -
    • To prevent revisiting the same cell within the same word, mark the cell as visited (e.g., change its character to a special character like ‘#’) before exploring it and restore its original character after the DFS traversal.

    • -
    -
  6. -
  7. Return the result:

    -
      -
    • After completing the DFS traversal for all cells on the board, you will have collected all the valid words in the result set.

    • -
    • Convert the result set to a list and return it as the final output.

    • -
    -
  8. -
-

This approach efficiently finds all words on the board by utilizing the Trie data structure to prune unnecessary DFS paths and avoiding duplicate visits to the same cell within the same word. It ensures that each word is constructed from letters of sequentially adjacent cells without using the same letter cell more than once in a word.

-
-
-

Solution:#

-

Here’s a Python function to implement this algorithm:

-
-
-
# Define a TrieNode class to represent nodes in the Trie.
-class TrieNode:
-    def __init__(self):
-        self.children = {}  # Dictionary to store child nodes.
-        self.is_end_of_word = False  # Flag to mark the end of a word.
-
-# Main function to find words on the board.
-def findWords(board, words):
-    # DFS function to search for words starting from a given cell.
-    def dfs(node, i, j, path):
-        char = board[i][j]  # Get the character at the current cell.
-        curr_node = node.children.get(char)  # Find the corresponding Trie node.
-
-        if not curr_node:
-            return  # If no matching Trie node, stop the search.
-
-        path += char  # Add the character to the current path.
-
-        if curr_node.is_end_of_word:
-            result.add(path)  # If the path matches a word, add it to the result.
-
-        temp, board[i][j] = board[i][j], "#"  # Mark the cell as visited.
-
-        # Explore neighboring cells (up, down, left, right).
-        if i > 0:
-            dfs(curr_node, i - 1, j, path)
-        if i < m - 1:
-            dfs(curr_node, i + 1, j, path)
-        if j > 0:
-            dfs(curr_node, i, j - 1, path)
-        if j < n - 1:
-            dfs(curr_node, i, j + 1, path)
-
-        board[i][j] = temp  # Restore the cell's original character.
-
-    # Function to build a Trie from the list of words.
-    def buildTrie():
-        root = TrieNode()  # Create a root node.
-        for word in words:
-            node = root
-            for char in word:
-                if char not in node.children:
-                    node.children[char] = TrieNode()  # Create a new node if needed.
-                node = node.children[char]
-            node.is_end_of_word = True  # Mark the end of the word.
-        return root
-
-    m, n = len(board), len(board[0])  # Get the dimensions of the board.
-    root = buildTrie()  # Build the Trie from the list of words.
-    result = set()  # Use a set to store unique words found on the board.
-
-    # Iterate through each cell on the board and start DFS from there.
-    for i in range(m):
-        for j in range(n):
-            dfs(root, i, j, "")  # Start DFS from each cell on the board.
-
-    return list(result)  # Convert the set to a list and return the result.
-
-
-
-
-
-
-

Explanation:#

-

The code solves the “Word Search II” problem, where you have a grid of characters and a list of words. The goal is to find all words from the list that can be constructed by traversing adjacent cells (horizontally or vertically) in the grid, without using the same cell more than once for a single word.

-

The code does the following:

-
    -
  1. Defines a TrieNode class to represent nodes in a Trie data structure. Each node has children (other characters in the word) and a flag to mark the end of a word.

  2. -
  3. Defines the findWords function, which takes the grid (board) and a list of words (words) as input.

  4. -
  5. Inside the findWords function, there is a dfs (depth-first search) function. This function is used to explore the grid starting from a specific cell. It checks if the current path matches any word in the Trie and adds it to the result if found.

  6. -
  7. The code also includes a buildTrie function that constructs a Trie data structure from the list of words. It iterates through each word, creating nodes for each character in the Trie and marking the end of words.

  8. -
  9. The dimensions of the grid are obtained (m x n).

  10. -
  11. A Trie is built using the buildTrie function.

  12. -
  13. A set called result is used to store unique words found in the grid.

  14. -
  15. The code iterates through each cell on the grid (using nested loops) and starts a DFS search from each cell.

  16. -
  17. During the DFS, it explores neighboring cells (up, down, left, right) if they haven’t been visited before and if the current path matches a prefix in the Trie.

  18. -
  19. When a word is found during the DFS traversal, it is added to the result set.

  20. -
  21. The grid cell is marked as visited during the DFS by changing its character to “#”, and it is restored to its original character after the DFS traversal.

  22. -
  23. Finally, the set of unique words found is converted to a list and returned as the output.

  24. -
-

The code effectively uses a Trie data structure to optimize the search and ensures that each word is constructed from adjacent cells without reusing the same cell for the same word.

-
-
-

Test cases:#

-

Here’s how you can use this solution:

-
-
-
# Example 1: 
-
-board1 = [["o","a","a","n"],["e","t","a","e"],["i","h","k","r"],["i","f","l","v"]]
-words1 = ["oath","pea","eat","rain"]
-print(findWords(board1, words1))  # Output: ["eat", "oath"]
-
-
-
-
-
['eat', 'oath']
-
-
-
-
-
-
-
# Example 2
-
-board2 = [["a","b"],["c","d"]]
-words2 = ["abcb"]
-print(findWords(board2, words2))  # Output: []
-
-
-
-
-
[]
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the provided code:

-

Time Complexity:

-
    -
  1. Building the Trie (buildTrie function):

    -
      -
    • Suppose there are N words in the input list, and the average length of a word is L.

    • -
    • Building the Trie takes O(N * L) time, as we iterate through each word and insert each character into the Trie.

    • -
    -
  2. -
  3. DFS Traversal (dfs function):

    -
      -
    • In the worst case, the DFS function explores all possible paths in the grid.

    • -
    • The maximum number of recursive calls for each cell is 4 (up, down, left, right).

    • -
    • The maximum depth of the DFS is limited by the length of the longest word in the Trie, which is at most L.

    • -
    • Therefore, the DFS traversal for each cell takes \(O(4^L)\) time.

    • -
    -
  4. -
  5. Iterating Through the Grid (findWords function):

    -
      -
    • In the worst case, we iterate through all m rows and n columns in the grid.

    • -
    • For each cell, we start a DFS traversal.

    • -
    • Therefore, iterating through the entire grid takes \(O(m * n * 4^L)\) time.

    • -
    -
  6. -
-

Overall, the time complexity of the code is \(O(N * L + m * n * 4^L)\).

-

Space Complexity:

-
    -
  1. Trie Data Structure:

    -
      -
    • The space required to store the Trie depends on the number of unique characters in all the words.

    • -
    • In the worst case, where all words are unique and have no common prefixes, the space complexity of the Trie is O(N * L).

    • -
    • In practice, it may be less if there are common prefixes among words.

    • -
    -
  2. -
  3. DFS Stack (Recursive Calls):

    -
      -
    • The depth of the recursive call stack during DFS is at most L, where L is the length of the longest word in the Trie.

    • -
    • Therefore, the space complexity for the recursive call stack is O(L).

    • -
    -
  4. -
  5. Result Set (result set):

    -
      -
    • The space used to store the result set depends on the number of valid words found in the grid.

    • -
    • In the worst case, when all words are found, the space complexity of the result set is O(N * L).

    • -
    -
  6. -
-

Overall, the space complexity of the code is O(N * L) for the Trie and O(L) for the recursive call stack.

-

In summary, the time complexity is dominated by the DFS traversal and is influenced by the number of words, their lengths, and the size of the grid. The space complexity is mainly determined by the Trie structure and the recursive call stack depth during DFS.

-
-
-

Challenging Exercises:#

-
    -
  1. Word Search Paths: -Extend the basic word search exercise to find all possible paths (sequences of cells) that spell out a given word on the board. Return a list of paths if the word can be formed, otherwise an empty list.

  2. -
  3. Reverse Word Search: -Modify the code to search for words in reverse order on the board. Given a 2D grid of characters and a list of words, find all words from the list that can be formed by traversing the board in reverse (right to left, bottom to top, etc.).

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/08. Tries/README.html b/docs/_build/html/08. Tries/README.html deleted file mode 100644 index 329360f..0000000 --- a/docs/_build/html/08. Tries/README.html +++ /dev/null @@ -1,623 +0,0 @@ - - - - - - - - - - - - Trie Problems - Blind 75 LeetCode — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Trie Problems - Blind 75 LeetCode

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

Trie Problems - Blind 75 LeetCode#

- - - - - - - - - - - - - - - - - -

Problem Name

Difficulty

208. Implement Trie Prefix Tree

Medium

211. Design Add And Search Words Data Structure

Medium

212. Word Search II

Hard

-
-

Contribute#

-

If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements.

-
-
-

Resources#

-
    -
  • LeetCode: The official LeetCode website.

  • -
  • LeetCode Discuss: LeetCode’s discussion forum for each problem. You can find helpful hints and discussions here.

  • -
-

Happy coding!

-
-
-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/09. Heap - Priority Queue/1046. Last Stone Weight.html b/docs/_build/html/09. Heap - Priority Queue/1046. Last Stone Weight.html deleted file mode 100644 index ae83555..0000000 --- a/docs/_build/html/09. Heap - Priority Queue/1046. Last Stone Weight.html +++ /dev/null @@ -1,763 +0,0 @@ - - - - - - - - - - - - 1046. Last Stone Weight — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

1046. Last Stone Weight

- -
- -
-
- - - - -
- -
-

1046. Last Stone Weight#

-

Difficulty: Easy

-

Link to Problem: To see the Last Stone Weight problem on LeetCode, click here!

-
-

You are given an array of integers stones where stones[i] is the weight of the ith stone.

-

We are playing a game with the stones. On each turn, you choose the heaviest two stones and smash them together. Suppose the heaviest two stones have weights x and y with x <= y. The result of this smash is:

-
    -
  1. If x == y, both stones are destroyed.

  2. -
  3. If x != y, the stone of weight x is destroyed, and the stone of weight y has new weight y - x.

  4. -
-

At the end of the game, there is at most one stone left.

-

Return the weight of the last remaining stone. If there are no stones left, return 0.

-

Constraints:

-
    -
  • 1 <= stones.length <= 30

  • -
  • 1 <= stones[i] <= 1000

  • -
-
-

Probelm Explanation:#

-

The “Last Stone Weight” problem involves a game played with a collection of stones, each stone having a certain weight. The goal is to find the weight of the last remaining stone after applying a specific set of rules.

-

Here’s how the game works:

-
    -
  1. You start with an array of stones, where each stone is represented by its weight. The weights of the stones are given in the input as an array.

  2. -
  3. In each turn of the game, you select the two heaviest stones from the remaining stones. If there is only one stone left, you’ve found the answer.

  4. -
  5. If there are two stones with weights x and y, where x is less than or equal to y, the following happens:

    -
      -
    • If x is equal to y, both stones are completely destroyed, and they are removed from the array of stones.

    • -
    • If x is not equal to y, the stone with weight x is destroyed, and the stone with weight y now has a new weight of y - x. The stone with weight x is removed from the array, and the modified stone with weight y - x remains in the array.

    • -
    -
  6. -
  7. The game continues with the modified array of stones until there is at most one stone left.

  8. -
  9. The goal is to find the weight of the last remaining stone, or if there are no stones left, return 0.

  10. -
-
-
-

Solution:#

-

Here’s a Python function to implement this algorithm:

-
-
-
import heapq
-
-def lastStoneWeight(stones):
-    # Convert the input list to a max heap (negate the values to simulate a max heap)
-    max_heap = [-stone for stone in stones]
-    heapq.heapify(max_heap)
-
-    # Continue as long as there are more than 1 stone in the heap
-    while len(max_heap) > 1:
-        # Get the two heaviest stones
-        y = -heapq.heappop(max_heap)  # Get the heaviest stone and negate it back to positive
-        x = -heapq.heappop(max_heap)  # Get the second heaviest stone and negate it back to positive
-
-        # Calculate the new stone's weight after smashing
-        if x != y:
-            new_stone = y - x
-            heapq.heappush(max_heap, -new_stone)  # Negate the value and push it back to the heap
-
-    # If there is one stone left, return its weight (negate it back to positive)
-    if max_heap:
-        return -max_heap[0]
-    else:
-        return 0
-
-
-
-
-
-
-

Explanation:#

-

The code defines a Python function called lastStoneWeight that takes a list of stone weights as input. It aims to find the weight of the last remaining stone after playing the stone smashing game described in the problem statement.

-

Here’s a step-by-step explanation of the code:

-
    -
  1. We import the heapq library, which allows us to create and manipulate a heap (priority queue).

  2. -
  3. Inside the lastStoneWeight function:

    -
      -
    • We create a max heap (negating stone weights to simulate a max heap) using the heapq.heapify function. This heap will keep track of the heaviest stones.

    • -
    • We enter a loop that continues as long as there are more than 1 stone in the heap.

    • -
    • Inside the loop, we:

      -
        -
      • Retrieve and negate the heaviest stone (y) from the heap.

      • -
      • Retrieve and negate the second heaviest stone (x) from the heap.

      • -
      • Calculate the new stone’s weight after smashing (y - x), and negate it back to simulate a max heap.

      • -
      • Add the new stone back to the heap using heapq.heappush.

      • -
      -
    • -
    -
  4. -
  5. After the loop, if there is one stone left in the heap, we retrieve and negate it to get its actual weight, and return it as the result.

  6. -
  7. If there are no stones left (the heap is empty), we return 0, indicating that no stones remain.

  8. -
  9. Finally, we provide two test cases to demonstrate the function’s usage and correctness.

  10. -
-

In summary, the code efficiently implements the stone smashing game by maintaining a max heap, selecting the heaviest stones in each turn, smashing them, and updating the heap until there is at most one stone left. It then returns the weight of the last remaining stone or 0 if there are no stones left.

-
-
-

Test cases:#

-

Here’s how you can use this solution:

-
-
-
# Example 1: 
-
-stones1 = [2, 7, 4, 1, 8, 1]
-print(lastStoneWeight(stones1))  # Output: 1
-
-
-
-
-
1
-
-
-
-
-
-
-
# Example 2: 
-
-stones2 = [1]
-print(lastStoneWeight(stones2))  # Output: 1
-
-
-
-
-
1
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the provided Python code for the “Last Stone Weight” problem:

-

Time Complexity:

-
    -
  1. The heapq.heapify operation to create the max heap from the input stone weights has a time complexity of O(n), where n is the number of stones.

  2. -
  3. The loop that continues until there are more than 1 stone in the heap performs the following operations in each iteration:

    -
      -
    • Retrieving and negating the heaviest stone (y) from the heap, which takes O(log n) time.

    • -
    • Retrieving and negating the second heaviest stone (x) from the heap, also taking O(log n) time.

    • -
    • Calculating the new stone’s weight and pushing it back into the heap using heapq.heappush, which takes O(log n) time.

    • -
    -
  4. -
  5. In the worst case, the loop runs until there is only one stone left, which requires approximately (n-1) iterations.

  6. -
-

Overall, the dominant time complexity is O(n) for the initial heap creation, and within the loop, each iteration takes O(log n) time. Therefore, the overall time complexity of the algorithm is O(n log n).

-

Space Complexity:

-
    -
  1. The space complexity is primarily determined by the space required for the max heap. In the worst case, this heap can contain all the stones, so the space complexity for the heap is O(n).

  2. -
  3. The rest of the variables used in the function (e.g., x, y, new_stone) require only constant space, so they do not significantly contribute to the space complexity.

  4. -
-

Therefore, the overall space complexity of the algorithm is O(n) due to the space used for the max heap.

-

In summary:

-
    -
  • Time Complexity: \(O(n\ log\ n)\)

  • -
  • Space Complexity: \(O(n)\)

  • -
-

The algorithm is efficient enough to handle the problem’s constraints, as the worst-case time and space complexities are both linearithmic in terms of the number of stones.

-
-
-

Challenging Exercises:#

-
    -
  1. Kth Last Stone Weight: Modify the problem to find the weight of the Kth last remaining stone, where K is an integer input. Your function should work efficiently for large values of K.

  2. -
  3. Multiple Stones Smash: Modify the problem so that instead of smashing two stones at a time, you can smash up to K stones at each turn, where K is an integer input. Determine the weight of the last remaining stone in this variation.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/09. Heap - Priority Queue/295. Find Median from Data Stream.html b/docs/_build/html/09. Heap - Priority Queue/295. Find Median from Data Stream.html deleted file mode 100644 index c8fe5a3..0000000 --- a/docs/_build/html/09. Heap - Priority Queue/295. Find Median from Data Stream.html +++ /dev/null @@ -1,758 +0,0 @@ - - - - - - - - - - - - 295. Find Median from Data Stream — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

295. Find Median from Data Stream

- -
- -
-
- - - - -
- -
-

295. Find Median from Data Stream#

-

Difficulty: Hard

-

Link to Problem: To see the Find Median from Data Stream problem on LeetCode, click here!

-
-

The median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value, and the median is the mean of the two middle values.

-

Implement the MedianFinder class:

-
    -
  • MedianFinder() initializes the MedianFinder object.

  • -
  • void addNum(int num) adds the integer num from the data stream to the data structure.

  • -
  • double findMedian() returns the median of all elements so far. Answers within \(10^{-5}\) of the actual answer will be accepted.

  • -
-

Constraints:

-
    -
  • \(-10^{5}\) <= num <= \(10^{5}\)

  • -
  • There will be at least one element in the data structure before calling findMedian.

  • -
  • At most \(5 * 10^4\) calls will be made to addNum and findMedian.

  • -
-

Follow-up:

-
    -
  1. If all integer numbers from the stream are in the range [0, 100], how would you optimize your solution?

  2. -
  3. If 99% of all integer numbers from the stream are in the range [0, 100], how would you optimize your solution?

  4. -
-
-

Probelm Explanation:#

-

The problem, “Find Median from Data Stream,” deals with efficiently computing the median of a sequence of numbers as they are incrementally provided. The median is the middle value in an ordered list of numbers. When the list has an even number of elements, the median is the average of the two middle values.

-

Here’s a breakdown of the problem:

-
    -
  1. Initialization: You are asked to implement a MedianFinder class that supports the following operations:

    -
      -
    • MedianFinder(): Initializes the MedianFinder object.

    • -
    • addNum(int num): Adds an integer num from the data stream to the data structure.

    • -
    • findMedian(): Returns the median of all elements added to the data structure.

    • -
    -
  2. -
  3. Median Calculation: The findMedian operation should efficiently compute the median, and the result should have a precision of at least \(10^{-5}\) (i.e., answers within this range will be considered correct).

  4. -
  5. Examples:

    -
      -
    • If you add numbers [1, 2], the median should be 1.5 because (1 + 2) / 2 = 1.5.

    • -
    • If you add numbers [1, 2, 3], the median should be 2 because it’s the middle value.

    • -
    -
  6. -
  7. Constraints:

    -
      -
    • The integers provided in the data stream are in the range from \(-10^5\) to \(10^5\).

    • -
    • There will be at least one element in the data structure before calling findMedian.

    • -
    • At most, \(5 * 10^4\) calls will be made to addNum and findMedian.

    • -
    -
  8. -
-

The problem can be solved by using two priority queues (heaps): one max-heap to store the smaller half of the numbers and one min-heap to store the larger half of the numbers. The max-heap ensures that the largest number in the smaller half is at the top, and the min-heap ensures that the smallest number in the larger half is at the top. These heaps are balanced to efficiently find the median when requested.

-
-
-

Solution:#

-

Here’s a Python function to implement this algorithm:

-
-
-
import heapq
-
-class MedianFinder:
-
-    def __init__(self):
-        # Initialize two heaps: a max-heap (small_half) for the smaller half of numbers,
-        # and a min-heap (large_half) for the larger half of numbers.
-        self.small_half = []  # Max-heap for the smaller half of the numbers
-        self.large_half = []  # Min-heap for the larger half of the numbers
-
-    def addNum(self, num: int) -> None:
-        # Add the number to the appropriate heap based on its value
-        if not self.small_half or num <= -self.small_half[0]:
-            # If the number is less than or equal to the current maximum in the smaller half,
-            # add it to the smaller half (max-heap)
-            heapq.heappush(self.small_half, -num)
-        else:
-            # Otherwise, add it to the larger half (min-heap)
-            heapq.heappush(self.large_half, num)
-
-        # Balance the heaps if necessary to ensure the size difference is at most 1
-        if len(self.small_half) > len(self.large_half) + 1:
-            # If the size of the smaller half is more than one greater than the size of the larger half,
-            # move the maximum from the smaller half to the larger half to balance them.
-            heapq.heappush(self.large_half, -heapq.heappop(self.small_half))
-        elif len(self.large_half) > len(self.small_half):
-            # If the size of the larger half is greater than the size of the smaller half,
-            # move the minimum from the larger half to the smaller half to balance them.
-            heapq.heappush(self.small_half, -heapq.heappop(self.large_half))
-
-    def findMedian(self) -> float:
-        if len(self.small_half) == len(self.large_half):
-            # If both halves have the same size, there's an even number of elements,
-            # so the median is the average of the top elements in both heaps.
-            return (-self.small_half[0] + self.large_half[0]) / 2.0
-        else:
-            # If the smaller half has more elements, it contains the median (odd number of elements).
-            return -self.small_half[0]
-
-
-
-
-
-
-

Explanation:#

-

The code defines a MedianFinder class for efficiently finding the median of a stream of numbers. It uses two heaps: a max-heap (small_half) to store the smaller half of the numbers and a min-heap (large_half) to store the larger half. Here’s how the code works:

-
    -
  1. The __init__ method initializes the two heaps.

  2. -
  3. The addNum method adds a number to the appropriate heap, ensuring that the heaps remain balanced. It does this by comparing the number to the current maximum in the smaller half and adding it to the appropriate heap. Then, it checks the sizes of the two heaps and rebalances them if necessary.

  4. -
  5. The findMedian method calculates and returns the median. If both halves have the same size (even number of elements), it computes the average of the tops of both heaps. If the smaller half has more elements (odd number of elements), it returns the top of the max-heap, which is the median.

  6. -
-

In summary, this code efficiently maintains two heaps to divide the elements into smaller and larger halves, allowing for quick median retrieval. It offers a time complexity of O(log N) for adding elements and O(1) for finding the median, where N is the total number of elements processed. The space complexity is O(1) as the space used by the two heaps is independent of the input size.

-
-
-

Test cases:#

-

Here’s how you can use this solution:

-
-
-
# Example 1: 
-
-# Example usage:
-medianFinder = MedianFinder()
-medianFinder.addNum(1)
-medianFinder.addNum(2)
-print(medianFinder.findMedian())  # Output: 1.5
-medianFinder.addNum(3)
-print(medianFinder.findMedian())  # Output: 2.0
-
-
-
-
-
1.5
-2
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the MedianFinder class:

-

Time Complexity:

-
    -
  1. MedianFinder() Initialization: This operation has a time complexity of O(1). It simply initializes the two heaps.

  2. -
  3. addNum(int num): The time complexity for adding a number is O(log N), where N is the total number of elements processed so far. This is because, in the worst case, you might need to perform logarithmic operations on the heaps to maintain their balance.

  4. -
  5. findMedian(): Finding the median has a time complexity of O(1). It simply involves accessing the tops of the two heaps, which takes constant time.

  6. -
-

Space Complexity:

-
    -
  1. MedianFinder() Initialization: The space complexity for initialization is O(1). It involves creating two empty heaps, which do not depend on the size of the data stream.

  2. -
  3. addNum(int num): The space complexity for adding a number is also O(1). It involves adding the number to one of the two heaps, which do not significantly affect the overall space complexity.

  4. -
  5. findMedian(): The space complexity for finding the median is O(1). It doesn’t require any additional data structures that grow with the input size.

  6. -
-

In summary, the time complexity of the addNum operation is O(log N), and the time complexity of the findMedian operation is O(1). The space complexity is O(1) as well, as the space used by the two heaps is independent of the size of the data stream. This solution efficiently maintains and retrieves the median, making it suitable for the given problem constraints.

-
-
-

Challenging Exercises:#

-
    -
  1. Generalized kth Element: Extend the MedianFinder class to support finding the kth element in the data stream efficiently. This means finding the kth smallest or kth largest element in the stream.

  2. -
  3. Sliding Window Median: Given an array and a sliding window size, find the median within the window as it slides over the array. This is an extension of the problem to a moving window scenario.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.html b/docs/_build/html/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.html deleted file mode 100644 index a31cb11..0000000 --- a/docs/_build/html/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.html +++ /dev/null @@ -1,770 +0,0 @@ - - - - - - - - - - - - 703. Kth Largest Element in a Stream — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

703. Kth Largest Element in a Stream

- -
- -
-
- - - - -
- -
-

703. Kth Largest Element in a Stream#

-

Difficulty: Easy

-

Link to Problem: To see the Kth Largest Element in a Stream problem on LeetCode, click here!

-
-

Design a class to find the kth largest element in a stream. Note that it is the kth largest element in the sorted order, not the kth distinct element.

-

Implement the KthLargest class with the following methods:

-
    -
  • KthLargest(int k, int[] nums): Initializes the object with the integer k and the stream of integers nums.

  • -
  • int add(int val): Appends the integer val to the stream and returns the element representing the kth largest element in the stream.

  • -
-

Constraints:

-
    -
  • 1 <= k <= \(10^4\)

  • -
  • 0 <= nums.length <= \(10^4\)

  • -
  • \(-10^4\) <= nums[i] <= \(10^4\)

  • -
  • \(-10^4\) <= val <= \(10^4\)

  • -
  • At most \(10^4\) calls will be made to add.

  • -
  • It is guaranteed that there will be at least k elements in the array when you search for the kth element.

  • -
-
-

Probelm Explanation:#

-

The problem you’re trying to solve is to design a class called KthLargest that can efficiently find the kth largest element in a stream of integers. You need to support two main operations:

-

To solve this problem efficiently, you can use a min-heap data structure. Here’s how the approach works:

-
    -
  1. Initialize a min-heap to store the k largest elements. Initially, it’s empty.

  2. -
  3. In the __init__ method, populate the min-heap with the first k elements from nums. This ensures that you have the k largest elements seen so far.

  4. -
  5. Whenever you add a new element to the stream using the add method, follow these steps:

    -
      -
    • Add the new element to the min-heap.

    • -
    • If the size of the min-heap exceeds k, remove the smallest element from the min-heap. This ensures that you always have the k largest elements in the min-heap.

    • -
    • The smallest element in the min-heap (the root) will always represent the kth largest element in the stream.

    • -
    -
  6. -
-

Here’s why this approach works efficiently:

-
    -
  • By using a min-heap, you can quickly maintain the k largest elements, and finding the smallest element in the heap (the root) takes constant time.

  • -
  • When you add a new element, the min-heap’s size is kept at most k, which ensures that you only track the k largest elements and discard the smaller ones.

  • -
  • The time complexity for adding an element is O(log k), which is very efficient compared to sorting the entire stream, which would be O(n log n).

  • -
  • This approach meets the constraints of the problem, including handling large streams and having a low time complexity for both initialization and adding elements.

  • -
-

In summary, the min-heap approach efficiently tracks the kth largest element in the stream by maintaining a heap of the k largest elements seen so far, updating it as new elements are added. This approach provides a fast and scalable solution to the problem.

-
-
-

Solution:#

-

Here’s a Python function to implement this algorithm:

-
-
-
import heapq
-from typing import List  # Import the List type from the typing module
-
-class KthLargest:
-
-    def __init__(self, k: int, nums: List[int]):
-        # Initialize the KthLargest object with k and nums.
-        self.k = k
-        # Create a min-heap to store the k largest elements.
-        self.min_heap = []
-        # Populate the min-heap with the first k elements from nums.
-        for num in nums:
-            self.add(num)
-
-    def add(self, val: int) -> int:
-        # Add val to the min-heap.
-        heapq.heappush(self.min_heap, val)
-        # If the size of the min-heap exceeds k, remove the smallest element.
-        if len(self.min_heap) > self.k:
-            heapq.heappop(self.min_heap)
-        # The root of the min-heap is the kth largest element.
-        return self.min_heap[0]
-
-
-
-
-
-
-

Explanation:#

-
    -
  • We start by importing the necessary modules:

    -
      -
    • heapq: This module provides functions to create and manipulate heaps.

    • -
    • List from the typing module: This is used to specify the type of the nums parameter.

    • -
    -
  • -
  • We define the KthLargest class:

    -
      -
    • The __init__ method initializes the object with the integer k and the list of integers nums.

    • -
    • It also creates an empty min-heap called self.min_heap to store the k largest elements.

    • -
    • It populates the min-heap with the first k elements from nums by calling the add method.

    • -
    -
  • -
  • The add method:

    -
      -
    • Adds the new integer val to the min-heap using heapq.heappush. This maintains the min-heap property.

    • -
    • Checks if the size of the min-heap exceeds k. If it does, it removes the smallest element (the k+1th largest) using heapq.heappop.

    • -
    • Finally, it returns the smallest element in the min-heap, which is always the kth largest element.

    • -
    -
  • -
-

Overall, this code implements a class that efficiently finds the kth largest element in a stream of integers by maintaining a min-heap of the k largest elements seen so far.

-
-
-

Test cases:#

-

Here’s how you can use this solution:

-
-
-
# Example 1: 
-
-# Example usage:
-kthLargest = KthLargest(3, [4, 5, 8, 2])
-print(kthLargest.add(3))  # Output: 4
-print(kthLargest.add(5))  # Output: 5
-print(kthLargest.add(10)) # Output: 5
-print(kthLargest.add(9))  # Output: 8
-print(kthLargest.add(4))  # Output: 8
-
-
-
-
-
4
-5
-5
-8
-8
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the KthLargest class using the min-heap approach:

-

Time Complexity:

-
    -
  1. __init__ method:

    -
      -
    • In the __init__ method, you iterate over the first k elements in nums and add them to the min-heap. Each heapq.heappush operation takes O(log k) time.

    • -
    • Therefore, the time complexity of the __init__ method is O(k * log k).

    • -
    -
  2. -
  3. add method:

    -
      -
    • In the add method, you perform the following operations:

      -
        -
      • heapq.heappush: O(log k) to add the new element to the min-heap.

      • -
      • If the size of the min-heap exceeds k, you perform heapq.heappop, which is also O(log k).

      • -
      • Finally, you return the smallest element from the min-heap, which is O(1) because it’s always the root.

      • -
      -
    • -
    • Overall, the time complexity of the add method is O(log k).

    • -
    -
  4. -
  5. Overall, if you make n calls to the add method, the total time complexity is O(n * log k), where n is the total number of elements added to the stream.

  6. -
-

Space Complexity:

-
    -
  1. The space complexity is determined by the space used to store the min-heap and the instance variables.

  2. -
  3. The min-heap stores at most k elements at any given time, so its space complexity is O(k).

  4. -
  5. The instance variables (such as self.k and self.min_heap) have constant space requirements.

  6. -
  7. Therefore, the overall space complexity of the KthLargest class is O(k).

  8. -
-

In summary, the time complexity of the KthLargest class is O(n * log k) for n add operations, and the space complexity is O(k), where k is the parameter passed during initialization. This implementation efficiently maintains the kth largest element in the stream while meeting the problem’s constraints.

-
-
-

Challenging Exercises:#

-
    -
  1. Dynamic k: Modify the KthLargest class to support dynamic changes in the value of k. Implement a method update_k that allows changing the value of k during the lifetime of the object. Ensure that the object can still correctly find the kth largest element based on the updated value of k.

  2. -
  3. Implement kth Smallest: Create a new class called KthSmallest that finds the kth smallest element in a stream instead of the kth largest. You may need to modify the data structure used in the implementation.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/09. Heap - Priority Queue/README.html b/docs/_build/html/09. Heap - Priority Queue/README.html deleted file mode 100644 index 0f7b22b..0000000 --- a/docs/_build/html/09. Heap - Priority Queue/README.html +++ /dev/null @@ -1,623 +0,0 @@ - - - - - - - - - - - - Heap / Priority Queue Problems - Blind 75 LeetCode — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Heap / Priority Queue Problems - Blind 75 LeetCode

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

Heap / Priority Queue Problems - Blind 75 LeetCode#

- - - - - - - - - - - - - - - - - -

Problem Name

Difficulty

703. Kth Largest Element in a Stream

Easy

1046. Last Stone Weight

Easy

295. Find Median From Data Stream

Hard

-
-

Contribute#

-

If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements.

-
-
-

Resources#

-
    -
  • LeetCode: The official LeetCode website.

  • -
  • LeetCode Discuss: LeetCode’s discussion forum for each problem. You can find helpful hints and discussions here.

  • -
-

Happy coding!

-
-
-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/10. Backtracking/39. Combination Sum.html b/docs/_build/html/10. Backtracking/39. Combination Sum.html deleted file mode 100644 index c20daec..0000000 --- a/docs/_build/html/10. Backtracking/39. Combination Sum.html +++ /dev/null @@ -1,773 +0,0 @@ - - - - - - - - - - - - 39. Combination Sum — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

39. Combination Sum#

-

Difficulty: Medium

-

Link to Problem: To see the Combination Sum problem on LeetCode, click here!

-
-

Given an array of distinct integers candidates and a target integer target, return a list of all unique combinations of candidates where the chosen numbers sum to the target. You may return the combinations in any order.

-

The same number may be chosen from candidates an unlimited number of times. Two combinations are unique if the frequency of at least one of the chosen numbers is different.

-

The test cases are generated such that the number of unique combinations that sum up to target is less than 150 combinations for the given input.

-

Constraints:

-
    -
  • 1 <= candidates.length <= 30

  • -
  • 2 <= candidates[i] <= 40

  • -
  • All elements of candidates are distinct.

  • -
  • 1 <= target <= 40

  • -
-
-

Probelm Explanation:#

-

The problem is to find all unique combinations of numbers from a given array (candidates) such that their sum equals a target number. Here are the details of the problem:

-
    -
  • You are given an array of distinct integers called “candidates.”

  • -
  • You are also given a target integer called “target.”

  • -
-

The goal is to find all unique combinations of numbers from the candidates array where the sum of the selected numbers is equal to the target. You can use the same number from the candidates array an unlimited number of times. A combination is considered unique if it has a different frequency (i.e., a different number of occurrences) of at least one chosen number compared to other combinations.

-

For example:

-

Example 1:

-
Input: candidates = [2, 3, 6, 7], target = 7
-Output: [[2, 2, 3], [7]]
-
-
-

In this example, there are two unique combinations that sum up to the target:

-
    -
  • 2 + 2 + 3 = 7

  • -
  • 7 = 7

  • -
-

Example 2:

-
Input: candidates = [2, 3, 5], target = 8
-Output: [[2, 2, 2, 2], [2, 3, 3], [3, 5]]
-
-
-

Here, there are three unique combinations that sum up to the target.

-

Example 3:

-
Input: candidates = [2], target = 1
-Output: []
-
-
-

In this case, there are no combinations that can be formed from the candidates to reach the target of 1, so the output is an empty list.

-

The problem asks you to find and return these combinations in any order.

-

The constraints for this problem include the length of the candidates array, the values of candidates, and the target value.

-
-
-

Solution:#

-

Here’s a Python function to implement this algorithm:

-
-
-
def combinationSum(candidates, target):
-    # Define a recursive DFS function to find combinations
-    def dfs(remaining, start, path):
-        # If the remaining target is 0, we found a valid combination
-        if remaining == 0:
-            result.append(path)
-            return
-        # If the remaining target is negative, this path is invalid
-        if remaining < 0:
-            return
-        # Iterate through candidates starting from 'start' to avoid duplicates
-        for i in range(start, len(candidates)):
-            # Explore the current candidate by subtracting it from the remaining target
-            # Add the current candidate to the path
-            dfs(remaining - candidates[i], i, path + [candidates[i]])
-
-    result = []  # Initialize an empty list to store the result
-    candidates.sort()  # Sort the candidates for deduplication and early stopping
-    dfs(target, 0, [])  # Start the DFS from the target value with an empty path
-    return result  # Return the list of unique combinations
-
-
-
-
-
-
-

Explanation:#

-

The combinationSum function takes an array of distinct integers candidates and a target integer target. It returns a list of all unique combinations of candidates where the chosen numbers sum to the target. Each number in the candidates array can be used an unlimited number of times.

-

Here’s an overview of how the code works:

-
    -
  1. The combinationSum function is defined, and it takes two arguments: candidates and target.

  2. -
  3. Inside the function, there is a nested helper function called backtrack. This function is responsible for the actual combination generation using a recursive approach.

  4. -
  5. The backtrack function is called with three arguments: start, target, and path. The start variable helps keep track of the current index in the candidates array, target keeps track of the remaining sum to be achieved, and path is a list that stores the current combination.

  6. -
  7. Within the backtrack function, there are three main conditional statements:

    -
      -
    • If target becomes zero, it means we have found a combination that sums up to the target, so we add path to the result list.

    • -
    • If target becomes negative, it means the current combination doesn’t work, so we return without doing anything.

    • -
    • Otherwise, we enter a loop that iterates over the candidates array, starting from the current index start.

    • -
    -
  8. -
  9. In the loop, the backtrack function is called recursively with the updated target and path after including the current candidate. This process explores different combinations by considering the current candidate or moving to the next candidate.

  10. -
  11. After the loop completes, the result list contains all unique combinations that sum to the target.

  12. -
  13. The candidates array is sorted to optimize the search. Sorting helps in avoiding unnecessary recursive branches and reduces the number of explored combinations.

  14. -
  15. Finally, the backtrack function is initially called from the combinationSum function with start set to 0, target set to the original target value, and an empty path. The result is returned as a list of unique combinations.

  16. -
-

The code includes a few example cases to demonstrate how the function works with different inputs.

-
-
-

Test cases:#

-

Here’s how you can use this solution:

-
-
-
# Example 1: 
-
-# Example 1
-candidates1 = [2, 3, 6, 7]
-target1 = 7
-print(combinationSum(candidates1, target1))  # Output: [[2, 2, 3], [7]]
-
-
-
-
-
[[2, 2, 3], [7]]
-
-
-
-
-
-
-
# Example 2
-candidates2 = [2, 3, 5]
-target2 = 8
-print(combinationSum(candidates2, target2))  # Output: [[2, 2, 2, 2], [2, 3, 3], [3, 5]]
-
-
-
-
-
[[2, 2, 2, 2], [2, 3, 3], [3, 5]]
-
-
-
-
-
-
-
# Example 3
-candidates3 = [2]
-target3 = 1
-print(combinationSum(candidates3, target3))  # Output: []
-
-
-
-
-
[]
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the combinationSum function.

-

Time Complexity: -The time complexity of this function is influenced by the number of recursive calls made by the backtrack function and the amount of work done within each call. In the worst case, the function will explore all possible combinations.

-

The worst-case scenario occurs when we have many combinations to reach the target. The time complexity can be expressed as \(O(2^n)\), where ‘n’ is the maximum number of recursive calls. In this context, ‘n’ corresponds to the number of elements in the candidates list, and it may be up to 30 (as per the constraints). However, the actual number of combinations explored is generally much smaller because we eliminate branches when the target becomes negative, and we skip over candidates that cannot lead to a solution. The sorting step also helps to optimize the search.

-

Space Complexity: -The space complexity is determined by the auxiliary space used for storing the results and the stack space for the recursive calls.

-
    -
  1. The space required for the result list can be up to \(O(2^n)\) in the worst case because each combination is stored.

  2. -
  3. The stack space for the recursive calls can also be up to O(n) in the worst case, where ‘n’ is the number of elements in the candidates list.

  4. -
-

Therefore, the overall space complexity of the function is \(O(2^n + n)\). However, in practice, the space used for the results list is often the dominant factor, and the actual space used may be much smaller than 2^n because not all combinations are explored.

-

In summary, the time complexity is exponential but typically smaller in practice due to optimization, and the space complexity is influenced by the number of results and the depth of the recursion.

-
-
-

Challenging Exercises:#

-
    -
  1. Find the Number of Unique Combinations: Instead of listing all unique combinations, modify the function to return the count of unique combinations that sum to the target.

  2. -
  3. Combinations with a Maximum Value: Add a maximum value constraint for each combination, so they cannot exceed a certain value. Modify the code to find combinations respecting this constraint.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/10. Backtracking/79. Word Search.html b/docs/_build/html/10. Backtracking/79. Word Search.html deleted file mode 100644 index 47447c7..0000000 --- a/docs/_build/html/10. Backtracking/79. Word Search.html +++ /dev/null @@ -1,800 +0,0 @@ - - - - - - - - - - - - 79. Word Search — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- - - - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/10. Backtracking/README.html b/docs/_build/html/10. Backtracking/README.html deleted file mode 100644 index ae289fb..0000000 --- a/docs/_build/html/10. Backtracking/README.html +++ /dev/null @@ -1,620 +0,0 @@ - - - - - - - - - - - - Backtracking Problems - Blind 75 LeetCode — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Backtracking Problems - Blind 75 LeetCode

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

Backtracking Problems - Blind 75 LeetCode#

- - - - - - - - - - - - - - -

Problem Name

Difficulty

39. Combination Sum

Medium

79. Word Search

Medium

-
-

Contribute#

-

If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements.

-
-
-

Resources#

-
    -
  • LeetCode: The official LeetCode website.

  • -
  • LeetCode Discuss: LeetCode’s discussion forum for each problem. You can find helpful hints and discussions here.

  • -
-

Happy coding!

-
-
-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/11. Graphs/133. Clone Graph.html b/docs/_build/html/11. Graphs/133. Clone Graph.html deleted file mode 100644 index fa3d704..0000000 --- a/docs/_build/html/11. Graphs/133. Clone Graph.html +++ /dev/null @@ -1,811 +0,0 @@ - - - - - - - - - - - - 133. Clone Graph — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

133. Clone Graph#

-

Difficulty: Medium

-

Link to Problem: To see the Clone Graph problem on LeetCode, click here!

-
-

Given a reference of a node in a connected undirected graph.

-

Return a deep copy (clone) of the graph.

-

Each node in the graph contains a value (int) and a list (List[Node]) of its neighbors.

-
class Node {
-    public int val;
-    public List<Node> neighbors;
-}
-
-
-

Test case format:

-

For simplicity, each node’s value is the same as the node’s index (1-indexed). For example, the first node with val == 1, the second node with val == 2, and so on. The graph is represented in the test case using an adjacency list.

-

An adjacency list is a collection of unordered lists used to represent a finite graph. Each list describes the set of neighbors of a node in the graph.

-

The given node will always be the first node with val = 1. You must return the copy of the given node as a reference to the cloned graph.

-

Constraints:

-
    -
  • The number of nodes in the graph is in the range [0, 100].

  • -
  • 1 <= Node.val <= 100

  • -
  • Node.val is unique for each node.

  • -
  • There are no repeated edges and no self-loops in the graph.

  • -
  • The Graph is connected and all nodes can be visited starting from the given node.

  • -
-
-

Probelm Explanation:#

-

The problem at hand is to clone a connected undirected graph, which means we need to create a deep copy of the original graph while preserving its structure and relationships between nodes. The graph is represented using adjacency lists, where each node has a value (an integer) and a list of its neighbors.

-

Here are the key aspects of the problem:

-
    -
  1. Input: You are given a reference to one of the nodes in the original graph. This reference node serves as the entry point to the graph. The entire graph can be explored starting from this node.

  2. -
  3. Output: The goal is to create a deep copy of the graph and return a reference to the cloned graph. The cloned graph should have the same structure and relationships as the original one but should be a separate instance in memory.

  4. -
  5. Graph Structure: The graph is composed of nodes (vertices) and edges. Nodes have values (integers) and are connected to other nodes through edges (undirected connections). Each node has a list of neighbors, which are other nodes it is connected to.

  6. -
  7. Connected Graph: The problem assumes that the graph is connected, meaning that you can start from the reference node provided and traverse the entire graph by following the edges. This ensures that there are no isolated components in the graph.

  8. -
-

To solve this problem, you typically need to perform a graph traversal (e.g., depth-first search or breadth-first search) to visit all the nodes in the original graph, create corresponding nodes in the clone, and establish the same connections between nodes in the cloned graph as in the original one. To avoid duplication of nodes, you also need to keep track of visited nodes to ensure that the cloning process is efficient and that nodes are not duplicated in the clone.

-

The problem can be challenging because you need to create a deep copy of the graph while handling cyclic dependencies between nodes and ensuring that the structure and relationships of the original graph are preserved in the clone. The solution requires recursion or a data structure to maintain the mapping between original nodes and their clones to achieve an efficient and accurate cloning process.

-
-
-

Solution:#

-

Here’s a Python function to implement this algorithm:

-
-
-
# Definition for a Node.
-class Node:
-    def __init__(self, val=0, neighbors=None):
-        self.val = val
-        self.neighbors = neighbors if neighbors is not None else []
-
-class Solution:
-    def cloneGraph(self, node: 'Node') -> 'Node':
-        if not node:
-            return None
-
-        visited = {}  # Dictionary to keep track of visited nodes
-
-        def dfs(original_node):
-            if original_node in visited:
-                return visited[original_node]
-
-            # Create a copy of the original node
-            copy_node = Node(original_node.val)
-            visited[original_node] = copy_node
-
-            # Recursively clone the neighbors of the original node
-            for neighbor in original_node.neighbors:
-                copy_node.neighbors.append(dfs(neighbor))
-
-            return copy_node
-
-        return dfs(node)
-
-
-
-
-
-
-

Explanation:#

-

The given code defines a Python class, Node, and a solution class, Solution, to clone a connected undirected graph represented by nodes and their neighbors. Here’s an explanation of the code:

-
    -
  1. The Node class defines a node in the graph. Each node has a value (val) which is an integer and a list of neighbors (neighbors) that are other nodes in the graph.

  2. -
  3. The Solution class contains the method cloneGraph, which takes a reference to the first node of the graph (node) as input and returns a deep copy of the entire graph, preserving the structure and relationships between nodes.

  4. -
  5. Inside the cloneGraph method:

    -
      -
    • It first checks if the input node is None. If it’s None, it means there is no graph to clone, and the method returns None.

    • -
    • It initializes a visited dictionary to keep track of visited nodes. This dictionary is used to ensure that each node is cloned only once to avoid duplication.

    • -
    • The dfs (depth-first search) function is defined within the cloneGraph method. It takes an original node as input and returns its corresponding clone. This function performs the actual cloning of the graph.

    • -
    • Inside the dfs function:

      -
        -
      • It checks if the original node has been visited before by looking it up in the visited dictionary. If it has been visited, it returns the corresponding clone from the visited dictionary.

      • -
      • If the original node is not visited, it creates a new node, copy_node, with the same value as the original node. This is the first step in creating the clone of the original node.

      • -
      • It then recursively clones the neighbors of the original node by iterating through the neighbors list of the original node and appending the corresponding cloned neighbors to the neighbors list of the copy_node. This step ensures that the relationships between nodes are preserved in the clone.

      • -
      • The copy_node is added to the visited dictionary with the original node as the key and the clone as the value.

      • -
      • Finally, the copy_node is returned as the result of the DFS for the original node.

      • -
      -
    • -
    -
  6. -
  7. The cloneGraph method returns the result of the DFS on the input node, which is the clone of the entire graph with its structure and relationships intact.

  8. -
-

In summary, the code uses depth-first search (DFS) to traverse the original graph, creating a clone for each node and its neighbors. It ensures that each node is cloned only once to avoid duplication and returns a reference to the cloned graph.

-
-
-

Test cases:#

-

Here’s how you can use this solution:

-
-
-
def get_adjacency_list(node):
-    visited = {}  # Dictionary to keep track of visited nodes
-
-    def dfs(node):
-        if not node:
-            return []
-
-        if node in visited:
-            return visited[node]
-
-        neighbors = [n.val for n in node.neighbors]
-        visited[node] = neighbors
-
-        for neighbor in node.neighbors:
-            dfs(neighbor)
-
-    dfs(node)
-    result = []
-
-    def get_node_and_neighbors(node):
-        result.append([node.val] + visited[node])
-
-    get_node_and_neighbors(node)
-    return result
-
-
-# Testing the code with the provided examples
-adjList1 = [[2, 4], [1, 3], [2, 4], [1, 3]]
-solution = Solution()
-
-# Create the graph from adjList
-nodes = [Node(i) for i in range(1, len(adjList1) + 1)]
-for i, adj in enumerate(adjList1):
-    nodes[i].neighbors = [nodes[j - 1] for j in adj]
-
-# Clone the graph and get its adjacency list
-cloned_node1 = solution.cloneGraph(nodes[0])
-cloned_adjList1 = get_adjacency_list(cloned_node1)
-
-# Print the cloned graph as an adjacency list
-print(cloned_adjList1)
-
-# Output should match adjList1
-
-
-
-
-
[[1, 2, 4]]
-
-
-
-
-
-
-
# Example 2
-# Input: adjList = [[]]
-
-adjList2 = [[]]
-solution = Solution()
-
-# Create the graph from adjList
-node1 = Node(1)
-
-# Clone the graph and get its adjacency list
-cloned_node1 = solution.cloneGraph(node1)
-cloned_adjList2 = get_adjacency_list(cloned_node1)
-
-# Print the cloned graph as an adjacency list
-print(cloned_adjList2)
-
-# Output should be [[]], which represents an empty graph
-
-
-
-
-
[[1]]
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the provided code for cloning a graph using depth-first search (DFS).

-

Time Complexity:

-
    -
  1. Creating the graph: The time complexity to create the original graph from adjList is O(V + E), where V is the number of vertices (nodes) and E is the number of edges. We iterate through each node and its neighbors in adjList.

  2. -
  3. Cloning the graph (DFS): The depth-first search (DFS) is used to traverse the original graph and create a clone. The time complexity of DFS is O(V + E), as we visit each node and each edge once.

  4. -
-

Overall, the time complexity is O(V + E) for both creating the original graph and cloning it.

-

Space Complexity:

-
    -
  1. Storage for the original graph: We need to store the original graph, which includes all nodes and their adjacency lists. In the worst case, this requires O(V + E) space, where V is the number of nodes, and E is the number of edges.

  2. -
  3. Storage for the visited dictionary: The visited dictionary stores mappings from original nodes to their corresponding clones. In the worst case, this requires O(V) space because each node is visited once.

  4. -
  5. Recursive stack for DFS: The space used for the recursive call stack during DFS can be up to O(V) in the worst case, where V is the number of nodes.

  6. -
-

Overall, the space complexity is O(V + E) for storing the original graph, and O(V) for auxiliary data structures, including the visited dictionary and the DFS call stack. Therefore, the overall space complexity is O(V + E).

-

In summary, the time and space complexities of the provided code for cloning a graph are both O(V + E), where V is the number of nodes, and E is the number of edges in the graph.

-
-
-

Challenging Exercises:#

-
    -
  1. Cyclic Graph: Design a graph with cycles (nodes connected in a cycle). Test if the code can correctly clone graphs with cycles and doesn’t fall into an infinite loop during traversal.

  2. -
  3. Partial Graph Cloning: Modify the code to clone only a subset of the graph starting from a given reference node, rather than the entire graph. Implement this as an extension to the problem.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/11. Graphs/178. Graph Valid Tree.html b/docs/_build/html/11. Graphs/178. Graph Valid Tree.html deleted file mode 100644 index b80a6d9..0000000 --- a/docs/_build/html/11. Graphs/178. Graph Valid Tree.html +++ /dev/null @@ -1,749 +0,0 @@ - - - - - - - - - - - - 178. Graph Valid Tree — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

178. Graph Valid Tree

- -
- -
-
- - - - -
- -
-

178. Graph Valid Tree#

-

Difficulty: Medium

-

Link to Problem: To see the Graph Valid Tree problem on LintCode, click here!

-
-

Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), write a function to check whether these edges make up a valid tree.

-

Constraints:

-
    -
  • You can assume that no duplicate edges will appear in edges. Since all edges are undirected, [0, 1] is the same as [1, 0] and thus will not appear together in edges.

  • -
-
-

Probelm Explanation:#

-

The problem is to determine whether a given set of undirected edges can form a valid tree. In this context, a “tree” is a specific type of graph with the following properties:

-
    -
  1. It is a connected graph, meaning there is a path between any pair of nodes in the graph.

  2. -
  3. It has no cycles, which means there are no closed loops or circuits in the graph.

  4. -
  5. It has exactly n - 1 edges, where n is the number of nodes in the tree.

  6. -
-

The problem is typically given with two pieces of information:

-
    -
  1. The number of nodes (n), which are usually labeled from 0 to n-1.

  2. -
  3. A list of undirected edges, where each edge is represented as a pair of nodes.

  4. -
-

The task is to write a function or algorithm to determine whether the provided set of edges can be arranged to form a valid tree based on the properties mentioned above.

-

To solve this problem, you need to check the following conditions:

-
    -
  1. There should be exactly n - 1 edges to ensure that the graph is connected and tree-like.

  2. -
  3. There should be no cycles in the graph. If there are any cycles, the set of edges cannot form a tree.

  4. -
  5. The graph should be connected, which means you can reach any node from any other node through a series of edges.

  6. -
-

The solution typically involves using graph traversal algorithms like Depth-First Search (DFS) or Breadth-First Search (BFS) to explore the graph and check these conditions. If all conditions are met, the given edges form a valid tree; otherwise, they do not.

-
-
-

Solution:#

-

Here’s a Python function to implement this algorithm:

-
-
-
def validTree(n, edges):
-    if len(edges) != n - 1:
-        return False  # A tree with n nodes must have n-1 edges.
-
-    # Create an adjacency list to represent the graph.
-    adj_list = {i: [] for i in range(n)}
-    for u, v in edges:
-        adj_list[u].append(v)
-        adj_list[v].append(u)
-
-    visited = set()
-
-    # Define a recursive DFS function.
-    def dfs(node, parent):
-        if node in visited:
-            return False  # If we encounter a visited node, there's a cycle.
-        visited.add(node)
-
-        for neighbor in adj_list[node]:
-            if neighbor != parent:
-                if not dfs(neighbor, node):
-                    return False
-
-        return True
-
-    # Start DFS from any node (e.g., node 0).
-    if not dfs(0, -1):
-        return False  # If there's a cycle, it's not a valid tree.
-
-    return len(visited) == n
-
-
-
-
-
-
-

Explanation:#

-

The validTree function checks if a given set of undirected edges forms a valid tree. A valid tree must satisfy these conditions:

-
    -
  1. It has exactly n - 1 edges, where n is the number of nodes.

  2. -
  3. There are no cycles in the graph.

  4. -
  5. The graph is connected, meaning all nodes are reachable from any starting node.

  6. -
-

The code accomplishes this as follows:

-
    -
  • It first checks if the number of edges is equal to n - 1. If not, it immediately returns False since a tree with n nodes must have n - 1 edges to be connected.

  • -
  • It then constructs an adjacency list (adj_list) to represent the graph efficiently. This data structure stores the neighbors of each node.

  • -
  • The code uses a visited set to keep track of nodes visited during depth-first search (DFS).

  • -
  • The dfs function is a recursive function that checks for cycles in the graph. It does this by visiting nodes and marking them as visited. If it encounters a node that has already been visited (indicating a cycle), it returns False.

  • -
  • The DFS function explores the neighbors of each node, avoiding revisiting the parent node to prevent cycles.

  • -
  • After the DFS is complete, the code checks if the number of visited nodes is equal to n, ensuring the graph is connected.

  • -
  • Finally, if all conditions are met, the code returns True, indicating that the given edges form a valid tree. Otherwise, it returns False.

  • -
-

The code provides examples to demonstrate how to use the validTree function to check whether a set of edges forms a valid tree or not.

-
-
-

Test cases:#

-

Here’s how you can use this solution:

-
-
-
# Example 1
-n1 = 5
-edges1 = [[0, 1], [0, 2], [0, 3], [1, 4]]
-print(validTree(n1, edges1))  # Output: true
-
-
-
-
-
True
-
-
-
-
-
-
-
# Example 2
-n2 = 5
-edges2 = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]]
-print(validTree(n2, edges2))  # Output: false
-
-
-
-
-
False
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexities of the validTree function:

-

Time Complexity:

-
    -
  1. Constructing the adjacency list (adj_list) takes O(E) time, where E is the number of edges in the input graph (|edges|).

  2. -
  3. The DFS function, when considering all nodes, has a time complexity of O(V + E), where V is the number of nodes in the graph. This is because, in the worst case, the DFS function visits each node and each edge once.

  4. -
  5. Checking if the number of visited nodes is equal to n takes O(1) time.

  6. -
-

Overall, the time complexity of the validTree function is O(E + V) in the worst case.

-

Space Complexity:

-
    -
  1. The adjacency list (adj_list) consumes additional space to store the graph structure, taking O(V + E) space. This is because it stores information about each node and its adjacent nodes.

  2. -
  3. The visited set keeps track of visited nodes, and its space complexity is O(V) in the worst case, as there can be at most V unique nodes in the set.

  4. -
  5. The depth of the function call stack during DFS can be at most V, which contributes O(V) space to the space complexity.

  6. -
-

Overall, the space complexity of the validTree function is O(V + E) due to the adjacency list and O(V) due to the visited set and DFS call stack.

-

In summary, the time complexity is O(E + V), and the space complexity is O(V + E). These complexities are based on the worst-case scenario, where all nodes and edges are considered. In practical cases, the actual complexities may be smaller, depending on the specific structure of the graph.

-
-
-

Challenging Exercises:#

-
    -
  1. Minimum Spanning Tree (MST): Implement an algorithm to find the minimum spanning tree of a connected graph using either Kruskal’s or Prim’s algorithm. Compare the MST to the original graph to determine if the original graph is a tree. This exercise reinforces the concept of tree properties.

  2. -
  3. Detecting Cycles: Modify the code to not only check if the input forms a tree but also to identify and print out any cycles present in the graph if it’s not a tree. This exercise enhances your ability to detect and visualize cycles in a graph.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/11. Graphs/200. Number of Islands.html b/docs/_build/html/11. Graphs/200. Number of Islands.html deleted file mode 100644 index 02fafc9..0000000 --- a/docs/_build/html/11. Graphs/200. Number of Islands.html +++ /dev/null @@ -1,744 +0,0 @@ - - - - - - - - - - - - 200. Number of Islands — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

200. Number of Islands

- -
- -
-
- - - - -
- -
-

200. Number of Islands#

-

Difficulty: Medium

-

Link to Problem: To see the Number of Islands problem on LeetCode, click here!

-
-

Given an m x n 2D binary grid grid which represents a map of '1's (land) and '0's (water), return the number of islands.

-

An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.

-

Constraints:

-
    -
  • m == grid.length

  • -
  • n == grid[i].length

  • -
  • 1 <= m, n <= 300

  • -
  • grid[i][j] is '0' or '1'.

  • -
-
-

Probelm Explanation:#

-

The problem is about counting the number of islands in a 2D binary grid. In this grid, ‘1’ represents land, and ‘0’ represents water. An island is defined as a group of ‘1’ cells that are adjacent to each other either horizontally or vertically. It’s important to note that diagonal connections do not count. Additionally, it’s assumed that all four edges of the grid are surrounded by water, meaning the grid is finite and doesn’t “wrap around.”

-

The objective is to determine how many distinct islands exist in the grid. To clarify, an island consists of connected ‘1’ cells, and these connections can only occur horizontally or vertically. If there are no ‘1’ cells in the grid, the number of islands would be zero.

-

The problem often involves using graph traversal techniques like Depth-First Search (DFS) or Breadth-First Search (BFS) to identify and count these islands. You start at one ‘1’ cell and explore its adjacent cells to determine the extent of the island. Once you’ve visited all the ‘1’ cells in an island, you move on to the next unvisited ‘1’ cell and repeat the process until you’ve counted all the islands in the grid.

-

In essence, the problem asks you to analyze the grid to find groups of connected ‘1’ cells and count them as individual islands. The goal is to return the total count of islands in the given grid.

-
-
-

Solution:#

-

Here’s a Python function to implement this algorithm:

-
-
-
from typing import List
-
-class Solution:
-    def numIslands(self, grid: List[List[str]]) -> int:
-        if not grid:
-            return 0
-
-        m, n = len(grid), len(grid[0])  # Get the dimensions of the grid
-        num_islands = 0  # Initialize the count of islands
-
-        def dfs(row, col):
-            if row < 0 or row >= m or col < 0 or col >= n or grid[row][col] == '0':
-                return
-
-            grid[row][col] = '0'  # Mark the current cell as visited by changing it to '0'
-            directions = [(1, 0), (-1, 0), (0, 1), (0, -1)]  # Define four possible directions to move
-
-            for dr, dc in directions:
-                # Explore adjacent cells
-                dfs(row + dr, col + dc)
-
-        for i in range(m):
-            for j in range(n):
-                if grid[i][j] == '1':
-                    num_islands += 1  # Increment the island count
-                    dfs(i, j)  # Start a DFS from the current '1' cell to explore the entire island
-
-        return num_islands
-
-
-
-
-
-
-

Explanation:#

-

The provided code defines a Python class called Solution with a method called numIslands. This class is designed to count the number of islands in a 2D binary grid.

-

The numIslands method takes a 2D grid as input, where ‘1’ represents land, and ‘0’ represents water. It uses a depth-first search (DFS) approach to identify and count islands. The key steps in the code include:

-
    -
  1. Checking if the input grid is empty, and if so, returning 0 (indicating there are no islands).

  2. -
  3. Determining the dimensions of the grid (number of rows and columns).

  4. -
  5. Initializing a variable num_islands to keep track of the count of islands.

  6. -
  7. Defining a nested function dfs to perform depth-first search. This function recursively explores adjacent land cells connected to the current cell and marks them as visited by changing ‘1’ to ‘0’.

  8. -
  9. In the dfs function, it checks for boundary conditions and whether the current cell is ‘0’. If these conditions are met, it returns without further exploration.

  10. -
  11. The dfs function explores neighboring cells in all four directions (up, down, left, right) using a loop.

  12. -
  13. The main loop iterates through each cell of the grid. When a ‘1’ cell is encountered, it increments the num_islands count and starts a DFS from that cell to explore the entire island.

  14. -
  15. Finally, the method returns the total count of islands found in the grid.

  16. -
-

This code encapsulates the solution in a class, allowing you to create an instance of the Solution class and call the numIslands method on it to count the number of islands in a given grid.

-
-
-

Test cases:#

-

Here’s how you can use this solution:

-
-
-
grid1 = [
-  ["1", "1", "1", "1", "0"],
-  ["1", "1", "0", "1", "0"],
-  ["1", "1", "0", "0", "0"],
-  ["0", "0", "0", "0", "0"]
-]
-
-solution = Solution()
-result1 = solution.numIslands(grid1)
-print("Example 1 Output:", result1)  # Expected output: 1
-
-
-
-
-
Example 1 Output: 1
-
-
-
-
-
-
-
grid2 = [
-  ["1", "1", "0", "0", "0"],
-  ["1", "1", "0", "0", "0"],
-  ["0", "0", "1", "0", "0"],
-  ["0", "0", "0", "1", "1"]
-]
-
-result2 = solution.numIslands(grid2)
-print("Example 2 Output:", result2)  # Expected output: 3
-
-
-
-
-
Example 2 Output: 3
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the provided code:

-

Time Complexity:

-
    -
  • The code uses a depth-first search (DFS) to explore the grid and count the number of islands.

  • -
  • In the worst case, it visits every cell in the grid exactly once.

  • -
  • The DFS function explores neighboring cells in four directions (up, down, left, right), so it has a time complexity of \(O(4^{max(m, n)})\), where m is the number of rows and n is the number of columns.

  • -
  • Therefore, the overall time complexity of the code is O(m * n), where m is the number of rows, and n is the number of columns.

  • -
-

Space Complexity:

-
    -
  • The space complexity is determined by the recursive calls and the depth of the DFS stack.

  • -
  • In the worst case, when the entire grid consists of ‘1’s, the depth of the DFS recursion can be as deep as max(m, n).

  • -
  • Therefore, the space complexity of the code is O(max(m, n)), representing the maximum depth of the DFS stack.

  • -
-

In practical terms, for reasonably sized grids, the time and space complexity is linear, and the code should perform well. However, it’s important to keep in mind that the worst-case time complexity is O(m * n), and the space complexity can be O(max(m, n)).

-
-
-

Challenging Exercises:#

-
    -
  1. Identify Largest Island: In addition to counting the number of islands, modify the code to identify the largest island in the grid and return its size.

  2. -
  3. Optimize for Space: Modify the solution to reduce its space complexity to O(1) without modifying the input grid. This is a more memory-efficient version of the problem.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/11. Graphs/207. Course Schedule.html b/docs/_build/html/11. Graphs/207. Course Schedule.html deleted file mode 100644 index e47cc04..0000000 --- a/docs/_build/html/11. Graphs/207. Course Schedule.html +++ /dev/null @@ -1,747 +0,0 @@ - - - - - - - - - - - - 207. Course Schedule — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

207. Course Schedule

- -
- -
-
- - - - -
- -
-

207. Course Schedule#

-

Difficulty: Medium

-

Link to Problem: To see the Course Schedule problem on LeetCode, click here!

-
-

There are a total of numCourses courses to take, labeled from 0 to numCourses - 1. You are given an array prerequisites where prerequisites[i] = [ai, bi] indicates that you must take course bi first if you want to take course ai.

-
    -
  • For example, the pair [0, 1], indicates that to take course 0 you have to first take course 1.

  • -
-

Return true if you can finish all courses. Otherwise, return false.

-

Constraints:

-
    -
  • 1 <= numCourses <= 2000

  • -
  • 0 <= prerequisites.length <= 5000

  • -
  • prerequisites[i].length == 2

  • -
  • 0 <= ai, bi < numCourses

  • -
  • All the pairs prerequisites[i] are unique.

  • -
-
-

Probelm Explanation:#

-

The problem is to determine whether it’s possible to complete a set of courses given a list of prerequisites. You are given the following:

-
    -
  • numCourses: The total number of courses to be taken, labeled from 0 to numCourses - 1.

  • -
  • prerequisites: A list of prerequisite courses, where each element prerequisites[i] is a pair [ai, bi], indicating that you must take course bi before you can take course ai.

  • -
-

The goal is to check whether it’s possible to complete all the courses while respecting the prerequisite requirements. In other words, you need to determine if there are any circular dependencies in the course prerequisites that would prevent you from taking all the courses.

-

For example:

-
    -
  • If numCourses is 2, and prerequisites is [[1, 0]], it means you have two courses, and you must finish course 0 before you can take course 1. In this case, it’s possible to complete all courses, so the function should return True.

  • -
  • If numCourses is 2, and prerequisites is [[1, 0], [0, 1]], it means you have two courses, but there’s a circular dependency where course 1 requires course 0 and course 0 requires course 1. In this case, it’s impossible to complete all courses, so the function should return False.

  • -
-

The problem is essentially about checking for the presence of cycles in a directed graph, where the courses are nodes, and the prerequisites represent directed edges between them. If there are no cycles, it’s possible to complete all courses; otherwise, it’s not possible.

-
-
-

Solution:#

-

Here’s a Python function to implement this algorithm:

-
-
-
from collections import defaultdict, deque
-from typing import List
-
-class Solution:
-    def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
-        # Create a graph using an adjacency list to represent the courses and their prerequisites.
-        graph = defaultdict(list)  # Initialize an empty adjacency list.
-        in_degree = [0] * numCourses  # Initialize an array to store in-degrees of courses.
-
-        # Populate the graph and calculate in-degrees.
-        for course, prerequisite in prerequisites:
-            graph[prerequisite].append(course)  # Add the course as a neighbor to its prerequisite.
-            in_degree[course] += 1  # Increment the in-degree of the course.
-
-        # Initialize a queue with courses that have no prerequisites.
-        queue = deque()
-        for course in range(numCourses):
-            if in_degree[course] == 0:
-                queue.append(course)
-
-        # Perform topological sorting.
-        while queue:
-            course = queue.popleft()  # Take a course with no prerequisites.
-            numCourses -= 1  # Decrement the count of remaining courses.
-
-            for neighbor in graph[course]:
-                in_degree[neighbor] -= 1  # Remove the prerequisite relationship.
-                if in_degree[neighbor] == 0:
-                    queue.append(neighbor)  # If no more prerequisites, add to the queue.
-
-        # If all courses were successfully taken (numCourses becomes 0), return True.
-        return numCourses == 0
-
-
-
-
-
-
-

Explanation:#

-

This Python code is designed to determine whether it is possible to complete all the required courses given a set of prerequisites. It uses a topological sorting algorithm to accomplish this. Here’s a brief explanation of the code:

-
    -
  1. The code defines a Solution class with a canFinish method that takes two parameters: numCourses (the total number of courses) and prerequisites (a list of pairs indicating which course must be taken before another).

  2. -
  3. It initializes an empty graph as an adjacency list using a defaultdict to represent the courses and their prerequisites. It also initializes a list called in_degree to keep track of the in-degrees of courses, which is used in the topological sorting process.

  4. -
  5. The code then populates the graph by iterating through the prerequisites list. For each pair (ai, bi), it adds course ai as a neighbor to its prerequisite course bi in the graph and increments the in-degree of course ai.

  6. -
  7. Next, it initializes a queue with courses that have no prerequisites. It does this by iterating through all the courses and adding those with an in-degree of 0 to the queue.

  8. -
  9. The code performs a topological sorting of the courses using a while loop. In each iteration of the loop, it dequeues a course from the front of the queue (a course with no prerequisites).

  10. -
  11. For each neighbor (course that depends on the dequeued course), it decrements the in-degree of the neighbor. If the neighbor’s in-degree becomes 0, it means all of its prerequisites have been taken, so the neighbor is added to the queue.

  12. -
  13. The loop continues until there are no more courses with no prerequisites to dequeue, and the in-degrees are updated accordingly.

  14. -
  15. After the loop, if all courses were successfully taken (i.e., numCourses becomes 0), it means that there were no circular dependencies, and it’s possible to finish all courses. In this case, the method returns True. Otherwise, if there are remaining courses (indicating a circular dependency), it returns False.

  16. -
-
-
-

Test cases:#

-

Here’s how you can use this solution:

-
-
-
# Example 1
-numCourses1 = 2
-prerequisites1 = [[1, 0]]
-sol = Solution()
-print(sol.canFinish(numCourses1, prerequisites1))  # Output: True
-
-
-
-
-
True
-
-
-
-
-
-
-
# Example 2
-numCourses2 = 2
-prerequisites2 = [[1, 0], [0, 1]]
-print(sol.canFinish(numCourses2, prerequisites2))  # Output: False
-
-
-
-
-
False
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the canFinish method:

-

Time Complexity:

-
    -
  1. Constructing the graph: In the first loop where we iterate through the prerequisites list, we populate the graph with prerequisites. This loop has a time complexity of O(E), where E is the number of prerequisites (edges).

  2. -
  3. Initializing in-degrees and finding courses with no prerequisites: In the worst case, we iterate through all numCourses courses to initialize in-degrees and find the courses with no prerequisites. This has a time complexity of O(V), where V is the number of courses (vertices).

  4. -
  5. Topological Sorting: In the while loop, we perform topological sorting, processing each course once and its outgoing edges. In the worst case, each course is processed once. This has a time complexity of O(V + E).

  6. -
-

The overall time complexity is O(V + E), where V is the number of courses, and E is the number of prerequisites.

-

Space Complexity:

-
    -
  1. Graph Representation: The space complexity for storing the graph as an adjacency list is O(E), where E is the number of prerequisites.

  2. -
  3. In-Degree Array: The space complexity for storing the in-degrees of courses is O(V), where V is the number of courses.

  4. -
  5. Queue: The space complexity for the queue is O(V), as it may contain all the courses.

  6. -
-

The overall space complexity is O(V + E), where V is the number of courses, and E is the number of prerequisites.

-

In most practical cases, the number of prerequisites (E) is much smaller than the number of courses (V), so the time and space complexity can often be considered as O(V).

-
-
-

Challenging Exercises:#

-
    -
  1. Optimizing Course Scheduling: Given a list of courses with their durations and prerequisites, find the most efficient way to schedule these courses to minimize the time it takes to complete all of them.

  2. -
  3. Detecting Cycles in Course Dependencies: Modify the original problem to not just determine if you can finish all courses but also to identify the specific courses that form a cycle in the prerequisite dependencies.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/11. Graphs/3651. Number of Connected Components in an Undirected Graph.html b/docs/_build/html/11. Graphs/3651. Number of Connected Components in an Undirected Graph.html deleted file mode 100644 index 09c6f64..0000000 --- a/docs/_build/html/11. Graphs/3651. Number of Connected Components in an Undirected Graph.html +++ /dev/null @@ -1,734 +0,0 @@ - - - - - - - - - - - - 3651. Number of Connected Components in an Undirected Graph — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

3651. Number of Connected Components in an Undirected Graph

- -
- -
-
- - - - -
- -
-

3651. Number of Connected Components in an Undirected Graph#

-

Difficulty: Medium

-

Link to Problem: To see the Number of Connected Components in an Undirected Graph problem on LintCode, click here!

-
-

In this problem, there is an undirected graph with n nodes. There is also an edges array. Where edges[i] = [a, b] means that there is an edge between node a and node b in the graph.

-

You need to return the number of connected components in that graph.

-
-

Probelm Explanation:#

-

The problem at hand is to determine the number of connected components in an undirected graph. Here’s a more detailed explanation of the problem:

-
    -
  • You are given an undirected graph, which consists of nodes and edges. The graph may have multiple distinct connected components.

  • -
  • A connected component is a group of nodes within the graph where each node can be reached from every other node in the same component. In other words, there is a path between any two nodes in the same connected component, but there are no paths connecting nodes from different components.

  • -
  • Your task is to write a function that takes as input the number of nodes n and a list of edges edges, where each edge is represented as a pair of nodes [a, b] indicating an edge between node a and node b.

  • -
  • The goal is to determine the number of distinct connected components in the graph.

  • -
  • You need to implement an algorithm that can identify these connected components and count how many there are in the given graph.

  • -
-
-
-

Solution:#

-

Here’s a Python function to implement this algorithm:

-
-
-
def countConnectedComponents(n, edges):
-    # Define a helper function for depth-first search (DFS).
-    def dfs(node):
-        if not visited[node]:  # If the node has not been visited yet:
-            visited[node] = True  # Mark it as visited.
-            for neighbor in graph[node]:  # Explore all neighbors of the current node.
-                dfs(neighbor)  # Recursively call DFS on the neighbor.
-
-    # Create an empty adjacency list to represent the graph.
-    graph = [[] for _ in range(n)]
-
-    # Initialize a boolean list to keep track of visited nodes.
-    visited = [False] * n
-
-    # Populate the adjacency list with edges from the input.
-    for a, b in edges:
-        graph[a].append(b)
-        graph[b].append(a)  # Since the graph is undirected, we add edges in both directions.
-
-    # Initialize a counter to keep track of the number of connected components.
-    count = 0
-
-    # Iterate through all nodes in the graph.
-    for i in range(n):
-        if not visited[i]:  # If the node has not been visited:
-            count += 1  # Increment the count since we've found a new connected component.
-            dfs(i)  # Start a depth-first search from the unvisited node to explore the component.
-
-    return count
-
-
-
-
-
-
-

Explanation:#

-

The provided Python code calculates the number of connected components in an undirected graph. Here’s a high-level explanation of how the code works:

-
    -
  1. The countConnectedComponents function takes two arguments: n (the number of nodes in the graph) and edges (a list of edge pairs representing connections between nodes).

  2. -
  3. Inside the function, there is a helper function called dfs (depth-first search), which is used to explore and mark nodes as visited.

  4. -
  5. An empty adjacency list called graph is created to represent the graph. The graph is a list of lists where each element represents a node, and the list associated with each node contains its neighboring nodes.

  6. -
  7. Another list called visited is created to keep track of visited nodes. Initially, all nodes are marked as not visited (False).

  8. -
  9. The code populates the graph by iterating through the edges list and adding each edge to the adjacency list. Since the graph is undirected, both directions of each edge are added.

  10. -
  11. A counter variable called count is initialized to keep track of the number of connected components.

  12. -
  13. The code iterates through all nodes from 0 to n-1. For each node, it checks whether it has been visited yet. If it hasn’t been visited, it means a new connected component is found. The counter count is incremented, and a depth-first search (DFS) is initiated from this unvisited node to explore the connected component.

  14. -
  15. The dfs function recursively visits all nodes in the connected component, marking them as visited. It does this by checking each neighbor of the current node and recursively calling dfs on unvisited neighbors.

  16. -
  17. After the loop through all nodes, the count variable contains the total number of connected components in the graph.

  18. -
  19. The function returns the value of count, which represents the number of connected components.

  20. -
  21. Two examples are provided at the end to demonstrate how to use the function with different inputs.

  22. -
-
-
-

Test cases:#

-

Here’s how you can use this solution:

-
-
-
# Example 1
-n1 = 3
-edges1 = [[0, 1], [0, 2]]
-print(countConnectedComponents(n1, edges1))  # Output: 1
-
-
-
-
-
1
-
-
-
-
-
-
-
# Example 2
-n2 = 6
-edges2 = [[0, 1], [1, 2], [2, 3], [4, 5]]
-print(countConnectedComponents(n2, edges2))  # Output: 2
-
-
-
-
-
2
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the code for counting the number of connected components in an undirected graph using depth-first search (DFS).

-

Time Complexity:

-
    -
  • The code iterates through all nodes in the graph (from 0 to n-1).

  • -
  • For each unvisited node, it initiates a depth-first search (DFS) from that node to explore the connected component.

  • -
  • In the worst case, every node may belong to a separate connected component, and you perform a DFS for each node.

  • -
  • The time complexity of the DFS for a single connected component is O(V + E), where V is the number of nodes in the component, and E is the number of edges.

  • -
  • In the worst case, you perform O(n) DFS calls, each with its own O(V + E) complexity.

  • -
-

So, the overall time complexity of the code is O(n * (V + E)). In the worst case, if the graph is connected (a single connected component), this simplifies to O(n * (n + m)), where m is the number of edges.

-

Space Complexity:

-
    -
  • The main data structures used are the graph (adjacency list), visited (boolean array), and the recursive call stack for DFS.

  • -
  • The graph has a space complexity of O(n + m), where n is the number of nodes, and m is the number of edges.

  • -
  • The visited boolean array also has a space complexity of O(n) to keep track of whether nodes have been visited.

  • -
  • The depth of the recursive call stack for DFS can go up to O(n) in the worst case, when all nodes are part of a single connected component.

  • -
-

So, the overall space complexity of the code is O(n + m) for data structures and O(n) for the call stack. In the worst case, this simplifies to O(n + m).

-

In summary, the time complexity is O(n * (V + E)), and the space complexity is O(n + m).

-
-
-

Challenging Exercises:#

-
    -
  1. Disconnected Components with Multiple Queries: You are given an undirected graph with n nodes and m edges. Initially, the graph is disconnected, and you need to process q queries. Each query consists of adding an edge to connect two nodes. After each query, you need to output the number of connected components in the updated graph.

  2. -
  3. Maximum Size of Connected Components: Given an undirected graph with n nodes and m edges, find the size of the largest connected component in the graph. Additionally, identify the nodes that belong to this largest component. You can assume there is at least one connected component in the graph.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/11. Graphs/417. Pacific Atlantic Water Flow.html b/docs/_build/html/11. Graphs/417. Pacific Atlantic Water Flow.html deleted file mode 100644 index ad7b711..0000000 --- a/docs/_build/html/11. Graphs/417. Pacific Atlantic Water Flow.html +++ /dev/null @@ -1,757 +0,0 @@ - - - - - - - - - - - - 417. Pacific Atlantic Water Flow — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

417. Pacific Atlantic Water Flow

- -
- -
-
- - - - -
- -
-

417. Pacific Atlantic Water Flow#

-

Difficulty: Medium

-

Link to Problem: To see the Pacific Atlantic Water Flow problem on LeetCode, click here!

-
-

There is an m x n rectangular island that borders both the Pacific Ocean and Atlantic Ocean. The Pacific Ocean touches the island’s left and top edges, and the Atlantic Ocean touches the island’s right and bottom edges.

-

The island is partitioned into a grid of square cells. You are given an m x n integer matrix heights where heights[r][c] represents the height above sea level of the cell at coordinate (r, c).

-

The island receives a lot of rain, and the rain water can flow to neighboring cells directly north, south, east, and west if the neighboring cell’s height is less than or equal to the current cell’s height. Water can flow from any cell adjacent to an ocean into the ocean.

-

Return a 2D list of grid coordinates result where \(result[i] = [r_i, c_i]\) denotes that rain water can flow from cell \((r_i, c_i)\) to both the Pacific and Atlantic oceans.

-

Constraints:

-
    -
  • m == heights.length

  • -
  • n == heights[r].length

  • -
  • 1 <= m, n <= 200

  • -
  • 0 <= heights[r][c] <= \(10^5\)

  • -
-
-

Probelm Explanation:#

-

The problem at hand involves a scenario with a rectangular island surrounded by both the Pacific Ocean and the Atlantic Ocean. The Pacific Ocean is in contact with the island’s left and top edges, while the Atlantic Ocean is in contact with the island’s right and bottom edges. The goal is to determine which cells on the island can allow rainwater to flow to both the Pacific and Atlantic Oceans.

-

Here are the key details and constraints of the problem:

-
    -
  1. The island is divided into a grid of square cells.

  2. -
  3. Each cell is represented by an integer value in a matrix heights. The value at heights[r][c] represents the height above sea level of the cell at coordinates (r, c) on the island.

  4. -
  5. Rainwater can flow from a cell to neighboring cells directly north, south, east, or west only if the neighboring cell’s height is less than or equal to the current cell’s height.

  6. -
  7. Water can flow from any cell adjacent to the ocean into the ocean. This means water can flow from cells on the edge of the island to the Pacific Ocean and the Atlantic Ocean.

  8. -
-

The task is to find and return a 2D list of grid coordinates where rainwater can flow from a cell to both the Pacific and Atlantic Oceans. In other words, you need to identify the cells that can send water to both the left and top edges (Pacific) and the right and bottom edges (Atlantic) of the island.

-

The problem is solved by performing a depth-first search (DFS) starting from the ocean edges and marking the cells that can flow to each ocean. Then, the algorithm identifies cells that are reachable from both oceans and returns their coordinates as the result.

-

The problem involves both traversal of the island and backtracking to find the solution, which makes it a classic graph traversal problem.

-
-
-

Solution:#

-

Here’s a Python function to implement this algorithm:

-
-
-
from typing import List
-
-class Solution:
-    def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]:
-        # Check if the input matrix is empty
-        if not heights:
-            return []
-        
-        m, n = len(heights), len(heights[0])
-        
-        # Initialize boolean matrices to keep track of cells reachable from each ocean
-        pacific_reachable = [[False] * n for _ in range(m)]
-        atlantic_reachable = [[False] * n for _ in range(m)]
-        
-        # Depth-First Search (DFS) function to mark cells that can be reached from an ocean
-        def dfs(x, y, reachable):
-            if reachable[x][y]:
-                return
-            reachable[x][y] = True
-            for dx, dy in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
-                new_x, new_y = x + dx, y + dy
-                if 0 <= new_x < m and 0 <= new_y < n and heights[new_x][new_y] >= heights[x][y]:
-                    dfs(new_x, new_y, reachable)
-        
-        # Start DFS from the Pacific Ocean (left and top edges)
-        for i in range(m):
-            dfs(i, 0, pacific_reachable)
-            dfs(i, n - 1, atlantic_reachable)
-        
-        for j in range(n):
-            dfs(0, j, pacific_reachable)
-            dfs(m - 1, j, atlantic_reachable)
-        
-        result = []
-        
-        # Find cells that can flow to both the Pacific and Atlantic oceans
-        for i in range(m):
-            for j in range(n):
-                if pacific_reachable[i][j] and atlantic_reachable[i][j]:
-                    result.append([i, j])
-        
-        return result
-
-
-
-
-
-
-

Explanation:#

-

The code defines a class called Solution with a method named pacificAtlantic. This method takes a 2D matrix heights, where each element represents the height above sea level of a cell on a rectangular island. The goal of the method is to find and return a list of grid coordinates (cells) from which rainwater can flow into both the Pacific and Atlantic Oceans.

-

The code uses a Depth-First Search (DFS) algorithm to traverse the island, starting from the ocean edges, and marks cells that are reachable from either the Pacific or Atlantic Ocean. It does this by creating two boolean matrices, pacific_reachable and atlantic_reachable, to keep track of cells that can be reached from each ocean.

-

The code iterates through the entire island, initiating DFS searches from the edges of the island. If a cell is reachable from an ocean (either Pacific or Atlantic), it is marked as reachable in the corresponding boolean matrix. The DFS function ensures that the traversal follows the rule that water can flow to a neighboring cell if the neighboring cell’s height is less than or equal to the current cell’s height.

-

After marking all reachable cells from both oceans, the code then looks for cells that are reachable from both the Pacific and Atlantic Oceans. If a cell satisfies this condition, it is added to the result list.

-

Finally, the code returns the result list, which contains the grid coordinates of cells from which rainwater can flow into both the Pacific and Atlantic Oceans.

-

The code provides a solution to the problem of finding cells on the island where water can reach both oceans, demonstrating a traversal algorithm that explores the connectivity of cells on the island.

-
-
-

Test cases:#

-

Here’s how you can use this solution:

-
-
-
# Example 1
-heights1 = [
-    [1,2,2,3,5],
-    [3,2,3,4,4],
-    [2,4,5,3,1],
-    [6,7,1,4,5],
-    [5,1,1,2,4]
-]
-
-solution = Solution()
-print(solution.pacificAtlantic(heights1)) # Expected Output: [[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]]
-
-
-
-
-
[[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]]
-
-
-
-
-
-
-
# Example 2
-heights2 = [[1]]
-print(solution.pacificAtlantic(heights2)) # Expected Output: [[0, 0]]
-
-
-
-
-
[[0, 0]]
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Time Complexity: -The time complexity of this solution is O(m * n), where ‘m’ is the number of rows in the input matrix and ‘n’ is the number of columns. Here’s a breakdown of the time complexity:

-
    -
  1. Creating the pacific_reachable and atlantic_reachable matrices with dimensions m x n takes O(m * n) time.

  2. -
  3. Initiating Depth-First Search (DFS) from the edges of the island takes O(m * n) time because it processes each cell once.

  4. -
  5. The DFS function visits each cell at most once, and its time complexity is O(1) for each cell. The number of cells visited by the DFS in the worst case is m * n.

  6. -
  7. The final step of identifying and appending cells to the result list takes O(m * n) time in the worst case.

  8. -
-

Overall, the time complexity is dominated by the DFS and is O(m * n).

-

Space Complexity: -The space complexity of this solution is also O(m * n). Here’s how the space is used:

-
    -
  1. Two boolean matrices, pacific_reachable and atlantic_reachable, are created with dimensions m x n. Each matrix takes O(m * n) space, resulting in O(2 * m * n) space usage.

  2. -
  3. The depth-first search (DFS) stack space during the recursive calls can go as deep as the diagonal of the grid, which is at most min(m, n). This additional space for the call stack is relatively small compared to the boolean matrices and can be considered O(min(m, n)).

  4. -
  5. The result list stores the grid coordinates, and its size is determined by the number of cells that can flow to both oceans. In the worst case, this list can contain all m * n cells, so it takes O(m * n) space.

  6. -
-

The overall space complexity is the sum of these components, which is O(m * n) + O(min(m, n)) + O(m * n). In big O notation, we can simplify this to O(m * n).

-
-
-

Challenging Exercises:#

-
    -
  1. Optimization Challenge: Modify the algorithm to find the maximum flow of water from any cell to both the Pacific and Atlantic Oceans. In other words, find the cell(s) that can send the most water to both oceans.

  2. -
  3. Efficiency Challenge: Optimize the time and space complexity of the algorithm while maintaining correctness. Aim to reduce both time and space complexity as much as possible.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/11. Graphs/README.html b/docs/_build/html/11. Graphs/README.html deleted file mode 100644 index fa61914..0000000 --- a/docs/_build/html/11. Graphs/README.html +++ /dev/null @@ -1,632 +0,0 @@ - - - - - - - - - - - - Graphs Problems - Blind 75 LeetCode — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Graphs Problems - Blind 75 LeetCode

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

Graphs Problems - Blind 75 LeetCode#

- - - - - - - - - - - - - - - - - - - - - - - - - - -

Problem Name

Difficulty

200. Number of Islands

Medium

133. Clone Graph

Medium

417. Pacific Atlantic Water Flow

Medium

207. Course Schedule

Medium

323. Number of Connected Components In An Undirected Graph

Medium

261. Graph Valid Tree

Medium

-
-

Contribute#

-

If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements.

-
-
-

Resources#

-
    -
  • LeetCode: The official LeetCode website.

  • -
  • LeetCode Discuss: LeetCode’s discussion forum for each problem. You can find helpful hints and discussions here.

  • -
-

Happy coding!

-
-
-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/12. Advanced Graphs/892. Alien Dictionary.html b/docs/_build/html/12. Advanced Graphs/892. Alien Dictionary.html deleted file mode 100644 index 4bcf731..0000000 --- a/docs/_build/html/12. Advanced Graphs/892. Alien Dictionary.html +++ /dev/null @@ -1,756 +0,0 @@ - - - - - - - - - - - - 892. Alien Dictionary — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

892. Alien Dictionary

- -
- -
-
- - - - -
- -
-

892. Alien Dictionary#

-

Difficulty: Hard

-

Link to Problem: To see the Alien Dictionary problem on LintCode, click here!

-
-

There is a new alien language which uses the latin alphabet. However, the order among letters are unknown to you. You receive a list of non-empty words from the dictionary, where words are sorted lexicographically by the rules of this new language. Derive the order of letters in this language.

-

Constraints:

-
    -
  • You may assume all letters are in lowercase.

  • -
  • The dictionary is invalid, if string a is prefix of string b and b is appear before a.

  • -
  • If the order is invalid, return an empty string.

  • -
  • There may be multiple valid order of letters, return the smallest in normal lexicographical order.

  • -
  • The letters in one string are of the same rank by default and are sorted in Human dictionary order.

  • -
-
-

Probelm Explanation:#

-

The problem at hand involves determining the order of letters in a new alien language that uses the Latin alphabet. However, the order of letters in this alien language is unknown. To solve this problem, we are given a list of non-empty words from the dictionary, where the words are sorted lexicographically based on the rules of the alien language. The goal is to derive the correct order of letters in this new language.

-

Here’s a more detailed explanation of the problem:

-
    -
  1. The alphabet: The new alien language uses the Latin alphabet, which consists of lowercase letters.

  2. -
  3. Dictionary: We are provided with a list of non-empty words. These words are sorted in lexicographical order based on the rules of the alien language. The order of letters in the words reflects the correct order in the new language.

  4. -
  5. Invalid order: The problem specifies that the dictionary is considered invalid if there exists a situation where one string ‘a’ is a prefix of another string ‘b,’ and ‘b’ appears before ‘a’ in the dictionary. This condition ensures that there are no inconsistencies in the order of letters.

  6. -
  7. Multiple valid orders: It’s possible that there are multiple valid orders of letters that satisfy the provided dictionary. However, we are instructed to return the smallest valid order in normal lexicographical order.

  8. -
-

To solve this problem, you need to analyze the given list of words and determine the correct order of letters in the alien language while adhering to the specified constraints. You should return the order as a string in lexicographical order if it’s valid, and an empty string if the order is invalid.

-

The key to solving this problem is to construct a directed graph of letter relationships based on the order information provided by the words in the dictionary. Then, perform a topological sort on this graph to derive the order of letters, ensuring that the order is consistent and valid according to the given constraints.

-
-
-

Solution:#

-

Here’s a Python function to implement this algorithm:

-
-
-
from collections import defaultdict, deque
-
-def alienOrder(words):
-    # Create an adjacency list to represent the graph
-    graph = defaultdict(list)
-    
-    # Create a dictionary to store the in-degrees of each letter
-    in_degree = {}
-    
-    # Initialize in-degrees to 0 for all letters
-    for word in words:
-        for char in word:
-            if char not in in_degree:
-                in_degree[char] = 0
-    
-    # Build the graph and update in-degrees
-    for i in range(1, len(words)):
-        word1, word2 = words[i-1], words[i]
-        min_length = min(len(word1), len(word2))
-        
-        # Compare characters in the two words
-        j = 0
-        while j < min_length and word1[j] == word2[j]:
-            j += 1
-        
-        if j < min_length:
-            # If word1[j] is lexicographically before word2[j], add an edge
-            graph[word1[j]].append(word2[j])
-            in_degree[word2[j]] += 1
-            
-            # Break the loop to avoid further comparisons
-            break
-    
-    # Perform topological sorting using Kahn's algorithm
-    result = []
-    queue = deque([char for char in in_degree if in_degree[char] == 0])
-    
-    while queue:
-        char = queue.popleft()
-        result.append(char)
-        
-        for neighbor in graph[char]:
-            in_degree[neighbor] -= 1
-            if in_degree[neighbor] == 0:
-                queue.append(neighbor)
-    
-    # Check if there is a valid order
-    if len(result) < len(in_degree):
-        return ""
-    
-    return "".join(result)
-
-
-
-
-
-
-

Explanation:#

-

The code is designed to determine the order of letters in an unknown alien language that uses the Latin alphabet. It takes a list of non-empty words from a dictionary as input, where the words are sorted lexicographically based on the rules of this alien language.

-

The code follows these main steps:

-
    -
  1. Create a data structure to represent the graph of letters and their relationships in the alien language. It uses a defaultdict to store a list of letters that come after each letter. Additionally, it uses a dictionary called in_degree to keep track of the in-degrees (the number of letters that precede a letter) for each letter.

  2. -
  3. Initialize the in-degrees of all letters to 0. This is done by iterating through all the words and characters in the words, adding each character to the in_degree dictionary with an initial in-degree of 0.

  4. -
  5. Build the graph by comparing adjacent words in the dictionary. For each pair of adjacent words, the code finds the first differing character between the two words. If such a character exists, it means there’s an order relationship between the letters represented by these characters. The code updates the graph and in-degrees accordingly.

  6. -
  7. After constructing the graph, the code performs a topological sorting of the letters using Kahn’s algorithm. It starts by initializing an empty result list and a queue containing letters with in-degrees of 0. The algorithm repeatedly removes a letter with an in-degree of 0 from the queue, adds it to the result list, and updates the in-degrees of its neighbors. This process continues until the queue is empty.

  8. -
  9. Finally, the code checks if the topological sorting was successful by comparing the length of the result list with the number of unique letters in the input. If the lengths differ, it means there’s a cycle in the graph, and the order is invalid. In such a case, an empty string is returned. Otherwise, the result list is joined together to form the smallest order of letters in normal lexicographical order, and it is returned as the output.

  10. -
-

The code provides a way to determine the order of letters in the alien language while handling various edge cases, including checking for invalid order conditions.

-
-
-

Test cases:#

-

Here’s how you can use this solution:

-
-
-
# Example 1
-words1 = ["wrt", "wrf", "er", "ett", "rftt"]
-print(alienOrder(words1))  # Output: "wertf"
-
-
-
-
-
wrtef
-
-
-
-
-
-
-
# Example 2
-words2 = ["z", "x"]
-print(alienOrder(words2))  # Output: "zx"
-
-
-
-
-
zx
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the provided code for determining the order of letters in an alien language.

-

Time Complexity:

-
    -
  1. Building the graph: The code iterates through the list of words and compares adjacent words. In the worst case, where all words have the same prefix, it takes O(N) time to build the graph, where N is the total number of characters in all the words.

  2. -
  3. Topological sorting: Performing a topological sort on the graph takes O(V + E) time, where V is the number of unique letters (vertices) and E is the number of relationships between letters (edges) in the graph.

  4. -
-

Overall, the time complexity is O(N + V + E), where N is the total number of characters in the words, V is the number of unique letters, and E is the number of order relationships between letters.

-

Space Complexity:

-
    -
  1. Graph and In-degrees: The code uses data structures to represent the graph and in-degrees. The space complexity for these data structures is O(V + E), where V is the number of unique letters, and E is the number of order relationships between letters in the words.

  2. -
  3. Result List: The result list stores the order of letters, which can have a maximum size of V, where V is the number of unique letters.

  4. -
  5. Queue: The space used by the queue during topological sorting is also O(V).

  6. -
-

Overall, the space complexity is O(V + E) due to the data structures used for graph representation and the space needed for storing the result and the queue.

-

In the worst case, where there are many unique letters and many order relationships, the space complexity is dominated by the number of unique letters and their relationships.

-

In summary, the time complexity of the code is O(N + V + E), and the space complexity is O(V + E). The actual performance will depend on the specific input data, such as the number of unique letters and the relationships between them in the alien language.

-
-
-

Challenging Exercises:#

-
    -
  1. Multiple Valid Orders: Extend the problem to handle cases where there are multiple valid orders of letters in the alien language. Modify the code to return all valid orders instead of just one. Be mindful of performance.

  2. -
  3. Detect Invalid Dictionary: Given a dictionary of words, write a function to detect whether the dictionary is valid or not based on the constraints mentioned in the problem statement.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/12. Advanced Graphs/README.html b/docs/_build/html/12. Advanced Graphs/README.html deleted file mode 100644 index 5fd3bca..0000000 --- a/docs/_build/html/12. Advanced Graphs/README.html +++ /dev/null @@ -1,617 +0,0 @@ - - - - - - - - - - - - Advanced Graphs Problems - Blind 75 LeetCode — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Advanced Graphs Problems - Blind 75 LeetCode

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

Advanced Graphs Problems - Blind 75 LeetCode#

- - - - - - - - - - - -

Problem Name

Difficulty

269. Alien Dictionary

Hard

-
-

Contribute#

-

If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements.

-
-
-

Resources#

-
    -
  • LeetCode: The official LeetCode website.

  • -
  • LeetCode Discuss: LeetCode’s discussion forum for each problem. You can find helpful hints and discussions here.

  • -
-

Happy coding!

-
-
-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/13. One-D Dynamic Programming/198. House Robber.html b/docs/_build/html/13. One-D Dynamic Programming/198. House Robber.html deleted file mode 100644 index ae9b6ca..0000000 --- a/docs/_build/html/13. One-D Dynamic Programming/198. House Robber.html +++ /dev/null @@ -1,732 +0,0 @@ - - - - - - - - - - - - House Robber — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

House Robber#

-

Difficulty: Medium

-
-

You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security systems connected and it will automatically contact the police if two adjacent houses were broken into on the same night.

-

Given an integer array nums representing the amount of money of each house, return the maximum amount of money you can rob tonight without alerting the police.

-

Constraints:

-
    -
  • 1 <= nums.length <= 100

  • -
  • 0 <= nums[i] <= 400

  • -
-
-

Probelm Explanation:#

-

The problem is a classic dynamic programming challenge known as the “House Robber” problem. The scenario is that you are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, but the constraint is that adjacent houses have security systems connected. If two adjacent houses are broken into on the same night, the security systems will automatically contact the police.

-

The goal is to determine the maximum amount of money you can rob tonight without alerting the police. You need to find a strategy to maximize your earnings while avoiding robbing two adjacent houses.

-

The input to the problem is an array nums, where nums[i] represents the amount of money in the i-th house. The task is to return the maximum amount of money that can be robbed without triggering the security system.

-

For example:

-
Input: nums = [1,2,3,1]
-Output: 4
-Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).
-Total amount you can rob = 1 + 3 = 4.
-
-Input: nums = [2,7,9,3,1]
-Output: 12
-Explanation: Rob house 1 (money = 2), rob house 3 (money = 9), and rob house 5 (money = 1).
-Total amount you can rob = 2 + 9 + 1 = 12.
-
-
-

The challenge involves designing an algorithm to efficiently solve this problem and find the optimal strategy for robbing houses to maximize the stolen money while adhering to the constraint of not robbing adjacent houses. The provided solution utilizes dynamic programming to achieve this.

-
-
-

Solution:#

-

Here’s a Python function to implement this algorithm:

-
-
-
from typing import List
-
-class Solution:
-    def rob(self, nums: List[int]) -> int:
-        # Initialize variables to keep track of the maximum amount of money robbed at the previous and current houses
-        prev, curr = 0, 0
-
-        # Iterate through the houses
-        for n in nums:
-            # Calculate the maximum amount of money that can be robbed at the current house
-            # It is the maximum of either robbing the current house and the money robbed at the house before the previous one (prev),
-            # or skipping the current house and taking the maximum amount from the previous house (curr)
-            temp = max(n + prev, curr)
-
-            # Update the variables for the next iteration
-            prev, curr = curr, temp
-
-        # The final result is the maximum amount of money that can be robbed at the last house
-        return curr
-
-
-
-
-
-
-

Explanation:#

-

The provided code is a Python implementation of the “House Robber” problem using a dynamic programming approach. It’s part of a class Solution and includes a method rob that takes a list of integers nums as input and returns the maximum amount of money that can be robbed without alerting the police.

-

The key idea of the algorithm is to maintain two variables, prev and curr, which represent the maximum amount of money that can be robbed up to the previous house and the current house, respectively. The algorithm iterates through the houses, updating these variables based on the maximum amount that can be robbed at the current house, considering the constraint of not robbing adjacent houses.

-

The loop calculates a temporary variable temp that represents the maximum amount of money that can be robbed at the current house. It considers two scenarios: either robbing the current house and adding the money robbed at the house before the previous one (n + prev), or skipping the current house and taking the maximum amount from the previous house (curr). The maximum of these two scenarios is assigned to temp.

-

The prev and curr variables are then updated for the next iteration. prev is set to the previous value of curr, and curr is set to the calculated temp.

-

The final result is the value stored in the curr variable, representing the maximum amount of money that can be robbed at the last house. This value is returned as the result of the rob method.

-

The provided test cases at the end demonstrate the usage of the rob method with different input arrays.

-
-
-

Test cases:#

-

Here’s how you can use this solution:

-
-
-
# Example 1:
-sol = Solution()
-
-nums1 = [1, 2, 3, 1]
-print(sol.rob(nums1))  # Output: 4
-
-
-
-
-
4
-
-
-
-
-
-
-
# Example 2:
-nums2 = [2, 7, 9, 3, 1]
-print(sol.rob(nums2))  # Output: 12
-
-
-
-
-
12
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the provided code.

-
-

Time Complexity:#

-

The time complexity of the code is O(n), where n is the number of houses. The algorithm iterates through the array once, and in each iteration, it performs constant time operations. The loop runs for each house, and the number of operations inside the loop is independent of the input size. Therefore, the overall time complexity is linear, O(n).

-
-
-

Space Complexity:#

-

The space complexity is O(1), constant space. The algorithm uses only a constant amount of extra space regardless of the input size. The variables prev, curr, and temp are the only additional variables used, and they do not depend on the size of the input array. Thus, the space complexity is constant, O(1).

-

In summary:

-
    -
  • Time Complexity: O(n)

  • -
  • Space Complexity: O(1)

  • -
-
-
-
-

Challenging Exercises:#

-
    -
  1. Variation with Maximum Number of Houses to Rob: Modify the problem to include an additional constraint: you are allowed to rob at most ‘k’ houses without triggering the alarm. Find the maximum amount you can rob under this new constraint.

  2. -
  3. Robbing in a Circular Street: Extend the problem to a circular street where the first and last houses are adjacent. You cannot rob both the first and last houses simultaneously. Find the maximum amount you can rob in this circular setting.

  4. -
-

Link to Problem: To see the House Robber problem on LeetCode, click here!

-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/13. One-D Dynamic Programming/213. House Robber II.html b/docs/_build/html/13. One-D Dynamic Programming/213. House Robber II.html deleted file mode 100644 index f095313..0000000 --- a/docs/_build/html/13. One-D Dynamic Programming/213. House Robber II.html +++ /dev/null @@ -1,765 +0,0 @@ - - - - - - - - - - - - House Robber II — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

House Robber II#

-

Difficulty: Medium

-
-

You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. All houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, adjacent houses have a security system connected, and it will automatically contact the police if two adjacent houses were broken into on the same night.

-

Given an integer array nums representing the amount of money of each house, return the maximum amount of money you can rob tonight without alerting the police.

-

Constraints:

-
    -
  • 1 <= nums.length <= 100

  • -
  • 0 <= nums[i] <= 1000

  • -
-
-

Probelm Explanation:#

-

Certainly! The problem statement describes a scenario where you are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. However, there is a security system in place: adjacent houses have a security system connected, and it will automatically contact the police if two adjacent houses are broken into on the same night.

-

The twist in this problem is that the houses are arranged in a circle. That means the first house is the neighbor of the last one. So, robbing the first house has implications for the last house, and vice versa.

-

The goal is to find the maximum amount of money you can rob tonight without alerting the police. You need to implement a function that takes an integer array nums representing the amount of money in each house and returns the maximum amount of money that can be robbed without triggering the security system.

-

Here are a few examples to illustrate the problem:

-
    -
  1. Example 1:

    -
    Input: nums = [2, 3, 2]
    -Output: 3
    -Explanation: You cannot rob house 1 (money = 2) and then rob house 3 (money = 2) because they are adjacent houses. The optimal strategy is to rob house 2 (money = 3).
    -
    -
    -
  2. -
  3. Example 2:

    -
    Input: nums = [1, 2, 3, 1]
    -Output: 4
    -Explanation: Robbing house 1 (money = 1) and then robbing house 3 (money = 3) results in a total amount of 4. Robbing house 2 is skipped to avoid alerting the police.
    -
    -
    -
  4. -
  5. Example 3:

    -
    Input: nums = [1, 2, 3]
    -Output: 3
    -Explanation: Since the houses are in a circle, you can choose either house 1, 2, or 3. The optimal strategy is to rob house 3 for a total amount of 3.
    -
    -
    -
  6. -
-

The constraints for the problem are that the length of the nums array is between 1 and 100, and the amount of money in each house (nums[i]) is between 0 and 1000.

-
-
-

Solution:#

-

Here’s a Python function to implement this algorithm:

-
-
-
from typing import List
-
-class Solution:
-    def rob(self, nums: List[int]) -> int:
-        def simple_rob(nums):
-            # Helper function for basic house robbery problem
-            prev, curr = 0, 0
-            for num in nums:
-                # Calculate the maximum amount of money that can be robbed
-                # without alerting the police for each house
-                prev, curr = curr, max(prev + num, curr)
-            return curr
-
-        # Check the base cases where the length of nums is 1 or 2
-        if len(nums) == 1:
-            return nums[0]
-        elif len(nums) == 2:
-            return max(nums[0], nums[1])
-
-        # Case 1: First house is robbed, last house is not
-        case1 = simple_rob(nums[:-1])
-
-        # Case 2: First house is not robbed, last house is
-        case2 = simple_rob(nums[1:])
-
-        # Maximum of the two cases
-        return max(case1, case2)
-
-
-
-
-
-
-

Explanation:#

-

The provided code defines a class Solution with a method rob, which aims to determine the maximum amount of money a professional robber can steal from houses arranged in a circle without alerting the police. Each house contains a certain amount of money, and adjacent houses have a security system that triggers if both are robbed on the same night.

-

The code uses dynamic programming to solve the problem efficiently. It contains a helper function simple_rob that computes the maximum amount of money that can be robbed from a linear arrangement of houses. The main method rob handles the circular arrangement by considering two cases: robbing the first house and not robbing the last, and not robbing the first house and robbing the last. The result is the maximum of these two cases.

-

The class is instantiated as solution, and the rob method is applied to three different scenarios (test cases) to demonstrate its functionality. The final output represents the maximum amount of money the robber can steal without triggering the security system.

-
-
-

Test cases:#

-

Here’s how you can use this solution:

-
-
-
# Example 1:
-
-# Create an instance of the Solution class
-solution = Solution()
-
-nums1 = [2, 3, 2]
-print(solution.rob(nums1))  # Output: 3
-
-
-
-
-
3
-
-
-
-
-
-
-
# Example 2:
-nums2 = [1, 2, 3, 1]
-print(solution.rob(nums2))  # Output: 4
-
-
-
-
-
4
-
-
-
-
-
-
-
# Example 2:
-nums3 = [1, 2, 3]
-print(solution.rob(nums3))  # Output: 3
-
-
-
-
-
3
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Let’s analyze the time and space complexity of the provided code:

-
-

Time Complexity:#

-

The time complexity is primarily determined by the simple_rob helper function, which has a time complexity of O(N), where N is the number of houses in the input array. The main rob function calls simple_rob twice, once for the case of robbing the first house and not robbing the last, and once for the case of not robbing the first house and robbing the last. Therefore, the overall time complexity is O(N).

-
-
-

Space Complexity:#

-

The space complexity is O(1) because the space used by the algorithm is constant, regardless of the size of the input array. The only variables used are prev and curr in the simple_rob function, which represent the previous and current maximum amounts of money that can be robbed without alerting the police. These variables are updated iteratively, and no additional data structures are used that scale with the input size. Therefore, the space complexity is constant, or O(1).

-

In summary:

-
    -
  • Time Complexity: O(N)

  • -
  • Space Complexity: O(1)

  • -
-
-
-
-

Challenging Exercises:#

-
    -
  1. Optimization Challenge: Optimize the space complexity of the solution. Can you solve the problem with O(1) space complexity without sacrificing the time complexity?

  2. -
  3. Circular Robbery Variations: Consider variations of the circular house robbery problem, such as allowing the robber to skip a certain number of houses or restricting the number of consecutive houses that can be robbed. Modify the solution to accommodate these variations.

  4. -
-

Link to Problem: To see the House Robber II problem on LeetCode, click here!

-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/13. One-D Dynamic Programming/70. Climbing Stairs.html b/docs/_build/html/13. One-D Dynamic Programming/70. Climbing Stairs.html deleted file mode 100644 index c12bd86..0000000 --- a/docs/_build/html/13. One-D Dynamic Programming/70. Climbing Stairs.html +++ /dev/null @@ -1,717 +0,0 @@ - - - - - - - - - - - - 70. Climbing Stairs — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

70. Climbing Stairs#

-

Difficulty: Easy

-

Link to Problem: To see the Climbing Stairs problem on LeetCode, click here!

-
-

You are climbing a staircase. It takes n steps to reach the top.

-

Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

-

Constraints:

-
    -
  • 1 <= n <= 45

  • -
-
-

Probelm Explanation:#

-

The “Climbing Stairs” problem is a classic algorithmic problem that asks you to find the number of distinct ways to climb a staircase with a given number of steps. Here’s the problem statement:

-

You are given a staircase with ‘n’ steps. Each time you can either climb 1 step or 2 steps. You need to find out how many distinct ways there are to reach the top of the staircase.

-

For example, if ‘n’ is 2, there are two ways to climb to the top:

-
    -
  1. Climbing two steps at once.

  2. -
  3. Climbing one step, and then another step.

  4. -
-

If ‘n’ is 3, there are three ways:

-
    -
  1. Climbing one step, then one step, and finally one step.

  2. -
  3. Climbing one step, then two steps.

  4. -
  5. Climbing two steps, then one step.

  6. -
-

The problem essentially asks you to find a solution that counts the possible combinations of 1-step and 2-step climbs that can be taken to reach the top of the staircase. It’s a classic example of a dynamic programming problem where you can break it down into smaller subproblems and build a solution incrementally, as shown in the code I provided earlier.

-
-
-

Solution:#

-

Here’s a Python function to implement this algorithm:

-
-
-
class Solution:
-    def climbStairs(self, n: int) -> int:
-        # If there are 1 or 2 steps, there are exactly n ways to reach the top.
-        if n <= 2:
-            return n
-
-        # Create an array to store the number of ways to reach each step.
-        dp = [0] * (n + 1)
-
-        # There is one way to reach the first step (base case).
-        dp[1] = 1
-
-        # There are two ways to reach the second step (base case).
-        dp[2] = 2
-
-        # Calculate the number of ways to reach each step from the previous steps.
-        for i in range(3, n + 1):
-            # The number of ways to reach step 'i' is the sum of the ways to reach
-            # the previous two steps, as you can take 1 or 2 steps at a time.
-            dp[i] = dp[i - 1] + dp[i - 2]
-
-        # The result is the number of ways to reach the top, which is stored in dp[n].
-        return dp[n]
-
-
-
-
-
-
-

Explanation:#

-

The code defines a class Solution with a method climbStairs that takes an integer n as input and returns the number of distinct ways to climb a staircase with n steps.

-
    -
  1. If n is 1 or 2, the function returns n directly because there are only 1 or 2 distinct ways to reach the top in those cases.

  2. -
  3. For n greater than 2, the code uses dynamic programming to calculate the number of ways to reach each step. It creates an array dp of length n + 1 to store these values.

  4. -
  5. The dp[1] and dp[2] are initialized to 1 and 2, respectively. This is because there is only one way to reach the first step (by taking 1 step), and there are two ways to reach the second step (by taking 2 steps or two 1-step climbs).

  6. -
  7. The code then uses a loop to fill in the dp array for steps 3 and above. For each step i from 3 to n, it calculates the number of ways to reach that step by adding the number of ways to reach the previous two steps, as you can either take 1 step or 2 steps at a time.

  8. -
  9. Finally, the function returns the value stored in dp[n], which represents the total number of distinct ways to climb the staircase with n steps.

  10. -
-
-
-

Test cases:#

-

Here’s how you can use this solution:

-
-
-
# Example 1:
-n = 2
-solution = Solution()
-print(f"Example 1 - Input: n = {n}, Output: {solution.climbStairs(n)}")  # Output should be 2
-
-
-
-
-
Example 1 - Input: n = 2, Output: 2
-
-
-
-
-
-
-
# Example 2:
-n = 3
-print(f"Example 2 - Input: n = {n}, Output: {solution.climbStairs(n)}")  # Output should be 3
-
-
-
-
-
Example 2 - Input: n = 3, Output: 3
-
-
-
-
-
-
-

Time and Space Complexity Analysis#

-

Time Complexity: -The time complexity of the solution is O(n) because we use a single for loop that iterates from 3 to n to fill the dp array. In each iteration, we perform constant time operations (addition and assignment). Therefore, the time complexity is linear with respect to the input value n.

-

Space Complexity: -The space complexity of the solution is O(n) as well. We use an array dp of length n + 1 to store the number of ways to reach each step. The size of this array is directly proportional to the input value n, which makes the space complexity linear in terms of n. The rest of the variables used in the function (e.g., i) occupy constant space and do not contribute significantly to the overall space complexity.

-

In summary, the time complexity is O(n), and the space complexity is O(n) for this dynamic programming solution to the “Climbing Stairs” problem.

-
-
-

Challenging Exercises:#

-
    -
  1. Generalized Step Sizes: Instead of being limited to 1 step or 2 steps, consider a scenario where you can take steps of sizes [1, 2, 3]. Implement a function that calculates the number of ways to climb the staircase with these different step sizes.

  2. -
  3. Minimize Steps: Given an integer n, find the minimum number of steps required to reach the top of the staircase. Return both the minimum number of steps and the specific sequence of steps taken.

  4. -
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/13. One-D Dynamic Programming/README.html b/docs/_build/html/13. One-D Dynamic Programming/README.html deleted file mode 100644 index 88ff6a7..0000000 --- a/docs/_build/html/13. One-D Dynamic Programming/README.html +++ /dev/null @@ -1,644 +0,0 @@ - - - - - - - - - - - - 1-D Dynamic Programming Problems - Blind 75 LeetCode — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

1-D Dynamic Programming Problems - Blind 75 LeetCode

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

1-D Dynamic Programming Problems - Blind 75 LeetCode#

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Problem Name

Difficulty

70. Climbing Stairs

Easy

198. House Robber

Medium

213. House Robber II

Medium

5. Longest Palindromic Substring

Medium

647. Palindromic Substrings

Medium

91. Decode Ways

Medium

322. Coin Change

Medium

152. Maximum Product Subarray

Medium

139. Word Break

Medium

300. Longest Increasing Subsequence

Medium

-
-

Contribute#

-

If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements.

-
-
-

Resources#

-
    -
  • LeetCode: The official LeetCode website.

  • -
  • LeetCode Discuss: LeetCode’s discussion forum for each problem. You can find helpful hints and discussions here.

  • -
-

Happy coding!

-
-
-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/14. Two-D Dynamic Programming/README.html b/docs/_build/html/14. Two-D Dynamic Programming/README.html deleted file mode 100644 index 72a7ecf..0000000 --- a/docs/_build/html/14. Two-D Dynamic Programming/README.html +++ /dev/null @@ -1,661 +0,0 @@ - - - - - - - - - - - - Blind 75 LeetCode Problems — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Blind 75 LeetCode Problems

- -
- -
-
- - - - -
- -
-

Blind 75 LeetCode Problems#

-

This repository contains a curated list of 75 LeetCode problems that are commonly known as the “Blind 75.” These problems cover a wide range of data structures and algorithms and are frequently asked in technical interviews. Solving these problems can help you build a strong foundation in algorithmic problem-solving.

-
-

Problem List#

-
-

2-D Dynamic Programming#

- - - - - - - - - - - - - - -

Problem Name

Difficulty

62. Unique Paths

Medium

1143. Longest Common Subsequence

Medium

-
-
-
-

How to Use#

-
    -
  1. Clone or download this repository to your local machine.

  2. -
-
git clone https://github.com/mohsentabibian/LeetCode-Solutions/Blind-75-LeetCode.git
-
-
-
    -
  1. Navigate to the directory of the specific problem you want to solve.

  2. -
-
cd Blind-75-LeetCode/Problem-Directory
-
-
-
    -
  1. Open the problem’s directory to find its description, code template, and solution(s).

  2. -
  3. Solve the problem using your preferred programming language.

  4. -
  5. Check the solution(s) provided in the directory for reference and to compare your solution.

  6. -
-
-
-

Contribute#

-

If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements.

-
-
-

Resources#

-
    -
  • LeetCode: The official LeetCode website.

  • -
  • LeetCode Discuss: LeetCode’s discussion forum for each problem. You can find helpful hints and discussions here.

  • -
-
-
-

Disclaimer#

-

This repository is meant for educational purposes and to help individuals prepare for technical interviews. Please respect LeetCode’s terms of use and guidelines when using this repository.

-

Happy coding!

-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/15. Greedy/README.html b/docs/_build/html/15. Greedy/README.html deleted file mode 100644 index 1f683de..0000000 --- a/docs/_build/html/15. Greedy/README.html +++ /dev/null @@ -1,661 +0,0 @@ - - - - - - - - - - - - Blind 75 LeetCode Problems — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Blind 75 LeetCode Problems

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

Blind 75 LeetCode Problems#

-

This repository contains a curated list of 75 LeetCode problems that are commonly known as the “Blind 75.” These problems cover a wide range of data structures and algorithms and are frequently asked in technical interviews. Solving these problems can help you build a strong foundation in algorithmic problem-solving.

-
-

Problem List#

-
-

Greedy#

- - - - - - - - - - - - - - -

Problem Name

Difficulty

53. Maximum Subarray

Easy

55. Jump Game

Medium

-
-
-
-

How to Use#

-
    -
  1. Clone or download this repository to your local machine.

  2. -
-
git clone https://github.com/mohsentabibian/LeetCode-Solutions/Blind-75-LeetCode.git
-
-
-
    -
  1. Navigate to the directory of the specific problem you want to solve.

  2. -
-
cd Blind-75-LeetCode/Problem-Directory
-
-
-
    -
  1. Open the problem’s directory to find its description, code template, and solution(s).

  2. -
  3. Solve the problem using your preferred programming language.

  4. -
  5. Check the solution(s) provided in the directory for reference and to compare your solution.

  6. -
-
-
-

Contribute#

-

If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements.

-
-
-

Resources#

-
    -
  • LeetCode: The official LeetCode website.

  • -
  • LeetCode Discuss: LeetCode’s discussion forum for each problem. You can find helpful hints and discussions here.

  • -
-
-
-

Disclaimer#

-

This repository is meant for educational purposes and to help individuals prepare for technical interviews. Please respect LeetCode’s terms of use and guidelines when using this repository.

-

Happy coding!

-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/16. Intervals/README.html b/docs/_build/html/16. Intervals/README.html deleted file mode 100644 index b1c7318..0000000 --- a/docs/_build/html/16. Intervals/README.html +++ /dev/null @@ -1,670 +0,0 @@ - - - - - - - - - - - - Blind 75 LeetCode Problems — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Blind 75 LeetCode Problems

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

Blind 75 LeetCode Problems#

-

This repository contains a curated list of 75 LeetCode problems that are commonly known as the “Blind 75.” These problems cover a wide range of data structures and algorithms and are frequently asked in technical interviews. Solving these problems can help you build a strong foundation in algorithmic problem-solving.

-
-

Problem List#

-
-

Intervals#

- - - - - - - - - - - - - - - - - - - - - - - -

Problem Name

Difficulty

57. Insert Interval

Hard

56. Merge Intervals

Medium

435. Non Overlapping Intervals

Medium

252. Meeting Rooms

Easy

253. Meeting Rooms II

Medium

-
-
-
-

How to Use#

-
    -
  1. Clone or download this repository to your local machine.

  2. -
-
git clone https://github.com/mohsentabibian/LeetCode-Solutions/Blind-75-LeetCode.git
-
-
-
    -
  1. Navigate to the directory of the specific problem you want to solve.

  2. -
-
cd Blind-75-LeetCode/Problem-Directory
-
-
-
    -
  1. Open the problem’s directory to find its description, code template, and solution(s).

  2. -
  3. Solve the problem using your preferred programming language.

  4. -
  5. Check the solution(s) provided in the directory for reference and to compare your solution.

  6. -
-
-
-

Contribute#

-

If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements.

-
-
-

Resources#

-
    -
  • LeetCode: The official LeetCode website.

  • -
  • LeetCode Discuss: LeetCode’s discussion forum for each problem. You can find helpful hints and discussions here.

  • -
-
-
-

Disclaimer#

-

This repository is meant for educational purposes and to help individuals prepare for technical interviews. Please respect LeetCode’s terms of use and guidelines when using this repository.

-

Happy coding!

-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/17. Math Geometry/README.html b/docs/_build/html/17. Math Geometry/README.html deleted file mode 100644 index f840c85..0000000 --- a/docs/_build/html/17. Math Geometry/README.html +++ /dev/null @@ -1,664 +0,0 @@ - - - - - - - - - - - - Blind 75 LeetCode Problems — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Blind 75 LeetCode Problems

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

Blind 75 LeetCode Problems#

-

This repository contains a curated list of 75 LeetCode problems that are commonly known as the “Blind 75.” These problems cover a wide range of data structures and algorithms and are frequently asked in technical interviews. Solving these problems can help you build a strong foundation in algorithmic problem-solving.

-
-

Problem List#

-
-

Math & Geometry#

- - - - - - - - - - - - - - - - - -

Problem Name

Difficulty

48. Rotate Image

Medium

54. Spiral Matrix

Medium

73. Set Matrix Zeroes

Medium

-
-
-
-

How to Use#

-
    -
  1. Clone or download this repository to your local machine.

  2. -
-
git clone https://github.com/mohsentabibian/LeetCode-Solutions/Blind-75-LeetCode.git
-
-
-
    -
  1. Navigate to the directory of the specific problem you want to solve.

  2. -
-
cd Blind-75-LeetCode/Problem-Directory
-
-
-
    -
  1. Open the problem’s directory to find its description, code template, and solution(s).

  2. -
  3. Solve the problem using your preferred programming language.

  4. -
  5. Check the solution(s) provided in the directory for reference and to compare your solution.

  6. -
-
-
-

Contribute#

-

If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements.

-
-
-

Resources#

-
    -
  • LeetCode: The official LeetCode website.

  • -
  • LeetCode Discuss: LeetCode’s discussion forum for each problem. You can find helpful hints and discussions here.

  • -
-
-
-

Disclaimer#

-

This repository is meant for educational purposes and to help individuals prepare for technical interviews. Please respect LeetCode’s terms of use and guidelines when using this repository.

-

Happy coding!

-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/18. Bit Manipulation/README.html b/docs/_build/html/18. Bit Manipulation/README.html deleted file mode 100644 index 0729db3..0000000 --- a/docs/_build/html/18. Bit Manipulation/README.html +++ /dev/null @@ -1,660 +0,0 @@ - - - - - - - - - - - - Blind 75 LeetCode Problems — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Blind 75 LeetCode Problems

- -
- -
-
- - - - -
- -
-

Blind 75 LeetCode Problems#

-

This repository contains a curated list of 75 LeetCode problems that are commonly known as the “Blind 75.” These problems cover a wide range of data structures and algorithms and are frequently asked in technical interviews. Solving these problems can help you build a strong foundation in algorithmic problem-solving.

-
-

Problem List#

-
-

Bit Manupulation#

- - - - - - - - - - - - - - - - - - - - - - - -

Problem Name

Difficulty

191. Number of 1 Bits

Easy

338. Counting Bits

Medium

190. Reverse Bits

Easy

268. Missing Number

Easy

371. Sum of Two Integers

Medium

-
-
-
-

How to Use#

-
    -
  1. Clone or download this repository to your local machine.

  2. -
-
git clone https://github.com/mohsentabibian/LeetCode-Solutions/Blind-75-LeetCode.git
-
-
-
    -
  1. Navigate to the directory of the specific problem you want to solve.

  2. -
-
cd Blind-75-LeetCode/Problem-Directory
-
-
-
    -
  1. Open the problem’s directory to find its description, code template, and solution(s).

  2. -
  3. Solve the problem using your preferred programming language.

  4. -
  5. Check the solution(s) provided in the directory for reference and to compare your solution.

  6. -
-
-
-

Contribute#

-

If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements.

-
-
-

Resources#

-
    -
  • LeetCode: The official LeetCode website.

  • -
  • LeetCode Discuss: LeetCode’s discussion forum for each problem. You can find helpful hints and discussions here.

  • -
-
-
-

Disclaimer#

-

This repository is meant for educational purposes and to help individuals prepare for technical interviews. Please respect LeetCode’s terms of use and guidelines when using this repository.

-

Happy coding!

-
-
- - - - -
- - - - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/Book.html b/docs/_build/html/Book.html deleted file mode 100644 index b11e1fe..0000000 --- a/docs/_build/html/Book.html +++ /dev/null @@ -1,1151 +0,0 @@ - - - - - - - - - - - - <no title> — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-
-
!python -m pip install --upgrade pip
-%pip install jupyter-book
-
-
-
-
-
Requirement already satisfied: pip in /usr/local/python/3.10.8/lib/python3.10/site-packages (23.3.1)
-
-
-
Requirement already satisfied: jupyter-book in /usr/local/python/3.10.8/lib/python3.10/site-packages (0.15.1)
-
-
-
Requirement already satisfied: click<9,>=7.1 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (8.1.7)
-Requirement already satisfied: docutils<0.19,>=0.15 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (0.18.1)
-Requirement already satisfied: Jinja2 in /home/codespace/.local/lib/python3.10/site-packages (from jupyter-book) (3.1.2)
-Requirement already satisfied: jsonschema<5 in /home/codespace/.local/lib/python3.10/site-packages (from jupyter-book) (4.19.1)
-Requirement already satisfied: linkify-it-py~=2.0.0 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (2.0.2)
-Requirement already satisfied: myst-nb~=0.17.1 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (0.17.2)
-Requirement already satisfied: pyyaml in /home/codespace/.local/lib/python3.10/site-packages (from jupyter-book) (6.0.1)
-Requirement already satisfied: sphinx<6,>=4 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (5.0.2)
-Requirement already satisfied: sphinx-comments in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (0.0.3)
-Requirement already satisfied: sphinx-copybutton in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (0.5.2)
-Requirement already satisfied: sphinx-external-toc~=0.3.1 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (0.3.1)
-Requirement already satisfied: sphinx-jupyterbook-latex~=0.5.2 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (0.5.2)
-Requirement already satisfied: sphinx-design~=0.3.0 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (0.3.0)
-Requirement already satisfied: sphinx-thebe~=0.2.0 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (0.2.1)
-Requirement already satisfied: sphinx-book-theme~=1.0.0 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (1.0.1)
-Requirement already satisfied: sphinx_togglebutton in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (0.3.2)
-Requirement already satisfied: sphinxcontrib-bibtex<=2.5.0,>=2.2.0 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (2.5.0)
-Requirement already satisfied: sphinx-multitoc-numbering~=0.1.3 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-book) (0.1.3)
-
-
-
Requirement already satisfied: attrs>=22.2.0 in /home/codespace/.local/lib/python3.10/site-packages (from jsonschema<5->jupyter-book) (23.1.0)
-Requirement already satisfied: jsonschema-specifications>=2023.03.6 in /home/codespace/.local/lib/python3.10/site-packages (from jsonschema<5->jupyter-book) (2023.7.1)
-Requirement already satisfied: referencing>=0.28.4 in /home/codespace/.local/lib/python3.10/site-packages (from jsonschema<5->jupyter-book) (0.30.2)
-Requirement already satisfied: rpds-py>=0.7.1 in /home/codespace/.local/lib/python3.10/site-packages (from jsonschema<5->jupyter-book) (0.10.6)
-Requirement already satisfied: uc-micro-py in /usr/local/python/3.10.8/lib/python3.10/site-packages (from linkify-it-py~=2.0.0->jupyter-book) (1.0.2)
-
-
-
Requirement already satisfied: importlib_metadata in /usr/local/python/3.10.8/lib/python3.10/site-packages (from myst-nb~=0.17.1->jupyter-book) (6.8.0)
-Requirement already satisfied: ipython in /home/codespace/.local/lib/python3.10/site-packages (from myst-nb~=0.17.1->jupyter-book) (8.16.1)
-Requirement already satisfied: jupyter-cache<0.7,>=0.5 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from myst-nb~=0.17.1->jupyter-book) (0.6.1)
-Requirement already satisfied: nbclient in /usr/local/python/3.10.8/lib/python3.10/site-packages (from myst-nb~=0.17.1->jupyter-book) (0.7.4)
-Requirement already satisfied: myst-parser~=0.18.0 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from myst-nb~=0.17.1->jupyter-book) (0.18.1)
-Requirement already satisfied: nbformat~=5.0 in /home/codespace/.local/lib/python3.10/site-packages (from myst-nb~=0.17.1->jupyter-book) (5.9.2)
-Requirement already satisfied: typing-extensions in /home/codespace/.local/lib/python3.10/site-packages (from myst-nb~=0.17.1->jupyter-book) (4.8.0)
-Requirement already satisfied: ipykernel in /home/codespace/.local/lib/python3.10/site-packages (from myst-nb~=0.17.1->jupyter-book) (6.25.2)
-Requirement already satisfied: sphinxcontrib-applehelp in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sphinx<6,>=4->jupyter-book) (1.0.7)
-Requirement already satisfied: sphinxcontrib-devhelp in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sphinx<6,>=4->jupyter-book) (1.0.5)
-Requirement already satisfied: sphinxcontrib-jsmath in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sphinx<6,>=4->jupyter-book) (1.0.1)
-Requirement already satisfied: sphinxcontrib-htmlhelp>=2.0.0 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sphinx<6,>=4->jupyter-book) (2.0.4)
-Requirement already satisfied: sphinxcontrib-serializinghtml>=1.1.5 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sphinx<6,>=4->jupyter-book) (1.1.9)
-Requirement already satisfied: sphinxcontrib-qthelp in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sphinx<6,>=4->jupyter-book) (1.0.6)
-Requirement already satisfied: Pygments>=2.0 in /home/codespace/.local/lib/python3.10/site-packages (from sphinx<6,>=4->jupyter-book) (2.16.1)
-Requirement already satisfied: snowballstemmer>=1.1 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sphinx<6,>=4->jupyter-book) (2.2.0)
-Requirement already satisfied: babel>=1.3 in /home/codespace/.local/lib/python3.10/site-packages (from sphinx<6,>=4->jupyter-book) (2.13.0)
-Requirement already satisfied: alabaster<0.8,>=0.7 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sphinx<6,>=4->jupyter-book) (0.7.13)
-Requirement already satisfied: imagesize in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sphinx<6,>=4->jupyter-book) (1.4.1)
-Requirement already satisfied: requests>=2.5.0 in /home/codespace/.local/lib/python3.10/site-packages (from sphinx<6,>=4->jupyter-book) (2.31.0)
-Requirement already satisfied: packaging in /home/codespace/.local/lib/python3.10/site-packages (from sphinx<6,>=4->jupyter-book) (23.2)
-Requirement already satisfied: MarkupSafe>=2.0 in /home/codespace/.local/lib/python3.10/site-packages (from Jinja2->jupyter-book) (2.1.3)
-
-
-
Requirement already satisfied: pydata-sphinx-theme>=0.13.3 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sphinx-book-theme~=1.0.0->jupyter-book) (0.14.3)
-
-
-
Requirement already satisfied: pybtex>=0.24 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sphinxcontrib-bibtex<=2.5.0,>=2.2.0->jupyter-book) (0.24.0)
-Requirement already satisfied: pybtex-docutils>=1.0.0 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sphinxcontrib-bibtex<=2.5.0,>=2.2.0->jupyter-book) (1.0.3)
-
-
-
Requirement already satisfied: setuptools in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sphinx_togglebutton->jupyter-book) (68.0.0)
-Requirement already satisfied: wheel in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sphinx_togglebutton->jupyter-book) (0.41.3)
-
-
-
Requirement already satisfied: sqlalchemy<3,>=1.3.12 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-cache<0.7,>=0.5->myst-nb~=0.17.1->jupyter-book) (2.0.23)
-Requirement already satisfied: tabulate in /usr/local/python/3.10.8/lib/python3.10/site-packages (from jupyter-cache<0.7,>=0.5->myst-nb~=0.17.1->jupyter-book) (0.9.0)
-
-
-
Requirement already satisfied: markdown-it-py<3.0.0,>=1.0.0 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from myst-parser~=0.18.0->myst-nb~=0.17.1->jupyter-book) (2.2.0)
-Requirement already satisfied: mdit-py-plugins~=0.3.1 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from myst-parser~=0.18.0->myst-nb~=0.17.1->jupyter-book) (0.3.5)
-Requirement already satisfied: jupyter-client>=6.1.12 in /home/codespace/.local/lib/python3.10/site-packages (from nbclient->myst-nb~=0.17.1->jupyter-book) (8.4.0)
-Requirement already satisfied: jupyter-core!=5.0.*,>=4.12 in /home/codespace/.local/lib/python3.10/site-packages (from nbclient->myst-nb~=0.17.1->jupyter-book) (5.4.0)
-Requirement already satisfied: traitlets>=5.3 in /home/codespace/.local/lib/python3.10/site-packages (from nbclient->myst-nb~=0.17.1->jupyter-book) (5.11.2)
-Requirement already satisfied: fastjsonschema in /home/codespace/.local/lib/python3.10/site-packages (from nbformat~=5.0->myst-nb~=0.17.1->jupyter-book) (2.18.1)
-
-
-
Requirement already satisfied: latexcodec>=1.0.4 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from pybtex>=0.24->sphinxcontrib-bibtex<=2.5.0,>=2.2.0->jupyter-book) (2.0.1)
-Requirement already satisfied: six in /home/codespace/.local/lib/python3.10/site-packages (from pybtex>=0.24->sphinxcontrib-bibtex<=2.5.0,>=2.2.0->jupyter-book) (1.16.0)
-Requirement already satisfied: beautifulsoup4 in /home/codespace/.local/lib/python3.10/site-packages (from pydata-sphinx-theme>=0.13.3->sphinx-book-theme~=1.0.0->jupyter-book) (4.12.2)
-Requirement already satisfied: accessible-pygments in /usr/local/python/3.10.8/lib/python3.10/site-packages (from pydata-sphinx-theme>=0.13.3->sphinx-book-theme~=1.0.0->jupyter-book) (0.0.4)
-
-
-
Requirement already satisfied: charset-normalizer<4,>=2 in /home/codespace/.local/lib/python3.10/site-packages (from requests>=2.5.0->sphinx<6,>=4->jupyter-book) (3.3.0)
-Requirement already satisfied: idna<4,>=2.5 in /home/codespace/.local/lib/python3.10/site-packages (from requests>=2.5.0->sphinx<6,>=4->jupyter-book) (3.4)
-Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from requests>=2.5.0->sphinx<6,>=4->jupyter-book) (1.26.18)
-Requirement already satisfied: certifi>=2017.4.17 in /home/codespace/.local/lib/python3.10/site-packages (from requests>=2.5.0->sphinx<6,>=4->jupyter-book) (2023.7.22)
-
-
-
Requirement already satisfied: zipp>=0.5 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from importlib_metadata->myst-nb~=0.17.1->jupyter-book) (3.17.0)
-
-
-
Requirement already satisfied: comm>=0.1.1 in /home/codespace/.local/lib/python3.10/site-packages (from ipykernel->myst-nb~=0.17.1->jupyter-book) (0.1.4)
-Requirement already satisfied: debugpy>=1.6.5 in /home/codespace/.local/lib/python3.10/site-packages (from ipykernel->myst-nb~=0.17.1->jupyter-book) (1.8.0)
-Requirement already satisfied: matplotlib-inline>=0.1 in /home/codespace/.local/lib/python3.10/site-packages (from ipykernel->myst-nb~=0.17.1->jupyter-book) (0.1.6)
-Requirement already satisfied: nest-asyncio in /home/codespace/.local/lib/python3.10/site-packages (from ipykernel->myst-nb~=0.17.1->jupyter-book) (1.5.8)
-Requirement already satisfied: psutil in /home/codespace/.local/lib/python3.10/site-packages (from ipykernel->myst-nb~=0.17.1->jupyter-book) (5.9.6)
-Requirement already satisfied: pyzmq>=20 in /home/codespace/.local/lib/python3.10/site-packages (from ipykernel->myst-nb~=0.17.1->jupyter-book) (25.1.1)
-Requirement already satisfied: tornado>=6.1 in /home/codespace/.local/lib/python3.10/site-packages (from ipykernel->myst-nb~=0.17.1->jupyter-book) (6.3.3)
-
-
-
Requirement already satisfied: backcall in /home/codespace/.local/lib/python3.10/site-packages (from ipython->myst-nb~=0.17.1->jupyter-book) (0.2.0)
-Requirement already satisfied: decorator in /home/codespace/.local/lib/python3.10/site-packages (from ipython->myst-nb~=0.17.1->jupyter-book) (5.1.1)
-Requirement already satisfied: jedi>=0.16 in /home/codespace/.local/lib/python3.10/site-packages (from ipython->myst-nb~=0.17.1->jupyter-book) (0.19.1)
-Requirement already satisfied: pickleshare in /home/codespace/.local/lib/python3.10/site-packages (from ipython->myst-nb~=0.17.1->jupyter-book) (0.7.5)
-Requirement already satisfied: prompt-toolkit!=3.0.37,<3.1.0,>=3.0.30 in /home/codespace/.local/lib/python3.10/site-packages (from ipython->myst-nb~=0.17.1->jupyter-book) (3.0.39)
-Requirement already satisfied: stack-data in /home/codespace/.local/lib/python3.10/site-packages (from ipython->myst-nb~=0.17.1->jupyter-book) (0.6.3)
-Requirement already satisfied: exceptiongroup in /home/codespace/.local/lib/python3.10/site-packages (from ipython->myst-nb~=0.17.1->jupyter-book) (1.1.3)
-Requirement already satisfied: pexpect>4.3 in /home/codespace/.local/lib/python3.10/site-packages (from ipython->myst-nb~=0.17.1->jupyter-book) (4.8.0)
-
-
-
Requirement already satisfied: parso<0.9.0,>=0.8.3 in /home/codespace/.local/lib/python3.10/site-packages (from jedi>=0.16->ipython->myst-nb~=0.17.1->jupyter-book) (0.8.3)
-
-
-
Requirement already satisfied: python-dateutil>=2.8.2 in /home/codespace/.local/lib/python3.10/site-packages (from jupyter-client>=6.1.12->nbclient->myst-nb~=0.17.1->jupyter-book) (2.8.2)
-Requirement already satisfied: platformdirs>=2.5 in /home/codespace/.local/lib/python3.10/site-packages (from jupyter-core!=5.0.*,>=4.12->nbclient->myst-nb~=0.17.1->jupyter-book) (3.11.0)
-
-
-
Requirement already satisfied: mdurl~=0.1 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from markdown-it-py<3.0.0,>=1.0.0->myst-parser~=0.18.0->myst-nb~=0.17.1->jupyter-book) (0.1.2)
-Requirement already satisfied: ptyprocess>=0.5 in /home/codespace/.local/lib/python3.10/site-packages (from pexpect>4.3->ipython->myst-nb~=0.17.1->jupyter-book) (0.7.0)
-Requirement already satisfied: wcwidth in /home/codespace/.local/lib/python3.10/site-packages (from prompt-toolkit!=3.0.37,<3.1.0,>=3.0.30->ipython->myst-nb~=0.17.1->jupyter-book) (0.2.8)
-
-
-
Requirement already satisfied: greenlet!=0.4.17 in /usr/local/python/3.10.8/lib/python3.10/site-packages (from sqlalchemy<3,>=1.3.12->jupyter-cache<0.7,>=0.5->myst-nb~=0.17.1->jupyter-book) (3.0.1)
-
-
-
Requirement already satisfied: soupsieve>1.2 in /home/codespace/.local/lib/python3.10/site-packages (from beautifulsoup4->pydata-sphinx-theme>=0.13.3->sphinx-book-theme~=1.0.0->jupyter-book) (2.5)
-
-
-
Requirement already satisfied: executing>=1.2.0 in /home/codespace/.local/lib/python3.10/site-packages (from stack-data->ipython->myst-nb~=0.17.1->jupyter-book) (2.0.0)
-Requirement already satisfied: asttokens>=2.1.0 in /home/codespace/.local/lib/python3.10/site-packages (from stack-data->ipython->myst-nb~=0.17.1->jupyter-book) (2.4.0)
-Requirement already satisfied: pure-eval in /home/codespace/.local/lib/python3.10/site-packages (from stack-data->ipython->myst-nb~=0.17.1->jupyter-book) (0.2.2)
-
-
-
Note: you may need to restart the kernel to use updated packages.
-
-
-
-
-
-
-
%cd /workspaces/LeetCode-Solutions
-
-
-
-
-
/workspaces/LeetCode-Solutions
-
-
-
-
-
-
-
!jupyter-book toc migrate /workspaces/LeetCode-Solutions/_toc.yml -o /workspaces/LeetCode-Solutions/_toc.yml
-
-
-
-
-
Traceback (most recent call last):
-  File "/home/codespace/.python/current/bin/jupyter-book", line 8, in <module>
-    sys.exit(main())
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/click/core.py", line 1157, in __call__
-    return self.main(*args, **kwargs)
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/click/core.py", line 1078, in main
-    rv = self.invoke(ctx)
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/click/core.py", line 1688, in invoke
-    return _process_result(sub_ctx.command.invoke(sub_ctx))
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/click/core.py", line 1688, in invoke
-    return _process_result(sub_ctx.command.invoke(sub_ctx))
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/click/core.py", line 1434, in invoke
-    return ctx.invoke(self.callback, **ctx.params)
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/click/core.py", line 783, in invoke
-    return __callback(*args, **kwargs)
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/sphinx_external_toc/cli.py", line 139, in migrate_toc
-    toc = migrate_jupyter_book(Path(toc_file))
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/sphinx_external_toc/tools.py", line 327, in migrate_jupyter_book
-    raise MalformedError("no top-level 'file' key found")
-sphinx_external_toc.parsing.MalformedError: no top-level 'file' key found
-
-
-
-
-
-
-
!jupyter-book build .
-
-
-
-
-
Running Jupyter-Book v0.15.1
-
-
-
Source Folder: /workspaces/LeetCode-Solutions
-Config Path: /workspaces/LeetCode-Solutions/_config.yml
-Output Path: /workspaces/LeetCode-Solutions/_build/html
-Running Sphinx v5.0.2
-
-
-
[etoc] Changing master_doc to 'README'
-
-
-
myst v0.18.1: MdParserConfig(commonmark_only=False, gfm_only=False, enable_extensions=['colon_fence', 'dollarmath', 'linkify', 'substitution', 'tasklist'], disable_syntax=[], all_links_external=False, url_schemes=['mailto', 'http', 'https'], ref_domains=None, highlight_code_blocks=True, number_code_blocks=[], title_to_header=False, heading_anchors=None, heading_slug_func=None, footnote_transition=True, words_per_minute=200, sub_delimiters=('{', '}'), linkify_fuzzy_links=True, dmath_allow_labels=True, dmath_allow_space=True, dmath_allow_digits=True, dmath_double_inline=False, update_mathjax=True, mathjax_classes='tex2jax_process|mathjax_process|math|output_area')
-myst-nb v0.17.2: NbParserConfig(custom_formats={}, metadata_key='mystnb', cell_metadata_key='mystnb', kernel_rgx_aliases={}, execution_mode='auto', execution_cache_path='', execution_excludepatterns=[], execution_timeout=30, execution_in_temp=False, execution_allow_errors=False, execution_raise_on_error=False, execution_show_tb=False, merge_streams=False, render_plugin='default', remove_code_source=False, remove_code_outputs=False, code_prompt_show='Show code cell {type}', code_prompt_hide='Hide code cell {type}', number_source_lines=False, output_stderr='show', render_text_lexer='myst-ansi', render_error_lexer='ipythontb', render_image_options={}, render_figure_options={}, render_markdown_format='commonmark', output_folder='build', append_css=True, metadata_to_fm=False)
-Using jupyter-cache at: /workspaces/LeetCode-Solutions/_build/.jupyter_cache
-
-
-
building [mo]: targets for 0 po files that are out of date
-building [html]: targets for 77 source files that are out of date
-updating environment: [new config] 77 added, 0 changed, 0 removed
-reading sources... [  1%] 01. Array Hashing/1. Two Sum                          
-
-
-
/workspaces/LeetCode-Solutions/01. Array Hashing/1. Two Sum.ipynb: Executing notebook using local CWD [mystnb]
-
-
-
/workspaces/LeetCode-Solutions/01. Array Hashing/1. Two Sum.ipynb: Executed notebook in 1.07 seconds [mystnb]
-
-
-
reading sources... [  2%] 01. Array Hashing/128. Longest Consecutive Sequence   
-/workspaces/LeetCode-Solutions/01. Array Hashing/128. Longest Consecutive Sequence.ipynb: Executing notebook using local CWD [mystnb]
-
-
-
/workspaces/LeetCode-Solutions/01. Array Hashing/128. Longest Consecutive Sequence.ipynb: Executed notebook in 1.17 seconds [mystnb]
-reading sources... [  3%] 01. Array Hashing/217. Contains Duplicate             
-/workspaces/LeetCode-Solutions/01. Array Hashing/217. Contains Duplicate.ipynb: Executing notebook using local CWD [mystnb]
-
-
-
/workspaces/LeetCode-Solutions/01. Array Hashing/217. Contains Duplicate.ipynb: Executed notebook in 1.19 seconds [mystnb]
-reading sources... [  5%] 01. Array Hashing/238. Product of Array Except Self   
-/workspaces/LeetCode-Solutions/01. Array Hashing/238. Product of Array Except Self.ipynb: Executing notebook using local CWD [mystnb]
-
-
-
/workspaces/LeetCode-Solutions/01. Array Hashing/238. Product of Array Except Self.ipynb: Executed notebook in 1.26 seconds [mystnb]
-
-
-
reading sources... [  6%] 01. Array Hashing/242. Valid Anagram                  
-/workspaces/LeetCode-Solutions/01. Array Hashing/242. Valid Anagram.ipynb: Executing notebook using local CWD [mystnb]
-
-
-
/workspaces/LeetCode-Solutions/01. Array Hashing/242. Valid Anagram.ipynb: Executed notebook in 1.18 seconds [mystnb]
-
-
-
reading sources... [  7%] 01. Array Hashing/347. Top K Frequent Elements        
-/workspaces/LeetCode-Solutions/01. Array Hashing/347. Top K Frequent Elements.ipynb: Executing notebook using local CWD [mystnb]
-
-
-
/workspaces/LeetCode-Solutions/01. Array Hashing/347. Top K Frequent Elements.ipynb: Executed notebook in 1.13 seconds [mystnb]
-
-
-
reading sources... [  9%] 01. Array Hashing/49. Group Anagrams                  
-/workspaces/LeetCode-Solutions/01. Array Hashing/49. Group Anagrams.ipynb: Executing notebook using local CWD [mystnb]
-
-
-
/workspaces/LeetCode-Solutions/01. Array Hashing/49. Group Anagrams.ipynb: Executed notebook in 4.02 seconds [mystnb]
-reading sources... [ 10%] 01. Array Hashing/659. Encode and Decode Strings      
-
-
-
/workspaces/LeetCode-Solutions/01. Array Hashing/659. Encode and Decode Strings.ipynb: Executing notebook using local CWD [mystnb]
-
-
-
/workspaces/LeetCode-Solutions/01. Array Hashing/659. Encode and Decode Strings.ipynb: Executed notebook in 1.05 seconds [mystnb]
-
-
-
reading sources... [ 11%] 01. Array Hashing/README                              
-reading sources... [ 12%] 02. Two Pointers/11. Container With Most Water        
-/workspaces/LeetCode-Solutions/02. Two Pointers/11. Container With Most Water.ipynb: Executing notebook using local CWD [mystnb]
-
-
-
/workspaces/LeetCode-Solutions/02. Two Pointers/11. Container With Most Water.ipynb: Executed notebook in 1.26 seconds [mystnb]
-reading sources... [ 14%] 02. Two Pointers/125. Valid Palindrome                
-/workspaces/LeetCode-Solutions/02. Two Pointers/125. Valid Palindrome.ipynb: Executing notebook using local CWD [mystnb]
-
-
-
/workspaces/LeetCode-Solutions/02. Two Pointers/125. Valid Palindrome.ipynb: Executed notebook in 1.07 seconds [mystnb]
-
-
-
reading sources... [ 15%] 02. Two Pointers/15. 3Sum                             
-/workspaces/LeetCode-Solutions/02. Two Pointers/15. 3Sum.ipynb: Executing notebook using local CWD [mystnb]
-
-
-
/workspaces/LeetCode-Solutions/02. Two Pointers/15. 3Sum.ipynb: Executed notebook in 1.00 seconds [mystnb]
-
-
-
reading sources... [ 16%] 02. Two Pointers/README                               
-reading sources... [ 18%] 03. Sliding Window/121. Best Time to Buy and Sell Stock
-
-
-
/workspaces/LeetCode-Solutions/03. Sliding Window/121. Best Time to Buy and Sell Stock.ipynb: Executing notebook using local CWD [mystnb]
-
-
-
/workspaces/LeetCode-Solutions/03. Sliding Window/121. Best Time to Buy and Sell Stock.ipynb: Executed notebook in 0.89 seconds [mystnb]
-reading sources... [ 19%] 03. Sliding Window/3. Longest Substring Without Repeating Characters
-
-
-
/workspaces/LeetCode-Solutions/03. Sliding Window/3. Longest Substring Without Repeating Characters.ipynb: Executing notebook using local CWD [mystnb]
-
-
-
/workspaces/LeetCode-Solutions/03. Sliding Window/3. Longest Substring Without Repeating Characters.ipynb: Executed notebook in 1.16 seconds [mystnb]
-
-
-
reading sources... [ 20%] 03. Sliding Window/424. Longest Repeating Character Replacement
-/workspaces/LeetCode-Solutions/03. Sliding Window/424. Longest Repeating Character Replacement.ipynb: Executing notebook using local CWD [mystnb]
-
-
-
/workspaces/LeetCode-Solutions/03. Sliding Window/424. Longest Repeating Character Replacement.ipynb: Executed notebook in 1.05 seconds [mystnb]
-reading sources... [ 22%] 03. Sliding Window/76. Minimum Window Substring       
-/workspaces/LeetCode-Solutions/03. Sliding Window/76. Minimum Window Substring.ipynb: Executing notebook using local CWD [mystnb]
-
-
-
/workspaces/LeetCode-Solutions/03. Sliding Window/76. Minimum Window Substring.ipynb: Executed notebook in 0.87 seconds [mystnb]
-
-
-
reading sources... [ 23%] 03. Sliding Window/README                             
-reading sources... [ 24%] 04. Stack/20. Valid Parentheses                       
-/workspaces/LeetCode-Solutions/04. Stack/20. Valid Parentheses.ipynb: Executing notebook using local CWD [mystnb]
-
-
-
/workspaces/LeetCode-Solutions/04. Stack/20. Valid Parentheses.ipynb: Executed notebook in 4.02 seconds [mystnb]
-reading sources... [ 25%] 04. Stack/README                                      
-reading sources... [ 27%] 05. Binary Search/153. Find Minimum in Rotated Sorted Array
-
-
-
/workspaces/LeetCode-Solutions/05. Binary Search/153. Find Minimum in Rotated Sorted Array.ipynb: Executing notebook using local CWD [mystnb]
-
-
-
/workspaces/LeetCode-Solutions/05. Binary Search/153. Find Minimum in Rotated Sorted Array.ipynb: Executed notebook in 0.98 seconds [mystnb]
-reading sources... [ 28%] 05. Binary Search/33. Search in Rotated Sorted Array  
-
-
-
/workspaces/LeetCode-Solutions/05. Binary Search/33. Search in Rotated Sorted Array.ipynb: Executing notebook using local CWD [mystnb]
-
-
-
/workspaces/LeetCode-Solutions/05. Binary Search/33. Search in Rotated Sorted Array.ipynb: Executed notebook in 1.05 seconds [mystnb]
-reading sources... [ 29%] 05. Binary Search/README                              
-
-
-
reading sources... [ 31%] 06. Linked List/141. Linked List Cycle                
-/workspaces/LeetCode-Solutions/06. Linked List/141. Linked List Cycle.ipynb: Executing notebook using local CWD [mystnb]
-
-
-
/workspaces/LeetCode-Solutions/06. Linked List/141. Linked List Cycle.ipynb: Executed notebook in 0.96 seconds [mystnb]
-reading sources... [ 32%] 06. Linked List/143. Reorder List                     
-
-
-
/workspaces/LeetCode-Solutions/06. Linked List/143. Reorder List.ipynb: Executing notebook using local CWD [mystnb]
-
-
-
^C
-
-Exception occurred:
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/nbclient/client.py", line 512, in _async_cleanup_kernel
-    await ensure_async(self.km.cleanup_resources())
-AttributeError: 'NoneType' object has no attribute 'cleanup_resources'
-The full traceback has been saved in /tmp/sphinx-err-tl19fjln.log, if you want to report the issue to the developers.
-Please also report this if it was a user error, so that a better error message can be provided next time.
-A bug report can be filed in the tracker at <https://github.com/sphinx-doc/sphinx/issues>. Thanks!
-Traceback (most recent call last):
-  File "/home/codespace/.local/lib/python3.10/site-packages/jupyter_client/manager.py", line 89, in wrapper
-    self._ready.set_result(None)
-asyncio.exceptions.InvalidStateError: invalid state
-
-During handling of the above exception, another exception occurred:
-
-Traceback (most recent call last):
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/nbclient/client.py", line 505, in _async_cleanup_kernel
-    await ensure_async(self.km.shutdown_kernel(now=now))
-  File "/home/codespace/.local/lib/python3.10/site-packages/jupyter_core/utils/__init__.py", line 189, in ensure_async
-    result = await obj
-  File "/home/codespace/.local/lib/python3.10/site-packages/jupyter_client/manager.py", line 92, in wrapper
-    self._ready.set_exception(e)
-asyncio.exceptions.InvalidStateError: invalid state
-
-During handling of the above exception, another exception occurred:
-
-Traceback (most recent call last):
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/jupyter_book/sphinx.py", line 171, in build_sphinx
-    app.build(force_all, filenames)
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/sphinx/application.py", line 329, in build
-    self.builder.build_update()
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/sphinx/builders/__init__.py", line 288, in build_update
-    self.build(to_build,
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/sphinx/builders/__init__.py", line 302, in build
-    updated_docnames = set(self.read())
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/sphinx/builders/__init__.py", line 409, in read
-    self._read_serial(docnames)
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/sphinx/builders/__init__.py", line 430, in _read_serial
-    self.read_doc(docname)
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/sphinx/builders/__init__.py", line 483, in read_doc
-    publisher.publish()
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/docutils/core.py", line 217, in publish
-    self.document = self.reader.read(self.source, self.parser,
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/sphinx/io.py", line 103, in read
-    self.parse()
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/docutils/readers/__init__.py", line 78, in parse
-    self.parser.parse(self.input, document)
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/myst_nb/sphinx_.py", line 150, in parse
-    with create_client(
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/myst_nb/core/execute/base.py", line 83, in __enter__
-    self.start_client()
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/myst_nb/core/execute/direct.py", line 40, in start_client
-    result = single_nb_execution(
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/jupyter_cache/executors/utils.py", line 58, in single_nb_execution
-    executenb(
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/nbclient/client.py", line 1305, in execute
-    return NotebookClient(nb=nb, resources=resources, km=km, **kwargs).execute()
-  File "/home/codespace/.local/lib/python3.10/site-packages/jupyter_core/utils/__init__.py", line 173, in wrapped
-    return loop.run_until_complete(inner)
-  File "/usr/local/python/3.10.8/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete
-    return future.result()
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/nbclient/client.py", line 689, in async_execute
-    async with self.async_setup_kernel(**kwargs):
-  File "/usr/local/python/3.10.8/lib/python3.10/contextlib.py", line 206, in __aexit__
-    await anext(self.gen)
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/nbclient/client.py", line 656, in async_setup_kernel
-    await self._async_cleanup_kernel()
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/nbclient/client.py", line 512, in _async_cleanup_kernel
-    await ensure_async(self.km.cleanup_resources())
-AttributeError: 'NoneType' object has no attribute 'cleanup_resources'
-
-The above exception was the direct cause of the following exception:
-
-Traceback (most recent call last):
-  File "/home/codespace/.python/current/bin/jupyter-book", line 8, in <module>
-    sys.exit(main())
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/click/core.py", line 1157, in __call__
-    return self.main(*args, **kwargs)
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/click/core.py", line 1078, in main
-    rv = self.invoke(ctx)
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/click/core.py", line 1688, in invoke
-    return _process_result(sub_ctx.command.invoke(sub_ctx))
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/click/core.py", line 1434, in invoke
-    return ctx.invoke(self.callback, **ctx.params)
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/click/core.py", line 783, in invoke
-    return __callback(*args, **kwargs)
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/jupyter_book/cli/main.py", line 317, in build
-    builder_specific_actions(
-  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/jupyter_book/cli/main.py", line 525, in builder_specific_actions
-    raise RuntimeError(_message_box(msg, color="red", doprint=False)) from result
-RuntimeError: 
-===============================================================================
-
-There was an error in building your book. Look above for the cause.
-
-===============================================================================
-
-
-
-
-
-
-
!jupyter-book build /workspaces/LeetCode-Solutions/ --builder pdfhtml
-
-
-
-
-
-
-
from IPython.display import HTML
-HTML('<a href="_build/html/index.html" target="_blank">Click here to view your Jupyter Book</a>')
-
-
-
- -
-
-
-
!jupyter-book create mybook
-
-
-
-
-
===============================================================================
-
-Your book template can be found at
-
-    mybook/
-
-===============================================================================
-
-
-
-
-
-
-
!jupyter-book build mybook
-
-
-
-
-
Running Jupyter-Book v0.15.1
-Source Folder: /workspaces/LeetCode-Solutions/mybook
-Config Path: /workspaces/LeetCode-Solutions/mybook/_config.yml
-Output Path: /workspaces/LeetCode-Solutions/mybook/_build/html
-[sphinxcontrib-bibtex] Beware that docutils versions 0.18 and 0.19 (you are running 0.18.1) are known to generate invalid html for citations. If this issue affects you, please use docutils<0.18 (or >=0.20 once released) instead. For more details, see https://sourceforge.net/p/docutils/patches/195/
-Running Sphinx v5.0.2
-[etoc] Changing master_doc to 'intro'
-checking bibtex cache... out of date
-parsing bibtex file /workspaces/LeetCode-Solutions/mybook/references.bib... parsed 5 entries
-myst v0.18.1: MdParserConfig(commonmark_only=False, gfm_only=False, enable_extensions=['colon_fence', 'dollarmath', 'linkify', 'substitution', 'tasklist'], disable_syntax=[], all_links_external=False, url_schemes=['mailto', 'http', 'https'], ref_domains=None, highlight_code_blocks=True, number_code_blocks=[], title_to_header=False, heading_anchors=None, heading_slug_func=None, footnote_transition=True, words_per_minute=200, sub_delimiters=('{', '}'), linkify_fuzzy_links=True, dmath_allow_labels=True, dmath_allow_space=True, dmath_allow_digits=True, dmath_double_inline=False, update_mathjax=True, mathjax_classes='tex2jax_process|mathjax_process|math|output_area')
-myst-nb v0.17.2: NbParserConfig(custom_formats={}, metadata_key='mystnb', cell_metadata_key='mystnb', kernel_rgx_aliases={}, execution_mode='force', execution_cache_path='', execution_excludepatterns=[], execution_timeout=30, execution_in_temp=False, execution_allow_errors=False, execution_raise_on_error=False, execution_show_tb=False, merge_streams=False, render_plugin='default', remove_code_source=False, remove_code_outputs=False, code_prompt_show='Show code cell {type}', code_prompt_hide='Hide code cell {type}', number_source_lines=False, output_stderr='show', render_text_lexer='myst-ansi', render_error_lexer='ipythontb', render_image_options={}, render_figure_options={}, render_markdown_format='commonmark', output_folder='build', append_css=True, metadata_to_fm=False)
-Using jupyter-cache at: /workspaces/LeetCode-Solutions/mybook/_build/.jupyter_cache
-building [mo]: targets for 0 po files that are out of date
-building [html]: targets for 14 source files that are out of date
-updating environment: [new config] 14 added, 0 changed, 0 removed
-/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/1. Two Sum.ipynb: Executing notebook using local CWD [mystnb]
-/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/1. Two Sum.ipynb: Executed notebook in 1.35 seconds [mystnb]
-/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/128. Longest Consecutive Sequence.ipynb: Executing notebook using local CWD [mystnb]
-/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/128. Longest Consecutive Sequence.ipynb: Executed notebook in 1.09 seconds [mystnb]
-/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/217. Contains Duplicate.ipynb: Executing notebook using local CWD [mystnb]
-/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/217. Contains Duplicate.ipynb: Executed notebook in 1.04 seconds [mystnb]
-/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/238. Product of Array Except Self.ipynb: Executing notebook using local CWD [mystnb]
-/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/238. Product of Array Except Self.ipynb: Executed notebook in 4.02 seconds [mystnb]
-/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/242. Valid Anagram.ipynb: Executing notebook using local CWD [mystnb]
-/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/242. Valid Anagram.ipynb: Executed notebook in 0.97 seconds [mystnb]
-/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/347. Top K Frequent Elements.ipynb: Executing notebook using local CWD [mystnb]
-/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/347. Top K Frequent Elements.ipynb: Executed notebook in 1.14 seconds [mystnb]
-/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/49. Group Anagrams.ipynb: Executing notebook using local CWD [mystnb]
-/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/49. Group Anagrams.ipynb: Executed notebook in 0.88 seconds [mystnb]
-/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/659. Encode and Decode Strings.ipynb: Executing notebook using local CWD [mystnb]
-/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/659. Encode and Decode Strings.ipynb: Executed notebook in 1.10 seconds [mystnb]
-/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/11. Container With Most Water.ipynb: Executing notebook using local CWD [mystnb]
-/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/11. Container With Most Water.ipynb: Executed notebook in 1.12 seconds [mystnb]
-/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/125. Valid Palindrome.ipynb: Executing notebook using local CWD [mystnb]
-/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/125. Valid Palindrome.ipynb: Executed notebook in 0.98 seconds [mystnb]
-/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/15. 3Sum.ipynb: Executing notebook using local CWD [mystnb]
-/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/15. 3Sum.ipynb: Executed notebook in 0.83 seconds [mystnb]
-reading sources... [100%] intro                                                 
-looking for now-outdated files... none found
-pickling environment... done
-checking consistency... /workspaces/LeetCode-Solutions/mybook/01. Array Hashing/README.md: WARNING: document isn't included in any toctree
-/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/README.md: WARNING: document isn't included in any toctree
-done
-preparing documents... done
-writing output... [100%] intro                                                  
-generating indices... genindex done
-writing additional pages... search done
-copying static files... done
-copying extra files... done
-dumping search index in English (code: en)... done
-dumping object inventory... done
-[etoc] missing index.html written as redirect to 'intro.html'
-build succeeded, 2 warnings.
-
-The HTML pages are in mybook/_build/html.
-
-===============================================================================
-
-Finished generating HTML for book.
-Your book's HTML pages are here:
-    mybook/_build/html/
-You can look at your book by opening this file in a browser:
-    mybook/_build/html/index.html
-Or paste this line directly into your browser bar:
-    file:///workspaces/LeetCode-Solutions/mybook/_build/html/index.html            
-
-===============================================================================
-
-
-
-
-
-
-
!jupyter-book toc from-project /workspaces/LeetCode-Solutions/mybook/ -f jb-book
-
-
-
-
-
format: jb-book
-root: intro
-
-
-
-
- - - - -
- - - - - - -
- -
-
-
- -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/CODE_OF_CONDUCT.html b/docs/_build/html/CODE_OF_CONDUCT.html deleted file mode 100644 index e1f3fd1..0000000 --- a/docs/_build/html/CODE_OF_CONDUCT.html +++ /dev/null @@ -1,710 +0,0 @@ - - - - - - - - - - - - Contributor Covenant Code of Conduct — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

Contributor Covenant Code of Conduct#

-
-

Our Pledge#

-

We as members, contributors, and leaders pledge to make participation in our -community a harassment-free experience for everyone, regardless of age, body -size, visible or invisible disability, ethnicity, sex characteristics, gender -identity and expression, level of experience, education, socio-economic status, -nationality, personal appearance, race, religion, or sexual identity -and orientation.

-

We pledge to act and interact in ways that contribute to an open, welcoming, -diverse, inclusive, and healthy community.

-
-
-

Our Standards#

-

Examples of behavior that contributes to a positive environment for our -community include:

-
    -
  • Demonstrating empathy and kindness toward other people

  • -
  • Being respectful of differing opinions, viewpoints, and experiences

  • -
  • Giving and gracefully accepting constructive feedback

  • -
  • Accepting responsibility and apologizing to those affected by our mistakes, -and learning from the experience

  • -
  • Focusing on what is best not just for us as individuals, but for the -overall community

  • -
-

Examples of unacceptable behavior include:

-
    -
  • The use of sexualized language or imagery, and sexual attention or -advances of any kind

  • -
  • Trolling, insulting or derogatory comments, and personal or political attacks

  • -
  • Public or private harassment

  • -
  • Publishing others’ private information, such as a physical or email -address, without their explicit permission

  • -
  • Other conduct which could reasonably be considered inappropriate in a -professional setting

  • -
-
-
-

Enforcement Responsibilities#

-

Community leaders are responsible for clarifying and enforcing our standards of -acceptable behavior and will take appropriate and fair corrective action in -response to any behavior that they deem inappropriate, threatening, offensive, -or harmful.

-

Community leaders 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, and will communicate reasons for moderation -decisions when appropriate.

-
-
-

Scope#

-

This Code of Conduct applies within all community spaces, and also applies when -an individual is officially representing the community in public spaces. -Examples of representing our community include using an official e-mail address, -posting via an official social media account, or acting as an appointed -representative at an online or offline event.

-
-
-

Enforcement#

-

Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported to the community leaders responsible for enforcement at -Email. -All complaints will be reviewed and investigated promptly and fairly.

-

All community leaders are obligated to respect the privacy and security of the -reporter of any incident.

-
-
-

Enforcement Guidelines#

-

Community leaders will follow these Community Impact Guidelines in determining -the consequences for any action they deem in violation of this Code of Conduct:

-
-

1. Correction#

-

Community Impact: Use of inappropriate language or other behavior deemed -unprofessional or unwelcome in the community.

-

Consequence: A private, written warning from community leaders, providing -clarity around the nature of the violation and an explanation of why the -behavior was inappropriate. A public apology may be requested.

-
-
-

2. Warning#

-

Community Impact: A violation through a single incident or series -of actions.

-

Consequence: A warning with consequences for continued behavior. No -interaction with the people involved, including unsolicited interaction with -those enforcing the Code of Conduct, for a specified period of time. This -includes avoiding interactions in community spaces as well as external channels -like social media. Violating these terms may lead to a temporary or -permanent ban.

-
-
-

3. Temporary Ban#

-

Community Impact: A serious violation of community standards, including -sustained inappropriate behavior.

-

Consequence: A temporary ban from any sort of interaction or public -communication with the community for a specified period of time. No public or -private interaction with the people involved, including unsolicited interaction -with those enforcing the Code of Conduct, is allowed during this period. -Violating these terms may lead to a permanent ban.

-
-
-

4. Permanent Ban#

-

Community Impact: Demonstrating a pattern of violation of community -standards, including sustained inappropriate behavior, harassment of an -individual, or aggression toward or disparagement of classes of individuals.

-

Consequence: A permanent ban from any sort of public interaction within -the community.

-
-
-
-

Attribution#

-

This Code of Conduct is adapted from the Contributor Covenant, -version 2.0, available at -https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.

-

Community Impact Guidelines were inspired by Mozilla’s code of conduct -enforcement ladder.

-

For answers to common questions about this code of conduct, see the FAQ at -https://www.contributor-covenant.org/faq. Translations are available at -https://www.contributor-covenant.org/translations.

-
-
- - - - -
- - - - - - -
- -
-
-
- -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/CONTRIBUTING.html b/docs/_build/html/CONTRIBUTING.html deleted file mode 100644 index 9254de9..0000000 --- a/docs/_build/html/CONTRIBUTING.html +++ /dev/null @@ -1,645 +0,0 @@ - - - - - - - - - - - - Contributing Guidelines — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Contributing Guidelines

- -
- -
-
- - - - -
- -
-

Contributing Guidelines#

-

Thank you for considering contributing to the Blind 75 LeetCode repository! We welcome contributions from the community to help improve this resource and make it even more valuable.

-

Please take a moment to review this document to understand how you can contribute.

-
-

Table of Contents#

-
    -
  • Ways to Contribute

  • -
  • Getting Started

  • -
  • Contributing Process

  • -
  • Code of Conduct

  • -
-
-
-

Ways to Contribute#

-

There are several ways you can contribute to this repository:

-
    -
  1. Suggest Improvements: If you have ideas for making the Blind 75 LeetCode repository better, please open an issue to discuss your suggestions.

  2. -
  3. Report Issues: If you encounter any issues with the existing content or code, please open an issue and provide as much detail as possible.

  4. -
  5. Contribute Solutions: You can contribute solutions to the problems listed in the repository. Please follow the guidelines mentioned below when submitting your solutions.

  6. -
  7. Enhance Documentation: Improve documentation, including explanations and time/space complexity analysis, for existing solutions.

  8. -
  9. Fix Bugs: If you find and fix any bugs in the existing code or documentation, you are welcome to submit a pull request.

  10. -
-
-
-

Getting Started#

-

Before you start contributing, please ensure you have the following prerequisites:

-
    -
  • A GitHub account.

  • -
  • Familiarity with Git and GitHub.

  • -
  • Code editor or IDE for making changes.

  • -
-
-
-

Contributing Process#

-

Here’s the general process for contributing:

-
    -
  1. Fork the Repository: Click the “Fork” button at the top of this repository to create your copy.

  2. -
  3. Clone Your Fork: Clone your fork to your local machine.

    -
    git clone https://github.com/your-username/Blind-75-LeetCode.git
    -
    -
    -
  4. -
  5. Create a Branch: Create a new branch for your contribution.

    -
    git checkout -b feature/your-feature-name
    -
    -
    -
  6. -
  7. Make Changes: Implement your changes, following the guidelines provided.

  8. -
  9. Test Your Changes: Ensure that your changes do not introduce new issues and are consistent with the repository’s style and structure.

  10. -
  11. Commit Changes: Commit your changes with a meaningful commit message.

    -
    git commit -m "Add solution to problem X"
    -
    -
    -
  12. -
  13. Push Changes: Push your changes to your fork on GitHub.

    -
    git push origin feature/your-feature-name
    -
    -
    -
  14. -
  15. Create a Pull Request: Go to the original repository and create a pull request. Please provide a detailed description of your changes.

  16. -
  17. Review and Collaboration: Your pull request will be reviewed, and you may need to make further changes. Be responsive to comments and feedback.

  18. -
  19. Merge: Once your pull request is approved, it will be merged into the main branch.

  20. -
-
-
-

Code of Conduct#

-

Please note that we have a Code of Conduct that we expect all contributors to adhere to. By participating in this project, you agree to follow this code.

-

We appreciate your contributions to the Blind 75 LeetCode repository and look forward to working together to make it an even better resource for the community!

-
-
- - - - -
- - - - - - -
- -
-
-
- -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/README.html b/docs/_build/html/README.html deleted file mode 100644 index 49e44aa..0000000 --- a/docs/_build/html/README.html +++ /dev/null @@ -1,1141 +0,0 @@ - - - - - - - - - - - - Blind 75 LeetCode Solutions — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

Blind 75 LeetCode Solutions#

-

Blind 75 LeetCode

-

This repository contains a curated list of 75 LeetCode problems that are commonly known as the “Blind 75.” These problems cover a wide range of data structures and algorithms and are frequently asked in technical interviews. Solving these problems can help you build a strong foundation in algorithmic problem-solving.

-
-

Problem List#

-
-

Array & Hashing#

-

Array & Hashing

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Problem Name

Difficulty

217. Contains Duplicate

Easy

242. Valid Anagram

Easy

1. Two Sum

Easy

49. Group Anagrams

Medium

347. Top K Frequent Elements

Medium

238. Product of Array Except Self

Medium

659. Encode and Decode Strings

Medium

128. Longest Consecutive Sequence

Hard

-
-
-

Two Pointers#

-

Array & Hashing

- - - - - - - - - - - - - - - - - -

Problem Name

Difficulty

125. Valid Palindrome

Easy

15. 3Sum

Medium

11. Container With Most Water

Medium

-
-
-

Sliding Window#

-

Array & Hashing

- - - - - - - - - - - - - - - - - - - - -

Problem Name

Difficulty

121. Best Time to Buy And Sell Stock

Easy

3. Longest Substring Without Repeating Characters

Medium

424. Longest Repeating Character Replacement

Medium

76. Minimum Window Substring

Hard

-
-
-

Stack#

-

Array & Hashing

- - - - - - - - - - - -

Problem Name

Difficulty

20. Valid Parentheses

Easy

-
- -
-

Linked List#

-

Array & Hashing

- - - - - - - - - - - - - - - - - - - - - - - - - - -

Problem Name

Difficulty

206. Reverse Linked List

Easy

21. Merge Two Sorted Lists

Easy

143. Reorder List

Medium

19. Remove Nth Node From End of List

Medium

141. Linked List Cycle

Medium

23. Merge K Sorted Lists

Hard

-
-
-

Trees#

-

Array & Hashing

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Problem Name

Difficulty

226. Invert Binary Tree

Easy

104. Maximum Depth of Binary Tree

Easy

100. Same Tree

Easy

572. Subtree of Another Tree

Easy

235. Lowest Common Ancestor of a Binary Search Tree

Easy

102. Binary Tree Level Order Traversal

Medium

98. Validate Binary Search Tree

Medium

230. Kth Smallest Element In a BST

Medium

105. Construct Binary Tree From Preorder And Inorder Traversal

Medium

124. Binary Tree Maximum Path Sum

Hard

297. Serialize And Deserialize Binary Tree

Hard

-
-
-

Tries#

-

Array & Hashing

- - - - - - - - - - - - - - - - - -

Problem Name

Difficulty

208. Implement Trie Prefix Tree

Medium

211. Design Add And Search Words Data Structure

Medium

212. Word Search II

Hard

-
-
-

Heap / Priority Queue#

-

Array & Hashing

- - - - - - - - - - - -

Problem Name

Difficulty

295. Find Median From Data Stream

Hard

-
-
-

Backtracking#

-

Array & Hashing

- - - - - - - - - - - - - - -

Problem Name

Difficulty

39. Combination Sum

Medium

79. Word Search

Medium

-
-
-

Graphs#

-

Array & Hashing

- - - - - - - - - - - - - - - - - - - - - - - - - - -

Problem Name

Difficulty

200. Number of Islands

Medium

133. Clone Graph

Medium

417. Pacific Atlantic Water Flow

Medium

207. Course Schedule

Medium

323. Number of Connected Components In An Undirected Graph

Medium

261. Graph Valid Tree

Medium

-
-
-

Advanced Graphs#

-

Array & Hashing

- - - - - - - - - - - -

Problem Name

Difficulty

269. Alien Dictionary

Hard

-
-
-

1-D Dynamic Programming#

-

Array & Hashing

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Problem Name

Difficulty

70. Climbing Stairs

Easy

198. House Robber

Easy

213. House Robber II

Medium

5. Longest Palindromic Substring

Medium

647. Palindromic Substrings

Medium

91. Decode Ways

Medium

322. Coin Change

Medium

152. Maximum Product Subarray

Medium

139. Word Break

Medium

300. Longest Increasing Subsequence

Medium

-
-
-

2-D Dynamic Programming#

-

Array & Hashing

- - - - - - - - - - - - - - -

Problem Name

Difficulty

62. Unique Paths

Medium

1143. Longest Common Subsequence

Medium

-
-
-

Greedy#

-

Array & Hashing

- - - - - - - - - - - - - - -

Problem Name

Difficulty

53. Maximum Subarray

Easy

55. Jump Game

Medium

-
-
-

Intervals#

-

Array & Hashing

- - - - - - - - - - - - - - - - - - - - - - - -

Problem Name

Difficulty

57. Insert Interval

Hard

56. Merge Intervals

Medium

435. Non Overlapping Intervals

Medium

252. Meeting Rooms

Easy

253. Meeting Rooms II

Medium

-
-
-

Math & Geometry#

-

Array & Hashing

- - - - - - - - - - - - - - - - - -

Problem Name

Difficulty

48. Rotate Image

Medium

54. Spiral Matrix

Medium

73. Set Matrix Zeroes

Medium

-
-
-

Bit Manipulation#

-

Array & Hashing

- - - - - - - - - - - - - - - - - - - - - - - -

Problem Name

Difficulty

191. Number of 1 Bits

Easy

338. Counting Bits

Medium

190. Reverse Bits

Easy

268. Missing Number

Easy

371. Sum of Two Integers

Medium

-
-
-
-

How to Use#

-
    -
  1. Clone or download this repository to your local machine.

  2. -
-
git clone https://github.com/mohsentabibian/LeetCode-Solutions/Blind-75-LeetCode.git
-
-
-
    -
  1. Navigate to the directory of the specific problem you want to solve.

  2. -
-
cd Blind-75-LeetCode/Problem-Directory
-
-
-
    -
  1. Open the problem’s directory to find its description, code template, and solution(s).

  2. -
  3. Solve the problem using your preferred programming language.

  4. -
  5. Check the solution(s) provided in the directory for reference and to compare your solution.

  6. -
-
-
-

Contribute#

-

If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements.

-
-
-

Resources#

-
    -
  • LeetCode: The official LeetCode website.

  • -
  • LeetCode Discuss: LeetCode’s discussion forum for each problem. You can find helpful hints and discussions here.

  • -
-
-
-

Disclaimer#

-

This repository is meant for educational purposes and to help individuals prepare for technical interviews. Please respect LeetCode’s terms of use and guidelines when using this repository.

-
-
-

Code of Conduct#

-

We have a Code of Conduct that we expect all contributors to adhere to. By participating in this project, you agree to follow this code.

-
-
-

Security Policy#

-

We take security seriously. Please review our Security Policy for information on reporting security vulnerabilities.

-

Happy coding!

-
-
-
-
- - - - -
- - - - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/SECURITY.html b/docs/_build/html/SECURITY.html deleted file mode 100644 index 1816264..0000000 --- a/docs/_build/html/SECURITY.html +++ /dev/null @@ -1,610 +0,0 @@ - - - - - - - - - - - - Security Policy — Hands-On Problem-Solving in Python: Mastering the Blind 75 LeetCode Challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Security Policy

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

Security Policy#

-
-

Reporting a Vulnerability#

-

We take the security of the Blind 75 LeetCode repository seriously. If you believe you have found a security vulnerability, please help us by following these steps:

-
    -
  1. Do Not Disclose Publicly: Please do not disclose the issue publicly until it has been addressed by our team.

  2. -
  3. Report Privately: Create a GitHub issue with the title “Security Vulnerability Report” and provide a detailed description of the vulnerability. You can use a sample report template as follows:

    -
    **Description**
    -A clear and concise description of the security vulnerability.
    -
    -**Steps to Reproduce**
    -Provide detailed steps on how to reproduce the vulnerability.
    -
    -**Expected Behavior**
    -Describe what you expected to happen.
    -
    -**Actual Behavior**
    -Describe what actually happened.
    -
    -**Additional Information**
    -Any additional information that can help us understand and reproduce the issue, such as environment details, configuration, or screenshots.
    -
    -
    -
  4. -
  5. Secure Communication: If the vulnerability involves sensitive data, please encrypt your communication with our PGP key. Contact us for our PGP key information.

  6. -
  7. Response: We will acknowledge your report within 5 business days and provide an estimated timeline for the resolution.

  8. -
  9. Fix and Disclosure: We will work to fix the issue promptly and privately. Once resolved, we will provide a security advisory and give credit to the reporter if desired.

  10. -
  11. Responsible Disclosure: We encourage responsible disclosure. Please do not take advantage of the vulnerability or attempt to exploit it for malicious purposes.

  12. -
-
-
-

Security Updates#

-

We are committed to promptly addressing and resolving any security issues. We recommend that you stay up-to-date with the latest releases of this repository, as they may include security updates and fixes.

-
-
-

Contact#

-

If you have any questions or need further assistance regarding security, you can contact us at mohsentabibian@gmail.com.

-
-
- - - - -
- - - - - - -
- -
-
-
- -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/docs/_build/html/_sources/01. Array Hashing/1. Two Sum.ipynb b/docs/_build/html/_sources/01. Array Hashing/1. Two Sum.ipynb deleted file mode 100644 index b3b517f..0000000 --- a/docs/_build/html/_sources/01. Array Hashing/1. Two Sum.ipynb +++ /dev/null @@ -1,211 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 100: Same Tree\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Same Tree problem on LeetCode, click here!](https://leetcode.com/problems/same-tree/)\n", - "\n", - "---\n", - "Given the roots of two binary trees `p` and `q`, write a function to check if they are the same or not.\n", - "\n", - "Two binary trees are considered the same if they are structurally identical, and the nodes have the same value.\n", - "\n", - "**Constraints**\n", - "\n", - "1. The number of nodes in both trees is in the range `[0, 100]`.\n", - "2. $-10^4$ <= `Node.val` <= $10^4$" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for a binary tree node.\n", - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " # Initialize a TreeNode with a value (val), left child, and right child.\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def isSameTree(p, q):\n", - " # Base case: If both p and q are None, the trees are the same.\n", - " if not p and not q:\n", - " return True\n", - " \n", - " # Base case: If either p or q is None (but not both), the trees are different.\n", - " if not p or not q:\n", - " return False\n", - " \n", - " # Check if the values of the current nodes (p.val and q.val) are equal.\n", - " if p.val != q.val:\n", - " return False\n", - " \n", - " # Recursively check the left and right subtrees of p and q.\n", - " # If both subtrees are the same, the entire trees are the same.\n", - " return isSameTree(p.left, q.left) and isSameTree(p.right, q.right)" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "In this code, we define a `TreeNode` class to represent binary tree nodes and a `isSameTree` function to check if two binary trees are the same. The function uses recursive traversal to compare the trees' structures and values.\n", - "\n", - "1. We start by defining a `TreeNode` class, which represents a node in a binary tree. Each node has a `val` (the node's value), a `left` child, and a right child. This class will help us create and work with binary trees.\n", - "2. Next, we define the `isSameTree` function, which checks if two binary trees (`p` and `q`) are the same.\n", - " + The base case for the recursion is when both `p` and `q` are `None`. In this case, they are considered the same, so we return `True`.\n", - " + If either `p` or `q` is `None` (but not both), they cannot be the same, so we return `False`.\n", - " + If the values of the current nodes `p.val` and `q.val` are not equal, we return `False` because the trees cannot be the same.\n", - " + Finally, we recursively check the left and right subtrees of `p` and `q` to see if they are the same." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "### Example 1\n", - "\n", - "#Input: `p = [1,2,3]`, `q = [1,2,3]`\n", - "\n", - "p1 = TreeNode(1, TreeNode(2), TreeNode(3))\n", - "q1 = TreeNode(1, TreeNode(2), TreeNode(3))\n", - "print(isSameTree(p1, q1)) " - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "### Example 2\n", - "\n", - "#Input: `p = [1,2]`, `q = [1,null,2]`\n", - "\n", - "p2 = TreeNode(1, TreeNode(2), None)\n", - "q2 = TreeNode(1, None, TreeNode(2))\n", - "print(isSameTree(p2, q2))" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "5897c29d-26f8-486a-878c-43c09ff25ce4", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "### Example 3\n", - "\n", - "#Input: p = [1,2,1], q = [1,1,2]\n", - "\n", - "p3 = TreeNode(1, TreeNode(2), TreeNode(1))\n", - "q3 = TreeNode(1, TreeNode(1), TreeNode(2))\n", - "print(isSameTree(p3, q3))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "**Time Complexity**\n", - "\n", - "The time complexity of the `isSameTree` function can be analyzed as follows:\n", - "\n", - "In the worst case, the function needs to visit every node in both trees once to determine if they are the same.\n", - "Since each node is visited exactly once, the time complexity is $O(n)$, where $n$ is the total number of nodes in the input trees.\n", - "\n", - "**Space Complexity**\n", - "The space complexity of the `isSameTree` function can be analyzed as follows:\n", - "\n", - "The space used by the function's call stack during recursion is proportional to the maximum depth of the binary trees.\n", - "In the worst case, when the trees are completely unbalanced (all nodes form a single branch), the maximum depth will be $n$, where $n$ is the total number of nodes in the input trees.\n", - "Therefore, the space complexity is $O(n)$ due to the recursive call stack.\n", - "In addition to the call stack, there is a small constant amount of space used for variables and comparisons within each recursive call, but this space is not significant in terms of the overall space complexity.\n", - "\n", - "**In summary:**\n", - "\n", - "+ Time Complexity: $O(n)$ where $n$ is the total number of nodes in the input trees.\n", - "+ Space Complexity: $O(n)$ due to the recursive call stack." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/01. Array Hashing/128. Longest Consecutive Sequence.ipynb b/docs/_build/html/_sources/01. Array Hashing/128. Longest Consecutive Sequence.ipynb deleted file mode 100644 index a77a03d..0000000 --- a/docs/_build/html/_sources/01. Array Hashing/128. Longest Consecutive Sequence.ipynb +++ /dev/null @@ -1,209 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 128. Longest Consecutive Sequence\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Longest Consecutive Sequence problem on LeetCode, click here!](https://leetcode.com/problems/longest-consecutive-sequence/)\n", - "\n", - "---\n", - "\n", - "Given an unsorted array of integers `nums`, return *the length of the longest consecutive elements sequence.*\n", - "\n", - "You must write an algorithm that runs in `O(n)` time.\n", - "\n", - "*Constraints:**\n", - "- 0 <= `nums.length` <= $10^5$\n", - "- $-10^9$ <= `nums[i]` <= $10^9$\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 58, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def longestConsecutive(nums):\n", - " if not nums:\n", - " return 0\n", - "\n", - " num_set = set(nums)\n", - " max_length = 0\n", - "\n", - " for num in num_set:\n", - " if num - 1 not in num_set:\n", - " current_num = num\n", - " current_length = 1\n", - "\n", - " while current_num + 1 in num_set:\n", - " current_num += 1\n", - " current_length += 1\n", - "\n", - " max_length = max(max_length, current_length)\n", - "\n", - " return max_length" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start by defining the `longestConsecutive` function that takes the `nums` array as input.\n", - "\n", - "2. We check if the `nums` array is empty. If it's empty, there are no consecutive elements, so we return 0.\n", - "\n", - "3. We create a Python set called `num_set` and insert all elements from the `nums` array into it. Using a set allows us to efficiently check for the existence of elements in O(1) time.\n", - "\n", - "4. We initialize a variable `max_length` to 0. This variable will keep track of the maximum length of consecutive elements sequence found.\n", - "\n", - "5. We iterate through the elements of the `num_set`. For each element `num`, we check if `num - 1` exists in the `num_set`. If it doesn't exist, it means `num` is the starting element of a potential consecutive sequence.\n", - "\n", - "6. Inside the loop, we initialize two variables: `current_num` to the current element `num` and `current_length` to 1. We start with a length of 1 because `num` itself is part of the sequence.\n", - "\n", - "7. We then enter a while loop that continues as long as `current_num + 1` exists in the `num_set`. This means we are incrementing the consecutive sequence.\n", - "\n", - "8. Inside the while loop, we increment `current_num` by 1 and also increment `current_length` by 1 to account for the next consecutive element.\n", - "\n", - "9. We compare `current_length` with the `max_length` and update `max_length` if the current sequence is longer.\n", - "\n", - "10. After the while loop, we move to the next element in the outer loop and repeat the process.\n", - "\n", - "11. Finally, we return the `max_length` as the result, which represents the length of the longest consecutive elements sequence in the `nums` array.\n", - "\n", - "The key idea here is to use a set to efficiently check for the existence of elements and to iterate through the elements, considering each element as the potential start of a consecutive sequence. By doing this, we can find the longest consecutive sequence in O(n) time complexity, where n is the number of elements in the array." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 59, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "nums1 = [100, 4, 200, 1, 3, 2]\n", - "print(longestConsecutive(nums1))" - ] - }, - { - "cell_type": "code", - "execution_count": 60, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "9\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "nums2 = [0, 3, 7, 2, 5, 8, 4, 6, 0, 1]\n", - "print(longestConsecutive(nums2)) " - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "The code is designed to run in O(n) time complexity, where n is the number of elements in the `nums` array. Here's the breakdown:\n", - "\n", - "1. Constructing the `num_set` by inserting all elements from `nums` into it takes O(n) time because we perform an insertion operation for each element in `nums`.\n", - "\n", - "2. The main loop iterates through the elements in `num_set`. In the worst case, each element is visited only once, so the loop itself takes O(n) time.\n", - "\n", - "3. Within the loop, we have a while loop that may also take O(n) time in the worst case. However, this while loop is nested inside the main loop, so its overall time complexity remains O(n).\n", - "\n", - "Therefore, the overall time complexity of the code is O(n).\n", - "\n", - "**Space Complexity:**\n", - "The space complexity of the code is determined by the space used by the `num_set` and a few additional variables. Here's the breakdown:\n", - "\n", - "1. `num_set` is a set that stores the unique elements from `nums`. In the worst case, it can store all n elements from `nums`, so the space complexity is O(n).\n", - "\n", - "2. The additional variables used, such as `max_length`, `current_num`, and `current_length`, have constant space requirements and do not depend on the size of the input array.\n", - "\n", - "Therefore, the overall space complexity of the code is O(n) due to the space used by the `num_set`." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. Write an algorithm that not only returns the length of the longest consecutive elements sequence but also returns the actual consecutive sequence itself.\n", - "\n", - "2. Extend the problem to allow elements to be considered consecutive if they are within a certain absolute difference (e.g., less than or equal to k) instead of exactly 1. Write an algorithm that finds the longest such sequence and runs in O(n) time." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/01. Array Hashing/217. Contains Duplicate.ipynb b/docs/_build/html/_sources/01. Array Hashing/217. Contains Duplicate.ipynb deleted file mode 100644 index 57bb55d..0000000 --- a/docs/_build/html/_sources/01. Array Hashing/217. Contains Duplicate.ipynb +++ /dev/null @@ -1,218 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 217. Contains Duplicate\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Contains Duplicate problem on LeetCode, click here!](https://leetcode.com/problems/contains-duplicate/)\n", - "\n", - "---\n", - "\n", - "Given an integer array `nums`, return `true` if any value appears **at least twice** in the array, and return `false` if every element is distinct.\n", - "\n", - "**Constraints:**\n", - "- 1 <= `nums.length` <= $10^5$\n", - "- $-10^9$ <= `nums[i]` <= $10^9$\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def containsDuplicate(nums):\n", - " # Create an empty set to store unique elements\n", - " unique_elements = set()\n", - " \n", - " # Iterate through the array\n", - " for num in nums:\n", - " # If the element is already in the set, return True\n", - " if num in unique_elements:\n", - " return True\n", - " # Otherwise, add it to the set\n", - " else:\n", - " unique_elements.add(num)\n", - " \n", - " # If the loop completes without finding duplicates, return False\n", - " return False" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. The `containsDuplicate` function takes a single argument, `nums`, which is the input integer array.\n", - "\n", - "2. Inside the function, an empty set called `unique_elements` is created. This set will be used to keep track of unique elements in the input array.\n", - "\n", - "3. The function then iterates through the input array `nums` using a `for` loop.\n", - "\n", - "4. For each element `num` in the array, it checks whether `num` is already in the `unique_elements` set using the `if num in unique_elements:` condition.\n", - "\n", - "5. If `num` is already in the set, it means there is a duplicate element in the array, and the function immediately returns `True`.\n", - "\n", - "6. If `num` is not in the set, it is added to the `unique_elements` set using `unique_elements.add(num)`.\n", - "\n", - "7. The loop continues to the next element, and the process repeats.\n", - "\n", - "8. If the loop completes without finding any duplicates, it means that all elements in the array are distinct, and the function returns `False`.\n", - "\n", - "The code efficiently utilizes a set data structure to keep track of unique elements while iterating through the array, allowing it to quickly detect duplicate elements. This code meets the problem's requirements and constraints, as explained earlier." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "nums1 = [1, 2, 3, 1]\n", - "print(containsDuplicate(nums1))" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 2\n", - "nums2 = [1, 2, 3, 4]\n", - "print(containsDuplicate(nums2))" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "e191cf7e-95f9-4e5c-a99b-146c2a779c0b", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 3\n", - "nums3 = [1, 1, 1, 3, 3, 4, 3, 2, 4, 2]\n", - "print(containsDuplicate(nums3))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code for the \"Contains Duplicate\" problem:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The primary operation that affects the time complexity is the `for` loop that iterates through the input array `nums`. In the worst case, the loop will iterate through all `n` elements of the array, where `n` is the length of the input array.\n", - "\n", - "- Iterating through the array: O(n)\n", - "\n", - "Inside the loop, we perform two operations:\n", - "\n", - "1. Checking whether an element exists in the `unique_elements` set (`if num in unique_elements`). This operation has an average time complexity of O(1) for a set.\n", - "2. Adding an element to the `unique_elements` set (`unique_elements.add(num)`), which also has an average time complexity of O(1) for a set.\n", - "\n", - "Since these operations are performed for each element in the array, the overall time complexity remains O(n).\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity is determined by the additional data structures used in the code, which are the `unique_elements` set.\n", - "\n", - "- `unique_elements` set: This set stores unique elements from the input array. In the worst case, if all elements in the input array are distinct, the set will store all `n` elements.\n", - "\n", - "Therefore, the space complexity is O(n) because, in the worst case, the set's size will grow linearly with the input array's size.\n", - "\n", - "**In summary**, the time complexity of the code is O(n), where `n` is the length of the input array, and the space complexity is also O(n) in the worst case. This code is efficient and meets the constraints of the problem." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **K Duplicates:** Modify the problem to return `true` if there are exactly K duplicate elements in the array. Write a function that takes an additional integer parameter K and returns `true` if there are exactly K duplicates.\n", - "2. **Frequency Count:** Write a function that returns a list of all the elements that appear more than once in the array, along with their frequencies." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/01. Array Hashing/238. Product of Array Except Self.ipynb b/docs/_build/html/_sources/01. Array Hashing/238. Product of Array Except Self.ipynb deleted file mode 100644 index 1ff9a9c..0000000 --- a/docs/_build/html/_sources/01. Array Hashing/238. Product of Array Except Self.ipynb +++ /dev/null @@ -1,197 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 238. Product of Array Except Self\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Product of Array Except Self problem on LeetCode, click here!](https://leetcode.com/problems/product-of-array-except-self/)\n", - "\n", - "---\n", - "Given an integer array `nums`, return *an array `answer` such that `answer[i]` is equal to the product of all the elements of `nums` except `nums[i]`.*\n", - "\n", - "The product of any prefix or suffix of `nums` is **guaranteed** to fit in a **32-bit** integer.\n", - "\n", - "You must write an algorithm that runs in O(n) time and without using the division operation.\n", - "\n", - "Constraints:\n", - "- 2 <= `nums.length` <= $10^5$\n", - "- `-30 <= nums[i] <= 30`\n", - "- The product of any prefix or suffix of `nums` is **guaranteed** to fit in a **32-bit** integer.\n", - "\n", - "**Follow-up:** Can you solve the problem in O(1) extra space complexity? (The output array **does not** count as extra space for space complexity analysis.)\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def productExceptSelf(nums):\n", - " n = len(nums)\n", - " \n", - " # Initialize two arrays to store products to the left and right of each element\n", - " left_products = [1] * n\n", - " right_products = [1] * n\n", - " \n", - " # Calculate products to the left of each element\n", - " left_product = 1\n", - " for i in range(n):\n", - " left_products[i] = left_product\n", - " left_product *= nums[i]\n", - " \n", - " # Calculate products to the right of each element\n", - " right_product = 1\n", - " for i in range(n - 1, -1, -1):\n", - " right_products[i] = right_product\n", - " right_product *= nums[i]\n", - " \n", - " # Calculate the final answer using left and right products\n", - " answer = [left_products[i] * right_products[i] for i in range(n)]\n", - " \n", - " return answer" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. `n` is initialized as the length of the `nums` array.\n", - "2. Two arrays, `left_products` and `right_products`, are created, each with a length of `n` and filled with ones initially.\n", - "3. `left_product` is initialized to 1.\n", - "4. A loop iterates through the `nums` array, from left to right. For each element at index `i`, it stores the product of all elements to its left (including itself) in the `left_products` array and updates `left_product` accordingly.\n", - "5. `right_product` is initialized to 1.\n", - "6. Another loop iterates through the `nums` array in reverse order, from right to left. For each element at index `i`, it stores the product of all elements to its right (including itself) in the `right_products` array and updates `right_product`.\n", - "7. The final `answer` list is constructed by multiplying corresponding elements from the `left_products` and `right_products` arrays for each index `i`.\n", - "8. The function returns the `answer` list, which contains the desired results.\n", - "\n", - "Overall, this algorithm efficiently computes the product of all elements except the current element, as required. It runs in O(n) time complexity and uses O(n) extra space, which is within the problem's constraints." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[24, 12, 8, 6]\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "nums = [1,2,3,4]\n", - "result1 = productExceptSelf(nums)\n", - "print(result1)" - ] - }, - { - "cell_type": "code", - "execution_count": 53, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[0, 0, 9, 0, 0]\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "nums = [-1,1,0,-3,3]\n", - "result2 = productExceptSelf(nums)\n", - "print(result2)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "1. The first loop iterates through the `nums` array to calculate the products to the left of each element. This loop runs in O(n) time, where n is the length of the `nums` array.\n", - "2. The second loop also iterates through the `nums` array in reverse order to calculate the products to the right of each element. This loop also runs in O(n) time.\n", - "3. The final loop constructs the `answer` list by multiplying elements from the `left_products` and `right_products` arrays. This loop runs in O(n) time.\n", - "\n", - "Since all the loops are independent and sequential, the overall time complexity is O(n).\n", - "\n", - "**Space Complexity:**\n", - "1. Two additional arrays, `left_products` and `right_products`, are created with a length of `n`, where `n` is the length of the `nums` array. Therefore, these arrays consume O(n) extra space.\n", - "2. The `left_product` and `right_product` variables are used to keep track of the product to the left and right of each element, respectively. These variables occupy O(1) extra space.\n", - "3. The `answer` list, which contains the final results, also consumes O(n) space, but it's not counted toward the extra space complexity analysis as per the problem's constraints.\n", - "\n", - "Overall, the space complexity is O(n) for this solution." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Handle Zeros in the Input**: Modify the solution to handle cases where the input array contains zeros. For example, if `nums = [0, 1, 2, 3, 0]`, the output should be `[0, 0, 0, 0, 0]` because any element multiplied by zero results in zero.\n", - "\n", - "2. **In-Place Modification**: Attempt to solve the problem with in-place modification of the `nums` array, where the output is stored directly in the input array without using any additional space." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/01. Array Hashing/242. Valid Anagram.ipynb b/docs/_build/html/_sources/01. Array Hashing/242. Valid Anagram.ipynb deleted file mode 100644 index d165899..0000000 --- a/docs/_build/html/_sources/01. Array Hashing/242. Valid Anagram.ipynb +++ /dev/null @@ -1,198 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 242. Valid Anagram\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Valid Anagram problem on LeetCode, click here!](https://leetcode.com/problems/valid-anagram/)\n", - "\n", - "---\n", - "Given two strings `s` and `t`, return `true` if `t` is an anagram of `s`, and `false` otherwise.\n", - "\n", - "An **Anagram** is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.\n", - "\n", - "**Constraints:**\n", - "- 1 <= `s.length`, `t.length` <= $5 * 10^4$\n", - "- `s` and `t` consist of lowercase English letters.\n", - "\n", - "**Follow-up:** What if the inputs contain Unicode characters? How would you adapt your solution to such a case?\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def isAnagram(s: str, t: str) -> bool:\n", - " # Check if the lengths of s and t are not equal\n", - " if len(s) != len(t):\n", - " return False\n", - "\n", - " # Create dictionaries to store character frequencies for s and t\n", - " countS, countT = {}, {}\n", - "\n", - " # Count character frequencies in s\n", - " for i in range(len(s)):\n", - " countS[s[i]] = 1 + countS.get(s[i], 0)\n", - "\n", - " # Count character frequencies in t\n", - " for i in range(len(t)):\n", - " countT[t[i]] = 1 + countT.get(t[i], 0)\n", - "\n", - " # Check if the character frequencies in s and t are the same\n", - " return countS == countT" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. The code defines a class called `Solution` with a method `isAnagram` that takes two input strings, `s` and `t`, and returns a boolean (`True` or `False`) based on whether `t` is an anagram of `s`.\n", - "\n", - "2. The first check performed in the method is whether the lengths of `s` and `t` are equal. If they are not equal, it immediately returns `False` because strings of different lengths cannot be anagrams of each other.\n", - "\n", - "3. Two dictionaries, `countS` and `countT`, are created to store the frequency of characters in `s` and `t`, respectively. These dictionaries will be used to count the occurrences of each character in the strings.\n", - "\n", - "4. The code then enters a loop to iterate through each character in string `s` using a `for` loop. Inside the loop, it updates the `countS` dictionary. The line `countS[s[i]] = 1 + countS.get(s[i], 0)` increments the count of character `s[i]` in `countS` by 1. If the character is not already in the dictionary, it initializes the count to 1.\n", - "\n", - "5. Similarly, the code iterates through each character in string `t` and updates the `countT` dictionary in the same way.\n", - "\n", - "6. After counting the character frequencies in both strings, the code compares the two dictionaries using `countS == countT`. If the dictionaries are equal, it means that both strings have the same character frequencies, and therefore, `t` is an anagram of `s`. In this case, the method returns `True`.\n", - "\n", - "7. If the dictionaries are not equal, the method returns `False`, indicating that `t` is not an anagram of `s`.\n", - "\n", - "In summary, this code efficiently determines whether two input strings are anagrams by counting the character frequencies in each string using dictionaries and then comparing these counts. If the character frequencies match, the strings are considered anagrams, and the method returns `True`; otherwise, it returns `False`." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "s = \"anagram\"\n", - "t = \"nagaram\"\n", - "print(isAnagram(s, t))" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 2\n", - "s = \"rat\"\n", - "t = \"car\"\n", - "print(isAnagram(s, t))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. The code first checks whether the lengths of the input strings `s` and `t` are equal, which takes constant time. This check has a time complexity of O(1).\n", - "\n", - "2. The code then iterates through both strings, `s` and `t`, once to count the character frequencies. Since both strings have a maximum length of 5 * 10^4, the worst-case scenario is that the code iterates through 5 * 10^4 characters in each string. This results in a linear time complexity of O(n), where n is the length of the longer of the two input strings (`s` or `t`).\n", - "\n", - "3. Finally, the code compares the two dictionaries `countS` and `countT` to check if the character frequencies match. This comparison takes O(n) time in the worst case, where n is the length of the longer string.\n", - "\n", - "Overall, the time complexity of the code is O(n), where n is the length of the longer input string.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. The code uses two dictionaries, `countS` and `countT`, to store the character frequencies of the input strings `s` and `t`. In the worst case, both dictionaries can contain all unique characters from the input strings. Since the input strings can have a maximum length of 5 * 10^4, the space complexity for these dictionaries is O(5 * 10^4) or simply O(n), where n is the length of the longer input string.\n", - "\n", - "2. The code uses a few additional variables for bookkeeping, but these variables have constant space requirements and do not depend on the input size. Therefore, they do not significantly impact the overall space complexity.\n", - "\n", - "**In summary**, the space complexity of the code is O(n), where n is the length of the longer input string." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Anagram Chains**: Given a list of words, find the longest chain of anagrams, where each word in the chain is an anagram of the previous word. For example, given [\"bat\", \"tab\", \"cat\", \"tac\", \"dog\"], the longest anagram chain is [\"bat\", \"tab\", \"cat\", \"tac\"].\n", - "\n", - "2. **Minimum Deletions to Make Anagrams**: Given two strings `s` and `t`, find the minimum number of character deletions required in both strings to make them anagrams of each other. For example, if `s = \"hello\"` and `t = \"billion\"`, you can remove the characters \"heo\" from `s` and \"billi\" from `t` to make them anagrams (\"lo\" and \"on\" are left in the two strings)." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/01. Array Hashing/347. Top K Frequent Elements.ipynb b/docs/_build/html/_sources/01. Array Hashing/347. Top K Frequent Elements.ipynb deleted file mode 100644 index ecfa494..0000000 --- a/docs/_build/html/_sources/01. Array Hashing/347. Top K Frequent Elements.ipynb +++ /dev/null @@ -1,215 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 347. Top K Frequent Elements\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Top K Frequent Elements problem on LeetCode, click here!](https://leetcode.com/problems/top-k-frequent-elements/)\n", - "\n", - "---\n", - "Given an integer array `nums` and an integer `k`, return the `k` most frequent elements. You may return the answer in **any order**.\n", - "\n", - "Constraints:\n", - "- 1 <= `nums.length` <= $10^5$\n", - "- $-10^4$ <= `nums[i]` <= $10^4$\n", - "- `k` is in the range `[1, the number of unique elements in the array]`.\n", - "- It is **guaranteed** that the answer is **unique**.\n", - "\n", - "**Follow-up:** Your algorithm's time complexity must be better than $O(n\\ log\\ n)$, where n is the array's size.\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def topKFrequent(nums, k):\n", - " # Create a dictionary to store the frequency of each element\n", - " count = {}\n", - " # Create a list of lists to store elements with the same frequency\n", - " frequency = [[] for i in range(len(nums) + 1)]\n", - "\n", - " # Count the frequency of each element in nums\n", - " for n in nums:\n", - " count[n] = 1 + count.get(n, 0)\n", - "\n", - " # Place elements in the freq list according to their frequency\n", - " for n, c in count.items():\n", - " frequency[c].append(n)\n", - "\n", - " res = []\n", - " # Traverse freq list from the end (higher frequencies)\n", - " for i in range(len(frequency) - 1, 0, -1):\n", - " for n in frequency[i]:\n", - " res.append(n)\n", - " if len(res) == k:\n", - " return res" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. `def topKFrequent(nums, k):`: This is a function that takes two arguments: `nums`, which is the input array of integers, and `k`, which is the number of most frequent elements to return.\n", - "\n", - "2. `count = {}`: This dictionary `count` will be used to store the frequency of each unique element in the `nums` array. The keys are elements from the input array, and the values are their corresponding frequencies.\n", - "\n", - "3. `frequency = [[] for i in range(len(nums) + 1)]`: This creates a list of empty lists called `frequency`. It's used to store elements based on their frequencies, similar to the `freq` list in the previous code. The size of this list is set to be one greater than the length of the input `nums`.\n", - "\n", - "4. `for n in nums:`: This loop iterates through each element `n` in the input `nums` array.\n", - "\n", - "5. `count[n] = 1 + count.get(n, 0)`: This line counts the frequency of each element `n` in the `nums` array. It uses the `count.get(n, 0)` method to retrieve the current count of `n` from the `count` dictionary. If `n` is not in the dictionary, it defaults to 0. It then increments the count by 1.\n", - "\n", - "6. After the above loop, the `count` dictionary will contain counts of each unique element in the `nums` array.\n", - "\n", - "7. `for n, c in count.items():`: This loop iterates through the items (key-value pairs) of the `count` dictionary. `n` represents the element, and `c` represents its frequency.\n", - "\n", - "8. `frequency[c].append(n)`: This line places the element `n` into the bucket corresponding to its frequency `c`. Buckets are represented by the `frequency` list. For example, if an element `n` has a frequency of 3, it will be added to `frequency[3]`.\n", - "\n", - "9. After this loop, the `frequency` list will contain buckets of elements grouped by their frequencies.\n", - "\n", - "10. `res = []`: This list `res` will be used to store the k most frequent elements.\n", - "\n", - "11. `for i in range(len(freq) - 1, 0, -1):`: This loop iterates in reverse order through the `frequency` list, starting from the highest frequency and going down to 1. Note that there is a typo here; it should be `frequency` instead of `freq`.\n", - "\n", - "12. `for n in frequency[i]:`: For each element `n` in the current bucket (i.e., elements with frequency `i`), it appends `n` to the result list `res`.\n", - "\n", - "13. `if len(res) == k:`: Once `res` contains k elements, the code exits and returns the result.\n", - "\n", - "The code efficiently finds the k most frequent elements in the input array without using sorting, similar to the previous explanation, with the only difference being the variable names (e.g., `frequency` instead of `freq`)." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 48, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 2]\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "nums = [1,1,1,2,2,3]\n", - "k = 2\n", - "result1 = topKFrequent(nums, k)\n", - "print(result1)" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1]\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "nums = [1]\n", - "k = 1\n", - "result2 = topKFrequent(nums, k)\n", - "print(result2)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "1. The first loop that counts the frequency of elements by iterating through `nums` has a time complexity of O(n), where n is the number of elements in the input array `nums`.\n", - "\n", - "2. The second loop iterates through the keys in the `count` dictionary, which has at most `k` unique elements (as per the constraints). Therefore, the second loop also has a time complexity of O(k).\n", - "\n", - "3. The third loop iterates through the `frequency` list, which has a length equal to the maximum frequency of elements in `nums`. In the worst case, this loop can have a time complexity of O(n), where n is the number of elements in `nums`.\n", - "\n", - "Overall, the dominant factor in terms of time complexity is the loop that iterates through the `count` dictionary. So, the total time complexity of the code is O(n + k).\n", - "\n", - "**Space Complexity:**\n", - "1. The `count` dictionary stores the frequency of each unique element in `nums`. In the worst case, it can have at most `k` unique elements, so the space complexity for `count` is O(k).\n", - "\n", - "2. The `frequency` list is used to store elements grouped by their frequencies. It has a length of `len(nums) + 1`, which can be at most 105 based on the constraints. Therefore, the space complexity for `frequency` is O(105).\n", - "\n", - "3. The `res` list stores the k most frequent elements, which can be at most `k` elements, so the space complexity for `res` is O(k).\n", - "\n", - "**In summary**, the space complexity is dominated by the `count` dictionary and the `frequency` list, both of which have a space complexity of O(k + 105)." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Optimized k Most Frequent Elements:** Modify the code to find the k most frequent elements in an array while ensuring that the time complexity is O(n + klogk). You can use a priority queue (heap) to achieve this.\n", - "\n", - "2. **Handling Duplicate Frequencies:** Extend the code to handle cases where multiple elements have the same frequency and are among the k most frequent elements. Ensure that the output contains exactly k elements." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/01. Array Hashing/49. Group Anagrams.ipynb b/docs/_build/html/_sources/01. Array Hashing/49. Group Anagrams.ipynb deleted file mode 100644 index afe89ec..0000000 --- a/docs/_build/html/_sources/01. Array Hashing/49. Group Anagrams.ipynb +++ /dev/null @@ -1,229 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 49. Group Anagrams\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Group Anagrams problem on LeetCode, click here!](https://leetcode.com/problems/group-anagrams/)\n", - "\n", - "---\n", - "Given an array of strings `strs`, group **the anagrams** together. You can return the answer in **any order**.\n", - "\n", - "An **Anagram** is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.\n", - "\n", - "**Constraints:**\n", - "- 1 <= `strs.length <= $10^4$\n", - "- `0 <= strs[i].length <= 100`\n", - "- `strs[i]` consists of lowercase English letters.\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "from collections import defaultdict\n", - "\n", - "\n", - "def groupAnagrams(strs):\n", - " ans = defaultdict(list)\n", - "\n", - " # Iterate through the list of input strings\n", - " for s in strs:\n", - " # Initialize a list to represent character counts for each character (a-z)\n", - " count = [0] * 26\n", - "\n", - " # Count the occurrences of each character in the current word\n", - " for c in s:\n", - " count[ord(c) - ord(\"a\")] += 1\n", - "\n", - " # Use a tuple of character counts as the key and append the word to the anagram group\n", - " ans[tuple(count)].append(s)\n", - "\n", - " # Convert the values (lists of anagrams) to a list of lists\n", - " return list(ans.values())" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. Inside the method, a `defaultdict` called `ans` is created to store anagram groups. This dictionary will have a list as its default value, meaning that each key in the dictionary will be associated with an empty list by default.\n", - "\n", - "2. The code then iterates through the list of input strings, `strs`, using a `for` loop. For each word `s` in `strs`, it performs the following steps:\n", - "\n", - " - It initializes a list `count` of length 26, where each element represents the count of a specific character (a-z) in the word `s`.\n", - "\n", - " - The code then iterates through the characters of `s`. For each character `c`, it increments the corresponding count in the `count` list based on its ASCII value.\n", - "\n", - " - After counting the characters in `s`, it converts the `count` list into a tuple `tuple(count)` to use as a key for the `ans` dictionary.\n", - "\n", - " - It appends the word `s` to the list associated with the key (tuple) in the `ans` dictionary. This groups all anagrams of the same word together under the same key.\n", - "\n", - "3. After processing all words in `strs`, the code converts the values of the `ans` dictionary (which are lists of anagrams) to a list of lists using the `list()` constructor.\n", - "\n", - "4. Finally, the code returns the list of anagram groups, which is the result of grouping the anagrams in the input list.\n", - "\n", - "In summary, the code efficiently groups anagrams together by counting the characters in each word and using a dictionary to store them under the same key. The result is a list of lists, where each inner list represents a group of anagrams." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[['eat', 'tea', 'ate'], ['tan', 'nat'], ['bat']]\n" - ] - } - ], - "source": [ - "# Example 1: Group anagrams from a list of words\n", - "strs1 = [\"eat\", \"tea\", \"tan\", \"ate\", \"nat\", \"bat\"]\n", - "result1 = groupAnagrams(strs1)\n", - "print(result1)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[['']]\n" - ] - } - ], - "source": [ - "# Example 2: Group anagrams from a list with an empty string\n", - "strs2 = [\"\"]\n", - "result2 = groupAnagrams(strs2)\n", - "print(result2)" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "id": "c8367e2a-e7d5-4e18-8235-2870e341a04b", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[['a']]\n" - ] - } - ], - "source": [ - "# Example 3: Group anagrams from a list with a single word\n", - "strs3 = [\"a\"]\n", - "result3 = groupAnagrams(strs3)\n", - "print(result3)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `groupAnagrams` method:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. First, we create an instance of the `Solution` class, which is an O(1) operation.\n", - "\n", - "2. Inside the `groupAnagrams` method, we iterate through the list of input strings `strs` once in a loop:\n", - " - For each word in `strs`, we perform character counting, which is done in O(K) time, where K is the maximum length of a word in the list.\n", - "\n", - "3. The overall time complexity of the method is O(N * K), where N is the number of words in the input list `strs`, and K is the maximum length of a word in `strs`.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. We use a `defaultdict` called `ans` to store the anagram groups. In the worst case, each word belongs to a distinct anagram group, so the space complexity for `ans` is O(N).\n", - "\n", - "2. Within the loop, we create a `count` list of length 26 to store character counts for each word. This is a fixed-size list and does not depend on the input size, so it has a constant space complexity of O(26), which is effectively O(1).\n", - "\n", - "3. The space used for other variables is also constant and does not depend on the input size.\n", - "\n", - "4. The final result, `result`, is a list of lists that contains the grouped anagrams. In the worst case, each word is a distinct anagram group, so the space complexity for `result` is O(N).\n", - "\n", - "5. The overall space complexity of the method is O(N) due to the space used by `ans` and `result`. The space used by the `count` list and other variables is constant and does not significantly affect the overall space complexity.\n", - "\n", - "**In summary,** the time complexity of the `groupAnagrams` method is O(N * K), and the space complexity is O(N), where N is the number of words in the input list `strs`, and K is the maximum length of a word in `strs`." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Anagramic Palindromes**: Given a list of strings, find all the groups of anagrams where each group contains words that can be rearranged into a palindrome. For example, in the list [\"bat\", \"tab\", \"act\", \"tac\", \"dog\"], there are two groups: [\"bat\", \"tab\", \"act\", \"tac\"] and [\"dog\"].\n", - "\n", - "2. **Largest Anagram Group**: Given a list of strings, find the largest group of anagrams. Return the list of anagrams in that group. If there are multiple largest groups, return all of them." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/01. Array Hashing/659. Encode and Decode Strings.ipynb b/docs/_build/html/_sources/01. Array Hashing/659. Encode and Decode Strings.ipynb deleted file mode 100644 index 037c476..0000000 --- a/docs/_build/html/_sources/01. Array Hashing/659. Encode and Decode Strings.ipynb +++ /dev/null @@ -1,204 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 659· Encode and Decode Strings\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Encode and Decode Strings problem on LintCode, click here!](https://www.lintcode.com/problem/659/)\n", - "\n", - "---\n", - "Design an algorithm to encode a list of strings to a string. The encoded string is then sent over the network and is decoded back to the original list of strings.\n", - "\n", - "Please implement `encode` and `decode`.\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class Codec:\n", - "\n", - " def encode(self, strs):\n", - " \"\"\"Encodes a list of strings to a single string.\n", - " \n", - " :type strs: List[str]\n", - " :rtype: str\n", - " \"\"\"\n", - " encoded = \"\"\n", - " for s in strs:\n", - " encoded += s.replace(':', '::') + ':;'\n", - " return encoded\n", - "\n", - " def decode(self, s):\n", - " \"\"\"Decodes a single string to a list of strings.\n", - " \n", - " :type s: str\n", - " :rtype: List[str]\n", - " \"\"\"\n", - " decoded = []\n", - " i = 0\n", - " while i < len(s):\n", - " end = s.find(':;', i)\n", - " if end == -1:\n", - " end = len(s)\n", - " decoded.append(s[i:end].replace('::', ':'))\n", - " i = end + 2\n", - " return decoded" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We define a class called `Codec` to encapsulate the encoding and decoding operations for a list of strings.\n", - "\n", - "2. In the `encode` method, we take a list of strings (`strs`) as input and return a single encoded string. The encoding process involves concatenating the strings together with a delimiter `:;`. We iterate through each string in the input list, replace any occurrence of `:` with `::` (to avoid conflicts with the delimiter), and then append `:;` to indicate the end of that string.\n", - "\n", - "3. In the `decode` method, we take an encoded string (`s`) as input and return a list of strings. The decoding process involves splitting the encoded string using the `:;` delimiter. We start from the beginning of the encoded string (`i = 0`) and repeatedly find the next occurrence of `:;`. We extract the substring between the current position (`i`) and the next delimiter (`end`). Before adding it to the result list, we replace any `::` with `:` to revert the encoding. We then update the current position `i` to be after the delimiter, so we can find the next substring in the next iteration.\n", - "\n", - "4. Finally, we create an instance of the `Codec` class and test it with two examples:\n", - "\n", - "By using the `:;` delimiter and handling the `::` escaping, this code can encode and decode lists of strings, preserving the original content even if it contains colons or the delimiter itself." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 55, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['lint', 'code', 'love', 'you']\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "codec = Codec()\n", - "\n", - "input1 = [\"lint\", \"code\", \"love\", \"you\"]\n", - "encoded1 = codec.encode(input1)\n", - "decoded1 = codec.decode(encoded1)\n", - "print(decoded1)" - ] - }, - { - "cell_type": "code", - "execution_count": 57, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['we', 'say', ':', 'yes']\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "codec = Codec() \n", - "\n", - "input2 = [\"we\", \"say\", \":\", \"yes\"]\n", - "encoded2 = codec.encode(input2)\n", - "decoded2 = codec.decode(encoded2)\n", - "print(decoded2) " - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `encode` and `decode` methods in the provided code.\n", - "\n", - "**Encode Method (`encode`):**\n", - "\n", - "- Time Complexity: O(n * m)\n", - " - Here, `n` is the number of strings in the input list `strs`, and `m` is the average length of these strings.\n", - " - In the worst case, for each string in the list, we iterate over its characters once to replace any colons (`:`) with double colons (`::`) and then append `:;`. This is done for each string in the list.\n", - "\n", - "- Space Complexity: O(n * m)\n", - " - The space complexity is also O(n * m) because we build the encoded string by concatenating the modified strings. In the worst case, the encoded string can be of the same length as the original strings.\n", - "\n", - "**Decode Method (`decode`):**\n", - "\n", - "- Time Complexity: O(n * m)\n", - " - Similar to the encode method, we iterate through the encoded string in the decode method. In the worst case, we may have to scan each character in the encoded string to find the `:;` delimiter.\n", - "\n", - "- Space Complexity: O(n * m)\n", - " - The space complexity of the decode method is also O(n * m) because we build the list of decoded strings, which can be of the same length as the encoded string.\n", - "\n", - "Overall, both the `encode` and `decode` methods have time and space complexities of O(n * m), where `n` is the number of strings in the input list, and `m` is the average length of these strings. The space complexity arises from storing the encoded or decoded strings, and the time complexity arises from iterating through the characters in these strings." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Multiple Delimiters**: Modify the code to allow for multiple delimiters, not just one. Each string could have its own delimiter, and the code should be able to handle this complexity.\n", - "\n", - "2. **Optimize Encoding**: Modify the `encode` method to achieve a more efficient encoding algorithm. Try to minimize the length of the encoded string while ensuring that it can be correctly decoded." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/01. Array Hashing/README.md b/docs/_build/html/_sources/01. Array Hashing/README.md deleted file mode 100644 index a331dab..0000000 --- a/docs/_build/html/_sources/01. Array Hashing/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# Array & Hashing Solutions - Blind 75 LeetCode Problems -![Array & Hashing Solutions](https://img.shields.io/badge/Array_&_Hashing_Solutions-blue)![Blind 75 LeetCode](https://img.shields.io/badge/Blind_75_LeetCode-Problems-blue?labelColor=red) - -This repository contains my solutions to Array & Hashing Problems from Blind 75 LeetCode problems. I've organized the solutions by categories for easier navigation and reference. Each problem solution is presented in Jupyter Notebook format (`.ipynb`). - - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [217. Contains Duplicate](https://github.com/mohsentabibian/LeetCode-Solutions/blob/main/01.%20Array%20Hashing/217.%20Contains%20Duplicate.ipynb) | Easy | -| [242. Valid Anagram](https://github.com/mohsentabibian/LeetCode-Solutions/blob/main/01.%20Array%20Hashing/242.%20Valid%20Anagram.ipynb) | Easy | -| [1. Two Sum](https://github.com/mohsentabibian/LeetCode-Solutions/blob/main/01.%20Array%20Hashing/1.%20Two%20Sum.ipynb) | Easy | -| [49. Group Anagrams](https://github.com/mohsentabibian/LeetCode-Solutions/blob/main/01.%20Array%20Hashing/49.%20Group%20Anagrams.ipynb) | Medium | -| [347. Top K Frequent Elements](https://github.com/mohsentabibian/LeetCode-Solutions/blob/main/01.%20Array%20Hashing/347.%20Top%20K%20Frequent%20Elements.ipynb) | Medium | -| [238. Product of Array Except Self](https://github.com/mohsentabibian/LeetCode-Solutions/blob/main/01.%20Array%20Hashing/238.%20Product%20of%20Array%20Except%20Self.ipynb) | Medium | -| [659. Encode and Decode Strings](https://github.com/mohsentabibian/LeetCode-Solutions/blob/main/01.%20Array%20Hashing/659.%20Encode%20and%20Decode%20Strings.ipynb) | Medium | -| [128. Longest Consecutive Sequence](https://github.com/mohsentabibian/LeetCode-Solutions/blob/main/01.%20Array%20Hashing/128.%20Longest%20Consecutive%20Sequence.ipynb) | Hard | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! diff --git a/docs/_build/html/_sources/02. Two Pointers/11. Container With Most Water.ipynb b/docs/_build/html/_sources/02. Two Pointers/11. Container With Most Water.ipynb deleted file mode 100644 index 284c832..0000000 --- a/docs/_build/html/_sources/02. Two Pointers/11. Container With Most Water.ipynb +++ /dev/null @@ -1,220 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 11. Container With Most Water\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Container With Most Water problem on LeetCode, click here!](https://leetcode.com/problems/container-with-most-water/)\n", - "\n", - "---\n", - "You are given an integer array `height` of length `n`. There are `n` vertical lines drawn such that the two endpoints of the $i^{th}$ line are `(i, 0)` and `(i, height[i])`.\n", - "\n", - "Find two lines that together with the x-axis form a container, such that the container contains the most water.\n", - "\n", - "Return *the maximum amount of water a container can store.*\n", - "\n", - "**Notice** that you may not slant the container.\n", - "\n", - "**Constraints:**\n", - "- `n == height.length`\n", - "- 2 <= `n` <= $10^5$\n", - "- 0 <= `height[i]` <= $10^4$\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def maxArea(height):\n", - " # Initialize the maximum area to 0.\n", - " max_area = 0\n", - " # Initialize two pointers, one at the beginning (left) and one at the end (right) of the array.\n", - " left = 0\n", - " right = len(height) - 1\n", - "\n", - " # Iterate until the left pointer is less than the right pointer.\n", - " while left < right:\n", - " # Calculate the height of the container, which is the minimum height of the two lines.\n", - " h = min(height[left], height[right])\n", - " # Calculate the width of the container, which is the distance between the two pointers.\n", - " width = right - left\n", - " # Calculate the area of the container using height and width and update max_area if it's greater.\n", - " max_area = max(max_area, h * width)\n", - "\n", - " # Move the pointer with the shorter line inward.\n", - " if height[left] < height[right]:\n", - " left += 1\n", - " else:\n", - " right -= 1\n", - "\n", - " # Continue this process until left < right, and then return the maximum area.\n", - " return max_area" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start with initializing `max_area` to 0, which will store the maximum area of water that can be contained by the lines.\n", - "\n", - "2. Two pointers, `left` and `right`, are initialized to the beginning and end of the input `height` array.\n", - "\n", - "3. The main loop runs while `left` is less than `right`. This ensures that we are checking all possible pairs of lines in a systematic way.\n", - "\n", - "4. Inside the loop:\n", - " - We calculate the height of the container `h` as the minimum of the heights at the `left` and `right` pointers. This represents the height of the water the container can hold.\n", - " - We calculate the width of the container as the difference between `right` and `left`. This represents the distance between the two lines.\n", - " - We calculate the area of the container using `h * width` and update `max_area` if the calculated area is greater than the current `max_area`.\n", - "\n", - "5. After calculating the area and updating `max_area`, we move one of the pointers. We move the pointer pointing to the shorter line inward because moving the pointer pointing to the taller line won't increase the height and will only decrease the width, which will result in a smaller area.\n", - "\n", - "6. We continue this process until `left` is no longer less than `right`, indicating that we have checked all possible pairs of lines.\n", - "\n", - "7. Finally, we return the `max_area` which contains the maximum area of water that can be contained by two lines from the input array." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Output: 49\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "height1 = [1, 8, 6, 2, 5, 4, 8, 3, 7]\n", - "result1 = maxArea(height1)\n", - "print(\"Output:\", result1)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Output: 1\n" - ] - } - ], - "source": [ - "# Example 2\n", - "height2 = [1, 1]\n", - "result2 = maxArea(height2)\n", - "print(\"Output:\", result2)" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "e191cf7e-95f9-4e5c-a99b-146c2a779c0b", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Output: 45\n" - ] - } - ], - "source": [ - "# Additional Example\n", - "height3 = [3, 9, 3, 4, 7, 2, 12, 6]\n", - "result3 = maxArea(height3)\n", - "print(\"Output:\", result3)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `maxArea` function:\n", - "\n", - "**Time Complexity:**\n", - "The function uses a two-pointer approach to find the maximum area of water. In the worst case, both the left and right pointers traverse the entire input array once. Therefore, the time complexity is O(n), where n is the number of elements in the `height` array.\n", - "\n", - "**Space Complexity:**\n", - "The function uses a constant amount of extra space for variables like `max_area`, `left`, `right`, `h`, and `width`. It does not use any data structures whose space consumption depends on the input size. As a result, the space complexity is O(1), which means it has constant space complexity.\n", - "\n", - "**In summary,** the `maxArea` function has a time complexity of O(n) and a space complexity of O(1), making it an efficient algorithm for finding the maximum area of water that can be contained by two lines in the input array." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Optimization Challenge:** Modify the maxArea function to not only return the maximum area but also the indices of the two lines that form the container with the maximum area.\n", - "2. **Variant Problem:** Instead of finding the maximum area of water, find the minimum amount of water required to fill all the gaps between the lines. You'll need to return the total water volume needed." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/02. Two Pointers/125. Valid Palindrome.ipynb b/docs/_build/html/_sources/02. Two Pointers/125. Valid Palindrome.ipynb deleted file mode 100644 index 8520b3b..0000000 --- a/docs/_build/html/_sources/02. Two Pointers/125. Valid Palindrome.ipynb +++ /dev/null @@ -1,218 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 125. Valid Palindrome\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Valid Palindrome problem on LeetCode, click here!](https://leetcode.com/problems/valid-palindrome/)\n", - "\n", - "---\n", - "\n", - "A phrase is a **palindrome** if, after converting all uppercase letters into lowercase letters and removing all non-alphanumeric characters, it reads the same forward and backward. Alphanumeric characters include letters and numbers.\n", - "\n", - "Given a string `s`, *return `true` if it is a **palindrome**, or `false` otherwise.*\n", - "\n", - "**Constraints:**\n", - "\n", - "- 1 <= `s.length` <= $2*10^5$\n", - "- `s` consists only of printable ASCII characters.\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def isPalindrome(s):\n", - " # Step 1: Convert the input string to lowercase\n", - " s = s.lower()\n", - " \n", - " # Step 2: Remove all non-alphanumeric characters from the string\n", - " cleaned_s = ''.join(c for c in s if c.isalnum())\n", - " \n", - " # Step 3: Initialize two pointers, one at the beginning and one at the end of the cleaned string\n", - " left, right = 0, len(cleaned_s) - 1\n", - " \n", - " # Step 4: Compare characters using the two pointers while moving them towards each other\n", - " while left < right:\n", - " if cleaned_s[left] != cleaned_s[right]:\n", - " return False # If characters don't match, it's not a palindrome\n", - " left += 1\n", - " right -= 1\n", - " \n", - " # Step 5: If the loop completes without returning False, it's a palindrome\n", - " return True" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. The `isPalindrome` function takes an input string `s`.\n", - "\n", - "2. It starts by converting the input string to lowercase using `s.lower()`. This step ensures that the function is case-insensitive when checking for palindromes.\n", - "\n", - "3. Next, it removes all non-alphanumeric characters from the string and stores the result in the `cleaned_s` variable. It does this by iterating through each character in the input string and only keeping characters that are alphanumeric (letters and digits). This step removes spaces, punctuation, and other non-alphanumeric characters.\n", - "\n", - "4. The function then initializes two pointers, `left` and `right`, which will be used to compare characters from the beginning and end of the cleaned string.\n", - "\n", - "5. In a while loop, it compares characters using the two pointers while moving them towards each other. The loop continues until the `left` pointer is less than the `right` pointer. This is done to check all characters in the cleaned string.\n", - "\n", - "6. Inside the loop, it checks if the characters at the `left` and `right` pointers don't match. If they don't match, it means the input is not a palindrome, so the function returns `False`.\n", - "\n", - "7. If the characters at the `left` and `right` pointers match, the pointers are moved closer to each other by incrementing `left` and decrementing `right`.\n", - "\n", - "8. The loop continues to compare characters until it either finds a mismatch (returning `False`) or until the `left` pointer is greater than or equal to the `right` pointer. If the loop completes without finding a mismatch, it means the input is a palindrome, so the function returns `True`.\n", - "\n", - "In summary, the code converts the input string to lowercase, removes non-alphanumeric characters, and then uses two pointers to compare characters from the cleaned string's beginning and end. If all characters match during the comparison, the function returns `True`, indicating that the input is a palindrome. If any characters do not match, it returns `False`." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "input1 = \"A man, a plan, a canal: Panama\"\n", - "output1 = isPalindrome(input1)\n", - "print(output1)" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 2\n", - "input2 = \"race a car\"\n", - "output2 = isPalindrome(input2)\n", - "print(output2)" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "e191cf7e-95f9-4e5c-a99b-146c2a779c0b", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 3\n", - "input3 = \"\"\n", - "output3 = isPalindrome(input3)\n", - "print(output3)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `isPalindrome` function that uses two pointers:\n", - "\n", - "1. **Time Complexity:**\n", - " - Converting the input string to lowercase using `s.lower()` takes O(n) time, where 'n' is the length of the input string.\n", - " - Removing non-alphanumeric characters using the list comprehension `''.join(c for c in s if c.isalnum())` also takes O(n) time because it iterates through each character in the string once.\n", - " - The comparison of characters using the two pointers (`left` and `right`) is done in a loop that runs until `left` is less than `right`. In the worst case, the loop iterates through half of the string, so it takes O(n/2) time, which is still considered O(n).\n", - "\n", - " Therefore, the overall time complexity of the `isPalindrome` function is O(n), where 'n' is the length of the input string.\n", - "\n", - "2. **Space Complexity:**\n", - " - The space complexity is primarily determined by the additional string `cleaned_s` created to store the cleaned version of the input string. In the worst case, if all characters in the input string are alphanumeric, this cleaned string can be as large as the original input string.\n", - " - Additionally, the function uses two pointers, `left` and `right`, which consume constant space and do not depend on the size of the input.\n", - "\n", - "**In summary,** the overall space complexity of the `isPalindrome` function is O(n) in the worst case, where 'n' is the length of the input string. The space complexity is dominated by the space required for `cleaned_s`." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Longest Palindromic Substring:** Given a string `s`, find and return the longest palindromic substring within `s`. For example, if `s = \"babad\"`, the function should return `\"bab\"` or `\"aba\"`.\n", - "2. **Palindrome with Limited Characters:** Given a string `s` and a list of characters `allowed_chars`, check if `s` is a palindrome considering only the characters from `allowed_chars`. Ignore all other characters. For example, if `s = \"A man, a plan, a canal: Panama\"` and `allowed_chars = ['a', 'm', 'n', 'p']`, the function should return `True`." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/02. Two Pointers/15. 3Sum.ipynb b/docs/_build/html/_sources/02. Two Pointers/15. 3Sum.ipynb deleted file mode 100644 index 06de549..0000000 --- a/docs/_build/html/_sources/02. Two Pointers/15. 3Sum.ipynb +++ /dev/null @@ -1,250 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 15. 3Sum\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the 3Sum problem on LeetCode, click here!](https://leetcode.com/problems/3sum/)\n", - "\n", - "---\n", - "Given an integer array nums, *return all the triplets `[nums[i], nums[j], nums[k]]` such that `i != j`, `i != k`, and `j != k`, and `nums[i] + nums[j] + nums[k] == 0`.*\n", - "\n", - "**Notice** that the solution set must not contain duplicate triplets.\n", - "\n", - "**Constraints:**\n", - "\n", - "- `3 <= nums.length <= 3000`\n", - "- $-10^5$ <= `nums[i]` <= $10^5$\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def threeSum(nums):\n", - " # Sort the input array in ascending order\n", - " nums.sort()\n", - " triplets = []\n", - " \n", - " for i in range(len(nums) - 2):\n", - " # Skip duplicates to avoid duplicate triplets\n", - " if i > 0 and nums[i] == nums[i - 1]:\n", - " continue\n", - " \n", - " left, right = i + 1, len(nums) - 1\n", - " \n", - " while left < right:\n", - " # Calculate the total sum of the current triplet\n", - " total = nums[i] + nums[left] + nums[right]\n", - " \n", - " if total == 0:\n", - " # If the total is zero, we found a valid triplet\n", - " triplets.append([nums[i], nums[left], nums[right]])\n", - " \n", - " # Skip duplicates of left and right pointers\n", - " while left < right and nums[left] == nums[left + 1]:\n", - " left += 1\n", - " while left < right and nums[right] == nums[right - 1]:\n", - " right -= 1\n", - " \n", - " # Move the pointers to the next unique elements\n", - " left += 1\n", - " right -= 1\n", - " elif total < 0:\n", - " # If the total is negative, we need to increase the sum by moving the left pointer to the right\n", - " left += 1\n", - " else:\n", - " # If the total is positive, we need to decrease the sum by moving the right pointer to the left\n", - " right -= 1\n", - " \n", - " return triplets" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. It starts by sorting the input array `nums` in ascending order. Sorting helps in efficiently finding triplets that sum up to zero.\n", - "\n", - "2. It initializes an empty list `triplets` to store the unique triplets that meet the given conditions.\n", - "\n", - "3. The code then iterates through the `nums` array using a loop with index `i`. This loop will consider each element of the array as a potential starting point for a triplet.\n", - "\n", - "4. Inside the loop, it checks for duplicates and skips them. This is done to ensure that the solution set does not contain duplicate triplets. If `nums[i]` is the same as the previous element `nums[i-1]`, it continues to the next iteration of the loop.\n", - "\n", - "5. Two pointers, `left` and `right`, are initialized. `left` starts just after the current element `nums[i]`, and `right` starts at the end of the array.\n", - "\n", - "6. The code enters another loop with `left` and `right` pointers, trying to find a triplet that sums up to zero.\n", - "\n", - "7. It calculates the `total` sum of the current triplet as `nums[i] + nums[left] + nums[right]`.\n", - "\n", - "8. If `total` is zero, it means a valid triplet is found, so it appends `[nums[i], nums[left], nums[right]]` to the `triplets` list. Then, it moves both the `left` and `right` pointers to their next unique elements while skipping duplicates.\n", - "\n", - "9. If `total` is less than zero, it means the sum is negative, so it increments the `left` pointer to move towards a larger sum.\n", - "\n", - "10. If `total` is greater than zero, it means the sum is positive, so it decrements the `right` pointer to move towards a smaller sum.\n", - "\n", - "11. This process continues until all possible triplets have been considered.\n", - "\n", - "12. Finally, the function returns the `triplets` list, which contains all the unique triplets that sum up to zero in the sorted `nums` array." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[-1, -1, 2], [-1, 0, 1]]\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "nums = [-1, 0, 1, 2, -1, -4]\n", - "result = threeSum(nums)\n", - "print(result)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[]\n" - ] - } - ], - "source": [ - "# Example 2\n", - "nums = [0, 1, 1]\n", - "result = threeSum(nums)\n", - "print(result)" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "e191cf7e-95f9-4e5c-a99b-146c2a779c0b", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[0, 0, 0]]\n" - ] - } - ], - "source": [ - "# Example 3\n", - "nums = [0, 0, 0]\n", - "result = threeSum(nums)\n", - "print(result)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `threeSum` function:\n", - "\n", - "**Time Complexity:**\n", - "1. Sorting the input array `nums` takes O(n log n) time, where n is the length of the array.\n", - "\n", - "2. The outer loop runs for each element of the array, so it iterates O(n) times.\n", - "\n", - "3. Inside the outer loop, we have a while loop with two pointers (`left` and `right`). In the worst case, the while loop can iterate O(n) times (when all elements are unique).\n", - "\n", - "4. Inside the while loop, we have constant time operations (additions, comparisons, and list appends).\n", - "\n", - "Overall, the time complexity of the `threeSum` function is dominated by the sorting step, so it is O(n log n) due to the sorting. The other operations inside the loops contribute linearly but are dominated by the sorting step.\n", - "\n", - "**Space Complexity:**\n", - "1. The space used by the `triplets` list to store the output triplets is O(k), where k is the number of unique triplets that sum up to zero. In the worst case, this can be O(n^2/3) because there can be roughly O(n^2) possible triplets, and many of them may sum up to zero.\n", - "\n", - "2. Other than the `triplets` list, the function uses only a constant amount of additional space for variables like `i`, `left`, `right`, and `total`.\n", - "\n", - "Overall, the space complexity of the `threeSum` function is O(k), where k is the number of unique triplets that meet the criteria. It's important to note that the space complexity does not depend on the size of the input array but rather on the number of valid triplets found.\n", - "\n", - "**In summary:**\n", - "- Time Complexity: O(n log n) due to sorting (dominant factor) and O(n^2) in the worst case for the nested loops.\n", - "- Space Complexity: O(k) for storing the output triplets, where k is the number of unique triplets that meet the criteria." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **K-Sum Problem:** Generalize the problem to the K-Sum problem, where instead of finding triplets that sum to zero, you need to find K elements that sum to a target value. Implement a function for this generalization.\n", - "2. **Count the Number of Unique Triplets:** Modify the algorithm to count the number of unique triplets that satisfy the conditions instead of returning the triplets themselves. This will require some modifications to handle duplicates efficiently." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/02. Two Pointers/README.md b/docs/_build/html/_sources/02. Two Pointers/README.md deleted file mode 100644 index 0d4c7cf..0000000 --- a/docs/_build/html/_sources/02. Two Pointers/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# Two Pointers Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [125. Valid Palindrome](https://leetcode.com/problems/valid-palindrome/) | Easy | -| [15. 3Sum](https://leetcode.com/problems/3sum/) | Medium | -| [11. Container With Most Water](https://leetcode.com/problems/container-with-most-water/) | Medium | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! \ No newline at end of file diff --git a/docs/_build/html/_sources/03. Sliding Window/121. Best Time to Buy and Sell Stock.ipynb b/docs/_build/html/_sources/03. Sliding Window/121. Best Time to Buy and Sell Stock.ipynb deleted file mode 100644 index 554c940..0000000 --- a/docs/_build/html/_sources/03. Sliding Window/121. Best Time to Buy and Sell Stock.ipynb +++ /dev/null @@ -1,191 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 121. Best Time to Buy and Sell Stock\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Best Time to Buy and Sell Stock problem on LeetCode, click here!](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/)\n", - "\n", - "---\n", - "\n", - "You are given an array `prices` where `prices[i]` is the price of a given stock on the $i^{th}$ day.\n", - "\n", - "You want to maximize your profit by choosing a **single day** to buy one stock and choosing a **different day in the future** to sell that stock.\n", - "\n", - "*Return the maximum profit you can achieve from this transaction. If you cannot achieve any profit, return `0`.*\n", - "\n", - "**Constraints:**\n", - "\n", - "- 1 <= `prices.length` <= $10^5$\n", - "- 0 <= `prices[i]` <= $10^4$\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 65, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def maxProfit(prices):\n", - " if not prices:\n", - " return 0\n", - " \n", - " min_price = prices[0]\n", - " max_profit = 0\n", - " \n", - " for price in prices:\n", - " # Update the minimum price if a lower price is encountered\n", - " min_price = min(min_price, price)\n", - " # Calculate the profit if selling at the current price\n", - " max_profit = max(max_profit, price - min_price)\n", - " \n", - " return max_profit" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "- The `maxProfit` function takes a single argument, `prices`, which is a list of stock prices.\n", - "- The first line of the function checks if the `prices` list is empty. If it's empty, there are no prices to analyze, so the function returns 0 (no profit can be made).\n", - "\n", - "- Then, we initialize two variables:\n", - " - `min_price`: This variable will keep track of the minimum price seen so far. We initialize it with the price of the first day in the list (`prices[0]`).\n", - " - `max_profit`: This variable will keep track of the maximum profit we can achieve. We initialize it to 0 because initially, we haven't made any profit.\n", - "\n", - "- We start iterating through the `prices` list, where `price` represents the stock price for the current day.\n", - "\n", - "- In each iteration, we check if the current `price` is lower than the `min_price` we've seen so far. If it is, we update `min_price` to the current `price`. This is because we want to buy the stock at the lowest possible price.\n", - "\n", - "- Next, we calculate the profit we would make if we sold the stock at the current `price` (assuming we bought it at `min_price`). We do this by subtracting `min_price` from the current `price`. This represents the profit for the current day.\n", - "\n", - "- We also use the `max` function to keep track of the maximum profit seen so far. If the profit calculated for the current day is greater than the `max_profit` we've seen previously, we update `max_profit` with this higher value.\n", - "\n", - "- Finally, after iterating through all the days in the `prices` list, we return `max_profit`, which represents the maximum profit that can be achieved by buying and selling a single stock." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 66, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "5\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "prices1 = [7, 1, 5, 3, 6, 4]\n", - "print(maxProfit(prices1))" - ] - }, - { - "cell_type": "code", - "execution_count": 67, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "prices2 = [7, 6, 4, 3, 1]\n", - "print(maxProfit(prices2))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "- The code iterates through the `prices` array once, examining each price exactly once.\n", - "- Within the loop, there are constant-time operations such as comparisons, additions, and subtractions.\n", - "- Therefore, the time complexity of this code is O(n), where n is the length of the `prices` array. It performs a linear number of operations relative to the size of the input.\n", - "\n", - "**Space Complexity:**\n", - "- The space complexity of the code is constant, O(1).\n", - "- Regardless of the size of the input `prices` array, the code only uses a fixed amount of additional memory to store two variables (`min_price` and `max_profit`) and a few loop variables.\n", - "- The memory usage does not depend on the size of the input, so it is considered constant space complexity.\n", - "\n", - "**In summary:**\n", - "- Time Complexity: O(n) where n is the length of the `prices` array.\n", - "- Space Complexity: O(1) (constant space usage)." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Multiple Transactions Allowed:** Modify the problem to allow multiple transactions (buy and sell multiple times), but you must sell before buying again. Find the maximum profit in this scenario.\n", - "2. **K Transactions Allowed:** Extend the problem to allow at most k transactions. Find the maximum profit considering this constraint.\n", - "3. **With Transaction Fee:** Introduce a transaction fee for each buy/sell operation. Modify the code to maximize profit while considering the transaction fee." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/03. Sliding Window/3. Longest Substring Without Repeating Characters.ipynb b/docs/_build/html/_sources/03. Sliding Window/3. Longest Substring Without Repeating Characters.ipynb deleted file mode 100644 index 4a516de..0000000 --- a/docs/_build/html/_sources/03. Sliding Window/3. Longest Substring Without Repeating Characters.ipynb +++ /dev/null @@ -1,214 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 3. Longest Substring Without Repeating Characters\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Longest Substring Without Repeating Characters problem on LeetCode, click here!](https://leetcode.com/problems/longest-substring-without-repeating-characters/)\n", - "\n", - "---\n", - "Given a string `s`, find the length of the **longest substring** without repeating characters.\n", - "\n", - "**Constraints:**\n", - "\n", - "- 0 <= `s.length` <= $5 * 10^4$\n", - "- `s` consists of English letters, digits, symbols and spaces.\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 61, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def length_of_longest_substring(s):\n", - " # Create a dictionary to store the index of each character's last occurrence.\n", - " char_index = {}\n", - " \n", - " # Initialize variables to keep track of the start and end of the current substring.\n", - " start = 0\n", - " max_length = 0\n", - " \n", - " for end in range(len(s)):\n", - " # If the character is in the dictionary and its last occurrence is after the start of the current substring,\n", - " # update the start of the substring to the next character after its last occurrence.\n", - " if s[end] in char_index and char_index[s[end]] >= start:\n", - " start = char_index[s[end]] + 1\n", - " \n", - " # Update the last occurrence index of the current character.\n", - " char_index[s[end]] = end\n", - " \n", - " # Calculate the length of the current substring and update the maximum length if necessary.\n", - " current_length = end - start + 1\n", - " max_length = max(max_length, current_length)\n", - " \n", - " return max_length" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start by defining a function called `length_of_longest_substring` that takes a single argument `s`, which is the input string for which we want to find the length of the longest substring without repeating characters.\n", - "\n", - "2. We create a dictionary called `char_index` to store the index of the last occurrence of each character in the input string. This dictionary will help us keep track of where each character was last seen.\n", - "\n", - "3. We initialize two variables, `start` and `max_length`. \n", - " - `start` represents the start index of the current substring without repeating characters. It starts at 0.\n", - " - `max_length` is used to keep track of the maximum length found so far and is initially set to 0.\n", - "\n", - "4. We then iterate through the input string `s` using a for loop, where the loop variable `end` represents the current end index of the substring we are considering.\n", - "\n", - "5. Inside the loop:\n", - " - We check if the character `s[end]` is already in the `char_index` dictionary and if its last occurrence is within or after the current substring. If so, it means that we've encountered a repeating character, and we need to update the `start` of the substring to the next character after the last occurrence of `s[end]`. This ensures that we have a new valid substring without repeating characters.\n", - " - We then update the `char_index` dictionary by storing the current index `end` as the last occurrence index of the character `s[end]`.\n", - "\n", - "6. Next, we calculate the length of the current substring without repeating characters, which is `current_length = end - start + 1`. We add 1 to account for the fact that the indices are zero-based.\n", - "\n", - "7. We update the `max_length` with the maximum of its current value and the `current_length`. This step ensures that we keep track of the longest valid substring we have encountered so far.\n", - "\n", - "8. The loop continues to iterate through the input string, and at the end, we return the `max_length`, which represents the length of the longest substring without repeating characters." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 62, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "print(length_of_longest_substring(\"abcabcbb\"))" - ] - }, - { - "cell_type": "code", - "execution_count": 63, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "print(length_of_longest_substring(\"bbbbb\"))" - ] - }, - { - "cell_type": "code", - "execution_count": 64, - "id": "cf04eba0-0ead-4e8b-ba33-4316ea64a9d3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "print(length_of_longest_substring(\"pwwkew\"))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "Let's analyze the time and space complexity of the `length_of_longest_substring` function:\n", - "\n", - "**Time Complexity:**\n", - "- The function iterates through the input string `s` using a single for loop. The loop runs from the beginning of the string to the end once.\n", - "- Inside the loop, we perform constant-time operations such as dictionary lookups and updates, comparisons, and arithmetic operations.\n", - "- Therefore, the time complexity of the function is O(n), where n is the length of the input string `s`.\n", - "\n", - "**Space Complexity:**\n", - "- The primary data structure that consumes space in this function is the `char_index` dictionary.\n", - "- In the worst case, if there are no repeating characters in the input string, the dictionary can store all unique characters in the string.\n", - "- Therefore, the space complexity is O(min(n, m)), where n is the length of the input string `s`, and m is the number of unique characters in the string. In the worst case, when all characters are unique, m is equal to n, so the space complexity is O(n).\n", - "- Additionally, there are a few integer variables used for indices and lengths, which consume constant space.\n", - "- Overall, the space complexity of the function is O(min(n, m)) or simply O(n) in the worst case.\n", - "\n", - "**In summary,** the time complexity of the `length_of_longest_substring` function is O(n), and the space complexity is O(n) in the worst case due to the `char_index` dictionary. This algorithm provides an efficient way to find the length of the longest substring without repeating characters in linear time." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Longest Substring with K Distinct Characters:** Modify the problem to find the length of the longest substring with exactly K distinct characters. For example, given the input string \"abcabcbb\" and K = 2, the answer would be 4 because the longest substring with two distinct characters is \"abca.\"\n", - "2. **Longest Substring with Unique Characters:** Write a function to find the length of the longest substring in a given string where all characters are unique. For example, given the input string \"abcabcbb,\" the answer would be 4 because \"abcd\" is the longest substring with unique characters." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/03. Sliding Window/424. Longest Repeating Character Replacement.ipynb b/docs/_build/html/_sources/03. Sliding Window/424. Longest Repeating Character Replacement.ipynb deleted file mode 100644 index 07e96a2..0000000 --- a/docs/_build/html/_sources/03. Sliding Window/424. Longest Repeating Character Replacement.ipynb +++ /dev/null @@ -1,195 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 424. Longest Repeating Character Replacement\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Longest Repeating Character Replacement problem on LeetCode, click here!](https://leetcode.com/problems/longest-repeating-character-replacement/)\n", - "\n", - "---\n", - "You are given a string `s` and an integer `k`. You can choose any character of the string and change it to any other uppercase English character. You can perform this operation at most `k` times.\n", - "\n", - "*Return the length of the longest substring containing the same letter you can get after performing the above operations.*\n", - "\n", - "**Constraints:**\n", - "\n", - "- 1 <= `s.length` <= $10^5$\n", - "- `s` consists of only uppercase English letters.\n", - "- `0 <= k <= s.length`" - ] - }, - { - "cell_type": "code", - "execution_count": 58, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def characterReplacement(s, k):\n", - " max_length = 0 # Initialize the maximum length\n", - " max_count = 0 # Initialize the maximum count of repeating characters\n", - " start = 0 # Initialize the start of the sliding window\n", - " char_count = {} # Dictionary to store the count of each character\n", - "\n", - " for end in range(len(s)):\n", - " # Update the count of the current character in the dictionary\n", - " char_count[s[end]] = char_count.get(s[end], 0) + 1\n", - " \n", - " # Update the maximum count of repeating characters\n", - " max_count = max(max_count, char_count[s[end]])\n", - " \n", - " # Check if the current window size is greater than k\n", - " if (end - start + 1) - max_count > k:\n", - " # Move the start of the window to the right\n", - " char_count[s[start]] -= 1\n", - " start += 1\n", - " \n", - " # Update the maximum length\n", - " max_length = max(max_length, end - start + 1)\n", - "\n", - " return max_length" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We initialize some variables:\n", - " - `max_length` to keep track of the maximum length of the substring containing the same letter.\n", - " - `max_count` to keep track of the maximum count of repeating characters within the current window.\n", - " - `start` to represent the start index of the sliding window.\n", - " - `char_count` is a dictionary that will store the count of each character within the current window.\n", - "\n", - "2. We use a `for` loop to iterate through the characters of the string `s`.\n", - "\n", - "3. Inside the loop, we do the following for each character at position `end`:\n", - " - Update the count of the current character in the `char_count` dictionary.\n", - " - Update the `max_count` to be the maximum of the current `max_count` and the count of the current character. This keeps track of the maximum count of repeating characters within the current window.\n", - "\n", - "4. We check if the current window size (the difference between `end` and `start` plus one) minus the `max_count` is greater than `k`. This condition checks whether we have exceeded the allowed number of replacements (`k`) within the current window.\n", - "\n", - " - If we have exceeded the allowed replacements, it means we need to shrink the window from the left side. We do this by moving the `start` of the window to the right and decrementing the count of the character at `s[start]` in the `char_count` dictionary. This effectively removes characters from the left side of the window until we have a valid window again.\n", - "\n", - " - By doing this, we ensure that the difference between the current window size and the `max_count` is always less than or equal to `k`.\n", - "\n", - "5. After each character, we update the `max_length` to be the maximum of the current `max_length` and the size of the current window (`end - start + 1`).\n", - "\n", - "6. Finally, we return `max_length`, which holds the length of the longest substring containing the same letter with at most `k` replacements." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 59, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "s1 = \"ABAB\"\n", - "k1 = 2\n", - "print(characterReplacement(s1, k1))" - ] - }, - { - "cell_type": "code", - "execution_count": 60, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "s2 = \"AABABBA\"\n", - "k2 = 1\n", - "print(characterReplacement(s2, k2))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "- The code uses a single `for` loop to iterate through the characters of the input string `s`. The loop runs from the beginning to the end of the string.\n", - "- Inside the loop, we perform constant-time operations such as updating the `char_count` dictionary and updating variables like `max_count` and `max_length`.\n", - "- The code's time complexity is primarily determined by the loop, which iterates through each character in the string once. Therefore, the time complexity is O(n), where n is the length of the input string `s`.\n", - "\n", - "**Space Complexity:**\n", - "- The code uses several variables to store information, but the space they consume is constant and does not depend on the size of the input string. These variables include `max_length`, `max_count`, `start`, and `char_count`. Therefore, the space complexity is O(1) or constant space.\n", - "\n", - "**In summary**, the time complexity of the code is O(n), where n is the length of the input string, and the space complexity is O(1), as it uses a constant amount of additional space regardless of the input size. This algorithm efficiently solves the problem with a linear time complexity." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Optimization Challenge:** Modify the code to find the longest substring containing the same letter with at most k replacements in O(n) time complexity and O(1) space complexity. Hint: You may need to update the approach to achieve this.\n", - "2. **Variation with Lowercase Letters:** Extend the problem to include both uppercase and lowercase English letters in the input string s. Write a function that can handle this extended input and still find the longest substring with at most k replacements efficiently." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/03. Sliding Window/76. Minimum Window Substring.ipynb b/docs/_build/html/_sources/03. Sliding Window/76. Minimum Window Substring.ipynb deleted file mode 100644 index 33c2a44..0000000 --- a/docs/_build/html/_sources/03. Sliding Window/76. Minimum Window Substring.ipynb +++ /dev/null @@ -1,273 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 76. Minimum Window Substring\n", - "\n", - "**Difficulty:** Hard\n", - "\n", - "**Link to Problem:** [To see the Minimum Window Substring problem on LeetCode, click here!](https://leetcode.com/problems/minimum-window-substring/)\n", - "\n", - "---\n", - "Given two strings `s` and `t` of lengths `m` and `n` respectively, return *the **minimum window substring** of `s` such that every character in `t` (**including duplicates**) is included in the window. If there is no such substring, return the empty string `\"\"`.*\n", - "\n", - "The testcases will be generated such that the answer is **unique**.\n", - "\n", - "**Constraints:**\n", - "\n", - "- `m == s.length`\n", - "- `n == t.length`\n", - "- 1 <= `m, n` <= $10^5$\n", - "- `s` and `t` consist of uppercase and lowercase English letters.\n", - "\n", - "**Follow up**: Could you find an algorithm that runs in $O(m + n)$ time?" - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def min_window_substring(s, t):\n", - " if not s or not t:\n", - " return \"\"\n", - "\n", - " # Initialize dictionaries to keep track of character counts for t and the current window in s.\n", - " t_dict = {}\n", - " current_window_dict = {}\n", - " \n", - " # Populate t_dict with character counts for string t.\n", - " for char in t:\n", - " t_dict[char] = t_dict.get(char, 0) + 1\n", - "\n", - " # Initialize pointers for the sliding window.\n", - " left = 0\n", - " min_len = float('inf')\n", - " min_window = \"\"\n", - " required_chars = len(t_dict)\n", - "\n", - " # Initialize a variable to keep track of how many required characters have been found in the current window.\n", - " found_chars = 0\n", - "\n", - " # Iterate over the string s using the right pointer.\n", - " for right in range(len(s)):\n", - " char = s[right]\n", - "\n", - " # Update the current_window_dict.\n", - " current_window_dict[char] = current_window_dict.get(char, 0) + 1\n", - "\n", - " # Check if the current character is a required character and if its count matches the required count.\n", - " if char in t_dict and current_window_dict[char] == t_dict[char]:\n", - " found_chars += 1\n", - "\n", - " # Try to minimize the window by moving the left pointer.\n", - " while left <= right and found_chars == required_chars:\n", - " # Calculate the current window size.\n", - " window_size = right - left + 1\n", - "\n", - " # If the current window is smaller than the minimum found so far, update min_len and min_window.\n", - " if window_size < min_len:\n", - " min_len = window_size\n", - " min_window = s[left:right+1]\n", - "\n", - " # Move the left pointer to the right to shrink the window.\n", - " left_char = s[left]\n", - " current_window_dict[left_char] -= 1\n", - "\n", - " # Check if the character removed from the window was a required character.\n", - " if left_char in t_dict and current_window_dict[left_char] < t_dict[left_char]:\n", - " found_chars -= 1\n", - "\n", - " # Move the left pointer further to continue shrinking the window.\n", - " left += 1\n", - "\n", - " return min_window" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start by checking if either of the input strings `s` or `t` is empty. If either of them is empty, we return an empty string since there can't be any valid substring in this case.\n", - "\n", - "2. We initialize two dictionaries: `t_dict` and `current_window_dict`. These dictionaries will be used to keep track of character counts in the string `t` and the current window in string `s`, respectively.\n", - "\n", - "3. We populate the `t_dict` dictionary by iterating through string `t`. For each character, we increment its count in the dictionary using `t_dict.get(char, 0) + 1`. This allows us to count the occurrences of each character in `t`.\n", - "\n", - "4. We initialize two pointers: `left` and `right`. The `left` pointer will represent the start of the current window, and the `right` pointer will represent the end of the current window. We also initialize `min_len` to store the length of the minimum window found so far, and `min_window` to store the actual minimum window substring.\n", - "\n", - "5. We determine the number of required characters in `t` (i.e., the number of distinct characters in `t`) and store it in the variable `required_chars`.\n", - "\n", - "6. We initialize a variable `found_chars` to keep track of how many required characters have been found in the current window. Initially, it is set to 0.\n", - "\n", - "7. We iterate over the string `s` using the `right` pointer. In each iteration, we do the following:\n", - "\n", - " - Update the `current_window_dict` by incrementing the count of the current character.\n", - " \n", - " - Check if the current character is a required character (present in `t_dict`) and if its count in the `current_window_dict` matches the required count from `t_dict`. If so, we increment `found_chars`.\n", - "\n", - "8. After updating the window, we attempt to minimize the window size by moving the `left` pointer to the right. In this step, we:\n", - "\n", - " - Calculate the size of the current window.\n", - " \n", - " - If the current window size is smaller than the minimum found so far (`min_len`), we update `min_len` and `min_window` to store the current window substring.\n", - " \n", - " - Move the `left` pointer to the right to shrink the window.\n", - " \n", - " - Check if the character being removed from the window was a required character. If it was, we decrement `found_chars`.\n", - " \n", - " - Continue moving the `left` pointer further to continue shrinking the window if the window still contains all required characters.\n", - "\n", - "9. Finally, we return `min_window`, which will contain the minimum window substring that contains all characters from `t`." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 55, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "BANC\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "print(min_window_substring(\"ADOBECODEBANC\", \"ABC\"))" - ] - }, - { - "cell_type": "code", - "execution_count": 56, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "a\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "print(min_window_substring(\"a\", \"a\")) " - ] - }, - { - "cell_type": "code", - "execution_count": 57, - "id": "6c69a707-02af-4212-b2e7-1881d62a62d2", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "print(min_window_substring(\"a\", \"aa\")) " - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the `min_window_substring` function:\n", - "\n", - "**Time Complexity:**\n", - "- The main loop iterates through the string `s` from left to right using the `right` pointer. This loop runs in O(m) time, where 'm' is the length of string `s`.\n", - "\n", - "- Inside the loop, we have a while loop that moves the `left` pointer to the right to shrink the window as needed. In the worst case, this while loop can also run in O(m) time because in the worst case, we may have to move the `left` pointer all the way to the end of the string.\n", - "\n", - "- Within each iteration of the while loop, we perform constant time operations, such as updating dictionaries and comparing character counts.\n", - "\n", - "- The initialization of the `t_dict` dictionary takes O(n) time, where 'n' is the length of string `t`.\n", - "\n", - "Therefore, the overall time complexity of the function is O(m + n) because the dominant factor is the length of string `s`, and the length of string `t` has a smaller impact.\n", - "\n", - "**Space Complexity:**\n", - "- The space complexity is determined by the space used by the `t_dict` dictionary, the `current_window_dict` dictionary, and a few variables.\n", - "\n", - "- The `t_dict` dictionary stores character counts for string `t`. In the worst case, when all characters in `t` are distinct, this dictionary can have a maximum of 'n' key-value pairs. So, the space complexity for `t_dict` is O(n).\n", - "\n", - "- The `current_window_dict` dictionary stores character counts for the current window. In the worst case, it can have a maximum of 'm' key-value pairs. So, the space complexity for `current_window_dict` is also O(m).\n", - "\n", - "- Other variables used in the function, such as `left`, `right`, `min_len`, `min_window`, `required_chars`, and `found_chars`, are all of constant size and do not depend on the input sizes.\n", - "\n", - "**In summary**, the overall space complexity of the function is O(max(m, n)), which means it is determined by the larger of the two input strings' lengths. This is because the space used for `t_dict` and `current_window_dict` dominates the space complexity." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Smallest Distinct Substring:** Instead of finding the minimum window substring containing all characters, find the smallest distinct (unique) substring of s that contains all characters from t. This variation adds complexity because you must find a substring with distinct characters.\n", - "2. **No Extra Space:** Solve the problem without using any extra space, such as dictionaries or arrays, other than a constant amount of space. This is a significant optimization challenge." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/03. Sliding Window/README.md b/docs/_build/html/_sources/03. Sliding Window/README.md deleted file mode 100644 index e1294ff..0000000 --- a/docs/_build/html/_sources/03. Sliding Window/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# Sliding Window Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [121. Best Time to Buy And Sell Stock](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/) | Easy | -| [3. Longest Substring Without Repeating Characters](https://leetcode.com/problems/longest-substring-without-repeating-characters/) | Medium | -| [424. Longest Repeating Character Replacement](https://leetcode.com/problems/longest-repeating-character-replacement/) | Medium | -| [76. Minimum Window Substring](https://leetcode.com/problems/minimum-window-substring/) | Hard | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! \ No newline at end of file diff --git a/docs/_build/html/_sources/04. Stack/20. Valid Parentheses.ipynb b/docs/_build/html/_sources/04. Stack/20. Valid Parentheses.ipynb deleted file mode 100644 index c47292f..0000000 --- a/docs/_build/html/_sources/04. Stack/20. Valid Parentheses.ipynb +++ /dev/null @@ -1,220 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 20. Valid Parentheses\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Valid Parentheses problem on LeetCode, click here!](https://leetcode.com/problems/valid-parentheses/)\n", - "\n", - "---\n", - "\n", - "Given a string s containing just the characters `'('`, `')'`, `'{'`, `'}'`, `'['` and `']'`, determine if the input string is valid.\n", - "\n", - "An input string is valid if:\n", - "\n", - "1. Open brackets must be closed by the same type of brackets.\n", - "2. Open brackets must be closed in the correct order.\n", - "3. Every close bracket has a corresponding open bracket of the same type.\n", - "\n", - "**Constraints:**\n", - "\n", - "- 1 <= `s.length` <= $10^4$\n", - "- `s` consists of parentheses only `'()[]{}'`." - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def isValid(s):\n", - " # Create an empty stack to store opening brackets\n", - " stack = []\n", - " \n", - " # Define a mapping for matching brackets\n", - " bracket_mapping = {')': '(', '}': '{', ']': '['}\n", - " \n", - " # Iterate through the characters in the input string\n", - " for char in s:\n", - " # If the character is an opening bracket, push it onto the stack\n", - " if char in bracket_mapping.values():\n", - " stack.append(char)\n", - " # If the character is a closing bracket\n", - " elif char in bracket_mapping.keys():\n", - " # Pop the top element from the stack if it exists, or use a dummy value '#'\n", - " top_element = stack.pop() if stack else '#'\n", - " # If the popped element does not match the corresponding opening bracket, return False\n", - " if bracket_mapping[char] != top_element:\n", - " return False\n", - " # If the character is not a bracket, ignore it\n", - " \n", - " # After processing the entire string, if there are any unmatched opening brackets left in the stack, return False\n", - " return len(stack) == 0" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start by defining the `isValid` function that takes a single argument `s`, which is the input string containing parentheses and brackets.\n", - "\n", - "2. Inside the function, we create an empty stack, which is a list in Python, to store opening brackets as we encounter them in the input string. The stack will help us keep track of the brackets and their order.\n", - "\n", - "3. We define a `bracket_mapping` dictionary that maps each closing bracket to its corresponding opening bracket. This mapping will be used to check if a closing bracket matches the most recent opening bracket in the stack.\n", - "\n", - "4. We iterate through each character `char` in the input string `s` using a `for` loop.\n", - "\n", - "5. If the character `char` is an opening bracket (i.e., it exists in the `values()` of `bracket_mapping`), we push it onto the stack using the `append()` method.\n", - "\n", - "6. If the character `char` is a closing bracket (i.e., it exists in the `keys()` of `bracket_mapping`), we need to check if it matches the corresponding opening bracket. To do this, we pop the top element from the stack (if it exists) and store it in `top_element`. We use a dummy value `'#'` if the stack is empty to avoid errors.\n", - "\n", - "7. We then compare `top_element` with the corresponding opening bracket using `bracket_mapping[char]`. If they do not match, it means the string is not valid, and we return `False`.\n", - "\n", - "8. If the character `char` is not a bracket, we simply ignore it and continue the loop.\n", - "\n", - "9. After processing the entire string, we check if there are any unmatched opening brackets left in the stack. If the stack is empty, it means all opening brackets have been properly matched and closed, and we return `True`. Otherwise, we return `False`.\n", - "\n", - "10. Finally, we provide some test cases at the bottom of the code to demonstrate how the function works for different input strings." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "print(isValid(\"()\")) " - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "print(isValid(\"()[]{}\")) " - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "id": "6c69a707-02af-4212-b2e7-1881d62a62d2", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "print(isValid(\"(]\")) " - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the `isValid` function:\n", - "\n", - "**Time Complexity:**\n", - "- The function iterates through each character in the input string `s` once, performing constant-time operations for each character.\n", - "- Pushing and popping elements from the stack (list) also takes constant time in most cases.\n", - "- Therefore, the overall time complexity of the function is $O(n)$, where $n$ is the length of the input string `s`.\n", - "\n", - "**Space Complexity:**\n", - "- The space complexity of the function is determined by the space used by the stack and the `bracket_mapping` dictionary.\n", - "- In the worst case, if the input string `s` consists entirely of opening brackets, the stack can potentially contain all of these opening brackets, resulting in a space complexity of $O(n)$ in terms of the stack.\n", - "- The `bracket_mapping` dictionary has a constant number of key-value pairs (3 pairs in this case).\n", - "- Therefore, the overall space complexity of the function is $O(n)$, where $n$ is the length of the input string `s`, mainly due to the stack space.\n", - "\n", - "**In summary:**\n", - "- The time complexity is $O(n)$ because we iterate through the string once.\n", - "- The space complexity is $O(n)$ due to the stack used to keep track of opening brackets." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Valid Expressions:** Modify the problem to validate not only brackets but also arithmetic expressions containing parentheses, such as \"$2 * (3 + 5) / (4 - 2)$\".\n", - "2. **Valid Parentheses Combinations:**\n", - "Write a function to generate all valid combinations of n pairs of parentheses, where $n$ is a positive integer. For example, for $n = 3$, the valid combinations are [\"((()))\", \"(()())\", \"(())()\", \"()(())\", \"()()()\"]." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/04. Stack/README.md b/docs/_build/html/_sources/04. Stack/README.md deleted file mode 100644 index 2ed115b..0000000 --- a/docs/_build/html/_sources/04. Stack/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# Stack Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [20. Valid Parentheses](https://leetcode.com/problems/valid-parentheses/) | Easy | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! \ No newline at end of file diff --git a/docs/_build/html/_sources/05. Binary Search/153. Find Minimum in Rotated Sorted Array.ipynb b/docs/_build/html/_sources/05. Binary Search/153. Find Minimum in Rotated Sorted Array.ipynb deleted file mode 100644 index 98f2331..0000000 --- a/docs/_build/html/_sources/05. Binary Search/153. Find Minimum in Rotated Sorted Array.ipynb +++ /dev/null @@ -1,228 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 153. Find Minimum in Rotated Sorted Array\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Find Minimum in Rotated Sorted Array problem on LeetCode, click here!](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/)\n", - "\n", - "---\n", - "\n", - "Suppose an array of length `n` sorted in ascending order is **rotated** between `1` and `n` times. For example, the array `nums = [0,1,2,4,5,6,7]` might become:\n", - "\n", - "- `[4,5,6,7,0,1,2]` if it was rotated `4` times.\n", - "- `[0,1,2,4,5,6,7]` if it was rotated `7` times.\n", - "\n", - "Notice that **rotating** an array `[a[0], a[1], a[2], ..., a[n-1]]` 1 time results in the array `[a[n-1], a[0], a[1], a[2], ..., a[n-2]]`.\n", - "\n", - "Given the sorted rotated array `nums` of **unique** elements, return *the minimum element of this array.*\n", - "\n", - "You must write an algorithm that runs in $O(log\\ n)$ time.\n", - " \n", - "\n", - "**Constraints:**\n", - "\n", - "- `n == nums.length`\n", - "- `1 <= n <= 5000`\n", - "- `-5000 <= nums[i] <= 5000`\n", - "- All the integers of `nums` are **unique**.\n", - "- `nums` is sorted and rotated between `1` and `n` times." - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def findMin(nums):\n", - " left, right = 0, len(nums) - 1\n", - " \n", - " while left < right:\n", - " mid = left + (right - left) // 2\n", - " \n", - " # If the mid element is greater than the rightmost element,\n", - " # it means the minimum element is in the right half.\n", - " if nums[mid] > nums[right]:\n", - " left = mid + 1\n", - " # If the mid element is less than or equal to the rightmost element,\n", - " # it means the minimum element is in the left half or at the mid itself.\n", - " else:\n", - " right = mid\n", - " \n", - " # The loop will break when left and right converge to the minimum element.\n", - " # At this point, left (or right) will be pointing to the minimum element.\n", - " return nums[left]" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. The function `findMin(nums)` takes an input list `nums`, which represents the rotated sorted array.\n", - "\n", - "2. Initialize two pointers `left` and `right` to track the current search range. Initially, `left` is set to 0 (the beginning of the array), and `right` is set to `len(nums) - 1` (the end of the array).\n", - "\n", - "3. Enter a `while` loop with the condition `left < right`. This loop continues until `left` and `right` converge to a single element, which will be the minimum element in the rotated array.\n", - "\n", - "4. Inside the loop, calculate the middle index `mid` using integer division. This helps in finding the middle element of the current search range.\n", - "\n", - "5. Check if the element at the middle index (`nums[mid]`) is greater than the element at the rightmost index (`nums[right]`). If this condition is true, it means that the minimum element must be in the right half of the current search range. So, update `left` to `mid + 1`, effectively eliminating the left half of the search range.\n", - "\n", - "6. If the condition from step 5 is not met, it implies that the minimum element can be in the left half of the current search range or could be the element at the `mid` index itself. In this case, update `right` to `mid`, effectively eliminating the right half of the search range.\n", - "\n", - "7. Repeat steps 4-6 until `left` and `right` converge to the minimum element.\n", - "\n", - "8. When the loop exits, it means that `left` (or `right`) points to the minimum element in the array.\n", - "\n", - "9. Return `nums[left]` (or `nums[right]`) as the result, which is the minimum element in the rotated sorted array." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n" - ] - } - ], - "source": [ - "### Example 1:\n", - "nums1 = [3, 4, 5, 1, 2]\n", - "print(findMin(nums1))" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "nums2 = [4, 5, 6, 7, 0, 1, 2]\n", - "print(findMin(nums2))" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "id": "6c69a707-02af-4212-b2e7-1881d62a62d2", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "11\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "nums3 = [11, 13, 15, 17]\n", - "print(findMin(nums3))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "The time complexity of this code is $O(log\\ n)$, where '$n$' is the length of the input array `nums`. This is because the binary search algorithm is employed, which continually divides the search range in half with each iteration.\n", - "\n", - "In each iteration of the `while` loop, the search range is halved, and this process continues until the `left` and `right` pointers converge to the minimum element. In the worst case, it will take logarithmic time to reduce the search range to a single element.\n", - "\n", - "Therefore, the binary search used in this code runs in $O(log\\ n)$ time complexity.\n", - "\n", - "**Space Complexity:**\n", - "The space complexity of this code is $O(1)$, which means it uses a constant amount of additional space that does not depend on the size of the input array.\n", - "\n", - "The algorithm uses a fixed number of variables (`left`, `right`, `mid`) to keep track of the search range and indices, but the number of these variables does not grow with the size of the input array. Hence, the space complexity is constant.\n", - "\n", - "**In summary:**\n", - "- Time Complexity: $O(log\\ n)$\n", - "- Space Complexity: $O(1)$" - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. Solve the problem with a variation where the input array may contain duplicates.\n", - "\n", - "2. Modify the problem to return the index of the minimum element in the rotated sorted array, rather than the element itself. The algorithm should still run in $O(log\\ n)$ time.\n", - "\n", - "3. Implement a function that finds the maximum element in a rotated sorted array. How would you adapt the binary search algorithm to solve this problem efficiently in $O(log\\ n)$ time?\n", - "\n", - "4. Implement a function that can find the kth smallest element in a rotated sorted array. This is an extension of the original problem, and the algorithm should still run in $O(log\\ n)$ time." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/05. Binary Search/33. Search in Rotated Sorted Array.ipynb b/docs/_build/html/_sources/05. Binary Search/33. Search in Rotated Sorted Array.ipynb deleted file mode 100644 index d8d4202..0000000 --- a/docs/_build/html/_sources/05. Binary Search/33. Search in Rotated Sorted Array.ipynb +++ /dev/null @@ -1,245 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 33. Search in Rotated Sorted Array\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Search in Rotated Sorted Array problem on LeetCode, click here!](https://leetcode.com/problems/search-in-rotated-sorted-array/)\n", - "\n", - "---\n", - "\n", - "There is an integer array `nums` sorted in ascending order (with **distinct** values).\n", - "\n", - "Prior to being passed to your function, `nums` is **possibly rotated** at an unknown pivot index `k (1 <= k < nums.length)` such that the resulting array is `[nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]]` (**0-indexed**). For example, `[0,1,2,4,5,6,7]` might be rotated at pivot index 3 and become `[4,5,6,7,0,1,2]`.\n", - "\n", - "Given the array `nums` **after** the possible rotation and an integer `target`, return *the index of `target` if it is in `nums`, or `-1` if it is not in `nums`.*\n", - "\n", - "You must write an algorithm with $O(log\\ n)$ runtime complexity.\n", - " \n", - "\n", - "**Constraints:**\n", - "\n", - "- `1 <= nums.length <= 5000`\n", - "- $-10^4$ <= `nums[i]` <= $10^4$\n", - "- All values of `nums` are **unique**.\n", - "- `nums` is an ascending array that is possibly rotated.\n", - "- $-10^4$ <= `target` <= $10^4$" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def search(nums, target):\n", - " left, right = 0, len(nums) - 1\n", - "\n", - " # Find the pivot index using binary search\n", - " while left < right:\n", - " mid = left + (right - left) // 2\n", - "\n", - " if nums[mid] > nums[right]:\n", - " left = mid + 1\n", - " else:\n", - " right = mid\n", - "\n", - " pivot = left\n", - " left, right = 0, len(nums) - 1\n", - "\n", - " # Determine which part of the array to search in\n", - " if target >= nums[pivot] and target <= nums[right]:\n", - " left = pivot\n", - " else:\n", - " right = pivot\n", - "\n", - " # Perform binary search to find the target\n", - " while left <= right:\n", - " mid = left + (right - left) // 2\n", - "\n", - " if nums[mid] == target:\n", - " return mid\n", - " elif nums[mid] < target:\n", - " left = mid + 1\n", - " else:\n", - " right = mid - 1\n", - "\n", - " return -1" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. The `search` function takes two arguments: `nums`, which is the rotated sorted array, and `target`, which is the value we want to find in the array.\n", - "\n", - "2. We initialize two pointers, `left` and `right`, which represent the range in which we are going to perform binary search. Initially, `left` is set to 0, and `right` is set to the index of the last element in the array (`len(nums) - 1`).\n", - "\n", - "3. We start by finding the pivot index using binary search. The pivot index is the index at which the array is rotated. We use a `while` loop to continue the search until `left` is less than `right`.\n", - "\n", - "4. Inside the loop, we calculate the middle index `mid` using integer division. We then compare the value at `mid` with the value at `right`. If `nums[mid]` is greater than `nums[right]`, it means the pivot point lies to the right of `mid`, so we update `left` to `mid + 1`. Otherwise, the pivot point lies to the left of `mid`, so we update `right` to `mid`. This process continues until we find the pivot index.\n", - "\n", - "5. After finding the pivot index, we have divided the array into two parts: one part is sorted in ascending order, and the other part is also sorted in ascending order but rotated. We need to determine which part of the array contains the target value.\n", - "\n", - "6. We reset `left` and `right` pointers. If the target value is within the range `[nums[pivot], nums[right]]`, we set `left` to `pivot` (the start of the rotated part), indicating that we should search in the rotated part. Otherwise, we set `right` to `pivot` (the end of the sorted part), indicating that we should search in the sorted part.\n", - "\n", - "7. We then perform binary search again within the chosen range (`left` to `right`) to find the target element. The binary search continues until `left` is less than or equal to `right`.\n", - "\n", - "8. Inside the binary search loop, we calculate the middle index `mid` and compare `nums[mid]` with the target value. If they are equal, we return `mid` as the index of the target element. If `nums[mid]` is less than the target, we update `left` to `mid + 1` to search in the right half. If `nums[mid]` is greater than the target, we update `right` to `mid - 1` to search in the left half.\n", - "\n", - "9. If we exit the binary search loop without finding the target, we return -1 to indicate that the target is not present in the array." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n" - ] - } - ], - "source": [ - "nums1 = [4, 5, 6, 7, 0, 1, 2]\n", - "target1 = 0\n", - "result1 = search(nums1, target1)\n", - "print(result1) " - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "-1\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "nums2 = [4, 5, 6, 7, 0, 1, 2]\n", - "target2 = 3\n", - "result2 = search(nums2, target2)\n", - "print(result2) " - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "id": "6c69a707-02af-4212-b2e7-1881d62a62d2", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "-1\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "nums3 = [1]\n", - "target3 = 0\n", - "result3 = search(nums3, target3)\n", - "print(result3) " - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. Finding the pivot index using binary search takes $O(log\\ n)$ time, where '$n$' is the number of elements in the array.\n", - "2. After finding the pivot index, performing binary search to find the target element also takes $O(log\\ n)$ time in the worst case.\n", - "\n", - "The dominant factor in the time complexity is the binary search, and since we perform two binary searches sequentially, the overall time complexity of the code is $O(log\\ n)$.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity of the code is very minimal:\n", - "\n", - "1. We use a constant amount of additional space for variables such as `left`, `right`, `pivot`, and `mid`. These variables do not depend on the input size, so they contribute $O(1)$ space complexity.\n", - "2. The function does not use any additional data structures that scale with the input size.\n", - "\n", - "Therefore, the space complexity of the code is $O(1)$, which means it has a constant space complexity and does not depend on the size of the input array.\n", - "\n", - "**In summary:**\n", - "- Time Complexity: $O(log\\ n)$\n", - "- Space Complexity: $O(1)$" - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Find Minimum Element in Rotated Sorted Array**: Write an algorithm to find the minimum element in a rotated sorted array. This is a variation of the problem where you don't need to search for a target value but instead find the smallest element.\n", - "\n", - "2. **Search in a Circularly Sorted Array**: Consider an array that is sorted in a circular manner (e.g., [4, 5, 6, 7, 0, 1, 2, 3]). Adapt the search algorithm to work for circularly sorted arrays while maintaining $O(log\\ n)$ complexity." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/05. Binary Search/README.md b/docs/_build/html/_sources/05. Binary Search/README.md deleted file mode 100644 index 6086b9b..0000000 --- a/docs/_build/html/_sources/05. Binary Search/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Binary search Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [153. Find Minimum In Rotated Sorted Array](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/) | Medium | -| [33. Search In Rotated Sorted Array](https://leetcode.com/problems/search-in-rotated-sorted-array/) | Medium | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! diff --git a/docs/_build/html/_sources/06. Linked List/141. Linked List Cycle.ipynb b/docs/_build/html/_sources/06. Linked List/141. Linked List Cycle.ipynb deleted file mode 100644 index 0336bc8..0000000 --- a/docs/_build/html/_sources/06. Linked List/141. Linked List Cycle.ipynb +++ /dev/null @@ -1,271 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 141. Linked List Cycle\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Linked List Cycle problem on LeetCode, click here!](https://leetcode.com/problems/linked-list-cycle/)\n", - "\n", - "---\n", - "\n", - "Given `head`, the head of a linked list, determine if the linked list has a cycle in it.\n", - "\n", - "There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the `next` pointer. Internally, `pos` is used to denote the index of the node that tail's `next` pointer is connected to. **Note that `pos` is not passed as a parameter.**\n", - "\n", - "Return `true` if there is a cycle in the linked list. Otherwise, return `false`.\n", - "\n", - " \n", - "\n", - "**Constraints:**\n", - "\n", - "- The number of the nodes in the list is in the range $[0, 10^4]$.\n", - "- $-10^5$ <= Node.val <= $10^5$\n", - "- `pos` is `-1` or a **valid index** in the linked-list.\n", - "\n", - "**Follow up:** Can you solve it using $O(1)$ (i.e. constant) memory?" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for singly-linked list.\n", - "class ListNode:\n", - " def __init__(self, val=0):\n", - " self.val = val\n", - " self.next = None\n", - "\n", - "class Solution:\n", - " def hasCycle(self, head: ListNode) -> bool:\n", - " if not head:\n", - " return False\n", - " \n", - " slow = head\n", - " fast = head\n", - " \n", - " while fast and fast.next:\n", - " slow = slow.next\n", - " fast = fast.next.next\n", - " \n", - " if slow == fast:\n", - " return True\n", - " \n", - " return False" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The given code defines a class `Solution` with a method `hasCycle` for determining if a linked list has a cycle.\n", - "\n", - "The `ListNode` class represents nodes in the linked list, where each node has a `val` (a value associated with the node) and a `next` attribute (a reference to the next node in the list).\n", - "\n", - "The `hasCycle` method takes the `head` of a linked list as input and returns `True` if there is a cycle in the linked list, and `False` otherwise. It uses two pointers, `slow` and `fast`, to traverse the linked list. If there is a cycle, the `fast` pointer will eventually catch up to the `slow` pointer.\n", - "\n", - "The algorithm works as follows:\n", - "1. It checks if the input `head` is `None` (an empty list). If it is, the method returns `False` because an empty list can't have a cycle.\n", - "2. Two pointers, `slow` and `fast`, initially point to the `head` of the list.\n", - "3. The code enters a `while` loop where `fast` moves two steps at a time, and `slow` moves one step at a time.\n", - "4. If there is a cycle, `fast` will eventually catch up to `slow`, and the method returns `True`.\n", - "5. If the loop completes without finding a cycle, the method returns `False`." - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "01849ced-1bbf-4956-8e54-451b358cb4fe", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Helper function to create a linked list with a cycle\n", - "def create_linked_list_with_cycle(values, pos):\n", - " dummy = ListNode()\n", - " current = dummy\n", - " cycle_node = None\n", - " \n", - " for i, val in enumerate(values):\n", - " current.next = ListNode(val)\n", - " current = current.next\n", - " \n", - " if i == pos:\n", - " cycle_node = current\n", - " \n", - " if cycle_node:\n", - " current.next = cycle_node\n", - " \n", - " return dummy.next" - ] - }, - { - "cell_type": "markdown", - "id": "f7490d01-d64e-4f20-b178-e14490d6dd6f", - "metadata": {}, - "source": [ - "This helper function is designed to create a linked list with a cycle for testing purposes. It takes two arguments:\n", - "\n", - "1. `values`: A list of values representing the nodes in the linked list.\n", - "2. `pos`: An integer representing the index of the node where the cycle begins.\n", - "\n", - "Here's how the function works:\n", - "\n", - "- It starts by creating an empty `ListNode` called `dummy`. This `dummy` node is used to simplify the creation of the linked list.\n", - "- It initializes a `current` pointer to the `dummy` node. This pointer will be used to traverse the linked list.\n", - "- It initializes a `cycle_node` variable to `None`. This variable will hold the reference to the node where the cycle begins, if any.\n", - "- It then iterates through the `values` list, creating a new `ListNode` for each value and appending it to the linked list.\n", - "- Inside the loop, it checks if the current index `i` is equal to the specified `pos`. If they match, it sets `cycle_node` to the current node. This simulates the creation of a cycle in the linked list.\n", - "- After the loop, if `cycle_node` is not `None` (indicating a cycle should be created), it connects the last node in the linked list to `cycle_node`, effectively creating a cycle.\n", - "- Finally, it returns the reference to the first node of the linked list (not the `dummy` node).\n", - "\n", - "This helper function allows you to easily create test cases where you can specify the values for the linked list and the position where the cycle starts. It's particularly useful for testing the code's ability to detect cycles in linked lists." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "### Example 1\n", - "head = [3,2,0,-4]\n", - "pos = 1\n", - "\n", - "head = create_linked_list_with_cycle(head, pos)\n", - "solution = Solution()\n", - "result = solution.hasCycle(head)\n", - "print(result)" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "### Example 2\n", - "head = [1,2]\n", - "pos = 0\n", - "\n", - "head = create_linked_list_with_cycle(head, pos)\n", - "solution = Solution()\n", - "result = solution.hasCycle(head)\n", - "print(result)" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "e140b956-7b3d-40d5-b6b0-9615860af67e", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "### Example 3\n", - "head = [1]\n", - "pos = -1\n", - "\n", - "head = create_linked_list_with_cycle(head, pos)\n", - "solution = Solution()\n", - "result = solution.hasCycle(head)\n", - "print(result)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's discuss the time and space complexity of the code for detecting a cycle in a linked list:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The time complexity of this code is $O(n)$, where \"$n$\" is the number of nodes in the linked list.\n", - "\n", - "The reason for this is that both the `slow` and `fast` pointers traverse the linked list, and they move at different speeds. In the worst case, when there is no cycle, the `fast` pointer will reach the end of the list after going through approximately $n/2$ nodes. In the case of a cycle, it may take some extra iterations for the `fast` pointer to catch up to the `slow` pointer. However, the total number of iterations is still proportional to the number of nodes in the linked list, making it $O(n)$.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity of this code is $O(1)$, which means it uses constant space.\n", - "\n", - "The reason for this is that regardless of the size of the linked list, the code only uses two additional pointers (`slow` and `fast`) to traverse the list. These pointers do not depend on the size of the input linked list, so the space complexity remains constant.\n", - "\n", - "**In summary**, this code efficiently detects cycles in a linked list with a time complexity of $O(n)$ and a space complexity of $O(1)$. It is an example of an algorithm that solves a complex problem with minimal memory usage." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/06. Linked List/143. Reorder List.ipynb b/docs/_build/html/_sources/06. Linked List/143. Reorder List.ipynb deleted file mode 100644 index a83545b..0000000 --- a/docs/_build/html/_sources/06. Linked List/143. Reorder List.ipynb +++ /dev/null @@ -1,285 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 143. Reorder List\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Reorder List problem on LeetCode, click here!](https://leetcode.com/problems/reorder-list/)\n", - "\n", - "---\n", - "\n", - "You are given the head of a singly linked-list. The list can be represented as:\n", - "\n", - "$L_0 → L_1 → … → L_{n - 1} → L_n$\n", - "\n", - "Reorder the list to be on the following form:\n", - "\n", - "$L_0 → L_n → L_1 → L_{n - 1} → L_2 → L_{n - 2} → …$\n", - "\n", - "You may not modify the values in the list's nodes. Only nodes themselves may be changed.\n", - " \n", - "\n", - "**Constraints:**\n", - "\n", - "- The number of nodes in the list is in the range $[1, 5 * 10^4]$.\n", - "- `1 <= Node.val <= 1000`" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class ListNode:\n", - " def __init__(self, val=0, next=None):\n", - " self.val = val\n", - " self.next = next\n", - "\n", - "def reorderList(head):\n", - " if not head or not head.next:\n", - " return head\n", - "\n", - " # Step 1: Find the middle of the linked list\n", - " slow, fast = head, head\n", - " while fast.next and fast.next.next:\n", - " slow = slow.next\n", - " fast = fast.next.next\n", - "\n", - " # Split the list into two halves\n", - " first_half = head\n", - " second_half = slow.next\n", - " slow.next = None\n", - "\n", - " # Step 2: Reverse the second half of the linked list\n", - " prev = None\n", - " current = second_half\n", - " while current:\n", - " next_node = current.next\n", - " current.next = prev\n", - " prev = current\n", - " current = next_node\n", - " second_half = prev\n", - "\n", - " # Step 3: Merge the first and reversed second halves alternately\n", - " p1, p2 = first_half, second_half\n", - " while p2:\n", - " next_p1 = p1.next\n", - " next_p2 = p2.next\n", - " p1.next = p2\n", - " p2.next = next_p1\n", - " p1 = next_p1\n", - " p2 = next_p2\n", - "\n", - " return head" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The `reorderList` function is designed to reorder a singly linked list following the specific pattern described in the problem statement. Here's a detailed explanation of how the function works:\n", - "\n", - "1. **Base Cases Handling**:\n", - " - The function first checks if the input linked list is empty (`not head`) or contains only one element (`not head.next`). If either of these conditions is met, the list cannot be reordered, so the function returns the original list as-is.\n", - "\n", - "2. **Finding the Middle of the Linked List**:\n", - " - To reorder the list, we first need to find the middle point so that we can split the list into two halves. This is done using two pointers, `slow` and `fast`, initialized to the head of the list.\n", - " - `slow` moves one step at a time while `fast` moves two steps at a time. When `fast` reaches the end of the list or the second-to-last node, `slow` will be at the middle node.\n", - "\n", - "3. **Splitting the List**:\n", - " - After finding the middle node, we split the list into two halves:\n", - " - The first half, `first_half`, contains nodes from the beginning up to the middle.\n", - " - The second half, `second_half`, contains nodes from the middle to the end.\n", - " - To split the list, we set the `next` pointer of the node before the middle node to `None`.\n", - "\n", - "4. **Reversing the Second Half**:\n", - " - We reverse the second half of the linked list using the `prev`, `current`, and `next_node` pointers.\n", - " - `prev` is initially `None`, and we iterate through the second half. For each node, we:\n", - " - Set the `next` of the current node to `prev`, effectively reversing the next pointer direction.\n", - " - Update `prev` to the current node.\n", - " - Move to the next node using the `next_node`.\n", - "\n", - "5. **Merging the Two Halves Alternately**:\n", - " - We now have two linked lists: `first_half` and the reversed `second_half`.\n", - " - We merge these two lists alternately by adjusting the `next` pointers of the nodes.\n", - " - `p1` and `p2` are pointers to the current nodes in `first_half` and `second_half`, respectively.\n", - " - We iterate through both lists while reordering nodes:\n", - " - Set the `next` of `p1` to `p2` to link a node from the first half to a node from the reversed second half.\n", - " - Update `p1` and `p2` to their respective next nodes.\n", - " - Repeat this process until we have processed all nodes in both halves.\n", - "\n", - "6. **Returning the Reordered List**:\n", - " - After the merging process is complete, the linked list is reordered as specified.\n", - " - The function returns the `head` of the reordered list.\n", - "\n", - "The overall result is a singly linked list that has been reordered according to the given pattern. The time complexity of this algorithm is O(N), where N is the number of nodes in the linked list, as we traverse the list once to find the middle, once to reverse the second half, and once to merge the two halves." - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "id": "01849ced-1bbf-4956-8e54-451b358cb4fe", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Helper function to print the linked list\n", - "def printLinkedList(head):\n", - " result = []\n", - " while head:\n", - " result.append(head.val)\n", - " head = head.next\n", - " return result" - ] - }, - { - "cell_type": "markdown", - "id": "f7490d01-d64e-4f20-b178-e14490d6dd6f", - "metadata": {}, - "source": [ - "Let's explain the helper functions:\n", - "**printLinkedList Function**:\n", - " - The `printLinkedList` function takes the `head` of a linked list as input and returns a list of values representing the nodes in the linked list.\n", - " - Inside the function, a `result` list is initialized to store the values of the linked list nodes.\n", - " - The function then iterates through the linked list starting from the `head` node and appends the `val` attribute of each node to the `result` list.\n", - " - As it iterates through the list, it moves to the next node using the `next` attribute of each node.\n", - " - Finally, the function returns the `result` list containing the values of the linked list nodes in the order they appear in the linked list.\n", - "\n", - " This function is useful for debugging and displaying the contents of a linked list. It allows you to easily convert a linked list into a regular Python list for visualization and testing purposes." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 4, 2, 3]\n" - ] - } - ], - "source": [ - "# Example 1\n", - "head1 = ListNode(1, ListNode(2, ListNode(3, ListNode(4))))\n", - "reorderList(head1)\n", - "print(printLinkedList(head1))" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 5, 2, 4, 3]\n" - ] - } - ], - "source": [ - "# Example 2\n", - "head2 = ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5)))))\n", - "reorderList(head2)\n", - "print(printLinkedList(head2))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the `reorderList` function:\n", - "\n", - "**Time Complexity**:\n", - "1. **Finding the Middle of the Linked List**: In this step, we use two pointers, one moving one step at a time (`slow`) and the other moving two steps at a time (`fast`). This process takes $O(N/2)$ time, where $N$ is the number of nodes in the linked list.\n", - "\n", - "2. **Splitting the List**: After finding the middle, we split the list into two halves by setting the `next` pointer of the node before the middle node to `None`. This step takes $O(1)$ time.\n", - "\n", - "3. **Reversing the Second Half**: We reverse the second half of the linked list using a while loop that iterates through the second half of the list once. Therefore, this step also takes $O(N/2)$ time.\n", - "\n", - "4. **Merging the Two Halves Alternately**: In this step, we merge the two halves alternately by adjusting the `next` pointers of the nodes. We iterate through both halves once, so this step takes $O(N/2)$ time.\n", - "\n", - "Overall, the time complexity of the `reorderList` function is dominated by the steps involving reversing and merging the two halves, both of which take $O(N/2)$ time. Therefore, the total time complexity is $O(N)$.\n", - "\n", - "**Space Complexity**:\n", - "The space complexity of the `reorderList` function is primarily determined by the variables and data structures used within the function. Let's break down the space complexity components:\n", - "\n", - "1. **Constant Space Variables**: The variables `slow`, `fast`, `prev`, `current`, `next_node`, `p1`, and `p2` are used to traverse and manipulate the linked list. These variables occupy constant space, regardless of the input size. Therefore, they contribute $O(1)$ to the space complexity.\n", - "\n", - "2. **Split Linked Lists**: In the splitting step, we create two new linked list segments (`first_half` and `second_half`) that store references to nodes from the original linked list. These segments occupy space proportional to half of the input list, $O(N/2)$. \n", - "\n", - "3. **Reversed Second Half**: During the reversal step, we reverse the second half of the linked list in-place without creating any additional data structures. Therefore, it doesn't contribute to additional space complexity.\n", - "\n", - "4. **Overall**: Combining the above components, the total space complexity is $O(N/2)$, which simplifies to $O(N)$ in terms of space complexity.\n", - "\n", - "**In summary**, the `reorderList` function has a time complexity of $O(N)$ and a space complexity of $O(N)$ due to the creation of two new linked list segments while splitting the list. The constant space variables used for traversal do not significantly impact the overall space complexity." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Reorder by K Elements:** Generalize the reorderList function to reorder the list in a different pattern, where you reorder the list by $K$ elements at a time. For example, for $K=3$, you would reorder it as ($L_0 → L_1 → L_2 → L_n → L_{n-1} → L_{n-2} → ...$).\n", - "You may need to handle cases where the number of nodes is not a multiple of $K$.\n", - "\n", - "2. **Reorder by Odd and Even Nodes:** Modify the reorderList function to reorder the list in a pattern where odd-indexed nodes (1-based index) come before even-indexed nodes. For example, ($L_0 → L_n → L_1 → L_{n-1} → L_2 → L_{n-2} → ...$)." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/06. Linked List/19. Remove Nth Node From End of List.ipynb b/docs/_build/html/_sources/06. Linked List/19. Remove Nth Node From End of List.ipynb deleted file mode 100644 index 263124e..0000000 --- a/docs/_build/html/_sources/06. Linked List/19. Remove Nth Node From End of List.ipynb +++ /dev/null @@ -1,278 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 19. Remove Nth Node From End of List\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Remove Nth Node From End of List problem on LeetCode, click here!](https://leetcode.com/problems/remove-nth-node-from-end-of-list/)\n", - "\n", - "---\n", - "\n", - "Given the head of a linked list, remove the $n^{th}$ node from the end of the list and return its head.\n", - " \n", - "\n", - "**Constraints:**\n", - "\n", - "- The number of nodes in the list is `sz`.\n", - "- `1 <= sz <= 30`\n", - "- `0 <= Node.val <= 100`\n", - "- `1 <= n <= sz`\n", - "\n", - "**Follow up:** Could you do this in one pass?" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class ListNode:\n", - " def __init__(self, val=0, next=None):\n", - " self.val = val\n", - " self.next = next\n", - "\n", - "def removeNthFromEnd(head, n):\n", - " # Create a dummy node to handle the case of removing the head node.\n", - " dummy = ListNode(0)\n", - " dummy.next = head\n", - " first = dummy\n", - " second = dummy\n", - " \n", - " # Advance the first pointer by n+1 nodes.\n", - " for _ in range(n + 1):\n", - " first = first.next\n", - " \n", - " # Move both pointers simultaneously until first reaches the end.\n", - " while first is not None:\n", - " first = first.next\n", - " second = second.next\n", - " \n", - " # Remove the nth node by updating the next pointer of the previous node.\n", - " second.next = second.next.next\n", - " \n", - " return dummy.next # Return the modified head of the linked list" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start by defining a `ListNode` class to represent individual nodes in a linked list. Each node has two attributes: `val` (the value of the node) and `next` (a reference to the next node in the list).\n", - "\n", - "2. The `removeNthFromEnd` function takes the head of a linked list (`head`) and the value `n`, which represents the position from the end of the list of the node to be removed. It returns the modified head of the linked list after the removal.\n", - "\n", - "3. We create a dummy node (`dummy`) at the beginning of the list. This dummy node simplifies the code by handling cases where the head of the list needs to be removed.\n", - "\n", - "4. We initialize two pointers, `first` and `second`, both initially pointing to the dummy node.\n", - "\n", - "5. To advance the `first` pointer by `n+1` nodes, we use a `for` loop. This positions the `first` pointer `n` nodes ahead of the `second` pointer.\n", - "\n", - "6. We then move both `first` and `second` pointers simultaneously until `first` reaches the end of the list. This ensures that the `second` pointer ends up pointing to the node that needs to be removed.\n", - "\n", - "7. To remove the nth node from the end, we update the `next` pointer of the node pointed to by the `second` pointer to skip over the node to be removed.\n", - "\n", - "8. Finally, we return `dummy.next`, which is the modified head of the linked list without the removed node.\n", - "\n", - "9. Additionally, there are two helper functions:\n", - " - `createLinkedList(values)` creates a linked list from a list of values.\n", - " - `convertToList(head)` converts a linked list back into a list of values." - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "id": "01849ced-1bbf-4956-8e54-451b358cb4fe", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Helper function to create a linked list from a list of values.\n", - "def createLinkedList(values):\n", - " if not values:\n", - " return None\n", - " head = ListNode(values[0])\n", - " current = head\n", - " for val in values[1:]:\n", - " current.next = ListNode(val)\n", - " current = current.next\n", - " return head\n", - "\n", - "# Helper function to convert a linked list to a list of values.\n", - "def convertToList(head):\n", - " result = []\n", - " current = head\n", - " while current:\n", - " result.append(current.val)\n", - " current = current.next\n", - " return result" - ] - }, - { - "cell_type": "markdown", - "id": "f7490d01-d64e-4f20-b178-e14490d6dd6f", - "metadata": {}, - "source": [ - "Let's explain the two helper functions:\n", - "\n", - "1. `createLinkedList(values)`: This function creates a linked list from a list of values.\n", - "\n", - " - Input: `values` is a list containing values that you want to insert into the linked list.\n", - " - Output: The function returns the head of the created linked list.\n", - "\n", - " Explanation:\n", - " - The function starts by checking if the `values` list is empty. If it is, it returns `None` to indicate an empty linked list.\n", - " - If the `values` list is not empty, it creates the first node of the linked list with the value from the first element of `values`.\n", - " - It then iterates through the remaining elements of `values` and creates new nodes for each value, connecting them together using the `next` attribute to form a linked list.\n", - " - Finally, it returns the head of the linked list, which is the first node created.\n", - " \n", - "\n", - "2. `convertToList(head)`: This function converts a linked list into a list of values.\n", - "\n", - " - Input: `head` is the head node of the linked list that you want to convert.\n", - " - Output: The function returns a list containing the values of the nodes in the linked list in order.\n", - "\n", - " Explanation:\n", - " - The function starts by initializing an empty list, `result`, to store the values of the linked list nodes.\n", - " - It then iterates through the linked list starting from the `head` node and appends the `val` attribute of each node to the `result` list.\n", - " - The iteration continues until it reaches the end of the linked list (i.e., the `next` attribute of the current node becomes `None`).\n", - " - After the iteration is complete, the function returns the `result` list, which now contains the values of all the nodes in the linked list in the same order as they appear in the linked list.\n", - "\n", - "These helper functions are useful for creating linked lists from lists of values and converting linked lists back into lists of values, making it easier to work with linked list examples and test cases in a more familiar list format." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 2, 3, 5]\n" - ] - } - ], - "source": [ - "# Example 1\n", - "head1 = createLinkedList([1, 2, 3, 4, 5])\n", - "n1 = 2\n", - "new_head1 = removeNthFromEnd(head1, n1)\n", - "print(convertToList(new_head1))" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[]\n" - ] - } - ], - "source": [ - "# Example 2\n", - "head2 = createLinkedList([1])\n", - "n2 = 1\n", - "new_head2 = removeNthFromEnd(head2, n2)\n", - "print(convertToList(new_head2))" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "id": "e140b956-7b3d-40d5-b6b0-9615860af67e", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1]\n" - ] - } - ], - "source": [ - "# Example 3\n", - "head3 = createLinkedList([1, 2])\n", - "n3 = 1\n", - "new_head3 = removeNthFromEnd(head3, n3)\n", - "print(convertToList(new_head3))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Certainly! Let's analyze the time and space complexity of the `removeNthFromEnd` function in isolation:\n", - "\n", - "**Time Complexity:**\n", - "- The `removeNthFromEnd` function performs two passes through the linked list. In the worst case, it needs to traverse the entire linked list of length $N$.\n", - "- The first pass positions the `first` pointer $n$ nodes ahead of the `second` pointer. This pass takes $O(N)$ time because it involves iterating through all N nodes.\n", - "- The second pass moves both `first` and `second` pointers simultaneously until `first` reaches the end of the list. This also takes $O(N)$ time in the worst case.\n", - "- Therefore, the overall time complexity of the `removeNthFromEnd` function is $O(N)$.\n", - "\n", - "**Space Complexity:**\n", - "- The `removeNthFromEnd` function uses a constant amount of extra space for its variables (e.g., `first`, `second`, and `dummy`). This space usage does not depend on the size of the linked list.\n", - "- The space complexity is $O(1)$, indicating that the space used by the function is constant and independent of the size of the input linked list.\n", - "\n", - "**In summary**, the `removeNthFromEnd` function has a time complexity of $O(N)$ and a space complexity of $O(1)$. It efficiently removes the nth node from the end of the linked list with a single pass through the list and constant extra space usage." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/06. Linked List/206. Reverse Linked List.ipynb b/docs/_build/html/_sources/06. Linked List/206. Reverse Linked List.ipynb deleted file mode 100644 index c97de2d..0000000 --- a/docs/_build/html/_sources/06. Linked List/206. Reverse Linked List.ipynb +++ /dev/null @@ -1,316 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 206. Reverse Linked List\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Reverse Linked List problem on LeetCode, click here!](https://leetcode.com/problems/reverse-linked-list/)\n", - "\n", - "---\n", - "\n", - "Given the `head` of a singly linked list, reverse the list, and return the reversed list.\n", - " \n", - "\n", - "**Constraints:**\n", - "\n", - "- The number of nodes in the list is the range `[0, 5000]`.\n", - "- `-5000 <= Node.val <= 5000`\n", - "\n", - "**Follow up:** A linked list can be reversed either iteratively or recursively. Could you implement both?" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for singly-linked list.\n", - "class ListNode:\n", - " def __init__(self, val=0, next=None):\n", - " self.val = val\n", - " self.next = next\n", - "\n", - "# Function to reverse a linked list iteratively\n", - "def reverseListIterative(head):\n", - " prev = None\n", - " current = head\n", - " \n", - " while current:\n", - " next_node = current.next\n", - " current.next = prev\n", - " prev = current\n", - " current = next_node\n", - " \n", - " return prev\n", - "\n", - "# Function to reverse a linked list recursively\n", - "def reverseListRecursive(head):\n", - " if not head or not head.next:\n", - " return head\n", - "\n", - " new_head = reverseListRecursive(head.next)\n", - " head.next.next = head\n", - " head.next = None\n", - "\n", - " return new_head" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. `reverseListIterative(head)`: This function reverses a linked list iteratively using a loop. Here's a step-by-step explanation:\n", - "\n", - " - It takes the `head` of the input linked list as a parameter.\n", - " - It initializes two pointers, `prev` and `current`, initially set to `None` and the `head` of the list, respectively.\n", - " - It enters a `while` loop that continues until `current` reaches the end of the list (i.e., becomes `None`).\n", - " - Inside the loop:\n", - " - It stores the `next_node` which is the next node after `current`.\n", - " - It updates the `next` pointer of `current` to point to the `prev` node. This effectively reverses the link direction.\n", - " - It moves `prev` to `current` and `current` to `next_node`, advancing the pointers one step further in the list.\n", - " - Once the loop completes, `prev` will be pointing to the new head of the reversed list (which was the last node of the original list), so it returns `prev`.\n", - "\n", - "2. `reverseListRecursive(head)`: This function reverses a linked list recursively. Here's how it works:\n", - "\n", - " - It takes the `head` of the input linked list as a parameter.\n", - " - The base case is checked: if `head` is `None` or `head.next` is `None`, meaning the list is empty or has only one node, it returns `head` as there's no need to reverse a list with zero or one element.\n", - " - In the recursive case:\n", - " - It calls itself with `head.next`, effectively moving down the list until it reaches the end.\n", - " - Once it reaches the end, it starts reversing the links:\n", - " - `head.next.next` is set to `head`, reversing the link between `head` and the next node.\n", - " - `head.next` is set to `None` to avoid cycles.\n", - " - Finally, it returns the new head of the reversed list, which will be the last node of the original list.\n", - "\n", - "**In summary,** `reverseListIterative` reverses the linked list by iterating through it and changing the next pointers, while `reverseListRecursive` reverses the linked list by recursively reaching the end and then reversing the links on the way back up the recursion stack. Both functions achieve the same result: reversing the linked list." - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "id": "01849ced-1bbf-4956-8e54-451b358cb4fe", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Helper function to create a linked list from a list of values\n", - "def createLinkedList(values):\n", - " if not values:\n", - " return None\n", - " head = ListNode(values[0])\n", - " current = head\n", - " for val in values[1:]:\n", - " current.next = ListNode(val)\n", - " current = current.next\n", - " return head\n", - "\n", - "# Helper function to convert a linked list to a list for testing\n", - "def linkedListToList(head):\n", - " result = []\n", - " current = head\n", - " while current:\n", - " result.append(current.val)\n", - " current = current.next\n", - " return result\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "f7490d01-d64e-4f20-b178-e14490d6dd6f", - "metadata": {}, - "source": [ - "Let's explain the two helper functions used in the provided code:\n", - "\n", - "1. `createLinkedList(values)`:\n", - "\n", - " - Purpose: This function is used to create a linked list from a list of values. It takes a list of values as input and returns the head of the linked list.\n", - "\n", - " - How it works:\n", - " - It first checks if the input list `values` is empty. If it's empty, it returns `None` to indicate an empty linked list.\n", - " - If `values` is not empty, it initializes a `head` node with the value of the first element in `values`.\n", - " - It then iterates through the remaining values in `values`, creating new nodes for each value and linking them together to form a linked list.\n", - " - Finally, it returns the `head` node of the newly created linked list.\n", - "\n", - "2. `linkedListToList(head)`:\n", - "\n", - " - Purpose: This function is used to convert a linked list back into a Python list for testing and output purposes.\n", - "\n", - " - How it works:\n", - " - It takes the `head` of the linked list as input.\n", - " - It initializes an empty list called `result`.\n", - " - It then iterates through the linked list, starting from `head`, and appends each node's `val` (value) to the `result` list.\n", - " - This process continues until the end of the linked list is reached.\n", - " - Finally, it returns the `result` list, which contains the values from the linked list in the same order.\n", - "\n", - "These helper functions are used to simplify the process of creating linked lists from lists of values and converting linked lists back into lists, making it easier to work with linked lists in the provided examples and test cases." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "[1, 1, 2, 3, 4, 4]" - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Example 1: Iterative\n", - "head1 = [1,2,3,4,5]\n", - "head1 = createLinkedList(head1)\n", - "reversed_head1 = reverseListIterative(head1)\n", - "print(linkedListToList(reversed_head1))" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 37, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Example 2: Recursive\n", - "head2 = [1,2]\n", - "head2 = createLinkedList(head2)\n", - "reversed_head2 = reverseListRecursive(head2)\n", - "print(linkedListToList(reversed_head2))" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "id": "6c69a707-02af-4212-b2e7-1881d62a62d2", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "[0]" - ] - }, - "execution_count": 38, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Example 3: Empty list\n", - "head3 = []\n", - "head3 = createLinkedList(head3)\n", - "reversed_head3 = reverseListIterative(head3)\n", - "print(linkedListToList(reversed_head3))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the two functions:\n", - "\n", - "1. `reverseListIterative(head)`:\n", - "\n", - " - Time Complexity: $O(n)$\n", - " - The iterative function visits each node in the linked list exactly once in a single pass, where \"$n$\" is the number of nodes in the list. Therefore, the time complexity is linear in the number of nodes.\n", - "\n", - " - Space Complexity: $O(1)$\n", - " - This function uses a constant amount of extra space for the `prev`, `current`, and `next_node` pointers. Regardless of the size of the input list, the amount of additional memory used remains the same, so the space complexity is constant.\n", - "\n", - "2. `reverseListRecursive(head)`:\n", - "\n", - " - Time Complexity: $O(n)$\n", - " - The recursive function also visits each node in the linked list exactly once. It recursively traverses the list from the head to the tail, reversing the links on the way back. Therefore, like the iterative approach, the time complexity is $O(n)$, where \"$n$\" is the number of nodes.\n", - "\n", - " - Space Complexity: $O(n)$\n", - " - The recursive function uses space on the call stack for each recursive call. In the worst case, when the list has \"$n$\" nodes, it will create \"$n$\" recursive function calls on the stack, resulting in a space complexity of $O(n)$. This is because each function call stores information about its state, including the `head` pointer, until it reaches the base case and starts returning.\n", - "\n", - "**In summary:**\n", - "\n", - "- The time complexity of both functions is $O(n)$ because they both visit each node once.\n", - "- The space complexity of `reverseListIterative` is $O(1)$ because it uses a constant amount of extra space.\n", - "- The space complexity of `reverseListRecursive` is $O(n)$ due to the recursive function calls and the associated call stack space.\n", - "\n", - "Both functions are efficient in terms of time complexity, but `reverseListIterative` is more memory-efficient because it uses a constant amount of additional space, while `reverseListRecursive` uses space on the call stack proportional to the number of nodes in the list." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **K-Group Reverse:** Modify the reverseListIterative function to reverse the linked list in groups of $K$ elements. For example, if the input linked list is [1, 2, 3, 4, 5, 6], and $K$ is 3, the output should be [3, 2, 1, 6, 5, 4].\n", - "\n", - "2. **Rotate Linked List:** Write a function to rotate a linked list to the right by $K$ places. For example, if the input is [1, 2, 3, 4, 5] and $K$ is 2, the output should be [4, 5, 1, 2, 3]." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/06. Linked List/21. Merge Two Sorted Lists.ipynb b/docs/_build/html/_sources/06. Linked List/21. Merge Two Sorted Lists.ipynb deleted file mode 100644 index 876d633..0000000 --- a/docs/_build/html/_sources/06. Linked List/21. Merge Two Sorted Lists.ipynb +++ /dev/null @@ -1,249 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 21. Merge Two Sorted Lists\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Merge Two Sorted Lists problem on LeetCode, click here!](https://leetcode.com/problems/merge-two-sorted-lists/)\n", - "\n", - "---\n", - "\n", - "You are given the heads of two sorted linked lists `list1` and `list2`.\n", - "\n", - "Merge the two lists into one **sorted** list. The list should be made by splicing together the nodes of the first two lists.\n", - "\n", - "*Return the head of the merged linked list.*\n", - " \n", - "\n", - "**Constraints:**\n", - "\n", - "- The number of nodes in both lists is in the range `[0, 50]`.\n", - "- `-100 <= Node.val <= 100`\n", - "- Both `list1` and `list2` are sorted in non-decreasing order." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class ListNode:\n", - " def __init__(self, val=0, next=None):\n", - " self.val = val\n", - " self.next = next\n", - "\n", - "def mergeTwoLists(list1, list2):\n", - " # Create a dummy node to simplify the code.\n", - " dummy = ListNode()\n", - " current = dummy\n", - "\n", - " while list1 and list2:\n", - " if list1.val < list2.val:\n", - " current.next = list1\n", - " list1 = list1.next\n", - " else:\n", - " current.next = list2\n", - " list2 = list2.next\n", - " current = current.next\n", - "\n", - " # Append the remaining elements from either list.\n", - " if list1:\n", - " current.next = list1\n", - " else:\n", - " current.next = list2\n", - "\n", - " return dummy.next" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We define a class `ListNode` to represent the nodes of a singly-linked list. Each node has a `val` attribute to store the value of the node and a `next` attribute to point to the next node in the list.\n", - "\n", - "2. We define the `mergeTwoLists` function that takes two linked list heads, `list1` and `list2`, as input.\n", - "\n", - "3. We create a `dummy` node at the beginning of the merged list. The `dummy` node simplifies the code by serving as a placeholder, and its `next` attribute will point to the actual merged list.\n", - "\n", - "4. We initialize a `current` pointer to point to the `dummy` node initially. This `current` pointer helps us traverse and build the merged list.\n", - "\n", - "5. We enter a `while` loop that continues until either `list1` or `list2` becomes empty. Inside the loop, we compare the values of the nodes at the current positions of `list1` and `list2`.\n", - "\n", - "6. If the `val` of the node in `list1` is smaller than the `val` of the node in `list2`, we attach the node from `list1` to the merged list by updating the `next` attribute of the `current` node to point to the node in `list1`. We then move the `list1` pointer to the next node.\n", - "\n", - "7. If the `val` of the node in `list2` is smaller than or equal to the `val` of the node in `list1`, we attach the node from `list2` to the merged list in a similar manner. We move the `list2` pointer to the next node.\n", - "\n", - "8. After attaching a node to the merged list, we move the `current` pointer to the newly added node. This step is essential for keeping track of the end of the merged list.\n", - "\n", - "9. The loop continues until either `list1` or `list2` becomes empty.\n", - "\n", - "10. Once the loop exits, we check if there are any remaining elements in `list1` or `list2`. If `list1` is not empty, we attach the remaining elements of `list1` to the merged list. If `list2` is not empty, we attach the remaining elements of `list2`.\n", - "\n", - "11. Finally, we return the `next` attribute of the `dummy` node as the head of the merged list, which represents the sorted merged list." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "01849ced-1bbf-4956-8e54-451b358cb4fe", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Helper function to print the linked list\n", - "def printLinkedList(head):\n", - " result = []\n", - " while head:\n", - " result.append(head.val)\n", - " head = head.next\n", - " return result" - ] - }, - { - "cell_type": "markdown", - "id": "f7490d01-d64e-4f20-b178-e14490d6dd6f", - "metadata": {}, - "source": [ - "Let's explain the helper functions:\n", - "**printLinkedList Function**:\n", - " - The `printLinkedList` function takes the `head` of a linked list as input and returns a list of values representing the nodes in the linked list.\n", - " - Inside the function, a `result` list is initialized to store the values of the linked list nodes.\n", - " - The function then iterates through the linked list starting from the `head` node and appends the `val` attribute of each node to the `result` list.\n", - " - As it iterates through the list, it moves to the next node using the `next` attribute of each node.\n", - " - Finally, the function returns the `result` list containing the values of the linked list nodes in the order they appear in the linked list.\n", - "\n", - " This function is useful for debugging and displaying the contents of a linked list. It allows you to easily convert a linked list into a regular Python list for visualization and testing purposes." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Example 1:\n", - "# Input: list1 = [1,2,4], list2 = [1,3,4]\n", - "list1 = ListNode(1, ListNode(2, ListNode(4)))\n", - "list2 = ListNode(1, ListNode(3, ListNode(4)))\n", - "merged_list = mergeTwoLists(list1, list2)\n", - "printLinkedList(merged_list)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Example 2:\n", - "# Input: list1 = [], list2 = []\n", - "list1 = None\n", - "list2 = None\n", - "merged_list = mergeTwoLists(list1, list2)\n", - "printLinkedList(merged_list)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6c69a707-02af-4212-b2e7-1881d62a62d2", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Example 3:\n", - "# list1 = [], list2 = [0]\n", - "list1 = None\n", - "list2 = ListNode(0)\n", - "merged_list = mergeTwoLists(list1, list2)\n", - "printLinkedList(merged_list)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the `mergeTwoLists` function.\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The time complexity of this function is $O(N + M$), where $N$ and $M$ are the lengths of `list1` and `list2`, respectively. Here's why:\n", - "\n", - "1. In the worst case, we need to traverse both `list1` and `list2` completely. This involves iterating through all the nodes in both lists once.\n", - "\n", - "2. The while loop runs until either `list1` or `list2` becomes empty. The number of iterations depends on the total number of nodes in both lists, which is N + M in the worst case.\n", - "\n", - "3. Inside the loop, we perform constant-time operations for each iteration, such as comparisons and updating pointers.\n", - "\n", - "Therefore, the dominant factor in the time complexity is the combined length of both input lists, resulting in a linear time complexity of $O(N + M)$.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity of this function is $O(1)$, which means it uses a constant amount of extra space regardless of the input sizes. Here's why:\n", - "\n", - "1. We create a few extra pointers (`dummy`, `current`) and temporary variables (`val`) to manage the merging process. These consume a fixed amount of memory, regardless of the input sizes. The number of these extra variables is independent of the lengths of `list1` and `list2`.\n", - "\n", - "2. We do not create a new data structure or allocate memory for the merged list. Instead, we rearrange the existing nodes from `list1` and `list2` to form the merged list. This operation does not consume additional memory proportional to the input sizes.\n", - "\n", - "**In summary**, the `mergeTwoLists` function has a time complexity of $O(N + M)$ and a space complexity of $O(1)$, making it an efficient solution for merging two sorted linked lists." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Merge K Sorted Lists:** Extend the problem to merge $K$ sorted linked lists instead of just two. You need to efficiently merge $K$ lists into one sorted list.\n", - "\n", - "2. **Merge Lists in a Zigzag Pattern:** Merge two sorted lists in a zigzag pattern. For example, given [1, 2, 4] and [1, 3, 5], the merged list should be [1, 1, 2, 3, 4, 5]." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": "sql", - "file_extension": "", - "mimetype": "", - "name": "sql", - "version": "3.32.3" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/06. Linked List/23. Merge k Sorted Lists.ipynb b/docs/_build/html/_sources/06. Linked List/23. Merge k Sorted Lists.ipynb deleted file mode 100644 index a850734..0000000 --- a/docs/_build/html/_sources/06. Linked List/23. Merge k Sorted Lists.ipynb +++ /dev/null @@ -1,285 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 23. Merge k Sorted Lists\n", - "\n", - "**Difficulty:** Hard\n", - "\n", - "**Link to Problem:** [To see the Merge k Sorted Lists problem on LeetCode, click here!](https://leetcode.com/problems/merge-k-sorted-lists/)\n", - "\n", - "---\n", - "\n", - "You are given an array of $k$ linked-lists lists, each linked-list is sorted in ascending order.\n", - "\n", - "Merge all the linked-lists into one sorted linked-list and return it.\n", - "\n", - "**Constraints:**\n", - "\n", - "- `k == lists.length`\n", - "- 0 <= k <= $10^4$\n", - "- `0 <= lists[i].length <= 500`\n", - "- $-10^4$ <= lists[i][j] <= $10^4$\n", - "- `lists[i]` is sorted in ascending order.\n", - "- The sum of `lists[i].length` will not exceed $10^4$.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for singly-linked list.\n", - "class ListNode:\n", - " def __init__(self, val=0, next=None):\n", - " self.val = val\n", - " self.next = next\n", - "\n", - "class Solution:\n", - " def mergeKLists(self, lists: [[ListNode]]) -> ListNode:\n", - " # Check if the input list of linked lists is empty\n", - " if not lists or len(lists) == 0:\n", - " return None\n", - "\n", - " # Loop until there is only one merged list left\n", - " while len(lists) > 1:\n", - " mergedLists = []\n", - "\n", - " # Merge pairs of lists\n", - " for i in range(0, len(lists), 2):\n", - " l1 = lists[i]\n", - " l2 = lists[i + 1] if (i + 1) < len(lists) else None\n", - " mergedLists.append(self.mergeList(l1, l2))\n", - "\n", - " # Update the list of lists with merged results\n", - " lists = mergedLists\n", - " \n", - " # Return the final merged list\n", - " return lists[0]\n", - "\n", - " def mergeList(self, l1, l2):\n", - " # Create a dummy node to simplify merging\n", - " dummy = ListNode()\n", - " tail = dummy\n", - "\n", - " # Merge the two sorted lists\n", - " while l1 and l2:\n", - " if l1.val < l2.val:\n", - " tail.next = l1\n", - " l1 = l1.next\n", - " else:\n", - " tail.next = l2\n", - " l2 = l2.next\n", - " tail = tail.next\n", - "\n", - " # Append any remaining elements from l1 or l2 (if any)\n", - " if l1:\n", - " tail.next = l1\n", - " if l2:\n", - " tail.next = l2\n", - "\n", - " # Return the merged result starting from the next of the dummy node\n", - " return dummy.next\n" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The provided code defines a Python class `Solution` with two methods for merging k sorted linked lists:\n", - "\n", - "1. `mergeKLists(self, lists: List[ListNode]) -> ListNode`: This method takes a list of k sorted linked lists as input and returns a single merged sorted linked list. It uses a divide-and-conquer approach to repeatedly merge pairs of lists until only one merged list remains.\n", - "\n", - "2. `mergeList(self, l1, l2)`: This method takes two sorted linked lists, `l1` and `l2`, as input and merges them into a single sorted linked list. It uses a dummy node to simplify the merging process.\n", - "\n", - "Here's a high-level overview of how the code works:\n", - "\n", - "- The `mergeKLists` method checks if the input list of linked lists is empty or contains no lists. If there are no lists, it returns `None`.\n", - "\n", - "- Inside a `while` loop, the code repeatedly merges pairs of linked lists until only one merged list remains in the `lists` array. It does this by iterating through the input lists in pairs and calling the `mergeList` method to merge each pair.\n", - "\n", - "- The `mergeList` method takes two sorted linked lists, `l1` and `l2`, and merges them into a single sorted linked list. It uses a dummy node (`dummy`) and a `tail` pointer to keep track of the merged list while comparing and merging elements from `l1` and `l2`.\n", - "\n", - "- After merging all pairs of lists and updating the `lists` array with the merged results, the loop continues until only one merged list remains in the `lists` array.\n", - "\n", - "- Finally, the `mergeKLists` method returns the merged list.\n", - "\n", - "Overall, this code efficiently merges k sorted linked lists using a divide-and-conquer strategy, resulting in a single merged sorted linked list as the output." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1 -> 1 -> 2 -> 3 -> 4 -> 4 -> 5 -> 6 -> " - ] - } - ], - "source": [ - "### Example 1\n", - "# Input: lists = [[1,4,5],[1,3,4],[2,6]]\n", - "\n", - "lists1 = [\n", - " ListNode(1, ListNode(4, ListNode(5))),\n", - " ListNode(1, ListNode(3, ListNode(4))),\n", - " ListNode(2, ListNode(6))\n", - "]\n", - "solution = Solution()\n", - "result1 = solution.mergeKLists(lists1)\n", - "\n", - "# Print the result\n", - "if result1:\n", - " current = result1\n", - " while current:\n", - " print(current.val, end=\" -> \")\n", - " current = current.next\n", - "else:\n", - " print(\"None\") # Print \"None\" for input with a single None element" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "None\n" - ] - } - ], - "source": [ - "### Example 2\n", - "# Input: lists = []\n", - "\n", - "lists2 = []\n", - "solution = Solution()\n", - "result2 = solution.mergeKLists(lists2)\n", - "\n", - "# Print the result\n", - "if result2:\n", - " current = result2\n", - " while current:\n", - " print(current.val, end=\" -> \")\n", - " current = current.next\n", - "else:\n", - " print(\"None\") # Print \"None\" for input with a single None element" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "e140b956-7b3d-40d5-b6b0-9615860af67e", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "None\n" - ] - } - ], - "source": [ - "### Example 3\n", - "# Input: lists = [[]]\n", - "\n", - "lists3 = [None]\n", - "solution = Solution()\n", - "result3 = solution.mergeKLists(lists3)\n", - "\n", - "# Print the result\n", - "if result3:\n", - " current = result3\n", - " while current:\n", - " print(current.val, end=\" -> \")\n", - " current = current.next\n", - "else:\n", - " print(\"None\") # Print \"None\" for input with a single None element" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. **Heap Initialization:** The code does not use a heap. Instead, it uses a divide-and-conquer approach. The initial check for empty input lists takes $O(1)$ time.\n", - "\n", - "2. **Merging:** The merging operation is performed in a divide-and-conquer fashion. In each iteration of the `while` loop, we merge pairs of linked lists, and the number of comparisons made is proportional to the total number of nodes across all the linked lists ($n$). In each merge step, we effectively process each node once. The number of iterations required to reduce k lists to 1 is $O(log\\ k)$.\n", - "\n", - " Therefore, the overall time complexity of the code is $O(n * log\\ k)$, where n is the total number of nodes across all lists, and $k$ is the number of linked lists.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. **Heap Space:** The code doesn't use a heap data structure, so there's no additional space complexity due to a heap.\n", - "\n", - "2. **Merged Lists:** In the `mergeList` method, we create a new merged list. However, this list is not stored in memory for all lists; it's replaced with each merged pair. The space used for these merged lists is proportional to the size of the largest merged list, which is $O(n)$ in the worst case.\n", - "\n", - "3. **Additional Variables:** The code uses a few additional variables, such as `dummy` and `tail`, but these occupy a constant amount of space and don't depend on the input size.\n", - "\n", - " Therefore, the overall space complexity of the code is $O(n)$, where n is the total number of nodes across all lists.\n", - "\n", - "In summary, the code's time complexity is $O(n * log(k))$, and its space complexity is $O(n)$. This code efficiently merges $k$ sorted linked lists using a divide-and-conquer approach with a relatively low space overhead." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/06. Linked List/README.md b/docs/_build/html/_sources/06. Linked List/README.md deleted file mode 100644 index fb7b3ee..0000000 --- a/docs/_build/html/_sources/06. Linked List/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Linked List Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [206. Reverse Linked List](https://leetcode.com/problems/reverse-linked-list/) | Easy | -| [21. Merge Two Sorted Lists](https://leetcode.com/problems/merge-two-sorted-lists/) | Easy | -| [143. Reorder List](https://leetcode.com/problems/reorder-list/) | Medium | -| [19. Remove Nth Node From End of List](https://leetcode.com/problems/remove-nth-node-from-end-of-list/) | Medium | -| [141. Linked List Cycle](https://leetcode.com/problems/linked-list-cycle/) | Medium | -| [23. Merge K Sorted Lists](https://leetcode.com/problems/merge-k-sorted-lists/) | Hard | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! diff --git a/docs/_build/html/_sources/07. Trees/100. Same Tree.ipynb b/docs/_build/html/_sources/07. Trees/100. Same Tree.ipynb deleted file mode 100644 index a270fab..0000000 --- a/docs/_build/html/_sources/07. Trees/100. Same Tree.ipynb +++ /dev/null @@ -1,211 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 100: Same Tree\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Same Tree problem on LeetCode, click here!](https://leetcode.com/problems/same-tree/)\n", - "\n", - "---\n", - "\n", - "Given the roots of two binary trees `p` and `q`, write a function to check if they are the same or not.\n", - "\n", - "Two binary trees are considered the same if they are structurally identical, and the nodes have the same value.\n", - "\n", - "**Constraints**\n", - "\n", - "1. The number of nodes in both trees is in the range `[0, 100]`.\n", - "2. $-10^4$ <= Node.val <= $10^4$\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for a binary tree node.\n", - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " # Initialize a TreeNode with a value (val), left child, and right child.\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def isSameTree(p, q):\n", - " # Base case: If both p and q are None, the trees are the same.\n", - " if not p and not q:\n", - " return True\n", - " \n", - " # Base case: If either p or q is None (but not both), the trees are different.\n", - " if not p or not q:\n", - " return False\n", - " \n", - " # Check if the values of the current nodes (p.val and q.val) are equal.\n", - " if p.val != q.val:\n", - " return False\n", - " \n", - " # Recursively check the left and right subtrees of p and q.\n", - " # If both subtrees are the same, the entire trees are the same.\n", - " return isSameTree(p.left, q.left) and isSameTree(p.right, q.right)" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "In this code, we define a `TreeNode` class to represent binary tree nodes and a `isSameTree` function to check if two binary trees are the same. The function uses recursive traversal to compare the trees' structures and values.\n", - "\n", - "1. We start by defining a `TreeNode` class, which represents a node in a binary tree. Each node has a `val` (the node's value), a `left` child, and a right child. This class will help us create and work with binary trees.\n", - "2. Next, we define the `isSameTree` function, which checks if two binary trees (`p` and `q`) are the same.\n", - " + The base case for the recursion is when both `p` and `q` are `None`. In this case, they are considered the same, so we return `True`.\n", - " + If either `p` or `q` is `None` (but not both), they cannot be the same, so we return `False`.\n", - " + If the values of the current nodes `p.val` and `q.val` are not equal, we return `False` because the trees cannot be the same.\n", - " + Finally, we recursively check the left and right subtrees of `p` and `q` to see if they are the same." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "### Example 1\n", - "\n", - "#Input: `p = [1,2,3]`, `q = [1,2,3]`\n", - "\n", - "p1 = TreeNode(1, TreeNode(2), TreeNode(3))\n", - "q1 = TreeNode(1, TreeNode(2), TreeNode(3))\n", - "print(isSameTree(p1, q1)) " - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "### Example 2\n", - "\n", - "#Input: `p = [1,2]`, `q = [1,null,2]`\n", - "\n", - "p2 = TreeNode(1, TreeNode(2), None)\n", - "q2 = TreeNode(1, None, TreeNode(2))\n", - "print(isSameTree(p2, q2))" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "5897c29d-26f8-486a-878c-43c09ff25ce4", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "### Example 3\n", - "\n", - "#Input: p = [1,2,1], q = [1,1,2]\n", - "\n", - "p3 = TreeNode(1, TreeNode(2), TreeNode(1))\n", - "q3 = TreeNode(1, TreeNode(1), TreeNode(2))\n", - "print(isSameTree(p3, q3))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time Complexity\n", - "\n", - "The time complexity of the `isSameTree` function can be analyzed as follows:\n", - "\n", - "In the worst case, the function needs to visit every node in both trees once to determine if they are the same.\n", - "Since each node is visited exactly once, the time complexity is $O(n)$, where $n$ is the total number of nodes in the input trees.\n", - "\n", - "## Space Complexity\n", - "The space complexity of the `isSameTree` function can be analyzed as follows:\n", - "\n", - "The space used by the function's call stack during recursion is proportional to the maximum depth of the binary trees.\n", - "In the worst case, when the trees are completely unbalanced (all nodes form a single branch), the maximum depth will be $n$, where $n$ is the total number of nodes in the input trees.\n", - "Therefore, the space complexity is $O(n)$ due to the recursive call stack.\n", - "In addition to the call stack, there is a small constant amount of space used for variables and comparisons within each recursive call, but this space is not significant in terms of the overall space complexity.\n", - "\n", - "## In summary:\n", - "\n", - "+ **Time Complexity:** $O(n)$ where $n$ is the total number of nodes in the input trees.\n", - "+ **Space Complexity:** $O(n)$ due to the recursive call stack." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/07. Trees/102. Binary Tree Level Order Traversal.ipynb b/docs/_build/html/_sources/07. Trees/102. Binary Tree Level Order Traversal.ipynb deleted file mode 100644 index 8cb08b7..0000000 --- a/docs/_build/html/_sources/07. Trees/102. Binary Tree Level Order Traversal.ipynb +++ /dev/null @@ -1,271 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 102. Binary Tree Level Order Traversal\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Binary Tree Level Order Traversal problem on LeetCode, click here!](https://leetcode.com/problems/binary-tree-level-order-traversal/)\n", - "\n", - "---\n", - "Given the `root` of a binary tree, return *the level order traversal of its nodes' values*. (i.e., from left to right, level by level).\n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the tree is in the range `[0, 2000]`.\n", - "- `-1000 <= Node.val <= 1000`\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def levelOrder(root):\n", - " # Check if the tree is empty, if so, return an empty list.\n", - " if not root:\n", - " return []\n", - "\n", - " # Initialize an empty list to store the result.\n", - " result = []\n", - " \n", - " # Initialize a queue with the root node to perform BFS.\n", - " queue = [root]\n", - "\n", - " while queue:\n", - " # Initialize an empty list to store the values of nodes at the current level.\n", - " level_values = []\n", - " \n", - " # Get the number of nodes at the current level.\n", - " level_size = len(queue)\n", - "\n", - " # Iterate through the nodes at the current level.\n", - " for _ in range(level_size):\n", - " # Dequeue the front node from the queue.\n", - " node = queue.pop(0)\n", - " \n", - " # Append the value of the current node to the level_values list.\n", - " level_values.append(node.val)\n", - "\n", - " # Enqueue the left and right children of the current node if they exist.\n", - " if node.left:\n", - " queue.append(node.left)\n", - " if node.right:\n", - " queue.append(node.right)\n", - "\n", - " # Append the level_values list (values at the current level) to the result list.\n", - " result.append(level_values)\n", - "\n", - " # Return the final result, which is a list of lists representing level order traversal.\n", - " return result" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We define a `TreeNode` class that represents a node in the binary tree. Each `TreeNode` object has a value (`val`) and two child nodes: `left` and `right`.\n", - "\n", - "2. The `levelOrder` function takes the root of the binary tree as its input and returns the level order traversal of the tree as a list of lists.\n", - "\n", - "3. We start by checking if the input `root` is `None`, which indicates an empty tree. If the tree is empty, we return an empty list because there are no nodes to traverse.\n", - "\n", - "4. We initialize an empty list called `result` to store the final result, which will be a list of lists containing node values at each level.\n", - "\n", - "5. We initialize a queue called `queue` with the root node. This queue will be used for breadth-first traversal of the tree.\n", - "\n", - "6. We enter a while loop that continues until the `queue` is empty. Inside the loop, we perform the following steps:\n", - "\n", - " - We initialize an empty list called `level_values` to store the values of nodes at the current level.\n", - "\n", - " - We determine the number of nodes at the current level by getting the length of the `queue`. This is done to process nodes level by level.\n", - "\n", - " - We iterate through the nodes at the current level using a for loop. For each node in the current level:\n", - "\n", - " - We dequeue (remove) the front node from the `queue`.\n", - "\n", - " - We append the value of the dequeued node to the `level_values` list, effectively collecting the values of nodes at the current level.\n", - "\n", - " - If the dequeued node has a left child, we enqueue the left child to the `queue`.\n", - "\n", - " - If the dequeued node has a right child, we enqueue the right child to the `queue`.\n", - "\n", - " - After processing all nodes at the current level, we append the `level_values` list to the `result` list. This represents the values at the current level.\n", - "\n", - "7. The loop continues until all levels have been traversed, and the `queue` becomes empty.\n", - "\n", - "8. Finally, we return the `result` list, which contains lists of node values at each level, representing the level order traversal of the binary tree.\n", - "\n", - "The code effectively performs a breadth-first traversal of the binary tree, processing nodes level by level, and constructs the result list that represents the level order traversal." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[3], [9, 20], [15, 7]]\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Construct the tree\n", - "root = TreeNode(3)\n", - "root.left = TreeNode(9)\n", - "root.right = TreeNode(20)\n", - "root.right.left = TreeNode(15)\n", - "root.right.right = TreeNode(7)\n", - "\n", - "result = levelOrder(root)\n", - "print(result)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[1]]\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "# Using the same tree as before\n", - "root = TreeNode(1)\n", - "result = levelOrder(root)\n", - "print(result)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "7fc71180-e586-4c37-9fcf-2f574cb2b9d6", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[]\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "# Creating a new tree for this example\n", - "root = None\n", - "result = levelOrder(root)\n", - "print(result)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `levelOrder` function:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The time complexity of this function is O(N), where N is the number of nodes in the binary tree. This is because we visit each node exactly once during the breadth-first traversal.\n", - "\n", - "In the worst case, we have to enqueue and dequeue all nodes in the binary tree, which is proportional to the number of nodes (N). In each level, we process all nodes in that level, and since there are a total of log(N) levels in a balanced binary tree, the time complexity can also be approximated as O(N) for unbalanced trees.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity of this function is O(N), where N is the number of nodes in the binary tree. Here's how the space complexity breaks down:\n", - "\n", - "1. The `result` list stores the level order traversal, and in the worst case, it contains N/2 levels (for a completely unbalanced binary tree). So, the space used by `result` is O(N).\n", - "\n", - "2. The `queue` data structure is used for BFS traversal. In the worst case, it can store all nodes at the last level of the tree. In a balanced binary tree, the maximum number of nodes at any level is 2^(log(N)), which is still O(N). In the case of an unbalanced tree, it can be even worse. So, the space used by `queue` is O(N).\n", - "\n", - "Overall, the dominant factor in terms of space complexity is the `queue`, and the space complexity is O(N).\n", - "\n", - "In summary, the function's time complexity is O(N), and its space complexity is also O(N). It is an efficient and optimal solution for performing a level order traversal of a binary tree." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Reverse Level Order Traversal:** Modify the `levelOrder` function to return the level order traversal in reverse order (from bottom to top). For example, if the input tree is `[3, 9, 20, null, null, 15, 7]`, the output should be `[[15, 7], [9, 20], [3]]`.\n", - "\n", - "2. **Zigzag Level Order Traversal:** Write a function that performs a level order traversal of a binary tree in a zigzag pattern. In a zigzag traversal, the nodes at even levels are traversed from left to right, and nodes at odd levels are traversed from right to left. For example, if the input tree is `[3, 9, 20, null, null, 15, 7]`, the output should be `[[3], [20, 9], [15, 7]]`." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/07. Trees/104. Maximum Depth of Binary Tree.ipynb b/docs/_build/html/_sources/07. Trees/104. Maximum Depth of Binary Tree.ipynb deleted file mode 100644 index 213989d..0000000 --- a/docs/_build/html/_sources/07. Trees/104. Maximum Depth of Binary Tree.ipynb +++ /dev/null @@ -1,209 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 104. Maximum Depth of Binary Tree\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Invert Binary Tree problem on LeetCode, click here!](https://leetcode.com/problems/invert-binary-tree/)\n", - "\n", - "---\n", - "\n", - "Given the `root` of a binary tree, return its maximum depth.\n", - "\n", - "A binary tree's **maximum depth** is the number of nodes along the longest path from the root node down to the farthest leaf node.\n", - "\n", - "**Constraints:**\n", - "\n", - "- The number of nodes in the tree is in the range $[0, 10^4]$.\n", - "- `-100 <= Node.val <= 100`\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for a binary tree node.\n", - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def maxDepth(root):\n", - " # Base case: If the root is None, the depth is 0.\n", - " if root is None:\n", - " return 0\n", - " \n", - " # Recursively calculate the maximum depth of the left and right subtrees.\n", - " left_depth = maxDepth(root.left)\n", - " right_depth = maxDepth(root.right)\n", - " \n", - " # Return the maximum depth of the tree by adding 1 to the maximum depth of the subtrees.\n", - " return max(left_depth, right_depth) + 1" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "Let's go through the code step by step to understand how it works:\n", - "\n", - "1. We start by defining a `TreeNode` class to represent the nodes of the binary tree. Each node has three attributes:\n", - " - `val`: the value stored in the node.\n", - " - `left`: a reference to the left child node.\n", - " - `right`: a reference to the right child node.\n", - "\n", - "2. The `maxDepth` function is the main function that calculates the maximum depth of the binary tree. It takes a single argument, `root`, which is the root node of the binary tree.\n", - "\n", - "3. In the `maxDepth` function, we have a base case:\n", - " - If the `root` is `None`, it means we have reached the end of a branch of the tree (a leaf node or an empty subtree). In this case, the depth is 0 because there are no nodes to count.\n", - "\n", - "4. If the `root` is not `None`, we recursively calculate the maximum depth of the left and right subtrees:\n", - " - We call `maxDepth` on the `root.left` to calculate the maximum depth of the left subtree and store it in the variable `left_depth`.\n", - " - We call `maxDepth` on the `root.right` to calculate the maximum depth of the right subtree and store it in the variable `right_depth`.\n", - "\n", - "5. Finally, we return the maximum depth of the tree by taking the maximum of `left_depth` and `right_depth` and adding 1 to it. This is because we are counting the current level as well." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3\n" - ] - } - ], - "source": [ - "### Example 1\n", - "# Input: root = [3,9,20,null,null,15,7]\n", - "\n", - "root = TreeNode(3)\n", - "root.left = TreeNode(9)\n", - "root.right = TreeNode(20)\n", - "root.right.left = TreeNode(15)\n", - "root.right.right = TreeNode(7)\n", - "\n", - "print(maxDepth(root))" - ] - }, - { - "cell_type": "markdown", - "id": "a230be4f-1f47-4919-87e3-62fc3f072d97", - "metadata": {}, - "source": [ - "In this example, we create a binary tree based on the given input `[3,9,20,null,null,15,7]` and calculate its maximum depth, which is `3`. The tree structure is as follows:\n", - " ```\n", - " 3\n", - " / \\\n", - " 9 20\n", - " / \\\n", - " 15 7\n", - " ```\n", - "\n", - "So, the maximum depth is the length of the longest path from the root to a leaf node, which is 3 in this case." - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2\n" - ] - } - ], - "source": [ - "### Example 2\n", - "# Input: root = [1,null,2]\n", - "\n", - "root = TreeNode(1)\n", - "root.right = TreeNode(2)\n", - "\n", - "# Calculate the maximum depth of the tree and print the result\n", - "print(maxDepth(root))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "- The time complexity of the `maxDepth` function is $O(N)$, where $N$ is the number of nodes in the binary tree.\n", - "- This is because in the worst case, the function visits every node exactly once in a depth-first manner.\n", - "- The recursion explores all nodes of the tree, so the time complexity is linear with respect to the number of nodes.\n", - "\n", - "**Space Complexity:**\n", - "- The space complexity of the `maxDepth` function is $O(H)$, where H is the height of the binary tree.\n", - "- In the worst case, if the binary tree is completely unbalanced (skewed), the recursion stack can go as deep as the height of the tree.\n", - "- In the best case, if the binary tree is perfectly balanced, the height is $O(log\\ N)$, where $N$ is the number of nodes.\n", - "- Therefore, the space complexity can vary from $O(log\\ N)$ to $O(N)$ depending on the shape of the tree.\n", - "- In addition to the recursion stack, there is a small constant amount of space used for variables and function call overhead.\n", - "\n", - "**In summary:**\n", - "- The time complexity of the code is $O(N)$ as it visits each node once.\n", - "- The space complexity is $O(H)$, where H is the height of the tree, which can vary from $O(log\\ N)$ to $O(N)$ depending on the tree's shape." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.ipynb b/docs/_build/html/_sources/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.ipynb deleted file mode 100644 index 31c9e69..0000000 --- a/docs/_build/html/_sources/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.ipynb +++ /dev/null @@ -1,313 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 105. Construct Binary Tree from Preorder and Inorder Traversal\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Construct Binary Tree from Preorder and Inorder Traversal problem on LeetCode, click here!](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/)\n", - "\n", - "---\n", - "Given two integer arrays `preorder` and `inorder` where `preorder` is the preorder traversal of a binary tree and `inorder` is the inorder traversal of the same tree, construct and return *the binary tree.*\n", - "\n", - "**Constraints:**\n", - "- `1 <= preorder.length <= 3000`\n", - "- `inorder.length == preorder.length`\n", - "- `-3000 <= preorder[i], inorder[i] <= 3000`\n", - "- `preorder` and `inorder` consist of **unique** values.\n", - "- Each value of `inorder` also appears in `preorder`.\n", - "- `preorder` is **guaranteed** to be the preorder traversal of the tree.\n", - "- `inorder` is **guaranteed** to be the inorder traversal of the tree.\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def buildTree(preorder, inorder):\n", - " if not preorder:\n", - " return None\n", - "\n", - " # The first element in the preorder traversal is the root of the current subtree\n", - " root_val = preorder[0]\n", - " root = TreeNode(root_val)\n", - "\n", - " # Find the index of the root value in the inorder traversal\n", - " root_idx_inorder = inorder.index(root_val)\n", - "\n", - " # Recursively build left and right subtrees\n", - " root.left = buildTree(preorder[1:1 + root_idx_inorder], inorder[:root_idx_inorder])\n", - " root.right = buildTree(preorder[1 + root_idx_inorder:], inorder[root_idx_inorder + 1:])\n", - "\n", - " return root" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. `class TreeNode:`: This is a class definition for a binary tree node. It has three attributes:\n", - " - `val`: The value of the node.\n", - " - `left`: A reference to the left child node.\n", - " - `right`: A reference to the right child node.\n", - "\n", - " This class is used to create instances of binary tree nodes, which will be used to build the binary tree.\n", - "\n", - "2. `def buildTree(preorder, inorder):`: This is the main function that constructs a binary tree from its preorder and inorder traversals.\n", - "\n", - " - `preorder`: A list representing the preorder traversal of the binary tree.\n", - " - `inorder`: A list representing the inorder traversal of the binary tree.\n", - "\n", - "3. `if not preorder: return None`: This line checks if the `preorder` list is empty. If it is, it means there are no nodes to construct, so the function returns `None`.\n", - "\n", - "4. `root_val = preorder[0]`: The value of the root node is extracted from the first element of the `preorder` list.\n", - "\n", - "5. `root = TreeNode(root_val)`: A new `TreeNode` object is created with the `root_val` as its value. This represents the root of the current subtree.\n", - "\n", - "6. `root_idx_inorder = inorder.index(root_val)`: The index of the `root_val` in the `inorder` list is found. This index indicates the position of the root node in the inorder traversal.\n", - "\n", - "7. `root.left`: The left subtree is constructed recursively by calling the `buildTree` function with the appropriate sublists of `preorder` and `inorder`. The left subtree's preorder and inorder traversals are the slices of `preorder` and `inorder` lists up to the `root_idx_inorder`.\n", - "\n", - "8. `root.right`: The right subtree is constructed recursively by calling the `buildTree` function with the appropriate sublists of `preorder` and `inorder`. The right subtree's preorder and inorder traversals are the slices of `preorder` and `inorder` lists starting from `root_idx_inorder + 1`.\n", - "\n", - "9. Finally, the function returns the `root` of the subtree it just constructed.\n", - "\n", - "The recursive approach used here divides the problem of constructing the entire binary tree into smaller subproblems, starting with the root node and then recursively building the left and right subtrees until the entire tree is constructed." - ] - }, - { - "cell_type": "markdown", - "id": "2d82857b-4fbe-474f-bf33-17b55c20147b", - "metadata": {}, - "source": [ - "## Helper Function \n", - "\n", - "Here is a helper function to represent the binary tree elements." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "13e6f3e1-659d-479d-9521-75629b8c782f", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def treeToList(root):\n", - " # Initialize an empty list to store the elements of the binary tree\n", - " result = []\n", - " \n", - " # Initialize a queue for level-order traversal starting with the root\n", - " queue = [root]\n", - "\n", - " while queue:\n", - " # Pop the front node from the queue\n", - " node = queue.pop(0)\n", - " \n", - " # If the node is not None (i.e., a valid node), add its value to the result list\n", - " if node:\n", - " result.append(node.val)\n", - " \n", - " # Add the left and right children of the node to the queue\n", - " queue.append(node.left)\n", - " queue.append(node.right)\n", - " else:\n", - " # If the node is None, add None to the result to represent an empty node\n", - " result.append(None)\n", - "\n", - " # Remove any trailing None values from the result list\n", - " while result and result[-1] is None:\n", - " result.pop()\n", - "\n", - " # Return the resulting list representing the binary tree elements\n", - " return result" - ] - }, - { - "cell_type": "markdown", - "id": "86cd4c9d-a120-4dd1-a1bd-530436012574", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "Let's break down the `treeToList` helper function step by step:\n", - "\n", - "1. `def treeToList(root):`: This function takes the root of a binary tree as input and converts it into a list.\n", - "\n", - "2. `result = []`: Initialize an empty list called `result` to store the elements of the binary tree in list format.\n", - "\n", - "3. `queue = [root]`: Initialize a queue data structure for a level-order traversal, starting with the root node.\n", - "\n", - "4. `while queue:`: This starts a loop that continues until the queue is empty, indicating that all nodes have been processed.\n", - "\n", - "5. `node = queue.pop(0)`: Dequeue the first node from the queue, effectively processing it.\n", - "\n", - "6. `if node:`: Check if the `node` is not None, which means it's a valid node in the binary tree.\n", - "\n", - " a. `result.append(node.val)`: If the node is valid, append its value (`node.val`) to the `result` list. This represents the value of the current node in the binary tree.\n", - "\n", - " b. `queue.append(node.left)`: Enqueue the left child of the current node if it exists. This adds the left child to the queue for processing in the next iteration.\n", - "\n", - " c. `queue.append(node.right)`: Enqueue the right child of the current node if it exists. This adds the right child to the queue for processing in the next iteration.\n", - "\n", - "7. `else:`: If the `node` is None, it represents an empty node in the binary tree.\n", - "\n", - " a. `result.append(None)`: Append `None` to the `result` list to indicate an empty node.\n", - "\n", - "8. `while result and result[-1] is None:`: After the traversal is complete, there might be trailing `None` values in the `result` list. This loop removes any such trailing `None` values to ensure a clean representation of the tree's elements.\n", - "\n", - "9. `return result`: Return the `result` list, which now contains the elements of the binary tree in a format where `None` represents empty nodes and the order of elements reflects a level-order traversal of the tree.\n", - "\n", - "In summary, the `treeToList` function performs a level-order traversal of the binary tree using a queue, constructing a list where each element corresponds to a node's value or represents an empty node with `None`. This list represents the binary tree's elements in a structured format." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[3, 9, 20, None, None, 15, 7]\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "preorder = [3, 9, 20, 15, 7]\n", - "inorder = [9, 3, 15, 20, 7]\n", - "result = buildTree(preorder, inorder)\n", - "\n", - "print(treeToList(result))" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[-1]\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "preorder = [-1]\n", - "inorder = [-1]\n", - "result = buildTree(preorder, inorder)\n", - "\n", - "print(treeToList(result))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `buildTree` function:\n", - "\n", - "**Time Complexity:**\n", - "The time complexity of the `buildTree` function can be analyzed in terms of the number of nodes in the binary tree. Let's assume there are `n` nodes in the binary tree.\n", - "\n", - "1. Finding the root value in the `preorder` traversal takes O(1) time as it's just extracting the first element from the list.\n", - "2. Finding the index of the root value in the `inorder` traversal using `inorder.index(root_val)` takes O(n) time in the worst case because in the worst case, it might have to search through all `n` elements in the `inorder` list to find the index.\n", - "3. The recursive calls to `buildTree` for the left and right subtrees are made once for each node in the tree. Therefore, the recursive calls have a combined time complexity of O(n) as they process each node once.\n", - "\n", - "The total time complexity of the `buildTree` function is O(n) due to the recursive calls and finding the root's index in the `inorder` list.\n", - "\n", - "**Space Complexity:**\n", - "The space complexity is determined by the space used by the function's call stack during recursion and any additional data structures used. \n", - "\n", - "1. The space used by the function call stack during recursion depends on the height of the binary tree. In the worst case, where the tree is highly unbalanced (e.g., a skewed tree), the space complexity for the call stack is O(n) as it can go as deep as the number of nodes in the tree.\n", - "\n", - "2. Additionally, the function creates TreeNode objects for each node in the binary tree. Therefore, the space complexity for these objects is also O(n).\n", - "\n", - "Overall, the space complexity of the `buildTree` function is O(n) due to the space used by the call stack and the TreeNode objects.\n", - "\n", - "In summary, the time complexity of `buildTree` is O(n), and the space complexity is O(n), where 'n' is the number of nodes in the binary tree." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Construct Binary Tree from Postorder and Inorder Traversal:**\n", - " Modify the problem to construct a binary tree from its postorder and inorder traversals. Implement a function similar to `buildTree` but for postorder and inorder traversals.\n", - "\n", - "2. **Reconstruct Binary Tree with Duplicate Values:**\n", - " Extend the problem to handle binary trees with duplicate values. Ensure that your solution correctly handles scenarios where there are duplicate values in the preorder and inorder traversals." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/07. Trees/124. Binary Tree Maximum Path Sum.ipynb b/docs/_build/html/_sources/07. Trees/124. Binary Tree Maximum Path Sum.ipynb deleted file mode 100644 index 59d8e7d..0000000 --- a/docs/_build/html/_sources/07. Trees/124. Binary Tree Maximum Path Sum.ipynb +++ /dev/null @@ -1,249 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 124. Binary Tree Maximum Path Sum\n", - "\n", - "**Difficulty:** Hard\n", - "\n", - "**Link to Problem:** [To see the Binary Tree Maximum Path Sum problem on LeetCode, click here!](https://leetcode.com/problems/binary-tree-maximum-path-sum/)\n", - "\n", - "---\n", - "A **path** in a binary tree is a sequence of nodes where each pair of adjacent nodes in the sequence has an edge connecting them. A node can only appear in the sequence **at most once**. Note that the path does not need to pass through the root.\n", - "\n", - "The **path sum** of a path is the sum of the node's values in the path.\n", - "\n", - "Given the `root` of a binary tree, return *the maximum **path sum** of any **non-empty** path*.\n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the tree is in the range $[1, 3*10^4]$.\n", - "- `-1000 <= Node.val <= 1000`" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is to find the maximum path sum in a binary tree. A path in a binary tree is a sequence of nodes where each pair of adjacent nodes in the sequence has an edge connecting them. The path sum of a path is the sum of the node values in that path.\n", - "\n", - "In this problem, you are given the root of a binary tree, and you need to find the maximum path sum among all possible paths in the tree. Note that the path does not need to start at the root node or end at a leaf node; it can start and end at any nodes in the tree.\n", - "\n", - "To find the maximum path sum, you need to consider both left and right subtrees of each node while traversing the tree. At each node, you have two choices:\n", - "\n", - "1. Include the current node in the path: In this case, you add the value of the current node to the sum and continue exploring both the left and right subtrees for possible extensions of the path.\n", - "\n", - "2. Start a new path from the current node: In this case, you do not include the current node in the path sum, and you choose either the left subtree or the right subtree to start a new path.\n", - "\n", - "To solve this problem, you can use a recursive approach to traverse the binary tree. For each node, you calculate the maximum path sum that can pass through that node (option 1) and also return the maximum path sum that can be extended from that node (option 2). You keep track of the global maximum path sum encountered during the traversal.\n", - "\n", - "Ultimately, the maximum path sum among all paths in the tree will be the maximum of the global maximum path sum and the maximum path sum calculated for each node.\n", - "\n", - "The constraints for this problem include:\n", - "\n", - "- The number of nodes in the tree is in the range $[1, 3 * 10^4]$.\n", - "- Node values are in the range [-1000, 1000].\n", - "\n", - "By considering all possible paths through the tree, the algorithm aims to find the most significant sum of node values in any path in the binary tree.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "class Solution:\n", - " def maxPathSum(self, root):\n", - " def max_path_sum_helper(node):\n", - " if not node:\n", - " return 0\n", - " \n", - " # Recursively calculate the maximum path sum for left and right subtrees\n", - " left_max = max(0, max_path_sum_helper(node.left))\n", - " right_max = max(0, max_path_sum_helper(node.right))\n", - " \n", - " # Update the global maximum path sum\n", - " self.max_sum = max(self.max_sum, left_max + right_max + node.val)\n", - " \n", - " # Return the maximum path sum starting from the current node\n", - " return max(left_max, right_max) + node.val\n", - " \n", - " self.max_sum = float('-inf') # Initialize the global maximum to negative infinity\n", - " max_path_sum_helper(root) # Start the recursive traversal from the root\n", - " return self.max_sum" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. The code starts by defining a `TreeNode` class to represent nodes in the binary tree. Each `TreeNode` has a `val` attribute representing its value, a `left` attribute pointing to the left child, and a `right` attribute pointing to the right child.\n", - "\n", - "2. Next, a `Solution` class is defined to contain the `maxPathSum` method, which will be used to find the maximum path sum in the binary tree.\n", - "\n", - "3. Within the `maxPathSum` method, a helper function called `max_path_sum_helper` is defined. This recursive function takes a single argument, `node`, which is the current node being considered during traversal.\n", - "\n", - "4. Inside the `max_path_sum_helper` function:\n", - " - If `node` is `None` (i.e., the current node is a null node), it returns 0. This is the base case of the recursion.\n", - " - It calculates the maximum path sum starting from the left subtree (`left_max`) and the right subtree (`right_max`). Importantly, it uses `max(0, ...)` to ensure that negative values (which would make the path sum smaller) are not considered. If a subtree's path sum is negative, it's better to not include it in the path.\n", - " - The code then updates the global maximum path sum (`self.max_sum`) by checking if the sum of `left_max`, `right_max`, and the current node's value is greater than the current maximum.\n", - " - Finally, it returns the maximum path sum starting from the current node, which is the maximum of `left_max` and `right_max` plus the current node's value.\n", - "\n", - "5. Before calling the `max_path_sum_helper` function, the `max_sum` attribute of the `Solution` class is initialized to negative infinity (`float('-inf')`). This is done to ensure that any valid path sum encountered during traversal will be greater than the initial value of `max_sum`.\n", - "\n", - "6. The `max_path_sum_helper` function is called with the root of the binary tree, effectively starting the traversal from the root node.\n", - "\n", - "7. Once the traversal is complete, the method returns the value of `self.max_sum`, which contains the maximum path sum found in the binary tree.\n", - "\n", - "8. Example usage at the bottom of the code demonstrates how to create binary trees and use the `maxPathSum` method to find the maximum path sum for two different tree structures.\n", - "\n", - "In summary, the code uses a recursive approach to explore all possible paths in the binary tree, ensuring that negative path sums are not considered. It keeps track of the maximum path sum encountered and returns that maximum value as the result." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "6\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "root1 = TreeNode(1)\n", - "root1.left = TreeNode(2)\n", - "root1.right = TreeNode(3)\n", - "solution = Solution()\n", - "print(solution.maxPathSum(root1))" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "42\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "root2 = TreeNode(-10)\n", - "root2.left = TreeNode(9)\n", - "root2.right = TreeNode(20)\n", - "root2.right.left = TreeNode(15)\n", - "root2.right.right = TreeNode(7)\n", - "print(solution.maxPathSum(root2))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the given code:\n", - "\n", - "Time Complexity:\n", - "- The code uses a recursive depth-first traversal to explore each node in the binary tree exactly once.\n", - "- During the traversal, for each node, we perform constant time operations, such as updating the `max_sum` variable and calculating the maximum path sum starting from that node.\n", - "- Therefore, the time complexity of the code is O(N), where N is the number of nodes in the binary tree.\n", - "\n", - "Space Complexity:\n", - "- The space complexity of the code is determined by the space used in the call stack during the recursive traversal.\n", - "- In the worst case, the depth of the call stack can be equal to the height of the binary tree. In an unbalanced tree, this could be O(N), but in a balanced binary tree, the height is O(log N).\n", - "- Additionally, the code uses a constant amount of space for variables like `left_max`, `right_max`, and `max_sum`.\n", - "- Therefore, the overall space complexity is O(H), where H is the height of the binary tree. In the worst case, it's O(N), and in the best case (a balanced binary tree), it's O(log N).\n", - "\n", - "In summary:\n", - "- Time Complexity: O(N)\n", - "- Space Complexity: O(H), where H is the height of the binary tree, ranging from O(log N) to O(N) depending on the tree's balance." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Print the Maximum Path:**\n", - " Modify the code to not only find the maximum path sum but also print the nodes involved in the maximum path. You can print the nodes in the correct order from the root to the leaf.\n", - "\n", - "2. **Path Sum Count:**\n", - " Instead of finding the maximum path sum, find the count of unique paths that sum to a given target value. Each path can start and end anywhere in the tree." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/07. Trees/199. Binary Tree Right Side View.ipynb b/docs/_build/html/_sources/07. Trees/199. Binary Tree Right Side View.ipynb deleted file mode 100644 index 55dc944..0000000 --- a/docs/_build/html/_sources/07. Trees/199. Binary Tree Right Side View.ipynb +++ /dev/null @@ -1,257 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 199. Binary Tree Right Side View\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Binary Tree Right Side View problem on LeetCode, click here!](https://leetcode.com/problems/binary-tree-right-side-view/)\n", - "\n", - "---\n", - "Given the `root` of a binary tree, imagine yourself standing on the **right side** of it, return *the values of the nodes you can see ordered from top to bottom*.\n", - "\n", - " \n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the tree is in the range `[0, 2000]`.\n", - "- `-100 <= Node.val <= 100`\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def rightSideView(root):\n", - " if not root:\n", - " return [] # If the tree is empty, return an empty list.\n", - "\n", - " result = [] # Initialize a list to store the right side view values.\n", - " queue = [root] # Initialize a queue for level-order traversal with the root node.\n", - "\n", - " while queue:\n", - " # Get the number of nodes at the current level.\n", - " level_size = len(queue)\n", - "\n", - " # Traverse all nodes at the current level and add the rightmost node to the result.\n", - " for i in range(level_size):\n", - " node = queue.pop(0) # Dequeue the first node from the queue.\n", - "\n", - " # If it's the rightmost node at this level, add its value to the result.\n", - " if i == level_size - 1:\n", - " result.append(node.val)\n", - "\n", - " # Add the children of the current node to the queue.\n", - " if node.left:\n", - " queue.append(node.left)\n", - " if node.right:\n", - " queue.append(node.right)\n", - "\n", - " return result # Return the list of right side view values.\n" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start with a binary tree represented using a TreeNode class. Each node has a value (`val`) and can have a left child (`left`) and a right child (`right`).\n", - "\n", - "2. The `rightSideView` function takes the root node of the binary tree as input and returns a list of values representing the nodes you can see when standing on the right side of the tree.\n", - "\n", - "3. We check if the `root` is `None`, which means the tree is empty. If it's empty, we return an empty list because there are no nodes to see.\n", - "\n", - "4. We initialize an empty list called `result` to store the right side view values.\n", - "\n", - "5. We initialize a queue called `queue` with the root node. This queue is used for a level-order traversal of the tree.\n", - "\n", - "6. We enter a while loop that continues until the `queue` is empty. Inside this loop, we perform the following steps for each level of the tree:\n", - "\n", - " a. We determine the number of nodes at the current level by getting the length of the `queue`. This is important for processing nodes at the same level together.\n", - "\n", - " b. We then iterate through the nodes at the current level using a for loop. For each node in the level, we dequeue it from the `queue` using `queue.pop(0)`.\n", - "\n", - " c. If the node we dequeue is the rightmost node at the current level (determined by `i == level_size - 1`), we add its `val` to the `result` list. This is because, when standing on the right side of the tree, you can see the rightmost node at each level.\n", - "\n", - " d. We enqueue the left and right children of the current node (if they exist) to the `queue`. This ensures that we process the next level in the subsequent iterations of the while loop.\n", - "\n", - "7. After processing all levels of the tree, the `result` list contains the values of the rightmost nodes in each level, ordered from top to bottom.\n", - "\n", - "8. Finally, we return the `result` list as the output of the function, which represents the right side view of the binary tree.\n", - "\n", - "The code effectively performs a level-order traversal of the binary tree while keeping track of the rightmost nodes at each level and adding them to the result list. This ensures that we obtain the correct order of nodes visible from the right side of the tree." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 3, 4]\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Construct the tree\n", - "root1 = TreeNode(1)\n", - "root1.left = TreeNode(2)\n", - "root1.right = TreeNode(3)\n", - "root1.left.right = TreeNode(5)\n", - "root1.right.right = TreeNode(4)\n", - "print(rightSideView(root1))" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 3]\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "root2 = TreeNode(1)\n", - "root2.right = TreeNode(3)\n", - "print(rightSideView(root2))" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "7fc71180-e586-4c37-9fcf-2f574cb2b9d6", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[]\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "# Creating a new tree for this example\n", - "root = None\n", - "result = rightSideView(root)\n", - "print(result)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the given code:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The time complexity of the code is O(N), where N is the number of nodes in the binary tree. Here's why:\n", - "\n", - "1. We perform a level-order traversal of the tree using a queue. In the worst case, we visit all nodes once, which takes O(N) time since we visit each node exactly once.\n", - "\n", - "2. For each node, we perform constant-time operations like dequeuing it from the queue, checking if it's the rightmost node at the current level, and enqueuing its children (if they exist). These operations do not depend on the size of the tree, so they do not contribute to the overall time complexity.\n", - "\n", - "Therefore, the dominant factor in the time complexity is the level-order traversal, making it O(N).\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity of the code is also O(N). Here's why:\n", - "\n", - "1. We use a queue to perform level-order traversal. In the worst case, the queue can contain all nodes at the maximum width of the tree, which can be up to N/2 nodes for a completely unbalanced tree. Therefore, the space required for the queue is O(N).\n", - "\n", - "2. The `result` list stores the values of the rightmost nodes. In the worst case, when the binary tree is a complete binary tree, it can have roughly N/2 rightmost nodes. Therefore, the space required for the `result` list is also O(N).\n", - "\n", - "3. Other auxiliary variables like `level_size`, `i`, and `node` require only constant space and do not depend on the size of the tree.\n", - "\n", - "Combining the space used by the queue and the `result` list, we get a space complexity of O(N).\n", - "\n", - "In summary, the code has a time complexity of O(N) and a space complexity of O(N), where N is the number of nodes in the binary tree. These complexities are efficient and scale linearly with the size of the input tree." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Variant with Left Side View**: Modify the code to find and return the values of nodes visible from the left side of the binary tree instead of the right side.\n", - "\n", - "2. **Zigzag Right Side View**: Extend the code to return the right side view values in a zigzag order. In a zigzag order, you alternate between starting from the rightmost node at level 0, then the leftmost at level 1, rightmost at level 2, and so on." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/07. Trees/226. Invert Binary Tree.ipynb b/docs/_build/html/_sources/07. Trees/226. Invert Binary Tree.ipynb deleted file mode 100644 index 8ea4609..0000000 --- a/docs/_build/html/_sources/07. Trees/226. Invert Binary Tree.ipynb +++ /dev/null @@ -1,223 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 226: Invert Binary Tree\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Invert Binary Tree problem on LeetCode, click here!](https://leetcode.com/problems/invert-binary-tree/)\n", - "\n", - "---\n", - "\n", - "Given the root of a binary tree, invert the tree, and return its root.\n", - "\n", - "**Constraints:**\n", - "\n", - "- The number of nodes in the tree is in the range `[0, 100]`.\n", - "- `-100 <= Node.val <= 100`\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for a binary tree node.\n", - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def invertTree(root):\n", - " # Base case: If the root is None or the tree is empty, return None.\n", - " if not root:\n", - " return None\n", - "\n", - " # Swap the left and right subtrees of the current node.\n", - " root.left, root.right = root.right, root.left\n", - "\n", - " # Recursively invert the left and right subtrees.\n", - " invertTree(root.left)\n", - " invertTree(root.right)\n", - "\n", - " return root" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start by defining a TreeNode class, which represents a node in a binary tree. Each node has a value (`val`), a left child (`left`), and a right child (`right`).\n", - "\n", - "2. The `invertTree` function is defined to invert the binary tree. It takes the root node of the tree as an argument.\n", - "\n", - "3. In the `invertTree` function, we have a base case to handle the scenario when the root is `None` (empty tree). In such cases, we return `None` because there's nothing to invert.\n", - "\n", - "4. For non-empty trees, we swap the left and right subtrees of the current node. This effectively inverts the tree at the current node.\n", - "\n", - "5. We then recursively call `invertTree` on the left and right subtrees to invert them.\n", - "\n", - "6. Finally, we return the root of the inverted tree." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Inverted Tree (Example 1): <__main__.TreeNode object at 0x270c9c0>\n" - ] - } - ], - "source": [ - "### Example 1\n", - "# Input: root = [4,2,7,1,3,6,9]\n", - "\n", - "root1 = TreeNode(4)\n", - "root1.left = TreeNode(2)\n", - "root1.right = TreeNode(7)\n", - "root1.left.left = TreeNode(1)\n", - "root1.left.right = TreeNode(3)\n", - "root1.right.left = TreeNode(6)\n", - "root1.right.right = TreeNode(9)\n", - "\n", - "inverted_root1 = invertTree(root1)\n", - "print(\"Inverted Tree (Example 1):\", inverted_root1)" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Inorder Traversal of Inverted Tree (Example 2): <__main__.TreeNode object at 0x2255fc0>\n" - ] - } - ], - "source": [ - "### Example 2\n", - "# Input: root = [2,1,3]\n", - "\n", - "root2 = TreeNode(2)\n", - "root2.left = TreeNode(1)\n", - "root2.right = TreeNode(3)\n", - "\n", - "inverted_root2 = invertTree(root2)\n", - "print(\"Inverted Tree (Example 2):\", inverted_root2)" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "5897c29d-26f8-486a-878c-43c09ff25ce4", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Inverted Tree (Example 3): None\n" - ] - } - ], - "source": [ - "### Example 3\n", - "# Input: root = []\n", - "\n", - "root3 = None # Empty tree\n", - "\n", - "inverted_root3 = invertTree(root3)\n", - "print(\"Inverted Tree (Example 3):\", inverted_root3)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "Let's discuss the time and space complexity of the provided Python code to invert a binary tree.\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The time complexity of the `invertTree` function is $O(n)$, where $n$ is the number of nodes in the binary tree. This is because we visit each node exactly once during the traversal of the tree. In the worst case, we have to visit all nodes in the tree.\n", - "\n", - "The reason for this time complexity is the depth-first traversal of the tree, where we recursively process the left and right subtrees of each node.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity of the code is determined by the function call stack during the recursion. In the worst case, the space complexity is $O(h)$, where $h$ is the height of the binary tree. \n", - "\n", - "In a completely unbalanced binary tree (essentially a linked list), the height $h$ is equal to the number of nodes $n$, resulting in a space complexity of $O(n)$. This occurs when the tree is skewed to one side.\n", - "\n", - "In a balanced binary tree, such as a full binary tree, the height $h$ is $O(log\\ n)$, and the space complexity is $O(log\\ n)$.\n", - "\n", - "The space complexity depends on how balanced the tree is. In practical scenarios, binary trees are often approximately balanced, so the space complexity is typically closer to $O(log\\ n)$.\n", - "\n", - "**In summary:**\n", - "\n", - "- Time Complexity: $O(n)$ where $n$ is the number of nodes.\n", - "- Space Complexity: $O(h)$, where $h$ is the height of the binary tree. In the worst case, it can be $O(n)$, and in a balanced tree, it is $O(log\\ n)$.\n", - "\n", - "Keep in mind that these complexities are based on the recursive implementation provided. Iterative solutions can achieve the same task with $O(1)$ space complexity, using auxiliary data structures like stacks or queues to mimic the recursion stack." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/07. Trees/230. Kth Smallest Element in a BST.ipynb b/docs/_build/html/_sources/07. Trees/230. Kth Smallest Element in a BST.ipynb deleted file mode 100644 index 673ced2..0000000 --- a/docs/_build/html/_sources/07. Trees/230. Kth Smallest Element in a BST.ipynb +++ /dev/null @@ -1,221 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 230. Kth Smallest Element in a BST\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Kth Smallest Element in a BST problem on LeetCode, click here!](https://leetcode.com/problems/kth-smallest-element-in-a-bst/)\n", - "\n", - "---\n", - "Given the `root` of a binary search tree, and an integer `k`, return *the $k^{th}$ smallest value (**1-indexed**) of all the values of the nodes in the tree.*\n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the tree is `n`.\n", - "- 1 <= `k <= n` <= $10^4$\n", - "- 0 <= `Node.val` <= $10^4$\n", - "\n", - "**Follow up**: If the BST is modified often (i.e., we can do insert and delete operations) and you need to find the kth smallest frequently, how would you optimize?\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def kthSmallest(root, k):\n", - " stack = [] # Initialize an empty stack to simulate the traversal\n", - " while root or stack:\n", - " while root:\n", - " stack.append(root) # Push the current node onto the stack\n", - " root = root.left # Move to the left child\n", - " root = stack.pop() # Pop a node from the stack\n", - " k -= 1 # Decrement k since we've visited a node\n", - " if k == 0:\n", - " return root.val # If k becomes 0, return the current node's value as the kth smallest\n", - " root = root.right # Move to the right child to continue the traversal" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. We start by defining a `TreeNode` class, which represents a node in the binary search tree (BST). Each node has a value (`val`), a left child (`left`), and a right child (`right`).\n", - "\n", - "2. The `kthSmallest` function takes two parameters: `root`, which is the root of the BST, and `k`, which represents the kth smallest element we want to find.\n", - "\n", - "3. We initialize an empty stack (`stack`) to simulate the traversal of the BST. The stack will be used to keep track of nodes as we traverse the tree in an iterative manner.\n", - "\n", - "4. We enter a while loop that continues until either `root` becomes `None` (indicating we have traversed the entire tree) or the `stack` is empty.\n", - "\n", - "5. Within the loop, we start another while loop to traverse as far left as possible in the BST. We repeatedly push nodes onto the `stack` and move to their left children until we reach the leftmost leaf node. This is the smallest node in the BST.\n", - "\n", - "6. Once we have reached the leftmost leaf node (the smallest node), we pop nodes from the `stack` one by one. As we pop each node, we decrement `k` by 1 to keep track of the number of nodes we have visited.\n", - "\n", - "7. If `k` becomes 0 after decrementing, it means we have found the kth smallest element. In this case, we return the `val` of the current node as the result.\n", - "\n", - "8. If `k` is still greater than 0, it means we haven't found the kth smallest element yet. In this case, we move to the right child of the current node to continue the traversal, as the kth smallest element, if it exists, will be in the right subtree of the current node.\n", - "\n", - "9. The process continues until we find the kth smallest element or traverse the entire tree.\n", - "\n", - "10. Finally, we return the kth smallest element found.\n", - "\n", - "The key idea in this code is to perform an in-order traversal of the BST while keeping track of the kth smallest element. By visiting nodes in ascending order, we can efficiently find the kth smallest element in O(h + k) time, where h is the height of the BST and k is the desired kth element. This approach is both concise and efficient for this problem." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "# Create the tree for the first example: root = [3,1,4,null,2], k = 1\n", - "root1 = TreeNode(3)\n", - "root1.left = TreeNode(1)\n", - "root1.right = TreeNode(4)\n", - "root1.left.right = TreeNode(2)\n", - "k1 = 1\n", - "print(kthSmallest(root1, k1)) " - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "# Create the tree for the second example: root = [5,3,6,2,4,null,null,1], k = 3\n", - "root2 = TreeNode(5)\n", - "root2.left = TreeNode(3)\n", - "root2.right = TreeNode(6)\n", - "root2.left.left = TreeNode(2)\n", - "root2.left.right = TreeNode(4)\n", - "root2.left.left.left = TreeNode(1)\n", - "k2 = 3\n", - "print(kthSmallest(root2, k2))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the given code:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The time complexity of this code is O(h + k), where:\n", - "- h is the height of the binary search tree (BST).\n", - "- k is the desired kth smallest element we want to find.\n", - "\n", - "1. In the worst case, where the BST is highly unbalanced and resembles a linked list, the height (h) of the tree can be equal to the number of nodes (n) in the tree. In this case, the time complexity is O(n + k).\n", - "\n", - "2. In the best case, where the BST is perfectly balanced, the height (h) is log(n), where n is the number of nodes in the tree. In this case, the time complexity is O(log(n) + k).\n", - "\n", - "So, the time complexity can vary from O(log(n) + k) in the best-case scenario to O(n + k) in the worst-case scenario. Typically, for balanced BSTs, the time complexity is closer to O(log(n) + k).\n", - "\n", - "**Space Complexity:**\n", - "\n", - "The space complexity of this code is O(h) due to the stack used for the iterative in-order traversal, where h is the height of the BST.\n", - "\n", - "1. In the worst case, when the BST is highly unbalanced and resembles a linked list, the height (h) of the tree can be equal to the number of nodes (n) in the tree. In this case, the space complexity is O(n) because the stack can potentially store all n nodes.\n", - "\n", - "2. In the best case, when the BST is perfectly balanced, the height (h) is log(n), where n is the number of nodes in the tree. In this case, the space complexity is O(log(n)) because the stack will have at most log(n) nodes.\n", - "\n", - "So, the space complexity depends on the height of the BST and can vary from O(log(n)) in the best-case scenario to O(n) in the worst-case scenario.\n", - "\n", - "In practical terms, for balanced BSTs or moderately unbalanced BSTs, the space complexity is usually close to O(log(n)), and the code is efficient in terms of space usage." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Kth Largest Element**: Modify the code to find the kth largest element in the BST instead of the kth smallest element.\n", - "\n", - "2. **Kth Smallest Element in Two BSTs**: Given two BSTs, find the kth smallest element when considering both BSTs as a single sorted list. This involves merging the two BSTs while finding the kth element efficiently." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.ipynb b/docs/_build/html/_sources/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.ipynb deleted file mode 100644 index 666bcd9..0000000 --- a/docs/_build/html/_sources/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.ipynb +++ /dev/null @@ -1,245 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 235. Lowest Common Ancestor of a Binary Search Tree\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Lowest Common Ancestor of a Binary Search Tree problem on LeetCode, click here!](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/)\n", - "\n", - "---\n", - "Given a binary search tree (BST), find the lowest common ancestor (LCA) node of two given nodes in the BST.\n", - "\n", - "According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes `p` and `q` as the lowest node in `T` that has both `p` and `q` as descendants (where we allow **a node to be a descendant of itself**).”\n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the tree is in the range $[2, 10^5]$.\n", - "- $-10^9$ <= `Node.val` <= $10^9$\n", - "- All `Node.val` are **unique**.\n", - "- `p != q`\n", - "- `p` and `q` will exist in the BST.\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def lowestCommonAncestor(root, p, q):\n", - " # Ensure p is less than q\n", - " if p.val > q.val:\n", - " p, q = q, p\n", - "\n", - " while root:\n", - " # If the current node value is greater than both p and q, move left\n", - " if root.val > q.val:\n", - " root = root.left\n", - " # If the current node value is less than both p and q, move right\n", - " elif root.val < p.val:\n", - " root = root.right\n", - " # If the current node value is between p and q (inclusive), or it matches either p or q, it's the LCA\n", - " else:\n", - " return root" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. `class TreeNode:` defines a simple class for representing nodes in a binary tree. Each `TreeNode` has three attributes:\n", - " - `val`: The value of the node.\n", - " - `left`: A reference to the left child node.\n", - " - `right`: A reference to the right child node.\n", - "\n", - "2. `def lowestCommonAncestor(root, p, q):` is a function that takes three arguments:\n", - " - `root`: The root node of the BST.\n", - " - `p`: A TreeNode representing one of the nodes for which we want to find the LCA.\n", - " - `q`: A TreeNode representing the other node for which we want to find the LCA.\n", - "\n", - "3. `if p.val > q.val:` checks if the value of `p` is greater than the value of `q`. In a BST, it's essential to ensure that `p` represents the smaller value, and `q` represents the larger value. If `p` is greater than `q`, the code swaps their values.\n", - "\n", - "4. The main logic is inside the `while` loop, which runs until `root` becomes `None`. It performs the following steps to find the LCA:\n", - " - If the current `root` node's value is greater than the value of `q`, it means both `p` and `q` are on the left subtree of the current node. So, we move to the left child of the current node by setting `root = root.left`.\n", - " - If the current `root` node's value is less than the value of `p`, it means both `p` and `q` are on the right subtree of the current node. So, we move to the right child of the current node by setting `root = root.right`.\n", - " - If neither of the above conditions is met, it means the current `root` node's value is between `p` and `q`, or it matches either `p` or `q`. In this case, the current node is the lowest common ancestor (LCA), so we return `root`.\n", - "\n", - "The algorithm is efficient because it takes advantage of the properties of a BST. It eliminates subtrees that cannot contain the LCA by comparing the values of `p`, `q`, and the current `root` node. Eventually, it reaches the LCA node, and that node is returned as the result." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "6\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Construct the tree\n", - "root = TreeNode(6)\n", - "root.left = TreeNode(2)\n", - "root.right = TreeNode(8)\n", - "root.left.left = TreeNode(0)\n", - "root.left.right = TreeNode(4)\n", - "root.right.left = TreeNode(7)\n", - "root.right.right = TreeNode(9)\n", - "root.left.right.left = TreeNode(3)\n", - "root.left.right.right = TreeNode(5)\n", - "\n", - "p = root.left # Node 2\n", - "q = root.right # Node 8\n", - "\n", - "result = lowestCommonAncestor(root, p, q)\n", - "print(result.val)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "# Using the same tree as before\n", - "p = root.left # Node 2\n", - "q = root.left.right # Node 4\n", - "\n", - "result = lowestCommonAncestor(root, p, q)\n", - "print(result.val) " - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "7fc71180-e586-4c37-9fcf-2f574cb2b9d6", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2\n" - ] - } - ], - "source": [ - "# Example 3:\n", - "# Creating a new tree for this example\n", - "root2 = TreeNode(2)\n", - "root2.left = TreeNode(1)\n", - "\n", - "p = root2 # Node 2\n", - "q = root2.left # Node 1\n", - "\n", - "result = lowestCommonAncestor(root2, p, q)\n", - "print(result.val)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided algorithm for finding the lowest common ancestor (LCA) in a Binary Search Tree (BST).\n", - "\n", - "**Time Complexity:**\n", - "The time complexity of this algorithm is O(h), where \"h\" is the height of the BST. In the worst case, where the tree is completely unbalanced (essentially a linked list), the height of the tree is O(n), where \"n\" is the number of nodes in the tree. However, in a well-balanced BST, the height is logarithmic, which is O(log n).\n", - "\n", - "The reason for this time complexity is that the algorithm efficiently narrows down the search space by traversing either left or right subtrees based on the values of the target nodes `p` and `q`. It eliminates entire subtrees that cannot contain the LCA, leading to a relatively quick search.\n", - "\n", - "**Space Complexity:**\n", - "The space complexity of the algorithm is O(1). This is because it uses a constant amount of extra space, regardless of the size of the input BST. The only variables used are `root`, `p`, and `q`, and there are no data structures like stacks or queues used for additional space. The algorithm performs a simple traversal without recursion, so it does not consume extra memory as the tree depth increases.\n", - "\n", - "**In summary**, the provided algorithm for finding the LCA in a BST is both time and space-efficient. Its time complexity is O(h), where \"h\" is the height of the tree, and its space complexity is O(1), making it suitable for practical use even in large BSTs." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "### Challenging Exercises:\n", - "\n", - "1. **Multiple LCAs:** Extend the algorithm to find all the lowest common ancestors of two given nodes `p` and `q` in a BST. In some cases, there can be multiple LCAs.\n", - "\n", - "2. **LCA with k Nodes:** Given a BST and k nodes, find the lowest common ancestor of these k nodes. This is an extension of the problem where you must find the LCA of more than two nodes." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/07. Trees/297. Serialize and Deserialize Binary Tree.ipynb b/docs/_build/html/_sources/07. Trees/297. Serialize and Deserialize Binary Tree.ipynb deleted file mode 100644 index 75c48ea..0000000 --- a/docs/_build/html/_sources/07. Trees/297. Serialize and Deserialize Binary Tree.ipynb +++ /dev/null @@ -1,297 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 297. Serialize and Deserialize Binary Tree\n", - "\n", - "**Difficulty:** Hard\n", - "\n", - "**Link to Problem:** [To see the Serialize and Deserialize Binary Tree problem on LeetCode, click here!](https://leetcode.com/problems/serialize-and-deserialize-binary-tree/)\n", - "\n", - "---\n", - "Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.\n", - "\n", - "Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure.\n", - "\n", - "**Clarification:** The input/output format is the same as how LeetCode serializes a binary tree. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself.\n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the tree is in the range $[0, 10^4]$.\n", - "- `-1000 <= Node.val <= 1000`" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "TThe problem is to design an algorithm to serialize and deserialize a binary tree. Serialization is the process of converting a data structure or object into a sequence of characters or bytes so that it can be easily stored in a file, transmitted over a network, or otherwise persisted. Deserialization is the reverse process of converting the serialized data back into the original data structure.\n", - "\n", - "In the context of this problem:\n", - "\n", - "1. **Serialization**: You are given a binary tree, and your task is to convert it into a string representation such that you can later recreate the same binary tree from this string. The format of serialization is flexible, but it should allow you to reconstruct the original binary tree accurately.\n", - "\n", - "2. **Deserialization**: Given a serialized string, you need to reconstruct the binary tree it represents, ensuring that it is identical to the original tree.\n", - "\n", - "Here are some key points to consider in solving this problem:\n", - "\n", - "- The input can include any valid binary tree, including trees with nodes having integer values within the range [-1000, 1000].\n", - "- You don't necessarily need to follow a specific format for serialization, but it should be designed in a way that allows unambiguous deserialization.\n", - "- The goal is to serialize the tree structure and its values and then deserialize it back into the same structure and values.\n", - "\n", - "A common approach for serialization is to use a traversal method like preorder traversal, where you visit nodes in the order: root, left subtree, right subtree. This way, you can serialize the tree into a string, and during deserialization, you can reconstruct the tree by parsing the string in the same order.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for a binary tree node.\n", - "class TreeNode(object):\n", - " def __init__(self, x):\n", - " self.val = x\n", - " self.left = None\n", - " self.right = None\n", - "\n", - "class Codec:\n", - " def serialize(self, root):\n", - " serialized = []\n", - "\n", - " def dfs(node):\n", - " if not node:\n", - " # If the node is None, represent it as \"Null\" in the serialized string\n", - " serialized .append(\"Null\")\n", - " return\n", - " # Convert the node's value to a string and add it to the serialized string\n", - " serialized .append(str(node.val))\n", - " dfs(node.left)\n", - " dfs(node.right)\n", - "\n", - " dfs(root)\n", - " # Join the serialized values with \",\"\n", - " return \",\".join(serialized )\n", - "\n", - " def deserialize(self, data):\n", - " vals = data.split(\",\")\n", - " self.i = 0\n", - "\n", - " def dfs():\n", - " if vals[self.i] == \"Null\":\n", - " self.i += 1\n", - " return None\n", - " # Convert the value to an integer to create a new node\n", - " node = TreeNode(int(vals[self.i]))\n", - " self.i += 1\n", - " node.left = dfs()\n", - " node.right = dfs()\n", - " return node\n", - "\n", - " return dfs()" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "Here's a step-by-step explanation of the code:\n", - "\n", - "1. **Definition of TreeNode**:\n", - " - The code defines a simple `TreeNode` class that represents a node in a binary tree. Each `TreeNode` has three attributes:\n", - " - `val`: The integer value stored in the node.\n", - " - `left`: A reference to the left child node (or None if there is no left child).\n", - " - `right`: A reference to the right child node (or None if there is no right child).\n", - " - This class allows you to create binary tree nodes with integer values and left and right child references.\n", - "\n", - "2. **Serialization (serialize method)**:\n", - " - The `serialize` method takes a `root` node as input, which is the root of the binary tree that needs to be serialized.\n", - " - It initializes an empty list `serialized` to store the serialized elements.\n", - " - The `dfs` (depth-first search) function is defined within the `serialize` method to perform a preorder traversal of the binary tree.\n", - " - In the `dfs` function:\n", - " - If the current `node` is `None` (i.e., a leaf node or a child of a leaf node), it appends the string \"Null\" to the `serialized` list to represent the absence of a node.\n", - " - If the current `node` is not `None`, it appends the string representation of the `node.val` to the `serialized` list and then recursively calls `dfs` on the left and right children.\n", - " - After the `dfs` traversal, the `serialized` list contains the serialized binary tree elements.\n", - " - The method returns a string obtained by joining the elements in the `serialized` list with commas.\n", - "\n", - "3. **Deserialization (deserialize method)**:\n", - " - The `deserialize` method takes a serialized string `data` as input, which represents a binary tree in the custom format.\n", - " - It splits the `data` string by commas to obtain a list of elements called `vals`.\n", - " - The method initializes an index `self.i` to 0. This index keeps track of the current position in the `vals` list during deserialization.\n", - " - The `dfs` function is defined within the `deserialize` method to perform the deserialization process using a recursive approach.\n", - " - In the `dfs` function:\n", - " - If the current element in `vals` is \"Null,\" it means there is no node at this position in the binary tree, so it returns `None`.\n", - " - If the current element is not \"Null,\" it converts the element to an integer to create a new `TreeNode` with that value.\n", - " - It then recursively calls `dfs` to set the left and right children of the current node.\n", - " - The method returns the root node of the reconstructed binary tree.\n", - "\n", - "Overall, this code demonstrates a way to serialize a binary tree into a string format and then deserialize it back into the original tree structure, allowing for the representation of both the tree structure and the values stored in the nodes." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1,2,Null,Null,3,4,Null,Null,5,Null,Null\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "# Serialize a binary tree\n", - "root = TreeNode(1)\n", - "root.left = TreeNode(2)\n", - "root.right = TreeNode(3)\n", - "root.right.left = TreeNode(4)\n", - "root.right.right = TreeNode(5)\n", - "\n", - "codec = Codec()\n", - "serialized_tree = codec.serialize(root)\n", - "print(serialized_tree)\n", - "\n", - "# Deserialize the serialized tree\n", - "new_root = codec.deserialize(serialized_tree)" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Null\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "# Example usage:\n", - "# Serialize a binary tree\n", - "root = None\n", - "\n", - "codec = Codec()\n", - "serialized_tree = codec.serialize(root)\n", - "print(serialized_tree)\n", - "\n", - "# Deserialize the serialized tree\n", - "new_root = codec.deserialize(serialized_tree)" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code for serializing and deserializing a binary tree:\n", - "\n", - "1. **Serialization (serialize method)**:\n", - "\n", - " - Time Complexity:\n", - " - The `serialize` method uses a depth-first traversal (preorder) of the binary tree.\n", - " - It visits each node exactly once.\n", - " - At each node, it performs constant-time operations (string conversion and list append).\n", - " - Therefore, the time complexity for serialization is O(N), where N is the number of nodes in the binary tree.\n", - "\n", - " - Space Complexity:\n", - " - The space complexity for serialization includes the space used by the `serialized` list and the recursive call stack.\n", - " - The `serialized` list stores the serialized elements, and its space is proportional to the number of nodes.\n", - " - The recursive call stack depth is determined by the height of the binary tree, and in the worst case (completely unbalanced tree), it can be O(N).\n", - " - Therefore, the space complexity for serialization is O(N) due to the list and O(H) due to the recursive call stack, where H is the height of the tree. In most cases, the dominant factor is O(N).\n", - "\n", - "2. **Deserialization (deserialize method)**:\n", - "\n", - " - Time Complexity:\n", - " - The `deserialize` method splits the serialized string into a list of elements, which takes O(N) time.\n", - " - The `dfs` function is a recursive function that visits each element in the list exactly once.\n", - " - At each element, it performs constant-time operations (string comparison, integer conversion, and recursive function calls).\n", - " - Therefore, the time complexity for deserialization is O(N).\n", - "\n", - " - Space Complexity:\n", - " - The space complexity for deserialization includes the space used by the `vals` list and the recursive call stack.\n", - " - The `vals` list stores the elements from the serialized string, and its space is proportional to the number of nodes.\n", - " - The recursive call stack depth is determined by the height of the binary tree, and in the worst case (completely unbalanced tree), it can be O(N).\n", - " - Therefore, the space complexity for deserialization is O(N) due to the list and O(H) due to the recursive call stack, where H is the height of the tree. In most cases, the dominant factor is O(N).\n", - "\n", - "Overall, the provided code has a time complexity of O(N) for both serialization and deserialization and a space complexity of O(N) in the majority of cases (unless the tree is severely unbalanced, in which case the height H dominates the space complexity). It efficiently serializes and deserializes a binary tree while using a linear amount of memory." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Efficient Serialization**:\n", - " Optimize the serialization process to minimize the length of the serialized string. Consider using techniques like binary encoding to represent node values more efficiently.\n", - "\n", - "2. **Custom Serialization Format**:\n", - " Modify the serialization and deserialization methods to use a custom format different from the one provided. Ensure that the new format allows for accurate reconstruction of the original binary tree." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/07. Trees/572. Subtree of Another Tree.ipynb b/docs/_build/html/_sources/07. Trees/572. Subtree of Another Tree.ipynb deleted file mode 100644 index 8a41c3b..0000000 --- a/docs/_build/html/_sources/07. Trees/572. Subtree of Another Tree.ipynb +++ /dev/null @@ -1,265 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 572: Subtree of Another Tree\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Subtree of Another Tree problem on LeetCode, click here!](https://leetcode.com/problems/subtree-of-another-tree/)\n", - "\n", - "---\n", - "\n", - "**Problem Description:**\n", - "\n", - "Given the roots of two binary trees `root` and `subRoot`, return `True` if there is a subtree of `root` with the same structure and node values as `subRoot`, and `False` otherwise.\n", - "\n", - "A subtree of a binary tree `tree` is a tree that consists of a node in `tree` and all of this node's descendants. The tree `tree` could also be considered as a subtree of itself.\n", - "\n", - "**Constraints:**\n", - "\n", - "1. The number of nodes in the `root` tree is in the range $[1, 2000]$.\n", - "2. The number of nodes in the `subRoot` tree is in the range $[1, 1000]$.\n", - "3. $-10^4$ <= root.val <= $10^4$\n", - "4. $-10^4$ <= subRoot.val <= $10^4$\n" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for a binary tree node.\n", - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "class Solution:\n", - " def isSubtree(self, root, subRoot):\n", - " if not root:\n", - " return False\n", - " \n", - " # Check if the current subtree is equal to the subRoot\n", - " if self.isSameTree(root, subRoot):\n", - " return True\n", - " \n", - " # Recursively check the left and right subtrees\n", - " return self.isSubtree(root.left, subRoot) or self.isSubtree(root.right, subRoot)\n", - " \n", - " def isSameTree(self, tree1, tree2):\n", - " if not tree1 and not tree2:\n", - " return True\n", - " if not tree1 or not tree2:\n", - " return False\n", - " \n", - " return (\n", - " tree1.val == tree2.val and\n", - " self.isSameTree(tree1.left, tree2.left) and\n", - " self.isSameTree(tree1.right, tree2.right)\n", - " )" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "This code defines a TreeNode class for the binary tree nodes and a Solution class with two methods:\n", - "\n", - "1. `isSubtree`: This method checks if there is a subtree of the `root` tree with the same structure and node values as the `subRoot` tree. It uses a helper function `isSameTree` to compare two trees for equality.\n", - "\n", - "2. `isSameTree`: This helper method recursively compares two trees to check if they are the same in structure and node values.\n", - "\n", - "### Here's a detailed explanation of the code:\n", - "\n", - "1. **TreeNode Class:**\n", - "\n", - "The `TreeNode` class is defined to represent nodes in a binary tree. Each node has a `val` (the node's value) and may have a `left` and `right` child.\n", - "\n", - "2. **Solution Class:**\n", - "\n", - " + The `Solution` class contains the solution for the problem and defines two important methods:\n", - "\n", - " + `isSubtree(self, root, subRoot)`:\n", - "\n", - " - This method checks whether `subRoot` is a subtree of `root`. It takes two tree nodes, `root` and `subRoot`, as input arguments.\n", - " - If `root` is `None`, it returns `False` because there is no subtree to search.\n", - " - It then checks if the current subtree with `root` as its root is equal to `subRoot` using the `isSameTree` method. If they are the same, it returns `True`.\n", - " - If the current subtree is not the same as `subRoot`, it recursively checks the left and right subtrees of `root` to see if `subRoot` is a subtree of any of them.\n", - " - It returns `True` if `subRoot` is found in either the left or right subtree; otherwise, it returns `False`.\n", - "\n", - " + `isSameTree(self, tree1, tree2)`:\n", - "\n", - " - This method checks whether two trees, `tree1` and `tree2`, are the same.\n", - " - If both `tree1` and `tree2` are `None`, they are considered the same tree, so it returns `True`.\n", - " - If only one of them is `None` (but not both), they are different trees, so it returns `False`.\n", - " - If both `tree1` and `tree2` have values, it checks if their values are equal and recursively checks if their left and right subtrees are the same.\n", - " - It returns `True` if the trees are the same; otherwise, it returns `False`.\n", - "\n", - "The code effectively uses recursion to traverse the binary trees and check for subtree equality. The `isSubtree` method starts the recursive search, and the `isSameTree` method is used to compare individual subtrees. The approach is efficient and avoids unnecessary checks when possible.\n", - "\n", - "This solution allows you to determine if there exists a subtree within the `root` tree that matches the structure and node values of `subRoot`." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Is subRoot a subtree of root? True\n" - ] - } - ], - "source": [ - "#root = [3,4,5,1,2]\n", - "#subRoot = [4,1,2]\n", - "\n", - "# Example input\n", - "root = TreeNode(3)\n", - "root.left = TreeNode(4)\n", - "root.right = TreeNode(5)\n", - "root.left.left = TreeNode(1)\n", - "root.left.right = TreeNode(2)\n", - "\n", - "subRoot = TreeNode(4)\n", - "subRoot.left = TreeNode(1)\n", - "subRoot.right = TreeNode(2)\n", - "\n", - "# Create an instance of the Solution class\n", - "solution = Solution()\n", - "\n", - "# Test the isSubtree method\n", - "result = solution.isSubtree(root, subRoot)\n", - "print(\"Is subRoot a subtree of root?\", result)" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Is subRoot a subtree of root? False\n" - ] - } - ], - "source": [ - "#root = [3,4,5,1,2,null,null,null,null,0] \n", - "#subRoot = [4,1,2]\n", - "\n", - "\n", - "# Example input\n", - "root = TreeNode(3)\n", - "root.left = TreeNode(4)\n", - "root.right = TreeNode(5)\n", - "root.left.left = TreeNode(1)\n", - "root.left.right = TreeNode(2)\n", - "root.left.right.left = TreeNode(0)\n", - "\n", - "subRoot = TreeNode(4)\n", - "subRoot.left = TreeNode(1)\n", - "subRoot.right = TreeNode(2)\n", - "\n", - "# Create an instance of the Solution class\n", - "solution = Solution()\n", - "\n", - "# Test the isSubtree method\n", - "result = solution.isSubtree(root, subRoot)\n", - "print(\"Is subRoot a subtree of root?\", result)" - ] - }, - { - "cell_type": "markdown", - "id": "86a34f0d-0789-498c-818c-2d30f84754d0", - "metadata": {}, - "source": [ - "Let's analyze the time and space complexity of the provided code for the \"Subtree of Another Tree\" problem:\n", - "\n", - "**Time Complexity**\n", - "\n", - "The time complexity of the code primarily depends on the recursive traversal of the binary tree. In both the `isSubtree` and `isSameTree` functions, we visit each node in the binary trees once. Let's break down the time complexity:\n", - "\n", - "1. The `isSubtree` function:\n", - " - In the worst case, we need to visit every node in the `root` tree.\n", - " - For each node in the `root` tree, we call the `isSameTree` function, which has its own traversal.\n", - " - So, the total time complexity is $O(n * m)$, where $n$ is the number of nodes in the `root` tree, and $m$ is the number of nodes in the `subRoot` tree.\n", - "\n", - "2. The `isSameTree` function:\n", - " - In the worst case, we visit every node in both `tree1` and `tree2`.\n", - " - The number of recursive calls made is proportional to the number of nodes in the trees.\n", - " - So, the time complexity of this function is $O(max(n, m))$, where $n$ and $m$ are the numbers of nodes in `tree1` and `tree2`, respectively.\n", - "\n", - "Overall, the time complexity of the entire code is $O(n * m)$, where $n$ is the number of nodes in the `root` tree, and $m$ is the number of nodes in the `subRoot` tree. In practice, it may be less than $O(n * m)$ if a subtree mismatch is detected early during the traversal.\n", - "\n", - "**Space Complexity**\n", - "\n", - "The space complexity of the code is determined by the function call stack during recursion and the space used by the recursive functions. Let's analyze the space complexity:\n", - "\n", - "1. The `isSubtree` function:\n", - " - It uses the call stack for recursion.\n", - " - The maximum depth of the recursion is equal to the height of the `root` tree, which can be $O(n)$ in the worst case (unbalanced tree).\n", - " - Additionally, the function doesn't use any significant extra space other than the recursion stack.\n", - "\n", - "2. The `isSameTree` function:\n", - " - It also uses the call stack for recursion.\n", - " - The maximum depth of the recursion is equal to the height of the `tree1` or `tree2`, whichever is greater.\n", - " - So, the maximum space used for the call stack is $O(max(n, m))$.\n", - "\n", - "In summary, the space complexity of the code is $O(max(n, m))$ due to the function call stack. It scales with the maximum height of the trees being compared.\n", - "\n", - "Overall, the code is efficient and works well for trees with moderate sizes. However, it's important to keep in mind that the worst-case time complexity is $O(n * m)$, so for very large trees, the performance may degrade." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/07. Trees/98. Validate Binary Search Tree.ipynb b/docs/_build/html/_sources/07. Trees/98. Validate Binary Search Tree.ipynb deleted file mode 100644 index ad86882..0000000 --- a/docs/_build/html/_sources/07. Trees/98. Validate Binary Search Tree.ipynb +++ /dev/null @@ -1,221 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 98. Validate Binary Search Tree\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Validate Binary Search Tree problem on LeetCode, click here!](https://leetcode.com/problems/validate-binary-search-tree/)\n", - "\n", - "---\n", - "Given the `root` of a binary tree, *determine if it is a valid binary search tree (BST)*.\n", - "\n", - "A **valid BST** is defined as follows:\n", - "\n", - "- The left subtree of a node contains only nodes with keys **less than** the node's key.\n", - "- The right subtree of a node contains only nodes with keys **greater than** the node's key.\n", - "- Both the left and right subtrees must also be binary search trees. \n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the tree is in the range $[1, 10^4]$.\n", - "- $-2^{31}$ <= `Node.val` <= $2^{31} - 1$\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to solve this problem:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class TreeNode:\n", - " def __init__(self, val=0, left=None, right=None):\n", - " self.val = val\n", - " self.left = left\n", - " self.right = right\n", - "\n", - "def is_valid_BST(root):\n", - " def is_valid(node, min_val, max_val):\n", - " # Base case: If the node is None, it's a valid BST.\n", - " if node is None:\n", - " return True\n", - " \n", - " # Check if the current node's value is within the valid range.\n", - " if not (min_val < node.val < max_val):\n", - " return False\n", - " \n", - " # Recursively check the left and right subtrees with updated ranges.\n", - " return (is_valid(node.left, min_val, node.val) and\n", - " is_valid(node.right, node.val, max_val))\n", - " \n", - " # Call the helper function starting with a wide range for root node.\n", - " return is_valid(root, float('-inf'), float('inf'))" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "- It defines a `TreeNode` class to represent nodes in the binary tree.\n", - "\n", - "- The `is_valid_BST` function takes the root node of the binary tree as input and returns `True` if the tree is a valid BST, and `False` otherwise.\n", - "\n", - "- Inside the `is_valid_BST` function, there is a helper function called `is_valid` that performs the actual validation using a recursive approach.\n", - "\n", - "- The `is_valid` function checks each node in the tree to ensure that it satisfies the properties of a BST:\n", - " - The value of the current node must be within a valid range defined by `min_val` and `max_val`.\n", - " - The left subtree of the current node should contain values less than the current node's value.\n", - " - The right subtree of the current node should contain values greater than the current node's value.\n", - "\n", - "- If any of these conditions are violated, the function returns `False`, indicating that the tree is not a valid BST.\n", - "\n", - "- If all nodes satisfy these conditions, the function returns `True`, indicating that the tree is a valid BST.\n", - "\n", - "- The code calls the `is_valid` function with the root node and initial range values of negative infinity to positive infinity to start the validation.\n", - "\n", - "- The time complexity of the code is O(N), where N is the number of nodes in the tree, as it traverses each node once.\n", - "\n", - "- The space complexity depends on the height of the tree. In the average case for a balanced BST, the space complexity is O(log N), but in the worst case (skewed tree), it can be O(N) due to the recursive call stack.\n", - "\n", - "In summary, this code checks whether a given binary tree is a valid BST by recursively validating each node's value and its left and right subtrees while maintaining valid value ranges. If all nodes satisfy the BST properties, the tree is considered a valid BST." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "# Create the tree for the first example: [2, 1, 3]\n", - "root1 = TreeNode(2)\n", - "root1.left = TreeNode(1)\n", - "root1.right = TreeNode(3)\n", - "print(is_valid_BST(root1))" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "192912fb-9d12-4911-9a4f-bfd37043e11d", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "\n", - "# Create the tree for the second example: [5, 1, 4, None, None, 3, 6]\n", - "root2 = TreeNode(5)\n", - "root2.left = TreeNode(1)\n", - "root2.right = TreeNode(4)\n", - "root2.right.left = TreeNode(3)\n", - "root2.right.right = TreeNode(6)\n", - "print(is_valid_BST(root2))" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `is_valid_BST` function:\n", - "\n", - "**Time Complexity:**\n", - "- The time complexity of the function primarily depends on the number of nodes in the binary tree.\n", - "- In the worst case, we may have to visit every node in the tree once to validate whether it's part of a valid BST.\n", - "- Since we are performing a depth-first search (DFS) traversal of the tree, the time complexity is O(N), where N is the number of nodes in the tree.\n", - "\n", - "**Space Complexity:**\n", - "- The space complexity is determined by the space used by the recursive call stack during the DFS traversal.\n", - "- In the worst case, if the tree is completely unbalanced (a skewed tree), the maximum depth of the call stack would be equal to the height of the tree.\n", - "- In a balanced BST, the height is approximately log2(N), where N is the number of nodes.\n", - "- Therefore, the space complexity of the call stack is O(log N) for a balanced BST.\n", - "- In the worst case (skewed tree), the space complexity can be O(N) as the height of the tree can be equal to N.\n", - "\n", - "**Overall:**\n", - "- Time Complexity: O(N)\n", - "- Space Complexity: O(log N) on average for a balanced BST, and O(N) in the worst case for a skewed tree.\n", - "\n", - "The space complexity is typically dominated by the recursive call stack, and it varies depending on the shape of the binary tree. In practice, for balanced binary trees, the space complexity is often close to O(log N), which is quite efficient." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Complex Constraints**: Modify the problem to have more complex constraints on the tree. For example, consider a binary tree with constraints like \"The left subtree of a node contains only nodes with keys less than or equal to the node's key,\" and \"The right subtree of a node contains only nodes with keys greater than or equal to the node's key.\" How would you adapt the code to handle these constraints?\n", - "\n", - "2. **Handling Duplicates**: Modify the code to handle binary search trees that allow duplicate values. In a standard BST, each value is unique, but in this case, multiple nodes can have the same value. The tree should still be considered valid if it follows the BST property." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/07. Trees/README.md b/docs/_build/html/_sources/07. Trees/README.md deleted file mode 100644 index 1eba5d4..0000000 --- a/docs/_build/html/_sources/07. Trees/README.md +++ /dev/null @@ -1,26 +0,0 @@ -# Trees Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [226. Invert Binary Tree](https://leetcode.com/problems/invert-binary-tree/) | Easy | -| [104. Maximum Depth of Binary Tree](https://leetcode.com/problems/maximum-depth-of-binary-tree/) | Easy | -| [100. Same Tree](https://leetcode.com/problems/same-tree/) | Easy | -| [572. Subtree of Another Tree](https://leetcode.com/problems/subtree-of-another-tree/) | Easy | -| [235. Lowest Common Ancestor of a Binary Search Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/) | Easy | -| [102. Binary Tree Level Order Traversal](https://leetcode.com/problems/binary-tree-level-order-traversal/) | Medium | -| [98. Validate Binary Search Tree](https://leetcode.com/problems/validate-binary-search-tree/) | Medium | -| [230. Kth Smallest Element In a BST](https://leetcode.com/problems/kth-smallest-element-in-a-bst/) | Medium | -| [105. Construct Binary Tree From Preorder And Inorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/) | Medium | -| [124. Binary Tree Maximum Path Sum](https://leetcode.com/problems/binary-tree-maximum-path-sum/) | Hard | -| [297. Serialize And Deserialize Binary Tree](https://leetcode.com/problems/serialize-and-deserialize-binary-tree/) | Hard | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! diff --git a/docs/_build/html/_sources/08. Tries/208. Implement Trie (Prefix Tree).ipynb b/docs/_build/html/_sources/08. Tries/208. Implement Trie (Prefix Tree).ipynb deleted file mode 100644 index 9da2a17..0000000 --- a/docs/_build/html/_sources/08. Tries/208. Implement Trie (Prefix Tree).ipynb +++ /dev/null @@ -1,249 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 208. Implement Trie (Prefix Tree)\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Implement Trie problem on LeetCode, click here!](https://leetcode.com/problems/implement-trie-prefix-tree/)\n", - "\n", - "---\n", - "A **trie** (pronounced as \"try\") or **prefix tree** is a tree data structure used to efficiently store and retrieve keys in a dataset of strings. There are various applications of this data structure, such as autocomplete and spellchecker.\n", - "\n", - "Implement the Trie class:\n", - "\n", - "- `Trie()` Initializes the trie object.\n", - "- `void insert(String word)` Inserts the string `word` into the trie.\n", - "- `boolean search(String word)` Returns `true` if the string `word` is in the trie (i.e., was inserted before), and `false` otherwise.\n", - "- `boolean startsWith(String prefix)` Returns `true` if there is a previously inserted string `word` that has the prefix `prefix`, and `false` otherwise.\n", - "\n", - "\n", - "**Constraints:**\n", - "- `1 <= word.length, prefix.length <= 2000`\n", - "- `word` and `prefix` consist only of lowercase English letters.\n", - "- At most $3 * 10^4$ calls in total will be made to `insert`, `search`, and `startsWith`." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem at hand is to implement a data structure known as a Trie (pronounced \"try\") or Prefix Tree. A Trie is a tree-like data structure that is used to efficiently store and retrieve a set of strings or words. It's particularly useful for tasks involving string manipulation, such as autocomplete and spell-checking. The problem statement defines the following operations for implementing the Trie class:\n", - "\n", - "1. `Trie()`: This is the constructor that initializes the Trie object.\n", - "\n", - "2. `void insert(String word)`: This method inserts the given string `word` into the Trie. It effectively adds the characters of the word to the Trie's structure, creating nodes for each character if they don't already exist. At the end of the word, a special flag is set to indicate that this node represents the end of a valid word.\n", - "\n", - "3. `boolean search(String word)`: This method checks if the given string `word` is present in the Trie. It starts from the root of the Trie and traverses the Trie by following the characters in the word. If it successfully traverses the Trie and reaches the end of the word, it returns `true`, indicating that the word exists in the Trie; otherwise, it returns `false`.\n", - "\n", - "4. `boolean startsWith(String prefix)`: This method checks if there is any previously inserted word in the Trie that has the given `prefix`. It's similar to the `search` method but does not require that the prefix be a complete word. If there is any word in the Trie that starts with the given prefix, it returns `true`; otherwise, it returns `false`.\n", - "\n", - "The problem also provides an example scenario where these operations are called, demonstrating the expected output for each operation.\n", - "\n", - "In summary, the goal is to create a data structure (Trie) that efficiently stores a set of strings and provides methods to insert new strings, search for complete words, and check if a given prefix exists in the stored set of strings.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class TrieNode:\n", - " def __init__(self):\n", - " self.children = {} # A dictionary to store child nodes\n", - " self.is_end_of_word = False # Indicates if a word ends at this node\n", - "\n", - "class Trie:\n", - " def __init__(self):\n", - " self.root = TrieNode() # Initialize the Trie with a root node\n", - "\n", - " def insert(self, word):\n", - " node = self.root # Start from the root\n", - " for char in word:\n", - " if char not in node.children:\n", - " node.children[char] = TrieNode() # Create a new node if the character is not present\n", - " node = node.children[char] # Move to the child node\n", - " node.is_end_of_word = True # Mark the end of the inserted word\n", - "\n", - " def search(self, word):\n", - " node = self.root # Start from the root\n", - " for char in word:\n", - " if char not in node.children:\n", - " return False # If the character is not found, the word is not in the Trie\n", - " node = node.children[char] # Move to the child node\n", - " return node.is_end_of_word # Check if the node represents the end of a valid word\n", - "\n", - " def startsWith(self, prefix):\n", - " node = self.root # Start from the root\n", - " for char in prefix:\n", - " if char not in node.children:\n", - " return False # If the character is not found, no word starts with the prefix\n", - " node = node.children[char] # Move to the child node\n", - " return True # Prefix found in the Trie" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "Let's explain how the code works step by step:\n", - "\n", - "1. `TrieNode` Class:\n", - " - `TrieNode` is a class that represents nodes in the Trie. Each node has two attributes:\n", - " - `children`: This is a dictionary that stores child nodes. Each key in the dictionary represents a character, and the corresponding value is the child node for that character.\n", - " - `is_end_of_word`: This boolean flag indicates whether the node represents the end of a complete word. Initially, it's set to `False` for all nodes.\n", - "\n", - "2. `Trie` Class:\n", - " - `Trie` is the main class that implements the Trie data structure. It has the following methods:\n", - "\n", - " - `__init__(self)`: The constructor initializes the Trie object by creating a root node, which serves as the starting point for all Trie operations.\n", - "\n", - " - `insert(self, word)`: This method inserts a string `word` into the Trie. It starts from the root node and iterates through each character in the word.\n", - " - If a character is not present as a child node, it creates a new node for that character.\n", - " - It then moves to the child node and continues the process until the entire word is inserted.\n", - " - Finally, it sets the `is_end_of_word` flag to `True` for the last node to mark the end of the inserted word.\n", - "\n", - " - `search(self, word)`: This method checks if a complete word (string) exists in the Trie. It starts from the root node and iterates through each character in the word.\n", - " - If a character is not found as a child node, it immediately returns `False` because the word is not in the Trie.\n", - " - It continues to move to the child node for each character.\n", - " - After reaching the end of the word, it checks if the `is_end_of_word` flag is `True` for the last node to confirm the presence of the word.\n", - "\n", - " - `startsWith(self, prefix)`: This method checks if there is any previously inserted word in the Trie that starts with a given `prefix`. It follows the same logic as the `search` method but does not require the entire word to be present.\n", - " - If the prefix is found in the Trie, it returns `True`; otherwise, it returns `False`.\n", - "\n", - "3. Example Usage:\n", - " - The code demonstrates how to create a Trie object, insert words (\"apple\" and \"app\"), and perform operations on the Trie:\n", - " - It inserts the word \"apple\" into the Trie.\n", - " - It checks if \"apple\" is in the Trie, which returns `True`.\n", - " - It checks if \"app\" is in the Trie, which returns `False`.\n", - " - It checks if there is any word in the Trie that starts with \"app,\" which returns `True`.\n", - " - It inserts the word \"app\" into the Trie.\n", - " - It checks if \"app\" is in the Trie again, which now returns `True`.\n", - "\n", - "In summary, the code efficiently implements a Trie data structure with the ability to insert words, search for complete words, and check for the existence of words with a given prefix. The Trie is organized as a tree of nodes, with each node representing a character in the words being stored." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n", - "False\n", - "True\n", - "True\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "\n", - "trie = Trie()\n", - "trie.insert(\"apple\")\n", - "print(trie.search(\"apple\")) # Output: True\n", - "print(trie.search(\"app\")) # Output: False\n", - "print(trie.startsWith(\"app\")) # Output: True\n", - "trie.insert(\"app\")\n", - "print(trie.search(\"app\")) # Output: True" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the Trie implementation:\n", - "\n", - "1. Time Complexity:\n", - " - Insertion (`insert` method): The time complexity of inserting a word into the Trie is O(m), where m is the length of the word. In the worst case, you may need to traverse the entire word to insert it into the Trie.\n", - " - Search (`search` method): The time complexity of searching for a word in the Trie is also O(m), where m is the length of the word. In the worst case, you may need to traverse the entire word to determine if it exists in the Trie.\n", - " - Starts with (`startsWith` method): The time complexity of checking if a prefix exists in the Trie is O(p), where p is the length of the prefix. In the worst case, you may need to traverse the entire prefix to determine its presence.\n", - "\n", - " Therefore, for each operation (insertion, search, or starts with), the time complexity is O(m) or O(p), where m is the length of the word being operated on, and p is the length of the prefix.\n", - "\n", - "2. Space Complexity:\n", - " - The space complexity of the Trie is determined by the number of nodes and characters stored in it. In the worst case, where none of the inserted words share common prefixes, the space complexity is O(N), where N is the total number of characters across all inserted words.\n", - " - Each node in the Trie represents a character, and the number of nodes is directly related to the total number of characters.\n", - "\n", - " In practice, the space complexity can be less than O(N) because common prefixes are shared among words in the Trie, leading to space optimization.\n", - "\n", - "In summary:\n", - "- Time complexity for each operation (insertion, search, starts with) is O(m) or O(p), where m is the length of the word and p is the length of the prefix.\n", - "- Space complexity is O(N) in the worst case, where N is the total number of characters across all inserted words. However, space optimization occurs due to common prefix sharing in practice, potentially reducing the actual space used." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Count Prefixes**:\n", - " Implement a method to count the number of words in the Trie that have a specific prefix. This exercise requires you to maintain additional data in the Trie nodes to keep track of the count.\n", - "\n", - "2. **Auto-Complete Suggestions**:\n", - " Implement an auto-complete feature using the Trie. Given a prefix, the program should return a list of suggested words based on the words previously inserted into the Trie." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/08. Tries/211. Design Add and Search Words Data Structure.ipynb b/docs/_build/html/_sources/08. Tries/211. Design Add and Search Words Data Structure.ipynb deleted file mode 100644 index 2de472c..0000000 --- a/docs/_build/html/_sources/08. Tries/211. Design Add and Search Words Data Structure.ipynb +++ /dev/null @@ -1,275 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 211. Design Add and Search Words Data Structure\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Design Add and Search Words Data Structure problem on LeetCode, click here!](https://leetcode.com/problems/design-add-and-search-words-data-structure/)\n", - "\n", - "---\n", - "Design a data structure that supports adding new words and finding if a string matches any previously added string.\n", - "\n", - "Implement the `WordDictionary` class:\n", - "\n", - "- `WordDictionary()` Initializes the object.\n", - "- `void addWord(word)` Adds `word` to the data structure, it can be matched later.\n", - "- `bool search(word)` Returns `true` if there is any string in the data structure that matches `word` or `false` otherwise. `word` may contain dots `'.'` where dots can be matched with any letter.\n", - "\n", - "**Constraints:**\n", - "- `1 <= word.length <= 25`\n", - "- `word` in `addWord` consists of lowercase English letters.\n", - "- `word` in `search` consist of `'.'` or lowercase English letters.\n", - "- There will be at most `2` dots in `word` for `search` queries.\n", - "- At most $10^4$ calls will be made to `addWord` and `search`." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is to design a data structure called `WordDictionary` that allows you to add words and search for words efficiently. The key feature of this data structure is that it should support wildcard search, where a dot ('.') can match any letter.\n", - "\n", - "Here are the specific requirements and explanations for the problem:\n", - "\n", - "1. Initialize the `WordDictionary` object using the constructor `WordDictionary()`.\n", - "\n", - "2. The `addWord(word)` method allows you to add a word to the data structure. Once added, you should be able to search for this word later. The words consist of lowercase English letters, and each word has a length between 1 and 25 characters.\n", - "\n", - "3. The `search(word)` method allows you to search for a word in the data structure. This method returns `True` if there is any string in the data structure that matches the given word or `False` otherwise. The word you are searching for may contain dots ('.'), where each dot can match any letter.\n", - "\n", - "4. The wildcard character ('.') in the `search` method allows for partial or fuzzy searching. For example, if the word dictionary contains the words \"bad,\" \"dad,\" and \"mad,\" then:\n", - " - Searching for \"pad\" should return `False` because there is no exact match.\n", - " - Searching for \"bad\" should return `True` because \"bad\" is in the dictionary.\n", - " - Searching for \".ad\" should return `True` because it can match \"bad,\" \"dad,\" or \"mad.\"\n", - " - Searching for \"b..\" should return `True` because it can match \"bad,\" \"bed,\" \"bet,\" etc.\n", - "\n", - "5. The problem specifies that there will be at most two dots ('.') in search queries, and there will be at most 10^4 calls to both `addWord` and `search`.\n", - "\n", - "In summary, you need to implement the `WordDictionary` class that efficiently supports adding words and searching for words, where the search can include wildcard characters ('.') that match any letter.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class TrieNode:\n", - " def __init__(self):\n", - " # Initialize a TrieNode with children and a flag to indicate the end of a word.\n", - " self.children = {}\n", - " self.is_end_of_word = False\n", - "\n", - "class WordDictionary:\n", - "\n", - " def __init__(self):\n", - " # Initialize the WordDictionary with a root node.\n", - " self.root = TrieNode()\n", - "\n", - " def addWord(self, word: str) -> None:\n", - " node = self.root\n", - " # Iterate through the characters in the word.\n", - " for char in word:\n", - " if char not in node.children:\n", - " # Create a new node for the character if it doesn't exist.\n", - " node.children[char] = TrieNode()\n", - " # Move to the next node.\n", - " node = node.children[char]\n", - " # Mark the end of the word by setting the flag to True.\n", - " node.is_end_of_word = True\n", - "\n", - " def search_helper(self, node: TrieNode, word: str) -> bool:\n", - " if not word:\n", - " # If there are no characters left in the word, check if we reached the end of a word in the trie.\n", - " return node.is_end_of_word\n", - " \n", - " char = word[0]\n", - " if char == '.':\n", - " # If the character is a dot, explore all possible child nodes.\n", - " for child in node.children.values():\n", - " if self.search_helper(child, word[1:]):\n", - " return True\n", - " elif char in node.children:\n", - " # If the character is in the children of the current node, move to the next node.\n", - " return self.search_helper(node.children[char], word[1:])\n", - " \n", - " # If the character is not found and is not a dot, the word is not in the trie.\n", - " return False\n", - "\n", - " def search(self, word: str) -> bool:\n", - " # Start the search from the root of the trie.\n", - " return self.search_helper(self.root, word)" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "This code defines a `WordDictionary` class that uses a Trie data structure to efficiently store and search for words. Here's a step-by-step explanation:\n", - "\n", - "1. `TrieNode` class: This class represents nodes in the Trie data structure. Each node has two attributes: `children` (a dictionary to store child nodes) and `is_end_of_word` (a flag to indicate whether the node marks the end of a word).\n", - "\n", - "2. `WordDictionary` class: This class initializes with an empty Trie by creating a root node.\n", - "\n", - "3. `addWord` method: This method adds a word to the Trie. It iterates through each character in the word and creates Trie nodes as necessary. It sets the `is_end_of_word` flag to `True` for the final character of the word to mark the end of the word.\n", - "\n", - "4. `search_helper` method: This is a recursive helper function for searching words in the Trie. It takes a Trie node (`node`) and a word to search (`word`) as input. If there are no characters left in the word (`not word`), it checks if the current node marks the end of a word. If it does, it returns `True`.\n", - "\n", - "5. If the first character of the word is a dot ('.'), the function explores all possible child nodes by iterating through `node.children.values()` and recursively calls `search_helper` for each child with the remaining part of the word (`word[1:]`).\n", - "\n", - "6. If the first character of the word is not a dot and is found in the children of the current node, the function recursively moves to the next node by calling `search_helper` on the child node and the remaining part of the word.\n", - "\n", - "7. If the character is not found in the children and is not a dot, the word is not in the Trie, so the function returns `False`.\n", - "\n", - "8. `search` method: This is the public method for searching words. It initiates the search process by calling `search_helper` starting from the root node of the Trie.\n", - "\n", - "Overall, this code efficiently implements a Trie-based data structure that allows adding and searching for words, including support for wildcard characters represented by dots ('.')." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n", - "True\n", - "True\n", - "True\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "\n", - "wordDictionary = WordDictionary()\n", - "wordDictionary.addWord(\"bad\")\n", - "wordDictionary.addWord(\"dad\")\n", - "wordDictionary.addWord(\"mad\")\n", - "print(wordDictionary.search(\"pad\")) # Output: False\n", - "print(wordDictionary.search(\"bad\")) # Output: True\n", - "print(wordDictionary.search(\".ad\")) # Output: True\n", - "print(wordDictionary.search(\"b..\")) # Output: True" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `WordDictionary` class methods:\n", - "\n", - "1. `addWord` Method:\n", - "\n", - " - Time Complexity: O(L)\n", - " - L is the length of the word being added.\n", - " - In the worst case, we need to iterate through each character in the word and create nodes in the Trie. This takes O(L) time.\n", - "\n", - " - Space Complexity: O(L)\n", - " - The space complexity for storing the word in the Trie is also O(L) because we create nodes for each character in the word.\n", - "\n", - "2. `search_helper` Method (called by `search`):\n", - "\n", - " - Time Complexity: O(2^M * L)\n", - " - M is the maximum number of dots ('.') in the search word.\n", - " - In the worst case, when there are M dots in the search word, we may explore all possible child nodes at each dot. This results in a branching factor of 26 (for lowercase letters) at each dot.\n", - " - So, the time complexity is exponential in the number of dots and linear in the length of the word being searched (L).\n", - "\n", - " - Space Complexity: O(L)\n", - " - The space complexity for the recursive call stack is O(L) in the worst case because we may have to recurse to a depth equal to the length of the search word.\n", - "\n", - "3. `search` Method:\n", - "\n", - " - Time Complexity: O(2^M * L)\n", - " - The `search` method calls the `search_helper` method, which has the same time complexity explained above.\n", - "\n", - " - Space Complexity: O(L)\n", - " - The space complexity for the recursive call stack is O(L) in the worst case, as explained earlier.\n", - "\n", - "Overall, the time complexity of the `search` method is mainly affected by the number of dots ('.') in the search word. In the worst case, when there are multiple dots and many possibilities to explore at each dot, the time complexity can be exponential. However, for most practical cases, it performs reasonably well.\n", - "\n", - "The space complexity primarily depends on the space required to store the words in the Trie. It is proportional to the total number of characters in all added words and is linear with respect to the length of the words added.\n", - "\n", - "In summary:\n", - "\n", - "- Time Complexity for `addWord`: O(L)\n", - "- Time Complexity for `search`: O(2^M * L)\n", - "- Space Complexity: O(L) for storing words in the Trie, O(L) for the recursive call stack during search.\n", - "\n", - "Note: The space complexity analysis assumes that the dictionary contains a reasonable number of words and does not account for the overhead of Python objects or system-level memory allocation." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Dictionary Auto-Completion**: Extend the `WordDictionary` class to provide auto-completion suggestions based on the prefix of a word. Implement a method that returns a list of words that match the given prefix.\n", - "\n", - "2. **Support Word Deletion**: Extend the `WordDictionary` class to support word deletion. Add a method `deleteWord(word)` that removes a word from the data structure. Ensure that the search operation still works correctly after deletion." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/08. Tries/212. Word Search II.ipynb b/docs/_build/html/_sources/08. Tries/212. Word Search II.ipynb deleted file mode 100644 index 71597b8..0000000 --- a/docs/_build/html/_sources/08. Tries/212. Word Search II.ipynb +++ /dev/null @@ -1,316 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 212. Word Search II\n", - "\n", - "**Difficulty:** Hard\n", - "\n", - "**Link to Problem:** [To see the Word Search II problem on LeetCode, click here!](https://leetcode.com/problems/word-search-ii/)\n", - "\n", - "---\n", - "Given an `m x n` `board` of characters and a list of strings `words`, the task is to return *all words on the board*.\n", - "\n", - "Each word must be constructed from letters of sequentially **adjacent cells**, where adjacent cells are horizontally or vertically neighboring. The same letter cell may not be used more than once in a word.\n", - "\n", - "\n", - "**Constraints:**\n", - "- `m == board.length`\n", - "- `n == board[i].length`\n", - "- `1 <= m, n <= 12`\n", - "- `board[i][j]` is a lowercase English letter.\n", - "- 1 <= `words.length` <= $3 * 10^4$\n", - "- `1 <= words[i].length <= 10`\n", - "- `words[i]` consists of lowercase English letters.\n", - "- All the strings of `words` are unique." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "To solve the \"Word Search II\" problem, you can use a Trie data structure and perform a depth-first search (DFS) on the board. Here's a step-by-step approach to solve the problem:\n", - "\n", - "1. Build a Trie from the given list of words:\n", - " - Create a Trie data structure to store all the words from the input list.\n", - " - For each word in the input list, insert it into the Trie, character by character. Make sure to mark the end of each word in the Trie.\n", - "\n", - "2. Perform DFS on the board:\n", - " - Iterate through each cell (i, j) on the board.\n", - " - For each cell, start a DFS traversal from that cell to search for words.\n", - " - During the DFS traversal, maintain a current path string.\n", - " - At each cell, check if the current path string, concatenated with the character in the cell, matches any word prefix in the Trie. If it does, continue the DFS.\n", - " - If the current path string matches a word in the Trie, add it to the result.\n", - "\n", - "3. Implement DFS with backtracking:\n", - " - During the DFS traversal, you will explore neighboring cells (horizontally and vertically) if they are within bounds and haven't been visited before.\n", - " - To prevent revisiting the same cell within the same word, mark the cell as visited (e.g., change its character to a special character like '#') before exploring it and restore its original character after the DFS traversal.\n", - "\n", - "4. Return the result:\n", - " - After completing the DFS traversal for all cells on the board, you will have collected all the valid words in the result set.\n", - " - Convert the result set to a list and return it as the final output.\n", - "\n", - "This approach efficiently finds all words on the board by utilizing the Trie data structure to prune unnecessary DFS paths and avoiding duplicate visits to the same cell within the same word. It ensures that each word is constructed from letters of sequentially adjacent cells without using the same letter cell more than once in a word.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Define a TrieNode class to represent nodes in the Trie.\n", - "class TrieNode:\n", - " def __init__(self):\n", - " self.children = {} # Dictionary to store child nodes.\n", - " self.is_end_of_word = False # Flag to mark the end of a word.\n", - "\n", - "# Main function to find words on the board.\n", - "def findWords(board, words):\n", - " # DFS function to search for words starting from a given cell.\n", - " def dfs(node, i, j, path):\n", - " char = board[i][j] # Get the character at the current cell.\n", - " curr_node = node.children.get(char) # Find the corresponding Trie node.\n", - "\n", - " if not curr_node:\n", - " return # If no matching Trie node, stop the search.\n", - "\n", - " path += char # Add the character to the current path.\n", - "\n", - " if curr_node.is_end_of_word:\n", - " result.add(path) # If the path matches a word, add it to the result.\n", - "\n", - " temp, board[i][j] = board[i][j], \"#\" # Mark the cell as visited.\n", - "\n", - " # Explore neighboring cells (up, down, left, right).\n", - " if i > 0:\n", - " dfs(curr_node, i - 1, j, path)\n", - " if i < m - 1:\n", - " dfs(curr_node, i + 1, j, path)\n", - " if j > 0:\n", - " dfs(curr_node, i, j - 1, path)\n", - " if j < n - 1:\n", - " dfs(curr_node, i, j + 1, path)\n", - "\n", - " board[i][j] = temp # Restore the cell's original character.\n", - "\n", - " # Function to build a Trie from the list of words.\n", - " def buildTrie():\n", - " root = TrieNode() # Create a root node.\n", - " for word in words:\n", - " node = root\n", - " for char in word:\n", - " if char not in node.children:\n", - " node.children[char] = TrieNode() # Create a new node if needed.\n", - " node = node.children[char]\n", - " node.is_end_of_word = True # Mark the end of the word.\n", - " return root\n", - "\n", - " m, n = len(board), len(board[0]) # Get the dimensions of the board.\n", - " root = buildTrie() # Build the Trie from the list of words.\n", - " result = set() # Use a set to store unique words found on the board.\n", - "\n", - " # Iterate through each cell on the board and start DFS from there.\n", - " for i in range(m):\n", - " for j in range(n):\n", - " dfs(root, i, j, \"\") # Start DFS from each cell on the board.\n", - "\n", - " return list(result) # Convert the set to a list and return the result." - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The code solves the \"Word Search II\" problem, where you have a grid of characters and a list of words. The goal is to find all words from the list that can be constructed by traversing adjacent cells (horizontally or vertically) in the grid, without using the same cell more than once for a single word.\n", - "\n", - "The code does the following:\n", - "\n", - "1. Defines a `TrieNode` class to represent nodes in a Trie data structure. Each node has children (other characters in the word) and a flag to mark the end of a word.\n", - "\n", - "2. Defines the `findWords` function, which takes the grid (`board`) and a list of words (`words`) as input.\n", - "\n", - "3. Inside the `findWords` function, there is a `dfs` (depth-first search) function. This function is used to explore the grid starting from a specific cell. It checks if the current path matches any word in the Trie and adds it to the result if found.\n", - "\n", - "4. The code also includes a `buildTrie` function that constructs a Trie data structure from the list of words. It iterates through each word, creating nodes for each character in the Trie and marking the end of words.\n", - "\n", - "5. The dimensions of the grid are obtained (m x n).\n", - "\n", - "6. A Trie is built using the `buildTrie` function.\n", - "\n", - "7. A set called `result` is used to store unique words found in the grid.\n", - "\n", - "8. The code iterates through each cell on the grid (using nested loops) and starts a DFS search from each cell.\n", - "\n", - "9. During the DFS, it explores neighboring cells (up, down, left, right) if they haven't been visited before and if the current path matches a prefix in the Trie.\n", - "\n", - "10. When a word is found during the DFS traversal, it is added to the `result` set.\n", - "\n", - "11. The grid cell is marked as visited during the DFS by changing its character to \"#\", and it is restored to its original character after the DFS traversal.\n", - "\n", - "12. Finally, the set of unique words found is converted to a list and returned as the output.\n", - "\n", - "The code effectively uses a Trie data structure to optimize the search and ensures that each word is constructed from adjacent cells without reusing the same cell for the same word." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['eat', 'oath']\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "board1 = [[\"o\",\"a\",\"a\",\"n\"],[\"e\",\"t\",\"a\",\"e\"],[\"i\",\"h\",\"k\",\"r\"],[\"i\",\"f\",\"l\",\"v\"]]\n", - "words1 = [\"oath\",\"pea\",\"eat\",\"rain\"]\n", - "print(findWords(board1, words1)) # Output: [\"eat\", \"oath\"]" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "c748b879-a2d8-4298-a42c-c7f61f9c7fc6", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[]\n" - ] - } - ], - "source": [ - "# Example 2\n", - "\n", - "board2 = [[\"a\",\"b\"],[\"c\",\"d\"]]\n", - "words2 = [\"abcb\"]\n", - "print(findWords(board2, words2)) # Output: []" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. **Building the Trie (`buildTrie` function):** \n", - " - Suppose there are `N` words in the input list, and the average length of a word is `L`.\n", - " - Building the Trie takes O(N * L) time, as we iterate through each word and insert each character into the Trie.\n", - "\n", - "2. **DFS Traversal (`dfs` function):** \n", - " - In the worst case, the DFS function explores all possible paths in the grid.\n", - " - The maximum number of recursive calls for each cell is 4 (up, down, left, right).\n", - " - The maximum depth of the DFS is limited by the length of the longest word in the Trie, which is at most `L`.\n", - " - Therefore, the DFS traversal for each cell takes $O(4^L)$ time.\n", - "\n", - "3. **Iterating Through the Grid (`findWords` function):**\n", - " - In the worst case, we iterate through all `m` rows and `n` columns in the grid.\n", - " - For each cell, we start a DFS traversal.\n", - " - Therefore, iterating through the entire grid takes $O(m * n * 4^L)$ time.\n", - "\n", - "Overall, the time complexity of the code is $O(N * L + m * n * 4^L)$.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. **Trie Data Structure:**\n", - " - The space required to store the Trie depends on the number of unique characters in all the words.\n", - " - In the worst case, where all words are unique and have no common prefixes, the space complexity of the Trie is O(N * L).\n", - " - In practice, it may be less if there are common prefixes among words.\n", - "\n", - "2. **DFS Stack (Recursive Calls):**\n", - " - The depth of the recursive call stack during DFS is at most `L`, where `L` is the length of the longest word in the Trie.\n", - " - Therefore, the space complexity for the recursive call stack is O(L).\n", - "\n", - "3. **Result Set (`result` set):**\n", - " - The space used to store the result set depends on the number of valid words found in the grid.\n", - " - In the worst case, when all words are found, the space complexity of the result set is O(N * L).\n", - "\n", - "Overall, the space complexity of the code is O(N * L) for the Trie and O(L) for the recursive call stack.\n", - "\n", - "In summary, the time complexity is dominated by the DFS traversal and is influenced by the number of words, their lengths, and the size of the grid. The space complexity is mainly determined by the Trie structure and the recursive call stack depth during DFS." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Word Search Paths:**\n", - " Extend the basic word search exercise to find all possible paths (sequences of cells) that spell out a given word on the board. Return a list of paths if the word can be formed, otherwise an empty list.\n", - "\n", - "\n", - "2. **Reverse Word Search:**\n", - " Modify the code to search for words in reverse order on the board. Given a 2D grid of characters and a list of words, find all words from the list that can be formed by traversing the board in reverse (right to left, bottom to top, etc.)." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/08. Tries/README.md b/docs/_build/html/_sources/08. Tries/README.md deleted file mode 100644 index 22c3bcd..0000000 --- a/docs/_build/html/_sources/08. Tries/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# Trie Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [208. Implement Trie Prefix Tree](https://leetcode.com/problems/implement-trie-prefix-tree/) | Medium | -| [211. Design Add And Search Words Data Structure](https://leetcode.com/problems/design-add-and-search-words-data-structure/) | Medium | -| [212. Word Search II](https://leetcode.com/problems/word-search-ii/) | Hard | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! diff --git a/docs/_build/html/_sources/09. Heap - Priority Queue/1046. Last Stone Weight.ipynb b/docs/_build/html/_sources/09. Heap - Priority Queue/1046. Last Stone Weight.ipynb deleted file mode 100644 index cb66b6a..0000000 --- a/docs/_build/html/_sources/09. Heap - Priority Queue/1046. Last Stone Weight.ipynb +++ /dev/null @@ -1,254 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 1046. Last Stone Weight\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Last Stone Weight problem on LeetCode, click here!](https://leetcode.com/problems/last-stone-weight/)\n", - "\n", - "---\n", - "You are given an array of integers `stones` where `stones[i]` is the weight of the `i`th stone.\n", - "\n", - "We are playing a game with the stones. On each turn, you choose the **heaviest two stones** and smash them together. Suppose the heaviest two stones have weights `x` and `y` with `x <= y`. The result of this smash is:\n", - "\n", - "1. If `x == y`, both stones are destroyed.\n", - "2. If `x != y`, the stone of weight `x` is destroyed, and the stone of weight `y` has new weight `y - x`.\n", - "\n", - "At the end of the game, there is **at most one** stone left.\n", - "\n", - "Return *the weight of the last remaining stone*. If there are no stones left, return `0`.\n", - "\n", - "**Constraints:**\n", - "- `1 <= stones.length <= 30`\n", - "- `1 <= stones[i] <= 1000`" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The \"Last Stone Weight\" problem involves a game played with a collection of stones, each stone having a certain weight. The goal is to find the weight of the last remaining stone after applying a specific set of rules.\n", - "\n", - "Here's how the game works:\n", - "\n", - "1. You start with an array of stones, where each stone is represented by its weight. The weights of the stones are given in the input as an array.\n", - "\n", - "2. In each turn of the game, you select the two heaviest stones from the remaining stones. If there is only one stone left, you've found the answer.\n", - "\n", - "3. If there are two stones with weights `x` and `y`, where `x` is less than or equal to `y`, the following happens:\n", - " - If `x` is equal to `y`, both stones are completely destroyed, and they are removed from the array of stones.\n", - " - If `x` is not equal to `y`, the stone with weight `x` is destroyed, and the stone with weight `y` now has a new weight of `y - x`. The stone with weight `x` is removed from the array, and the modified stone with weight `y - x` remains in the array.\n", - "\n", - "4. The game continues with the modified array of stones until there is at most one stone left.\n", - "\n", - "5. The goal is to find the weight of the last remaining stone, or if there are no stones left, return `0`.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "import heapq\n", - "\n", - "def lastStoneWeight(stones):\n", - " # Convert the input list to a max heap (negate the values to simulate a max heap)\n", - " max_heap = [-stone for stone in stones]\n", - " heapq.heapify(max_heap)\n", - "\n", - " # Continue as long as there are more than 1 stone in the heap\n", - " while len(max_heap) > 1:\n", - " # Get the two heaviest stones\n", - " y = -heapq.heappop(max_heap) # Get the heaviest stone and negate it back to positive\n", - " x = -heapq.heappop(max_heap) # Get the second heaviest stone and negate it back to positive\n", - "\n", - " # Calculate the new stone's weight after smashing\n", - " if x != y:\n", - " new_stone = y - x\n", - " heapq.heappush(max_heap, -new_stone) # Negate the value and push it back to the heap\n", - "\n", - " # If there is one stone left, return its weight (negate it back to positive)\n", - " if max_heap:\n", - " return -max_heap[0]\n", - " else:\n", - " return 0" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The code defines a Python function called `lastStoneWeight` that takes a list of stone weights as input. It aims to find the weight of the last remaining stone after playing the stone smashing game described in the problem statement.\n", - "\n", - "Here's a step-by-step explanation of the code:\n", - "\n", - "1. We import the `heapq` library, which allows us to create and manipulate a heap (priority queue).\n", - "\n", - "2. Inside the `lastStoneWeight` function:\n", - " - We create a max heap (negating stone weights to simulate a max heap) using the `heapq.heapify` function. This heap will keep track of the heaviest stones.\n", - " \n", - " - We enter a loop that continues as long as there are more than 1 stone in the heap.\n", - " \n", - " - Inside the loop, we:\n", - " - Retrieve and negate the heaviest stone (`y`) from the heap.\n", - " - Retrieve and negate the second heaviest stone (`x`) from the heap.\n", - " \n", - " - Calculate the new stone's weight after smashing (`y - x`), and negate it back to simulate a max heap.\n", - " - Add the new stone back to the heap using `heapq.heappush`.\n", - " \n", - "3. After the loop, if there is one stone left in the heap, we retrieve and negate it to get its actual weight, and return it as the result.\n", - " \n", - "4. If there are no stones left (the heap is empty), we return `0`, indicating that no stones remain.\n", - "\n", - "5. Finally, we provide two test cases to demonstrate the function's usage and correctness.\n", - "\n", - "In summary, the code efficiently implements the stone smashing game by maintaining a max heap, selecting the heaviest stones in each turn, smashing them, and updating the heap until there is at most one stone left. It then returns the weight of the last remaining stone or 0 if there are no stones left." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "stones1 = [2, 7, 4, 1, 8, 1]\n", - "print(lastStoneWeight(stones1)) # Output: 1" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "b7e79514-4821-48d0-bb9d-0f2de8150945", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n" - ] - } - ], - "source": [ - "# Example 2: \n", - "\n", - "stones2 = [1]\n", - "print(lastStoneWeight(stones2)) # Output: 1" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided Python code for the \"Last Stone Weight\" problem:\n", - "\n", - "**Time Complexity:**\n", - "1. The `heapq.heapify` operation to create the max heap from the input stone weights has a time complexity of O(n), where n is the number of stones.\n", - "\n", - "2. The loop that continues until there are more than 1 stone in the heap performs the following operations in each iteration:\n", - " - Retrieving and negating the heaviest stone (`y`) from the heap, which takes O(log n) time.\n", - " - Retrieving and negating the second heaviest stone (`x`) from the heap, also taking O(log n) time.\n", - " - Calculating the new stone's weight and pushing it back into the heap using `heapq.heappush`, which takes O(log n) time.\n", - "\n", - "3. In the worst case, the loop runs until there is only one stone left, which requires approximately (n-1) iterations.\n", - "\n", - "Overall, the dominant time complexity is O(n) for the initial heap creation, and within the loop, each iteration takes O(log n) time. Therefore, the overall time complexity of the algorithm is O(n log n).\n", - "\n", - "**Space Complexity:**\n", - "1. The space complexity is primarily determined by the space required for the max heap. In the worst case, this heap can contain all the stones, so the space complexity for the heap is O(n).\n", - "\n", - "2. The rest of the variables used in the function (e.g., `x`, `y`, `new_stone`) require only constant space, so they do not significantly contribute to the space complexity.\n", - "\n", - "Therefore, the overall space complexity of the algorithm is O(n) due to the space used for the max heap.\n", - "\n", - "In summary:\n", - "- Time Complexity: $O(n\\ log\\ n)$\n", - "- Space Complexity: $O(n)$\n", - "\n", - "The algorithm is efficient enough to handle the problem's constraints, as the worst-case time and space complexities are both linearithmic in terms of the number of stones." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Kth Last Stone Weight**: Modify the problem to find the weight of the Kth last remaining stone, where K is an integer input. Your function should work efficiently for large values of K.\n", - "\n", - "\n", - "2. **Multiple Stones Smash**: Modify the problem so that instead of smashing two stones at a time, you can smash up to K stones at each turn, where K is an integer input. Determine the weight of the last remaining stone in this variation." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/09. Heap - Priority Queue/295. Find Median from Data Stream.ipynb b/docs/_build/html/_sources/09. Heap - Priority Queue/295. Find Median from Data Stream.ipynb deleted file mode 100644 index 847dd60..0000000 --- a/docs/_build/html/_sources/09. Heap - Priority Queue/295. Find Median from Data Stream.ipynb +++ /dev/null @@ -1,242 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 295. Find Median from Data Stream\n", - "\n", - "**Difficulty:** Hard\n", - "\n", - "**Link to Problem:** [To see the Find Median from Data Stream problem on LeetCode, click here!](https://leetcode.com/problems/find-median-from-data-stream/)\n", - "\n", - "---\n", - "\n", - "The **median** is the middle value in an ordered integer list. If the size of the list is even, there is no middle value, and the median is the mean of the two middle values.\n", - "\n", - "Implement the MedianFinder class:\n", - "\n", - "- `MedianFinder()` initializes the `MedianFinder` object.\n", - "- `void addNum(int num)` adds the integer `num` from the data stream to the data structure.\n", - "- `double findMedian()` returns the median of all elements so far. Answers within $10^{-5}$ of the actual answer will be accepted.\n", - "\n", - "**Constraints:**\n", - "\n", - "- $-10^{5}$ <= `num` <= $10^{5}$\n", - "- There will be at least one element in the data structure before calling `findMedian`.\n", - "- At most $5 * 10^4$ calls will be made to `addNum` and `findMedian`.\n", - "\n", - "**Follow-up:**\n", - "\n", - "1. If all integer numbers from the stream are in the range `[0, 100]`, how would you optimize your solution?\n", - "2. If `99%` of all integer numbers from the stream are in the range `[0, 100]`, how would you optimize your solution?" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem, \"Find Median from Data Stream,\" deals with efficiently computing the median of a sequence of numbers as they are incrementally provided. The median is the middle value in an ordered list of numbers. When the list has an even number of elements, the median is the average of the two middle values.\n", - "\n", - "Here's a breakdown of the problem:\n", - "\n", - "1. **Initialization**: You are asked to implement a `MedianFinder` class that supports the following operations:\n", - "\n", - " - `MedianFinder()`: Initializes the MedianFinder object.\n", - " - `addNum(int num)`: Adds an integer `num` from the data stream to the data structure.\n", - " - `findMedian()`: Returns the median of all elements added to the data structure.\n", - "\n", - "2. **Median Calculation**: The `findMedian` operation should efficiently compute the median, and the result should have a precision of at least $10^{-5}$ (i.e., answers within this range will be considered correct).\n", - "\n", - "3. **Examples**:\n", - " \n", - " - If you add numbers [1, 2], the median should be 1.5 because (1 + 2) / 2 = 1.5.\n", - " - If you add numbers [1, 2, 3], the median should be 2 because it's the middle value.\n", - " \n", - "4. **Constraints**:\n", - "\n", - " - The integers provided in the data stream are in the range from $-10^5$ to $10^5$.\n", - " - There will be at least one element in the data structure before calling `findMedian`.\n", - " - At most, $5 * 10^4$ calls will be made to `addNum` and `findMedian`.\n", - "\n", - "The problem can be solved by using two priority queues (heaps): one max-heap to store the smaller half of the numbers and one min-heap to store the larger half of the numbers. The max-heap ensures that the largest number in the smaller half is at the top, and the min-heap ensures that the smallest number in the larger half is at the top. These heaps are balanced to efficiently find the median when requested.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "import heapq\n", - "\n", - "class MedianFinder:\n", - "\n", - " def __init__(self):\n", - " # Initialize two heaps: a max-heap (small_half) for the smaller half of numbers,\n", - " # and a min-heap (large_half) for the larger half of numbers.\n", - " self.small_half = [] # Max-heap for the smaller half of the numbers\n", - " self.large_half = [] # Min-heap for the larger half of the numbers\n", - "\n", - " def addNum(self, num: int) -> None:\n", - " # Add the number to the appropriate heap based on its value\n", - " if not self.small_half or num <= -self.small_half[0]:\n", - " # If the number is less than or equal to the current maximum in the smaller half,\n", - " # add it to the smaller half (max-heap)\n", - " heapq.heappush(self.small_half, -num)\n", - " else:\n", - " # Otherwise, add it to the larger half (min-heap)\n", - " heapq.heappush(self.large_half, num)\n", - "\n", - " # Balance the heaps if necessary to ensure the size difference is at most 1\n", - " if len(self.small_half) > len(self.large_half) + 1:\n", - " # If the size of the smaller half is more than one greater than the size of the larger half,\n", - " # move the maximum from the smaller half to the larger half to balance them.\n", - " heapq.heappush(self.large_half, -heapq.heappop(self.small_half))\n", - " elif len(self.large_half) > len(self.small_half):\n", - " # If the size of the larger half is greater than the size of the smaller half,\n", - " # move the minimum from the larger half to the smaller half to balance them.\n", - " heapq.heappush(self.small_half, -heapq.heappop(self.large_half))\n", - "\n", - " def findMedian(self) -> float:\n", - " if len(self.small_half) == len(self.large_half):\n", - " # If both halves have the same size, there's an even number of elements,\n", - " # so the median is the average of the top elements in both heaps.\n", - " return (-self.small_half[0] + self.large_half[0]) / 2.0\n", - " else:\n", - " # If the smaller half has more elements, it contains the median (odd number of elements).\n", - " return -self.small_half[0]" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The code defines a `MedianFinder` class for efficiently finding the median of a stream of numbers. It uses two heaps: a max-heap (`small_half`) to store the smaller half of the numbers and a min-heap (`large_half`) to store the larger half. Here's how the code works:\n", - "\n", - "1. The `__init__` method initializes the two heaps.\n", - "\n", - "2. The `addNum` method adds a number to the appropriate heap, ensuring that the heaps remain balanced. It does this by comparing the number to the current maximum in the smaller half and adding it to the appropriate heap. Then, it checks the sizes of the two heaps and rebalances them if necessary.\n", - "\n", - "3. The `findMedian` method calculates and returns the median. If both halves have the same size (even number of elements), it computes the average of the tops of both heaps. If the smaller half has more elements (odd number of elements), it returns the top of the max-heap, which is the median.\n", - "\n", - "In summary, this code efficiently maintains two heaps to divide the elements into smaller and larger halves, allowing for quick median retrieval. It offers a time complexity of O(log N) for adding elements and O(1) for finding the median, where N is the total number of elements processed. The space complexity is O(1) as the space used by the two heaps is independent of the input size." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1.5\n", - "2\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "medianFinder = MedianFinder()\n", - "medianFinder.addNum(1)\n", - "medianFinder.addNum(2)\n", - "print(medianFinder.findMedian()) # Output: 1.5\n", - "medianFinder.addNum(3)\n", - "print(medianFinder.findMedian()) # Output: 2.0\n" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `MedianFinder` class:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. `MedianFinder()` Initialization: This operation has a time complexity of O(1). It simply initializes the two heaps.\n", - "\n", - "2. `addNum(int num)`: The time complexity for adding a number is O(log N), where N is the total number of elements processed so far. This is because, in the worst case, you might need to perform logarithmic operations on the heaps to maintain their balance.\n", - "\n", - "3. `findMedian()`: Finding the median has a time complexity of O(1). It simply involves accessing the tops of the two heaps, which takes constant time.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. `MedianFinder()` Initialization: The space complexity for initialization is O(1). It involves creating two empty heaps, which do not depend on the size of the data stream.\n", - "\n", - "2. `addNum(int num)`: The space complexity for adding a number is also O(1). It involves adding the number to one of the two heaps, which do not significantly affect the overall space complexity.\n", - "\n", - "3. `findMedian()`: The space complexity for finding the median is O(1). It doesn't require any additional data structures that grow with the input size.\n", - "\n", - "In summary, the time complexity of the `addNum` operation is O(log N), and the time complexity of the `findMedian` operation is O(1). The space complexity is O(1) as well, as the space used by the two heaps is independent of the size of the data stream. This solution efficiently maintains and retrieves the median, making it suitable for the given problem constraints." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Generalized kth Element**: Extend the `MedianFinder` class to support finding the kth element in the data stream efficiently. This means finding the kth smallest or kth largest element in the stream.\n", - "\n", - "2. **Sliding Window Median**: Given an array and a sliding window size, find the median within the window as it slides over the array. This is an extension of the problem to a moving window scenario." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.ipynb b/docs/_build/html/_sources/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.ipynb deleted file mode 100644 index 2e1522d..0000000 --- a/docs/_build/html/_sources/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.ipynb +++ /dev/null @@ -1,239 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 703. Kth Largest Element in a Stream\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Kth Largest Element in a Stream problem on LeetCode, click here!](https://leetcode.com/problems/kth-largest-element-in-a-stream/)\n", - "\n", - "---\n", - "Design a class to find the `kth` largest element in a stream. Note that it is the `kth` largest element in the sorted order, not the `kth` distinct element.\n", - "\n", - "Implement the `KthLargest` class with the following methods:\n", - "\n", - "- `KthLargest(int k, int[] nums)`: Initializes the object with the integer `k` and the stream of integers `nums`.\n", - "- `int add(int val)`: Appends the integer `val` to the stream and returns the element representing the `kth` largest element in the stream.\n", - "\n", - "\n", - "**Constraints:**\n", - "\n", - "- 1 <= `k` <= $10^4$\n", - "- 0 <= `nums.length` <= $10^4$\n", - "- $-10^4$ <= `nums[i]` <= $10^4$\n", - "- $-10^4$ <= `val` <= $10^4$\n", - "- At most $10^4$ calls will be made to `add`.\n", - "- It is guaranteed that there will be at least `k` elements in the array when you search for the `kth` element." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem you're trying to solve is to design a class called `KthLargest` that can efficiently find the kth largest element in a stream of integers. You need to support two main operations:\n", - "\n", - "To solve this problem efficiently, you can use a min-heap data structure. Here's how the approach works:\n", - "\n", - "1. Initialize a min-heap to store the k largest elements. Initially, it's empty.\n", - "\n", - "2. In the `__init__` method, populate the min-heap with the first `k` elements from `nums`. This ensures that you have the k largest elements seen so far.\n", - "\n", - "3. Whenever you add a new element to the stream using the `add` method, follow these steps:\n", - " - Add the new element to the min-heap.\n", - " - If the size of the min-heap exceeds `k`, remove the smallest element from the min-heap. This ensures that you always have the k largest elements in the min-heap.\n", - " - The smallest element in the min-heap (the root) will always represent the kth largest element in the stream.\n", - "\n", - "Here's why this approach works efficiently:\n", - "\n", - "- By using a min-heap, you can quickly maintain the k largest elements, and finding the smallest element in the heap (the root) takes constant time.\n", - "\n", - "- When you add a new element, the min-heap's size is kept at most `k`, which ensures that you only track the k largest elements and discard the smaller ones.\n", - "\n", - "- The time complexity for adding an element is O(log k), which is very efficient compared to sorting the entire stream, which would be O(n log n).\n", - "\n", - "- This approach meets the constraints of the problem, including handling large streams and having a low time complexity for both initialization and adding elements.\n", - "\n", - "In summary, the min-heap approach efficiently tracks the kth largest element in the stream by maintaining a heap of the k largest elements seen so far, updating it as new elements are added. This approach provides a fast and scalable solution to the problem.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "import heapq\n", - "from typing import List # Import the List type from the typing module\n", - "\n", - "class KthLargest:\n", - "\n", - " def __init__(self, k: int, nums: List[int]):\n", - " # Initialize the KthLargest object with k and nums.\n", - " self.k = k\n", - " # Create a min-heap to store the k largest elements.\n", - " self.min_heap = []\n", - " # Populate the min-heap with the first k elements from nums.\n", - " for num in nums:\n", - " self.add(num)\n", - "\n", - " def add(self, val: int) -> int:\n", - " # Add val to the min-heap.\n", - " heapq.heappush(self.min_heap, val)\n", - " # If the size of the min-heap exceeds k, remove the smallest element.\n", - " if len(self.min_heap) > self.k:\n", - " heapq.heappop(self.min_heap)\n", - " # The root of the min-heap is the kth largest element.\n", - " return self.min_heap[0]" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "- We start by importing the necessary modules:\n", - " - `heapq`: This module provides functions to create and manipulate heaps.\n", - " - `List` from the `typing` module: This is used to specify the type of the `nums` parameter.\n", - "\n", - "- We define the `KthLargest` class:\n", - " - The `__init__` method initializes the object with the integer `k` and the list of integers `nums`.\n", - " - It also creates an empty min-heap called `self.min_heap` to store the k largest elements.\n", - " - It populates the min-heap with the first `k` elements from `nums` by calling the `add` method.\n", - "\n", - "- The `add` method:\n", - " - Adds the new integer `val` to the min-heap using `heapq.heappush`. This maintains the min-heap property.\n", - " - Checks if the size of the min-heap exceeds `k`. If it does, it removes the smallest element (the k+1th largest) using `heapq.heappop`.\n", - " - Finally, it returns the smallest element in the min-heap, which is always the kth largest element.\n", - "\n", - "Overall, this code implements a class that efficiently finds the kth largest element in a stream of integers by maintaining a min-heap of the k largest elements seen so far.\n" - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n", - "5\n", - "5\n", - "8\n", - "8\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example usage:\n", - "kthLargest = KthLargest(3, [4, 5, 8, 2])\n", - "print(kthLargest.add(3)) # Output: 4\n", - "print(kthLargest.add(5)) # Output: 5\n", - "print(kthLargest.add(10)) # Output: 5\n", - "print(kthLargest.add(9)) # Output: 8\n", - "print(kthLargest.add(4)) # Output: 8" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `KthLargest` class using the min-heap approach:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. `__init__` method:\n", - " - In the `__init__` method, you iterate over the first `k` elements in `nums` and add them to the min-heap. Each `heapq.heappush` operation takes O(log k) time.\n", - " - Therefore, the time complexity of the `__init__` method is O(k * log k).\n", - "\n", - "2. `add` method:\n", - " - In the `add` method, you perform the following operations:\n", - " - `heapq.heappush`: O(log k) to add the new element to the min-heap.\n", - " - If the size of the min-heap exceeds `k`, you perform `heapq.heappop`, which is also O(log k).\n", - " - Finally, you return the smallest element from the min-heap, which is O(1) because it's always the root.\n", - " - Overall, the time complexity of the `add` method is O(log k).\n", - "\n", - "3. Overall, if you make `n` calls to the `add` method, the total time complexity is O(n * log k), where `n` is the total number of elements added to the stream.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. The space complexity is determined by the space used to store the min-heap and the instance variables.\n", - "2. The min-heap stores at most `k` elements at any given time, so its space complexity is O(k).\n", - "3. The instance variables (such as `self.k` and `self.min_heap`) have constant space requirements.\n", - "4. Therefore, the overall space complexity of the `KthLargest` class is O(k).\n", - "\n", - "In summary, the time complexity of the `KthLargest` class is O(n * log k) for `n` add operations, and the space complexity is O(k), where `k` is the parameter passed during initialization. This implementation efficiently maintains the kth largest element in the stream while meeting the problem's constraints." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Dynamic k:** Modify the `KthLargest` class to support dynamic changes in the value of `k`. Implement a method `update_k` that allows changing the value of `k` during the lifetime of the object. Ensure that the object can still correctly find the kth largest element based on the updated value of `k`.\n", - "\n", - "\n", - "2. **Implement kth Smallest:** Create a new class called `KthSmallest` that finds the kth smallest element in a stream instead of the kth largest. You may need to modify the data structure used in the implementation." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/09. Heap - Priority Queue/README.md b/docs/_build/html/_sources/09. Heap - Priority Queue/README.md deleted file mode 100644 index 2eac70c..0000000 --- a/docs/_build/html/_sources/09. Heap - Priority Queue/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# Heap / Priority Queue Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [703. Kth Largest Element in a Stream](https://leetcode.com/problems/kth-largest-element-in-a-stream/) | Easy | -| [1046. Last Stone Weight](https://leetcode.com/problems/last-stone-weight/) | Easy | -| [295. Find Median From Data Stream](https://leetcode.com/problems/find-median-from-data-stream/) | Hard | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! diff --git a/docs/_build/html/_sources/10. Backtracking/39. Combination Sum.ipynb b/docs/_build/html/_sources/10. Backtracking/39. Combination Sum.ipynb deleted file mode 100644 index 228a62e..0000000 --- a/docs/_build/html/_sources/10. Backtracking/39. Combination Sum.ipynb +++ /dev/null @@ -1,282 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 39. Combination Sum\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Combination Sum problem on LeetCode, click here!](https://leetcode.com/problems/combination-sum/)\n", - "\n", - "---\n", - "Given an array of **distinct** integers `candidates` and a target integer `target`, return *a list of all **unique combinations** of `candidates` where the chosen numbers sum to the `target`*. You may return the combinations in **any order**. \n", - "\n", - "The **same** number may be chosen from `candidates` an **unlimited number** of times. Two combinations are unique if the **frequency** of at least one of the chosen numbers is different.\n", - "\n", - "The test cases are generated such that the number of unique combinations that sum up to `target` is less than `150` combinations for the given input.\n", - "\n", - "**Constraints:**\n", - "- `1 <= candidates.length <= 30`\n", - "- `2 <= candidates[i] <= 40`\n", - "- All elements of `candidates` are **distinct**.\n", - "- `1 <= target <= 40`" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is to find all unique combinations of numbers from a given array (candidates) such that their sum equals a target number. Here are the details of the problem:\n", - "\n", - "- You are given an array of distinct integers called \"candidates.\"\n", - "- You are also given a target integer called \"target.\"\n", - "\n", - "The goal is to find all unique combinations of numbers from the candidates array where the sum of the selected numbers is equal to the target. You can use the same number from the candidates array an unlimited number of times. A combination is considered unique if it has a different frequency (i.e., a different number of occurrences) of at least one chosen number compared to other combinations.\n", - "\n", - "For example:\n", - "\n", - "**Example 1:**\n", - "```python\n", - "Input: candidates = [2, 3, 6, 7], target = 7\n", - "Output: [[2, 2, 3], [7]]\n", - "```\n", - "In this example, there are two unique combinations that sum up to the target:\n", - "- 2 + 2 + 3 = 7\n", - "- 7 = 7\n", - "\n", - "**Example 2:**\n", - "```python\n", - "Input: candidates = [2, 3, 5], target = 8\n", - "Output: [[2, 2, 2, 2], [2, 3, 3], [3, 5]]\n", - "```\n", - "Here, there are three unique combinations that sum up to the target.\n", - "\n", - "**Example 3:**\n", - "```python\n", - "Input: candidates = [2], target = 1\n", - "Output: []\n", - "```\n", - "In this case, there are no combinations that can be formed from the candidates to reach the target of 1, so the output is an empty list.\n", - "\n", - "The problem asks you to find and return these combinations in any order.\n", - "\n", - "The constraints for this problem include the length of the candidates array, the values of candidates, and the target value.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def combinationSum(candidates, target):\n", - " # Define a recursive DFS function to find combinations\n", - " def dfs(remaining, start, path):\n", - " # If the remaining target is 0, we found a valid combination\n", - " if remaining == 0:\n", - " result.append(path)\n", - " return\n", - " # If the remaining target is negative, this path is invalid\n", - " if remaining < 0:\n", - " return\n", - " # Iterate through candidates starting from 'start' to avoid duplicates\n", - " for i in range(start, len(candidates)):\n", - " # Explore the current candidate by subtracting it from the remaining target\n", - " # Add the current candidate to the path\n", - " dfs(remaining - candidates[i], i, path + [candidates[i]])\n", - "\n", - " result = [] # Initialize an empty list to store the result\n", - " candidates.sort() # Sort the candidates for deduplication and early stopping\n", - " dfs(target, 0, []) # Start the DFS from the target value with an empty path\n", - " return result # Return the list of unique combinations" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The `combinationSum` function takes an array of distinct integers `candidates` and a target integer `target`. It returns a list of all unique combinations of `candidates` where the chosen numbers sum to the `target`. Each number in the `candidates` array can be used an unlimited number of times.\n", - "\n", - "Here's an overview of how the code works:\n", - "\n", - "1. The `combinationSum` function is defined, and it takes two arguments: `candidates` and `target`.\n", - "\n", - "2. Inside the function, there is a nested helper function called `backtrack`. This function is responsible for the actual combination generation using a recursive approach.\n", - "\n", - "3. The `backtrack` function is called with three arguments: `start`, `target`, and `path`. The `start` variable helps keep track of the current index in the `candidates` array, `target` keeps track of the remaining sum to be achieved, and `path` is a list that stores the current combination.\n", - "\n", - "4. Within the `backtrack` function, there are three main conditional statements:\n", - " - If `target` becomes zero, it means we have found a combination that sums up to the target, so we add `path` to the `result` list.\n", - " - If `target` becomes negative, it means the current combination doesn't work, so we return without doing anything.\n", - " - Otherwise, we enter a loop that iterates over the `candidates` array, starting from the current index `start`.\n", - "\n", - "5. In the loop, the `backtrack` function is called recursively with the updated `target` and `path` after including the current candidate. This process explores different combinations by considering the current candidate or moving to the next candidate.\n", - "\n", - "6. After the loop completes, the `result` list contains all unique combinations that sum to the target.\n", - "\n", - "7. The `candidates` array is sorted to optimize the search. Sorting helps in avoiding unnecessary recursive branches and reduces the number of explored combinations.\n", - "\n", - "8. Finally, the `backtrack` function is initially called from the `combinationSum` function with `start` set to 0, `target` set to the original target value, and an empty `path`. The result is returned as a list of unique combinations.\n", - "\n", - "The code includes a few example cases to demonstrate how the function works with different inputs." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[2, 2, 3], [7]]\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Example 1\n", - "candidates1 = [2, 3, 6, 7]\n", - "target1 = 7\n", - "print(combinationSum(candidates1, target1)) # Output: [[2, 2, 3], [7]]" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[2, 2, 2, 2], [2, 3, 3], [3, 5]]\n" - ] - } - ], - "source": [ - "# Example 2\n", - "candidates2 = [2, 3, 5]\n", - "target2 = 8\n", - "print(combinationSum(candidates2, target2)) # Output: [[2, 2, 2, 2], [2, 3, 3], [3, 5]]" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "b5fca8ab-8c98-45b1-b44b-0503309121c9", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[]\n" - ] - } - ], - "source": [ - "# Example 3\n", - "candidates3 = [2]\n", - "target3 = 1\n", - "print(combinationSum(candidates3, target3)) # Output: []" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `combinationSum` function.\n", - "\n", - "**Time Complexity:**\n", - "The time complexity of this function is influenced by the number of recursive calls made by the `backtrack` function and the amount of work done within each call. In the worst case, the function will explore all possible combinations.\n", - "\n", - "The worst-case scenario occurs when we have many combinations to reach the target. The time complexity can be expressed as $O(2^n)$, where 'n' is the maximum number of recursive calls. In this context, 'n' corresponds to the number of elements in the `candidates` list, and it may be up to 30 (as per the constraints). However, the actual number of combinations explored is generally much smaller because we eliminate branches when the target becomes negative, and we skip over candidates that cannot lead to a solution. The sorting step also helps to optimize the search.\n", - "\n", - "**Space Complexity:**\n", - "The space complexity is determined by the auxiliary space used for storing the results and the stack space for the recursive calls.\n", - "\n", - "1. The space required for the `result` list can be up to $O(2^n)$ in the worst case because each combination is stored.\n", - "\n", - "2. The stack space for the recursive calls can also be up to O(n) in the worst case, where 'n' is the number of elements in the `candidates` list.\n", - "\n", - "Therefore, the overall space complexity of the function is $O(2^n + n)$. However, in practice, the space used for the results list is often the dominant factor, and the actual space used may be much smaller than 2^n because not all combinations are explored.\n", - "\n", - "In summary, the time complexity is exponential but typically smaller in practice due to optimization, and the space complexity is influenced by the number of results and the depth of the recursion." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Find the Number of Unique Combinations:** Instead of listing all unique combinations, modify the function to return the count of unique combinations that sum to the target.\n", - "\n", - "2. **Combinations with a Maximum Value:** Add a maximum value constraint for each combination, so they cannot exceed a certain value. Modify the code to find combinations respecting this constraint." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/10. Backtracking/79. Word Search.ipynb b/docs/_build/html/_sources/10. Backtracking/79. Word Search.ipynb deleted file mode 100644 index cee509b..0000000 --- a/docs/_build/html/_sources/10. Backtracking/79. Word Search.ipynb +++ /dev/null @@ -1,298 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 79. Word Search\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Word Search problem on LeetCode, click here!](https://leetcode.com/problems/word-search/)\n", - "\n", - "---\n", - "Given an `m x n` grid of characters `board` and a string `word`, return *`true` if `word` exists in the grid.*\n", - "\n", - "The word can be constructed from letters of sequentially adjacent cells, where adjacent cells are horizontally or vertically neighboring. The same letter cell may not be used more than once.\n", - "\n", - "**Constraints:**\n", - "- `m == board.length`\n", - "- `n = board[i].length`\n", - "- `1 <= m, n <= 6`\n", - "- `1 <= word.length <= 15`\n", - "- `board` and `word` consists of only lowercase and uppercase English letters.\n", - "\n", - "**Follow up:** Could you use search pruning to make your solution faster with a larger `board`?" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is to determine whether a given word can be constructed from characters in an `m x n` grid of characters. The word can be formed by moving sequentially through horizontally or vertically neighboring cells in the grid, and you cannot use the same cell more than once.\n", - "\n", - "Here are the specifics of the problem:\n", - "\n", - "- You are given an `m x n` grid, which is a 2D board of characters.\n", - "- You are also given a string `word` consisting of lowercase and uppercase English letters.\n", - "- Your task is to determine if the word can be found in the grid by moving from one cell to an adjacent cell (horizontally or vertically) and collecting the characters sequentially to form the word.\n", - "- You can't use the same cell more than once when forming the word.\n", - "- If it's possible to form the word in the grid, return `True`; otherwise, return `False`.\n", - "\n", - "For example, consider the following grid and word:\n", - "\n", - "```python\n", - "board = [[\"A\", \"B\", \"C\", \"E\"],\n", - " [\"S\", \"F\", \"C\", \"S\"],\n", - " [\"A\", \"D\", \"E\", \"E\"]] \n", - "word = \"ABCCED\"\n", - "```\n", - "\n", - "In this case, the word \"ABCCED\" can be formed by moving through the cells (0,0) -> (0,1) -> (0,2) -> (1,2) -> (2,2) -> (2,3) in the grid. Therefore, the function should return `True`.\n", - "\n", - "Conversely, if the word is impossible to construct, such as in the case of the word \"ABCB\" for the same grid, where there's no valid path that forms the word, the function should return `False`.\n", - "\n", - "The problem involves searching for a path through the grid that matches the characters in the word while respecting the constraints mentioned. It can be solved using depth-first search (DFS) or backtracking.\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "from typing import List\n", - "\n", - "class Solution:\n", - " def exist(self, board: List[List[str]], word: str) -> bool:\n", - " def dfs(i, j, k):\n", - " # Check if the current position is out of bounds or doesn't match the character in the word.\n", - " if not (0 <= i < len(board)) or not (0 <= j < len(board[0])) or board[i][j] != word[k]:\n", - " return False\n", - " \n", - " # If we have matched all characters in the word, return True.\n", - " if k == len(word) - 1:\n", - " return True\n", - "\n", - " # Temporarily mark the current cell to prevent revisiting.\n", - " tmp, board[i][j] = board[i][j], \"/\"\n", - "\n", - " # Explore adjacent cells by making recursive calls in all four directions.\n", - " found = dfs(i + 1, j, k + 1) or dfs(i - 1, j, k + 1) or dfs(i, j + 1, k + 1) or dfs(i, j - 1, k + 1)\n", - "\n", - " # Restore the original character in the cell.\n", - " board[i][j] = tmp\n", - "\n", - " return found\n", - "\n", - " # Iterate through all cells in the board.\n", - " for i in range(len(board)):\n", - " for j in range(len(board[0])):\n", - " # Check if the 'dfs' function starting from this cell returns True.\n", - " if dfs(i, j, 0):\n", - " return True\n", - "\n", - " # If no match is found after exploring all cells, return False.\n", - " return False" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "1. Import the necessary module:\n", - " - `from typing import List`: This line imports the `List` type from the `typing` module, which is used to specify the type of the `board` parameter in the method signature.\n", - "\n", - "2. Define the `Solution` class:\n", - " - `class Solution:`: This line defines a class called `Solution` to encapsulate the solution for the word search problem.\n", - "\n", - "3. Define the `exist` method:\n", - " - `def exist(self, board: List[List[str]], word: str) -> bool:`: This method is a member of the `Solution` class and takes two parameters: `board`, which is a 2D list of characters, and `word`, which is a string. It returns a boolean value, indicating whether the word exists in the board.\n", - "\n", - "4. Implement the inner `dfs` function:\n", - " - `def dfs(i, j, k):`: This is a helper function used for depth-first search (DFS). It is called recursively to explore the board and search for the word. It takes three parameters: `i` and `j` representing the current position on the board, and `k` representing the current index in the `word` string.\n", - "\n", - " - Inside `dfs`, it checks if the current position is out of bounds or if the character at the current position on the board does not match the character at the current index in the `word`. If either of these conditions is met, it returns `False`.\n", - "\n", - " - If `k` is equal to the length of the `word` minus one, it means we have successfully matched all characters in the `word`, so it returns `True`.\n", - "\n", - " - The function then temporarily replaces the character at the current position with a marker, \"/\", to prevent revisiting the same cell. It then explores adjacent cells by making recursive calls in all four directions: up, down, left, and right. If any of these recursive calls return `True`, it propagates the `True` result up the call stack. After the exploration is complete, it restores the original character in the cell.\n", - "\n", - "5. Iterate through the board:\n", - " - The outer loop iterates through all cells in the `board` using two nested loops. For each cell, it checks if the `dfs` function starting from that cell (with `k` initially set to 0) returns `True`. If it does, it means the word exists, so the method returns `True`.\n", - "\n", - "6. Return `False`:\n", - " - If the loop completes without finding the word in the board, the method returns `False`.\n", - "\n", - "To use this code, you can create an instance of the `Solution` class and call the `exist` method on that instance, passing the `board` and the `word` as arguments to check if the word exists in the board." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1: \n", - "\n", - "# Create an instance of the Solution class\n", - "solution = Solution()\n", - "\n", - "# Test case 1: Word \"ABCCED\" can be found in the grid\n", - "board1 = [[\"A\",\"B\",\"C\",\"E\"],\n", - " [\"S\",\"F\",\"C\",\"S\"],\n", - " [\"A\",\"D\",\"E\",\"E\"]]\n", - "word1 = \"ABCCED\"\n", - "print(solution.exist(board1, word1)) # Expected output: True" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 2\n", - "\n", - "# Test case 2: Word \"SEE\" can be found in the grid\n", - "word2 = \"SEE\"\n", - "print(solution.exist(board1, word2)) # Expected output: True" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "b5fca8ab-8c98-45b1-b44b-0503309121c9", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 3\n", - "\n", - "# Test case 3: Word \"ABCB\" cannot be found in the grid\n", - "word3 = \"ABCB\"\n", - "print(solution.exist(board1, word3)) # Expected output: False" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `exist` method in the given code.\n", - "\n", - "**Time Complexity:**\n", - "\n", - "The primary work in this code is done by the `dfs` function, which performs a depth-first search through the grid. The time complexity of the `dfs` function is $O(4^(n))$, where \"n\" is the length of the `word`. This is because, in the worst case, the function explores all possible directions (up, down, left, right) for each character in the `word`.\n", - "\n", - "The outer loops iterate through all cells in the `board`, which has dimensions `m x n`. So, the total number of iterations of `dfs` is O(m * n). However, since the `dfs` function has a higher time complexity, the overall time complexity is still dominated by the `dfs` function.\n", - "\n", - "Therefore, the overall time complexity of the `exist` method is $O(m * n * 4^n)$, where \"m\" and \"n\" are the dimensions of the board, and \"n\" is the length of the word.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. The primary space usage comes from the recursive calls in the `dfs` function. The depth of the recursion can be at most equal to the length of the `word`, which is O(n).\n", - "\n", - "2. Additionally, the `tmp` variable and the recursive calls on the call stack consume a small amount of additional memory.\n", - "\n", - "3. The marking of visited cells with the \"/\" character temporarily modifies the `board` in-place but doesn't significantly contribute to the space complexity.\n", - "\n", - "Therefore, the overall space complexity is O(n) due to the recursive call stack.\n", - "\n", - "In summary, the time complexity is $O(m * n * 4^n)$, and the space complexity is O(n), where \"m\" and \"n\" are the dimensions of the board, and \"n\" is the length of the word. The time complexity is exponential in the worst case due to the depth-first search through all possible paths in the grid." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Optimization Challenge:** Modify the code to find all unique words that can be constructed from the grid. Instead of returning `True` or `False`, return a list of words found. Ensure that the same cell is not used more than once in constructing each word.\n", - "\n", - "2. **Board Generation:** Create a function to generate random grids of characters and then use the `exist` method to solve them. Test the efficiency and correctness of your code by generating larger boards and words." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/10. Backtracking/README.md b/docs/_build/html/_sources/10. Backtracking/README.md deleted file mode 100644 index 0d1ea13..0000000 --- a/docs/_build/html/_sources/10. Backtracking/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Backtracking Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [39. Combination Sum](https://leetcode.com/problems/combination-sum/) | Medium | -| [79. Word Search](https://leetcode.com/problems/word-search/) | Medium | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! \ No newline at end of file diff --git a/docs/_build/html/_sources/11. Graphs/133. Clone Graph.ipynb b/docs/_build/html/_sources/11. Graphs/133. Clone Graph.ipynb deleted file mode 100644 index 07351b6..0000000 --- a/docs/_build/html/_sources/11. Graphs/133. Clone Graph.ipynb +++ /dev/null @@ -1,317 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 133. Clone Graph\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Clone Graph problem on LeetCode, click here!](https://leetcode.com/problems/clone-graph/)\n", - "\n", - "---\n", - "Given a reference of a node in a **connected** undirected graph.\n", - "\n", - "Return a **deep copy** (clone) of the graph.\n", - "\n", - "Each node in the graph contains a value (`int`) and a list (`List[Node]`) of its neighbors.\n", - "\n", - "```\n", - "class Node {\n", - " public int val;\n", - " public List neighbors;\n", - "}\n", - "```\n", - "\n", - "**Test case format:**\n", - "\n", - "For simplicity, each node's value is the same as the node's index (1-indexed). For example, the first node with `val == 1`, the second node with `val == 2`, and so on. The graph is represented in the test case using an adjacency list.\n", - "\n", - "**An adjacency list** is a collection of unordered **lists** used to represent a finite graph. Each list describes the set of neighbors of a node in the graph.\n", - "\n", - "The given node will always be the first node with `val = 1`. You must return the **copy of the given node** as a reference to the cloned graph.\n", - "\n", - "**Constraints:**\n", - "- The number of nodes in the graph is in the range `[0, 100]`.\n", - "- `1 <= Node.val <= 100`\n", - "- `Node.val` is unique for each node.\n", - "- There are no repeated edges and no self-loops in the graph.\n", - "- The Graph is connected and all nodes can be visited starting from the given node." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem at hand is to clone a connected undirected graph, which means we need to create a deep copy of the original graph while preserving its structure and relationships between nodes. The graph is represented using adjacency lists, where each node has a value (an integer) and a list of its neighbors.\n", - "\n", - "Here are the key aspects of the problem:\n", - "\n", - "1. **Input**: You are given a reference to one of the nodes in the original graph. This reference node serves as the entry point to the graph. The entire graph can be explored starting from this node.\n", - "\n", - "2. **Output**: The goal is to create a deep copy of the graph and return a reference to the cloned graph. The cloned graph should have the same structure and relationships as the original one but should be a separate instance in memory.\n", - "\n", - "3. **Graph Structure**: The graph is composed of nodes (vertices) and edges. Nodes have values (integers) and are connected to other nodes through edges (undirected connections). Each node has a list of neighbors, which are other nodes it is connected to.\n", - "\n", - "4. **Connected Graph**: The problem assumes that the graph is connected, meaning that you can start from the reference node provided and traverse the entire graph by following the edges. This ensures that there are no isolated components in the graph.\n", - "\n", - "To solve this problem, you typically need to perform a graph traversal (e.g., depth-first search or breadth-first search) to visit all the nodes in the original graph, create corresponding nodes in the clone, and establish the same connections between nodes in the cloned graph as in the original one. To avoid duplication of nodes, you also need to keep track of visited nodes to ensure that the cloning process is efficient and that nodes are not duplicated in the clone.\n", - "\n", - "The problem can be challenging because you need to create a deep copy of the graph while handling cyclic dependencies between nodes and ensuring that the structure and relationships of the original graph are preserved in the clone. The solution requires recursion or a data structure to maintain the mapping between original nodes and their clones to achieve an efficient and accurate cloning process.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "# Definition for a Node.\n", - "class Node:\n", - " def __init__(self, val=0, neighbors=None):\n", - " self.val = val\n", - " self.neighbors = neighbors if neighbors is not None else []\n", - "\n", - "class Solution:\n", - " def cloneGraph(self, node: 'Node') -> 'Node':\n", - " if not node:\n", - " return None\n", - "\n", - " visited = {} # Dictionary to keep track of visited nodes\n", - "\n", - " def dfs(original_node):\n", - " if original_node in visited:\n", - " return visited[original_node]\n", - "\n", - " # Create a copy of the original node\n", - " copy_node = Node(original_node.val)\n", - " visited[original_node] = copy_node\n", - "\n", - " # Recursively clone the neighbors of the original node\n", - " for neighbor in original_node.neighbors:\n", - " copy_node.neighbors.append(dfs(neighbor))\n", - "\n", - " return copy_node\n", - "\n", - " return dfs(node)" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The given code defines a Python class, `Node`, and a solution class, `Solution`, to clone a connected undirected graph represented by nodes and their neighbors. Here's an explanation of the code:\n", - "\n", - "1. The `Node` class defines a node in the graph. Each node has a value (`val`) which is an integer and a list of neighbors (`neighbors`) that are other nodes in the graph.\n", - "\n", - "2. The `Solution` class contains the method `cloneGraph`, which takes a reference to the first node of the graph (`node`) as input and returns a deep copy of the entire graph, preserving the structure and relationships between nodes.\n", - "\n", - "3. Inside the `cloneGraph` method:\n", - " - It first checks if the input `node` is `None`. If it's `None`, it means there is no graph to clone, and the method returns `None`.\n", - "\n", - " - It initializes a `visited` dictionary to keep track of visited nodes. This dictionary is used to ensure that each node is cloned only once to avoid duplication.\n", - "\n", - " - The `dfs` (depth-first search) function is defined within the `cloneGraph` method. It takes an original node as input and returns its corresponding clone. This function performs the actual cloning of the graph.\n", - "\n", - " - Inside the `dfs` function:\n", - " - It checks if the original node has been visited before by looking it up in the `visited` dictionary. If it has been visited, it returns the corresponding clone from the `visited` dictionary.\n", - "\n", - " - If the original node is not visited, it creates a new node, `copy_node`, with the same value as the original node. This is the first step in creating the clone of the original node.\n", - "\n", - " - It then recursively clones the neighbors of the original node by iterating through the `neighbors` list of the original node and appending the corresponding cloned neighbors to the `neighbors` list of the `copy_node`. This step ensures that the relationships between nodes are preserved in the clone.\n", - "\n", - " - The `copy_node` is added to the `visited` dictionary with the original node as the key and the clone as the value.\n", - "\n", - " - Finally, the `copy_node` is returned as the result of the DFS for the original node.\n", - "\n", - "4. The `cloneGraph` method returns the result of the DFS on the input `node`, which is the clone of the entire graph with its structure and relationships intact.\n", - "\n", - "In summary, the code uses depth-first search (DFS) to traverse the original graph, creating a clone for each node and its neighbors. It ensures that each node is cloned only once to avoid duplication and returns a reference to the cloned graph." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "f12c5a63-b811-4be7-83c2-34ee396b546c", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[1, 2, 4]]\n" - ] - } - ], - "source": [ - "def get_adjacency_list(node):\n", - " visited = {} # Dictionary to keep track of visited nodes\n", - "\n", - " def dfs(node):\n", - " if not node:\n", - " return []\n", - "\n", - " if node in visited:\n", - " return visited[node]\n", - "\n", - " neighbors = [n.val for n in node.neighbors]\n", - " visited[node] = neighbors\n", - "\n", - " for neighbor in node.neighbors:\n", - " dfs(neighbor)\n", - "\n", - " dfs(node)\n", - " result = []\n", - "\n", - " def get_node_and_neighbors(node):\n", - " result.append([node.val] + visited[node])\n", - "\n", - " get_node_and_neighbors(node)\n", - " return result\n", - "\n", - "\n", - "# Testing the code with the provided examples\n", - "adjList1 = [[2, 4], [1, 3], [2, 4], [1, 3]]\n", - "solution = Solution()\n", - "\n", - "# Create the graph from adjList\n", - "nodes = [Node(i) for i in range(1, len(adjList1) + 1)]\n", - "for i, adj in enumerate(adjList1):\n", - " nodes[i].neighbors = [nodes[j - 1] for j in adj]\n", - "\n", - "# Clone the graph and get its adjacency list\n", - "cloned_node1 = solution.cloneGraph(nodes[0])\n", - "cloned_adjList1 = get_adjacency_list(cloned_node1)\n", - "\n", - "# Print the cloned graph as an adjacency list\n", - "print(cloned_adjList1)\n", - "\n", - "# Output should match adjList1\n" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[1]]\n" - ] - } - ], - "source": [ - "# Example 2\n", - "# Input: adjList = [[]]\n", - "\n", - "adjList2 = [[]]\n", - "solution = Solution()\n", - "\n", - "# Create the graph from adjList\n", - "node1 = Node(1)\n", - "\n", - "# Clone the graph and get its adjacency list\n", - "cloned_node1 = solution.cloneGraph(node1)\n", - "cloned_adjList2 = get_adjacency_list(cloned_node1)\n", - "\n", - "# Print the cloned graph as an adjacency list\n", - "print(cloned_adjList2)\n", - "\n", - "# Output should be [[]], which represents an empty graph" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code for cloning a graph using depth-first search (DFS).\n", - "\n", - "Time Complexity:\n", - "1. Creating the graph: The time complexity to create the original graph from `adjList` is O(V + E), where V is the number of vertices (nodes) and E is the number of edges. We iterate through each node and its neighbors in `adjList`.\n", - "\n", - "2. Cloning the graph (DFS): The depth-first search (DFS) is used to traverse the original graph and create a clone. The time complexity of DFS is O(V + E), as we visit each node and each edge once.\n", - "\n", - "Overall, the time complexity is O(V + E) for both creating the original graph and cloning it.\n", - "\n", - "Space Complexity:\n", - "1. Storage for the original graph: We need to store the original graph, which includes all nodes and their adjacency lists. In the worst case, this requires O(V + E) space, where V is the number of nodes, and E is the number of edges.\n", - "\n", - "2. Storage for the visited dictionary: The `visited` dictionary stores mappings from original nodes to their corresponding clones. In the worst case, this requires O(V) space because each node is visited once.\n", - "\n", - "3. Recursive stack for DFS: The space used for the recursive call stack during DFS can be up to O(V) in the worst case, where V is the number of nodes.\n", - "\n", - "Overall, the space complexity is O(V + E) for storing the original graph, and O(V) for auxiliary data structures, including the `visited` dictionary and the DFS call stack. Therefore, the overall space complexity is O(V + E).\n", - "\n", - "In summary, the time and space complexities of the provided code for cloning a graph are both O(V + E), where V is the number of nodes, and E is the number of edges in the graph." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Cyclic Graph**: Design a graph with cycles (nodes connected in a cycle). Test if the code can correctly clone graphs with cycles and doesn't fall into an infinite loop during traversal.\n", - "\n", - "\n", - "2. **Partial Graph Cloning**: Modify the code to clone only a subset of the graph starting from a given reference node, rather than the entire graph. Implement this as an extension to the problem." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/11. Graphs/178. Graph Valid Tree.ipynb b/docs/_build/html/_sources/11. Graphs/178. Graph Valid Tree.ipynb deleted file mode 100644 index e0235d6..0000000 --- a/docs/_build/html/_sources/11. Graphs/178. Graph Valid Tree.ipynb +++ /dev/null @@ -1,248 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 178. Graph Valid Tree\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Graph Valid Tree problem on LintCode, click here!](https://www.lintcode.com/problem/178/)\n", - "\n", - "---\n", - "Given `n` nodes labeled from `0` to `n - 1` and a list of `undirected` edges (each edge is a pair of nodes), write a function to check whether these edges make up a valid tree.\n", - "\n", - "**Constraints:**\n", - "- You can assume that no duplicate edges will appear in edges. Since all edges are `undirected`, `[0, 1]` is the same as `[1, 0]` and thus will not appear together in edges." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is to determine whether a given set of undirected edges can form a valid tree. In this context, a \"tree\" is a specific type of graph with the following properties:\n", - "\n", - "1. It is a connected graph, meaning there is a path between any pair of nodes in the graph.\n", - "2. It has no cycles, which means there are no closed loops or circuits in the graph.\n", - "3. It has exactly `n - 1` edges, where `n` is the number of nodes in the tree.\n", - "\n", - "The problem is typically given with two pieces of information:\n", - "\n", - "1. The number of nodes (`n`), which are usually labeled from 0 to `n-1`.\n", - "2. A list of undirected edges, where each edge is represented as a pair of nodes.\n", - "\n", - "The task is to write a function or algorithm to determine whether the provided set of edges can be arranged to form a valid tree based on the properties mentioned above.\n", - "\n", - "To solve this problem, you need to check the following conditions:\n", - "\n", - "1. There should be exactly `n - 1` edges to ensure that the graph is connected and tree-like.\n", - "2. There should be no cycles in the graph. If there are any cycles, the set of edges cannot form a tree.\n", - "3. The graph should be connected, which means you can reach any node from any other node through a series of edges.\n", - "\n", - "The solution typically involves using graph traversal algorithms like Depth-First Search (DFS) or Breadth-First Search (BFS) to explore the graph and check these conditions. If all conditions are met, the given edges form a valid tree; otherwise, they do not.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def validTree(n, edges):\n", - " if len(edges) != n - 1:\n", - " return False # A tree with n nodes must have n-1 edges.\n", - "\n", - " # Create an adjacency list to represent the graph.\n", - " adj_list = {i: [] for i in range(n)}\n", - " for u, v in edges:\n", - " adj_list[u].append(v)\n", - " adj_list[v].append(u)\n", - "\n", - " visited = set()\n", - "\n", - " # Define a recursive DFS function.\n", - " def dfs(node, parent):\n", - " if node in visited:\n", - " return False # If we encounter a visited node, there's a cycle.\n", - " visited.add(node)\n", - "\n", - " for neighbor in adj_list[node]:\n", - " if neighbor != parent:\n", - " if not dfs(neighbor, node):\n", - " return False\n", - "\n", - " return True\n", - "\n", - " # Start DFS from any node (e.g., node 0).\n", - " if not dfs(0, -1):\n", - " return False # If there's a cycle, it's not a valid tree.\n", - "\n", - " return len(visited) == n" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The `validTree` function checks if a given set of undirected edges forms a valid tree. A valid tree must satisfy these conditions:\n", - "\n", - "1. It has exactly `n - 1` edges, where `n` is the number of nodes.\n", - "2. There are no cycles in the graph.\n", - "3. The graph is connected, meaning all nodes are reachable from any starting node.\n", - "\n", - "The code accomplishes this as follows:\n", - "\n", - "- It first checks if the number of edges is equal to `n - 1`. If not, it immediately returns `False` since a tree with `n` nodes must have `n - 1` edges to be connected.\n", - "\n", - "- It then constructs an adjacency list (`adj_list`) to represent the graph efficiently. This data structure stores the neighbors of each node.\n", - "\n", - "- The code uses a `visited` set to keep track of nodes visited during depth-first search (DFS).\n", - "\n", - "- The `dfs` function is a recursive function that checks for cycles in the graph. It does this by visiting nodes and marking them as visited. If it encounters a node that has already been visited (indicating a cycle), it returns `False`.\n", - "\n", - "- The DFS function explores the neighbors of each node, avoiding revisiting the parent node to prevent cycles.\n", - "\n", - "- After the DFS is complete, the code checks if the number of visited nodes is equal to `n`, ensuring the graph is connected.\n", - "\n", - "- Finally, if all conditions are met, the code returns `True`, indicating that the given edges form a valid tree. Otherwise, it returns `False`.\n", - "\n", - "The code provides examples to demonstrate how to use the `validTree` function to check whether a set of edges forms a valid tree or not." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1\n", - "n1 = 5\n", - "edges1 = [[0, 1], [0, 2], [0, 3], [1, 4]]\n", - "print(validTree(n1, edges1)) # Output: true" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 2\n", - "n2 = 5\n", - "edges2 = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]]\n", - "print(validTree(n2, edges2)) # Output: false" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexities of the `validTree` function:\n", - "\n", - "**Time Complexity:**\n", - "1. Constructing the adjacency list (`adj_list`) takes O(E) time, where E is the number of edges in the input graph (|edges|).\n", - "\n", - "2. The DFS function, when considering all nodes, has a time complexity of O(V + E), where V is the number of nodes in the graph. This is because, in the worst case, the DFS function visits each node and each edge once.\n", - "\n", - "3. Checking if the number of visited nodes is equal to `n` takes O(1) time.\n", - "\n", - "Overall, the time complexity of the `validTree` function is O(E + V) in the worst case.\n", - "\n", - "**Space Complexity:**\n", - "1. The adjacency list (`adj_list`) consumes additional space to store the graph structure, taking O(V + E) space. This is because it stores information about each node and its adjacent nodes.\n", - "\n", - "2. The `visited` set keeps track of visited nodes, and its space complexity is O(V) in the worst case, as there can be at most V unique nodes in the set.\n", - "\n", - "3. The depth of the function call stack during DFS can be at most V, which contributes O(V) space to the space complexity.\n", - "\n", - "Overall, the space complexity of the `validTree` function is O(V + E) due to the adjacency list and O(V) due to the `visited` set and DFS call stack.\n", - "\n", - "In summary, the time complexity is O(E + V), and the space complexity is O(V + E). These complexities are based on the worst-case scenario, where all nodes and edges are considered. In practical cases, the actual complexities may be smaller, depending on the specific structure of the graph." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Minimum Spanning Tree (MST)**: Implement an algorithm to find the minimum spanning tree of a connected graph using either Kruskal's or Prim's algorithm. Compare the MST to the original graph to determine if the original graph is a tree. This exercise reinforces the concept of tree properties.\n", - "\n", - "2. **Detecting Cycles**: Modify the code to not only check if the input forms a tree but also to identify and print out any cycles present in the graph if it's not a tree. This exercise enhances your ability to detect and visualize cycles in a graph." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/11. Graphs/200. Number of Islands.ipynb b/docs/_build/html/_sources/11. Graphs/200. Number of Islands.ipynb deleted file mode 100644 index a8a7727..0000000 --- a/docs/_build/html/_sources/11. Graphs/200. Number of Islands.ipynb +++ /dev/null @@ -1,242 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 200. Number of Islands\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Number of Islands problem on LeetCode, click here!](https://leetcode.com/problems/number-of-islands/)\n", - "\n", - "---\n", - "\n", - "Given an `m x n` 2D binary grid `grid` which represents a map of `'1'`s (land) and `'0'`s (water), return *the number of islands*. \n", - "\n", - "An **island** is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.\n", - "\n", - "**Constraints:**\n", - "- `m == grid.length`\n", - "- `n == grid[i].length`\n", - "- `1 <= m, n <= 300`\n", - "- `grid[i][j]` is `'0'` or `'1'`." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is about counting the number of islands in a 2D binary grid. In this grid, '1' represents land, and '0' represents water. An island is defined as a group of '1' cells that are adjacent to each other either horizontally or vertically. It's important to note that diagonal connections do not count. Additionally, it's assumed that all four edges of the grid are surrounded by water, meaning the grid is finite and doesn't \"wrap around.\"\n", - "\n", - "The objective is to determine how many distinct islands exist in the grid. To clarify, an island consists of connected '1' cells, and these connections can only occur horizontally or vertically. If there are no '1' cells in the grid, the number of islands would be zero.\n", - "\n", - "The problem often involves using graph traversal techniques like Depth-First Search (DFS) or Breadth-First Search (BFS) to identify and count these islands. You start at one '1' cell and explore its adjacent cells to determine the extent of the island. Once you've visited all the '1' cells in an island, you move on to the next unvisited '1' cell and repeat the process until you've counted all the islands in the grid.\n", - "\n", - "In essence, the problem asks you to analyze the grid to find groups of connected '1' cells and count them as individual islands. The goal is to return the total count of islands in the given grid.\n", - "\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "from typing import List\n", - "\n", - "class Solution:\n", - " def numIslands(self, grid: List[List[str]]) -> int:\n", - " if not grid:\n", - " return 0\n", - "\n", - " m, n = len(grid), len(grid[0]) # Get the dimensions of the grid\n", - " num_islands = 0 # Initialize the count of islands\n", - "\n", - " def dfs(row, col):\n", - " if row < 0 or row >= m or col < 0 or col >= n or grid[row][col] == '0':\n", - " return\n", - "\n", - " grid[row][col] = '0' # Mark the current cell as visited by changing it to '0'\n", - " directions = [(1, 0), (-1, 0), (0, 1), (0, -1)] # Define four possible directions to move\n", - "\n", - " for dr, dc in directions:\n", - " # Explore adjacent cells\n", - " dfs(row + dr, col + dc)\n", - "\n", - " for i in range(m):\n", - " for j in range(n):\n", - " if grid[i][j] == '1':\n", - " num_islands += 1 # Increment the island count\n", - " dfs(i, j) # Start a DFS from the current '1' cell to explore the entire island\n", - "\n", - " return num_islands\n" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The provided code defines a Python class called `Solution` with a method called `numIslands`. This class is designed to count the number of islands in a 2D binary grid.\n", - "\n", - "The `numIslands` method takes a 2D grid as input, where '1' represents land, and '0' represents water. It uses a depth-first search (DFS) approach to identify and count islands. The key steps in the code include:\n", - "\n", - "1. Checking if the input grid is empty, and if so, returning 0 (indicating there are no islands).\n", - "\n", - "2. Determining the dimensions of the grid (number of rows and columns).\n", - "\n", - "3. Initializing a variable `num_islands` to keep track of the count of islands.\n", - "\n", - "4. Defining a nested function `dfs` to perform depth-first search. This function recursively explores adjacent land cells connected to the current cell and marks them as visited by changing '1' to '0'.\n", - "\n", - "5. In the `dfs` function, it checks for boundary conditions and whether the current cell is '0'. If these conditions are met, it returns without further exploration.\n", - "\n", - "6. The `dfs` function explores neighboring cells in all four directions (up, down, left, right) using a loop.\n", - "\n", - "7. The main loop iterates through each cell of the grid. When a '1' cell is encountered, it increments the `num_islands` count and starts a DFS from that cell to explore the entire island.\n", - "\n", - "8. Finally, the method returns the total count of islands found in the grid.\n", - "\n", - "This code encapsulates the solution in a class, allowing you to create an instance of the `Solution` class and call the `numIslands` method on it to count the number of islands in a given grid." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Example 1 Output: 1\n" - ] - } - ], - "source": [ - "grid1 = [\n", - " [\"1\", \"1\", \"1\", \"1\", \"0\"],\n", - " [\"1\", \"1\", \"0\", \"1\", \"0\"],\n", - " [\"1\", \"1\", \"0\", \"0\", \"0\"],\n", - " [\"0\", \"0\", \"0\", \"0\", \"0\"]\n", - "]\n", - "\n", - "solution = Solution()\n", - "result1 = solution.numIslands(grid1)\n", - "print(\"Example 1 Output:\", result1) # Expected output: 1\n" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Example 2 Output: 3\n" - ] - } - ], - "source": [ - "grid2 = [\n", - " [\"1\", \"1\", \"0\", \"0\", \"0\"],\n", - " [\"1\", \"1\", \"0\", \"0\", \"0\"],\n", - " [\"0\", \"0\", \"1\", \"0\", \"0\"],\n", - " [\"0\", \"0\", \"0\", \"1\", \"1\"]\n", - "]\n", - "\n", - "result2 = solution.numIslands(grid2)\n", - "print(\"Example 2 Output:\", result2) # Expected output: 3\n" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code:\n", - "\n", - "Time Complexity:\n", - "- The code uses a depth-first search (DFS) to explore the grid and count the number of islands.\n", - "- In the worst case, it visits every cell in the grid exactly once.\n", - "- The DFS function explores neighboring cells in four directions (up, down, left, right), so it has a time complexity of $O(4^{max(m, n)})$, where m is the number of rows and n is the number of columns.\n", - "- Therefore, the overall time complexity of the code is O(m * n), where m is the number of rows, and n is the number of columns.\n", - "\n", - "Space Complexity:\n", - "- The space complexity is determined by the recursive calls and the depth of the DFS stack.\n", - "- In the worst case, when the entire grid consists of '1's, the depth of the DFS recursion can be as deep as max(m, n).\n", - "- Therefore, the space complexity of the code is O(max(m, n)), representing the maximum depth of the DFS stack.\n", - "\n", - "In practical terms, for reasonably sized grids, the time and space complexity is linear, and the code should perform well. However, it's important to keep in mind that the worst-case time complexity is O(m * n), and the space complexity can be O(max(m, n))." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Identify Largest Island:** In addition to counting the number of islands, modify the code to identify the largest island in the grid and return its size.\n", - "\n", - "2. **Optimize for Space:** Modify the solution to reduce its space complexity to O(1) without modifying the input grid. This is a more memory-efficient version of the problem." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/11. Graphs/207. Course Schedule.ipynb b/docs/_build/html/_sources/11. Graphs/207. Course Schedule.ipynb deleted file mode 100644 index 37624f6..0000000 --- a/docs/_build/html/_sources/11. Graphs/207. Course Schedule.ipynb +++ /dev/null @@ -1,249 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 207. Course Schedule\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Course Schedule problem on LeetCode, click here!](https://leetcode.com/problems/course-schedule/)\n", - "\n", - "---\n", - "There are a total of `numCourses` courses to take, labeled from 0 to `numCourses - 1`. You are given an array `prerequisites` where `prerequisites[i] = [ai, bi]` indicates that you **must** take course `bi` first if you want to take course `ai`. \n", - "\n", - "- For example, the pair `[0, 1]`, indicates that to take course `0` you have to first take course `1`.\n", - "\n", - "Return `true` if you can finish all courses. Otherwise, return `false`.\n", - "\n", - "**Constraints:**\n", - "- 1 <= `numCourses` <= 2000\n", - "- 0 <= `prerequisites.length` <= 5000\n", - "- `prerequisites[i].length` == 2\n", - "- 0 <= `ai`, `bi` < `numCourses`\n", - "- All the pairs `prerequisites[i]` are **unique**." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem is to determine whether it's possible to complete a set of courses given a list of prerequisites. You are given the following:\n", - "\n", - "- `numCourses`: The total number of courses to be taken, labeled from 0 to `numCourses - 1`.\n", - "- `prerequisites`: A list of prerequisite courses, where each element `prerequisites[i]` is a pair `[ai, bi]`, indicating that you must take course `bi` before you can take course `ai`.\n", - "\n", - "The goal is to check whether it's possible to complete all the courses while respecting the prerequisite requirements. In other words, you need to determine if there are any circular dependencies in the course prerequisites that would prevent you from taking all the courses.\n", - "\n", - "For example:\n", - "\n", - "- If `numCourses` is 2, and `prerequisites` is `[[1, 0]]`, it means you have two courses, and you must finish course 0 before you can take course 1. In this case, it's possible to complete all courses, so the function should return `True`.\n", - "\n", - "- If `numCourses` is 2, and `prerequisites` is `[[1, 0], [0, 1]]`, it means you have two courses, but there's a circular dependency where course 1 requires course 0 and course 0 requires course 1. In this case, it's impossible to complete all courses, so the function should return `False`.\n", - "\n", - "The problem is essentially about checking for the presence of cycles in a directed graph, where the courses are nodes, and the prerequisites represent directed edges between them. If there are no cycles, it's possible to complete all courses; otherwise, it's not possible.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "from collections import defaultdict, deque\n", - "from typing import List\n", - "\n", - "class Solution:\n", - " def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:\n", - " # Create a graph using an adjacency list to represent the courses and their prerequisites.\n", - " graph = defaultdict(list) # Initialize an empty adjacency list.\n", - " in_degree = [0] * numCourses # Initialize an array to store in-degrees of courses.\n", - "\n", - " # Populate the graph and calculate in-degrees.\n", - " for course, prerequisite in prerequisites:\n", - " graph[prerequisite].append(course) # Add the course as a neighbor to its prerequisite.\n", - " in_degree[course] += 1 # Increment the in-degree of the course.\n", - "\n", - " # Initialize a queue with courses that have no prerequisites.\n", - " queue = deque()\n", - " for course in range(numCourses):\n", - " if in_degree[course] == 0:\n", - " queue.append(course)\n", - "\n", - " # Perform topological sorting.\n", - " while queue:\n", - " course = queue.popleft() # Take a course with no prerequisites.\n", - " numCourses -= 1 # Decrement the count of remaining courses.\n", - "\n", - " for neighbor in graph[course]:\n", - " in_degree[neighbor] -= 1 # Remove the prerequisite relationship.\n", - " if in_degree[neighbor] == 0:\n", - " queue.append(neighbor) # If no more prerequisites, add to the queue.\n", - "\n", - " # If all courses were successfully taken (numCourses becomes 0), return True.\n", - " return numCourses == 0" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "This Python code is designed to determine whether it is possible to complete all the required courses given a set of prerequisites. It uses a topological sorting algorithm to accomplish this. Here's a brief explanation of the code:\n", - "\n", - "1. The code defines a `Solution` class with a `canFinish` method that takes two parameters: `numCourses` (the total number of courses) and `prerequisites` (a list of pairs indicating which course must be taken before another).\n", - "\n", - "2. It initializes an empty graph as an adjacency list using a `defaultdict` to represent the courses and their prerequisites. It also initializes a list called `in_degree` to keep track of the in-degrees of courses, which is used in the topological sorting process.\n", - "\n", - "3. The code then populates the graph by iterating through the `prerequisites` list. For each pair `(ai, bi)`, it adds course `ai` as a neighbor to its prerequisite course `bi` in the graph and increments the in-degree of course `ai`.\n", - "\n", - "4. Next, it initializes a queue with courses that have no prerequisites. It does this by iterating through all the courses and adding those with an in-degree of 0 to the queue.\n", - "\n", - "5. The code performs a topological sorting of the courses using a while loop. In each iteration of the loop, it dequeues a course from the front of the queue (a course with no prerequisites).\n", - "\n", - "6. For each neighbor (course that depends on the dequeued course), it decrements the in-degree of the neighbor. If the neighbor's in-degree becomes 0, it means all of its prerequisites have been taken, so the neighbor is added to the queue.\n", - "\n", - "7. The loop continues until there are no more courses with no prerequisites to dequeue, and the in-degrees are updated accordingly.\n", - "\n", - "8. After the loop, if all courses were successfully taken (i.e., `numCourses` becomes 0), it means that there were no circular dependencies, and it's possible to finish all courses. In this case, the method returns `True`. Otherwise, if there are remaining courses (indicating a circular dependency), it returns `False`." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "# Example 1\n", - "numCourses1 = 2\n", - "prerequisites1 = [[1, 0]]\n", - "sol = Solution()\n", - "print(sol.canFinish(numCourses1, prerequisites1)) # Output: True" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "# Example 2\n", - "numCourses2 = 2\n", - "prerequisites2 = [[1, 0], [0, 1]]\n", - "print(sol.canFinish(numCourses2, prerequisites2)) # Output: False" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the `canFinish` method:\n", - "\n", - "**Time Complexity:**\n", - "\n", - "1. Constructing the graph: In the first loop where we iterate through the `prerequisites` list, we populate the graph with prerequisites. This loop has a time complexity of O(E), where E is the number of prerequisites (edges).\n", - "\n", - "2. Initializing in-degrees and finding courses with no prerequisites: In the worst case, we iterate through all `numCourses` courses to initialize in-degrees and find the courses with no prerequisites. This has a time complexity of O(V), where V is the number of courses (vertices).\n", - "\n", - "3. Topological Sorting: In the while loop, we perform topological sorting, processing each course once and its outgoing edges. In the worst case, each course is processed once. This has a time complexity of O(V + E).\n", - "\n", - "The overall time complexity is O(V + E), where V is the number of courses, and E is the number of prerequisites.\n", - "\n", - "**Space Complexity:**\n", - "\n", - "1. Graph Representation: The space complexity for storing the graph as an adjacency list is O(E), where E is the number of prerequisites.\n", - "\n", - "2. In-Degree Array: The space complexity for storing the in-degrees of courses is O(V), where V is the number of courses.\n", - "\n", - "3. Queue: The space complexity for the queue is O(V), as it may contain all the courses.\n", - "\n", - "The overall space complexity is O(V + E), where V is the number of courses, and E is the number of prerequisites.\n", - "\n", - "In most practical cases, the number of prerequisites (E) is much smaller than the number of courses (V), so the time and space complexity can often be considered as O(V)." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Optimizing Course Scheduling**: Given a list of courses with their durations and prerequisites, find the most efficient way to schedule these courses to minimize the time it takes to complete all of them.\n", - "\n", - "2. **Detecting Cycles in Course Dependencies**: Modify the original problem to not just determine if you can finish all courses but also to identify the specific courses that form a cycle in the prerequisite dependencies." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/11. Graphs/3651. Number of Connected Components in an Undirected Graph.ipynb b/docs/_build/html/_sources/11. Graphs/3651. Number of Connected Components in an Undirected Graph.ipynb deleted file mode 100644 index fb186f2..0000000 --- a/docs/_build/html/_sources/11. Graphs/3651. Number of Connected Components in an Undirected Graph.ipynb +++ /dev/null @@ -1,236 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 3651. Number of Connected Components in an Undirected Graph\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Number of Connected Components in an Undirected Graph problem on LintCode, click here!](https://www.lintcode.com/problem/3651/)\n", - "\n", - "---\n", - "In this problem, there is an undirected graph with `n` nodes. There is also an `edges` array. Where `edges[i] = [a, b]` means that there is an edge between *node a* and *node b* in the graph.\n", - "\n", - "You need to return *the number of connected components in that graph*." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem at hand is to determine the number of connected components in an undirected graph. Here's a more detailed explanation of the problem:\n", - "\n", - "- You are given an undirected graph, which consists of nodes and edges. The graph may have multiple distinct connected components.\n", - "\n", - "- A connected component is a group of nodes within the graph where each node can be reached from every other node in the same component. In other words, there is a path between any two nodes in the same connected component, but there are no paths connecting nodes from different components.\n", - "\n", - "- Your task is to write a function that takes as input the number of nodes `n` and a list of edges `edges`, where each edge is represented as a pair of nodes `[a, b]` indicating an edge between node `a` and node `b`.\n", - "\n", - "- The goal is to determine the number of distinct connected components in the graph.\n", - "\n", - "- You need to implement an algorithm that can identify these connected components and count how many there are in the given graph.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "def countConnectedComponents(n, edges):\n", - " # Define a helper function for depth-first search (DFS).\n", - " def dfs(node):\n", - " if not visited[node]: # If the node has not been visited yet:\n", - " visited[node] = True # Mark it as visited.\n", - " for neighbor in graph[node]: # Explore all neighbors of the current node.\n", - " dfs(neighbor) # Recursively call DFS on the neighbor.\n", - "\n", - " # Create an empty adjacency list to represent the graph.\n", - " graph = [[] for _ in range(n)]\n", - "\n", - " # Initialize a boolean list to keep track of visited nodes.\n", - " visited = [False] * n\n", - "\n", - " # Populate the adjacency list with edges from the input.\n", - " for a, b in edges:\n", - " graph[a].append(b)\n", - " graph[b].append(a) # Since the graph is undirected, we add edges in both directions.\n", - "\n", - " # Initialize a counter to keep track of the number of connected components.\n", - " count = 0\n", - "\n", - " # Iterate through all nodes in the graph.\n", - " for i in range(n):\n", - " if not visited[i]: # If the node has not been visited:\n", - " count += 1 # Increment the count since we've found a new connected component.\n", - " dfs(i) # Start a depth-first search from the unvisited node to explore the component.\n", - "\n", - " return count" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The provided Python code calculates the number of connected components in an undirected graph. Here's a high-level explanation of how the code works:\n", - "\n", - "1. The `countConnectedComponents` function takes two arguments: `n` (the number of nodes in the graph) and `edges` (a list of edge pairs representing connections between nodes).\n", - "\n", - "2. Inside the function, there is a helper function called `dfs` (depth-first search), which is used to explore and mark nodes as visited.\n", - "\n", - "3. An empty adjacency list called `graph` is created to represent the graph. The `graph` is a list of lists where each element represents a node, and the list associated with each node contains its neighboring nodes.\n", - "\n", - "4. Another list called `visited` is created to keep track of visited nodes. Initially, all nodes are marked as not visited (`False`).\n", - "\n", - "5. The code populates the `graph` by iterating through the `edges` list and adding each edge to the adjacency list. Since the graph is undirected, both directions of each edge are added.\n", - "\n", - "6. A counter variable called `count` is initialized to keep track of the number of connected components.\n", - "\n", - "7. The code iterates through all nodes from `0` to `n-1`. For each node, it checks whether it has been visited yet. If it hasn't been visited, it means a new connected component is found. The counter `count` is incremented, and a depth-first search (DFS) is initiated from this unvisited node to explore the connected component.\n", - "\n", - "8. The `dfs` function recursively visits all nodes in the connected component, marking them as visited. It does this by checking each neighbor of the current node and recursively calling `dfs` on unvisited neighbors.\n", - "\n", - "9. After the loop through all nodes, the `count` variable contains the total number of connected components in the graph.\n", - "\n", - "10. The function returns the value of `count`, which represents the number of connected components.\n", - "\n", - "11. Two examples are provided at the end to demonstrate how to use the function with different inputs." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n" - ] - } - ], - "source": [ - "# Example 1\n", - "n1 = 3\n", - "edges1 = [[0, 1], [0, 2]]\n", - "print(countConnectedComponents(n1, edges1)) # Output: 1" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2\n" - ] - } - ], - "source": [ - "# Example 2\n", - "n2 = 6\n", - "edges2 = [[0, 1], [1, 2], [2, 3], [4, 5]]\n", - "print(countConnectedComponents(n2, edges2)) # Output: 2" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the code for counting the number of connected components in an undirected graph using depth-first search (DFS).\n", - "\n", - "**Time Complexity:**\n", - "- The code iterates through all nodes in the graph (from 0 to `n-1`).\n", - "- For each unvisited node, it initiates a depth-first search (DFS) from that node to explore the connected component.\n", - "- In the worst case, every node may belong to a separate connected component, and you perform a DFS for each node.\n", - "- The time complexity of the DFS for a single connected component is O(V + E), where V is the number of nodes in the component, and E is the number of edges.\n", - "- In the worst case, you perform O(n) DFS calls, each with its own O(V + E) complexity.\n", - "\n", - "So, the overall time complexity of the code is O(n * (V + E)). In the worst case, if the graph is connected (a single connected component), this simplifies to O(n * (n + m)), where m is the number of edges.\n", - "\n", - "**Space Complexity:**\n", - "- The main data structures used are the `graph` (adjacency list), `visited` (boolean array), and the recursive call stack for DFS.\n", - "- The `graph` has a space complexity of O(n + m), where n is the number of nodes, and m is the number of edges.\n", - "- The `visited` boolean array also has a space complexity of O(n) to keep track of whether nodes have been visited.\n", - "- The depth of the recursive call stack for DFS can go up to O(n) in the worst case, when all nodes are part of a single connected component.\n", - "\n", - "So, the overall space complexity of the code is O(n + m) for data structures and O(n) for the call stack. In the worst case, this simplifies to O(n + m).\n", - "\n", - "In summary, the time complexity is O(n * (V + E)), and the space complexity is O(n + m)." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Disconnected Components with Multiple Queries:** You are given an undirected graph with `n` nodes and `m` edges. Initially, the graph is disconnected, and you need to process `q` queries. Each query consists of adding an edge to connect two nodes. After each query, you need to output the number of connected components in the updated graph.\n", - "\n", - "2. **Maximum Size of Connected Components:** Given an undirected graph with `n` nodes and `m` edges, find the size of the largest connected component in the graph. Additionally, identify the nodes that belong to this largest component. You can assume there is at least one connected component in the graph.\n" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/11. Graphs/417. Pacific Atlantic Water Flow.ipynb b/docs/_build/html/_sources/11. Graphs/417. Pacific Atlantic Water Flow.ipynb deleted file mode 100644 index eb34497..0000000 --- a/docs/_build/html/_sources/11. Graphs/417. Pacific Atlantic Water Flow.ipynb +++ /dev/null @@ -1,261 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 417. Pacific Atlantic Water Flow\n", - "\n", - "\n", - "**Difficulty:** Medium\n", - "\n", - "**Link to Problem:** [To see the Pacific Atlantic Water Flow problem on LeetCode, click here!](https://leetcode.com/problems/pacific-atlantic-water-flow/)\n", - "\n", - "---\n", - "There is an `m x n` rectangular island that borders both the **Pacific Ocean** and **Atlantic Ocean**. The **Pacific Ocea**n touches the island's left and top edges, and the **Atlantic Ocean** touches the island's right and bottom edges.\n", - "\n", - "The island is partitioned into a grid of square cells. You are given an `m x n` integer matrix `heights` where `heights[r][c]` represents the **height above sea level** of the cell at coordinate `(r, c)`.\n", - "\n", - "The island receives a lot of rain, and the rain water can flow to neighboring cells directly north, south, east, and west if the neighboring cell's height is **less than or equal to** the current cell's height. Water can flow from any cell adjacent to an ocean into the ocean.\n", - "\n", - "Return *a **2D list** of grid coordinates `result` where $result[i] = [r_i, c_i]$ denotes that rain water can flow from cell $(r_i, c_i)$ to **both** the Pacific and Atlantic oceans*.\n", - "\n", - "**Constraints:**\n", - "- `m == heights.length`\n", - "- `n == heights[r].length`\n", - "- `1 <= m, n <= 200`\n", - "- 0 <= `heights[r][c]` <= $10^5$" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem at hand involves a scenario with a rectangular island surrounded by both the Pacific Ocean and the Atlantic Ocean. The Pacific Ocean is in contact with the island's left and top edges, while the Atlantic Ocean is in contact with the island's right and bottom edges. The goal is to determine which cells on the island can allow rainwater to flow to both the Pacific and Atlantic Oceans.\n", - "\n", - "Here are the key details and constraints of the problem:\n", - "\n", - "1. The island is divided into a grid of square cells.\n", - "\n", - "2. Each cell is represented by an integer value in a matrix `heights`. The value at `heights[r][c]` represents the height above sea level of the cell at coordinates `(r, c)` on the island.\n", - "\n", - "3. Rainwater can flow from a cell to neighboring cells directly north, south, east, or west only if the neighboring cell's height is less than or equal to the current cell's height.\n", - "\n", - "4. Water can flow from any cell adjacent to the ocean into the ocean. This means water can flow from cells on the edge of the island to the Pacific Ocean and the Atlantic Ocean.\n", - "\n", - "The task is to find and return a 2D list of grid coordinates where rainwater can flow from a cell to both the Pacific and Atlantic Oceans. In other words, you need to identify the cells that can send water to both the left and top edges (Pacific) and the right and bottom edges (Atlantic) of the island.\n", - "\n", - "The problem is solved by performing a depth-first search (DFS) starting from the ocean edges and marking the cells that can flow to each ocean. Then, the algorithm identifies cells that are reachable from both oceans and returns their coordinates as the result.\n", - "\n", - "The problem involves both traversal of the island and backtracking to find the solution, which makes it a classic graph traversal problem.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "from typing import List\n", - "\n", - "class Solution:\n", - " def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]:\n", - " # Check if the input matrix is empty\n", - " if not heights:\n", - " return []\n", - " \n", - " m, n = len(heights), len(heights[0])\n", - " \n", - " # Initialize boolean matrices to keep track of cells reachable from each ocean\n", - " pacific_reachable = [[False] * n for _ in range(m)]\n", - " atlantic_reachable = [[False] * n for _ in range(m)]\n", - " \n", - " # Depth-First Search (DFS) function to mark cells that can be reached from an ocean\n", - " def dfs(x, y, reachable):\n", - " if reachable[x][y]:\n", - " return\n", - " reachable[x][y] = True\n", - " for dx, dy in [(0, 1), (0, -1), (1, 0), (-1, 0)]:\n", - " new_x, new_y = x + dx, y + dy\n", - " if 0 <= new_x < m and 0 <= new_y < n and heights[new_x][new_y] >= heights[x][y]:\n", - " dfs(new_x, new_y, reachable)\n", - " \n", - " # Start DFS from the Pacific Ocean (left and top edges)\n", - " for i in range(m):\n", - " dfs(i, 0, pacific_reachable)\n", - " dfs(i, n - 1, atlantic_reachable)\n", - " \n", - " for j in range(n):\n", - " dfs(0, j, pacific_reachable)\n", - " dfs(m - 1, j, atlantic_reachable)\n", - " \n", - " result = []\n", - " \n", - " # Find cells that can flow to both the Pacific and Atlantic oceans\n", - " for i in range(m):\n", - " for j in range(n):\n", - " if pacific_reachable[i][j] and atlantic_reachable[i][j]:\n", - " result.append([i, j])\n", - " \n", - " return result" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The code defines a class called `Solution` with a method named `pacificAtlantic`. This method takes a 2D matrix `heights`, where each element represents the height above sea level of a cell on a rectangular island. The goal of the method is to find and return a list of grid coordinates (cells) from which rainwater can flow into both the Pacific and Atlantic Oceans.\n", - "\n", - "The code uses a Depth-First Search (DFS) algorithm to traverse the island, starting from the ocean edges, and marks cells that are reachable from either the Pacific or Atlantic Ocean. It does this by creating two boolean matrices, `pacific_reachable` and `atlantic_reachable`, to keep track of cells that can be reached from each ocean.\n", - "\n", - "The code iterates through the entire island, initiating DFS searches from the edges of the island. If a cell is reachable from an ocean (either Pacific or Atlantic), it is marked as reachable in the corresponding boolean matrix. The DFS function ensures that the traversal follows the rule that water can flow to a neighboring cell if the neighboring cell's height is less than or equal to the current cell's height.\n", - "\n", - "After marking all reachable cells from both oceans, the code then looks for cells that are reachable from both the Pacific and Atlantic Oceans. If a cell satisfies this condition, it is added to the `result` list.\n", - "\n", - "Finally, the code returns the `result` list, which contains the grid coordinates of cells from which rainwater can flow into both the Pacific and Atlantic Oceans.\n", - "\n", - "The code provides a solution to the problem of finding cells on the island where water can reach both oceans, demonstrating a traversal algorithm that explores the connectivity of cells on the island." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]]\n" - ] - } - ], - "source": [ - "# Example 1\n", - "heights1 = [\n", - " [1,2,2,3,5],\n", - " [3,2,3,4,4],\n", - " [2,4,5,3,1],\n", - " [6,7,1,4,5],\n", - " [5,1,1,2,4]\n", - "]\n", - "\n", - "solution = Solution()\n", - "print(solution.pacificAtlantic(heights1)) # Expected Output: [[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]]" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[0, 0]]\n" - ] - } - ], - "source": [ - "# Example 2\n", - "heights2 = [[1]]\n", - "print(solution.pacificAtlantic(heights2)) # Expected Output: [[0, 0]]" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Time Complexity:\n", - "The time complexity of this solution is O(m * n), where 'm' is the number of rows in the input matrix and 'n' is the number of columns. Here's a breakdown of the time complexity:\n", - "\n", - "1. Creating the `pacific_reachable` and `atlantic_reachable` matrices with dimensions m x n takes O(m * n) time.\n", - "\n", - "2. Initiating Depth-First Search (DFS) from the edges of the island takes O(m * n) time because it processes each cell once.\n", - "\n", - "3. The DFS function visits each cell at most once, and its time complexity is O(1) for each cell. The number of cells visited by the DFS in the worst case is m * n.\n", - "\n", - "4. The final step of identifying and appending cells to the result list takes O(m * n) time in the worst case.\n", - "\n", - "Overall, the time complexity is dominated by the DFS and is O(m * n).\n", - "\n", - "Space Complexity:\n", - "The space complexity of this solution is also O(m * n). Here's how the space is used:\n", - "\n", - "1. Two boolean matrices, `pacific_reachable` and `atlantic_reachable`, are created with dimensions m x n. Each matrix takes O(m * n) space, resulting in O(2 * m * n) space usage.\n", - "\n", - "2. The depth-first search (DFS) stack space during the recursive calls can go as deep as the diagonal of the grid, which is at most min(m, n). This additional space for the call stack is relatively small compared to the boolean matrices and can be considered O(min(m, n)).\n", - "\n", - "3. The `result` list stores the grid coordinates, and its size is determined by the number of cells that can flow to both oceans. In the worst case, this list can contain all m * n cells, so it takes O(m * n) space.\n", - "\n", - "The overall space complexity is the sum of these components, which is O(m * n) + O(min(m, n)) + O(m * n). In big O notation, we can simplify this to O(m * n)." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Optimization Challenge:** Modify the algorithm to find the maximum flow of water from any cell to both the Pacific and Atlantic Oceans. In other words, find the cell(s) that can send the most water to both oceans.\n", - "\n", - "2. **Efficiency Challenge:** Optimize the time and space complexity of the algorithm while maintaining correctness. Aim to reduce both time and space complexity as much as possible." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/11. Graphs/README.md b/docs/_build/html/_sources/11. Graphs/README.md deleted file mode 100644 index aad262c..0000000 --- a/docs/_build/html/_sources/11. Graphs/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# Graphs Problems - Blind 75 LeetCode - - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [200. Number of Islands](https://leetcode.com/problems/number-of-islands/) | Medium | -| [133. Clone Graph](https://leetcode.com/problems/clone-graph/) | Medium | -| [417. Pacific Atlantic Water Flow](https://leetcode.com/problems/pacific-atlantic-water-flow/) | Medium | -| [207. Course Schedule](https://leetcode.com/problems/course-schedule/) | Medium | -| [323. Number of Connected Components In An Undirected Graph](https://leetcode.com/problems/number-of-connected-components-in-an-undirected-graph/) | Medium | -| [261. Graph Valid Tree](https://leetcode.com/problems/graph-valid-tree/) | Medium | - - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! \ No newline at end of file diff --git a/docs/_build/html/_sources/12. Advanced Graphs/892. Alien Dictionary.ipynb b/docs/_build/html/_sources/12. Advanced Graphs/892. Alien Dictionary.ipynb deleted file mode 100644 index 81f0e5b..0000000 --- a/docs/_build/html/_sources/12. Advanced Graphs/892. Alien Dictionary.ipynb +++ /dev/null @@ -1,256 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# 892. Alien Dictionary\n", - "\n", - "**Difficulty:** Hard\n", - "\n", - "**Link to Problem:** [To see the Alien Dictionary problem on LintCode, click here!](https://www.lintcode.com/problem/892/)\n", - "\n", - "---\n", - "\n", - "There is a new alien language which uses the latin alphabet. However, the order among letters are unknown to you. You receive a list of **non-empty** words from the dictionary, where words are **sorted lexicographically by the rules of this new language**. Derive the order of letters in this language.\n", - "\n", - "**Constraints:**\n", - "- You may assume all letters are in lowercase.\n", - "- The dictionary is invalid, if string a is prefix of string b and b is appear before a.\n", - "- If the order is invalid, return an empty string.\n", - "- There may be multiple valid order of letters, return the smallest in normal lexicographical order.\n", - "- The letters in **one** string are of the same rank by default and are sorted in Human dictionary order." - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The problem at hand involves determining the order of letters in a new alien language that uses the Latin alphabet. However, the order of letters in this alien language is unknown. To solve this problem, we are given a list of non-empty words from the dictionary, where the words are sorted lexicographically based on the rules of the alien language. The goal is to derive the correct order of letters in this new language.\n", - "\n", - "Here's a more detailed explanation of the problem:\n", - "\n", - "1. The alphabet: The new alien language uses the Latin alphabet, which consists of lowercase letters.\n", - "\n", - "2. Dictionary: We are provided with a list of non-empty words. These words are sorted in lexicographical order based on the rules of the alien language. The order of letters in the words reflects the correct order in the new language.\n", - "\n", - "3. Invalid order: The problem specifies that the dictionary is considered invalid if there exists a situation where one string 'a' is a prefix of another string 'b,' and 'b' appears before 'a' in the dictionary. This condition ensures that there are no inconsistencies in the order of letters.\n", - "\n", - "4. Multiple valid orders: It's possible that there are multiple valid orders of letters that satisfy the provided dictionary. However, we are instructed to return the smallest valid order in normal lexicographical order.\n", - "\n", - "To solve this problem, you need to analyze the given list of words and determine the correct order of letters in the alien language while adhering to the specified constraints. You should return the order as a string in lexicographical order if it's valid, and an empty string if the order is invalid.\n", - "\n", - "The key to solving this problem is to construct a directed graph of letter relationships based on the order information provided by the words in the dictionary. Then, perform a topological sort on this graph to derive the order of letters, ensuring that the order is consistent and valid according to the given constraints.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "from collections import defaultdict, deque\n", - "\n", - "def alienOrder(words):\n", - " # Create an adjacency list to represent the graph\n", - " graph = defaultdict(list)\n", - " \n", - " # Create a dictionary to store the in-degrees of each letter\n", - " in_degree = {}\n", - " \n", - " # Initialize in-degrees to 0 for all letters\n", - " for word in words:\n", - " for char in word:\n", - " if char not in in_degree:\n", - " in_degree[char] = 0\n", - " \n", - " # Build the graph and update in-degrees\n", - " for i in range(1, len(words)):\n", - " word1, word2 = words[i-1], words[i]\n", - " min_length = min(len(word1), len(word2))\n", - " \n", - " # Compare characters in the two words\n", - " j = 0\n", - " while j < min_length and word1[j] == word2[j]:\n", - " j += 1\n", - " \n", - " if j < min_length:\n", - " # If word1[j] is lexicographically before word2[j], add an edge\n", - " graph[word1[j]].append(word2[j])\n", - " in_degree[word2[j]] += 1\n", - " \n", - " # Break the loop to avoid further comparisons\n", - " break\n", - " \n", - " # Perform topological sorting using Kahn's algorithm\n", - " result = []\n", - " queue = deque([char for char in in_degree if in_degree[char] == 0])\n", - " \n", - " while queue:\n", - " char = queue.popleft()\n", - " result.append(char)\n", - " \n", - " for neighbor in graph[char]:\n", - " in_degree[neighbor] -= 1\n", - " if in_degree[neighbor] == 0:\n", - " queue.append(neighbor)\n", - " \n", - " # Check if there is a valid order\n", - " if len(result) < len(in_degree):\n", - " return \"\"\n", - " \n", - " return \"\".join(result)" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The code is designed to determine the order of letters in an unknown alien language that uses the Latin alphabet. It takes a list of non-empty words from a dictionary as input, where the words are sorted lexicographically based on the rules of this alien language.\n", - "\n", - "The code follows these main steps:\n", - "\n", - "1. Create a data structure to represent the graph of letters and their relationships in the alien language. It uses a defaultdict to store a list of letters that come after each letter. Additionally, it uses a dictionary called `in_degree` to keep track of the in-degrees (the number of letters that precede a letter) for each letter.\n", - "\n", - "2. Initialize the in-degrees of all letters to 0. This is done by iterating through all the words and characters in the words, adding each character to the `in_degree` dictionary with an initial in-degree of 0.\n", - "\n", - "3. Build the graph by comparing adjacent words in the dictionary. For each pair of adjacent words, the code finds the first differing character between the two words. If such a character exists, it means there's an order relationship between the letters represented by these characters. The code updates the graph and in-degrees accordingly.\n", - "\n", - "4. After constructing the graph, the code performs a topological sorting of the letters using Kahn's algorithm. It starts by initializing an empty result list and a queue containing letters with in-degrees of 0. The algorithm repeatedly removes a letter with an in-degree of 0 from the queue, adds it to the result list, and updates the in-degrees of its neighbors. This process continues until the queue is empty.\n", - "\n", - "5. Finally, the code checks if the topological sorting was successful by comparing the length of the result list with the number of unique letters in the input. If the lengths differ, it means there's a cycle in the graph, and the order is invalid. In such a case, an empty string is returned. Otherwise, the result list is joined together to form the smallest order of letters in normal lexicographical order, and it is returned as the output.\n", - "\n", - "The code provides a way to determine the order of letters in the alien language while handling various edge cases, including checking for invalid order conditions." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "355f5bfd-94e1-4c5b-9914-cc20775f4160", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "wrtef\n" - ] - } - ], - "source": [ - "# Example 1\n", - "words1 = [\"wrt\", \"wrf\", \"er\", \"ett\", \"rftt\"]\n", - "print(alienOrder(words1)) # Output: \"wertf\"" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "zx\n" - ] - } - ], - "source": [ - "# Example 2\n", - "words2 = [\"z\", \"x\"]\n", - "print(alienOrder(words2)) # Output: \"zx\"" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Let's analyze the time and space complexity of the provided code for determining the order of letters in an alien language.\n", - "\n", - "Time Complexity:\n", - "1. Building the graph: The code iterates through the list of words and compares adjacent words. In the worst case, where all words have the same prefix, it takes O(N) time to build the graph, where N is the total number of characters in all the words.\n", - "2. Topological sorting: Performing a topological sort on the graph takes O(V + E) time, where V is the number of unique letters (vertices) and E is the number of relationships between letters (edges) in the graph.\n", - "\n", - "Overall, the time complexity is O(N + V + E), where N is the total number of characters in the words, V is the number of unique letters, and E is the number of order relationships between letters.\n", - "\n", - "Space Complexity:\n", - "1. Graph and In-degrees: The code uses data structures to represent the graph and in-degrees. The space complexity for these data structures is O(V + E), where V is the number of unique letters, and E is the number of order relationships between letters in the words.\n", - "2. Result List: The result list stores the order of letters, which can have a maximum size of V, where V is the number of unique letters.\n", - "3. Queue: The space used by the queue during topological sorting is also O(V).\n", - "\n", - "Overall, the space complexity is O(V + E) due to the data structures used for graph representation and the space needed for storing the result and the queue.\n", - "\n", - "In the worst case, where there are many unique letters and many order relationships, the space complexity is dominated by the number of unique letters and their relationships.\n", - "\n", - "In summary, the time complexity of the code is O(N + V + E), and the space complexity is O(V + E). The actual performance will depend on the specific input data, such as the number of unique letters and the relationships between them in the alien language." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Multiple Valid Orders**: Extend the problem to handle cases where there are multiple valid orders of letters in the alien language. Modify the code to return all valid orders instead of just one. Be mindful of performance.\n", - "\n", - "2. **Detect Invalid Dictionary**: Given a dictionary of words, write a function to detect whether the dictionary is valid or not based on the constraints mentioned in the problem statement." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/12. Advanced Graphs/README.md b/docs/_build/html/_sources/12. Advanced Graphs/README.md deleted file mode 100644 index f362de7..0000000 --- a/docs/_build/html/_sources/12. Advanced Graphs/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# Advanced Graphs Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [269. Alien Dictionary](https://leetcode.com/problems/alien-dictionary/) | Hard | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! \ No newline at end of file diff --git a/docs/_build/html/_sources/13. One-D Dynamic Programming/198. House Robber.ipynb b/docs/_build/html/_sources/13. One-D Dynamic Programming/198. House Robber.ipynb deleted file mode 100644 index 8d32e21..0000000 --- a/docs/_build/html/_sources/13. One-D Dynamic Programming/198. House Robber.ipynb +++ /dev/null @@ -1,103 +0,0 @@ -{ - "metadata": { - "kernelspec": { - "name": "python", - "display_name": "Python (Pyodide)", - "language": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat_minor": 5, - "nbformat": 4, - "cells": [ - { - "cell_type": "markdown", - "source": "# House Robber\n**Difficulty:** Medium\n\n---\nYou are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security systems connected and **it will automatically contact the police if two adjacent houses were broken into on the same night.**\n\nGiven an integer array `nums` representing the amount of money of each house, return *the maximum amount of money you can rob tonight **without alerting the police**.*\n\n**Constraints:**\n- `1 <= nums.length <= 100`\n- `0 <= nums[i] <= 400`", - "metadata": {}, - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49" - }, - { - "cell_type": "markdown", - "source": "## Probelm Explanation:\n\nThe problem is a classic dynamic programming challenge known as the \"House Robber\" problem. The scenario is that you are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, but the constraint is that adjacent houses have security systems connected. If two adjacent houses are broken into on the same night, the security systems will automatically contact the police.\n\nThe goal is to determine the maximum amount of money you can rob tonight without alerting the police. You need to find a strategy to maximize your earnings while avoiding robbing two adjacent houses.\n\nThe input to the problem is an array `nums`, where `nums[i]` represents the amount of money in the `i`-th house. The task is to return the maximum amount of money that can be robbed without triggering the security system.\n\nFor example:\n```\nInput: nums = [1,2,3,1]\nOutput: 4\nExplanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).\nTotal amount you can rob = 1 + 3 = 4.\n\nInput: nums = [2,7,9,3,1]\nOutput: 12\nExplanation: Rob house 1 (money = 2), rob house 3 (money = 9), and rob house 5 (money = 1).\nTotal amount you can rob = 2 + 9 + 1 = 12.\n```\n\nThe challenge involves designing an algorithm to efficiently solve this problem and find the optimal strategy for robbing houses to maximize the stolen money while adhering to the constraint of not robbing adjacent houses. The provided solution utilizes dynamic programming to achieve this.\n\n## Solution:\nHere's a Python function to implement this algorithm:", - "metadata": {}, - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76" - }, - { - "cell_type": "code", - "source": "from typing import List\n\nclass Solution:\n def rob(self, nums: List[int]) -> int:\n # Initialize variables to keep track of the maximum amount of money robbed at the previous and current houses\n prev, curr = 0, 0\n\n # Iterate through the houses\n for n in nums:\n # Calculate the maximum amount of money that can be robbed at the current house\n # It is the maximum of either robbing the current house and the money robbed at the house before the previous one (prev),\n # or skipping the current house and taking the maximum amount from the previous house (curr)\n temp = max(n + prev, curr)\n\n # Update the variables for the next iteration\n prev, curr = curr, temp\n\n # The final result is the maximum amount of money that can be robbed at the last house\n return curr", - "metadata": { - "trusted": true - }, - "execution_count": 4, - "outputs": [], - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5" - }, - { - "cell_type": "markdown", - "source": "## Explanation:\n\nThe provided code is a Python implementation of the \"House Robber\" problem using a dynamic programming approach. It's part of a class `Solution` and includes a method `rob` that takes a list of integers `nums` as input and returns the maximum amount of money that can be robbed without alerting the police.\n\nThe key idea of the algorithm is to maintain two variables, `prev` and `curr`, which represent the maximum amount of money that can be robbed up to the previous house and the current house, respectively. The algorithm iterates through the houses, updating these variables based on the maximum amount that can be robbed at the current house, considering the constraint of not robbing adjacent houses.\n\nThe loop calculates a temporary variable `temp` that represents the maximum amount of money that can be robbed at the current house. It considers two scenarios: either robbing the current house and adding the money robbed at the house before the previous one (`n + prev`), or skipping the current house and taking the maximum amount from the previous house (`curr`). The maximum of these two scenarios is assigned to `temp`.\n\nThe `prev` and `curr` variables are then updated for the next iteration. `prev` is set to the previous value of `curr`, and `curr` is set to the calculated `temp`.\n\nThe final result is the value stored in the `curr` variable, representing the maximum amount of money that can be robbed at the last house. This value is returned as the result of the `rob` method.\n\nThe provided test cases at the end demonstrate the usage of the `rob` method with different input arrays.", - "metadata": {}, - "id": "ece39324-cd9e-47d7-8677-a001878494d9" - }, - { - "cell_type": "markdown", - "source": "## Test cases:\n\nHere's how you can use this solution:", - "metadata": {}, - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244" - }, - { - "cell_type": "code", - "source": "# Example 1:\nsol = Solution()\n\nnums1 = [1, 2, 3, 1]\nprint(sol.rob(nums1)) # Output: 4", - "metadata": { - "trusted": true - }, - "execution_count": 5, - "outputs": [ - { - "name": "stdout", - "text": "4\n", - "output_type": "stream" - } - ], - "id": "f12c5a63-b811-4be7-83c2-34ee396b546c" - }, - { - "cell_type": "code", - "source": "# Example 2:\nnums2 = [2, 7, 9, 3, 1]\nprint(sol.rob(nums2)) # Output: 12", - "metadata": { - "trusted": true - }, - "execution_count": 6, - "outputs": [ - { - "name": "stdout", - "text": "12\n", - "output_type": "stream" - } - ], - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3" - }, - { - "cell_type": "markdown", - "source": "## Time and Space Complexity Analysis\n\nLet's analyze the time and space complexity of the provided code.\n\n### Time Complexity:\n\nThe time complexity of the code is O(n), where n is the number of houses. The algorithm iterates through the array once, and in each iteration, it performs constant time operations. The loop runs for each house, and the number of operations inside the loop is independent of the input size. Therefore, the overall time complexity is linear, O(n).\n\n### Space Complexity:\n\nThe space complexity is O(1), constant space. The algorithm uses only a constant amount of extra space regardless of the input size. The variables `prev`, `curr`, and `temp` are the only additional variables used, and they do not depend on the size of the input array. Thus, the space complexity is constant, O(1).\n\nIn summary:\n- Time Complexity: O(n)\n- Space Complexity: O(1)", - "metadata": {}, - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2" - }, - { - "cell_type": "markdown", - "source": "## Challenging Exercises:\n\n1. **Variation with Maximum Number of Houses to Rob:** Modify the problem to include an additional constraint: you are allowed to rob at most 'k' houses without triggering the alarm. Find the maximum amount you can rob under this new constraint.\n\n2. **Robbing in a Circular Street:** Extend the problem to a circular street where the first and last houses are adjacent. You cannot rob both the first and last houses simultaneously. Find the maximum amount you can rob in this circular setting.\n\n\n**Link to Problem:** [To see the House Robber problem on LeetCode, click here!](https://leetcode.com/problems/house-robber/description/)\n", - "metadata": {}, - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6" - } - ] -} \ No newline at end of file diff --git a/docs/_build/html/_sources/13. One-D Dynamic Programming/213. House Robber II.ipynb b/docs/_build/html/_sources/13. One-D Dynamic Programming/213. House Robber II.ipynb deleted file mode 100644 index b1080e8..0000000 --- a/docs/_build/html/_sources/13. One-D Dynamic Programming/213. House Robber II.ipynb +++ /dev/null @@ -1,119 +0,0 @@ -{ - "metadata": { - "kernelspec": { - "name": "python", - "display_name": "Python (Pyodide)", - "language": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat_minor": 5, - "nbformat": 4, - "cells": [ - { - "cell_type": "markdown", - "source": "# House Robber II\n**Difficulty:** Medium\n\n---\nYou are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. All houses at this place are **arranged in a circle**. That means the first house is the neighbor of the last one. Meanwhile, adjacent houses have a security system connected, and **it will automatically contact the police if two adjacent houses were broken into on the same night**.\n\nGiven an integer array `nums` representing the amount of money of each house, return *the maximum amount of money you can rob tonight without alerting the police*.\n\n**Constraints:**\n- `1 <= nums.length <= 100`\n- `0 <= nums[i] <= 1000`", - "metadata": {}, - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49" - }, - { - "cell_type": "markdown", - "source": "## Probelm Explanation:\n\nCertainly! The problem statement describes a scenario where you are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. However, there is a security system in place: adjacent houses have a security system connected, and it will automatically contact the police if two adjacent houses are broken into on the same night.\n\nThe twist in this problem is that the houses are arranged in a circle. That means the first house is the neighbor of the last one. So, robbing the first house has implications for the last house, and vice versa.\n\nThe goal is to find the maximum amount of money you can rob tonight without alerting the police. You need to implement a function that takes an integer array `nums` representing the amount of money in each house and returns the maximum amount of money that can be robbed without triggering the security system.\n\nHere are a few examples to illustrate the problem:\n\n1. **Example 1:**\n ```python\n Input: nums = [2, 3, 2]\n Output: 3\n Explanation: You cannot rob house 1 (money = 2) and then rob house 3 (money = 2) because they are adjacent houses. The optimal strategy is to rob house 2 (money = 3).\n ```\n\n2. **Example 2:**\n ```python\n Input: nums = [1, 2, 3, 1]\n Output: 4\n Explanation: Robbing house 1 (money = 1) and then robbing house 3 (money = 3) results in a total amount of 4. Robbing house 2 is skipped to avoid alerting the police.\n ```\n\n3. **Example 3:**\n ```python\n Input: nums = [1, 2, 3]\n Output: 3\n Explanation: Since the houses are in a circle, you can choose either house 1, 2, or 3. The optimal strategy is to rob house 3 for a total amount of 3.\n ```\n\nThe constraints for the problem are that the length of the `nums` array is between 1 and 100, and the amount of money in each house (`nums[i]`) is between 0 and 1000.\n\n## Solution:\nHere's a Python function to implement this algorithm:", - "metadata": {}, - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76" - }, - { - "cell_type": "code", - "source": "from typing import List\n\nclass Solution:\n def rob(self, nums: List[int]) -> int:\n def simple_rob(nums):\n # Helper function for basic house robbery problem\n prev, curr = 0, 0\n for num in nums:\n # Calculate the maximum amount of money that can be robbed\n # without alerting the police for each house\n prev, curr = curr, max(prev + num, curr)\n return curr\n\n # Check the base cases where the length of nums is 1 or 2\n if len(nums) == 1:\n return nums[0]\n elif len(nums) == 2:\n return max(nums[0], nums[1])\n\n # Case 1: First house is robbed, last house is not\n case1 = simple_rob(nums[:-1])\n\n # Case 2: First house is not robbed, last house is\n case2 = simple_rob(nums[1:])\n\n # Maximum of the two cases\n return max(case1, case2)", - "metadata": { - "trusted": true - }, - "execution_count": 7, - "outputs": [], - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5" - }, - { - "cell_type": "markdown", - "source": "## Explanation:\n\nThe provided code defines a class `Solution` with a method `rob`, which aims to determine the maximum amount of money a professional robber can steal from houses arranged in a circle without alerting the police. Each house contains a certain amount of money, and adjacent houses have a security system that triggers if both are robbed on the same night.\n\nThe code uses dynamic programming to solve the problem efficiently. It contains a helper function `simple_rob` that computes the maximum amount of money that can be robbed from a linear arrangement of houses. The main method `rob` handles the circular arrangement by considering two cases: robbing the first house and not robbing the last, and not robbing the first house and robbing the last. The result is the maximum of these two cases.\n\nThe class is instantiated as `solution`, and the `rob` method is applied to three different scenarios (test cases) to demonstrate its functionality. The final output represents the maximum amount of money the robber can steal without triggering the security system.", - "metadata": {}, - "id": "ece39324-cd9e-47d7-8677-a001878494d9" - }, - { - "cell_type": "markdown", - "source": "## Test cases:\n\nHere's how you can use this solution:", - "metadata": {}, - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244" - }, - { - "cell_type": "code", - "source": "# Example 1:\n\n# Create an instance of the Solution class\nsolution = Solution()\n\nnums1 = [2, 3, 2]\nprint(solution.rob(nums1)) # Output: 3", - "metadata": { - "trusted": true - }, - "execution_count": 8, - "outputs": [ - { - "name": "stdout", - "text": "3\n", - "output_type": "stream" - } - ], - "id": "f12c5a63-b811-4be7-83c2-34ee396b546c" - }, - { - "cell_type": "code", - "source": "# Example 2:\nnums2 = [1, 2, 3, 1]\nprint(solution.rob(nums2)) # Output: 4", - "metadata": { - "trusted": true - }, - "execution_count": 9, - "outputs": [ - { - "name": "stdout", - "text": "4\n", - "output_type": "stream" - } - ], - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3" - }, - { - "cell_type": "code", - "source": "# Example 2:\nnums3 = [1, 2, 3]\nprint(solution.rob(nums3)) # Output: 3", - "metadata": { - "trusted": true - }, - "execution_count": 10, - "outputs": [ - { - "name": "stdout", - "text": "3\n", - "output_type": "stream" - } - ], - "id": "e6e1554f-ae77-410c-8af2-e59e5428166c" - }, - { - "cell_type": "markdown", - "source": "## Time and Space Complexity Analysis\n\nLet's analyze the time and space complexity of the provided code:\n\n### Time Complexity:\nThe time complexity is primarily determined by the `simple_rob` helper function, which has a time complexity of O(N), where N is the number of houses in the input array. The main `rob` function calls `simple_rob` twice, once for the case of robbing the first house and not robbing the last, and once for the case of not robbing the first house and robbing the last. Therefore, the overall time complexity is O(N).\n\n### Space Complexity:\nThe space complexity is O(1) because the space used by the algorithm is constant, regardless of the size of the input array. The only variables used are `prev` and `curr` in the `simple_rob` function, which represent the previous and current maximum amounts of money that can be robbed without alerting the police. These variables are updated iteratively, and no additional data structures are used that scale with the input size. Therefore, the space complexity is constant, or O(1).\n\nIn summary:\n- Time Complexity: O(N)\n- Space Complexity: O(1)", - "metadata": {}, - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2" - }, - { - "cell_type": "markdown", - "source": "## Challenging Exercises:\n\n1. **Optimization Challenge:** Optimize the space complexity of the solution. Can you solve the problem with O(1) space complexity without sacrificing the time complexity?\n\n2. **Circular Robbery Variations:** Consider variations of the circular house robbery problem, such as allowing the robber to skip a certain number of houses or restricting the number of consecutive houses that can be robbed. Modify the solution to accommodate these variations.\n\n**Link to Problem:** [To see the House Robber II problem on LeetCode, click here!](https://leetcode.com/problems/house-robber-ii/)", - "metadata": {}, - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6" - } - ] -} \ No newline at end of file diff --git a/docs/_build/html/_sources/13. One-D Dynamic Programming/70. Climbing Stairs.ipynb b/docs/_build/html/_sources/13. One-D Dynamic Programming/70. Climbing Stairs.ipynb deleted file mode 100644 index b727489..0000000 --- a/docs/_build/html/_sources/13. One-D Dynamic Programming/70. Climbing Stairs.ipynb +++ /dev/null @@ -1,210 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6161252-e815-48d5-a2a3-5444c12e3b49", - "metadata": {}, - "source": [ - "# 70. Climbing Stairs\n", - "\n", - "**Difficulty:** Easy\n", - "\n", - "**Link to Problem:** [To see the Climbing Stairs problem on LeetCode, click here!](https://leetcode.com/problems/climbing-stairs/)\n", - "\n", - "---\n", - "You are climbing a staircase. It takes `n` steps to reach the top.\n", - "\n", - "Each time you can either climb `1` or `2` steps. In how many distinct ways can you climb to the top?\n", - "\n", - "**Constraints:**\n", - "- `1 <= n <= 45`" - ] - }, - { - "cell_type": "markdown", - "id": "fe9e71ae-2099-4eb9-b7a1-ec795ce92c76", - "metadata": {}, - "source": [ - "## Probelm Explanation:\n", - "\n", - "The \"Climbing Stairs\" problem is a classic algorithmic problem that asks you to find the number of distinct ways to climb a staircase with a given number of steps. Here's the problem statement:\n", - "\n", - "You are given a staircase with 'n' steps. Each time you can either climb 1 step or 2 steps. You need to find out how many distinct ways there are to reach the top of the staircase.\n", - "\n", - "For example, if 'n' is 2, there are two ways to climb to the top:\n", - "\n", - "1. Climbing two steps at once.\n", - "2. Climbing one step, and then another step.\n", - "\n", - "If 'n' is 3, there are three ways:\n", - "\n", - "1. Climbing one step, then one step, and finally one step.\n", - "2. Climbing one step, then two steps.\n", - "3. Climbing two steps, then one step.\n", - "\n", - "The problem essentially asks you to find a solution that counts the possible combinations of 1-step and 2-step climbs that can be taken to reach the top of the staircase. It's a classic example of a dynamic programming problem where you can break it down into smaller subproblems and build a solution incrementally, as shown in the code I provided earlier.\n", - "\n", - "## Solution:\n", - "Here's a Python function to implement this algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "aabf7095-07dc-4ab7-876c-ec7213ed0de5", - "metadata": { - "trusted": true - }, - "outputs": [], - "source": [ - "class Solution:\n", - " def climbStairs(self, n: int) -> int:\n", - " # If there are 1 or 2 steps, there are exactly n ways to reach the top.\n", - " if n <= 2:\n", - " return n\n", - "\n", - " # Create an array to store the number of ways to reach each step.\n", - " dp = [0] * (n + 1)\n", - "\n", - " # There is one way to reach the first step (base case).\n", - " dp[1] = 1\n", - "\n", - " # There are two ways to reach the second step (base case).\n", - " dp[2] = 2\n", - "\n", - " # Calculate the number of ways to reach each step from the previous steps.\n", - " for i in range(3, n + 1):\n", - " # The number of ways to reach step 'i' is the sum of the ways to reach\n", - " # the previous two steps, as you can take 1 or 2 steps at a time.\n", - " dp[i] = dp[i - 1] + dp[i - 2]\n", - "\n", - " # The result is the number of ways to reach the top, which is stored in dp[n].\n", - " return dp[n]" - ] - }, - { - "cell_type": "markdown", - "id": "ece39324-cd9e-47d7-8677-a001878494d9", - "metadata": {}, - "source": [ - "## Explanation:\n", - "\n", - "The code defines a class `Solution` with a method `climbStairs` that takes an integer `n` as input and returns the number of distinct ways to climb a staircase with `n` steps.\n", - "\n", - "1. If `n` is 1 or 2, the function returns `n` directly because there are only 1 or 2 distinct ways to reach the top in those cases.\n", - "\n", - "2. For `n` greater than 2, the code uses dynamic programming to calculate the number of ways to reach each step. It creates an array `dp` of length `n + 1` to store these values.\n", - "\n", - "3. The `dp[1]` and `dp[2]` are initialized to 1 and 2, respectively. This is because there is only one way to reach the first step (by taking 1 step), and there are two ways to reach the second step (by taking 2 steps or two 1-step climbs).\n", - "\n", - "4. The code then uses a loop to fill in the `dp` array for steps 3 and above. For each step `i` from 3 to `n`, it calculates the number of ways to reach that step by adding the number of ways to reach the previous two steps, as you can either take 1 step or 2 steps at a time.\n", - "\n", - "5. Finally, the function returns the value stored in `dp[n]`, which represents the total number of distinct ways to climb the staircase with `n` steps." - ] - }, - { - "cell_type": "markdown", - "id": "a54ea5b7-c53f-46c0-a44f-ef769ac68244", - "metadata": {}, - "source": [ - "## Test cases:\n", - "\n", - "Here's how you can use this solution:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "f12c5a63-b811-4be7-83c2-34ee396b546c", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Example 1 - Input: n = 2, Output: 2\n" - ] - } - ], - "source": [ - "# Example 1:\n", - "n = 2\n", - "solution = Solution()\n", - "print(f\"Example 1 - Input: n = {n}, Output: {solution.climbStairs(n)}\") # Output should be 2" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "364aa061-a452-45eb-96db-36f7dbdbdcb3", - "metadata": { - "trusted": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Example 2 - Input: n = 3, Output: 3\n" - ] - } - ], - "source": [ - "# Example 2:\n", - "n = 3\n", - "print(f\"Example 2 - Input: n = {n}, Output: {solution.climbStairs(n)}\") # Output should be 3\n" - ] - }, - { - "cell_type": "markdown", - "id": "7d9dd448-c5f5-4192-8aa5-7c70ec7f42e2", - "metadata": {}, - "source": [ - "## Time and Space Complexity Analysis\n", - "\n", - "Time Complexity:\n", - "The time complexity of the solution is O(n) because we use a single for loop that iterates from 3 to n to fill the `dp` array. In each iteration, we perform constant time operations (addition and assignment). Therefore, the time complexity is linear with respect to the input value `n`.\n", - "\n", - "Space Complexity:\n", - "The space complexity of the solution is O(n) as well. We use an array `dp` of length `n + 1` to store the number of ways to reach each step. The size of this array is directly proportional to the input value `n`, which makes the space complexity linear in terms of `n`. The rest of the variables used in the function (e.g., `i`) occupy constant space and do not contribute significantly to the overall space complexity.\n", - "\n", - "In summary, the time complexity is O(n), and the space complexity is O(n) for this dynamic programming solution to the \"Climbing Stairs\" problem." - ] - }, - { - "cell_type": "markdown", - "id": "037b210a-555b-4da3-8130-b74d1e4f33f6", - "metadata": {}, - "source": [ - "## Challenging Exercises:\n", - "\n", - "1. **Generalized Step Sizes**: Instead of being limited to 1 step or 2 steps, consider a scenario where you can take steps of sizes `[1, 2, 3]`. Implement a function that calculates the number of ways to climb the staircase with these different step sizes.\n", - "\n", - "2. **Minimize Steps**: Given an integer `n`, find the minimum number of steps required to reach the top of the staircase. Return both the minimum number of steps and the specific sequence of steps taken." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/_build/html/_sources/13. One-D Dynamic Programming/README.md b/docs/_build/html/_sources/13. One-D Dynamic Programming/README.md deleted file mode 100644 index 73f4de3..0000000 --- a/docs/_build/html/_sources/13. One-D Dynamic Programming/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# 1-D Dynamic Programming Problems - Blind 75 LeetCode - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [70. Climbing Stairs](https://leetcode.com/problems/climbing-stairs/) | Easy | -| [198. House Robber](https://leetcode.com/problems/house-robber/) | Medium | -| [213. House Robber II](https://leetcode.com/problems/house-robber-ii/) | Medium | -| [5. Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/) | Medium | -| [647. Palindromic Substrings](https://leetcode.com/problems/palindromic-substrings/) | Medium | -| [91. Decode Ways](https://leetcode.com/problems/decode-ways/) | Medium | -| [322. Coin Change](https://leetcode.com/problems/coin-change/) | Medium | -| [152. Maximum Product Subarray](https://leetcode.com/problems/maximum-product-subarray/) | Medium | -| [139. Word Break](https://leetcode.com/problems/word-break/) | Medium | -| [300. Longest Increasing Subsequence](https://leetcode.com/problems/longest-increasing-subsequence/) | Medium | - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -Happy coding! \ No newline at end of file diff --git a/docs/_build/html/_sources/14. Two-D Dynamic Programming/README.md b/docs/_build/html/_sources/14. Two-D Dynamic Programming/README.md deleted file mode 100644 index 8bab876..0000000 --- a/docs/_build/html/_sources/14. Two-D Dynamic Programming/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# Blind 75 LeetCode Problems - -This repository contains a curated list of 75 LeetCode problems that are commonly known as the "Blind 75." These problems cover a wide range of data structures and algorithms and are frequently asked in technical interviews. Solving these problems can help you build a strong foundation in algorithmic problem-solving. - -## Problem List - -### 2-D Dynamic Programming - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [62. Unique Paths](https://leetcode.com/problems/unique-paths/) | Medium | -| [1143. Longest Common Subsequence](https://leetcode.com/problems/longest-common-subsequence/) | Medium | - -## How to Use - -1. Clone or download this repository to your local machine. - -```bash -git clone https://github.com/mohsentabibian/LeetCode-Solutions/Blind-75-LeetCode.git -``` - -2. Navigate to the directory of the specific problem you want to solve. - -```bash -cd Blind-75-LeetCode/Problem-Directory -``` - -3. Open the problem's directory to find its description, code template, and solution(s). - -4. Solve the problem using your preferred programming language. - -5. Check the solution(s) provided in the directory for reference and to compare your solution. - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -## Disclaimer - -This repository is meant for educational purposes and to help individuals prepare for technical interviews. Please respect LeetCode's terms of use and guidelines when using this repository. - -Happy coding! \ No newline at end of file diff --git a/docs/_build/html/_sources/15. Greedy/README.md b/docs/_build/html/_sources/15. Greedy/README.md deleted file mode 100644 index 82b6543..0000000 --- a/docs/_build/html/_sources/15. Greedy/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# Blind 75 LeetCode Problems - -This repository contains a curated list of 75 LeetCode problems that are commonly known as the "Blind 75." These problems cover a wide range of data structures and algorithms and are frequently asked in technical interviews. Solving these problems can help you build a strong foundation in algorithmic problem-solving. - -## Problem List - -### Greedy - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [53. Maximum Subarray](https://leetcode.com/problems/maximum-subarray/) | Easy | -| [55. Jump Game](https://leetcode.com/problems/jump-game/) | Medium | - -## How to Use - -1. Clone or download this repository to your local machine. - -```bash -git clone https://github.com/mohsentabibian/LeetCode-Solutions/Blind-75-LeetCode.git -``` - -2. Navigate to the directory of the specific problem you want to solve. - -```bash -cd Blind-75-LeetCode/Problem-Directory -``` - -3. Open the problem's directory to find its description, code template, and solution(s). - -4. Solve the problem using your preferred programming language. - -5. Check the solution(s) provided in the directory for reference and to compare your solution. - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -## Disclaimer - -This repository is meant for educational purposes and to help individuals prepare for technical interviews. Please respect LeetCode's terms of use and guidelines when using this repository. - -Happy coding! \ No newline at end of file diff --git a/docs/_build/html/_sources/16. Intervals/README.md b/docs/_build/html/_sources/16. Intervals/README.md deleted file mode 100644 index a57713e..0000000 --- a/docs/_build/html/_sources/16. Intervals/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# Blind 75 LeetCode Problems - -This repository contains a curated list of 75 LeetCode problems that are commonly known as the "Blind 75." These problems cover a wide range of data structures and algorithms and are frequently asked in technical interviews. Solving these problems can help you build a strong foundation in algorithmic problem-solving. - -## Problem List - -### Intervals - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [57. Insert Interval](https://leetcode.com/problems/insert-interval/) | Hard | -| [56. Merge Intervals](https://leetcode.com/problems/merge-intervals/) | Medium | -| [435. Non Overlapping Intervals](https://leetcode.com/problems/non-overlapping-intervals/) | Medium | -| [252. Meeting Rooms](https://leetcode.com/problems/meeting-rooms/) | Easy | -| [253. Meeting Rooms II](https://leetcode.com/problems/meeting-rooms-ii/) | Medium | - -## How to Use - -1. Clone or download this repository to your local machine. - -```bash -git clone https://github.com/mohsentabibian/LeetCode-Solutions/Blind-75-LeetCode.git -``` - -2. Navigate to the directory of the specific problem you want to solve. - -```bash -cd Blind-75-LeetCode/Problem-Directory -``` - -3. Open the problem's directory to find its description, code template, and solution(s). - -4. Solve the problem using your preferred programming language. - -5. Check the solution(s) provided in the directory for reference and to compare your solution. - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -## Disclaimer - -This repository is meant for educational purposes and to help individuals prepare for technical interviews. Please respect LeetCode's terms of use and guidelines when using this repository. - -Happy coding! \ No newline at end of file diff --git a/docs/_build/html/_sources/17. Math Geometry/README.md b/docs/_build/html/_sources/17. Math Geometry/README.md deleted file mode 100644 index 8b2f180..0000000 --- a/docs/_build/html/_sources/17. Math Geometry/README.md +++ /dev/null @@ -1,48 +0,0 @@ -# Blind 75 LeetCode Problems - -This repository contains a curated list of 75 LeetCode problems that are commonly known as the "Blind 75." These problems cover a wide range of data structures and algorithms and are frequently asked in technical interviews. Solving these problems can help you build a strong foundation in algorithmic problem-solving. - -## Problem List - -### Math & Geometry - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [48. Rotate Image](https://leetcode.com/problems/rotate-image/) | Medium | -| [54. Spiral Matrix](https://leetcode.com/problems/spiral-matrix/) | Medium | -| [73. Set Matrix Zeroes](https://leetcode.com/problems/set-matrix-zeroes/) | Medium | - -## How to Use - -1. Clone or download this repository to your local machine. - -```bash -git clone https://github.com/mohsentabibian/LeetCode-Solutions/Blind-75-LeetCode.git -``` - -2. Navigate to the directory of the specific problem you want to solve. - -```bash -cd Blind-75-LeetCode/Problem-Directory -``` - -3. Open the problem's directory to find its description, code template, and solution(s). - -4. Solve the problem using your preferred programming language. - -5. Check the solution(s) provided in the directory for reference and to compare your solution. - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -## Disclaimer - -This repository is meant for educational purposes and to help individuals prepare for technical interviews. Please respect LeetCode's terms of use and guidelines when using this repository. - -Happy coding! \ No newline at end of file diff --git a/docs/_build/html/_sources/18. Bit Manipulation/README.md b/docs/_build/html/_sources/18. Bit Manipulation/README.md deleted file mode 100644 index 05b2fef..0000000 --- a/docs/_build/html/_sources/18. Bit Manipulation/README.md +++ /dev/null @@ -1,51 +0,0 @@ -# Blind 75 LeetCode Problems - -This repository contains a curated list of 75 LeetCode problems that are commonly known as the "Blind 75." These problems cover a wide range of data structures and algorithms and are frequently asked in technical interviews. Solving these problems can help you build a strong foundation in algorithmic problem-solving. - -## Problem List - -### Bit Manupulation - -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [191. Number of 1 Bits](https://leetcode.com/problems/number-of-1-bits/) | Easy | -| [338. Counting Bits](https://leetcode.com/problems/counting-bits/) | Medium | -| [190. Reverse Bits](https://leetcode.com/problems/reverse-bits/) | Easy | -| [268. Missing Number](https://leetcode.com/problems/missing-number/) | Easy | -| [371. Sum of Two Integers](https://leetcode.com/problems/sum-of-two-integers/) | Medium | - - -## How to Use - -1. Clone or download this repository to your local machine. - -```bash -git clone https://github.com/mohsentabibian/LeetCode-Solutions/Blind-75-LeetCode.git -``` - -2. Navigate to the directory of the specific problem you want to solve. - -```bash -cd Blind-75-LeetCode/Problem-Directory -``` - -3. Open the problem's directory to find its description, code template, and solution(s). - -4. Solve the problem using your preferred programming language. - -5. Check the solution(s) provided in the directory for reference and to compare your solution. - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -## Disclaimer - -This repository is meant for educational purposes and to help individuals prepare for technical interviews. Please respect LeetCode's terms of use and guidelines when using this repository. - -Happy coding! \ No newline at end of file diff --git a/docs/_build/html/_sources/Book.ipynb b/docs/_build/html/_sources/Book.ipynb deleted file mode 100644 index d400192..0000000 --- a/docs/_build/html/_sources/Book.ipynb +++ /dev/null @@ -1,373 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "!python -m pip install --upgrade pip\n", - "%pip install jupyter-book" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/workspaces/LeetCode-Solutions\n" - ] - } - ], - "source": [ - "%cd /workspaces/LeetCode-Solutions" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "!jupyter-book toc migrate /workspaces/LeetCode-Solutions/_toc.yml -o /workspaces/LeetCode-Solutions/_toc.yml" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[32m\u001b[1mRunning Jupyter-Book v0.15.1\u001b[0m\n", - "\u001b[34m\u001b[1mSource Folder: \u001b[0m/workspaces/LeetCode-Solutions\n", - "\u001b[34m\u001b[1mConfig Path: \u001b[0m/workspaces/LeetCode-Solutions/_config.yml\n", - "\u001b[34m\u001b[1mOutput Path: \u001b[0m/workspaces/LeetCode-Solutions/_build/html\n", - "\u001b[01mRunning Sphinx v5.0.2\u001b[39;49;00m\n", - "\u001b[01mmaking output directory... \u001b[39;49;00mdone\n", - "[etoc] Changing master_doc to 'README'\n", - "\u001b[01mmyst v0.18.1:\u001b[39;49;00m MdParserConfig(commonmark_only=False, gfm_only=False, enable_extensions=['colon_fence', 'dollarmath', 'linkify', 'substitution', 'tasklist'], disable_syntax=[], all_links_external=False, url_schemes=['mailto', 'http', 'https'], ref_domains=None, highlight_code_blocks=True, number_code_blocks=[], title_to_header=False, heading_anchors=None, heading_slug_func=None, footnote_transition=True, words_per_minute=200, sub_delimiters=('{', '}'), linkify_fuzzy_links=True, dmath_allow_labels=True, dmath_allow_space=True, dmath_allow_digits=True, dmath_double_inline=False, update_mathjax=True, mathjax_classes='tex2jax_process|mathjax_process|math|output_area')\n", - "\u001b[01mmyst-nb v0.17.2:\u001b[39;49;00m NbParserConfig(custom_formats={}, metadata_key='mystnb', cell_metadata_key='mystnb', kernel_rgx_aliases={}, execution_mode='auto', execution_cache_path='', execution_excludepatterns=[], execution_timeout=30, execution_in_temp=False, execution_allow_errors=False, execution_raise_on_error=False, execution_show_tb=False, merge_streams=False, render_plugin='default', remove_code_source=False, remove_code_outputs=False, code_prompt_show='Show code cell {type}', code_prompt_hide='Hide code cell {type}', number_source_lines=False, output_stderr='show', render_text_lexer='myst-ansi', render_error_lexer='ipythontb', render_image_options={}, render_figure_options={}, render_markdown_format='commonmark', output_folder='build', append_css=True, metadata_to_fm=False)\n", - "Using jupyter-cache at: /workspaces/LeetCode-Solutions/_build/.jupyter_cache\n", - "\u001b[01mbuilding [mo]: \u001b[39;49;00mtargets for 0 po files that are out of date\n", - "\u001b[01mbuilding [html]: \u001b[39;49;00mtargets for 77 source files that are out of date\n", - "\u001b[01mupdating environment: \u001b[39;49;00m[new config] 77 added, 0 changed, 0 removed\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/1. Two Sum.ipynb: Executing notebook using local CWD [mystnb] \n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/1. Two Sum.ipynb: Executed notebook in 1.26 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/128. Longest Consecutive Sequence.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/128. Longest Consecutive Sequence.ipynb: Executed notebook in 1.07 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/217. Contains Duplicate.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/217. Contains Duplicate.ipynb: Executed notebook in 1.05 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/238. Product of Array Except Self.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/238. Product of Array Except Self.ipynb: Executed notebook in 0.98 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/242. Valid Anagram.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/242. Valid Anagram.ipynb: Executed notebook in 0.96 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/347. Top K Frequent Elements.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/347. Top K Frequent Elements.ipynb: Executed notebook in 1.00 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/49. Group Anagrams.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/49. Group Anagrams.ipynb: Executed notebook in 1.07 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/659. Encode and Decode Strings.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/01. Array Hashing/659. Encode and Decode Strings.ipynb: Executed notebook in 0.93 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/02. Two Pointers/11. Container With Most Water.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/02. Two Pointers/11. Container With Most Water.ipynb: Executed notebook in 0.88 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/02. Two Pointers/125. Valid Palindrome.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/02. Two Pointers/125. Valid Palindrome.ipynb: Executed notebook in 0.98 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/02. Two Pointers/15. 3Sum.ipynb: Executing notebook using local CWD [mystnb] \n", - "/workspaces/LeetCode-Solutions/02. Two Pointers/15. 3Sum.ipynb: Executed notebook in 1.08 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/03. Sliding Window/121. Best Time to Buy and Sell Stock.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/03. Sliding Window/121. Best Time to Buy and Sell Stock.ipynb: Executed notebook in 0.92 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/03. Sliding Window/3. Longest Substring Without Repeating Characters.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/03. Sliding Window/3. Longest Substring Without Repeating Characters.ipynb: Executed notebook in 0.90 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/03. Sliding Window/424. Longest Repeating Character Replacement.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/03. Sliding Window/424. Longest Repeating Character Replacement.ipynb: Executed notebook in 1.09 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/03. Sliding Window/76. Minimum Window Substring.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/03. Sliding Window/76. Minimum Window Substring.ipynb: Executed notebook in 1.09 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/04. Stack/20. Valid Parentheses.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/04. Stack/20. Valid Parentheses.ipynb: Executed notebook in 0.98 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/05. Binary Search/153. Find Minimum in Rotated Sorted Array.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/05. Binary Search/153. Find Minimum in Rotated Sorted Array.ipynb: Executed notebook in 1.15 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/05. Binary Search/33. Search in Rotated Sorted Array.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/05. Binary Search/33. Search in Rotated Sorted Array.ipynb: Executed notebook in 1.08 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/141. Linked List Cycle.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/141. Linked List Cycle.ipynb: Executed notebook in 1.28 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/143. Reorder List.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/143. Reorder List.ipynb: Executed notebook in 1.01 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/19. Remove Nth Node From End of List.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/19. Remove Nth Node From End of List.ipynb: Executed notebook in 1.10 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/206. Reverse Linked List.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/206. Reverse Linked List.ipynb: Executed notebook in 1.14 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/21. Merge Two Sorted Lists.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/21. Merge Two Sorted Lists.ipynb: Executed notebook in 0.91 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/23. Merge k Sorted Lists.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/06. Linked List/23. Merge k Sorted Lists.ipynb: Executed notebook in 1.13 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/100. Same Tree.ipynb: Executing notebook using local CWD [mystnb] \n", - "/workspaces/LeetCode-Solutions/07. Trees/100. Same Tree.ipynb: Executed notebook in 1.07 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/102. Binary Tree Level Order Traversal.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/102. Binary Tree Level Order Traversal.ipynb: Executed notebook in 0.99 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/104. Maximum Depth of Binary Tree.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/104. Maximum Depth of Binary Tree.ipynb: Executed notebook in 0.91 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/105. Construct Binary Tree from Preorder and Inorder Traversal.ipynb: Executed notebook in 1.17 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/124. Binary Tree Maximum Path Sum.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/124. Binary Tree Maximum Path Sum.ipynb: Executed notebook in 0.99 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/199. Binary Tree Right Side View.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/199. Binary Tree Right Side View.ipynb: Executed notebook in 1.07 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/226. Invert Binary Tree.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/226. Invert Binary Tree.ipynb: Executed notebook in 0.96 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/230. Kth Smallest Element in a BST.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/230. Kth Smallest Element in a BST.ipynb: Executed notebook in 0.98 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/235. Lowest Common Ancestor of a Binary Search Tree.ipynb: Executed notebook in 1.11 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/297. Serialize and Deserialize Binary Tree.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/297. Serialize and Deserialize Binary Tree.ipynb: Executed notebook in 0.98 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/572. Subtree of Another Tree.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/572. Subtree of Another Tree.ipynb: Executed notebook in 1.16 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/98. Validate Binary Search Tree.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/07. Trees/98. Validate Binary Search Tree.ipynb: Executed notebook in 1.15 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/08. Tries/208. Implement Trie (Prefix Tree).ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/08. Tries/208. Implement Trie (Prefix Tree).ipynb: Executed notebook in 0.98 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/08. Tries/211. Design Add and Search Words Data Structure.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/08. Tries/211. Design Add and Search Words Data Structure.ipynb: Executed notebook in 1.05 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/08. Tries/212. Word Search II.ipynb: Executing notebook using local CWD [mystnb] \n", - "/workspaces/LeetCode-Solutions/08. Tries/212. Word Search II.ipynb: Executed notebook in 1.27 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/09. Heap - Priority Queue/1046. Last Stone Weight.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/09. Heap - Priority Queue/1046. Last Stone Weight.ipynb: Executed notebook in 0.93 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/09. Heap - Priority Queue/295. Find Median from Data Stream.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/09. Heap - Priority Queue/295. Find Median from Data Stream.ipynb: Executed notebook in 1.06 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/09. Heap - Priority Queue/703. Kth Largest Element in a Stream.ipynb: Executed notebook in 0.87 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/10. Backtracking/39. Combination Sum.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/10. Backtracking/39. Combination Sum.ipynb: Executed notebook in 1.24 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/10. Backtracking/79. Word Search.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/10. Backtracking/79. Word Search.ipynb: Executed notebook in 4.03 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/133. Clone Graph.ipynb: Executing notebook using local CWD [mystnb] \n", - "/workspaces/LeetCode-Solutions/11. Graphs/133. Clone Graph.ipynb: Executed notebook in 1.08 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/178. Graph Valid Tree.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/178. Graph Valid Tree.ipynb: Executed notebook in 1.12 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/200. Number of Islands.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/200. Number of Islands.ipynb: Executed notebook in 1.08 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/207. Course Schedule.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/207. Course Schedule.ipynb: Executed notebook in 1.09 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/3651. Number of Connected Components in an Undirected Graph.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/3651. Number of Connected Components in an Undirected Graph.ipynb: Executed notebook in 4.02 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/417. Pacific Atlantic Water Flow.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/11. Graphs/417. Pacific Atlantic Water Flow.ipynb: Executed notebook in 0.87 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/12. Advanced Graphs/892. Alien Dictionary.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/12. Advanced Graphs/892. Alien Dictionary.ipynb: Executed notebook in 1.12 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/13. One-D Dynamic Programming/198. House Robber.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/13. One-D Dynamic Programming/198. House Robber.ipynb: Executed notebook in 0.99 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/13. One-D Dynamic Programming/213. House Robber II.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/13. One-D Dynamic Programming/213. House Robber II.ipynb: Executed notebook in 1.08 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/13. One-D Dynamic Programming/70. Climbing Stairs.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/13. One-D Dynamic Programming/70. Climbing Stairs.ipynb: Executed notebook in 1.06 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/Book.ipynb: Executing notebook using local CWD [mystnb] \n", - "\u001b[01mreading sources... \u001b[39;49;00m[100%] \u001b[35mSECURITY\u001b[39;49;00m \n", - "\u001b[91m/workspaces/LeetCode-Solutions/07. Trees/572. Subtree of Another Tree.ipynb:30008: WARNING: Non-consecutive header level increase; H1 to H3 [myst.header]\u001b[39;49;00m\n", - "\u001b[91m/workspaces/LeetCode-Solutions/Book.ipynb: WARNING: Executing notebook failed: CellTimeoutError [mystnb.exec]\u001b[39;49;00m\n", - "\u001b[91m/workspaces/LeetCode-Solutions/Book.ipynb: WARNING: Notebook exception traceback saved in: /workspaces/LeetCode-Solutions/_build/html/reports/Book.err.log [mystnb.exec]\u001b[39;49;00m\n", - "\u001b[01mlooking for now-outdated files... \u001b[39;49;00mnone found\n", - "\u001b[01mpickling environment... \u001b[39;49;00mdone\n", - "\u001b[01mchecking consistency... \u001b[39;49;00m\u001b[91m/workspaces/LeetCode-Solutions/Book.ipynb: WARNING: document isn't included in any toctree\u001b[39;49;00m\n", - "\u001b[91m/workspaces/LeetCode-Solutions/CODE_OF_CONDUCT.md: WARNING: document isn't included in any toctree\u001b[39;49;00m\n", - "\u001b[91m/workspaces/LeetCode-Solutions/CONTRIBUTING.md: WARNING: document isn't included in any toctree\u001b[39;49;00m\n", - "\u001b[91m/workspaces/LeetCode-Solutions/SECURITY.md: WARNING: document isn't included in any toctree\u001b[39;49;00m\n", - "done\n", - "\u001b[01mpreparing documents... \u001b[39;49;00mdone\n", - "\u001b[01mwriting output... \u001b[39;49;00m[ 94%] \u001b[32mBook\u001b[39;49;00m raph\u001b[39;49;00m0m\r" - ] - } - ], - "source": [ - "!jupyter-book build ." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "!jupyter-book build /workspaces/LeetCode-Solutions/ --builder pdfhtml" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "Click here to view your Jupyter Book" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from IPython.display import HTML\n", - "HTML('Click here to view your Jupyter Book')\n" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "\u001b[92m===============================================================================\u001b[0m\n", - "\n", - "Your book template can be found at\n", - "\n", - " mybook/\n", - "\n", - "\u001b[92m===============================================================================\u001b[0m\n", - "\n" - ] - } - ], - "source": [ - "!jupyter-book create mybook" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[32m\u001b[1mRunning Jupyter-Book v0.15.1\u001b[0m\n", - "\u001b[34m\u001b[1mSource Folder: \u001b[0m/workspaces/LeetCode-Solutions/mybook\n", - "\u001b[34m\u001b[1mConfig Path: \u001b[0m/workspaces/LeetCode-Solutions/mybook/_config.yml\n", - "\u001b[34m\u001b[1mOutput Path: \u001b[0m/workspaces/LeetCode-Solutions/mybook/_build/html\n", - "[sphinxcontrib-bibtex] Beware that docutils versions 0.18 and 0.19 (you are running 0.18.1) are known to generate invalid html for citations. If this issue affects you, please use docutils<0.18 (or >=0.20 once released) instead. For more details, see https://sourceforge.net/p/docutils/patches/195/\n", - "\u001b[01mRunning Sphinx v5.0.2\u001b[39;49;00m\n", - "[etoc] Changing master_doc to 'intro'\n", - "checking bibtex cache... out of date\n", - "parsing bibtex file /workspaces/LeetCode-Solutions/mybook/references.bib... parsed 5 entries\n", - "\u001b[01mmyst v0.18.1:\u001b[39;49;00m MdParserConfig(commonmark_only=False, gfm_only=False, enable_extensions=['colon_fence', 'dollarmath', 'linkify', 'substitution', 'tasklist'], disable_syntax=[], all_links_external=False, url_schemes=['mailto', 'http', 'https'], ref_domains=None, highlight_code_blocks=True, number_code_blocks=[], title_to_header=False, heading_anchors=None, heading_slug_func=None, footnote_transition=True, words_per_minute=200, sub_delimiters=('{', '}'), linkify_fuzzy_links=True, dmath_allow_labels=True, dmath_allow_space=True, dmath_allow_digits=True, dmath_double_inline=False, update_mathjax=True, mathjax_classes='tex2jax_process|mathjax_process|math|output_area')\n", - "\u001b[01mmyst-nb v0.17.2:\u001b[39;49;00m NbParserConfig(custom_formats={}, metadata_key='mystnb', cell_metadata_key='mystnb', kernel_rgx_aliases={}, execution_mode='force', execution_cache_path='', execution_excludepatterns=[], execution_timeout=30, execution_in_temp=False, execution_allow_errors=False, execution_raise_on_error=False, execution_show_tb=False, merge_streams=False, render_plugin='default', remove_code_source=False, remove_code_outputs=False, code_prompt_show='Show code cell {type}', code_prompt_hide='Hide code cell {type}', number_source_lines=False, output_stderr='show', render_text_lexer='myst-ansi', render_error_lexer='ipythontb', render_image_options={}, render_figure_options={}, render_markdown_format='commonmark', output_folder='build', append_css=True, metadata_to_fm=False)\n", - "Using jupyter-cache at: /workspaces/LeetCode-Solutions/mybook/_build/.jupyter_cache\n", - "\u001b[01mbuilding [mo]: \u001b[39;49;00mtargets for 0 po files that are out of date\n", - "\u001b[01mbuilding [html]: \u001b[39;49;00mtargets for 14 source files that are out of date\n", - "\u001b[01mupdating environment: \u001b[39;49;00m[new config] 14 added, 0 changed, 0 removed\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/1. Two Sum.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/1. Two Sum.ipynb: Executed notebook in 1.35 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/128. Longest Consecutive Sequence.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/128. Longest Consecutive Sequence.ipynb: Executed notebook in 1.09 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/217. Contains Duplicate.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/217. Contains Duplicate.ipynb: Executed notebook in 1.04 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/238. Product of Array Except Self.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/238. Product of Array Except Self.ipynb: Executed notebook in 4.02 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/242. Valid Anagram.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/242. Valid Anagram.ipynb: Executed notebook in 0.97 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/347. Top K Frequent Elements.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/347. Top K Frequent Elements.ipynb: Executed notebook in 1.14 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/49. Group Anagrams.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/49. Group Anagrams.ipynb: Executed notebook in 0.88 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/659. Encode and Decode Strings.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/659. Encode and Decode Strings.ipynb: Executed notebook in 1.10 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/11. Container With Most Water.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/11. Container With Most Water.ipynb: Executed notebook in 1.12 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/125. Valid Palindrome.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/125. Valid Palindrome.ipynb: Executed notebook in 0.98 seconds [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/15. 3Sum.ipynb: Executing notebook using local CWD [mystnb]\n", - "/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/15. 3Sum.ipynb: Executed notebook in 0.83 seconds [mystnb]\n", - "\u001b[01mreading sources... \u001b[39;49;00m[100%] \u001b[35mintro\u001b[39;49;00m \n", - "\u001b[01mlooking for now-outdated files... \u001b[39;49;00mnone found\n", - "\u001b[01mpickling environment... \u001b[39;49;00mdone\n", - "\u001b[01mchecking consistency... \u001b[39;49;00m\u001b[91m/workspaces/LeetCode-Solutions/mybook/01. Array Hashing/README.md: WARNING: document isn't included in any toctree\u001b[39;49;00m\n", - "\u001b[91m/workspaces/LeetCode-Solutions/mybook/02. Two Pointers/README.md: WARNING: document isn't included in any toctree\u001b[39;49;00m\n", - "done\n", - "\u001b[01mpreparing documents... \u001b[39;49;00mdone\n", - "\u001b[01mwriting output... \u001b[39;49;00m[100%] \u001b[32mintro\u001b[39;49;00m \n", - "\u001b[01mgenerating indices... \u001b[39;49;00mgenindex done\n", - "\u001b[01mwriting additional pages... \u001b[39;49;00msearch done\n", - "\u001b[01mcopying static files... \u001b[39;49;00mdone\n", - "\u001b[01mcopying extra files... \u001b[39;49;00mdone\n", - "\u001b[01mdumping search index in English (code: en)... \u001b[39;49;00mdone\n", - "\u001b[01mdumping object inventory... \u001b[39;49;00mdone\n", - "[etoc] missing index.html written as redirect to 'intro.html'\n", - "\u001b[01mbuild succeeded, 2 warnings.\u001b[39;49;00m\n", - "\n", - "The HTML pages are in mybook/_build/html.\n", - "\n", - "\u001b[92m===============================================================================\u001b[0m\n", - "\n", - "Finished generating HTML for book.\n", - "Your book's HTML pages are here:\n", - " mybook/_build/html/\n", - "You can look at your book by opening this file in a browser:\n", - " mybook/_build/html/index.html\n", - "Or paste this line directly into your browser bar:\n", - " file:///workspaces/LeetCode-Solutions/mybook/_build/html/index.html \n", - "\n", - "\u001b[92m===============================================================================\u001b[0m\n", - "\n" - ] - } - ], - "source": [ - "!jupyter-book build mybook" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "format: jb-book\n", - "root: intro\n", - "\n" - ] - } - ], - "source": [ - "!jupyter-book toc from-project /workspaces/LeetCode-Solutions/mybook/ -f jb-book" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/docs/_build/html/_sources/CODE_OF_CONDUCT.md b/docs/_build/html/_sources/CODE_OF_CONDUCT.md deleted file mode 100644 index 5fe5041..0000000 --- a/docs/_build/html/_sources/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,128 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -We as members, contributors, and leaders pledge to make participation in our -community a harassment-free experience for everyone, regardless of age, body -size, visible or invisible disability, ethnicity, sex characteristics, gender -identity and expression, level of experience, education, socio-economic status, -nationality, personal appearance, race, religion, or sexual identity -and orientation. - -We pledge to act and interact in ways that contribute to an open, welcoming, -diverse, inclusive, and healthy community. - -## Our Standards - -Examples of behavior that contributes to a positive environment for our -community include: - -* Demonstrating empathy and kindness toward other people -* Being respectful of differing opinions, viewpoints, and experiences -* Giving and gracefully accepting constructive feedback -* Accepting responsibility and apologizing to those affected by our mistakes, - and learning from the experience -* Focusing on what is best not just for us as individuals, but for the - overall community - -Examples of unacceptable behavior include: - -* The use of sexualized language or imagery, and sexual attention or - advances of any kind -* Trolling, insulting or derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or email - address, without their explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Enforcement Responsibilities - -Community leaders are responsible for clarifying and enforcing our standards of -acceptable behavior and will take appropriate and fair corrective action in -response to any behavior that they deem inappropriate, threatening, offensive, -or harmful. - -Community leaders 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, and will communicate reasons for moderation -decisions when appropriate. - -## Scope - -This Code of Conduct applies within all community spaces, and also applies when -an individual is officially representing the community in public spaces. -Examples of representing our community include using an official e-mail address, -posting via an official social media account, or acting as an appointed -representative at an online or offline event. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported to the community leaders responsible for enforcement at -Email. -All complaints will be reviewed and investigated promptly and fairly. - -All community leaders are obligated to respect the privacy and security of the -reporter of any incident. - -## Enforcement Guidelines - -Community leaders will follow these Community Impact Guidelines in determining -the consequences for any action they deem in violation of this Code of Conduct: - -### 1. Correction - -**Community Impact**: Use of inappropriate language or other behavior deemed -unprofessional or unwelcome in the community. - -**Consequence**: A private, written warning from community leaders, providing -clarity around the nature of the violation and an explanation of why the -behavior was inappropriate. A public apology may be requested. - -### 2. Warning - -**Community Impact**: A violation through a single incident or series -of actions. - -**Consequence**: A warning with consequences for continued behavior. No -interaction with the people involved, including unsolicited interaction with -those enforcing the Code of Conduct, for a specified period of time. This -includes avoiding interactions in community spaces as well as external channels -like social media. Violating these terms may lead to a temporary or -permanent ban. - -### 3. Temporary Ban - -**Community Impact**: A serious violation of community standards, including -sustained inappropriate behavior. - -**Consequence**: A temporary ban from any sort of interaction or public -communication with the community for a specified period of time. No public or -private interaction with the people involved, including unsolicited interaction -with those enforcing the Code of Conduct, is allowed during this period. -Violating these terms may lead to a permanent ban. - -### 4. Permanent Ban - -**Community Impact**: Demonstrating a pattern of violation of community -standards, including sustained inappropriate behavior, harassment of an -individual, or aggression toward or disparagement of classes of individuals. - -**Consequence**: A permanent ban from any sort of public interaction within -the community. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], -version 2.0, available at -https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. - -Community Impact Guidelines were inspired by [Mozilla's code of conduct -enforcement ladder](https://github.com/mozilla/diversity). - -[homepage]: https://www.contributor-covenant.org - -For answers to common questions about this code of conduct, see the FAQ at -https://www.contributor-covenant.org/faq. Translations are available at -https://www.contributor-covenant.org/translations. diff --git a/docs/_build/html/_sources/CONTRIBUTING.md b/docs/_build/html/_sources/CONTRIBUTING.md deleted file mode 100644 index ca794ef..0000000 --- a/docs/_build/html/_sources/CONTRIBUTING.md +++ /dev/null @@ -1,79 +0,0 @@ -# Contributing Guidelines - -Thank you for considering contributing to the Blind 75 LeetCode repository! We welcome contributions from the community to help improve this resource and make it even more valuable. - -Please take a moment to review this document to understand how you can contribute. - -## Table of Contents -- [Ways to Contribute](#ways-to-contribute) -- [Getting Started](#getting-started) -- [Contributing Process](#contributing-process) -- [Code of Conduct](#code-of-conduct) - -## Ways to Contribute - -There are several ways you can contribute to this repository: - -1. **Suggest Improvements**: If you have ideas for making the Blind 75 LeetCode repository better, please open an issue to discuss your suggestions. - -2. **Report Issues**: If you encounter any issues with the existing content or code, please open an issue and provide as much detail as possible. - -3. **Contribute Solutions**: You can contribute solutions to the problems listed in the repository. Please follow the guidelines mentioned below when submitting your solutions. - -4. **Enhance Documentation**: Improve documentation, including explanations and time/space complexity analysis, for existing solutions. - -5. **Fix Bugs**: If you find and fix any bugs in the existing code or documentation, you are welcome to submit a pull request. - -## Getting Started - -Before you start contributing, please ensure you have the following prerequisites: - -- A GitHub account. -- Familiarity with Git and GitHub. -- Code editor or IDE for making changes. - -## Contributing Process - -Here's the general process for contributing: - -1. **Fork the Repository**: Click the "Fork" button at the top of this repository to create your copy. - -2. **Clone Your Fork**: Clone your fork to your local machine. - - ``` - git clone https://github.com/your-username/Blind-75-LeetCode.git - ``` - -3. **Create a Branch**: Create a new branch for your contribution. - - ``` - git checkout -b feature/your-feature-name - ``` - -4. **Make Changes**: Implement your changes, following the guidelines provided. - -5. **Test Your Changes**: Ensure that your changes do not introduce new issues and are consistent with the repository's style and structure. - -6. **Commit Changes**: Commit your changes with a meaningful commit message. - - ``` - git commit -m "Add solution to problem X" - ``` - -7. **Push Changes**: Push your changes to your fork on GitHub. - - ``` - git push origin feature/your-feature-name - ``` - -8. **Create a Pull Request**: Go to the original repository and create a pull request. Please provide a detailed description of your changes. - -9. **Review and Collaboration**: Your pull request will be reviewed, and you may need to make further changes. Be responsive to comments and feedback. - -10. **Merge**: Once your pull request is approved, it will be merged into the main branch. - -## Code of Conduct - -Please note that we have a [Code of Conduct](CODE_OF_CONDUCT.md) that we expect all contributors to adhere to. By participating in this project, you agree to follow this code. - -We appreciate your contributions to the Blind 75 LeetCode repository and look forward to working together to make it an even better resource for the community! diff --git a/docs/_build/html/_sources/README.md b/docs/_build/html/_sources/README.md deleted file mode 100644 index a9b8b2e..0000000 --- a/docs/_build/html/_sources/README.md +++ /dev/null @@ -1,216 +0,0 @@ -# Blind 75 LeetCode Solutions - -![Blind 75 LeetCode](https://img.shields.io/badge/Blind_75_LeetCode-Solutions-blue?labelColor=red) - -This repository contains a curated list of 75 LeetCode problems that are commonly known as the "Blind 75." These problems cover a wide range of data structures and algorithms and are frequently asked in technical interviews. Solving these problems can help you build a strong foundation in algorithmic problem-solving. - -## Problem List - -### Array & Hashing -![Array & Hashing](https://img.shields.io/badge/Array_&_Hashing-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [217. Contains Duplicate](https://leetcode.com/problems/contains-duplicate/) | Easy | -| [242. Valid Anagram](https://leetcode.com/problems/valid-anagram/) | Easy | -| [1. Two Sum](https://leetcode.com/problems/two-sum/) | Easy | -| [49. Group Anagrams](https://leetcode.com/problems/group-anagrams/) | Medium | -| [347. Top K Frequent Elements](https://leetcode.com/problems/top-k-frequent-elements/) | Medium | -| [238. Product of Array Except Self](https://leetcode.com/problems/product-of-array-except-self/) | Medium | -| [659. Encode and Decode Strings](https://leetcode.com/problems/encode-and-decode-strings/) | Medium | -| [128. Longest Consecutive Sequence](https://leetcode.com/problems/longest-consecutive-sequence/) | Hard | - -### Two Pointers -![Array & Hashing](https://img.shields.io/badge/Two_Pointers-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [125. Valid Palindrome](https://leetcode.com/problems/valid-palindrome/) | Easy | -| [15. 3Sum](https://leetcode.com/problems/3sum/) | Medium | -| [11. Container With Most Water](https://leetcode.com/problems/container-with-most-water/) | Medium | - -### Sliding Window -![Array & Hashing](https://img.shields.io/badge/Sliding_Window-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [121. Best Time to Buy And Sell Stock](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/) | Easy | -| [3. Longest Substring Without Repeating Characters](https://leetcode.com/problems/longest-substring-without-repeating-characters/) | Medium | -| [424. Longest Repeating Character Replacement](https://leetcode.com/problems/longest-repeating-character-replacement/) | Medium | -| [76. Minimum Window Substring](https://leetcode.com/problems/minimum-window-substring/) | Hard | - -### Stack -![Array & Hashing](https://img.shields.io/badge/Stack-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [20. Valid Parentheses](https://leetcode.com/problems/valid-parentheses/) | Easy | - -### Binary Search -![Array & Hashing](https://img.shields.io/badge/Binary_Search-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [153. Find Minimum In Rotated Sorted Array](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/) | Medium | -| [33. Search In Rotated Sorted Array](https://leetcode.com/problems/search-in-rotated-sorted-array/) | Medium | - -### Linked List -![Array & Hashing](https://img.shields.io/badge/Linked_List-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [206. Reverse Linked List](https://leetcode.com/problems/reverse-linked-list/) | Easy | -| [21. Merge Two Sorted Lists](https://leetcode.com/problems/merge-two-sorted-lists/) | Easy | -| [143. Reorder List](https://leetcode.com/problems/reorder-list/) | Medium | -| [19. Remove Nth Node From End of List](https://leetcode.com/problems/remove-nth-node-from-end-of-list/) | Medium | -| [141. Linked List Cycle](https://leetcode.com/problems/linked-list-cycle/) | Medium | -| [23. Merge K Sorted Lists](https://leetcode.com/problems/merge-k-sorted-lists/) | Hard | - -### Trees -![Array & Hashing](https://img.shields.io/badge/Trees-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [226. Invert Binary Tree](https://leetcode.com/problems/invert-binary-tree/) | Easy | -| [104. Maximum Depth of Binary Tree](https://leetcode.com/problems/maximum-depth-of-binary-tree/) | Easy | -| [100. Same Tree](https://leetcode.com/problems/same-tree/) | Easy | -| [572. Subtree of Another Tree](https://leetcode.com/problems/subtree-of-another-tree/) | Easy | -| [235. Lowest Common Ancestor of a Binary Search Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/) | Easy | -| [102. Binary Tree Level Order Traversal](https://leetcode.com/problems/binary-tree-level-order-traversal/) | Medium | -| [98. Validate Binary Search Tree](https://leetcode.com/problems/validate-binary-search-tree/) | Medium | -| [230. Kth Smallest Element In a BST](https://leetcode.com/problems/kth-smallest-element-in-a-bst/) | Medium | -| [105. Construct Binary Tree From Preorder And Inorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/) | Medium | -| [124. Binary Tree Maximum Path Sum](https://leetcode.com/problems/binary-tree-maximum-path-sum/) | Hard | -| [297. Serialize And Deserialize Binary Tree](https://leetcode.com/problems/serialize-and-deserialize-binary-tree/) | Hard | - -### Tries -![Array & Hashing](https://img.shields.io/badge/Tries-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [208. Implement Trie Prefix Tree](https://leetcode.com/problems/implement-trie-prefix-tree/) | Medium | -| [211. Design Add And Search Words Data Structure](https://leetcode.com/problems/design-add-and-search-words-data-structure/) | Medium | -| [212. Word Search II](https://leetcode.com/problems/word-search-ii/) | Hard | - -### Heap / Priority Queue -![Array & Hashing](https://img.shields.io/badge/Heap_/_Priority_Queue-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [295. Find Median From Data Stream](https://leetcode.com/problems/find-median-from-data-stream/) | Hard | - -### Backtracking -![Array & Hashing](https://img.shields.io/badge/Backtracking-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [39. Combination Sum](https://leetcode.com/problems/combination-sum/) | Medium | -| [79. Word Search](https://leetcode.com/problems/word-search/) | Medium | - -### Graphs -![Array & Hashing](https://img.shields.io/badge/Graphs-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [200. Number of Islands](https://leetcode.com/problems/number-of-islands/) | Medium | -| [133. Clone Graph](https://leetcode.com/problems/clone-graph/) | Medium | -| [417. Pacific Atlantic Water Flow](https://leetcode.com/problems/pacific-atlantic-water-flow/) | Medium | -| [207. Course Schedule](https://leetcode.com/problems/course-schedule/) | Medium | -| [323. Number of Connected Components In An Undirected Graph](https://leetcode.com/problems/number-of-connected-components-in-an-undirected-graph/) | Medium | -| [261. Graph Valid Tree](https://leetcode.com/problems/graph-valid-tree/) | Medium | - -### Advanced Graphs -![Array & Hashing](https://img.shields.io/badge/Advanced_Graphs-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [269. Alien Dictionary](https://leetcode.com/problems/alien-dictionary/) | Hard | - -### 1-D Dynamic Programming -![Array & Hashing](https://img.shields.io/badge/1_D_Dynamic_Programming-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [70. Climbing Stairs](https://leetcode.com/problems/climbing-stairs/) | Easy | -| [198. House Robber](https://leetcode.com/problems/house-robber/) | Easy | -| [213. House Robber II](https://leetcode.com/problems/house-robber-ii/) | Medium | -| [5. Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/) | Medium | -| [647. Palindromic Substrings](https://leetcode.com/problems/palindromic-substrings/) | Medium | -| [91. Decode Ways](https://leetcode.com/problems/decode-ways/) | Medium | -| [322. Coin Change](https://leetcode.com/problems/coin-change/) | Medium | -| [152. Maximum Product Subarray](https://leetcode.com/problems/maximum-product-subarray/) | Medium | -| [139. Word Break](https://leetcode.com/problems/word-break/) | Medium | -| [300. Longest Increasing Subsequence](https://leetcode.com/problems/longest-increasing-subsequence/) | Medium | - -### 2-D Dynamic Programming -![Array & Hashing](https://img.shields.io/badge/2_D_Dynamic_Programming-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [62. Unique Paths](https://leetcode.com/problems/unique-paths/) | Medium | -| [1143. Longest Common Subsequence](https://leetcode.com/problems/longest-common-subsequence/) | Medium | - -### Greedy -![Array & Hashing](https://img.shields.io/badge/Greedy-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [53. Maximum Subarray](https://leetcode.com/problems/maximum-subarray/) | Easy | -| [55. Jump Game](https://leetcode.com/problems/jump-game/) | Medium | - -### Intervals -![Array & Hashing](https://img.shields.io/badge/Intervals-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [57. Insert Interval](https://leetcode.com/problems/insert-interval/) | Hard | -| [56. Merge Intervals](https://leetcode.com/problems/merge-intervals/) | Medium | -| [435. Non Overlapping Intervals](https://leetcode.com/problems/non-overlapping-intervals/) | Medium | -| [252. Meeting Rooms](https://leetcode.com/problems/meeting-rooms/) | Easy | -| [253. Meeting Rooms II](https://leetcode.com/problems/meeting-rooms-ii/) | Medium | - -### Math & Geometry -![Array & Hashing](https://img.shields.io/badge/Math_&_Geometry-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [48. Rotate Image](https://leetcode.com/problems/rotate-image/) | Medium | -| [54. Spiral Matrix](https://leetcode.com/problems/spiral-matrix/) | Medium | -| [73. Set Matrix Zeroes](https://leetcode.com/problems/set-matrix-zeroes/) | Medium | - -### Bit Manipulation -![Array & Hashing](https://img.shields.io/badge/Bit_Manipulation-Solutions-blue?labelColor=red) -| Problem Name | Difficulty | -| ----------------------------------------------- | ---------- | -| [191. Number of 1 Bits](https://leetcode.com/problems/number-of-1-bits/) | Easy | -| [338. Counting Bits](https://leetcode.com/problems/counting-bits/) | Medium | -| [190. Reverse Bits](https://leetcode.com/problems/reverse-bits/) | Easy | -| [268. Missing Number](https://leetcode.com/problems/missing-number/) | Easy | -| [371. Sum of Two Integers](https://leetcode.com/problems/sum-of-two-integers/) | Medium | - - -## How to Use - -1. Clone or download this repository to your local machine. - -```bash -git clone https://github.com/mohsentabibian/LeetCode-Solutions/Blind-75-LeetCode.git -``` - -2. Navigate to the directory of the specific problem you want to solve. - -```bash -cd Blind-75-LeetCode/Problem-Directory -``` - -3. Open the problem's directory to find its description, code template, and solution(s). - -4. Solve the problem using your preferred programming language. - -5. Check the solution(s) provided in the directory for reference and to compare your solution. - -## Contribute - -If you have a better solution or want to add more problems to the collection, feel free to contribute. You can create a pull request or open an issue to discuss additions or improvements. - -## Resources - -- [LeetCode](https://leetcode.com/): The official LeetCode website. -- [LeetCode Discuss](https://leetcode.com/discuss/): LeetCode's discussion forum for each problem. You can find helpful hints and discussions here. - -## Disclaimer - -This repository is meant for educational purposes and to help individuals prepare for technical interviews. Please respect LeetCode's terms of use and guidelines when using this repository. - -## Code of Conduct - -We have a [Code of Conduct](CODE_OF_CONDUCT.md) that we expect all contributors to adhere to. By participating in this project, you agree to follow this code. - -## Security Policy - -We take security seriously. Please review our [Security Policy](SECURITY.md) for information on reporting security vulnerabilities. - -Happy coding! diff --git a/docs/_build/html/_sources/SECURITY.md b/docs/_build/html/_sources/SECURITY.md deleted file mode 100644 index 7c19993..0000000 --- a/docs/_build/html/_sources/SECURITY.md +++ /dev/null @@ -1,42 +0,0 @@ -# Security Policy - -## Reporting a Vulnerability - -We take the security of the Blind 75 LeetCode repository seriously. If you believe you have found a security vulnerability, please help us by following these steps: - -1. **Do Not Disclose Publicly**: Please do not disclose the issue publicly until it has been addressed by our team. - -2. **Report Privately**: Create a GitHub issue with the title "Security Vulnerability Report" and provide a detailed description of the vulnerability. You can use a sample report template as follows: - - ``` - **Description** - A clear and concise description of the security vulnerability. - - **Steps to Reproduce** - Provide detailed steps on how to reproduce the vulnerability. - - **Expected Behavior** - Describe what you expected to happen. - - **Actual Behavior** - Describe what actually happened. - - **Additional Information** - Any additional information that can help us understand and reproduce the issue, such as environment details, configuration, or screenshots. - ``` - -3. **Secure Communication**: If the vulnerability involves sensitive data, please encrypt your communication with our PGP key. Contact us for our PGP key information. - -4. **Response**: We will acknowledge your report within 5 business days and provide an estimated timeline for the resolution. - -5. **Fix and Disclosure**: We will work to fix the issue promptly and privately. Once resolved, we will provide a security advisory and give credit to the reporter if desired. - -6. **Responsible Disclosure**: We encourage responsible disclosure. Please do not take advantage of the vulnerability or attempt to exploit it for malicious purposes. - -## Security Updates - -We are committed to promptly addressing and resolving any security issues. We recommend that you stay up-to-date with the latest releases of this repository, as they may include security updates and fixes. - -## Contact - -If you have any questions or need further assistance regarding security, you can contact us at mohsentabibian@gmail.com. diff --git a/docs/_build/html/_sphinx_design_static/design-style.4045f2051d55cab465a707391d5b2007.min.css b/docs/_build/html/_sphinx_design_static/design-style.4045f2051d55cab465a707391d5b2007.min.css deleted file mode 100644 index 3225661..0000000 --- a/docs/_build/html/_sphinx_design_static/design-style.4045f2051d55cab465a707391d5b2007.min.css +++ /dev/null @@ -1 +0,0 @@ -.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative}details.sd-dropdown .sd-summary-title{font-weight:700;padding-right:3em !important;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary{list-style:none;padding:1em}details.sd-dropdown summary .sd-octicon.no-title{vertical-align:middle}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown summary::-webkit-details-marker{display:none}details.sd-dropdown summary:focus{outline:none}details.sd-dropdown .sd-summary-icon{margin-right:.5em}details.sd-dropdown .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary:hover .sd-summary-up svg,details.sd-dropdown summary:hover .sd-summary-down svg{opacity:1;transform:scale(1.1)}details.sd-dropdown .sd-summary-up svg,details.sd-dropdown .sd-summary-down svg{display:block;opacity:.6}details.sd-dropdown .sd-summary-up,details.sd-dropdown .sd-summary-down{pointer-events:none;position:absolute;right:1em;top:1em}details.sd-dropdown[open]>.sd-summary-title .sd-summary-down{visibility:hidden}details.sd-dropdown:not([open])>.sd-summary-title .sd-summary-up{visibility:hidden}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #007bff;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0069d9;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem} diff --git a/docs/_build/html/_sphinx_design_static/design-tabs.js b/docs/_build/html/_sphinx_design_static/design-tabs.js deleted file mode 100644 index 36b38cf..0000000 --- a/docs/_build/html/_sphinx_design_static/design-tabs.js +++ /dev/null @@ -1,27 +0,0 @@ -var sd_labels_by_text = {}; - -function ready() { - const li = document.getElementsByClassName("sd-tab-label"); - for (const label of li) { - syncId = label.getAttribute("data-sync-id"); - if (syncId) { - label.onclick = onLabelClick; - if (!sd_labels_by_text[syncId]) { - sd_labels_by_text[syncId] = []; - } - sd_labels_by_text[syncId].push(label); - } - } -} - -function onLabelClick() { - // Activate other inputs with the same sync id. - syncId = this.getAttribute("data-sync-id"); - for (label of sd_labels_by_text[syncId]) { - if (label === this) continue; - label.previousElementSibling.checked = true; - } - window.localStorage.setItem("sphinx-design-last-tab", syncId); -} - -document.addEventListener("DOMContentLoaded", ready, false); diff --git a/docs/_build/html/_static/_sphinx_javascript_frameworks_compat.js b/docs/_build/html/_static/_sphinx_javascript_frameworks_compat.js deleted file mode 100644 index 8549469..0000000 --- a/docs/_build/html/_static/_sphinx_javascript_frameworks_compat.js +++ /dev/null @@ -1,134 +0,0 @@ -/* - * _sphinx_javascript_frameworks_compat.js - * ~~~~~~~~~~ - * - * Compatability shim for jQuery and underscores.js. - * - * WILL BE REMOVED IN Sphinx 6.0 - * xref RemovedInSphinx60Warning - * - */ - -/** - * select a different prefix for underscore - */ -$u = _.noConflict(); - - -/** - * small helper function to urldecode strings - * - * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL - */ -jQuery.urldecode = function(x) { - if (!x) { - return x - } - return decodeURIComponent(x.replace(/\+/g, ' ')); -}; - -/** - * small helper function to urlencode strings - */ -jQuery.urlencode = encodeURIComponent; - -/** - * This function returns the parsed url parameters of the - * current request. Multiple values per key are supported, - * it will always return arrays of strings for the value parts. - */ -jQuery.getQueryParameters = function(s) { - if (typeof s === 'undefined') - s = document.location.search; - var parts = s.substr(s.indexOf('?') + 1).split('&'); - var result = {}; - for (var i = 0; i < parts.length; i++) { - var tmp = parts[i].split('=', 2); - var key = jQuery.urldecode(tmp[0]); - var value = jQuery.urldecode(tmp[1]); - if (key in result) - result[key].push(value); - else - result[key] = [value]; - } - return result; -}; - -/** - * highlight a given string on a jquery object by wrapping it in - * span elements with the given class name. - */ -jQuery.fn.highlightText = function(text, className) { - function highlight(node, addItems) { - if (node.nodeType === 3) { - var val = node.nodeValue; - var pos = val.toLowerCase().indexOf(text); - if (pos >= 0 && - !jQuery(node.parentNode).hasClass(className) && - !jQuery(node.parentNode).hasClass("nohighlight")) { - var span; - var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); - if (isInSVG) { - span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); - } else { - span = document.createElement("span"); - span.className = className; - } - span.appendChild(document.createTextNode(val.substr(pos, text.length))); - node.parentNode.insertBefore(span, node.parentNode.insertBefore( - document.createTextNode(val.substr(pos + text.length)), - node.nextSibling)); - node.nodeValue = val.substr(0, pos); - if (isInSVG) { - var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); - var bbox = node.parentElement.getBBox(); - rect.x.baseVal.value = bbox.x; - rect.y.baseVal.value = bbox.y; - rect.width.baseVal.value = bbox.width; - rect.height.baseVal.value = bbox.height; - rect.setAttribute('class', className); - addItems.push({ - "parent": node.parentNode, - "target": rect}); - } - } - } - else if (!jQuery(node).is("button, select, textarea")) { - jQuery.each(node.childNodes, function() { - highlight(this, addItems); - }); - } - } - var addItems = []; - var result = this.each(function() { - highlight(this, addItems); - }); - for (var i = 0; i < addItems.length; ++i) { - jQuery(addItems[i].parent).before(addItems[i].target); - } - return result; -}; - -/* - * backward compatibility for jQuery.browser - * This will be supported until firefox bug is fixed. - */ -if (!jQuery.browser) { - jQuery.uaMatch = function(ua) { - ua = ua.toLowerCase(); - - var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || - /(webkit)[ \/]([\w.]+)/.exec(ua) || - /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || - /(msie) ([\w.]+)/.exec(ua) || - ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || - []; - - return { - browser: match[ 1 ] || "", - version: match[ 2 ] || "0" - }; - }; - jQuery.browser = {}; - jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; -} diff --git a/docs/_build/html/_static/basic.css b/docs/_build/html/_static/basic.css deleted file mode 100644 index 9e364ed..0000000 --- a/docs/_build/html/_static/basic.css +++ /dev/null @@ -1,930 +0,0 @@ -/* - * basic.css - * ~~~~~~~~~ - * - * Sphinx stylesheet -- basic theme. - * - * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -/* -- main layout ----------------------------------------------------------- */ - -div.clearer { - clear: both; -} - -div.section::after { - display: block; - content: ''; - clear: left; -} - -/* -- relbar ---------------------------------------------------------------- */ - -div.related { - width: 100%; - font-size: 90%; -} - -div.related h3 { - display: none; -} - -div.related ul { - margin: 0; - padding: 0 0 0 10px; - list-style: none; -} - -div.related li { - display: inline; -} - -div.related li.right { - float: right; - margin-right: 5px; -} - -/* -- sidebar --------------------------------------------------------------- */ - -div.sphinxsidebarwrapper { - padding: 10px 5px 0 10px; -} - -div.sphinxsidebar { - float: left; - width: 270px; - margin-left: -100%; - font-size: 90%; - word-wrap: break-word; - overflow-wrap : break-word; -} - -div.sphinxsidebar ul { - list-style: none; -} - -div.sphinxsidebar ul ul, -div.sphinxsidebar ul.want-points { - margin-left: 20px; - list-style: square; -} - -div.sphinxsidebar ul ul { - margin-top: 0; - margin-bottom: 0; -} - -div.sphinxsidebar form { - margin-top: 10px; -} - -div.sphinxsidebar input { - border: 1px solid #98dbcc; - font-family: sans-serif; - font-size: 1em; -} - -div.sphinxsidebar #searchbox form.search { - overflow: hidden; -} - -div.sphinxsidebar #searchbox input[type="text"] { - float: left; - width: 80%; - padding: 0.25em; - box-sizing: border-box; -} - -div.sphinxsidebar #searchbox input[type="submit"] { - float: left; - width: 20%; - border-left: none; - padding: 0.25em; - box-sizing: border-box; -} - - -img { - border: 0; - max-width: 100%; -} - -/* -- search page ----------------------------------------------------------- */ - -ul.search { - margin: 10px 0 0 20px; - padding: 0; -} - -ul.search li { - padding: 5px 0 5px 20px; - background-image: url(file.png); - background-repeat: no-repeat; - background-position: 0 7px; -} - -ul.search li a { - font-weight: bold; -} - -ul.search li p.context { - color: #888; - margin: 2px 0 0 30px; - text-align: left; -} - -ul.keywordmatches li.goodmatch a { - font-weight: bold; -} - -/* -- index page ------------------------------------------------------------ */ - -table.contentstable { - width: 90%; - margin-left: auto; - margin-right: auto; -} - -table.contentstable p.biglink { - line-height: 150%; -} - -a.biglink { - font-size: 1.3em; -} - -span.linkdescr { - font-style: italic; - padding-top: 5px; - font-size: 90%; -} - -/* -- general index --------------------------------------------------------- */ - -table.indextable { - width: 100%; -} - -table.indextable td { - text-align: left; - vertical-align: top; -} - -table.indextable ul { - margin-top: 0; - margin-bottom: 0; - list-style-type: none; -} - -table.indextable > tbody > tr > td > ul { - padding-left: 0em; -} - -table.indextable tr.pcap { - height: 10px; -} - -table.indextable tr.cap { - margin-top: 10px; - background-color: #f2f2f2; -} - -img.toggler { - margin-right: 3px; - margin-top: 3px; - cursor: pointer; -} - -div.modindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -div.genindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -/* -- domain module index --------------------------------------------------- */ - -table.modindextable td { - padding: 2px; - border-collapse: collapse; -} - -/* -- general body styles --------------------------------------------------- */ - -div.body { - min-width: 360px; - max-width: 800px; -} - -div.body p, div.body dd, div.body li, div.body blockquote { - -moz-hyphens: auto; - -ms-hyphens: auto; - -webkit-hyphens: auto; - hyphens: auto; -} - -a.headerlink { - visibility: hidden; -} - -h1:hover > a.headerlink, -h2:hover > a.headerlink, -h3:hover > a.headerlink, -h4:hover > a.headerlink, -h5:hover > a.headerlink, -h6:hover > a.headerlink, -dt:hover > a.headerlink, -caption:hover > a.headerlink, -p.caption:hover > a.headerlink, -div.code-block-caption:hover > a.headerlink { - visibility: visible; -} - -div.body p.caption { - text-align: inherit; -} - -div.body td { - text-align: left; -} - -.first { - margin-top: 0 !important; -} - -p.rubric { - margin-top: 30px; - font-weight: bold; -} - -img.align-left, figure.align-left, .figure.align-left, object.align-left { - clear: left; - float: left; - margin-right: 1em; -} - -img.align-right, figure.align-right, .figure.align-right, object.align-right { - clear: right; - float: right; - margin-left: 1em; -} - -img.align-center, figure.align-center, .figure.align-center, object.align-center { - display: block; - margin-left: auto; - margin-right: auto; -} - -img.align-default, figure.align-default, .figure.align-default { - display: block; - margin-left: auto; - margin-right: auto; -} - -.align-left { - text-align: left; -} - -.align-center { - text-align: center; -} - -.align-default { - text-align: center; -} - -.align-right { - text-align: right; -} - -/* -- sidebars -------------------------------------------------------------- */ - -div.sidebar, -aside.sidebar { - margin: 0 0 0.5em 1em; - border: 1px solid #ddb; - padding: 7px; - background-color: #ffe; - width: 40%; - float: right; - clear: right; - overflow-x: auto; -} - -p.sidebar-title { - font-weight: bold; -} -nav.contents, -aside.topic, - -div.admonition, div.topic, blockquote { - clear: left; -} - -/* -- topics ---------------------------------------------------------------- */ -nav.contents, -aside.topic, - -div.topic { - border: 1px solid #ccc; - padding: 7px; - margin: 10px 0 10px 0; -} - -p.topic-title { - font-size: 1.1em; - font-weight: bold; - margin-top: 10px; -} - -/* -- admonitions ----------------------------------------------------------- */ - -div.admonition { - margin-top: 10px; - margin-bottom: 10px; - padding: 7px; -} - -div.admonition dt { - font-weight: bold; -} - -p.admonition-title { - margin: 0px 10px 5px 0px; - font-weight: bold; -} - -div.body p.centered { - text-align: center; - margin-top: 25px; -} - -/* -- content of sidebars/topics/admonitions -------------------------------- */ - -div.sidebar > :last-child, -aside.sidebar > :last-child, -nav.contents > :last-child, -aside.topic > :last-child, - -div.topic > :last-child, -div.admonition > :last-child { - margin-bottom: 0; -} - -div.sidebar::after, -aside.sidebar::after, -nav.contents::after, -aside.topic::after, - -div.topic::after, -div.admonition::after, -blockquote::after { - display: block; - content: ''; - clear: both; -} - -/* -- tables ---------------------------------------------------------------- */ - -table.docutils { - margin-top: 10px; - margin-bottom: 10px; - border: 0; - border-collapse: collapse; -} - -table.align-center { - margin-left: auto; - margin-right: auto; -} - -table.align-default { - margin-left: auto; - margin-right: auto; -} - -table caption span.caption-number { - font-style: italic; -} - -table caption span.caption-text { -} - -table.docutils td, table.docutils th { - padding: 1px 8px 1px 5px; - border-top: 0; - border-left: 0; - border-right: 0; - border-bottom: 1px solid #aaa; -} - -th { - text-align: left; - padding-right: 5px; -} - -table.citation { - border-left: solid 1px gray; - margin-left: 1px; -} - -table.citation td { - border-bottom: none; -} - -th > :first-child, -td > :first-child { - margin-top: 0px; -} - -th > :last-child, -td > :last-child { - margin-bottom: 0px; -} - -/* -- figures --------------------------------------------------------------- */ - -div.figure, figure { - margin: 0.5em; - padding: 0.5em; -} - -div.figure p.caption, figcaption { - padding: 0.3em; -} - -div.figure p.caption span.caption-number, -figcaption span.caption-number { - font-style: italic; -} - -div.figure p.caption span.caption-text, -figcaption span.caption-text { -} - -/* -- field list styles ----------------------------------------------------- */ - -table.field-list td, table.field-list th { - border: 0 !important; -} - -.field-list ul { - margin: 0; - padding-left: 1em; -} - -.field-list p { - margin: 0; -} - -.field-name { - -moz-hyphens: manual; - -ms-hyphens: manual; - -webkit-hyphens: manual; - hyphens: manual; -} - -/* -- hlist styles ---------------------------------------------------------- */ - -table.hlist { - margin: 1em 0; -} - -table.hlist td { - vertical-align: top; -} - -/* -- object description styles --------------------------------------------- */ - -.sig { - font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; -} - -.sig-name, code.descname { - background-color: transparent; - font-weight: bold; -} - -.sig-name { - font-size: 1.1em; -} - -code.descname { - font-size: 1.2em; -} - -.sig-prename, code.descclassname { - background-color: transparent; -} - -.optional { - font-size: 1.3em; -} - -.sig-paren { - font-size: larger; -} - -.sig-param.n { - font-style: italic; -} - -/* C++ specific styling */ - -.sig-inline.c-texpr, -.sig-inline.cpp-texpr { - font-family: unset; -} - -.sig.c .k, .sig.c .kt, -.sig.cpp .k, .sig.cpp .kt { - color: #0033B3; -} - -.sig.c .m, -.sig.cpp .m { - color: #1750EB; -} - -.sig.c .s, .sig.c .sc, -.sig.cpp .s, .sig.cpp .sc { - color: #067D17; -} - - -/* -- other body styles ----------------------------------------------------- */ - -ol.arabic { - list-style: decimal; -} - -ol.loweralpha { - list-style: lower-alpha; -} - -ol.upperalpha { - list-style: upper-alpha; -} - -ol.lowerroman { - list-style: lower-roman; -} - -ol.upperroman { - list-style: upper-roman; -} - -:not(li) > ol > li:first-child > :first-child, -:not(li) > ul > li:first-child > :first-child { - margin-top: 0px; -} - -:not(li) > ol > li:last-child > :last-child, -:not(li) > ul > li:last-child > :last-child { - margin-bottom: 0px; -} - -ol.simple ol p, -ol.simple ul p, -ul.simple ol p, -ul.simple ul p { - margin-top: 0; -} - -ol.simple > li:not(:first-child) > p, -ul.simple > li:not(:first-child) > p { - margin-top: 0; -} - -ol.simple p, -ul.simple p { - margin-bottom: 0; -} - -/* Docutils 0.17 and older (footnotes & citations) */ -dl.footnote > dt, -dl.citation > dt { - float: left; - margin-right: 0.5em; -} - -dl.footnote > dd, -dl.citation > dd { - margin-bottom: 0em; -} - -dl.footnote > dd:after, -dl.citation > dd:after { - content: ""; - clear: both; -} - -/* Docutils 0.18+ (footnotes & citations) */ -aside.footnote > span, -div.citation > span { - float: left; -} -aside.footnote > span:last-of-type, -div.citation > span:last-of-type { - padding-right: 0.5em; -} -aside.footnote > p { - margin-left: 2em; -} -div.citation > p { - margin-left: 4em; -} -aside.footnote > p:last-of-type, -div.citation > p:last-of-type { - margin-bottom: 0em; -} -aside.footnote > p:last-of-type:after, -div.citation > p:last-of-type:after { - content: ""; - clear: both; -} - -/* Footnotes & citations ends */ - -dl.field-list { - display: grid; - grid-template-columns: fit-content(30%) auto; -} - -dl.field-list > dt { - font-weight: bold; - word-break: break-word; - padding-left: 0.5em; - padding-right: 5px; -} - -dl.field-list > dt:after { - content: ":"; -} - -dl.field-list > dd { - padding-left: 0.5em; - margin-top: 0em; - margin-left: 0em; - margin-bottom: 0em; -} - -dl { - margin-bottom: 15px; -} - -dd > :first-child { - margin-top: 0px; -} - -dd ul, dd table { - margin-bottom: 10px; -} - -dd { - margin-top: 3px; - margin-bottom: 10px; - margin-left: 30px; -} - -dl > dd:last-child, -dl > dd:last-child > :last-child { - margin-bottom: 0; -} - -dt:target, span.highlighted { - background-color: #fbe54e; -} - -rect.highlighted { - fill: #fbe54e; -} - -dl.glossary dt { - font-weight: bold; - font-size: 1.1em; -} - -.versionmodified { - font-style: italic; -} - -.system-message { - background-color: #fda; - padding: 5px; - border: 3px solid red; -} - -.footnote:target { - background-color: #ffa; -} - -.line-block { - display: block; - margin-top: 1em; - margin-bottom: 1em; -} - -.line-block .line-block { - margin-top: 0; - margin-bottom: 0; - margin-left: 1.5em; -} - -.guilabel, .menuselection { - font-family: sans-serif; -} - -.accelerator { - text-decoration: underline; -} - -.classifier { - font-style: oblique; -} - -.classifier:before { - font-style: normal; - margin: 0 0.5em; - content: ":"; - display: inline-block; -} - -abbr, acronym { - border-bottom: dotted 1px; - cursor: help; -} - -/* -- code displays --------------------------------------------------------- */ - -pre { - overflow: auto; - overflow-y: hidden; /* fixes display issues on Chrome browsers */ -} - -pre, div[class*="highlight-"] { - clear: both; -} - -span.pre { - -moz-hyphens: none; - -ms-hyphens: none; - -webkit-hyphens: none; - hyphens: none; - white-space: nowrap; -} - -div[class*="highlight-"] { - margin: 1em 0; -} - -td.linenos pre { - border: 0; - background-color: transparent; - color: #aaa; -} - -table.highlighttable { - display: block; -} - -table.highlighttable tbody { - display: block; -} - -table.highlighttable tr { - display: flex; -} - -table.highlighttable td { - margin: 0; - padding: 0; -} - -table.highlighttable td.linenos { - padding-right: 0.5em; -} - -table.highlighttable td.code { - flex: 1; - overflow: hidden; -} - -.highlight .hll { - display: block; -} - -div.highlight pre, -table.highlighttable pre { - margin: 0; -} - -div.code-block-caption + div { - margin-top: 0; -} - -div.code-block-caption { - margin-top: 1em; - padding: 2px 5px; - font-size: small; -} - -div.code-block-caption code { - background-color: transparent; -} - -table.highlighttable td.linenos, -span.linenos, -div.highlight span.gp { /* gp: Generic.Prompt */ - user-select: none; - -webkit-user-select: text; /* Safari fallback only */ - -webkit-user-select: none; /* Chrome/Safari */ - -moz-user-select: none; /* Firefox */ - -ms-user-select: none; /* IE10+ */ -} - -div.code-block-caption span.caption-number { - padding: 0.1em 0.3em; - font-style: italic; -} - -div.code-block-caption span.caption-text { -} - -div.literal-block-wrapper { - margin: 1em 0; -} - -code.xref, a code { - background-color: transparent; - font-weight: bold; -} - -h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { - background-color: transparent; -} - -.viewcode-link { - float: right; -} - -.viewcode-back { - float: right; - font-family: sans-serif; -} - -div.viewcode-block:target { - margin: -1px -10px; - padding: 0 10px; -} - -/* -- math display ---------------------------------------------------------- */ - -img.math { - vertical-align: middle; -} - -div.body div.math p { - text-align: center; -} - -span.eqno { - float: right; -} - -span.eqno a.headerlink { - position: absolute; - z-index: 1; -} - -div.math:hover a.headerlink { - visibility: visible; -} - -/* -- printout stylesheet --------------------------------------------------- */ - -@media print { - div.document, - div.documentwrapper, - div.bodywrapper { - margin: 0 !important; - width: 100%; - } - - div.sphinxsidebar, - div.related, - div.footer, - #top-link { - display: none; - } -} \ No newline at end of file diff --git a/docs/_build/html/_static/check-solid.svg b/docs/_build/html/_static/check-solid.svg deleted file mode 100644 index 92fad4b..0000000 --- a/docs/_build/html/_static/check-solid.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/docs/_build/html/_static/clipboard.min.js b/docs/_build/html/_static/clipboard.min.js deleted file mode 100644 index 54b3c46..0000000 --- a/docs/_build/html/_static/clipboard.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * clipboard.js v2.0.8 - * https://clipboardjs.com/ - * - * Licensed MIT © Zeno Rocha - */ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return o}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),c=n.n(e);function a(t){try{return document.execCommand(t)}catch(t){return}}var f=function(t){t=c()(t);return a("cut"),t};var l=function(t){var e,n,o,r=1 - - - - diff --git a/docs/_build/html/_static/copybutton.css b/docs/_build/html/_static/copybutton.css deleted file mode 100644 index f1916ec..0000000 --- a/docs/_build/html/_static/copybutton.css +++ /dev/null @@ -1,94 +0,0 @@ -/* Copy buttons */ -button.copybtn { - position: absolute; - display: flex; - top: .3em; - right: .3em; - width: 1.7em; - height: 1.7em; - opacity: 0; - transition: opacity 0.3s, border .3s, background-color .3s; - user-select: none; - padding: 0; - border: none; - outline: none; - border-radius: 0.4em; - /* The colors that GitHub uses */ - border: #1b1f2426 1px solid; - background-color: #f6f8fa; - color: #57606a; -} - -button.copybtn.success { - border-color: #22863a; - color: #22863a; -} - -button.copybtn svg { - stroke: currentColor; - width: 1.5em; - height: 1.5em; - padding: 0.1em; -} - -div.highlight { - position: relative; -} - -/* Show the copybutton */ -.highlight:hover button.copybtn, button.copybtn.success { - opacity: 1; -} - -.highlight button.copybtn:hover { - background-color: rgb(235, 235, 235); -} - -.highlight button.copybtn:active { - background-color: rgb(187, 187, 187); -} - -/** - * A minimal CSS-only tooltip copied from: - * https://codepen.io/mildrenben/pen/rVBrpK - * - * To use, write HTML like the following: - * - *

Short

- */ - .o-tooltip--left { - position: relative; - } - - .o-tooltip--left:after { - opacity: 0; - visibility: hidden; - position: absolute; - content: attr(data-tooltip); - padding: .2em; - font-size: .8em; - left: -.2em; - background: grey; - color: white; - white-space: nowrap; - z-index: 2; - border-radius: 2px; - transform: translateX(-102%) translateY(0); - transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); -} - -.o-tooltip--left:hover:after { - display: block; - opacity: 1; - visibility: visible; - transform: translateX(-100%) translateY(0); - transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); - transition-delay: .5s; -} - -/* By default the copy button shouldn't show up when printing a page */ -@media print { - button.copybtn { - display: none; - } -} diff --git a/docs/_build/html/_static/copybutton.js b/docs/_build/html/_static/copybutton.js deleted file mode 100644 index 2ea7ff3..0000000 --- a/docs/_build/html/_static/copybutton.js +++ /dev/null @@ -1,248 +0,0 @@ -// Localization support -const messages = { - 'en': { - 'copy': 'Copy', - 'copy_to_clipboard': 'Copy to clipboard', - 'copy_success': 'Copied!', - 'copy_failure': 'Failed to copy', - }, - 'es' : { - 'copy': 'Copiar', - 'copy_to_clipboard': 'Copiar al portapapeles', - 'copy_success': '¡Copiado!', - 'copy_failure': 'Error al copiar', - }, - 'de' : { - 'copy': 'Kopieren', - 'copy_to_clipboard': 'In die Zwischenablage kopieren', - 'copy_success': 'Kopiert!', - 'copy_failure': 'Fehler beim Kopieren', - }, - 'fr' : { - 'copy': 'Copier', - 'copy_to_clipboard': 'Copier dans le presse-papier', - 'copy_success': 'Copié !', - 'copy_failure': 'Échec de la copie', - }, - 'ru': { - 'copy': 'Скопировать', - 'copy_to_clipboard': 'Скопировать в буфер', - 'copy_success': 'Скопировано!', - 'copy_failure': 'Не удалось скопировать', - }, - 'zh-CN': { - 'copy': '复制', - 'copy_to_clipboard': '复制到剪贴板', - 'copy_success': '复制成功!', - 'copy_failure': '复制失败', - }, - 'it' : { - 'copy': 'Copiare', - 'copy_to_clipboard': 'Copiato negli appunti', - 'copy_success': 'Copiato!', - 'copy_failure': 'Errore durante la copia', - } -} - -let locale = 'en' -if( document.documentElement.lang !== undefined - && messages[document.documentElement.lang] !== undefined ) { - locale = document.documentElement.lang -} - -let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; -if (doc_url_root == '#') { - doc_url_root = ''; -} - -/** - * SVG files for our copy buttons - */ -let iconCheck = ` - ${messages[locale]['copy_success']} - - -` - -// If the user specified their own SVG use that, otherwise use the default -let iconCopy = ``; -if (!iconCopy) { - iconCopy = ` - ${messages[locale]['copy_to_clipboard']} - - - -` -} - -/** - * Set up copy/paste for code blocks - */ - -const runWhenDOMLoaded = cb => { - if (document.readyState != 'loading') { - cb() - } else if (document.addEventListener) { - document.addEventListener('DOMContentLoaded', cb) - } else { - document.attachEvent('onreadystatechange', function() { - if (document.readyState == 'complete') cb() - }) - } -} - -const codeCellId = index => `codecell${index}` - -// Clears selected text since ClipboardJS will select the text when copying -const clearSelection = () => { - if (window.getSelection) { - window.getSelection().removeAllRanges() - } else if (document.selection) { - document.selection.empty() - } -} - -// Changes tooltip text for a moment, then changes it back -// We want the timeout of our `success` class to be a bit shorter than the -// tooltip and icon change, so that we can hide the icon before changing back. -var timeoutIcon = 2000; -var timeoutSuccessClass = 1500; - -const temporarilyChangeTooltip = (el, oldText, newText) => { - el.setAttribute('data-tooltip', newText) - el.classList.add('success') - // Remove success a little bit sooner than we change the tooltip - // So that we can use CSS to hide the copybutton first - setTimeout(() => el.classList.remove('success'), timeoutSuccessClass) - setTimeout(() => el.setAttribute('data-tooltip', oldText), timeoutIcon) -} - -// Changes the copy button icon for two seconds, then changes it back -const temporarilyChangeIcon = (el) => { - el.innerHTML = iconCheck; - setTimeout(() => {el.innerHTML = iconCopy}, timeoutIcon) -} - -const addCopyButtonToCodeCells = () => { - // If ClipboardJS hasn't loaded, wait a bit and try again. This - // happens because we load ClipboardJS asynchronously. - if (window.ClipboardJS === undefined) { - setTimeout(addCopyButtonToCodeCells, 250) - return - } - - // Add copybuttons to all of our code cells - const COPYBUTTON_SELECTOR = 'div.highlight pre'; - const codeCells = document.querySelectorAll(COPYBUTTON_SELECTOR) - codeCells.forEach((codeCell, index) => { - const id = codeCellId(index) - codeCell.setAttribute('id', id) - - const clipboardButton = id => - `` - codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) - }) - -function escapeRegExp(string) { - return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string -} - -/** - * Removes excluded text from a Node. - * - * @param {Node} target Node to filter. - * @param {string} exclude CSS selector of nodes to exclude. - * @returns {DOMString} Text from `target` with text removed. - */ -function filterText(target, exclude) { - const clone = target.cloneNode(true); // clone as to not modify the live DOM - if (exclude) { - // remove excluded nodes - clone.querySelectorAll(exclude).forEach(node => node.remove()); - } - return clone.innerText; -} - -// Callback when a copy button is clicked. Will be passed the node that was clicked -// should then grab the text and replace pieces of text that shouldn't be used in output -function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { - var regexp; - var match; - - // Do we check for line continuation characters and "HERE-documents"? - var useLineCont = !!lineContinuationChar - var useHereDoc = !!hereDocDelim - - // create regexp to capture prompt and remaining line - if (isRegexp) { - regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') - } else { - regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') - } - - const outputLines = []; - var promptFound = false; - var gotLineCont = false; - var gotHereDoc = false; - const lineGotPrompt = []; - for (const line of textContent.split('\n')) { - match = line.match(regexp) - if (match || gotLineCont || gotHereDoc) { - promptFound = regexp.test(line) - lineGotPrompt.push(promptFound) - if (removePrompts && promptFound) { - outputLines.push(match[2]) - } else { - outputLines.push(line) - } - gotLineCont = line.endsWith(lineContinuationChar) & useLineCont - if (line.includes(hereDocDelim) & useHereDoc) - gotHereDoc = !gotHereDoc - } else if (!onlyCopyPromptLines) { - outputLines.push(line) - } else if (copyEmptyLines && line.trim() === '') { - outputLines.push(line) - } - } - - // If no lines with the prompt were found then just use original lines - if (lineGotPrompt.some(v => v === true)) { - textContent = outputLines.join('\n'); - } - - // Remove a trailing newline to avoid auto-running when pasting - if (textContent.endsWith("\n")) { - textContent = textContent.slice(0, -1) - } - return textContent -} - - -var copyTargetText = (trigger) => { - var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); - - // get filtered text - let exclude = '.linenos'; - - let text = filterText(target, exclude); - return formatCopyText(text, '', false, true, true, true, '', '') -} - - // Initialize with a callback so we can modify the text before copy - const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText}) - - // Update UI with error/success messages - clipboard.on('success', event => { - clearSelection() - temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success']) - temporarilyChangeIcon(event.trigger) - }) - - clipboard.on('error', event => { - temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure']) - }) -} - -runWhenDOMLoaded(addCopyButtonToCodeCells) \ No newline at end of file diff --git a/docs/_build/html/_static/copybutton_funcs.js b/docs/_build/html/_static/copybutton_funcs.js deleted file mode 100644 index dbe1aaa..0000000 --- a/docs/_build/html/_static/copybutton_funcs.js +++ /dev/null @@ -1,73 +0,0 @@ -function escapeRegExp(string) { - return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string -} - -/** - * Removes excluded text from a Node. - * - * @param {Node} target Node to filter. - * @param {string} exclude CSS selector of nodes to exclude. - * @returns {DOMString} Text from `target` with text removed. - */ -export function filterText(target, exclude) { - const clone = target.cloneNode(true); // clone as to not modify the live DOM - if (exclude) { - // remove excluded nodes - clone.querySelectorAll(exclude).forEach(node => node.remove()); - } - return clone.innerText; -} - -// Callback when a copy button is clicked. Will be passed the node that was clicked -// should then grab the text and replace pieces of text that shouldn't be used in output -export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { - var regexp; - var match; - - // Do we check for line continuation characters and "HERE-documents"? - var useLineCont = !!lineContinuationChar - var useHereDoc = !!hereDocDelim - - // create regexp to capture prompt and remaining line - if (isRegexp) { - regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') - } else { - regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') - } - - const outputLines = []; - var promptFound = false; - var gotLineCont = false; - var gotHereDoc = false; - const lineGotPrompt = []; - for (const line of textContent.split('\n')) { - match = line.match(regexp) - if (match || gotLineCont || gotHereDoc) { - promptFound = regexp.test(line) - lineGotPrompt.push(promptFound) - if (removePrompts && promptFound) { - outputLines.push(match[2]) - } else { - outputLines.push(line) - } - gotLineCont = line.endsWith(lineContinuationChar) & useLineCont - if (line.includes(hereDocDelim) & useHereDoc) - gotHereDoc = !gotHereDoc - } else if (!onlyCopyPromptLines) { - outputLines.push(line) - } else if (copyEmptyLines && line.trim() === '') { - outputLines.push(line) - } - } - - // If no lines with the prompt were found then just use original lines - if (lineGotPrompt.some(v => v === true)) { - textContent = outputLines.join('\n'); - } - - // Remove a trailing newline to avoid auto-running when pasting - if (textContent.endsWith("\n")) { - textContent = textContent.slice(0, -1) - } - return textContent -} diff --git a/docs/_build/html/_static/design-style.4045f2051d55cab465a707391d5b2007.min.css b/docs/_build/html/_static/design-style.4045f2051d55cab465a707391d5b2007.min.css deleted file mode 100644 index 3225661..0000000 --- a/docs/_build/html/_static/design-style.4045f2051d55cab465a707391d5b2007.min.css +++ /dev/null @@ -1 +0,0 @@ -.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative}details.sd-dropdown .sd-summary-title{font-weight:700;padding-right:3em !important;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary{list-style:none;padding:1em}details.sd-dropdown summary .sd-octicon.no-title{vertical-align:middle}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown summary::-webkit-details-marker{display:none}details.sd-dropdown summary:focus{outline:none}details.sd-dropdown .sd-summary-icon{margin-right:.5em}details.sd-dropdown .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary:hover .sd-summary-up svg,details.sd-dropdown summary:hover .sd-summary-down svg{opacity:1;transform:scale(1.1)}details.sd-dropdown .sd-summary-up svg,details.sd-dropdown .sd-summary-down svg{display:block;opacity:.6}details.sd-dropdown .sd-summary-up,details.sd-dropdown .sd-summary-down{pointer-events:none;position:absolute;right:1em;top:1em}details.sd-dropdown[open]>.sd-summary-title .sd-summary-down{visibility:hidden}details.sd-dropdown:not([open])>.sd-summary-title .sd-summary-up{visibility:hidden}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #007bff;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0069d9;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem} diff --git a/docs/_build/html/_static/design-tabs.js b/docs/_build/html/_static/design-tabs.js deleted file mode 100644 index 36b38cf..0000000 --- a/docs/_build/html/_static/design-tabs.js +++ /dev/null @@ -1,27 +0,0 @@ -var sd_labels_by_text = {}; - -function ready() { - const li = document.getElementsByClassName("sd-tab-label"); - for (const label of li) { - syncId = label.getAttribute("data-sync-id"); - if (syncId) { - label.onclick = onLabelClick; - if (!sd_labels_by_text[syncId]) { - sd_labels_by_text[syncId] = []; - } - sd_labels_by_text[syncId].push(label); - } - } -} - -function onLabelClick() { - // Activate other inputs with the same sync id. - syncId = this.getAttribute("data-sync-id"); - for (label of sd_labels_by_text[syncId]) { - if (label === this) continue; - label.previousElementSibling.checked = true; - } - window.localStorage.setItem("sphinx-design-last-tab", syncId); -} - -document.addEventListener("DOMContentLoaded", ready, false); diff --git a/docs/_build/html/_static/doctools.js b/docs/_build/html/_static/doctools.js deleted file mode 100644 index c3db08d..0000000 --- a/docs/_build/html/_static/doctools.js +++ /dev/null @@ -1,264 +0,0 @@ -/* - * doctools.js - * ~~~~~~~~~~~ - * - * Base JavaScript utilities for all Sphinx HTML documentation. - * - * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ -"use strict"; - -const _ready = (callback) => { - if (document.readyState !== "loading") { - callback(); - } else { - document.addEventListener("DOMContentLoaded", callback); - } -}; - -/** - * highlight a given string on a node by wrapping it in - * span elements with the given class name. - */ -const _highlight = (node, addItems, text, className) => { - if (node.nodeType === Node.TEXT_NODE) { - const val = node.nodeValue; - const parent = node.parentNode; - const pos = val.toLowerCase().indexOf(text); - if ( - pos >= 0 && - !parent.classList.contains(className) && - !parent.classList.contains("nohighlight") - ) { - let span; - - const closestNode = parent.closest("body, svg, foreignObject"); - const isInSVG = closestNode && closestNode.matches("svg"); - if (isInSVG) { - span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); - } else { - span = document.createElement("span"); - span.classList.add(className); - } - - span.appendChild(document.createTextNode(val.substr(pos, text.length))); - parent.insertBefore( - span, - parent.insertBefore( - document.createTextNode(val.substr(pos + text.length)), - node.nextSibling - ) - ); - node.nodeValue = val.substr(0, pos); - - if (isInSVG) { - const rect = document.createElementNS( - "http://www.w3.org/2000/svg", - "rect" - ); - const bbox = parent.getBBox(); - rect.x.baseVal.value = bbox.x; - rect.y.baseVal.value = bbox.y; - rect.width.baseVal.value = bbox.width; - rect.height.baseVal.value = bbox.height; - rect.setAttribute("class", className); - addItems.push({ parent: parent, target: rect }); - } - } - } else if (node.matches && !node.matches("button, select, textarea")) { - node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); - } -}; -const _highlightText = (thisNode, text, className) => { - let addItems = []; - _highlight(thisNode, addItems, text, className); - addItems.forEach((obj) => - obj.parent.insertAdjacentElement("beforebegin", obj.target) - ); -}; - -/** - * Small JavaScript module for the documentation. - */ -const Documentation = { - init: () => { - Documentation.highlightSearchWords(); - Documentation.initDomainIndexTable(); - Documentation.initOnKeyListeners(); - }, - - /** - * i18n support - */ - TRANSLATIONS: {}, - PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), - LOCALE: "unknown", - - // gettext and ngettext don't access this so that the functions - // can safely bound to a different name (_ = Documentation.gettext) - gettext: (string) => { - const translated = Documentation.TRANSLATIONS[string]; - switch (typeof translated) { - case "undefined": - return string; // no translation - case "string": - return translated; // translation exists - default: - return translated[0]; // (singular, plural) translation tuple exists - } - }, - - ngettext: (singular, plural, n) => { - const translated = Documentation.TRANSLATIONS[singular]; - if (typeof translated !== "undefined") - return translated[Documentation.PLURAL_EXPR(n)]; - return n === 1 ? singular : plural; - }, - - addTranslations: (catalog) => { - Object.assign(Documentation.TRANSLATIONS, catalog.messages); - Documentation.PLURAL_EXPR = new Function( - "n", - `return (${catalog.plural_expr})` - ); - Documentation.LOCALE = catalog.locale; - }, - - /** - * highlight the search words provided in the url in the text - */ - highlightSearchWords: () => { - const highlight = - new URLSearchParams(window.location.search).get("highlight") || ""; - const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); - if (terms.length === 0) return; // nothing to do - - // There should never be more than one element matching "div.body" - const divBody = document.querySelectorAll("div.body"); - const body = divBody.length ? divBody[0] : document.querySelector("body"); - window.setTimeout(() => { - terms.forEach((term) => _highlightText(body, term, "highlighted")); - }, 10); - - const searchBox = document.getElementById("searchbox"); - if (searchBox === null) return; - searchBox.appendChild( - document - .createRange() - .createContextualFragment( - '" - ) - ); - }, - - /** - * helper function to hide the search marks again - */ - hideSearchWords: () => { - document - .querySelectorAll("#searchbox .highlight-link") - .forEach((el) => el.remove()); - document - .querySelectorAll("span.highlighted") - .forEach((el) => el.classList.remove("highlighted")); - const url = new URL(window.location); - url.searchParams.delete("highlight"); - window.history.replaceState({}, "", url); - }, - - /** - * helper function to focus on search bar - */ - focusSearchBar: () => { - document.querySelectorAll("input[name=q]")[0]?.focus(); - }, - - /** - * Initialise the domain index toggle buttons - */ - initDomainIndexTable: () => { - const toggler = (el) => { - const idNumber = el.id.substr(7); - const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); - if (el.src.substr(-9) === "minus.png") { - el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; - toggledRows.forEach((el) => (el.style.display = "none")); - } else { - el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; - toggledRows.forEach((el) => (el.style.display = "")); - } - }; - - const togglerElements = document.querySelectorAll("img.toggler"); - togglerElements.forEach((el) => - el.addEventListener("click", (event) => toggler(event.currentTarget)) - ); - togglerElements.forEach((el) => (el.style.display = "")); - if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); - }, - - initOnKeyListeners: () => { - // only install a listener if it is really needed - if ( - !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && - !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS - ) - return; - - const blacklistedElements = new Set([ - "TEXTAREA", - "INPUT", - "SELECT", - "BUTTON", - ]); - document.addEventListener("keydown", (event) => { - if (blacklistedElements.has(document.activeElement.tagName)) return; // bail for input elements - if (event.altKey || event.ctrlKey || event.metaKey) return; // bail with special keys - - if (!event.shiftKey) { - switch (event.key) { - case "ArrowLeft": - if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; - - const prevLink = document.querySelector('link[rel="prev"]'); - if (prevLink && prevLink.href) { - window.location.href = prevLink.href; - event.preventDefault(); - } - break; - case "ArrowRight": - if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; - - const nextLink = document.querySelector('link[rel="next"]'); - if (nextLink && nextLink.href) { - window.location.href = nextLink.href; - event.preventDefault(); - } - break; - case "Escape": - if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; - Documentation.hideSearchWords(); - event.preventDefault(); - } - } - - // some keyboard layouts may need Shift to get / - switch (event.key) { - case "/": - if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; - Documentation.focusSearchBar(); - event.preventDefault(); - } - }); - }, -}; - -// quick alias for translations -const _ = Documentation.gettext; - -_ready(Documentation.init); diff --git a/docs/_build/html/_static/documentation_options.js b/docs/_build/html/_static/documentation_options.js deleted file mode 100644 index 162a6ba..0000000 --- a/docs/_build/html/_static/documentation_options.js +++ /dev/null @@ -1,14 +0,0 @@ -var DOCUMENTATION_OPTIONS = { - URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), - VERSION: '', - LANGUAGE: 'en', - COLLAPSE_INDEX: false, - BUILDER: 'html', - FILE_SUFFIX: '.html', - LINK_SUFFIX: '.html', - HAS_SOURCE: true, - SOURCELINK_SUFFIX: '', - NAVIGATION_WITH_KEYS: false, - SHOW_SEARCH_SUMMARY: true, - ENABLE_SEARCH_SHORTCUTS: false, -}; \ No newline at end of file diff --git a/docs/_build/html/_static/file.png b/docs/_build/html/_static/file.png deleted file mode 100644 index a858a41..0000000 Binary files a/docs/_build/html/_static/file.png and /dev/null differ diff --git a/docs/_build/html/_static/images/logo_binder.svg b/docs/_build/html/_static/images/logo_binder.svg deleted file mode 100644 index 45fecf7..0000000 --- a/docs/_build/html/_static/images/logo_binder.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - -logo - - - - - - - - diff --git a/docs/_build/html/_static/images/logo_colab.png b/docs/_build/html/_static/images/logo_colab.png deleted file mode 100644 index b7560ec..0000000 Binary files a/docs/_build/html/_static/images/logo_colab.png and /dev/null differ diff --git a/docs/_build/html/_static/images/logo_deepnote.svg b/docs/_build/html/_static/images/logo_deepnote.svg deleted file mode 100644 index fa77ebf..0000000 --- a/docs/_build/html/_static/images/logo_deepnote.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docs/_build/html/_static/images/logo_jupyterhub.svg b/docs/_build/html/_static/images/logo_jupyterhub.svg deleted file mode 100644 index 60cfe9f..0000000 --- a/docs/_build/html/_static/images/logo_jupyterhub.svg +++ /dev/null @@ -1 +0,0 @@ -logo_jupyterhubHub diff --git a/docs/_build/html/_static/jquery-3.6.0.js b/docs/_build/html/_static/jquery-3.6.0.js deleted file mode 100644 index fc6c299..0000000 --- a/docs/_build/html/_static/jquery-3.6.0.js +++ /dev/null @@ -1,10881 +0,0 @@ -/*! - * jQuery JavaScript Library v3.6.0 - * https://jquery.com/ - * - * Includes Sizzle.js - * https://sizzlejs.com/ - * - * Copyright OpenJS Foundation and other contributors - * Released under the MIT license - * https://jquery.org/license - * - * Date: 2021-03-02T17:08Z - */ -( function( global, factory ) { - - "use strict"; - - if ( typeof module === "object" && typeof module.exports === "object" ) { - - // For CommonJS and CommonJS-like environments where a proper `window` - // is present, execute the factory and get jQuery. - // For environments that do not have a `window` with a `document` - // (such as Node.js), expose a factory as module.exports. - // This accentuates the need for the creation of a real `window`. - // e.g. var jQuery = require("jquery")(window); - // See ticket #14549 for more info. - module.exports = global.document ? - factory( global, true ) : - function( w ) { - if ( !w.document ) { - throw new Error( "jQuery requires a window with a document" ); - } - return factory( w ); - }; - } else { - factory( global ); - } - -// Pass this if window is not defined yet -} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { - -// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 -// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode -// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common -// enough that all such attempts are guarded in a try block. -"use strict"; - -var arr = []; - -var getProto = Object.getPrototypeOf; - -var slice = arr.slice; - -var flat = arr.flat ? function( array ) { - return arr.flat.call( array ); -} : function( array ) { - return arr.concat.apply( [], array ); -}; - - -var push = arr.push; - -var indexOf = arr.indexOf; - -var class2type = {}; - -var toString = class2type.toString; - -var hasOwn = class2type.hasOwnProperty; - -var fnToString = hasOwn.toString; - -var ObjectFunctionString = fnToString.call( Object ); - -var support = {}; - -var isFunction = function isFunction( obj ) { - - // Support: Chrome <=57, Firefox <=52 - // In some browsers, typeof returns "function" for HTML elements - // (i.e., `typeof document.createElement( "object" ) === "function"`). - // We don't want to classify *any* DOM node as a function. - // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5 - // Plus for old WebKit, typeof returns "function" for HTML collections - // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756) - return typeof obj === "function" && typeof obj.nodeType !== "number" && - typeof obj.item !== "function"; - }; - - -var isWindow = function isWindow( obj ) { - return obj != null && obj === obj.window; - }; - - -var document = window.document; - - - - var preservedScriptAttributes = { - type: true, - src: true, - nonce: true, - noModule: true - }; - - function DOMEval( code, node, doc ) { - doc = doc || document; - - var i, val, - script = doc.createElement( "script" ); - - script.text = code; - if ( node ) { - for ( i in preservedScriptAttributes ) { - - // Support: Firefox 64+, Edge 18+ - // Some browsers don't support the "nonce" property on scripts. - // On the other hand, just using `getAttribute` is not enough as - // the `nonce` attribute is reset to an empty string whenever it - // becomes browsing-context connected. - // See https://github.com/whatwg/html/issues/2369 - // See https://html.spec.whatwg.org/#nonce-attributes - // The `node.getAttribute` check was added for the sake of - // `jQuery.globalEval` so that it can fake a nonce-containing node - // via an object. - val = node[ i ] || node.getAttribute && node.getAttribute( i ); - if ( val ) { - script.setAttribute( i, val ); - } - } - } - doc.head.appendChild( script ).parentNode.removeChild( script ); - } - - -function toType( obj ) { - if ( obj == null ) { - return obj + ""; - } - - // Support: Android <=2.3 only (functionish RegExp) - return typeof obj === "object" || typeof obj === "function" ? - class2type[ toString.call( obj ) ] || "object" : - typeof obj; -} -/* global Symbol */ -// Defining this global in .eslintrc.json would create a danger of using the global -// unguarded in another place, it seems safer to define global only for this module - - - -var - version = "3.6.0", - - // Define a local copy of jQuery - jQuery = function( selector, context ) { - - // The jQuery object is actually just the init constructor 'enhanced' - // Need init if jQuery is called (just allow error to be thrown if not included) - return new jQuery.fn.init( selector, context ); - }; - -jQuery.fn = jQuery.prototype = { - - // The current version of jQuery being used - jquery: version, - - constructor: jQuery, - - // The default length of a jQuery object is 0 - length: 0, - - toArray: function() { - return slice.call( this ); - }, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { - - // Return all the elements in a clean array - if ( num == null ) { - return slice.call( this ); - } - - // Return just the one element from the set - return num < 0 ? this[ num + this.length ] : this[ num ]; - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems ) { - - // Build a new jQuery matched element set - var ret = jQuery.merge( this.constructor(), elems ); - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - - // Return the newly-formed element set - return ret; - }, - - // Execute a callback for every element in the matched set. - each: function( callback ) { - return jQuery.each( this, callback ); - }, - - map: function( callback ) { - return this.pushStack( jQuery.map( this, function( elem, i ) { - return callback.call( elem, i, elem ); - } ) ); - }, - - slice: function() { - return this.pushStack( slice.apply( this, arguments ) ); - }, - - first: function() { - return this.eq( 0 ); - }, - - last: function() { - return this.eq( -1 ); - }, - - even: function() { - return this.pushStack( jQuery.grep( this, function( _elem, i ) { - return ( i + 1 ) % 2; - } ) ); - }, - - odd: function() { - return this.pushStack( jQuery.grep( this, function( _elem, i ) { - return i % 2; - } ) ); - }, - - eq: function( i ) { - var len = this.length, - j = +i + ( i < 0 ? len : 0 ); - return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); - }, - - end: function() { - return this.prevObject || this.constructor(); - }, - - // For internal use only. - // Behaves like an Array's method, not like a jQuery method. - push: push, - sort: arr.sort, - splice: arr.splice -}; - -jQuery.extend = jQuery.fn.extend = function() { - var options, name, src, copy, copyIsArray, clone, - target = arguments[ 0 ] || {}, - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - - // Skip the boolean and the target - target = arguments[ i ] || {}; - i++; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !isFunction( target ) ) { - target = {}; - } - - // Extend jQuery itself if only one argument is passed - if ( i === length ) { - target = this; - i--; - } - - for ( ; i < length; i++ ) { - - // Only deal with non-null/undefined values - if ( ( options = arguments[ i ] ) != null ) { - - // Extend the base object - for ( name in options ) { - copy = options[ name ]; - - // Prevent Object.prototype pollution - // Prevent never-ending loop - if ( name === "__proto__" || target === copy ) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( jQuery.isPlainObject( copy ) || - ( copyIsArray = Array.isArray( copy ) ) ) ) { - src = target[ name ]; - - // Ensure proper type for the source value - if ( copyIsArray && !Array.isArray( src ) ) { - clone = []; - } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { - clone = {}; - } else { - clone = src; - } - copyIsArray = false; - - // Never move original objects, clone them - target[ name ] = jQuery.extend( deep, clone, copy ); - - // Don't bring in undefined values - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - } - } - - // Return the modified object - return target; -}; - -jQuery.extend( { - - // Unique for each copy of jQuery on the page - expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), - - // Assume jQuery is ready without the ready module - isReady: true, - - error: function( msg ) { - throw new Error( msg ); - }, - - noop: function() {}, - - isPlainObject: function( obj ) { - var proto, Ctor; - - // Detect obvious negatives - // Use toString instead of jQuery.type to catch host objects - if ( !obj || toString.call( obj ) !== "[object Object]" ) { - return false; - } - - proto = getProto( obj ); - - // Objects with no prototype (e.g., `Object.create( null )`) are plain - if ( !proto ) { - return true; - } - - // Objects with prototype are plain iff they were constructed by a global Object function - Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; - return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; - }, - - isEmptyObject: function( obj ) { - var name; - - for ( name in obj ) { - return false; - } - return true; - }, - - // Evaluates a script in a provided context; falls back to the global one - // if not specified. - globalEval: function( code, options, doc ) { - DOMEval( code, { nonce: options && options.nonce }, doc ); - }, - - each: function( obj, callback ) { - var length, i = 0; - - if ( isArrayLike( obj ) ) { - length = obj.length; - for ( ; i < length; i++ ) { - if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { - break; - } - } - } else { - for ( i in obj ) { - if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { - break; - } - } - } - - return obj; - }, - - // results is for internal usage only - makeArray: function( arr, results ) { - var ret = results || []; - - if ( arr != null ) { - if ( isArrayLike( Object( arr ) ) ) { - jQuery.merge( ret, - typeof arr === "string" ? - [ arr ] : arr - ); - } else { - push.call( ret, arr ); - } - } - - return ret; - }, - - inArray: function( elem, arr, i ) { - return arr == null ? -1 : indexOf.call( arr, elem, i ); - }, - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - merge: function( first, second ) { - var len = +second.length, - j = 0, - i = first.length; - - for ( ; j < len; j++ ) { - first[ i++ ] = second[ j ]; - } - - first.length = i; - - return first; - }, - - grep: function( elems, callback, invert ) { - var callbackInverse, - matches = [], - i = 0, - length = elems.length, - callbackExpect = !invert; - - // Go through the array, only saving the items - // that pass the validator function - for ( ; i < length; i++ ) { - callbackInverse = !callback( elems[ i ], i ); - if ( callbackInverse !== callbackExpect ) { - matches.push( elems[ i ] ); - } - } - - return matches; - }, - - // arg is for internal usage only - map: function( elems, callback, arg ) { - var length, value, - i = 0, - ret = []; - - // Go through the array, translating each of the items to their new values - if ( isArrayLike( elems ) ) { - length = elems.length; - for ( ; i < length; i++ ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - - // Go through every key on the object, - } else { - for ( i in elems ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - } - - // Flatten any nested arrays - return flat( ret ); - }, - - // A global GUID counter for objects - guid: 1, - - // jQuery.support is not used in Core but other projects attach their - // properties to it so it needs to exist. - support: support -} ); - -if ( typeof Symbol === "function" ) { - jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; -} - -// Populate the class2type map -jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), - function( _i, name ) { - class2type[ "[object " + name + "]" ] = name.toLowerCase(); - } ); - -function isArrayLike( obj ) { - - // Support: real iOS 8.2 only (not reproducible in simulator) - // `in` check used to prevent JIT error (gh-2145) - // hasOwn isn't used here due to false negatives - // regarding Nodelist length in IE - var length = !!obj && "length" in obj && obj.length, - type = toType( obj ); - - if ( isFunction( obj ) || isWindow( obj ) ) { - return false; - } - - return type === "array" || length === 0 || - typeof length === "number" && length > 0 && ( length - 1 ) in obj; -} -var Sizzle = -/*! - * Sizzle CSS Selector Engine v2.3.6 - * https://sizzlejs.com/ - * - * Copyright JS Foundation and other contributors - * Released under the MIT license - * https://js.foundation/ - * - * Date: 2021-02-16 - */ -( function( window ) { -var i, - support, - Expr, - getText, - isXML, - tokenize, - compile, - select, - outermostContext, - sortInput, - hasDuplicate, - - // Local document vars - setDocument, - document, - docElem, - documentIsHTML, - rbuggyQSA, - rbuggyMatches, - matches, - contains, - - // Instance-specific data - expando = "sizzle" + 1 * new Date(), - preferredDoc = window.document, - dirruns = 0, - done = 0, - classCache = createCache(), - tokenCache = createCache(), - compilerCache = createCache(), - nonnativeSelectorCache = createCache(), - sortOrder = function( a, b ) { - if ( a === b ) { - hasDuplicate = true; - } - return 0; - }, - - // Instance methods - hasOwn = ( {} ).hasOwnProperty, - arr = [], - pop = arr.pop, - pushNative = arr.push, - push = arr.push, - slice = arr.slice, - - // Use a stripped-down indexOf as it's faster than native - // https://jsperf.com/thor-indexof-vs-for/5 - indexOf = function( list, elem ) { - var i = 0, - len = list.length; - for ( ; i < len; i++ ) { - if ( list[ i ] === elem ) { - return i; - } - } - return -1; - }, - - booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + - "ismap|loop|multiple|open|readonly|required|scoped", - - // Regular expressions - - // http://www.w3.org/TR/css3-selectors/#whitespace - whitespace = "[\\x20\\t\\r\\n\\f]", - - // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram - identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + - "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", - - // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors - attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + - - // Operator (capture 2) - "*([*^$|!~]?=)" + whitespace + - - // "Attribute values must be CSS identifiers [capture 5] - // or strings [capture 3 or capture 4]" - "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + - whitespace + "*\\]", - - pseudos = ":(" + identifier + ")(?:\\((" + - - // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: - // 1. quoted (capture 3; capture 4 or capture 5) - "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + - - // 2. simple (capture 6) - "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + - - // 3. anything else (capture 2) - ".*" + - ")\\)|)", - - // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter - rwhitespace = new RegExp( whitespace + "+", "g" ), - rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + - whitespace + "+$", "g" ), - - rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), - rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + - "*" ), - rdescend = new RegExp( whitespace + "|>" ), - - rpseudo = new RegExp( pseudos ), - ridentifier = new RegExp( "^" + identifier + "$" ), - - matchExpr = { - "ID": new RegExp( "^#(" + identifier + ")" ), - "CLASS": new RegExp( "^\\.(" + identifier + ")" ), - "TAG": new RegExp( "^(" + identifier + "|[*])" ), - "ATTR": new RegExp( "^" + attributes ), - "PSEUDO": new RegExp( "^" + pseudos ), - "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + - whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + - whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), - "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), - - // For use in libraries implementing .is() - // We use this for POS matching in `select` - "needsContext": new RegExp( "^" + whitespace + - "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + - "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) - }, - - rhtml = /HTML$/i, - rinputs = /^(?:input|select|textarea|button)$/i, - rheader = /^h\d$/i, - - rnative = /^[^{]+\{\s*\[native \w/, - - // Easily-parseable/retrievable ID or TAG or CLASS selectors - rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, - - rsibling = /[+~]/, - - // CSS escapes - // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters - runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), - funescape = function( escape, nonHex ) { - var high = "0x" + escape.slice( 1 ) - 0x10000; - - return nonHex ? - - // Strip the backslash prefix from a non-hex escape sequence - nonHex : - - // Replace a hexadecimal escape sequence with the encoded Unicode code point - // Support: IE <=11+ - // For values outside the Basic Multilingual Plane (BMP), manually construct a - // surrogate pair - high < 0 ? - String.fromCharCode( high + 0x10000 ) : - String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); - }, - - // CSS string/identifier serialization - // https://drafts.csswg.org/cssom/#common-serializing-idioms - rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, - fcssescape = function( ch, asCodePoint ) { - if ( asCodePoint ) { - - // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER - if ( ch === "\0" ) { - return "\uFFFD"; - } - - // Control characters and (dependent upon position) numbers get escaped as code points - return ch.slice( 0, -1 ) + "\\" + - ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; - } - - // Other potentially-special ASCII characters get backslash-escaped - return "\\" + ch; - }, - - // Used for iframes - // See setDocument() - // Removing the function wrapper causes a "Permission Denied" - // error in IE - unloadHandler = function() { - setDocument(); - }, - - inDisabledFieldset = addCombinator( - function( elem ) { - return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; - }, - { dir: "parentNode", next: "legend" } - ); - -// Optimize for push.apply( _, NodeList ) -try { - push.apply( - ( arr = slice.call( preferredDoc.childNodes ) ), - preferredDoc.childNodes - ); - - // Support: Android<4.0 - // Detect silently failing push.apply - // eslint-disable-next-line no-unused-expressions - arr[ preferredDoc.childNodes.length ].nodeType; -} catch ( e ) { - push = { apply: arr.length ? - - // Leverage slice if possible - function( target, els ) { - pushNative.apply( target, slice.call( els ) ); - } : - - // Support: IE<9 - // Otherwise append directly - function( target, els ) { - var j = target.length, - i = 0; - - // Can't trust NodeList.length - while ( ( target[ j++ ] = els[ i++ ] ) ) {} - target.length = j - 1; - } - }; -} - -function Sizzle( selector, context, results, seed ) { - var m, i, elem, nid, match, groups, newSelector, - newContext = context && context.ownerDocument, - - // nodeType defaults to 9, since context defaults to document - nodeType = context ? context.nodeType : 9; - - results = results || []; - - // Return early from calls with invalid selector or context - if ( typeof selector !== "string" || !selector || - nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { - - return results; - } - - // Try to shortcut find operations (as opposed to filters) in HTML documents - if ( !seed ) { - setDocument( context ); - context = context || document; - - if ( documentIsHTML ) { - - // If the selector is sufficiently simple, try using a "get*By*" DOM method - // (excepting DocumentFragment context, where the methods don't exist) - if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { - - // ID selector - if ( ( m = match[ 1 ] ) ) { - - // Document context - if ( nodeType === 9 ) { - if ( ( elem = context.getElementById( m ) ) ) { - - // Support: IE, Opera, Webkit - // TODO: identify versions - // getElementById can match elements by name instead of ID - if ( elem.id === m ) { - results.push( elem ); - return results; - } - } else { - return results; - } - - // Element context - } else { - - // Support: IE, Opera, Webkit - // TODO: identify versions - // getElementById can match elements by name instead of ID - if ( newContext && ( elem = newContext.getElementById( m ) ) && - contains( context, elem ) && - elem.id === m ) { - - results.push( elem ); - return results; - } - } - - // Type selector - } else if ( match[ 2 ] ) { - push.apply( results, context.getElementsByTagName( selector ) ); - return results; - - // Class selector - } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && - context.getElementsByClassName ) { - - push.apply( results, context.getElementsByClassName( m ) ); - return results; - } - } - - // Take advantage of querySelectorAll - if ( support.qsa && - !nonnativeSelectorCache[ selector + " " ] && - ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && - - // Support: IE 8 only - // Exclude object elements - ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { - - newSelector = selector; - newContext = context; - - // qSA considers elements outside a scoping root when evaluating child or - // descendant combinators, which is not what we want. - // In such cases, we work around the behavior by prefixing every selector in the - // list with an ID selector referencing the scope context. - // The technique has to be used as well when a leading combinator is used - // as such selectors are not recognized by querySelectorAll. - // Thanks to Andrew Dupont for this technique. - if ( nodeType === 1 && - ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { - - // Expand context for sibling selectors - newContext = rsibling.test( selector ) && testContext( context.parentNode ) || - context; - - // We can use :scope instead of the ID hack if the browser - // supports it & if we're not changing the context. - if ( newContext !== context || !support.scope ) { - - // Capture the context ID, setting it first if necessary - if ( ( nid = context.getAttribute( "id" ) ) ) { - nid = nid.replace( rcssescape, fcssescape ); - } else { - context.setAttribute( "id", ( nid = expando ) ); - } - } - - // Prefix every selector in the list - groups = tokenize( selector ); - i = groups.length; - while ( i-- ) { - groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + - toSelector( groups[ i ] ); - } - newSelector = groups.join( "," ); - } - - try { - push.apply( results, - newContext.querySelectorAll( newSelector ) - ); - return results; - } catch ( qsaError ) { - nonnativeSelectorCache( selector, true ); - } finally { - if ( nid === expando ) { - context.removeAttribute( "id" ); - } - } - } - } - } - - // All others - return select( selector.replace( rtrim, "$1" ), context, results, seed ); -} - -/** - * Create key-value caches of limited size - * @returns {function(string, object)} Returns the Object data after storing it on itself with - * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) - * deleting the oldest entry - */ -function createCache() { - var keys = []; - - function cache( key, value ) { - - // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) - if ( keys.push( key + " " ) > Expr.cacheLength ) { - - // Only keep the most recent entries - delete cache[ keys.shift() ]; - } - return ( cache[ key + " " ] = value ); - } - return cache; -} - -/** - * Mark a function for special use by Sizzle - * @param {Function} fn The function to mark - */ -function markFunction( fn ) { - fn[ expando ] = true; - return fn; -} - -/** - * Support testing using an element - * @param {Function} fn Passed the created element and returns a boolean result - */ -function assert( fn ) { - var el = document.createElement( "fieldset" ); - - try { - return !!fn( el ); - } catch ( e ) { - return false; - } finally { - - // Remove from its parent by default - if ( el.parentNode ) { - el.parentNode.removeChild( el ); - } - - // release memory in IE - el = null; - } -} - -/** - * Adds the same handler for all of the specified attrs - * @param {String} attrs Pipe-separated list of attributes - * @param {Function} handler The method that will be applied - */ -function addHandle( attrs, handler ) { - var arr = attrs.split( "|" ), - i = arr.length; - - while ( i-- ) { - Expr.attrHandle[ arr[ i ] ] = handler; - } -} - -/** - * Checks document order of two siblings - * @param {Element} a - * @param {Element} b - * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b - */ -function siblingCheck( a, b ) { - var cur = b && a, - diff = cur && a.nodeType === 1 && b.nodeType === 1 && - a.sourceIndex - b.sourceIndex; - - // Use IE sourceIndex if available on both nodes - if ( diff ) { - return diff; - } - - // Check if b follows a - if ( cur ) { - while ( ( cur = cur.nextSibling ) ) { - if ( cur === b ) { - return -1; - } - } - } - - return a ? 1 : -1; -} - -/** - * Returns a function to use in pseudos for input types - * @param {String} type - */ -function createInputPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for buttons - * @param {String} type - */ -function createButtonPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return ( name === "input" || name === "button" ) && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for :enabled/:disabled - * @param {Boolean} disabled true for :disabled; false for :enabled - */ -function createDisabledPseudo( disabled ) { - - // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable - return function( elem ) { - - // Only certain elements can match :enabled or :disabled - // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled - // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled - if ( "form" in elem ) { - - // Check for inherited disabledness on relevant non-disabled elements: - // * listed form-associated elements in a disabled fieldset - // https://html.spec.whatwg.org/multipage/forms.html#category-listed - // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled - // * option elements in a disabled optgroup - // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled - // All such elements have a "form" property. - if ( elem.parentNode && elem.disabled === false ) { - - // Option elements defer to a parent optgroup if present - if ( "label" in elem ) { - if ( "label" in elem.parentNode ) { - return elem.parentNode.disabled === disabled; - } else { - return elem.disabled === disabled; - } - } - - // Support: IE 6 - 11 - // Use the isDisabled shortcut property to check for disabled fieldset ancestors - return elem.isDisabled === disabled || - - // Where there is no isDisabled, check manually - /* jshint -W018 */ - elem.isDisabled !== !disabled && - inDisabledFieldset( elem ) === disabled; - } - - return elem.disabled === disabled; - - // Try to winnow out elements that can't be disabled before trusting the disabled property. - // Some victims get caught in our net (label, legend, menu, track), but it shouldn't - // even exist on them, let alone have a boolean value. - } else if ( "label" in elem ) { - return elem.disabled === disabled; - } - - // Remaining elements are neither :enabled nor :disabled - return false; - }; -} - -/** - * Returns a function to use in pseudos for positionals - * @param {Function} fn - */ -function createPositionalPseudo( fn ) { - return markFunction( function( argument ) { - argument = +argument; - return markFunction( function( seed, matches ) { - var j, - matchIndexes = fn( [], seed.length, argument ), - i = matchIndexes.length; - - // Match elements found at the specified indexes - while ( i-- ) { - if ( seed[ ( j = matchIndexes[ i ] ) ] ) { - seed[ j ] = !( matches[ j ] = seed[ j ] ); - } - } - } ); - } ); -} - -/** - * Checks a node for validity as a Sizzle context - * @param {Element|Object=} context - * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value - */ -function testContext( context ) { - return context && typeof context.getElementsByTagName !== "undefined" && context; -} - -// Expose support vars for convenience -support = Sizzle.support = {}; - -/** - * Detects XML nodes - * @param {Element|Object} elem An element or a document - * @returns {Boolean} True iff elem is a non-HTML XML node - */ -isXML = Sizzle.isXML = function( elem ) { - var namespace = elem && elem.namespaceURI, - docElem = elem && ( elem.ownerDocument || elem ).documentElement; - - // Support: IE <=8 - // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes - // https://bugs.jquery.com/ticket/4833 - return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); -}; - -/** - * Sets document-related variables once based on the current document - * @param {Element|Object} [doc] An element or document object to use to set the document - * @returns {Object} Returns the current document - */ -setDocument = Sizzle.setDocument = function( node ) { - var hasCompare, subWindow, - doc = node ? node.ownerDocument || node : preferredDoc; - - // Return early if doc is invalid or already selected - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { - return document; - } - - // Update global variables - document = doc; - docElem = document.documentElement; - documentIsHTML = !isXML( document ); - - // Support: IE 9 - 11+, Edge 12 - 18+ - // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( preferredDoc != document && - ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { - - // Support: IE 11, Edge - if ( subWindow.addEventListener ) { - subWindow.addEventListener( "unload", unloadHandler, false ); - - // Support: IE 9 - 10 only - } else if ( subWindow.attachEvent ) { - subWindow.attachEvent( "onunload", unloadHandler ); - } - } - - // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, - // Safari 4 - 5 only, Opera <=11.6 - 12.x only - // IE/Edge & older browsers don't support the :scope pseudo-class. - // Support: Safari 6.0 only - // Safari 6.0 supports :scope but it's an alias of :root there. - support.scope = assert( function( el ) { - docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); - return typeof el.querySelectorAll !== "undefined" && - !el.querySelectorAll( ":scope fieldset div" ).length; - } ); - - /* Attributes - ---------------------------------------------------------------------- */ - - // Support: IE<8 - // Verify that getAttribute really returns attributes and not properties - // (excepting IE8 booleans) - support.attributes = assert( function( el ) { - el.className = "i"; - return !el.getAttribute( "className" ); - } ); - - /* getElement(s)By* - ---------------------------------------------------------------------- */ - - // Check if getElementsByTagName("*") returns only elements - support.getElementsByTagName = assert( function( el ) { - el.appendChild( document.createComment( "" ) ); - return !el.getElementsByTagName( "*" ).length; - } ); - - // Support: IE<9 - support.getElementsByClassName = rnative.test( document.getElementsByClassName ); - - // Support: IE<10 - // Check if getElementById returns elements by name - // The broken getElementById methods don't pick up programmatically-set names, - // so use a roundabout getElementsByName test - support.getById = assert( function( el ) { - docElem.appendChild( el ).id = expando; - return !document.getElementsByName || !document.getElementsByName( expando ).length; - } ); - - // ID filter and find - if ( support.getById ) { - Expr.filter[ "ID" ] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - return elem.getAttribute( "id" ) === attrId; - }; - }; - Expr.find[ "ID" ] = function( id, context ) { - if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { - var elem = context.getElementById( id ); - return elem ? [ elem ] : []; - } - }; - } else { - Expr.filter[ "ID" ] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - var node = typeof elem.getAttributeNode !== "undefined" && - elem.getAttributeNode( "id" ); - return node && node.value === attrId; - }; - }; - - // Support: IE 6 - 7 only - // getElementById is not reliable as a find shortcut - Expr.find[ "ID" ] = function( id, context ) { - if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { - var node, i, elems, - elem = context.getElementById( id ); - - if ( elem ) { - - // Verify the id attribute - node = elem.getAttributeNode( "id" ); - if ( node && node.value === id ) { - return [ elem ]; - } - - // Fall back on getElementsByName - elems = context.getElementsByName( id ); - i = 0; - while ( ( elem = elems[ i++ ] ) ) { - node = elem.getAttributeNode( "id" ); - if ( node && node.value === id ) { - return [ elem ]; - } - } - } - - return []; - } - }; - } - - // Tag - Expr.find[ "TAG" ] = support.getElementsByTagName ? - function( tag, context ) { - if ( typeof context.getElementsByTagName !== "undefined" ) { - return context.getElementsByTagName( tag ); - - // DocumentFragment nodes don't have gEBTN - } else if ( support.qsa ) { - return context.querySelectorAll( tag ); - } - } : - - function( tag, context ) { - var elem, - tmp = [], - i = 0, - - // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too - results = context.getElementsByTagName( tag ); - - // Filter out possible comments - if ( tag === "*" ) { - while ( ( elem = results[ i++ ] ) ) { - if ( elem.nodeType === 1 ) { - tmp.push( elem ); - } - } - - return tmp; - } - return results; - }; - - // Class - Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { - if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { - return context.getElementsByClassName( className ); - } - }; - - /* QSA/matchesSelector - ---------------------------------------------------------------------- */ - - // QSA and matchesSelector support - - // matchesSelector(:active) reports false when true (IE9/Opera 11.5) - rbuggyMatches = []; - - // qSa(:focus) reports false when true (Chrome 21) - // We allow this because of a bug in IE8/9 that throws an error - // whenever `document.activeElement` is accessed on an iframe - // So, we allow :focus to pass through QSA all the time to avoid the IE error - // See https://bugs.jquery.com/ticket/13378 - rbuggyQSA = []; - - if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { - - // Build QSA regex - // Regex strategy adopted from Diego Perini - assert( function( el ) { - - var input; - - // Select is set to empty string on purpose - // This is to test IE's treatment of not explicitly - // setting a boolean content attribute, - // since its presence should be enough - // https://bugs.jquery.com/ticket/12359 - docElem.appendChild( el ).innerHTML = "" + - ""; - - // Support: IE8, Opera 11-12.16 - // Nothing should be selected when empty strings follow ^= or $= or *= - // The test attribute must be unknown in Opera but "safe" for WinRT - // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section - if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { - rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); - } - - // Support: IE8 - // Boolean attributes and "value" are not treated correctly - if ( !el.querySelectorAll( "[selected]" ).length ) { - rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); - } - - // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ - if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { - rbuggyQSA.push( "~=" ); - } - - // Support: IE 11+, Edge 15 - 18+ - // IE 11/Edge don't find elements on a `[name='']` query in some cases. - // Adding a temporary attribute to the document before the selection works - // around the issue. - // Interestingly, IE 10 & older don't seem to have the issue. - input = document.createElement( "input" ); - input.setAttribute( "name", "" ); - el.appendChild( input ); - if ( !el.querySelectorAll( "[name='']" ).length ) { - rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + - whitespace + "*(?:''|\"\")" ); - } - - // Webkit/Opera - :checked should return selected option elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - // IE8 throws error here and will not see later tests - if ( !el.querySelectorAll( ":checked" ).length ) { - rbuggyQSA.push( ":checked" ); - } - - // Support: Safari 8+, iOS 8+ - // https://bugs.webkit.org/show_bug.cgi?id=136851 - // In-page `selector#id sibling-combinator selector` fails - if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { - rbuggyQSA.push( ".#.+[+~]" ); - } - - // Support: Firefox <=3.6 - 5 only - // Old Firefox doesn't throw on a badly-escaped identifier. - el.querySelectorAll( "\\\f" ); - rbuggyQSA.push( "[\\r\\n\\f]" ); - } ); - - assert( function( el ) { - el.innerHTML = "" + - ""; - - // Support: Windows 8 Native Apps - // The type and name attributes are restricted during .innerHTML assignment - var input = document.createElement( "input" ); - input.setAttribute( "type", "hidden" ); - el.appendChild( input ).setAttribute( "name", "D" ); - - // Support: IE8 - // Enforce case-sensitivity of name attribute - if ( el.querySelectorAll( "[name=d]" ).length ) { - rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); - } - - // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) - // IE8 throws error here and will not see later tests - if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { - rbuggyQSA.push( ":enabled", ":disabled" ); - } - - // Support: IE9-11+ - // IE's :disabled selector does not pick up the children of disabled fieldsets - docElem.appendChild( el ).disabled = true; - if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { - rbuggyQSA.push( ":enabled", ":disabled" ); - } - - // Support: Opera 10 - 11 only - // Opera 10-11 does not throw on post-comma invalid pseudos - el.querySelectorAll( "*,:x" ); - rbuggyQSA.push( ",.*:" ); - } ); - } - - if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || - docElem.webkitMatchesSelector || - docElem.mozMatchesSelector || - docElem.oMatchesSelector || - docElem.msMatchesSelector ) ) ) ) { - - assert( function( el ) { - - // Check to see if it's possible to do matchesSelector - // on a disconnected node (IE 9) - support.disconnectedMatch = matches.call( el, "*" ); - - // This should fail with an exception - // Gecko does not error, returns false instead - matches.call( el, "[s!='']:x" ); - rbuggyMatches.push( "!=", pseudos ); - } ); - } - - rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); - rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); - - /* Contains - ---------------------------------------------------------------------- */ - hasCompare = rnative.test( docElem.compareDocumentPosition ); - - // Element contains another - // Purposefully self-exclusive - // As in, an element does not contain itself - contains = hasCompare || rnative.test( docElem.contains ) ? - function( a, b ) { - var adown = a.nodeType === 9 ? a.documentElement : a, - bup = b && b.parentNode; - return a === bup || !!( bup && bup.nodeType === 1 && ( - adown.contains ? - adown.contains( bup ) : - a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 - ) ); - } : - function( a, b ) { - if ( b ) { - while ( ( b = b.parentNode ) ) { - if ( b === a ) { - return true; - } - } - } - return false; - }; - - /* Sorting - ---------------------------------------------------------------------- */ - - // Document order sorting - sortOrder = hasCompare ? - function( a, b ) { - - // Flag for duplicate removal - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - // Sort on method existence if only one input has compareDocumentPosition - var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; - if ( compare ) { - return compare; - } - - // Calculate position if both inputs belong to the same document - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? - a.compareDocumentPosition( b ) : - - // Otherwise we know they are disconnected - 1; - - // Disconnected nodes - if ( compare & 1 || - ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { - - // Choose the first element that is related to our preferred document - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( a == document || a.ownerDocument == preferredDoc && - contains( preferredDoc, a ) ) { - return -1; - } - - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( b == document || b.ownerDocument == preferredDoc && - contains( preferredDoc, b ) ) { - return 1; - } - - // Maintain original order - return sortInput ? - ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : - 0; - } - - return compare & 4 ? -1 : 1; - } : - function( a, b ) { - - // Exit early if the nodes are identical - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - var cur, - i = 0, - aup = a.parentNode, - bup = b.parentNode, - ap = [ a ], - bp = [ b ]; - - // Parentless nodes are either documents or disconnected - if ( !aup || !bup ) { - - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - /* eslint-disable eqeqeq */ - return a == document ? -1 : - b == document ? 1 : - /* eslint-enable eqeqeq */ - aup ? -1 : - bup ? 1 : - sortInput ? - ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : - 0; - - // If the nodes are siblings, we can do a quick check - } else if ( aup === bup ) { - return siblingCheck( a, b ); - } - - // Otherwise we need full lists of their ancestors for comparison - cur = a; - while ( ( cur = cur.parentNode ) ) { - ap.unshift( cur ); - } - cur = b; - while ( ( cur = cur.parentNode ) ) { - bp.unshift( cur ); - } - - // Walk down the tree looking for a discrepancy - while ( ap[ i ] === bp[ i ] ) { - i++; - } - - return i ? - - // Do a sibling check if the nodes have a common ancestor - siblingCheck( ap[ i ], bp[ i ] ) : - - // Otherwise nodes in our document sort first - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - /* eslint-disable eqeqeq */ - ap[ i ] == preferredDoc ? -1 : - bp[ i ] == preferredDoc ? 1 : - /* eslint-enable eqeqeq */ - 0; - }; - - return document; -}; - -Sizzle.matches = function( expr, elements ) { - return Sizzle( expr, null, null, elements ); -}; - -Sizzle.matchesSelector = function( elem, expr ) { - setDocument( elem ); - - if ( support.matchesSelector && documentIsHTML && - !nonnativeSelectorCache[ expr + " " ] && - ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && - ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { - - try { - var ret = matches.call( elem, expr ); - - // IE 9's matchesSelector returns false on disconnected nodes - if ( ret || support.disconnectedMatch || - - // As well, disconnected nodes are said to be in a document - // fragment in IE 9 - elem.document && elem.document.nodeType !== 11 ) { - return ret; - } - } catch ( e ) { - nonnativeSelectorCache( expr, true ); - } - } - - return Sizzle( expr, document, null, [ elem ] ).length > 0; -}; - -Sizzle.contains = function( context, elem ) { - - // Set document vars if needed - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( ( context.ownerDocument || context ) != document ) { - setDocument( context ); - } - return contains( context, elem ); -}; - -Sizzle.attr = function( elem, name ) { - - // Set document vars if needed - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( ( elem.ownerDocument || elem ) != document ) { - setDocument( elem ); - } - - var fn = Expr.attrHandle[ name.toLowerCase() ], - - // Don't get fooled by Object.prototype properties (jQuery #13807) - val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? - fn( elem, name, !documentIsHTML ) : - undefined; - - return val !== undefined ? - val : - support.attributes || !documentIsHTML ? - elem.getAttribute( name ) : - ( val = elem.getAttributeNode( name ) ) && val.specified ? - val.value : - null; -}; - -Sizzle.escape = function( sel ) { - return ( sel + "" ).replace( rcssescape, fcssescape ); -}; - -Sizzle.error = function( msg ) { - throw new Error( "Syntax error, unrecognized expression: " + msg ); -}; - -/** - * Document sorting and removing duplicates - * @param {ArrayLike} results - */ -Sizzle.uniqueSort = function( results ) { - var elem, - duplicates = [], - j = 0, - i = 0; - - // Unless we *know* we can detect duplicates, assume their presence - hasDuplicate = !support.detectDuplicates; - sortInput = !support.sortStable && results.slice( 0 ); - results.sort( sortOrder ); - - if ( hasDuplicate ) { - while ( ( elem = results[ i++ ] ) ) { - if ( elem === results[ i ] ) { - j = duplicates.push( i ); - } - } - while ( j-- ) { - results.splice( duplicates[ j ], 1 ); - } - } - - // Clear input after sorting to release objects - // See https://github.com/jquery/sizzle/pull/225 - sortInput = null; - - return results; -}; - -/** - * Utility function for retrieving the text value of an array of DOM nodes - * @param {Array|Element} elem - */ -getText = Sizzle.getText = function( elem ) { - var node, - ret = "", - i = 0, - nodeType = elem.nodeType; - - if ( !nodeType ) { - - // If no nodeType, this is expected to be an array - while ( ( node = elem[ i++ ] ) ) { - - // Do not traverse comment nodes - ret += getText( node ); - } - } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { - - // Use textContent for elements - // innerText usage removed for consistency of new lines (jQuery #11153) - if ( typeof elem.textContent === "string" ) { - return elem.textContent; - } else { - - // Traverse its children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - ret += getText( elem ); - } - } - } else if ( nodeType === 3 || nodeType === 4 ) { - return elem.nodeValue; - } - - // Do not include comment or processing instruction nodes - - return ret; -}; - -Expr = Sizzle.selectors = { - - // Can be adjusted by the user - cacheLength: 50, - - createPseudo: markFunction, - - match: matchExpr, - - attrHandle: {}, - - find: {}, - - relative: { - ">": { dir: "parentNode", first: true }, - " ": { dir: "parentNode" }, - "+": { dir: "previousSibling", first: true }, - "~": { dir: "previousSibling" } - }, - - preFilter: { - "ATTR": function( match ) { - match[ 1 ] = match[ 1 ].replace( runescape, funescape ); - - // Move the given value to match[3] whether quoted or unquoted - match[ 3 ] = ( match[ 3 ] || match[ 4 ] || - match[ 5 ] || "" ).replace( runescape, funescape ); - - if ( match[ 2 ] === "~=" ) { - match[ 3 ] = " " + match[ 3 ] + " "; - } - - return match.slice( 0, 4 ); - }, - - "CHILD": function( match ) { - - /* matches from matchExpr["CHILD"] - 1 type (only|nth|...) - 2 what (child|of-type) - 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) - 4 xn-component of xn+y argument ([+-]?\d*n|) - 5 sign of xn-component - 6 x of xn-component - 7 sign of y-component - 8 y of y-component - */ - match[ 1 ] = match[ 1 ].toLowerCase(); - - if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { - - // nth-* requires argument - if ( !match[ 3 ] ) { - Sizzle.error( match[ 0 ] ); - } - - // numeric x and y parameters for Expr.filter.CHILD - // remember that false/true cast respectively to 0/1 - match[ 4 ] = +( match[ 4 ] ? - match[ 5 ] + ( match[ 6 ] || 1 ) : - 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); - match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); - - // other types prohibit arguments - } else if ( match[ 3 ] ) { - Sizzle.error( match[ 0 ] ); - } - - return match; - }, - - "PSEUDO": function( match ) { - var excess, - unquoted = !match[ 6 ] && match[ 2 ]; - - if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { - return null; - } - - // Accept quoted arguments as-is - if ( match[ 3 ] ) { - match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; - - // Strip excess characters from unquoted arguments - } else if ( unquoted && rpseudo.test( unquoted ) && - - // Get excess from tokenize (recursively) - ( excess = tokenize( unquoted, true ) ) && - - // advance to the next closing parenthesis - ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { - - // excess is a negative index - match[ 0 ] = match[ 0 ].slice( 0, excess ); - match[ 2 ] = unquoted.slice( 0, excess ); - } - - // Return only captures needed by the pseudo filter method (type and argument) - return match.slice( 0, 3 ); - } - }, - - filter: { - - "TAG": function( nodeNameSelector ) { - var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); - return nodeNameSelector === "*" ? - function() { - return true; - } : - function( elem ) { - return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; - }; - }, - - "CLASS": function( className ) { - var pattern = classCache[ className + " " ]; - - return pattern || - ( pattern = new RegExp( "(^|" + whitespace + - ")" + className + "(" + whitespace + "|$)" ) ) && classCache( - className, function( elem ) { - return pattern.test( - typeof elem.className === "string" && elem.className || - typeof elem.getAttribute !== "undefined" && - elem.getAttribute( "class" ) || - "" - ); - } ); - }, - - "ATTR": function( name, operator, check ) { - return function( elem ) { - var result = Sizzle.attr( elem, name ); - - if ( result == null ) { - return operator === "!="; - } - if ( !operator ) { - return true; - } - - result += ""; - - /* eslint-disable max-len */ - - return operator === "=" ? result === check : - operator === "!=" ? result !== check : - operator === "^=" ? check && result.indexOf( check ) === 0 : - operator === "*=" ? check && result.indexOf( check ) > -1 : - operator === "$=" ? check && result.slice( -check.length ) === check : - operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : - operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : - false; - /* eslint-enable max-len */ - - }; - }, - - "CHILD": function( type, what, _argument, first, last ) { - var simple = type.slice( 0, 3 ) !== "nth", - forward = type.slice( -4 ) !== "last", - ofType = what === "of-type"; - - return first === 1 && last === 0 ? - - // Shortcut for :nth-*(n) - function( elem ) { - return !!elem.parentNode; - } : - - function( elem, _context, xml ) { - var cache, uniqueCache, outerCache, node, nodeIndex, start, - dir = simple !== forward ? "nextSibling" : "previousSibling", - parent = elem.parentNode, - name = ofType && elem.nodeName.toLowerCase(), - useCache = !xml && !ofType, - diff = false; - - if ( parent ) { - - // :(first|last|only)-(child|of-type) - if ( simple ) { - while ( dir ) { - node = elem; - while ( ( node = node[ dir ] ) ) { - if ( ofType ? - node.nodeName.toLowerCase() === name : - node.nodeType === 1 ) { - - return false; - } - } - - // Reverse direction for :only-* (if we haven't yet done so) - start = dir = type === "only" && !start && "nextSibling"; - } - return true; - } - - start = [ forward ? parent.firstChild : parent.lastChild ]; - - // non-xml :nth-child(...) stores cache data on `parent` - if ( forward && useCache ) { - - // Seek `elem` from a previously-cached index - - // ...in a gzip-friendly way - node = parent; - outerCache = node[ expando ] || ( node[ expando ] = {} ); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ node.uniqueID ] || - ( outerCache[ node.uniqueID ] = {} ); - - cache = uniqueCache[ type ] || []; - nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; - diff = nodeIndex && cache[ 2 ]; - node = nodeIndex && parent.childNodes[ nodeIndex ]; - - while ( ( node = ++nodeIndex && node && node[ dir ] || - - // Fallback to seeking `elem` from the start - ( diff = nodeIndex = 0 ) || start.pop() ) ) { - - // When found, cache indexes on `parent` and break - if ( node.nodeType === 1 && ++diff && node === elem ) { - uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; - break; - } - } - - } else { - - // Use previously-cached element index if available - if ( useCache ) { - - // ...in a gzip-friendly way - node = elem; - outerCache = node[ expando ] || ( node[ expando ] = {} ); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ node.uniqueID ] || - ( outerCache[ node.uniqueID ] = {} ); - - cache = uniqueCache[ type ] || []; - nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; - diff = nodeIndex; - } - - // xml :nth-child(...) - // or :nth-last-child(...) or :nth(-last)?-of-type(...) - if ( diff === false ) { - - // Use the same loop as above to seek `elem` from the start - while ( ( node = ++nodeIndex && node && node[ dir ] || - ( diff = nodeIndex = 0 ) || start.pop() ) ) { - - if ( ( ofType ? - node.nodeName.toLowerCase() === name : - node.nodeType === 1 ) && - ++diff ) { - - // Cache the index of each encountered element - if ( useCache ) { - outerCache = node[ expando ] || - ( node[ expando ] = {} ); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ node.uniqueID ] || - ( outerCache[ node.uniqueID ] = {} ); - - uniqueCache[ type ] = [ dirruns, diff ]; - } - - if ( node === elem ) { - break; - } - } - } - } - } - - // Incorporate the offset, then check against cycle size - diff -= last; - return diff === first || ( diff % first === 0 && diff / first >= 0 ); - } - }; - }, - - "PSEUDO": function( pseudo, argument ) { - - // pseudo-class names are case-insensitive - // http://www.w3.org/TR/selectors/#pseudo-classes - // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters - // Remember that setFilters inherits from pseudos - var args, - fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || - Sizzle.error( "unsupported pseudo: " + pseudo ); - - // The user may use createPseudo to indicate that - // arguments are needed to create the filter function - // just as Sizzle does - if ( fn[ expando ] ) { - return fn( argument ); - } - - // But maintain support for old signatures - if ( fn.length > 1 ) { - args = [ pseudo, pseudo, "", argument ]; - return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? - markFunction( function( seed, matches ) { - var idx, - matched = fn( seed, argument ), - i = matched.length; - while ( i-- ) { - idx = indexOf( seed, matched[ i ] ); - seed[ idx ] = !( matches[ idx ] = matched[ i ] ); - } - } ) : - function( elem ) { - return fn( elem, 0, args ); - }; - } - - return fn; - } - }, - - pseudos: { - - // Potentially complex pseudos - "not": markFunction( function( selector ) { - - // Trim the selector passed to compile - // to avoid treating leading and trailing - // spaces as combinators - var input = [], - results = [], - matcher = compile( selector.replace( rtrim, "$1" ) ); - - return matcher[ expando ] ? - markFunction( function( seed, matches, _context, xml ) { - var elem, - unmatched = matcher( seed, null, xml, [] ), - i = seed.length; - - // Match elements unmatched by `matcher` - while ( i-- ) { - if ( ( elem = unmatched[ i ] ) ) { - seed[ i ] = !( matches[ i ] = elem ); - } - } - } ) : - function( elem, _context, xml ) { - input[ 0 ] = elem; - matcher( input, null, xml, results ); - - // Don't keep the element (issue #299) - input[ 0 ] = null; - return !results.pop(); - }; - } ), - - "has": markFunction( function( selector ) { - return function( elem ) { - return Sizzle( selector, elem ).length > 0; - }; - } ), - - "contains": markFunction( function( text ) { - text = text.replace( runescape, funescape ); - return function( elem ) { - return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; - }; - } ), - - // "Whether an element is represented by a :lang() selector - // is based solely on the element's language value - // being equal to the identifier C, - // or beginning with the identifier C immediately followed by "-". - // The matching of C against the element's language value is performed case-insensitively. - // The identifier C does not have to be a valid language name." - // http://www.w3.org/TR/selectors/#lang-pseudo - "lang": markFunction( function( lang ) { - - // lang value must be a valid identifier - if ( !ridentifier.test( lang || "" ) ) { - Sizzle.error( "unsupported lang: " + lang ); - } - lang = lang.replace( runescape, funescape ).toLowerCase(); - return function( elem ) { - var elemLang; - do { - if ( ( elemLang = documentIsHTML ? - elem.lang : - elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { - - elemLang = elemLang.toLowerCase(); - return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; - } - } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); - return false; - }; - } ), - - // Miscellaneous - "target": function( elem ) { - var hash = window.location && window.location.hash; - return hash && hash.slice( 1 ) === elem.id; - }, - - "root": function( elem ) { - return elem === docElem; - }, - - "focus": function( elem ) { - return elem === document.activeElement && - ( !document.hasFocus || document.hasFocus() ) && - !!( elem.type || elem.href || ~elem.tabIndex ); - }, - - // Boolean properties - "enabled": createDisabledPseudo( false ), - "disabled": createDisabledPseudo( true ), - - "checked": function( elem ) { - - // In CSS3, :checked should return both checked and selected elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - var nodeName = elem.nodeName.toLowerCase(); - return ( nodeName === "input" && !!elem.checked ) || - ( nodeName === "option" && !!elem.selected ); - }, - - "selected": function( elem ) { - - // Accessing this property makes selected-by-default - // options in Safari work properly - if ( elem.parentNode ) { - // eslint-disable-next-line no-unused-expressions - elem.parentNode.selectedIndex; - } - - return elem.selected === true; - }, - - // Contents - "empty": function( elem ) { - - // http://www.w3.org/TR/selectors/#empty-pseudo - // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), - // but not by others (comment: 8; processing instruction: 7; etc.) - // nodeType < 6 works because attributes (2) do not appear as children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - if ( elem.nodeType < 6 ) { - return false; - } - } - return true; - }, - - "parent": function( elem ) { - return !Expr.pseudos[ "empty" ]( elem ); - }, - - // Element/input types - "header": function( elem ) { - return rheader.test( elem.nodeName ); - }, - - "input": function( elem ) { - return rinputs.test( elem.nodeName ); - }, - - "button": function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === "button" || name === "button"; - }, - - "text": function( elem ) { - var attr; - return elem.nodeName.toLowerCase() === "input" && - elem.type === "text" && - - // Support: IE<8 - // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" - ( ( attr = elem.getAttribute( "type" ) ) == null || - attr.toLowerCase() === "text" ); - }, - - // Position-in-collection - "first": createPositionalPseudo( function() { - return [ 0 ]; - } ), - - "last": createPositionalPseudo( function( _matchIndexes, length ) { - return [ length - 1 ]; - } ), - - "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { - return [ argument < 0 ? argument + length : argument ]; - } ), - - "even": createPositionalPseudo( function( matchIndexes, length ) { - var i = 0; - for ( ; i < length; i += 2 ) { - matchIndexes.push( i ); - } - return matchIndexes; - } ), - - "odd": createPositionalPseudo( function( matchIndexes, length ) { - var i = 1; - for ( ; i < length; i += 2 ) { - matchIndexes.push( i ); - } - return matchIndexes; - } ), - - "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { - var i = argument < 0 ? - argument + length : - argument > length ? - length : - argument; - for ( ; --i >= 0; ) { - matchIndexes.push( i ); - } - return matchIndexes; - } ), - - "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { - var i = argument < 0 ? argument + length : argument; - for ( ; ++i < length; ) { - matchIndexes.push( i ); - } - return matchIndexes; - } ) - } -}; - -Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; - -// Add button/input type pseudos -for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { - Expr.pseudos[ i ] = createInputPseudo( i ); -} -for ( i in { submit: true, reset: true } ) { - Expr.pseudos[ i ] = createButtonPseudo( i ); -} - -// Easy API for creating new setFilters -function setFilters() {} -setFilters.prototype = Expr.filters = Expr.pseudos; -Expr.setFilters = new setFilters(); - -tokenize = Sizzle.tokenize = function( selector, parseOnly ) { - var matched, match, tokens, type, - soFar, groups, preFilters, - cached = tokenCache[ selector + " " ]; - - if ( cached ) { - return parseOnly ? 0 : cached.slice( 0 ); - } - - soFar = selector; - groups = []; - preFilters = Expr.preFilter; - - while ( soFar ) { - - // Comma and first run - if ( !matched || ( match = rcomma.exec( soFar ) ) ) { - if ( match ) { - - // Don't consume trailing commas as valid - soFar = soFar.slice( match[ 0 ].length ) || soFar; - } - groups.push( ( tokens = [] ) ); - } - - matched = false; - - // Combinators - if ( ( match = rcombinators.exec( soFar ) ) ) { - matched = match.shift(); - tokens.push( { - value: matched, - - // Cast descendant combinators to space - type: match[ 0 ].replace( rtrim, " " ) - } ); - soFar = soFar.slice( matched.length ); - } - - // Filters - for ( type in Expr.filter ) { - if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || - ( match = preFilters[ type ]( match ) ) ) ) { - matched = match.shift(); - tokens.push( { - value: matched, - type: type, - matches: match - } ); - soFar = soFar.slice( matched.length ); - } - } - - if ( !matched ) { - break; - } - } - - // Return the length of the invalid excess - // if we're just parsing - // Otherwise, throw an error or return tokens - return parseOnly ? - soFar.length : - soFar ? - Sizzle.error( selector ) : - - // Cache the tokens - tokenCache( selector, groups ).slice( 0 ); -}; - -function toSelector( tokens ) { - var i = 0, - len = tokens.length, - selector = ""; - for ( ; i < len; i++ ) { - selector += tokens[ i ].value; - } - return selector; -} - -function addCombinator( matcher, combinator, base ) { - var dir = combinator.dir, - skip = combinator.next, - key = skip || dir, - checkNonElements = base && key === "parentNode", - doneName = done++; - - return combinator.first ? - - // Check against closest ancestor/preceding element - function( elem, context, xml ) { - while ( ( elem = elem[ dir ] ) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - return matcher( elem, context, xml ); - } - } - return false; - } : - - // Check against all ancestor/preceding elements - function( elem, context, xml ) { - var oldCache, uniqueCache, outerCache, - newCache = [ dirruns, doneName ]; - - // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching - if ( xml ) { - while ( ( elem = elem[ dir ] ) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - if ( matcher( elem, context, xml ) ) { - return true; - } - } - } - } else { - while ( ( elem = elem[ dir ] ) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - outerCache = elem[ expando ] || ( elem[ expando ] = {} ); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ elem.uniqueID ] || - ( outerCache[ elem.uniqueID ] = {} ); - - if ( skip && skip === elem.nodeName.toLowerCase() ) { - elem = elem[ dir ] || elem; - } else if ( ( oldCache = uniqueCache[ key ] ) && - oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { - - // Assign to newCache so results back-propagate to previous elements - return ( newCache[ 2 ] = oldCache[ 2 ] ); - } else { - - // Reuse newcache so results back-propagate to previous elements - uniqueCache[ key ] = newCache; - - // A match means we're done; a fail means we have to keep checking - if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { - return true; - } - } - } - } - } - return false; - }; -} - -function elementMatcher( matchers ) { - return matchers.length > 1 ? - function( elem, context, xml ) { - var i = matchers.length; - while ( i-- ) { - if ( !matchers[ i ]( elem, context, xml ) ) { - return false; - } - } - return true; - } : - matchers[ 0 ]; -} - -function multipleContexts( selector, contexts, results ) { - var i = 0, - len = contexts.length; - for ( ; i < len; i++ ) { - Sizzle( selector, contexts[ i ], results ); - } - return results; -} - -function condense( unmatched, map, filter, context, xml ) { - var elem, - newUnmatched = [], - i = 0, - len = unmatched.length, - mapped = map != null; - - for ( ; i < len; i++ ) { - if ( ( elem = unmatched[ i ] ) ) { - if ( !filter || filter( elem, context, xml ) ) { - newUnmatched.push( elem ); - if ( mapped ) { - map.push( i ); - } - } - } - } - - return newUnmatched; -} - -function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { - if ( postFilter && !postFilter[ expando ] ) { - postFilter = setMatcher( postFilter ); - } - if ( postFinder && !postFinder[ expando ] ) { - postFinder = setMatcher( postFinder, postSelector ); - } - return markFunction( function( seed, results, context, xml ) { - var temp, i, elem, - preMap = [], - postMap = [], - preexisting = results.length, - - // Get initial elements from seed or context - elems = seed || multipleContexts( - selector || "*", - context.nodeType ? [ context ] : context, - [] - ), - - // Prefilter to get matcher input, preserving a map for seed-results synchronization - matcherIn = preFilter && ( seed || !selector ) ? - condense( elems, preMap, preFilter, context, xml ) : - elems, - - matcherOut = matcher ? - - // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, - postFinder || ( seed ? preFilter : preexisting || postFilter ) ? - - // ...intermediate processing is necessary - [] : - - // ...otherwise use results directly - results : - matcherIn; - - // Find primary matches - if ( matcher ) { - matcher( matcherIn, matcherOut, context, xml ); - } - - // Apply postFilter - if ( postFilter ) { - temp = condense( matcherOut, postMap ); - postFilter( temp, [], context, xml ); - - // Un-match failing elements by moving them back to matcherIn - i = temp.length; - while ( i-- ) { - if ( ( elem = temp[ i ] ) ) { - matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); - } - } - } - - if ( seed ) { - if ( postFinder || preFilter ) { - if ( postFinder ) { - - // Get the final matcherOut by condensing this intermediate into postFinder contexts - temp = []; - i = matcherOut.length; - while ( i-- ) { - if ( ( elem = matcherOut[ i ] ) ) { - - // Restore matcherIn since elem is not yet a final match - temp.push( ( matcherIn[ i ] = elem ) ); - } - } - postFinder( null, ( matcherOut = [] ), temp, xml ); - } - - // Move matched elements from seed to results to keep them synchronized - i = matcherOut.length; - while ( i-- ) { - if ( ( elem = matcherOut[ i ] ) && - ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { - - seed[ temp ] = !( results[ temp ] = elem ); - } - } - } - - // Add elements to results, through postFinder if defined - } else { - matcherOut = condense( - matcherOut === results ? - matcherOut.splice( preexisting, matcherOut.length ) : - matcherOut - ); - if ( postFinder ) { - postFinder( null, results, matcherOut, xml ); - } else { - push.apply( results, matcherOut ); - } - } - } ); -} - -function matcherFromTokens( tokens ) { - var checkContext, matcher, j, - len = tokens.length, - leadingRelative = Expr.relative[ tokens[ 0 ].type ], - implicitRelative = leadingRelative || Expr.relative[ " " ], - i = leadingRelative ? 1 : 0, - - // The foundational matcher ensures that elements are reachable from top-level context(s) - matchContext = addCombinator( function( elem ) { - return elem === checkContext; - }, implicitRelative, true ), - matchAnyContext = addCombinator( function( elem ) { - return indexOf( checkContext, elem ) > -1; - }, implicitRelative, true ), - matchers = [ function( elem, context, xml ) { - var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( - ( checkContext = context ).nodeType ? - matchContext( elem, context, xml ) : - matchAnyContext( elem, context, xml ) ); - - // Avoid hanging onto element (issue #299) - checkContext = null; - return ret; - } ]; - - for ( ; i < len; i++ ) { - if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { - matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; - } else { - matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); - - // Return special upon seeing a positional matcher - if ( matcher[ expando ] ) { - - // Find the next relative operator (if any) for proper handling - j = ++i; - for ( ; j < len; j++ ) { - if ( Expr.relative[ tokens[ j ].type ] ) { - break; - } - } - return setMatcher( - i > 1 && elementMatcher( matchers ), - i > 1 && toSelector( - - // If the preceding token was a descendant combinator, insert an implicit any-element `*` - tokens - .slice( 0, i - 1 ) - .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) - ).replace( rtrim, "$1" ), - matcher, - i < j && matcherFromTokens( tokens.slice( i, j ) ), - j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), - j < len && toSelector( tokens ) - ); - } - matchers.push( matcher ); - } - } - - return elementMatcher( matchers ); -} - -function matcherFromGroupMatchers( elementMatchers, setMatchers ) { - var bySet = setMatchers.length > 0, - byElement = elementMatchers.length > 0, - superMatcher = function( seed, context, xml, results, outermost ) { - var elem, j, matcher, - matchedCount = 0, - i = "0", - unmatched = seed && [], - setMatched = [], - contextBackup = outermostContext, - - // We must always have either seed elements or outermost context - elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), - - // Use integer dirruns iff this is the outermost matcher - dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), - len = elems.length; - - if ( outermost ) { - - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - outermostContext = context == document || context || outermost; - } - - // Add elements passing elementMatchers directly to results - // Support: IE<9, Safari - // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id - for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { - if ( byElement && elem ) { - j = 0; - - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( !context && elem.ownerDocument != document ) { - setDocument( elem ); - xml = !documentIsHTML; - } - while ( ( matcher = elementMatchers[ j++ ] ) ) { - if ( matcher( elem, context || document, xml ) ) { - results.push( elem ); - break; - } - } - if ( outermost ) { - dirruns = dirrunsUnique; - } - } - - // Track unmatched elements for set filters - if ( bySet ) { - - // They will have gone through all possible matchers - if ( ( elem = !matcher && elem ) ) { - matchedCount--; - } - - // Lengthen the array for every element, matched or not - if ( seed ) { - unmatched.push( elem ); - } - } - } - - // `i` is now the count of elements visited above, and adding it to `matchedCount` - // makes the latter nonnegative. - matchedCount += i; - - // Apply set filters to unmatched elements - // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` - // equals `i`), unless we didn't visit _any_ elements in the above loop because we have - // no element matchers and no seed. - // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that - // case, which will result in a "00" `matchedCount` that differs from `i` but is also - // numerically zero. - if ( bySet && i !== matchedCount ) { - j = 0; - while ( ( matcher = setMatchers[ j++ ] ) ) { - matcher( unmatched, setMatched, context, xml ); - } - - if ( seed ) { - - // Reintegrate element matches to eliminate the need for sorting - if ( matchedCount > 0 ) { - while ( i-- ) { - if ( !( unmatched[ i ] || setMatched[ i ] ) ) { - setMatched[ i ] = pop.call( results ); - } - } - } - - // Discard index placeholder values to get only actual matches - setMatched = condense( setMatched ); - } - - // Add matches to results - push.apply( results, setMatched ); - - // Seedless set matches succeeding multiple successful matchers stipulate sorting - if ( outermost && !seed && setMatched.length > 0 && - ( matchedCount + setMatchers.length ) > 1 ) { - - Sizzle.uniqueSort( results ); - } - } - - // Override manipulation of globals by nested matchers - if ( outermost ) { - dirruns = dirrunsUnique; - outermostContext = contextBackup; - } - - return unmatched; - }; - - return bySet ? - markFunction( superMatcher ) : - superMatcher; -} - -compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { - var i, - setMatchers = [], - elementMatchers = [], - cached = compilerCache[ selector + " " ]; - - if ( !cached ) { - - // Generate a function of recursive functions that can be used to check each element - if ( !match ) { - match = tokenize( selector ); - } - i = match.length; - while ( i-- ) { - cached = matcherFromTokens( match[ i ] ); - if ( cached[ expando ] ) { - setMatchers.push( cached ); - } else { - elementMatchers.push( cached ); - } - } - - // Cache the compiled function - cached = compilerCache( - selector, - matcherFromGroupMatchers( elementMatchers, setMatchers ) - ); - - // Save selector and tokenization - cached.selector = selector; - } - return cached; -}; - -/** - * A low-level selection function that works with Sizzle's compiled - * selector functions - * @param {String|Function} selector A selector or a pre-compiled - * selector function built with Sizzle.compile - * @param {Element} context - * @param {Array} [results] - * @param {Array} [seed] A set of elements to match against - */ -select = Sizzle.select = function( selector, context, results, seed ) { - var i, tokens, token, type, find, - compiled = typeof selector === "function" && selector, - match = !seed && tokenize( ( selector = compiled.selector || selector ) ); - - results = results || []; - - // Try to minimize operations if there is only one selector in the list and no seed - // (the latter of which guarantees us context) - if ( match.length === 1 ) { - - // Reduce context if the leading compound selector is an ID - tokens = match[ 0 ] = match[ 0 ].slice( 0 ); - if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && - context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { - - context = ( Expr.find[ "ID" ]( token.matches[ 0 ] - .replace( runescape, funescape ), context ) || [] )[ 0 ]; - if ( !context ) { - return results; - - // Precompiled matchers will still verify ancestry, so step up a level - } else if ( compiled ) { - context = context.parentNode; - } - - selector = selector.slice( tokens.shift().value.length ); - } - - // Fetch a seed set for right-to-left matching - i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; - while ( i-- ) { - token = tokens[ i ]; - - // Abort if we hit a combinator - if ( Expr.relative[ ( type = token.type ) ] ) { - break; - } - if ( ( find = Expr.find[ type ] ) ) { - - // Search, expanding context for leading sibling combinators - if ( ( seed = find( - token.matches[ 0 ].replace( runescape, funescape ), - rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || - context - ) ) ) { - - // If seed is empty or no tokens remain, we can return early - tokens.splice( i, 1 ); - selector = seed.length && toSelector( tokens ); - if ( !selector ) { - push.apply( results, seed ); - return results; - } - - break; - } - } - } - } - - // Compile and execute a filtering function if one is not provided - // Provide `match` to avoid retokenization if we modified the selector above - ( compiled || compile( selector, match ) )( - seed, - context, - !documentIsHTML, - results, - !context || rsibling.test( selector ) && testContext( context.parentNode ) || context - ); - return results; -}; - -// One-time assignments - -// Sort stability -support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; - -// Support: Chrome 14-35+ -// Always assume duplicates if they aren't passed to the comparison function -support.detectDuplicates = !!hasDuplicate; - -// Initialize against the default document -setDocument(); - -// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) -// Detached nodes confoundingly follow *each other* -support.sortDetached = assert( function( el ) { - - // Should return 1, but returns 4 (following) - return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; -} ); - -// Support: IE<8 -// Prevent attribute/property "interpolation" -// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx -if ( !assert( function( el ) { - el.innerHTML = ""; - return el.firstChild.getAttribute( "href" ) === "#"; -} ) ) { - addHandle( "type|href|height|width", function( elem, name, isXML ) { - if ( !isXML ) { - return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); - } - } ); -} - -// Support: IE<9 -// Use defaultValue in place of getAttribute("value") -if ( !support.attributes || !assert( function( el ) { - el.innerHTML = ""; - el.firstChild.setAttribute( "value", "" ); - return el.firstChild.getAttribute( "value" ) === ""; -} ) ) { - addHandle( "value", function( elem, _name, isXML ) { - if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { - return elem.defaultValue; - } - } ); -} - -// Support: IE<9 -// Use getAttributeNode to fetch booleans when getAttribute lies -if ( !assert( function( el ) { - return el.getAttribute( "disabled" ) == null; -} ) ) { - addHandle( booleans, function( elem, name, isXML ) { - var val; - if ( !isXML ) { - return elem[ name ] === true ? name.toLowerCase() : - ( val = elem.getAttributeNode( name ) ) && val.specified ? - val.value : - null; - } - } ); -} - -return Sizzle; - -} )( window ); - - - -jQuery.find = Sizzle; -jQuery.expr = Sizzle.selectors; - -// Deprecated -jQuery.expr[ ":" ] = jQuery.expr.pseudos; -jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; -jQuery.text = Sizzle.getText; -jQuery.isXMLDoc = Sizzle.isXML; -jQuery.contains = Sizzle.contains; -jQuery.escapeSelector = Sizzle.escape; - - - - -var dir = function( elem, dir, until ) { - var matched = [], - truncate = until !== undefined; - - while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { - if ( elem.nodeType === 1 ) { - if ( truncate && jQuery( elem ).is( until ) ) { - break; - } - matched.push( elem ); - } - } - return matched; -}; - - -var siblings = function( n, elem ) { - var matched = []; - - for ( ; n; n = n.nextSibling ) { - if ( n.nodeType === 1 && n !== elem ) { - matched.push( n ); - } - } - - return matched; -}; - - -var rneedsContext = jQuery.expr.match.needsContext; - - - -function nodeName( elem, name ) { - - return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); - -} -var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); - - - -// Implement the identical functionality for filter and not -function winnow( elements, qualifier, not ) { - if ( isFunction( qualifier ) ) { - return jQuery.grep( elements, function( elem, i ) { - return !!qualifier.call( elem, i, elem ) !== not; - } ); - } - - // Single element - if ( qualifier.nodeType ) { - return jQuery.grep( elements, function( elem ) { - return ( elem === qualifier ) !== not; - } ); - } - - // Arraylike of elements (jQuery, arguments, Array) - if ( typeof qualifier !== "string" ) { - return jQuery.grep( elements, function( elem ) { - return ( indexOf.call( qualifier, elem ) > -1 ) !== not; - } ); - } - - // Filtered directly for both simple and complex selectors - return jQuery.filter( qualifier, elements, not ); -} - -jQuery.filter = function( expr, elems, not ) { - var elem = elems[ 0 ]; - - if ( not ) { - expr = ":not(" + expr + ")"; - } - - if ( elems.length === 1 && elem.nodeType === 1 ) { - return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; - } - - return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { - return elem.nodeType === 1; - } ) ); -}; - -jQuery.fn.extend( { - find: function( selector ) { - var i, ret, - len = this.length, - self = this; - - if ( typeof selector !== "string" ) { - return this.pushStack( jQuery( selector ).filter( function() { - for ( i = 0; i < len; i++ ) { - if ( jQuery.contains( self[ i ], this ) ) { - return true; - } - } - } ) ); - } - - ret = this.pushStack( [] ); - - for ( i = 0; i < len; i++ ) { - jQuery.find( selector, self[ i ], ret ); - } - - return len > 1 ? jQuery.uniqueSort( ret ) : ret; - }, - filter: function( selector ) { - return this.pushStack( winnow( this, selector || [], false ) ); - }, - not: function( selector ) { - return this.pushStack( winnow( this, selector || [], true ) ); - }, - is: function( selector ) { - return !!winnow( - this, - - // If this is a positional/relative selector, check membership in the returned set - // so $("p:first").is("p:last") won't return true for a doc with two "p". - typeof selector === "string" && rneedsContext.test( selector ) ? - jQuery( selector ) : - selector || [], - false - ).length; - } -} ); - - -// Initialize a jQuery object - - -// A central reference to the root jQuery(document) -var rootjQuery, - - // A simple way to check for HTML strings - // Prioritize #id over to avoid XSS via location.hash (#9521) - // Strict HTML recognition (#11290: must start with <) - // Shortcut simple #id case for speed - rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, - - init = jQuery.fn.init = function( selector, context, root ) { - var match, elem; - - // HANDLE: $(""), $(null), $(undefined), $(false) - if ( !selector ) { - return this; - } - - // Method init() accepts an alternate rootjQuery - // so migrate can support jQuery.sub (gh-2101) - root = root || rootjQuery; - - // Handle HTML strings - if ( typeof selector === "string" ) { - if ( selector[ 0 ] === "<" && - selector[ selector.length - 1 ] === ">" && - selector.length >= 3 ) { - - // Assume that strings that start and end with <> are HTML and skip the regex check - match = [ null, selector, null ]; - - } else { - match = rquickExpr.exec( selector ); - } - - // Match html or make sure no context is specified for #id - if ( match && ( match[ 1 ] || !context ) ) { - - // HANDLE: $(html) -> $(array) - if ( match[ 1 ] ) { - context = context instanceof jQuery ? context[ 0 ] : context; - - // Option to run scripts is true for back-compat - // Intentionally let the error be thrown if parseHTML is not present - jQuery.merge( this, jQuery.parseHTML( - match[ 1 ], - context && context.nodeType ? context.ownerDocument || context : document, - true - ) ); - - // HANDLE: $(html, props) - if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { - for ( match in context ) { - - // Properties of context are called as methods if possible - if ( isFunction( this[ match ] ) ) { - this[ match ]( context[ match ] ); - - // ...and otherwise set as attributes - } else { - this.attr( match, context[ match ] ); - } - } - } - - return this; - - // HANDLE: $(#id) - } else { - elem = document.getElementById( match[ 2 ] ); - - if ( elem ) { - - // Inject the element directly into the jQuery object - this[ 0 ] = elem; - this.length = 1; - } - return this; - } - - // HANDLE: $(expr, $(...)) - } else if ( !context || context.jquery ) { - return ( context || root ).find( selector ); - - // HANDLE: $(expr, context) - // (which is just equivalent to: $(context).find(expr) - } else { - return this.constructor( context ).find( selector ); - } - - // HANDLE: $(DOMElement) - } else if ( selector.nodeType ) { - this[ 0 ] = selector; - this.length = 1; - return this; - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( isFunction( selector ) ) { - return root.ready !== undefined ? - root.ready( selector ) : - - // Execute immediately if ready is not present - selector( jQuery ); - } - - return jQuery.makeArray( selector, this ); - }; - -// Give the init function the jQuery prototype for later instantiation -init.prototype = jQuery.fn; - -// Initialize central reference -rootjQuery = jQuery( document ); - - -var rparentsprev = /^(?:parents|prev(?:Until|All))/, - - // Methods guaranteed to produce a unique set when starting from a unique set - guaranteedUnique = { - children: true, - contents: true, - next: true, - prev: true - }; - -jQuery.fn.extend( { - has: function( target ) { - var targets = jQuery( target, this ), - l = targets.length; - - return this.filter( function() { - var i = 0; - for ( ; i < l; i++ ) { - if ( jQuery.contains( this, targets[ i ] ) ) { - return true; - } - } - } ); - }, - - closest: function( selectors, context ) { - var cur, - i = 0, - l = this.length, - matched = [], - targets = typeof selectors !== "string" && jQuery( selectors ); - - // Positional selectors never match, since there's no _selection_ context - if ( !rneedsContext.test( selectors ) ) { - for ( ; i < l; i++ ) { - for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { - - // Always skip document fragments - if ( cur.nodeType < 11 && ( targets ? - targets.index( cur ) > -1 : - - // Don't pass non-elements to Sizzle - cur.nodeType === 1 && - jQuery.find.matchesSelector( cur, selectors ) ) ) { - - matched.push( cur ); - break; - } - } - } - } - - return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); - }, - - // Determine the position of an element within the set - index: function( elem ) { - - // No argument, return index in parent - if ( !elem ) { - return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; - } - - // Index in selector - if ( typeof elem === "string" ) { - return indexOf.call( jQuery( elem ), this[ 0 ] ); - } - - // Locate the position of the desired element - return indexOf.call( this, - - // If it receives a jQuery object, the first element is used - elem.jquery ? elem[ 0 ] : elem - ); - }, - - add: function( selector, context ) { - return this.pushStack( - jQuery.uniqueSort( - jQuery.merge( this.get(), jQuery( selector, context ) ) - ) - ); - }, - - addBack: function( selector ) { - return this.add( selector == null ? - this.prevObject : this.prevObject.filter( selector ) - ); - } -} ); - -function sibling( cur, dir ) { - while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} - return cur; -} - -jQuery.each( { - parent: function( elem ) { - var parent = elem.parentNode; - return parent && parent.nodeType !== 11 ? parent : null; - }, - parents: function( elem ) { - return dir( elem, "parentNode" ); - }, - parentsUntil: function( elem, _i, until ) { - return dir( elem, "parentNode", until ); - }, - next: function( elem ) { - return sibling( elem, "nextSibling" ); - }, - prev: function( elem ) { - return sibling( elem, "previousSibling" ); - }, - nextAll: function( elem ) { - return dir( elem, "nextSibling" ); - }, - prevAll: function( elem ) { - return dir( elem, "previousSibling" ); - }, - nextUntil: function( elem, _i, until ) { - return dir( elem, "nextSibling", until ); - }, - prevUntil: function( elem, _i, until ) { - return dir( elem, "previousSibling", until ); - }, - siblings: function( elem ) { - return siblings( ( elem.parentNode || {} ).firstChild, elem ); - }, - children: function( elem ) { - return siblings( elem.firstChild ); - }, - contents: function( elem ) { - if ( elem.contentDocument != null && - - // Support: IE 11+ - // elements with no `data` attribute has an object - // `contentDocument` with a `null` prototype. - getProto( elem.contentDocument ) ) { - - return elem.contentDocument; - } - - // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only - // Treat the template element as a regular one in browsers that - // don't support it. - if ( nodeName( elem, "template" ) ) { - elem = elem.content || elem; - } - - return jQuery.merge( [], elem.childNodes ); - } -}, function( name, fn ) { - jQuery.fn[ name ] = function( until, selector ) { - var matched = jQuery.map( this, fn, until ); - - if ( name.slice( -5 ) !== "Until" ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - matched = jQuery.filter( selector, matched ); - } - - if ( this.length > 1 ) { - - // Remove duplicates - if ( !guaranteedUnique[ name ] ) { - jQuery.uniqueSort( matched ); - } - - // Reverse order for parents* and prev-derivatives - if ( rparentsprev.test( name ) ) { - matched.reverse(); - } - } - - return this.pushStack( matched ); - }; -} ); -var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); - - - -// Convert String-formatted options into Object-formatted ones -function createOptions( options ) { - var object = {}; - jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { - object[ flag ] = true; - } ); - return object; -} - -/* - * Create a callback list using the following parameters: - * - * options: an optional list of space-separated options that will change how - * the callback list behaves or a more traditional option object - * - * By default a callback list will act like an event callback list and can be - * "fired" multiple times. - * - * Possible options: - * - * once: will ensure the callback list can only be fired once (like a Deferred) - * - * memory: will keep track of previous values and will call any callback added - * after the list has been fired right away with the latest "memorized" - * values (like a Deferred) - * - * unique: will ensure a callback can only be added once (no duplicate in the list) - * - * stopOnFalse: interrupt callings when a callback returns false - * - */ -jQuery.Callbacks = function( options ) { - - // Convert options from String-formatted to Object-formatted if needed - // (we check in cache first) - options = typeof options === "string" ? - createOptions( options ) : - jQuery.extend( {}, options ); - - var // Flag to know if list is currently firing - firing, - - // Last fire value for non-forgettable lists - memory, - - // Flag to know if list was already fired - fired, - - // Flag to prevent firing - locked, - - // Actual callback list - list = [], - - // Queue of execution data for repeatable lists - queue = [], - - // Index of currently firing callback (modified by add/remove as needed) - firingIndex = -1, - - // Fire callbacks - fire = function() { - - // Enforce single-firing - locked = locked || options.once; - - // Execute callbacks for all pending executions, - // respecting firingIndex overrides and runtime changes - fired = firing = true; - for ( ; queue.length; firingIndex = -1 ) { - memory = queue.shift(); - while ( ++firingIndex < list.length ) { - - // Run callback and check for early termination - if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && - options.stopOnFalse ) { - - // Jump to end and forget the data so .add doesn't re-fire - firingIndex = list.length; - memory = false; - } - } - } - - // Forget the data if we're done with it - if ( !options.memory ) { - memory = false; - } - - firing = false; - - // Clean up if we're done firing for good - if ( locked ) { - - // Keep an empty list if we have data for future add calls - if ( memory ) { - list = []; - - // Otherwise, this object is spent - } else { - list = ""; - } - } - }, - - // Actual Callbacks object - self = { - - // Add a callback or a collection of callbacks to the list - add: function() { - if ( list ) { - - // If we have memory from a past run, we should fire after adding - if ( memory && !firing ) { - firingIndex = list.length - 1; - queue.push( memory ); - } - - ( function add( args ) { - jQuery.each( args, function( _, arg ) { - if ( isFunction( arg ) ) { - if ( !options.unique || !self.has( arg ) ) { - list.push( arg ); - } - } else if ( arg && arg.length && toType( arg ) !== "string" ) { - - // Inspect recursively - add( arg ); - } - } ); - } )( arguments ); - - if ( memory && !firing ) { - fire(); - } - } - return this; - }, - - // Remove a callback from the list - remove: function() { - jQuery.each( arguments, function( _, arg ) { - var index; - while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { - list.splice( index, 1 ); - - // Handle firing indexes - if ( index <= firingIndex ) { - firingIndex--; - } - } - } ); - return this; - }, - - // Check if a given callback is in the list. - // If no argument is given, return whether or not list has callbacks attached. - has: function( fn ) { - return fn ? - jQuery.inArray( fn, list ) > -1 : - list.length > 0; - }, - - // Remove all callbacks from the list - empty: function() { - if ( list ) { - list = []; - } - return this; - }, - - // Disable .fire and .add - // Abort any current/pending executions - // Clear all callbacks and values - disable: function() { - locked = queue = []; - list = memory = ""; - return this; - }, - disabled: function() { - return !list; - }, - - // Disable .fire - // Also disable .add unless we have memory (since it would have no effect) - // Abort any pending executions - lock: function() { - locked = queue = []; - if ( !memory && !firing ) { - list = memory = ""; - } - return this; - }, - locked: function() { - return !!locked; - }, - - // Call all callbacks with the given context and arguments - fireWith: function( context, args ) { - if ( !locked ) { - args = args || []; - args = [ context, args.slice ? args.slice() : args ]; - queue.push( args ); - if ( !firing ) { - fire(); - } - } - return this; - }, - - // Call all the callbacks with the given arguments - fire: function() { - self.fireWith( this, arguments ); - return this; - }, - - // To know if the callbacks have already been called at least once - fired: function() { - return !!fired; - } - }; - - return self; -}; - - -function Identity( v ) { - return v; -} -function Thrower( ex ) { - throw ex; -} - -function adoptValue( value, resolve, reject, noValue ) { - var method; - - try { - - // Check for promise aspect first to privilege synchronous behavior - if ( value && isFunction( ( method = value.promise ) ) ) { - method.call( value ).done( resolve ).fail( reject ); - - // Other thenables - } else if ( value && isFunction( ( method = value.then ) ) ) { - method.call( value, resolve, reject ); - - // Other non-thenables - } else { - - // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: - // * false: [ value ].slice( 0 ) => resolve( value ) - // * true: [ value ].slice( 1 ) => resolve() - resolve.apply( undefined, [ value ].slice( noValue ) ); - } - - // For Promises/A+, convert exceptions into rejections - // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in - // Deferred#then to conditionally suppress rejection. - } catch ( value ) { - - // Support: Android 4.0 only - // Strict mode functions invoked without .call/.apply get global-object context - reject.apply( undefined, [ value ] ); - } -} - -jQuery.extend( { - - Deferred: function( func ) { - var tuples = [ - - // action, add listener, callbacks, - // ... .then handlers, argument index, [final state] - [ "notify", "progress", jQuery.Callbacks( "memory" ), - jQuery.Callbacks( "memory" ), 2 ], - [ "resolve", "done", jQuery.Callbacks( "once memory" ), - jQuery.Callbacks( "once memory" ), 0, "resolved" ], - [ "reject", "fail", jQuery.Callbacks( "once memory" ), - jQuery.Callbacks( "once memory" ), 1, "rejected" ] - ], - state = "pending", - promise = { - state: function() { - return state; - }, - always: function() { - deferred.done( arguments ).fail( arguments ); - return this; - }, - "catch": function( fn ) { - return promise.then( null, fn ); - }, - - // Keep pipe for back-compat - pipe: function( /* fnDone, fnFail, fnProgress */ ) { - var fns = arguments; - - return jQuery.Deferred( function( newDefer ) { - jQuery.each( tuples, function( _i, tuple ) { - - // Map tuples (progress, done, fail) to arguments (done, fail, progress) - var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; - - // deferred.progress(function() { bind to newDefer or newDefer.notify }) - // deferred.done(function() { bind to newDefer or newDefer.resolve }) - // deferred.fail(function() { bind to newDefer or newDefer.reject }) - deferred[ tuple[ 1 ] ]( function() { - var returned = fn && fn.apply( this, arguments ); - if ( returned && isFunction( returned.promise ) ) { - returned.promise() - .progress( newDefer.notify ) - .done( newDefer.resolve ) - .fail( newDefer.reject ); - } else { - newDefer[ tuple[ 0 ] + "With" ]( - this, - fn ? [ returned ] : arguments - ); - } - } ); - } ); - fns = null; - } ).promise(); - }, - then: function( onFulfilled, onRejected, onProgress ) { - var maxDepth = 0; - function resolve( depth, deferred, handler, special ) { - return function() { - var that = this, - args = arguments, - mightThrow = function() { - var returned, then; - - // Support: Promises/A+ section 2.3.3.3.3 - // https://promisesaplus.com/#point-59 - // Ignore double-resolution attempts - if ( depth < maxDepth ) { - return; - } - - returned = handler.apply( that, args ); - - // Support: Promises/A+ section 2.3.1 - // https://promisesaplus.com/#point-48 - if ( returned === deferred.promise() ) { - throw new TypeError( "Thenable self-resolution" ); - } - - // Support: Promises/A+ sections 2.3.3.1, 3.5 - // https://promisesaplus.com/#point-54 - // https://promisesaplus.com/#point-75 - // Retrieve `then` only once - then = returned && - - // Support: Promises/A+ section 2.3.4 - // https://promisesaplus.com/#point-64 - // Only check objects and functions for thenability - ( typeof returned === "object" || - typeof returned === "function" ) && - returned.then; - - // Handle a returned thenable - if ( isFunction( then ) ) { - - // Special processors (notify) just wait for resolution - if ( special ) { - then.call( - returned, - resolve( maxDepth, deferred, Identity, special ), - resolve( maxDepth, deferred, Thrower, special ) - ); - - // Normal processors (resolve) also hook into progress - } else { - - // ...and disregard older resolution values - maxDepth++; - - then.call( - returned, - resolve( maxDepth, deferred, Identity, special ), - resolve( maxDepth, deferred, Thrower, special ), - resolve( maxDepth, deferred, Identity, - deferred.notifyWith ) - ); - } - - // Handle all other returned values - } else { - - // Only substitute handlers pass on context - // and multiple values (non-spec behavior) - if ( handler !== Identity ) { - that = undefined; - args = [ returned ]; - } - - // Process the value(s) - // Default process is resolve - ( special || deferred.resolveWith )( that, args ); - } - }, - - // Only normal processors (resolve) catch and reject exceptions - process = special ? - mightThrow : - function() { - try { - mightThrow(); - } catch ( e ) { - - if ( jQuery.Deferred.exceptionHook ) { - jQuery.Deferred.exceptionHook( e, - process.stackTrace ); - } - - // Support: Promises/A+ section 2.3.3.3.4.1 - // https://promisesaplus.com/#point-61 - // Ignore post-resolution exceptions - if ( depth + 1 >= maxDepth ) { - - // Only substitute handlers pass on context - // and multiple values (non-spec behavior) - if ( handler !== Thrower ) { - that = undefined; - args = [ e ]; - } - - deferred.rejectWith( that, args ); - } - } - }; - - // Support: Promises/A+ section 2.3.3.3.1 - // https://promisesaplus.com/#point-57 - // Re-resolve promises immediately to dodge false rejection from - // subsequent errors - if ( depth ) { - process(); - } else { - - // Call an optional hook to record the stack, in case of exception - // since it's otherwise lost when execution goes async - if ( jQuery.Deferred.getStackHook ) { - process.stackTrace = jQuery.Deferred.getStackHook(); - } - window.setTimeout( process ); - } - }; - } - - return jQuery.Deferred( function( newDefer ) { - - // progress_handlers.add( ... ) - tuples[ 0 ][ 3 ].add( - resolve( - 0, - newDefer, - isFunction( onProgress ) ? - onProgress : - Identity, - newDefer.notifyWith - ) - ); - - // fulfilled_handlers.add( ... ) - tuples[ 1 ][ 3 ].add( - resolve( - 0, - newDefer, - isFunction( onFulfilled ) ? - onFulfilled : - Identity - ) - ); - - // rejected_handlers.add( ... ) - tuples[ 2 ][ 3 ].add( - resolve( - 0, - newDefer, - isFunction( onRejected ) ? - onRejected : - Thrower - ) - ); - } ).promise(); - }, - - // Get a promise for this deferred - // If obj is provided, the promise aspect is added to the object - promise: function( obj ) { - return obj != null ? jQuery.extend( obj, promise ) : promise; - } - }, - deferred = {}; - - // Add list-specific methods - jQuery.each( tuples, function( i, tuple ) { - var list = tuple[ 2 ], - stateString = tuple[ 5 ]; - - // promise.progress = list.add - // promise.done = list.add - // promise.fail = list.add - promise[ tuple[ 1 ] ] = list.add; - - // Handle state - if ( stateString ) { - list.add( - function() { - - // state = "resolved" (i.e., fulfilled) - // state = "rejected" - state = stateString; - }, - - // rejected_callbacks.disable - // fulfilled_callbacks.disable - tuples[ 3 - i ][ 2 ].disable, - - // rejected_handlers.disable - // fulfilled_handlers.disable - tuples[ 3 - i ][ 3 ].disable, - - // progress_callbacks.lock - tuples[ 0 ][ 2 ].lock, - - // progress_handlers.lock - tuples[ 0 ][ 3 ].lock - ); - } - - // progress_handlers.fire - // fulfilled_handlers.fire - // rejected_handlers.fire - list.add( tuple[ 3 ].fire ); - - // deferred.notify = function() { deferred.notifyWith(...) } - // deferred.resolve = function() { deferred.resolveWith(...) } - // deferred.reject = function() { deferred.rejectWith(...) } - deferred[ tuple[ 0 ] ] = function() { - deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); - return this; - }; - - // deferred.notifyWith = list.fireWith - // deferred.resolveWith = list.fireWith - // deferred.rejectWith = list.fireWith - deferred[ tuple[ 0 ] + "With" ] = list.fireWith; - } ); - - // Make the deferred a promise - promise.promise( deferred ); - - // Call given func if any - if ( func ) { - func.call( deferred, deferred ); - } - - // All done! - return deferred; - }, - - // Deferred helper - when: function( singleValue ) { - var - - // count of uncompleted subordinates - remaining = arguments.length, - - // count of unprocessed arguments - i = remaining, - - // subordinate fulfillment data - resolveContexts = Array( i ), - resolveValues = slice.call( arguments ), - - // the primary Deferred - primary = jQuery.Deferred(), - - // subordinate callback factory - updateFunc = function( i ) { - return function( value ) { - resolveContexts[ i ] = this; - resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; - if ( !( --remaining ) ) { - primary.resolveWith( resolveContexts, resolveValues ); - } - }; - }; - - // Single- and empty arguments are adopted like Promise.resolve - if ( remaining <= 1 ) { - adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject, - !remaining ); - - // Use .then() to unwrap secondary thenables (cf. gh-3000) - if ( primary.state() === "pending" || - isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { - - return primary.then(); - } - } - - // Multiple arguments are aggregated like Promise.all array elements - while ( i-- ) { - adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject ); - } - - return primary.promise(); - } -} ); - - -// These usually indicate a programmer mistake during development, -// warn about them ASAP rather than swallowing them by default. -var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; - -jQuery.Deferred.exceptionHook = function( error, stack ) { - - // Support: IE 8 - 9 only - // Console exists when dev tools are open, which can happen at any time - if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { - window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); - } -}; - - - - -jQuery.readyException = function( error ) { - window.setTimeout( function() { - throw error; - } ); -}; - - - - -// The deferred used on DOM ready -var readyList = jQuery.Deferred(); - -jQuery.fn.ready = function( fn ) { - - readyList - .then( fn ) - - // Wrap jQuery.readyException in a function so that the lookup - // happens at the time of error handling instead of callback - // registration. - .catch( function( error ) { - jQuery.readyException( error ); - } ); - - return this; -}; - -jQuery.extend( { - - // Is the DOM ready to be used? Set to true once it occurs. - isReady: false, - - // A counter to track how many items to wait for before - // the ready event fires. See #6781 - readyWait: 1, - - // Handle when the DOM is ready - ready: function( wait ) { - - // Abort if there are pending holds or we're already ready - if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { - return; - } - - // Remember that the DOM is ready - jQuery.isReady = true; - - // If a normal DOM Ready event fired, decrement, and wait if need be - if ( wait !== true && --jQuery.readyWait > 0 ) { - return; - } - - // If there are functions bound, to execute - readyList.resolveWith( document, [ jQuery ] ); - } -} ); - -jQuery.ready.then = readyList.then; - -// The ready event handler and self cleanup method -function completed() { - document.removeEventListener( "DOMContentLoaded", completed ); - window.removeEventListener( "load", completed ); - jQuery.ready(); -} - -// Catch cases where $(document).ready() is called -// after the browser event has already occurred. -// Support: IE <=9 - 10 only -// Older IE sometimes signals "interactive" too soon -if ( document.readyState === "complete" || - ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { - - // Handle it asynchronously to allow scripts the opportunity to delay ready - window.setTimeout( jQuery.ready ); - -} else { - - // Use the handy event callback - document.addEventListener( "DOMContentLoaded", completed ); - - // A fallback to window.onload, that will always work - window.addEventListener( "load", completed ); -} - - - - -// Multifunctional method to get and set values of a collection -// The value/s can optionally be executed if it's a function -var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { - var i = 0, - len = elems.length, - bulk = key == null; - - // Sets many values - if ( toType( key ) === "object" ) { - chainable = true; - for ( i in key ) { - access( elems, fn, i, key[ i ], true, emptyGet, raw ); - } - - // Sets one value - } else if ( value !== undefined ) { - chainable = true; - - if ( !isFunction( value ) ) { - raw = true; - } - - if ( bulk ) { - - // Bulk operations run against the entire set - if ( raw ) { - fn.call( elems, value ); - fn = null; - - // ...except when executing function values - } else { - bulk = fn; - fn = function( elem, _key, value ) { - return bulk.call( jQuery( elem ), value ); - }; - } - } - - if ( fn ) { - for ( ; i < len; i++ ) { - fn( - elems[ i ], key, raw ? - value : - value.call( elems[ i ], i, fn( elems[ i ], key ) ) - ); - } - } - } - - if ( chainable ) { - return elems; - } - - // Gets - if ( bulk ) { - return fn.call( elems ); - } - - return len ? fn( elems[ 0 ], key ) : emptyGet; -}; - - -// Matches dashed string for camelizing -var rmsPrefix = /^-ms-/, - rdashAlpha = /-([a-z])/g; - -// Used by camelCase as callback to replace() -function fcamelCase( _all, letter ) { - return letter.toUpperCase(); -} - -// Convert dashed to camelCase; used by the css and data modules -// Support: IE <=9 - 11, Edge 12 - 15 -// Microsoft forgot to hump their vendor prefix (#9572) -function camelCase( string ) { - return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); -} -var acceptData = function( owner ) { - - // Accepts only: - // - Node - // - Node.ELEMENT_NODE - // - Node.DOCUMENT_NODE - // - Object - // - Any - return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); -}; - - - - -function Data() { - this.expando = jQuery.expando + Data.uid++; -} - -Data.uid = 1; - -Data.prototype = { - - cache: function( owner ) { - - // Check if the owner object already has a cache - var value = owner[ this.expando ]; - - // If not, create one - if ( !value ) { - value = {}; - - // We can accept data for non-element nodes in modern browsers, - // but we should not, see #8335. - // Always return an empty object. - if ( acceptData( owner ) ) { - - // If it is a node unlikely to be stringify-ed or looped over - // use plain assignment - if ( owner.nodeType ) { - owner[ this.expando ] = value; - - // Otherwise secure it in a non-enumerable property - // configurable must be true to allow the property to be - // deleted when data is removed - } else { - Object.defineProperty( owner, this.expando, { - value: value, - configurable: true - } ); - } - } - } - - return value; - }, - set: function( owner, data, value ) { - var prop, - cache = this.cache( owner ); - - // Handle: [ owner, key, value ] args - // Always use camelCase key (gh-2257) - if ( typeof data === "string" ) { - cache[ camelCase( data ) ] = value; - - // Handle: [ owner, { properties } ] args - } else { - - // Copy the properties one-by-one to the cache object - for ( prop in data ) { - cache[ camelCase( prop ) ] = data[ prop ]; - } - } - return cache; - }, - get: function( owner, key ) { - return key === undefined ? - this.cache( owner ) : - - // Always use camelCase key (gh-2257) - owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; - }, - access: function( owner, key, value ) { - - // In cases where either: - // - // 1. No key was specified - // 2. A string key was specified, but no value provided - // - // Take the "read" path and allow the get method to determine - // which value to return, respectively either: - // - // 1. The entire cache object - // 2. The data stored at the key - // - if ( key === undefined || - ( ( key && typeof key === "string" ) && value === undefined ) ) { - - return this.get( owner, key ); - } - - // When the key is not a string, or both a key and value - // are specified, set or extend (existing objects) with either: - // - // 1. An object of properties - // 2. A key and value - // - this.set( owner, key, value ); - - // Since the "set" path can have two possible entry points - // return the expected data based on which path was taken[*] - return value !== undefined ? value : key; - }, - remove: function( owner, key ) { - var i, - cache = owner[ this.expando ]; - - if ( cache === undefined ) { - return; - } - - if ( key !== undefined ) { - - // Support array or space separated string of keys - if ( Array.isArray( key ) ) { - - // If key is an array of keys... - // We always set camelCase keys, so remove that. - key = key.map( camelCase ); - } else { - key = camelCase( key ); - - // If a key with the spaces exists, use it. - // Otherwise, create an array by matching non-whitespace - key = key in cache ? - [ key ] : - ( key.match( rnothtmlwhite ) || [] ); - } - - i = key.length; - - while ( i-- ) { - delete cache[ key[ i ] ]; - } - } - - // Remove the expando if there's no more data - if ( key === undefined || jQuery.isEmptyObject( cache ) ) { - - // Support: Chrome <=35 - 45 - // Webkit & Blink performance suffers when deleting properties - // from DOM nodes, so set to undefined instead - // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) - if ( owner.nodeType ) { - owner[ this.expando ] = undefined; - } else { - delete owner[ this.expando ]; - } - } - }, - hasData: function( owner ) { - var cache = owner[ this.expando ]; - return cache !== undefined && !jQuery.isEmptyObject( cache ); - } -}; -var dataPriv = new Data(); - -var dataUser = new Data(); - - - -// Implementation Summary -// -// 1. Enforce API surface and semantic compatibility with 1.9.x branch -// 2. Improve the module's maintainability by reducing the storage -// paths to a single mechanism. -// 3. Use the same single mechanism to support "private" and "user" data. -// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) -// 5. Avoid exposing implementation details on user objects (eg. expando properties) -// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 - -var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, - rmultiDash = /[A-Z]/g; - -function getData( data ) { - if ( data === "true" ) { - return true; - } - - if ( data === "false" ) { - return false; - } - - if ( data === "null" ) { - return null; - } - - // Only convert to a number if it doesn't change the string - if ( data === +data + "" ) { - return +data; - } - - if ( rbrace.test( data ) ) { - return JSON.parse( data ); - } - - return data; -} - -function dataAttr( elem, key, data ) { - var name; - - // If nothing was found internally, try to fetch any - // data from the HTML5 data-* attribute - if ( data === undefined && elem.nodeType === 1 ) { - name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); - data = elem.getAttribute( name ); - - if ( typeof data === "string" ) { - try { - data = getData( data ); - } catch ( e ) {} - - // Make sure we set the data so it isn't changed later - dataUser.set( elem, key, data ); - } else { - data = undefined; - } - } - return data; -} - -jQuery.extend( { - hasData: function( elem ) { - return dataUser.hasData( elem ) || dataPriv.hasData( elem ); - }, - - data: function( elem, name, data ) { - return dataUser.access( elem, name, data ); - }, - - removeData: function( elem, name ) { - dataUser.remove( elem, name ); - }, - - // TODO: Now that all calls to _data and _removeData have been replaced - // with direct calls to dataPriv methods, these can be deprecated. - _data: function( elem, name, data ) { - return dataPriv.access( elem, name, data ); - }, - - _removeData: function( elem, name ) { - dataPriv.remove( elem, name ); - } -} ); - -jQuery.fn.extend( { - data: function( key, value ) { - var i, name, data, - elem = this[ 0 ], - attrs = elem && elem.attributes; - - // Gets all values - if ( key === undefined ) { - if ( this.length ) { - data = dataUser.get( elem ); - - if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { - i = attrs.length; - while ( i-- ) { - - // Support: IE 11 only - // The attrs elements can be null (#14894) - if ( attrs[ i ] ) { - name = attrs[ i ].name; - if ( name.indexOf( "data-" ) === 0 ) { - name = camelCase( name.slice( 5 ) ); - dataAttr( elem, name, data[ name ] ); - } - } - } - dataPriv.set( elem, "hasDataAttrs", true ); - } - } - - return data; - } - - // Sets multiple values - if ( typeof key === "object" ) { - return this.each( function() { - dataUser.set( this, key ); - } ); - } - - return access( this, function( value ) { - var data; - - // The calling jQuery object (element matches) is not empty - // (and therefore has an element appears at this[ 0 ]) and the - // `value` parameter was not undefined. An empty jQuery object - // will result in `undefined` for elem = this[ 0 ] which will - // throw an exception if an attempt to read a data cache is made. - if ( elem && value === undefined ) { - - // Attempt to get data from the cache - // The key will always be camelCased in Data - data = dataUser.get( elem, key ); - if ( data !== undefined ) { - return data; - } - - // Attempt to "discover" the data in - // HTML5 custom data-* attrs - data = dataAttr( elem, key ); - if ( data !== undefined ) { - return data; - } - - // We tried really hard, but the data doesn't exist. - return; - } - - // Set the data... - this.each( function() { - - // We always store the camelCased key - dataUser.set( this, key, value ); - } ); - }, null, value, arguments.length > 1, null, true ); - }, - - removeData: function( key ) { - return this.each( function() { - dataUser.remove( this, key ); - } ); - } -} ); - - -jQuery.extend( { - queue: function( elem, type, data ) { - var queue; - - if ( elem ) { - type = ( type || "fx" ) + "queue"; - queue = dataPriv.get( elem, type ); - - // Speed up dequeue by getting out quickly if this is just a lookup - if ( data ) { - if ( !queue || Array.isArray( data ) ) { - queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); - } else { - queue.push( data ); - } - } - return queue || []; - } - }, - - dequeue: function( elem, type ) { - type = type || "fx"; - - var queue = jQuery.queue( elem, type ), - startLength = queue.length, - fn = queue.shift(), - hooks = jQuery._queueHooks( elem, type ), - next = function() { - jQuery.dequeue( elem, type ); - }; - - // If the fx queue is dequeued, always remove the progress sentinel - if ( fn === "inprogress" ) { - fn = queue.shift(); - startLength--; - } - - if ( fn ) { - - // Add a progress sentinel to prevent the fx queue from being - // automatically dequeued - if ( type === "fx" ) { - queue.unshift( "inprogress" ); - } - - // Clear up the last queue stop function - delete hooks.stop; - fn.call( elem, next, hooks ); - } - - if ( !startLength && hooks ) { - hooks.empty.fire(); - } - }, - - // Not public - generate a queueHooks object, or return the current one - _queueHooks: function( elem, type ) { - var key = type + "queueHooks"; - return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { - empty: jQuery.Callbacks( "once memory" ).add( function() { - dataPriv.remove( elem, [ type + "queue", key ] ); - } ) - } ); - } -} ); - -jQuery.fn.extend( { - queue: function( type, data ) { - var setter = 2; - - if ( typeof type !== "string" ) { - data = type; - type = "fx"; - setter--; - } - - if ( arguments.length < setter ) { - return jQuery.queue( this[ 0 ], type ); - } - - return data === undefined ? - this : - this.each( function() { - var queue = jQuery.queue( this, type, data ); - - // Ensure a hooks for this queue - jQuery._queueHooks( this, type ); - - if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { - jQuery.dequeue( this, type ); - } - } ); - }, - dequeue: function( type ) { - return this.each( function() { - jQuery.dequeue( this, type ); - } ); - }, - clearQueue: function( type ) { - return this.queue( type || "fx", [] ); - }, - - // Get a promise resolved when queues of a certain type - // are emptied (fx is the type by default) - promise: function( type, obj ) { - var tmp, - count = 1, - defer = jQuery.Deferred(), - elements = this, - i = this.length, - resolve = function() { - if ( !( --count ) ) { - defer.resolveWith( elements, [ elements ] ); - } - }; - - if ( typeof type !== "string" ) { - obj = type; - type = undefined; - } - type = type || "fx"; - - while ( i-- ) { - tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); - if ( tmp && tmp.empty ) { - count++; - tmp.empty.add( resolve ); - } - } - resolve(); - return defer.promise( obj ); - } -} ); -var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; - -var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); - - -var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; - -var documentElement = document.documentElement; - - - - var isAttached = function( elem ) { - return jQuery.contains( elem.ownerDocument, elem ); - }, - composed = { composed: true }; - - // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only - // Check attachment across shadow DOM boundaries when possible (gh-3504) - // Support: iOS 10.0-10.2 only - // Early iOS 10 versions support `attachShadow` but not `getRootNode`, - // leading to errors. We need to check for `getRootNode`. - if ( documentElement.getRootNode ) { - isAttached = function( elem ) { - return jQuery.contains( elem.ownerDocument, elem ) || - elem.getRootNode( composed ) === elem.ownerDocument; - }; - } -var isHiddenWithinTree = function( elem, el ) { - - // isHiddenWithinTree might be called from jQuery#filter function; - // in that case, element will be second argument - elem = el || elem; - - // Inline style trumps all - return elem.style.display === "none" || - elem.style.display === "" && - - // Otherwise, check computed style - // Support: Firefox <=43 - 45 - // Disconnected elements can have computed display: none, so first confirm that elem is - // in the document. - isAttached( elem ) && - - jQuery.css( elem, "display" ) === "none"; - }; - - - -function adjustCSS( elem, prop, valueParts, tween ) { - var adjusted, scale, - maxIterations = 20, - currentValue = tween ? - function() { - return tween.cur(); - } : - function() { - return jQuery.css( elem, prop, "" ); - }, - initial = currentValue(), - unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), - - // Starting value computation is required for potential unit mismatches - initialInUnit = elem.nodeType && - ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && - rcssNum.exec( jQuery.css( elem, prop ) ); - - if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { - - // Support: Firefox <=54 - // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) - initial = initial / 2; - - // Trust units reported by jQuery.css - unit = unit || initialInUnit[ 3 ]; - - // Iteratively approximate from a nonzero starting point - initialInUnit = +initial || 1; - - while ( maxIterations-- ) { - - // Evaluate and update our best guess (doubling guesses that zero out). - // Finish if the scale equals or crosses 1 (making the old*new product non-positive). - jQuery.style( elem, prop, initialInUnit + unit ); - if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { - maxIterations = 0; - } - initialInUnit = initialInUnit / scale; - - } - - initialInUnit = initialInUnit * 2; - jQuery.style( elem, prop, initialInUnit + unit ); - - // Make sure we update the tween properties later on - valueParts = valueParts || []; - } - - if ( valueParts ) { - initialInUnit = +initialInUnit || +initial || 0; - - // Apply relative offset (+=/-=) if specified - adjusted = valueParts[ 1 ] ? - initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : - +valueParts[ 2 ]; - if ( tween ) { - tween.unit = unit; - tween.start = initialInUnit; - tween.end = adjusted; - } - } - return adjusted; -} - - -var defaultDisplayMap = {}; - -function getDefaultDisplay( elem ) { - var temp, - doc = elem.ownerDocument, - nodeName = elem.nodeName, - display = defaultDisplayMap[ nodeName ]; - - if ( display ) { - return display; - } - - temp = doc.body.appendChild( doc.createElement( nodeName ) ); - display = jQuery.css( temp, "display" ); - - temp.parentNode.removeChild( temp ); - - if ( display === "none" ) { - display = "block"; - } - defaultDisplayMap[ nodeName ] = display; - - return display; -} - -function showHide( elements, show ) { - var display, elem, - values = [], - index = 0, - length = elements.length; - - // Determine new display value for elements that need to change - for ( ; index < length; index++ ) { - elem = elements[ index ]; - if ( !elem.style ) { - continue; - } - - display = elem.style.display; - if ( show ) { - - // Since we force visibility upon cascade-hidden elements, an immediate (and slow) - // check is required in this first loop unless we have a nonempty display value (either - // inline or about-to-be-restored) - if ( display === "none" ) { - values[ index ] = dataPriv.get( elem, "display" ) || null; - if ( !values[ index ] ) { - elem.style.display = ""; - } - } - if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { - values[ index ] = getDefaultDisplay( elem ); - } - } else { - if ( display !== "none" ) { - values[ index ] = "none"; - - // Remember what we're overwriting - dataPriv.set( elem, "display", display ); - } - } - } - - // Set the display of the elements in a second loop to avoid constant reflow - for ( index = 0; index < length; index++ ) { - if ( values[ index ] != null ) { - elements[ index ].style.display = values[ index ]; - } - } - - return elements; -} - -jQuery.fn.extend( { - show: function() { - return showHide( this, true ); - }, - hide: function() { - return showHide( this ); - }, - toggle: function( state ) { - if ( typeof state === "boolean" ) { - return state ? this.show() : this.hide(); - } - - return this.each( function() { - if ( isHiddenWithinTree( this ) ) { - jQuery( this ).show(); - } else { - jQuery( this ).hide(); - } - } ); - } -} ); -var rcheckableType = ( /^(?:checkbox|radio)$/i ); - -var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); - -var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); - - - -( function() { - var fragment = document.createDocumentFragment(), - div = fragment.appendChild( document.createElement( "div" ) ), - input = document.createElement( "input" ); - - // Support: Android 4.0 - 4.3 only - // Check state lost if the name is set (#11217) - // Support: Windows Web Apps (WWA) - // `name` and `type` must use .setAttribute for WWA (#14901) - input.setAttribute( "type", "radio" ); - input.setAttribute( "checked", "checked" ); - input.setAttribute( "name", "t" ); - - div.appendChild( input ); - - // Support: Android <=4.1 only - // Older WebKit doesn't clone checked state correctly in fragments - support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; - - // Support: IE <=11 only - // Make sure textarea (and checkbox) defaultValue is properly cloned - div.innerHTML = ""; - support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; - - // Support: IE <=9 only - // IE <=9 replaces "; - support.option = !!div.lastChild; -} )(); - - -// We have to close these tags to support XHTML (#13200) -var wrapMap = { - - // XHTML parsers do not magically insert elements in the - // same way that tag soup parsers do. So we cannot shorten - // this by omitting or other required elements. - thead: [ 1, "", "
" ], - col: [ 2, "", "
" ], - tr: [ 2, "", "
" ], - td: [ 3, "", "
" ], - - _default: [ 0, "", "" ] -}; - -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - -// Support: IE <=9 only -if ( !support.option ) { - wrapMap.optgroup = wrapMap.option = [ 1, "" ]; -} - - -function getAll( context, tag ) { - - // Support: IE <=9 - 11 only - // Use typeof to avoid zero-argument method invocation on host objects (#15151) - var ret; - - if ( typeof context.getElementsByTagName !== "undefined" ) { - ret = context.getElementsByTagName( tag || "*" ); - - } else if ( typeof context.querySelectorAll !== "undefined" ) { - ret = context.querySelectorAll( tag || "*" ); - - } else { - ret = []; - } - - if ( tag === undefined || tag && nodeName( context, tag ) ) { - return jQuery.merge( [ context ], ret ); - } - - return ret; -} - - -// Mark scripts as having already been evaluated -function setGlobalEval( elems, refElements ) { - var i = 0, - l = elems.length; - - for ( ; i < l; i++ ) { - dataPriv.set( - elems[ i ], - "globalEval", - !refElements || dataPriv.get( refElements[ i ], "globalEval" ) - ); - } -} - - -var rhtml = /<|&#?\w+;/; - -function buildFragment( elems, context, scripts, selection, ignored ) { - var elem, tmp, tag, wrap, attached, j, - fragment = context.createDocumentFragment(), - nodes = [], - i = 0, - l = elems.length; - - for ( ; i < l; i++ ) { - elem = elems[ i ]; - - if ( elem || elem === 0 ) { - - // Add nodes directly - if ( toType( elem ) === "object" ) { - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); - - // Convert non-html into a text node - } else if ( !rhtml.test( elem ) ) { - nodes.push( context.createTextNode( elem ) ); - - // Convert html into DOM nodes - } else { - tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); - - // Deserialize a standard representation - tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); - wrap = wrapMap[ tag ] || wrapMap._default; - tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; - - // Descend through wrappers to the right content - j = wrap[ 0 ]; - while ( j-- ) { - tmp = tmp.lastChild; - } - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( nodes, tmp.childNodes ); - - // Remember the top-level container - tmp = fragment.firstChild; - - // Ensure the created nodes are orphaned (#12392) - tmp.textContent = ""; - } - } - } - - // Remove wrapper from fragment - fragment.textContent = ""; - - i = 0; - while ( ( elem = nodes[ i++ ] ) ) { - - // Skip elements already in the context collection (trac-4087) - if ( selection && jQuery.inArray( elem, selection ) > -1 ) { - if ( ignored ) { - ignored.push( elem ); - } - continue; - } - - attached = isAttached( elem ); - - // Append to fragment - tmp = getAll( fragment.appendChild( elem ), "script" ); - - // Preserve script evaluation history - if ( attached ) { - setGlobalEval( tmp ); - } - - // Capture executables - if ( scripts ) { - j = 0; - while ( ( elem = tmp[ j++ ] ) ) { - if ( rscriptType.test( elem.type || "" ) ) { - scripts.push( elem ); - } - } - } - } - - return fragment; -} - - -var rtypenamespace = /^([^.]*)(?:\.(.+)|)/; - -function returnTrue() { - return true; -} - -function returnFalse() { - return false; -} - -// Support: IE <=9 - 11+ -// focus() and blur() are asynchronous, except when they are no-op. -// So expect focus to be synchronous when the element is already active, -// and blur to be synchronous when the element is not already active. -// (focus and blur are always synchronous in other supported browsers, -// this just defines when we can count on it). -function expectSync( elem, type ) { - return ( elem === safeActiveElement() ) === ( type === "focus" ); -} - -// Support: IE <=9 only -// Accessing document.activeElement can throw unexpectedly -// https://bugs.jquery.com/ticket/13393 -function safeActiveElement() { - try { - return document.activeElement; - } catch ( err ) { } -} - -function on( elem, types, selector, data, fn, one ) { - var origFn, type; - - // Types can be a map of types/handlers - if ( typeof types === "object" ) { - - // ( types-Object, selector, data ) - if ( typeof selector !== "string" ) { - - // ( types-Object, data ) - data = data || selector; - selector = undefined; - } - for ( type in types ) { - on( elem, type, selector, data, types[ type ], one ); - } - return elem; - } - - if ( data == null && fn == null ) { - - // ( types, fn ) - fn = selector; - data = selector = undefined; - } else if ( fn == null ) { - if ( typeof selector === "string" ) { - - // ( types, selector, fn ) - fn = data; - data = undefined; - } else { - - // ( types, data, fn ) - fn = data; - data = selector; - selector = undefined; - } - } - if ( fn === false ) { - fn = returnFalse; - } else if ( !fn ) { - return elem; - } - - if ( one === 1 ) { - origFn = fn; - fn = function( event ) { - - // Can use an empty set, since event contains the info - jQuery().off( event ); - return origFn.apply( this, arguments ); - }; - - // Use same guid so caller can remove using origFn - fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); - } - return elem.each( function() { - jQuery.event.add( this, types, fn, data, selector ); - } ); -} - -/* - * Helper functions for managing events -- not part of the public interface. - * Props to Dean Edwards' addEvent library for many of the ideas. - */ -jQuery.event = { - - global: {}, - - add: function( elem, types, handler, data, selector ) { - - var handleObjIn, eventHandle, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = dataPriv.get( elem ); - - // Only attach events to objects that accept data - if ( !acceptData( elem ) ) { - return; - } - - // Caller can pass in an object of custom data in lieu of the handler - if ( handler.handler ) { - handleObjIn = handler; - handler = handleObjIn.handler; - selector = handleObjIn.selector; - } - - // Ensure that invalid selectors throw exceptions at attach time - // Evaluate against documentElement in case elem is a non-element node (e.g., document) - if ( selector ) { - jQuery.find.matchesSelector( documentElement, selector ); - } - - // Make sure that the handler has a unique ID, used to find/remove it later - if ( !handler.guid ) { - handler.guid = jQuery.guid++; - } - - // Init the element's event structure and main handler, if this is the first - if ( !( events = elemData.events ) ) { - events = elemData.events = Object.create( null ); - } - if ( !( eventHandle = elemData.handle ) ) { - eventHandle = elemData.handle = function( e ) { - - // Discard the second event of a jQuery.event.trigger() and - // when an event is called after a page has unloaded - return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? - jQuery.event.dispatch.apply( elem, arguments ) : undefined; - }; - } - - // Handle multiple events separated by a space - types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[ t ] ) || []; - type = origType = tmp[ 1 ]; - namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); - - // There *must* be a type, no attaching namespace-only handlers - if ( !type ) { - continue; - } - - // If event changes its type, use the special event handlers for the changed type - special = jQuery.event.special[ type ] || {}; - - // If selector defined, determine special event api type, otherwise given type - type = ( selector ? special.delegateType : special.bindType ) || type; - - // Update special based on newly reset type - special = jQuery.event.special[ type ] || {}; - - // handleObj is passed to all event handlers - handleObj = jQuery.extend( { - type: type, - origType: origType, - data: data, - handler: handler, - guid: handler.guid, - selector: selector, - needsContext: selector && jQuery.expr.match.needsContext.test( selector ), - namespace: namespaces.join( "." ) - }, handleObjIn ); - - // Init the event handler queue if we're the first - if ( !( handlers = events[ type ] ) ) { - handlers = events[ type ] = []; - handlers.delegateCount = 0; - - // Only use addEventListener if the special events handler returns false - if ( !special.setup || - special.setup.call( elem, data, namespaces, eventHandle ) === false ) { - - if ( elem.addEventListener ) { - elem.addEventListener( type, eventHandle ); - } - } - } - - if ( special.add ) { - special.add.call( elem, handleObj ); - - if ( !handleObj.handler.guid ) { - handleObj.handler.guid = handler.guid; - } - } - - // Add to the element's handler list, delegates in front - if ( selector ) { - handlers.splice( handlers.delegateCount++, 0, handleObj ); - } else { - handlers.push( handleObj ); - } - - // Keep track of which events have ever been used, for event optimization - jQuery.event.global[ type ] = true; - } - - }, - - // Detach an event or set of events from an element - remove: function( elem, types, handler, selector, mappedTypes ) { - - var j, origCount, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); - - if ( !elemData || !( events = elemData.events ) ) { - return; - } - - // Once for each type.namespace in types; type may be omitted - types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[ t ] ) || []; - type = origType = tmp[ 1 ]; - namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); - - // Unbind all events (on this namespace, if provided) for the element - if ( !type ) { - for ( type in events ) { - jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); - } - continue; - } - - special = jQuery.event.special[ type ] || {}; - type = ( selector ? special.delegateType : special.bindType ) || type; - handlers = events[ type ] || []; - tmp = tmp[ 2 ] && - new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); - - // Remove matching events - origCount = j = handlers.length; - while ( j-- ) { - handleObj = handlers[ j ]; - - if ( ( mappedTypes || origType === handleObj.origType ) && - ( !handler || handler.guid === handleObj.guid ) && - ( !tmp || tmp.test( handleObj.namespace ) ) && - ( !selector || selector === handleObj.selector || - selector === "**" && handleObj.selector ) ) { - handlers.splice( j, 1 ); - - if ( handleObj.selector ) { - handlers.delegateCount--; - } - if ( special.remove ) { - special.remove.call( elem, handleObj ); - } - } - } - - // Remove generic event handler if we removed something and no more handlers exist - // (avoids potential for endless recursion during removal of special event handlers) - if ( origCount && !handlers.length ) { - if ( !special.teardown || - special.teardown.call( elem, namespaces, elemData.handle ) === false ) { - - jQuery.removeEvent( elem, type, elemData.handle ); - } - - delete events[ type ]; - } - } - - // Remove data and the expando if it's no longer used - if ( jQuery.isEmptyObject( events ) ) { - dataPriv.remove( elem, "handle events" ); - } - }, - - dispatch: function( nativeEvent ) { - - var i, j, ret, matched, handleObj, handlerQueue, - args = new Array( arguments.length ), - - // Make a writable jQuery.Event from the native event object - event = jQuery.event.fix( nativeEvent ), - - handlers = ( - dataPriv.get( this, "events" ) || Object.create( null ) - )[ event.type ] || [], - special = jQuery.event.special[ event.type ] || {}; - - // Use the fix-ed jQuery.Event rather than the (read-only) native event - args[ 0 ] = event; - - for ( i = 1; i < arguments.length; i++ ) { - args[ i ] = arguments[ i ]; - } - - event.delegateTarget = this; - - // Call the preDispatch hook for the mapped type, and let it bail if desired - if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { - return; - } - - // Determine handlers - handlerQueue = jQuery.event.handlers.call( this, event, handlers ); - - // Run delegates first; they may want to stop propagation beneath us - i = 0; - while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { - event.currentTarget = matched.elem; - - j = 0; - while ( ( handleObj = matched.handlers[ j++ ] ) && - !event.isImmediatePropagationStopped() ) { - - // If the event is namespaced, then each handler is only invoked if it is - // specially universal or its namespaces are a superset of the event's. - if ( !event.rnamespace || handleObj.namespace === false || - event.rnamespace.test( handleObj.namespace ) ) { - - event.handleObj = handleObj; - event.data = handleObj.data; - - ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || - handleObj.handler ).apply( matched.elem, args ); - - if ( ret !== undefined ) { - if ( ( event.result = ret ) === false ) { - event.preventDefault(); - event.stopPropagation(); - } - } - } - } - } - - // Call the postDispatch hook for the mapped type - if ( special.postDispatch ) { - special.postDispatch.call( this, event ); - } - - return event.result; - }, - - handlers: function( event, handlers ) { - var i, handleObj, sel, matchedHandlers, matchedSelectors, - handlerQueue = [], - delegateCount = handlers.delegateCount, - cur = event.target; - - // Find delegate handlers - if ( delegateCount && - - // Support: IE <=9 - // Black-hole SVG instance trees (trac-13180) - cur.nodeType && - - // Support: Firefox <=42 - // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) - // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click - // Support: IE 11 only - // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) - !( event.type === "click" && event.button >= 1 ) ) { - - for ( ; cur !== this; cur = cur.parentNode || this ) { - - // Don't check non-elements (#13208) - // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) - if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { - matchedHandlers = []; - matchedSelectors = {}; - for ( i = 0; i < delegateCount; i++ ) { - handleObj = handlers[ i ]; - - // Don't conflict with Object.prototype properties (#13203) - sel = handleObj.selector + " "; - - if ( matchedSelectors[ sel ] === undefined ) { - matchedSelectors[ sel ] = handleObj.needsContext ? - jQuery( sel, this ).index( cur ) > -1 : - jQuery.find( sel, this, null, [ cur ] ).length; - } - if ( matchedSelectors[ sel ] ) { - matchedHandlers.push( handleObj ); - } - } - if ( matchedHandlers.length ) { - handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); - } - } - } - } - - // Add the remaining (directly-bound) handlers - cur = this; - if ( delegateCount < handlers.length ) { - handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); - } - - return handlerQueue; - }, - - addProp: function( name, hook ) { - Object.defineProperty( jQuery.Event.prototype, name, { - enumerable: true, - configurable: true, - - get: isFunction( hook ) ? - function() { - if ( this.originalEvent ) { - return hook( this.originalEvent ); - } - } : - function() { - if ( this.originalEvent ) { - return this.originalEvent[ name ]; - } - }, - - set: function( value ) { - Object.defineProperty( this, name, { - enumerable: true, - configurable: true, - writable: true, - value: value - } ); - } - } ); - }, - - fix: function( originalEvent ) { - return originalEvent[ jQuery.expando ] ? - originalEvent : - new jQuery.Event( originalEvent ); - }, - - special: { - load: { - - // Prevent triggered image.load events from bubbling to window.load - noBubble: true - }, - click: { - - // Utilize native event to ensure correct state for checkable inputs - setup: function( data ) { - - // For mutual compressibility with _default, replace `this` access with a local var. - // `|| data` is dead code meant only to preserve the variable through minification. - var el = this || data; - - // Claim the first handler - if ( rcheckableType.test( el.type ) && - el.click && nodeName( el, "input" ) ) { - - // dataPriv.set( el, "click", ... ) - leverageNative( el, "click", returnTrue ); - } - - // Return false to allow normal processing in the caller - return false; - }, - trigger: function( data ) { - - // For mutual compressibility with _default, replace `this` access with a local var. - // `|| data` is dead code meant only to preserve the variable through minification. - var el = this || data; - - // Force setup before triggering a click - if ( rcheckableType.test( el.type ) && - el.click && nodeName( el, "input" ) ) { - - leverageNative( el, "click" ); - } - - // Return non-false to allow normal event-path propagation - return true; - }, - - // For cross-browser consistency, suppress native .click() on links - // Also prevent it if we're currently inside a leveraged native-event stack - _default: function( event ) { - var target = event.target; - return rcheckableType.test( target.type ) && - target.click && nodeName( target, "input" ) && - dataPriv.get( target, "click" ) || - nodeName( target, "a" ); - } - }, - - beforeunload: { - postDispatch: function( event ) { - - // Support: Firefox 20+ - // Firefox doesn't alert if the returnValue field is not set. - if ( event.result !== undefined && event.originalEvent ) { - event.originalEvent.returnValue = event.result; - } - } - } - } -}; - -// Ensure the presence of an event listener that handles manually-triggered -// synthetic events by interrupting progress until reinvoked in response to -// *native* events that it fires directly, ensuring that state changes have -// already occurred before other listeners are invoked. -function leverageNative( el, type, expectSync ) { - - // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add - if ( !expectSync ) { - if ( dataPriv.get( el, type ) === undefined ) { - jQuery.event.add( el, type, returnTrue ); - } - return; - } - - // Register the controller as a special universal handler for all event namespaces - dataPriv.set( el, type, false ); - jQuery.event.add( el, type, { - namespace: false, - handler: function( event ) { - var notAsync, result, - saved = dataPriv.get( this, type ); - - if ( ( event.isTrigger & 1 ) && this[ type ] ) { - - // Interrupt processing of the outer synthetic .trigger()ed event - // Saved data should be false in such cases, but might be a leftover capture object - // from an async native handler (gh-4350) - if ( !saved.length ) { - - // Store arguments for use when handling the inner native event - // There will always be at least one argument (an event object), so this array - // will not be confused with a leftover capture object. - saved = slice.call( arguments ); - dataPriv.set( this, type, saved ); - - // Trigger the native event and capture its result - // Support: IE <=9 - 11+ - // focus() and blur() are asynchronous - notAsync = expectSync( this, type ); - this[ type ](); - result = dataPriv.get( this, type ); - if ( saved !== result || notAsync ) { - dataPriv.set( this, type, false ); - } else { - result = {}; - } - if ( saved !== result ) { - - // Cancel the outer synthetic event - event.stopImmediatePropagation(); - event.preventDefault(); - - // Support: Chrome 86+ - // In Chrome, if an element having a focusout handler is blurred by - // clicking outside of it, it invokes the handler synchronously. If - // that handler calls `.remove()` on the element, the data is cleared, - // leaving `result` undefined. We need to guard against this. - return result && result.value; - } - - // If this is an inner synthetic event for an event with a bubbling surrogate - // (focus or blur), assume that the surrogate already propagated from triggering the - // native event and prevent that from happening again here. - // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the - // bubbling surrogate propagates *after* the non-bubbling base), but that seems - // less bad than duplication. - } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { - event.stopPropagation(); - } - - // If this is a native event triggered above, everything is now in order - // Fire an inner synthetic event with the original arguments - } else if ( saved.length ) { - - // ...and capture the result - dataPriv.set( this, type, { - value: jQuery.event.trigger( - - // Support: IE <=9 - 11+ - // Extend with the prototype to reset the above stopImmediatePropagation() - jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), - saved.slice( 1 ), - this - ) - } ); - - // Abort handling of the native event - event.stopImmediatePropagation(); - } - } - } ); -} - -jQuery.removeEvent = function( elem, type, handle ) { - - // This "if" is needed for plain objects - if ( elem.removeEventListener ) { - elem.removeEventListener( type, handle ); - } -}; - -jQuery.Event = function( src, props ) { - - // Allow instantiation without the 'new' keyword - if ( !( this instanceof jQuery.Event ) ) { - return new jQuery.Event( src, props ); - } - - // Event object - if ( src && src.type ) { - this.originalEvent = src; - this.type = src.type; - - // Events bubbling up the document may have been marked as prevented - // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = src.defaultPrevented || - src.defaultPrevented === undefined && - - // Support: Android <=2.3 only - src.returnValue === false ? - returnTrue : - returnFalse; - - // Create target properties - // Support: Safari <=6 - 7 only - // Target should not be a text node (#504, #13143) - this.target = ( src.target && src.target.nodeType === 3 ) ? - src.target.parentNode : - src.target; - - this.currentTarget = src.currentTarget; - this.relatedTarget = src.relatedTarget; - - // Event type - } else { - this.type = src; - } - - // Put explicitly provided properties onto the event object - if ( props ) { - jQuery.extend( this, props ); - } - - // Create a timestamp if incoming event doesn't have one - this.timeStamp = src && src.timeStamp || Date.now(); - - // Mark it as fixed - this[ jQuery.expando ] = true; -}; - -// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding -// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html -jQuery.Event.prototype = { - constructor: jQuery.Event, - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse, - isSimulated: false, - - preventDefault: function() { - var e = this.originalEvent; - - this.isDefaultPrevented = returnTrue; - - if ( e && !this.isSimulated ) { - e.preventDefault(); - } - }, - stopPropagation: function() { - var e = this.originalEvent; - - this.isPropagationStopped = returnTrue; - - if ( e && !this.isSimulated ) { - e.stopPropagation(); - } - }, - stopImmediatePropagation: function() { - var e = this.originalEvent; - - this.isImmediatePropagationStopped = returnTrue; - - if ( e && !this.isSimulated ) { - e.stopImmediatePropagation(); - } - - this.stopPropagation(); - } -}; - -// Includes all common event props including KeyEvent and MouseEvent specific props -jQuery.each( { - altKey: true, - bubbles: true, - cancelable: true, - changedTouches: true, - ctrlKey: true, - detail: true, - eventPhase: true, - metaKey: true, - pageX: true, - pageY: true, - shiftKey: true, - view: true, - "char": true, - code: true, - charCode: true, - key: true, - keyCode: true, - button: true, - buttons: true, - clientX: true, - clientY: true, - offsetX: true, - offsetY: true, - pointerId: true, - pointerType: true, - screenX: true, - screenY: true, - targetTouches: true, - toElement: true, - touches: true, - which: true -}, jQuery.event.addProp ); - -jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { - jQuery.event.special[ type ] = { - - // Utilize native event if possible so blur/focus sequence is correct - setup: function() { - - // Claim the first handler - // dataPriv.set( this, "focus", ... ) - // dataPriv.set( this, "blur", ... ) - leverageNative( this, type, expectSync ); - - // Return false to allow normal processing in the caller - return false; - }, - trigger: function() { - - // Force setup before trigger - leverageNative( this, type ); - - // Return non-false to allow normal event-path propagation - return true; - }, - - // Suppress native focus or blur as it's already being fired - // in leverageNative. - _default: function() { - return true; - }, - - delegateType: delegateType - }; -} ); - -// Create mouseenter/leave events using mouseover/out and event-time checks -// so that event delegation works in jQuery. -// Do the same for pointerenter/pointerleave and pointerover/pointerout -// -// Support: Safari 7 only -// Safari sends mouseenter too often; see: -// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 -// for the description of the bug (it existed in older Chrome versions as well). -jQuery.each( { - mouseenter: "mouseover", - mouseleave: "mouseout", - pointerenter: "pointerover", - pointerleave: "pointerout" -}, function( orig, fix ) { - jQuery.event.special[ orig ] = { - delegateType: fix, - bindType: fix, - - handle: function( event ) { - var ret, - target = this, - related = event.relatedTarget, - handleObj = event.handleObj; - - // For mouseenter/leave call the handler if related is outside the target. - // NB: No relatedTarget if the mouse left/entered the browser window - if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { - event.type = handleObj.origType; - ret = handleObj.handler.apply( this, arguments ); - event.type = fix; - } - return ret; - } - }; -} ); - -jQuery.fn.extend( { - - on: function( types, selector, data, fn ) { - return on( this, types, selector, data, fn ); - }, - one: function( types, selector, data, fn ) { - return on( this, types, selector, data, fn, 1 ); - }, - off: function( types, selector, fn ) { - var handleObj, type; - if ( types && types.preventDefault && types.handleObj ) { - - // ( event ) dispatched jQuery.Event - handleObj = types.handleObj; - jQuery( types.delegateTarget ).off( - handleObj.namespace ? - handleObj.origType + "." + handleObj.namespace : - handleObj.origType, - handleObj.selector, - handleObj.handler - ); - return this; - } - if ( typeof types === "object" ) { - - // ( types-object [, selector] ) - for ( type in types ) { - this.off( type, selector, types[ type ] ); - } - return this; - } - if ( selector === false || typeof selector === "function" ) { - - // ( types [, fn] ) - fn = selector; - selector = undefined; - } - if ( fn === false ) { - fn = returnFalse; - } - return this.each( function() { - jQuery.event.remove( this, types, fn, selector ); - } ); - } -} ); - - -var - - // Support: IE <=10 - 11, Edge 12 - 13 only - // In IE/Edge using regex groups here causes severe slowdowns. - // See https://connect.microsoft.com/IE/feedback/details/1736512/ - rnoInnerhtml = /\s*$/g; - -// Prefer a tbody over its parent table for containing new rows -function manipulationTarget( elem, content ) { - if ( nodeName( elem, "table" ) && - nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { - - return jQuery( elem ).children( "tbody" )[ 0 ] || elem; - } - - return elem; -} - -// Replace/restore the type attribute of script elements for safe DOM manipulation -function disableScript( elem ) { - elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; - return elem; -} -function restoreScript( elem ) { - if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { - elem.type = elem.type.slice( 5 ); - } else { - elem.removeAttribute( "type" ); - } - - return elem; -} - -function cloneCopyEvent( src, dest ) { - var i, l, type, pdataOld, udataOld, udataCur, events; - - if ( dest.nodeType !== 1 ) { - return; - } - - // 1. Copy private data: events, handlers, etc. - if ( dataPriv.hasData( src ) ) { - pdataOld = dataPriv.get( src ); - events = pdataOld.events; - - if ( events ) { - dataPriv.remove( dest, "handle events" ); - - for ( type in events ) { - for ( i = 0, l = events[ type ].length; i < l; i++ ) { - jQuery.event.add( dest, type, events[ type ][ i ] ); - } - } - } - } - - // 2. Copy user data - if ( dataUser.hasData( src ) ) { - udataOld = dataUser.access( src ); - udataCur = jQuery.extend( {}, udataOld ); - - dataUser.set( dest, udataCur ); - } -} - -// Fix IE bugs, see support tests -function fixInput( src, dest ) { - var nodeName = dest.nodeName.toLowerCase(); - - // Fails to persist the checked state of a cloned checkbox or radio button. - if ( nodeName === "input" && rcheckableType.test( src.type ) ) { - dest.checked = src.checked; - - // Fails to return the selected option to the default selected state when cloning options - } else if ( nodeName === "input" || nodeName === "textarea" ) { - dest.defaultValue = src.defaultValue; - } -} - -function domManip( collection, args, callback, ignored ) { - - // Flatten any nested arrays - args = flat( args ); - - var fragment, first, scripts, hasScripts, node, doc, - i = 0, - l = collection.length, - iNoClone = l - 1, - value = args[ 0 ], - valueIsFunction = isFunction( value ); - - // We can't cloneNode fragments that contain checked, in WebKit - if ( valueIsFunction || - ( l > 1 && typeof value === "string" && - !support.checkClone && rchecked.test( value ) ) ) { - return collection.each( function( index ) { - var self = collection.eq( index ); - if ( valueIsFunction ) { - args[ 0 ] = value.call( this, index, self.html() ); - } - domManip( self, args, callback, ignored ); - } ); - } - - if ( l ) { - fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); - first = fragment.firstChild; - - if ( fragment.childNodes.length === 1 ) { - fragment = first; - } - - // Require either new content or an interest in ignored elements to invoke the callback - if ( first || ignored ) { - scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); - hasScripts = scripts.length; - - // Use the original fragment for the last item - // instead of the first because it can end up - // being emptied incorrectly in certain situations (#8070). - for ( ; i < l; i++ ) { - node = fragment; - - if ( i !== iNoClone ) { - node = jQuery.clone( node, true, true ); - - // Keep references to cloned scripts for later restoration - if ( hasScripts ) { - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( scripts, getAll( node, "script" ) ); - } - } - - callback.call( collection[ i ], node, i ); - } - - if ( hasScripts ) { - doc = scripts[ scripts.length - 1 ].ownerDocument; - - // Reenable scripts - jQuery.map( scripts, restoreScript ); - - // Evaluate executable scripts on first document insertion - for ( i = 0; i < hasScripts; i++ ) { - node = scripts[ i ]; - if ( rscriptType.test( node.type || "" ) && - !dataPriv.access( node, "globalEval" ) && - jQuery.contains( doc, node ) ) { - - if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { - - // Optional AJAX dependency, but won't run scripts if not present - if ( jQuery._evalUrl && !node.noModule ) { - jQuery._evalUrl( node.src, { - nonce: node.nonce || node.getAttribute( "nonce" ) - }, doc ); - } - } else { - DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); - } - } - } - } - } - } - - return collection; -} - -function remove( elem, selector, keepData ) { - var node, - nodes = selector ? jQuery.filter( selector, elem ) : elem, - i = 0; - - for ( ; ( node = nodes[ i ] ) != null; i++ ) { - if ( !keepData && node.nodeType === 1 ) { - jQuery.cleanData( getAll( node ) ); - } - - if ( node.parentNode ) { - if ( keepData && isAttached( node ) ) { - setGlobalEval( getAll( node, "script" ) ); - } - node.parentNode.removeChild( node ); - } - } - - return elem; -} - -jQuery.extend( { - htmlPrefilter: function( html ) { - return html; - }, - - clone: function( elem, dataAndEvents, deepDataAndEvents ) { - var i, l, srcElements, destElements, - clone = elem.cloneNode( true ), - inPage = isAttached( elem ); - - // Fix IE cloning issues - if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && - !jQuery.isXMLDoc( elem ) ) { - - // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 - destElements = getAll( clone ); - srcElements = getAll( elem ); - - for ( i = 0, l = srcElements.length; i < l; i++ ) { - fixInput( srcElements[ i ], destElements[ i ] ); - } - } - - // Copy the events from the original to the clone - if ( dataAndEvents ) { - if ( deepDataAndEvents ) { - srcElements = srcElements || getAll( elem ); - destElements = destElements || getAll( clone ); - - for ( i = 0, l = srcElements.length; i < l; i++ ) { - cloneCopyEvent( srcElements[ i ], destElements[ i ] ); - } - } else { - cloneCopyEvent( elem, clone ); - } - } - - // Preserve script evaluation history - destElements = getAll( clone, "script" ); - if ( destElements.length > 0 ) { - setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); - } - - // Return the cloned set - return clone; - }, - - cleanData: function( elems ) { - var data, elem, type, - special = jQuery.event.special, - i = 0; - - for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { - if ( acceptData( elem ) ) { - if ( ( data = elem[ dataPriv.expando ] ) ) { - if ( data.events ) { - for ( type in data.events ) { - if ( special[ type ] ) { - jQuery.event.remove( elem, type ); - - // This is a shortcut to avoid jQuery.event.remove's overhead - } else { - jQuery.removeEvent( elem, type, data.handle ); - } - } - } - - // Support: Chrome <=35 - 45+ - // Assign undefined instead of using delete, see Data#remove - elem[ dataPriv.expando ] = undefined; - } - if ( elem[ dataUser.expando ] ) { - - // Support: Chrome <=35 - 45+ - // Assign undefined instead of using delete, see Data#remove - elem[ dataUser.expando ] = undefined; - } - } - } - } -} ); - -jQuery.fn.extend( { - detach: function( selector ) { - return remove( this, selector, true ); - }, - - remove: function( selector ) { - return remove( this, selector ); - }, - - text: function( value ) { - return access( this, function( value ) { - return value === undefined ? - jQuery.text( this ) : - this.empty().each( function() { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - this.textContent = value; - } - } ); - }, null, value, arguments.length ); - }, - - append: function() { - return domManip( this, arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.appendChild( elem ); - } - } ); - }, - - prepend: function() { - return domManip( this, arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.insertBefore( elem, target.firstChild ); - } - } ); - }, - - before: function() { - return domManip( this, arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this ); - } - } ); - }, - - after: function() { - return domManip( this, arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this.nextSibling ); - } - } ); - }, - - empty: function() { - var elem, - i = 0; - - for ( ; ( elem = this[ i ] ) != null; i++ ) { - if ( elem.nodeType === 1 ) { - - // Prevent memory leaks - jQuery.cleanData( getAll( elem, false ) ); - - // Remove any remaining nodes - elem.textContent = ""; - } - } - - return this; - }, - - clone: function( dataAndEvents, deepDataAndEvents ) { - dataAndEvents = dataAndEvents == null ? false : dataAndEvents; - deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; - - return this.map( function() { - return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); - } ); - }, - - html: function( value ) { - return access( this, function( value ) { - var elem = this[ 0 ] || {}, - i = 0, - l = this.length; - - if ( value === undefined && elem.nodeType === 1 ) { - return elem.innerHTML; - } - - // See if we can take a shortcut and just use innerHTML - if ( typeof value === "string" && !rnoInnerhtml.test( value ) && - !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { - - value = jQuery.htmlPrefilter( value ); - - try { - for ( ; i < l; i++ ) { - elem = this[ i ] || {}; - - // Remove element nodes and prevent memory leaks - if ( elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem, false ) ); - elem.innerHTML = value; - } - } - - elem = 0; - - // If using innerHTML throws an exception, use the fallback method - } catch ( e ) {} - } - - if ( elem ) { - this.empty().append( value ); - } - }, null, value, arguments.length ); - }, - - replaceWith: function() { - var ignored = []; - - // Make the changes, replacing each non-ignored context element with the new content - return domManip( this, arguments, function( elem ) { - var parent = this.parentNode; - - if ( jQuery.inArray( this, ignored ) < 0 ) { - jQuery.cleanData( getAll( this ) ); - if ( parent ) { - parent.replaceChild( elem, this ); - } - } - - // Force callback invocation - }, ignored ); - } -} ); - -jQuery.each( { - appendTo: "append", - prependTo: "prepend", - insertBefore: "before", - insertAfter: "after", - replaceAll: "replaceWith" -}, function( name, original ) { - jQuery.fn[ name ] = function( selector ) { - var elems, - ret = [], - insert = jQuery( selector ), - last = insert.length - 1, - i = 0; - - for ( ; i <= last; i++ ) { - elems = i === last ? this : this.clone( true ); - jQuery( insert[ i ] )[ original ]( elems ); - - // Support: Android <=4.0 only, PhantomJS 1 only - // .get() because push.apply(_, arraylike) throws on ancient WebKit - push.apply( ret, elems.get() ); - } - - return this.pushStack( ret ); - }; -} ); -var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); - -var getStyles = function( elem ) { - - // Support: IE <=11 only, Firefox <=30 (#15098, #14150) - // IE throws on elements created in popups - // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" - var view = elem.ownerDocument.defaultView; - - if ( !view || !view.opener ) { - view = window; - } - - return view.getComputedStyle( elem ); - }; - -var swap = function( elem, options, callback ) { - var ret, name, - old = {}; - - // Remember the old values, and insert the new ones - for ( name in options ) { - old[ name ] = elem.style[ name ]; - elem.style[ name ] = options[ name ]; - } - - ret = callback.call( elem ); - - // Revert the old values - for ( name in options ) { - elem.style[ name ] = old[ name ]; - } - - return ret; -}; - - -var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); - - - -( function() { - - // Executing both pixelPosition & boxSizingReliable tests require only one layout - // so they're executed at the same time to save the second computation. - function computeStyleTests() { - - // This is a singleton, we need to execute it only once - if ( !div ) { - return; - } - - container.style.cssText = "position:absolute;left:-11111px;width:60px;" + - "margin-top:1px;padding:0;border:0"; - div.style.cssText = - "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + - "margin:auto;border:1px;padding:1px;" + - "width:60%;top:1%"; - documentElement.appendChild( container ).appendChild( div ); - - var divStyle = window.getComputedStyle( div ); - pixelPositionVal = divStyle.top !== "1%"; - - // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 - reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; - - // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 - // Some styles come back with percentage values, even though they shouldn't - div.style.right = "60%"; - pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; - - // Support: IE 9 - 11 only - // Detect misreporting of content dimensions for box-sizing:border-box elements - boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; - - // Support: IE 9 only - // Detect overflow:scroll screwiness (gh-3699) - // Support: Chrome <=64 - // Don't get tricked when zoom affects offsetWidth (gh-4029) - div.style.position = "absolute"; - scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; - - documentElement.removeChild( container ); - - // Nullify the div so it wouldn't be stored in the memory and - // it will also be a sign that checks already performed - div = null; - } - - function roundPixelMeasures( measure ) { - return Math.round( parseFloat( measure ) ); - } - - var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, - reliableTrDimensionsVal, reliableMarginLeftVal, - container = document.createElement( "div" ), - div = document.createElement( "div" ); - - // Finish early in limited (non-browser) environments - if ( !div.style ) { - return; - } - - // Support: IE <=9 - 11 only - // Style of cloned element affects source element cloned (#8908) - div.style.backgroundClip = "content-box"; - div.cloneNode( true ).style.backgroundClip = ""; - support.clearCloneStyle = div.style.backgroundClip === "content-box"; - - jQuery.extend( support, { - boxSizingReliable: function() { - computeStyleTests(); - return boxSizingReliableVal; - }, - pixelBoxStyles: function() { - computeStyleTests(); - return pixelBoxStylesVal; - }, - pixelPosition: function() { - computeStyleTests(); - return pixelPositionVal; - }, - reliableMarginLeft: function() { - computeStyleTests(); - return reliableMarginLeftVal; - }, - scrollboxSize: function() { - computeStyleTests(); - return scrollboxSizeVal; - }, - - // Support: IE 9 - 11+, Edge 15 - 18+ - // IE/Edge misreport `getComputedStyle` of table rows with width/height - // set in CSS while `offset*` properties report correct values. - // Behavior in IE 9 is more subtle than in newer versions & it passes - // some versions of this test; make sure not to make it pass there! - // - // Support: Firefox 70+ - // Only Firefox includes border widths - // in computed dimensions. (gh-4529) - reliableTrDimensions: function() { - var table, tr, trChild, trStyle; - if ( reliableTrDimensionsVal == null ) { - table = document.createElement( "table" ); - tr = document.createElement( "tr" ); - trChild = document.createElement( "div" ); - - table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate"; - tr.style.cssText = "border:1px solid"; - - // Support: Chrome 86+ - // Height set through cssText does not get applied. - // Computed height then comes back as 0. - tr.style.height = "1px"; - trChild.style.height = "9px"; - - // Support: Android 8 Chrome 86+ - // In our bodyBackground.html iframe, - // display for all div elements is set to "inline", - // which causes a problem only in Android 8 Chrome 86. - // Ensuring the div is display: block - // gets around this issue. - trChild.style.display = "block"; - - documentElement - .appendChild( table ) - .appendChild( tr ) - .appendChild( trChild ); - - trStyle = window.getComputedStyle( tr ); - reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) + - parseInt( trStyle.borderTopWidth, 10 ) + - parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight; - - documentElement.removeChild( table ); - } - return reliableTrDimensionsVal; - } - } ); -} )(); - - -function curCSS( elem, name, computed ) { - var width, minWidth, maxWidth, ret, - - // Support: Firefox 51+ - // Retrieving style before computed somehow - // fixes an issue with getting wrong values - // on detached elements - style = elem.style; - - computed = computed || getStyles( elem ); - - // getPropertyValue is needed for: - // .css('filter') (IE 9 only, #12537) - // .css('--customProperty) (#3144) - if ( computed ) { - ret = computed.getPropertyValue( name ) || computed[ name ]; - - if ( ret === "" && !isAttached( elem ) ) { - ret = jQuery.style( elem, name ); - } - - // A tribute to the "awesome hack by Dean Edwards" - // Android Browser returns percentage for some values, - // but width seems to be reliably pixels. - // This is against the CSSOM draft spec: - // https://drafts.csswg.org/cssom/#resolved-values - if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { - - // Remember the original values - width = style.width; - minWidth = style.minWidth; - maxWidth = style.maxWidth; - - // Put in the new values to get a computed value out - style.minWidth = style.maxWidth = style.width = ret; - ret = computed.width; - - // Revert the changed values - style.width = width; - style.minWidth = minWidth; - style.maxWidth = maxWidth; - } - } - - return ret !== undefined ? - - // Support: IE <=9 - 11 only - // IE returns zIndex value as an integer. - ret + "" : - ret; -} - - -function addGetHookIf( conditionFn, hookFn ) { - - // Define the hook, we'll check on the first run if it's really needed. - return { - get: function() { - if ( conditionFn() ) { - - // Hook not needed (or it's not possible to use it due - // to missing dependency), remove it. - delete this.get; - return; - } - - // Hook needed; redefine it so that the support test is not executed again. - return ( this.get = hookFn ).apply( this, arguments ); - } - }; -} - - -var cssPrefixes = [ "Webkit", "Moz", "ms" ], - emptyStyle = document.createElement( "div" ).style, - vendorProps = {}; - -// Return a vendor-prefixed property or undefined -function vendorPropName( name ) { - - // Check for vendor prefixed names - var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), - i = cssPrefixes.length; - - while ( i-- ) { - name = cssPrefixes[ i ] + capName; - if ( name in emptyStyle ) { - return name; - } - } -} - -// Return a potentially-mapped jQuery.cssProps or vendor prefixed property -function finalPropName( name ) { - var final = jQuery.cssProps[ name ] || vendorProps[ name ]; - - if ( final ) { - return final; - } - if ( name in emptyStyle ) { - return name; - } - return vendorProps[ name ] = vendorPropName( name ) || name; -} - - -var - - // Swappable if display is none or starts with table - // except "table", "table-cell", or "table-caption" - // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display - rdisplayswap = /^(none|table(?!-c[ea]).+)/, - rcustomProp = /^--/, - cssShow = { position: "absolute", visibility: "hidden", display: "block" }, - cssNormalTransform = { - letterSpacing: "0", - fontWeight: "400" - }; - -function setPositiveNumber( _elem, value, subtract ) { - - // Any relative (+/-) values have already been - // normalized at this point - var matches = rcssNum.exec( value ); - return matches ? - - // Guard against undefined "subtract", e.g., when used as in cssHooks - Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : - value; -} - -function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { - var i = dimension === "width" ? 1 : 0, - extra = 0, - delta = 0; - - // Adjustment may not be necessary - if ( box === ( isBorderBox ? "border" : "content" ) ) { - return 0; - } - - for ( ; i < 4; i += 2 ) { - - // Both box models exclude margin - if ( box === "margin" ) { - delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); - } - - // If we get here with a content-box, we're seeking "padding" or "border" or "margin" - if ( !isBorderBox ) { - - // Add padding - delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); - - // For "border" or "margin", add border - if ( box !== "padding" ) { - delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); - - // But still keep track of it otherwise - } else { - extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); - } - - // If we get here with a border-box (content + padding + border), we're seeking "content" or - // "padding" or "margin" - } else { - - // For "content", subtract padding - if ( box === "content" ) { - delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); - } - - // For "content" or "padding", subtract border - if ( box !== "margin" ) { - delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); - } - } - } - - // Account for positive content-box scroll gutter when requested by providing computedVal - if ( !isBorderBox && computedVal >= 0 ) { - - // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border - // Assuming integer scroll gutter, subtract the rest and round down - delta += Math.max( 0, Math.ceil( - elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - - computedVal - - delta - - extra - - 0.5 - - // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter - // Use an explicit zero to avoid NaN (gh-3964) - ) ) || 0; - } - - return delta; -} - -function getWidthOrHeight( elem, dimension, extra ) { - - // Start with computed style - var styles = getStyles( elem ), - - // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). - // Fake content-box until we know it's needed to know the true value. - boxSizingNeeded = !support.boxSizingReliable() || extra, - isBorderBox = boxSizingNeeded && - jQuery.css( elem, "boxSizing", false, styles ) === "border-box", - valueIsBorderBox = isBorderBox, - - val = curCSS( elem, dimension, styles ), - offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); - - // Support: Firefox <=54 - // Return a confounding non-pixel value or feign ignorance, as appropriate. - if ( rnumnonpx.test( val ) ) { - if ( !extra ) { - return val; - } - val = "auto"; - } - - - // Support: IE 9 - 11 only - // Use offsetWidth/offsetHeight for when box sizing is unreliable. - // In those cases, the computed value can be trusted to be border-box. - if ( ( !support.boxSizingReliable() && isBorderBox || - - // Support: IE 10 - 11+, Edge 15 - 18+ - // IE/Edge misreport `getComputedStyle` of table rows with width/height - // set in CSS while `offset*` properties report correct values. - // Interestingly, in some cases IE 9 doesn't suffer from this issue. - !support.reliableTrDimensions() && nodeName( elem, "tr" ) || - - // Fall back to offsetWidth/offsetHeight when value is "auto" - // This happens for inline elements with no explicit setting (gh-3571) - val === "auto" || - - // Support: Android <=4.1 - 4.3 only - // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) - !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && - - // Make sure the element is visible & connected - elem.getClientRects().length ) { - - isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; - - // Where available, offsetWidth/offsetHeight approximate border box dimensions. - // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the - // retrieved value as a content box dimension. - valueIsBorderBox = offsetProp in elem; - if ( valueIsBorderBox ) { - val = elem[ offsetProp ]; - } - } - - // Normalize "" and auto - val = parseFloat( val ) || 0; - - // Adjust for the element's box model - return ( val + - boxModelAdjustment( - elem, - dimension, - extra || ( isBorderBox ? "border" : "content" ), - valueIsBorderBox, - styles, - - // Provide the current computed size to request scroll gutter calculation (gh-3589) - val - ) - ) + "px"; -} - -jQuery.extend( { - - // Add in style property hooks for overriding the default - // behavior of getting and setting a style property - cssHooks: { - opacity: { - get: function( elem, computed ) { - if ( computed ) { - - // We should always get a number back from opacity - var ret = curCSS( elem, "opacity" ); - return ret === "" ? "1" : ret; - } - } - } - }, - - // Don't automatically add "px" to these possibly-unitless properties - cssNumber: { - "animationIterationCount": true, - "columnCount": true, - "fillOpacity": true, - "flexGrow": true, - "flexShrink": true, - "fontWeight": true, - "gridArea": true, - "gridColumn": true, - "gridColumnEnd": true, - "gridColumnStart": true, - "gridRow": true, - "gridRowEnd": true, - "gridRowStart": true, - "lineHeight": true, - "opacity": true, - "order": true, - "orphans": true, - "widows": true, - "zIndex": true, - "zoom": true - }, - - // Add in properties whose names you wish to fix before - // setting or getting the value - cssProps: {}, - - // Get and set the style property on a DOM Node - style: function( elem, name, value, extra ) { - - // Don't set styles on text and comment nodes - if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { - return; - } - - // Make sure that we're working with the right name - var ret, type, hooks, - origName = camelCase( name ), - isCustomProp = rcustomProp.test( name ), - style = elem.style; - - // Make sure that we're working with the right name. We don't - // want to query the value if it is a CSS custom property - // since they are user-defined. - if ( !isCustomProp ) { - name = finalPropName( origName ); - } - - // Gets hook for the prefixed version, then unprefixed version - hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; - - // Check if we're setting a value - if ( value !== undefined ) { - type = typeof value; - - // Convert "+=" or "-=" to relative numbers (#7345) - if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { - value = adjustCSS( elem, name, ret ); - - // Fixes bug #9237 - type = "number"; - } - - // Make sure that null and NaN values aren't set (#7116) - if ( value == null || value !== value ) { - return; - } - - // If a number was passed in, add the unit (except for certain CSS properties) - // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append - // "px" to a few hardcoded values. - if ( type === "number" && !isCustomProp ) { - value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); - } - - // background-* props affect original clone's values - if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { - style[ name ] = "inherit"; - } - - // If a hook was provided, use that value, otherwise just set the specified value - if ( !hooks || !( "set" in hooks ) || - ( value = hooks.set( elem, value, extra ) ) !== undefined ) { - - if ( isCustomProp ) { - style.setProperty( name, value ); - } else { - style[ name ] = value; - } - } - - } else { - - // If a hook was provided get the non-computed value from there - if ( hooks && "get" in hooks && - ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { - - return ret; - } - - // Otherwise just get the value from the style object - return style[ name ]; - } - }, - - css: function( elem, name, extra, styles ) { - var val, num, hooks, - origName = camelCase( name ), - isCustomProp = rcustomProp.test( name ); - - // Make sure that we're working with the right name. We don't - // want to modify the value if it is a CSS custom property - // since they are user-defined. - if ( !isCustomProp ) { - name = finalPropName( origName ); - } - - // Try prefixed name followed by the unprefixed name - hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; - - // If a hook was provided get the computed value from there - if ( hooks && "get" in hooks ) { - val = hooks.get( elem, true, extra ); - } - - // Otherwise, if a way to get the computed value exists, use that - if ( val === undefined ) { - val = curCSS( elem, name, styles ); - } - - // Convert "normal" to computed value - if ( val === "normal" && name in cssNormalTransform ) { - val = cssNormalTransform[ name ]; - } - - // Make numeric if forced or a qualifier was provided and val looks numeric - if ( extra === "" || extra ) { - num = parseFloat( val ); - return extra === true || isFinite( num ) ? num || 0 : val; - } - - return val; - } -} ); - -jQuery.each( [ "height", "width" ], function( _i, dimension ) { - jQuery.cssHooks[ dimension ] = { - get: function( elem, computed, extra ) { - if ( computed ) { - - // Certain elements can have dimension info if we invisibly show them - // but it must have a current display style that would benefit - return rdisplayswap.test( jQuery.css( elem, "display" ) ) && - - // Support: Safari 8+ - // Table columns in Safari have non-zero offsetWidth & zero - // getBoundingClientRect().width unless display is changed. - // Support: IE <=11 only - // Running getBoundingClientRect on a disconnected node - // in IE throws an error. - ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? - swap( elem, cssShow, function() { - return getWidthOrHeight( elem, dimension, extra ); - } ) : - getWidthOrHeight( elem, dimension, extra ); - } - }, - - set: function( elem, value, extra ) { - var matches, - styles = getStyles( elem ), - - // Only read styles.position if the test has a chance to fail - // to avoid forcing a reflow. - scrollboxSizeBuggy = !support.scrollboxSize() && - styles.position === "absolute", - - // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) - boxSizingNeeded = scrollboxSizeBuggy || extra, - isBorderBox = boxSizingNeeded && - jQuery.css( elem, "boxSizing", false, styles ) === "border-box", - subtract = extra ? - boxModelAdjustment( - elem, - dimension, - extra, - isBorderBox, - styles - ) : - 0; - - // Account for unreliable border-box dimensions by comparing offset* to computed and - // faking a content-box to get border and padding (gh-3699) - if ( isBorderBox && scrollboxSizeBuggy ) { - subtract -= Math.ceil( - elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - - parseFloat( styles[ dimension ] ) - - boxModelAdjustment( elem, dimension, "border", false, styles ) - - 0.5 - ); - } - - // Convert to pixels if value adjustment is needed - if ( subtract && ( matches = rcssNum.exec( value ) ) && - ( matches[ 3 ] || "px" ) !== "px" ) { - - elem.style[ dimension ] = value; - value = jQuery.css( elem, dimension ); - } - - return setPositiveNumber( elem, value, subtract ); - } - }; -} ); - -jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, - function( elem, computed ) { - if ( computed ) { - return ( parseFloat( curCSS( elem, "marginLeft" ) ) || - elem.getBoundingClientRect().left - - swap( elem, { marginLeft: 0 }, function() { - return elem.getBoundingClientRect().left; - } ) - ) + "px"; - } - } -); - -// These hooks are used by animate to expand properties -jQuery.each( { - margin: "", - padding: "", - border: "Width" -}, function( prefix, suffix ) { - jQuery.cssHooks[ prefix + suffix ] = { - expand: function( value ) { - var i = 0, - expanded = {}, - - // Assumes a single number if not a string - parts = typeof value === "string" ? value.split( " " ) : [ value ]; - - for ( ; i < 4; i++ ) { - expanded[ prefix + cssExpand[ i ] + suffix ] = - parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; - } - - return expanded; - } - }; - - if ( prefix !== "margin" ) { - jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; - } -} ); - -jQuery.fn.extend( { - css: function( name, value ) { - return access( this, function( elem, name, value ) { - var styles, len, - map = {}, - i = 0; - - if ( Array.isArray( name ) ) { - styles = getStyles( elem ); - len = name.length; - - for ( ; i < len; i++ ) { - map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); - } - - return map; - } - - return value !== undefined ? - jQuery.style( elem, name, value ) : - jQuery.css( elem, name ); - }, name, value, arguments.length > 1 ); - } -} ); - - -function Tween( elem, options, prop, end, easing ) { - return new Tween.prototype.init( elem, options, prop, end, easing ); -} -jQuery.Tween = Tween; - -Tween.prototype = { - constructor: Tween, - init: function( elem, options, prop, end, easing, unit ) { - this.elem = elem; - this.prop = prop; - this.easing = easing || jQuery.easing._default; - this.options = options; - this.start = this.now = this.cur(); - this.end = end; - this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); - }, - cur: function() { - var hooks = Tween.propHooks[ this.prop ]; - - return hooks && hooks.get ? - hooks.get( this ) : - Tween.propHooks._default.get( this ); - }, - run: function( percent ) { - var eased, - hooks = Tween.propHooks[ this.prop ]; - - if ( this.options.duration ) { - this.pos = eased = jQuery.easing[ this.easing ]( - percent, this.options.duration * percent, 0, 1, this.options.duration - ); - } else { - this.pos = eased = percent; - } - this.now = ( this.end - this.start ) * eased + this.start; - - if ( this.options.step ) { - this.options.step.call( this.elem, this.now, this ); - } - - if ( hooks && hooks.set ) { - hooks.set( this ); - } else { - Tween.propHooks._default.set( this ); - } - return this; - } -}; - -Tween.prototype.init.prototype = Tween.prototype; - -Tween.propHooks = { - _default: { - get: function( tween ) { - var result; - - // Use a property on the element directly when it is not a DOM element, - // or when there is no matching style property that exists. - if ( tween.elem.nodeType !== 1 || - tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { - return tween.elem[ tween.prop ]; - } - - // Passing an empty string as a 3rd parameter to .css will automatically - // attempt a parseFloat and fallback to a string if the parse fails. - // Simple values such as "10px" are parsed to Float; - // complex values such as "rotate(1rad)" are returned as-is. - result = jQuery.css( tween.elem, tween.prop, "" ); - - // Empty strings, null, undefined and "auto" are converted to 0. - return !result || result === "auto" ? 0 : result; - }, - set: function( tween ) { - - // Use step hook for back compat. - // Use cssHook if its there. - // Use .style if available and use plain properties where available. - if ( jQuery.fx.step[ tween.prop ] ) { - jQuery.fx.step[ tween.prop ]( tween ); - } else if ( tween.elem.nodeType === 1 && ( - jQuery.cssHooks[ tween.prop ] || - tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { - jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); - } else { - tween.elem[ tween.prop ] = tween.now; - } - } - } -}; - -// Support: IE <=9 only -// Panic based approach to setting things on disconnected nodes -Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { - set: function( tween ) { - if ( tween.elem.nodeType && tween.elem.parentNode ) { - tween.elem[ tween.prop ] = tween.now; - } - } -}; - -jQuery.easing = { - linear: function( p ) { - return p; - }, - swing: function( p ) { - return 0.5 - Math.cos( p * Math.PI ) / 2; - }, - _default: "swing" -}; - -jQuery.fx = Tween.prototype.init; - -// Back compat <1.8 extension point -jQuery.fx.step = {}; - - - - -var - fxNow, inProgress, - rfxtypes = /^(?:toggle|show|hide)$/, - rrun = /queueHooks$/; - -function schedule() { - if ( inProgress ) { - if ( document.hidden === false && window.requestAnimationFrame ) { - window.requestAnimationFrame( schedule ); - } else { - window.setTimeout( schedule, jQuery.fx.interval ); - } - - jQuery.fx.tick(); - } -} - -// Animations created synchronously will run synchronously -function createFxNow() { - window.setTimeout( function() { - fxNow = undefined; - } ); - return ( fxNow = Date.now() ); -} - -// Generate parameters to create a standard animation -function genFx( type, includeWidth ) { - var which, - i = 0, - attrs = { height: type }; - - // If we include width, step value is 1 to do all cssExpand values, - // otherwise step value is 2 to skip over Left and Right - includeWidth = includeWidth ? 1 : 0; - for ( ; i < 4; i += 2 - includeWidth ) { - which = cssExpand[ i ]; - attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; - } - - if ( includeWidth ) { - attrs.opacity = attrs.width = type; - } - - return attrs; -} - -function createTween( value, prop, animation ) { - var tween, - collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), - index = 0, - length = collection.length; - for ( ; index < length; index++ ) { - if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { - - // We're done with this property - return tween; - } - } -} - -function defaultPrefilter( elem, props, opts ) { - var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, - isBox = "width" in props || "height" in props, - anim = this, - orig = {}, - style = elem.style, - hidden = elem.nodeType && isHiddenWithinTree( elem ), - dataShow = dataPriv.get( elem, "fxshow" ); - - // Queue-skipping animations hijack the fx hooks - if ( !opts.queue ) { - hooks = jQuery._queueHooks( elem, "fx" ); - if ( hooks.unqueued == null ) { - hooks.unqueued = 0; - oldfire = hooks.empty.fire; - hooks.empty.fire = function() { - if ( !hooks.unqueued ) { - oldfire(); - } - }; - } - hooks.unqueued++; - - anim.always( function() { - - // Ensure the complete handler is called before this completes - anim.always( function() { - hooks.unqueued--; - if ( !jQuery.queue( elem, "fx" ).length ) { - hooks.empty.fire(); - } - } ); - } ); - } - - // Detect show/hide animations - for ( prop in props ) { - value = props[ prop ]; - if ( rfxtypes.test( value ) ) { - delete props[ prop ]; - toggle = toggle || value === "toggle"; - if ( value === ( hidden ? "hide" : "show" ) ) { - - // Pretend to be hidden if this is a "show" and - // there is still data from a stopped show/hide - if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { - hidden = true; - - // Ignore all other no-op show/hide data - } else { - continue; - } - } - orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); - } - } - - // Bail out if this is a no-op like .hide().hide() - propTween = !jQuery.isEmptyObject( props ); - if ( !propTween && jQuery.isEmptyObject( orig ) ) { - return; - } - - // Restrict "overflow" and "display" styles during box animations - if ( isBox && elem.nodeType === 1 ) { - - // Support: IE <=9 - 11, Edge 12 - 15 - // Record all 3 overflow attributes because IE does not infer the shorthand - // from identically-valued overflowX and overflowY and Edge just mirrors - // the overflowX value there. - opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; - - // Identify a display type, preferring old show/hide data over the CSS cascade - restoreDisplay = dataShow && dataShow.display; - if ( restoreDisplay == null ) { - restoreDisplay = dataPriv.get( elem, "display" ); - } - display = jQuery.css( elem, "display" ); - if ( display === "none" ) { - if ( restoreDisplay ) { - display = restoreDisplay; - } else { - - // Get nonempty value(s) by temporarily forcing visibility - showHide( [ elem ], true ); - restoreDisplay = elem.style.display || restoreDisplay; - display = jQuery.css( elem, "display" ); - showHide( [ elem ] ); - } - } - - // Animate inline elements as inline-block - if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { - if ( jQuery.css( elem, "float" ) === "none" ) { - - // Restore the original display value at the end of pure show/hide animations - if ( !propTween ) { - anim.done( function() { - style.display = restoreDisplay; - } ); - if ( restoreDisplay == null ) { - display = style.display; - restoreDisplay = display === "none" ? "" : display; - } - } - style.display = "inline-block"; - } - } - } - - if ( opts.overflow ) { - style.overflow = "hidden"; - anim.always( function() { - style.overflow = opts.overflow[ 0 ]; - style.overflowX = opts.overflow[ 1 ]; - style.overflowY = opts.overflow[ 2 ]; - } ); - } - - // Implement show/hide animations - propTween = false; - for ( prop in orig ) { - - // General show/hide setup for this element animation - if ( !propTween ) { - if ( dataShow ) { - if ( "hidden" in dataShow ) { - hidden = dataShow.hidden; - } - } else { - dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); - } - - // Store hidden/visible for toggle so `.stop().toggle()` "reverses" - if ( toggle ) { - dataShow.hidden = !hidden; - } - - // Show elements before animating them - if ( hidden ) { - showHide( [ elem ], true ); - } - - /* eslint-disable no-loop-func */ - - anim.done( function() { - - /* eslint-enable no-loop-func */ - - // The final step of a "hide" animation is actually hiding the element - if ( !hidden ) { - showHide( [ elem ] ); - } - dataPriv.remove( elem, "fxshow" ); - for ( prop in orig ) { - jQuery.style( elem, prop, orig[ prop ] ); - } - } ); - } - - // Per-property setup - propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); - if ( !( prop in dataShow ) ) { - dataShow[ prop ] = propTween.start; - if ( hidden ) { - propTween.end = propTween.start; - propTween.start = 0; - } - } - } -} - -function propFilter( props, specialEasing ) { - var index, name, easing, value, hooks; - - // camelCase, specialEasing and expand cssHook pass - for ( index in props ) { - name = camelCase( index ); - easing = specialEasing[ name ]; - value = props[ index ]; - if ( Array.isArray( value ) ) { - easing = value[ 1 ]; - value = props[ index ] = value[ 0 ]; - } - - if ( index !== name ) { - props[ name ] = value; - delete props[ index ]; - } - - hooks = jQuery.cssHooks[ name ]; - if ( hooks && "expand" in hooks ) { - value = hooks.expand( value ); - delete props[ name ]; - - // Not quite $.extend, this won't overwrite existing keys. - // Reusing 'index' because we have the correct "name" - for ( index in value ) { - if ( !( index in props ) ) { - props[ index ] = value[ index ]; - specialEasing[ index ] = easing; - } - } - } else { - specialEasing[ name ] = easing; - } - } -} - -function Animation( elem, properties, options ) { - var result, - stopped, - index = 0, - length = Animation.prefilters.length, - deferred = jQuery.Deferred().always( function() { - - // Don't match elem in the :animated selector - delete tick.elem; - } ), - tick = function() { - if ( stopped ) { - return false; - } - var currentTime = fxNow || createFxNow(), - remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), - - // Support: Android 2.3 only - // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) - temp = remaining / animation.duration || 0, - percent = 1 - temp, - index = 0, - length = animation.tweens.length; - - for ( ; index < length; index++ ) { - animation.tweens[ index ].run( percent ); - } - - deferred.notifyWith( elem, [ animation, percent, remaining ] ); - - // If there's more to do, yield - if ( percent < 1 && length ) { - return remaining; - } - - // If this was an empty animation, synthesize a final progress notification - if ( !length ) { - deferred.notifyWith( elem, [ animation, 1, 0 ] ); - } - - // Resolve the animation and report its conclusion - deferred.resolveWith( elem, [ animation ] ); - return false; - }, - animation = deferred.promise( { - elem: elem, - props: jQuery.extend( {}, properties ), - opts: jQuery.extend( true, { - specialEasing: {}, - easing: jQuery.easing._default - }, options ), - originalProperties: properties, - originalOptions: options, - startTime: fxNow || createFxNow(), - duration: options.duration, - tweens: [], - createTween: function( prop, end ) { - var tween = jQuery.Tween( elem, animation.opts, prop, end, - animation.opts.specialEasing[ prop ] || animation.opts.easing ); - animation.tweens.push( tween ); - return tween; - }, - stop: function( gotoEnd ) { - var index = 0, - - // If we are going to the end, we want to run all the tweens - // otherwise we skip this part - length = gotoEnd ? animation.tweens.length : 0; - if ( stopped ) { - return this; - } - stopped = true; - for ( ; index < length; index++ ) { - animation.tweens[ index ].run( 1 ); - } - - // Resolve when we played the last frame; otherwise, reject - if ( gotoEnd ) { - deferred.notifyWith( elem, [ animation, 1, 0 ] ); - deferred.resolveWith( elem, [ animation, gotoEnd ] ); - } else { - deferred.rejectWith( elem, [ animation, gotoEnd ] ); - } - return this; - } - } ), - props = animation.props; - - propFilter( props, animation.opts.specialEasing ); - - for ( ; index < length; index++ ) { - result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); - if ( result ) { - if ( isFunction( result.stop ) ) { - jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = - result.stop.bind( result ); - } - return result; - } - } - - jQuery.map( props, createTween, animation ); - - if ( isFunction( animation.opts.start ) ) { - animation.opts.start.call( elem, animation ); - } - - // Attach callbacks from options - animation - .progress( animation.opts.progress ) - .done( animation.opts.done, animation.opts.complete ) - .fail( animation.opts.fail ) - .always( animation.opts.always ); - - jQuery.fx.timer( - jQuery.extend( tick, { - elem: elem, - anim: animation, - queue: animation.opts.queue - } ) - ); - - return animation; -} - -jQuery.Animation = jQuery.extend( Animation, { - - tweeners: { - "*": [ function( prop, value ) { - var tween = this.createTween( prop, value ); - adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); - return tween; - } ] - }, - - tweener: function( props, callback ) { - if ( isFunction( props ) ) { - callback = props; - props = [ "*" ]; - } else { - props = props.match( rnothtmlwhite ); - } - - var prop, - index = 0, - length = props.length; - - for ( ; index < length; index++ ) { - prop = props[ index ]; - Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; - Animation.tweeners[ prop ].unshift( callback ); - } - }, - - prefilters: [ defaultPrefilter ], - - prefilter: function( callback, prepend ) { - if ( prepend ) { - Animation.prefilters.unshift( callback ); - } else { - Animation.prefilters.push( callback ); - } - } -} ); - -jQuery.speed = function( speed, easing, fn ) { - var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { - complete: fn || !fn && easing || - isFunction( speed ) && speed, - duration: speed, - easing: fn && easing || easing && !isFunction( easing ) && easing - }; - - // Go to the end state if fx are off - if ( jQuery.fx.off ) { - opt.duration = 0; - - } else { - if ( typeof opt.duration !== "number" ) { - if ( opt.duration in jQuery.fx.speeds ) { - opt.duration = jQuery.fx.speeds[ opt.duration ]; - - } else { - opt.duration = jQuery.fx.speeds._default; - } - } - } - - // Normalize opt.queue - true/undefined/null -> "fx" - if ( opt.queue == null || opt.queue === true ) { - opt.queue = "fx"; - } - - // Queueing - opt.old = opt.complete; - - opt.complete = function() { - if ( isFunction( opt.old ) ) { - opt.old.call( this ); - } - - if ( opt.queue ) { - jQuery.dequeue( this, opt.queue ); - } - }; - - return opt; -}; - -jQuery.fn.extend( { - fadeTo: function( speed, to, easing, callback ) { - - // Show any hidden elements after setting opacity to 0 - return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() - - // Animate to the value specified - .end().animate( { opacity: to }, speed, easing, callback ); - }, - animate: function( prop, speed, easing, callback ) { - var empty = jQuery.isEmptyObject( prop ), - optall = jQuery.speed( speed, easing, callback ), - doAnimation = function() { - - // Operate on a copy of prop so per-property easing won't be lost - var anim = Animation( this, jQuery.extend( {}, prop ), optall ); - - // Empty animations, or finishing resolves immediately - if ( empty || dataPriv.get( this, "finish" ) ) { - anim.stop( true ); - } - }; - - doAnimation.finish = doAnimation; - - return empty || optall.queue === false ? - this.each( doAnimation ) : - this.queue( optall.queue, doAnimation ); - }, - stop: function( type, clearQueue, gotoEnd ) { - var stopQueue = function( hooks ) { - var stop = hooks.stop; - delete hooks.stop; - stop( gotoEnd ); - }; - - if ( typeof type !== "string" ) { - gotoEnd = clearQueue; - clearQueue = type; - type = undefined; - } - if ( clearQueue ) { - this.queue( type || "fx", [] ); - } - - return this.each( function() { - var dequeue = true, - index = type != null && type + "queueHooks", - timers = jQuery.timers, - data = dataPriv.get( this ); - - if ( index ) { - if ( data[ index ] && data[ index ].stop ) { - stopQueue( data[ index ] ); - } - } else { - for ( index in data ) { - if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { - stopQueue( data[ index ] ); - } - } - } - - for ( index = timers.length; index--; ) { - if ( timers[ index ].elem === this && - ( type == null || timers[ index ].queue === type ) ) { - - timers[ index ].anim.stop( gotoEnd ); - dequeue = false; - timers.splice( index, 1 ); - } - } - - // Start the next in the queue if the last step wasn't forced. - // Timers currently will call their complete callbacks, which - // will dequeue but only if they were gotoEnd. - if ( dequeue || !gotoEnd ) { - jQuery.dequeue( this, type ); - } - } ); - }, - finish: function( type ) { - if ( type !== false ) { - type = type || "fx"; - } - return this.each( function() { - var index, - data = dataPriv.get( this ), - queue = data[ type + "queue" ], - hooks = data[ type + "queueHooks" ], - timers = jQuery.timers, - length = queue ? queue.length : 0; - - // Enable finishing flag on private data - data.finish = true; - - // Empty the queue first - jQuery.queue( this, type, [] ); - - if ( hooks && hooks.stop ) { - hooks.stop.call( this, true ); - } - - // Look for any active animations, and finish them - for ( index = timers.length; index--; ) { - if ( timers[ index ].elem === this && timers[ index ].queue === type ) { - timers[ index ].anim.stop( true ); - timers.splice( index, 1 ); - } - } - - // Look for any animations in the old queue and finish them - for ( index = 0; index < length; index++ ) { - if ( queue[ index ] && queue[ index ].finish ) { - queue[ index ].finish.call( this ); - } - } - - // Turn off finishing flag - delete data.finish; - } ); - } -} ); - -jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { - var cssFn = jQuery.fn[ name ]; - jQuery.fn[ name ] = function( speed, easing, callback ) { - return speed == null || typeof speed === "boolean" ? - cssFn.apply( this, arguments ) : - this.animate( genFx( name, true ), speed, easing, callback ); - }; -} ); - -// Generate shortcuts for custom animations -jQuery.each( { - slideDown: genFx( "show" ), - slideUp: genFx( "hide" ), - slideToggle: genFx( "toggle" ), - fadeIn: { opacity: "show" }, - fadeOut: { opacity: "hide" }, - fadeToggle: { opacity: "toggle" } -}, function( name, props ) { - jQuery.fn[ name ] = function( speed, easing, callback ) { - return this.animate( props, speed, easing, callback ); - }; -} ); - -jQuery.timers = []; -jQuery.fx.tick = function() { - var timer, - i = 0, - timers = jQuery.timers; - - fxNow = Date.now(); - - for ( ; i < timers.length; i++ ) { - timer = timers[ i ]; - - // Run the timer and safely remove it when done (allowing for external removal) - if ( !timer() && timers[ i ] === timer ) { - timers.splice( i--, 1 ); - } - } - - if ( !timers.length ) { - jQuery.fx.stop(); - } - fxNow = undefined; -}; - -jQuery.fx.timer = function( timer ) { - jQuery.timers.push( timer ); - jQuery.fx.start(); -}; - -jQuery.fx.interval = 13; -jQuery.fx.start = function() { - if ( inProgress ) { - return; - } - - inProgress = true; - schedule(); -}; - -jQuery.fx.stop = function() { - inProgress = null; -}; - -jQuery.fx.speeds = { - slow: 600, - fast: 200, - - // Default speed - _default: 400 -}; - - -// Based off of the plugin by Clint Helfers, with permission. -// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ -jQuery.fn.delay = function( time, type ) { - time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; - type = type || "fx"; - - return this.queue( type, function( next, hooks ) { - var timeout = window.setTimeout( next, time ); - hooks.stop = function() { - window.clearTimeout( timeout ); - }; - } ); -}; - - -( function() { - var input = document.createElement( "input" ), - select = document.createElement( "select" ), - opt = select.appendChild( document.createElement( "option" ) ); - - input.type = "checkbox"; - - // Support: Android <=4.3 only - // Default value for a checkbox should be "on" - support.checkOn = input.value !== ""; - - // Support: IE <=11 only - // Must access selectedIndex to make default options select - support.optSelected = opt.selected; - - // Support: IE <=11 only - // An input loses its value after becoming a radio - input = document.createElement( "input" ); - input.value = "t"; - input.type = "radio"; - support.radioValue = input.value === "t"; -} )(); - - -var boolHook, - attrHandle = jQuery.expr.attrHandle; - -jQuery.fn.extend( { - attr: function( name, value ) { - return access( this, jQuery.attr, name, value, arguments.length > 1 ); - }, - - removeAttr: function( name ) { - return this.each( function() { - jQuery.removeAttr( this, name ); - } ); - } -} ); - -jQuery.extend( { - attr: function( elem, name, value ) { - var ret, hooks, - nType = elem.nodeType; - - // Don't get/set attributes on text, comment and attribute nodes - if ( nType === 3 || nType === 8 || nType === 2 ) { - return; - } - - // Fallback to prop when attributes are not supported - if ( typeof elem.getAttribute === "undefined" ) { - return jQuery.prop( elem, name, value ); - } - - // Attribute hooks are determined by the lowercase version - // Grab necessary hook if one is defined - if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { - hooks = jQuery.attrHooks[ name.toLowerCase() ] || - ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); - } - - if ( value !== undefined ) { - if ( value === null ) { - jQuery.removeAttr( elem, name ); - return; - } - - if ( hooks && "set" in hooks && - ( ret = hooks.set( elem, value, name ) ) !== undefined ) { - return ret; - } - - elem.setAttribute( name, value + "" ); - return value; - } - - if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { - return ret; - } - - ret = jQuery.find.attr( elem, name ); - - // Non-existent attributes return null, we normalize to undefined - return ret == null ? undefined : ret; - }, - - attrHooks: { - type: { - set: function( elem, value ) { - if ( !support.radioValue && value === "radio" && - nodeName( elem, "input" ) ) { - var val = elem.value; - elem.setAttribute( "type", value ); - if ( val ) { - elem.value = val; - } - return value; - } - } - } - }, - - removeAttr: function( elem, value ) { - var name, - i = 0, - - // Attribute names can contain non-HTML whitespace characters - // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 - attrNames = value && value.match( rnothtmlwhite ); - - if ( attrNames && elem.nodeType === 1 ) { - while ( ( name = attrNames[ i++ ] ) ) { - elem.removeAttribute( name ); - } - } - } -} ); - -// Hooks for boolean attributes -boolHook = { - set: function( elem, value, name ) { - if ( value === false ) { - - // Remove boolean attributes when set to false - jQuery.removeAttr( elem, name ); - } else { - elem.setAttribute( name, name ); - } - return name; - } -}; - -jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { - var getter = attrHandle[ name ] || jQuery.find.attr; - - attrHandle[ name ] = function( elem, name, isXML ) { - var ret, handle, - lowercaseName = name.toLowerCase(); - - if ( !isXML ) { - - // Avoid an infinite loop by temporarily removing this function from the getter - handle = attrHandle[ lowercaseName ]; - attrHandle[ lowercaseName ] = ret; - ret = getter( elem, name, isXML ) != null ? - lowercaseName : - null; - attrHandle[ lowercaseName ] = handle; - } - return ret; - }; -} ); - - - - -var rfocusable = /^(?:input|select|textarea|button)$/i, - rclickable = /^(?:a|area)$/i; - -jQuery.fn.extend( { - prop: function( name, value ) { - return access( this, jQuery.prop, name, value, arguments.length > 1 ); - }, - - removeProp: function( name ) { - return this.each( function() { - delete this[ jQuery.propFix[ name ] || name ]; - } ); - } -} ); - -jQuery.extend( { - prop: function( elem, name, value ) { - var ret, hooks, - nType = elem.nodeType; - - // Don't get/set properties on text, comment and attribute nodes - if ( nType === 3 || nType === 8 || nType === 2 ) { - return; - } - - if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { - - // Fix name and attach hooks - name = jQuery.propFix[ name ] || name; - hooks = jQuery.propHooks[ name ]; - } - - if ( value !== undefined ) { - if ( hooks && "set" in hooks && - ( ret = hooks.set( elem, value, name ) ) !== undefined ) { - return ret; - } - - return ( elem[ name ] = value ); - } - - if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { - return ret; - } - - return elem[ name ]; - }, - - propHooks: { - tabIndex: { - get: function( elem ) { - - // Support: IE <=9 - 11 only - // elem.tabIndex doesn't always return the - // correct value when it hasn't been explicitly set - // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ - // Use proper attribute retrieval(#12072) - var tabindex = jQuery.find.attr( elem, "tabindex" ); - - if ( tabindex ) { - return parseInt( tabindex, 10 ); - } - - if ( - rfocusable.test( elem.nodeName ) || - rclickable.test( elem.nodeName ) && - elem.href - ) { - return 0; - } - - return -1; - } - } - }, - - propFix: { - "for": "htmlFor", - "class": "className" - } -} ); - -// Support: IE <=11 only -// Accessing the selectedIndex property -// forces the browser to respect setting selected -// on the option -// The getter ensures a default option is selected -// when in an optgroup -// eslint rule "no-unused-expressions" is disabled for this code -// since it considers such accessions noop -if ( !support.optSelected ) { - jQuery.propHooks.selected = { - get: function( elem ) { - - /* eslint no-unused-expressions: "off" */ - - var parent = elem.parentNode; - if ( parent && parent.parentNode ) { - parent.parentNode.selectedIndex; - } - return null; - }, - set: function( elem ) { - - /* eslint no-unused-expressions: "off" */ - - var parent = elem.parentNode; - if ( parent ) { - parent.selectedIndex; - - if ( parent.parentNode ) { - parent.parentNode.selectedIndex; - } - } - } - }; -} - -jQuery.each( [ - "tabIndex", - "readOnly", - "maxLength", - "cellSpacing", - "cellPadding", - "rowSpan", - "colSpan", - "useMap", - "frameBorder", - "contentEditable" -], function() { - jQuery.propFix[ this.toLowerCase() ] = this; -} ); - - - - - // Strip and collapse whitespace according to HTML spec - // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace - function stripAndCollapse( value ) { - var tokens = value.match( rnothtmlwhite ) || []; - return tokens.join( " " ); - } - - -function getClass( elem ) { - return elem.getAttribute && elem.getAttribute( "class" ) || ""; -} - -function classesToArray( value ) { - if ( Array.isArray( value ) ) { - return value; - } - if ( typeof value === "string" ) { - return value.match( rnothtmlwhite ) || []; - } - return []; -} - -jQuery.fn.extend( { - addClass: function( value ) { - var classes, elem, cur, curValue, clazz, j, finalValue, - i = 0; - - if ( isFunction( value ) ) { - return this.each( function( j ) { - jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); - } ); - } - - classes = classesToArray( value ); - - if ( classes.length ) { - while ( ( elem = this[ i++ ] ) ) { - curValue = getClass( elem ); - cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); - - if ( cur ) { - j = 0; - while ( ( clazz = classes[ j++ ] ) ) { - if ( cur.indexOf( " " + clazz + " " ) < 0 ) { - cur += clazz + " "; - } - } - - // Only assign if different to avoid unneeded rendering. - finalValue = stripAndCollapse( cur ); - if ( curValue !== finalValue ) { - elem.setAttribute( "class", finalValue ); - } - } - } - } - - return this; - }, - - removeClass: function( value ) { - var classes, elem, cur, curValue, clazz, j, finalValue, - i = 0; - - if ( isFunction( value ) ) { - return this.each( function( j ) { - jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); - } ); - } - - if ( !arguments.length ) { - return this.attr( "class", "" ); - } - - classes = classesToArray( value ); - - if ( classes.length ) { - while ( ( elem = this[ i++ ] ) ) { - curValue = getClass( elem ); - - // This expression is here for better compressibility (see addClass) - cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); - - if ( cur ) { - j = 0; - while ( ( clazz = classes[ j++ ] ) ) { - - // Remove *all* instances - while ( cur.indexOf( " " + clazz + " " ) > -1 ) { - cur = cur.replace( " " + clazz + " ", " " ); - } - } - - // Only assign if different to avoid unneeded rendering. - finalValue = stripAndCollapse( cur ); - if ( curValue !== finalValue ) { - elem.setAttribute( "class", finalValue ); - } - } - } - } - - return this; - }, - - toggleClass: function( value, stateVal ) { - var type = typeof value, - isValidValue = type === "string" || Array.isArray( value ); - - if ( typeof stateVal === "boolean" && isValidValue ) { - return stateVal ? this.addClass( value ) : this.removeClass( value ); - } - - if ( isFunction( value ) ) { - return this.each( function( i ) { - jQuery( this ).toggleClass( - value.call( this, i, getClass( this ), stateVal ), - stateVal - ); - } ); - } - - return this.each( function() { - var className, i, self, classNames; - - if ( isValidValue ) { - - // Toggle individual class names - i = 0; - self = jQuery( this ); - classNames = classesToArray( value ); - - while ( ( className = classNames[ i++ ] ) ) { - - // Check each className given, space separated list - if ( self.hasClass( className ) ) { - self.removeClass( className ); - } else { - self.addClass( className ); - } - } - - // Toggle whole class name - } else if ( value === undefined || type === "boolean" ) { - className = getClass( this ); - if ( className ) { - - // Store className if set - dataPriv.set( this, "__className__", className ); - } - - // If the element has a class name or if we're passed `false`, - // then remove the whole classname (if there was one, the above saved it). - // Otherwise bring back whatever was previously saved (if anything), - // falling back to the empty string if nothing was stored. - if ( this.setAttribute ) { - this.setAttribute( "class", - className || value === false ? - "" : - dataPriv.get( this, "__className__" ) || "" - ); - } - } - } ); - }, - - hasClass: function( selector ) { - var className, elem, - i = 0; - - className = " " + selector + " "; - while ( ( elem = this[ i++ ] ) ) { - if ( elem.nodeType === 1 && - ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { - return true; - } - } - - return false; - } -} ); - - - - -var rreturn = /\r/g; - -jQuery.fn.extend( { - val: function( value ) { - var hooks, ret, valueIsFunction, - elem = this[ 0 ]; - - if ( !arguments.length ) { - if ( elem ) { - hooks = jQuery.valHooks[ elem.type ] || - jQuery.valHooks[ elem.nodeName.toLowerCase() ]; - - if ( hooks && - "get" in hooks && - ( ret = hooks.get( elem, "value" ) ) !== undefined - ) { - return ret; - } - - ret = elem.value; - - // Handle most common string cases - if ( typeof ret === "string" ) { - return ret.replace( rreturn, "" ); - } - - // Handle cases where value is null/undef or number - return ret == null ? "" : ret; - } - - return; - } - - valueIsFunction = isFunction( value ); - - return this.each( function( i ) { - var val; - - if ( this.nodeType !== 1 ) { - return; - } - - if ( valueIsFunction ) { - val = value.call( this, i, jQuery( this ).val() ); - } else { - val = value; - } - - // Treat null/undefined as ""; convert numbers to string - if ( val == null ) { - val = ""; - - } else if ( typeof val === "number" ) { - val += ""; - - } else if ( Array.isArray( val ) ) { - val = jQuery.map( val, function( value ) { - return value == null ? "" : value + ""; - } ); - } - - hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; - - // If set returns undefined, fall back to normal setting - if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { - this.value = val; - } - } ); - } -} ); - -jQuery.extend( { - valHooks: { - option: { - get: function( elem ) { - - var val = jQuery.find.attr( elem, "value" ); - return val != null ? - val : - - // Support: IE <=10 - 11 only - // option.text throws exceptions (#14686, #14858) - // Strip and collapse whitespace - // https://html.spec.whatwg.org/#strip-and-collapse-whitespace - stripAndCollapse( jQuery.text( elem ) ); - } - }, - select: { - get: function( elem ) { - var value, option, i, - options = elem.options, - index = elem.selectedIndex, - one = elem.type === "select-one", - values = one ? null : [], - max = one ? index + 1 : options.length; - - if ( index < 0 ) { - i = max; - - } else { - i = one ? index : 0; - } - - // Loop through all the selected options - for ( ; i < max; i++ ) { - option = options[ i ]; - - // Support: IE <=9 only - // IE8-9 doesn't update selected after form reset (#2551) - if ( ( option.selected || i === index ) && - - // Don't return options that are disabled or in a disabled optgroup - !option.disabled && - ( !option.parentNode.disabled || - !nodeName( option.parentNode, "optgroup" ) ) ) { - - // Get the specific value for the option - value = jQuery( option ).val(); - - // We don't need an array for one selects - if ( one ) { - return value; - } - - // Multi-Selects return an array - values.push( value ); - } - } - - return values; - }, - - set: function( elem, value ) { - var optionSet, option, - options = elem.options, - values = jQuery.makeArray( value ), - i = options.length; - - while ( i-- ) { - option = options[ i ]; - - /* eslint-disable no-cond-assign */ - - if ( option.selected = - jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 - ) { - optionSet = true; - } - - /* eslint-enable no-cond-assign */ - } - - // Force browsers to behave consistently when non-matching value is set - if ( !optionSet ) { - elem.selectedIndex = -1; - } - return values; - } - } - } -} ); - -// Radios and checkboxes getter/setter -jQuery.each( [ "radio", "checkbox" ], function() { - jQuery.valHooks[ this ] = { - set: function( elem, value ) { - if ( Array.isArray( value ) ) { - return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); - } - } - }; - if ( !support.checkOn ) { - jQuery.valHooks[ this ].get = function( elem ) { - return elem.getAttribute( "value" ) === null ? "on" : elem.value; - }; - } -} ); - - - - -// Return jQuery for attributes-only inclusion - - -support.focusin = "onfocusin" in window; - - -var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, - stopPropagationCallback = function( e ) { - e.stopPropagation(); - }; - -jQuery.extend( jQuery.event, { - - trigger: function( event, data, elem, onlyHandlers ) { - - var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, - eventPath = [ elem || document ], - type = hasOwn.call( event, "type" ) ? event.type : event, - namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; - - cur = lastElement = tmp = elem = elem || document; - - // Don't do events on text and comment nodes - if ( elem.nodeType === 3 || elem.nodeType === 8 ) { - return; - } - - // focus/blur morphs to focusin/out; ensure we're not firing them right now - if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { - return; - } - - if ( type.indexOf( "." ) > -1 ) { - - // Namespaced trigger; create a regexp to match event type in handle() - namespaces = type.split( "." ); - type = namespaces.shift(); - namespaces.sort(); - } - ontype = type.indexOf( ":" ) < 0 && "on" + type; - - // Caller can pass in a jQuery.Event object, Object, or just an event type string - event = event[ jQuery.expando ] ? - event : - new jQuery.Event( type, typeof event === "object" && event ); - - // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) - event.isTrigger = onlyHandlers ? 2 : 3; - event.namespace = namespaces.join( "." ); - event.rnamespace = event.namespace ? - new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : - null; - - // Clean up the event in case it is being reused - event.result = undefined; - if ( !event.target ) { - event.target = elem; - } - - // Clone any incoming data and prepend the event, creating the handler arg list - data = data == null ? - [ event ] : - jQuery.makeArray( data, [ event ] ); - - // Allow special events to draw outside the lines - special = jQuery.event.special[ type ] || {}; - if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { - return; - } - - // Determine event propagation path in advance, per W3C events spec (#9951) - // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) - if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { - - bubbleType = special.delegateType || type; - if ( !rfocusMorph.test( bubbleType + type ) ) { - cur = cur.parentNode; - } - for ( ; cur; cur = cur.parentNode ) { - eventPath.push( cur ); - tmp = cur; - } - - // Only add window if we got to document (e.g., not plain obj or detached DOM) - if ( tmp === ( elem.ownerDocument || document ) ) { - eventPath.push( tmp.defaultView || tmp.parentWindow || window ); - } - } - - // Fire handlers on the event path - i = 0; - while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { - lastElement = cur; - event.type = i > 1 ? - bubbleType : - special.bindType || type; - - // jQuery handler - handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] && - dataPriv.get( cur, "handle" ); - if ( handle ) { - handle.apply( cur, data ); - } - - // Native handler - handle = ontype && cur[ ontype ]; - if ( handle && handle.apply && acceptData( cur ) ) { - event.result = handle.apply( cur, data ); - if ( event.result === false ) { - event.preventDefault(); - } - } - } - event.type = type; - - // If nobody prevented the default action, do it now - if ( !onlyHandlers && !event.isDefaultPrevented() ) { - - if ( ( !special._default || - special._default.apply( eventPath.pop(), data ) === false ) && - acceptData( elem ) ) { - - // Call a native DOM method on the target with the same name as the event. - // Don't do default actions on window, that's where global variables be (#6170) - if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { - - // Don't re-trigger an onFOO event when we call its FOO() method - tmp = elem[ ontype ]; - - if ( tmp ) { - elem[ ontype ] = null; - } - - // Prevent re-triggering of the same event, since we already bubbled it above - jQuery.event.triggered = type; - - if ( event.isPropagationStopped() ) { - lastElement.addEventListener( type, stopPropagationCallback ); - } - - elem[ type ](); - - if ( event.isPropagationStopped() ) { - lastElement.removeEventListener( type, stopPropagationCallback ); - } - - jQuery.event.triggered = undefined; - - if ( tmp ) { - elem[ ontype ] = tmp; - } - } - } - } - - return event.result; - }, - - // Piggyback on a donor event to simulate a different one - // Used only for `focus(in | out)` events - simulate: function( type, elem, event ) { - var e = jQuery.extend( - new jQuery.Event(), - event, - { - type: type, - isSimulated: true - } - ); - - jQuery.event.trigger( e, null, elem ); - } - -} ); - -jQuery.fn.extend( { - - trigger: function( type, data ) { - return this.each( function() { - jQuery.event.trigger( type, data, this ); - } ); - }, - triggerHandler: function( type, data ) { - var elem = this[ 0 ]; - if ( elem ) { - return jQuery.event.trigger( type, data, elem, true ); - } - } -} ); - - -// Support: Firefox <=44 -// Firefox doesn't have focus(in | out) events -// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 -// -// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 -// focus(in | out) events fire after focus & blur events, -// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order -// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 -if ( !support.focusin ) { - jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { - - // Attach a single capturing handler on the document while someone wants focusin/focusout - var handler = function( event ) { - jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); - }; - - jQuery.event.special[ fix ] = { - setup: function() { - - // Handle: regular nodes (via `this.ownerDocument`), window - // (via `this.document`) & document (via `this`). - var doc = this.ownerDocument || this.document || this, - attaches = dataPriv.access( doc, fix ); - - if ( !attaches ) { - doc.addEventListener( orig, handler, true ); - } - dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); - }, - teardown: function() { - var doc = this.ownerDocument || this.document || this, - attaches = dataPriv.access( doc, fix ) - 1; - - if ( !attaches ) { - doc.removeEventListener( orig, handler, true ); - dataPriv.remove( doc, fix ); - - } else { - dataPriv.access( doc, fix, attaches ); - } - } - }; - } ); -} -var location = window.location; - -var nonce = { guid: Date.now() }; - -var rquery = ( /\?/ ); - - - -// Cross-browser xml parsing -jQuery.parseXML = function( data ) { - var xml, parserErrorElem; - if ( !data || typeof data !== "string" ) { - return null; - } - - // Support: IE 9 - 11 only - // IE throws on parseFromString with invalid input. - try { - xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); - } catch ( e ) {} - - parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ]; - if ( !xml || parserErrorElem ) { - jQuery.error( "Invalid XML: " + ( - parserErrorElem ? - jQuery.map( parserErrorElem.childNodes, function( el ) { - return el.textContent; - } ).join( "\n" ) : - data - ) ); - } - return xml; -}; - - -var - rbracket = /\[\]$/, - rCRLF = /\r?\n/g, - rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, - rsubmittable = /^(?:input|select|textarea|keygen)/i; - -function buildParams( prefix, obj, traditional, add ) { - var name; - - if ( Array.isArray( obj ) ) { - - // Serialize array item. - jQuery.each( obj, function( i, v ) { - if ( traditional || rbracket.test( prefix ) ) { - - // Treat each array item as a scalar. - add( prefix, v ); - - } else { - - // Item is non-scalar (array or object), encode its numeric index. - buildParams( - prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", - v, - traditional, - add - ); - } - } ); - - } else if ( !traditional && toType( obj ) === "object" ) { - - // Serialize object item. - for ( name in obj ) { - buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); - } - - } else { - - // Serialize scalar item. - add( prefix, obj ); - } -} - -// Serialize an array of form elements or a set of -// key/values into a query string -jQuery.param = function( a, traditional ) { - var prefix, - s = [], - add = function( key, valueOrFunction ) { - - // If value is a function, invoke it and use its return value - var value = isFunction( valueOrFunction ) ? - valueOrFunction() : - valueOrFunction; - - s[ s.length ] = encodeURIComponent( key ) + "=" + - encodeURIComponent( value == null ? "" : value ); - }; - - if ( a == null ) { - return ""; - } - - // If an array was passed in, assume that it is an array of form elements. - if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { - - // Serialize the form elements - jQuery.each( a, function() { - add( this.name, this.value ); - } ); - - } else { - - // If traditional, encode the "old" way (the way 1.3.2 or older - // did it), otherwise encode params recursively. - for ( prefix in a ) { - buildParams( prefix, a[ prefix ], traditional, add ); - } - } - - // Return the resulting serialization - return s.join( "&" ); -}; - -jQuery.fn.extend( { - serialize: function() { - return jQuery.param( this.serializeArray() ); - }, - serializeArray: function() { - return this.map( function() { - - // Can add propHook for "elements" to filter or add form elements - var elements = jQuery.prop( this, "elements" ); - return elements ? jQuery.makeArray( elements ) : this; - } ).filter( function() { - var type = this.type; - - // Use .is( ":disabled" ) so that fieldset[disabled] works - return this.name && !jQuery( this ).is( ":disabled" ) && - rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && - ( this.checked || !rcheckableType.test( type ) ); - } ).map( function( _i, elem ) { - var val = jQuery( this ).val(); - - if ( val == null ) { - return null; - } - - if ( Array.isArray( val ) ) { - return jQuery.map( val, function( val ) { - return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; - } ); - } - - return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; - } ).get(); - } -} ); - - -var - r20 = /%20/g, - rhash = /#.*$/, - rantiCache = /([?&])_=[^&]*/, - rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, - - // #7653, #8125, #8152: local protocol detection - rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, - rnoContent = /^(?:GET|HEAD)$/, - rprotocol = /^\/\//, - - /* Prefilters - * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) - * 2) These are called: - * - BEFORE asking for a transport - * - AFTER param serialization (s.data is a string if s.processData is true) - * 3) key is the dataType - * 4) the catchall symbol "*" can be used - * 5) execution will start with transport dataType and THEN continue down to "*" if needed - */ - prefilters = {}, - - /* Transports bindings - * 1) key is the dataType - * 2) the catchall symbol "*" can be used - * 3) selection will start with transport dataType and THEN go to "*" if needed - */ - transports = {}, - - // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression - allTypes = "*/".concat( "*" ), - - // Anchor tag for parsing the document origin - originAnchor = document.createElement( "a" ); - -originAnchor.href = location.href; - -// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport -function addToPrefiltersOrTransports( structure ) { - - // dataTypeExpression is optional and defaults to "*" - return function( dataTypeExpression, func ) { - - if ( typeof dataTypeExpression !== "string" ) { - func = dataTypeExpression; - dataTypeExpression = "*"; - } - - var dataType, - i = 0, - dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; - - if ( isFunction( func ) ) { - - // For each dataType in the dataTypeExpression - while ( ( dataType = dataTypes[ i++ ] ) ) { - - // Prepend if requested - if ( dataType[ 0 ] === "+" ) { - dataType = dataType.slice( 1 ) || "*"; - ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); - - // Otherwise append - } else { - ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); - } - } - } - }; -} - -// Base inspection function for prefilters and transports -function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { - - var inspected = {}, - seekingTransport = ( structure === transports ); - - function inspect( dataType ) { - var selected; - inspected[ dataType ] = true; - jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { - var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); - if ( typeof dataTypeOrTransport === "string" && - !seekingTransport && !inspected[ dataTypeOrTransport ] ) { - - options.dataTypes.unshift( dataTypeOrTransport ); - inspect( dataTypeOrTransport ); - return false; - } else if ( seekingTransport ) { - return !( selected = dataTypeOrTransport ); - } - } ); - return selected; - } - - return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); -} - -// A special extend for ajax options -// that takes "flat" options (not to be deep extended) -// Fixes #9887 -function ajaxExtend( target, src ) { - var key, deep, - flatOptions = jQuery.ajaxSettings.flatOptions || {}; - - for ( key in src ) { - if ( src[ key ] !== undefined ) { - ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; - } - } - if ( deep ) { - jQuery.extend( true, target, deep ); - } - - return target; -} - -/* Handles responses to an ajax request: - * - finds the right dataType (mediates between content-type and expected dataType) - * - returns the corresponding response - */ -function ajaxHandleResponses( s, jqXHR, responses ) { - - var ct, type, finalDataType, firstDataType, - contents = s.contents, - dataTypes = s.dataTypes; - - // Remove auto dataType and get content-type in the process - while ( dataTypes[ 0 ] === "*" ) { - dataTypes.shift(); - if ( ct === undefined ) { - ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); - } - } - - // Check if we're dealing with a known content-type - if ( ct ) { - for ( type in contents ) { - if ( contents[ type ] && contents[ type ].test( ct ) ) { - dataTypes.unshift( type ); - break; - } - } - } - - // Check to see if we have a response for the expected dataType - if ( dataTypes[ 0 ] in responses ) { - finalDataType = dataTypes[ 0 ]; - } else { - - // Try convertible dataTypes - for ( type in responses ) { - if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { - finalDataType = type; - break; - } - if ( !firstDataType ) { - firstDataType = type; - } - } - - // Or just use first one - finalDataType = finalDataType || firstDataType; - } - - // If we found a dataType - // We add the dataType to the list if needed - // and return the corresponding response - if ( finalDataType ) { - if ( finalDataType !== dataTypes[ 0 ] ) { - dataTypes.unshift( finalDataType ); - } - return responses[ finalDataType ]; - } -} - -/* Chain conversions given the request and the original response - * Also sets the responseXXX fields on the jqXHR instance - */ -function ajaxConvert( s, response, jqXHR, isSuccess ) { - var conv2, current, conv, tmp, prev, - converters = {}, - - // Work with a copy of dataTypes in case we need to modify it for conversion - dataTypes = s.dataTypes.slice(); - - // Create converters map with lowercased keys - if ( dataTypes[ 1 ] ) { - for ( conv in s.converters ) { - converters[ conv.toLowerCase() ] = s.converters[ conv ]; - } - } - - current = dataTypes.shift(); - - // Convert to each sequential dataType - while ( current ) { - - if ( s.responseFields[ current ] ) { - jqXHR[ s.responseFields[ current ] ] = response; - } - - // Apply the dataFilter if provided - if ( !prev && isSuccess && s.dataFilter ) { - response = s.dataFilter( response, s.dataType ); - } - - prev = current; - current = dataTypes.shift(); - - if ( current ) { - - // There's only work to do if current dataType is non-auto - if ( current === "*" ) { - - current = prev; - - // Convert response if prev dataType is non-auto and differs from current - } else if ( prev !== "*" && prev !== current ) { - - // Seek a direct converter - conv = converters[ prev + " " + current ] || converters[ "* " + current ]; - - // If none found, seek a pair - if ( !conv ) { - for ( conv2 in converters ) { - - // If conv2 outputs current - tmp = conv2.split( " " ); - if ( tmp[ 1 ] === current ) { - - // If prev can be converted to accepted input - conv = converters[ prev + " " + tmp[ 0 ] ] || - converters[ "* " + tmp[ 0 ] ]; - if ( conv ) { - - // Condense equivalence converters - if ( conv === true ) { - conv = converters[ conv2 ]; - - // Otherwise, insert the intermediate dataType - } else if ( converters[ conv2 ] !== true ) { - current = tmp[ 0 ]; - dataTypes.unshift( tmp[ 1 ] ); - } - break; - } - } - } - } - - // Apply converter (if not an equivalence) - if ( conv !== true ) { - - // Unless errors are allowed to bubble, catch and return them - if ( conv && s.throws ) { - response = conv( response ); - } else { - try { - response = conv( response ); - } catch ( e ) { - return { - state: "parsererror", - error: conv ? e : "No conversion from " + prev + " to " + current - }; - } - } - } - } - } - } - - return { state: "success", data: response }; -} - -jQuery.extend( { - - // Counter for holding the number of active queries - active: 0, - - // Last-Modified header cache for next request - lastModified: {}, - etag: {}, - - ajaxSettings: { - url: location.href, - type: "GET", - isLocal: rlocalProtocol.test( location.protocol ), - global: true, - processData: true, - async: true, - contentType: "application/x-www-form-urlencoded; charset=UTF-8", - - /* - timeout: 0, - data: null, - dataType: null, - username: null, - password: null, - cache: null, - throws: false, - traditional: false, - headers: {}, - */ - - accepts: { - "*": allTypes, - text: "text/plain", - html: "text/html", - xml: "application/xml, text/xml", - json: "application/json, text/javascript" - }, - - contents: { - xml: /\bxml\b/, - html: /\bhtml/, - json: /\bjson\b/ - }, - - responseFields: { - xml: "responseXML", - text: "responseText", - json: "responseJSON" - }, - - // Data converters - // Keys separate source (or catchall "*") and destination types with a single space - converters: { - - // Convert anything to text - "* text": String, - - // Text to html (true = no transformation) - "text html": true, - - // Evaluate text as a json expression - "text json": JSON.parse, - - // Parse text as xml - "text xml": jQuery.parseXML - }, - - // For options that shouldn't be deep extended: - // you can add your own custom options here if - // and when you create one that shouldn't be - // deep extended (see ajaxExtend) - flatOptions: { - url: true, - context: true - } - }, - - // Creates a full fledged settings object into target - // with both ajaxSettings and settings fields. - // If target is omitted, writes into ajaxSettings. - ajaxSetup: function( target, settings ) { - return settings ? - - // Building a settings object - ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : - - // Extending ajaxSettings - ajaxExtend( jQuery.ajaxSettings, target ); - }, - - ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), - ajaxTransport: addToPrefiltersOrTransports( transports ), - - // Main method - ajax: function( url, options ) { - - // If url is an object, simulate pre-1.5 signature - if ( typeof url === "object" ) { - options = url; - url = undefined; - } - - // Force options to be an object - options = options || {}; - - var transport, - - // URL without anti-cache param - cacheURL, - - // Response headers - responseHeadersString, - responseHeaders, - - // timeout handle - timeoutTimer, - - // Url cleanup var - urlAnchor, - - // Request state (becomes false upon send and true upon completion) - completed, - - // To know if global events are to be dispatched - fireGlobals, - - // Loop variable - i, - - // uncached part of the url - uncached, - - // Create the final options object - s = jQuery.ajaxSetup( {}, options ), - - // Callbacks context - callbackContext = s.context || s, - - // Context for global events is callbackContext if it is a DOM node or jQuery collection - globalEventContext = s.context && - ( callbackContext.nodeType || callbackContext.jquery ) ? - jQuery( callbackContext ) : - jQuery.event, - - // Deferreds - deferred = jQuery.Deferred(), - completeDeferred = jQuery.Callbacks( "once memory" ), - - // Status-dependent callbacks - statusCode = s.statusCode || {}, - - // Headers (they are sent all at once) - requestHeaders = {}, - requestHeadersNames = {}, - - // Default abort message - strAbort = "canceled", - - // Fake xhr - jqXHR = { - readyState: 0, - - // Builds headers hashtable if needed - getResponseHeader: function( key ) { - var match; - if ( completed ) { - if ( !responseHeaders ) { - responseHeaders = {}; - while ( ( match = rheaders.exec( responseHeadersString ) ) ) { - responseHeaders[ match[ 1 ].toLowerCase() + " " ] = - ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) - .concat( match[ 2 ] ); - } - } - match = responseHeaders[ key.toLowerCase() + " " ]; - } - return match == null ? null : match.join( ", " ); - }, - - // Raw string - getAllResponseHeaders: function() { - return completed ? responseHeadersString : null; - }, - - // Caches the header - setRequestHeader: function( name, value ) { - if ( completed == null ) { - name = requestHeadersNames[ name.toLowerCase() ] = - requestHeadersNames[ name.toLowerCase() ] || name; - requestHeaders[ name ] = value; - } - return this; - }, - - // Overrides response content-type header - overrideMimeType: function( type ) { - if ( completed == null ) { - s.mimeType = type; - } - return this; - }, - - // Status-dependent callbacks - statusCode: function( map ) { - var code; - if ( map ) { - if ( completed ) { - - // Execute the appropriate callbacks - jqXHR.always( map[ jqXHR.status ] ); - } else { - - // Lazy-add the new callbacks in a way that preserves old ones - for ( code in map ) { - statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; - } - } - } - return this; - }, - - // Cancel the request - abort: function( statusText ) { - var finalText = statusText || strAbort; - if ( transport ) { - transport.abort( finalText ); - } - done( 0, finalText ); - return this; - } - }; - - // Attach deferreds - deferred.promise( jqXHR ); - - // Add protocol if not provided (prefilters might expect it) - // Handle falsy url in the settings object (#10093: consistency with old signature) - // We also use the url parameter if available - s.url = ( ( url || s.url || location.href ) + "" ) - .replace( rprotocol, location.protocol + "//" ); - - // Alias method option to type as per ticket #12004 - s.type = options.method || options.type || s.method || s.type; - - // Extract dataTypes list - s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; - - // A cross-domain request is in order when the origin doesn't match the current origin. - if ( s.crossDomain == null ) { - urlAnchor = document.createElement( "a" ); - - // Support: IE <=8 - 11, Edge 12 - 15 - // IE throws exception on accessing the href property if url is malformed, - // e.g. http://example.com:80x/ - try { - urlAnchor.href = s.url; - - // Support: IE <=8 - 11 only - // Anchor's host property isn't correctly set when s.url is relative - urlAnchor.href = urlAnchor.href; - s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== - urlAnchor.protocol + "//" + urlAnchor.host; - } catch ( e ) { - - // If there is an error parsing the URL, assume it is crossDomain, - // it can be rejected by the transport if it is invalid - s.crossDomain = true; - } - } - - // Convert data if not already a string - if ( s.data && s.processData && typeof s.data !== "string" ) { - s.data = jQuery.param( s.data, s.traditional ); - } - - // Apply prefilters - inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); - - // If request was aborted inside a prefilter, stop there - if ( completed ) { - return jqXHR; - } - - // We can fire global events as of now if asked to - // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) - fireGlobals = jQuery.event && s.global; - - // Watch for a new set of requests - if ( fireGlobals && jQuery.active++ === 0 ) { - jQuery.event.trigger( "ajaxStart" ); - } - - // Uppercase the type - s.type = s.type.toUpperCase(); - - // Determine if request has content - s.hasContent = !rnoContent.test( s.type ); - - // Save the URL in case we're toying with the If-Modified-Since - // and/or If-None-Match header later on - // Remove hash to simplify url manipulation - cacheURL = s.url.replace( rhash, "" ); - - // More options handling for requests with no content - if ( !s.hasContent ) { - - // Remember the hash so we can put it back - uncached = s.url.slice( cacheURL.length ); - - // If data is available and should be processed, append data to url - if ( s.data && ( s.processData || typeof s.data === "string" ) ) { - cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; - - // #9682: remove data so that it's not used in an eventual retry - delete s.data; - } - - // Add or update anti-cache param if needed - if ( s.cache === false ) { - cacheURL = cacheURL.replace( rantiCache, "$1" ); - uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + - uncached; - } - - // Put hash and anti-cache on the URL that will be requested (gh-1732) - s.url = cacheURL + uncached; - - // Change '%20' to '+' if this is encoded form body content (gh-2658) - } else if ( s.data && s.processData && - ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { - s.data = s.data.replace( r20, "+" ); - } - - // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. - if ( s.ifModified ) { - if ( jQuery.lastModified[ cacheURL ] ) { - jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); - } - if ( jQuery.etag[ cacheURL ] ) { - jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); - } - } - - // Set the correct header, if data is being sent - if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { - jqXHR.setRequestHeader( "Content-Type", s.contentType ); - } - - // Set the Accepts header for the server, depending on the dataType - jqXHR.setRequestHeader( - "Accept", - s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? - s.accepts[ s.dataTypes[ 0 ] ] + - ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : - s.accepts[ "*" ] - ); - - // Check for headers option - for ( i in s.headers ) { - jqXHR.setRequestHeader( i, s.headers[ i ] ); - } - - // Allow custom headers/mimetypes and early abort - if ( s.beforeSend && - ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { - - // Abort if not done already and return - return jqXHR.abort(); - } - - // Aborting is no longer a cancellation - strAbort = "abort"; - - // Install callbacks on deferreds - completeDeferred.add( s.complete ); - jqXHR.done( s.success ); - jqXHR.fail( s.error ); - - // Get transport - transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); - - // If no transport, we auto-abort - if ( !transport ) { - done( -1, "No Transport" ); - } else { - jqXHR.readyState = 1; - - // Send global event - if ( fireGlobals ) { - globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); - } - - // If request was aborted inside ajaxSend, stop there - if ( completed ) { - return jqXHR; - } - - // Timeout - if ( s.async && s.timeout > 0 ) { - timeoutTimer = window.setTimeout( function() { - jqXHR.abort( "timeout" ); - }, s.timeout ); - } - - try { - completed = false; - transport.send( requestHeaders, done ); - } catch ( e ) { - - // Rethrow post-completion exceptions - if ( completed ) { - throw e; - } - - // Propagate others as results - done( -1, e ); - } - } - - // Callback for when everything is done - function done( status, nativeStatusText, responses, headers ) { - var isSuccess, success, error, response, modified, - statusText = nativeStatusText; - - // Ignore repeat invocations - if ( completed ) { - return; - } - - completed = true; - - // Clear timeout if it exists - if ( timeoutTimer ) { - window.clearTimeout( timeoutTimer ); - } - - // Dereference transport for early garbage collection - // (no matter how long the jqXHR object will be used) - transport = undefined; - - // Cache response headers - responseHeadersString = headers || ""; - - // Set readyState - jqXHR.readyState = status > 0 ? 4 : 0; - - // Determine if successful - isSuccess = status >= 200 && status < 300 || status === 304; - - // Get response data - if ( responses ) { - response = ajaxHandleResponses( s, jqXHR, responses ); - } - - // Use a noop converter for missing script but not if jsonp - if ( !isSuccess && - jQuery.inArray( "script", s.dataTypes ) > -1 && - jQuery.inArray( "json", s.dataTypes ) < 0 ) { - s.converters[ "text script" ] = function() {}; - } - - // Convert no matter what (that way responseXXX fields are always set) - response = ajaxConvert( s, response, jqXHR, isSuccess ); - - // If successful, handle type chaining - if ( isSuccess ) { - - // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. - if ( s.ifModified ) { - modified = jqXHR.getResponseHeader( "Last-Modified" ); - if ( modified ) { - jQuery.lastModified[ cacheURL ] = modified; - } - modified = jqXHR.getResponseHeader( "etag" ); - if ( modified ) { - jQuery.etag[ cacheURL ] = modified; - } - } - - // if no content - if ( status === 204 || s.type === "HEAD" ) { - statusText = "nocontent"; - - // if not modified - } else if ( status === 304 ) { - statusText = "notmodified"; - - // If we have data, let's convert it - } else { - statusText = response.state; - success = response.data; - error = response.error; - isSuccess = !error; - } - } else { - - // Extract error from statusText and normalize for non-aborts - error = statusText; - if ( status || !statusText ) { - statusText = "error"; - if ( status < 0 ) { - status = 0; - } - } - } - - // Set data for the fake xhr object - jqXHR.status = status; - jqXHR.statusText = ( nativeStatusText || statusText ) + ""; - - // Success/Error - if ( isSuccess ) { - deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); - } else { - deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); - } - - // Status-dependent callbacks - jqXHR.statusCode( statusCode ); - statusCode = undefined; - - if ( fireGlobals ) { - globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", - [ jqXHR, s, isSuccess ? success : error ] ); - } - - // Complete - completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); - - if ( fireGlobals ) { - globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); - - // Handle the global AJAX counter - if ( !( --jQuery.active ) ) { - jQuery.event.trigger( "ajaxStop" ); - } - } - } - - return jqXHR; - }, - - getJSON: function( url, data, callback ) { - return jQuery.get( url, data, callback, "json" ); - }, - - getScript: function( url, callback ) { - return jQuery.get( url, undefined, callback, "script" ); - } -} ); - -jQuery.each( [ "get", "post" ], function( _i, method ) { - jQuery[ method ] = function( url, data, callback, type ) { - - // Shift arguments if data argument was omitted - if ( isFunction( data ) ) { - type = type || callback; - callback = data; - data = undefined; - } - - // The url can be an options object (which then must have .url) - return jQuery.ajax( jQuery.extend( { - url: url, - type: method, - dataType: type, - data: data, - success: callback - }, jQuery.isPlainObject( url ) && url ) ); - }; -} ); - -jQuery.ajaxPrefilter( function( s ) { - var i; - for ( i in s.headers ) { - if ( i.toLowerCase() === "content-type" ) { - s.contentType = s.headers[ i ] || ""; - } - } -} ); - - -jQuery._evalUrl = function( url, options, doc ) { - return jQuery.ajax( { - url: url, - - // Make this explicit, since user can override this through ajaxSetup (#11264) - type: "GET", - dataType: "script", - cache: true, - async: false, - global: false, - - // Only evaluate the response if it is successful (gh-4126) - // dataFilter is not invoked for failure responses, so using it instead - // of the default converter is kludgy but it works. - converters: { - "text script": function() {} - }, - dataFilter: function( response ) { - jQuery.globalEval( response, options, doc ); - } - } ); -}; - - -jQuery.fn.extend( { - wrapAll: function( html ) { - var wrap; - - if ( this[ 0 ] ) { - if ( isFunction( html ) ) { - html = html.call( this[ 0 ] ); - } - - // The elements to wrap the target around - wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); - - if ( this[ 0 ].parentNode ) { - wrap.insertBefore( this[ 0 ] ); - } - - wrap.map( function() { - var elem = this; - - while ( elem.firstElementChild ) { - elem = elem.firstElementChild; - } - - return elem; - } ).append( this ); - } - - return this; - }, - - wrapInner: function( html ) { - if ( isFunction( html ) ) { - return this.each( function( i ) { - jQuery( this ).wrapInner( html.call( this, i ) ); - } ); - } - - return this.each( function() { - var self = jQuery( this ), - contents = self.contents(); - - if ( contents.length ) { - contents.wrapAll( html ); - - } else { - self.append( html ); - } - } ); - }, - - wrap: function( html ) { - var htmlIsFunction = isFunction( html ); - - return this.each( function( i ) { - jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); - } ); - }, - - unwrap: function( selector ) { - this.parent( selector ).not( "body" ).each( function() { - jQuery( this ).replaceWith( this.childNodes ); - } ); - return this; - } -} ); - - -jQuery.expr.pseudos.hidden = function( elem ) { - return !jQuery.expr.pseudos.visible( elem ); -}; -jQuery.expr.pseudos.visible = function( elem ) { - return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); -}; - - - - -jQuery.ajaxSettings.xhr = function() { - try { - return new window.XMLHttpRequest(); - } catch ( e ) {} -}; - -var xhrSuccessStatus = { - - // File protocol always yields status code 0, assume 200 - 0: 200, - - // Support: IE <=9 only - // #1450: sometimes IE returns 1223 when it should be 204 - 1223: 204 - }, - xhrSupported = jQuery.ajaxSettings.xhr(); - -support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); -support.ajax = xhrSupported = !!xhrSupported; - -jQuery.ajaxTransport( function( options ) { - var callback, errorCallback; - - // Cross domain only allowed if supported through XMLHttpRequest - if ( support.cors || xhrSupported && !options.crossDomain ) { - return { - send: function( headers, complete ) { - var i, - xhr = options.xhr(); - - xhr.open( - options.type, - options.url, - options.async, - options.username, - options.password - ); - - // Apply custom fields if provided - if ( options.xhrFields ) { - for ( i in options.xhrFields ) { - xhr[ i ] = options.xhrFields[ i ]; - } - } - - // Override mime type if needed - if ( options.mimeType && xhr.overrideMimeType ) { - xhr.overrideMimeType( options.mimeType ); - } - - // X-Requested-With header - // For cross-domain requests, seeing as conditions for a preflight are - // akin to a jigsaw puzzle, we simply never set it to be sure. - // (it can always be set on a per-request basis or even using ajaxSetup) - // For same-domain requests, won't change header if already provided. - if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { - headers[ "X-Requested-With" ] = "XMLHttpRequest"; - } - - // Set headers - for ( i in headers ) { - xhr.setRequestHeader( i, headers[ i ] ); - } - - // Callback - callback = function( type ) { - return function() { - if ( callback ) { - callback = errorCallback = xhr.onload = - xhr.onerror = xhr.onabort = xhr.ontimeout = - xhr.onreadystatechange = null; - - if ( type === "abort" ) { - xhr.abort(); - } else if ( type === "error" ) { - - // Support: IE <=9 only - // On a manual native abort, IE9 throws - // errors on any property access that is not readyState - if ( typeof xhr.status !== "number" ) { - complete( 0, "error" ); - } else { - complete( - - // File: protocol always yields status 0; see #8605, #14207 - xhr.status, - xhr.statusText - ); - } - } else { - complete( - xhrSuccessStatus[ xhr.status ] || xhr.status, - xhr.statusText, - - // Support: IE <=9 only - // IE9 has no XHR2 but throws on binary (trac-11426) - // For XHR2 non-text, let the caller handle it (gh-2498) - ( xhr.responseType || "text" ) !== "text" || - typeof xhr.responseText !== "string" ? - { binary: xhr.response } : - { text: xhr.responseText }, - xhr.getAllResponseHeaders() - ); - } - } - }; - }; - - // Listen to events - xhr.onload = callback(); - errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); - - // Support: IE 9 only - // Use onreadystatechange to replace onabort - // to handle uncaught aborts - if ( xhr.onabort !== undefined ) { - xhr.onabort = errorCallback; - } else { - xhr.onreadystatechange = function() { - - // Check readyState before timeout as it changes - if ( xhr.readyState === 4 ) { - - // Allow onerror to be called first, - // but that will not handle a native abort - // Also, save errorCallback to a variable - // as xhr.onerror cannot be accessed - window.setTimeout( function() { - if ( callback ) { - errorCallback(); - } - } ); - } - }; - } - - // Create the abort callback - callback = callback( "abort" ); - - try { - - // Do send the request (this may raise an exception) - xhr.send( options.hasContent && options.data || null ); - } catch ( e ) { - - // #14683: Only rethrow if this hasn't been notified as an error yet - if ( callback ) { - throw e; - } - } - }, - - abort: function() { - if ( callback ) { - callback(); - } - } - }; - } -} ); - - - - -// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) -jQuery.ajaxPrefilter( function( s ) { - if ( s.crossDomain ) { - s.contents.script = false; - } -} ); - -// Install script dataType -jQuery.ajaxSetup( { - accepts: { - script: "text/javascript, application/javascript, " + - "application/ecmascript, application/x-ecmascript" - }, - contents: { - script: /\b(?:java|ecma)script\b/ - }, - converters: { - "text script": function( text ) { - jQuery.globalEval( text ); - return text; - } - } -} ); - -// Handle cache's special case and crossDomain -jQuery.ajaxPrefilter( "script", function( s ) { - if ( s.cache === undefined ) { - s.cache = false; - } - if ( s.crossDomain ) { - s.type = "GET"; - } -} ); - -// Bind script tag hack transport -jQuery.ajaxTransport( "script", function( s ) { - - // This transport only deals with cross domain or forced-by-attrs requests - if ( s.crossDomain || s.scriptAttrs ) { - var script, callback; - return { - send: function( _, complete ) { - script = jQuery( " -{% endmacro %} diff --git a/docs/_build/html/_static/scripts/bootstrap.js b/docs/_build/html/_static/scripts/bootstrap.js deleted file mode 100644 index bda8a60..0000000 --- a/docs/_build/html/_static/scripts/bootstrap.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! For license information please see bootstrap.js.LICENSE.txt */ -(()=>{"use strict";var t={d:(e,i)=>{for(var n in i)t.o(i,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:i[n]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{afterMain:()=>w,afterRead:()=>b,afterWrite:()=>T,applyStyles:()=>D,arrow:()=>G,auto:()=>r,basePlacements:()=>a,beforeMain:()=>v,beforeRead:()=>g,beforeWrite:()=>E,bottom:()=>n,clippingParents:()=>h,computeStyles:()=>et,createPopper:()=>St,createPopperBase:()=>Lt,createPopperLite:()=>Dt,detectOverflow:()=>gt,end:()=>c,eventListeners:()=>nt,flip:()=>_t,hide:()=>yt,left:()=>o,main:()=>y,modifierPhases:()=>C,offset:()=>wt,placements:()=>m,popper:()=>u,popperGenerator:()=>kt,popperOffsets:()=>Et,preventOverflow:()=>At,read:()=>_,reference:()=>f,right:()=>s,start:()=>l,top:()=>i,variationPlacements:()=>p,viewport:()=>d,write:()=>A});var i="top",n="bottom",s="right",o="left",r="auto",a=[i,n,s,o],l="start",c="end",h="clippingParents",d="viewport",u="popper",f="reference",p=a.reduce((function(t,e){return t.concat([e+"-"+l,e+"-"+c])}),[]),m=[].concat(a,[r]).reduce((function(t,e){return t.concat([e,e+"-"+l,e+"-"+c])}),[]),g="beforeRead",_="read",b="afterRead",v="beforeMain",y="main",w="afterMain",E="beforeWrite",A="write",T="afterWrite",C=[g,_,b,v,y,w,E,A,T];function O(t){return t?(t.nodeName||"").toLowerCase():null}function x(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function k(t){return t instanceof x(t).Element||t instanceof Element}function L(t){return t instanceof x(t).HTMLElement||t instanceof HTMLElement}function S(t){return"undefined"!=typeof ShadowRoot&&(t instanceof x(t).ShadowRoot||t instanceof ShadowRoot)}const D={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];L(s)&&O(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});L(n)&&O(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function $(t){return t.split("-")[0]}var I=Math.max,N=Math.min,P=Math.round;function M(){var t=navigator.userAgentData;return null!=t&&t.brands&&Array.isArray(t.brands)?t.brands.map((function(t){return t.brand+"/"+t.version})).join(" "):navigator.userAgent}function j(){return!/^((?!chrome|android).)*safari/i.test(M())}function F(t,e,i){void 0===e&&(e=!1),void 0===i&&(i=!1);var n=t.getBoundingClientRect(),s=1,o=1;e&&L(t)&&(s=t.offsetWidth>0&&P(n.width)/t.offsetWidth||1,o=t.offsetHeight>0&&P(n.height)/t.offsetHeight||1);var r=(k(t)?x(t):window).visualViewport,a=!j()&&i,l=(n.left+(a&&r?r.offsetLeft:0))/s,c=(n.top+(a&&r?r.offsetTop:0))/o,h=n.width/s,d=n.height/o;return{width:h,height:d,top:c,right:l+h,bottom:c+d,left:l,x:l,y:c}}function H(t){var e=F(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function B(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&S(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function W(t){return x(t).getComputedStyle(t)}function z(t){return["table","td","th"].indexOf(O(t))>=0}function R(t){return((k(t)?t.ownerDocument:t.document)||window.document).documentElement}function q(t){return"html"===O(t)?t:t.assignedSlot||t.parentNode||(S(t)?t.host:null)||R(t)}function V(t){return L(t)&&"fixed"!==W(t).position?t.offsetParent:null}function Y(t){for(var e=x(t),i=V(t);i&&z(i)&&"static"===W(i).position;)i=V(i);return i&&("html"===O(i)||"body"===O(i)&&"static"===W(i).position)?e:i||function(t){var e=/firefox/i.test(M());if(/Trident/i.test(M())&&L(t)&&"fixed"===W(t).position)return null;var i=q(t);for(S(i)&&(i=i.host);L(i)&&["html","body"].indexOf(O(i))<0;){var n=W(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function K(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}function Q(t,e,i){return I(t,N(e,i))}function X(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function U(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const G={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,r=t.state,l=t.name,c=t.options,h=r.elements.arrow,d=r.modifiersData.popperOffsets,u=$(r.placement),f=K(u),p=[o,s].indexOf(u)>=0?"height":"width";if(h&&d){var m=function(t,e){return X("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:U(t,a))}(c.padding,r),g=H(h),_="y"===f?i:o,b="y"===f?n:s,v=r.rects.reference[p]+r.rects.reference[f]-d[f]-r.rects.popper[p],y=d[f]-r.rects.reference[f],w=Y(h),E=w?"y"===f?w.clientHeight||0:w.clientWidth||0:0,A=v/2-y/2,T=m[_],C=E-g[p]-m[b],O=E/2-g[p]/2+A,x=Q(T,O,C),k=f;r.modifiersData[l]=((e={})[k]=x,e.centerOffset=x-O,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&B(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function J(t){return t.split("-")[1]}var Z={top:"auto",right:"auto",bottom:"auto",left:"auto"};function tt(t){var e,r=t.popper,a=t.popperRect,l=t.placement,h=t.variation,d=t.offsets,u=t.position,f=t.gpuAcceleration,p=t.adaptive,m=t.roundOffsets,g=t.isFixed,_=d.x,b=void 0===_?0:_,v=d.y,y=void 0===v?0:v,w="function"==typeof m?m({x:b,y}):{x:b,y};b=w.x,y=w.y;var E=d.hasOwnProperty("x"),A=d.hasOwnProperty("y"),T=o,C=i,O=window;if(p){var k=Y(r),L="clientHeight",S="clientWidth";k===x(r)&&"static"!==W(k=R(r)).position&&"absolute"===u&&(L="scrollHeight",S="scrollWidth"),(l===i||(l===o||l===s)&&h===c)&&(C=n,y-=(g&&k===O&&O.visualViewport?O.visualViewport.height:k[L])-a.height,y*=f?1:-1),l!==o&&(l!==i&&l!==n||h!==c)||(T=s,b-=(g&&k===O&&O.visualViewport?O.visualViewport.width:k[S])-a.width,b*=f?1:-1)}var D,$=Object.assign({position:u},p&&Z),I=!0===m?function(t,e){var i=t.x,n=t.y,s=e.devicePixelRatio||1;return{x:P(i*s)/s||0,y:P(n*s)/s||0}}({x:b,y},x(r)):{x:b,y};return b=I.x,y=I.y,f?Object.assign({},$,((D={})[C]=A?"0":"",D[T]=E?"0":"",D.transform=(O.devicePixelRatio||1)<=1?"translate("+b+"px, "+y+"px)":"translate3d("+b+"px, "+y+"px, 0)",D)):Object.assign({},$,((e={})[C]=A?y+"px":"",e[T]=E?b+"px":"",e.transform="",e))}const et={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:$(e.placement),variation:J(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s,isFixed:"fixed"===e.options.strategy};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,tt(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,tt(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var it={passive:!0};const nt={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=x(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,it)})),a&&l.addEventListener("resize",i.update,it),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,it)})),a&&l.removeEventListener("resize",i.update,it)}},data:{}};var st={left:"right",right:"left",bottom:"top",top:"bottom"};function ot(t){return t.replace(/left|right|bottom|top/g,(function(t){return st[t]}))}var rt={start:"end",end:"start"};function at(t){return t.replace(/start|end/g,(function(t){return rt[t]}))}function lt(t){var e=x(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function ct(t){return F(R(t)).left+lt(t).scrollLeft}function ht(t){var e=W(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function dt(t){return["html","body","#document"].indexOf(O(t))>=0?t.ownerDocument.body:L(t)&&ht(t)?t:dt(q(t))}function ut(t,e){var i;void 0===e&&(e=[]);var n=dt(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=x(n),r=s?[o].concat(o.visualViewport||[],ht(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(ut(q(r)))}function ft(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function pt(t,e,i){return e===d?ft(function(t,e){var i=x(t),n=R(t),s=i.visualViewport,o=n.clientWidth,r=n.clientHeight,a=0,l=0;if(s){o=s.width,r=s.height;var c=j();(c||!c&&"fixed"===e)&&(a=s.offsetLeft,l=s.offsetTop)}return{width:o,height:r,x:a+ct(t),y:l}}(t,i)):k(e)?function(t,e){var i=F(t,!1,"fixed"===e);return i.top=i.top+t.clientTop,i.left=i.left+t.clientLeft,i.bottom=i.top+t.clientHeight,i.right=i.left+t.clientWidth,i.width=t.clientWidth,i.height=t.clientHeight,i.x=i.left,i.y=i.top,i}(e,i):ft(function(t){var e,i=R(t),n=lt(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=I(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=I(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+ct(t),l=-n.scrollTop;return"rtl"===W(s||i).direction&&(a+=I(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(R(t)))}function mt(t){var e,r=t.reference,a=t.element,h=t.placement,d=h?$(h):null,u=h?J(h):null,f=r.x+r.width/2-a.width/2,p=r.y+r.height/2-a.height/2;switch(d){case i:e={x:f,y:r.y-a.height};break;case n:e={x:f,y:r.y+r.height};break;case s:e={x:r.x+r.width,y:p};break;case o:e={x:r.x-a.width,y:p};break;default:e={x:r.x,y:r.y}}var m=d?K(d):null;if(null!=m){var g="y"===m?"height":"width";switch(u){case l:e[m]=e[m]-(r[g]/2-a[g]/2);break;case c:e[m]=e[m]+(r[g]/2-a[g]/2)}}return e}function gt(t,e){void 0===e&&(e={});var o=e,r=o.placement,l=void 0===r?t.placement:r,c=o.strategy,p=void 0===c?t.strategy:c,m=o.boundary,g=void 0===m?h:m,_=o.rootBoundary,b=void 0===_?d:_,v=o.elementContext,y=void 0===v?u:v,w=o.altBoundary,E=void 0!==w&&w,A=o.padding,T=void 0===A?0:A,C=X("number"!=typeof T?T:U(T,a)),x=y===u?f:u,S=t.rects.popper,D=t.elements[E?x:y],$=function(t,e,i,n){var s="clippingParents"===e?function(t){var e=ut(q(t)),i=["absolute","fixed"].indexOf(W(t).position)>=0&&L(t)?Y(t):t;return k(i)?e.filter((function(t){return k(t)&&B(t,i)&&"body"!==O(t)})):[]}(t):[].concat(e),o=[].concat(s,[i]),r=o[0],a=o.reduce((function(e,i){var s=pt(t,i,n);return e.top=I(s.top,e.top),e.right=N(s.right,e.right),e.bottom=N(s.bottom,e.bottom),e.left=I(s.left,e.left),e}),pt(t,r,n));return a.width=a.right-a.left,a.height=a.bottom-a.top,a.x=a.left,a.y=a.top,a}(k(D)?D:D.contextElement||R(t.elements.popper),g,b,p),P=F(t.elements.reference),M=mt({reference:P,element:S,strategy:"absolute",placement:l}),j=ft(Object.assign({},S,M)),H=y===u?j:P,z={top:$.top-H.top+C.top,bottom:H.bottom-$.bottom+C.bottom,left:$.left-H.left+C.left,right:H.right-$.right+C.right},V=t.modifiersData.offset;if(y===u&&V){var K=V[l];Object.keys(z).forEach((function(t){var e=[s,n].indexOf(t)>=0?1:-1,o=[i,n].indexOf(t)>=0?"y":"x";z[t]+=K[o]*e}))}return z}const _t={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,c=t.options,h=t.name;if(!e.modifiersData[h]._skip){for(var d=c.mainAxis,u=void 0===d||d,f=c.altAxis,g=void 0===f||f,_=c.fallbackPlacements,b=c.padding,v=c.boundary,y=c.rootBoundary,w=c.altBoundary,E=c.flipVariations,A=void 0===E||E,T=c.allowedAutoPlacements,C=e.options.placement,O=$(C),x=_||(O!==C&&A?function(t){if($(t)===r)return[];var e=ot(t);return[at(t),e,at(e)]}(C):[ot(C)]),k=[C].concat(x).reduce((function(t,i){return t.concat($(i)===r?function(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,l=i.flipVariations,c=i.allowedAutoPlacements,h=void 0===c?m:c,d=J(n),u=d?l?p:p.filter((function(t){return J(t)===d})):a,f=u.filter((function(t){return h.indexOf(t)>=0}));0===f.length&&(f=u);var g=f.reduce((function(e,i){return e[i]=gt(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[$(i)],e}),{});return Object.keys(g).sort((function(t,e){return g[t]-g[e]}))}(e,{placement:i,boundary:v,rootBoundary:y,padding:b,flipVariations:A,allowedAutoPlacements:T}):i)}),[]),L=e.rects.reference,S=e.rects.popper,D=new Map,I=!0,N=k[0],P=0;P=0,B=H?"width":"height",W=gt(e,{placement:M,boundary:v,rootBoundary:y,altBoundary:w,padding:b}),z=H?F?s:o:F?n:i;L[B]>S[B]&&(z=ot(z));var R=ot(z),q=[];if(u&&q.push(W[j]<=0),g&&q.push(W[z]<=0,W[R]<=0),q.every((function(t){return t}))){N=M,I=!1;break}D.set(M,q)}if(I)for(var V=function(t){var e=k.find((function(e){var i=D.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return N=e,"break"},Y=A?3:1;Y>0&&"break"!==V(Y);Y--);e.placement!==N&&(e.modifiersData[h]._skip=!0,e.placement=N,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function bt(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function vt(t){return[i,s,n,o].some((function(e){return t[e]>=0}))}const yt={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=gt(e,{elementContext:"reference"}),a=gt(e,{altBoundary:!0}),l=bt(r,n),c=bt(a,s,o),h=vt(l),d=vt(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":d})}},wt={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,n=t.options,r=t.name,a=n.offset,l=void 0===a?[0,0]:a,c=m.reduce((function(t,n){return t[n]=function(t,e,n){var r=$(t),a=[o,i].indexOf(r)>=0?-1:1,l="function"==typeof n?n(Object.assign({},e,{placement:t})):n,c=l[0],h=l[1];return c=c||0,h=(h||0)*a,[o,s].indexOf(r)>=0?{x:h,y:c}:{x:c,y:h}}(n,e.rects,l),t}),{}),h=c[e.placement],d=h.x,u=h.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=d,e.modifiersData.popperOffsets.y+=u),e.modifiersData[r]=c}},Et={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=mt({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},At={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,r=t.options,a=t.name,c=r.mainAxis,h=void 0===c||c,d=r.altAxis,u=void 0!==d&&d,f=r.boundary,p=r.rootBoundary,m=r.altBoundary,g=r.padding,_=r.tether,b=void 0===_||_,v=r.tetherOffset,y=void 0===v?0:v,w=gt(e,{boundary:f,rootBoundary:p,padding:g,altBoundary:m}),E=$(e.placement),A=J(e.placement),T=!A,C=K(E),O="x"===C?"y":"x",x=e.modifiersData.popperOffsets,k=e.rects.reference,L=e.rects.popper,S="function"==typeof y?y(Object.assign({},e.rects,{placement:e.placement})):y,D="number"==typeof S?{mainAxis:S,altAxis:S}:Object.assign({mainAxis:0,altAxis:0},S),P=e.modifiersData.offset?e.modifiersData.offset[e.placement]:null,M={x:0,y:0};if(x){if(h){var j,F="y"===C?i:o,B="y"===C?n:s,W="y"===C?"height":"width",z=x[C],R=z+w[F],q=z-w[B],V=b?-L[W]/2:0,X=A===l?k[W]:L[W],U=A===l?-L[W]:-k[W],G=e.elements.arrow,Z=b&&G?H(G):{width:0,height:0},tt=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},et=tt[F],it=tt[B],nt=Q(0,k[W],Z[W]),st=T?k[W]/2-V-nt-et-D.mainAxis:X-nt-et-D.mainAxis,ot=T?-k[W]/2+V+nt+it+D.mainAxis:U+nt+it+D.mainAxis,rt=e.elements.arrow&&Y(e.elements.arrow),at=rt?"y"===C?rt.clientTop||0:rt.clientLeft||0:0,lt=null!=(j=null==P?void 0:P[C])?j:0,ct=z+ot-lt,ht=Q(b?N(R,z+st-lt-at):R,z,b?I(q,ct):q);x[C]=ht,M[C]=ht-z}if(u){var dt,ut="x"===C?i:o,ft="x"===C?n:s,pt=x[O],mt="y"===O?"height":"width",_t=pt+w[ut],bt=pt-w[ft],vt=-1!==[i,o].indexOf(E),yt=null!=(dt=null==P?void 0:P[O])?dt:0,wt=vt?_t:pt-k[mt]-L[mt]-yt+D.altAxis,Et=vt?pt+k[mt]+L[mt]-yt-D.altAxis:bt,At=b&&vt?function(t,e,i){var n=Q(t,e,i);return n>i?i:n}(wt,pt,Et):Q(b?wt:_t,pt,b?Et:bt);x[O]=At,M[O]=At-pt}e.modifiersData[a]=M}},requiresIfExists:["offset"]};function Tt(t,e,i){void 0===i&&(i=!1);var n,s,o=L(e),r=L(e)&&function(t){var e=t.getBoundingClientRect(),i=P(e.width)/t.offsetWidth||1,n=P(e.height)/t.offsetHeight||1;return 1!==i||1!==n}(e),a=R(e),l=F(t,r,i),c={scrollLeft:0,scrollTop:0},h={x:0,y:0};return(o||!o&&!i)&&(("body"!==O(e)||ht(a))&&(c=(n=e)!==x(n)&&L(n)?{scrollLeft:(s=n).scrollLeft,scrollTop:s.scrollTop}:lt(n)),L(e)?((h=F(e,!0)).x+=e.clientLeft,h.y+=e.clientTop):a&&(h.x=ct(a))),{x:l.left+c.scrollLeft-h.x,y:l.top+c.scrollTop-h.y,width:l.width,height:l.height}}function Ct(t){var e=new Map,i=new Set,n=[];function s(t){i.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach((function(t){if(!i.has(t)){var n=e.get(t);n&&s(n)}})),n.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){i.has(t.name)||s(t)})),n}var Ot={placement:"bottom",modifiers:[],strategy:"absolute"};function xt(){for(var t=arguments.length,e=new Array(t),i=0;i$t.has(t)&&$t.get(t).get(e)||null,remove(t,e){if(!$t.has(t))return;const i=$t.get(t);i.delete(e),0===i.size&&$t.delete(t)}},Nt="transitionend",Pt=t=>(t&&window.CSS&&window.CSS.escape&&(t=t.replace(/#([^\s"#']+)/g,((t,e)=>`#${CSS.escape(e)}`))),t),Mt=t=>{t.dispatchEvent(new Event(Nt))},jt=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),Ft=t=>jt(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(Pt(t)):null,Ht=t=>{if(!jt(t)||0===t.getClientRects().length)return!1;const e="visible"===getComputedStyle(t).getPropertyValue("visibility"),i=t.closest("details:not([open])");if(!i)return e;if(i!==t){const e=t.closest("summary");if(e&&e.parentNode!==i)return!1;if(null===e)return!1}return e},Bt=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),Wt=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?Wt(t.parentNode):null},zt=()=>{},Rt=t=>{t.offsetHeight},qt=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,Vt=[],Yt=()=>"rtl"===document.documentElement.dir,Kt=t=>{var e;e=()=>{const e=qt();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(Vt.length||document.addEventListener("DOMContentLoaded",(()=>{for(const t of Vt)t()})),Vt.push(e)):e()},Qt=(t,e=[],i=t)=>"function"==typeof t?t(...e):i,Xt=(t,e,i=!0)=>{if(!i)return void Qt(t);const n=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(e)+5;let s=!1;const o=({target:i})=>{i===e&&(s=!0,e.removeEventListener(Nt,o),Qt(t))};e.addEventListener(Nt,o),setTimeout((()=>{s||Mt(e)}),n)},Ut=(t,e,i,n)=>{const s=t.length;let o=t.indexOf(e);return-1===o?!i&&n?t[s-1]:t[0]:(o+=i?1:-1,n&&(o=(o+s)%s),t[Math.max(0,Math.min(o,s-1))])},Gt=/[^.]*(?=\..*)\.|.*/,Jt=/\..*/,Zt=/::\d+$/,te={};let ee=1;const ie={mouseenter:"mouseover",mouseleave:"mouseout"},ne=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function se(t,e){return e&&`${e}::${ee++}`||t.uidEvent||ee++}function oe(t){const e=se(t);return t.uidEvent=e,te[e]=te[e]||{},te[e]}function re(t,e,i=null){return Object.values(t).find((t=>t.callable===e&&t.delegationSelector===i))}function ae(t,e,i){const n="string"==typeof e,s=n?i:e||i;let o=de(t);return ne.has(o)||(o=t),[n,s,o]}function le(t,e,i,n,s){if("string"!=typeof e||!t)return;let[o,r,a]=ae(e,i,n);if(e in ie){const t=t=>function(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};r=t(r)}const l=oe(t),c=l[a]||(l[a]={}),h=re(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=se(r,e.replace(Gt,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(const a of o)if(a===r)return fe(s,{delegateTarget:r}),n.oneOff&&ue.off(t,s.type,e,i),i.apply(r,[s])}}(t,i,r):function(t,e){return function i(n){return fe(n,{delegateTarget:t}),i.oneOff&&ue.off(t,n.type,e),e.apply(t,[n])}}(t,r);u.delegationSelector=o?i:null,u.callable=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function ce(t,e,i,n,s){const o=re(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function he(t,e,i,n){const s=e[i]||{};for(const[o,r]of Object.entries(s))o.includes(n)&&ce(t,e,i,r.callable,r.delegationSelector)}function de(t){return t=t.replace(Jt,""),ie[t]||t}const ue={on(t,e,i,n){le(t,e,i,n,!1)},one(t,e,i,n){le(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=ae(e,i,n),a=r!==e,l=oe(t),c=l[r]||{},h=e.startsWith(".");if(void 0===o){if(h)for(const i of Object.keys(l))he(t,l,i,e.slice(1));for(const[i,n]of Object.entries(c)){const s=i.replace(Zt,"");a&&!e.includes(s)||ce(t,l,r,n.callable,n.delegationSelector)}}else{if(!Object.keys(c).length)return;ce(t,l,r,o,s?i:null)}},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=qt();let s=null,o=!0,r=!0,a=!1;e!==de(e)&&n&&(s=n.Event(e,i),n(t).trigger(s),o=!s.isPropagationStopped(),r=!s.isImmediatePropagationStopped(),a=s.isDefaultPrevented());const l=fe(new Event(e,{bubbles:o,cancelable:!0}),i);return a&&l.preventDefault(),r&&t.dispatchEvent(l),l.defaultPrevented&&s&&s.preventDefault(),l}};function fe(t,e={}){for(const[i,n]of Object.entries(e))try{t[i]=n}catch(e){Object.defineProperty(t,i,{configurable:!0,get:()=>n})}return t}function pe(t){if("true"===t)return!0;if("false"===t)return!1;if(t===Number(t).toString())return Number(t);if(""===t||"null"===t)return null;if("string"!=typeof t)return t;try{return JSON.parse(decodeURIComponent(t))}catch(e){return t}}function me(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}const ge={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${me(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${me(e)}`)},getDataAttributes(t){if(!t)return{};const e={},i=Object.keys(t.dataset).filter((t=>t.startsWith("bs")&&!t.startsWith("bsConfig")));for(const n of i){let i=n.replace(/^bs/,"");i=i.charAt(0).toLowerCase()+i.slice(1,i.length),e[i]=pe(t.dataset[n])}return e},getDataAttribute:(t,e)=>pe(t.getAttribute(`data-bs-${me(e)}`))};class _e{static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(t){return t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t}_mergeConfigObj(t,e){const i=jt(e)?ge.getDataAttribute(e,"config"):{};return{...this.constructor.Default,..."object"==typeof i?i:{},...jt(e)?ge.getDataAttributes(e):{},..."object"==typeof t?t:{}}}_typeCheckConfig(t,e=this.constructor.DefaultType){for(const[n,s]of Object.entries(e)){const e=t[n],o=jt(e)?"element":null==(i=e)?`${i}`:Object.prototype.toString.call(i).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(s).test(o))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${n}" provided type "${o}" but expected type "${s}".`)}var i}}class be extends _e{constructor(t,e){super(),(t=Ft(t))&&(this._element=t,this._config=this._getConfig(e),It.set(this._element,this.constructor.DATA_KEY,this))}dispose(){It.remove(this._element,this.constructor.DATA_KEY),ue.off(this._element,this.constructor.EVENT_KEY);for(const t of Object.getOwnPropertyNames(this))this[t]=null}_queueCallback(t,e,i=!0){Xt(t,e,i)}_getConfig(t){return t=this._mergeConfigObj(t,this._element),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}static getInstance(t){return It.get(Ft(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.3.2"}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(t){return`${t}${this.EVENT_KEY}`}}const ve=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i=`#${i.split("#")[1]}`),e=i&&"#"!==i?Pt(i.trim()):null}return e},ye={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let n=t.parentNode.closest(e);for(;n;)i.push(n),n=n.parentNode.closest(e);return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(",");return this.find(e,t).filter((t=>!Bt(t)&&Ht(t)))},getSelectorFromElement(t){const e=ve(t);return e&&ye.findOne(e)?e:null},getElementFromSelector(t){const e=ve(t);return e?ye.findOne(e):null},getMultipleElementsFromSelector(t){const e=ve(t);return e?ye.find(e):[]}},we=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,n=t.NAME;ue.on(document,i,`[data-bs-dismiss="${n}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),Bt(this))return;const s=ye.getElementFromSelector(this)||this.closest(`.${n}`);t.getOrCreateInstance(s)[e]()}))},Ee=".bs.alert",Ae=`close${Ee}`,Te=`closed${Ee}`;class Ce extends be{static get NAME(){return"alert"}close(){if(ue.trigger(this._element,Ae).defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),ue.trigger(this._element,Te),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=Ce.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}we(Ce,"close"),Kt(Ce);const Oe='[data-bs-toggle="button"]';class xe extends be{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=xe.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}ue.on(document,"click.bs.button.data-api",Oe,(t=>{t.preventDefault();const e=t.target.closest(Oe);xe.getOrCreateInstance(e).toggle()})),Kt(xe);const ke=".bs.swipe",Le=`touchstart${ke}`,Se=`touchmove${ke}`,De=`touchend${ke}`,$e=`pointerdown${ke}`,Ie=`pointerup${ke}`,Ne={endCallback:null,leftCallback:null,rightCallback:null},Pe={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"};class Me extends _e{constructor(t,e){super(),this._element=t,t&&Me.isSupported()&&(this._config=this._getConfig(e),this._deltaX=0,this._supportPointerEvents=Boolean(window.PointerEvent),this._initEvents())}static get Default(){return Ne}static get DefaultType(){return Pe}static get NAME(){return"swipe"}dispose(){ue.off(this._element,ke)}_start(t){this._supportPointerEvents?this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX):this._deltaX=t.touches[0].clientX}_end(t){this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX-this._deltaX),this._handleSwipe(),Qt(this._config.endCallback)}_move(t){this._deltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this._deltaX}_handleSwipe(){const t=Math.abs(this._deltaX);if(t<=40)return;const e=t/this._deltaX;this._deltaX=0,e&&Qt(e>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?(ue.on(this._element,$e,(t=>this._start(t))),ue.on(this._element,Ie,(t=>this._end(t))),this._element.classList.add("pointer-event")):(ue.on(this._element,Le,(t=>this._start(t))),ue.on(this._element,Se,(t=>this._move(t))),ue.on(this._element,De,(t=>this._end(t))))}_eventIsPointerPenTouch(t){return this._supportPointerEvents&&("pen"===t.pointerType||"touch"===t.pointerType)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}}const je=".bs.carousel",Fe=".data-api",He="next",Be="prev",We="left",ze="right",Re=`slide${je}`,qe=`slid${je}`,Ve=`keydown${je}`,Ye=`mouseenter${je}`,Ke=`mouseleave${je}`,Qe=`dragstart${je}`,Xe=`load${je}${Fe}`,Ue=`click${je}${Fe}`,Ge="carousel",Je="active",Ze=".active",ti=".carousel-item",ei=Ze+ti,ii={ArrowLeft:ze,ArrowRight:We},ni={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},si={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"};class oi extends be{constructor(t,e){super(t,e),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=ye.findOne(".carousel-indicators",this._element),this._addEventListeners(),this._config.ride===Ge&&this.cycle()}static get Default(){return ni}static get DefaultType(){return si}static get NAME(){return"carousel"}next(){this._slide(He)}nextWhenVisible(){!document.hidden&&Ht(this._element)&&this.next()}prev(){this._slide(Be)}pause(){this._isSliding&&Mt(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval((()=>this.nextWhenVisible()),this._config.interval)}_maybeEnableCycle(){this._config.ride&&(this._isSliding?ue.one(this._element,qe,(()=>this.cycle())):this.cycle())}to(t){const e=this._getItems();if(t>e.length-1||t<0)return;if(this._isSliding)return void ue.one(this._element,qe,(()=>this.to(t)));const i=this._getItemIndex(this._getActive());if(i===t)return;const n=t>i?He:Be;this._slide(n,e[t])}dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(t){return t.defaultInterval=t.interval,t}_addEventListeners(){this._config.keyboard&&ue.on(this._element,Ve,(t=>this._keydown(t))),"hover"===this._config.pause&&(ue.on(this._element,Ye,(()=>this.pause())),ue.on(this._element,Ke,(()=>this._maybeEnableCycle()))),this._config.touch&&Me.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(const t of ye.find(".carousel-item img",this._element))ue.on(t,Qe,(t=>t.preventDefault()));const t={leftCallback:()=>this._slide(this._directionToOrder(We)),rightCallback:()=>this._slide(this._directionToOrder(ze)),endCallback:()=>{"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((()=>this._maybeEnableCycle()),500+this._config.interval))}};this._swipeHelper=new Me(this._element,t)}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=ii[t.key];e&&(t.preventDefault(),this._slide(this._directionToOrder(e)))}_getItemIndex(t){return this._getItems().indexOf(t)}_setActiveIndicatorElement(t){if(!this._indicatorsElement)return;const e=ye.findOne(Ze,this._indicatorsElement);e.classList.remove(Je),e.removeAttribute("aria-current");const i=ye.findOne(`[data-bs-slide-to="${t}"]`,this._indicatorsElement);i&&(i.classList.add(Je),i.setAttribute("aria-current","true"))}_updateInterval(){const t=this._activeElement||this._getActive();if(!t)return;const e=Number.parseInt(t.getAttribute("data-bs-interval"),10);this._config.interval=e||this._config.defaultInterval}_slide(t,e=null){if(this._isSliding)return;const i=this._getActive(),n=t===He,s=e||Ut(this._getItems(),i,n,this._config.wrap);if(s===i)return;const o=this._getItemIndex(s),r=e=>ue.trigger(this._element,e,{relatedTarget:s,direction:this._orderToDirection(t),from:this._getItemIndex(i),to:o});if(r(Re).defaultPrevented)return;if(!i||!s)return;const a=Boolean(this._interval);this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(o),this._activeElement=s;const l=n?"carousel-item-start":"carousel-item-end",c=n?"carousel-item-next":"carousel-item-prev";s.classList.add(c),Rt(s),i.classList.add(l),s.classList.add(l),this._queueCallback((()=>{s.classList.remove(l,c),s.classList.add(Je),i.classList.remove(Je,c,l),this._isSliding=!1,r(qe)}),i,this._isAnimated()),a&&this.cycle()}_isAnimated(){return this._element.classList.contains("slide")}_getActive(){return ye.findOne(ei,this._element)}_getItems(){return ye.find(ti,this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(t){return Yt()?t===We?Be:He:t===We?He:Be}_orderToDirection(t){return Yt()?t===Be?We:ze:t===Be?ze:We}static jQueryInterface(t){return this.each((function(){const e=oi.getOrCreateInstance(this,t);if("number"!=typeof t){if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}else e.to(t)}))}}ue.on(document,Ue,"[data-bs-slide], [data-bs-slide-to]",(function(t){const e=ye.getElementFromSelector(this);if(!e||!e.classList.contains(Ge))return;t.preventDefault();const i=oi.getOrCreateInstance(e),n=this.getAttribute("data-bs-slide-to");return n?(i.to(n),void i._maybeEnableCycle()):"next"===ge.getDataAttribute(this,"slide")?(i.next(),void i._maybeEnableCycle()):(i.prev(),void i._maybeEnableCycle())})),ue.on(window,Xe,(()=>{const t=ye.find('[data-bs-ride="carousel"]');for(const e of t)oi.getOrCreateInstance(e)})),Kt(oi);const ri=".bs.collapse",ai=`show${ri}`,li=`shown${ri}`,ci=`hide${ri}`,hi=`hidden${ri}`,di=`click${ri}.data-api`,ui="show",fi="collapse",pi="collapsing",mi=`:scope .${fi} .${fi}`,gi='[data-bs-toggle="collapse"]',_i={parent:null,toggle:!0},bi={parent:"(null|element)",toggle:"boolean"};class vi extends be{constructor(t,e){super(t,e),this._isTransitioning=!1,this._triggerArray=[];const i=ye.find(gi);for(const t of i){const e=ye.getSelectorFromElement(t),i=ye.find(e).filter((t=>t===this._element));null!==e&&i.length&&this._triggerArray.push(t)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return _i}static get DefaultType(){return bi}static get NAME(){return"collapse"}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t=[];if(this._config.parent&&(t=this._getFirstLevelChildren(".collapse.show, .collapse.collapsing").filter((t=>t!==this._element)).map((t=>vi.getOrCreateInstance(t,{toggle:!1})))),t.length&&t[0]._isTransitioning)return;if(ue.trigger(this._element,ai).defaultPrevented)return;for(const e of t)e.hide();const e=this._getDimension();this._element.classList.remove(fi),this._element.classList.add(pi),this._element.style[e]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const i=`scroll${e[0].toUpperCase()+e.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(pi),this._element.classList.add(fi,ui),this._element.style[e]="",ue.trigger(this._element,li)}),this._element,!0),this._element.style[e]=`${this._element[i]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(ue.trigger(this._element,ci).defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,Rt(this._element),this._element.classList.add(pi),this._element.classList.remove(fi,ui);for(const t of this._triggerArray){const e=ye.getElementFromSelector(t);e&&!this._isShown(e)&&this._addAriaAndCollapsedClass([t],!1)}this._isTransitioning=!0,this._element.style[t]="",this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(pi),this._element.classList.add(fi),ue.trigger(this._element,hi)}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(ui)}_configAfterMerge(t){return t.toggle=Boolean(t.toggle),t.parent=Ft(t.parent),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=this._getFirstLevelChildren(gi);for(const e of t){const t=ye.getElementFromSelector(e);t&&this._addAriaAndCollapsedClass([e],this._isShown(t))}}_getFirstLevelChildren(t){const e=ye.find(mi,this._config.parent);return ye.find(t,this._config.parent).filter((t=>!e.includes(t)))}_addAriaAndCollapsedClass(t,e){if(t.length)for(const i of t)i.classList.toggle("collapsed",!e),i.setAttribute("aria-expanded",e)}static jQueryInterface(t){const e={};return"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1),this.each((function(){const i=vi.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}ue.on(document,di,gi,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();for(const t of ye.getMultipleElementsFromSelector(this))vi.getOrCreateInstance(t,{toggle:!1}).toggle()})),Kt(vi);const yi="dropdown",wi=".bs.dropdown",Ei=".data-api",Ai="ArrowUp",Ti="ArrowDown",Ci=`hide${wi}`,Oi=`hidden${wi}`,xi=`show${wi}`,ki=`shown${wi}`,Li=`click${wi}${Ei}`,Si=`keydown${wi}${Ei}`,Di=`keyup${wi}${Ei}`,$i="show",Ii='[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)',Ni=`${Ii}.${$i}`,Pi=".dropdown-menu",Mi=Yt()?"top-end":"top-start",ji=Yt()?"top-start":"top-end",Fi=Yt()?"bottom-end":"bottom-start",Hi=Yt()?"bottom-start":"bottom-end",Bi=Yt()?"left-start":"right-start",Wi=Yt()?"right-start":"left-start",zi={autoClose:!0,boundary:"clippingParents",display:"dynamic",offset:[0,2],popperConfig:null,reference:"toggle"},Ri={autoClose:"(boolean|string)",boundary:"(string|element)",display:"string",offset:"(array|string|function)",popperConfig:"(null|object|function)",reference:"(string|element|object)"};class qi extends be{constructor(t,e){super(t,e),this._popper=null,this._parent=this._element.parentNode,this._menu=ye.next(this._element,Pi)[0]||ye.prev(this._element,Pi)[0]||ye.findOne(Pi,this._parent),this._inNavbar=this._detectNavbar()}static get Default(){return zi}static get DefaultType(){return Ri}static get NAME(){return yi}toggle(){return this._isShown()?this.hide():this.show()}show(){if(Bt(this._element)||this._isShown())return;const t={relatedTarget:this._element};if(!ue.trigger(this._element,xi,t).defaultPrevented){if(this._createPopper(),"ontouchstart"in document.documentElement&&!this._parent.closest(".navbar-nav"))for(const t of[].concat(...document.body.children))ue.on(t,"mouseover",zt);this._element.focus(),this._element.setAttribute("aria-expanded",!0),this._menu.classList.add($i),this._element.classList.add($i),ue.trigger(this._element,ki,t)}}hide(){if(Bt(this._element)||!this._isShown())return;const t={relatedTarget:this._element};this._completeHide(t)}dispose(){this._popper&&this._popper.destroy(),super.dispose()}update(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.update()}_completeHide(t){if(!ue.trigger(this._element,Ci,t).defaultPrevented){if("ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))ue.off(t,"mouseover",zt);this._popper&&this._popper.destroy(),this._menu.classList.remove($i),this._element.classList.remove($i),this._element.setAttribute("aria-expanded","false"),ge.removeDataAttribute(this._menu,"popper"),ue.trigger(this._element,Oi,t)}}_getConfig(t){if("object"==typeof(t=super._getConfig(t)).reference&&!jt(t.reference)&&"function"!=typeof t.reference.getBoundingClientRect)throw new TypeError(`${yi.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);return t}_createPopper(){if(void 0===e)throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");let t=this._element;"parent"===this._config.reference?t=this._parent:jt(this._config.reference)?t=Ft(this._config.reference):"object"==typeof this._config.reference&&(t=this._config.reference);const i=this._getPopperConfig();this._popper=St(t,this._menu,i)}_isShown(){return this._menu.classList.contains($i)}_getPlacement(){const t=this._parent;if(t.classList.contains("dropend"))return Bi;if(t.classList.contains("dropstart"))return Wi;if(t.classList.contains("dropup-center"))return"top";if(t.classList.contains("dropdown-center"))return"bottom";const e="end"===getComputedStyle(this._menu).getPropertyValue("--bs-position").trim();return t.classList.contains("dropup")?e?ji:Mi:e?Hi:Fi}_detectNavbar(){return null!==this._element.closest(".navbar")}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||"static"===this._config.display)&&(ge.setDataAttribute(this._menu,"popper","static"),t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,...Qt(this._config.popperConfig,[t])}}_selectMenuItem({key:t,target:e}){const i=ye.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter((t=>Ht(t)));i.length&&Ut(i,e,t===Ti,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=qi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(2===t.button||"keyup"===t.type&&"Tab"!==t.key)return;const e=ye.find(Ni);for(const i of e){const e=qi.getInstance(i);if(!e||!1===e._config.autoClose)continue;const n=t.composedPath(),s=n.includes(e._menu);if(n.includes(e._element)||"inside"===e._config.autoClose&&!s||"outside"===e._config.autoClose&&s)continue;if(e._menu.contains(t.target)&&("keyup"===t.type&&"Tab"===t.key||/input|select|option|textarea|form/i.test(t.target.tagName)))continue;const o={relatedTarget:e._element};"click"===t.type&&(o.clickEvent=t),e._completeHide(o)}}static dataApiKeydownHandler(t){const e=/input|textarea/i.test(t.target.tagName),i="Escape"===t.key,n=[Ai,Ti].includes(t.key);if(!n&&!i)return;if(e&&!i)return;t.preventDefault();const s=this.matches(Ii)?this:ye.prev(this,Ii)[0]||ye.next(this,Ii)[0]||ye.findOne(Ii,t.delegateTarget.parentNode),o=qi.getOrCreateInstance(s);if(n)return t.stopPropagation(),o.show(),void o._selectMenuItem(t);o._isShown()&&(t.stopPropagation(),o.hide(),s.focus())}}ue.on(document,Si,Ii,qi.dataApiKeydownHandler),ue.on(document,Si,Pi,qi.dataApiKeydownHandler),ue.on(document,Li,qi.clearMenus),ue.on(document,Di,qi.clearMenus),ue.on(document,Li,Ii,(function(t){t.preventDefault(),qi.getOrCreateInstance(this).toggle()})),Kt(qi);const Vi="backdrop",Yi="show",Ki=`mousedown.bs.${Vi}`,Qi={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},Xi={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"};class Ui extends _e{constructor(t){super(),this._config=this._getConfig(t),this._isAppended=!1,this._element=null}static get Default(){return Qi}static get DefaultType(){return Xi}static get NAME(){return Vi}show(t){if(!this._config.isVisible)return void Qt(t);this._append();const e=this._getElement();this._config.isAnimated&&Rt(e),e.classList.add(Yi),this._emulateAnimation((()=>{Qt(t)}))}hide(t){this._config.isVisible?(this._getElement().classList.remove(Yi),this._emulateAnimation((()=>{this.dispose(),Qt(t)}))):Qt(t)}dispose(){this._isAppended&&(ue.off(this._element,Ki),this._element.remove(),this._isAppended=!1)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_configAfterMerge(t){return t.rootElement=Ft(t.rootElement),t}_append(){if(this._isAppended)return;const t=this._getElement();this._config.rootElement.append(t),ue.on(t,Ki,(()=>{Qt(this._config.clickCallback)})),this._isAppended=!0}_emulateAnimation(t){Xt(t,this._getElement(),this._config.isAnimated)}}const Gi=".bs.focustrap",Ji=`focusin${Gi}`,Zi=`keydown.tab${Gi}`,tn="backward",en={autofocus:!0,trapElement:null},nn={autofocus:"boolean",trapElement:"element"};class sn extends _e{constructor(t){super(),this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return en}static get DefaultType(){return nn}static get NAME(){return"focustrap"}activate(){this._isActive||(this._config.autofocus&&this._config.trapElement.focus(),ue.off(document,Gi),ue.on(document,Ji,(t=>this._handleFocusin(t))),ue.on(document,Zi,(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,ue.off(document,Gi))}_handleFocusin(t){const{trapElement:e}=this._config;if(t.target===document||t.target===e||e.contains(t.target))return;const i=ye.focusableChildren(e);0===i.length?e.focus():this._lastTabNavDirection===tn?i[i.length-1].focus():i[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?tn:"forward")}}const on=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",rn=".sticky-top",an="padding-right",ln="margin-right";class cn{constructor(){this._element=document.body}getWidth(){const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)}hide(){const t=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,an,(e=>e+t)),this._setElementAttributes(on,an,(e=>e+t)),this._setElementAttributes(rn,ln,(e=>e-t))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,an),this._resetElementAttributes(on,an),this._resetElementAttributes(rn,ln)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t).getPropertyValue(e);t.style.setProperty(e,`${i(Number.parseFloat(s))}px`)}))}_saveInitialAttribute(t,e){const i=t.style.getPropertyValue(e);i&&ge.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=ge.getDataAttribute(t,e);null!==i?(ge.removeDataAttribute(t,e),t.style.setProperty(e,i)):t.style.removeProperty(e)}))}_applyManipulationCallback(t,e){if(jt(t))e(t);else for(const i of ye.find(t,this._element))e(i)}}const hn=".bs.modal",dn=`hide${hn}`,un=`hidePrevented${hn}`,fn=`hidden${hn}`,pn=`show${hn}`,mn=`shown${hn}`,gn=`resize${hn}`,_n=`click.dismiss${hn}`,bn=`mousedown.dismiss${hn}`,vn=`keydown.dismiss${hn}`,yn=`click${hn}.data-api`,wn="modal-open",En="show",An="modal-static",Tn={backdrop:!0,focus:!0,keyboard:!0},Cn={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"};class On extends be{constructor(t,e){super(t,e),this._dialog=ye.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new cn,this._addEventListeners()}static get Default(){return Tn}static get DefaultType(){return Cn}static get NAME(){return"modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||ue.trigger(this._element,pn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(wn),this._adjustDialog(),this._backdrop.show((()=>this._showElement(t))))}hide(){this._isShown&&!this._isTransitioning&&(ue.trigger(this._element,dn).defaultPrevented||(this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove(En),this._queueCallback((()=>this._hideModal()),this._element,this._isAnimated())))}dispose(){ue.off(window,hn),ue.off(this._dialog,hn),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new Ui({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new sn({trapElement:this._element})}_showElement(t){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;const e=ye.findOne(".modal-body",this._dialog);e&&(e.scrollTop=0),Rt(this._element),this._element.classList.add(En),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,ue.trigger(this._element,mn,{relatedTarget:t})}),this._dialog,this._isAnimated())}_addEventListeners(){ue.on(this._element,vn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():this._triggerBackdropTransition())})),ue.on(window,gn,(()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()})),ue.on(this._element,bn,(t=>{ue.one(this._element,_n,(e=>{this._element===t.target&&this._element===e.target&&("static"!==this._config.backdrop?this._config.backdrop&&this.hide():this._triggerBackdropTransition())}))}))}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(wn),this._resetAdjustments(),this._scrollBar.reset(),ue.trigger(this._element,fn)}))}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(ue.trigger(this._element,un).defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._element.style.overflowY;"hidden"===e||this._element.classList.contains(An)||(t||(this._element.style.overflowY="hidden"),this._element.classList.add(An),this._queueCallback((()=>{this._element.classList.remove(An),this._queueCallback((()=>{this._element.style.overflowY=e}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;if(i&&!t){const t=Yt()?"paddingLeft":"paddingRight";this._element.style[t]=`${e}px`}if(!i&&t){const t=Yt()?"paddingRight":"paddingLeft";this._element.style[t]=`${e}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=On.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}ue.on(document,yn,'[data-bs-toggle="modal"]',(function(t){const e=ye.getElementFromSelector(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),ue.one(e,pn,(t=>{t.defaultPrevented||ue.one(e,fn,(()=>{Ht(this)&&this.focus()}))}));const i=ye.findOne(".modal.show");i&&On.getInstance(i).hide(),On.getOrCreateInstance(e).toggle(this)})),we(On),Kt(On);const xn=".bs.offcanvas",kn=".data-api",Ln=`load${xn}${kn}`,Sn="show",Dn="showing",$n="hiding",In=".offcanvas.show",Nn=`show${xn}`,Pn=`shown${xn}`,Mn=`hide${xn}`,jn=`hidePrevented${xn}`,Fn=`hidden${xn}`,Hn=`resize${xn}`,Bn=`click${xn}${kn}`,Wn=`keydown.dismiss${xn}`,zn={backdrop:!0,keyboard:!0,scroll:!1},Rn={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"};class qn extends be{constructor(t,e){super(t,e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return zn}static get DefaultType(){return Rn}static get NAME(){return"offcanvas"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||ue.trigger(this._element,Nn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._backdrop.show(),this._config.scroll||(new cn).hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add(Dn),this._queueCallback((()=>{this._config.scroll&&!this._config.backdrop||this._focustrap.activate(),this._element.classList.add(Sn),this._element.classList.remove(Dn),ue.trigger(this._element,Pn,{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(ue.trigger(this._element,Mn).defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add($n),this._backdrop.hide(),this._queueCallback((()=>{this._element.classList.remove(Sn,$n),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||(new cn).reset(),ue.trigger(this._element,Fn)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){const t=Boolean(this._config.backdrop);return new Ui({className:"offcanvas-backdrop",isVisible:t,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:t?()=>{"static"!==this._config.backdrop?this.hide():ue.trigger(this._element,jn)}:null})}_initializeFocusTrap(){return new sn({trapElement:this._element})}_addEventListeners(){ue.on(this._element,Wn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():ue.trigger(this._element,jn))}))}static jQueryInterface(t){return this.each((function(){const e=qn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}ue.on(document,Bn,'[data-bs-toggle="offcanvas"]',(function(t){const e=ye.getElementFromSelector(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),Bt(this))return;ue.one(e,Fn,(()=>{Ht(this)&&this.focus()}));const i=ye.findOne(In);i&&i!==e&&qn.getInstance(i).hide(),qn.getOrCreateInstance(e).toggle(this)})),ue.on(window,Ln,(()=>{for(const t of ye.find(In))qn.getOrCreateInstance(t).show()})),ue.on(window,Hn,(()=>{for(const t of ye.find("[aria-modal][class*=show][class*=offcanvas-]"))"fixed"!==getComputedStyle(t).position&&qn.getOrCreateInstance(t).hide()})),we(qn),Kt(qn);const Vn={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},Yn=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Kn=/^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i,Qn=(t,e)=>{const i=t.nodeName.toLowerCase();return e.includes(i)?!Yn.has(i)||Boolean(Kn.test(t.nodeValue)):e.filter((t=>t instanceof RegExp)).some((t=>t.test(i)))},Xn={allowList:Vn,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"
"},Un={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},Gn={entry:"(string|element|function|null)",selector:"(string|element)"};class Jn extends _e{constructor(t){super(),this._config=this._getConfig(t)}static get Default(){return Xn}static get DefaultType(){return Un}static get NAME(){return"TemplateFactory"}getContent(){return Object.values(this._config.content).map((t=>this._resolvePossibleFunction(t))).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(t){return this._checkContent(t),this._config.content={...this._config.content,...t},this}toHtml(){const t=document.createElement("div");t.innerHTML=this._maybeSanitize(this._config.template);for(const[e,i]of Object.entries(this._config.content))this._setContent(t,i,e);const e=t.children[0],i=this._resolvePossibleFunction(this._config.extraClass);return i&&e.classList.add(...i.split(" ")),e}_typeCheckConfig(t){super._typeCheckConfig(t),this._checkContent(t.content)}_checkContent(t){for(const[e,i]of Object.entries(t))super._typeCheckConfig({selector:e,entry:i},Gn)}_setContent(t,e,i){const n=ye.findOne(i,t);n&&((e=this._resolvePossibleFunction(e))?jt(e)?this._putElementInTemplate(Ft(e),n):this._config.html?n.innerHTML=this._maybeSanitize(e):n.textContent=e:n.remove())}_maybeSanitize(t){return this._config.sanitize?function(t,e,i){if(!t.length)return t;if(i&&"function"==typeof i)return i(t);const n=(new window.DOMParser).parseFromString(t,"text/html"),s=[].concat(...n.body.querySelectorAll("*"));for(const t of s){const i=t.nodeName.toLowerCase();if(!Object.keys(e).includes(i)){t.remove();continue}const n=[].concat(...t.attributes),s=[].concat(e["*"]||[],e[i]||[]);for(const e of n)Qn(e,s)||t.removeAttribute(e.nodeName)}return n.body.innerHTML}(t,this._config.allowList,this._config.sanitizeFn):t}_resolvePossibleFunction(t){return Qt(t,[this])}_putElementInTemplate(t,e){if(this._config.html)return e.innerHTML="",void e.append(t);e.textContent=t.textContent}}const Zn=new Set(["sanitize","allowList","sanitizeFn"]),ts="fade",es="show",is=".modal",ns="hide.bs.modal",ss="hover",os="focus",rs={AUTO:"auto",TOP:"top",RIGHT:Yt()?"left":"right",BOTTOM:"bottom",LEFT:Yt()?"right":"left"},as={allowList:Vn,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,6],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'',title:"",trigger:"hover focus"},ls={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"};class cs extends be{constructor(t,i){if(void 0===e)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t,i),this._isEnabled=!0,this._timeout=0,this._isHovered=null,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners(),this._config.selector||this._fixTitle()}static get Default(){return as}static get DefaultType(){return ls}static get NAME(){return"tooltip"}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(){this._isEnabled&&(this._activeTrigger.click=!this._activeTrigger.click,this._isShown()?this._leave():this._enter())}dispose(){clearTimeout(this._timeout),ue.off(this._element.closest(is),ns,this._hideModalHandler),this._element.getAttribute("data-bs-original-title")&&this._element.setAttribute("title",this._element.getAttribute("data-bs-original-title")),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this._isWithContent()||!this._isEnabled)return;const t=ue.trigger(this._element,this.constructor.eventName("show")),e=(Wt(this._element)||this._element.ownerDocument.documentElement).contains(this._element);if(t.defaultPrevented||!e)return;this._disposePopper();const i=this._getTipElement();this._element.setAttribute("aria-describedby",i.getAttribute("id"));const{container:n}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(n.append(i),ue.trigger(this._element,this.constructor.eventName("inserted"))),this._popper=this._createPopper(i),i.classList.add(es),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))ue.on(t,"mouseover",zt);this._queueCallback((()=>{ue.trigger(this._element,this.constructor.eventName("shown")),!1===this._isHovered&&this._leave(),this._isHovered=!1}),this.tip,this._isAnimated())}hide(){if(this._isShown()&&!ue.trigger(this._element,this.constructor.eventName("hide")).defaultPrevented){if(this._getTipElement().classList.remove(es),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))ue.off(t,"mouseover",zt);this._activeTrigger.click=!1,this._activeTrigger[os]=!1,this._activeTrigger[ss]=!1,this._isHovered=null,this._queueCallback((()=>{this._isWithActiveTrigger()||(this._isHovered||this._disposePopper(),this._element.removeAttribute("aria-describedby"),ue.trigger(this._element,this.constructor.eventName("hidden")))}),this.tip,this._isAnimated())}}update(){this._popper&&this._popper.update()}_isWithContent(){return Boolean(this._getTitle())}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(t){const e=this._getTemplateFactory(t).toHtml();if(!e)return null;e.classList.remove(ts,es),e.classList.add(`bs-${this.constructor.NAME}-auto`);const i=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME).toString();return e.setAttribute("id",i),this._isAnimated()&&e.classList.add(ts),e}setContent(t){this._newContent=t,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(t){return this._templateFactory?this._templateFactory.changeContent(t):this._templateFactory=new Jn({...this._config,content:t,extraClass:this._resolvePossibleFunction(this._config.customClass)}),this._templateFactory}_getContentForTemplate(){return{".tooltip-inner":this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute("data-bs-original-title")}_initializeOnDelegatedTarget(t){return this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(ts)}_isShown(){return this.tip&&this.tip.classList.contains(es)}_createPopper(t){const e=Qt(this._config.placement,[this,t,this._element]),i=rs[e.toUpperCase()];return St(this._element,t,this._getPopperConfig(i))}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return Qt(t,[this._element])}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:t=>{this._getTipElement().setAttribute("data-popper-placement",t.state.placement)}}]};return{...e,...Qt(this._config.popperConfig,[e])}}_setListeners(){const t=this._config.trigger.split(" ");for(const e of t)if("click"===e)ue.on(this._element,this.constructor.eventName("click"),this._config.selector,(t=>{this._initializeOnDelegatedTarget(t).toggle()}));else if("manual"!==e){const t=e===ss?this.constructor.eventName("mouseenter"):this.constructor.eventName("focusin"),i=e===ss?this.constructor.eventName("mouseleave"):this.constructor.eventName("focusout");ue.on(this._element,t,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusin"===t.type?os:ss]=!0,e._enter()})),ue.on(this._element,i,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusout"===t.type?os:ss]=e._element.contains(t.relatedTarget),e._leave()}))}this._hideModalHandler=()=>{this._element&&this.hide()},ue.on(this._element.closest(is),ns,this._hideModalHandler)}_fixTitle(){const t=this._element.getAttribute("title");t&&(this._element.getAttribute("aria-label")||this._element.textContent.trim()||this._element.setAttribute("aria-label",t),this._element.setAttribute("data-bs-original-title",t),this._element.removeAttribute("title"))}_enter(){this._isShown()||this._isHovered?this._isHovered=!0:(this._isHovered=!0,this._setTimeout((()=>{this._isHovered&&this.show()}),this._config.delay.show))}_leave(){this._isWithActiveTrigger()||(this._isHovered=!1,this._setTimeout((()=>{this._isHovered||this.hide()}),this._config.delay.hide))}_setTimeout(t,e){clearTimeout(this._timeout),this._timeout=setTimeout(t,e)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(t){const e=ge.getDataAttributes(this._element);for(const t of Object.keys(e))Zn.has(t)&&delete e[t];return t={...e,..."object"==typeof t&&t?t:{}},t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t.container=!1===t.container?document.body:Ft(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),t}_getDelegateConfig(){const t={};for(const[e,i]of Object.entries(this._config))this.constructor.Default[e]!==i&&(t[e]=i);return t.selector=!1,t.trigger="manual",t}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null),this.tip&&(this.tip.remove(),this.tip=null)}static jQueryInterface(t){return this.each((function(){const e=cs.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}Kt(cs);const hs={...cs.Default,content:"",offset:[0,8],placement:"right",template:'',trigger:"click"},ds={...cs.DefaultType,content:"(null|string|element|function)"};class us extends cs{static get Default(){return hs}static get DefaultType(){return ds}static get NAME(){return"popover"}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{".popover-header":this._getTitle(),".popover-body":this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(t){return this.each((function(){const e=us.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}Kt(us);const fs=".bs.scrollspy",ps=`activate${fs}`,ms=`click${fs}`,gs=`load${fs}.data-api`,_s="active",bs="[href]",vs=".nav-link",ys=`${vs}, .nav-item > ${vs}, .list-group-item`,ws={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null,threshold:[.1,.5,1]},Es={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element",threshold:"array"};class As extends be{constructor(t,e){super(t,e),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement="visible"===getComputedStyle(this._element).overflowY?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return ws}static get DefaultType(){return Es}static get NAME(){return"scrollspy"}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(const t of this._observableSections.values())this._observer.observe(t)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(t){return t.target=Ft(t.target)||document.body,t.rootMargin=t.offset?`${t.offset}px 0px -30%`:t.rootMargin,"string"==typeof t.threshold&&(t.threshold=t.threshold.split(",").map((t=>Number.parseFloat(t)))),t}_maybeEnableSmoothScroll(){this._config.smoothScroll&&(ue.off(this._config.target,ms),ue.on(this._config.target,ms,bs,(t=>{const e=this._observableSections.get(t.target.hash);if(e){t.preventDefault();const i=this._rootElement||window,n=e.offsetTop-this._element.offsetTop;if(i.scrollTo)return void i.scrollTo({top:n,behavior:"smooth"});i.scrollTop=n}})))}_getNewObserver(){const t={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver((t=>this._observerCallback(t)),t)}_observerCallback(t){const e=t=>this._targetLinks.get(`#${t.target.id}`),i=t=>{this._previousScrollData.visibleEntryTop=t.target.offsetTop,this._process(e(t))},n=(this._rootElement||document.documentElement).scrollTop,s=n>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=n;for(const o of t){if(!o.isIntersecting){this._activeTarget=null,this._clearActiveClass(e(o));continue}const t=o.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(s&&t){if(i(o),!n)return}else s||t||i(o)}}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;const t=ye.find(bs,this._config.target);for(const e of t){if(!e.hash||Bt(e))continue;const t=ye.findOne(decodeURI(e.hash),this._element);Ht(t)&&(this._targetLinks.set(decodeURI(e.hash),e),this._observableSections.set(e.hash,t))}}_process(t){this._activeTarget!==t&&(this._clearActiveClass(this._config.target),this._activeTarget=t,t.classList.add(_s),this._activateParents(t),ue.trigger(this._element,ps,{relatedTarget:t}))}_activateParents(t){if(t.classList.contains("dropdown-item"))ye.findOne(".dropdown-toggle",t.closest(".dropdown")).classList.add(_s);else for(const e of ye.parents(t,".nav, .list-group"))for(const t of ye.prev(e,ys))t.classList.add(_s)}_clearActiveClass(t){t.classList.remove(_s);const e=ye.find(`${bs}.${_s}`,t);for(const t of e)t.classList.remove(_s)}static jQueryInterface(t){return this.each((function(){const e=As.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}ue.on(window,gs,(()=>{for(const t of ye.find('[data-bs-spy="scroll"]'))As.getOrCreateInstance(t)})),Kt(As);const Ts=".bs.tab",Cs=`hide${Ts}`,Os=`hidden${Ts}`,xs=`show${Ts}`,ks=`shown${Ts}`,Ls=`click${Ts}`,Ss=`keydown${Ts}`,Ds=`load${Ts}`,$s="ArrowLeft",Is="ArrowRight",Ns="ArrowUp",Ps="ArrowDown",Ms="Home",js="End",Fs="active",Hs="fade",Bs="show",Ws=".dropdown-toggle",zs=`:not(${Ws})`,Rs='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',qs=`.nav-link${zs}, .list-group-item${zs}, [role="tab"]${zs}, ${Rs}`,Vs=`.${Fs}[data-bs-toggle="tab"], .${Fs}[data-bs-toggle="pill"], .${Fs}[data-bs-toggle="list"]`;class Ys extends be{constructor(t){super(t),this._parent=this._element.closest('.list-group, .nav, [role="tablist"]'),this._parent&&(this._setInitialAttributes(this._parent,this._getChildren()),ue.on(this._element,Ss,(t=>this._keydown(t))))}static get NAME(){return"tab"}show(){const t=this._element;if(this._elemIsActive(t))return;const e=this._getActiveElem(),i=e?ue.trigger(e,Cs,{relatedTarget:t}):null;ue.trigger(t,xs,{relatedTarget:e}).defaultPrevented||i&&i.defaultPrevented||(this._deactivate(e,t),this._activate(t,e))}_activate(t,e){t&&(t.classList.add(Fs),this._activate(ye.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.removeAttribute("tabindex"),t.setAttribute("aria-selected",!0),this._toggleDropDown(t,!0),ue.trigger(t,ks,{relatedTarget:e})):t.classList.add(Bs)}),t,t.classList.contains(Hs)))}_deactivate(t,e){t&&(t.classList.remove(Fs),t.blur(),this._deactivate(ye.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.setAttribute("aria-selected",!1),t.setAttribute("tabindex","-1"),this._toggleDropDown(t,!1),ue.trigger(t,Os,{relatedTarget:e})):t.classList.remove(Bs)}),t,t.classList.contains(Hs)))}_keydown(t){if(![$s,Is,Ns,Ps,Ms,js].includes(t.key))return;t.stopPropagation(),t.preventDefault();const e=this._getChildren().filter((t=>!Bt(t)));let i;if([Ms,js].includes(t.key))i=e[t.key===Ms?0:e.length-1];else{const n=[Is,Ps].includes(t.key);i=Ut(e,t.target,n,!0)}i&&(i.focus({preventScroll:!0}),Ys.getOrCreateInstance(i).show())}_getChildren(){return ye.find(qs,this._parent)}_getActiveElem(){return this._getChildren().find((t=>this._elemIsActive(t)))||null}_setInitialAttributes(t,e){this._setAttributeIfNotExists(t,"role","tablist");for(const t of e)this._setInitialAttributesOnChild(t)}_setInitialAttributesOnChild(t){t=this._getInnerElement(t);const e=this._elemIsActive(t),i=this._getOuterElement(t);t.setAttribute("aria-selected",e),i!==t&&this._setAttributeIfNotExists(i,"role","presentation"),e||t.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(t,"role","tab"),this._setInitialAttributesOnTargetPanel(t)}_setInitialAttributesOnTargetPanel(t){const e=ye.getElementFromSelector(t);e&&(this._setAttributeIfNotExists(e,"role","tabpanel"),t.id&&this._setAttributeIfNotExists(e,"aria-labelledby",`${t.id}`))}_toggleDropDown(t,e){const i=this._getOuterElement(t);if(!i.classList.contains("dropdown"))return;const n=(t,n)=>{const s=ye.findOne(t,i);s&&s.classList.toggle(n,e)};n(Ws,Fs),n(".dropdown-menu",Bs),i.setAttribute("aria-expanded",e)}_setAttributeIfNotExists(t,e,i){t.hasAttribute(e)||t.setAttribute(e,i)}_elemIsActive(t){return t.classList.contains(Fs)}_getInnerElement(t){return t.matches(qs)?t:ye.findOne(qs,t)}_getOuterElement(t){return t.closest(".nav-item, .list-group-item")||t}static jQueryInterface(t){return this.each((function(){const e=Ys.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}ue.on(document,Ls,Rs,(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),Bt(this)||Ys.getOrCreateInstance(this).show()})),ue.on(window,Ds,(()=>{for(const t of ye.find(Vs))Ys.getOrCreateInstance(t)})),Kt(Ys);const Ks=".bs.toast",Qs=`mouseover${Ks}`,Xs=`mouseout${Ks}`,Us=`focusin${Ks}`,Gs=`focusout${Ks}`,Js=`hide${Ks}`,Zs=`hidden${Ks}`,to=`show${Ks}`,eo=`shown${Ks}`,io="hide",no="show",so="showing",oo={animation:"boolean",autohide:"boolean",delay:"number"},ro={animation:!0,autohide:!0,delay:5e3};class ao extends be{constructor(t,e){super(t,e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return ro}static get DefaultType(){return oo}static get NAME(){return"toast"}show(){ue.trigger(this._element,to).defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(io),Rt(this._element),this._element.classList.add(no,so),this._queueCallback((()=>{this._element.classList.remove(so),ue.trigger(this._element,eo),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this.isShown()&&(ue.trigger(this._element,Js).defaultPrevented||(this._element.classList.add(so),this._queueCallback((()=>{this._element.classList.add(io),this._element.classList.remove(so,no),ue.trigger(this._element,Zs)}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(no),super.dispose()}isShown(){return this._element.classList.contains(no)}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){ue.on(this._element,Qs,(t=>this._onInteraction(t,!0))),ue.on(this._element,Xs,(t=>this._onInteraction(t,!1))),ue.on(this._element,Us,(t=>this._onInteraction(t,!0))),ue.on(this._element,Gs,(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=ao.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}function lo(t){"loading"!=document.readyState?t():document.addEventListener("DOMContentLoaded",t)}we(ao),Kt(ao),lo((function(){[].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]')).map((function(t){return new cs(t,{delay:{show:500,hide:100}})}))})),lo((function(){document.getElementById("pst-back-to-top").addEventListener("click",(function(){document.body.scrollTop=0,document.documentElement.scrollTop=0}))})),lo((function(){var t=document.getElementById("pst-back-to-top"),e=document.getElementsByClassName("bd-header")[0].getBoundingClientRect();window.addEventListener("scroll",(function(){this.oldScroll>this.scrollY&&this.scrollY>e.bottom?t.style.display="block":t.style.display="none",this.oldScroll=this.scrollY}))}))})(); -//# sourceMappingURL=bootstrap.js.map \ No newline at end of file diff --git a/docs/_build/html/_static/scripts/bootstrap.js.LICENSE.txt b/docs/_build/html/_static/scripts/bootstrap.js.LICENSE.txt deleted file mode 100644 index 10f979d..0000000 --- a/docs/_build/html/_static/scripts/bootstrap.js.LICENSE.txt +++ /dev/null @@ -1,5 +0,0 @@ -/*! - * Bootstrap v5.3.2 (https://getbootstrap.com/) - * Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - */ diff --git a/docs/_build/html/_static/scripts/bootstrap.js.map b/docs/_build/html/_static/scripts/bootstrap.js.map deleted file mode 100644 index e5bc157..0000000 --- a/docs/_build/html/_static/scripts/bootstrap.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"scripts/bootstrap.js","mappings":";mBACA,IAAIA,EAAsB,CCA1BA,EAAwB,CAACC,EAASC,KACjC,IAAI,IAAIC,KAAOD,EACXF,EAAoBI,EAAEF,EAAYC,KAASH,EAAoBI,EAAEH,EAASE,IAC5EE,OAAOC,eAAeL,EAASE,EAAK,CAAEI,YAAY,EAAMC,IAAKN,EAAWC,IAE1E,ECNDH,EAAwB,CAACS,EAAKC,IAAUL,OAAOM,UAAUC,eAAeC,KAAKJ,EAAKC,GCClFV,EAAyBC,IACH,oBAAXa,QAA0BA,OAAOC,aAC1CV,OAAOC,eAAeL,EAASa,OAAOC,YAAa,CAAEC,MAAO,WAE7DX,OAAOC,eAAeL,EAAS,aAAc,CAAEe,OAAO,GAAO,ipBCLvD,IAAI,EAAM,MACNC,EAAS,SACTC,EAAQ,QACRC,EAAO,OACPC,EAAO,OACPC,EAAiB,CAAC,EAAKJ,EAAQC,EAAOC,GACtCG,EAAQ,QACRC,EAAM,MACNC,EAAkB,kBAClBC,EAAW,WACXC,EAAS,SACTC,EAAY,YACZC,EAAmCP,EAAeQ,QAAO,SAAUC,EAAKC,GACjF,OAAOD,EAAIE,OAAO,CAACD,EAAY,IAAMT,EAAOS,EAAY,IAAMR,GAChE,GAAG,IACQ,EAA0B,GAAGS,OAAOX,EAAgB,CAACD,IAAOS,QAAO,SAAUC,EAAKC,GAC3F,OAAOD,EAAIE,OAAO,CAACD,EAAWA,EAAY,IAAMT,EAAOS,EAAY,IAAMR,GAC3E,GAAG,IAEQU,EAAa,aACbC,EAAO,OACPC,EAAY,YAEZC,EAAa,aACbC,EAAO,OACPC,EAAY,YAEZC,EAAc,cACdC,EAAQ,QACRC,EAAa,aACbC,EAAiB,CAACT,EAAYC,EAAMC,EAAWC,EAAYC,EAAMC,EAAWC,EAAaC,EAAOC,GC9B5F,SAASE,EAAYC,GAClC,OAAOA,GAAWA,EAAQC,UAAY,IAAIC,cAAgB,IAC5D,CCFe,SAASC,EAAUC,GAChC,GAAY,MAARA,EACF,OAAOC,OAGT,GAAwB,oBAApBD,EAAKE,WAAkC,CACzC,IAAIC,EAAgBH,EAAKG,cACzB,OAAOA,GAAgBA,EAAcC,aAAwBH,MAC/D,CAEA,OAAOD,CACT,CCTA,SAASK,EAAUL,GAEjB,OAAOA,aADUD,EAAUC,GAAMM,SACIN,aAAgBM,OACvD,CAEA,SAASC,EAAcP,GAErB,OAAOA,aADUD,EAAUC,GAAMQ,aACIR,aAAgBQ,WACvD,CAEA,SAASC,EAAaT,GAEpB,MAA0B,oBAAfU,aAKJV,aADUD,EAAUC,GAAMU,YACIV,aAAgBU,WACvD,CCwDA,SACEC,KAAM,cACNC,SAAS,EACTC,MAAO,QACPC,GA5EF,SAAqBC,GACnB,IAAIC,EAAQD,EAAKC,MACjB3D,OAAO4D,KAAKD,EAAME,UAAUC,SAAQ,SAAUR,GAC5C,IAAIS,EAAQJ,EAAMK,OAAOV,IAAS,CAAC,EAC/BW,EAAaN,EAAMM,WAAWX,IAAS,CAAC,EACxCf,EAAUoB,EAAME,SAASP,GAExBJ,EAAcX,IAAaD,EAAYC,KAO5CvC,OAAOkE,OAAO3B,EAAQwB,MAAOA,GAC7B/D,OAAO4D,KAAKK,GAAYH,SAAQ,SAAUR,GACxC,IAAI3C,EAAQsD,EAAWX,IAET,IAAV3C,EACF4B,EAAQ4B,gBAAgBb,GAExBf,EAAQ6B,aAAad,GAAgB,IAAV3C,EAAiB,GAAKA,EAErD,IACF,GACF,EAoDE0D,OAlDF,SAAgBC,GACd,IAAIX,EAAQW,EAAMX,MACdY,EAAgB,CAClBlD,OAAQ,CACNmD,SAAUb,EAAMc,QAAQC,SACxB5D,KAAM,IACN6D,IAAK,IACLC,OAAQ,KAEVC,MAAO,CACLL,SAAU,YAEZlD,UAAW,CAAC,GASd,OAPAtB,OAAOkE,OAAOP,EAAME,SAASxC,OAAO0C,MAAOQ,EAAclD,QACzDsC,EAAMK,OAASO,EAEXZ,EAAME,SAASgB,OACjB7E,OAAOkE,OAAOP,EAAME,SAASgB,MAAMd,MAAOQ,EAAcM,OAGnD,WACL7E,OAAO4D,KAAKD,EAAME,UAAUC,SAAQ,SAAUR,GAC5C,IAAIf,EAAUoB,EAAME,SAASP,GACzBW,EAAaN,EAAMM,WAAWX,IAAS,CAAC,EAGxCS,EAFkB/D,OAAO4D,KAAKD,EAAMK,OAAOzD,eAAe+C,GAAQK,EAAMK,OAAOV,GAAQiB,EAAcjB,IAE7E9B,QAAO,SAAUuC,EAAOe,GAElD,OADAf,EAAMe,GAAY,GACXf,CACT,GAAG,CAAC,GAECb,EAAcX,IAAaD,EAAYC,KAI5CvC,OAAOkE,OAAO3B,EAAQwB,MAAOA,GAC7B/D,OAAO4D,KAAKK,GAAYH,SAAQ,SAAUiB,GACxCxC,EAAQ4B,gBAAgBY,EAC1B,IACF,GACF,CACF,EASEC,SAAU,CAAC,kBCjFE,SAASC,EAAiBvD,GACvC,OAAOA,EAAUwD,MAAM,KAAK,EAC9B,CCHO,IAAI,EAAMC,KAAKC,IACX,EAAMD,KAAKE,IACXC,EAAQH,KAAKG,MCFT,SAASC,IACtB,IAAIC,EAASC,UAAUC,cAEvB,OAAc,MAAVF,GAAkBA,EAAOG,QAAUC,MAAMC,QAAQL,EAAOG,QACnDH,EAAOG,OAAOG,KAAI,SAAUC,GACjC,OAAOA,EAAKC,MAAQ,IAAMD,EAAKE,OACjC,IAAGC,KAAK,KAGHT,UAAUU,SACnB,CCTe,SAASC,IACtB,OAAQ,iCAAiCC,KAAKd,IAChD,CCCe,SAASe,EAAsB/D,EAASgE,EAAcC,QAC9C,IAAjBD,IACFA,GAAe,QAGO,IAApBC,IACFA,GAAkB,GAGpB,IAAIC,EAAalE,EAAQ+D,wBACrBI,EAAS,EACTC,EAAS,EAETJ,GAAgBrD,EAAcX,KAChCmE,EAASnE,EAAQqE,YAAc,GAAItB,EAAMmB,EAAWI,OAAStE,EAAQqE,aAAmB,EACxFD,EAASpE,EAAQuE,aAAe,GAAIxB,EAAMmB,EAAWM,QAAUxE,EAAQuE,cAAoB,GAG7F,IACIE,GADOhE,EAAUT,GAAWG,EAAUH,GAAWK,QAC3BoE,eAEtBC,GAAoBb,KAAsBI,EAC1CU,GAAKT,EAAW3F,MAAQmG,GAAoBD,EAAiBA,EAAeG,WAAa,IAAMT,EAC/FU,GAAKX,EAAW9B,KAAOsC,GAAoBD,EAAiBA,EAAeK,UAAY,IAAMV,EAC7FE,EAAQJ,EAAWI,MAAQH,EAC3BK,EAASN,EAAWM,OAASJ,EACjC,MAAO,CACLE,MAAOA,EACPE,OAAQA,EACRpC,IAAKyC,EACLvG,MAAOqG,EAAIL,EACXjG,OAAQwG,EAAIL,EACZjG,KAAMoG,EACNA,EAAGA,EACHE,EAAGA,EAEP,CCrCe,SAASE,EAAc/E,GACpC,IAAIkE,EAAaH,EAAsB/D,GAGnCsE,EAAQtE,EAAQqE,YAChBG,EAASxE,EAAQuE,aAUrB,OARI3B,KAAKoC,IAAId,EAAWI,MAAQA,IAAU,IACxCA,EAAQJ,EAAWI,OAGjB1B,KAAKoC,IAAId,EAAWM,OAASA,IAAW,IAC1CA,EAASN,EAAWM,QAGf,CACLG,EAAG3E,EAAQ4E,WACXC,EAAG7E,EAAQ8E,UACXR,MAAOA,EACPE,OAAQA,EAEZ,CCvBe,SAASS,EAASC,EAAQC,GACvC,IAAIC,EAAWD,EAAME,aAAeF,EAAME,cAE1C,GAAIH,EAAOD,SAASE,GAClB,OAAO,EAEJ,GAAIC,GAAYvE,EAAauE,GAAW,CACzC,IAAIE,EAAOH,EAEX,EAAG,CACD,GAAIG,GAAQJ,EAAOK,WAAWD,GAC5B,OAAO,EAITA,EAAOA,EAAKE,YAAcF,EAAKG,IACjC,OAASH,EACX,CAGF,OAAO,CACT,CCrBe,SAAS,EAAiBtF,GACvC,OAAOG,EAAUH,GAAS0F,iBAAiB1F,EAC7C,CCFe,SAAS2F,EAAe3F,GACrC,MAAO,CAAC,QAAS,KAAM,MAAM4F,QAAQ7F,EAAYC,KAAa,CAChE,CCFe,SAAS6F,EAAmB7F,GAEzC,QAASS,EAAUT,GAAWA,EAAQO,cACtCP,EAAQ8F,WAAazF,OAAOyF,UAAUC,eACxC,CCFe,SAASC,EAAchG,GACpC,MAA6B,SAAzBD,EAAYC,GACPA,EAMPA,EAAQiG,cACRjG,EAAQwF,aACR3E,EAAab,GAAWA,EAAQyF,KAAO,OAEvCI,EAAmB7F,EAGvB,CCVA,SAASkG,EAAoBlG,GAC3B,OAAKW,EAAcX,IACoB,UAAvC,EAAiBA,GAASiC,SAInBjC,EAAQmG,aAHN,IAIX,CAwCe,SAASC,EAAgBpG,GAItC,IAHA,IAAIK,EAASF,EAAUH,GACnBmG,EAAeD,EAAoBlG,GAEhCmG,GAAgBR,EAAeQ,IAA6D,WAA5C,EAAiBA,GAAclE,UACpFkE,EAAeD,EAAoBC,GAGrC,OAAIA,IAA+C,SAA9BpG,EAAYoG,IAA0D,SAA9BpG,EAAYoG,IAAwE,WAA5C,EAAiBA,GAAclE,UAC3H5B,EAGF8F,GAhDT,SAA4BnG,GAC1B,IAAIqG,EAAY,WAAWvC,KAAKd,KAGhC,GAFW,WAAWc,KAAKd,MAEfrC,EAAcX,IAII,UAFX,EAAiBA,GAEnBiC,SACb,OAAO,KAIX,IAAIqE,EAAcN,EAAchG,GAMhC,IAJIa,EAAayF,KACfA,EAAcA,EAAYb,MAGrB9E,EAAc2F,IAAgB,CAAC,OAAQ,QAAQV,QAAQ7F,EAAYuG,IAAgB,GAAG,CAC3F,IAAIC,EAAM,EAAiBD,GAI3B,GAAsB,SAAlBC,EAAIC,WAA4C,SAApBD,EAAIE,aAA0C,UAAhBF,EAAIG,UAAiF,IAA1D,CAAC,YAAa,eAAed,QAAQW,EAAII,aAAsBN,GAAgC,WAAnBE,EAAII,YAA2BN,GAAaE,EAAIK,QAAyB,SAAfL,EAAIK,OACjO,OAAON,EAEPA,EAAcA,EAAYd,UAE9B,CAEA,OAAO,IACT,CAgByBqB,CAAmB7G,IAAYK,CACxD,CCpEe,SAASyG,EAAyB3H,GAC/C,MAAO,CAAC,MAAO,UAAUyG,QAAQzG,IAAc,EAAI,IAAM,GAC3D,CCDO,SAAS4H,EAAOjE,EAAK1E,EAAOyE,GACjC,OAAO,EAAQC,EAAK,EAAQ1E,EAAOyE,GACrC,CCFe,SAASmE,EAAmBC,GACzC,OAAOxJ,OAAOkE,OAAO,CAAC,ECDf,CACLS,IAAK,EACL9D,MAAO,EACPD,OAAQ,EACRE,KAAM,GDHuC0I,EACjD,CEHe,SAASC,EAAgB9I,EAAOiD,GAC7C,OAAOA,EAAKpC,QAAO,SAAUkI,EAAS5J,GAEpC,OADA4J,EAAQ5J,GAAOa,EACR+I,CACT,GAAG,CAAC,EACN,CC4EA,SACEpG,KAAM,QACNC,SAAS,EACTC,MAAO,OACPC,GApEF,SAAeC,GACb,IAAIiG,EAEAhG,EAAQD,EAAKC,MACbL,EAAOI,EAAKJ,KACZmB,EAAUf,EAAKe,QACfmF,EAAejG,EAAME,SAASgB,MAC9BgF,EAAgBlG,EAAMmG,cAAcD,cACpCE,EAAgB9E,EAAiBtB,EAAMjC,WACvCsI,EAAOX,EAAyBU,GAEhCE,EADa,CAACnJ,EAAMD,GAAOsH,QAAQ4B,IAAkB,EAClC,SAAW,QAElC,GAAKH,GAAiBC,EAAtB,CAIA,IAAIL,EAxBgB,SAAyBU,EAASvG,GAItD,OAAO4F,EAAsC,iBAH7CW,EAA6B,mBAAZA,EAAyBA,EAAQlK,OAAOkE,OAAO,CAAC,EAAGP,EAAMwG,MAAO,CAC/EzI,UAAWiC,EAAMjC,aACbwI,GACkDA,EAAUT,EAAgBS,EAASlJ,GAC7F,CAmBsBoJ,CAAgB3F,EAAQyF,QAASvG,GACjD0G,EAAY/C,EAAcsC,GAC1BU,EAAmB,MAATN,EAAe,EAAMlJ,EAC/ByJ,EAAmB,MAATP,EAAepJ,EAASC,EAClC2J,EAAU7G,EAAMwG,MAAM7I,UAAU2I,GAAOtG,EAAMwG,MAAM7I,UAAU0I,GAAQH,EAAcG,GAAQrG,EAAMwG,MAAM9I,OAAO4I,GAC9GQ,EAAYZ,EAAcG,GAAQrG,EAAMwG,MAAM7I,UAAU0I,GACxDU,EAAoB/B,EAAgBiB,GACpCe,EAAaD,EAA6B,MAATV,EAAeU,EAAkBE,cAAgB,EAAIF,EAAkBG,aAAe,EAAI,EAC3HC,EAAoBN,EAAU,EAAIC,EAAY,EAG9CpF,EAAMmE,EAAcc,GACpBlF,EAAMuF,EAAaN,EAAUJ,GAAOT,EAAce,GAClDQ,EAASJ,EAAa,EAAIN,EAAUJ,GAAO,EAAIa,EAC/CE,EAAS1B,EAAOjE,EAAK0F,EAAQ3F,GAE7B6F,EAAWjB,EACfrG,EAAMmG,cAAcxG,KAASqG,EAAwB,CAAC,GAAyBsB,GAAYD,EAAQrB,EAAsBuB,aAAeF,EAASD,EAAQpB,EAnBzJ,CAoBF,EAkCEtF,OAhCF,SAAgBC,GACd,IAAIX,EAAQW,EAAMX,MAEdwH,EADU7G,EAAMG,QACWlC,QAC3BqH,OAAoC,IAArBuB,EAA8B,sBAAwBA,EAErD,MAAhBvB,IAKwB,iBAAjBA,IACTA,EAAejG,EAAME,SAASxC,OAAO+J,cAAcxB,MAOhDpC,EAAS7D,EAAME,SAASxC,OAAQuI,KAIrCjG,EAAME,SAASgB,MAAQ+E,EACzB,EASE5E,SAAU,CAAC,iBACXqG,iBAAkB,CAAC,oBCxFN,SAASC,EAAa5J,GACnC,OAAOA,EAAUwD,MAAM,KAAK,EAC9B,CCOA,IAAIqG,EAAa,CACf5G,IAAK,OACL9D,MAAO,OACPD,OAAQ,OACRE,KAAM,QAeD,SAAS0K,GAAYlH,GAC1B,IAAImH,EAEApK,EAASiD,EAAMjD,OACfqK,EAAapH,EAAMoH,WACnBhK,EAAY4C,EAAM5C,UAClBiK,EAAYrH,EAAMqH,UAClBC,EAAUtH,EAAMsH,QAChBpH,EAAWF,EAAME,SACjBqH,EAAkBvH,EAAMuH,gBACxBC,EAAWxH,EAAMwH,SACjBC,EAAezH,EAAMyH,aACrBC,EAAU1H,EAAM0H,QAChBC,EAAaL,EAAQ1E,EACrBA,OAAmB,IAAf+E,EAAwB,EAAIA,EAChCC,EAAaN,EAAQxE,EACrBA,OAAmB,IAAf8E,EAAwB,EAAIA,EAEhCC,EAAgC,mBAAjBJ,EAA8BA,EAAa,CAC5D7E,EAAGA,EACHE,IACG,CACHF,EAAGA,EACHE,GAGFF,EAAIiF,EAAMjF,EACVE,EAAI+E,EAAM/E,EACV,IAAIgF,EAAOR,EAAQrL,eAAe,KAC9B8L,EAAOT,EAAQrL,eAAe,KAC9B+L,EAAQxL,EACRyL,EAAQ,EACRC,EAAM5J,OAEV,GAAIkJ,EAAU,CACZ,IAAIpD,EAAeC,EAAgBtH,GAC/BoL,EAAa,eACbC,EAAY,cAEZhE,IAAiBhG,EAAUrB,IAGmB,WAA5C,EAFJqH,EAAeN,EAAmB/G,IAECmD,UAAsC,aAAbA,IAC1DiI,EAAa,eACbC,EAAY,gBAOZhL,IAAc,IAAQA,IAAcZ,GAAQY,IAAcb,IAAU8K,IAAczK,KACpFqL,EAAQ3L,EAGRwG,IAFc4E,GAAWtD,IAAiB8D,GAAOA,EAAIxF,eAAiBwF,EAAIxF,eAAeD,OACzF2B,EAAa+D,IACEf,EAAW3E,OAC1BK,GAAKyE,EAAkB,GAAK,GAG1BnK,IAAcZ,IAASY,IAAc,GAAOA,IAAcd,GAAW+K,IAAczK,KACrFoL,EAAQzL,EAGRqG,IAFc8E,GAAWtD,IAAiB8D,GAAOA,EAAIxF,eAAiBwF,EAAIxF,eAAeH,MACzF6B,EAAagE,IACEhB,EAAW7E,MAC1BK,GAAK2E,EAAkB,GAAK,EAEhC,CAEA,IAgBMc,EAhBFC,EAAe5M,OAAOkE,OAAO,CAC/BM,SAAUA,GACTsH,GAAYP,GAEXsB,GAAyB,IAAjBd,EAlFd,SAA2BrI,EAAM8I,GAC/B,IAAItF,EAAIxD,EAAKwD,EACTE,EAAI1D,EAAK0D,EACT0F,EAAMN,EAAIO,kBAAoB,EAClC,MAAO,CACL7F,EAAG5B,EAAM4B,EAAI4F,GAAOA,GAAO,EAC3B1F,EAAG9B,EAAM8B,EAAI0F,GAAOA,GAAO,EAE/B,CA0EsCE,CAAkB,CACpD9F,EAAGA,EACHE,GACC1E,EAAUrB,IAAW,CACtB6F,EAAGA,EACHE,GAMF,OAHAF,EAAI2F,EAAM3F,EACVE,EAAIyF,EAAMzF,EAENyE,EAGK7L,OAAOkE,OAAO,CAAC,EAAG0I,IAAeD,EAAiB,CAAC,GAAkBJ,GAASF,EAAO,IAAM,GAAIM,EAAeL,GAASF,EAAO,IAAM,GAAIO,EAAe5D,WAAayD,EAAIO,kBAAoB,IAAM,EAAI,aAAe7F,EAAI,OAASE,EAAI,MAAQ,eAAiBF,EAAI,OAASE,EAAI,SAAUuF,IAG5R3M,OAAOkE,OAAO,CAAC,EAAG0I,IAAenB,EAAkB,CAAC,GAAmBc,GAASF,EAAOjF,EAAI,KAAO,GAAIqE,EAAgBa,GAASF,EAAOlF,EAAI,KAAO,GAAIuE,EAAgB1C,UAAY,GAAI0C,GAC9L,CA4CA,UACEnI,KAAM,gBACNC,SAAS,EACTC,MAAO,cACPC,GA9CF,SAAuBwJ,GACrB,IAAItJ,EAAQsJ,EAAMtJ,MACdc,EAAUwI,EAAMxI,QAChByI,EAAwBzI,EAAQoH,gBAChCA,OAA4C,IAA1BqB,GAA0CA,EAC5DC,EAAoB1I,EAAQqH,SAC5BA,OAAiC,IAAtBqB,GAAsCA,EACjDC,EAAwB3I,EAAQsH,aAChCA,OAAyC,IAA1BqB,GAA0CA,EACzDR,EAAe,CACjBlL,UAAWuD,EAAiBtB,EAAMjC,WAClCiK,UAAWL,EAAa3H,EAAMjC,WAC9BL,OAAQsC,EAAME,SAASxC,OACvBqK,WAAY/H,EAAMwG,MAAM9I,OACxBwK,gBAAiBA,EACjBG,QAAoC,UAA3BrI,EAAMc,QAAQC,UAGgB,MAArCf,EAAMmG,cAAcD,gBACtBlG,EAAMK,OAAO3C,OAASrB,OAAOkE,OAAO,CAAC,EAAGP,EAAMK,OAAO3C,OAAQmK,GAAYxL,OAAOkE,OAAO,CAAC,EAAG0I,EAAc,CACvGhB,QAASjI,EAAMmG,cAAcD,cAC7BrF,SAAUb,EAAMc,QAAQC,SACxBoH,SAAUA,EACVC,aAAcA,OAIe,MAA7BpI,EAAMmG,cAAcjF,QACtBlB,EAAMK,OAAOa,MAAQ7E,OAAOkE,OAAO,CAAC,EAAGP,EAAMK,OAAOa,MAAO2G,GAAYxL,OAAOkE,OAAO,CAAC,EAAG0I,EAAc,CACrGhB,QAASjI,EAAMmG,cAAcjF,MAC7BL,SAAU,WACVsH,UAAU,EACVC,aAAcA,OAIlBpI,EAAMM,WAAW5C,OAASrB,OAAOkE,OAAO,CAAC,EAAGP,EAAMM,WAAW5C,OAAQ,CACnE,wBAAyBsC,EAAMjC,WAEnC,EAQE2L,KAAM,CAAC,GCrKT,IAAIC,GAAU,CACZA,SAAS,GAsCX,UACEhK,KAAM,iBACNC,SAAS,EACTC,MAAO,QACPC,GAAI,WAAe,EACnBY,OAxCF,SAAgBX,GACd,IAAIC,EAAQD,EAAKC,MACb4J,EAAW7J,EAAK6J,SAChB9I,EAAUf,EAAKe,QACf+I,EAAkB/I,EAAQgJ,OAC1BA,OAA6B,IAApBD,GAAoCA,EAC7CE,EAAkBjJ,EAAQkJ,OAC1BA,OAA6B,IAApBD,GAAoCA,EAC7C9K,EAASF,EAAUiB,EAAME,SAASxC,QAClCuM,EAAgB,GAAGjM,OAAOgC,EAAMiK,cAActM,UAAWqC,EAAMiK,cAAcvM,QAYjF,OAVIoM,GACFG,EAAc9J,SAAQ,SAAU+J,GAC9BA,EAAaC,iBAAiB,SAAUP,EAASQ,OAAQT,GAC3D,IAGEK,GACF/K,EAAOkL,iBAAiB,SAAUP,EAASQ,OAAQT,IAG9C,WACDG,GACFG,EAAc9J,SAAQ,SAAU+J,GAC9BA,EAAaG,oBAAoB,SAAUT,EAASQ,OAAQT,GAC9D,IAGEK,GACF/K,EAAOoL,oBAAoB,SAAUT,EAASQ,OAAQT,GAE1D,CACF,EASED,KAAM,CAAC,GC/CT,IAAIY,GAAO,CACTnN,KAAM,QACND,MAAO,OACPD,OAAQ,MACR+D,IAAK,UAEQ,SAASuJ,GAAqBxM,GAC3C,OAAOA,EAAUyM,QAAQ,0BAA0B,SAAUC,GAC3D,OAAOH,GAAKG,EACd,GACF,CCVA,IAAI,GAAO,CACTnN,MAAO,MACPC,IAAK,SAEQ,SAASmN,GAA8B3M,GACpD,OAAOA,EAAUyM,QAAQ,cAAc,SAAUC,GAC/C,OAAO,GAAKA,EACd,GACF,CCPe,SAASE,GAAgB3L,GACtC,IAAI6J,EAAM9J,EAAUC,GAGpB,MAAO,CACL4L,WAHe/B,EAAIgC,YAInBC,UAHcjC,EAAIkC,YAKtB,CCNe,SAASC,GAAoBpM,GAQ1C,OAAO+D,EAAsB8B,EAAmB7F,IAAUzB,KAAOwN,GAAgB/L,GAASgM,UAC5F,CCXe,SAASK,GAAerM,GAErC,IAAIsM,EAAoB,EAAiBtM,GACrCuM,EAAWD,EAAkBC,SAC7BC,EAAYF,EAAkBE,UAC9BC,EAAYH,EAAkBG,UAElC,MAAO,6BAA6B3I,KAAKyI,EAAWE,EAAYD,EAClE,CCLe,SAASE,GAAgBtM,GACtC,MAAI,CAAC,OAAQ,OAAQ,aAAawF,QAAQ7F,EAAYK,KAAU,EAEvDA,EAAKG,cAAcoM,KAGxBhM,EAAcP,IAASiM,GAAejM,GACjCA,EAGFsM,GAAgB1G,EAAc5F,GACvC,CCJe,SAASwM,GAAkB5M,EAAS6M,GACjD,IAAIC,OAES,IAATD,IACFA,EAAO,IAGT,IAAIvB,EAAeoB,GAAgB1M,GAC/B+M,EAASzB,KAAqE,OAAlDwB,EAAwB9M,EAAQO,oBAAyB,EAASuM,EAAsBH,MACpH1C,EAAM9J,EAAUmL,GAChB0B,EAASD,EAAS,CAAC9C,GAAK7K,OAAO6K,EAAIxF,gBAAkB,GAAI4H,GAAef,GAAgBA,EAAe,IAAMA,EAC7G2B,EAAcJ,EAAKzN,OAAO4N,GAC9B,OAAOD,EAASE,EAChBA,EAAY7N,OAAOwN,GAAkB5G,EAAcgH,IACrD,CCzBe,SAASE,GAAiBC,GACvC,OAAO1P,OAAOkE,OAAO,CAAC,EAAGwL,EAAM,CAC7B5O,KAAM4O,EAAKxI,EACXvC,IAAK+K,EAAKtI,EACVvG,MAAO6O,EAAKxI,EAAIwI,EAAK7I,MACrBjG,OAAQ8O,EAAKtI,EAAIsI,EAAK3I,QAE1B,CCqBA,SAAS4I,GAA2BpN,EAASqN,EAAgBlL,GAC3D,OAAOkL,IAAmBxO,EAAWqO,GCzBxB,SAAyBlN,EAASmC,GAC/C,IAAI8H,EAAM9J,EAAUH,GAChBsN,EAAOzH,EAAmB7F,GAC1ByE,EAAiBwF,EAAIxF,eACrBH,EAAQgJ,EAAKhF,YACb9D,EAAS8I,EAAKjF,aACd1D,EAAI,EACJE,EAAI,EAER,GAAIJ,EAAgB,CAClBH,EAAQG,EAAeH,MACvBE,EAASC,EAAeD,OACxB,IAAI+I,EAAiB1J,KAEjB0J,IAAmBA,GAA+B,UAAbpL,KACvCwC,EAAIF,EAAeG,WACnBC,EAAIJ,EAAeK,UAEvB,CAEA,MAAO,CACLR,MAAOA,EACPE,OAAQA,EACRG,EAAGA,EAAIyH,GAAoBpM,GAC3B6E,EAAGA,EAEP,CDDwD2I,CAAgBxN,EAASmC,IAAa1B,EAAU4M,GAdxG,SAAoCrN,EAASmC,GAC3C,IAAIgL,EAAOpJ,EAAsB/D,GAAS,EAAoB,UAAbmC,GASjD,OARAgL,EAAK/K,IAAM+K,EAAK/K,IAAMpC,EAAQyN,UAC9BN,EAAK5O,KAAO4O,EAAK5O,KAAOyB,EAAQ0N,WAChCP,EAAK9O,OAAS8O,EAAK/K,IAAMpC,EAAQqI,aACjC8E,EAAK7O,MAAQ6O,EAAK5O,KAAOyB,EAAQsI,YACjC6E,EAAK7I,MAAQtE,EAAQsI,YACrB6E,EAAK3I,OAASxE,EAAQqI,aACtB8E,EAAKxI,EAAIwI,EAAK5O,KACd4O,EAAKtI,EAAIsI,EAAK/K,IACP+K,CACT,CAG0HQ,CAA2BN,EAAgBlL,GAAY+K,GEtBlK,SAAyBlN,GACtC,IAAI8M,EAEAQ,EAAOzH,EAAmB7F,GAC1B4N,EAAY7B,GAAgB/L,GAC5B2M,EAA0D,OAAlDG,EAAwB9M,EAAQO,oBAAyB,EAASuM,EAAsBH,KAChGrI,EAAQ,EAAIgJ,EAAKO,YAAaP,EAAKhF,YAAaqE,EAAOA,EAAKkB,YAAc,EAAGlB,EAAOA,EAAKrE,YAAc,GACvG9D,EAAS,EAAI8I,EAAKQ,aAAcR,EAAKjF,aAAcsE,EAAOA,EAAKmB,aAAe,EAAGnB,EAAOA,EAAKtE,aAAe,GAC5G1D,GAAKiJ,EAAU5B,WAAaI,GAAoBpM,GAChD6E,GAAK+I,EAAU1B,UAMnB,MAJiD,QAA7C,EAAiBS,GAAQW,GAAMS,YACjCpJ,GAAK,EAAI2I,EAAKhF,YAAaqE,EAAOA,EAAKrE,YAAc,GAAKhE,GAGrD,CACLA,MAAOA,EACPE,OAAQA,EACRG,EAAGA,EACHE,EAAGA,EAEP,CFCkMmJ,CAAgBnI,EAAmB7F,IACrO,CG1Be,SAASiO,GAAe9M,GACrC,IAOIkI,EAPAtK,EAAYoC,EAAKpC,UACjBiB,EAAUmB,EAAKnB,QACfb,EAAYgC,EAAKhC,UACjBqI,EAAgBrI,EAAYuD,EAAiBvD,GAAa,KAC1DiK,EAAYjK,EAAY4J,EAAa5J,GAAa,KAClD+O,EAAUnP,EAAU4F,EAAI5F,EAAUuF,MAAQ,EAAItE,EAAQsE,MAAQ,EAC9D6J,EAAUpP,EAAU8F,EAAI9F,EAAUyF,OAAS,EAAIxE,EAAQwE,OAAS,EAGpE,OAAQgD,GACN,KAAK,EACH6B,EAAU,CACR1E,EAAGuJ,EACHrJ,EAAG9F,EAAU8F,EAAI7E,EAAQwE,QAE3B,MAEF,KAAKnG,EACHgL,EAAU,CACR1E,EAAGuJ,EACHrJ,EAAG9F,EAAU8F,EAAI9F,EAAUyF,QAE7B,MAEF,KAAKlG,EACH+K,EAAU,CACR1E,EAAG5F,EAAU4F,EAAI5F,EAAUuF,MAC3BO,EAAGsJ,GAEL,MAEF,KAAK5P,EACH8K,EAAU,CACR1E,EAAG5F,EAAU4F,EAAI3E,EAAQsE,MACzBO,EAAGsJ,GAEL,MAEF,QACE9E,EAAU,CACR1E,EAAG5F,EAAU4F,EACbE,EAAG9F,EAAU8F,GAInB,IAAIuJ,EAAW5G,EAAgBV,EAAyBU,GAAiB,KAEzE,GAAgB,MAAZ4G,EAAkB,CACpB,IAAI1G,EAAmB,MAAb0G,EAAmB,SAAW,QAExC,OAAQhF,GACN,KAAK1K,EACH2K,EAAQ+E,GAAY/E,EAAQ+E,IAAarP,EAAU2I,GAAO,EAAI1H,EAAQ0H,GAAO,GAC7E,MAEF,KAAK/I,EACH0K,EAAQ+E,GAAY/E,EAAQ+E,IAAarP,EAAU2I,GAAO,EAAI1H,EAAQ0H,GAAO,GAKnF,CAEA,OAAO2B,CACT,CC3De,SAASgF,GAAejN,EAAOc,QAC5B,IAAZA,IACFA,EAAU,CAAC,GAGb,IAAIoM,EAAWpM,EACXqM,EAAqBD,EAASnP,UAC9BA,OAAmC,IAAvBoP,EAAgCnN,EAAMjC,UAAYoP,EAC9DC,EAAoBF,EAASnM,SAC7BA,OAAiC,IAAtBqM,EAA+BpN,EAAMe,SAAWqM,EAC3DC,EAAoBH,EAASI,SAC7BA,OAAiC,IAAtBD,EAA+B7P,EAAkB6P,EAC5DE,EAAwBL,EAASM,aACjCA,OAAyC,IAA1BD,EAAmC9P,EAAW8P,EAC7DE,EAAwBP,EAASQ,eACjCA,OAA2C,IAA1BD,EAAmC/P,EAAS+P,EAC7DE,EAAuBT,EAASU,YAChCA,OAAuC,IAAzBD,GAA0CA,EACxDE,EAAmBX,EAAS3G,QAC5BA,OAA+B,IAArBsH,EAA8B,EAAIA,EAC5ChI,EAAgBD,EAAsC,iBAAZW,EAAuBA,EAAUT,EAAgBS,EAASlJ,IACpGyQ,EAAaJ,IAAmBhQ,EAASC,EAAYD,EACrDqK,EAAa/H,EAAMwG,MAAM9I,OACzBkB,EAAUoB,EAAME,SAAS0N,EAAcE,EAAaJ,GACpDK,EJkBS,SAAyBnP,EAAS0O,EAAUE,EAAczM,GACvE,IAAIiN,EAAmC,oBAAbV,EAlB5B,SAA4B1O,GAC1B,IAAIpB,EAAkBgO,GAAkB5G,EAAchG,IAElDqP,EADoB,CAAC,WAAY,SAASzJ,QAAQ,EAAiB5F,GAASiC,WAAa,GACnDtB,EAAcX,GAAWoG,EAAgBpG,GAAWA,EAE9F,OAAKS,EAAU4O,GAKRzQ,EAAgBgI,QAAO,SAAUyG,GACtC,OAAO5M,EAAU4M,IAAmBpI,EAASoI,EAAgBgC,IAAmD,SAAhCtP,EAAYsN,EAC9F,IANS,EAOX,CAK6DiC,CAAmBtP,GAAW,GAAGZ,OAAOsP,GAC/F9P,EAAkB,GAAGQ,OAAOgQ,EAAqB,CAACR,IAClDW,EAAsB3Q,EAAgB,GACtC4Q,EAAe5Q,EAAgBK,QAAO,SAAUwQ,EAASpC,GAC3D,IAAIF,EAAOC,GAA2BpN,EAASqN,EAAgBlL,GAK/D,OAJAsN,EAAQrN,IAAM,EAAI+K,EAAK/K,IAAKqN,EAAQrN,KACpCqN,EAAQnR,MAAQ,EAAI6O,EAAK7O,MAAOmR,EAAQnR,OACxCmR,EAAQpR,OAAS,EAAI8O,EAAK9O,OAAQoR,EAAQpR,QAC1CoR,EAAQlR,KAAO,EAAI4O,EAAK5O,KAAMkR,EAAQlR,MAC/BkR,CACT,GAAGrC,GAA2BpN,EAASuP,EAAqBpN,IAK5D,OAJAqN,EAAalL,MAAQkL,EAAalR,MAAQkR,EAAajR,KACvDiR,EAAahL,OAASgL,EAAanR,OAASmR,EAAapN,IACzDoN,EAAa7K,EAAI6K,EAAajR,KAC9BiR,EAAa3K,EAAI2K,EAAapN,IACvBoN,CACT,CInC2BE,CAAgBjP,EAAUT,GAAWA,EAAUA,EAAQ2P,gBAAkB9J,EAAmBzE,EAAME,SAASxC,QAAS4P,EAAUE,EAAczM,GACjKyN,EAAsB7L,EAAsB3C,EAAME,SAASvC,WAC3DuI,EAAgB2G,GAAe,CACjClP,UAAW6Q,EACX5P,QAASmJ,EACThH,SAAU,WACVhD,UAAWA,IAET0Q,EAAmB3C,GAAiBzP,OAAOkE,OAAO,CAAC,EAAGwH,EAAY7B,IAClEwI,EAAoBhB,IAAmBhQ,EAAS+Q,EAAmBD,EAGnEG,EAAkB,CACpB3N,IAAK+M,EAAmB/M,IAAM0N,EAAkB1N,IAAM6E,EAAc7E,IACpE/D,OAAQyR,EAAkBzR,OAAS8Q,EAAmB9Q,OAAS4I,EAAc5I,OAC7EE,KAAM4Q,EAAmB5Q,KAAOuR,EAAkBvR,KAAO0I,EAAc1I,KACvED,MAAOwR,EAAkBxR,MAAQ6Q,EAAmB7Q,MAAQ2I,EAAc3I,OAExE0R,EAAa5O,EAAMmG,cAAckB,OAErC,GAAIqG,IAAmBhQ,GAAUkR,EAAY,CAC3C,IAAIvH,EAASuH,EAAW7Q,GACxB1B,OAAO4D,KAAK0O,GAAiBxO,SAAQ,SAAUhE,GAC7C,IAAI0S,EAAW,CAAC3R,EAAOD,GAAQuH,QAAQrI,IAAQ,EAAI,GAAK,EACpDkK,EAAO,CAAC,EAAKpJ,GAAQuH,QAAQrI,IAAQ,EAAI,IAAM,IACnDwS,EAAgBxS,IAAQkL,EAAOhB,GAAQwI,CACzC,GACF,CAEA,OAAOF,CACT,CCyEA,UACEhP,KAAM,OACNC,SAAS,EACTC,MAAO,OACPC,GA5HF,SAAcC,GACZ,IAAIC,EAAQD,EAAKC,MACbc,EAAUf,EAAKe,QACfnB,EAAOI,EAAKJ,KAEhB,IAAIK,EAAMmG,cAAcxG,GAAMmP,MAA9B,CAoCA,IAhCA,IAAIC,EAAoBjO,EAAQkM,SAC5BgC,OAAsC,IAAtBD,GAAsCA,EACtDE,EAAmBnO,EAAQoO,QAC3BC,OAAoC,IAArBF,GAAqCA,EACpDG,EAA8BtO,EAAQuO,mBACtC9I,EAAUzF,EAAQyF,QAClB+G,EAAWxM,EAAQwM,SACnBE,EAAe1M,EAAQ0M,aACvBI,EAAc9M,EAAQ8M,YACtB0B,EAAwBxO,EAAQyO,eAChCA,OAA2C,IAA1BD,GAA0CA,EAC3DE,EAAwB1O,EAAQ0O,sBAChCC,EAAqBzP,EAAMc,QAAQ/C,UACnCqI,EAAgB9E,EAAiBmO,GAEjCJ,EAAqBD,IADHhJ,IAAkBqJ,GACqCF,EAjC/E,SAAuCxR,GACrC,GAAIuD,EAAiBvD,KAAeX,EAClC,MAAO,GAGT,IAAIsS,EAAoBnF,GAAqBxM,GAC7C,MAAO,CAAC2M,GAA8B3M,GAAY2R,EAAmBhF,GAA8BgF,GACrG,CA0B6IC,CAA8BF,GAA3E,CAAClF,GAAqBkF,KAChHG,EAAa,CAACH,GAAoBzR,OAAOqR,GAAoBxR,QAAO,SAAUC,EAAKC,GACrF,OAAOD,EAAIE,OAAOsD,EAAiBvD,KAAeX,ECvCvC,SAA8B4C,EAAOc,QAClC,IAAZA,IACFA,EAAU,CAAC,GAGb,IAAIoM,EAAWpM,EACX/C,EAAYmP,EAASnP,UACrBuP,EAAWJ,EAASI,SACpBE,EAAeN,EAASM,aACxBjH,EAAU2G,EAAS3G,QACnBgJ,EAAiBrC,EAASqC,eAC1BM,EAAwB3C,EAASsC,sBACjCA,OAAkD,IAA1BK,EAAmC,EAAgBA,EAC3E7H,EAAYL,EAAa5J,GACzB6R,EAAa5H,EAAYuH,EAAiB3R,EAAsBA,EAAoB4H,QAAO,SAAUzH,GACvG,OAAO4J,EAAa5J,KAAeiK,CACrC,IAAK3K,EACDyS,EAAoBF,EAAWpK,QAAO,SAAUzH,GAClD,OAAOyR,EAAsBhL,QAAQzG,IAAc,CACrD,IAEiC,IAA7B+R,EAAkBC,SACpBD,EAAoBF,GAItB,IAAII,EAAYF,EAAkBjS,QAAO,SAAUC,EAAKC,GAOtD,OANAD,EAAIC,GAAakP,GAAejN,EAAO,CACrCjC,UAAWA,EACXuP,SAAUA,EACVE,aAAcA,EACdjH,QAASA,IACRjF,EAAiBvD,IACbD,CACT,GAAG,CAAC,GACJ,OAAOzB,OAAO4D,KAAK+P,GAAWC,MAAK,SAAUC,EAAGC,GAC9C,OAAOH,EAAUE,GAAKF,EAAUG,EAClC,GACF,CDC6DC,CAAqBpQ,EAAO,CACnFjC,UAAWA,EACXuP,SAAUA,EACVE,aAAcA,EACdjH,QAASA,EACTgJ,eAAgBA,EAChBC,sBAAuBA,IACpBzR,EACP,GAAG,IACCsS,EAAgBrQ,EAAMwG,MAAM7I,UAC5BoK,EAAa/H,EAAMwG,MAAM9I,OACzB4S,EAAY,IAAIC,IAChBC,GAAqB,EACrBC,EAAwBb,EAAW,GAE9Bc,EAAI,EAAGA,EAAId,EAAWG,OAAQW,IAAK,CAC1C,IAAI3S,EAAY6R,EAAWc,GAEvBC,EAAiBrP,EAAiBvD,GAElC6S,EAAmBjJ,EAAa5J,KAAeT,EAC/CuT,EAAa,CAAC,EAAK5T,GAAQuH,QAAQmM,IAAmB,EACtDrK,EAAMuK,EAAa,QAAU,SAC7B1F,EAAW8B,GAAejN,EAAO,CACnCjC,UAAWA,EACXuP,SAAUA,EACVE,aAAcA,EACdI,YAAaA,EACbrH,QAASA,IAEPuK,EAAoBD,EAAaD,EAAmB1T,EAAQC,EAAOyT,EAAmB3T,EAAS,EAE/FoT,EAAc/J,GAAOyB,EAAWzB,KAClCwK,EAAoBvG,GAAqBuG,IAG3C,IAAIC,EAAmBxG,GAAqBuG,GACxCE,EAAS,GAUb,GARIhC,GACFgC,EAAOC,KAAK9F,EAASwF,IAAmB,GAGtCxB,GACF6B,EAAOC,KAAK9F,EAAS2F,IAAsB,EAAG3F,EAAS4F,IAAqB,GAG1EC,EAAOE,OAAM,SAAUC,GACzB,OAAOA,CACT,IAAI,CACFV,EAAwB1S,EACxByS,GAAqB,EACrB,KACF,CAEAF,EAAUc,IAAIrT,EAAWiT,EAC3B,CAEA,GAAIR,EAqBF,IAnBA,IAEIa,EAAQ,SAAeC,GACzB,IAAIC,EAAmB3B,EAAW4B,MAAK,SAAUzT,GAC/C,IAAIiT,EAASV,EAAU9T,IAAIuB,GAE3B,GAAIiT,EACF,OAAOA,EAAOS,MAAM,EAAGH,GAAIJ,OAAM,SAAUC,GACzC,OAAOA,CACT,GAEJ,IAEA,GAAII,EAEF,OADAd,EAAwBc,EACjB,OAEX,EAESD,EAnBY/B,EAAiB,EAAI,EAmBZ+B,EAAK,GAGpB,UAFFD,EAAMC,GADmBA,KAOpCtR,EAAMjC,YAAc0S,IACtBzQ,EAAMmG,cAAcxG,GAAMmP,OAAQ,EAClC9O,EAAMjC,UAAY0S,EAClBzQ,EAAM0R,OAAQ,EA5GhB,CA8GF,EAQEhK,iBAAkB,CAAC,UACnBgC,KAAM,CACJoF,OAAO,IE7IX,SAAS6C,GAAexG,EAAUY,EAAM6F,GAQtC,YAPyB,IAArBA,IACFA,EAAmB,CACjBrO,EAAG,EACHE,EAAG,IAIA,CACLzC,IAAKmK,EAASnK,IAAM+K,EAAK3I,OAASwO,EAAiBnO,EACnDvG,MAAOiO,EAASjO,MAAQ6O,EAAK7I,MAAQ0O,EAAiBrO,EACtDtG,OAAQkO,EAASlO,OAAS8O,EAAK3I,OAASwO,EAAiBnO,EACzDtG,KAAMgO,EAAShO,KAAO4O,EAAK7I,MAAQ0O,EAAiBrO,EAExD,CAEA,SAASsO,GAAsB1G,GAC7B,MAAO,CAAC,EAAKjO,EAAOD,EAAQE,GAAM2U,MAAK,SAAUC,GAC/C,OAAO5G,EAAS4G,IAAS,CAC3B,GACF,CA+BA,UACEpS,KAAM,OACNC,SAAS,EACTC,MAAO,OACP6H,iBAAkB,CAAC,mBACnB5H,GAlCF,SAAcC,GACZ,IAAIC,EAAQD,EAAKC,MACbL,EAAOI,EAAKJ,KACZ0Q,EAAgBrQ,EAAMwG,MAAM7I,UAC5BoK,EAAa/H,EAAMwG,MAAM9I,OACzBkU,EAAmB5R,EAAMmG,cAAc6L,gBACvCC,EAAoBhF,GAAejN,EAAO,CAC5C0N,eAAgB,cAEdwE,EAAoBjF,GAAejN,EAAO,CAC5C4N,aAAa,IAEXuE,EAA2BR,GAAeM,EAAmB5B,GAC7D+B,EAAsBT,GAAeO,EAAmBnK,EAAY6J,GACpES,EAAoBR,GAAsBM,GAC1CG,EAAmBT,GAAsBO,GAC7CpS,EAAMmG,cAAcxG,GAAQ,CAC1BwS,yBAA0BA,EAC1BC,oBAAqBA,EACrBC,kBAAmBA,EACnBC,iBAAkBA,GAEpBtS,EAAMM,WAAW5C,OAASrB,OAAOkE,OAAO,CAAC,EAAGP,EAAMM,WAAW5C,OAAQ,CACnE,+BAAgC2U,EAChC,sBAAuBC,GAE3B,GCJA,IACE3S,KAAM,SACNC,SAAS,EACTC,MAAO,OACPwB,SAAU,CAAC,iBACXvB,GA5BF,SAAgBa,GACd,IAAIX,EAAQW,EAAMX,MACdc,EAAUH,EAAMG,QAChBnB,EAAOgB,EAAMhB,KACb4S,EAAkBzR,EAAQuG,OAC1BA,OAA6B,IAApBkL,EAA6B,CAAC,EAAG,GAAKA,EAC/C7I,EAAO,EAAW7L,QAAO,SAAUC,EAAKC,GAE1C,OADAD,EAAIC,GA5BD,SAAiCA,EAAWyI,EAAOa,GACxD,IAAIjB,EAAgB9E,EAAiBvD,GACjCyU,EAAiB,CAACrV,EAAM,GAAKqH,QAAQ4B,IAAkB,GAAK,EAAI,EAEhErG,EAAyB,mBAAXsH,EAAwBA,EAAOhL,OAAOkE,OAAO,CAAC,EAAGiG,EAAO,CACxEzI,UAAWA,KACPsJ,EACFoL,EAAW1S,EAAK,GAChB2S,EAAW3S,EAAK,GAIpB,OAFA0S,EAAWA,GAAY,EACvBC,GAAYA,GAAY,GAAKF,EACtB,CAACrV,EAAMD,GAAOsH,QAAQ4B,IAAkB,EAAI,CACjD7C,EAAGmP,EACHjP,EAAGgP,GACD,CACFlP,EAAGkP,EACHhP,EAAGiP,EAEP,CASqBC,CAAwB5U,EAAWiC,EAAMwG,MAAOa,GAC1DvJ,CACT,GAAG,CAAC,GACA8U,EAAwBlJ,EAAK1J,EAAMjC,WACnCwF,EAAIqP,EAAsBrP,EAC1BE,EAAImP,EAAsBnP,EAEW,MAArCzD,EAAMmG,cAAcD,gBACtBlG,EAAMmG,cAAcD,cAAc3C,GAAKA,EACvCvD,EAAMmG,cAAcD,cAAczC,GAAKA,GAGzCzD,EAAMmG,cAAcxG,GAAQ+J,CAC9B,GC1BA,IACE/J,KAAM,gBACNC,SAAS,EACTC,MAAO,OACPC,GApBF,SAAuBC,GACrB,IAAIC,EAAQD,EAAKC,MACbL,EAAOI,EAAKJ,KAKhBK,EAAMmG,cAAcxG,GAAQkN,GAAe,CACzClP,UAAWqC,EAAMwG,MAAM7I,UACvBiB,QAASoB,EAAMwG,MAAM9I,OACrBqD,SAAU,WACVhD,UAAWiC,EAAMjC,WAErB,EAQE2L,KAAM,CAAC,GCgHT,IACE/J,KAAM,kBACNC,SAAS,EACTC,MAAO,OACPC,GA/HF,SAAyBC,GACvB,IAAIC,EAAQD,EAAKC,MACbc,EAAUf,EAAKe,QACfnB,EAAOI,EAAKJ,KACZoP,EAAoBjO,EAAQkM,SAC5BgC,OAAsC,IAAtBD,GAAsCA,EACtDE,EAAmBnO,EAAQoO,QAC3BC,OAAoC,IAArBF,GAAsCA,EACrD3B,EAAWxM,EAAQwM,SACnBE,EAAe1M,EAAQ0M,aACvBI,EAAc9M,EAAQ8M,YACtBrH,EAAUzF,EAAQyF,QAClBsM,EAAkB/R,EAAQgS,OAC1BA,OAA6B,IAApBD,GAAoCA,EAC7CE,EAAwBjS,EAAQkS,aAChCA,OAAyC,IAA1BD,EAAmC,EAAIA,EACtD5H,EAAW8B,GAAejN,EAAO,CACnCsN,SAAUA,EACVE,aAAcA,EACdjH,QAASA,EACTqH,YAAaA,IAEXxH,EAAgB9E,EAAiBtB,EAAMjC,WACvCiK,EAAYL,EAAa3H,EAAMjC,WAC/BkV,GAAmBjL,EACnBgF,EAAWtH,EAAyBU,GACpC8I,ECrCY,MDqCSlC,ECrCH,IAAM,IDsCxB9G,EAAgBlG,EAAMmG,cAAcD,cACpCmK,EAAgBrQ,EAAMwG,MAAM7I,UAC5BoK,EAAa/H,EAAMwG,MAAM9I,OACzBwV,EAA4C,mBAAjBF,EAA8BA,EAAa3W,OAAOkE,OAAO,CAAC,EAAGP,EAAMwG,MAAO,CACvGzI,UAAWiC,EAAMjC,aACbiV,EACFG,EAA2D,iBAAtBD,EAAiC,CACxElG,SAAUkG,EACVhE,QAASgE,GACP7W,OAAOkE,OAAO,CAChByM,SAAU,EACVkC,QAAS,GACRgE,GACCE,EAAsBpT,EAAMmG,cAAckB,OAASrH,EAAMmG,cAAckB,OAAOrH,EAAMjC,WAAa,KACjG2L,EAAO,CACTnG,EAAG,EACHE,EAAG,GAGL,GAAKyC,EAAL,CAIA,GAAI8I,EAAe,CACjB,IAAIqE,EAEAC,EAAwB,MAAbtG,EAAmB,EAAM7P,EACpCoW,EAAuB,MAAbvG,EAAmB/P,EAASC,EACtCoJ,EAAmB,MAAb0G,EAAmB,SAAW,QACpC3F,EAASnB,EAAc8G,GACvBtL,EAAM2F,EAAS8D,EAASmI,GACxB7R,EAAM4F,EAAS8D,EAASoI,GACxBC,EAAWV,GAAU/K,EAAWzB,GAAO,EAAI,EAC3CmN,EAASzL,IAAc1K,EAAQ+S,EAAc/J,GAAOyB,EAAWzB,GAC/DoN,EAAS1L,IAAc1K,GAASyK,EAAWzB,IAAQ+J,EAAc/J,GAGjEL,EAAejG,EAAME,SAASgB,MAC9BwF,EAAYoM,GAAU7M,EAAetC,EAAcsC,GAAgB,CACrE/C,MAAO,EACPE,OAAQ,GAENuQ,GAAqB3T,EAAMmG,cAAc,oBAAsBnG,EAAMmG,cAAc,oBAAoBI,QxBhFtG,CACLvF,IAAK,EACL9D,MAAO,EACPD,OAAQ,EACRE,KAAM,GwB6EFyW,GAAkBD,GAAmBL,GACrCO,GAAkBF,GAAmBJ,GAMrCO,GAAWnO,EAAO,EAAG0K,EAAc/J,GAAMI,EAAUJ,IACnDyN,GAAYd,EAAkB5C,EAAc/J,GAAO,EAAIkN,EAAWM,GAAWF,GAAkBT,EAA4BnG,SAAWyG,EAASK,GAAWF,GAAkBT,EAA4BnG,SACxMgH,GAAYf,GAAmB5C,EAAc/J,GAAO,EAAIkN,EAAWM,GAAWD,GAAkBV,EAA4BnG,SAAW0G,EAASI,GAAWD,GAAkBV,EAA4BnG,SACzMjG,GAAoB/G,EAAME,SAASgB,OAAS8D,EAAgBhF,EAAME,SAASgB,OAC3E+S,GAAelN,GAAiC,MAAbiG,EAAmBjG,GAAkBsF,WAAa,EAAItF,GAAkBuF,YAAc,EAAI,EAC7H4H,GAAwH,OAAjGb,EAA+C,MAAvBD,OAA8B,EAASA,EAAoBpG,IAAqBqG,EAAwB,EAEvJc,GAAY9M,EAAS2M,GAAYE,GACjCE,GAAkBzO,EAAOmN,EAAS,EAAQpR,EAF9B2F,EAAS0M,GAAYG,GAAsBD,IAEKvS,EAAK2F,EAAQyL,EAAS,EAAQrR,EAAK0S,IAAa1S,GAChHyE,EAAc8G,GAAYoH,GAC1B1K,EAAKsD,GAAYoH,GAAkB/M,CACrC,CAEA,GAAI8H,EAAc,CAChB,IAAIkF,GAEAC,GAAyB,MAAbtH,EAAmB,EAAM7P,EAErCoX,GAAwB,MAAbvH,EAAmB/P,EAASC,EAEvCsX,GAAUtO,EAAcgJ,GAExBuF,GAAmB,MAAZvF,EAAkB,SAAW,QAEpCwF,GAAOF,GAAUrJ,EAASmJ,IAE1BK,GAAOH,GAAUrJ,EAASoJ,IAE1BK,IAAuD,IAAxC,CAAC,EAAKzX,GAAMqH,QAAQ4B,GAEnCyO,GAAyH,OAAjGR,GAAgD,MAAvBjB,OAA8B,EAASA,EAAoBlE,IAAoBmF,GAAyB,EAEzJS,GAAaF,GAAeF,GAAOF,GAAUnE,EAAcoE,IAAQ1M,EAAW0M,IAAQI,GAAuB1B,EAA4BjE,QAEzI6F,GAAaH,GAAeJ,GAAUnE,EAAcoE,IAAQ1M,EAAW0M,IAAQI,GAAuB1B,EAA4BjE,QAAUyF,GAE5IK,GAAmBlC,GAAU8B,G1BzH9B,SAAwBlT,EAAK1E,EAAOyE,GACzC,IAAIwT,EAAItP,EAAOjE,EAAK1E,EAAOyE,GAC3B,OAAOwT,EAAIxT,EAAMA,EAAMwT,CACzB,C0BsHoDC,CAAeJ,GAAYN,GAASO,IAAcpP,EAAOmN,EAASgC,GAAaJ,GAAMF,GAAS1B,EAASiC,GAAaJ,IAEpKzO,EAAcgJ,GAAW8F,GACzBtL,EAAKwF,GAAW8F,GAAmBR,EACrC,CAEAxU,EAAMmG,cAAcxG,GAAQ+J,CAvE5B,CAwEF,EAQEhC,iBAAkB,CAAC,WE1HN,SAASyN,GAAiBC,EAAyBrQ,EAAcsD,QAC9D,IAAZA,IACFA,GAAU,GAGZ,ICnBoCrJ,ECJOJ,EFuBvCyW,EAA0B9V,EAAcwF,GACxCuQ,EAAuB/V,EAAcwF,IAf3C,SAAyBnG,GACvB,IAAImN,EAAOnN,EAAQ+D,wBACfI,EAASpB,EAAMoK,EAAK7I,OAAStE,EAAQqE,aAAe,EACpDD,EAASrB,EAAMoK,EAAK3I,QAAUxE,EAAQuE,cAAgB,EAC1D,OAAkB,IAAXJ,GAA2B,IAAXC,CACzB,CAU4DuS,CAAgBxQ,GACtEJ,EAAkBF,EAAmBM,GACrCgH,EAAOpJ,EAAsByS,EAAyBE,EAAsBjN,GAC5EyB,EAAS,CACXc,WAAY,EACZE,UAAW,GAET7C,EAAU,CACZ1E,EAAG,EACHE,EAAG,GAkBL,OAfI4R,IAA4BA,IAA4BhN,MACxB,SAA9B1J,EAAYoG,IAChBkG,GAAetG,MACbmF,GCnCgC9K,EDmCT+F,KClCdhG,EAAUC,IAAUO,EAAcP,GCJxC,CACL4L,YAFyChM,EDQbI,GCNR4L,WACpBE,UAAWlM,EAAQkM,WDGZH,GAAgB3L,IDoCnBO,EAAcwF,KAChBkD,EAAUtF,EAAsBoC,GAAc,IACtCxB,GAAKwB,EAAauH,WAC1BrE,EAAQxE,GAAKsB,EAAasH,WACjB1H,IACTsD,EAAQ1E,EAAIyH,GAAoBrG,KAI7B,CACLpB,EAAGwI,EAAK5O,KAAO2M,EAAOc,WAAa3C,EAAQ1E,EAC3CE,EAAGsI,EAAK/K,IAAM8I,EAAOgB,UAAY7C,EAAQxE,EACzCP,MAAO6I,EAAK7I,MACZE,OAAQ2I,EAAK3I,OAEjB,CGvDA,SAASoS,GAAMC,GACb,IAAItT,EAAM,IAAIoO,IACVmF,EAAU,IAAIC,IACdC,EAAS,GAKb,SAAS3F,EAAK4F,GACZH,EAAQI,IAAID,EAASlW,MACN,GAAG3B,OAAO6X,EAASxU,UAAY,GAAIwU,EAASnO,kBAAoB,IACtEvH,SAAQ,SAAU4V,GACzB,IAAKL,EAAQM,IAAID,GAAM,CACrB,IAAIE,EAAc9T,EAAI3F,IAAIuZ,GAEtBE,GACFhG,EAAKgG,EAET,CACF,IACAL,EAAO3E,KAAK4E,EACd,CAQA,OAzBAJ,EAAUtV,SAAQ,SAAU0V,GAC1B1T,EAAIiP,IAAIyE,EAASlW,KAAMkW,EACzB,IAiBAJ,EAAUtV,SAAQ,SAAU0V,GACrBH,EAAQM,IAAIH,EAASlW,OAExBsQ,EAAK4F,EAET,IACOD,CACT,CCvBA,IAAIM,GAAkB,CACpBnY,UAAW,SACX0X,UAAW,GACX1U,SAAU,YAGZ,SAASoV,KACP,IAAK,IAAI1B,EAAO2B,UAAUrG,OAAQsG,EAAO,IAAIpU,MAAMwS,GAAO6B,EAAO,EAAGA,EAAO7B,EAAM6B,IAC/ED,EAAKC,GAAQF,UAAUE,GAGzB,OAAQD,EAAKvE,MAAK,SAAUlT,GAC1B,QAASA,GAAoD,mBAAlCA,EAAQ+D,sBACrC,GACF,CAEO,SAAS4T,GAAgBC,QACL,IAArBA,IACFA,EAAmB,CAAC,GAGtB,IAAIC,EAAoBD,EACpBE,EAAwBD,EAAkBE,iBAC1CA,OAA6C,IAA1BD,EAAmC,GAAKA,EAC3DE,EAAyBH,EAAkBI,eAC3CA,OAA4C,IAA3BD,EAAoCV,GAAkBU,EAC3E,OAAO,SAAsBjZ,EAAWD,EAAQoD,QAC9B,IAAZA,IACFA,EAAU+V,GAGZ,ICxC6B/W,EAC3BgX,EDuCE9W,EAAQ,CACVjC,UAAW,SACXgZ,iBAAkB,GAClBjW,QAASzE,OAAOkE,OAAO,CAAC,EAAG2V,GAAiBW,GAC5C1Q,cAAe,CAAC,EAChBjG,SAAU,CACRvC,UAAWA,EACXD,OAAQA,GAEV4C,WAAY,CAAC,EACbD,OAAQ,CAAC,GAEP2W,EAAmB,GACnBC,GAAc,EACdrN,EAAW,CACb5J,MAAOA,EACPkX,WAAY,SAAoBC,GAC9B,IAAIrW,EAAsC,mBAArBqW,EAAkCA,EAAiBnX,EAAMc,SAAWqW,EACzFC,IACApX,EAAMc,QAAUzE,OAAOkE,OAAO,CAAC,EAAGsW,EAAgB7W,EAAMc,QAASA,GACjEd,EAAMiK,cAAgB,CACpBtM,UAAW0B,EAAU1B,GAAa6N,GAAkB7N,GAAaA,EAAU4Q,eAAiB/C,GAAkB7N,EAAU4Q,gBAAkB,GAC1I7Q,OAAQ8N,GAAkB9N,IAI5B,IElE4B+X,EAC9B4B,EFiEMN,EDhCG,SAAwBtB,GAErC,IAAIsB,EAAmBvB,GAAMC,GAE7B,OAAO/W,EAAeb,QAAO,SAAUC,EAAK+B,GAC1C,OAAO/B,EAAIE,OAAO+Y,EAAiBvR,QAAO,SAAUqQ,GAClD,OAAOA,EAAShW,QAAUA,CAC5B,IACF,GAAG,GACL,CCuB+ByX,EElEK7B,EFkEsB,GAAGzX,OAAO2Y,EAAkB3W,EAAMc,QAAQ2U,WEjE9F4B,EAAS5B,EAAU5X,QAAO,SAAUwZ,EAAQE,GAC9C,IAAIC,EAAWH,EAAOE,EAAQ5X,MAK9B,OAJA0X,EAAOE,EAAQ5X,MAAQ6X,EAAWnb,OAAOkE,OAAO,CAAC,EAAGiX,EAAUD,EAAS,CACrEzW,QAASzE,OAAOkE,OAAO,CAAC,EAAGiX,EAAS1W,QAASyW,EAAQzW,SACrD4I,KAAMrN,OAAOkE,OAAO,CAAC,EAAGiX,EAAS9N,KAAM6N,EAAQ7N,QAC5C6N,EACEF,CACT,GAAG,CAAC,GAEGhb,OAAO4D,KAAKoX,GAAQlV,KAAI,SAAUhG,GACvC,OAAOkb,EAAOlb,EAChB,MF4DM,OAJA6D,EAAM+W,iBAAmBA,EAAiBvR,QAAO,SAAUiS,GACzD,OAAOA,EAAE7X,OACX,IA+FFI,EAAM+W,iBAAiB5W,SAAQ,SAAUJ,GACvC,IAAIJ,EAAOI,EAAKJ,KACZ+X,EAAe3X,EAAKe,QACpBA,OAA2B,IAAjB4W,EAA0B,CAAC,EAAIA,EACzChX,EAASX,EAAKW,OAElB,GAAsB,mBAAXA,EAAuB,CAChC,IAAIiX,EAAYjX,EAAO,CACrBV,MAAOA,EACPL,KAAMA,EACNiK,SAAUA,EACV9I,QAASA,IAKXkW,EAAiB/F,KAAK0G,GAFT,WAAmB,EAGlC,CACF,IA/GS/N,EAASQ,QAClB,EAMAwN,YAAa,WACX,IAAIX,EAAJ,CAIA,IAAIY,EAAkB7X,EAAME,SACxBvC,EAAYka,EAAgBla,UAC5BD,EAASma,EAAgBna,OAG7B,GAAKyY,GAAiBxY,EAAWD,GAAjC,CAKAsC,EAAMwG,MAAQ,CACZ7I,UAAWwX,GAAiBxX,EAAWqH,EAAgBtH,GAAoC,UAA3BsC,EAAMc,QAAQC,UAC9ErD,OAAQiG,EAAcjG,IAOxBsC,EAAM0R,OAAQ,EACd1R,EAAMjC,UAAYiC,EAAMc,QAAQ/C,UAKhCiC,EAAM+W,iBAAiB5W,SAAQ,SAAU0V,GACvC,OAAO7V,EAAMmG,cAAc0P,EAASlW,MAAQtD,OAAOkE,OAAO,CAAC,EAAGsV,EAASnM,KACzE,IAEA,IAAK,IAAIoO,EAAQ,EAAGA,EAAQ9X,EAAM+W,iBAAiBhH,OAAQ+H,IACzD,IAAoB,IAAhB9X,EAAM0R,MAAV,CAMA,IAAIqG,EAAwB/X,EAAM+W,iBAAiBe,GAC/ChY,EAAKiY,EAAsBjY,GAC3BkY,EAAyBD,EAAsBjX,QAC/CoM,OAAsC,IAA3B8K,EAAoC,CAAC,EAAIA,EACpDrY,EAAOoY,EAAsBpY,KAEf,mBAAPG,IACTE,EAAQF,EAAG,CACTE,MAAOA,EACPc,QAASoM,EACTvN,KAAMA,EACNiK,SAAUA,KACN5J,EAdR,MAHEA,EAAM0R,OAAQ,EACdoG,GAAS,CAzBb,CATA,CAqDF,EAGA1N,QC1I2BtK,ED0IV,WACf,OAAO,IAAImY,SAAQ,SAAUC,GAC3BtO,EAASgO,cACTM,EAAQlY,EACV,GACF,EC7IG,WAUL,OATK8W,IACHA,EAAU,IAAImB,SAAQ,SAAUC,GAC9BD,QAAQC,UAAUC,MAAK,WACrBrB,OAAUsB,EACVF,EAAQpY,IACV,GACF,KAGKgX,CACT,GDmIIuB,QAAS,WACPjB,IACAH,GAAc,CAChB,GAGF,IAAKd,GAAiBxY,EAAWD,GAC/B,OAAOkM,EAmCT,SAASwN,IACPJ,EAAiB7W,SAAQ,SAAUL,GACjC,OAAOA,GACT,IACAkX,EAAmB,EACrB,CAEA,OAvCApN,EAASsN,WAAWpW,GAASqX,MAAK,SAAUnY,IACrCiX,GAAenW,EAAQwX,eAC1BxX,EAAQwX,cAActY,EAE1B,IAmCO4J,CACT,CACF,CACO,IAAI2O,GAA4BhC,KGzLnC,GAA4BA,GAAgB,CAC9CI,iBAFqB,CAAC6B,GAAgB,GAAe,GAAe,EAAa,GAAQ,GAAM,GAAiB,EAAO,MCJrH,GAA4BjC,GAAgB,CAC9CI,iBAFqB,CAAC6B,GAAgB,GAAe,GAAe,KCatE,MAAMC,GAAa,IAAIlI,IACjBmI,GAAO,CACX,GAAAtH,CAAIxS,EAASzC,EAAKyN,GACX6O,GAAWzC,IAAIpX,IAClB6Z,GAAWrH,IAAIxS,EAAS,IAAI2R,KAE9B,MAAMoI,EAAcF,GAAWjc,IAAIoC,GAI9B+Z,EAAY3C,IAAI7Z,IAA6B,IAArBwc,EAAYC,KAKzCD,EAAYvH,IAAIjV,EAAKyN,GAHnBiP,QAAQC,MAAM,+EAA+E7W,MAAM8W,KAAKJ,EAAY1Y,QAAQ,MAIhI,EACAzD,IAAG,CAACoC,EAASzC,IACPsc,GAAWzC,IAAIpX,IACV6Z,GAAWjc,IAAIoC,GAASpC,IAAIL,IAE9B,KAET,MAAA6c,CAAOpa,EAASzC,GACd,IAAKsc,GAAWzC,IAAIpX,GAClB,OAEF,MAAM+Z,EAAcF,GAAWjc,IAAIoC,GACnC+Z,EAAYM,OAAO9c,GAGM,IAArBwc,EAAYC,MACdH,GAAWQ,OAAOra,EAEtB,GAYIsa,GAAiB,gBAOjBC,GAAgBC,IAChBA,GAAYna,OAAOoa,KAAOpa,OAAOoa,IAAIC,SAEvCF,EAAWA,EAAS5O,QAAQ,iBAAiB,CAAC+O,EAAOC,IAAO,IAAIH,IAAIC,OAAOE,QAEtEJ,GA4CHK,GAAuB7a,IAC3BA,EAAQ8a,cAAc,IAAIC,MAAMT,IAAgB,EAE5C,GAAYU,MACXA,GAA4B,iBAAXA,UAGO,IAAlBA,EAAOC,SAChBD,EAASA,EAAO,SAEgB,IAApBA,EAAOE,UAEjBC,GAAaH,GAEb,GAAUA,GACLA,EAAOC,OAASD,EAAO,GAAKA,EAEf,iBAAXA,GAAuBA,EAAO7J,OAAS,EACzCrL,SAAS+C,cAAc0R,GAAcS,IAEvC,KAEHI,GAAYpb,IAChB,IAAK,GAAUA,IAAgD,IAApCA,EAAQqb,iBAAiBlK,OAClD,OAAO,EAET,MAAMmK,EAAgF,YAA7D5V,iBAAiB1F,GAASub,iBAAiB,cAE9DC,EAAgBxb,EAAQyb,QAAQ,uBACtC,IAAKD,EACH,OAAOF,EAET,GAAIE,IAAkBxb,EAAS,CAC7B,MAAM0b,EAAU1b,EAAQyb,QAAQ,WAChC,GAAIC,GAAWA,EAAQlW,aAAegW,EACpC,OAAO,EAET,GAAgB,OAAZE,EACF,OAAO,CAEX,CACA,OAAOJ,CAAgB,EAEnBK,GAAa3b,IACZA,GAAWA,EAAQkb,WAAaU,KAAKC,gBAGtC7b,EAAQ8b,UAAU7W,SAAS,mBAGC,IAArBjF,EAAQ+b,SACV/b,EAAQ+b,SAEV/b,EAAQgc,aAAa,aAAoD,UAArChc,EAAQic,aAAa,aAE5DC,GAAiBlc,IACrB,IAAK8F,SAASC,gBAAgBoW,aAC5B,OAAO,KAIT,GAAmC,mBAAxBnc,EAAQqF,YAA4B,CAC7C,MAAM+W,EAAOpc,EAAQqF,cACrB,OAAO+W,aAAgBtb,WAAasb,EAAO,IAC7C,CACA,OAAIpc,aAAmBc,WACdd,EAIJA,EAAQwF,WAGN0W,GAAelc,EAAQwF,YAFrB,IAEgC,EAErC6W,GAAO,OAUPC,GAAStc,IACbA,EAAQuE,YAAY,EAGhBgY,GAAY,IACZlc,OAAOmc,SAAW1W,SAAS6G,KAAKqP,aAAa,qBACxC3b,OAAOmc,OAET,KAEHC,GAA4B,GAgB5BC,GAAQ,IAAuC,QAAjC5W,SAASC,gBAAgB4W,IACvCC,GAAqBC,IAhBAC,QAiBN,KACjB,MAAMC,EAAIR,KAEV,GAAIQ,EAAG,CACL,MAAMhc,EAAO8b,EAAOG,KACdC,EAAqBF,EAAE7b,GAAGH,GAChCgc,EAAE7b,GAAGH,GAAQ8b,EAAOK,gBACpBH,EAAE7b,GAAGH,GAAMoc,YAAcN,EACzBE,EAAE7b,GAAGH,GAAMqc,WAAa,KACtBL,EAAE7b,GAAGH,GAAQkc,EACNJ,EAAOK,gBAElB,GA5B0B,YAAxBpX,SAASuX,YAENZ,GAA0BtL,QAC7BrL,SAASyF,iBAAiB,oBAAoB,KAC5C,IAAK,MAAMuR,KAAYL,GACrBK,GACF,IAGJL,GAA0BpK,KAAKyK,IAE/BA,GAkBA,EAEEQ,GAAU,CAACC,EAAkB9F,EAAO,GAAI+F,EAAeD,IACxB,mBAArBA,EAAkCA,KAAoB9F,GAAQ+F,EAExEC,GAAyB,CAACX,EAAUY,EAAmBC,GAAoB,KAC/E,IAAKA,EAEH,YADAL,GAAQR,GAGV,MACMc,EAhKiC5d,KACvC,IAAKA,EACH,OAAO,EAIT,IAAI,mBACF6d,EAAkB,gBAClBC,GACEzd,OAAOqF,iBAAiB1F,GAC5B,MAAM+d,EAA0BC,OAAOC,WAAWJ,GAC5CK,EAAuBF,OAAOC,WAAWH,GAG/C,OAAKC,GAA4BG,GAKjCL,EAAqBA,EAAmBlb,MAAM,KAAK,GACnDmb,EAAkBA,EAAgBnb,MAAM,KAAK,GAtDf,KAuDtBqb,OAAOC,WAAWJ,GAAsBG,OAAOC,WAAWH,KANzD,CAMoG,EA2IpFK,CAAiCT,GADlC,EAExB,IAAIU,GAAS,EACb,MAAMC,EAAU,EACdrR,aAEIA,IAAW0Q,IAGfU,GAAS,EACTV,EAAkBjS,oBAAoB6O,GAAgB+D,GACtDf,GAAQR,GAAS,EAEnBY,EAAkBnS,iBAAiB+O,GAAgB+D,GACnDC,YAAW,KACJF,GACHvD,GAAqB6C,EACvB,GACCE,EAAiB,EAYhBW,GAAuB,CAAC1R,EAAM2R,EAAeC,EAAeC,KAChE,MAAMC,EAAa9R,EAAKsE,OACxB,IAAI+H,EAAQrM,EAAKjH,QAAQ4Y,GAIzB,OAAe,IAAXtF,GACMuF,GAAiBC,EAAiB7R,EAAK8R,EAAa,GAAK9R,EAAK,IAExEqM,GAASuF,EAAgB,GAAK,EAC1BC,IACFxF,GAASA,EAAQyF,GAAcA,GAE1B9R,EAAKjK,KAAKC,IAAI,EAAGD,KAAKE,IAAIoW,EAAOyF,EAAa,KAAI,EAerDC,GAAiB,qBACjBC,GAAiB,OACjBC,GAAgB,SAChBC,GAAgB,CAAC,EACvB,IAAIC,GAAW,EACf,MAAMC,GAAe,CACnBC,WAAY,YACZC,WAAY,YAERC,GAAe,IAAIrI,IAAI,CAAC,QAAS,WAAY,UAAW,YAAa,cAAe,aAAc,iBAAkB,YAAa,WAAY,YAAa,cAAe,YAAa,UAAW,WAAY,QAAS,oBAAqB,aAAc,YAAa,WAAY,cAAe,cAAe,cAAe,YAAa,eAAgB,gBAAiB,eAAgB,gBAAiB,aAAc,QAAS,OAAQ,SAAU,QAAS,SAAU,SAAU,UAAW,WAAY,OAAQ,SAAU,eAAgB,SAAU,OAAQ,mBAAoB,mBAAoB,QAAS,QAAS,WAM/lB,SAASsI,GAAarf,EAASsf,GAC7B,OAAOA,GAAO,GAAGA,MAAQN,QAAgBhf,EAAQgf,UAAYA,IAC/D,CACA,SAASO,GAAiBvf,GACxB,MAAMsf,EAAMD,GAAarf,GAGzB,OAFAA,EAAQgf,SAAWM,EACnBP,GAAcO,GAAOP,GAAcO,IAAQ,CAAC,EACrCP,GAAcO,EACvB,CAiCA,SAASE,GAAYC,EAAQC,EAAUC,EAAqB,MAC1D,OAAOliB,OAAOmiB,OAAOH,GAAQ7M,MAAKiN,GAASA,EAAMH,WAAaA,GAAYG,EAAMF,qBAAuBA,GACzG,CACA,SAASG,GAAoBC,EAAmB1B,EAAS2B,GACvD,MAAMC,EAAiC,iBAAZ5B,EAErBqB,EAAWO,EAAcD,EAAqB3B,GAAW2B,EAC/D,IAAIE,EAAYC,GAAaJ,GAI7B,OAHKX,GAAahI,IAAI8I,KACpBA,EAAYH,GAEP,CAACE,EAAaP,EAAUQ,EACjC,CACA,SAASE,GAAWpgB,EAAS+f,EAAmB1B,EAAS2B,EAAoBK,GAC3E,GAAiC,iBAAtBN,IAAmC/f,EAC5C,OAEF,IAAKigB,EAAaP,EAAUQ,GAAaJ,GAAoBC,EAAmB1B,EAAS2B,GAIzF,GAAID,KAAqBd,GAAc,CACrC,MAAMqB,EAAepf,GACZ,SAAU2e,GACf,IAAKA,EAAMU,eAAiBV,EAAMU,gBAAkBV,EAAMW,iBAAmBX,EAAMW,eAAevb,SAAS4a,EAAMU,eAC/G,OAAOrf,EAAGjD,KAAKwiB,KAAMZ,EAEzB,EAEFH,EAAWY,EAAaZ,EAC1B,CACA,MAAMD,EAASF,GAAiBvf,GAC1B0gB,EAAWjB,EAAOS,KAAeT,EAAOS,GAAa,CAAC,GACtDS,EAAmBnB,GAAYkB,EAAUhB,EAAUO,EAAc5B,EAAU,MACjF,GAAIsC,EAEF,YADAA,EAAiBN,OAASM,EAAiBN,QAAUA,GAGvD,MAAMf,EAAMD,GAAaK,EAAUK,EAAkBnU,QAAQgT,GAAgB,KACvE1d,EAAK+e,EA5Db,SAAoCjgB,EAASwa,EAAUtZ,GACrD,OAAO,SAASmd,EAAQwB,GACtB,MAAMe,EAAc5gB,EAAQ6gB,iBAAiBrG,GAC7C,IAAK,IAAI,OACPxN,GACE6S,EAAO7S,GAAUA,IAAWyT,KAAMzT,EAASA,EAAOxH,WACpD,IAAK,MAAMsb,KAAcF,EACvB,GAAIE,IAAe9T,EASnB,OANA+T,GAAWlB,EAAO,CAChBW,eAAgBxT,IAEdqR,EAAQgC,QACVW,GAAaC,IAAIjhB,EAAS6f,EAAMqB,KAAM1G,EAAUtZ,GAE3CA,EAAGigB,MAAMnU,EAAQ,CAAC6S,GAG/B,CACF,CAwC2BuB,CAA2BphB,EAASqe,EAASqB,GAvExE,SAA0B1f,EAASkB,GACjC,OAAO,SAASmd,EAAQwB,GAOtB,OANAkB,GAAWlB,EAAO,CAChBW,eAAgBxgB,IAEdqe,EAAQgC,QACVW,GAAaC,IAAIjhB,EAAS6f,EAAMqB,KAAMhgB,GAEjCA,EAAGigB,MAAMnhB,EAAS,CAAC6f,GAC5B,CACF,CA6DoFwB,CAAiBrhB,EAAS0f,GAC5Gxe,EAAGye,mBAAqBM,EAAc5B,EAAU,KAChDnd,EAAGwe,SAAWA,EACdxe,EAAGmf,OAASA,EACZnf,EAAG8d,SAAWM,EACdoB,EAASpB,GAAOpe,EAChBlB,EAAQuL,iBAAiB2U,EAAWhf,EAAI+e,EAC1C,CACA,SAASqB,GAActhB,EAASyf,EAAQS,EAAW7B,EAASsB,GAC1D,MAAMze,EAAKse,GAAYC,EAAOS,GAAY7B,EAASsB,GAC9Cze,IAGLlB,EAAQyL,oBAAoByU,EAAWhf,EAAIqgB,QAAQ5B,WAC5CF,EAAOS,GAAWhf,EAAG8d,UAC9B,CACA,SAASwC,GAAyBxhB,EAASyf,EAAQS,EAAWuB,GAC5D,MAAMC,EAAoBjC,EAAOS,IAAc,CAAC,EAChD,IAAK,MAAOyB,EAAY9B,KAAUpiB,OAAOmkB,QAAQF,GAC3CC,EAAWE,SAASJ,IACtBH,GAActhB,EAASyf,EAAQS,EAAWL,EAAMH,SAAUG,EAAMF,mBAGtE,CACA,SAASQ,GAAaN,GAGpB,OADAA,EAAQA,EAAMjU,QAAQiT,GAAgB,IAC/BI,GAAaY,IAAUA,CAChC,CACA,MAAMmB,GAAe,CACnB,EAAAc,CAAG9hB,EAAS6f,EAAOxB,EAAS2B,GAC1BI,GAAWpgB,EAAS6f,EAAOxB,EAAS2B,GAAoB,EAC1D,EACA,GAAA+B,CAAI/hB,EAAS6f,EAAOxB,EAAS2B,GAC3BI,GAAWpgB,EAAS6f,EAAOxB,EAAS2B,GAAoB,EAC1D,EACA,GAAAiB,CAAIjhB,EAAS+f,EAAmB1B,EAAS2B,GACvC,GAAiC,iBAAtBD,IAAmC/f,EAC5C,OAEF,MAAOigB,EAAaP,EAAUQ,GAAaJ,GAAoBC,EAAmB1B,EAAS2B,GACrFgC,EAAc9B,IAAcH,EAC5BN,EAASF,GAAiBvf,GAC1B0hB,EAAoBjC,EAAOS,IAAc,CAAC,EAC1C+B,EAAclC,EAAkBmC,WAAW,KACjD,QAAwB,IAAbxC,EAAX,CAQA,GAAIuC,EACF,IAAK,MAAME,KAAgB1kB,OAAO4D,KAAKoe,GACrC+B,GAAyBxhB,EAASyf,EAAQ0C,EAAcpC,EAAkBlN,MAAM,IAGpF,IAAK,MAAOuP,EAAavC,KAAUpiB,OAAOmkB,QAAQF,GAAoB,CACpE,MAAMC,EAAaS,EAAYxW,QAAQkT,GAAe,IACjDkD,IAAejC,EAAkB8B,SAASF,IAC7CL,GAActhB,EAASyf,EAAQS,EAAWL,EAAMH,SAAUG,EAAMF,mBAEpE,CAXA,KAPA,CAEE,IAAKliB,OAAO4D,KAAKqgB,GAAmBvQ,OAClC,OAEFmQ,GAActhB,EAASyf,EAAQS,EAAWR,EAAUO,EAAc5B,EAAU,KAE9E,CAYF,EACA,OAAAgE,CAAQriB,EAAS6f,EAAOpI,GACtB,GAAqB,iBAAVoI,IAAuB7f,EAChC,OAAO,KAET,MAAM+c,EAAIR,KAGV,IAAI+F,EAAc,KACdC,GAAU,EACVC,GAAiB,EACjBC,GAAmB,EAJH5C,IADFM,GAAaN,IAMZ9C,IACjBuF,EAAcvF,EAAEhC,MAAM8E,EAAOpI,GAC7BsF,EAAE/c,GAASqiB,QAAQC,GACnBC,GAAWD,EAAYI,uBACvBF,GAAkBF,EAAYK,gCAC9BF,EAAmBH,EAAYM,sBAEjC,MAAMC,EAAM9B,GAAW,IAAIhG,MAAM8E,EAAO,CACtC0C,UACAO,YAAY,IACVrL,GAUJ,OATIgL,GACFI,EAAIE,iBAEFP,GACFxiB,EAAQ8a,cAAc+H,GAEpBA,EAAIJ,kBAAoBH,GAC1BA,EAAYS,iBAEPF,CACT,GAEF,SAAS9B,GAAWljB,EAAKmlB,EAAO,CAAC,GAC/B,IAAK,MAAOzlB,EAAKa,KAAUX,OAAOmkB,QAAQoB,GACxC,IACEnlB,EAAIN,GAAOa,CACb,CAAE,MAAO6kB,GACPxlB,OAAOC,eAAeG,EAAKN,EAAK,CAC9B2lB,cAAc,EACdtlB,IAAG,IACMQ,GAGb,CAEF,OAAOP,CACT,CASA,SAASslB,GAAc/kB,GACrB,GAAc,SAAVA,EACF,OAAO,EAET,GAAc,UAAVA,EACF,OAAO,EAET,GAAIA,IAAU4f,OAAO5f,GAAOkC,WAC1B,OAAO0d,OAAO5f,GAEhB,GAAc,KAAVA,GAA0B,SAAVA,EAClB,OAAO,KAET,GAAqB,iBAAVA,EACT,OAAOA,EAET,IACE,OAAOglB,KAAKC,MAAMC,mBAAmBllB,GACvC,CAAE,MAAO6kB,GACP,OAAO7kB,CACT,CACF,CACA,SAASmlB,GAAiBhmB,GACxB,OAAOA,EAAIqO,QAAQ,UAAU4X,GAAO,IAAIA,EAAItjB,iBAC9C,CACA,MAAMujB,GAAc,CAClB,gBAAAC,CAAiB1jB,EAASzC,EAAKa,GAC7B4B,EAAQ6B,aAAa,WAAW0hB,GAAiBhmB,KAAQa,EAC3D,EACA,mBAAAulB,CAAoB3jB,EAASzC,GAC3ByC,EAAQ4B,gBAAgB,WAAW2hB,GAAiBhmB,KACtD,EACA,iBAAAqmB,CAAkB5jB,GAChB,IAAKA,EACH,MAAO,CAAC,EAEV,MAAM0B,EAAa,CAAC,EACdmiB,EAASpmB,OAAO4D,KAAKrB,EAAQ8jB,SAASld,QAAOrJ,GAAOA,EAAI2kB,WAAW,QAAU3kB,EAAI2kB,WAAW,cAClG,IAAK,MAAM3kB,KAAOsmB,EAAQ,CACxB,IAAIE,EAAUxmB,EAAIqO,QAAQ,MAAO,IACjCmY,EAAUA,EAAQC,OAAO,GAAG9jB,cAAgB6jB,EAAQlR,MAAM,EAAGkR,EAAQ5S,QACrEzP,EAAWqiB,GAAWZ,GAAcnjB,EAAQ8jB,QAAQvmB,GACtD,CACA,OAAOmE,CACT,EACAuiB,iBAAgB,CAACjkB,EAASzC,IACjB4lB,GAAcnjB,EAAQic,aAAa,WAAWsH,GAAiBhmB,QAgB1E,MAAM2mB,GAEJ,kBAAWC,GACT,MAAO,CAAC,CACV,CACA,sBAAWC,GACT,MAAO,CAAC,CACV,CACA,eAAWpH,GACT,MAAM,IAAIqH,MAAM,sEAClB,CACA,UAAAC,CAAWC,GAIT,OAHAA,EAAS9D,KAAK+D,gBAAgBD,GAC9BA,EAAS9D,KAAKgE,kBAAkBF,GAChC9D,KAAKiE,iBAAiBH,GACfA,CACT,CACA,iBAAAE,CAAkBF,GAChB,OAAOA,CACT,CACA,eAAAC,CAAgBD,EAAQvkB,GACtB,MAAM2kB,EAAa,GAAU3kB,GAAWyjB,GAAYQ,iBAAiBjkB,EAAS,UAAY,CAAC,EAE3F,MAAO,IACFygB,KAAKmE,YAAYT,WACM,iBAAfQ,EAA0BA,EAAa,CAAC,KAC/C,GAAU3kB,GAAWyjB,GAAYG,kBAAkB5jB,GAAW,CAAC,KAC7C,iBAAXukB,EAAsBA,EAAS,CAAC,EAE/C,CACA,gBAAAG,CAAiBH,EAAQM,EAAcpE,KAAKmE,YAAYR,aACtD,IAAK,MAAO7hB,EAAUuiB,KAAkBrnB,OAAOmkB,QAAQiD,GAAc,CACnE,MAAMzmB,EAAQmmB,EAAOhiB,GACfwiB,EAAY,GAAU3mB,GAAS,UAjiBrC4c,OADSA,EAkiB+C5c,GAhiBnD,GAAG4c,IAELvd,OAAOM,UAAUuC,SAASrC,KAAK+c,GAAQL,MAAM,eAAe,GAAGza,cA+hBlE,IAAK,IAAI8kB,OAAOF,GAAehhB,KAAKihB,GAClC,MAAM,IAAIE,UAAU,GAAGxE,KAAKmE,YAAY5H,KAAKkI,0BAA0B3iB,qBAA4BwiB,yBAAiCD,MAExI,CAtiBW9J,KAuiBb,EAqBF,MAAMmK,WAAsBjB,GAC1B,WAAAU,CAAY5kB,EAASukB,GACnBa,SACAplB,EAAUmb,GAAWnb,MAIrBygB,KAAK4E,SAAWrlB,EAChBygB,KAAK6E,QAAU7E,KAAK6D,WAAWC,GAC/BzK,GAAKtH,IAAIiO,KAAK4E,SAAU5E,KAAKmE,YAAYW,SAAU9E,MACrD,CAGA,OAAA+E,GACE1L,GAAKM,OAAOqG,KAAK4E,SAAU5E,KAAKmE,YAAYW,UAC5CvE,GAAaC,IAAIR,KAAK4E,SAAU5E,KAAKmE,YAAYa,WACjD,IAAK,MAAMC,KAAgBjoB,OAAOkoB,oBAAoBlF,MACpDA,KAAKiF,GAAgB,IAEzB,CACA,cAAAE,CAAe9I,EAAU9c,EAAS6lB,GAAa,GAC7CpI,GAAuBX,EAAU9c,EAAS6lB,EAC5C,CACA,UAAAvB,CAAWC,GAIT,OAHAA,EAAS9D,KAAK+D,gBAAgBD,EAAQ9D,KAAK4E,UAC3Cd,EAAS9D,KAAKgE,kBAAkBF,GAChC9D,KAAKiE,iBAAiBH,GACfA,CACT,CAGA,kBAAOuB,CAAY9lB,GACjB,OAAO8Z,GAAKlc,IAAIud,GAAWnb,GAAUygB,KAAK8E,SAC5C,CACA,0BAAOQ,CAAoB/lB,EAASukB,EAAS,CAAC,GAC5C,OAAO9D,KAAKqF,YAAY9lB,IAAY,IAAIygB,KAAKzgB,EAA2B,iBAAXukB,EAAsBA,EAAS,KAC9F,CACA,kBAAWyB,GACT,MA5CY,OA6Cd,CACA,mBAAWT,GACT,MAAO,MAAM9E,KAAKzD,MACpB,CACA,oBAAWyI,GACT,MAAO,IAAIhF,KAAK8E,UAClB,CACA,gBAAOU,CAAUllB,GACf,MAAO,GAAGA,IAAO0f,KAAKgF,WACxB,EAUF,MAAMS,GAAclmB,IAClB,IAAIwa,EAAWxa,EAAQic,aAAa,kBACpC,IAAKzB,GAAyB,MAAbA,EAAkB,CACjC,IAAI2L,EAAgBnmB,EAAQic,aAAa,QAMzC,IAAKkK,IAAkBA,EAActE,SAAS,OAASsE,EAAcjE,WAAW,KAC9E,OAAO,KAILiE,EAActE,SAAS,OAASsE,EAAcjE,WAAW,OAC3DiE,EAAgB,IAAIA,EAAcxjB,MAAM,KAAK,MAE/C6X,EAAW2L,GAAmC,MAAlBA,EAAwB5L,GAAc4L,EAAcC,QAAU,IAC5F,CACA,OAAO5L,CAAQ,EAEX6L,GAAiB,CACrBzT,KAAI,CAAC4H,EAAUxa,EAAU8F,SAASC,kBACzB,GAAG3G,UAAUsB,QAAQ3C,UAAU8iB,iBAAiB5iB,KAAK+B,EAASwa,IAEvE8L,QAAO,CAAC9L,EAAUxa,EAAU8F,SAASC,kBAC5BrF,QAAQ3C,UAAU8K,cAAc5K,KAAK+B,EAASwa,GAEvD+L,SAAQ,CAACvmB,EAASwa,IACT,GAAGpb,UAAUY,EAAQumB,UAAU3f,QAAOzB,GAASA,EAAMqhB,QAAQhM,KAEtE,OAAAiM,CAAQzmB,EAASwa,GACf,MAAMiM,EAAU,GAChB,IAAIC,EAAW1mB,EAAQwF,WAAWiW,QAAQjB,GAC1C,KAAOkM,GACLD,EAAQpU,KAAKqU,GACbA,EAAWA,EAASlhB,WAAWiW,QAAQjB,GAEzC,OAAOiM,CACT,EACA,IAAAE,CAAK3mB,EAASwa,GACZ,IAAIoM,EAAW5mB,EAAQ6mB,uBACvB,KAAOD,GAAU,CACf,GAAIA,EAASJ,QAAQhM,GACnB,MAAO,CAACoM,GAEVA,EAAWA,EAASC,sBACtB,CACA,MAAO,EACT,EAEA,IAAAvhB,CAAKtF,EAASwa,GACZ,IAAIlV,EAAOtF,EAAQ8mB,mBACnB,KAAOxhB,GAAM,CACX,GAAIA,EAAKkhB,QAAQhM,GACf,MAAO,CAAClV,GAEVA,EAAOA,EAAKwhB,kBACd,CACA,MAAO,EACT,EACA,iBAAAC,CAAkB/mB,GAChB,MAAMgnB,EAAa,CAAC,IAAK,SAAU,QAAS,WAAY,SAAU,UAAW,aAAc,4BAA4BzjB,KAAIiX,GAAY,GAAGA,2BAAiC7W,KAAK,KAChL,OAAO8c,KAAK7N,KAAKoU,EAAYhnB,GAAS4G,QAAOqgB,IAAOtL,GAAWsL,IAAO7L,GAAU6L,IAClF,EACA,sBAAAC,CAAuBlnB,GACrB,MAAMwa,EAAW0L,GAAYlmB,GAC7B,OAAIwa,GACK6L,GAAeC,QAAQ9L,GAAYA,EAErC,IACT,EACA,sBAAA2M,CAAuBnnB,GACrB,MAAMwa,EAAW0L,GAAYlmB,GAC7B,OAAOwa,EAAW6L,GAAeC,QAAQ9L,GAAY,IACvD,EACA,+BAAA4M,CAAgCpnB,GAC9B,MAAMwa,EAAW0L,GAAYlmB,GAC7B,OAAOwa,EAAW6L,GAAezT,KAAK4H,GAAY,EACpD,GAUI6M,GAAuB,CAACC,EAAWC,EAAS,UAChD,MAAMC,EAAa,gBAAgBF,EAAU7B,YACvC1kB,EAAOumB,EAAUtK,KACvBgE,GAAac,GAAGhc,SAAU0hB,EAAY,qBAAqBzmB,OAAU,SAAU8e,GAI7E,GAHI,CAAC,IAAK,QAAQgC,SAASpB,KAAKgH,UAC9B5H,EAAMkD,iBAEJpH,GAAW8E,MACb,OAEF,MAAMzT,EAASqZ,GAAec,uBAAuB1G,OAASA,KAAKhF,QAAQ,IAAI1a,KAC9DumB,EAAUvB,oBAAoB/Y,GAGtCua,IACX,GAAE,EAiBEG,GAAc,YACdC,GAAc,QAAQD,KACtBE,GAAe,SAASF,KAQ9B,MAAMG,WAAc1C,GAElB,eAAWnI,GACT,MAfW,OAgBb,CAGA,KAAA8K,GAEE,GADmB9G,GAAaqB,QAAQ5B,KAAK4E,SAAUsC,IACxClF,iBACb,OAEFhC,KAAK4E,SAASvJ,UAAU1B,OAlBF,QAmBtB,MAAMyL,EAAapF,KAAK4E,SAASvJ,UAAU7W,SApBrB,QAqBtBwb,KAAKmF,gBAAe,IAAMnF,KAAKsH,mBAAmBtH,KAAK4E,SAAUQ,EACnE,CAGA,eAAAkC,GACEtH,KAAK4E,SAASjL,SACd4G,GAAaqB,QAAQ5B,KAAK4E,SAAUuC,IACpCnH,KAAK+E,SACP,CAGA,sBAAOtI,CAAgBqH,GACrB,OAAO9D,KAAKuH,MAAK,WACf,MAAMld,EAAO+c,GAAM9B,oBAAoBtF,MACvC,GAAsB,iBAAX8D,EAAX,CAGA,QAAqB/K,IAAjB1O,EAAKyZ,IAAyBA,EAAOrC,WAAW,MAAmB,gBAAXqC,EAC1D,MAAM,IAAIU,UAAU,oBAAoBV,MAE1CzZ,EAAKyZ,GAAQ9D,KAJb,CAKF,GACF,EAOF4G,GAAqBQ,GAAO,SAM5BjL,GAAmBiL,IAcnB,MAKMI,GAAyB,4BAO/B,MAAMC,WAAe/C,GAEnB,eAAWnI,GACT,MAfW,QAgBb,CAGA,MAAAmL,GAEE1H,KAAK4E,SAASxjB,aAAa,eAAgB4e,KAAK4E,SAASvJ,UAAUqM,OAjB3C,UAkB1B,CAGA,sBAAOjL,CAAgBqH,GACrB,OAAO9D,KAAKuH,MAAK,WACf,MAAMld,EAAOod,GAAOnC,oBAAoBtF,MACzB,WAAX8D,GACFzZ,EAAKyZ,IAET,GACF,EAOFvD,GAAac,GAAGhc,SAjCe,2BAiCmBmiB,IAAwBpI,IACxEA,EAAMkD,iBACN,MAAMqF,EAASvI,EAAM7S,OAAOyO,QAAQwM,IACvBC,GAAOnC,oBAAoBqC,GACnCD,QAAQ,IAOfvL,GAAmBsL,IAcnB,MACMG,GAAc,YACdC,GAAmB,aAAaD,KAChCE,GAAkB,YAAYF,KAC9BG,GAAiB,WAAWH,KAC5BI,GAAoB,cAAcJ,KAClCK,GAAkB,YAAYL,KAK9BM,GAAY,CAChBC,YAAa,KACbC,aAAc,KACdC,cAAe,MAEXC,GAAgB,CACpBH,YAAa,kBACbC,aAAc,kBACdC,cAAe,mBAOjB,MAAME,WAAc9E,GAClB,WAAAU,CAAY5kB,EAASukB,GACnBa,QACA3E,KAAK4E,SAAWrlB,EACXA,GAAYgpB,GAAMC,gBAGvBxI,KAAK6E,QAAU7E,KAAK6D,WAAWC,GAC/B9D,KAAKyI,QAAU,EACfzI,KAAK0I,sBAAwB5H,QAAQlhB,OAAO+oB,cAC5C3I,KAAK4I,cACP,CAGA,kBAAWlF,GACT,OAAOwE,EACT,CACA,sBAAWvE,GACT,OAAO2E,EACT,CACA,eAAW/L,GACT,MA/CW,OAgDb,CAGA,OAAAwI,GACExE,GAAaC,IAAIR,KAAK4E,SAAUgD,GAClC,CAGA,MAAAiB,CAAOzJ,GACAY,KAAK0I,sBAIN1I,KAAK8I,wBAAwB1J,KAC/BY,KAAKyI,QAAUrJ,EAAM2J,SAJrB/I,KAAKyI,QAAUrJ,EAAM4J,QAAQ,GAAGD,OAMpC,CACA,IAAAE,CAAK7J,GACCY,KAAK8I,wBAAwB1J,KAC/BY,KAAKyI,QAAUrJ,EAAM2J,QAAU/I,KAAKyI,SAEtCzI,KAAKkJ,eACLrM,GAAQmD,KAAK6E,QAAQsD,YACvB,CACA,KAAAgB,CAAM/J,GACJY,KAAKyI,QAAUrJ,EAAM4J,SAAW5J,EAAM4J,QAAQtY,OAAS,EAAI,EAAI0O,EAAM4J,QAAQ,GAAGD,QAAU/I,KAAKyI,OACjG,CACA,YAAAS,GACE,MAAME,EAAYjnB,KAAKoC,IAAIyb,KAAKyI,SAChC,GAAIW,GAnEgB,GAoElB,OAEF,MAAM9b,EAAY8b,EAAYpJ,KAAKyI,QACnCzI,KAAKyI,QAAU,EACVnb,GAGLuP,GAAQvP,EAAY,EAAI0S,KAAK6E,QAAQwD,cAAgBrI,KAAK6E,QAAQuD,aACpE,CACA,WAAAQ,GACM5I,KAAK0I,uBACPnI,GAAac,GAAGrB,KAAK4E,SAAUoD,IAAmB5I,GAASY,KAAK6I,OAAOzJ,KACvEmB,GAAac,GAAGrB,KAAK4E,SAAUqD,IAAiB7I,GAASY,KAAKiJ,KAAK7J,KACnEY,KAAK4E,SAASvJ,UAAU5E,IAlFG,mBAoF3B8J,GAAac,GAAGrB,KAAK4E,SAAUiD,IAAkBzI,GAASY,KAAK6I,OAAOzJ,KACtEmB,GAAac,GAAGrB,KAAK4E,SAAUkD,IAAiB1I,GAASY,KAAKmJ,MAAM/J,KACpEmB,GAAac,GAAGrB,KAAK4E,SAAUmD,IAAgB3I,GAASY,KAAKiJ,KAAK7J,KAEtE,CACA,uBAAA0J,CAAwB1J,GACtB,OAAOY,KAAK0I,wBA3FS,QA2FiBtJ,EAAMiK,aA5FrB,UA4FyDjK,EAAMiK,YACxF,CAGA,kBAAOb,GACL,MAAO,iBAAkBnjB,SAASC,iBAAmB7C,UAAU6mB,eAAiB,CAClF,EAeF,MAEMC,GAAc,eACdC,GAAiB,YAKjBC,GAAa,OACbC,GAAa,OACbC,GAAiB,OACjBC,GAAkB,QAClBC,GAAc,QAAQN,KACtBO,GAAa,OAAOP,KACpBQ,GAAkB,UAAUR,KAC5BS,GAAqB,aAAaT,KAClCU,GAAqB,aAAaV,KAClCW,GAAmB,YAAYX,KAC/BY,GAAwB,OAAOZ,KAAcC,KAC7CY,GAAyB,QAAQb,KAAcC,KAC/Ca,GAAsB,WACtBC,GAAsB,SAMtBC,GAAkB,UAClBC,GAAgB,iBAChBC,GAAuBF,GAAkBC,GAKzCE,GAAmB,CACvB,UAAoBd,GACpB,WAAqBD,IAEjBgB,GAAY,CAChBC,SAAU,IACVC,UAAU,EACVC,MAAO,QACPC,MAAM,EACNC,OAAO,EACPC,MAAM,GAEFC,GAAgB,CACpBN,SAAU,mBAEVC,SAAU,UACVC,MAAO,mBACPC,KAAM,mBACNC,MAAO,UACPC,KAAM,WAOR,MAAME,WAAiBzG,GACrB,WAAAP,CAAY5kB,EAASukB,GACnBa,MAAMplB,EAASukB,GACf9D,KAAKoL,UAAY,KACjBpL,KAAKqL,eAAiB,KACtBrL,KAAKsL,YAAa,EAClBtL,KAAKuL,aAAe,KACpBvL,KAAKwL,aAAe,KACpBxL,KAAKyL,mBAAqB7F,GAAeC,QArCjB,uBAqC8C7F,KAAK4E,UAC3E5E,KAAK0L,qBACD1L,KAAK6E,QAAQkG,OAASV,IACxBrK,KAAK2L,OAET,CAGA,kBAAWjI,GACT,OAAOiH,EACT,CACA,sBAAWhH,GACT,OAAOuH,EACT,CACA,eAAW3O,GACT,MAnFW,UAoFb,CAGA,IAAA1X,GACEmb,KAAK4L,OAAOnC,GACd,CACA,eAAAoC,IAIOxmB,SAASymB,QAAUnR,GAAUqF,KAAK4E,WACrC5E,KAAKnb,MAET,CACA,IAAAqhB,GACElG,KAAK4L,OAAOlC,GACd,CACA,KAAAoB,GACM9K,KAAKsL,YACPlR,GAAqB4F,KAAK4E,UAE5B5E,KAAK+L,gBACP,CACA,KAAAJ,GACE3L,KAAK+L,iBACL/L,KAAKgM,kBACLhM,KAAKoL,UAAYa,aAAY,IAAMjM,KAAK6L,mBAAmB7L,KAAK6E,QAAQ+F,SAC1E,CACA,iBAAAsB,GACOlM,KAAK6E,QAAQkG,OAGd/K,KAAKsL,WACP/K,GAAae,IAAItB,KAAK4E,SAAUkF,IAAY,IAAM9J,KAAK2L,UAGzD3L,KAAK2L,QACP,CACA,EAAAQ,CAAG1T,GACD,MAAM2T,EAAQpM,KAAKqM,YACnB,GAAI5T,EAAQ2T,EAAM1b,OAAS,GAAK+H,EAAQ,EACtC,OAEF,GAAIuH,KAAKsL,WAEP,YADA/K,GAAae,IAAItB,KAAK4E,SAAUkF,IAAY,IAAM9J,KAAKmM,GAAG1T,KAG5D,MAAM6T,EAActM,KAAKuM,cAAcvM,KAAKwM,cAC5C,GAAIF,IAAgB7T,EAClB,OAEF,MAAMtC,EAAQsC,EAAQ6T,EAAc7C,GAAaC,GACjD1J,KAAK4L,OAAOzV,EAAOiW,EAAM3T,GAC3B,CACA,OAAAsM,GACM/E,KAAKwL,cACPxL,KAAKwL,aAAazG,UAEpBJ,MAAMI,SACR,CAGA,iBAAAf,CAAkBF,GAEhB,OADAA,EAAO2I,gBAAkB3I,EAAO8G,SACzB9G,CACT,CACA,kBAAA4H,GACM1L,KAAK6E,QAAQgG,UACftK,GAAac,GAAGrB,KAAK4E,SAAUmF,IAAiB3K,GAASY,KAAK0M,SAAStN,KAE9C,UAAvBY,KAAK6E,QAAQiG,QACfvK,GAAac,GAAGrB,KAAK4E,SAAUoF,IAAoB,IAAMhK,KAAK8K,UAC9DvK,GAAac,GAAGrB,KAAK4E,SAAUqF,IAAoB,IAAMjK,KAAKkM,uBAE5DlM,KAAK6E,QAAQmG,OAASzC,GAAMC,eAC9BxI,KAAK2M,yBAET,CACA,uBAAAA,GACE,IAAK,MAAMC,KAAOhH,GAAezT,KArIX,qBAqImC6N,KAAK4E,UAC5DrE,GAAac,GAAGuL,EAAK1C,IAAkB9K,GAASA,EAAMkD,mBAExD,MAmBMuK,EAAc,CAClBzE,aAAc,IAAMpI,KAAK4L,OAAO5L,KAAK8M,kBAAkBnD,KACvDtB,cAAe,IAAMrI,KAAK4L,OAAO5L,KAAK8M,kBAAkBlD,KACxDzB,YAtBkB,KACS,UAAvBnI,KAAK6E,QAAQiG,QAYjB9K,KAAK8K,QACD9K,KAAKuL,cACPwB,aAAa/M,KAAKuL,cAEpBvL,KAAKuL,aAAe1N,YAAW,IAAMmC,KAAKkM,qBAjLjB,IAiL+DlM,KAAK6E,QAAQ+F,UAAS,GAOhH5K,KAAKwL,aAAe,IAAIjD,GAAMvI,KAAK4E,SAAUiI,EAC/C,CACA,QAAAH,CAAStN,GACP,GAAI,kBAAkB/b,KAAK+b,EAAM7S,OAAOya,SACtC,OAEF,MAAM1Z,EAAYod,GAAiBtL,EAAMtiB,KACrCwQ,IACF8R,EAAMkD,iBACNtC,KAAK4L,OAAO5L,KAAK8M,kBAAkBxf,IAEvC,CACA,aAAAif,CAAchtB,GACZ,OAAOygB,KAAKqM,YAAYlnB,QAAQ5F,EAClC,CACA,0BAAAytB,CAA2BvU,GACzB,IAAKuH,KAAKyL,mBACR,OAEF,MAAMwB,EAAkBrH,GAAeC,QAAQ0E,GAAiBvK,KAAKyL,oBACrEwB,EAAgB5R,UAAU1B,OAAO2Q,IACjC2C,EAAgB9rB,gBAAgB,gBAChC,MAAM+rB,EAAqBtH,GAAeC,QAAQ,sBAAsBpN,MAAWuH,KAAKyL,oBACpFyB,IACFA,EAAmB7R,UAAU5E,IAAI6T,IACjC4C,EAAmB9rB,aAAa,eAAgB,QAEpD,CACA,eAAA4qB,GACE,MAAMzsB,EAAUygB,KAAKqL,gBAAkBrL,KAAKwM,aAC5C,IAAKjtB,EACH,OAEF,MAAM4tB,EAAkB5P,OAAO6P,SAAS7tB,EAAQic,aAAa,oBAAqB,IAClFwE,KAAK6E,QAAQ+F,SAAWuC,GAAmBnN,KAAK6E,QAAQ4H,eAC1D,CACA,MAAAb,CAAOzV,EAAO5W,EAAU,MACtB,GAAIygB,KAAKsL,WACP,OAEF,MAAMvN,EAAgBiC,KAAKwM,aACrBa,EAASlX,IAAUsT,GACnB6D,EAAc/tB,GAAWue,GAAqBkC,KAAKqM,YAAatO,EAAesP,EAAQrN,KAAK6E,QAAQoG,MAC1G,GAAIqC,IAAgBvP,EAClB,OAEF,MAAMwP,EAAmBvN,KAAKuM,cAAce,GACtCE,EAAehI,GACZjF,GAAaqB,QAAQ5B,KAAK4E,SAAUY,EAAW,CACpD1F,cAAewN,EACfhgB,UAAW0S,KAAKyN,kBAAkBtX,GAClCuD,KAAMsG,KAAKuM,cAAcxO,GACzBoO,GAAIoB,IAIR,GADmBC,EAAa3D,IACjB7H,iBACb,OAEF,IAAKjE,IAAkBuP,EAGrB,OAEF,MAAMI,EAAY5M,QAAQd,KAAKoL,WAC/BpL,KAAK8K,QACL9K,KAAKsL,YAAa,EAClBtL,KAAKgN,2BAA2BO,GAChCvN,KAAKqL,eAAiBiC,EACtB,MAAMK,EAAuBN,EA3OR,sBADF,oBA6ObO,EAAiBP,EA3OH,qBACA,qBA2OpBC,EAAYjS,UAAU5E,IAAImX,GAC1B/R,GAAOyR,GACPvP,EAAc1C,UAAU5E,IAAIkX,GAC5BL,EAAYjS,UAAU5E,IAAIkX,GAQ1B3N,KAAKmF,gBAPoB,KACvBmI,EAAYjS,UAAU1B,OAAOgU,EAAsBC,GACnDN,EAAYjS,UAAU5E,IAAI6T,IAC1BvM,EAAc1C,UAAU1B,OAAO2Q,GAAqBsD,EAAgBD,GACpE3N,KAAKsL,YAAa,EAClBkC,EAAa1D,GAAW,GAEY/L,EAAeiC,KAAK6N,eACtDH,GACF1N,KAAK2L,OAET,CACA,WAAAkC,GACE,OAAO7N,KAAK4E,SAASvJ,UAAU7W,SAhQV,QAiQvB,CACA,UAAAgoB,GACE,OAAO5G,GAAeC,QAAQ4E,GAAsBzK,KAAK4E,SAC3D,CACA,SAAAyH,GACE,OAAOzG,GAAezT,KAAKqY,GAAexK,KAAK4E,SACjD,CACA,cAAAmH,GACM/L,KAAKoL,YACP0C,cAAc9N,KAAKoL,WACnBpL,KAAKoL,UAAY,KAErB,CACA,iBAAA0B,CAAkBxf,GAChB,OAAI2O,KACK3O,IAAcqc,GAAiBD,GAAaD,GAE9Cnc,IAAcqc,GAAiBF,GAAaC,EACrD,CACA,iBAAA+D,CAAkBtX,GAChB,OAAI8F,KACK9F,IAAUuT,GAAaC,GAAiBC,GAE1CzT,IAAUuT,GAAaE,GAAkBD,EAClD,CAGA,sBAAOlN,CAAgBqH,GACrB,OAAO9D,KAAKuH,MAAK,WACf,MAAMld,EAAO8gB,GAAS7F,oBAAoBtF,KAAM8D,GAChD,GAAsB,iBAAXA,GAIX,GAAsB,iBAAXA,EAAqB,CAC9B,QAAqB/K,IAAjB1O,EAAKyZ,IAAyBA,EAAOrC,WAAW,MAAmB,gBAAXqC,EAC1D,MAAM,IAAIU,UAAU,oBAAoBV,MAE1CzZ,EAAKyZ,IACP,OAREzZ,EAAK8hB,GAAGrI,EASZ,GACF,EAOFvD,GAAac,GAAGhc,SAAU+kB,GAvSE,uCAuS2C,SAAUhL,GAC/E,MAAM7S,EAASqZ,GAAec,uBAAuB1G,MACrD,IAAKzT,IAAWA,EAAO8O,UAAU7W,SAAS6lB,IACxC,OAEFjL,EAAMkD,iBACN,MAAMyL,EAAW5C,GAAS7F,oBAAoB/Y,GACxCyhB,EAAahO,KAAKxE,aAAa,oBACrC,OAAIwS,GACFD,EAAS5B,GAAG6B,QACZD,EAAS7B,qBAGyC,SAAhDlJ,GAAYQ,iBAAiBxD,KAAM,UACrC+N,EAASlpB,YACTkpB,EAAS7B,sBAGX6B,EAAS7H,YACT6H,EAAS7B,oBACX,IACA3L,GAAac,GAAGzhB,OAAQuqB,IAAuB,KAC7C,MAAM8D,EAAYrI,GAAezT,KA5TR,6BA6TzB,IAAK,MAAM4b,KAAYE,EACrB9C,GAAS7F,oBAAoByI,EAC/B,IAOF5R,GAAmBgP,IAcnB,MAEM+C,GAAc,eAEdC,GAAe,OAAOD,KACtBE,GAAgB,QAAQF,KACxBG,GAAe,OAAOH,KACtBI,GAAiB,SAASJ,KAC1BK,GAAyB,QAAQL,cACjCM,GAAoB,OACpBC,GAAsB,WACtBC,GAAwB,aAExBC,GAA6B,WAAWF,OAAwBA,KAKhEG,GAAyB,8BACzBC,GAAY,CAChBpqB,OAAQ,KACRijB,QAAQ,GAEJoH,GAAgB,CACpBrqB,OAAQ,iBACRijB,OAAQ,WAOV,MAAMqH,WAAiBrK,GACrB,WAAAP,CAAY5kB,EAASukB,GACnBa,MAAMplB,EAASukB,GACf9D,KAAKgP,kBAAmB,EACxBhP,KAAKiP,cAAgB,GACrB,MAAMC,EAAatJ,GAAezT,KAAKyc,IACvC,IAAK,MAAMO,KAAQD,EAAY,CAC7B,MAAMnV,EAAW6L,GAAea,uBAAuB0I,GACjDC,EAAgBxJ,GAAezT,KAAK4H,GAAU5T,QAAOkpB,GAAgBA,IAAiBrP,KAAK4E,WAChF,OAAb7K,GAAqBqV,EAAc1e,QACrCsP,KAAKiP,cAAcrd,KAAKud,EAE5B,CACAnP,KAAKsP,sBACAtP,KAAK6E,QAAQpgB,QAChBub,KAAKuP,0BAA0BvP,KAAKiP,cAAejP,KAAKwP,YAEtDxP,KAAK6E,QAAQ6C,QACf1H,KAAK0H,QAET,CAGA,kBAAWhE,GACT,OAAOmL,EACT,CACA,sBAAWlL,GACT,OAAOmL,EACT,CACA,eAAWvS,GACT,MA9DW,UA+Db,CAGA,MAAAmL,GACM1H,KAAKwP,WACPxP,KAAKyP,OAELzP,KAAK0P,MAET,CACA,IAAAA,GACE,GAAI1P,KAAKgP,kBAAoBhP,KAAKwP,WAChC,OAEF,IAAIG,EAAiB,GAQrB,GALI3P,KAAK6E,QAAQpgB,SACfkrB,EAAiB3P,KAAK4P,uBAhEH,wCAgE4CzpB,QAAO5G,GAAWA,IAAYygB,KAAK4E,WAAU9hB,KAAIvD,GAAWwvB,GAASzJ,oBAAoB/lB,EAAS,CAC/JmoB,QAAQ,OAGRiI,EAAejf,QAAUif,EAAe,GAAGX,iBAC7C,OAGF,GADmBzO,GAAaqB,QAAQ5B,KAAK4E,SAAUuJ,IACxCnM,iBACb,OAEF,IAAK,MAAM6N,KAAkBF,EAC3BE,EAAeJ,OAEjB,MAAMK,EAAY9P,KAAK+P,gBACvB/P,KAAK4E,SAASvJ,UAAU1B,OAAO8U,IAC/BzO,KAAK4E,SAASvJ,UAAU5E,IAAIiY,IAC5B1O,KAAK4E,SAAS7jB,MAAM+uB,GAAa,EACjC9P,KAAKuP,0BAA0BvP,KAAKiP,eAAe,GACnDjP,KAAKgP,kBAAmB,EACxB,MAQMgB,EAAa,SADUF,EAAU,GAAGrL,cAAgBqL,EAAU1d,MAAM,KAE1E4N,KAAKmF,gBATY,KACfnF,KAAKgP,kBAAmB,EACxBhP,KAAK4E,SAASvJ,UAAU1B,OAAO+U,IAC/B1O,KAAK4E,SAASvJ,UAAU5E,IAAIgY,GAAqBD,IACjDxO,KAAK4E,SAAS7jB,MAAM+uB,GAAa,GACjCvP,GAAaqB,QAAQ5B,KAAK4E,SAAUwJ,GAAc,GAItBpO,KAAK4E,UAAU,GAC7C5E,KAAK4E,SAAS7jB,MAAM+uB,GAAa,GAAG9P,KAAK4E,SAASoL,MACpD,CACA,IAAAP,GACE,GAAIzP,KAAKgP,mBAAqBhP,KAAKwP,WACjC,OAGF,GADmBjP,GAAaqB,QAAQ5B,KAAK4E,SAAUyJ,IACxCrM,iBACb,OAEF,MAAM8N,EAAY9P,KAAK+P,gBACvB/P,KAAK4E,SAAS7jB,MAAM+uB,GAAa,GAAG9P,KAAK4E,SAASthB,wBAAwBwsB,OAC1EjU,GAAOmE,KAAK4E,UACZ5E,KAAK4E,SAASvJ,UAAU5E,IAAIiY,IAC5B1O,KAAK4E,SAASvJ,UAAU1B,OAAO8U,GAAqBD,IACpD,IAAK,MAAM5M,KAAW5B,KAAKiP,cAAe,CACxC,MAAM1vB,EAAUqmB,GAAec,uBAAuB9E,GAClDriB,IAAYygB,KAAKwP,SAASjwB,IAC5BygB,KAAKuP,0BAA0B,CAAC3N,IAAU,EAE9C,CACA5B,KAAKgP,kBAAmB,EAOxBhP,KAAK4E,SAAS7jB,MAAM+uB,GAAa,GACjC9P,KAAKmF,gBAPY,KACfnF,KAAKgP,kBAAmB,EACxBhP,KAAK4E,SAASvJ,UAAU1B,OAAO+U,IAC/B1O,KAAK4E,SAASvJ,UAAU5E,IAAIgY,IAC5BlO,GAAaqB,QAAQ5B,KAAK4E,SAAU0J,GAAe,GAGvBtO,KAAK4E,UAAU,EAC/C,CACA,QAAA4K,CAASjwB,EAAUygB,KAAK4E,UACtB,OAAOrlB,EAAQ8b,UAAU7W,SAASgqB,GACpC,CAGA,iBAAAxK,CAAkBF,GAGhB,OAFAA,EAAO4D,OAAS5G,QAAQgD,EAAO4D,QAC/B5D,EAAOrf,OAASiW,GAAWoJ,EAAOrf,QAC3Bqf,CACT,CACA,aAAAiM,GACE,OAAO/P,KAAK4E,SAASvJ,UAAU7W,SA3IL,uBAChB,QACC,QA0Ib,CACA,mBAAA8qB,GACE,IAAKtP,KAAK6E,QAAQpgB,OAChB,OAEF,MAAMqhB,EAAW9F,KAAK4P,uBAAuBhB,IAC7C,IAAK,MAAMrvB,KAAWumB,EAAU,CAC9B,MAAMmK,EAAWrK,GAAec,uBAAuBnnB,GACnD0wB,GACFjQ,KAAKuP,0BAA0B,CAAChwB,GAAUygB,KAAKwP,SAASS,GAE5D,CACF,CACA,sBAAAL,CAAuB7V,GACrB,MAAM+L,EAAWF,GAAezT,KAAKwc,GAA4B3O,KAAK6E,QAAQpgB,QAE9E,OAAOmhB,GAAezT,KAAK4H,EAAUiG,KAAK6E,QAAQpgB,QAAQ0B,QAAO5G,IAAYumB,EAAS1E,SAAS7hB,IACjG,CACA,yBAAAgwB,CAA0BW,EAAcC,GACtC,GAAKD,EAAaxf,OAGlB,IAAK,MAAMnR,KAAW2wB,EACpB3wB,EAAQ8b,UAAUqM,OArKK,aAqKyByI,GAChD5wB,EAAQ6B,aAAa,gBAAiB+uB,EAE1C,CAGA,sBAAO1T,CAAgBqH,GACrB,MAAMe,EAAU,CAAC,EAIjB,MAHsB,iBAAXf,GAAuB,YAAYzgB,KAAKygB,KACjDe,EAAQ6C,QAAS,GAEZ1H,KAAKuH,MAAK,WACf,MAAMld,EAAO0kB,GAASzJ,oBAAoBtF,KAAM6E,GAChD,GAAsB,iBAAXf,EAAqB,CAC9B,QAA4B,IAAjBzZ,EAAKyZ,GACd,MAAM,IAAIU,UAAU,oBAAoBV,MAE1CzZ,EAAKyZ,IACP,CACF,GACF,EAOFvD,GAAac,GAAGhc,SAAUkpB,GAAwBK,IAAwB,SAAUxP,IAErD,MAAzBA,EAAM7S,OAAOya,SAAmB5H,EAAMW,gBAAmD,MAAjCX,EAAMW,eAAeiH,UAC/E5H,EAAMkD,iBAER,IAAK,MAAM/iB,KAAWqmB,GAAee,gCAAgC3G,MACnE+O,GAASzJ,oBAAoB/lB,EAAS,CACpCmoB,QAAQ,IACPA,QAEP,IAMAvL,GAAmB4S,IAcnB,MAAMqB,GAAS,WAETC,GAAc,eACdC,GAAiB,YAGjBC,GAAiB,UACjBC,GAAmB,YAGnBC,GAAe,OAAOJ,KACtBK,GAAiB,SAASL,KAC1BM,GAAe,OAAON,KACtBO,GAAgB,QAAQP,KACxBQ,GAAyB,QAAQR,KAAcC,KAC/CQ,GAAyB,UAAUT,KAAcC,KACjDS,GAAuB,QAAQV,KAAcC,KAC7CU,GAAoB,OAMpBC,GAAyB,4DACzBC,GAA6B,GAAGD,MAA0BD,KAC1DG,GAAgB,iBAIhBC,GAAgBnV,KAAU,UAAY,YACtCoV,GAAmBpV,KAAU,YAAc,UAC3CqV,GAAmBrV,KAAU,aAAe,eAC5CsV,GAAsBtV,KAAU,eAAiB,aACjDuV,GAAkBvV,KAAU,aAAe,cAC3CwV,GAAiBxV,KAAU,cAAgB,aAG3CyV,GAAY,CAChBC,WAAW,EACX1jB,SAAU,kBACV2jB,QAAS,UACT5pB,OAAQ,CAAC,EAAG,GACZ6pB,aAAc,KACdvzB,UAAW,UAEPwzB,GAAgB,CACpBH,UAAW,mBACX1jB,SAAU,mBACV2jB,QAAS,SACT5pB,OAAQ,0BACR6pB,aAAc,yBACdvzB,UAAW,2BAOb,MAAMyzB,WAAiBrN,GACrB,WAAAP,CAAY5kB,EAASukB,GACnBa,MAAMplB,EAASukB,GACf9D,KAAKgS,QAAU,KACfhS,KAAKiS,QAAUjS,KAAK4E,SAAS7f,WAE7Bib,KAAKkS,MAAQtM,GAAe/gB,KAAKmb,KAAK4E,SAAUuM,IAAe,IAAMvL,GAAeM,KAAKlG,KAAK4E,SAAUuM,IAAe,IAAMvL,GAAeC,QAAQsL,GAAenR,KAAKiS,SACxKjS,KAAKmS,UAAYnS,KAAKoS,eACxB,CAGA,kBAAW1O,GACT,OAAOgO,EACT,CACA,sBAAW/N,GACT,OAAOmO,EACT,CACA,eAAWvV,GACT,OAAO6T,EACT,CAGA,MAAA1I,GACE,OAAO1H,KAAKwP,WAAaxP,KAAKyP,OAASzP,KAAK0P,MAC9C,CACA,IAAAA,GACE,GAAIxU,GAAW8E,KAAK4E,WAAa5E,KAAKwP,WACpC,OAEF,MAAM1P,EAAgB,CACpBA,cAAeE,KAAK4E,UAGtB,IADkBrE,GAAaqB,QAAQ5B,KAAK4E,SAAU+L,GAAc7Q,GACtDkC,iBAAd,CASA,GANAhC,KAAKqS,gBAMD,iBAAkBhtB,SAASC,kBAAoB0a,KAAKiS,QAAQjX,QAzExC,eA0EtB,IAAK,MAAMzb,IAAW,GAAGZ,UAAU0G,SAAS6G,KAAK4Z,UAC/CvF,GAAac,GAAG9hB,EAAS,YAAaqc,IAG1CoE,KAAK4E,SAAS0N,QACdtS,KAAK4E,SAASxjB,aAAa,iBAAiB,GAC5C4e,KAAKkS,MAAM7W,UAAU5E,IAAIua,IACzBhR,KAAK4E,SAASvJ,UAAU5E,IAAIua,IAC5BzQ,GAAaqB,QAAQ5B,KAAK4E,SAAUgM,GAAe9Q,EAhBnD,CAiBF,CACA,IAAA2P,GACE,GAAIvU,GAAW8E,KAAK4E,YAAc5E,KAAKwP,WACrC,OAEF,MAAM1P,EAAgB,CACpBA,cAAeE,KAAK4E,UAEtB5E,KAAKuS,cAAczS,EACrB,CACA,OAAAiF,GACM/E,KAAKgS,SACPhS,KAAKgS,QAAQhZ,UAEf2L,MAAMI,SACR,CACA,MAAAha,GACEiV,KAAKmS,UAAYnS,KAAKoS,gBAClBpS,KAAKgS,SACPhS,KAAKgS,QAAQjnB,QAEjB,CAGA,aAAAwnB,CAAczS,GAEZ,IADkBS,GAAaqB,QAAQ5B,KAAK4E,SAAU6L,GAAc3Q,GACtDkC,iBAAd,CAMA,GAAI,iBAAkB3c,SAASC,gBAC7B,IAAK,MAAM/F,IAAW,GAAGZ,UAAU0G,SAAS6G,KAAK4Z,UAC/CvF,GAAaC,IAAIjhB,EAAS,YAAaqc,IAGvCoE,KAAKgS,SACPhS,KAAKgS,QAAQhZ,UAEfgH,KAAKkS,MAAM7W,UAAU1B,OAAOqX,IAC5BhR,KAAK4E,SAASvJ,UAAU1B,OAAOqX,IAC/BhR,KAAK4E,SAASxjB,aAAa,gBAAiB,SAC5C4hB,GAAYE,oBAAoBlD,KAAKkS,MAAO,UAC5C3R,GAAaqB,QAAQ5B,KAAK4E,SAAU8L,GAAgB5Q,EAhBpD,CAiBF,CACA,UAAA+D,CAAWC,GAET,GAAgC,iBADhCA,EAASa,MAAMd,WAAWC,IACRxlB,YAA2B,GAAUwlB,EAAOxlB,YAAgE,mBAA3CwlB,EAAOxlB,UAAUgF,sBAElG,MAAM,IAAIkhB,UAAU,GAAG4L,GAAO3L,+GAEhC,OAAOX,CACT,CACA,aAAAuO,GACE,QAAsB,IAAX,EACT,MAAM,IAAI7N,UAAU,gEAEtB,IAAIgO,EAAmBxS,KAAK4E,SACG,WAA3B5E,KAAK6E,QAAQvmB,UACfk0B,EAAmBxS,KAAKiS,QACf,GAAUjS,KAAK6E,QAAQvmB,WAChCk0B,EAAmB9X,GAAWsF,KAAK6E,QAAQvmB,WACA,iBAA3B0hB,KAAK6E,QAAQvmB,YAC7Bk0B,EAAmBxS,KAAK6E,QAAQvmB,WAElC,MAAMuzB,EAAe7R,KAAKyS,mBAC1BzS,KAAKgS,QAAU,GAAoBQ,EAAkBxS,KAAKkS,MAAOL,EACnE,CACA,QAAArC,GACE,OAAOxP,KAAKkS,MAAM7W,UAAU7W,SAASwsB,GACvC,CACA,aAAA0B,GACE,MAAMC,EAAiB3S,KAAKiS,QAC5B,GAAIU,EAAetX,UAAU7W,SArKN,WAsKrB,OAAOgtB,GAET,GAAImB,EAAetX,UAAU7W,SAvKJ,aAwKvB,OAAOitB,GAET,GAAIkB,EAAetX,UAAU7W,SAzKA,iBA0K3B,MA5JsB,MA8JxB,GAAImuB,EAAetX,UAAU7W,SA3KE,mBA4K7B,MA9JyB,SAkK3B,MAAMouB,EAAkF,QAA1E3tB,iBAAiB+a,KAAKkS,OAAOpX,iBAAiB,iBAAiB6K,OAC7E,OAAIgN,EAAetX,UAAU7W,SArLP,UAsLbouB,EAAQvB,GAAmBD,GAE7BwB,EAAQrB,GAAsBD,EACvC,CACA,aAAAc,GACE,OAAkD,OAA3CpS,KAAK4E,SAAS5J,QAnLD,UAoLtB,CACA,UAAA6X,GACE,MAAM,OACJ7qB,GACEgY,KAAK6E,QACT,MAAsB,iBAAX7c,EACFA,EAAO9F,MAAM,KAAKY,KAAInF,GAAS4f,OAAO6P,SAASzvB,EAAO,MAEzC,mBAAXqK,EACF8qB,GAAc9qB,EAAO8qB,EAAY9S,KAAK4E,UAExC5c,CACT,CACA,gBAAAyqB,GACE,MAAMM,EAAwB,CAC5Br0B,UAAWshB,KAAK0S,gBAChBtc,UAAW,CAAC,CACV9V,KAAM,kBACNmB,QAAS,CACPwM,SAAU+R,KAAK6E,QAAQ5W,WAExB,CACD3N,KAAM,SACNmB,QAAS,CACPuG,OAAQgY,KAAK6S,iBAanB,OAPI7S,KAAKmS,WAAsC,WAAzBnS,KAAK6E,QAAQ+M,WACjC5O,GAAYC,iBAAiBjD,KAAKkS,MAAO,SAAU,UACnDa,EAAsB3c,UAAY,CAAC,CACjC9V,KAAM,cACNC,SAAS,KAGN,IACFwyB,KACAlW,GAAQmD,KAAK6E,QAAQgN,aAAc,CAACkB,IAE3C,CACA,eAAAC,EAAgB,IACdl2B,EAAG,OACHyP,IAEA,MAAM6f,EAAQxG,GAAezT,KAhOF,8DAgO+B6N,KAAKkS,OAAO/rB,QAAO5G,GAAWob,GAAUpb,KAC7F6sB,EAAM1b,QAMXoN,GAAqBsO,EAAO7f,EAAQzP,IAAQ0zB,IAAmBpE,EAAMhL,SAAS7U,IAAS+lB,OACzF,CAGA,sBAAO7V,CAAgBqH,GACrB,OAAO9D,KAAKuH,MAAK,WACf,MAAMld,EAAO0nB,GAASzM,oBAAoBtF,KAAM8D,GAChD,GAAsB,iBAAXA,EAAX,CAGA,QAA4B,IAAjBzZ,EAAKyZ,GACd,MAAM,IAAIU,UAAU,oBAAoBV,MAE1CzZ,EAAKyZ,IAJL,CAKF,GACF,CACA,iBAAOmP,CAAW7T,GAChB,GA5QuB,IA4QnBA,EAAMuI,QAAgD,UAAfvI,EAAMqB,MA/QnC,QA+QuDrB,EAAMtiB,IACzE,OAEF,MAAMo2B,EAActN,GAAezT,KAAK+e,IACxC,IAAK,MAAMxJ,KAAUwL,EAAa,CAChC,MAAMC,EAAUpB,GAAS1M,YAAYqC,GACrC,IAAKyL,IAAyC,IAA9BA,EAAQtO,QAAQ8M,UAC9B,SAEF,MAAMyB,EAAehU,EAAMgU,eACrBC,EAAeD,EAAahS,SAAS+R,EAAQjB,OACnD,GAAIkB,EAAahS,SAAS+R,EAAQvO,WAA2C,WAA9BuO,EAAQtO,QAAQ8M,YAA2B0B,GAA8C,YAA9BF,EAAQtO,QAAQ8M,WAA2B0B,EACnJ,SAIF,GAAIF,EAAQjB,MAAM1tB,SAAS4a,EAAM7S,UAA2B,UAAf6S,EAAMqB,MA/RvC,QA+R2DrB,EAAMtiB,KAAqB,qCAAqCuG,KAAK+b,EAAM7S,OAAOya,UACvJ,SAEF,MAAMlH,EAAgB,CACpBA,cAAeqT,EAAQvO,UAEN,UAAfxF,EAAMqB,OACRX,EAAciH,WAAa3H,GAE7B+T,EAAQZ,cAAczS,EACxB,CACF,CACA,4BAAOwT,CAAsBlU,GAI3B,MAAMmU,EAAU,kBAAkBlwB,KAAK+b,EAAM7S,OAAOya,SAC9CwM,EAjTW,WAiTKpU,EAAMtiB,IACtB22B,EAAkB,CAAClD,GAAgBC,IAAkBpP,SAAShC,EAAMtiB,KAC1E,IAAK22B,IAAoBD,EACvB,OAEF,GAAID,IAAYC,EACd,OAEFpU,EAAMkD,iBAGN,MAAMoR,EAAkB1T,KAAK+F,QAAQkL,IAA0BjR,KAAO4F,GAAeM,KAAKlG,KAAMiR,IAAwB,IAAMrL,GAAe/gB,KAAKmb,KAAMiR,IAAwB,IAAMrL,GAAeC,QAAQoL,GAAwB7R,EAAMW,eAAehb,YACpPwF,EAAWwnB,GAASzM,oBAAoBoO,GAC9C,GAAID,EAIF,OAHArU,EAAMuU,kBACNppB,EAASmlB,YACTnlB,EAASyoB,gBAAgB5T,GAGvB7U,EAASilB,aAEXpQ,EAAMuU,kBACNppB,EAASklB,OACTiE,EAAgBpB,QAEpB,EAOF/R,GAAac,GAAGhc,SAAUyrB,GAAwBG,GAAwBc,GAASuB,uBACnF/S,GAAac,GAAGhc,SAAUyrB,GAAwBK,GAAeY,GAASuB,uBAC1E/S,GAAac,GAAGhc,SAAUwrB,GAAwBkB,GAASkB,YAC3D1S,GAAac,GAAGhc,SAAU0rB,GAAsBgB,GAASkB,YACzD1S,GAAac,GAAGhc,SAAUwrB,GAAwBI,IAAwB,SAAU7R,GAClFA,EAAMkD,iBACNyP,GAASzM,oBAAoBtF,MAAM0H,QACrC,IAMAvL,GAAmB4V,IAcnB,MAAM6B,GAAS,WAETC,GAAoB,OACpBC,GAAkB,gBAAgBF,KAClCG,GAAY,CAChBC,UAAW,iBACXC,cAAe,KACf7O,YAAY,EACZzK,WAAW,EAEXuZ,YAAa,QAGTC,GAAgB,CACpBH,UAAW,SACXC,cAAe,kBACf7O,WAAY,UACZzK,UAAW,UACXuZ,YAAa,oBAOf,MAAME,WAAiB3Q,GACrB,WAAAU,CAAYL,GACVa,QACA3E,KAAK6E,QAAU7E,KAAK6D,WAAWC,GAC/B9D,KAAKqU,aAAc,EACnBrU,KAAK4E,SAAW,IAClB,CAGA,kBAAWlB,GACT,OAAOqQ,EACT,CACA,sBAAWpQ,GACT,OAAOwQ,EACT,CACA,eAAW5X,GACT,OAAOqX,EACT,CAGA,IAAAlE,CAAKrT,GACH,IAAK2D,KAAK6E,QAAQlK,UAEhB,YADAkC,GAAQR,GAGV2D,KAAKsU,UACL,MAAM/0B,EAAUygB,KAAKuU,cACjBvU,KAAK6E,QAAQO,YACfvJ,GAAOtc,GAETA,EAAQ8b,UAAU5E,IAAIod,IACtB7T,KAAKwU,mBAAkB,KACrB3X,GAAQR,EAAS,GAErB,CACA,IAAAoT,CAAKpT,GACE2D,KAAK6E,QAAQlK,WAIlBqF,KAAKuU,cAAclZ,UAAU1B,OAAOka,IACpC7T,KAAKwU,mBAAkB,KACrBxU,KAAK+E,UACLlI,GAAQR,EAAS,KANjBQ,GAAQR,EAQZ,CACA,OAAA0I,GACO/E,KAAKqU,cAGV9T,GAAaC,IAAIR,KAAK4E,SAAUkP,IAChC9T,KAAK4E,SAASjL,SACdqG,KAAKqU,aAAc,EACrB,CAGA,WAAAE,GACE,IAAKvU,KAAK4E,SAAU,CAClB,MAAM6P,EAAWpvB,SAASqvB,cAAc,OACxCD,EAAST,UAAYhU,KAAK6E,QAAQmP,UAC9BhU,KAAK6E,QAAQO,YACfqP,EAASpZ,UAAU5E,IArFD,QAuFpBuJ,KAAK4E,SAAW6P,CAClB,CACA,OAAOzU,KAAK4E,QACd,CACA,iBAAAZ,CAAkBF,GAGhB,OADAA,EAAOoQ,YAAcxZ,GAAWoJ,EAAOoQ,aAChCpQ,CACT,CACA,OAAAwQ,GACE,GAAItU,KAAKqU,YACP,OAEF,MAAM90B,EAAUygB,KAAKuU,cACrBvU,KAAK6E,QAAQqP,YAAYS,OAAOp1B,GAChCghB,GAAac,GAAG9hB,EAASu0B,IAAiB,KACxCjX,GAAQmD,KAAK6E,QAAQoP,cAAc,IAErCjU,KAAKqU,aAAc,CACrB,CACA,iBAAAG,CAAkBnY,GAChBW,GAAuBX,EAAU2D,KAAKuU,cAAevU,KAAK6E,QAAQO,WACpE,EAeF,MAEMwP,GAAc,gBACdC,GAAkB,UAAUD,KAC5BE,GAAoB,cAAcF,KAGlCG,GAAmB,WACnBC,GAAY,CAChBC,WAAW,EACXC,YAAa,MAGTC,GAAgB,CACpBF,UAAW,UACXC,YAAa,WAOf,MAAME,WAAkB3R,GACtB,WAAAU,CAAYL,GACVa,QACA3E,KAAK6E,QAAU7E,KAAK6D,WAAWC,GAC/B9D,KAAKqV,WAAY,EACjBrV,KAAKsV,qBAAuB,IAC9B,CAGA,kBAAW5R,GACT,OAAOsR,EACT,CACA,sBAAWrR,GACT,OAAOwR,EACT,CACA,eAAW5Y,GACT,MAtCW,WAuCb,CAGA,QAAAgZ,GACMvV,KAAKqV,YAGLrV,KAAK6E,QAAQoQ,WACfjV,KAAK6E,QAAQqQ,YAAY5C,QAE3B/R,GAAaC,IAAInb,SAAUuvB,IAC3BrU,GAAac,GAAGhc,SAAUwvB,IAAiBzV,GAASY,KAAKwV,eAAepW,KACxEmB,GAAac,GAAGhc,SAAUyvB,IAAmB1V,GAASY,KAAKyV,eAAerW,KAC1EY,KAAKqV,WAAY,EACnB,CACA,UAAAK,GACO1V,KAAKqV,YAGVrV,KAAKqV,WAAY,EACjB9U,GAAaC,IAAInb,SAAUuvB,IAC7B,CAGA,cAAAY,CAAepW,GACb,MAAM,YACJ8V,GACElV,KAAK6E,QACT,GAAIzF,EAAM7S,SAAWlH,UAAY+Z,EAAM7S,SAAW2oB,GAAeA,EAAY1wB,SAAS4a,EAAM7S,QAC1F,OAEF,MAAM1L,EAAW+kB,GAAeU,kBAAkB4O,GAC1B,IAApBr0B,EAAS6P,OACXwkB,EAAY5C,QACHtS,KAAKsV,uBAAyBP,GACvCl0B,EAASA,EAAS6P,OAAS,GAAG4hB,QAE9BzxB,EAAS,GAAGyxB,OAEhB,CACA,cAAAmD,CAAerW,GA1ED,QA2ERA,EAAMtiB,MAGVkjB,KAAKsV,qBAAuBlW,EAAMuW,SAAWZ,GA7EzB,UA8EtB,EAeF,MAAMa,GAAyB,oDACzBC,GAA0B,cAC1BC,GAAmB,gBACnBC,GAAkB,eAMxB,MAAMC,GACJ,WAAA7R,GACEnE,KAAK4E,SAAWvf,SAAS6G,IAC3B,CAGA,QAAA+pB,GAEE,MAAMC,EAAgB7wB,SAASC,gBAAgBuC,YAC/C,OAAO1F,KAAKoC,IAAI3E,OAAOu2B,WAAaD,EACtC,CACA,IAAAzG,GACE,MAAM5rB,EAAQmc,KAAKiW,WACnBjW,KAAKoW,mBAELpW,KAAKqW,sBAAsBrW,KAAK4E,SAAUkR,IAAkBQ,GAAmBA,EAAkBzyB,IAEjGmc,KAAKqW,sBAAsBT,GAAwBE,IAAkBQ,GAAmBA,EAAkBzyB,IAC1Gmc,KAAKqW,sBAAsBR,GAAyBE,IAAiBO,GAAmBA,EAAkBzyB,GAC5G,CACA,KAAAwO,GACE2N,KAAKuW,wBAAwBvW,KAAK4E,SAAU,YAC5C5E,KAAKuW,wBAAwBvW,KAAK4E,SAAUkR,IAC5C9V,KAAKuW,wBAAwBX,GAAwBE,IACrD9V,KAAKuW,wBAAwBV,GAAyBE,GACxD,CACA,aAAAS,GACE,OAAOxW,KAAKiW,WAAa,CAC3B,CAGA,gBAAAG,GACEpW,KAAKyW,sBAAsBzW,KAAK4E,SAAU,YAC1C5E,KAAK4E,SAAS7jB,MAAM+K,SAAW,QACjC,CACA,qBAAAuqB,CAAsBtc,EAAU2c,EAAera,GAC7C,MAAMsa,EAAiB3W,KAAKiW,WAS5BjW,KAAK4W,2BAA2B7c,GARHxa,IAC3B,GAAIA,IAAYygB,KAAK4E,UAAYhlB,OAAOu2B,WAAa52B,EAAQsI,YAAc8uB,EACzE,OAEF3W,KAAKyW,sBAAsBl3B,EAASm3B,GACpC,MAAMJ,EAAkB12B,OAAOqF,iBAAiB1F,GAASub,iBAAiB4b,GAC1En3B,EAAQwB,MAAM81B,YAAYH,EAAe,GAAGra,EAASkB,OAAOC,WAAW8Y,QAAsB,GAGjG,CACA,qBAAAG,CAAsBl3B,EAASm3B,GAC7B,MAAMI,EAAcv3B,EAAQwB,MAAM+Z,iBAAiB4b,GAC/CI,GACF9T,GAAYC,iBAAiB1jB,EAASm3B,EAAeI,EAEzD,CACA,uBAAAP,CAAwBxc,EAAU2c,GAWhC1W,KAAK4W,2BAA2B7c,GAVHxa,IAC3B,MAAM5B,EAAQqlB,GAAYQ,iBAAiBjkB,EAASm3B,GAEtC,OAAV/4B,GAIJqlB,GAAYE,oBAAoB3jB,EAASm3B,GACzCn3B,EAAQwB,MAAM81B,YAAYH,EAAe/4B,IAJvC4B,EAAQwB,MAAMg2B,eAAeL,EAIgB,GAGnD,CACA,0BAAAE,CAA2B7c,EAAUid,GACnC,GAAI,GAAUjd,GACZid,EAASjd,QAGX,IAAK,MAAMkd,KAAOrR,GAAezT,KAAK4H,EAAUiG,KAAK4E,UACnDoS,EAASC,EAEb,EAeF,MAEMC,GAAc,YAGdC,GAAe,OAAOD,KACtBE,GAAyB,gBAAgBF,KACzCG,GAAiB,SAASH,KAC1BI,GAAe,OAAOJ,KACtBK,GAAgB,QAAQL,KACxBM,GAAiB,SAASN,KAC1BO,GAAsB,gBAAgBP,KACtCQ,GAA0B,oBAAoBR,KAC9CS,GAA0B,kBAAkBT,KAC5CU,GAAyB,QAAQV,cACjCW,GAAkB,aAElBC,GAAoB,OACpBC,GAAoB,eAKpBC,GAAY,CAChBvD,UAAU,EACVnC,OAAO,EACPzH,UAAU,GAENoN,GAAgB,CACpBxD,SAAU,mBACVnC,MAAO,UACPzH,SAAU,WAOZ,MAAMqN,WAAcxT,GAClB,WAAAP,CAAY5kB,EAASukB,GACnBa,MAAMplB,EAASukB,GACf9D,KAAKmY,QAAUvS,GAAeC,QArBV,gBAqBmC7F,KAAK4E,UAC5D5E,KAAKoY,UAAYpY,KAAKqY,sBACtBrY,KAAKsY,WAAatY,KAAKuY,uBACvBvY,KAAKwP,UAAW,EAChBxP,KAAKgP,kBAAmB,EACxBhP,KAAKwY,WAAa,IAAIxC,GACtBhW,KAAK0L,oBACP,CAGA,kBAAWhI,GACT,OAAOsU,EACT,CACA,sBAAWrU,GACT,OAAOsU,EACT,CACA,eAAW1b,GACT,MA1DW,OA2Db,CAGA,MAAAmL,CAAO5H,GACL,OAAOE,KAAKwP,SAAWxP,KAAKyP,OAASzP,KAAK0P,KAAK5P,EACjD,CACA,IAAA4P,CAAK5P,GACCE,KAAKwP,UAAYxP,KAAKgP,kBAGRzO,GAAaqB,QAAQ5B,KAAK4E,SAAU0S,GAAc,CAClExX,kBAEYkC,mBAGdhC,KAAKwP,UAAW,EAChBxP,KAAKgP,kBAAmB,EACxBhP,KAAKwY,WAAW/I,OAChBpqB,SAAS6G,KAAKmP,UAAU5E,IAAIohB,IAC5B7X,KAAKyY,gBACLzY,KAAKoY,UAAU1I,MAAK,IAAM1P,KAAK0Y,aAAa5Y,KAC9C,CACA,IAAA2P,GACOzP,KAAKwP,WAAYxP,KAAKgP,mBAGTzO,GAAaqB,QAAQ5B,KAAK4E,SAAUuS,IACxCnV,mBAGdhC,KAAKwP,UAAW,EAChBxP,KAAKgP,kBAAmB,EACxBhP,KAAKsY,WAAW5C,aAChB1V,KAAK4E,SAASvJ,UAAU1B,OAAOme,IAC/B9X,KAAKmF,gBAAe,IAAMnF,KAAK2Y,cAAc3Y,KAAK4E,SAAU5E,KAAK6N,gBACnE,CACA,OAAA9I,GACExE,GAAaC,IAAI5gB,OAAQs3B,IACzB3W,GAAaC,IAAIR,KAAKmY,QAASjB,IAC/BlX,KAAKoY,UAAUrT,UACf/E,KAAKsY,WAAW5C,aAChB/Q,MAAMI,SACR,CACA,YAAA6T,GACE5Y,KAAKyY,eACP,CAGA,mBAAAJ,GACE,OAAO,IAAIjE,GAAS,CAClBzZ,UAAWmG,QAAQd,KAAK6E,QAAQ4P,UAEhCrP,WAAYpF,KAAK6N,eAErB,CACA,oBAAA0K,GACE,OAAO,IAAInD,GAAU,CACnBF,YAAalV,KAAK4E,UAEtB,CACA,YAAA8T,CAAa5Y,GAENza,SAAS6G,KAAK1H,SAASwb,KAAK4E,WAC/Bvf,SAAS6G,KAAKyoB,OAAO3U,KAAK4E,UAE5B5E,KAAK4E,SAAS7jB,MAAM6wB,QAAU,QAC9B5R,KAAK4E,SAASzjB,gBAAgB,eAC9B6e,KAAK4E,SAASxjB,aAAa,cAAc,GACzC4e,KAAK4E,SAASxjB,aAAa,OAAQ,UACnC4e,KAAK4E,SAASnZ,UAAY,EAC1B,MAAMotB,EAAYjT,GAAeC,QA7GT,cA6GsC7F,KAAKmY,SAC/DU,IACFA,EAAUptB,UAAY,GAExBoQ,GAAOmE,KAAK4E,UACZ5E,KAAK4E,SAASvJ,UAAU5E,IAAIqhB,IAU5B9X,KAAKmF,gBATsB,KACrBnF,KAAK6E,QAAQyN,OACftS,KAAKsY,WAAW/C,WAElBvV,KAAKgP,kBAAmB,EACxBzO,GAAaqB,QAAQ5B,KAAK4E,SAAU2S,GAAe,CACjDzX,iBACA,GAEoCE,KAAKmY,QAASnY,KAAK6N,cAC7D,CACA,kBAAAnC,GACEnL,GAAac,GAAGrB,KAAK4E,SAAU+S,IAAyBvY,IAhJvC,WAiJXA,EAAMtiB,MAGNkjB,KAAK6E,QAAQgG,SACf7K,KAAKyP,OAGPzP,KAAK8Y,6BAA4B,IAEnCvY,GAAac,GAAGzhB,OAAQ43B,IAAgB,KAClCxX,KAAKwP,WAAaxP,KAAKgP,kBACzBhP,KAAKyY,eACP,IAEFlY,GAAac,GAAGrB,KAAK4E,SAAU8S,IAAyBtY,IAEtDmB,GAAae,IAAItB,KAAK4E,SAAU6S,IAAqBsB,IAC/C/Y,KAAK4E,WAAaxF,EAAM7S,QAAUyT,KAAK4E,WAAamU,EAAOxsB,SAGjC,WAA1ByT,KAAK6E,QAAQ4P,SAIbzU,KAAK6E,QAAQ4P,UACfzU,KAAKyP,OAJLzP,KAAK8Y,6BAKP,GACA,GAEN,CACA,UAAAH,GACE3Y,KAAK4E,SAAS7jB,MAAM6wB,QAAU,OAC9B5R,KAAK4E,SAASxjB,aAAa,eAAe,GAC1C4e,KAAK4E,SAASzjB,gBAAgB,cAC9B6e,KAAK4E,SAASzjB,gBAAgB,QAC9B6e,KAAKgP,kBAAmB,EACxBhP,KAAKoY,UAAU3I,MAAK,KAClBpqB,SAAS6G,KAAKmP,UAAU1B,OAAOke,IAC/B7X,KAAKgZ,oBACLhZ,KAAKwY,WAAWnmB,QAChBkO,GAAaqB,QAAQ5B,KAAK4E,SAAUyS,GAAe,GAEvD,CACA,WAAAxJ,GACE,OAAO7N,KAAK4E,SAASvJ,UAAU7W,SAjLT,OAkLxB,CACA,0BAAAs0B,GAEE,GADkBvY,GAAaqB,QAAQ5B,KAAK4E,SAAUwS,IACxCpV,iBACZ,OAEF,MAAMiX,EAAqBjZ,KAAK4E,SAASvX,aAAehI,SAASC,gBAAgBsC,aAC3EsxB,EAAmBlZ,KAAK4E,SAAS7jB,MAAMiL,UAEpB,WAArBktB,GAAiClZ,KAAK4E,SAASvJ,UAAU7W,SAASuzB,MAGjEkB,IACHjZ,KAAK4E,SAAS7jB,MAAMiL,UAAY,UAElCgU,KAAK4E,SAASvJ,UAAU5E,IAAIshB,IAC5B/X,KAAKmF,gBAAe,KAClBnF,KAAK4E,SAASvJ,UAAU1B,OAAOoe,IAC/B/X,KAAKmF,gBAAe,KAClBnF,KAAK4E,SAAS7jB,MAAMiL,UAAYktB,CAAgB,GAC/ClZ,KAAKmY,QAAQ,GACfnY,KAAKmY,SACRnY,KAAK4E,SAAS0N,QAChB,CAMA,aAAAmG,GACE,MAAMQ,EAAqBjZ,KAAK4E,SAASvX,aAAehI,SAASC,gBAAgBsC,aAC3E+uB,EAAiB3W,KAAKwY,WAAWvC,WACjCkD,EAAoBxC,EAAiB,EAC3C,GAAIwC,IAAsBF,EAAoB,CAC5C,MAAMn3B,EAAWma,KAAU,cAAgB,eAC3C+D,KAAK4E,SAAS7jB,MAAMe,GAAY,GAAG60B,KACrC,CACA,IAAKwC,GAAqBF,EAAoB,CAC5C,MAAMn3B,EAAWma,KAAU,eAAiB,cAC5C+D,KAAK4E,SAAS7jB,MAAMe,GAAY,GAAG60B,KACrC,CACF,CACA,iBAAAqC,GACEhZ,KAAK4E,SAAS7jB,MAAMq4B,YAAc,GAClCpZ,KAAK4E,SAAS7jB,MAAMs4B,aAAe,EACrC,CAGA,sBAAO5c,CAAgBqH,EAAQhE,GAC7B,OAAOE,KAAKuH,MAAK,WACf,MAAMld,EAAO6tB,GAAM5S,oBAAoBtF,KAAM8D,GAC7C,GAAsB,iBAAXA,EAAX,CAGA,QAA4B,IAAjBzZ,EAAKyZ,GACd,MAAM,IAAIU,UAAU,oBAAoBV,MAE1CzZ,EAAKyZ,GAAQhE,EAJb,CAKF,GACF,EAOFS,GAAac,GAAGhc,SAAUuyB,GA9OK,4BA8O2C,SAAUxY,GAClF,MAAM7S,EAASqZ,GAAec,uBAAuB1G,MACjD,CAAC,IAAK,QAAQoB,SAASpB,KAAKgH,UAC9B5H,EAAMkD,iBAER/B,GAAae,IAAI/U,EAAQ+qB,IAAcgC,IACjCA,EAAUtX,kBAIdzB,GAAae,IAAI/U,EAAQ8qB,IAAgB,KACnC1c,GAAUqF,OACZA,KAAKsS,OACP,GACA,IAIJ,MAAMiH,EAAc3T,GAAeC,QAnQb,eAoQlB0T,GACFrB,GAAM7S,YAAYkU,GAAa9J,OAEpByI,GAAM5S,oBAAoB/Y,GAClCmb,OAAO1H,KACd,IACA4G,GAAqBsR,IAMrB/b,GAAmB+b,IAcnB,MAEMsB,GAAc,gBACdC,GAAiB,YACjBC,GAAwB,OAAOF,KAAcC,KAE7CE,GAAoB,OACpBC,GAAuB,UACvBC,GAAoB,SAEpBC,GAAgB,kBAChBC,GAAe,OAAOP,KACtBQ,GAAgB,QAAQR,KACxBS,GAAe,OAAOT,KACtBU,GAAuB,gBAAgBV,KACvCW,GAAiB,SAASX,KAC1BY,GAAe,SAASZ,KACxBa,GAAyB,QAAQb,KAAcC,KAC/Ca,GAAwB,kBAAkBd,KAE1Ce,GAAY,CAChB9F,UAAU,EACV5J,UAAU,EACVpgB,QAAQ,GAEJ+vB,GAAgB,CACpB/F,SAAU,mBACV5J,SAAU,UACVpgB,OAAQ,WAOV,MAAMgwB,WAAkB/V,GACtB,WAAAP,CAAY5kB,EAASukB,GACnBa,MAAMplB,EAASukB,GACf9D,KAAKwP,UAAW,EAChBxP,KAAKoY,UAAYpY,KAAKqY,sBACtBrY,KAAKsY,WAAatY,KAAKuY,uBACvBvY,KAAK0L,oBACP,CAGA,kBAAWhI,GACT,OAAO6W,EACT,CACA,sBAAW5W,GACT,OAAO6W,EACT,CACA,eAAWje,GACT,MApDW,WAqDb,CAGA,MAAAmL,CAAO5H,GACL,OAAOE,KAAKwP,SAAWxP,KAAKyP,OAASzP,KAAK0P,KAAK5P,EACjD,CACA,IAAA4P,CAAK5P,GACCE,KAAKwP,UAGSjP,GAAaqB,QAAQ5B,KAAK4E,SAAUmV,GAAc,CAClEja,kBAEYkC,mBAGdhC,KAAKwP,UAAW,EAChBxP,KAAKoY,UAAU1I,OACV1P,KAAK6E,QAAQpa,SAChB,IAAIurB,IAAkBvG,OAExBzP,KAAK4E,SAASxjB,aAAa,cAAc,GACzC4e,KAAK4E,SAASxjB,aAAa,OAAQ,UACnC4e,KAAK4E,SAASvJ,UAAU5E,IAAImjB,IAW5B5Z,KAAKmF,gBAVoB,KAClBnF,KAAK6E,QAAQpa,SAAUuV,KAAK6E,QAAQ4P,UACvCzU,KAAKsY,WAAW/C,WAElBvV,KAAK4E,SAASvJ,UAAU5E,IAAIkjB,IAC5B3Z,KAAK4E,SAASvJ,UAAU1B,OAAOigB,IAC/BrZ,GAAaqB,QAAQ5B,KAAK4E,SAAUoV,GAAe,CACjDla,iBACA,GAEkCE,KAAK4E,UAAU,GACvD,CACA,IAAA6K,GACOzP,KAAKwP,WAGQjP,GAAaqB,QAAQ5B,KAAK4E,SAAUqV,IACxCjY,mBAGdhC,KAAKsY,WAAW5C,aAChB1V,KAAK4E,SAAS8V,OACd1a,KAAKwP,UAAW,EAChBxP,KAAK4E,SAASvJ,UAAU5E,IAAIojB,IAC5B7Z,KAAKoY,UAAU3I,OAUfzP,KAAKmF,gBAToB,KACvBnF,KAAK4E,SAASvJ,UAAU1B,OAAOggB,GAAmBE,IAClD7Z,KAAK4E,SAASzjB,gBAAgB,cAC9B6e,KAAK4E,SAASzjB,gBAAgB,QACzB6e,KAAK6E,QAAQpa,SAChB,IAAIurB,IAAkB3jB,QAExBkO,GAAaqB,QAAQ5B,KAAK4E,SAAUuV,GAAe,GAEfna,KAAK4E,UAAU,IACvD,CACA,OAAAG,GACE/E,KAAKoY,UAAUrT,UACf/E,KAAKsY,WAAW5C,aAChB/Q,MAAMI,SACR,CAGA,mBAAAsT,GACE,MASM1d,EAAYmG,QAAQd,KAAK6E,QAAQ4P,UACvC,OAAO,IAAIL,GAAS,CAClBJ,UA3HsB,qBA4HtBrZ,YACAyK,YAAY,EACZ8O,YAAalU,KAAK4E,SAAS7f,WAC3BkvB,cAAetZ,EAfK,KACU,WAA1BqF,KAAK6E,QAAQ4P,SAIjBzU,KAAKyP,OAHHlP,GAAaqB,QAAQ5B,KAAK4E,SAAUsV,GAG3B,EAUgC,MAE/C,CACA,oBAAA3B,GACE,OAAO,IAAInD,GAAU,CACnBF,YAAalV,KAAK4E,UAEtB,CACA,kBAAA8G,GACEnL,GAAac,GAAGrB,KAAK4E,SAAU0V,IAAuBlb,IA5IvC,WA6ITA,EAAMtiB,MAGNkjB,KAAK6E,QAAQgG,SACf7K,KAAKyP,OAGPlP,GAAaqB,QAAQ5B,KAAK4E,SAAUsV,IAAqB,GAE7D,CAGA,sBAAOzd,CAAgBqH,GACrB,OAAO9D,KAAKuH,MAAK,WACf,MAAMld,EAAOowB,GAAUnV,oBAAoBtF,KAAM8D,GACjD,GAAsB,iBAAXA,EAAX,CAGA,QAAqB/K,IAAjB1O,EAAKyZ,IAAyBA,EAAOrC,WAAW,MAAmB,gBAAXqC,EAC1D,MAAM,IAAIU,UAAU,oBAAoBV,MAE1CzZ,EAAKyZ,GAAQ9D,KAJb,CAKF,GACF,EAOFO,GAAac,GAAGhc,SAAUg1B,GA7JK,gCA6J2C,SAAUjb,GAClF,MAAM7S,EAASqZ,GAAec,uBAAuB1G,MAIrD,GAHI,CAAC,IAAK,QAAQoB,SAASpB,KAAKgH,UAC9B5H,EAAMkD,iBAEJpH,GAAW8E,MACb,OAEFO,GAAae,IAAI/U,EAAQ4tB,IAAgB,KAEnCxf,GAAUqF,OACZA,KAAKsS,OACP,IAIF,MAAMiH,EAAc3T,GAAeC,QAAQiU,IACvCP,GAAeA,IAAgBhtB,GACjCkuB,GAAUpV,YAAYkU,GAAa9J,OAExBgL,GAAUnV,oBAAoB/Y,GACtCmb,OAAO1H,KACd,IACAO,GAAac,GAAGzhB,OAAQ85B,IAAuB,KAC7C,IAAK,MAAM3f,KAAY6L,GAAezT,KAAK2nB,IACzCW,GAAUnV,oBAAoBvL,GAAU2V,MAC1C,IAEFnP,GAAac,GAAGzhB,OAAQw6B,IAAc,KACpC,IAAK,MAAM76B,KAAWqmB,GAAezT,KAAK,gDACG,UAAvClN,iBAAiB1F,GAASiC,UAC5Bi5B,GAAUnV,oBAAoB/lB,GAASkwB,MAE3C,IAEF7I,GAAqB6T,IAMrBte,GAAmBse,IAUnB,MACME,GAAmB,CAEvB,IAAK,CAAC,QAAS,MAAO,KAAM,OAAQ,OAHP,kBAI7B9pB,EAAG,CAAC,SAAU,OAAQ,QAAS,OAC/B+pB,KAAM,GACN9pB,EAAG,GACH+pB,GAAI,GACJC,IAAK,GACLC,KAAM,GACNC,IAAK,GACLC,GAAI,GACJC,GAAI,GACJC,GAAI,GACJC,GAAI,GACJC,GAAI,GACJC,GAAI,GACJC,GAAI,GACJC,GAAI,GACJnqB,EAAG,GACHub,IAAK,CAAC,MAAO,SAAU,MAAO,QAAS,QAAS,UAChD6O,GAAI,GACJC,GAAI,GACJC,EAAG,GACHC,IAAK,GACLC,EAAG,GACHC,MAAO,GACPC,KAAM,GACNC,IAAK,GACLC,IAAK,GACLC,OAAQ,GACRC,EAAG,GACHC,GAAI,IAIAC,GAAgB,IAAI/lB,IAAI,CAAC,aAAc,OAAQ,OAAQ,WAAY,WAAY,SAAU,MAAO,eAShGgmB,GAAmB,0DACnBC,GAAmB,CAACx6B,EAAWy6B,KACnC,MAAMC,EAAgB16B,EAAUvC,SAASC,cACzC,OAAI+8B,EAAqBpb,SAASqb,IAC5BJ,GAAc1lB,IAAI8lB,IACb3b,QAAQwb,GAAiBj5B,KAAKtB,EAAU26B,YAM5CF,EAAqBr2B,QAAOw2B,GAAkBA,aAA0BpY,SAAQ9R,MAAKmqB,GAASA,EAAMv5B,KAAKo5B,IAAe,EA0C3HI,GAAY,CAChBC,UAAWnC,GACXoC,QAAS,CAAC,EAEVC,WAAY,GACZnwB,MAAM,EACNowB,UAAU,EACVC,WAAY,KACZC,SAAU,eAENC,GAAgB,CACpBN,UAAW,SACXC,QAAS,SACTC,WAAY,oBACZnwB,KAAM,UACNowB,SAAU,UACVC,WAAY,kBACZC,SAAU,UAENE,GAAqB,CACzBC,MAAO,iCACPvjB,SAAU,oBAOZ,MAAMwjB,WAAwB9Z,GAC5B,WAAAU,CAAYL,GACVa,QACA3E,KAAK6E,QAAU7E,KAAK6D,WAAWC,EACjC,CAGA,kBAAWJ,GACT,OAAOmZ,EACT,CACA,sBAAWlZ,GACT,OAAOyZ,EACT,CACA,eAAW7gB,GACT,MA3CW,iBA4Cb,CAGA,UAAAihB,GACE,OAAOxgC,OAAOmiB,OAAOa,KAAK6E,QAAQkY,SAASj6B,KAAIghB,GAAU9D,KAAKyd,yBAAyB3Z,KAAS3d,OAAO2a,QACzG,CACA,UAAA4c,GACE,OAAO1d,KAAKwd,aAAa9sB,OAAS,CACpC,CACA,aAAAitB,CAAcZ,GAMZ,OALA/c,KAAK4d,cAAcb,GACnB/c,KAAK6E,QAAQkY,QAAU,IAClB/c,KAAK6E,QAAQkY,WACbA,GAEE/c,IACT,CACA,MAAA6d,GACE,MAAMC,EAAkBz4B,SAASqvB,cAAc,OAC/CoJ,EAAgBC,UAAY/d,KAAKge,eAAehe,KAAK6E,QAAQsY,UAC7D,IAAK,MAAOpjB,EAAUkkB,KAASjhC,OAAOmkB,QAAQnB,KAAK6E,QAAQkY,SACzD/c,KAAKke,YAAYJ,EAAiBG,EAAMlkB,GAE1C,MAAMojB,EAAWW,EAAgBhY,SAAS,GACpCkX,EAAahd,KAAKyd,yBAAyBzd,KAAK6E,QAAQmY,YAI9D,OAHIA,GACFG,EAAS9hB,UAAU5E,OAAOumB,EAAW96B,MAAM,MAEtCi7B,CACT,CAGA,gBAAAlZ,CAAiBH,GACfa,MAAMV,iBAAiBH,GACvB9D,KAAK4d,cAAc9Z,EAAOiZ,QAC5B,CACA,aAAAa,CAAcO,GACZ,IAAK,MAAOpkB,EAAUgjB,KAAY//B,OAAOmkB,QAAQgd,GAC/CxZ,MAAMV,iBAAiB,CACrBlK,WACAujB,MAAOP,GACNM,GAEP,CACA,WAAAa,CAAYf,EAAUJ,EAAShjB,GAC7B,MAAMqkB,EAAkBxY,GAAeC,QAAQ9L,EAAUojB,GACpDiB,KAGLrB,EAAU/c,KAAKyd,yBAAyBV,IAKpC,GAAUA,GACZ/c,KAAKqe,sBAAsB3jB,GAAWqiB,GAAUqB,GAG9Cpe,KAAK6E,QAAQhY,KACfuxB,EAAgBL,UAAY/d,KAAKge,eAAejB,GAGlDqB,EAAgBE,YAAcvB,EAX5BqB,EAAgBzkB,SAYpB,CACA,cAAAqkB,CAAeG,GACb,OAAOne,KAAK6E,QAAQoY,SApJxB,SAAsBsB,EAAYzB,EAAW0B,GAC3C,IAAKD,EAAW7tB,OACd,OAAO6tB,EAET,GAAIC,GAAgD,mBAArBA,EAC7B,OAAOA,EAAiBD,GAE1B,MACME,GADY,IAAI7+B,OAAO8+B,WACKC,gBAAgBJ,EAAY,aACxD19B,EAAW,GAAGlC,UAAU8/B,EAAgBvyB,KAAKkU,iBAAiB,MACpE,IAAK,MAAM7gB,KAAWsB,EAAU,CAC9B,MAAM+9B,EAAcr/B,EAAQC,SAASC,cACrC,IAAKzC,OAAO4D,KAAKk8B,GAAW1b,SAASwd,GAAc,CACjDr/B,EAAQoa,SACR,QACF,CACA,MAAMklB,EAAgB,GAAGlgC,UAAUY,EAAQ0B,YACrC69B,EAAoB,GAAGngC,OAAOm+B,EAAU,MAAQ,GAAIA,EAAU8B,IAAgB,IACpF,IAAK,MAAM78B,KAAa88B,EACjBtC,GAAiBx6B,EAAW+8B,IAC/Bv/B,EAAQ4B,gBAAgBY,EAAUvC,SAGxC,CACA,OAAOi/B,EAAgBvyB,KAAK6xB,SAC9B,CA2HmCgB,CAAaZ,EAAKne,KAAK6E,QAAQiY,UAAW9c,KAAK6E,QAAQqY,YAAciB,CACtG,CACA,wBAAAV,CAAyBU,GACvB,OAAOthB,GAAQshB,EAAK,CAACne,MACvB,CACA,qBAAAqe,CAAsB9+B,EAAS6+B,GAC7B,GAAIpe,KAAK6E,QAAQhY,KAGf,OAFAuxB,EAAgBL,UAAY,QAC5BK,EAAgBzJ,OAAOp1B,GAGzB6+B,EAAgBE,YAAc/+B,EAAQ++B,WACxC,EAeF,MACMU,GAAwB,IAAI1oB,IAAI,CAAC,WAAY,YAAa,eAC1D2oB,GAAoB,OAEpBC,GAAoB,OAEpBC,GAAiB,SACjBC,GAAmB,gBACnBC,GAAgB,QAChBC,GAAgB,QAahBC,GAAgB,CACpBC,KAAM,OACNC,IAAK,MACLC,MAAOzjB,KAAU,OAAS,QAC1B0jB,OAAQ,SACRC,KAAM3jB,KAAU,QAAU,QAEtB4jB,GAAY,CAChB/C,UAAWnC,GACXmF,WAAW,EACX7xB,SAAU,kBACV8xB,WAAW,EACXC,YAAa,GACbC,MAAO,EACPjwB,mBAAoB,CAAC,MAAO,QAAS,SAAU,QAC/CnD,MAAM,EACN7E,OAAQ,CAAC,EAAG,GACZtJ,UAAW,MACXmzB,aAAc,KACdoL,UAAU,EACVC,WAAY,KACZnjB,UAAU,EACVojB,SAAU,+GACV+C,MAAO,GACPte,QAAS,eAELue,GAAgB,CACpBrD,UAAW,SACXgD,UAAW,UACX7xB,SAAU,mBACV8xB,UAAW,2BACXC,YAAa,oBACbC,MAAO,kBACPjwB,mBAAoB,QACpBnD,KAAM,UACN7E,OAAQ,0BACRtJ,UAAW,oBACXmzB,aAAc,yBACdoL,SAAU,UACVC,WAAY,kBACZnjB,SAAU,mBACVojB,SAAU,SACV+C,MAAO,4BACPte,QAAS,UAOX,MAAMwe,WAAgB1b,GACpB,WAAAP,CAAY5kB,EAASukB,GACnB,QAAsB,IAAX,EACT,MAAM,IAAIU,UAAU,+DAEtBG,MAAMplB,EAASukB,GAGf9D,KAAKqgB,YAAa,EAClBrgB,KAAKsgB,SAAW,EAChBtgB,KAAKugB,WAAa,KAClBvgB,KAAKwgB,eAAiB,CAAC,EACvBxgB,KAAKgS,QAAU,KACfhS,KAAKygB,iBAAmB,KACxBzgB,KAAK0gB,YAAc,KAGnB1gB,KAAK2gB,IAAM,KACX3gB,KAAK4gB,gBACA5gB,KAAK6E,QAAQ9K,UAChBiG,KAAK6gB,WAET,CAGA,kBAAWnd,GACT,OAAOmc,EACT,CACA,sBAAWlc,GACT,OAAOwc,EACT,CACA,eAAW5jB,GACT,MAxGW,SAyGb,CAGA,MAAAukB,GACE9gB,KAAKqgB,YAAa,CACpB,CACA,OAAAU,GACE/gB,KAAKqgB,YAAa,CACpB,CACA,aAAAW,GACEhhB,KAAKqgB,YAAcrgB,KAAKqgB,UAC1B,CACA,MAAA3Y,GACO1H,KAAKqgB,aAGVrgB,KAAKwgB,eAAeS,OAASjhB,KAAKwgB,eAAeS,MAC7CjhB,KAAKwP,WACPxP,KAAKkhB,SAGPlhB,KAAKmhB,SACP,CACA,OAAApc,GACEgI,aAAa/M,KAAKsgB,UAClB/f,GAAaC,IAAIR,KAAK4E,SAAS5J,QAAQmkB,IAAiBC,GAAkBpf,KAAKohB,mBAC3EphB,KAAK4E,SAASpJ,aAAa,2BAC7BwE,KAAK4E,SAASxjB,aAAa,QAAS4e,KAAK4E,SAASpJ,aAAa,2BAEjEwE,KAAKqhB,iBACL1c,MAAMI,SACR,CACA,IAAA2K,GACE,GAAoC,SAAhC1P,KAAK4E,SAAS7jB,MAAM6wB,QACtB,MAAM,IAAIhO,MAAM,uCAElB,IAAM5D,KAAKshB,mBAAoBthB,KAAKqgB,WAClC,OAEF,MAAM/G,EAAY/Y,GAAaqB,QAAQ5B,KAAK4E,SAAU5E,KAAKmE,YAAYqB,UAlItD,SAoIX+b,GADa9lB,GAAeuE,KAAK4E,WACL5E,KAAK4E,SAAS9kB,cAAcwF,iBAAiBd,SAASwb,KAAK4E,UAC7F,GAAI0U,EAAUtX,mBAAqBuf,EACjC,OAIFvhB,KAAKqhB,iBACL,MAAMV,EAAM3gB,KAAKwhB,iBACjBxhB,KAAK4E,SAASxjB,aAAa,mBAAoBu/B,EAAInlB,aAAa,OAChE,MAAM,UACJukB,GACE/f,KAAK6E,QAYT,GAXK7E,KAAK4E,SAAS9kB,cAAcwF,gBAAgBd,SAASwb,KAAK2gB,OAC7DZ,EAAUpL,OAAOgM,GACjBpgB,GAAaqB,QAAQ5B,KAAK4E,SAAU5E,KAAKmE,YAAYqB,UAhJpC,cAkJnBxF,KAAKgS,QAAUhS,KAAKqS,cAAcsO,GAClCA,EAAItlB,UAAU5E,IAAIyoB,IAMd,iBAAkB75B,SAASC,gBAC7B,IAAK,MAAM/F,IAAW,GAAGZ,UAAU0G,SAAS6G,KAAK4Z,UAC/CvF,GAAac,GAAG9hB,EAAS,YAAaqc,IAU1CoE,KAAKmF,gBAPY,KACf5E,GAAaqB,QAAQ5B,KAAK4E,SAAU5E,KAAKmE,YAAYqB,UAhKrC,WAiKQ,IAApBxF,KAAKugB,YACPvgB,KAAKkhB,SAEPlhB,KAAKugB,YAAa,CAAK,GAEKvgB,KAAK2gB,IAAK3gB,KAAK6N,cAC/C,CACA,IAAA4B,GACE,GAAKzP,KAAKwP,aAGQjP,GAAaqB,QAAQ5B,KAAK4E,SAAU5E,KAAKmE,YAAYqB,UA/KtD,SAgLHxD,iBAAd,CAQA,GALYhC,KAAKwhB,iBACbnmB,UAAU1B,OAAOulB,IAIjB,iBAAkB75B,SAASC,gBAC7B,IAAK,MAAM/F,IAAW,GAAGZ,UAAU0G,SAAS6G,KAAK4Z,UAC/CvF,GAAaC,IAAIjhB,EAAS,YAAaqc,IAG3CoE,KAAKwgB,eAA4B,OAAI,EACrCxgB,KAAKwgB,eAAelB,KAAiB,EACrCtf,KAAKwgB,eAAenB,KAAiB,EACrCrf,KAAKugB,WAAa,KAYlBvgB,KAAKmF,gBAVY,KACXnF,KAAKyhB,yBAGJzhB,KAAKugB,YACRvgB,KAAKqhB,iBAEPrhB,KAAK4E,SAASzjB,gBAAgB,oBAC9Bof,GAAaqB,QAAQ5B,KAAK4E,SAAU5E,KAAKmE,YAAYqB,UAzMpC,WAyM8D,GAEnDxF,KAAK2gB,IAAK3gB,KAAK6N,cA1B7C,CA2BF,CACA,MAAA9iB,GACMiV,KAAKgS,SACPhS,KAAKgS,QAAQjnB,QAEjB,CAGA,cAAAu2B,GACE,OAAOxgB,QAAQd,KAAK0hB,YACtB,CACA,cAAAF,GAIE,OAHKxhB,KAAK2gB,MACR3gB,KAAK2gB,IAAM3gB,KAAK2hB,kBAAkB3hB,KAAK0gB,aAAe1gB,KAAK4hB,2BAEtD5hB,KAAK2gB,GACd,CACA,iBAAAgB,CAAkB5E,GAChB,MAAM4D,EAAM3gB,KAAK6hB,oBAAoB9E,GAASc,SAG9C,IAAK8C,EACH,OAAO,KAETA,EAAItlB,UAAU1B,OAAOslB,GAAmBC,IAExCyB,EAAItlB,UAAU5E,IAAI,MAAMuJ,KAAKmE,YAAY5H,aACzC,MAAMulB,EAvuGKC,KACb,GACEA,GAAU5/B,KAAK6/B,MA/BH,IA+BS7/B,KAAK8/B,gBACnB58B,SAAS68B,eAAeH,IACjC,OAAOA,CAAM,EAmuGGI,CAAOniB,KAAKmE,YAAY5H,MAAM1c,WAK5C,OAJA8gC,EAAIv/B,aAAa,KAAM0gC,GACnB9hB,KAAK6N,eACP8S,EAAItlB,UAAU5E,IAAIwoB,IAEb0B,CACT,CACA,UAAAyB,CAAWrF,GACT/c,KAAK0gB,YAAc3D,EACf/c,KAAKwP,aACPxP,KAAKqhB,iBACLrhB,KAAK0P,OAET,CACA,mBAAAmS,CAAoB9E,GAYlB,OAXI/c,KAAKygB,iBACPzgB,KAAKygB,iBAAiB9C,cAAcZ,GAEpC/c,KAAKygB,iBAAmB,IAAIlD,GAAgB,IACvCvd,KAAK6E,QAGRkY,UACAC,WAAYhd,KAAKyd,yBAAyBzd,KAAK6E,QAAQmb,eAGpDhgB,KAAKygB,gBACd,CACA,sBAAAmB,GACE,MAAO,CACL,iBAA0B5hB,KAAK0hB,YAEnC,CACA,SAAAA,GACE,OAAO1hB,KAAKyd,yBAAyBzd,KAAK6E,QAAQqb,QAAUlgB,KAAK4E,SAASpJ,aAAa,yBACzF,CAGA,4BAAA6mB,CAA6BjjB,GAC3B,OAAOY,KAAKmE,YAAYmB,oBAAoBlG,EAAMW,eAAgBC,KAAKsiB,qBACzE,CACA,WAAAzU,GACE,OAAO7N,KAAK6E,QAAQib,WAAa9f,KAAK2gB,KAAO3gB,KAAK2gB,IAAItlB,UAAU7W,SAASy6B,GAC3E,CACA,QAAAzP,GACE,OAAOxP,KAAK2gB,KAAO3gB,KAAK2gB,IAAItlB,UAAU7W,SAAS06B,GACjD,CACA,aAAA7M,CAAcsO,GACZ,MAAMjiC,EAAYme,GAAQmD,KAAK6E,QAAQnmB,UAAW,CAACshB,KAAM2gB,EAAK3gB,KAAK4E,WAC7D2d,EAAahD,GAAc7gC,EAAU+lB,eAC3C,OAAO,GAAoBzE,KAAK4E,SAAU+b,EAAK3gB,KAAKyS,iBAAiB8P,GACvE,CACA,UAAA1P,GACE,MAAM,OACJ7qB,GACEgY,KAAK6E,QACT,MAAsB,iBAAX7c,EACFA,EAAO9F,MAAM,KAAKY,KAAInF,GAAS4f,OAAO6P,SAASzvB,EAAO,MAEzC,mBAAXqK,EACF8qB,GAAc9qB,EAAO8qB,EAAY9S,KAAK4E,UAExC5c,CACT,CACA,wBAAAy1B,CAAyBU,GACvB,OAAOthB,GAAQshB,EAAK,CAACne,KAAK4E,UAC5B,CACA,gBAAA6N,CAAiB8P,GACf,MAAMxP,EAAwB,CAC5Br0B,UAAW6jC,EACXnsB,UAAW,CAAC,CACV9V,KAAM,OACNmB,QAAS,CACPuO,mBAAoBgQ,KAAK6E,QAAQ7U,qBAElC,CACD1P,KAAM,SACNmB,QAAS,CACPuG,OAAQgY,KAAK6S,eAEd,CACDvyB,KAAM,kBACNmB,QAAS,CACPwM,SAAU+R,KAAK6E,QAAQ5W,WAExB,CACD3N,KAAM,QACNmB,QAAS,CACPlC,QAAS,IAAIygB,KAAKmE,YAAY5H,eAE/B,CACDjc,KAAM,kBACNC,SAAS,EACTC,MAAO,aACPC,GAAI4J,IAGF2V,KAAKwhB,iBAAiBpgC,aAAa,wBAAyBiJ,EAAK1J,MAAMjC,UAAU,KAIvF,MAAO,IACFq0B,KACAlW,GAAQmD,KAAK6E,QAAQgN,aAAc,CAACkB,IAE3C,CACA,aAAA6N,GACE,MAAM4B,EAAWxiB,KAAK6E,QAAQjD,QAAQ1f,MAAM,KAC5C,IAAK,MAAM0f,KAAW4gB,EACpB,GAAgB,UAAZ5gB,EACFrB,GAAac,GAAGrB,KAAK4E,SAAU5E,KAAKmE,YAAYqB,UAjVlC,SAiV4DxF,KAAK6E,QAAQ9K,UAAUqF,IAC/EY,KAAKqiB,6BAA6BjjB,GAC1CsI,QAAQ,SAEb,GA3VU,WA2VN9F,EAA4B,CACrC,MAAM6gB,EAAU7gB,IAAYyd,GAAgBrf,KAAKmE,YAAYqB,UAnV5C,cAmV0ExF,KAAKmE,YAAYqB,UArV5F,WAsVVkd,EAAW9gB,IAAYyd,GAAgBrf,KAAKmE,YAAYqB,UAnV7C,cAmV2ExF,KAAKmE,YAAYqB,UArV5F,YAsVjBjF,GAAac,GAAGrB,KAAK4E,SAAU6d,EAASziB,KAAK6E,QAAQ9K,UAAUqF,IAC7D,MAAM+T,EAAUnT,KAAKqiB,6BAA6BjjB,GAClD+T,EAAQqN,eAA8B,YAAfphB,EAAMqB,KAAqB6e,GAAgBD,KAAiB,EACnFlM,EAAQgO,QAAQ,IAElB5gB,GAAac,GAAGrB,KAAK4E,SAAU8d,EAAU1iB,KAAK6E,QAAQ9K,UAAUqF,IAC9D,MAAM+T,EAAUnT,KAAKqiB,6BAA6BjjB,GAClD+T,EAAQqN,eAA8B,aAAfphB,EAAMqB,KAAsB6e,GAAgBD,IAAiBlM,EAAQvO,SAASpgB,SAAS4a,EAAMU,eACpHqT,EAAQ+N,QAAQ,GAEpB,CAEFlhB,KAAKohB,kBAAoB,KACnBphB,KAAK4E,UACP5E,KAAKyP,MACP,EAEFlP,GAAac,GAAGrB,KAAK4E,SAAS5J,QAAQmkB,IAAiBC,GAAkBpf,KAAKohB,kBAChF,CACA,SAAAP,GACE,MAAMX,EAAQlgB,KAAK4E,SAASpJ,aAAa,SACpC0kB,IAGAlgB,KAAK4E,SAASpJ,aAAa,eAAkBwE,KAAK4E,SAAS0Z,YAAY3Y,QAC1E3F,KAAK4E,SAASxjB,aAAa,aAAc8+B,GAE3ClgB,KAAK4E,SAASxjB,aAAa,yBAA0B8+B,GACrDlgB,KAAK4E,SAASzjB,gBAAgB,SAChC,CACA,MAAAggC,GACMnhB,KAAKwP,YAAcxP,KAAKugB,WAC1BvgB,KAAKugB,YAAa,GAGpBvgB,KAAKugB,YAAa,EAClBvgB,KAAK2iB,aAAY,KACX3iB,KAAKugB,YACPvgB,KAAK0P,MACP,GACC1P,KAAK6E,QAAQob,MAAMvQ,MACxB,CACA,MAAAwR,GACMlhB,KAAKyhB,yBAGTzhB,KAAKugB,YAAa,EAClBvgB,KAAK2iB,aAAY,KACV3iB,KAAKugB,YACRvgB,KAAKyP,MACP,GACCzP,KAAK6E,QAAQob,MAAMxQ,MACxB,CACA,WAAAkT,CAAY/kB,EAASglB,GACnB7V,aAAa/M,KAAKsgB,UAClBtgB,KAAKsgB,SAAWziB,WAAWD,EAASglB,EACtC,CACA,oBAAAnB,GACE,OAAOzkC,OAAOmiB,OAAOa,KAAKwgB,gBAAgBpf,UAAS,EACrD,CACA,UAAAyC,CAAWC,GACT,MAAM+e,EAAiB7f,GAAYG,kBAAkBnD,KAAK4E,UAC1D,IAAK,MAAMke,KAAiB9lC,OAAO4D,KAAKiiC,GAClC7D,GAAsBroB,IAAImsB,WACrBD,EAAeC,GAU1B,OAPAhf,EAAS,IACJ+e,KACmB,iBAAX/e,GAAuBA,EAASA,EAAS,CAAC,GAEvDA,EAAS9D,KAAK+D,gBAAgBD,GAC9BA,EAAS9D,KAAKgE,kBAAkBF,GAChC9D,KAAKiE,iBAAiBH,GACfA,CACT,CACA,iBAAAE,CAAkBF,GAchB,OAbAA,EAAOic,WAAiC,IAArBjc,EAAOic,UAAsB16B,SAAS6G,KAAOwO,GAAWoJ,EAAOic,WACtD,iBAAjBjc,EAAOmc,QAChBnc,EAAOmc,MAAQ,CACbvQ,KAAM5L,EAAOmc,MACbxQ,KAAM3L,EAAOmc,QAGW,iBAAjBnc,EAAOoc,QAChBpc,EAAOoc,MAAQpc,EAAOoc,MAAMrgC,YAEA,iBAAnBikB,EAAOiZ,UAChBjZ,EAAOiZ,QAAUjZ,EAAOiZ,QAAQl9B,YAE3BikB,CACT,CACA,kBAAAwe,GACE,MAAMxe,EAAS,CAAC,EAChB,IAAK,MAAOhnB,EAAKa,KAAUX,OAAOmkB,QAAQnB,KAAK6E,SACzC7E,KAAKmE,YAAYT,QAAQ5mB,KAASa,IACpCmmB,EAAOhnB,GAAOa,GASlB,OANAmmB,EAAO/J,UAAW,EAClB+J,EAAOlC,QAAU,SAKVkC,CACT,CACA,cAAAud,GACMrhB,KAAKgS,UACPhS,KAAKgS,QAAQhZ,UACbgH,KAAKgS,QAAU,MAEbhS,KAAK2gB,MACP3gB,KAAK2gB,IAAIhnB,SACTqG,KAAK2gB,IAAM,KAEf,CAGA,sBAAOlkB,CAAgBqH,GACrB,OAAO9D,KAAKuH,MAAK,WACf,MAAMld,EAAO+1B,GAAQ9a,oBAAoBtF,KAAM8D,GAC/C,GAAsB,iBAAXA,EAAX,CAGA,QAA4B,IAAjBzZ,EAAKyZ,GACd,MAAM,IAAIU,UAAU,oBAAoBV,MAE1CzZ,EAAKyZ,IAJL,CAKF,GACF,EAOF3H,GAAmBikB,IAcnB,MAGM2C,GAAY,IACb3C,GAAQ1c,QACXqZ,QAAS,GACT/0B,OAAQ,CAAC,EAAG,GACZtJ,UAAW,QACXy+B,SAAU,8IACVvb,QAAS,SAELohB,GAAgB,IACjB5C,GAAQzc,YACXoZ,QAAS,kCAOX,MAAMkG,WAAgB7C,GAEpB,kBAAW1c,GACT,OAAOqf,EACT,CACA,sBAAWpf,GACT,OAAOqf,EACT,CACA,eAAWzmB,GACT,MA7BW,SA8Bb,CAGA,cAAA+kB,GACE,OAAOthB,KAAK0hB,aAAe1hB,KAAKkjB,aAClC,CAGA,sBAAAtB,GACE,MAAO,CACL,kBAAkB5hB,KAAK0hB,YACvB,gBAAoB1hB,KAAKkjB,cAE7B,CACA,WAAAA,GACE,OAAOljB,KAAKyd,yBAAyBzd,KAAK6E,QAAQkY,QACpD,CAGA,sBAAOtgB,CAAgBqH,GACrB,OAAO9D,KAAKuH,MAAK,WACf,MAAMld,EAAO44B,GAAQ3d,oBAAoBtF,KAAM8D,GAC/C,GAAsB,iBAAXA,EAAX,CAGA,QAA4B,IAAjBzZ,EAAKyZ,GACd,MAAM,IAAIU,UAAU,oBAAoBV,MAE1CzZ,EAAKyZ,IAJL,CAKF,GACF,EAOF3H,GAAmB8mB,IAcnB,MAEME,GAAc,gBAEdC,GAAiB,WAAWD,KAC5BE,GAAc,QAAQF,KACtBG,GAAwB,OAAOH,cAE/BI,GAAsB,SAEtBC,GAAwB,SAExBC,GAAqB,YAGrBC,GAAsB,GAAGD,mBAA+CA,uBAGxEE,GAAY,CAChB37B,OAAQ,KAER47B,WAAY,eACZC,cAAc,EACdt3B,OAAQ,KACRu3B,UAAW,CAAC,GAAK,GAAK,IAElBC,GAAgB,CACpB/7B,OAAQ,gBAER47B,WAAY,SACZC,aAAc,UACdt3B,OAAQ,UACRu3B,UAAW,SAOb,MAAME,WAAkBtf,GACtB,WAAAP,CAAY5kB,EAASukB,GACnBa,MAAMplB,EAASukB,GAGf9D,KAAKikB,aAAe,IAAI/yB,IACxB8O,KAAKkkB,oBAAsB,IAAIhzB,IAC/B8O,KAAKmkB,aAA6D,YAA9Cl/B,iBAAiB+a,KAAK4E,UAAU5Y,UAA0B,KAAOgU,KAAK4E,SAC1F5E,KAAKokB,cAAgB,KACrBpkB,KAAKqkB,UAAY,KACjBrkB,KAAKskB,oBAAsB,CACzBC,gBAAiB,EACjBC,gBAAiB,GAEnBxkB,KAAKykB,SACP,CAGA,kBAAW/gB,GACT,OAAOigB,EACT,CACA,sBAAWhgB,GACT,OAAOogB,EACT,CACA,eAAWxnB,GACT,MAhEW,WAiEb,CAGA,OAAAkoB,GACEzkB,KAAK0kB,mCACL1kB,KAAK2kB,2BACD3kB,KAAKqkB,UACPrkB,KAAKqkB,UAAUO,aAEf5kB,KAAKqkB,UAAYrkB,KAAK6kB,kBAExB,IAAK,MAAMC,KAAW9kB,KAAKkkB,oBAAoB/kB,SAC7Ca,KAAKqkB,UAAUU,QAAQD,EAE3B,CACA,OAAA/f,GACE/E,KAAKqkB,UAAUO,aACfjgB,MAAMI,SACR,CAGA,iBAAAf,CAAkBF,GAShB,OAPAA,EAAOvX,OAASmO,GAAWoJ,EAAOvX,SAAWlH,SAAS6G,KAGtD4X,EAAO8f,WAAa9f,EAAO9b,OAAS,GAAG8b,EAAO9b,oBAAsB8b,EAAO8f,WAC3C,iBAArB9f,EAAOggB,YAChBhgB,EAAOggB,UAAYhgB,EAAOggB,UAAU5hC,MAAM,KAAKY,KAAInF,GAAS4f,OAAOC,WAAW7f,MAEzEmmB,CACT,CACA,wBAAA6gB,GACO3kB,KAAK6E,QAAQgf,eAKlBtjB,GAAaC,IAAIR,KAAK6E,QAAQtY,OAAQ82B,IACtC9iB,GAAac,GAAGrB,KAAK6E,QAAQtY,OAAQ82B,GAAaG,IAAuBpkB,IACvE,MAAM4lB,EAAoBhlB,KAAKkkB,oBAAoB/mC,IAAIiiB,EAAM7S,OAAOtB,MACpE,GAAI+5B,EAAmB,CACrB5lB,EAAMkD,iBACN,MAAM3G,EAAOqE,KAAKmkB,cAAgBvkC,OAC5BmE,EAASihC,EAAkB3gC,UAAY2b,KAAK4E,SAASvgB,UAC3D,GAAIsX,EAAKspB,SAKP,YAJAtpB,EAAKspB,SAAS,CACZtjC,IAAKoC,EACLmhC,SAAU,WAMdvpB,EAAKlQ,UAAY1H,CACnB,KAEJ,CACA,eAAA8gC,GACE,MAAMpjC,EAAU,CACdka,KAAMqE,KAAKmkB,aACXL,UAAW9jB,KAAK6E,QAAQif,UACxBF,WAAY5jB,KAAK6E,QAAQ+e,YAE3B,OAAO,IAAIuB,sBAAqBhkB,GAAWnB,KAAKolB,kBAAkBjkB,IAAU1f,EAC9E,CAGA,iBAAA2jC,CAAkBjkB,GAChB,MAAMkkB,EAAgB/H,GAAStd,KAAKikB,aAAa9mC,IAAI,IAAImgC,EAAM/wB,OAAO4N,MAChEob,EAAW+H,IACftd,KAAKskB,oBAAoBC,gBAAkBjH,EAAM/wB,OAAOlI,UACxD2b,KAAKslB,SAASD,EAAc/H,GAAO,EAE/BkH,GAAmBxkB,KAAKmkB,cAAgB9+B,SAASC,iBAAiBmG,UAClE85B,EAAkBf,GAAmBxkB,KAAKskB,oBAAoBE,gBACpExkB,KAAKskB,oBAAoBE,gBAAkBA,EAC3C,IAAK,MAAMlH,KAASnc,EAAS,CAC3B,IAAKmc,EAAMkI,eAAgB,CACzBxlB,KAAKokB,cAAgB,KACrBpkB,KAAKylB,kBAAkBJ,EAAc/H,IACrC,QACF,CACA,MAAMoI,EAA2BpI,EAAM/wB,OAAOlI,WAAa2b,KAAKskB,oBAAoBC,gBAEpF,GAAIgB,GAAmBG,GAGrB,GAFAnQ,EAAS+H,IAEJkH,EACH,YAMCe,GAAoBG,GACvBnQ,EAAS+H,EAEb,CACF,CACA,gCAAAoH,GACE1kB,KAAKikB,aAAe,IAAI/yB,IACxB8O,KAAKkkB,oBAAsB,IAAIhzB,IAC/B,MAAMy0B,EAAc/f,GAAezT,KAAKqxB,GAAuBxjB,KAAK6E,QAAQtY,QAC5E,IAAK,MAAMq5B,KAAUD,EAAa,CAEhC,IAAKC,EAAO36B,MAAQiQ,GAAW0qB,GAC7B,SAEF,MAAMZ,EAAoBpf,GAAeC,QAAQggB,UAAUD,EAAO36B,MAAO+U,KAAK4E,UAG1EjK,GAAUqqB,KACZhlB,KAAKikB,aAAalyB,IAAI8zB,UAAUD,EAAO36B,MAAO26B,GAC9C5lB,KAAKkkB,oBAAoBnyB,IAAI6zB,EAAO36B,KAAM+5B,GAE9C,CACF,CACA,QAAAM,CAAS/4B,GACHyT,KAAKokB,gBAAkB73B,IAG3ByT,KAAKylB,kBAAkBzlB,KAAK6E,QAAQtY,QACpCyT,KAAKokB,cAAgB73B,EACrBA,EAAO8O,UAAU5E,IAAI8sB,IACrBvjB,KAAK8lB,iBAAiBv5B,GACtBgU,GAAaqB,QAAQ5B,KAAK4E,SAAUwe,GAAgB,CAClDtjB,cAAevT,IAEnB,CACA,gBAAAu5B,CAAiBv5B,GAEf,GAAIA,EAAO8O,UAAU7W,SA9LQ,iBA+L3BohB,GAAeC,QArLc,mBAqLsBtZ,EAAOyO,QAtLtC,cAsLkEK,UAAU5E,IAAI8sB,SAGtG,IAAK,MAAMwC,KAAangB,GAAeI,QAAQzZ,EA9LnB,qBAiM1B,IAAK,MAAMxJ,KAAQ6iB,GAAeM,KAAK6f,EAAWrC,IAChD3gC,EAAKsY,UAAU5E,IAAI8sB,GAGzB,CACA,iBAAAkC,CAAkBhhC,GAChBA,EAAO4W,UAAU1B,OAAO4pB,IACxB,MAAMyC,EAAcpgB,GAAezT,KAAK,GAAGqxB,MAAyBD,KAAuB9+B,GAC3F,IAAK,MAAM9E,KAAQqmC,EACjBrmC,EAAK0b,UAAU1B,OAAO4pB,GAE1B,CAGA,sBAAO9mB,CAAgBqH,GACrB,OAAO9D,KAAKuH,MAAK,WACf,MAAMld,EAAO25B,GAAU1e,oBAAoBtF,KAAM8D,GACjD,GAAsB,iBAAXA,EAAX,CAGA,QAAqB/K,IAAjB1O,EAAKyZ,IAAyBA,EAAOrC,WAAW,MAAmB,gBAAXqC,EAC1D,MAAM,IAAIU,UAAU,oBAAoBV,MAE1CzZ,EAAKyZ,IAJL,CAKF,GACF,EAOFvD,GAAac,GAAGzhB,OAAQ0jC,IAAuB,KAC7C,IAAK,MAAM2C,KAAOrgB,GAAezT,KApOT,0BAqOtB6xB,GAAU1e,oBAAoB2gB,EAChC,IAOF9pB,GAAmB6nB,IAcnB,MAEMkC,GAAc,UACdC,GAAe,OAAOD,KACtBE,GAAiB,SAASF,KAC1BG,GAAe,OAAOH,KACtBI,GAAgB,QAAQJ,KACxBK,GAAuB,QAAQL,KAC/BM,GAAgB,UAAUN,KAC1BO,GAAsB,OAAOP,KAC7BQ,GAAiB,YACjBC,GAAkB,aAClBC,GAAe,UACfC,GAAiB,YACjBC,GAAW,OACXC,GAAU,MACVC,GAAoB,SACpBC,GAAoB,OACpBC,GAAoB,OAEpBC,GAA2B,mBAE3BC,GAA+B,QAAQD,MAIvCE,GAAuB,2EACvBC,GAAsB,YAFOF,uBAAiDA,mBAA6CA,OAE/EC,KAC5CE,GAA8B,IAAIP,8BAA6CA,+BAA8CA,4BAMnI,MAAMQ,WAAY9iB,GAChB,WAAAP,CAAY5kB,GACVolB,MAAMplB,GACNygB,KAAKiS,QAAUjS,KAAK4E,SAAS5J,QAdN,uCAelBgF,KAAKiS,UAOVjS,KAAKynB,sBAAsBznB,KAAKiS,QAASjS,KAAK0nB,gBAC9CnnB,GAAac,GAAGrB,KAAK4E,SAAU4hB,IAAepnB,GAASY,KAAK0M,SAAStN,KACvE,CAGA,eAAW7C,GACT,MAnDW,KAoDb,CAGA,IAAAmT,GAEE,MAAMiY,EAAY3nB,KAAK4E,SACvB,GAAI5E,KAAK4nB,cAAcD,GACrB,OAIF,MAAME,EAAS7nB,KAAK8nB,iBACdC,EAAYF,EAAStnB,GAAaqB,QAAQimB,EAAQ1B,GAAc,CACpErmB,cAAe6nB,IACZ,KACapnB,GAAaqB,QAAQ+lB,EAAWtB,GAAc,CAC9DvmB,cAAe+nB,IAEH7lB,kBAAoB+lB,GAAaA,EAAU/lB,mBAGzDhC,KAAKgoB,YAAYH,EAAQF,GACzB3nB,KAAKioB,UAAUN,EAAWE,GAC5B,CAGA,SAAAI,CAAU1oC,EAAS2oC,GACZ3oC,IAGLA,EAAQ8b,UAAU5E,IAAIuwB,IACtBhnB,KAAKioB,UAAUriB,GAAec,uBAAuBnnB,IAcrDygB,KAAKmF,gBAZY,KACsB,QAAjC5lB,EAAQic,aAAa,SAIzBjc,EAAQ4B,gBAAgB,YACxB5B,EAAQ6B,aAAa,iBAAiB,GACtC4e,KAAKmoB,gBAAgB5oC,GAAS,GAC9BghB,GAAaqB,QAAQriB,EAAS+mC,GAAe,CAC3CxmB,cAAeooB,KAPf3oC,EAAQ8b,UAAU5E,IAAIywB,GAQtB,GAE0B3nC,EAASA,EAAQ8b,UAAU7W,SAASyiC,KACpE,CACA,WAAAe,CAAYzoC,EAAS2oC,GACd3oC,IAGLA,EAAQ8b,UAAU1B,OAAOqtB,IACzBznC,EAAQm7B,OACR1a,KAAKgoB,YAAYpiB,GAAec,uBAAuBnnB,IAcvDygB,KAAKmF,gBAZY,KACsB,QAAjC5lB,EAAQic,aAAa,SAIzBjc,EAAQ6B,aAAa,iBAAiB,GACtC7B,EAAQ6B,aAAa,WAAY,MACjC4e,KAAKmoB,gBAAgB5oC,GAAS,GAC9BghB,GAAaqB,QAAQriB,EAAS6mC,GAAgB,CAC5CtmB,cAAeooB,KAPf3oC,EAAQ8b,UAAU1B,OAAOutB,GAQzB,GAE0B3nC,EAASA,EAAQ8b,UAAU7W,SAASyiC,KACpE,CACA,QAAAva,CAAStN,GACP,IAAK,CAACsnB,GAAgBC,GAAiBC,GAAcC,GAAgBC,GAAUC,IAAS3lB,SAAShC,EAAMtiB,KACrG,OAEFsiB,EAAMuU,kBACNvU,EAAMkD,iBACN,MAAMwD,EAAW9F,KAAK0nB,eAAevhC,QAAO5G,IAAY2b,GAAW3b,KACnE,IAAI6oC,EACJ,GAAI,CAACtB,GAAUC,IAAS3lB,SAAShC,EAAMtiB,KACrCsrC,EAAoBtiB,EAAS1G,EAAMtiB,MAAQgqC,GAAW,EAAIhhB,EAASpV,OAAS,OACvE,CACL,MAAM2c,EAAS,CAACsZ,GAAiBE,IAAgBzlB,SAAShC,EAAMtiB,KAChEsrC,EAAoBtqB,GAAqBgI,EAAU1G,EAAM7S,OAAQ8gB,GAAQ,EAC3E,CACI+a,IACFA,EAAkB9V,MAAM,CACtB+V,eAAe,IAEjBb,GAAIliB,oBAAoB8iB,GAAmB1Y,OAE/C,CACA,YAAAgY,GAEE,OAAO9hB,GAAezT,KAAKm1B,GAAqBtnB,KAAKiS,QACvD,CACA,cAAA6V,GACE,OAAO9nB,KAAK0nB,eAAev1B,MAAKzN,GAASsb,KAAK4nB,cAAcljC,MAAW,IACzE,CACA,qBAAA+iC,CAAsBhjC,EAAQqhB,GAC5B9F,KAAKsoB,yBAAyB7jC,EAAQ,OAAQ,WAC9C,IAAK,MAAMC,KAASohB,EAClB9F,KAAKuoB,6BAA6B7jC,EAEtC,CACA,4BAAA6jC,CAA6B7jC,GAC3BA,EAAQsb,KAAKwoB,iBAAiB9jC,GAC9B,MAAM+jC,EAAWzoB,KAAK4nB,cAAcljC,GAC9BgkC,EAAY1oB,KAAK2oB,iBAAiBjkC,GACxCA,EAAMtD,aAAa,gBAAiBqnC,GAChCC,IAAchkC,GAChBsb,KAAKsoB,yBAAyBI,EAAW,OAAQ,gBAE9CD,GACH/jC,EAAMtD,aAAa,WAAY,MAEjC4e,KAAKsoB,yBAAyB5jC,EAAO,OAAQ,OAG7Csb,KAAK4oB,mCAAmClkC,EAC1C,CACA,kCAAAkkC,CAAmClkC,GACjC,MAAM6H,EAASqZ,GAAec,uBAAuBhiB,GAChD6H,IAGLyT,KAAKsoB,yBAAyB/7B,EAAQ,OAAQ,YAC1C7H,EAAMyV,IACR6F,KAAKsoB,yBAAyB/7B,EAAQ,kBAAmB,GAAG7H,EAAMyV,MAEtE,CACA,eAAAguB,CAAgB5oC,EAASspC,GACvB,MAAMH,EAAY1oB,KAAK2oB,iBAAiBppC,GACxC,IAAKmpC,EAAUrtB,UAAU7W,SApKN,YAqKjB,OAEF,MAAMkjB,EAAS,CAAC3N,EAAUia,KACxB,MAAMz0B,EAAUqmB,GAAeC,QAAQ9L,EAAU2uB,GAC7CnpC,GACFA,EAAQ8b,UAAUqM,OAAOsM,EAAW6U,EACtC,EAEFnhB,EAAOyf,GAA0BH,IACjCtf,EA5K2B,iBA4KIwf,IAC/BwB,EAAUtnC,aAAa,gBAAiBynC,EAC1C,CACA,wBAAAP,CAAyB/oC,EAASwC,EAAWpE,GACtC4B,EAAQgc,aAAaxZ,IACxBxC,EAAQ6B,aAAaW,EAAWpE,EAEpC,CACA,aAAAiqC,CAAczY,GACZ,OAAOA,EAAK9T,UAAU7W,SAASwiC,GACjC,CAGA,gBAAAwB,CAAiBrZ,GACf,OAAOA,EAAKpJ,QAAQuhB,IAAuBnY,EAAOvJ,GAAeC,QAAQyhB,GAAqBnY,EAChG,CAGA,gBAAAwZ,CAAiBxZ,GACf,OAAOA,EAAKnU,QA5LO,gCA4LoBmU,CACzC,CAGA,sBAAO1S,CAAgBqH,GACrB,OAAO9D,KAAKuH,MAAK,WACf,MAAMld,EAAOm9B,GAAIliB,oBAAoBtF,MACrC,GAAsB,iBAAX8D,EAAX,CAGA,QAAqB/K,IAAjB1O,EAAKyZ,IAAyBA,EAAOrC,WAAW,MAAmB,gBAAXqC,EAC1D,MAAM,IAAIU,UAAU,oBAAoBV,MAE1CzZ,EAAKyZ,IAJL,CAKF,GACF,EAOFvD,GAAac,GAAGhc,SAAUkhC,GAAsBc,IAAsB,SAAUjoB,GAC1E,CAAC,IAAK,QAAQgC,SAASpB,KAAKgH,UAC9B5H,EAAMkD,iBAEJpH,GAAW8E,OAGfwnB,GAAIliB,oBAAoBtF,MAAM0P,MAChC,IAKAnP,GAAac,GAAGzhB,OAAQ6mC,IAAqB,KAC3C,IAAK,MAAMlnC,KAAWqmB,GAAezT,KAAKo1B,IACxCC,GAAIliB,oBAAoB/lB,EAC1B,IAMF4c,GAAmBqrB,IAcnB,MAEMxiB,GAAY,YACZ8jB,GAAkB,YAAY9jB,KAC9B+jB,GAAiB,WAAW/jB,KAC5BgkB,GAAgB,UAAUhkB,KAC1BikB,GAAiB,WAAWjkB,KAC5BkkB,GAAa,OAAOlkB,KACpBmkB,GAAe,SAASnkB,KACxBokB,GAAa,OAAOpkB,KACpBqkB,GAAc,QAAQrkB,KAEtBskB,GAAkB,OAClBC,GAAkB,OAClBC,GAAqB,UACrB7lB,GAAc,CAClBmc,UAAW,UACX2J,SAAU,UACVxJ,MAAO,UAEHvc,GAAU,CACdoc,WAAW,EACX2J,UAAU,EACVxJ,MAAO,KAOT,MAAMyJ,WAAchlB,GAClB,WAAAP,CAAY5kB,EAASukB,GACnBa,MAAMplB,EAASukB,GACf9D,KAAKsgB,SAAW,KAChBtgB,KAAK2pB,sBAAuB,EAC5B3pB,KAAK4pB,yBAA0B,EAC/B5pB,KAAK4gB,eACP,CAGA,kBAAWld,GACT,OAAOA,EACT,CACA,sBAAWC,GACT,OAAOA,EACT,CACA,eAAWpH,GACT,MA/CS,OAgDX,CAGA,IAAAmT,GACoBnP,GAAaqB,QAAQ5B,KAAK4E,SAAUwkB,IACxCpnB,mBAGdhC,KAAK6pB,gBACD7pB,KAAK6E,QAAQib,WACf9f,KAAK4E,SAASvJ,UAAU5E,IA/CN,QAsDpBuJ,KAAK4E,SAASvJ,UAAU1B,OAAO2vB,IAC/BztB,GAAOmE,KAAK4E,UACZ5E,KAAK4E,SAASvJ,UAAU5E,IAAI8yB,GAAiBC,IAC7CxpB,KAAKmF,gBARY,KACfnF,KAAK4E,SAASvJ,UAAU1B,OAAO6vB,IAC/BjpB,GAAaqB,QAAQ5B,KAAK4E,SAAUykB,IACpCrpB,KAAK8pB,oBAAoB,GAKG9pB,KAAK4E,SAAU5E,KAAK6E,QAAQib,WAC5D,CACA,IAAArQ,GACOzP,KAAK+pB,YAGQxpB,GAAaqB,QAAQ5B,KAAK4E,SAAUskB,IACxClnB,mBAQdhC,KAAK4E,SAASvJ,UAAU5E,IAAI+yB,IAC5BxpB,KAAKmF,gBANY,KACfnF,KAAK4E,SAASvJ,UAAU5E,IAAI6yB,IAC5BtpB,KAAK4E,SAASvJ,UAAU1B,OAAO6vB,GAAoBD,IACnDhpB,GAAaqB,QAAQ5B,KAAK4E,SAAUukB,GAAa,GAGrBnpB,KAAK4E,SAAU5E,KAAK6E,QAAQib,YAC5D,CACA,OAAA/a,GACE/E,KAAK6pB,gBACD7pB,KAAK+pB,WACP/pB,KAAK4E,SAASvJ,UAAU1B,OAAO4vB,IAEjC5kB,MAAMI,SACR,CACA,OAAAglB,GACE,OAAO/pB,KAAK4E,SAASvJ,UAAU7W,SAAS+kC,GAC1C,CAIA,kBAAAO,GACO9pB,KAAK6E,QAAQ4kB,WAGdzpB,KAAK2pB,sBAAwB3pB,KAAK4pB,0BAGtC5pB,KAAKsgB,SAAWziB,YAAW,KACzBmC,KAAKyP,MAAM,GACVzP,KAAK6E,QAAQob,QAClB,CACA,cAAA+J,CAAe5qB,EAAO6qB,GACpB,OAAQ7qB,EAAMqB,MACZ,IAAK,YACL,IAAK,WAEDT,KAAK2pB,qBAAuBM,EAC5B,MAEJ,IAAK,UACL,IAAK,WAEDjqB,KAAK4pB,wBAA0BK,EAIrC,GAAIA,EAEF,YADAjqB,KAAK6pB,gBAGP,MAAMvc,EAAclO,EAAMU,cACtBE,KAAK4E,WAAa0I,GAAetN,KAAK4E,SAASpgB,SAAS8oB,IAG5DtN,KAAK8pB,oBACP,CACA,aAAAlJ,GACErgB,GAAac,GAAGrB,KAAK4E,SAAUkkB,IAAiB1pB,GAASY,KAAKgqB,eAAe5qB,GAAO,KACpFmB,GAAac,GAAGrB,KAAK4E,SAAUmkB,IAAgB3pB,GAASY,KAAKgqB,eAAe5qB,GAAO,KACnFmB,GAAac,GAAGrB,KAAK4E,SAAUokB,IAAe5pB,GAASY,KAAKgqB,eAAe5qB,GAAO,KAClFmB,GAAac,GAAGrB,KAAK4E,SAAUqkB,IAAgB7pB,GAASY,KAAKgqB,eAAe5qB,GAAO,IACrF,CACA,aAAAyqB,GACE9c,aAAa/M,KAAKsgB,UAClBtgB,KAAKsgB,SAAW,IAClB,CAGA,sBAAO7jB,CAAgBqH,GACrB,OAAO9D,KAAKuH,MAAK,WACf,MAAMld,EAAOq/B,GAAMpkB,oBAAoBtF,KAAM8D,GAC7C,GAAsB,iBAAXA,EAAqB,CAC9B,QAA4B,IAAjBzZ,EAAKyZ,GACd,MAAM,IAAIU,UAAU,oBAAoBV,MAE1CzZ,EAAKyZ,GAAQ9D,KACf,CACF,GACF,ECr0IK,SAASkqB,GAAc7tB,GACD,WAAvBhX,SAASuX,WAAyBP,IACjChX,SAASyF,iBAAiB,mBAAoBuR,EACrD,CDy0IAuK,GAAqB8iB,IAMrBvtB,GAAmButB,IEtyInBQ,IAvCA,WAC2B,GAAG93B,MAAM5U,KAChC6H,SAAS+a,iBAAiB,+BAETtd,KAAI,SAAUqnC,GAC/B,OAAO,IAAI/J,GAAQ+J,EAAkB,CAAElK,MAAO,CAAEvQ,KAAM,IAAKD,KAAM,MACnE,GACF,IAiCAya,IA5BA,WACY7kC,SAAS68B,eAAe,mBAC9Bp3B,iBAAiB,SAAS,WAC5BzF,SAAS6G,KAAKT,UAAY,EAC1BpG,SAASC,gBAAgBmG,UAAY,CACvC,GACF,IAuBAy+B,IArBA,WACE,IAAIE,EAAM/kC,SAAS68B,eAAe,mBAC9BmI,EAAShlC,SACVilC,uBAAuB,aAAa,GACpChnC,wBACH1D,OAAOkL,iBAAiB,UAAU,WAC5BkV,KAAKuqB,UAAYvqB,KAAKwqB,SAAWxqB,KAAKwqB,QAAUH,EAAOzsC,OACzDwsC,EAAIrpC,MAAM6wB,QAAU,QAEpBwY,EAAIrpC,MAAM6wB,QAAU,OAEtB5R,KAAKuqB,UAAYvqB,KAAKwqB,OACxB,GACF","sources":["webpack://pydata_sphinx_theme/webpack/bootstrap","webpack://pydata_sphinx_theme/webpack/runtime/define property getters","webpack://pydata_sphinx_theme/webpack/runtime/hasOwnProperty shorthand","webpack://pydata_sphinx_theme/webpack/runtime/make namespace object","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/enums.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getNodeName.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getWindow.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/instanceOf.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/applyStyles.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/getBasePlacement.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/math.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/userAgent.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/contains.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/isTableElement.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getParentNode.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/within.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/mergePaddingObject.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/getFreshSideObject.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/expandToHashMap.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/arrow.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/getVariation.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/computeStyles.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/eventListeners.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/getOppositePlacement.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/rectToClientRect.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/computeOffsets.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/detectOverflow.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/flip.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/hide.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/offset.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/popperOffsets.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/preventOverflow.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/getAltAxis.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/orderModifiers.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/createPopper.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/debounce.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/mergeByName.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/popper.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/popper-lite.js","webpack://pydata_sphinx_theme/./node_modules/bootstrap/dist/js/bootstrap.esm.js","webpack://pydata_sphinx_theme/./src/pydata_sphinx_theme/assets/scripts/mixin.js","webpack://pydata_sphinx_theme/./src/pydata_sphinx_theme/assets/scripts/bootstrap.js"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","export var top = 'top';\nexport var bottom = 'bottom';\nexport var right = 'right';\nexport var left = 'left';\nexport var auto = 'auto';\nexport var basePlacements = [top, bottom, right, left];\nexport var start = 'start';\nexport var end = 'end';\nexport var clippingParents = 'clippingParents';\nexport var viewport = 'viewport';\nexport var popper = 'popper';\nexport var reference = 'reference';\nexport var variationPlacements = /*#__PURE__*/basePlacements.reduce(function (acc, placement) {\n return acc.concat([placement + \"-\" + start, placement + \"-\" + end]);\n}, []);\nexport var placements = /*#__PURE__*/[].concat(basePlacements, [auto]).reduce(function (acc, placement) {\n return acc.concat([placement, placement + \"-\" + start, placement + \"-\" + end]);\n}, []); // modifiers that need to read the DOM\n\nexport var beforeRead = 'beforeRead';\nexport var read = 'read';\nexport var afterRead = 'afterRead'; // pure-logic modifiers\n\nexport var beforeMain = 'beforeMain';\nexport var main = 'main';\nexport var afterMain = 'afterMain'; // modifier with the purpose to write to the DOM (or write into a framework state)\n\nexport var beforeWrite = 'beforeWrite';\nexport var write = 'write';\nexport var afterWrite = 'afterWrite';\nexport var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite];","export default function getNodeName(element) {\n return element ? (element.nodeName || '').toLowerCase() : null;\n}","export default function getWindow(node) {\n if (node == null) {\n return window;\n }\n\n if (node.toString() !== '[object Window]') {\n var ownerDocument = node.ownerDocument;\n return ownerDocument ? ownerDocument.defaultView || window : window;\n }\n\n return node;\n}","import getWindow from \"./getWindow.js\";\n\nfunction isElement(node) {\n var OwnElement = getWindow(node).Element;\n return node instanceof OwnElement || node instanceof Element;\n}\n\nfunction isHTMLElement(node) {\n var OwnElement = getWindow(node).HTMLElement;\n return node instanceof OwnElement || node instanceof HTMLElement;\n}\n\nfunction isShadowRoot(node) {\n // IE 11 has no ShadowRoot\n if (typeof ShadowRoot === 'undefined') {\n return false;\n }\n\n var OwnElement = getWindow(node).ShadowRoot;\n return node instanceof OwnElement || node instanceof ShadowRoot;\n}\n\nexport { isElement, isHTMLElement, isShadowRoot };","import getNodeName from \"../dom-utils/getNodeName.js\";\nimport { isHTMLElement } from \"../dom-utils/instanceOf.js\"; // This modifier takes the styles prepared by the `computeStyles` modifier\n// and applies them to the HTMLElements such as popper and arrow\n\nfunction applyStyles(_ref) {\n var state = _ref.state;\n Object.keys(state.elements).forEach(function (name) {\n var style = state.styles[name] || {};\n var attributes = state.attributes[name] || {};\n var element = state.elements[name]; // arrow is optional + virtual elements\n\n if (!isHTMLElement(element) || !getNodeName(element)) {\n return;\n } // Flow doesn't support to extend this property, but it's the most\n // effective way to apply styles to an HTMLElement\n // $FlowFixMe[cannot-write]\n\n\n Object.assign(element.style, style);\n Object.keys(attributes).forEach(function (name) {\n var value = attributes[name];\n\n if (value === false) {\n element.removeAttribute(name);\n } else {\n element.setAttribute(name, value === true ? '' : value);\n }\n });\n });\n}\n\nfunction effect(_ref2) {\n var state = _ref2.state;\n var initialStyles = {\n popper: {\n position: state.options.strategy,\n left: '0',\n top: '0',\n margin: '0'\n },\n arrow: {\n position: 'absolute'\n },\n reference: {}\n };\n Object.assign(state.elements.popper.style, initialStyles.popper);\n state.styles = initialStyles;\n\n if (state.elements.arrow) {\n Object.assign(state.elements.arrow.style, initialStyles.arrow);\n }\n\n return function () {\n Object.keys(state.elements).forEach(function (name) {\n var element = state.elements[name];\n var attributes = state.attributes[name] || {};\n var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); // Set all values to an empty string to unset them\n\n var style = styleProperties.reduce(function (style, property) {\n style[property] = '';\n return style;\n }, {}); // arrow is optional + virtual elements\n\n if (!isHTMLElement(element) || !getNodeName(element)) {\n return;\n }\n\n Object.assign(element.style, style);\n Object.keys(attributes).forEach(function (attribute) {\n element.removeAttribute(attribute);\n });\n });\n };\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'applyStyles',\n enabled: true,\n phase: 'write',\n fn: applyStyles,\n effect: effect,\n requires: ['computeStyles']\n};","import { auto } from \"../enums.js\";\nexport default function getBasePlacement(placement) {\n return placement.split('-')[0];\n}","export var max = Math.max;\nexport var min = Math.min;\nexport var round = Math.round;","export default function getUAString() {\n var uaData = navigator.userAgentData;\n\n if (uaData != null && uaData.brands && Array.isArray(uaData.brands)) {\n return uaData.brands.map(function (item) {\n return item.brand + \"/\" + item.version;\n }).join(' ');\n }\n\n return navigator.userAgent;\n}","import getUAString from \"../utils/userAgent.js\";\nexport default function isLayoutViewport() {\n return !/^((?!chrome|android).)*safari/i.test(getUAString());\n}","import { isElement, isHTMLElement } from \"./instanceOf.js\";\nimport { round } from \"../utils/math.js\";\nimport getWindow from \"./getWindow.js\";\nimport isLayoutViewport from \"./isLayoutViewport.js\";\nexport default function getBoundingClientRect(element, includeScale, isFixedStrategy) {\n if (includeScale === void 0) {\n includeScale = false;\n }\n\n if (isFixedStrategy === void 0) {\n isFixedStrategy = false;\n }\n\n var clientRect = element.getBoundingClientRect();\n var scaleX = 1;\n var scaleY = 1;\n\n if (includeScale && isHTMLElement(element)) {\n scaleX = element.offsetWidth > 0 ? round(clientRect.width) / element.offsetWidth || 1 : 1;\n scaleY = element.offsetHeight > 0 ? round(clientRect.height) / element.offsetHeight || 1 : 1;\n }\n\n var _ref = isElement(element) ? getWindow(element) : window,\n visualViewport = _ref.visualViewport;\n\n var addVisualOffsets = !isLayoutViewport() && isFixedStrategy;\n var x = (clientRect.left + (addVisualOffsets && visualViewport ? visualViewport.offsetLeft : 0)) / scaleX;\n var y = (clientRect.top + (addVisualOffsets && visualViewport ? visualViewport.offsetTop : 0)) / scaleY;\n var width = clientRect.width / scaleX;\n var height = clientRect.height / scaleY;\n return {\n width: width,\n height: height,\n top: y,\n right: x + width,\n bottom: y + height,\n left: x,\n x: x,\n y: y\n };\n}","import getBoundingClientRect from \"./getBoundingClientRect.js\"; // Returns the layout rect of an element relative to its offsetParent. Layout\n// means it doesn't take into account transforms.\n\nexport default function getLayoutRect(element) {\n var clientRect = getBoundingClientRect(element); // Use the clientRect sizes if it's not been transformed.\n // Fixes https://github.com/popperjs/popper-core/issues/1223\n\n var width = element.offsetWidth;\n var height = element.offsetHeight;\n\n if (Math.abs(clientRect.width - width) <= 1) {\n width = clientRect.width;\n }\n\n if (Math.abs(clientRect.height - height) <= 1) {\n height = clientRect.height;\n }\n\n return {\n x: element.offsetLeft,\n y: element.offsetTop,\n width: width,\n height: height\n };\n}","import { isShadowRoot } from \"./instanceOf.js\";\nexport default function contains(parent, child) {\n var rootNode = child.getRootNode && child.getRootNode(); // First, attempt with faster native method\n\n if (parent.contains(child)) {\n return true;\n } // then fallback to custom implementation with Shadow DOM support\n else if (rootNode && isShadowRoot(rootNode)) {\n var next = child;\n\n do {\n if (next && parent.isSameNode(next)) {\n return true;\n } // $FlowFixMe[prop-missing]: need a better way to handle this...\n\n\n next = next.parentNode || next.host;\n } while (next);\n } // Give up, the result is false\n\n\n return false;\n}","import getWindow from \"./getWindow.js\";\nexport default function getComputedStyle(element) {\n return getWindow(element).getComputedStyle(element);\n}","import getNodeName from \"./getNodeName.js\";\nexport default function isTableElement(element) {\n return ['table', 'td', 'th'].indexOf(getNodeName(element)) >= 0;\n}","import { isElement } from \"./instanceOf.js\";\nexport default function getDocumentElement(element) {\n // $FlowFixMe[incompatible-return]: assume body is always available\n return ((isElement(element) ? element.ownerDocument : // $FlowFixMe[prop-missing]\n element.document) || window.document).documentElement;\n}","import getNodeName from \"./getNodeName.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport { isShadowRoot } from \"./instanceOf.js\";\nexport default function getParentNode(element) {\n if (getNodeName(element) === 'html') {\n return element;\n }\n\n return (// this is a quicker (but less type safe) way to save quite some bytes from the bundle\n // $FlowFixMe[incompatible-return]\n // $FlowFixMe[prop-missing]\n element.assignedSlot || // step into the shadow DOM of the parent of a slotted node\n element.parentNode || ( // DOM Element detected\n isShadowRoot(element) ? element.host : null) || // ShadowRoot detected\n // $FlowFixMe[incompatible-call]: HTMLElement is a Node\n getDocumentElement(element) // fallback\n\n );\n}","import getWindow from \"./getWindow.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport getComputedStyle from \"./getComputedStyle.js\";\nimport { isHTMLElement, isShadowRoot } from \"./instanceOf.js\";\nimport isTableElement from \"./isTableElement.js\";\nimport getParentNode from \"./getParentNode.js\";\nimport getUAString from \"../utils/userAgent.js\";\n\nfunction getTrueOffsetParent(element) {\n if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837\n getComputedStyle(element).position === 'fixed') {\n return null;\n }\n\n return element.offsetParent;\n} // `.offsetParent` reports `null` for fixed elements, while absolute elements\n// return the containing block\n\n\nfunction getContainingBlock(element) {\n var isFirefox = /firefox/i.test(getUAString());\n var isIE = /Trident/i.test(getUAString());\n\n if (isIE && isHTMLElement(element)) {\n // In IE 9, 10 and 11 fixed elements containing block is always established by the viewport\n var elementCss = getComputedStyle(element);\n\n if (elementCss.position === 'fixed') {\n return null;\n }\n }\n\n var currentNode = getParentNode(element);\n\n if (isShadowRoot(currentNode)) {\n currentNode = currentNode.host;\n }\n\n while (isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName(currentNode)) < 0) {\n var css = getComputedStyle(currentNode); // This is non-exhaustive but covers the most common CSS properties that\n // create a containing block.\n // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block\n\n if (css.transform !== 'none' || css.perspective !== 'none' || css.contain === 'paint' || ['transform', 'perspective'].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === 'filter' || isFirefox && css.filter && css.filter !== 'none') {\n return currentNode;\n } else {\n currentNode = currentNode.parentNode;\n }\n }\n\n return null;\n} // Gets the closest ancestor positioned element. Handles some edge cases,\n// such as table ancestors and cross browser bugs.\n\n\nexport default function getOffsetParent(element) {\n var window = getWindow(element);\n var offsetParent = getTrueOffsetParent(element);\n\n while (offsetParent && isTableElement(offsetParent) && getComputedStyle(offsetParent).position === 'static') {\n offsetParent = getTrueOffsetParent(offsetParent);\n }\n\n if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' && getComputedStyle(offsetParent).position === 'static')) {\n return window;\n }\n\n return offsetParent || getContainingBlock(element) || window;\n}","export default function getMainAxisFromPlacement(placement) {\n return ['top', 'bottom'].indexOf(placement) >= 0 ? 'x' : 'y';\n}","import { max as mathMax, min as mathMin } from \"./math.js\";\nexport function within(min, value, max) {\n return mathMax(min, mathMin(value, max));\n}\nexport function withinMaxClamp(min, value, max) {\n var v = within(min, value, max);\n return v > max ? max : v;\n}","import getFreshSideObject from \"./getFreshSideObject.js\";\nexport default function mergePaddingObject(paddingObject) {\n return Object.assign({}, getFreshSideObject(), paddingObject);\n}","export default function getFreshSideObject() {\n return {\n top: 0,\n right: 0,\n bottom: 0,\n left: 0\n };\n}","export default function expandToHashMap(value, keys) {\n return keys.reduce(function (hashMap, key) {\n hashMap[key] = value;\n return hashMap;\n }, {});\n}","import getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getLayoutRect from \"../dom-utils/getLayoutRect.js\";\nimport contains from \"../dom-utils/contains.js\";\nimport getOffsetParent from \"../dom-utils/getOffsetParent.js\";\nimport getMainAxisFromPlacement from \"../utils/getMainAxisFromPlacement.js\";\nimport { within } from \"../utils/within.js\";\nimport mergePaddingObject from \"../utils/mergePaddingObject.js\";\nimport expandToHashMap from \"../utils/expandToHashMap.js\";\nimport { left, right, basePlacements, top, bottom } from \"../enums.js\"; // eslint-disable-next-line import/no-unused-modules\n\nvar toPaddingObject = function toPaddingObject(padding, state) {\n padding = typeof padding === 'function' ? padding(Object.assign({}, state.rects, {\n placement: state.placement\n })) : padding;\n return mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));\n};\n\nfunction arrow(_ref) {\n var _state$modifiersData$;\n\n var state = _ref.state,\n name = _ref.name,\n options = _ref.options;\n var arrowElement = state.elements.arrow;\n var popperOffsets = state.modifiersData.popperOffsets;\n var basePlacement = getBasePlacement(state.placement);\n var axis = getMainAxisFromPlacement(basePlacement);\n var isVertical = [left, right].indexOf(basePlacement) >= 0;\n var len = isVertical ? 'height' : 'width';\n\n if (!arrowElement || !popperOffsets) {\n return;\n }\n\n var paddingObject = toPaddingObject(options.padding, state);\n var arrowRect = getLayoutRect(arrowElement);\n var minProp = axis === 'y' ? top : left;\n var maxProp = axis === 'y' ? bottom : right;\n var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets[axis] - state.rects.popper[len];\n var startDiff = popperOffsets[axis] - state.rects.reference[axis];\n var arrowOffsetParent = getOffsetParent(arrowElement);\n var clientSize = arrowOffsetParent ? axis === 'y' ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0;\n var centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the popper if the center point is\n // outside of the popper bounds\n\n var min = paddingObject[minProp];\n var max = clientSize - arrowRect[len] - paddingObject[maxProp];\n var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference;\n var offset = within(min, center, max); // Prevents breaking syntax highlighting...\n\n var axisProp = axis;\n state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset, _state$modifiersData$.centerOffset = offset - center, _state$modifiersData$);\n}\n\nfunction effect(_ref2) {\n var state = _ref2.state,\n options = _ref2.options;\n var _options$element = options.element,\n arrowElement = _options$element === void 0 ? '[data-popper-arrow]' : _options$element;\n\n if (arrowElement == null) {\n return;\n } // CSS selector\n\n\n if (typeof arrowElement === 'string') {\n arrowElement = state.elements.popper.querySelector(arrowElement);\n\n if (!arrowElement) {\n return;\n }\n }\n\n if (!contains(state.elements.popper, arrowElement)) {\n return;\n }\n\n state.elements.arrow = arrowElement;\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'arrow',\n enabled: true,\n phase: 'main',\n fn: arrow,\n effect: effect,\n requires: ['popperOffsets'],\n requiresIfExists: ['preventOverflow']\n};","export default function getVariation(placement) {\n return placement.split('-')[1];\n}","import { top, left, right, bottom, end } from \"../enums.js\";\nimport getOffsetParent from \"../dom-utils/getOffsetParent.js\";\nimport getWindow from \"../dom-utils/getWindow.js\";\nimport getDocumentElement from \"../dom-utils/getDocumentElement.js\";\nimport getComputedStyle from \"../dom-utils/getComputedStyle.js\";\nimport getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getVariation from \"../utils/getVariation.js\";\nimport { round } from \"../utils/math.js\"; // eslint-disable-next-line import/no-unused-modules\n\nvar unsetSides = {\n top: 'auto',\n right: 'auto',\n bottom: 'auto',\n left: 'auto'\n}; // Round the offsets to the nearest suitable subpixel based on the DPR.\n// Zooming can change the DPR, but it seems to report a value that will\n// cleanly divide the values into the appropriate subpixels.\n\nfunction roundOffsetsByDPR(_ref, win) {\n var x = _ref.x,\n y = _ref.y;\n var dpr = win.devicePixelRatio || 1;\n return {\n x: round(x * dpr) / dpr || 0,\n y: round(y * dpr) / dpr || 0\n };\n}\n\nexport function mapToStyles(_ref2) {\n var _Object$assign2;\n\n var popper = _ref2.popper,\n popperRect = _ref2.popperRect,\n placement = _ref2.placement,\n variation = _ref2.variation,\n offsets = _ref2.offsets,\n position = _ref2.position,\n gpuAcceleration = _ref2.gpuAcceleration,\n adaptive = _ref2.adaptive,\n roundOffsets = _ref2.roundOffsets,\n isFixed = _ref2.isFixed;\n var _offsets$x = offsets.x,\n x = _offsets$x === void 0 ? 0 : _offsets$x,\n _offsets$y = offsets.y,\n y = _offsets$y === void 0 ? 0 : _offsets$y;\n\n var _ref3 = typeof roundOffsets === 'function' ? roundOffsets({\n x: x,\n y: y\n }) : {\n x: x,\n y: y\n };\n\n x = _ref3.x;\n y = _ref3.y;\n var hasX = offsets.hasOwnProperty('x');\n var hasY = offsets.hasOwnProperty('y');\n var sideX = left;\n var sideY = top;\n var win = window;\n\n if (adaptive) {\n var offsetParent = getOffsetParent(popper);\n var heightProp = 'clientHeight';\n var widthProp = 'clientWidth';\n\n if (offsetParent === getWindow(popper)) {\n offsetParent = getDocumentElement(popper);\n\n if (getComputedStyle(offsetParent).position !== 'static' && position === 'absolute') {\n heightProp = 'scrollHeight';\n widthProp = 'scrollWidth';\n }\n } // $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it\n\n\n offsetParent = offsetParent;\n\n if (placement === top || (placement === left || placement === right) && variation === end) {\n sideY = bottom;\n var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : // $FlowFixMe[prop-missing]\n offsetParent[heightProp];\n y -= offsetY - popperRect.height;\n y *= gpuAcceleration ? 1 : -1;\n }\n\n if (placement === left || (placement === top || placement === bottom) && variation === end) {\n sideX = right;\n var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : // $FlowFixMe[prop-missing]\n offsetParent[widthProp];\n x -= offsetX - popperRect.width;\n x *= gpuAcceleration ? 1 : -1;\n }\n }\n\n var commonStyles = Object.assign({\n position: position\n }, adaptive && unsetSides);\n\n var _ref4 = roundOffsets === true ? roundOffsetsByDPR({\n x: x,\n y: y\n }, getWindow(popper)) : {\n x: x,\n y: y\n };\n\n x = _ref4.x;\n y = _ref4.y;\n\n if (gpuAcceleration) {\n var _Object$assign;\n\n return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? '0' : '', _Object$assign[sideX] = hasX ? '0' : '', _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? \"translate(\" + x + \"px, \" + y + \"px)\" : \"translate3d(\" + x + \"px, \" + y + \"px, 0)\", _Object$assign));\n }\n\n return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + \"px\" : '', _Object$assign2[sideX] = hasX ? x + \"px\" : '', _Object$assign2.transform = '', _Object$assign2));\n}\n\nfunction computeStyles(_ref5) {\n var state = _ref5.state,\n options = _ref5.options;\n var _options$gpuAccelerat = options.gpuAcceleration,\n gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat,\n _options$adaptive = options.adaptive,\n adaptive = _options$adaptive === void 0 ? true : _options$adaptive,\n _options$roundOffsets = options.roundOffsets,\n roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets;\n var commonStyles = {\n placement: getBasePlacement(state.placement),\n variation: getVariation(state.placement),\n popper: state.elements.popper,\n popperRect: state.rects.popper,\n gpuAcceleration: gpuAcceleration,\n isFixed: state.options.strategy === 'fixed'\n };\n\n if (state.modifiersData.popperOffsets != null) {\n state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, {\n offsets: state.modifiersData.popperOffsets,\n position: state.options.strategy,\n adaptive: adaptive,\n roundOffsets: roundOffsets\n })));\n }\n\n if (state.modifiersData.arrow != null) {\n state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, {\n offsets: state.modifiersData.arrow,\n position: 'absolute',\n adaptive: false,\n roundOffsets: roundOffsets\n })));\n }\n\n state.attributes.popper = Object.assign({}, state.attributes.popper, {\n 'data-popper-placement': state.placement\n });\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'computeStyles',\n enabled: true,\n phase: 'beforeWrite',\n fn: computeStyles,\n data: {}\n};","import getWindow from \"../dom-utils/getWindow.js\"; // eslint-disable-next-line import/no-unused-modules\n\nvar passive = {\n passive: true\n};\n\nfunction effect(_ref) {\n var state = _ref.state,\n instance = _ref.instance,\n options = _ref.options;\n var _options$scroll = options.scroll,\n scroll = _options$scroll === void 0 ? true : _options$scroll,\n _options$resize = options.resize,\n resize = _options$resize === void 0 ? true : _options$resize;\n var window = getWindow(state.elements.popper);\n var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper);\n\n if (scroll) {\n scrollParents.forEach(function (scrollParent) {\n scrollParent.addEventListener('scroll', instance.update, passive);\n });\n }\n\n if (resize) {\n window.addEventListener('resize', instance.update, passive);\n }\n\n return function () {\n if (scroll) {\n scrollParents.forEach(function (scrollParent) {\n scrollParent.removeEventListener('scroll', instance.update, passive);\n });\n }\n\n if (resize) {\n window.removeEventListener('resize', instance.update, passive);\n }\n };\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'eventListeners',\n enabled: true,\n phase: 'write',\n fn: function fn() {},\n effect: effect,\n data: {}\n};","var hash = {\n left: 'right',\n right: 'left',\n bottom: 'top',\n top: 'bottom'\n};\nexport default function getOppositePlacement(placement) {\n return placement.replace(/left|right|bottom|top/g, function (matched) {\n return hash[matched];\n });\n}","var hash = {\n start: 'end',\n end: 'start'\n};\nexport default function getOppositeVariationPlacement(placement) {\n return placement.replace(/start|end/g, function (matched) {\n return hash[matched];\n });\n}","import getWindow from \"./getWindow.js\";\nexport default function getWindowScroll(node) {\n var win = getWindow(node);\n var scrollLeft = win.pageXOffset;\n var scrollTop = win.pageYOffset;\n return {\n scrollLeft: scrollLeft,\n scrollTop: scrollTop\n };\n}","import getBoundingClientRect from \"./getBoundingClientRect.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport getWindowScroll from \"./getWindowScroll.js\";\nexport default function getWindowScrollBarX(element) {\n // If has a CSS width greater than the viewport, then this will be\n // incorrect for RTL.\n // Popper 1 is broken in this case and never had a bug report so let's assume\n // it's not an issue. I don't think anyone ever specifies width on \n // anyway.\n // Browsers where the left scrollbar doesn't cause an issue report `0` for\n // this (e.g. Edge 2019, IE11, Safari)\n return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft;\n}","import getComputedStyle from \"./getComputedStyle.js\";\nexport default function isScrollParent(element) {\n // Firefox wants us to check `-x` and `-y` variations as well\n var _getComputedStyle = getComputedStyle(element),\n overflow = _getComputedStyle.overflow,\n overflowX = _getComputedStyle.overflowX,\n overflowY = _getComputedStyle.overflowY;\n\n return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX);\n}","import getParentNode from \"./getParentNode.js\";\nimport isScrollParent from \"./isScrollParent.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport { isHTMLElement } from \"./instanceOf.js\";\nexport default function getScrollParent(node) {\n if (['html', 'body', '#document'].indexOf(getNodeName(node)) >= 0) {\n // $FlowFixMe[incompatible-return]: assume body is always available\n return node.ownerDocument.body;\n }\n\n if (isHTMLElement(node) && isScrollParent(node)) {\n return node;\n }\n\n return getScrollParent(getParentNode(node));\n}","import getScrollParent from \"./getScrollParent.js\";\nimport getParentNode from \"./getParentNode.js\";\nimport getWindow from \"./getWindow.js\";\nimport isScrollParent from \"./isScrollParent.js\";\n/*\ngiven a DOM element, return the list of all scroll parents, up the list of ancesors\nuntil we get to the top window object. This list is what we attach scroll listeners\nto, because if any of these parent elements scroll, we'll need to re-calculate the\nreference element's position.\n*/\n\nexport default function listScrollParents(element, list) {\n var _element$ownerDocumen;\n\n if (list === void 0) {\n list = [];\n }\n\n var scrollParent = getScrollParent(element);\n var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body);\n var win = getWindow(scrollParent);\n var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent;\n var updatedList = list.concat(target);\n return isBody ? updatedList : // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here\n updatedList.concat(listScrollParents(getParentNode(target)));\n}","export default function rectToClientRect(rect) {\n return Object.assign({}, rect, {\n left: rect.x,\n top: rect.y,\n right: rect.x + rect.width,\n bottom: rect.y + rect.height\n });\n}","import { viewport } from \"../enums.js\";\nimport getViewportRect from \"./getViewportRect.js\";\nimport getDocumentRect from \"./getDocumentRect.js\";\nimport listScrollParents from \"./listScrollParents.js\";\nimport getOffsetParent from \"./getOffsetParent.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport getComputedStyle from \"./getComputedStyle.js\";\nimport { isElement, isHTMLElement } from \"./instanceOf.js\";\nimport getBoundingClientRect from \"./getBoundingClientRect.js\";\nimport getParentNode from \"./getParentNode.js\";\nimport contains from \"./contains.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport rectToClientRect from \"../utils/rectToClientRect.js\";\nimport { max, min } from \"../utils/math.js\";\n\nfunction getInnerBoundingClientRect(element, strategy) {\n var rect = getBoundingClientRect(element, false, strategy === 'fixed');\n rect.top = rect.top + element.clientTop;\n rect.left = rect.left + element.clientLeft;\n rect.bottom = rect.top + element.clientHeight;\n rect.right = rect.left + element.clientWidth;\n rect.width = element.clientWidth;\n rect.height = element.clientHeight;\n rect.x = rect.left;\n rect.y = rect.top;\n return rect;\n}\n\nfunction getClientRectFromMixedType(element, clippingParent, strategy) {\n return clippingParent === viewport ? rectToClientRect(getViewportRect(element, strategy)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent, strategy) : rectToClientRect(getDocumentRect(getDocumentElement(element)));\n} // A \"clipping parent\" is an overflowable container with the characteristic of\n// clipping (or hiding) overflowing elements with a position different from\n// `initial`\n\n\nfunction getClippingParents(element) {\n var clippingParents = listScrollParents(getParentNode(element));\n var canEscapeClipping = ['absolute', 'fixed'].indexOf(getComputedStyle(element).position) >= 0;\n var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element;\n\n if (!isElement(clipperElement)) {\n return [];\n } // $FlowFixMe[incompatible-return]: https://github.com/facebook/flow/issues/1414\n\n\n return clippingParents.filter(function (clippingParent) {\n return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== 'body';\n });\n} // Gets the maximum area that the element is visible in due to any number of\n// clipping parents\n\n\nexport default function getClippingRect(element, boundary, rootBoundary, strategy) {\n var mainClippingParents = boundary === 'clippingParents' ? getClippingParents(element) : [].concat(boundary);\n var clippingParents = [].concat(mainClippingParents, [rootBoundary]);\n var firstClippingParent = clippingParents[0];\n var clippingRect = clippingParents.reduce(function (accRect, clippingParent) {\n var rect = getClientRectFromMixedType(element, clippingParent, strategy);\n accRect.top = max(rect.top, accRect.top);\n accRect.right = min(rect.right, accRect.right);\n accRect.bottom = min(rect.bottom, accRect.bottom);\n accRect.left = max(rect.left, accRect.left);\n return accRect;\n }, getClientRectFromMixedType(element, firstClippingParent, strategy));\n clippingRect.width = clippingRect.right - clippingRect.left;\n clippingRect.height = clippingRect.bottom - clippingRect.top;\n clippingRect.x = clippingRect.left;\n clippingRect.y = clippingRect.top;\n return clippingRect;\n}","import getWindow from \"./getWindow.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport getWindowScrollBarX from \"./getWindowScrollBarX.js\";\nimport isLayoutViewport from \"./isLayoutViewport.js\";\nexport default function getViewportRect(element, strategy) {\n var win = getWindow(element);\n var html = getDocumentElement(element);\n var visualViewport = win.visualViewport;\n var width = html.clientWidth;\n var height = html.clientHeight;\n var x = 0;\n var y = 0;\n\n if (visualViewport) {\n width = visualViewport.width;\n height = visualViewport.height;\n var layoutViewport = isLayoutViewport();\n\n if (layoutViewport || !layoutViewport && strategy === 'fixed') {\n x = visualViewport.offsetLeft;\n y = visualViewport.offsetTop;\n }\n }\n\n return {\n width: width,\n height: height,\n x: x + getWindowScrollBarX(element),\n y: y\n };\n}","import getDocumentElement from \"./getDocumentElement.js\";\nimport getComputedStyle from \"./getComputedStyle.js\";\nimport getWindowScrollBarX from \"./getWindowScrollBarX.js\";\nimport getWindowScroll from \"./getWindowScroll.js\";\nimport { max } from \"../utils/math.js\"; // Gets the entire size of the scrollable document area, even extending outside\n// of the `` and `` rect bounds if horizontally scrollable\n\nexport default function getDocumentRect(element) {\n var _element$ownerDocumen;\n\n var html = getDocumentElement(element);\n var winScroll = getWindowScroll(element);\n var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body;\n var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0);\n var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0);\n var x = -winScroll.scrollLeft + getWindowScrollBarX(element);\n var y = -winScroll.scrollTop;\n\n if (getComputedStyle(body || html).direction === 'rtl') {\n x += max(html.clientWidth, body ? body.clientWidth : 0) - width;\n }\n\n return {\n width: width,\n height: height,\n x: x,\n y: y\n };\n}","import getBasePlacement from \"./getBasePlacement.js\";\nimport getVariation from \"./getVariation.js\";\nimport getMainAxisFromPlacement from \"./getMainAxisFromPlacement.js\";\nimport { top, right, bottom, left, start, end } from \"../enums.js\";\nexport default function computeOffsets(_ref) {\n var reference = _ref.reference,\n element = _ref.element,\n placement = _ref.placement;\n var basePlacement = placement ? getBasePlacement(placement) : null;\n var variation = placement ? getVariation(placement) : null;\n var commonX = reference.x + reference.width / 2 - element.width / 2;\n var commonY = reference.y + reference.height / 2 - element.height / 2;\n var offsets;\n\n switch (basePlacement) {\n case top:\n offsets = {\n x: commonX,\n y: reference.y - element.height\n };\n break;\n\n case bottom:\n offsets = {\n x: commonX,\n y: reference.y + reference.height\n };\n break;\n\n case right:\n offsets = {\n x: reference.x + reference.width,\n y: commonY\n };\n break;\n\n case left:\n offsets = {\n x: reference.x - element.width,\n y: commonY\n };\n break;\n\n default:\n offsets = {\n x: reference.x,\n y: reference.y\n };\n }\n\n var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null;\n\n if (mainAxis != null) {\n var len = mainAxis === 'y' ? 'height' : 'width';\n\n switch (variation) {\n case start:\n offsets[mainAxis] = offsets[mainAxis] - (reference[len] / 2 - element[len] / 2);\n break;\n\n case end:\n offsets[mainAxis] = offsets[mainAxis] + (reference[len] / 2 - element[len] / 2);\n break;\n\n default:\n }\n }\n\n return offsets;\n}","import getClippingRect from \"../dom-utils/getClippingRect.js\";\nimport getDocumentElement from \"../dom-utils/getDocumentElement.js\";\nimport getBoundingClientRect from \"../dom-utils/getBoundingClientRect.js\";\nimport computeOffsets from \"./computeOffsets.js\";\nimport rectToClientRect from \"./rectToClientRect.js\";\nimport { clippingParents, reference, popper, bottom, top, right, basePlacements, viewport } from \"../enums.js\";\nimport { isElement } from \"../dom-utils/instanceOf.js\";\nimport mergePaddingObject from \"./mergePaddingObject.js\";\nimport expandToHashMap from \"./expandToHashMap.js\"; // eslint-disable-next-line import/no-unused-modules\n\nexport default function detectOverflow(state, options) {\n if (options === void 0) {\n options = {};\n }\n\n var _options = options,\n _options$placement = _options.placement,\n placement = _options$placement === void 0 ? state.placement : _options$placement,\n _options$strategy = _options.strategy,\n strategy = _options$strategy === void 0 ? state.strategy : _options$strategy,\n _options$boundary = _options.boundary,\n boundary = _options$boundary === void 0 ? clippingParents : _options$boundary,\n _options$rootBoundary = _options.rootBoundary,\n rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary,\n _options$elementConte = _options.elementContext,\n elementContext = _options$elementConte === void 0 ? popper : _options$elementConte,\n _options$altBoundary = _options.altBoundary,\n altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary,\n _options$padding = _options.padding,\n padding = _options$padding === void 0 ? 0 : _options$padding;\n var paddingObject = mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));\n var altContext = elementContext === popper ? reference : popper;\n var popperRect = state.rects.popper;\n var element = state.elements[altBoundary ? altContext : elementContext];\n var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary, strategy);\n var referenceClientRect = getBoundingClientRect(state.elements.reference);\n var popperOffsets = computeOffsets({\n reference: referenceClientRect,\n element: popperRect,\n strategy: 'absolute',\n placement: placement\n });\n var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets));\n var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; // positive = overflowing the clipping rect\n // 0 or negative = within the clipping rect\n\n var overflowOffsets = {\n top: clippingClientRect.top - elementClientRect.top + paddingObject.top,\n bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom,\n left: clippingClientRect.left - elementClientRect.left + paddingObject.left,\n right: elementClientRect.right - clippingClientRect.right + paddingObject.right\n };\n var offsetData = state.modifiersData.offset; // Offsets can be applied only to the popper element\n\n if (elementContext === popper && offsetData) {\n var offset = offsetData[placement];\n Object.keys(overflowOffsets).forEach(function (key) {\n var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1;\n var axis = [top, bottom].indexOf(key) >= 0 ? 'y' : 'x';\n overflowOffsets[key] += offset[axis] * multiply;\n });\n }\n\n return overflowOffsets;\n}","import getOppositePlacement from \"../utils/getOppositePlacement.js\";\nimport getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getOppositeVariationPlacement from \"../utils/getOppositeVariationPlacement.js\";\nimport detectOverflow from \"../utils/detectOverflow.js\";\nimport computeAutoPlacement from \"../utils/computeAutoPlacement.js\";\nimport { bottom, top, start, right, left, auto } from \"../enums.js\";\nimport getVariation from \"../utils/getVariation.js\"; // eslint-disable-next-line import/no-unused-modules\n\nfunction getExpandedFallbackPlacements(placement) {\n if (getBasePlacement(placement) === auto) {\n return [];\n }\n\n var oppositePlacement = getOppositePlacement(placement);\n return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)];\n}\n\nfunction flip(_ref) {\n var state = _ref.state,\n options = _ref.options,\n name = _ref.name;\n\n if (state.modifiersData[name]._skip) {\n return;\n }\n\n var _options$mainAxis = options.mainAxis,\n checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,\n _options$altAxis = options.altAxis,\n checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis,\n specifiedFallbackPlacements = options.fallbackPlacements,\n padding = options.padding,\n boundary = options.boundary,\n rootBoundary = options.rootBoundary,\n altBoundary = options.altBoundary,\n _options$flipVariatio = options.flipVariations,\n flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio,\n allowedAutoPlacements = options.allowedAutoPlacements;\n var preferredPlacement = state.options.placement;\n var basePlacement = getBasePlacement(preferredPlacement);\n var isBasePlacement = basePlacement === preferredPlacement;\n var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement));\n var placements = [preferredPlacement].concat(fallbackPlacements).reduce(function (acc, placement) {\n return acc.concat(getBasePlacement(placement) === auto ? computeAutoPlacement(state, {\n placement: placement,\n boundary: boundary,\n rootBoundary: rootBoundary,\n padding: padding,\n flipVariations: flipVariations,\n allowedAutoPlacements: allowedAutoPlacements\n }) : placement);\n }, []);\n var referenceRect = state.rects.reference;\n var popperRect = state.rects.popper;\n var checksMap = new Map();\n var makeFallbackChecks = true;\n var firstFittingPlacement = placements[0];\n\n for (var i = 0; i < placements.length; i++) {\n var placement = placements[i];\n\n var _basePlacement = getBasePlacement(placement);\n\n var isStartVariation = getVariation(placement) === start;\n var isVertical = [top, bottom].indexOf(_basePlacement) >= 0;\n var len = isVertical ? 'width' : 'height';\n var overflow = detectOverflow(state, {\n placement: placement,\n boundary: boundary,\n rootBoundary: rootBoundary,\n altBoundary: altBoundary,\n padding: padding\n });\n var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top;\n\n if (referenceRect[len] > popperRect[len]) {\n mainVariationSide = getOppositePlacement(mainVariationSide);\n }\n\n var altVariationSide = getOppositePlacement(mainVariationSide);\n var checks = [];\n\n if (checkMainAxis) {\n checks.push(overflow[_basePlacement] <= 0);\n }\n\n if (checkAltAxis) {\n checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0);\n }\n\n if (checks.every(function (check) {\n return check;\n })) {\n firstFittingPlacement = placement;\n makeFallbackChecks = false;\n break;\n }\n\n checksMap.set(placement, checks);\n }\n\n if (makeFallbackChecks) {\n // `2` may be desired in some cases – research later\n var numberOfChecks = flipVariations ? 3 : 1;\n\n var _loop = function _loop(_i) {\n var fittingPlacement = placements.find(function (placement) {\n var checks = checksMap.get(placement);\n\n if (checks) {\n return checks.slice(0, _i).every(function (check) {\n return check;\n });\n }\n });\n\n if (fittingPlacement) {\n firstFittingPlacement = fittingPlacement;\n return \"break\";\n }\n };\n\n for (var _i = numberOfChecks; _i > 0; _i--) {\n var _ret = _loop(_i);\n\n if (_ret === \"break\") break;\n }\n }\n\n if (state.placement !== firstFittingPlacement) {\n state.modifiersData[name]._skip = true;\n state.placement = firstFittingPlacement;\n state.reset = true;\n }\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'flip',\n enabled: true,\n phase: 'main',\n fn: flip,\n requiresIfExists: ['offset'],\n data: {\n _skip: false\n }\n};","import getVariation from \"./getVariation.js\";\nimport { variationPlacements, basePlacements, placements as allPlacements } from \"../enums.js\";\nimport detectOverflow from \"./detectOverflow.js\";\nimport getBasePlacement from \"./getBasePlacement.js\";\nexport default function computeAutoPlacement(state, options) {\n if (options === void 0) {\n options = {};\n }\n\n var _options = options,\n placement = _options.placement,\n boundary = _options.boundary,\n rootBoundary = _options.rootBoundary,\n padding = _options.padding,\n flipVariations = _options.flipVariations,\n _options$allowedAutoP = _options.allowedAutoPlacements,\n allowedAutoPlacements = _options$allowedAutoP === void 0 ? allPlacements : _options$allowedAutoP;\n var variation = getVariation(placement);\n var placements = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function (placement) {\n return getVariation(placement) === variation;\n }) : basePlacements;\n var allowedPlacements = placements.filter(function (placement) {\n return allowedAutoPlacements.indexOf(placement) >= 0;\n });\n\n if (allowedPlacements.length === 0) {\n allowedPlacements = placements;\n } // $FlowFixMe[incompatible-type]: Flow seems to have problems with two array unions...\n\n\n var overflows = allowedPlacements.reduce(function (acc, placement) {\n acc[placement] = detectOverflow(state, {\n placement: placement,\n boundary: boundary,\n rootBoundary: rootBoundary,\n padding: padding\n })[getBasePlacement(placement)];\n return acc;\n }, {});\n return Object.keys(overflows).sort(function (a, b) {\n return overflows[a] - overflows[b];\n });\n}","import { top, bottom, left, right } from \"../enums.js\";\nimport detectOverflow from \"../utils/detectOverflow.js\";\n\nfunction getSideOffsets(overflow, rect, preventedOffsets) {\n if (preventedOffsets === void 0) {\n preventedOffsets = {\n x: 0,\n y: 0\n };\n }\n\n return {\n top: overflow.top - rect.height - preventedOffsets.y,\n right: overflow.right - rect.width + preventedOffsets.x,\n bottom: overflow.bottom - rect.height + preventedOffsets.y,\n left: overflow.left - rect.width - preventedOffsets.x\n };\n}\n\nfunction isAnySideFullyClipped(overflow) {\n return [top, right, bottom, left].some(function (side) {\n return overflow[side] >= 0;\n });\n}\n\nfunction hide(_ref) {\n var state = _ref.state,\n name = _ref.name;\n var referenceRect = state.rects.reference;\n var popperRect = state.rects.popper;\n var preventedOffsets = state.modifiersData.preventOverflow;\n var referenceOverflow = detectOverflow(state, {\n elementContext: 'reference'\n });\n var popperAltOverflow = detectOverflow(state, {\n altBoundary: true\n });\n var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect);\n var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets);\n var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets);\n var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets);\n state.modifiersData[name] = {\n referenceClippingOffsets: referenceClippingOffsets,\n popperEscapeOffsets: popperEscapeOffsets,\n isReferenceHidden: isReferenceHidden,\n hasPopperEscaped: hasPopperEscaped\n };\n state.attributes.popper = Object.assign({}, state.attributes.popper, {\n 'data-popper-reference-hidden': isReferenceHidden,\n 'data-popper-escaped': hasPopperEscaped\n });\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'hide',\n enabled: true,\n phase: 'main',\n requiresIfExists: ['preventOverflow'],\n fn: hide\n};","import getBasePlacement from \"../utils/getBasePlacement.js\";\nimport { top, left, right, placements } from \"../enums.js\"; // eslint-disable-next-line import/no-unused-modules\n\nexport function distanceAndSkiddingToXY(placement, rects, offset) {\n var basePlacement = getBasePlacement(placement);\n var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1;\n\n var _ref = typeof offset === 'function' ? offset(Object.assign({}, rects, {\n placement: placement\n })) : offset,\n skidding = _ref[0],\n distance = _ref[1];\n\n skidding = skidding || 0;\n distance = (distance || 0) * invertDistance;\n return [left, right].indexOf(basePlacement) >= 0 ? {\n x: distance,\n y: skidding\n } : {\n x: skidding,\n y: distance\n };\n}\n\nfunction offset(_ref2) {\n var state = _ref2.state,\n options = _ref2.options,\n name = _ref2.name;\n var _options$offset = options.offset,\n offset = _options$offset === void 0 ? [0, 0] : _options$offset;\n var data = placements.reduce(function (acc, placement) {\n acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset);\n return acc;\n }, {});\n var _data$state$placement = data[state.placement],\n x = _data$state$placement.x,\n y = _data$state$placement.y;\n\n if (state.modifiersData.popperOffsets != null) {\n state.modifiersData.popperOffsets.x += x;\n state.modifiersData.popperOffsets.y += y;\n }\n\n state.modifiersData[name] = data;\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'offset',\n enabled: true,\n phase: 'main',\n requires: ['popperOffsets'],\n fn: offset\n};","import computeOffsets from \"../utils/computeOffsets.js\";\n\nfunction popperOffsets(_ref) {\n var state = _ref.state,\n name = _ref.name;\n // Offsets are the actual position the popper needs to have to be\n // properly positioned near its reference element\n // This is the most basic placement, and will be adjusted by\n // the modifiers in the next step\n state.modifiersData[name] = computeOffsets({\n reference: state.rects.reference,\n element: state.rects.popper,\n strategy: 'absolute',\n placement: state.placement\n });\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'popperOffsets',\n enabled: true,\n phase: 'read',\n fn: popperOffsets,\n data: {}\n};","import { top, left, right, bottom, start } from \"../enums.js\";\nimport getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getMainAxisFromPlacement from \"../utils/getMainAxisFromPlacement.js\";\nimport getAltAxis from \"../utils/getAltAxis.js\";\nimport { within, withinMaxClamp } from \"../utils/within.js\";\nimport getLayoutRect from \"../dom-utils/getLayoutRect.js\";\nimport getOffsetParent from \"../dom-utils/getOffsetParent.js\";\nimport detectOverflow from \"../utils/detectOverflow.js\";\nimport getVariation from \"../utils/getVariation.js\";\nimport getFreshSideObject from \"../utils/getFreshSideObject.js\";\nimport { min as mathMin, max as mathMax } from \"../utils/math.js\";\n\nfunction preventOverflow(_ref) {\n var state = _ref.state,\n options = _ref.options,\n name = _ref.name;\n var _options$mainAxis = options.mainAxis,\n checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,\n _options$altAxis = options.altAxis,\n checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis,\n boundary = options.boundary,\n rootBoundary = options.rootBoundary,\n altBoundary = options.altBoundary,\n padding = options.padding,\n _options$tether = options.tether,\n tether = _options$tether === void 0 ? true : _options$tether,\n _options$tetherOffset = options.tetherOffset,\n tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset;\n var overflow = detectOverflow(state, {\n boundary: boundary,\n rootBoundary: rootBoundary,\n padding: padding,\n altBoundary: altBoundary\n });\n var basePlacement = getBasePlacement(state.placement);\n var variation = getVariation(state.placement);\n var isBasePlacement = !variation;\n var mainAxis = getMainAxisFromPlacement(basePlacement);\n var altAxis = getAltAxis(mainAxis);\n var popperOffsets = state.modifiersData.popperOffsets;\n var referenceRect = state.rects.reference;\n var popperRect = state.rects.popper;\n var tetherOffsetValue = typeof tetherOffset === 'function' ? tetherOffset(Object.assign({}, state.rects, {\n placement: state.placement\n })) : tetherOffset;\n var normalizedTetherOffsetValue = typeof tetherOffsetValue === 'number' ? {\n mainAxis: tetherOffsetValue,\n altAxis: tetherOffsetValue\n } : Object.assign({\n mainAxis: 0,\n altAxis: 0\n }, tetherOffsetValue);\n var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null;\n var data = {\n x: 0,\n y: 0\n };\n\n if (!popperOffsets) {\n return;\n }\n\n if (checkMainAxis) {\n var _offsetModifierState$;\n\n var mainSide = mainAxis === 'y' ? top : left;\n var altSide = mainAxis === 'y' ? bottom : right;\n var len = mainAxis === 'y' ? 'height' : 'width';\n var offset = popperOffsets[mainAxis];\n var min = offset + overflow[mainSide];\n var max = offset - overflow[altSide];\n var additive = tether ? -popperRect[len] / 2 : 0;\n var minLen = variation === start ? referenceRect[len] : popperRect[len];\n var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; // We need to include the arrow in the calculation so the arrow doesn't go\n // outside the reference bounds\n\n var arrowElement = state.elements.arrow;\n var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : {\n width: 0,\n height: 0\n };\n var arrowPaddingObject = state.modifiersData['arrow#persistent'] ? state.modifiersData['arrow#persistent'].padding : getFreshSideObject();\n var arrowPaddingMin = arrowPaddingObject[mainSide];\n var arrowPaddingMax = arrowPaddingObject[altSide]; // If the reference length is smaller than the arrow length, we don't want\n // to include its full size in the calculation. If the reference is small\n // and near the edge of a boundary, the popper can overflow even if the\n // reference is not overflowing as well (e.g. virtual elements with no\n // width or height)\n\n var arrowLen = within(0, referenceRect[len], arrowRect[len]);\n var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis;\n var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis;\n var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow);\n var clientOffset = arrowOffsetParent ? mainAxis === 'y' ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0;\n var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0;\n var tetherMin = offset + minOffset - offsetModifierValue - clientOffset;\n var tetherMax = offset + maxOffset - offsetModifierValue;\n var preventedOffset = within(tether ? mathMin(min, tetherMin) : min, offset, tether ? mathMax(max, tetherMax) : max);\n popperOffsets[mainAxis] = preventedOffset;\n data[mainAxis] = preventedOffset - offset;\n }\n\n if (checkAltAxis) {\n var _offsetModifierState$2;\n\n var _mainSide = mainAxis === 'x' ? top : left;\n\n var _altSide = mainAxis === 'x' ? bottom : right;\n\n var _offset = popperOffsets[altAxis];\n\n var _len = altAxis === 'y' ? 'height' : 'width';\n\n var _min = _offset + overflow[_mainSide];\n\n var _max = _offset - overflow[_altSide];\n\n var isOriginSide = [top, left].indexOf(basePlacement) !== -1;\n\n var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0;\n\n var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis;\n\n var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max;\n\n var _preventedOffset = tether && isOriginSide ? withinMaxClamp(_tetherMin, _offset, _tetherMax) : within(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max);\n\n popperOffsets[altAxis] = _preventedOffset;\n data[altAxis] = _preventedOffset - _offset;\n }\n\n state.modifiersData[name] = data;\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'preventOverflow',\n enabled: true,\n phase: 'main',\n fn: preventOverflow,\n requiresIfExists: ['offset']\n};","export default function getAltAxis(axis) {\n return axis === 'x' ? 'y' : 'x';\n}","import getBoundingClientRect from \"./getBoundingClientRect.js\";\nimport getNodeScroll from \"./getNodeScroll.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport { isHTMLElement } from \"./instanceOf.js\";\nimport getWindowScrollBarX from \"./getWindowScrollBarX.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport isScrollParent from \"./isScrollParent.js\";\nimport { round } from \"../utils/math.js\";\n\nfunction isElementScaled(element) {\n var rect = element.getBoundingClientRect();\n var scaleX = round(rect.width) / element.offsetWidth || 1;\n var scaleY = round(rect.height) / element.offsetHeight || 1;\n return scaleX !== 1 || scaleY !== 1;\n} // Returns the composite rect of an element relative to its offsetParent.\n// Composite means it takes into account transforms as well as layout.\n\n\nexport default function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) {\n if (isFixed === void 0) {\n isFixed = false;\n }\n\n var isOffsetParentAnElement = isHTMLElement(offsetParent);\n var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent);\n var documentElement = getDocumentElement(offsetParent);\n var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled, isFixed);\n var scroll = {\n scrollLeft: 0,\n scrollTop: 0\n };\n var offsets = {\n x: 0,\n y: 0\n };\n\n if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {\n if (getNodeName(offsetParent) !== 'body' || // https://github.com/popperjs/popper-core/issues/1078\n isScrollParent(documentElement)) {\n scroll = getNodeScroll(offsetParent);\n }\n\n if (isHTMLElement(offsetParent)) {\n offsets = getBoundingClientRect(offsetParent, true);\n offsets.x += offsetParent.clientLeft;\n offsets.y += offsetParent.clientTop;\n } else if (documentElement) {\n offsets.x = getWindowScrollBarX(documentElement);\n }\n }\n\n return {\n x: rect.left + scroll.scrollLeft - offsets.x,\n y: rect.top + scroll.scrollTop - offsets.y,\n width: rect.width,\n height: rect.height\n };\n}","import getWindowScroll from \"./getWindowScroll.js\";\nimport getWindow from \"./getWindow.js\";\nimport { isHTMLElement } from \"./instanceOf.js\";\nimport getHTMLElementScroll from \"./getHTMLElementScroll.js\";\nexport default function getNodeScroll(node) {\n if (node === getWindow(node) || !isHTMLElement(node)) {\n return getWindowScroll(node);\n } else {\n return getHTMLElementScroll(node);\n }\n}","export default function getHTMLElementScroll(element) {\n return {\n scrollLeft: element.scrollLeft,\n scrollTop: element.scrollTop\n };\n}","import { modifierPhases } from \"../enums.js\"; // source: https://stackoverflow.com/questions/49875255\n\nfunction order(modifiers) {\n var map = new Map();\n var visited = new Set();\n var result = [];\n modifiers.forEach(function (modifier) {\n map.set(modifier.name, modifier);\n }); // On visiting object, check for its dependencies and visit them recursively\n\n function sort(modifier) {\n visited.add(modifier.name);\n var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []);\n requires.forEach(function (dep) {\n if (!visited.has(dep)) {\n var depModifier = map.get(dep);\n\n if (depModifier) {\n sort(depModifier);\n }\n }\n });\n result.push(modifier);\n }\n\n modifiers.forEach(function (modifier) {\n if (!visited.has(modifier.name)) {\n // check for visited object\n sort(modifier);\n }\n });\n return result;\n}\n\nexport default function orderModifiers(modifiers) {\n // order based on dependencies\n var orderedModifiers = order(modifiers); // order based on phase\n\n return modifierPhases.reduce(function (acc, phase) {\n return acc.concat(orderedModifiers.filter(function (modifier) {\n return modifier.phase === phase;\n }));\n }, []);\n}","import getCompositeRect from \"./dom-utils/getCompositeRect.js\";\nimport getLayoutRect from \"./dom-utils/getLayoutRect.js\";\nimport listScrollParents from \"./dom-utils/listScrollParents.js\";\nimport getOffsetParent from \"./dom-utils/getOffsetParent.js\";\nimport orderModifiers from \"./utils/orderModifiers.js\";\nimport debounce from \"./utils/debounce.js\";\nimport mergeByName from \"./utils/mergeByName.js\";\nimport detectOverflow from \"./utils/detectOverflow.js\";\nimport { isElement } from \"./dom-utils/instanceOf.js\";\nvar DEFAULT_OPTIONS = {\n placement: 'bottom',\n modifiers: [],\n strategy: 'absolute'\n};\n\nfunction areValidElements() {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n return !args.some(function (element) {\n return !(element && typeof element.getBoundingClientRect === 'function');\n });\n}\n\nexport function popperGenerator(generatorOptions) {\n if (generatorOptions === void 0) {\n generatorOptions = {};\n }\n\n var _generatorOptions = generatorOptions,\n _generatorOptions$def = _generatorOptions.defaultModifiers,\n defaultModifiers = _generatorOptions$def === void 0 ? [] : _generatorOptions$def,\n _generatorOptions$def2 = _generatorOptions.defaultOptions,\n defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2;\n return function createPopper(reference, popper, options) {\n if (options === void 0) {\n options = defaultOptions;\n }\n\n var state = {\n placement: 'bottom',\n orderedModifiers: [],\n options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions),\n modifiersData: {},\n elements: {\n reference: reference,\n popper: popper\n },\n attributes: {},\n styles: {}\n };\n var effectCleanupFns = [];\n var isDestroyed = false;\n var instance = {\n state: state,\n setOptions: function setOptions(setOptionsAction) {\n var options = typeof setOptionsAction === 'function' ? setOptionsAction(state.options) : setOptionsAction;\n cleanupModifierEffects();\n state.options = Object.assign({}, defaultOptions, state.options, options);\n state.scrollParents = {\n reference: isElement(reference) ? listScrollParents(reference) : reference.contextElement ? listScrollParents(reference.contextElement) : [],\n popper: listScrollParents(popper)\n }; // Orders the modifiers based on their dependencies and `phase`\n // properties\n\n var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers, state.options.modifiers))); // Strip out disabled modifiers\n\n state.orderedModifiers = orderedModifiers.filter(function (m) {\n return m.enabled;\n });\n runModifierEffects();\n return instance.update();\n },\n // Sync update – it will always be executed, even if not necessary. This\n // is useful for low frequency updates where sync behavior simplifies the\n // logic.\n // For high frequency updates (e.g. `resize` and `scroll` events), always\n // prefer the async Popper#update method\n forceUpdate: function forceUpdate() {\n if (isDestroyed) {\n return;\n }\n\n var _state$elements = state.elements,\n reference = _state$elements.reference,\n popper = _state$elements.popper; // Don't proceed if `reference` or `popper` are not valid elements\n // anymore\n\n if (!areValidElements(reference, popper)) {\n return;\n } // Store the reference and popper rects to be read by modifiers\n\n\n state.rects = {\n reference: getCompositeRect(reference, getOffsetParent(popper), state.options.strategy === 'fixed'),\n popper: getLayoutRect(popper)\n }; // Modifiers have the ability to reset the current update cycle. The\n // most common use case for this is the `flip` modifier changing the\n // placement, which then needs to re-run all the modifiers, because the\n // logic was previously ran for the previous placement and is therefore\n // stale/incorrect\n\n state.reset = false;\n state.placement = state.options.placement; // On each update cycle, the `modifiersData` property for each modifier\n // is filled with the initial data specified by the modifier. This means\n // it doesn't persist and is fresh on each update.\n // To ensure persistent data, use `${name}#persistent`\n\n state.orderedModifiers.forEach(function (modifier) {\n return state.modifiersData[modifier.name] = Object.assign({}, modifier.data);\n });\n\n for (var index = 0; index < state.orderedModifiers.length; index++) {\n if (state.reset === true) {\n state.reset = false;\n index = -1;\n continue;\n }\n\n var _state$orderedModifie = state.orderedModifiers[index],\n fn = _state$orderedModifie.fn,\n _state$orderedModifie2 = _state$orderedModifie.options,\n _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2,\n name = _state$orderedModifie.name;\n\n if (typeof fn === 'function') {\n state = fn({\n state: state,\n options: _options,\n name: name,\n instance: instance\n }) || state;\n }\n }\n },\n // Async and optimistically optimized update – it will not be executed if\n // not necessary (debounced to run at most once-per-tick)\n update: debounce(function () {\n return new Promise(function (resolve) {\n instance.forceUpdate();\n resolve(state);\n });\n }),\n destroy: function destroy() {\n cleanupModifierEffects();\n isDestroyed = true;\n }\n };\n\n if (!areValidElements(reference, popper)) {\n return instance;\n }\n\n instance.setOptions(options).then(function (state) {\n if (!isDestroyed && options.onFirstUpdate) {\n options.onFirstUpdate(state);\n }\n }); // Modifiers have the ability to execute arbitrary code before the first\n // update cycle runs. They will be executed in the same order as the update\n // cycle. This is useful when a modifier adds some persistent data that\n // other modifiers need to use, but the modifier is run after the dependent\n // one.\n\n function runModifierEffects() {\n state.orderedModifiers.forEach(function (_ref) {\n var name = _ref.name,\n _ref$options = _ref.options,\n options = _ref$options === void 0 ? {} : _ref$options,\n effect = _ref.effect;\n\n if (typeof effect === 'function') {\n var cleanupFn = effect({\n state: state,\n name: name,\n instance: instance,\n options: options\n });\n\n var noopFn = function noopFn() {};\n\n effectCleanupFns.push(cleanupFn || noopFn);\n }\n });\n }\n\n function cleanupModifierEffects() {\n effectCleanupFns.forEach(function (fn) {\n return fn();\n });\n effectCleanupFns = [];\n }\n\n return instance;\n };\n}\nexport var createPopper = /*#__PURE__*/popperGenerator(); // eslint-disable-next-line import/no-unused-modules\n\nexport { detectOverflow };","export default function debounce(fn) {\n var pending;\n return function () {\n if (!pending) {\n pending = new Promise(function (resolve) {\n Promise.resolve().then(function () {\n pending = undefined;\n resolve(fn());\n });\n });\n }\n\n return pending;\n };\n}","export default function mergeByName(modifiers) {\n var merged = modifiers.reduce(function (merged, current) {\n var existing = merged[current.name];\n merged[current.name] = existing ? Object.assign({}, existing, current, {\n options: Object.assign({}, existing.options, current.options),\n data: Object.assign({}, existing.data, current.data)\n }) : current;\n return merged;\n }, {}); // IE11 does not support Object.values\n\n return Object.keys(merged).map(function (key) {\n return merged[key];\n });\n}","import { popperGenerator, detectOverflow } from \"./createPopper.js\";\nimport eventListeners from \"./modifiers/eventListeners.js\";\nimport popperOffsets from \"./modifiers/popperOffsets.js\";\nimport computeStyles from \"./modifiers/computeStyles.js\";\nimport applyStyles from \"./modifiers/applyStyles.js\";\nimport offset from \"./modifiers/offset.js\";\nimport flip from \"./modifiers/flip.js\";\nimport preventOverflow from \"./modifiers/preventOverflow.js\";\nimport arrow from \"./modifiers/arrow.js\";\nimport hide from \"./modifiers/hide.js\";\nvar defaultModifiers = [eventListeners, popperOffsets, computeStyles, applyStyles, offset, flip, preventOverflow, arrow, hide];\nvar createPopper = /*#__PURE__*/popperGenerator({\n defaultModifiers: defaultModifiers\n}); // eslint-disable-next-line import/no-unused-modules\n\nexport { createPopper, popperGenerator, defaultModifiers, detectOverflow }; // eslint-disable-next-line import/no-unused-modules\n\nexport { createPopper as createPopperLite } from \"./popper-lite.js\"; // eslint-disable-next-line import/no-unused-modules\n\nexport * from \"./modifiers/index.js\";","import { popperGenerator, detectOverflow } from \"./createPopper.js\";\nimport eventListeners from \"./modifiers/eventListeners.js\";\nimport popperOffsets from \"./modifiers/popperOffsets.js\";\nimport computeStyles from \"./modifiers/computeStyles.js\";\nimport applyStyles from \"./modifiers/applyStyles.js\";\nvar defaultModifiers = [eventListeners, popperOffsets, computeStyles, applyStyles];\nvar createPopper = /*#__PURE__*/popperGenerator({\n defaultModifiers: defaultModifiers\n}); // eslint-disable-next-line import/no-unused-modules\n\nexport { createPopper, popperGenerator, defaultModifiers, detectOverflow };","/*!\n * Bootstrap v5.3.2 (https://getbootstrap.com/)\n * Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\nimport * as Popper from '@popperjs/core';\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/data.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n/**\n * Constants\n */\n\nconst elementMap = new Map();\nconst Data = {\n set(element, key, instance) {\n if (!elementMap.has(element)) {\n elementMap.set(element, new Map());\n }\n const instanceMap = elementMap.get(element);\n\n // make it clear we only want one instance per element\n // can be removed later when multiple key/instances are fine to be used\n if (!instanceMap.has(key) && instanceMap.size !== 0) {\n // eslint-disable-next-line no-console\n console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`);\n return;\n }\n instanceMap.set(key, instance);\n },\n get(element, key) {\n if (elementMap.has(element)) {\n return elementMap.get(element).get(key) || null;\n }\n return null;\n },\n remove(element, key) {\n if (!elementMap.has(element)) {\n return;\n }\n const instanceMap = elementMap.get(element);\n instanceMap.delete(key);\n\n // free up element references if there are no instances left for an element\n if (instanceMap.size === 0) {\n elementMap.delete(element);\n }\n }\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/index.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst MAX_UID = 1000000;\nconst MILLISECONDS_MULTIPLIER = 1000;\nconst TRANSITION_END = 'transitionend';\n\n/**\n * Properly escape IDs selectors to handle weird IDs\n * @param {string} selector\n * @returns {string}\n */\nconst parseSelector = selector => {\n if (selector && window.CSS && window.CSS.escape) {\n // document.querySelector needs escaping to handle IDs (html5+) containing for instance /\n selector = selector.replace(/#([^\\s\"#']+)/g, (match, id) => `#${CSS.escape(id)}`);\n }\n return selector;\n};\n\n// Shout-out Angus Croll (https://goo.gl/pxwQGp)\nconst toType = object => {\n if (object === null || object === undefined) {\n return `${object}`;\n }\n return Object.prototype.toString.call(object).match(/\\s([a-z]+)/i)[1].toLowerCase();\n};\n\n/**\n * Public Util API\n */\n\nconst getUID = prefix => {\n do {\n prefix += Math.floor(Math.random() * MAX_UID);\n } while (document.getElementById(prefix));\n return prefix;\n};\nconst getTransitionDurationFromElement = element => {\n if (!element) {\n return 0;\n }\n\n // Get transition-duration of the element\n let {\n transitionDuration,\n transitionDelay\n } = window.getComputedStyle(element);\n const floatTransitionDuration = Number.parseFloat(transitionDuration);\n const floatTransitionDelay = Number.parseFloat(transitionDelay);\n\n // Return 0 if element or transition duration is not found\n if (!floatTransitionDuration && !floatTransitionDelay) {\n return 0;\n }\n\n // If multiple durations are defined, take the first\n transitionDuration = transitionDuration.split(',')[0];\n transitionDelay = transitionDelay.split(',')[0];\n return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;\n};\nconst triggerTransitionEnd = element => {\n element.dispatchEvent(new Event(TRANSITION_END));\n};\nconst isElement = object => {\n if (!object || typeof object !== 'object') {\n return false;\n }\n if (typeof object.jquery !== 'undefined') {\n object = object[0];\n }\n return typeof object.nodeType !== 'undefined';\n};\nconst getElement = object => {\n // it's a jQuery object or a node element\n if (isElement(object)) {\n return object.jquery ? object[0] : object;\n }\n if (typeof object === 'string' && object.length > 0) {\n return document.querySelector(parseSelector(object));\n }\n return null;\n};\nconst isVisible = element => {\n if (!isElement(element) || element.getClientRects().length === 0) {\n return false;\n }\n const elementIsVisible = getComputedStyle(element).getPropertyValue('visibility') === 'visible';\n // Handle `details` element as its content may falsie appear visible when it is closed\n const closedDetails = element.closest('details:not([open])');\n if (!closedDetails) {\n return elementIsVisible;\n }\n if (closedDetails !== element) {\n const summary = element.closest('summary');\n if (summary && summary.parentNode !== closedDetails) {\n return false;\n }\n if (summary === null) {\n return false;\n }\n }\n return elementIsVisible;\n};\nconst isDisabled = element => {\n if (!element || element.nodeType !== Node.ELEMENT_NODE) {\n return true;\n }\n if (element.classList.contains('disabled')) {\n return true;\n }\n if (typeof element.disabled !== 'undefined') {\n return element.disabled;\n }\n return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';\n};\nconst findShadowRoot = element => {\n if (!document.documentElement.attachShadow) {\n return null;\n }\n\n // Can find the shadow root otherwise it'll return the document\n if (typeof element.getRootNode === 'function') {\n const root = element.getRootNode();\n return root instanceof ShadowRoot ? root : null;\n }\n if (element instanceof ShadowRoot) {\n return element;\n }\n\n // when we don't find a shadow root\n if (!element.parentNode) {\n return null;\n }\n return findShadowRoot(element.parentNode);\n};\nconst noop = () => {};\n\n/**\n * Trick to restart an element's animation\n *\n * @param {HTMLElement} element\n * @return void\n *\n * @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation\n */\nconst reflow = element => {\n element.offsetHeight; // eslint-disable-line no-unused-expressions\n};\n\nconst getjQuery = () => {\n if (window.jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {\n return window.jQuery;\n }\n return null;\n};\nconst DOMContentLoadedCallbacks = [];\nconst onDOMContentLoaded = callback => {\n if (document.readyState === 'loading') {\n // add listener on the first call when the document is in loading state\n if (!DOMContentLoadedCallbacks.length) {\n document.addEventListener('DOMContentLoaded', () => {\n for (const callback of DOMContentLoadedCallbacks) {\n callback();\n }\n });\n }\n DOMContentLoadedCallbacks.push(callback);\n } else {\n callback();\n }\n};\nconst isRTL = () => document.documentElement.dir === 'rtl';\nconst defineJQueryPlugin = plugin => {\n onDOMContentLoaded(() => {\n const $ = getjQuery();\n /* istanbul ignore if */\n if ($) {\n const name = plugin.NAME;\n const JQUERY_NO_CONFLICT = $.fn[name];\n $.fn[name] = plugin.jQueryInterface;\n $.fn[name].Constructor = plugin;\n $.fn[name].noConflict = () => {\n $.fn[name] = JQUERY_NO_CONFLICT;\n return plugin.jQueryInterface;\n };\n }\n });\n};\nconst execute = (possibleCallback, args = [], defaultValue = possibleCallback) => {\n return typeof possibleCallback === 'function' ? possibleCallback(...args) : defaultValue;\n};\nconst executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {\n if (!waitForTransition) {\n execute(callback);\n return;\n }\n const durationPadding = 5;\n const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;\n let called = false;\n const handler = ({\n target\n }) => {\n if (target !== transitionElement) {\n return;\n }\n called = true;\n transitionElement.removeEventListener(TRANSITION_END, handler);\n execute(callback);\n };\n transitionElement.addEventListener(TRANSITION_END, handler);\n setTimeout(() => {\n if (!called) {\n triggerTransitionEnd(transitionElement);\n }\n }, emulatedDuration);\n};\n\n/**\n * Return the previous/next element of a list.\n *\n * @param {array} list The list of elements\n * @param activeElement The active element\n * @param shouldGetNext Choose to get next or previous element\n * @param isCycleAllowed\n * @return {Element|elem} The proper element\n */\nconst getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {\n const listLength = list.length;\n let index = list.indexOf(activeElement);\n\n // if the element does not exist in the list return an element\n // depending on the direction and if cycle is allowed\n if (index === -1) {\n return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0];\n }\n index += shouldGetNext ? 1 : -1;\n if (isCycleAllowed) {\n index = (index + listLength) % listLength;\n }\n return list[Math.max(0, Math.min(index, listLength - 1))];\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/event-handler.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst namespaceRegex = /[^.]*(?=\\..*)\\.|.*/;\nconst stripNameRegex = /\\..*/;\nconst stripUidRegex = /::\\d+$/;\nconst eventRegistry = {}; // Events storage\nlet uidEvent = 1;\nconst customEvents = {\n mouseenter: 'mouseover',\n mouseleave: 'mouseout'\n};\nconst nativeEvents = new Set(['click', 'dblclick', 'mouseup', 'mousedown', 'contextmenu', 'mousewheel', 'DOMMouseScroll', 'mouseover', 'mouseout', 'mousemove', 'selectstart', 'selectend', 'keydown', 'keypress', 'keyup', 'orientationchange', 'touchstart', 'touchmove', 'touchend', 'touchcancel', 'pointerdown', 'pointermove', 'pointerup', 'pointerleave', 'pointercancel', 'gesturestart', 'gesturechange', 'gestureend', 'focus', 'blur', 'change', 'reset', 'select', 'submit', 'focusin', 'focusout', 'load', 'unload', 'beforeunload', 'resize', 'move', 'DOMContentLoaded', 'readystatechange', 'error', 'abort', 'scroll']);\n\n/**\n * Private methods\n */\n\nfunction makeEventUid(element, uid) {\n return uid && `${uid}::${uidEvent++}` || element.uidEvent || uidEvent++;\n}\nfunction getElementEvents(element) {\n const uid = makeEventUid(element);\n element.uidEvent = uid;\n eventRegistry[uid] = eventRegistry[uid] || {};\n return eventRegistry[uid];\n}\nfunction bootstrapHandler(element, fn) {\n return function handler(event) {\n hydrateObj(event, {\n delegateTarget: element\n });\n if (handler.oneOff) {\n EventHandler.off(element, event.type, fn);\n }\n return fn.apply(element, [event]);\n };\n}\nfunction bootstrapDelegationHandler(element, selector, fn) {\n return function handler(event) {\n const domElements = element.querySelectorAll(selector);\n for (let {\n target\n } = event; target && target !== this; target = target.parentNode) {\n for (const domElement of domElements) {\n if (domElement !== target) {\n continue;\n }\n hydrateObj(event, {\n delegateTarget: target\n });\n if (handler.oneOff) {\n EventHandler.off(element, event.type, selector, fn);\n }\n return fn.apply(target, [event]);\n }\n }\n };\n}\nfunction findHandler(events, callable, delegationSelector = null) {\n return Object.values(events).find(event => event.callable === callable && event.delegationSelector === delegationSelector);\n}\nfunction normalizeParameters(originalTypeEvent, handler, delegationFunction) {\n const isDelegated = typeof handler === 'string';\n // TODO: tooltip passes `false` instead of selector, so we need to check\n const callable = isDelegated ? delegationFunction : handler || delegationFunction;\n let typeEvent = getTypeEvent(originalTypeEvent);\n if (!nativeEvents.has(typeEvent)) {\n typeEvent = originalTypeEvent;\n }\n return [isDelegated, callable, typeEvent];\n}\nfunction addHandler(element, originalTypeEvent, handler, delegationFunction, oneOff) {\n if (typeof originalTypeEvent !== 'string' || !element) {\n return;\n }\n let [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction);\n\n // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position\n // this prevents the handler from being dispatched the same way as mouseover or mouseout does\n if (originalTypeEvent in customEvents) {\n const wrapFunction = fn => {\n return function (event) {\n if (!event.relatedTarget || event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget)) {\n return fn.call(this, event);\n }\n };\n };\n callable = wrapFunction(callable);\n }\n const events = getElementEvents(element);\n const handlers = events[typeEvent] || (events[typeEvent] = {});\n const previousFunction = findHandler(handlers, callable, isDelegated ? handler : null);\n if (previousFunction) {\n previousFunction.oneOff = previousFunction.oneOff && oneOff;\n return;\n }\n const uid = makeEventUid(callable, originalTypeEvent.replace(namespaceRegex, ''));\n const fn = isDelegated ? bootstrapDelegationHandler(element, handler, callable) : bootstrapHandler(element, callable);\n fn.delegationSelector = isDelegated ? handler : null;\n fn.callable = callable;\n fn.oneOff = oneOff;\n fn.uidEvent = uid;\n handlers[uid] = fn;\n element.addEventListener(typeEvent, fn, isDelegated);\n}\nfunction removeHandler(element, events, typeEvent, handler, delegationSelector) {\n const fn = findHandler(events[typeEvent], handler, delegationSelector);\n if (!fn) {\n return;\n }\n element.removeEventListener(typeEvent, fn, Boolean(delegationSelector));\n delete events[typeEvent][fn.uidEvent];\n}\nfunction removeNamespacedHandlers(element, events, typeEvent, namespace) {\n const storeElementEvent = events[typeEvent] || {};\n for (const [handlerKey, event] of Object.entries(storeElementEvent)) {\n if (handlerKey.includes(namespace)) {\n removeHandler(element, events, typeEvent, event.callable, event.delegationSelector);\n }\n }\n}\nfunction getTypeEvent(event) {\n // allow to get the native events from namespaced events ('click.bs.button' --> 'click')\n event = event.replace(stripNameRegex, '');\n return customEvents[event] || event;\n}\nconst EventHandler = {\n on(element, event, handler, delegationFunction) {\n addHandler(element, event, handler, delegationFunction, false);\n },\n one(element, event, handler, delegationFunction) {\n addHandler(element, event, handler, delegationFunction, true);\n },\n off(element, originalTypeEvent, handler, delegationFunction) {\n if (typeof originalTypeEvent !== 'string' || !element) {\n return;\n }\n const [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction);\n const inNamespace = typeEvent !== originalTypeEvent;\n const events = getElementEvents(element);\n const storeElementEvent = events[typeEvent] || {};\n const isNamespace = originalTypeEvent.startsWith('.');\n if (typeof callable !== 'undefined') {\n // Simplest case: handler is passed, remove that listener ONLY.\n if (!Object.keys(storeElementEvent).length) {\n return;\n }\n removeHandler(element, events, typeEvent, callable, isDelegated ? handler : null);\n return;\n }\n if (isNamespace) {\n for (const elementEvent of Object.keys(events)) {\n removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1));\n }\n }\n for (const [keyHandlers, event] of Object.entries(storeElementEvent)) {\n const handlerKey = keyHandlers.replace(stripUidRegex, '');\n if (!inNamespace || originalTypeEvent.includes(handlerKey)) {\n removeHandler(element, events, typeEvent, event.callable, event.delegationSelector);\n }\n }\n },\n trigger(element, event, args) {\n if (typeof event !== 'string' || !element) {\n return null;\n }\n const $ = getjQuery();\n const typeEvent = getTypeEvent(event);\n const inNamespace = event !== typeEvent;\n let jQueryEvent = null;\n let bubbles = true;\n let nativeDispatch = true;\n let defaultPrevented = false;\n if (inNamespace && $) {\n jQueryEvent = $.Event(event, args);\n $(element).trigger(jQueryEvent);\n bubbles = !jQueryEvent.isPropagationStopped();\n nativeDispatch = !jQueryEvent.isImmediatePropagationStopped();\n defaultPrevented = jQueryEvent.isDefaultPrevented();\n }\n const evt = hydrateObj(new Event(event, {\n bubbles,\n cancelable: true\n }), args);\n if (defaultPrevented) {\n evt.preventDefault();\n }\n if (nativeDispatch) {\n element.dispatchEvent(evt);\n }\n if (evt.defaultPrevented && jQueryEvent) {\n jQueryEvent.preventDefault();\n }\n return evt;\n }\n};\nfunction hydrateObj(obj, meta = {}) {\n for (const [key, value] of Object.entries(meta)) {\n try {\n obj[key] = value;\n } catch (_unused) {\n Object.defineProperty(obj, key, {\n configurable: true,\n get() {\n return value;\n }\n });\n }\n }\n return obj;\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/manipulator.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nfunction normalizeData(value) {\n if (value === 'true') {\n return true;\n }\n if (value === 'false') {\n return false;\n }\n if (value === Number(value).toString()) {\n return Number(value);\n }\n if (value === '' || value === 'null') {\n return null;\n }\n if (typeof value !== 'string') {\n return value;\n }\n try {\n return JSON.parse(decodeURIComponent(value));\n } catch (_unused) {\n return value;\n }\n}\nfunction normalizeDataKey(key) {\n return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`);\n}\nconst Manipulator = {\n setDataAttribute(element, key, value) {\n element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value);\n },\n removeDataAttribute(element, key) {\n element.removeAttribute(`data-bs-${normalizeDataKey(key)}`);\n },\n getDataAttributes(element) {\n if (!element) {\n return {};\n }\n const attributes = {};\n const bsKeys = Object.keys(element.dataset).filter(key => key.startsWith('bs') && !key.startsWith('bsConfig'));\n for (const key of bsKeys) {\n let pureKey = key.replace(/^bs/, '');\n pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length);\n attributes[pureKey] = normalizeData(element.dataset[key]);\n }\n return attributes;\n },\n getDataAttribute(element, key) {\n return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`));\n }\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/config.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Class definition\n */\n\nclass Config {\n // Getters\n static get Default() {\n return {};\n }\n static get DefaultType() {\n return {};\n }\n static get NAME() {\n throw new Error('You have to implement the static method \"NAME\", for each component!');\n }\n _getConfig(config) {\n config = this._mergeConfigObj(config);\n config = this._configAfterMerge(config);\n this._typeCheckConfig(config);\n return config;\n }\n _configAfterMerge(config) {\n return config;\n }\n _mergeConfigObj(config, element) {\n const jsonConfig = isElement(element) ? Manipulator.getDataAttribute(element, 'config') : {}; // try to parse\n\n return {\n ...this.constructor.Default,\n ...(typeof jsonConfig === 'object' ? jsonConfig : {}),\n ...(isElement(element) ? Manipulator.getDataAttributes(element) : {}),\n ...(typeof config === 'object' ? config : {})\n };\n }\n _typeCheckConfig(config, configTypes = this.constructor.DefaultType) {\n for (const [property, expectedTypes] of Object.entries(configTypes)) {\n const value = config[property];\n const valueType = isElement(value) ? 'element' : toType(value);\n if (!new RegExp(expectedTypes).test(valueType)) {\n throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option \"${property}\" provided type \"${valueType}\" but expected type \"${expectedTypes}\".`);\n }\n }\n }\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap base-component.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst VERSION = '5.3.2';\n\n/**\n * Class definition\n */\n\nclass BaseComponent extends Config {\n constructor(element, config) {\n super();\n element = getElement(element);\n if (!element) {\n return;\n }\n this._element = element;\n this._config = this._getConfig(config);\n Data.set(this._element, this.constructor.DATA_KEY, this);\n }\n\n // Public\n dispose() {\n Data.remove(this._element, this.constructor.DATA_KEY);\n EventHandler.off(this._element, this.constructor.EVENT_KEY);\n for (const propertyName of Object.getOwnPropertyNames(this)) {\n this[propertyName] = null;\n }\n }\n _queueCallback(callback, element, isAnimated = true) {\n executeAfterTransition(callback, element, isAnimated);\n }\n _getConfig(config) {\n config = this._mergeConfigObj(config, this._element);\n config = this._configAfterMerge(config);\n this._typeCheckConfig(config);\n return config;\n }\n\n // Static\n static getInstance(element) {\n return Data.get(getElement(element), this.DATA_KEY);\n }\n static getOrCreateInstance(element, config = {}) {\n return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null);\n }\n static get VERSION() {\n return VERSION;\n }\n static get DATA_KEY() {\n return `bs.${this.NAME}`;\n }\n static get EVENT_KEY() {\n return `.${this.DATA_KEY}`;\n }\n static eventName(name) {\n return `${name}${this.EVENT_KEY}`;\n }\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/selector-engine.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst getSelector = element => {\n let selector = element.getAttribute('data-bs-target');\n if (!selector || selector === '#') {\n let hrefAttribute = element.getAttribute('href');\n\n // The only valid content that could double as a selector are IDs or classes,\n // so everything starting with `#` or `.`. If a \"real\" URL is used as the selector,\n // `document.querySelector` will rightfully complain it is invalid.\n // See https://github.com/twbs/bootstrap/issues/32273\n if (!hrefAttribute || !hrefAttribute.includes('#') && !hrefAttribute.startsWith('.')) {\n return null;\n }\n\n // Just in case some CMS puts out a full URL with the anchor appended\n if (hrefAttribute.includes('#') && !hrefAttribute.startsWith('#')) {\n hrefAttribute = `#${hrefAttribute.split('#')[1]}`;\n }\n selector = hrefAttribute && hrefAttribute !== '#' ? parseSelector(hrefAttribute.trim()) : null;\n }\n return selector;\n};\nconst SelectorEngine = {\n find(selector, element = document.documentElement) {\n return [].concat(...Element.prototype.querySelectorAll.call(element, selector));\n },\n findOne(selector, element = document.documentElement) {\n return Element.prototype.querySelector.call(element, selector);\n },\n children(element, selector) {\n return [].concat(...element.children).filter(child => child.matches(selector));\n },\n parents(element, selector) {\n const parents = [];\n let ancestor = element.parentNode.closest(selector);\n while (ancestor) {\n parents.push(ancestor);\n ancestor = ancestor.parentNode.closest(selector);\n }\n return parents;\n },\n prev(element, selector) {\n let previous = element.previousElementSibling;\n while (previous) {\n if (previous.matches(selector)) {\n return [previous];\n }\n previous = previous.previousElementSibling;\n }\n return [];\n },\n // TODO: this is now unused; remove later along with prev()\n next(element, selector) {\n let next = element.nextElementSibling;\n while (next) {\n if (next.matches(selector)) {\n return [next];\n }\n next = next.nextElementSibling;\n }\n return [];\n },\n focusableChildren(element) {\n const focusables = ['a', 'button', 'input', 'textarea', 'select', 'details', '[tabindex]', '[contenteditable=\"true\"]'].map(selector => `${selector}:not([tabindex^=\"-\"])`).join(',');\n return this.find(focusables, element).filter(el => !isDisabled(el) && isVisible(el));\n },\n getSelectorFromElement(element) {\n const selector = getSelector(element);\n if (selector) {\n return SelectorEngine.findOne(selector) ? selector : null;\n }\n return null;\n },\n getElementFromSelector(element) {\n const selector = getSelector(element);\n return selector ? SelectorEngine.findOne(selector) : null;\n },\n getMultipleElementsFromSelector(element) {\n const selector = getSelector(element);\n return selector ? SelectorEngine.find(selector) : [];\n }\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/component-functions.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst enableDismissTrigger = (component, method = 'hide') => {\n const clickEvent = `click.dismiss${component.EVENT_KEY}`;\n const name = component.NAME;\n EventHandler.on(document, clickEvent, `[data-bs-dismiss=\"${name}\"]`, function (event) {\n if (['A', 'AREA'].includes(this.tagName)) {\n event.preventDefault();\n }\n if (isDisabled(this)) {\n return;\n }\n const target = SelectorEngine.getElementFromSelector(this) || this.closest(`.${name}`);\n const instance = component.getOrCreateInstance(target);\n\n // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method\n instance[method]();\n });\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$f = 'alert';\nconst DATA_KEY$a = 'bs.alert';\nconst EVENT_KEY$b = `.${DATA_KEY$a}`;\nconst EVENT_CLOSE = `close${EVENT_KEY$b}`;\nconst EVENT_CLOSED = `closed${EVENT_KEY$b}`;\nconst CLASS_NAME_FADE$5 = 'fade';\nconst CLASS_NAME_SHOW$8 = 'show';\n\n/**\n * Class definition\n */\n\nclass Alert extends BaseComponent {\n // Getters\n static get NAME() {\n return NAME$f;\n }\n\n // Public\n close() {\n const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE);\n if (closeEvent.defaultPrevented) {\n return;\n }\n this._element.classList.remove(CLASS_NAME_SHOW$8);\n const isAnimated = this._element.classList.contains(CLASS_NAME_FADE$5);\n this._queueCallback(() => this._destroyElement(), this._element, isAnimated);\n }\n\n // Private\n _destroyElement() {\n this._element.remove();\n EventHandler.trigger(this._element, EVENT_CLOSED);\n this.dispose();\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Alert.getOrCreateInstance(this);\n if (typeof config !== 'string') {\n return;\n }\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config](this);\n });\n }\n}\n\n/**\n * Data API implementation\n */\n\nenableDismissTrigger(Alert, 'close');\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Alert);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$e = 'button';\nconst DATA_KEY$9 = 'bs.button';\nconst EVENT_KEY$a = `.${DATA_KEY$9}`;\nconst DATA_API_KEY$6 = '.data-api';\nconst CLASS_NAME_ACTIVE$3 = 'active';\nconst SELECTOR_DATA_TOGGLE$5 = '[data-bs-toggle=\"button\"]';\nconst EVENT_CLICK_DATA_API$6 = `click${EVENT_KEY$a}${DATA_API_KEY$6}`;\n\n/**\n * Class definition\n */\n\nclass Button extends BaseComponent {\n // Getters\n static get NAME() {\n return NAME$e;\n }\n\n // Public\n toggle() {\n // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method\n this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE$3));\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Button.getOrCreateInstance(this);\n if (config === 'toggle') {\n data[config]();\n }\n });\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$6, SELECTOR_DATA_TOGGLE$5, event => {\n event.preventDefault();\n const button = event.target.closest(SELECTOR_DATA_TOGGLE$5);\n const data = Button.getOrCreateInstance(button);\n data.toggle();\n});\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Button);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/swipe.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$d = 'swipe';\nconst EVENT_KEY$9 = '.bs.swipe';\nconst EVENT_TOUCHSTART = `touchstart${EVENT_KEY$9}`;\nconst EVENT_TOUCHMOVE = `touchmove${EVENT_KEY$9}`;\nconst EVENT_TOUCHEND = `touchend${EVENT_KEY$9}`;\nconst EVENT_POINTERDOWN = `pointerdown${EVENT_KEY$9}`;\nconst EVENT_POINTERUP = `pointerup${EVENT_KEY$9}`;\nconst POINTER_TYPE_TOUCH = 'touch';\nconst POINTER_TYPE_PEN = 'pen';\nconst CLASS_NAME_POINTER_EVENT = 'pointer-event';\nconst SWIPE_THRESHOLD = 40;\nconst Default$c = {\n endCallback: null,\n leftCallback: null,\n rightCallback: null\n};\nconst DefaultType$c = {\n endCallback: '(function|null)',\n leftCallback: '(function|null)',\n rightCallback: '(function|null)'\n};\n\n/**\n * Class definition\n */\n\nclass Swipe extends Config {\n constructor(element, config) {\n super();\n this._element = element;\n if (!element || !Swipe.isSupported()) {\n return;\n }\n this._config = this._getConfig(config);\n this._deltaX = 0;\n this._supportPointerEvents = Boolean(window.PointerEvent);\n this._initEvents();\n }\n\n // Getters\n static get Default() {\n return Default$c;\n }\n static get DefaultType() {\n return DefaultType$c;\n }\n static get NAME() {\n return NAME$d;\n }\n\n // Public\n dispose() {\n EventHandler.off(this._element, EVENT_KEY$9);\n }\n\n // Private\n _start(event) {\n if (!this._supportPointerEvents) {\n this._deltaX = event.touches[0].clientX;\n return;\n }\n if (this._eventIsPointerPenTouch(event)) {\n this._deltaX = event.clientX;\n }\n }\n _end(event) {\n if (this._eventIsPointerPenTouch(event)) {\n this._deltaX = event.clientX - this._deltaX;\n }\n this._handleSwipe();\n execute(this._config.endCallback);\n }\n _move(event) {\n this._deltaX = event.touches && event.touches.length > 1 ? 0 : event.touches[0].clientX - this._deltaX;\n }\n _handleSwipe() {\n const absDeltaX = Math.abs(this._deltaX);\n if (absDeltaX <= SWIPE_THRESHOLD) {\n return;\n }\n const direction = absDeltaX / this._deltaX;\n this._deltaX = 0;\n if (!direction) {\n return;\n }\n execute(direction > 0 ? this._config.rightCallback : this._config.leftCallback);\n }\n _initEvents() {\n if (this._supportPointerEvents) {\n EventHandler.on(this._element, EVENT_POINTERDOWN, event => this._start(event));\n EventHandler.on(this._element, EVENT_POINTERUP, event => this._end(event));\n this._element.classList.add(CLASS_NAME_POINTER_EVENT);\n } else {\n EventHandler.on(this._element, EVENT_TOUCHSTART, event => this._start(event));\n EventHandler.on(this._element, EVENT_TOUCHMOVE, event => this._move(event));\n EventHandler.on(this._element, EVENT_TOUCHEND, event => this._end(event));\n }\n }\n _eventIsPointerPenTouch(event) {\n return this._supportPointerEvents && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH);\n }\n\n // Static\n static isSupported() {\n return 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0;\n }\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap carousel.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$c = 'carousel';\nconst DATA_KEY$8 = 'bs.carousel';\nconst EVENT_KEY$8 = `.${DATA_KEY$8}`;\nconst DATA_API_KEY$5 = '.data-api';\nconst ARROW_LEFT_KEY$1 = 'ArrowLeft';\nconst ARROW_RIGHT_KEY$1 = 'ArrowRight';\nconst TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch\n\nconst ORDER_NEXT = 'next';\nconst ORDER_PREV = 'prev';\nconst DIRECTION_LEFT = 'left';\nconst DIRECTION_RIGHT = 'right';\nconst EVENT_SLIDE = `slide${EVENT_KEY$8}`;\nconst EVENT_SLID = `slid${EVENT_KEY$8}`;\nconst EVENT_KEYDOWN$1 = `keydown${EVENT_KEY$8}`;\nconst EVENT_MOUSEENTER$1 = `mouseenter${EVENT_KEY$8}`;\nconst EVENT_MOUSELEAVE$1 = `mouseleave${EVENT_KEY$8}`;\nconst EVENT_DRAG_START = `dragstart${EVENT_KEY$8}`;\nconst EVENT_LOAD_DATA_API$3 = `load${EVENT_KEY$8}${DATA_API_KEY$5}`;\nconst EVENT_CLICK_DATA_API$5 = `click${EVENT_KEY$8}${DATA_API_KEY$5}`;\nconst CLASS_NAME_CAROUSEL = 'carousel';\nconst CLASS_NAME_ACTIVE$2 = 'active';\nconst CLASS_NAME_SLIDE = 'slide';\nconst CLASS_NAME_END = 'carousel-item-end';\nconst CLASS_NAME_START = 'carousel-item-start';\nconst CLASS_NAME_NEXT = 'carousel-item-next';\nconst CLASS_NAME_PREV = 'carousel-item-prev';\nconst SELECTOR_ACTIVE = '.active';\nconst SELECTOR_ITEM = '.carousel-item';\nconst SELECTOR_ACTIVE_ITEM = SELECTOR_ACTIVE + SELECTOR_ITEM;\nconst SELECTOR_ITEM_IMG = '.carousel-item img';\nconst SELECTOR_INDICATORS = '.carousel-indicators';\nconst SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]';\nconst SELECTOR_DATA_RIDE = '[data-bs-ride=\"carousel\"]';\nconst KEY_TO_DIRECTION = {\n [ARROW_LEFT_KEY$1]: DIRECTION_RIGHT,\n [ARROW_RIGHT_KEY$1]: DIRECTION_LEFT\n};\nconst Default$b = {\n interval: 5000,\n keyboard: true,\n pause: 'hover',\n ride: false,\n touch: true,\n wrap: true\n};\nconst DefaultType$b = {\n interval: '(number|boolean)',\n // TODO:v6 remove boolean support\n keyboard: 'boolean',\n pause: '(string|boolean)',\n ride: '(boolean|string)',\n touch: 'boolean',\n wrap: 'boolean'\n};\n\n/**\n * Class definition\n */\n\nclass Carousel extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n this._interval = null;\n this._activeElement = null;\n this._isSliding = false;\n this.touchTimeout = null;\n this._swipeHelper = null;\n this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element);\n this._addEventListeners();\n if (this._config.ride === CLASS_NAME_CAROUSEL) {\n this.cycle();\n }\n }\n\n // Getters\n static get Default() {\n return Default$b;\n }\n static get DefaultType() {\n return DefaultType$b;\n }\n static get NAME() {\n return NAME$c;\n }\n\n // Public\n next() {\n this._slide(ORDER_NEXT);\n }\n nextWhenVisible() {\n // FIXME TODO use `document.visibilityState`\n // Don't call next when the page isn't visible\n // or the carousel or its parent isn't visible\n if (!document.hidden && isVisible(this._element)) {\n this.next();\n }\n }\n prev() {\n this._slide(ORDER_PREV);\n }\n pause() {\n if (this._isSliding) {\n triggerTransitionEnd(this._element);\n }\n this._clearInterval();\n }\n cycle() {\n this._clearInterval();\n this._updateInterval();\n this._interval = setInterval(() => this.nextWhenVisible(), this._config.interval);\n }\n _maybeEnableCycle() {\n if (!this._config.ride) {\n return;\n }\n if (this._isSliding) {\n EventHandler.one(this._element, EVENT_SLID, () => this.cycle());\n return;\n }\n this.cycle();\n }\n to(index) {\n const items = this._getItems();\n if (index > items.length - 1 || index < 0) {\n return;\n }\n if (this._isSliding) {\n EventHandler.one(this._element, EVENT_SLID, () => this.to(index));\n return;\n }\n const activeIndex = this._getItemIndex(this._getActive());\n if (activeIndex === index) {\n return;\n }\n const order = index > activeIndex ? ORDER_NEXT : ORDER_PREV;\n this._slide(order, items[index]);\n }\n dispose() {\n if (this._swipeHelper) {\n this._swipeHelper.dispose();\n }\n super.dispose();\n }\n\n // Private\n _configAfterMerge(config) {\n config.defaultInterval = config.interval;\n return config;\n }\n _addEventListeners() {\n if (this._config.keyboard) {\n EventHandler.on(this._element, EVENT_KEYDOWN$1, event => this._keydown(event));\n }\n if (this._config.pause === 'hover') {\n EventHandler.on(this._element, EVENT_MOUSEENTER$1, () => this.pause());\n EventHandler.on(this._element, EVENT_MOUSELEAVE$1, () => this._maybeEnableCycle());\n }\n if (this._config.touch && Swipe.isSupported()) {\n this._addTouchEventListeners();\n }\n }\n _addTouchEventListeners() {\n for (const img of SelectorEngine.find(SELECTOR_ITEM_IMG, this._element)) {\n EventHandler.on(img, EVENT_DRAG_START, event => event.preventDefault());\n }\n const endCallBack = () => {\n if (this._config.pause !== 'hover') {\n return;\n }\n\n // If it's a touch-enabled device, mouseenter/leave are fired as\n // part of the mouse compatibility events on first tap - the carousel\n // would stop cycling until user tapped out of it;\n // here, we listen for touchend, explicitly pause the carousel\n // (as if it's the second time we tap on it, mouseenter compat event\n // is NOT fired) and after a timeout (to allow for mouse compatibility\n // events to fire) we explicitly restart cycling\n\n this.pause();\n if (this.touchTimeout) {\n clearTimeout(this.touchTimeout);\n }\n this.touchTimeout = setTimeout(() => this._maybeEnableCycle(), TOUCHEVENT_COMPAT_WAIT + this._config.interval);\n };\n const swipeConfig = {\n leftCallback: () => this._slide(this._directionToOrder(DIRECTION_LEFT)),\n rightCallback: () => this._slide(this._directionToOrder(DIRECTION_RIGHT)),\n endCallback: endCallBack\n };\n this._swipeHelper = new Swipe(this._element, swipeConfig);\n }\n _keydown(event) {\n if (/input|textarea/i.test(event.target.tagName)) {\n return;\n }\n const direction = KEY_TO_DIRECTION[event.key];\n if (direction) {\n event.preventDefault();\n this._slide(this._directionToOrder(direction));\n }\n }\n _getItemIndex(element) {\n return this._getItems().indexOf(element);\n }\n _setActiveIndicatorElement(index) {\n if (!this._indicatorsElement) {\n return;\n }\n const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE, this._indicatorsElement);\n activeIndicator.classList.remove(CLASS_NAME_ACTIVE$2);\n activeIndicator.removeAttribute('aria-current');\n const newActiveIndicator = SelectorEngine.findOne(`[data-bs-slide-to=\"${index}\"]`, this._indicatorsElement);\n if (newActiveIndicator) {\n newActiveIndicator.classList.add(CLASS_NAME_ACTIVE$2);\n newActiveIndicator.setAttribute('aria-current', 'true');\n }\n }\n _updateInterval() {\n const element = this._activeElement || this._getActive();\n if (!element) {\n return;\n }\n const elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10);\n this._config.interval = elementInterval || this._config.defaultInterval;\n }\n _slide(order, element = null) {\n if (this._isSliding) {\n return;\n }\n const activeElement = this._getActive();\n const isNext = order === ORDER_NEXT;\n const nextElement = element || getNextActiveElement(this._getItems(), activeElement, isNext, this._config.wrap);\n if (nextElement === activeElement) {\n return;\n }\n const nextElementIndex = this._getItemIndex(nextElement);\n const triggerEvent = eventName => {\n return EventHandler.trigger(this._element, eventName, {\n relatedTarget: nextElement,\n direction: this._orderToDirection(order),\n from: this._getItemIndex(activeElement),\n to: nextElementIndex\n });\n };\n const slideEvent = triggerEvent(EVENT_SLIDE);\n if (slideEvent.defaultPrevented) {\n return;\n }\n if (!activeElement || !nextElement) {\n // Some weirdness is happening, so we bail\n // TODO: change tests that use empty divs to avoid this check\n return;\n }\n const isCycling = Boolean(this._interval);\n this.pause();\n this._isSliding = true;\n this._setActiveIndicatorElement(nextElementIndex);\n this._activeElement = nextElement;\n const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END;\n const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV;\n nextElement.classList.add(orderClassName);\n reflow(nextElement);\n activeElement.classList.add(directionalClassName);\n nextElement.classList.add(directionalClassName);\n const completeCallBack = () => {\n nextElement.classList.remove(directionalClassName, orderClassName);\n nextElement.classList.add(CLASS_NAME_ACTIVE$2);\n activeElement.classList.remove(CLASS_NAME_ACTIVE$2, orderClassName, directionalClassName);\n this._isSliding = false;\n triggerEvent(EVENT_SLID);\n };\n this._queueCallback(completeCallBack, activeElement, this._isAnimated());\n if (isCycling) {\n this.cycle();\n }\n }\n _isAnimated() {\n return this._element.classList.contains(CLASS_NAME_SLIDE);\n }\n _getActive() {\n return SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element);\n }\n _getItems() {\n return SelectorEngine.find(SELECTOR_ITEM, this._element);\n }\n _clearInterval() {\n if (this._interval) {\n clearInterval(this._interval);\n this._interval = null;\n }\n }\n _directionToOrder(direction) {\n if (isRTL()) {\n return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT;\n }\n return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV;\n }\n _orderToDirection(order) {\n if (isRTL()) {\n return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT;\n }\n return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT;\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Carousel.getOrCreateInstance(this, config);\n if (typeof config === 'number') {\n data.to(config);\n return;\n }\n if (typeof config === 'string') {\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config]();\n }\n });\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$5, SELECTOR_DATA_SLIDE, function (event) {\n const target = SelectorEngine.getElementFromSelector(this);\n if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) {\n return;\n }\n event.preventDefault();\n const carousel = Carousel.getOrCreateInstance(target);\n const slideIndex = this.getAttribute('data-bs-slide-to');\n if (slideIndex) {\n carousel.to(slideIndex);\n carousel._maybeEnableCycle();\n return;\n }\n if (Manipulator.getDataAttribute(this, 'slide') === 'next') {\n carousel.next();\n carousel._maybeEnableCycle();\n return;\n }\n carousel.prev();\n carousel._maybeEnableCycle();\n});\nEventHandler.on(window, EVENT_LOAD_DATA_API$3, () => {\n const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE);\n for (const carousel of carousels) {\n Carousel.getOrCreateInstance(carousel);\n }\n});\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Carousel);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap collapse.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$b = 'collapse';\nconst DATA_KEY$7 = 'bs.collapse';\nconst EVENT_KEY$7 = `.${DATA_KEY$7}`;\nconst DATA_API_KEY$4 = '.data-api';\nconst EVENT_SHOW$6 = `show${EVENT_KEY$7}`;\nconst EVENT_SHOWN$6 = `shown${EVENT_KEY$7}`;\nconst EVENT_HIDE$6 = `hide${EVENT_KEY$7}`;\nconst EVENT_HIDDEN$6 = `hidden${EVENT_KEY$7}`;\nconst EVENT_CLICK_DATA_API$4 = `click${EVENT_KEY$7}${DATA_API_KEY$4}`;\nconst CLASS_NAME_SHOW$7 = 'show';\nconst CLASS_NAME_COLLAPSE = 'collapse';\nconst CLASS_NAME_COLLAPSING = 'collapsing';\nconst CLASS_NAME_COLLAPSED = 'collapsed';\nconst CLASS_NAME_DEEPER_CHILDREN = `:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`;\nconst CLASS_NAME_HORIZONTAL = 'collapse-horizontal';\nconst WIDTH = 'width';\nconst HEIGHT = 'height';\nconst SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing';\nconst SELECTOR_DATA_TOGGLE$4 = '[data-bs-toggle=\"collapse\"]';\nconst Default$a = {\n parent: null,\n toggle: true\n};\nconst DefaultType$a = {\n parent: '(null|element)',\n toggle: 'boolean'\n};\n\n/**\n * Class definition\n */\n\nclass Collapse extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n this._isTransitioning = false;\n this._triggerArray = [];\n const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE$4);\n for (const elem of toggleList) {\n const selector = SelectorEngine.getSelectorFromElement(elem);\n const filterElement = SelectorEngine.find(selector).filter(foundElement => foundElement === this._element);\n if (selector !== null && filterElement.length) {\n this._triggerArray.push(elem);\n }\n }\n this._initializeChildren();\n if (!this._config.parent) {\n this._addAriaAndCollapsedClass(this._triggerArray, this._isShown());\n }\n if (this._config.toggle) {\n this.toggle();\n }\n }\n\n // Getters\n static get Default() {\n return Default$a;\n }\n static get DefaultType() {\n return DefaultType$a;\n }\n static get NAME() {\n return NAME$b;\n }\n\n // Public\n toggle() {\n if (this._isShown()) {\n this.hide();\n } else {\n this.show();\n }\n }\n show() {\n if (this._isTransitioning || this._isShown()) {\n return;\n }\n let activeChildren = [];\n\n // find active children\n if (this._config.parent) {\n activeChildren = this._getFirstLevelChildren(SELECTOR_ACTIVES).filter(element => element !== this._element).map(element => Collapse.getOrCreateInstance(element, {\n toggle: false\n }));\n }\n if (activeChildren.length && activeChildren[0]._isTransitioning) {\n return;\n }\n const startEvent = EventHandler.trigger(this._element, EVENT_SHOW$6);\n if (startEvent.defaultPrevented) {\n return;\n }\n for (const activeInstance of activeChildren) {\n activeInstance.hide();\n }\n const dimension = this._getDimension();\n this._element.classList.remove(CLASS_NAME_COLLAPSE);\n this._element.classList.add(CLASS_NAME_COLLAPSING);\n this._element.style[dimension] = 0;\n this._addAriaAndCollapsedClass(this._triggerArray, true);\n this._isTransitioning = true;\n const complete = () => {\n this._isTransitioning = false;\n this._element.classList.remove(CLASS_NAME_COLLAPSING);\n this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7);\n this._element.style[dimension] = '';\n EventHandler.trigger(this._element, EVENT_SHOWN$6);\n };\n const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);\n const scrollSize = `scroll${capitalizedDimension}`;\n this._queueCallback(complete, this._element, true);\n this._element.style[dimension] = `${this._element[scrollSize]}px`;\n }\n hide() {\n if (this._isTransitioning || !this._isShown()) {\n return;\n }\n const startEvent = EventHandler.trigger(this._element, EVENT_HIDE$6);\n if (startEvent.defaultPrevented) {\n return;\n }\n const dimension = this._getDimension();\n this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`;\n reflow(this._element);\n this._element.classList.add(CLASS_NAME_COLLAPSING);\n this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7);\n for (const trigger of this._triggerArray) {\n const element = SelectorEngine.getElementFromSelector(trigger);\n if (element && !this._isShown(element)) {\n this._addAriaAndCollapsedClass([trigger], false);\n }\n }\n this._isTransitioning = true;\n const complete = () => {\n this._isTransitioning = false;\n this._element.classList.remove(CLASS_NAME_COLLAPSING);\n this._element.classList.add(CLASS_NAME_COLLAPSE);\n EventHandler.trigger(this._element, EVENT_HIDDEN$6);\n };\n this._element.style[dimension] = '';\n this._queueCallback(complete, this._element, true);\n }\n _isShown(element = this._element) {\n return element.classList.contains(CLASS_NAME_SHOW$7);\n }\n\n // Private\n _configAfterMerge(config) {\n config.toggle = Boolean(config.toggle); // Coerce string values\n config.parent = getElement(config.parent);\n return config;\n }\n _getDimension() {\n return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT;\n }\n _initializeChildren() {\n if (!this._config.parent) {\n return;\n }\n const children = this._getFirstLevelChildren(SELECTOR_DATA_TOGGLE$4);\n for (const element of children) {\n const selected = SelectorEngine.getElementFromSelector(element);\n if (selected) {\n this._addAriaAndCollapsedClass([element], this._isShown(selected));\n }\n }\n }\n _getFirstLevelChildren(selector) {\n const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent);\n // remove children if greater depth\n return SelectorEngine.find(selector, this._config.parent).filter(element => !children.includes(element));\n }\n _addAriaAndCollapsedClass(triggerArray, isOpen) {\n if (!triggerArray.length) {\n return;\n }\n for (const element of triggerArray) {\n element.classList.toggle(CLASS_NAME_COLLAPSED, !isOpen);\n element.setAttribute('aria-expanded', isOpen);\n }\n }\n\n // Static\n static jQueryInterface(config) {\n const _config = {};\n if (typeof config === 'string' && /show|hide/.test(config)) {\n _config.toggle = false;\n }\n return this.each(function () {\n const data = Collapse.getOrCreateInstance(this, _config);\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config]();\n }\n });\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$4, SELECTOR_DATA_TOGGLE$4, function (event) {\n // preventDefault only for elements (which change the URL) not inside the collapsible element\n if (event.target.tagName === 'A' || event.delegateTarget && event.delegateTarget.tagName === 'A') {\n event.preventDefault();\n }\n for (const element of SelectorEngine.getMultipleElementsFromSelector(this)) {\n Collapse.getOrCreateInstance(element, {\n toggle: false\n }).toggle();\n }\n});\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Collapse);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap dropdown.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$a = 'dropdown';\nconst DATA_KEY$6 = 'bs.dropdown';\nconst EVENT_KEY$6 = `.${DATA_KEY$6}`;\nconst DATA_API_KEY$3 = '.data-api';\nconst ESCAPE_KEY$2 = 'Escape';\nconst TAB_KEY$1 = 'Tab';\nconst ARROW_UP_KEY$1 = 'ArrowUp';\nconst ARROW_DOWN_KEY$1 = 'ArrowDown';\nconst RIGHT_MOUSE_BUTTON = 2; // MouseEvent.button value for the secondary button, usually the right button\n\nconst EVENT_HIDE$5 = `hide${EVENT_KEY$6}`;\nconst EVENT_HIDDEN$5 = `hidden${EVENT_KEY$6}`;\nconst EVENT_SHOW$5 = `show${EVENT_KEY$6}`;\nconst EVENT_SHOWN$5 = `shown${EVENT_KEY$6}`;\nconst EVENT_CLICK_DATA_API$3 = `click${EVENT_KEY$6}${DATA_API_KEY$3}`;\nconst EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY$6}${DATA_API_KEY$3}`;\nconst EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY$6}${DATA_API_KEY$3}`;\nconst CLASS_NAME_SHOW$6 = 'show';\nconst CLASS_NAME_DROPUP = 'dropup';\nconst CLASS_NAME_DROPEND = 'dropend';\nconst CLASS_NAME_DROPSTART = 'dropstart';\nconst CLASS_NAME_DROPUP_CENTER = 'dropup-center';\nconst CLASS_NAME_DROPDOWN_CENTER = 'dropdown-center';\nconst SELECTOR_DATA_TOGGLE$3 = '[data-bs-toggle=\"dropdown\"]:not(.disabled):not(:disabled)';\nconst SELECTOR_DATA_TOGGLE_SHOWN = `${SELECTOR_DATA_TOGGLE$3}.${CLASS_NAME_SHOW$6}`;\nconst SELECTOR_MENU = '.dropdown-menu';\nconst SELECTOR_NAVBAR = '.navbar';\nconst SELECTOR_NAVBAR_NAV = '.navbar-nav';\nconst SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)';\nconst PLACEMENT_TOP = isRTL() ? 'top-end' : 'top-start';\nconst PLACEMENT_TOPEND = isRTL() ? 'top-start' : 'top-end';\nconst PLACEMENT_BOTTOM = isRTL() ? 'bottom-end' : 'bottom-start';\nconst PLACEMENT_BOTTOMEND = isRTL() ? 'bottom-start' : 'bottom-end';\nconst PLACEMENT_RIGHT = isRTL() ? 'left-start' : 'right-start';\nconst PLACEMENT_LEFT = isRTL() ? 'right-start' : 'left-start';\nconst PLACEMENT_TOPCENTER = 'top';\nconst PLACEMENT_BOTTOMCENTER = 'bottom';\nconst Default$9 = {\n autoClose: true,\n boundary: 'clippingParents',\n display: 'dynamic',\n offset: [0, 2],\n popperConfig: null,\n reference: 'toggle'\n};\nconst DefaultType$9 = {\n autoClose: '(boolean|string)',\n boundary: '(string|element)',\n display: 'string',\n offset: '(array|string|function)',\n popperConfig: '(null|object|function)',\n reference: '(string|element|object)'\n};\n\n/**\n * Class definition\n */\n\nclass Dropdown extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n this._popper = null;\n this._parent = this._element.parentNode; // dropdown wrapper\n // TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/\n this._menu = SelectorEngine.next(this._element, SELECTOR_MENU)[0] || SelectorEngine.prev(this._element, SELECTOR_MENU)[0] || SelectorEngine.findOne(SELECTOR_MENU, this._parent);\n this._inNavbar = this._detectNavbar();\n }\n\n // Getters\n static get Default() {\n return Default$9;\n }\n static get DefaultType() {\n return DefaultType$9;\n }\n static get NAME() {\n return NAME$a;\n }\n\n // Public\n toggle() {\n return this._isShown() ? this.hide() : this.show();\n }\n show() {\n if (isDisabled(this._element) || this._isShown()) {\n return;\n }\n const relatedTarget = {\n relatedTarget: this._element\n };\n const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$5, relatedTarget);\n if (showEvent.defaultPrevented) {\n return;\n }\n this._createPopper();\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement && !this._parent.closest(SELECTOR_NAVBAR_NAV)) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.on(element, 'mouseover', noop);\n }\n }\n this._element.focus();\n this._element.setAttribute('aria-expanded', true);\n this._menu.classList.add(CLASS_NAME_SHOW$6);\n this._element.classList.add(CLASS_NAME_SHOW$6);\n EventHandler.trigger(this._element, EVENT_SHOWN$5, relatedTarget);\n }\n hide() {\n if (isDisabled(this._element) || !this._isShown()) {\n return;\n }\n const relatedTarget = {\n relatedTarget: this._element\n };\n this._completeHide(relatedTarget);\n }\n dispose() {\n if (this._popper) {\n this._popper.destroy();\n }\n super.dispose();\n }\n update() {\n this._inNavbar = this._detectNavbar();\n if (this._popper) {\n this._popper.update();\n }\n }\n\n // Private\n _completeHide(relatedTarget) {\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$5, relatedTarget);\n if (hideEvent.defaultPrevented) {\n return;\n }\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.off(element, 'mouseover', noop);\n }\n }\n if (this._popper) {\n this._popper.destroy();\n }\n this._menu.classList.remove(CLASS_NAME_SHOW$6);\n this._element.classList.remove(CLASS_NAME_SHOW$6);\n this._element.setAttribute('aria-expanded', 'false');\n Manipulator.removeDataAttribute(this._menu, 'popper');\n EventHandler.trigger(this._element, EVENT_HIDDEN$5, relatedTarget);\n }\n _getConfig(config) {\n config = super._getConfig(config);\n if (typeof config.reference === 'object' && !isElement(config.reference) && typeof config.reference.getBoundingClientRect !== 'function') {\n // Popper virtual elements require a getBoundingClientRect method\n throw new TypeError(`${NAME$a.toUpperCase()}: Option \"reference\" provided type \"object\" without a required \"getBoundingClientRect\" method.`);\n }\n return config;\n }\n _createPopper() {\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s dropdowns require Popper (https://popper.js.org)');\n }\n let referenceElement = this._element;\n if (this._config.reference === 'parent') {\n referenceElement = this._parent;\n } else if (isElement(this._config.reference)) {\n referenceElement = getElement(this._config.reference);\n } else if (typeof this._config.reference === 'object') {\n referenceElement = this._config.reference;\n }\n const popperConfig = this._getPopperConfig();\n this._popper = Popper.createPopper(referenceElement, this._menu, popperConfig);\n }\n _isShown() {\n return this._menu.classList.contains(CLASS_NAME_SHOW$6);\n }\n _getPlacement() {\n const parentDropdown = this._parent;\n if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) {\n return PLACEMENT_RIGHT;\n }\n if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) {\n return PLACEMENT_LEFT;\n }\n if (parentDropdown.classList.contains(CLASS_NAME_DROPUP_CENTER)) {\n return PLACEMENT_TOPCENTER;\n }\n if (parentDropdown.classList.contains(CLASS_NAME_DROPDOWN_CENTER)) {\n return PLACEMENT_BOTTOMCENTER;\n }\n\n // We need to trim the value because custom properties can also include spaces\n const isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end';\n if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) {\n return isEnd ? PLACEMENT_TOPEND : PLACEMENT_TOP;\n }\n return isEnd ? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM;\n }\n _detectNavbar() {\n return this._element.closest(SELECTOR_NAVBAR) !== null;\n }\n _getOffset() {\n const {\n offset\n } = this._config;\n if (typeof offset === 'string') {\n return offset.split(',').map(value => Number.parseInt(value, 10));\n }\n if (typeof offset === 'function') {\n return popperData => offset(popperData, this._element);\n }\n return offset;\n }\n _getPopperConfig() {\n const defaultBsPopperConfig = {\n placement: this._getPlacement(),\n modifiers: [{\n name: 'preventOverflow',\n options: {\n boundary: this._config.boundary\n }\n }, {\n name: 'offset',\n options: {\n offset: this._getOffset()\n }\n }]\n };\n\n // Disable Popper if we have a static display or Dropdown is in Navbar\n if (this._inNavbar || this._config.display === 'static') {\n Manipulator.setDataAttribute(this._menu, 'popper', 'static'); // TODO: v6 remove\n defaultBsPopperConfig.modifiers = [{\n name: 'applyStyles',\n enabled: false\n }];\n }\n return {\n ...defaultBsPopperConfig,\n ...execute(this._config.popperConfig, [defaultBsPopperConfig])\n };\n }\n _selectMenuItem({\n key,\n target\n }) {\n const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(element => isVisible(element));\n if (!items.length) {\n return;\n }\n\n // if target isn't included in items (e.g. when expanding the dropdown)\n // allow cycling to get the last item in case key equals ARROW_UP_KEY\n getNextActiveElement(items, target, key === ARROW_DOWN_KEY$1, !items.includes(target)).focus();\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Dropdown.getOrCreateInstance(this, config);\n if (typeof config !== 'string') {\n return;\n }\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config]();\n });\n }\n static clearMenus(event) {\n if (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY$1) {\n return;\n }\n const openToggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE_SHOWN);\n for (const toggle of openToggles) {\n const context = Dropdown.getInstance(toggle);\n if (!context || context._config.autoClose === false) {\n continue;\n }\n const composedPath = event.composedPath();\n const isMenuTarget = composedPath.includes(context._menu);\n if (composedPath.includes(context._element) || context._config.autoClose === 'inside' && !isMenuTarget || context._config.autoClose === 'outside' && isMenuTarget) {\n continue;\n }\n\n // Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu\n if (context._menu.contains(event.target) && (event.type === 'keyup' && event.key === TAB_KEY$1 || /input|select|option|textarea|form/i.test(event.target.tagName))) {\n continue;\n }\n const relatedTarget = {\n relatedTarget: context._element\n };\n if (event.type === 'click') {\n relatedTarget.clickEvent = event;\n }\n context._completeHide(relatedTarget);\n }\n }\n static dataApiKeydownHandler(event) {\n // If not an UP | DOWN | ESCAPE key => not a dropdown command\n // If input/textarea && if key is other than ESCAPE => not a dropdown command\n\n const isInput = /input|textarea/i.test(event.target.tagName);\n const isEscapeEvent = event.key === ESCAPE_KEY$2;\n const isUpOrDownEvent = [ARROW_UP_KEY$1, ARROW_DOWN_KEY$1].includes(event.key);\n if (!isUpOrDownEvent && !isEscapeEvent) {\n return;\n }\n if (isInput && !isEscapeEvent) {\n return;\n }\n event.preventDefault();\n\n // TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/\n const getToggleButton = this.matches(SELECTOR_DATA_TOGGLE$3) ? this : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE$3)[0] || SelectorEngine.next(this, SELECTOR_DATA_TOGGLE$3)[0] || SelectorEngine.findOne(SELECTOR_DATA_TOGGLE$3, event.delegateTarget.parentNode);\n const instance = Dropdown.getOrCreateInstance(getToggleButton);\n if (isUpOrDownEvent) {\n event.stopPropagation();\n instance.show();\n instance._selectMenuItem(event);\n return;\n }\n if (instance._isShown()) {\n // else is escape and we check if it is shown\n event.stopPropagation();\n instance.hide();\n getToggleButton.focus();\n }\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE$3, Dropdown.dataApiKeydownHandler);\nEventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler);\nEventHandler.on(document, EVENT_CLICK_DATA_API$3, Dropdown.clearMenus);\nEventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus);\nEventHandler.on(document, EVENT_CLICK_DATA_API$3, SELECTOR_DATA_TOGGLE$3, function (event) {\n event.preventDefault();\n Dropdown.getOrCreateInstance(this).toggle();\n});\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Dropdown);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/backdrop.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$9 = 'backdrop';\nconst CLASS_NAME_FADE$4 = 'fade';\nconst CLASS_NAME_SHOW$5 = 'show';\nconst EVENT_MOUSEDOWN = `mousedown.bs.${NAME$9}`;\nconst Default$8 = {\n className: 'modal-backdrop',\n clickCallback: null,\n isAnimated: false,\n isVisible: true,\n // if false, we use the backdrop helper without adding any element to the dom\n rootElement: 'body' // give the choice to place backdrop under different elements\n};\n\nconst DefaultType$8 = {\n className: 'string',\n clickCallback: '(function|null)',\n isAnimated: 'boolean',\n isVisible: 'boolean',\n rootElement: '(element|string)'\n};\n\n/**\n * Class definition\n */\n\nclass Backdrop extends Config {\n constructor(config) {\n super();\n this._config = this._getConfig(config);\n this._isAppended = false;\n this._element = null;\n }\n\n // Getters\n static get Default() {\n return Default$8;\n }\n static get DefaultType() {\n return DefaultType$8;\n }\n static get NAME() {\n return NAME$9;\n }\n\n // Public\n show(callback) {\n if (!this._config.isVisible) {\n execute(callback);\n return;\n }\n this._append();\n const element = this._getElement();\n if (this._config.isAnimated) {\n reflow(element);\n }\n element.classList.add(CLASS_NAME_SHOW$5);\n this._emulateAnimation(() => {\n execute(callback);\n });\n }\n hide(callback) {\n if (!this._config.isVisible) {\n execute(callback);\n return;\n }\n this._getElement().classList.remove(CLASS_NAME_SHOW$5);\n this._emulateAnimation(() => {\n this.dispose();\n execute(callback);\n });\n }\n dispose() {\n if (!this._isAppended) {\n return;\n }\n EventHandler.off(this._element, EVENT_MOUSEDOWN);\n this._element.remove();\n this._isAppended = false;\n }\n\n // Private\n _getElement() {\n if (!this._element) {\n const backdrop = document.createElement('div');\n backdrop.className = this._config.className;\n if (this._config.isAnimated) {\n backdrop.classList.add(CLASS_NAME_FADE$4);\n }\n this._element = backdrop;\n }\n return this._element;\n }\n _configAfterMerge(config) {\n // use getElement() with the default \"body\" to get a fresh Element on each instantiation\n config.rootElement = getElement(config.rootElement);\n return config;\n }\n _append() {\n if (this._isAppended) {\n return;\n }\n const element = this._getElement();\n this._config.rootElement.append(element);\n EventHandler.on(element, EVENT_MOUSEDOWN, () => {\n execute(this._config.clickCallback);\n });\n this._isAppended = true;\n }\n _emulateAnimation(callback) {\n executeAfterTransition(callback, this._getElement(), this._config.isAnimated);\n }\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/focustrap.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$8 = 'focustrap';\nconst DATA_KEY$5 = 'bs.focustrap';\nconst EVENT_KEY$5 = `.${DATA_KEY$5}`;\nconst EVENT_FOCUSIN$2 = `focusin${EVENT_KEY$5}`;\nconst EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY$5}`;\nconst TAB_KEY = 'Tab';\nconst TAB_NAV_FORWARD = 'forward';\nconst TAB_NAV_BACKWARD = 'backward';\nconst Default$7 = {\n autofocus: true,\n trapElement: null // The element to trap focus inside of\n};\n\nconst DefaultType$7 = {\n autofocus: 'boolean',\n trapElement: 'element'\n};\n\n/**\n * Class definition\n */\n\nclass FocusTrap extends Config {\n constructor(config) {\n super();\n this._config = this._getConfig(config);\n this._isActive = false;\n this._lastTabNavDirection = null;\n }\n\n // Getters\n static get Default() {\n return Default$7;\n }\n static get DefaultType() {\n return DefaultType$7;\n }\n static get NAME() {\n return NAME$8;\n }\n\n // Public\n activate() {\n if (this._isActive) {\n return;\n }\n if (this._config.autofocus) {\n this._config.trapElement.focus();\n }\n EventHandler.off(document, EVENT_KEY$5); // guard against infinite focus loop\n EventHandler.on(document, EVENT_FOCUSIN$2, event => this._handleFocusin(event));\n EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event));\n this._isActive = true;\n }\n deactivate() {\n if (!this._isActive) {\n return;\n }\n this._isActive = false;\n EventHandler.off(document, EVENT_KEY$5);\n }\n\n // Private\n _handleFocusin(event) {\n const {\n trapElement\n } = this._config;\n if (event.target === document || event.target === trapElement || trapElement.contains(event.target)) {\n return;\n }\n const elements = SelectorEngine.focusableChildren(trapElement);\n if (elements.length === 0) {\n trapElement.focus();\n } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {\n elements[elements.length - 1].focus();\n } else {\n elements[0].focus();\n }\n }\n _handleKeydown(event) {\n if (event.key !== TAB_KEY) {\n return;\n }\n this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD;\n }\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/scrollBar.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';\nconst SELECTOR_STICKY_CONTENT = '.sticky-top';\nconst PROPERTY_PADDING = 'padding-right';\nconst PROPERTY_MARGIN = 'margin-right';\n\n/**\n * Class definition\n */\n\nclass ScrollBarHelper {\n constructor() {\n this._element = document.body;\n }\n\n // Public\n getWidth() {\n // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes\n const documentWidth = document.documentElement.clientWidth;\n return Math.abs(window.innerWidth - documentWidth);\n }\n hide() {\n const width = this.getWidth();\n this._disableOverFlow();\n // give padding to element to balance the hidden scrollbar width\n this._setElementAttributes(this._element, PROPERTY_PADDING, calculatedValue => calculatedValue + width);\n // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth\n this._setElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING, calculatedValue => calculatedValue + width);\n this._setElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN, calculatedValue => calculatedValue - width);\n }\n reset() {\n this._resetElementAttributes(this._element, 'overflow');\n this._resetElementAttributes(this._element, PROPERTY_PADDING);\n this._resetElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING);\n this._resetElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN);\n }\n isOverflowing() {\n return this.getWidth() > 0;\n }\n\n // Private\n _disableOverFlow() {\n this._saveInitialAttribute(this._element, 'overflow');\n this._element.style.overflow = 'hidden';\n }\n _setElementAttributes(selector, styleProperty, callback) {\n const scrollbarWidth = this.getWidth();\n const manipulationCallBack = element => {\n if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {\n return;\n }\n this._saveInitialAttribute(element, styleProperty);\n const calculatedValue = window.getComputedStyle(element).getPropertyValue(styleProperty);\n element.style.setProperty(styleProperty, `${callback(Number.parseFloat(calculatedValue))}px`);\n };\n this._applyManipulationCallback(selector, manipulationCallBack);\n }\n _saveInitialAttribute(element, styleProperty) {\n const actualValue = element.style.getPropertyValue(styleProperty);\n if (actualValue) {\n Manipulator.setDataAttribute(element, styleProperty, actualValue);\n }\n }\n _resetElementAttributes(selector, styleProperty) {\n const manipulationCallBack = element => {\n const value = Manipulator.getDataAttribute(element, styleProperty);\n // We only want to remove the property if the value is `null`; the value can also be zero\n if (value === null) {\n element.style.removeProperty(styleProperty);\n return;\n }\n Manipulator.removeDataAttribute(element, styleProperty);\n element.style.setProperty(styleProperty, value);\n };\n this._applyManipulationCallback(selector, manipulationCallBack);\n }\n _applyManipulationCallback(selector, callBack) {\n if (isElement(selector)) {\n callBack(selector);\n return;\n }\n for (const sel of SelectorEngine.find(selector, this._element)) {\n callBack(sel);\n }\n }\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap modal.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$7 = 'modal';\nconst DATA_KEY$4 = 'bs.modal';\nconst EVENT_KEY$4 = `.${DATA_KEY$4}`;\nconst DATA_API_KEY$2 = '.data-api';\nconst ESCAPE_KEY$1 = 'Escape';\nconst EVENT_HIDE$4 = `hide${EVENT_KEY$4}`;\nconst EVENT_HIDE_PREVENTED$1 = `hidePrevented${EVENT_KEY$4}`;\nconst EVENT_HIDDEN$4 = `hidden${EVENT_KEY$4}`;\nconst EVENT_SHOW$4 = `show${EVENT_KEY$4}`;\nconst EVENT_SHOWN$4 = `shown${EVENT_KEY$4}`;\nconst EVENT_RESIZE$1 = `resize${EVENT_KEY$4}`;\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY$4}`;\nconst EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY$4}`;\nconst EVENT_KEYDOWN_DISMISS$1 = `keydown.dismiss${EVENT_KEY$4}`;\nconst EVENT_CLICK_DATA_API$2 = `click${EVENT_KEY$4}${DATA_API_KEY$2}`;\nconst CLASS_NAME_OPEN = 'modal-open';\nconst CLASS_NAME_FADE$3 = 'fade';\nconst CLASS_NAME_SHOW$4 = 'show';\nconst CLASS_NAME_STATIC = 'modal-static';\nconst OPEN_SELECTOR$1 = '.modal.show';\nconst SELECTOR_DIALOG = '.modal-dialog';\nconst SELECTOR_MODAL_BODY = '.modal-body';\nconst SELECTOR_DATA_TOGGLE$2 = '[data-bs-toggle=\"modal\"]';\nconst Default$6 = {\n backdrop: true,\n focus: true,\n keyboard: true\n};\nconst DefaultType$6 = {\n backdrop: '(boolean|string)',\n focus: 'boolean',\n keyboard: 'boolean'\n};\n\n/**\n * Class definition\n */\n\nclass Modal extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element);\n this._backdrop = this._initializeBackDrop();\n this._focustrap = this._initializeFocusTrap();\n this._isShown = false;\n this._isTransitioning = false;\n this._scrollBar = new ScrollBarHelper();\n this._addEventListeners();\n }\n\n // Getters\n static get Default() {\n return Default$6;\n }\n static get DefaultType() {\n return DefaultType$6;\n }\n static get NAME() {\n return NAME$7;\n }\n\n // Public\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget);\n }\n show(relatedTarget) {\n if (this._isShown || this._isTransitioning) {\n return;\n }\n const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$4, {\n relatedTarget\n });\n if (showEvent.defaultPrevented) {\n return;\n }\n this._isShown = true;\n this._isTransitioning = true;\n this._scrollBar.hide();\n document.body.classList.add(CLASS_NAME_OPEN);\n this._adjustDialog();\n this._backdrop.show(() => this._showElement(relatedTarget));\n }\n hide() {\n if (!this._isShown || this._isTransitioning) {\n return;\n }\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$4);\n if (hideEvent.defaultPrevented) {\n return;\n }\n this._isShown = false;\n this._isTransitioning = true;\n this._focustrap.deactivate();\n this._element.classList.remove(CLASS_NAME_SHOW$4);\n this._queueCallback(() => this._hideModal(), this._element, this._isAnimated());\n }\n dispose() {\n EventHandler.off(window, EVENT_KEY$4);\n EventHandler.off(this._dialog, EVENT_KEY$4);\n this._backdrop.dispose();\n this._focustrap.deactivate();\n super.dispose();\n }\n handleUpdate() {\n this._adjustDialog();\n }\n\n // Private\n _initializeBackDrop() {\n return new Backdrop({\n isVisible: Boolean(this._config.backdrop),\n // 'static' option will be translated to true, and booleans will keep their value,\n isAnimated: this._isAnimated()\n });\n }\n _initializeFocusTrap() {\n return new FocusTrap({\n trapElement: this._element\n });\n }\n _showElement(relatedTarget) {\n // try to append dynamic modal\n if (!document.body.contains(this._element)) {\n document.body.append(this._element);\n }\n this._element.style.display = 'block';\n this._element.removeAttribute('aria-hidden');\n this._element.setAttribute('aria-modal', true);\n this._element.setAttribute('role', 'dialog');\n this._element.scrollTop = 0;\n const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog);\n if (modalBody) {\n modalBody.scrollTop = 0;\n }\n reflow(this._element);\n this._element.classList.add(CLASS_NAME_SHOW$4);\n const transitionComplete = () => {\n if (this._config.focus) {\n this._focustrap.activate();\n }\n this._isTransitioning = false;\n EventHandler.trigger(this._element, EVENT_SHOWN$4, {\n relatedTarget\n });\n };\n this._queueCallback(transitionComplete, this._dialog, this._isAnimated());\n }\n _addEventListeners() {\n EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS$1, event => {\n if (event.key !== ESCAPE_KEY$1) {\n return;\n }\n if (this._config.keyboard) {\n this.hide();\n return;\n }\n this._triggerBackdropTransition();\n });\n EventHandler.on(window, EVENT_RESIZE$1, () => {\n if (this._isShown && !this._isTransitioning) {\n this._adjustDialog();\n }\n });\n EventHandler.on(this._element, EVENT_MOUSEDOWN_DISMISS, event => {\n // a bad trick to segregate clicks that may start inside dialog but end outside, and avoid listen to scrollbar clicks\n EventHandler.one(this._element, EVENT_CLICK_DISMISS, event2 => {\n if (this._element !== event.target || this._element !== event2.target) {\n return;\n }\n if (this._config.backdrop === 'static') {\n this._triggerBackdropTransition();\n return;\n }\n if (this._config.backdrop) {\n this.hide();\n }\n });\n });\n }\n _hideModal() {\n this._element.style.display = 'none';\n this._element.setAttribute('aria-hidden', true);\n this._element.removeAttribute('aria-modal');\n this._element.removeAttribute('role');\n this._isTransitioning = false;\n this._backdrop.hide(() => {\n document.body.classList.remove(CLASS_NAME_OPEN);\n this._resetAdjustments();\n this._scrollBar.reset();\n EventHandler.trigger(this._element, EVENT_HIDDEN$4);\n });\n }\n _isAnimated() {\n return this._element.classList.contains(CLASS_NAME_FADE$3);\n }\n _triggerBackdropTransition() {\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED$1);\n if (hideEvent.defaultPrevented) {\n return;\n }\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;\n const initialOverflowY = this._element.style.overflowY;\n // return if the following background transition hasn't yet completed\n if (initialOverflowY === 'hidden' || this._element.classList.contains(CLASS_NAME_STATIC)) {\n return;\n }\n if (!isModalOverflowing) {\n this._element.style.overflowY = 'hidden';\n }\n this._element.classList.add(CLASS_NAME_STATIC);\n this._queueCallback(() => {\n this._element.classList.remove(CLASS_NAME_STATIC);\n this._queueCallback(() => {\n this._element.style.overflowY = initialOverflowY;\n }, this._dialog);\n }, this._dialog);\n this._element.focus();\n }\n\n /**\n * The following methods are used to handle overflowing modals\n */\n\n _adjustDialog() {\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;\n const scrollbarWidth = this._scrollBar.getWidth();\n const isBodyOverflowing = scrollbarWidth > 0;\n if (isBodyOverflowing && !isModalOverflowing) {\n const property = isRTL() ? 'paddingLeft' : 'paddingRight';\n this._element.style[property] = `${scrollbarWidth}px`;\n }\n if (!isBodyOverflowing && isModalOverflowing) {\n const property = isRTL() ? 'paddingRight' : 'paddingLeft';\n this._element.style[property] = `${scrollbarWidth}px`;\n }\n }\n _resetAdjustments() {\n this._element.style.paddingLeft = '';\n this._element.style.paddingRight = '';\n }\n\n // Static\n static jQueryInterface(config, relatedTarget) {\n return this.each(function () {\n const data = Modal.getOrCreateInstance(this, config);\n if (typeof config !== 'string') {\n return;\n }\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config](relatedTarget);\n });\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$2, SELECTOR_DATA_TOGGLE$2, function (event) {\n const target = SelectorEngine.getElementFromSelector(this);\n if (['A', 'AREA'].includes(this.tagName)) {\n event.preventDefault();\n }\n EventHandler.one(target, EVENT_SHOW$4, showEvent => {\n if (showEvent.defaultPrevented) {\n // only register focus restorer if modal will actually get shown\n return;\n }\n EventHandler.one(target, EVENT_HIDDEN$4, () => {\n if (isVisible(this)) {\n this.focus();\n }\n });\n });\n\n // avoid conflict when clicking modal toggler while another one is open\n const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR$1);\n if (alreadyOpen) {\n Modal.getInstance(alreadyOpen).hide();\n }\n const data = Modal.getOrCreateInstance(target);\n data.toggle(this);\n});\nenableDismissTrigger(Modal);\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Modal);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap offcanvas.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$6 = 'offcanvas';\nconst DATA_KEY$3 = 'bs.offcanvas';\nconst EVENT_KEY$3 = `.${DATA_KEY$3}`;\nconst DATA_API_KEY$1 = '.data-api';\nconst EVENT_LOAD_DATA_API$2 = `load${EVENT_KEY$3}${DATA_API_KEY$1}`;\nconst ESCAPE_KEY = 'Escape';\nconst CLASS_NAME_SHOW$3 = 'show';\nconst CLASS_NAME_SHOWING$1 = 'showing';\nconst CLASS_NAME_HIDING = 'hiding';\nconst CLASS_NAME_BACKDROP = 'offcanvas-backdrop';\nconst OPEN_SELECTOR = '.offcanvas.show';\nconst EVENT_SHOW$3 = `show${EVENT_KEY$3}`;\nconst EVENT_SHOWN$3 = `shown${EVENT_KEY$3}`;\nconst EVENT_HIDE$3 = `hide${EVENT_KEY$3}`;\nconst EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY$3}`;\nconst EVENT_HIDDEN$3 = `hidden${EVENT_KEY$3}`;\nconst EVENT_RESIZE = `resize${EVENT_KEY$3}`;\nconst EVENT_CLICK_DATA_API$1 = `click${EVENT_KEY$3}${DATA_API_KEY$1}`;\nconst EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY$3}`;\nconst SELECTOR_DATA_TOGGLE$1 = '[data-bs-toggle=\"offcanvas\"]';\nconst Default$5 = {\n backdrop: true,\n keyboard: true,\n scroll: false\n};\nconst DefaultType$5 = {\n backdrop: '(boolean|string)',\n keyboard: 'boolean',\n scroll: 'boolean'\n};\n\n/**\n * Class definition\n */\n\nclass Offcanvas extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n this._isShown = false;\n this._backdrop = this._initializeBackDrop();\n this._focustrap = this._initializeFocusTrap();\n this._addEventListeners();\n }\n\n // Getters\n static get Default() {\n return Default$5;\n }\n static get DefaultType() {\n return DefaultType$5;\n }\n static get NAME() {\n return NAME$6;\n }\n\n // Public\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget);\n }\n show(relatedTarget) {\n if (this._isShown) {\n return;\n }\n const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$3, {\n relatedTarget\n });\n if (showEvent.defaultPrevented) {\n return;\n }\n this._isShown = true;\n this._backdrop.show();\n if (!this._config.scroll) {\n new ScrollBarHelper().hide();\n }\n this._element.setAttribute('aria-modal', true);\n this._element.setAttribute('role', 'dialog');\n this._element.classList.add(CLASS_NAME_SHOWING$1);\n const completeCallBack = () => {\n if (!this._config.scroll || this._config.backdrop) {\n this._focustrap.activate();\n }\n this._element.classList.add(CLASS_NAME_SHOW$3);\n this._element.classList.remove(CLASS_NAME_SHOWING$1);\n EventHandler.trigger(this._element, EVENT_SHOWN$3, {\n relatedTarget\n });\n };\n this._queueCallback(completeCallBack, this._element, true);\n }\n hide() {\n if (!this._isShown) {\n return;\n }\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$3);\n if (hideEvent.defaultPrevented) {\n return;\n }\n this._focustrap.deactivate();\n this._element.blur();\n this._isShown = false;\n this._element.classList.add(CLASS_NAME_HIDING);\n this._backdrop.hide();\n const completeCallback = () => {\n this._element.classList.remove(CLASS_NAME_SHOW$3, CLASS_NAME_HIDING);\n this._element.removeAttribute('aria-modal');\n this._element.removeAttribute('role');\n if (!this._config.scroll) {\n new ScrollBarHelper().reset();\n }\n EventHandler.trigger(this._element, EVENT_HIDDEN$3);\n };\n this._queueCallback(completeCallback, this._element, true);\n }\n dispose() {\n this._backdrop.dispose();\n this._focustrap.deactivate();\n super.dispose();\n }\n\n // Private\n _initializeBackDrop() {\n const clickCallback = () => {\n if (this._config.backdrop === 'static') {\n EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);\n return;\n }\n this.hide();\n };\n\n // 'static' option will be translated to true, and booleans will keep their value\n const isVisible = Boolean(this._config.backdrop);\n return new Backdrop({\n className: CLASS_NAME_BACKDROP,\n isVisible,\n isAnimated: true,\n rootElement: this._element.parentNode,\n clickCallback: isVisible ? clickCallback : null\n });\n }\n _initializeFocusTrap() {\n return new FocusTrap({\n trapElement: this._element\n });\n }\n _addEventListeners() {\n EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {\n if (event.key !== ESCAPE_KEY) {\n return;\n }\n if (this._config.keyboard) {\n this.hide();\n return;\n }\n EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);\n });\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Offcanvas.getOrCreateInstance(this, config);\n if (typeof config !== 'string') {\n return;\n }\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config](this);\n });\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$1, SELECTOR_DATA_TOGGLE$1, function (event) {\n const target = SelectorEngine.getElementFromSelector(this);\n if (['A', 'AREA'].includes(this.tagName)) {\n event.preventDefault();\n }\n if (isDisabled(this)) {\n return;\n }\n EventHandler.one(target, EVENT_HIDDEN$3, () => {\n // focus on trigger when it is closed\n if (isVisible(this)) {\n this.focus();\n }\n });\n\n // avoid conflict when clicking a toggler of an offcanvas, while another is open\n const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR);\n if (alreadyOpen && alreadyOpen !== target) {\n Offcanvas.getInstance(alreadyOpen).hide();\n }\n const data = Offcanvas.getOrCreateInstance(target);\n data.toggle(this);\n});\nEventHandler.on(window, EVENT_LOAD_DATA_API$2, () => {\n for (const selector of SelectorEngine.find(OPEN_SELECTOR)) {\n Offcanvas.getOrCreateInstance(selector).show();\n }\n});\nEventHandler.on(window, EVENT_RESIZE, () => {\n for (const element of SelectorEngine.find('[aria-modal][class*=show][class*=offcanvas-]')) {\n if (getComputedStyle(element).position !== 'fixed') {\n Offcanvas.getOrCreateInstance(element).hide();\n }\n }\n});\nenableDismissTrigger(Offcanvas);\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Offcanvas);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/sanitizer.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n// js-docs-start allow-list\nconst ARIA_ATTRIBUTE_PATTERN = /^aria-[\\w-]*$/i;\nconst DefaultAllowlist = {\n // Global attributes allowed on any supplied element below.\n '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],\n a: ['target', 'href', 'title', 'rel'],\n area: [],\n b: [],\n br: [],\n col: [],\n code: [],\n div: [],\n em: [],\n hr: [],\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: [],\n i: [],\n img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],\n li: [],\n ol: [],\n p: [],\n pre: [],\n s: [],\n small: [],\n span: [],\n sub: [],\n sup: [],\n strong: [],\n u: [],\n ul: []\n};\n// js-docs-end allow-list\n\nconst uriAttributes = new Set(['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']);\n\n/**\n * A pattern that recognizes URLs that are safe wrt. XSS in URL navigation\n * contexts.\n *\n * Shout-out to Angular https://github.com/angular/angular/blob/15.2.8/packages/core/src/sanitization/url_sanitizer.ts#L38\n */\n// eslint-disable-next-line unicorn/better-regex\nconst SAFE_URL_PATTERN = /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i;\nconst allowedAttribute = (attribute, allowedAttributeList) => {\n const attributeName = attribute.nodeName.toLowerCase();\n if (allowedAttributeList.includes(attributeName)) {\n if (uriAttributes.has(attributeName)) {\n return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue));\n }\n return true;\n }\n\n // Check if a regular expression validates the attribute.\n return allowedAttributeList.filter(attributeRegex => attributeRegex instanceof RegExp).some(regex => regex.test(attributeName));\n};\nfunction sanitizeHtml(unsafeHtml, allowList, sanitizeFunction) {\n if (!unsafeHtml.length) {\n return unsafeHtml;\n }\n if (sanitizeFunction && typeof sanitizeFunction === 'function') {\n return sanitizeFunction(unsafeHtml);\n }\n const domParser = new window.DOMParser();\n const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');\n const elements = [].concat(...createdDocument.body.querySelectorAll('*'));\n for (const element of elements) {\n const elementName = element.nodeName.toLowerCase();\n if (!Object.keys(allowList).includes(elementName)) {\n element.remove();\n continue;\n }\n const attributeList = [].concat(...element.attributes);\n const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || []);\n for (const attribute of attributeList) {\n if (!allowedAttribute(attribute, allowedAttributes)) {\n element.removeAttribute(attribute.nodeName);\n }\n }\n }\n return createdDocument.body.innerHTML;\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/template-factory.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$5 = 'TemplateFactory';\nconst Default$4 = {\n allowList: DefaultAllowlist,\n content: {},\n // { selector : text , selector2 : text2 , }\n extraClass: '',\n html: false,\n sanitize: true,\n sanitizeFn: null,\n template: '
'\n};\nconst DefaultType$4 = {\n allowList: 'object',\n content: 'object',\n extraClass: '(string|function)',\n html: 'boolean',\n sanitize: 'boolean',\n sanitizeFn: '(null|function)',\n template: 'string'\n};\nconst DefaultContentType = {\n entry: '(string|element|function|null)',\n selector: '(string|element)'\n};\n\n/**\n * Class definition\n */\n\nclass TemplateFactory extends Config {\n constructor(config) {\n super();\n this._config = this._getConfig(config);\n }\n\n // Getters\n static get Default() {\n return Default$4;\n }\n static get DefaultType() {\n return DefaultType$4;\n }\n static get NAME() {\n return NAME$5;\n }\n\n // Public\n getContent() {\n return Object.values(this._config.content).map(config => this._resolvePossibleFunction(config)).filter(Boolean);\n }\n hasContent() {\n return this.getContent().length > 0;\n }\n changeContent(content) {\n this._checkContent(content);\n this._config.content = {\n ...this._config.content,\n ...content\n };\n return this;\n }\n toHtml() {\n const templateWrapper = document.createElement('div');\n templateWrapper.innerHTML = this._maybeSanitize(this._config.template);\n for (const [selector, text] of Object.entries(this._config.content)) {\n this._setContent(templateWrapper, text, selector);\n }\n const template = templateWrapper.children[0];\n const extraClass = this._resolvePossibleFunction(this._config.extraClass);\n if (extraClass) {\n template.classList.add(...extraClass.split(' '));\n }\n return template;\n }\n\n // Private\n _typeCheckConfig(config) {\n super._typeCheckConfig(config);\n this._checkContent(config.content);\n }\n _checkContent(arg) {\n for (const [selector, content] of Object.entries(arg)) {\n super._typeCheckConfig({\n selector,\n entry: content\n }, DefaultContentType);\n }\n }\n _setContent(template, content, selector) {\n const templateElement = SelectorEngine.findOne(selector, template);\n if (!templateElement) {\n return;\n }\n content = this._resolvePossibleFunction(content);\n if (!content) {\n templateElement.remove();\n return;\n }\n if (isElement(content)) {\n this._putElementInTemplate(getElement(content), templateElement);\n return;\n }\n if (this._config.html) {\n templateElement.innerHTML = this._maybeSanitize(content);\n return;\n }\n templateElement.textContent = content;\n }\n _maybeSanitize(arg) {\n return this._config.sanitize ? sanitizeHtml(arg, this._config.allowList, this._config.sanitizeFn) : arg;\n }\n _resolvePossibleFunction(arg) {\n return execute(arg, [this]);\n }\n _putElementInTemplate(element, templateElement) {\n if (this._config.html) {\n templateElement.innerHTML = '';\n templateElement.append(element);\n return;\n }\n templateElement.textContent = element.textContent;\n }\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap tooltip.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$4 = 'tooltip';\nconst DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn']);\nconst CLASS_NAME_FADE$2 = 'fade';\nconst CLASS_NAME_MODAL = 'modal';\nconst CLASS_NAME_SHOW$2 = 'show';\nconst SELECTOR_TOOLTIP_INNER = '.tooltip-inner';\nconst SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`;\nconst EVENT_MODAL_HIDE = 'hide.bs.modal';\nconst TRIGGER_HOVER = 'hover';\nconst TRIGGER_FOCUS = 'focus';\nconst TRIGGER_CLICK = 'click';\nconst TRIGGER_MANUAL = 'manual';\nconst EVENT_HIDE$2 = 'hide';\nconst EVENT_HIDDEN$2 = 'hidden';\nconst EVENT_SHOW$2 = 'show';\nconst EVENT_SHOWN$2 = 'shown';\nconst EVENT_INSERTED = 'inserted';\nconst EVENT_CLICK$1 = 'click';\nconst EVENT_FOCUSIN$1 = 'focusin';\nconst EVENT_FOCUSOUT$1 = 'focusout';\nconst EVENT_MOUSEENTER = 'mouseenter';\nconst EVENT_MOUSELEAVE = 'mouseleave';\nconst AttachmentMap = {\n AUTO: 'auto',\n TOP: 'top',\n RIGHT: isRTL() ? 'left' : 'right',\n BOTTOM: 'bottom',\n LEFT: isRTL() ? 'right' : 'left'\n};\nconst Default$3 = {\n allowList: DefaultAllowlist,\n animation: true,\n boundary: 'clippingParents',\n container: false,\n customClass: '',\n delay: 0,\n fallbackPlacements: ['top', 'right', 'bottom', 'left'],\n html: false,\n offset: [0, 6],\n placement: 'top',\n popperConfig: null,\n sanitize: true,\n sanitizeFn: null,\n selector: false,\n template: '
' + '
' + '
' + '
',\n title: '',\n trigger: 'hover focus'\n};\nconst DefaultType$3 = {\n allowList: 'object',\n animation: 'boolean',\n boundary: '(string|element)',\n container: '(string|element|boolean)',\n customClass: '(string|function)',\n delay: '(number|object)',\n fallbackPlacements: 'array',\n html: 'boolean',\n offset: '(array|string|function)',\n placement: '(string|function)',\n popperConfig: '(null|object|function)',\n sanitize: 'boolean',\n sanitizeFn: '(null|function)',\n selector: '(string|boolean)',\n template: 'string',\n title: '(string|element|function)',\n trigger: 'string'\n};\n\n/**\n * Class definition\n */\n\nclass Tooltip extends BaseComponent {\n constructor(element, config) {\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s tooltips require Popper (https://popper.js.org)');\n }\n super(element, config);\n\n // Private\n this._isEnabled = true;\n this._timeout = 0;\n this._isHovered = null;\n this._activeTrigger = {};\n this._popper = null;\n this._templateFactory = null;\n this._newContent = null;\n\n // Protected\n this.tip = null;\n this._setListeners();\n if (!this._config.selector) {\n this._fixTitle();\n }\n }\n\n // Getters\n static get Default() {\n return Default$3;\n }\n static get DefaultType() {\n return DefaultType$3;\n }\n static get NAME() {\n return NAME$4;\n }\n\n // Public\n enable() {\n this._isEnabled = true;\n }\n disable() {\n this._isEnabled = false;\n }\n toggleEnabled() {\n this._isEnabled = !this._isEnabled;\n }\n toggle() {\n if (!this._isEnabled) {\n return;\n }\n this._activeTrigger.click = !this._activeTrigger.click;\n if (this._isShown()) {\n this._leave();\n return;\n }\n this._enter();\n }\n dispose() {\n clearTimeout(this._timeout);\n EventHandler.off(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler);\n if (this._element.getAttribute('data-bs-original-title')) {\n this._element.setAttribute('title', this._element.getAttribute('data-bs-original-title'));\n }\n this._disposePopper();\n super.dispose();\n }\n show() {\n if (this._element.style.display === 'none') {\n throw new Error('Please use show on visible elements');\n }\n if (!(this._isWithContent() && this._isEnabled)) {\n return;\n }\n const showEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOW$2));\n const shadowRoot = findShadowRoot(this._element);\n const isInTheDom = (shadowRoot || this._element.ownerDocument.documentElement).contains(this._element);\n if (showEvent.defaultPrevented || !isInTheDom) {\n return;\n }\n\n // TODO: v6 remove this or make it optional\n this._disposePopper();\n const tip = this._getTipElement();\n this._element.setAttribute('aria-describedby', tip.getAttribute('id'));\n const {\n container\n } = this._config;\n if (!this._element.ownerDocument.documentElement.contains(this.tip)) {\n container.append(tip);\n EventHandler.trigger(this._element, this.constructor.eventName(EVENT_INSERTED));\n }\n this._popper = this._createPopper(tip);\n tip.classList.add(CLASS_NAME_SHOW$2);\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.on(element, 'mouseover', noop);\n }\n }\n const complete = () => {\n EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOWN$2));\n if (this._isHovered === false) {\n this._leave();\n }\n this._isHovered = false;\n };\n this._queueCallback(complete, this.tip, this._isAnimated());\n }\n hide() {\n if (!this._isShown()) {\n return;\n }\n const hideEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDE$2));\n if (hideEvent.defaultPrevented) {\n return;\n }\n const tip = this._getTipElement();\n tip.classList.remove(CLASS_NAME_SHOW$2);\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.off(element, 'mouseover', noop);\n }\n }\n this._activeTrigger[TRIGGER_CLICK] = false;\n this._activeTrigger[TRIGGER_FOCUS] = false;\n this._activeTrigger[TRIGGER_HOVER] = false;\n this._isHovered = null; // it is a trick to support manual triggering\n\n const complete = () => {\n if (this._isWithActiveTrigger()) {\n return;\n }\n if (!this._isHovered) {\n this._disposePopper();\n }\n this._element.removeAttribute('aria-describedby');\n EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDDEN$2));\n };\n this._queueCallback(complete, this.tip, this._isAnimated());\n }\n update() {\n if (this._popper) {\n this._popper.update();\n }\n }\n\n // Protected\n _isWithContent() {\n return Boolean(this._getTitle());\n }\n _getTipElement() {\n if (!this.tip) {\n this.tip = this._createTipElement(this._newContent || this._getContentForTemplate());\n }\n return this.tip;\n }\n _createTipElement(content) {\n const tip = this._getTemplateFactory(content).toHtml();\n\n // TODO: remove this check in v6\n if (!tip) {\n return null;\n }\n tip.classList.remove(CLASS_NAME_FADE$2, CLASS_NAME_SHOW$2);\n // TODO: v6 the following can be achieved with CSS only\n tip.classList.add(`bs-${this.constructor.NAME}-auto`);\n const tipId = getUID(this.constructor.NAME).toString();\n tip.setAttribute('id', tipId);\n if (this._isAnimated()) {\n tip.classList.add(CLASS_NAME_FADE$2);\n }\n return tip;\n }\n setContent(content) {\n this._newContent = content;\n if (this._isShown()) {\n this._disposePopper();\n this.show();\n }\n }\n _getTemplateFactory(content) {\n if (this._templateFactory) {\n this._templateFactory.changeContent(content);\n } else {\n this._templateFactory = new TemplateFactory({\n ...this._config,\n // the `content` var has to be after `this._config`\n // to override config.content in case of popover\n content,\n extraClass: this._resolvePossibleFunction(this._config.customClass)\n });\n }\n return this._templateFactory;\n }\n _getContentForTemplate() {\n return {\n [SELECTOR_TOOLTIP_INNER]: this._getTitle()\n };\n }\n _getTitle() {\n return this._resolvePossibleFunction(this._config.title) || this._element.getAttribute('data-bs-original-title');\n }\n\n // Private\n _initializeOnDelegatedTarget(event) {\n return this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig());\n }\n _isAnimated() {\n return this._config.animation || this.tip && this.tip.classList.contains(CLASS_NAME_FADE$2);\n }\n _isShown() {\n return this.tip && this.tip.classList.contains(CLASS_NAME_SHOW$2);\n }\n _createPopper(tip) {\n const placement = execute(this._config.placement, [this, tip, this._element]);\n const attachment = AttachmentMap[placement.toUpperCase()];\n return Popper.createPopper(this._element, tip, this._getPopperConfig(attachment));\n }\n _getOffset() {\n const {\n offset\n } = this._config;\n if (typeof offset === 'string') {\n return offset.split(',').map(value => Number.parseInt(value, 10));\n }\n if (typeof offset === 'function') {\n return popperData => offset(popperData, this._element);\n }\n return offset;\n }\n _resolvePossibleFunction(arg) {\n return execute(arg, [this._element]);\n }\n _getPopperConfig(attachment) {\n const defaultBsPopperConfig = {\n placement: attachment,\n modifiers: [{\n name: 'flip',\n options: {\n fallbackPlacements: this._config.fallbackPlacements\n }\n }, {\n name: 'offset',\n options: {\n offset: this._getOffset()\n }\n }, {\n name: 'preventOverflow',\n options: {\n boundary: this._config.boundary\n }\n }, {\n name: 'arrow',\n options: {\n element: `.${this.constructor.NAME}-arrow`\n }\n }, {\n name: 'preSetPlacement',\n enabled: true,\n phase: 'beforeMain',\n fn: data => {\n // Pre-set Popper's placement attribute in order to read the arrow sizes properly.\n // Otherwise, Popper mixes up the width and height dimensions since the initial arrow style is for top placement\n this._getTipElement().setAttribute('data-popper-placement', data.state.placement);\n }\n }]\n };\n return {\n ...defaultBsPopperConfig,\n ...execute(this._config.popperConfig, [defaultBsPopperConfig])\n };\n }\n _setListeners() {\n const triggers = this._config.trigger.split(' ');\n for (const trigger of triggers) {\n if (trigger === 'click') {\n EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK$1), this._config.selector, event => {\n const context = this._initializeOnDelegatedTarget(event);\n context.toggle();\n });\n } else if (trigger !== TRIGGER_MANUAL) {\n const eventIn = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSEENTER) : this.constructor.eventName(EVENT_FOCUSIN$1);\n const eventOut = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSELEAVE) : this.constructor.eventName(EVENT_FOCUSOUT$1);\n EventHandler.on(this._element, eventIn, this._config.selector, event => {\n const context = this._initializeOnDelegatedTarget(event);\n context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true;\n context._enter();\n });\n EventHandler.on(this._element, eventOut, this._config.selector, event => {\n const context = this._initializeOnDelegatedTarget(event);\n context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = context._element.contains(event.relatedTarget);\n context._leave();\n });\n }\n }\n this._hideModalHandler = () => {\n if (this._element) {\n this.hide();\n }\n };\n EventHandler.on(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler);\n }\n _fixTitle() {\n const title = this._element.getAttribute('title');\n if (!title) {\n return;\n }\n if (!this._element.getAttribute('aria-label') && !this._element.textContent.trim()) {\n this._element.setAttribute('aria-label', title);\n }\n this._element.setAttribute('data-bs-original-title', title); // DO NOT USE IT. Is only for backwards compatibility\n this._element.removeAttribute('title');\n }\n _enter() {\n if (this._isShown() || this._isHovered) {\n this._isHovered = true;\n return;\n }\n this._isHovered = true;\n this._setTimeout(() => {\n if (this._isHovered) {\n this.show();\n }\n }, this._config.delay.show);\n }\n _leave() {\n if (this._isWithActiveTrigger()) {\n return;\n }\n this._isHovered = false;\n this._setTimeout(() => {\n if (!this._isHovered) {\n this.hide();\n }\n }, this._config.delay.hide);\n }\n _setTimeout(handler, timeout) {\n clearTimeout(this._timeout);\n this._timeout = setTimeout(handler, timeout);\n }\n _isWithActiveTrigger() {\n return Object.values(this._activeTrigger).includes(true);\n }\n _getConfig(config) {\n const dataAttributes = Manipulator.getDataAttributes(this._element);\n for (const dataAttribute of Object.keys(dataAttributes)) {\n if (DISALLOWED_ATTRIBUTES.has(dataAttribute)) {\n delete dataAttributes[dataAttribute];\n }\n }\n config = {\n ...dataAttributes,\n ...(typeof config === 'object' && config ? config : {})\n };\n config = this._mergeConfigObj(config);\n config = this._configAfterMerge(config);\n this._typeCheckConfig(config);\n return config;\n }\n _configAfterMerge(config) {\n config.container = config.container === false ? document.body : getElement(config.container);\n if (typeof config.delay === 'number') {\n config.delay = {\n show: config.delay,\n hide: config.delay\n };\n }\n if (typeof config.title === 'number') {\n config.title = config.title.toString();\n }\n if (typeof config.content === 'number') {\n config.content = config.content.toString();\n }\n return config;\n }\n _getDelegateConfig() {\n const config = {};\n for (const [key, value] of Object.entries(this._config)) {\n if (this.constructor.Default[key] !== value) {\n config[key] = value;\n }\n }\n config.selector = false;\n config.trigger = 'manual';\n\n // In the future can be replaced with:\n // const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]])\n // `Object.fromEntries(keysWithDifferentValues)`\n return config;\n }\n _disposePopper() {\n if (this._popper) {\n this._popper.destroy();\n this._popper = null;\n }\n if (this.tip) {\n this.tip.remove();\n this.tip = null;\n }\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Tooltip.getOrCreateInstance(this, config);\n if (typeof config !== 'string') {\n return;\n }\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config]();\n });\n }\n}\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Tooltip);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap popover.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$3 = 'popover';\nconst SELECTOR_TITLE = '.popover-header';\nconst SELECTOR_CONTENT = '.popover-body';\nconst Default$2 = {\n ...Tooltip.Default,\n content: '',\n offset: [0, 8],\n placement: 'right',\n template: '
' + '
' + '

' + '
' + '
',\n trigger: 'click'\n};\nconst DefaultType$2 = {\n ...Tooltip.DefaultType,\n content: '(null|string|element|function)'\n};\n\n/**\n * Class definition\n */\n\nclass Popover extends Tooltip {\n // Getters\n static get Default() {\n return Default$2;\n }\n static get DefaultType() {\n return DefaultType$2;\n }\n static get NAME() {\n return NAME$3;\n }\n\n // Overrides\n _isWithContent() {\n return this._getTitle() || this._getContent();\n }\n\n // Private\n _getContentForTemplate() {\n return {\n [SELECTOR_TITLE]: this._getTitle(),\n [SELECTOR_CONTENT]: this._getContent()\n };\n }\n _getContent() {\n return this._resolvePossibleFunction(this._config.content);\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Popover.getOrCreateInstance(this, config);\n if (typeof config !== 'string') {\n return;\n }\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config]();\n });\n }\n}\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Popover);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap scrollspy.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$2 = 'scrollspy';\nconst DATA_KEY$2 = 'bs.scrollspy';\nconst EVENT_KEY$2 = `.${DATA_KEY$2}`;\nconst DATA_API_KEY = '.data-api';\nconst EVENT_ACTIVATE = `activate${EVENT_KEY$2}`;\nconst EVENT_CLICK = `click${EVENT_KEY$2}`;\nconst EVENT_LOAD_DATA_API$1 = `load${EVENT_KEY$2}${DATA_API_KEY}`;\nconst CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item';\nconst CLASS_NAME_ACTIVE$1 = 'active';\nconst SELECTOR_DATA_SPY = '[data-bs-spy=\"scroll\"]';\nconst SELECTOR_TARGET_LINKS = '[href]';\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group';\nconst SELECTOR_NAV_LINKS = '.nav-link';\nconst SELECTOR_NAV_ITEMS = '.nav-item';\nconst SELECTOR_LIST_ITEMS = '.list-group-item';\nconst SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_NAV_ITEMS} > ${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`;\nconst SELECTOR_DROPDOWN = '.dropdown';\nconst SELECTOR_DROPDOWN_TOGGLE$1 = '.dropdown-toggle';\nconst Default$1 = {\n offset: null,\n // TODO: v6 @deprecated, keep it for backwards compatibility reasons\n rootMargin: '0px 0px -25%',\n smoothScroll: false,\n target: null,\n threshold: [0.1, 0.5, 1]\n};\nconst DefaultType$1 = {\n offset: '(number|null)',\n // TODO v6 @deprecated, keep it for backwards compatibility reasons\n rootMargin: 'string',\n smoothScroll: 'boolean',\n target: 'element',\n threshold: 'array'\n};\n\n/**\n * Class definition\n */\n\nclass ScrollSpy extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n\n // this._element is the observablesContainer and config.target the menu links wrapper\n this._targetLinks = new Map();\n this._observableSections = new Map();\n this._rootElement = getComputedStyle(this._element).overflowY === 'visible' ? null : this._element;\n this._activeTarget = null;\n this._observer = null;\n this._previousScrollData = {\n visibleEntryTop: 0,\n parentScrollTop: 0\n };\n this.refresh(); // initialize\n }\n\n // Getters\n static get Default() {\n return Default$1;\n }\n static get DefaultType() {\n return DefaultType$1;\n }\n static get NAME() {\n return NAME$2;\n }\n\n // Public\n refresh() {\n this._initializeTargetsAndObservables();\n this._maybeEnableSmoothScroll();\n if (this._observer) {\n this._observer.disconnect();\n } else {\n this._observer = this._getNewObserver();\n }\n for (const section of this._observableSections.values()) {\n this._observer.observe(section);\n }\n }\n dispose() {\n this._observer.disconnect();\n super.dispose();\n }\n\n // Private\n _configAfterMerge(config) {\n // TODO: on v6 target should be given explicitly & remove the {target: 'ss-target'} case\n config.target = getElement(config.target) || document.body;\n\n // TODO: v6 Only for backwards compatibility reasons. Use rootMargin only\n config.rootMargin = config.offset ? `${config.offset}px 0px -30%` : config.rootMargin;\n if (typeof config.threshold === 'string') {\n config.threshold = config.threshold.split(',').map(value => Number.parseFloat(value));\n }\n return config;\n }\n _maybeEnableSmoothScroll() {\n if (!this._config.smoothScroll) {\n return;\n }\n\n // unregister any previous listeners\n EventHandler.off(this._config.target, EVENT_CLICK);\n EventHandler.on(this._config.target, EVENT_CLICK, SELECTOR_TARGET_LINKS, event => {\n const observableSection = this._observableSections.get(event.target.hash);\n if (observableSection) {\n event.preventDefault();\n const root = this._rootElement || window;\n const height = observableSection.offsetTop - this._element.offsetTop;\n if (root.scrollTo) {\n root.scrollTo({\n top: height,\n behavior: 'smooth'\n });\n return;\n }\n\n // Chrome 60 doesn't support `scrollTo`\n root.scrollTop = height;\n }\n });\n }\n _getNewObserver() {\n const options = {\n root: this._rootElement,\n threshold: this._config.threshold,\n rootMargin: this._config.rootMargin\n };\n return new IntersectionObserver(entries => this._observerCallback(entries), options);\n }\n\n // The logic of selection\n _observerCallback(entries) {\n const targetElement = entry => this._targetLinks.get(`#${entry.target.id}`);\n const activate = entry => {\n this._previousScrollData.visibleEntryTop = entry.target.offsetTop;\n this._process(targetElement(entry));\n };\n const parentScrollTop = (this._rootElement || document.documentElement).scrollTop;\n const userScrollsDown = parentScrollTop >= this._previousScrollData.parentScrollTop;\n this._previousScrollData.parentScrollTop = parentScrollTop;\n for (const entry of entries) {\n if (!entry.isIntersecting) {\n this._activeTarget = null;\n this._clearActiveClass(targetElement(entry));\n continue;\n }\n const entryIsLowerThanPrevious = entry.target.offsetTop >= this._previousScrollData.visibleEntryTop;\n // if we are scrolling down, pick the bigger offsetTop\n if (userScrollsDown && entryIsLowerThanPrevious) {\n activate(entry);\n // if parent isn't scrolled, let's keep the first visible item, breaking the iteration\n if (!parentScrollTop) {\n return;\n }\n continue;\n }\n\n // if we are scrolling up, pick the smallest offsetTop\n if (!userScrollsDown && !entryIsLowerThanPrevious) {\n activate(entry);\n }\n }\n }\n _initializeTargetsAndObservables() {\n this._targetLinks = new Map();\n this._observableSections = new Map();\n const targetLinks = SelectorEngine.find(SELECTOR_TARGET_LINKS, this._config.target);\n for (const anchor of targetLinks) {\n // ensure that the anchor has an id and is not disabled\n if (!anchor.hash || isDisabled(anchor)) {\n continue;\n }\n const observableSection = SelectorEngine.findOne(decodeURI(anchor.hash), this._element);\n\n // ensure that the observableSection exists & is visible\n if (isVisible(observableSection)) {\n this._targetLinks.set(decodeURI(anchor.hash), anchor);\n this._observableSections.set(anchor.hash, observableSection);\n }\n }\n }\n _process(target) {\n if (this._activeTarget === target) {\n return;\n }\n this._clearActiveClass(this._config.target);\n this._activeTarget = target;\n target.classList.add(CLASS_NAME_ACTIVE$1);\n this._activateParents(target);\n EventHandler.trigger(this._element, EVENT_ACTIVATE, {\n relatedTarget: target\n });\n }\n _activateParents(target) {\n // Activate dropdown parents\n if (target.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {\n SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE$1, target.closest(SELECTOR_DROPDOWN)).classList.add(CLASS_NAME_ACTIVE$1);\n return;\n }\n for (const listGroup of SelectorEngine.parents(target, SELECTOR_NAV_LIST_GROUP)) {\n // Set triggered links parents as active\n // With both