From 09b85fbc6cac09ca41eb88e2a115c7dd62eb2149 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Mon, 11 Nov 2024 21:28:37 +0100 Subject: [PATCH 01/49] scaffolding --- leetcode_101/.gitignore | 20 + leetcode_101/README.md | 41 + .../1-1-algorithm-explanation.md | 12 + .../1-2-assignment-problems.md | 5 + .../1-3-interval-problems.md | 5 + .../docs/1-greedy-algorithms/1-4-exercises.md | 5 + .../docs/1-greedy-algorithms/_category_.json | 8 + .../docs/10-data-structures/10-1-cpp-stl.md | 5 + .../10-10-prefix-sum-integral-image.md | 5 + .../10-data-structures/10-11-exercises.md | 5 + .../10-2-python-data-structures.md | 5 + .../docs/10-data-structures/10-3-arrays.md | 5 + .../10-4-stack-and-queue.md | 5 + .../10-5-monotonic-stack.md | 5 + .../10-data-structures/10-6-priority-queue.md | 5 + .../docs/10-data-structures/10-7-deque.md | 5 + .../10-data-structures/10-8-hash-table.md | 5 + .../10-9-multisets-and-maps.md | 5 + .../docs/10-data-structures/_category_.json | 8 + .../11-1-introduction.md | 5 + .../11-2-string-comparison.md | 5 + .../11-3-string-interpretation.md | 5 + .../11-4-string-matching.md | 5 + .../11-string-manipulation/11-5-exercises.md | 5 + .../11-string-manipulation/_category_.json | 8 + .../12-1-data-structure-introduction.md | 5 + .../12-2-basic-linked-list-operations.md | 5 + .../12-3-other-linked-list-techniques.md | 5 + .../docs/12-linked-lists/12-4-exercises.md | 5 + .../docs/12-linked-lists/_category_.json | 8 + .../13-1-data-structure-introduction.md | 5 + .../docs/13-trees/13-2-tree-recursion.md | 5 + .../13-trees/13-3-level-order-traversal.md | 5 + ...-4-preorder-inorder-postorder-traversal.md | 5 + .../docs/13-trees/13-5-binary-search-tree.md | 5 + leetcode_101/docs/13-trees/13-6-trie.md | 5 + leetcode_101/docs/13-trees/13-7-exercises.md | 5 + leetcode_101/docs/13-trees/_category_.json | 8 + .../14-1-data-structure-introduction.md | 5 + .../docs/14-graphs/14-2-bipartite-graph.md | 5 + .../14-graphs/14-3-topological-sorting.md | 5 + leetcode_101/docs/14-graphs/14-4-exercises.md | 5 + leetcode_101/docs/14-graphs/_category_.json | 8 + .../15-1-introduction.md | 5 + .../15-2-union-find.md | 5 + .../15-3-composite-data-structures.md | 5 + .../15-4-exercises.md | 5 + .../_category_.json | 8 + .../2-1-algorithm-explanation.md | 5 + .../2-two-pointer-techniques/2-2-two-sum.md | 5 + .../2-3-merge-sorted-arrays.md | 5 + .../2-4-sliding-window.md | 5 + .../2-5-fast-slow-pointers.md | 5 + .../2-two-pointer-techniques/2-6-exercises.md | 5 + .../2-two-pointer-techniques/_category_.json | 8 + .../3-1-algorithm-explanation.md | 5 + .../3-2-square-root.md | 5 + .../3-3-interval-search.md | 5 + .../3-4-peak-finding.md | 5 + .../3-5-rotated-array-search.md | 5 + .../3-6-exercises.md | 5 + .../_category_.json | 8 + .../4-1-common-sorting-algorithms.md | 5 + .../4-sorting-algorithms/4-2-quick-select.md | 5 + .../4-sorting-algorithms/4-3-bucket-sort.md | 5 + .../4-sorting-algorithms/4-4-exercises.md | 5 + .../docs/4-sorting-algorithms/_category_.json | 8 + .../5-1-algorithm-explanation.md | 5 + .../5-2-depth-first-search.md | 5 + .../5-3-backtracking.md | 5 + .../5-4-breadth-first-search.md | 5 + .../5-searching-algorithms/5-5-exercises.md | 5 + .../5-searching-algorithms/_category_.json | 8 + .../6-1-algorithm-explanation.md | 5 + .../6-dynamic-programming/6-2-basic-dp-1d.md | 5 + .../6-dynamic-programming/6-3-basic-dp-2d.md | 5 + .../6-4-partition-problems.md | 5 + .../6-5-subsequence-problems.md | 5 + .../6-6-knapsack-problem.md | 5 + .../6-7-string-editing.md | 5 + .../6-8-stock-trading.md | 5 + .../6-dynamic-programming/6-9-exercises.md | 5 + .../6-dynamic-programming/_category_.json | 8 + .../7-1-algorithm-explanation.md | 5 + .../7-2-expression-problems.md | 5 + .../7-divide-and-conquer/7-3-exercises.md | 5 + .../docs/7-divide-and-conquer/_category_.json | 8 + .../8-1-introduction.md | 5 + .../8-mathematical-solutions/8-2-lcm-gcd.md | 5 + .../8-3-prime-numbers.md | 5 + .../8-4-number-processing.md | 5 + .../8-5-random-sampling.md | 5 + .../8-mathematical-solutions/8-6-exercises.md | 5 + .../8-mathematical-solutions/_category_.json | 8 + .../9-1-common-techniques.md | 5 + .../9-2-basic-bitwise-problems.md | 5 + .../9-3-binary-properties.md | 5 + .../9-bitwise-operations/9-4-exercises.md | 5 + .../docs/9-bitwise-operations/_category_.json | 8 + leetcode_101/docs/index.md | 50 + leetcode_101/docusaurus.config.ts | 148 + leetcode_101/i18n/en/code.json | 313 + .../current.json | 34 + .../1-greedy-algorithms/_category_.json | 8 + .../current/1-greedy-algorithms/greddy.md | 7 + .../current/index.md | 7 + .../en/docusaurus-theme-classic/footer.json | 42 + .../en/docusaurus-theme-classic/navbar.json | 14 + leetcode_101/i18n/zh-TW/code.json | 313 + .../current.json | 34 + .../1-greedy-algorithms/_category_.json | 8 + .../current/1-greedy-algorithms/greddy.md | 7 + .../current/index.md | 7 + .../docusaurus-theme-classic/footer.json | 42 + .../docusaurus-theme-classic/navbar.json | 14 + leetcode_101/package-lock.json | 16074 ++++++++++++++++ leetcode_101/package.json | 47 + leetcode_101/sidebars.ts | 33 + .../src/components/HomepageFeatures/index.tsx | 70 + .../HomepageFeatures/styles.module.css | 11 + leetcode_101/src/css/custom.css | 30 + leetcode_101/src/pages/index.module.css | 23 + leetcode_101/src/pages/markdown-page.md | 7 + leetcode_101/static/.nojekyll | 0 .../static/img/docusaurus-social-card.jpg | Bin 0 -> 55746 bytes leetcode_101/static/img/docusaurus.png | Bin 0 -> 5142 bytes leetcode_101/static/img/favicon.ico | Bin 0 -> 3626 bytes leetcode_101/static/img/logo.svg | 1 + .../static/img/undraw_docusaurus_mountain.svg | 171 + .../static/img/undraw_docusaurus_react.svg | 170 + .../static/img/undraw_docusaurus_tree.svg | 40 + leetcode_101/tsconfig.json | 7 + 132 files changed, 18330 insertions(+) create mode 100644 leetcode_101/.gitignore create mode 100644 leetcode_101/README.md create mode 100644 leetcode_101/docs/1-greedy-algorithms/1-1-algorithm-explanation.md create mode 100644 leetcode_101/docs/1-greedy-algorithms/1-2-assignment-problems.md create mode 100644 leetcode_101/docs/1-greedy-algorithms/1-3-interval-problems.md create mode 100644 leetcode_101/docs/1-greedy-algorithms/1-4-exercises.md create mode 100644 leetcode_101/docs/1-greedy-algorithms/_category_.json create mode 100644 leetcode_101/docs/10-data-structures/10-1-cpp-stl.md create mode 100644 leetcode_101/docs/10-data-structures/10-10-prefix-sum-integral-image.md create mode 100644 leetcode_101/docs/10-data-structures/10-11-exercises.md create mode 100644 leetcode_101/docs/10-data-structures/10-2-python-data-structures.md create mode 100644 leetcode_101/docs/10-data-structures/10-3-arrays.md create mode 100644 leetcode_101/docs/10-data-structures/10-4-stack-and-queue.md create mode 100644 leetcode_101/docs/10-data-structures/10-5-monotonic-stack.md create mode 100644 leetcode_101/docs/10-data-structures/10-6-priority-queue.md create mode 100644 leetcode_101/docs/10-data-structures/10-7-deque.md create mode 100644 leetcode_101/docs/10-data-structures/10-8-hash-table.md create mode 100644 leetcode_101/docs/10-data-structures/10-9-multisets-and-maps.md create mode 100644 leetcode_101/docs/10-data-structures/_category_.json create mode 100644 leetcode_101/docs/11-string-manipulation/11-1-introduction.md create mode 100644 leetcode_101/docs/11-string-manipulation/11-2-string-comparison.md create mode 100644 leetcode_101/docs/11-string-manipulation/11-3-string-interpretation.md create mode 100644 leetcode_101/docs/11-string-manipulation/11-4-string-matching.md create mode 100644 leetcode_101/docs/11-string-manipulation/11-5-exercises.md create mode 100644 leetcode_101/docs/11-string-manipulation/_category_.json create mode 100644 leetcode_101/docs/12-linked-lists/12-1-data-structure-introduction.md create mode 100644 leetcode_101/docs/12-linked-lists/12-2-basic-linked-list-operations.md create mode 100644 leetcode_101/docs/12-linked-lists/12-3-other-linked-list-techniques.md create mode 100644 leetcode_101/docs/12-linked-lists/12-4-exercises.md create mode 100644 leetcode_101/docs/12-linked-lists/_category_.json create mode 100644 leetcode_101/docs/13-trees/13-1-data-structure-introduction.md create mode 100644 leetcode_101/docs/13-trees/13-2-tree-recursion.md create mode 100644 leetcode_101/docs/13-trees/13-3-level-order-traversal.md create mode 100644 leetcode_101/docs/13-trees/13-4-preorder-inorder-postorder-traversal.md create mode 100644 leetcode_101/docs/13-trees/13-5-binary-search-tree.md create mode 100644 leetcode_101/docs/13-trees/13-6-trie.md create mode 100644 leetcode_101/docs/13-trees/13-7-exercises.md create mode 100644 leetcode_101/docs/13-trees/_category_.json create mode 100644 leetcode_101/docs/14-graphs/14-1-data-structure-introduction.md create mode 100644 leetcode_101/docs/14-graphs/14-2-bipartite-graph.md create mode 100644 leetcode_101/docs/14-graphs/14-3-topological-sorting.md create mode 100644 leetcode_101/docs/14-graphs/14-4-exercises.md create mode 100644 leetcode_101/docs/14-graphs/_category_.json create mode 100644 leetcode_101/docs/15-advanced-data-structures/15-1-introduction.md create mode 100644 leetcode_101/docs/15-advanced-data-structures/15-2-union-find.md create mode 100644 leetcode_101/docs/15-advanced-data-structures/15-3-composite-data-structures.md create mode 100644 leetcode_101/docs/15-advanced-data-structures/15-4-exercises.md create mode 100644 leetcode_101/docs/15-advanced-data-structures/_category_.json create mode 100644 leetcode_101/docs/2-two-pointer-techniques/2-1-algorithm-explanation.md create mode 100644 leetcode_101/docs/2-two-pointer-techniques/2-2-two-sum.md create mode 100644 leetcode_101/docs/2-two-pointer-techniques/2-3-merge-sorted-arrays.md create mode 100644 leetcode_101/docs/2-two-pointer-techniques/2-4-sliding-window.md create mode 100644 leetcode_101/docs/2-two-pointer-techniques/2-5-fast-slow-pointers.md create mode 100644 leetcode_101/docs/2-two-pointer-techniques/2-6-exercises.md create mode 100644 leetcode_101/docs/2-two-pointer-techniques/_category_.json create mode 100644 leetcode_101/docs/3-binary-search-techniques/3-1-algorithm-explanation.md create mode 100644 leetcode_101/docs/3-binary-search-techniques/3-2-square-root.md create mode 100644 leetcode_101/docs/3-binary-search-techniques/3-3-interval-search.md create mode 100644 leetcode_101/docs/3-binary-search-techniques/3-4-peak-finding.md create mode 100644 leetcode_101/docs/3-binary-search-techniques/3-5-rotated-array-search.md create mode 100644 leetcode_101/docs/3-binary-search-techniques/3-6-exercises.md create mode 100644 leetcode_101/docs/3-binary-search-techniques/_category_.json create mode 100644 leetcode_101/docs/4-sorting-algorithms/4-1-common-sorting-algorithms.md create mode 100644 leetcode_101/docs/4-sorting-algorithms/4-2-quick-select.md create mode 100644 leetcode_101/docs/4-sorting-algorithms/4-3-bucket-sort.md create mode 100644 leetcode_101/docs/4-sorting-algorithms/4-4-exercises.md create mode 100644 leetcode_101/docs/4-sorting-algorithms/_category_.json create mode 100644 leetcode_101/docs/5-searching-algorithms/5-1-algorithm-explanation.md create mode 100644 leetcode_101/docs/5-searching-algorithms/5-2-depth-first-search.md create mode 100644 leetcode_101/docs/5-searching-algorithms/5-3-backtracking.md create mode 100644 leetcode_101/docs/5-searching-algorithms/5-4-breadth-first-search.md create mode 100644 leetcode_101/docs/5-searching-algorithms/5-5-exercises.md create mode 100644 leetcode_101/docs/5-searching-algorithms/_category_.json create mode 100644 leetcode_101/docs/6-dynamic-programming/6-1-algorithm-explanation.md create mode 100644 leetcode_101/docs/6-dynamic-programming/6-2-basic-dp-1d.md create mode 100644 leetcode_101/docs/6-dynamic-programming/6-3-basic-dp-2d.md create mode 100644 leetcode_101/docs/6-dynamic-programming/6-4-partition-problems.md create mode 100644 leetcode_101/docs/6-dynamic-programming/6-5-subsequence-problems.md create mode 100644 leetcode_101/docs/6-dynamic-programming/6-6-knapsack-problem.md create mode 100644 leetcode_101/docs/6-dynamic-programming/6-7-string-editing.md create mode 100644 leetcode_101/docs/6-dynamic-programming/6-8-stock-trading.md create mode 100644 leetcode_101/docs/6-dynamic-programming/6-9-exercises.md create mode 100644 leetcode_101/docs/6-dynamic-programming/_category_.json create mode 100644 leetcode_101/docs/7-divide-and-conquer/7-1-algorithm-explanation.md create mode 100644 leetcode_101/docs/7-divide-and-conquer/7-2-expression-problems.md create mode 100644 leetcode_101/docs/7-divide-and-conquer/7-3-exercises.md create mode 100644 leetcode_101/docs/7-divide-and-conquer/_category_.json create mode 100644 leetcode_101/docs/8-mathematical-solutions/8-1-introduction.md create mode 100644 leetcode_101/docs/8-mathematical-solutions/8-2-lcm-gcd.md create mode 100644 leetcode_101/docs/8-mathematical-solutions/8-3-prime-numbers.md create mode 100644 leetcode_101/docs/8-mathematical-solutions/8-4-number-processing.md create mode 100644 leetcode_101/docs/8-mathematical-solutions/8-5-random-sampling.md create mode 100644 leetcode_101/docs/8-mathematical-solutions/8-6-exercises.md create mode 100644 leetcode_101/docs/8-mathematical-solutions/_category_.json create mode 100644 leetcode_101/docs/9-bitwise-operations/9-1-common-techniques.md create mode 100644 leetcode_101/docs/9-bitwise-operations/9-2-basic-bitwise-problems.md create mode 100644 leetcode_101/docs/9-bitwise-operations/9-3-binary-properties.md create mode 100644 leetcode_101/docs/9-bitwise-operations/9-4-exercises.md create mode 100644 leetcode_101/docs/9-bitwise-operations/_category_.json create mode 100644 leetcode_101/docs/index.md create mode 100644 leetcode_101/docusaurus.config.ts create mode 100644 leetcode_101/i18n/en/code.json create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current.json create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/_category_.json create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/greddy.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/index.md create mode 100644 leetcode_101/i18n/en/docusaurus-theme-classic/footer.json create mode 100644 leetcode_101/i18n/en/docusaurus-theme-classic/navbar.json create mode 100644 leetcode_101/i18n/zh-TW/code.json create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current.json create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/_category_.json create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/greddy.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/index.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-theme-classic/footer.json create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-theme-classic/navbar.json create mode 100644 leetcode_101/package-lock.json create mode 100644 leetcode_101/package.json create mode 100644 leetcode_101/sidebars.ts create mode 100644 leetcode_101/src/components/HomepageFeatures/index.tsx create mode 100644 leetcode_101/src/components/HomepageFeatures/styles.module.css create mode 100644 leetcode_101/src/css/custom.css create mode 100644 leetcode_101/src/pages/index.module.css create mode 100644 leetcode_101/src/pages/markdown-page.md create mode 100644 leetcode_101/static/.nojekyll create mode 100644 leetcode_101/static/img/docusaurus-social-card.jpg create mode 100644 leetcode_101/static/img/docusaurus.png create mode 100644 leetcode_101/static/img/favicon.ico create mode 100644 leetcode_101/static/img/logo.svg create mode 100644 leetcode_101/static/img/undraw_docusaurus_mountain.svg create mode 100644 leetcode_101/static/img/undraw_docusaurus_react.svg create mode 100644 leetcode_101/static/img/undraw_docusaurus_tree.svg create mode 100644 leetcode_101/tsconfig.json diff --git a/leetcode_101/.gitignore b/leetcode_101/.gitignore new file mode 100644 index 00000000..b2d6de30 --- /dev/null +++ b/leetcode_101/.gitignore @@ -0,0 +1,20 @@ +# Dependencies +/node_modules + +# Production +/build + +# Generated files +.docusaurus +.cache-loader + +# Misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/leetcode_101/README.md b/leetcode_101/README.md new file mode 100644 index 00000000..0c6c2c27 --- /dev/null +++ b/leetcode_101/README.md @@ -0,0 +1,41 @@ +# Website + +This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator. + +### Installation + +``` +$ yarn +``` + +### Local Development + +``` +$ yarn start +``` + +This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. + +### Build + +``` +$ yarn build +``` + +This command generates static content into the `build` directory and can be served using any static contents hosting service. + +### Deployment + +Using SSH: + +``` +$ USE_SSH=true yarn deploy +``` + +Not using SSH: + +``` +$ GIT_USER= yarn deploy +``` + +If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. diff --git a/leetcode_101/docs/1-greedy-algorithms/1-1-algorithm-explanation.md b/leetcode_101/docs/1-greedy-algorithms/1-1-algorithm-explanation.md new file mode 100644 index 00000000..f524ffd0 --- /dev/null +++ b/leetcode_101/docs/1-greedy-algorithms/1-1-algorithm-explanation.md @@ -0,0 +1,12 @@ +--- +sidebar_position: 1 +--- + +# 1.1 算法解释 + +顾名思义,`贪心算法或贪心思想` (greedy algorithm) 采用贪心的策略,`保证每次操作都是局部最优的`,从而使最后得到的结果是`全局最优的`。 + +举一个最简单的例子:小明和小王喜欢吃苹果,小明可以吃五个,小王可以吃三个。已知苹果园里有吃不完的苹果,求小明和小王一共最多吃多少个苹果。在这个例子中,我们可以选用的贪心策略为,每个人吃自己能吃的最多数量的苹果,这在每个人身上都是局部最优的。又因为全 +局结果是局部结果的简单求和,且局部结果互不相干,因此局部最优的策略同样是全局最优的。 + +证明一道题能用贪心算法解决,有时远比用贪心算法解决该题更复杂。一般情况下,在简单操作后,具有明显的从局部到整体的递推关系,或者可以通过数学归纳法推测结果时,我们才会使用贪心算法。 diff --git a/leetcode_101/docs/1-greedy-algorithms/1-2-assignment-problems.md b/leetcode_101/docs/1-greedy-algorithms/1-2-assignment-problems.md new file mode 100644 index 00000000..c915c37d --- /dev/null +++ b/leetcode_101/docs/1-greedy-algorithms/1-2-assignment-problems.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 2 +--- + +# 1.2 分配问题 diff --git a/leetcode_101/docs/1-greedy-algorithms/1-3-interval-problems.md b/leetcode_101/docs/1-greedy-algorithms/1-3-interval-problems.md new file mode 100644 index 00000000..3ce16f57 --- /dev/null +++ b/leetcode_101/docs/1-greedy-algorithms/1-3-interval-problems.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 3 +--- + +# 1.3 区间问题 diff --git a/leetcode_101/docs/1-greedy-algorithms/1-4-exercises.md b/leetcode_101/docs/1-greedy-algorithms/1-4-exercises.md new file mode 100644 index 00000000..db7a7831 --- /dev/null +++ b/leetcode_101/docs/1-greedy-algorithms/1-4-exercises.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 4 +--- + +# 1.4 练习 diff --git a/leetcode_101/docs/1-greedy-algorithms/_category_.json b/leetcode_101/docs/1-greedy-algorithms/_category_.json new file mode 100644 index 00000000..39fa7a85 --- /dev/null +++ b/leetcode_101/docs/1-greedy-algorithms/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "1. 最易懂的贪心算法", + "position": 1, + "link": { + "type": "generated-index", + "description": "最易懂的贪心算法" + } +} diff --git a/leetcode_101/docs/10-data-structures/10-1-cpp-stl.md b/leetcode_101/docs/10-data-structures/10-1-cpp-stl.md new file mode 100644 index 00000000..5a52eaa5 --- /dev/null +++ b/leetcode_101/docs/10-data-structures/10-1-cpp-stl.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 48 +--- + +# 10.1 C++ STL diff --git a/leetcode_101/docs/10-data-structures/10-10-prefix-sum-integral-image.md b/leetcode_101/docs/10-data-structures/10-10-prefix-sum-integral-image.md new file mode 100644 index 00000000..41c32ba8 --- /dev/null +++ b/leetcode_101/docs/10-data-structures/10-10-prefix-sum-integral-image.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 57 +--- + +# 10.10 前缀和与积分图 diff --git a/leetcode_101/docs/10-data-structures/10-11-exercises.md b/leetcode_101/docs/10-data-structures/10-11-exercises.md new file mode 100644 index 00000000..ee870329 --- /dev/null +++ b/leetcode_101/docs/10-data-structures/10-11-exercises.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 58 +--- + +# 10.11 练习 diff --git a/leetcode_101/docs/10-data-structures/10-2-python-data-structures.md b/leetcode_101/docs/10-data-structures/10-2-python-data-structures.md new file mode 100644 index 00000000..e1b45ecf --- /dev/null +++ b/leetcode_101/docs/10-data-structures/10-2-python-data-structures.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 49 +--- + +# 10.2 Python 常用数据结构 diff --git a/leetcode_101/docs/10-data-structures/10-3-arrays.md b/leetcode_101/docs/10-data-structures/10-3-arrays.md new file mode 100644 index 00000000..a04b6aa2 --- /dev/null +++ b/leetcode_101/docs/10-data-structures/10-3-arrays.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 50 +--- + +# 10.3 数组 diff --git a/leetcode_101/docs/10-data-structures/10-4-stack-and-queue.md b/leetcode_101/docs/10-data-structures/10-4-stack-and-queue.md new file mode 100644 index 00000000..e8803cc1 --- /dev/null +++ b/leetcode_101/docs/10-data-structures/10-4-stack-and-queue.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 51 +--- + +# 10.4 栈和队列 diff --git a/leetcode_101/docs/10-data-structures/10-5-monotonic-stack.md b/leetcode_101/docs/10-data-structures/10-5-monotonic-stack.md new file mode 100644 index 00000000..6956dadf --- /dev/null +++ b/leetcode_101/docs/10-data-structures/10-5-monotonic-stack.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 52 +--- + +# 10.5 单调栈 diff --git a/leetcode_101/docs/10-data-structures/10-6-priority-queue.md b/leetcode_101/docs/10-data-structures/10-6-priority-queue.md new file mode 100644 index 00000000..ee6bc912 --- /dev/null +++ b/leetcode_101/docs/10-data-structures/10-6-priority-queue.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 53 +--- + +# 10.6 优先队列 diff --git a/leetcode_101/docs/10-data-structures/10-7-deque.md b/leetcode_101/docs/10-data-structures/10-7-deque.md new file mode 100644 index 00000000..6ac26532 --- /dev/null +++ b/leetcode_101/docs/10-data-structures/10-7-deque.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 54 +--- + +# 10.7 双端队列 diff --git a/leetcode_101/docs/10-data-structures/10-8-hash-table.md b/leetcode_101/docs/10-data-structures/10-8-hash-table.md new file mode 100644 index 00000000..14afb6b0 --- /dev/null +++ b/leetcode_101/docs/10-data-structures/10-8-hash-table.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 55 +--- + +# 10.8 哈希表 diff --git a/leetcode_101/docs/10-data-structures/10-9-multisets-and-maps.md b/leetcode_101/docs/10-data-structures/10-9-multisets-and-maps.md new file mode 100644 index 00000000..d5c01fe5 --- /dev/null +++ b/leetcode_101/docs/10-data-structures/10-9-multisets-and-maps.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 56 +--- + +# 10.9 多重集合和映射 diff --git a/leetcode_101/docs/10-data-structures/_category_.json b/leetcode_101/docs/10-data-structures/_category_.json new file mode 100644 index 00000000..5a2165d0 --- /dev/null +++ b/leetcode_101/docs/10-data-structures/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "10. 妙用数据结构 ", + "position": 10, + "link": { + "type": "generated-index", + "description": "5 minutes to learn the most important Docusaurus concepts." + } +} diff --git a/leetcode_101/docs/11-string-manipulation/11-1-introduction.md b/leetcode_101/docs/11-string-manipulation/11-1-introduction.md new file mode 100644 index 00000000..3d296da7 --- /dev/null +++ b/leetcode_101/docs/11-string-manipulation/11-1-introduction.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 59 +--- + +# 11.1 引言 diff --git a/leetcode_101/docs/11-string-manipulation/11-2-string-comparison.md b/leetcode_101/docs/11-string-manipulation/11-2-string-comparison.md new file mode 100644 index 00000000..f916db53 --- /dev/null +++ b/leetcode_101/docs/11-string-manipulation/11-2-string-comparison.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 60 +--- + +# 11.2 字符串比较 diff --git a/leetcode_101/docs/11-string-manipulation/11-3-string-interpretation.md b/leetcode_101/docs/11-string-manipulation/11-3-string-interpretation.md new file mode 100644 index 00000000..5db24b00 --- /dev/null +++ b/leetcode_101/docs/11-string-manipulation/11-3-string-interpretation.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 61 +--- + +# 11.3 字符串理解 diff --git a/leetcode_101/docs/11-string-manipulation/11-4-string-matching.md b/leetcode_101/docs/11-string-manipulation/11-4-string-matching.md new file mode 100644 index 00000000..547c3da8 --- /dev/null +++ b/leetcode_101/docs/11-string-manipulation/11-4-string-matching.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 62 +--- + +# 11.4 字符串匹配 diff --git a/leetcode_101/docs/11-string-manipulation/11-5-exercises.md b/leetcode_101/docs/11-string-manipulation/11-5-exercises.md new file mode 100644 index 00000000..48cd7c6b --- /dev/null +++ b/leetcode_101/docs/11-string-manipulation/11-5-exercises.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 63 +--- + +# 11.5 练习 diff --git a/leetcode_101/docs/11-string-manipulation/_category_.json b/leetcode_101/docs/11-string-manipulation/_category_.json new file mode 100644 index 00000000..a2f250df --- /dev/null +++ b/leetcode_101/docs/11-string-manipulation/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "11. 令人头大的字符串 ", + "position": 11, + "link": { + "type": "generated-index", + "description": "5 minutes to learn the most important Docusaurus concepts." + } +} diff --git a/leetcode_101/docs/12-linked-lists/12-1-data-structure-introduction.md b/leetcode_101/docs/12-linked-lists/12-1-data-structure-introduction.md new file mode 100644 index 00000000..a056db25 --- /dev/null +++ b/leetcode_101/docs/12-linked-lists/12-1-data-structure-introduction.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 64 +--- + +# 12.1 数据结构介绍 diff --git a/leetcode_101/docs/12-linked-lists/12-2-basic-linked-list-operations.md b/leetcode_101/docs/12-linked-lists/12-2-basic-linked-list-operations.md new file mode 100644 index 00000000..bf0cf9ad --- /dev/null +++ b/leetcode_101/docs/12-linked-lists/12-2-basic-linked-list-operations.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 65 +--- + +# 12.2 链表的基本操作 diff --git a/leetcode_101/docs/12-linked-lists/12-3-other-linked-list-techniques.md b/leetcode_101/docs/12-linked-lists/12-3-other-linked-list-techniques.md new file mode 100644 index 00000000..fb563c55 --- /dev/null +++ b/leetcode_101/docs/12-linked-lists/12-3-other-linked-list-techniques.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 66 +--- + +# 12.3 其它链表技巧 diff --git a/leetcode_101/docs/12-linked-lists/12-4-exercises.md b/leetcode_101/docs/12-linked-lists/12-4-exercises.md new file mode 100644 index 00000000..717c288a --- /dev/null +++ b/leetcode_101/docs/12-linked-lists/12-4-exercises.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 67 +--- + +# 12.4 练习 diff --git a/leetcode_101/docs/12-linked-lists/_category_.json b/leetcode_101/docs/12-linked-lists/_category_.json new file mode 100644 index 00000000..982d29f5 --- /dev/null +++ b/leetcode_101/docs/12-linked-lists/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "12. 指针三剑客之一:链表", + "position": 2, + "link": { + "type": "generated-index", + "description": "5 minutes to learn the most important Docusaurus concepts." + } +} diff --git a/leetcode_101/docs/13-trees/13-1-data-structure-introduction.md b/leetcode_101/docs/13-trees/13-1-data-structure-introduction.md new file mode 100644 index 00000000..fea5fa67 --- /dev/null +++ b/leetcode_101/docs/13-trees/13-1-data-structure-introduction.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 68 +--- + +# 13.1 数据结构介绍 diff --git a/leetcode_101/docs/13-trees/13-2-tree-recursion.md b/leetcode_101/docs/13-trees/13-2-tree-recursion.md new file mode 100644 index 00000000..0d58455a --- /dev/null +++ b/leetcode_101/docs/13-trees/13-2-tree-recursion.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 69 +--- + +# 13.2 树的递归 diff --git a/leetcode_101/docs/13-trees/13-3-level-order-traversal.md b/leetcode_101/docs/13-trees/13-3-level-order-traversal.md new file mode 100644 index 00000000..8bde635f --- /dev/null +++ b/leetcode_101/docs/13-trees/13-3-level-order-traversal.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 70 +--- + +# 13.3 层次遍历 diff --git a/leetcode_101/docs/13-trees/13-4-preorder-inorder-postorder-traversal.md b/leetcode_101/docs/13-trees/13-4-preorder-inorder-postorder-traversal.md new file mode 100644 index 00000000..59d912e8 --- /dev/null +++ b/leetcode_101/docs/13-trees/13-4-preorder-inorder-postorder-traversal.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 71 +--- + +# 13.4 前中后序遍历 diff --git a/leetcode_101/docs/13-trees/13-5-binary-search-tree.md b/leetcode_101/docs/13-trees/13-5-binary-search-tree.md new file mode 100644 index 00000000..84ebd512 --- /dev/null +++ b/leetcode_101/docs/13-trees/13-5-binary-search-tree.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 72 +--- + +# 13.5 二叉查找树 diff --git a/leetcode_101/docs/13-trees/13-6-trie.md b/leetcode_101/docs/13-trees/13-6-trie.md new file mode 100644 index 00000000..7eeb30e2 --- /dev/null +++ b/leetcode_101/docs/13-trees/13-6-trie.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 73 +--- + +# 13.6 字典树 diff --git a/leetcode_101/docs/13-trees/13-7-exercises.md b/leetcode_101/docs/13-trees/13-7-exercises.md new file mode 100644 index 00000000..b96a6ac6 --- /dev/null +++ b/leetcode_101/docs/13-trees/13-7-exercises.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 74 +--- + +# 13.7 练习 diff --git a/leetcode_101/docs/13-trees/_category_.json b/leetcode_101/docs/13-trees/_category_.json new file mode 100644 index 00000000..a9c87d8a --- /dev/null +++ b/leetcode_101/docs/13-trees/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "13. 指针三剑客之二:树", + "position": 13, + "link": { + "type": "generated-index", + "description": "5 minutes to learn the most important Docusaurus concepts." + } +} diff --git a/leetcode_101/docs/14-graphs/14-1-data-structure-introduction.md b/leetcode_101/docs/14-graphs/14-1-data-structure-introduction.md new file mode 100644 index 00000000..09106d6f --- /dev/null +++ b/leetcode_101/docs/14-graphs/14-1-data-structure-introduction.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 75 +--- + +# 14.1 数据结构介绍 diff --git a/leetcode_101/docs/14-graphs/14-2-bipartite-graph.md b/leetcode_101/docs/14-graphs/14-2-bipartite-graph.md new file mode 100644 index 00000000..54cb3b66 --- /dev/null +++ b/leetcode_101/docs/14-graphs/14-2-bipartite-graph.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 76 +--- + +# 14.2 二分图 diff --git a/leetcode_101/docs/14-graphs/14-3-topological-sorting.md b/leetcode_101/docs/14-graphs/14-3-topological-sorting.md new file mode 100644 index 00000000..24f0ee63 --- /dev/null +++ b/leetcode_101/docs/14-graphs/14-3-topological-sorting.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 77 +--- + +# 14.3 拓扑排序 diff --git a/leetcode_101/docs/14-graphs/14-4-exercises.md b/leetcode_101/docs/14-graphs/14-4-exercises.md new file mode 100644 index 00000000..b507c7b4 --- /dev/null +++ b/leetcode_101/docs/14-graphs/14-4-exercises.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 78 +--- + +# 14.4 练习 diff --git a/leetcode_101/docs/14-graphs/_category_.json b/leetcode_101/docs/14-graphs/_category_.json new file mode 100644 index 00000000..dd9aa608 --- /dev/null +++ b/leetcode_101/docs/14-graphs/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "14. 指针三剑客之三:图", + "position": 14, + "link": { + "type": "generated-index", + "description": "5 minutes to learn the most important Docusaurus concepts." + } +} diff --git a/leetcode_101/docs/15-advanced-data-structures/15-1-introduction.md b/leetcode_101/docs/15-advanced-data-structures/15-1-introduction.md new file mode 100644 index 00000000..63c1d61b --- /dev/null +++ b/leetcode_101/docs/15-advanced-data-structures/15-1-introduction.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 75 +--- + +# 15.1 引言 diff --git a/leetcode_101/docs/15-advanced-data-structures/15-2-union-find.md b/leetcode_101/docs/15-advanced-data-structures/15-2-union-find.md new file mode 100644 index 00000000..3480ed30 --- /dev/null +++ b/leetcode_101/docs/15-advanced-data-structures/15-2-union-find.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 76 +--- + +# 15.2 并查集 diff --git a/leetcode_101/docs/15-advanced-data-structures/15-3-composite-data-structures.md b/leetcode_101/docs/15-advanced-data-structures/15-3-composite-data-structures.md new file mode 100644 index 00000000..5f3a4609 --- /dev/null +++ b/leetcode_101/docs/15-advanced-data-structures/15-3-composite-data-structures.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 77 +--- + +# 15.3 复合数据结构 diff --git a/leetcode_101/docs/15-advanced-data-structures/15-4-exercises.md b/leetcode_101/docs/15-advanced-data-structures/15-4-exercises.md new file mode 100644 index 00000000..9e3ac210 --- /dev/null +++ b/leetcode_101/docs/15-advanced-data-structures/15-4-exercises.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 78 +--- + +# 15.4 练习 diff --git a/leetcode_101/docs/15-advanced-data-structures/_category_.json b/leetcode_101/docs/15-advanced-data-structures/_category_.json new file mode 100644 index 00000000..531df2cd --- /dev/null +++ b/leetcode_101/docs/15-advanced-data-structures/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "15. 更加复杂的数据结构 ", + "position": 15, + "link": { + "type": "generated-index", + "description": "5 minutes to learn the most important Docusaurus concepts." + } +} diff --git a/leetcode_101/docs/2-two-pointer-techniques/2-1-algorithm-explanation.md b/leetcode_101/docs/2-two-pointer-techniques/2-1-algorithm-explanation.md new file mode 100644 index 00000000..8b093962 --- /dev/null +++ b/leetcode_101/docs/2-two-pointer-techniques/2-1-algorithm-explanation.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 5 +--- + +# 2.1 算法解释 diff --git a/leetcode_101/docs/2-two-pointer-techniques/2-2-two-sum.md b/leetcode_101/docs/2-two-pointer-techniques/2-2-two-sum.md new file mode 100644 index 00000000..60a6542c --- /dev/null +++ b/leetcode_101/docs/2-two-pointer-techniques/2-2-two-sum.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 6 +--- + +# 2.2 Two Sum diff --git a/leetcode_101/docs/2-two-pointer-techniques/2-3-merge-sorted-arrays.md b/leetcode_101/docs/2-two-pointer-techniques/2-3-merge-sorted-arrays.md new file mode 100644 index 00000000..2d890bdf --- /dev/null +++ b/leetcode_101/docs/2-two-pointer-techniques/2-3-merge-sorted-arrays.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 7 +--- + +# 2.3 归并两个有序数组 diff --git a/leetcode_101/docs/2-two-pointer-techniques/2-4-sliding-window.md b/leetcode_101/docs/2-two-pointer-techniques/2-4-sliding-window.md new file mode 100644 index 00000000..9fd45f2b --- /dev/null +++ b/leetcode_101/docs/2-two-pointer-techniques/2-4-sliding-window.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 8 +--- + +# 2.4 滑动窗口 diff --git a/leetcode_101/docs/2-two-pointer-techniques/2-5-fast-slow-pointers.md b/leetcode_101/docs/2-two-pointer-techniques/2-5-fast-slow-pointers.md new file mode 100644 index 00000000..6b5e3404 --- /dev/null +++ b/leetcode_101/docs/2-two-pointer-techniques/2-5-fast-slow-pointers.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 9 +--- + +# 2.5 快慢指针 diff --git a/leetcode_101/docs/2-two-pointer-techniques/2-6-exercises.md b/leetcode_101/docs/2-two-pointer-techniques/2-6-exercises.md new file mode 100644 index 00000000..2ed1860c --- /dev/null +++ b/leetcode_101/docs/2-two-pointer-techniques/2-6-exercises.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 10 +--- + +# 2.6 练习 diff --git a/leetcode_101/docs/2-two-pointer-techniques/_category_.json b/leetcode_101/docs/2-two-pointer-techniques/_category_.json new file mode 100644 index 00000000..856cde5b --- /dev/null +++ b/leetcode_101/docs/2-two-pointer-techniques/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "2. 玩转双指针", + "position": 2, + "link": { + "type": "generated-index", + "description": "5 minutes to learn the most important Docusaurus concepts." + } +} diff --git a/leetcode_101/docs/3-binary-search-techniques/3-1-algorithm-explanation.md b/leetcode_101/docs/3-binary-search-techniques/3-1-algorithm-explanation.md new file mode 100644 index 00000000..9f3919b8 --- /dev/null +++ b/leetcode_101/docs/3-binary-search-techniques/3-1-algorithm-explanation.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 11 +--- + +# 3.1 算法解释 diff --git a/leetcode_101/docs/3-binary-search-techniques/3-2-square-root.md b/leetcode_101/docs/3-binary-search-techniques/3-2-square-root.md new file mode 100644 index 00000000..8f394714 --- /dev/null +++ b/leetcode_101/docs/3-binary-search-techniques/3-2-square-root.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 12 +--- + +# 3.2 求开方 diff --git a/leetcode_101/docs/3-binary-search-techniques/3-3-interval-search.md b/leetcode_101/docs/3-binary-search-techniques/3-3-interval-search.md new file mode 100644 index 00000000..05b11d5f --- /dev/null +++ b/leetcode_101/docs/3-binary-search-techniques/3-3-interval-search.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 13 +--- + +# 3.3 查找区间 diff --git a/leetcode_101/docs/3-binary-search-techniques/3-4-peak-finding.md b/leetcode_101/docs/3-binary-search-techniques/3-4-peak-finding.md new file mode 100644 index 00000000..139a99d3 --- /dev/null +++ b/leetcode_101/docs/3-binary-search-techniques/3-4-peak-finding.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 14 +--- + +# 3.4 查找峰值 diff --git a/leetcode_101/docs/3-binary-search-techniques/3-5-rotated-array-search.md b/leetcode_101/docs/3-binary-search-techniques/3-5-rotated-array-search.md new file mode 100644 index 00000000..18413b49 --- /dev/null +++ b/leetcode_101/docs/3-binary-search-techniques/3-5-rotated-array-search.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 15 +--- + +# 3.5 旋转数组查找数字 diff --git a/leetcode_101/docs/3-binary-search-techniques/3-6-exercises.md b/leetcode_101/docs/3-binary-search-techniques/3-6-exercises.md new file mode 100644 index 00000000..d05876c5 --- /dev/null +++ b/leetcode_101/docs/3-binary-search-techniques/3-6-exercises.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 16 +--- + +# 3.6 练习 diff --git a/leetcode_101/docs/3-binary-search-techniques/_category_.json b/leetcode_101/docs/3-binary-search-techniques/_category_.json new file mode 100644 index 00000000..e3e4daa5 --- /dev/null +++ b/leetcode_101/docs/3-binary-search-techniques/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "3. 居合斩!二分查找", + "position": 3, + "link": { + "type": "generated-index", + "description": "5 minutes to learn the most important Docusaurus concepts." + } +} diff --git a/leetcode_101/docs/4-sorting-algorithms/4-1-common-sorting-algorithms.md b/leetcode_101/docs/4-sorting-algorithms/4-1-common-sorting-algorithms.md new file mode 100644 index 00000000..dc8c3741 --- /dev/null +++ b/leetcode_101/docs/4-sorting-algorithms/4-1-common-sorting-algorithms.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 17 +--- + +# 4.1 常用排序算法 diff --git a/leetcode_101/docs/4-sorting-algorithms/4-2-quick-select.md b/leetcode_101/docs/4-sorting-algorithms/4-2-quick-select.md new file mode 100644 index 00000000..92d00bab --- /dev/null +++ b/leetcode_101/docs/4-sorting-algorithms/4-2-quick-select.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 18 +--- + +# 4.2 快速选择 diff --git a/leetcode_101/docs/4-sorting-algorithms/4-3-bucket-sort.md b/leetcode_101/docs/4-sorting-algorithms/4-3-bucket-sort.md new file mode 100644 index 00000000..65cf9814 --- /dev/null +++ b/leetcode_101/docs/4-sorting-algorithms/4-3-bucket-sort.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 19 +--- + +# 4.3 桶排序 diff --git a/leetcode_101/docs/4-sorting-algorithms/4-4-exercises.md b/leetcode_101/docs/4-sorting-algorithms/4-4-exercises.md new file mode 100644 index 00000000..e8aecf4f --- /dev/null +++ b/leetcode_101/docs/4-sorting-algorithms/4-4-exercises.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 20 +--- + +# 4.4 练习 diff --git a/leetcode_101/docs/4-sorting-algorithms/_category_.json b/leetcode_101/docs/4-sorting-algorithms/_category_.json new file mode 100644 index 00000000..3065ccba --- /dev/null +++ b/leetcode_101/docs/4-sorting-algorithms/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "4. 千奇百怪的排序算法", + "position": 4, + "link": { + "type": "generated-index", + "description": "5 minutes to learn the most important Docusaurus concepts." + } +} diff --git a/leetcode_101/docs/5-searching-algorithms/5-1-algorithm-explanation.md b/leetcode_101/docs/5-searching-algorithms/5-1-algorithm-explanation.md new file mode 100644 index 00000000..594616f1 --- /dev/null +++ b/leetcode_101/docs/5-searching-algorithms/5-1-algorithm-explanation.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 21 +--- + +# 5.1 算法解释 diff --git a/leetcode_101/docs/5-searching-algorithms/5-2-depth-first-search.md b/leetcode_101/docs/5-searching-algorithms/5-2-depth-first-search.md new file mode 100644 index 00000000..af6c4914 --- /dev/null +++ b/leetcode_101/docs/5-searching-algorithms/5-2-depth-first-search.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 22 +--- + +# 5.2 深度优先搜索 diff --git a/leetcode_101/docs/5-searching-algorithms/5-3-backtracking.md b/leetcode_101/docs/5-searching-algorithms/5-3-backtracking.md new file mode 100644 index 00000000..5f7dc393 --- /dev/null +++ b/leetcode_101/docs/5-searching-algorithms/5-3-backtracking.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 23 +--- + +# 5.3 回溯法 diff --git a/leetcode_101/docs/5-searching-algorithms/5-4-breadth-first-search.md b/leetcode_101/docs/5-searching-algorithms/5-4-breadth-first-search.md new file mode 100644 index 00000000..7e7f672d --- /dev/null +++ b/leetcode_101/docs/5-searching-algorithms/5-4-breadth-first-search.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 24 +--- + +# 5.4 广度优先搜索 diff --git a/leetcode_101/docs/5-searching-algorithms/5-5-exercises.md b/leetcode_101/docs/5-searching-algorithms/5-5-exercises.md new file mode 100644 index 00000000..0a9bdce0 --- /dev/null +++ b/leetcode_101/docs/5-searching-algorithms/5-5-exercises.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 25 +--- + +# 5.5 练习 diff --git a/leetcode_101/docs/5-searching-algorithms/_category_.json b/leetcode_101/docs/5-searching-algorithms/_category_.json new file mode 100644 index 00000000..ccb8696c --- /dev/null +++ b/leetcode_101/docs/5-searching-algorithms/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "5. 一切皆可搜索", + "position": 5, + "link": { + "type": "generated-index", + "description": "5 minutes to learn the most important Docusaurus concepts." + } +} diff --git a/leetcode_101/docs/6-dynamic-programming/6-1-algorithm-explanation.md b/leetcode_101/docs/6-dynamic-programming/6-1-algorithm-explanation.md new file mode 100644 index 00000000..221ac667 --- /dev/null +++ b/leetcode_101/docs/6-dynamic-programming/6-1-algorithm-explanation.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 26 +--- + +# 6.1 算法解释 diff --git a/leetcode_101/docs/6-dynamic-programming/6-2-basic-dp-1d.md b/leetcode_101/docs/6-dynamic-programming/6-2-basic-dp-1d.md new file mode 100644 index 00000000..fa5059f4 --- /dev/null +++ b/leetcode_101/docs/6-dynamic-programming/6-2-basic-dp-1d.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 27 +--- + +# 6.2 基本动态规划:一维 diff --git a/leetcode_101/docs/6-dynamic-programming/6-3-basic-dp-2d.md b/leetcode_101/docs/6-dynamic-programming/6-3-basic-dp-2d.md new file mode 100644 index 00000000..f8e965f6 --- /dev/null +++ b/leetcode_101/docs/6-dynamic-programming/6-3-basic-dp-2d.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 28 +--- + +# 6.3 基本动态规划:二维 diff --git a/leetcode_101/docs/6-dynamic-programming/6-4-partition-problems.md b/leetcode_101/docs/6-dynamic-programming/6-4-partition-problems.md new file mode 100644 index 00000000..0d35ede6 --- /dev/null +++ b/leetcode_101/docs/6-dynamic-programming/6-4-partition-problems.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 29 +--- + +# 6.4 分割类型题 diff --git a/leetcode_101/docs/6-dynamic-programming/6-5-subsequence-problems.md b/leetcode_101/docs/6-dynamic-programming/6-5-subsequence-problems.md new file mode 100644 index 00000000..8cbb387e --- /dev/null +++ b/leetcode_101/docs/6-dynamic-programming/6-5-subsequence-problems.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 30 +--- + +# 6.5 子序列问题 diff --git a/leetcode_101/docs/6-dynamic-programming/6-6-knapsack-problem.md b/leetcode_101/docs/6-dynamic-programming/6-6-knapsack-problem.md new file mode 100644 index 00000000..e469aeb4 --- /dev/null +++ b/leetcode_101/docs/6-dynamic-programming/6-6-knapsack-problem.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 31 +--- + +# 6.6 背包问题 diff --git a/leetcode_101/docs/6-dynamic-programming/6-7-string-editing.md b/leetcode_101/docs/6-dynamic-programming/6-7-string-editing.md new file mode 100644 index 00000000..b70a7c3c --- /dev/null +++ b/leetcode_101/docs/6-dynamic-programming/6-7-string-editing.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 32 +--- + +# 6.7 字符串编辑 diff --git a/leetcode_101/docs/6-dynamic-programming/6-8-stock-trading.md b/leetcode_101/docs/6-dynamic-programming/6-8-stock-trading.md new file mode 100644 index 00000000..474a73d2 --- /dev/null +++ b/leetcode_101/docs/6-dynamic-programming/6-8-stock-trading.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 33 +--- + +# 6.8 股票交易 diff --git a/leetcode_101/docs/6-dynamic-programming/6-9-exercises.md b/leetcode_101/docs/6-dynamic-programming/6-9-exercises.md new file mode 100644 index 00000000..e279ca9d --- /dev/null +++ b/leetcode_101/docs/6-dynamic-programming/6-9-exercises.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 34 +--- + +# 6.9 练习 diff --git a/leetcode_101/docs/6-dynamic-programming/_category_.json b/leetcode_101/docs/6-dynamic-programming/_category_.json new file mode 100644 index 00000000..a7dc93eb --- /dev/null +++ b/leetcode_101/docs/6-dynamic-programming/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "6. 深入浅出动态规划", + "position": 6, + "link": { + "type": "generated-index", + "description": "5 minutes to learn the most important Docusaurus concepts." + } +} diff --git a/leetcode_101/docs/7-divide-and-conquer/7-1-algorithm-explanation.md b/leetcode_101/docs/7-divide-and-conquer/7-1-algorithm-explanation.md new file mode 100644 index 00000000..770e8d78 --- /dev/null +++ b/leetcode_101/docs/7-divide-and-conquer/7-1-algorithm-explanation.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 35 +--- + +# 7.1 算法解释 diff --git a/leetcode_101/docs/7-divide-and-conquer/7-2-expression-problems.md b/leetcode_101/docs/7-divide-and-conquer/7-2-expression-problems.md new file mode 100644 index 00000000..78ebe320 --- /dev/null +++ b/leetcode_101/docs/7-divide-and-conquer/7-2-expression-problems.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 36 +--- + +# 7.2 表达式问题 diff --git a/leetcode_101/docs/7-divide-and-conquer/7-3-exercises.md b/leetcode_101/docs/7-divide-and-conquer/7-3-exercises.md new file mode 100644 index 00000000..62624b22 --- /dev/null +++ b/leetcode_101/docs/7-divide-and-conquer/7-3-exercises.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 37 +--- + +# 7.3 练习 diff --git a/leetcode_101/docs/7-divide-and-conquer/_category_.json b/leetcode_101/docs/7-divide-and-conquer/_category_.json new file mode 100644 index 00000000..f24bf92c --- /dev/null +++ b/leetcode_101/docs/7-divide-and-conquer/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "7. 化繁为简的分治法", + "position": 7, + "link": { + "type": "generated-index", + "description": "5 minutes to learn the most important Docusaurus concepts." + } +} diff --git a/leetcode_101/docs/8-mathematical-solutions/8-1-introduction.md b/leetcode_101/docs/8-mathematical-solutions/8-1-introduction.md new file mode 100644 index 00000000..108afbcf --- /dev/null +++ b/leetcode_101/docs/8-mathematical-solutions/8-1-introduction.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 38 +--- + +# 8.1 引言 diff --git a/leetcode_101/docs/8-mathematical-solutions/8-2-lcm-gcd.md b/leetcode_101/docs/8-mathematical-solutions/8-2-lcm-gcd.md new file mode 100644 index 00000000..5bbdc1a7 --- /dev/null +++ b/leetcode_101/docs/8-mathematical-solutions/8-2-lcm-gcd.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 39 +--- + +# 8.2 公倍数与公因数 diff --git a/leetcode_101/docs/8-mathematical-solutions/8-3-prime-numbers.md b/leetcode_101/docs/8-mathematical-solutions/8-3-prime-numbers.md new file mode 100644 index 00000000..4347ee4f --- /dev/null +++ b/leetcode_101/docs/8-mathematical-solutions/8-3-prime-numbers.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 40 +--- + +# 8.3 质数 diff --git a/leetcode_101/docs/8-mathematical-solutions/8-4-number-processing.md b/leetcode_101/docs/8-mathematical-solutions/8-4-number-processing.md new file mode 100644 index 00000000..1248062e --- /dev/null +++ b/leetcode_101/docs/8-mathematical-solutions/8-4-number-processing.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 41 +--- + +# 8.4 数字处理 diff --git a/leetcode_101/docs/8-mathematical-solutions/8-5-random-sampling.md b/leetcode_101/docs/8-mathematical-solutions/8-5-random-sampling.md new file mode 100644 index 00000000..e850b084 --- /dev/null +++ b/leetcode_101/docs/8-mathematical-solutions/8-5-random-sampling.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 42 +--- + +# 8.5 随机与取样 diff --git a/leetcode_101/docs/8-mathematical-solutions/8-6-exercises.md b/leetcode_101/docs/8-mathematical-solutions/8-6-exercises.md new file mode 100644 index 00000000..e7069897 --- /dev/null +++ b/leetcode_101/docs/8-mathematical-solutions/8-6-exercises.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 43 +--- + +# 8.6 练习 diff --git a/leetcode_101/docs/8-mathematical-solutions/_category_.json b/leetcode_101/docs/8-mathematical-solutions/_category_.json new file mode 100644 index 00000000..e366176e --- /dev/null +++ b/leetcode_101/docs/8-mathematical-solutions/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "8. 巧解数学问题 ", + "position": 8, + "link": { + "type": "generated-index", + "description": "5 minutes to learn the most important Docusaurus concepts." + } +} diff --git a/leetcode_101/docs/9-bitwise-operations/9-1-common-techniques.md b/leetcode_101/docs/9-bitwise-operations/9-1-common-techniques.md new file mode 100644 index 00000000..8cd22e0e --- /dev/null +++ b/leetcode_101/docs/9-bitwise-operations/9-1-common-techniques.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 44 +--- + +# 9.1 常用技巧 diff --git a/leetcode_101/docs/9-bitwise-operations/9-2-basic-bitwise-problems.md b/leetcode_101/docs/9-bitwise-operations/9-2-basic-bitwise-problems.md new file mode 100644 index 00000000..9ac4630e --- /dev/null +++ b/leetcode_101/docs/9-bitwise-operations/9-2-basic-bitwise-problems.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 45 +--- + +# 9.2 位运算基础问题 diff --git a/leetcode_101/docs/9-bitwise-operations/9-3-binary-properties.md b/leetcode_101/docs/9-bitwise-operations/9-3-binary-properties.md new file mode 100644 index 00000000..823ef77b --- /dev/null +++ b/leetcode_101/docs/9-bitwise-operations/9-3-binary-properties.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 46 +--- + +# 9.3 二进制特性 diff --git a/leetcode_101/docs/9-bitwise-operations/9-4-exercises.md b/leetcode_101/docs/9-bitwise-operations/9-4-exercises.md new file mode 100644 index 00000000..704d4fdb --- /dev/null +++ b/leetcode_101/docs/9-bitwise-operations/9-4-exercises.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 47 +--- + +# 9.4 练习 diff --git a/leetcode_101/docs/9-bitwise-operations/_category_.json b/leetcode_101/docs/9-bitwise-operations/_category_.json new file mode 100644 index 00000000..9b1495a0 --- /dev/null +++ b/leetcode_101/docs/9-bitwise-operations/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "9. 神奇的位运算 ", + "position": 9, + "link": { + "type": "generated-index", + "description": "5 minutes to learn the most important Docusaurus concepts." + } +} diff --git a/leetcode_101/docs/index.md b/leetcode_101/docs/index.md new file mode 100644 index 00000000..4acbcaa1 --- /dev/null +++ b/leetcode_101/docs/index.md @@ -0,0 +1,50 @@ +--- +sidebar_position: 0 +--- + +# 0. LeetCode 101: 力扣刷题指南 (第二版) + +作者:高畅 Chang Gao + +语言:C++ & Python + +版本:正式版 2.0c,最新版见 GitHub [changgyhub/leetcode_101](https://github.com/changgyhub/leetcode_101) + +:::info +一个面向有一定的编程基础,但缺乏刷题经验的读者的教科书和工具书。 +::: + +## 序 + +2019 年底,本书第一版在 GitHub 上正式发布,反响十分热烈。过去的五年,作者积累了大量的工作经验,同时也越来越觉得这本书存在很多纰漏和不完善之处。于是在 2024 年底,作者重新整理了本书的内容,发布了第二版。 + +本书分为算法、数学和数据结构三大部分,包含十五个章节,详细讲解了刷 LeetCode 时常用的技巧。在第一版时,为了强行呼应 "101"(在英文里是入门的意思),作者把题目精简到了 101 道。但现如今面试中可能考察的题型越来越多,所以第二版增加了一些重点题目,方便读者查漏补缺。选题时作者尽量兼顾题目在面试中可能出现的频率、易学性和泛用性。每个章节之后都附带了练习题,作者十分推荐读者在学习完每个章节之后使用这些练习题巩固理解。 + +本书所有常规题目均附有 C++ 和 Python3 题解。由于本书的目的不是学习 C++ 和 Python 语言,作者在行文时不会过多解释语法细节,而且会适当使用一些新 C++ 标准的语法和 Pythonic code。截止 2024 年底,所有的书内代码在 LeetCode 上都是可以正常运行的,并且在保持易读的基础上,几乎都是最快或最省空间的解法。 + +请谨记,刷题只是提高面试乃至工作能力的一小部分。在计算机科学的海洋里,值得探索的东西太多,并不建议您花过多时间刷题。并且要成为一个优秀的计算机科学家,刷题只是入职的敲门砖,提高各种专业技能、打好专业基础、以及了解最新的专业方向或许更加重要。 + +本书是作者本人于闲余时间完成的,可能会有不少纰漏,部分题目的解释可能也存在不详细或者不清楚的情况。欢迎在 GitHub 提 issue 指正,作者会将您加入鸣谢名单(见后记)。另外,如果您有任何建议和咨询,欢迎前往作者的个人网站联系作者。如果需要私信,请通过邮箱或领英发送消息,作者会尽快回复。 + +感谢 GitHub 用户 CyC2018 的 LeetCode 题解,它对于作者早期的整理起到了很大的帮助作用。感谢 ElegantBook 提供的精美 LATEX 模版,使得作者可以轻松地把笔记变成看起来更专业的电子书。另外,第二版书的封面图片是作者于 2024 年 7 月,在旧金山金门大桥北的 Sausalito 小镇海边拍摄。当时还买了一筒三球超大份冰淇淋,可惜实在是太甜了,吃了几口实在是吃不下去,只能扔掉。 + +如果您觉得这本书对您有帮助,不妨打赏一下作者哟! + + + +## 重要声明 + +本书 GitHub 地址:[github.com/changgyhub/leetcode_101](https://github.com/changgyhub/leetcode_101) + +由于本书的目的是分享和教学,本书永久免费,也禁止任何营利性利用。欢迎以学术为目的的分享和传阅。由于作者不对 LeetCode 的任何题目拥有版权,一切题目版权以 LeetCode 官方为准,且本书不会展示 LeetCode 付费会员专享题目的内容或相关代码。 + +## 简介 + +打开 LeetCode 网站,如果我们按照题目类型数量分类,最多的几个题型包括数组、动态规划、数学、字符串、树、哈希表、深度优先搜索、二分查找、贪心算法、广度优先搜索、双指针等等。本书将包括上述题型以及网站上绝大多数流行的题型,在按照类型进行分类的同时,也按 +照难易程度进行由浅入深的讲解。 + +第一个大分类是算法。本书先从最简单的贪心算法讲起,然后逐渐进阶到双指针、二分查找、排序算法和搜索算法,最后是难度比较高的动态规划和分治算法。 + +第二个大分类是数学,包括偏向纯数学的数学问题,和偏向计算机知识的位运算问题。这类问题通常用来测试你是否聪敏,实际工作中并不常用,笔者建议可以优先把精力放在其它大类。 + +第三个大分类是数据结构,包括 C++ STL、Python3 自带的数据结构、字符串处理、链表、树和图。其中,链表、树、和图都是用指针表示的数据结构,且前者是后者的子集。最后我们也将介绍一些更加复杂的数据结构,比如经典的并查集和 LRU。 diff --git a/leetcode_101/docusaurus.config.ts b/leetcode_101/docusaurus.config.ts new file mode 100644 index 00000000..6c5f4812 --- /dev/null +++ b/leetcode_101/docusaurus.config.ts @@ -0,0 +1,148 @@ +import { themes as prismThemes } from "prism-react-renderer"; +import type { Config } from "@docusaurus/types"; +import type * as Preset from "@docusaurus/preset-classic"; + +// This runs in Node.js - Don't use client-side code here (browser APIs, JSX...) + +const config: Config = { + title: "LeetCode 101 - A Grinding Guide", + tagline: "LeetCode", + favicon: "img/favicon.ico", + + // Set the production url of your site here + url: "https://your-docusaurus-site.example.com", + // Set the // pathname under which your site is served + // For GitHub pages deployment, it is often '//' + baseUrl: "/", + + // GitHub pages deployment config. + // If you aren't using GitHub pages, you don't need these. + organizationName: "facebook", // Usually your GitHub org/user name. + projectName: "docusaurus", // Usually your repo name. + + onBrokenLinks: "throw", + onBrokenMarkdownLinks: "warn", + + // Even if you don't use internationalization, you can use this field to set + // useful metadata like html lang. For example, if your site is Chinese, you + // may want to replace "en" with "zh-Hans". + i18n: { + defaultLocale: "zh-CN", + locales: ["en", "zh-TW", "zh-CN"], + localeConfigs: { + en: { + label: "English", + }, + "zh-TW": { + label: "繁體中文", + }, + "zh-CN": { + label: "简体中文", + }, + }, + }, + + presets: [ + [ + "classic", + { + docs: { + routeBasePath: "/", + sidebarPath: "./sidebars.ts", + // Please change this to your repo. + // Remove this to remove the "edit this page" links. + editUrl: "https://github.com/noworneverev/leetcode_101", + }, + blog: false, + theme: { + customCss: "./src/css/custom.css", + }, + } satisfies Preset.Options, + ], + ], + + themeConfig: { + docs: { + sidebar: { + hideable: true, + }, + }, + // Replace with your project's social card + image: "img/docusaurus-social-card.jpg", + navbar: { + title: "LeetCode 101 - A Grinding Guide", + logo: { + alt: "My Site Logo", + src: "img/logo.svg", + }, + items: [ + // { + // type: "docSidebar", + // sidebarId: "tutorialSidebar", + // position: "left", + // label: "Tutorial", + // }, + { + type: "localeDropdown", + position: "right", + }, + { + href: "https://github.com/changgyhub/leetcode_101", + label: "GitHub", + position: "right", + }, + ], + }, + footer: { + style: "dark", + // links: [ + // { + // title: "Docs", + // items: [ + // { + // label: "Tutorial", + // to: "/docs/intro", + // }, + // ], + // }, + // { + // title: "Community", + // items: [ + // { + // label: "Stack Overflow", + // href: "https://stackoverflow.com/questions/tagged/docusaurus", + // }, + // { + // label: "Discord", + // href: "https://discordapp.com/invite/docusaurus", + // }, + // { + // label: "X", + // href: "https://x.com/docusaurus", + // }, + // ], + // }, + // { + // title: "More", + // items: [ + // { + // label: "Blog", + // to: "/blog", + // }, + // { + // label: "GitHub", + // href: "https://github.com/facebook/docusaurus", + // }, + // ], + // }, + // ], + copyright: `Copyright © ${new Date().getFullYear()} My Project, Inc. Built with Docusaurus.`, + }, + prism: { + theme: prismThemes.github, + darkTheme: prismThemes.dracula, + }, + } satisfies Preset.ThemeConfig, +}; + +export default config; diff --git a/leetcode_101/i18n/en/code.json b/leetcode_101/i18n/en/code.json new file mode 100644 index 00000000..a6d25b92 --- /dev/null +++ b/leetcode_101/i18n/en/code.json @@ -0,0 +1,313 @@ +{ + "theme.ErrorPageContent.title": { + "message": "This page crashed.", + "description": "The title of the fallback page when the page crashed" + }, + "theme.BackToTopButton.buttonAriaLabel": { + "message": "Scroll back to top", + "description": "The ARIA label for the back to top button" + }, + "theme.blog.archive.title": { + "message": "Archive", + "description": "The page & hero title of the blog archive page" + }, + "theme.blog.archive.description": { + "message": "Archive", + "description": "The page & hero description of the blog archive page" + }, + "theme.blog.paginator.navAriaLabel": { + "message": "Blog list page navigation", + "description": "The ARIA label for the blog pagination" + }, + "theme.blog.paginator.newerEntries": { + "message": "Newer entries", + "description": "The label used to navigate to the newer blog posts page (previous page)" + }, + "theme.blog.paginator.olderEntries": { + "message": "Older entries", + "description": "The label used to navigate to the older blog posts page (next page)" + }, + "theme.blog.post.paginator.navAriaLabel": { + "message": "Blog post page navigation", + "description": "The ARIA label for the blog posts pagination" + }, + "theme.blog.post.paginator.newerPost": { + "message": "Newer post", + "description": "The blog post button label to navigate to the newer/previous post" + }, + "theme.blog.post.paginator.olderPost": { + "message": "Older post", + "description": "The blog post button label to navigate to the older/next post" + }, + "theme.tags.tagsPageLink": { + "message": "View all tags", + "description": "The label of the link targeting the tag list page" + }, + "theme.colorToggle.ariaLabel": { + "message": "Switch between dark and light mode (currently {mode})", + "description": "The ARIA label for the navbar color mode toggle" + }, + "theme.colorToggle.ariaLabel.mode.dark": { + "message": "dark mode", + "description": "The name for the dark color mode" + }, + "theme.colorToggle.ariaLabel.mode.light": { + "message": "light mode", + "description": "The name for the light color mode" + }, + "theme.docs.breadcrumbs.navAriaLabel": { + "message": "Breadcrumbs", + "description": "The ARIA label for the breadcrumbs" + }, + "theme.docs.DocCard.categoryDescription.plurals": { + "message": "1 item|{count} items", + "description": "The default description for a category card in the generated index about how many items this category includes" + }, + "theme.docs.paginator.navAriaLabel": { + "message": "Docs pages", + "description": "The ARIA label for the docs pagination" + }, + "theme.docs.paginator.previous": { + "message": "Previous", + "description": "The label used to navigate to the previous doc" + }, + "theme.docs.paginator.next": { + "message": "Next", + "description": "The label used to navigate to the next doc" + }, + "theme.docs.tagDocListPageTitle.nDocsTagged": { + "message": "One doc tagged|{count} docs tagged", + "description": "Pluralized label for \"{count} docs tagged\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)" + }, + "theme.docs.tagDocListPageTitle": { + "message": "{nDocsTagged} with \"{tagName}\"", + "description": "The title of the page for a docs tag" + }, + "theme.docs.versionBadge.label": { + "message": "Version: {versionLabel}" + }, + "theme.docs.versions.unreleasedVersionLabel": { + "message": "This is unreleased documentation for {siteTitle} {versionLabel} version.", + "description": "The label used to tell the user that he's browsing an unreleased doc version" + }, + "theme.docs.versions.unmaintainedVersionLabel": { + "message": "This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained.", + "description": "The label used to tell the user that he's browsing an unmaintained doc version" + }, + "theme.docs.versions.latestVersionSuggestionLabel": { + "message": "For up-to-date documentation, see the {latestVersionLink} ({versionLabel}).", + "description": "The label used to tell the user to check the latest version" + }, + "theme.docs.versions.latestVersionLinkLabel": { + "message": "latest version", + "description": "The label used for the latest version suggestion link label" + }, + "theme.common.editThisPage": { + "message": "Edit this page", + "description": "The link label to edit the current page" + }, + "theme.common.headingLinkTitle": { + "message": "Direct link to {heading}", + "description": "Title for link to heading" + }, + "theme.lastUpdated.atDate": { + "message": " on {date}", + "description": "The words used to describe on which date a page has been last updated" + }, + "theme.lastUpdated.byUser": { + "message": " by {user}", + "description": "The words used to describe by who the page has been last updated" + }, + "theme.lastUpdated.lastUpdatedAtBy": { + "message": "Last updated{atDate}{byUser}", + "description": "The sentence used to display when a page has been last updated, and by who" + }, + "theme.navbar.mobileVersionsDropdown.label": { + "message": "Versions", + "description": "The label for the navbar versions dropdown on mobile view" + }, + "theme.NotFound.title": { + "message": "Page Not Found", + "description": "The title of the 404 page" + }, + "theme.tags.tagsListLabel": { + "message": "Tags:", + "description": "The label alongside a tag list" + }, + "theme.admonition.caution": { + "message": "caution", + "description": "The default label used for the Caution admonition (:::caution)" + }, + "theme.admonition.danger": { + "message": "danger", + "description": "The default label used for the Danger admonition (:::danger)" + }, + "theme.admonition.info": { + "message": "info", + "description": "The default label used for the Info admonition (:::info)" + }, + "theme.admonition.note": { + "message": "note", + "description": "The default label used for the Note admonition (:::note)" + }, + "theme.admonition.tip": { + "message": "tip", + "description": "The default label used for the Tip admonition (:::tip)" + }, + "theme.admonition.warning": { + "message": "warning", + "description": "The default label used for the Warning admonition (:::warning)" + }, + "theme.AnnouncementBar.closeButtonAriaLabel": { + "message": "Close", + "description": "The ARIA label for close button of announcement bar" + }, + "theme.blog.sidebar.navAriaLabel": { + "message": "Blog recent posts navigation", + "description": "The ARIA label for recent posts in the blog sidebar" + }, + "theme.CodeBlock.copied": { + "message": "Copied", + "description": "The copied button label on code blocks" + }, + "theme.CodeBlock.copyButtonAriaLabel": { + "message": "Copy code to clipboard", + "description": "The ARIA label for copy code blocks button" + }, + "theme.CodeBlock.copy": { + "message": "Copy", + "description": "The copy button label on code blocks" + }, + "theme.CodeBlock.wordWrapToggle": { + "message": "Toggle word wrap", + "description": "The title attribute for toggle word wrapping button of code block lines" + }, + "theme.DocSidebarItem.expandCategoryAriaLabel": { + "message": "Expand sidebar category '{label}'", + "description": "The ARIA label to expand the sidebar category" + }, + "theme.DocSidebarItem.collapseCategoryAriaLabel": { + "message": "Collapse sidebar category '{label}'", + "description": "The ARIA label to collapse the sidebar category" + }, + "theme.NavBar.navAriaLabel": { + "message": "Main", + "description": "The ARIA label for the main navigation" + }, + "theme.navbar.mobileLanguageDropdown.label": { + "message": "Languages", + "description": "The label for the mobile language switcher dropdown" + }, + "theme.NotFound.p1": { + "message": "We could not find what you were looking for.", + "description": "The first paragraph of the 404 page" + }, + "theme.NotFound.p2": { + "message": "Please contact the owner of the site that linked you to the original URL and let them know their link is broken.", + "description": "The 2nd paragraph of the 404 page" + }, + "theme.TOCCollapsible.toggleButtonLabel": { + "message": "On this page", + "description": "The label used by the button on the collapsible TOC component" + }, + "theme.blog.post.readMore": { + "message": "Read more", + "description": "The label used in blog post item excerpts to link to full blog posts" + }, + "theme.blog.post.readMoreLabel": { + "message": "Read more about {title}", + "description": "The ARIA label for the link to full blog posts from excerpts" + }, + "theme.blog.post.readingTime.plurals": { + "message": "One min read|{readingTime} min read", + "description": "Pluralized label for \"{readingTime} min read\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)" + }, + "theme.docs.breadcrumbs.home": { + "message": "Home page", + "description": "The ARIA label for the home page in the breadcrumbs" + }, + "theme.docs.sidebar.collapseButtonTitle": { + "message": "Collapse sidebar", + "description": "The title attribute for collapse button of doc sidebar" + }, + "theme.docs.sidebar.collapseButtonAriaLabel": { + "message": "Collapse sidebar", + "description": "The title attribute for collapse button of doc sidebar" + }, + "theme.docs.sidebar.navAriaLabel": { + "message": "Docs sidebar", + "description": "The ARIA label for the sidebar navigation" + }, + "theme.docs.sidebar.closeSidebarButtonAriaLabel": { + "message": "Close navigation bar", + "description": "The ARIA label for close button of mobile sidebar" + }, + "theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": { + "message": "← Back to main menu", + "description": "The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)" + }, + "theme.docs.sidebar.toggleSidebarButtonAriaLabel": { + "message": "Toggle navigation bar", + "description": "The ARIA label for hamburger menu button of mobile navigation" + }, + "theme.docs.sidebar.expandButtonTitle": { + "message": "Expand sidebar", + "description": "The ARIA label and title attribute for expand button of doc sidebar" + }, + "theme.docs.sidebar.expandButtonAriaLabel": { + "message": "Expand sidebar", + "description": "The ARIA label and title attribute for expand button of doc sidebar" + }, + "theme.blog.post.plurals": { + "message": "One post|{count} posts", + "description": "Pluralized label for \"{count} posts\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)" + }, + "theme.blog.tagTitle": { + "message": "{nPosts} tagged with \"{tagName}\"", + "description": "The title of the page for a blog tag" + }, + "theme.blog.author.pageTitle": { + "message": "{authorName} - {nPosts}", + "description": "The title of the page for a blog author" + }, + "theme.blog.authorsList.pageTitle": { + "message": "Authors", + "description": "The title of the authors page" + }, + "theme.blog.authorsList.viewAll": { + "message": "View all authors", + "description": "The label of the link targeting the blog authors page" + }, + "theme.blog.author.noPosts": { + "message": "This author has not written any posts yet.", + "description": "The text for authors with 0 blog post" + }, + "theme.contentVisibility.unlistedBanner.title": { + "message": "Unlisted page", + "description": "The unlisted content banner title" + }, + "theme.contentVisibility.unlistedBanner.message": { + "message": "This page is unlisted. Search engines will not index it, and only users having a direct link can access it.", + "description": "The unlisted content banner message" + }, + "theme.contentVisibility.draftBanner.title": { + "message": "Draft page", + "description": "The draft content banner title" + }, + "theme.contentVisibility.draftBanner.message": { + "message": "This page is a draft. It will only be visible in dev and be excluded from the production build.", + "description": "The draft content banner message" + }, + "theme.ErrorPageContent.tryAgain": { + "message": "Try again", + "description": "The label of the button to try again rendering when the React error boundary captures an error" + }, + "theme.common.skipToMainContent": { + "message": "Skip to main content", + "description": "The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation" + }, + "theme.tags.tagsPageTitle": { + "message": "Tags", + "description": "The title of the tag list page" + } +} diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current.json new file mode 100644 index 00000000..a20ddb42 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current.json @@ -0,0 +1,34 @@ +{ + "version.label": { + "message": "Next", + "description": "The label for version current" + }, + "sidebar.tutorialSidebar.category.1. 最易懂的贪心算法": { + "message": "1. greedy", + "description": "The label for category 1. 最易懂的贪心算法 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.1. 最易懂的贪心算法.link.generated-index.description": { + "message": "5 minutes to learn the most important Docusaurus concepts.", + "description": "The generated-index page description for category 1. 最易懂的贪心算法 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.2. 玩转双指针": { + "message": "2. 玩转双指针", + "description": "The label for category 2. 玩转双指针 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.2. 玩转双指针.link.generated-index.description": { + "message": "5 minutes to learn the most important Docusaurus concepts.", + "description": "The generated-index page description for category 2. 玩转双指针 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.Tutorial - Basics": { + "message": "Tutorial - Basics", + "description": "The label for category Tutorial - Basics in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.Tutorial - Basics.link.generated-index.description": { + "message": "5 minutes to learn the most important Docusaurus concepts.", + "description": "The generated-index page description for category Tutorial - Basics in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.Tutorial - Extras": { + "message": "Tutorial - Extras", + "description": "The label for category Tutorial - Extras in sidebar tutorialSidebar" + } +} diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/_category_.json new file mode 100644 index 00000000..e91e9e1e --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "1. 最易懂的贪心算法", + "position": 1, + "link": { + "type": "generated-index", + "description": "5 minutes to learn the most important Docusaurus concepts." + } +} diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/greddy.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/greddy.md new file mode 100644 index 00000000..7544d612 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/greddy.md @@ -0,0 +1,7 @@ +--- +sidebar_position: 6 +--- + +# 贪心! + +english greddy diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/index.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/index.md new file mode 100644 index 00000000..e019d6cd --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/index.md @@ -0,0 +1,7 @@ +--- +sidebar_position: 0 +--- + +# preface + +english preface diff --git a/leetcode_101/i18n/en/docusaurus-theme-classic/footer.json b/leetcode_101/i18n/en/docusaurus-theme-classic/footer.json new file mode 100644 index 00000000..b753f2a6 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-theme-classic/footer.json @@ -0,0 +1,42 @@ +{ + "link.title.Docs": { + "message": "Docs", + "description": "The title of the footer links column with title=Docs in the footer" + }, + "link.title.Community": { + "message": "Community", + "description": "The title of the footer links column with title=Community in the footer" + }, + "link.title.More": { + "message": "More", + "description": "The title of the footer links column with title=More in the footer" + }, + "link.item.label.Tutorial": { + "message": "Tutorial", + "description": "The label of footer link with label=Tutorial linking to /docs/intro" + }, + "link.item.label.Stack Overflow": { + "message": "Stack Overflow", + "description": "The label of footer link with label=Stack Overflow linking to https://stackoverflow.com/questions/tagged/docusaurus" + }, + "link.item.label.Discord": { + "message": "Discord", + "description": "The label of footer link with label=Discord linking to https://discordapp.com/invite/docusaurus" + }, + "link.item.label.X": { + "message": "X", + "description": "The label of footer link with label=X linking to https://x.com/docusaurus" + }, + "link.item.label.Blog": { + "message": "Blog", + "description": "The label of footer link with label=Blog linking to /blog" + }, + "link.item.label.GitHub": { + "message": "GitHub", + "description": "The label of footer link with label=GitHub linking to https://github.com/facebook/docusaurus" + }, + "copyright": { + "message": "Copyright © 2024 My Project, Inc. Built with Docusaurus.", + "description": "The footer copyright" + } +} diff --git a/leetcode_101/i18n/en/docusaurus-theme-classic/navbar.json b/leetcode_101/i18n/en/docusaurus-theme-classic/navbar.json new file mode 100644 index 00000000..6e59d8ef --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-theme-classic/navbar.json @@ -0,0 +1,14 @@ +{ + "title": { + "message": "LeetCode 101 - A Grinding Guide", + "description": "The title in the navbar" + }, + "logo.alt": { + "message": "My Site Logo", + "description": "The alt text of navbar logo" + }, + "item.label.GitHub": { + "message": "GitHub", + "description": "Navbar item with label GitHub" + } +} diff --git a/leetcode_101/i18n/zh-TW/code.json b/leetcode_101/i18n/zh-TW/code.json new file mode 100644 index 00000000..87ac7e0d --- /dev/null +++ b/leetcode_101/i18n/zh-TW/code.json @@ -0,0 +1,313 @@ +{ + "theme.ErrorPageContent.title": { + "message": "此頁已當機。", + "description": "The title of the fallback page when the page crashed" + }, + "theme.BackToTopButton.buttonAriaLabel": { + "message": "回到頂部", + "description": "The ARIA label for the back to top button" + }, + "theme.blog.archive.title": { + "message": "歷史文章", + "description": "The page & hero title of the blog archive page" + }, + "theme.blog.archive.description": { + "message": "歷史文章", + "description": "The page & hero description of the blog archive page" + }, + "theme.blog.paginator.navAriaLabel": { + "message": "部落格文章列表分頁導覽", + "description": "The ARIA label for the blog pagination" + }, + "theme.blog.paginator.newerEntries": { + "message": "較新的文章", + "description": "The label used to navigate to the newer blog posts page (previous page)" + }, + "theme.blog.paginator.olderEntries": { + "message": "較舊的文章", + "description": "The label used to navigate to the older blog posts page (next page)" + }, + "theme.blog.post.paginator.navAriaLabel": { + "message": "部落格文章分頁導覽", + "description": "The ARIA label for the blog posts pagination" + }, + "theme.blog.post.paginator.newerPost": { + "message": "較新一篇", + "description": "The blog post button label to navigate to the newer/previous post" + }, + "theme.blog.post.paginator.olderPost": { + "message": "較舊一篇", + "description": "The blog post button label to navigate to the older/next post" + }, + "theme.tags.tagsPageLink": { + "message": "檢視所有標籤", + "description": "The label of the link targeting the tag list page" + }, + "theme.colorToggle.ariaLabel": { + "message": "切換淺色/深色模式(當前為{mode})", + "description": "The ARIA label for the navbar color mode toggle" + }, + "theme.colorToggle.ariaLabel.mode.dark": { + "message": "深色模式", + "description": "The name for the dark color mode" + }, + "theme.colorToggle.ariaLabel.mode.light": { + "message": "淺色模式", + "description": "The name for the light color mode" + }, + "theme.docs.breadcrumbs.navAriaLabel": { + "message": "頁面路徑", + "description": "The ARIA label for the breadcrumbs" + }, + "theme.docs.DocCard.categoryDescription.plurals": { + "message": "{count} 個項目", + "description": "The default description for a category card in the generated index about how many items this category includes" + }, + "theme.docs.paginator.navAriaLabel": { + "message": "文件選項卡", + "description": "The ARIA label for the docs pagination" + }, + "theme.docs.paginator.previous": { + "message": "上一頁", + "description": "The label used to navigate to the previous doc" + }, + "theme.docs.paginator.next": { + "message": "下一頁", + "description": "The label used to navigate to the next doc" + }, + "theme.docs.tagDocListPageTitle.nDocsTagged": { + "message": "{count} 篇文件帶有標籤", + "description": "Pluralized label for \"{count} docs tagged\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)" + }, + "theme.docs.tagDocListPageTitle": { + "message": "{nDocsTagged}「{tagName}」", + "description": "The title of the page for a docs tag" + }, + "theme.docs.versionBadge.label": { + "message": "版本:{versionLabel}" + }, + "theme.docs.versions.unreleasedVersionLabel": { + "message": "此為 {siteTitle} {versionLabel} 版尚未發行的文件。", + "description": "The label used to tell the user that he's browsing an unreleased doc version" + }, + "theme.docs.versions.unmaintainedVersionLabel": { + "message": "此為 {siteTitle} {versionLabel} 版的文件,現已不再積極維護。", + "description": "The label used to tell the user that he's browsing an unmaintained doc version" + }, + "theme.docs.versions.latestVersionSuggestionLabel": { + "message": "最新的文件請參閱 {latestVersionLink} ({versionLabel})。", + "description": "The label used to tell the user to check the latest version" + }, + "theme.docs.versions.latestVersionLinkLabel": { + "message": "最新版本", + "description": "The label used for the latest version suggestion link label" + }, + "theme.common.editThisPage": { + "message": "編輯此頁", + "description": "The link label to edit the current page" + }, + "theme.common.headingLinkTitle": { + "message": "{heading}的直接連結", + "description": "Title for link to heading" + }, + "theme.lastUpdated.atDate": { + "message": "於 {date} ", + "description": "The words used to describe on which date a page has been last updated" + }, + "theme.lastUpdated.byUser": { + "message": "由 {user} ", + "description": "The words used to describe by who the page has been last updated" + }, + "theme.lastUpdated.lastUpdatedAtBy": { + "message": "最後{byUser}{atDate}更新", + "description": "The sentence used to display when a page has been last updated, and by who" + }, + "theme.navbar.mobileVersionsDropdown.label": { + "message": "選擇版本", + "description": "The label for the navbar versions dropdown on mobile view" + }, + "theme.NotFound.title": { + "message": "找不到頁面", + "description": "The title of the 404 page" + }, + "theme.tags.tagsListLabel": { + "message": "標籤:", + "description": "The label alongside a tag list" + }, + "theme.AnnouncementBar.closeButtonAriaLabel": { + "message": "關閉", + "description": "The ARIA label for close button of announcement bar" + }, + "theme.admonition.caution": { + "message": "警告", + "description": "The default label used for the Caution admonition (:::caution)" + }, + "theme.admonition.danger": { + "message": "危險", + "description": "The default label used for the Danger admonition (:::danger)" + }, + "theme.admonition.info": { + "message": "資訊", + "description": "The default label used for the Info admonition (:::info)" + }, + "theme.admonition.note": { + "message": "備註", + "description": "The default label used for the Note admonition (:::note)" + }, + "theme.admonition.tip": { + "message": "提示", + "description": "The default label used for the Tip admonition (:::tip)" + }, + "theme.admonition.warning": { + "message": "注意", + "description": "The default label used for the Warning admonition (:::warning)" + }, + "theme.blog.sidebar.navAriaLabel": { + "message": "最近部落格文章導覽", + "description": "The ARIA label for recent posts in the blog sidebar" + }, + "theme.CodeBlock.copied": { + "message": "複製成功", + "description": "The copied button label on code blocks" + }, + "theme.CodeBlock.copyButtonAriaLabel": { + "message": "複製程式碼至剪貼簿", + "description": "The ARIA label for copy code blocks button" + }, + "theme.CodeBlock.copy": { + "message": "複製", + "description": "The copy button label on code blocks" + }, + "theme.CodeBlock.wordWrapToggle": { + "message": "切換自動換行", + "description": "The title attribute for toggle word wrapping button of code block lines" + }, + "theme.DocSidebarItem.expandCategoryAriaLabel": { + "message": "展開側邊欄分類 '{label}'", + "description": "The ARIA label to expand the sidebar category" + }, + "theme.DocSidebarItem.collapseCategoryAriaLabel": { + "message": "收起側邊欄分類 '{label}'", + "description": "The ARIA label to collapse the sidebar category" + }, + "theme.NavBar.navAriaLabel": { + "message": "主導航", + "description": "The ARIA label for the main navigation" + }, + "theme.navbar.mobileLanguageDropdown.label": { + "message": "選擇語言", + "description": "The label for the mobile language switcher dropdown" + }, + "theme.NotFound.p1": { + "message": "我們沒有您要找的頁面。", + "description": "The first paragraph of the 404 page" + }, + "theme.NotFound.p2": { + "message": "請聯絡原始連結來源網站的所有者,並通知他們連結已毀損。", + "description": "The 2nd paragraph of the 404 page" + }, + "theme.TOCCollapsible.toggleButtonLabel": { + "message": "本頁導覽", + "description": "The label used by the button on the collapsible TOC component" + }, + "theme.blog.post.readMore": { + "message": "閱讀更多", + "description": "The label used in blog post item excerpts to link to full blog posts" + }, + "theme.blog.post.readMoreLabel": { + "message": "閱讀 {title} 全文", + "description": "The ARIA label for the link to full blog posts from excerpts" + }, + "theme.blog.post.readingTime.plurals": { + "message": "閱讀時間約 {readingTime} 分鐘", + "description": "Pluralized label for \"{readingTime} min read\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)" + }, + "theme.docs.breadcrumbs.home": { + "message": "主頁面", + "description": "The ARIA label for the home page in the breadcrumbs" + }, + "theme.docs.sidebar.collapseButtonTitle": { + "message": "收起側邊欄", + "description": "The title attribute for collapse button of doc sidebar" + }, + "theme.docs.sidebar.collapseButtonAriaLabel": { + "message": "收起側邊欄", + "description": "The title attribute for collapse button of doc sidebar" + }, + "theme.docs.sidebar.navAriaLabel": { + "message": "文件側邊欄", + "description": "The ARIA label for the sidebar navigation" + }, + "theme.docs.sidebar.closeSidebarButtonAriaLabel": { + "message": "Close navigation bar", + "description": "The ARIA label for close button of mobile sidebar" + }, + "theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": { + "message": "← 回到主選單", + "description": "The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)" + }, + "theme.docs.sidebar.toggleSidebarButtonAriaLabel": { + "message": "切換導覽列", + "description": "The ARIA label for hamburger menu button of mobile navigation" + }, + "theme.docs.sidebar.expandButtonTitle": { + "message": "展開側邊欄", + "description": "The ARIA label and title attribute for expand button of doc sidebar" + }, + "theme.docs.sidebar.expandButtonAriaLabel": { + "message": "展開側邊欄", + "description": "The ARIA label and title attribute for expand button of doc sidebar" + }, + "theme.blog.post.plurals": { + "message": "{count} 篇文章", + "description": "Pluralized label for \"{count} posts\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)" + }, + "theme.blog.tagTitle": { + "message": "{nPosts} 含有標籤「{tagName}」", + "description": "The title of the page for a blog tag" + }, + "theme.blog.author.pageTitle": { + "message": "{authorName} - {nPosts}", + "description": "The title of the page for a blog author" + }, + "theme.blog.authorsList.pageTitle": { + "message": "Authors", + "description": "The title of the authors page" + }, + "theme.blog.authorsList.viewAll": { + "message": "View All Authors", + "description": "The label of the link targeting the blog authors page" + }, + "theme.blog.author.noPosts": { + "message": "This author has not written any posts yet.", + "description": "The text for authors with 0 blog post" + }, + "theme.contentVisibility.unlistedBanner.title": { + "message": "未列出頁", + "description": "The unlisted content banner title" + }, + "theme.contentVisibility.unlistedBanner.message": { + "message": "此頁面未列出。搜索引擎不會對其索引,只有擁有直接連結的用戶才能訪問。", + "description": "The unlisted content banner message" + }, + "theme.contentVisibility.draftBanner.title": { + "message": "Draft page", + "description": "The draft content banner title" + }, + "theme.contentVisibility.draftBanner.message": { + "message": "This page is a draft. It will only be visible in dev and be excluded from the production build.", + "description": "The draft content banner message" + }, + "theme.ErrorPageContent.tryAgain": { + "message": "重試", + "description": "The label of the button to try again rendering when the React error boundary captures an error" + }, + "theme.common.skipToMainContent": { + "message": "跳至主要内容", + "description": "The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation" + }, + "theme.tags.tagsPageTitle": { + "message": "標籤", + "description": "The title of the tag list page" + } +} diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current.json new file mode 100644 index 00000000..4eca2e3e --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current.json @@ -0,0 +1,34 @@ +{ + "version.label": { + "message": "Next", + "description": "The label for version current" + }, + "sidebar.tutorialSidebar.category.1. 最易懂的贪心算法": { + "message": "1. 最易懂的貪心算法", + "description": "The label for category 1. 最易懂的贪心算法 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.1. 最易懂的贪心算法.link.generated-index.description": { + "message": "5 minutes to learn the most important Docusaurus concepts.", + "description": "The generated-index page description for category 1. 最易懂的贪心算法 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.2. 玩转双指针": { + "message": "2. 玩转双指针", + "description": "The label for category 2. 玩转双指针 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.2. 玩转双指针.link.generated-index.description": { + "message": "5 minutes to learn the most important Docusaurus concepts.", + "description": "The generated-index page description for category 2. 玩转双指针 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.Tutorial - Basics": { + "message": "Tutorial - Basics", + "description": "The label for category Tutorial - Basics in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.Tutorial - Basics.link.generated-index.description": { + "message": "5 minutes to learn the most important Docusaurus concepts.", + "description": "The generated-index page description for category Tutorial - Basics in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.Tutorial - Extras": { + "message": "Tutorial - Extras", + "description": "The label for category Tutorial - Extras in sidebar tutorialSidebar" + } +} diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/_category_.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/_category_.json new file mode 100644 index 00000000..e91e9e1e --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "1. 最易懂的贪心算法", + "position": 1, + "link": { + "type": "generated-index", + "description": "5 minutes to learn the most important Docusaurus concepts." + } +} diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/greddy.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/greddy.md new file mode 100644 index 00000000..ee4a0092 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/greddy.md @@ -0,0 +1,7 @@ +--- +sidebar_position: 6 +--- + +# 贪心! + +繁體中文版貪心 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/index.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/index.md new file mode 100644 index 00000000..b23b8581 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/index.md @@ -0,0 +1,7 @@ +--- +sidebar_position: 0 +--- + +# 繁體序 + +繁體序 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-theme-classic/footer.json b/leetcode_101/i18n/zh-TW/docusaurus-theme-classic/footer.json new file mode 100644 index 00000000..b753f2a6 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-theme-classic/footer.json @@ -0,0 +1,42 @@ +{ + "link.title.Docs": { + "message": "Docs", + "description": "The title of the footer links column with title=Docs in the footer" + }, + "link.title.Community": { + "message": "Community", + "description": "The title of the footer links column with title=Community in the footer" + }, + "link.title.More": { + "message": "More", + "description": "The title of the footer links column with title=More in the footer" + }, + "link.item.label.Tutorial": { + "message": "Tutorial", + "description": "The label of footer link with label=Tutorial linking to /docs/intro" + }, + "link.item.label.Stack Overflow": { + "message": "Stack Overflow", + "description": "The label of footer link with label=Stack Overflow linking to https://stackoverflow.com/questions/tagged/docusaurus" + }, + "link.item.label.Discord": { + "message": "Discord", + "description": "The label of footer link with label=Discord linking to https://discordapp.com/invite/docusaurus" + }, + "link.item.label.X": { + "message": "X", + "description": "The label of footer link with label=X linking to https://x.com/docusaurus" + }, + "link.item.label.Blog": { + "message": "Blog", + "description": "The label of footer link with label=Blog linking to /blog" + }, + "link.item.label.GitHub": { + "message": "GitHub", + "description": "The label of footer link with label=GitHub linking to https://github.com/facebook/docusaurus" + }, + "copyright": { + "message": "Copyright © 2024 My Project, Inc. Built with Docusaurus.", + "description": "The footer copyright" + } +} diff --git a/leetcode_101/i18n/zh-TW/docusaurus-theme-classic/navbar.json b/leetcode_101/i18n/zh-TW/docusaurus-theme-classic/navbar.json new file mode 100644 index 00000000..6e59d8ef --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-theme-classic/navbar.json @@ -0,0 +1,14 @@ +{ + "title": { + "message": "LeetCode 101 - A Grinding Guide", + "description": "The title in the navbar" + }, + "logo.alt": { + "message": "My Site Logo", + "description": "The alt text of navbar logo" + }, + "item.label.GitHub": { + "message": "GitHub", + "description": "Navbar item with label GitHub" + } +} diff --git a/leetcode_101/package-lock.json b/leetcode_101/package-lock.json new file mode 100644 index 00000000..25d32ad9 --- /dev/null +++ b/leetcode_101/package-lock.json @@ -0,0 +1,16074 @@ +{ + "name": "leetcode-101", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "leetcode-101", + "version": "0.0.0", + "dependencies": { + "@docusaurus/core": "3.6.1", + "@docusaurus/preset-classic": "3.6.1", + "@mdx-js/react": "^3.0.0", + "clsx": "^2.0.0", + "prism-react-renderer": "^2.3.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "devDependencies": { + "@docusaurus/module-type-aliases": "3.6.1", + "@docusaurus/tsconfig": "3.6.1", + "@docusaurus/types": "3.6.1", + "typescript": "~5.6.2" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@algolia/autocomplete-core": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.17.6.tgz", + "integrity": "sha512-lkDoW4I7h2kKlIgf3pUt1LqvxyYKkVyiypoGLlUnhPSnCpmeOwudM6rNq6YYsCmdQtnDQoW5lUNNuj6ASg3qeg==", + "license": "MIT", + "dependencies": { + "@algolia/autocomplete-plugin-algolia-insights": "1.17.6", + "@algolia/autocomplete-shared": "1.17.6" + } + }, + "node_modules/@algolia/autocomplete-plugin-algolia-insights": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.17.6.tgz", + "integrity": "sha512-17NnaacuFzSWVuZu4NKzVeaFIe9Abpw8w+/gjc7xhZFtqj+GadufzodIdchwiB2eM2cDdiR3icW7gbNTB3K2YA==", + "license": "MIT", + "dependencies": { + "@algolia/autocomplete-shared": "1.17.6" + }, + "peerDependencies": { + "search-insights": ">= 1 < 3" + } + }, + "node_modules/@algolia/autocomplete-preset-algolia": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.6.tgz", + "integrity": "sha512-Cvg5JENdSCMuClwhJ1ON1/jSuojaYMiUW2KePm18IkdCzPJj/NXojaOxw58RFtQFpJgfVW8h2E8mEoDtLlMdeA==", + "license": "MIT", + "dependencies": { + "@algolia/autocomplete-shared": "1.17.6" + }, + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" + } + }, + "node_modules/@algolia/autocomplete-shared": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.6.tgz", + "integrity": "sha512-aq/3V9E00Tw2GC/PqgyPGXtqJUlVc17v4cn1EUhSc+O/4zd04Uwb3UmPm8KDaYQQOrkt1lwvCj2vG2wRE5IKhw==", + "license": "MIT", + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" + } + }, + "node_modules/@algolia/cache-browser-local-storage": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.24.0.tgz", + "integrity": "sha512-t63W9BnoXVrGy9iYHBgObNXqYXM3tYXCjDSHeNwnsc324r4o5UiVKUiAB4THQ5z9U5hTj6qUvwg/Ez43ZD85ww==", + "license": "MIT", + "dependencies": { + "@algolia/cache-common": "4.24.0" + } + }, + "node_modules/@algolia/cache-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.24.0.tgz", + "integrity": "sha512-emi+v+DmVLpMGhp0V9q9h5CdkURsNmFC+cOS6uK9ndeJm9J4TiqSvPYVu+THUP8P/S08rxf5x2P+p3CfID0Y4g==", + "license": "MIT" + }, + "node_modules/@algolia/cache-in-memory": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.24.0.tgz", + "integrity": "sha512-gDrt2so19jW26jY3/MkFg5mEypFIPbPoXsQGQWAi6TrCPsNOSEYepBMPlucqWigsmEy/prp5ug2jy/N3PVG/8w==", + "license": "MIT", + "dependencies": { + "@algolia/cache-common": "4.24.0" + } + }, + "node_modules/@algolia/client-abtesting": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.13.0.tgz", + "integrity": "sha512-6CoQjlMi1pmQYMQO8tXfuGxSPf6iKX5FP9MuMe6IWmvC81wwTvOehnwchyBl2wuPVhcw2Ar53K53mQ60DAC64g==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-account": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.24.0.tgz", + "integrity": "sha512-adcvyJ3KjPZFDybxlqnf+5KgxJtBjwTPTeyG2aOyoJvx0Y8dUQAEOEVOJ/GBxX0WWNbmaSrhDURMhc+QeevDsA==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-account/node_modules/@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "license": "MIT", + "dependencies": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-account/node_modules/@algolia/client-search": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", + "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-analytics": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.24.0.tgz", + "integrity": "sha512-y8jOZt1OjwWU4N2qr8G4AxXAzaa8DBvyHTWlHzX/7Me1LX8OayfgHexqrsL4vSBcoMmVw2XnVW9MhL+Y2ZDJXg==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-analytics/node_modules/@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "license": "MIT", + "dependencies": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-analytics/node_modules/@algolia/client-search": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", + "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-common": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.13.0.tgz", + "integrity": "sha512-2SP6bGGWOTN920MLZv8s7yIR3OqY03vEe4U+vb2MGdL8a/8EQznF3L/nTC/rGf/hvEfZlX2tGFxPJaF2waravg==", + "license": "MIT", + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-insights": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.13.0.tgz", + "integrity": "sha512-ldHTe+LVgC6L4Wr6doAQQ7Ku0jAdhaaPg1T+IHzmmiRZb2Uq5OsjW2yC65JifOmzPCiMkIZE2mGRpWgkn5ktlw==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-personalization": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.24.0.tgz", + "integrity": "sha512-l5FRFm/yngztweU0HdUzz1rC4yoWCFo3IF+dVIVTfEPg906eZg5BOd1k0K6rZx5JzyyoP4LdmOikfkfGsKVE9w==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-personalization/node_modules/@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "license": "MIT", + "dependencies": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-query-suggestions": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.13.0.tgz", + "integrity": "sha512-pYo0jbLUtPDN1r341UHTaF2fgN5rbaZfDZqjPRKPM+FRlRmxFxqFQm1UUfpkSUWYGn7lECwDpbKYiKUf81MTwA==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-search": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.13.0.tgz", + "integrity": "sha512-s2ge3uZ6Zg2sPSFibqijgEYsuorxcc8KVHg3I95nOPHvFHdnBtSHymhZvq4sp/fu8ijt/Y8jLwkuqm5myn+2Sg==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/events": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz", + "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==", + "license": "MIT" + }, + "node_modules/@algolia/ingestion": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.13.0.tgz", + "integrity": "sha512-fm5LEOe4FPDOc1D+M9stEs8hfcdmbdD+pt9og5shql6ueTZJANDbFoQhDOpiPJizR/ps1GwmjkWfUEywx3sV+Q==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/logger-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.24.0.tgz", + "integrity": "sha512-LLUNjkahj9KtKYrQhFKCzMx0BY3RnNP4FEtO+sBybCjJ73E8jNdaKJ/Dd8A/VA4imVHP5tADZ8pn5B8Ga/wTMA==", + "license": "MIT" + }, + "node_modules/@algolia/logger-console": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.24.0.tgz", + "integrity": "sha512-X4C8IoHgHfiUROfoRCV+lzSy+LHMgkoEEU1BbKcsfnV0i0S20zyy0NLww9dwVHUWNfPPxdMU+/wKmLGYf96yTg==", + "license": "MIT", + "dependencies": { + "@algolia/logger-common": "4.24.0" + } + }, + "node_modules/@algolia/monitoring": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.13.0.tgz", + "integrity": "sha512-e8Hshlnm2G5fapyUgWTBwhJ22yXcnLtPC4LWZKx7KOvv35GcdoHtlUBX94I/sWCJLraUr65JvR8qOo3LXC43dg==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/recommend": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-4.24.0.tgz", + "integrity": "sha512-P9kcgerfVBpfYHDfVZDvvdJv0lEoCvzNlOy2nykyt5bK8TyieYyiD0lguIJdRZZYGre03WIAFf14pgE+V+IBlw==", + "license": "MIT", + "dependencies": { + "@algolia/cache-browser-local-storage": "4.24.0", + "@algolia/cache-common": "4.24.0", + "@algolia/cache-in-memory": "4.24.0", + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/logger-console": "4.24.0", + "@algolia/requester-browser-xhr": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/requester-node-http": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/recommend/node_modules/@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "license": "MIT", + "dependencies": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/recommend/node_modules/@algolia/client-search": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", + "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/recommend/node_modules/@algolia/requester-browser-xhr": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz", + "integrity": "sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==", + "license": "MIT", + "dependencies": { + "@algolia/requester-common": "4.24.0" + } + }, + "node_modules/@algolia/recommend/node_modules/@algolia/requester-node-http": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz", + "integrity": "sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==", + "license": "MIT", + "dependencies": { + "@algolia/requester-common": "4.24.0" + } + }, + "node_modules/@algolia/requester-browser-xhr": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.13.0.tgz", + "integrity": "sha512-NV6oSCt5lFuzfsVQoSBpewEWf/h4ySr7pv2bfwu9yF/jc/g39pig8+YpuqsxlRWBm/lTGVA2V0Ai9ySwrNumIA==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.24.0.tgz", + "integrity": "sha512-k3CXJ2OVnvgE3HMwcojpvY6d9kgKMPRxs/kVohrwF5WMr2fnqojnycZkxPoEg+bXm8fi5BBfFmOqgYztRtHsQA==", + "license": "MIT" + }, + "node_modules/@algolia/requester-fetch": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.13.0.tgz", + "integrity": "sha512-094bK4rumf+rXJazxv3mq6eKRM0ep5AxIo8T0YmOdldswQt79apeufFiPLN19nHEWH22xR2FelimD+T/wRSP+Q==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-node-http": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.13.0.tgz", + "integrity": "sha512-JY5xhEYMgki53Wm+A6R2jUpOUdD0zZnBq+PC5R1TGMNOYL1s6JjDrJeMsvaI2YWxYMUSoCnRoltN/yf9RI8n3A==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/transporter": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.24.0.tgz", + "integrity": "sha512-86nI7w6NzWxd1Zp9q3413dRshDqAzSbsQjhcDhPIatEFiZrL1/TjnHL8S7jVKFePlIMzDsZWXAXwXzcok9c5oA==", + "license": "MIT", + "dependencies": { + "@algolia/cache-common": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/requester-common": "4.24.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz", + "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.26.2", + "@babel/types": "^7.26.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.25.9.tgz", + "integrity": "sha512-C47lC7LIDCnz0h4vai/tpNOI95tCd5ZT3iBt/DBH5lXKHZsyNQv18yf1wIIg2ntiQNgmAvA+DgZ82iW8Qdym8g==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", + "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.9.tgz", + "integrity": "sha512-ORPNZ3h6ZRkOyAa/SaHU+XsLZr0UQzRwuDQ0cczIA17nAzZ+85G5cVkOJIj7QavLZGSe8QXUmNFxSZzjcZF9bw==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "regexpu-core": "^6.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", + "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", + "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", + "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", + "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz", + "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-wrap-function": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz", + "integrity": "sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.9.tgz", + "integrity": "sha512-c6WHXuiaRsJTyHYLJV75t9IqsmTbItYfdj99PnzYGQZkYKvan5/2jKJ7gu31J3/BJ/A18grImSPModuyG/Eo0Q==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", + "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz", + "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.26.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz", + "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz", + "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz", + "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz", + "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz", + "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", + "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz", + "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz", + "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz", + "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz", + "integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz", + "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.9.tgz", + "integrity": "sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz", + "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz", + "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz", + "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz", + "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz", + "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/template": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz", + "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz", + "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz", + "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz", + "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.25.9.tgz", + "integrity": "sha512-KRhdhlVk2nObA5AYa7QMgTMTVJdfHprfpAk4DjZVtllqRg9qarilstTKEhpVjyt+Npi8ThRyiV8176Am3CodPA==", + "license": "MIT", + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz", + "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz", + "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz", + "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz", + "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz", + "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz", + "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz", + "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz", + "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.25.9.tgz", + "integrity": "sha512-dwh2Ol1jWwL2MgkCzUSOvfmKElqQcuswAZypBSUsScMXvgdT8Ekq5YA6TtqpTVWH+4903NmboMuH1o9i8Rxlyg==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-simple-access": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz", + "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz", + "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz", + "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.9.tgz", + "integrity": "sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz", + "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz", + "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz", + "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz", + "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz", + "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz", + "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz", + "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz", + "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-constant-elements": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.25.9.tgz", + "integrity": "sha512-Ncw2JFsJVuvfRsa2lSHiC55kETQVLSnsYGQ1JDDwkUeWGTL/8Tom8aLTnlqgoeuopWrbbGndrc9AlLYrIosrow==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.25.9.tgz", + "integrity": "sha512-KJfMlYIUxQB1CJfO3e0+h0ZHWOTLCPP115Awhaz8U0Zpq36Gl/cXlpoyMRnUWlhNUBAzldnCiAZNvCDj7CrKxQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.9.tgz", + "integrity": "sha512-s5XwpQYCqGerXl+Pu6VDL3x0j2d82eiV77UJ8a2mDHAW7j9SWRqQ2y1fNo1Z74CdcYipl5Z41zvjj4Nfzq36rw==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-syntax-jsx": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.25.9.tgz", + "integrity": "sha512-9mj6rm7XVYs4mdLIpbZnHOYdpW42uoiBCTVowg7sP1thUOiANgMb4UtpRivR0pp5iL+ocvUv7X4mZgFRpJEzGw==", + "license": "MIT", + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.25.9.tgz", + "integrity": "sha512-KQ/Takk3T8Qzj5TppkS1be588lkbTp5uj7w6a0LeQaTMSckU/wK0oJ/pih+T690tkgI5jfmg2TqDJvd41Sj1Cg==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz", + "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz", + "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz", + "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.9.tgz", + "integrity": "sha512-nZp7GlEl+yULJrClz0SwHPqir3lc0zsPrDHQUcxGspSL7AKrexNSEfTbfqnDNJUO13bgKyfuOLMF8Xqtu8j3YQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz", + "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz", + "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz", + "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz", + "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz", + "integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.9.tgz", + "integrity": "sha512-7PbZQZP50tzv2KGGnhh82GSyMB01yKY9scIjf1a+GfZCtInOWqUH5+1EBU4t9fyR5Oykkkc9vFTs4OHrhHXljQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-syntax-typescript": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz", + "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz", + "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz", + "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz", + "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.0.tgz", + "integrity": "sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.26.0", + "@babel/plugin-syntax-import-attributes": "^7.26.0", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.25.9", + "@babel/plugin-transform-async-generator-functions": "^7.25.9", + "@babel/plugin-transform-async-to-generator": "^7.25.9", + "@babel/plugin-transform-block-scoped-functions": "^7.25.9", + "@babel/plugin-transform-block-scoping": "^7.25.9", + "@babel/plugin-transform-class-properties": "^7.25.9", + "@babel/plugin-transform-class-static-block": "^7.26.0", + "@babel/plugin-transform-classes": "^7.25.9", + "@babel/plugin-transform-computed-properties": "^7.25.9", + "@babel/plugin-transform-destructuring": "^7.25.9", + "@babel/plugin-transform-dotall-regex": "^7.25.9", + "@babel/plugin-transform-duplicate-keys": "^7.25.9", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-dynamic-import": "^7.25.9", + "@babel/plugin-transform-exponentiation-operator": "^7.25.9", + "@babel/plugin-transform-export-namespace-from": "^7.25.9", + "@babel/plugin-transform-for-of": "^7.25.9", + "@babel/plugin-transform-function-name": "^7.25.9", + "@babel/plugin-transform-json-strings": "^7.25.9", + "@babel/plugin-transform-literals": "^7.25.9", + "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", + "@babel/plugin-transform-member-expression-literals": "^7.25.9", + "@babel/plugin-transform-modules-amd": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-modules-systemjs": "^7.25.9", + "@babel/plugin-transform-modules-umd": "^7.25.9", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-new-target": "^7.25.9", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.25.9", + "@babel/plugin-transform-numeric-separator": "^7.25.9", + "@babel/plugin-transform-object-rest-spread": "^7.25.9", + "@babel/plugin-transform-object-super": "^7.25.9", + "@babel/plugin-transform-optional-catch-binding": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9", + "@babel/plugin-transform-private-methods": "^7.25.9", + "@babel/plugin-transform-private-property-in-object": "^7.25.9", + "@babel/plugin-transform-property-literals": "^7.25.9", + "@babel/plugin-transform-regenerator": "^7.25.9", + "@babel/plugin-transform-regexp-modifiers": "^7.26.0", + "@babel/plugin-transform-reserved-words": "^7.25.9", + "@babel/plugin-transform-shorthand-properties": "^7.25.9", + "@babel/plugin-transform-spread": "^7.25.9", + "@babel/plugin-transform-sticky-regex": "^7.25.9", + "@babel/plugin-transform-template-literals": "^7.25.9", + "@babel/plugin-transform-typeof-symbol": "^7.25.9", + "@babel/plugin-transform-unicode-escapes": "^7.25.9", + "@babel/plugin-transform-unicode-property-regex": "^7.25.9", + "@babel/plugin-transform-unicode-regex": "^7.25.9", + "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.38.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-react": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.25.9.tgz", + "integrity": "sha512-D3to0uSPiWE7rBrdIICCd0tJSIGpLaaGptna2+w7Pft5xMqLpA1sz99DK5TZ1TjGbdQ/VI1eCSZ06dv3lT4JOw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-transform-react-display-name": "^7.25.9", + "@babel/plugin-transform-react-jsx": "^7.25.9", + "@babel/plugin-transform-react-jsx-development": "^7.25.9", + "@babel/plugin-transform-react-pure-annotations": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.26.0.tgz", + "integrity": "sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-syntax-jsx": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-typescript": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime-corejs3": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.26.0.tgz", + "integrity": "sha512-YXHu5lN8kJCb1LOb9PgV6pvak43X2h4HvRApcN5SdWeaItQOzfn1hgP6jasD6KWQyJDBxrVmA9o9OivlnNJK/w==", + "license": "MIT", + "dependencies": { + "core-js-pure": "^3.30.2", + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", + "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/template": "^7.25.9", + "@babel/types": "^7.25.9", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", + "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@docsearch/css": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.7.0.tgz", + "integrity": "sha512-1OorbTwi1eeDmr0v5t+ckSRlt1zM5GHjm92iIl3kUu7im3GHuP+csf6E0WBg8pdXQczTWP9J9+o9n+Vg6DH5cQ==", + "license": "MIT" + }, + "node_modules/@docsearch/react": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.7.0.tgz", + "integrity": "sha512-8e6tdDfkYoxafEEPuX5eE1h9cTkLvhe4KgoFkO5JCddXSQONnN1FHcDZRI4r8894eMpbYq6rdJF0dVYh8ikwNQ==", + "license": "MIT", + "dependencies": { + "@algolia/autocomplete-core": "1.17.6", + "@algolia/autocomplete-preset-algolia": "1.17.6", + "@docsearch/css": "3.7.0", + "algoliasearch": "^5.12.0" + }, + "peerDependencies": { + "@types/react": ">= 16.8.0 < 19.0.0", + "react": ">= 16.8.0 < 19.0.0", + "react-dom": ">= 16.8.0 < 19.0.0", + "search-insights": ">= 1 < 3" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "search-insights": { + "optional": true + } + } + }, + "node_modules/@docsearch/react/node_modules/@algolia/client-analytics": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.13.0.tgz", + "integrity": "sha512-pS3qyXiWTwKnrt/jE79fqkNqZp7kjsFNlJDcBGkSWid74DNc6DmArlkvPqyLxnoaYGjUGACT6g56n7E3mVV2TA==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@docsearch/react/node_modules/@algolia/client-personalization": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.13.0.tgz", + "integrity": "sha512-RnCfOSN4OUJDuMNHFca2M8lY64Tmw0kQOZikge4TknTqHmlbKJb8IbJE7Rol79Z80W2Y+B1ydcjV7DPje4GMRA==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@docsearch/react/node_modules/@algolia/recommend": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.13.0.tgz", + "integrity": "sha512-53/wW96oaj1FKMzGdFcZ/epygfTppLDUvgI1thLkd475EtVZCH3ZZVUNCEvf1AtnNyH1RnItkFzX8ayWCpx2PQ==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@docsearch/react/node_modules/algoliasearch": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.13.0.tgz", + "integrity": "sha512-04lyQX3Ev/oLYQx+aagamQDXvkUUfX1mwrLrus15+9fNaYj28GDxxEzbwaRfvmHFcZyoxvup7mMtDTTw8SrTEQ==", + "license": "MIT", + "dependencies": { + "@algolia/client-abtesting": "5.13.0", + "@algolia/client-analytics": "5.13.0", + "@algolia/client-common": "5.13.0", + "@algolia/client-insights": "5.13.0", + "@algolia/client-personalization": "5.13.0", + "@algolia/client-query-suggestions": "5.13.0", + "@algolia/client-search": "5.13.0", + "@algolia/ingestion": "1.13.0", + "@algolia/monitoring": "1.13.0", + "@algolia/recommend": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@docusaurus/babel": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/babel/-/babel-3.6.1.tgz", + "integrity": "sha512-JcKaunW8Ml2nTnfnvFc55T00Y+aCpNWnf1KY/gG+wWxHYDH0IdXOOz+k6NAlEAerW8+VYLfUqRIqHZ7N/DVXvQ==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-transform-runtime": "^7.25.9", + "@babel/preset-env": "^7.25.9", + "@babel/preset-react": "^7.25.9", + "@babel/preset-typescript": "^7.25.9", + "@babel/runtime": "^7.25.9", + "@babel/runtime-corejs3": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@docusaurus/logger": "3.6.1", + "@docusaurus/utils": "3.6.1", + "babel-plugin-dynamic-import-node": "^2.3.3", + "fs-extra": "^11.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@docusaurus/bundler": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/bundler/-/bundler-3.6.1.tgz", + "integrity": "sha512-vHSEx8Ku9x/gfIC6k4xb8J2nTxagLia0KvZkPZhxfkD1+n8i+Dj4BZPWTmv+kCA17RbgAvECG0XRZ0/ZEspQBQ==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.25.9", + "@docusaurus/babel": "3.6.1", + "@docusaurus/cssnano-preset": "3.6.1", + "@docusaurus/logger": "3.6.1", + "@docusaurus/types": "3.6.1", + "@docusaurus/utils": "3.6.1", + "autoprefixer": "^10.4.14", + "babel-loader": "^9.2.1", + "clean-css": "^5.3.2", + "copy-webpack-plugin": "^11.0.0", + "css-loader": "^6.8.1", + "css-minimizer-webpack-plugin": "^5.0.1", + "cssnano": "^6.1.2", + "file-loader": "^6.2.0", + "html-minifier-terser": "^7.2.0", + "mini-css-extract-plugin": "^2.9.1", + "null-loader": "^4.0.1", + "postcss": "^8.4.26", + "postcss-loader": "^7.3.3", + "react-dev-utils": "^12.0.1", + "terser-webpack-plugin": "^5.3.9", + "tslib": "^2.6.0", + "url-loader": "^4.1.1", + "webpack": "^5.95.0", + "webpackbar": "^6.0.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "@docusaurus/faster": "*" + }, + "peerDependenciesMeta": { + "@docusaurus/faster": { + "optional": true + } + } + }, + "node_modules/@docusaurus/core": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.6.1.tgz", + "integrity": "sha512-cDKxPihiM2z7G+4QtpTczS7uxNfNG6naSqM65OmAJET0CFRHbc9mDlLFtQF0lsVES91SHqfcGaaLZmi2FjdwWA==", + "license": "MIT", + "dependencies": { + "@docusaurus/babel": "3.6.1", + "@docusaurus/bundler": "3.6.1", + "@docusaurus/logger": "3.6.1", + "@docusaurus/mdx-loader": "3.6.1", + "@docusaurus/utils": "3.6.1", + "@docusaurus/utils-common": "3.6.1", + "@docusaurus/utils-validation": "3.6.1", + "boxen": "^6.2.1", + "chalk": "^4.1.2", + "chokidar": "^3.5.3", + "cli-table3": "^0.6.3", + "combine-promises": "^1.1.0", + "commander": "^5.1.0", + "core-js": "^3.31.1", + "del": "^6.1.1", + "detect-port": "^1.5.1", + "escape-html": "^1.0.3", + "eta": "^2.2.0", + "eval": "^0.1.8", + "fs-extra": "^11.1.1", + "html-tags": "^3.3.1", + "html-webpack-plugin": "^5.6.0", + "leven": "^3.1.0", + "lodash": "^4.17.21", + "p-map": "^4.0.0", + "prompts": "^2.4.2", + "react-dev-utils": "^12.0.1", + "react-helmet-async": "^1.3.0", + "react-loadable": "npm:@docusaurus/react-loadable@6.0.0", + "react-loadable-ssr-addon-v5-slorber": "^1.0.1", + "react-router": "^5.3.4", + "react-router-config": "^5.1.1", + "react-router-dom": "^5.3.4", + "rtl-detect": "^1.0.4", + "semver": "^7.5.4", + "serve-handler": "^6.1.6", + "shelljs": "^0.8.5", + "tslib": "^2.6.0", + "update-notifier": "^6.0.2", + "webpack": "^5.95.0", + "webpack-bundle-analyzer": "^4.10.2", + "webpack-dev-server": "^4.15.2", + "webpack-merge": "^6.0.1" + }, + "bin": { + "docusaurus": "bin/docusaurus.mjs" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "@mdx-js/react": "^3.0.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/cssnano-preset": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.6.1.tgz", + "integrity": "sha512-ZxYUmNeyQHW2w4/PJ7d07jQDuxzmKr9uPAQ6IVe5dTkeIeV0mDBB3jOLeJkNoI42Ru9JKEqQ9aVDtM9ct6QHnw==", + "license": "MIT", + "dependencies": { + "cssnano-preset-advanced": "^6.1.2", + "postcss": "^8.4.38", + "postcss-sort-media-queries": "^5.2.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@docusaurus/logger": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.6.1.tgz", + "integrity": "sha512-OvetI/nnOMBSqCkUzKAQhnIjhxduECK4qTu3tq/8/h/qqvLsvKURojm04WPE54L+Uy+UXMas0hnbBJd8zDlEOw==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@docusaurus/mdx-loader": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.6.1.tgz", + "integrity": "sha512-KPIsYi0S3X3/rNrW3V1fgOu5t6ahYWc31zTHHod8pacFxdmk9Uf6uuw+Jd6Cly1ilgal+41Ku+s0gmMuqKqiqg==", + "license": "MIT", + "dependencies": { + "@docusaurus/logger": "3.6.1", + "@docusaurus/utils": "3.6.1", + "@docusaurus/utils-validation": "3.6.1", + "@mdx-js/mdx": "^3.0.0", + "@slorber/remark-comment": "^1.0.0", + "escape-html": "^1.0.3", + "estree-util-value-to-estree": "^3.0.1", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "image-size": "^1.0.2", + "mdast-util-mdx": "^3.0.0", + "mdast-util-to-string": "^4.0.0", + "rehype-raw": "^7.0.0", + "remark-directive": "^3.0.0", + "remark-emoji": "^4.0.0", + "remark-frontmatter": "^5.0.0", + "remark-gfm": "^4.0.0", + "stringify-object": "^3.3.0", + "tslib": "^2.6.0", + "unified": "^11.0.3", + "unist-util-visit": "^5.0.0", + "url-loader": "^4.1.1", + "vfile": "^6.0.1", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/module-type-aliases": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.6.1.tgz", + "integrity": "sha512-J+q1jgm7TnEfVIUZImSFeLA1rghb6nwtoB9siHdcgKpDqFJ9/S7xhQL2aEKE7iZMZYzpu+2F390E9A7GkdEJNA==", + "license": "MIT", + "dependencies": { + "@docusaurus/types": "3.6.1", + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router-config": "*", + "@types/react-router-dom": "*", + "react-helmet-async": "*", + "react-loadable": "npm:@docusaurus/react-loadable@6.0.0" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/@docusaurus/plugin-content-blog": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.6.1.tgz", + "integrity": "sha512-FUmsn3xg/XD/K/4FQd8XHrs92aQdZO5LUtpHnRvO1/6DY87SMz6B6ERAN9IGQQld//M2/LVTHkZy8oVhQZQHIQ==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.6.1", + "@docusaurus/logger": "3.6.1", + "@docusaurus/mdx-loader": "3.6.1", + "@docusaurus/theme-common": "3.6.1", + "@docusaurus/types": "3.6.1", + "@docusaurus/utils": "3.6.1", + "@docusaurus/utils-common": "3.6.1", + "@docusaurus/utils-validation": "3.6.1", + "cheerio": "1.0.0-rc.12", + "feed": "^4.2.2", + "fs-extra": "^11.1.1", + "lodash": "^4.17.21", + "reading-time": "^1.5.0", + "srcset": "^4.0.0", + "tslib": "^2.6.0", + "unist-util-visit": "^5.0.0", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "@docusaurus/plugin-content-docs": "*", + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-content-docs": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.6.1.tgz", + "integrity": "sha512-Uq8kyn5DYCDmkUlB9sWChhWghS4lUFNiQU+RXcAXJ3qCVXsBpPsh6RF+npQG1N+j4wAbjydM1iLLJJzp+x3eMQ==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.6.1", + "@docusaurus/logger": "3.6.1", + "@docusaurus/mdx-loader": "3.6.1", + "@docusaurus/module-type-aliases": "3.6.1", + "@docusaurus/theme-common": "3.6.1", + "@docusaurus/types": "3.6.1", + "@docusaurus/utils": "3.6.1", + "@docusaurus/utils-common": "3.6.1", + "@docusaurus/utils-validation": "3.6.1", + "@types/react-router-config": "^5.0.7", + "combine-promises": "^1.1.0", + "fs-extra": "^11.1.1", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "tslib": "^2.6.0", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-content-pages": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.6.1.tgz", + "integrity": "sha512-TZtL+2zq20gqGalzoIT2rEF1T4YCZ26jTvlCJXs78+incIajfdHtmdOq7rQW0oV7oqTjpGllbp788nY/vY9jgw==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.6.1", + "@docusaurus/mdx-loader": "3.6.1", + "@docusaurus/types": "3.6.1", + "@docusaurus/utils": "3.6.1", + "@docusaurus/utils-validation": "3.6.1", + "fs-extra": "^11.1.1", + "tslib": "^2.6.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-debug": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.6.1.tgz", + "integrity": "sha512-DeKPZtoVExDSYCbzoz7y5Dhc6+YPqRWfVGwEEUyKopSyQYefp0OV8hvASmbJCn2WyThRgspOUhog3FSEhz+agw==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.6.1", + "@docusaurus/types": "3.6.1", + "@docusaurus/utils": "3.6.1", + "fs-extra": "^11.1.1", + "react-json-view-lite": "^1.2.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-google-analytics": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.6.1.tgz", + "integrity": "sha512-ZEoERiDHxSfhaEeT35ukQ892NzGHWiUvfxUsnPiRuGEhMoQlxMSp60shBuSZ1sUKuZlndoEl5qAXJg09Wls/Sg==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.6.1", + "@docusaurus/types": "3.6.1", + "@docusaurus/utils-validation": "3.6.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-google-gtag": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.6.1.tgz", + "integrity": "sha512-u/E9vXUsZxYaV6Brvfee8NiH/iR0cMml9P/ifz4EpH/Jfxdbw8rbCT0Nm/h7EFgEY48Uqkl5huSbIvFB9n8aTQ==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.6.1", + "@docusaurus/types": "3.6.1", + "@docusaurus/utils-validation": "3.6.1", + "@types/gtag.js": "^0.0.12", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-google-tag-manager": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.6.1.tgz", + "integrity": "sha512-By+NKkGYV8tSo8/RyS1OXikOtqsko5jJZ/uioJfBjsBGgSbiMJ+Y/HogFBke0mgSvf7NPGKZTbYm5+FJ8YUtPQ==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.6.1", + "@docusaurus/types": "3.6.1", + "@docusaurus/utils-validation": "3.6.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-sitemap": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.6.1.tgz", + "integrity": "sha512-i8R/GTKew4Cufb+7YQTwfPcNOhKTJzZ1VZ5OqQwI9c3pZK2TltQyhqKDVN94KCTbSSKvOYYytYfRAB2uPnH1/A==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.6.1", + "@docusaurus/logger": "3.6.1", + "@docusaurus/types": "3.6.1", + "@docusaurus/utils": "3.6.1", + "@docusaurus/utils-common": "3.6.1", + "@docusaurus/utils-validation": "3.6.1", + "fs-extra": "^11.1.1", + "sitemap": "^7.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/preset-classic": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.6.1.tgz", + "integrity": "sha512-b90Y1XRH9e+oa/E3NmiFEFOwgYUd+knFcZUy81nM3FJs038WbEA0T55NQsuPW0s7nOsCShQ7dVFyKxV+Wp31Nw==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.6.1", + "@docusaurus/plugin-content-blog": "3.6.1", + "@docusaurus/plugin-content-docs": "3.6.1", + "@docusaurus/plugin-content-pages": "3.6.1", + "@docusaurus/plugin-debug": "3.6.1", + "@docusaurus/plugin-google-analytics": "3.6.1", + "@docusaurus/plugin-google-gtag": "3.6.1", + "@docusaurus/plugin-google-tag-manager": "3.6.1", + "@docusaurus/plugin-sitemap": "3.6.1", + "@docusaurus/theme-classic": "3.6.1", + "@docusaurus/theme-common": "3.6.1", + "@docusaurus/theme-search-algolia": "3.6.1", + "@docusaurus/types": "3.6.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/theme-classic": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.6.1.tgz", + "integrity": "sha512-5lVUmIXk7zp+n9Ki2lYWrmhbd6mssOlKCnnDJvY4QDi3EgjRisIu5g4yKXoWTIbiqE7m7q/dS9cbeShEtfkKng==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.6.1", + "@docusaurus/logger": "3.6.1", + "@docusaurus/mdx-loader": "3.6.1", + "@docusaurus/module-type-aliases": "3.6.1", + "@docusaurus/plugin-content-blog": "3.6.1", + "@docusaurus/plugin-content-docs": "3.6.1", + "@docusaurus/plugin-content-pages": "3.6.1", + "@docusaurus/theme-common": "3.6.1", + "@docusaurus/theme-translations": "3.6.1", + "@docusaurus/types": "3.6.1", + "@docusaurus/utils": "3.6.1", + "@docusaurus/utils-common": "3.6.1", + "@docusaurus/utils-validation": "3.6.1", + "@mdx-js/react": "^3.0.0", + "clsx": "^2.0.0", + "copy-text-to-clipboard": "^3.2.0", + "infima": "0.2.0-alpha.45", + "lodash": "^4.17.21", + "nprogress": "^0.2.0", + "postcss": "^8.4.26", + "prism-react-renderer": "^2.3.0", + "prismjs": "^1.29.0", + "react-router-dom": "^5.3.4", + "rtlcss": "^4.1.0", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/theme-common": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.6.1.tgz", + "integrity": "sha512-18iEYNpMvarGfq9gVRpGowSZD24vZ39Iz4acqaj64180i54V9el8tVnhNr/wRvrUm1FY30A1NHLqnMnDz4rYEQ==", + "license": "MIT", + "dependencies": { + "@docusaurus/mdx-loader": "3.6.1", + "@docusaurus/module-type-aliases": "3.6.1", + "@docusaurus/utils": "3.6.1", + "@docusaurus/utils-common": "3.6.1", + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router-config": "*", + "clsx": "^2.0.0", + "parse-numeric-range": "^1.3.0", + "prism-react-renderer": "^2.3.0", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "@docusaurus/plugin-content-docs": "*", + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/theme-search-algolia": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.6.1.tgz", + "integrity": "sha512-BjmuiFRpQP1WEm8Mzu1Bb0Wdas6G65VHXDDNr7XTKgbstxalE6vuxt0ioXTDFS2YVep5748aVhKvnxR9gm2Liw==", + "license": "MIT", + "dependencies": { + "@docsearch/react": "^3.5.2", + "@docusaurus/core": "3.6.1", + "@docusaurus/logger": "3.6.1", + "@docusaurus/plugin-content-docs": "3.6.1", + "@docusaurus/theme-common": "3.6.1", + "@docusaurus/theme-translations": "3.6.1", + "@docusaurus/utils": "3.6.1", + "@docusaurus/utils-validation": "3.6.1", + "algoliasearch": "^4.18.0", + "algoliasearch-helper": "^3.13.3", + "clsx": "^2.0.0", + "eta": "^2.2.0", + "fs-extra": "^11.1.1", + "lodash": "^4.17.21", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/theme-translations": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.6.1.tgz", + "integrity": "sha512-bNm5G6sueUezvyhsBegA1wwM38yW0BnqpZTE9KHO2yKnkERNMaV5x/yPJ/DNCOHjJtCcJ5Uz55g2AS75Go31xA==", + "license": "MIT", + "dependencies": { + "fs-extra": "^11.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@docusaurus/tsconfig": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/tsconfig/-/tsconfig-3.6.1.tgz", + "integrity": "sha512-RvjMG9M9YK8N/I5oudqJed8jjfWGI7csr4XCkGXBToNkkoi2QgkTz2DxH+obKdfLejQaASdIMynYaE5Lv7Qw9Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@docusaurus/types": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.6.1.tgz", + "integrity": "sha512-hCB1hj9DYutVYBisnPNobz9SzEmCcf1EetJv09O49Cov3BqOkm+vnnjB3d957YJMtpLGQoKBeN/FF1DZ830JwQ==", + "license": "MIT", + "dependencies": { + "@mdx-js/mdx": "^3.0.0", + "@types/history": "^4.7.11", + "@types/react": "*", + "commander": "^5.1.0", + "joi": "^17.9.2", + "react-helmet-async": "^1.3.0", + "utility-types": "^3.10.0", + "webpack": "^5.95.0", + "webpack-merge": "^5.9.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/types/node_modules/webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@docusaurus/utils": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.6.1.tgz", + "integrity": "sha512-nS3WCvepwrnBEgSG5vQu40XG95lC9Jeh/odV5u5IhU1eQFEGDst9xBi6IK5yZdsGvbuaXBZLZtOqWYtuuFa/rQ==", + "license": "MIT", + "dependencies": { + "@docusaurus/logger": "3.6.1", + "@docusaurus/types": "3.6.1", + "@docusaurus/utils-common": "3.6.1", + "@svgr/webpack": "^8.1.0", + "escape-string-regexp": "^4.0.0", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "github-slugger": "^1.5.0", + "globby": "^11.1.0", + "gray-matter": "^4.0.3", + "jiti": "^1.20.0", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "micromatch": "^4.0.5", + "prompts": "^2.4.2", + "resolve-pathname": "^3.0.0", + "shelljs": "^0.8.5", + "tslib": "^2.6.0", + "url-loader": "^4.1.1", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@docusaurus/utils-common": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.6.1.tgz", + "integrity": "sha512-LX1qiTiC0aS8c92uZ+Wj2iNCNJyYZJIKY8/nZDKNMBfo759VYVS3RX3fKP3DznB+16sYp7++MyCz/T6fOGaRfw==", + "license": "MIT", + "dependencies": { + "@docusaurus/types": "3.6.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@docusaurus/utils-validation": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.6.1.tgz", + "integrity": "sha512-+iMd6zRl5cJQm7nUP+7pSO/oAXsN79eHO34ME7l2YJt4GEAr70l5kkD58u2jEPpp+wSXT70c7x2A2lzJI1E8jw==", + "license": "MIT", + "dependencies": { + "@docusaurus/logger": "3.6.1", + "@docusaurus/utils": "3.6.1", + "@docusaurus/utils-common": "3.6.1", + "fs-extra": "^11.2.0", + "joi": "^17.9.2", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "license": "MIT" + }, + "node_modules/@mdx-js/mdx": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.0.tgz", + "integrity": "sha512-/QxEhPAvGwbQmy1Px8F899L5Uc2KZ6JtXwlCgJmjSTBedwOZkByYcBG4GceIGPXRDsmfxhHazuS+hlOShRLeDw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdx": "^2.0.0", + "collapse-white-space": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-util-scope": "^1.0.0", + "estree-walker": "^3.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "markdown-extensions": "^2.0.0", + "recma-build-jsx": "^1.0.0", + "recma-jsx": "^1.0.0", + "recma-stringify": "^1.0.0", + "rehype-recma": "^1.0.0", + "remark-mdx": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "source-map": "^0.7.0", + "unified": "^11.0.0", + "unist-util-position-from-estree": "^2.0.0", + "unist-util-stringify-position": "^4.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/react": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.0.tgz", + "integrity": "sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==", + "license": "MIT", + "dependencies": { + "@types/mdx": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=16", + "react": ">=16" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pnpm/config.env-replace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", + "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", + "license": "MIT", + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", + "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", + "license": "MIT", + "dependencies": { + "graceful-fs": "4.2.10" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "license": "ISC" + }, + "node_modules/@pnpm/npm-conf": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.3.1.tgz", + "integrity": "sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==", + "license": "MIT", + "dependencies": { + "@pnpm/config.env-replace": "^1.1.0", + "@pnpm/network.ca-file": "^1.0.1", + "config-chain": "^1.1.11" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.28", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz", + "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==", + "license": "MIT" + }, + "node_modules/@sideway/address": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@sideway/formula": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", + "license": "BSD-3-Clause" + }, + "node_modules/@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "license": "MIT" + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@slorber/remark-comment": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@slorber/remark-comment/-/remark-comment-1.0.0.tgz", + "integrity": "sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==", + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.1.0", + "micromark-util-symbol": "^1.0.1" + } + }, + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", + "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", + "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", + "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", + "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", + "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", + "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-preset": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", + "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", + "license": "MIT", + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", + "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", + "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", + "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", + "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", + "@svgr/babel-plugin-transform-svg-component": "8.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/core": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", + "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^8.1.3", + "snake-case": "^3.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", + "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.21.3", + "entities": "^4.4.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-jsx": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", + "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "@svgr/hast-util-to-babel-ast": "8.0.0", + "svg-parser": "^2.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@svgr/plugin-svgo": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz", + "integrity": "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==", + "license": "MIT", + "dependencies": { + "cosmiconfig": "^8.1.3", + "deepmerge": "^4.3.1", + "svgo": "^3.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@svgr/webpack": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-8.1.0.tgz", + "integrity": "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.21.3", + "@babel/plugin-transform-react-constant-elements": "^7.21.3", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.21.0", + "@svgr/core": "8.1.0", + "@svgr/plugin-jsx": "8.1.0", + "@svgr/plugin-svgo": "8.1.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "license": "MIT", + "dependencies": { + "defer-to-connect": "^2.0.1" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "license": "ISC", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@types/acorn": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", + "integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "license": "MIT", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "license": "MIT" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.1.tgz", + "integrity": "sha512-CRICJIl0N5cXDONAdlTv5ShATZ4HEwk6kDDIW2/w9qOWKg+NU/5F8wYRWCrONad0/UKkloNSmmyN/wX4rtpbVA==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/express/node_modules/@types/express-serve-static-core": { + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/gtag.js": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.12.tgz", + "integrity": "sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg==", + "license": "MIT" + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/history": { + "version": "4.7.11", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", + "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==", + "license": "MIT" + }, + "node_modules/@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", + "license": "MIT" + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "license": "MIT" + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "license": "MIT" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.15", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz", + "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "license": "MIT" + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdx": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", + "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==", + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "license": "MIT" + }, + "node_modules/@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.9.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", + "integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.8" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "license": "MIT" + }, + "node_modules/@types/prismjs": { + "version": "1.26.5", + "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.5.tgz", + "integrity": "sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==", + "license": "MIT" + }, + "node_modules/@types/prop-types": { + "version": "15.7.13", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", + "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==", + "license": "MIT" + }, + "node_modules/@types/qs": { + "version": "6.9.17", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.17.tgz", + "integrity": "sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==", + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.12", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.12.tgz", + "integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==", + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-router": { + "version": "5.1.20", + "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", + "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", + "license": "MIT", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*" + } + }, + "node_modules/@types/react-router-config": { + "version": "5.0.11", + "resolved": "https://registry.npmjs.org/@types/react-router-config/-/react-router-config-5.0.11.tgz", + "integrity": "sha512-WmSAg7WgqW7m4x8Mt4N6ZyKz0BubSj/2tVUMsAHp+Yd2AMwcSbeFq9WympT19p5heCFmF97R9eD5uUR/t4HEqw==", + "license": "MIT", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router": "^5.1.0" + } + }, + "node_modules/@types/react-router-dom": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", + "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", + "license": "MIT", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router": "*" + } + }, + "node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "license": "MIT" + }, + "node_modules/@types/sax": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", + "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "license": "MIT", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "8.5.13", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz", + "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "license": "MIT" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "license": "ISC" + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "license": "Apache-2.0" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/address": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", + "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/algoliasearch": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.24.0.tgz", + "integrity": "sha512-bf0QV/9jVejssFBmz2HQLxUadxk574t4iwjCKp5E7NBzwKkrDEhKPISIIjAU/p6K5qDx3qoeh4+26zWN1jmw3g==", + "license": "MIT", + "dependencies": { + "@algolia/cache-browser-local-storage": "4.24.0", + "@algolia/cache-common": "4.24.0", + "@algolia/cache-in-memory": "4.24.0", + "@algolia/client-account": "4.24.0", + "@algolia/client-analytics": "4.24.0", + "@algolia/client-common": "4.24.0", + "@algolia/client-personalization": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/logger-console": "4.24.0", + "@algolia/recommend": "4.24.0", + "@algolia/requester-browser-xhr": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/requester-node-http": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/algoliasearch-helper": { + "version": "3.22.5", + "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.22.5.tgz", + "integrity": "sha512-lWvhdnc+aKOKx8jyA3bsdEgHzm/sglC4cYdMG4xSQyRiPLJVJtH/IVYZG3Hp6PkTEhQqhyVYkeP9z2IlcHJsWw==", + "license": "MIT", + "dependencies": { + "@algolia/events": "^4.0.1" + }, + "peerDependencies": { + "algoliasearch": ">= 3.1 < 6" + } + }, + "node_modules/algoliasearch/node_modules/@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "license": "MIT", + "dependencies": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/algoliasearch/node_modules/@algolia/client-search": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", + "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/algoliasearch/node_modules/@algolia/requester-browser-xhr": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz", + "integrity": "sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==", + "license": "MIT", + "dependencies": { + "@algolia/requester-common": "4.24.0" + } + }, + "node_modules/algoliasearch/node_modules/@algolia/requester-node-http": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz", + "integrity": "sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==", + "license": "MIT", + "dependencies": { + "@algolia/requester-common": "4.24.0" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "license": "ISC", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-align/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/ansi-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "engines": [ + "node >= 0.8.0" + ], + "license": "Apache-2.0", + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "license": "MIT" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/astring": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", + "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", + "license": "MIT", + "bin": { + "astring": "bin/astring" + } + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/babel-loader": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.2.1.tgz", + "integrity": "sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==", + "license": "MIT", + "dependencies": { + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5" + } + }, + "node_modules/babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "license": "MIT", + "dependencies": { + "object.assign": "^4.1.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.2", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", + "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2", + "core-js-compat": "^3.38.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "license": "MIT" + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/bonjour-service": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", + "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, + "node_modules/boxen": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-6.2.1.tgz", + "integrity": "sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw==", + "license": "MIT", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^6.2.0", + "chalk": "^4.1.2", + "cli-boxes": "^3.0.0", + "string-width": "^5.0.1", + "type-fest": "^2.5.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" + }, + "node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacheable-lookup": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "license": "MIT", + "engines": { + "node": ">=14.16" + } + }, + "node_modules/cacheable-request": { + "version": "10.2.14", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", + "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", + "license": "MIT", + "dependencies": { + "@types/http-cache-semantics": "^4.0.2", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.3", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "license": "MIT", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001680", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz", + "integrity": "sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/cheerio": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/clean-css": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", + "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", + "license": "MIT", + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 10.0" + } + }, + "node_modules/clean-css/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-table3/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/cli-table3/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/collapse-white-space": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", + "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "license": "MIT" + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "license": "MIT" + }, + "node_modules/combine-promises": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/combine-promises/-/combine-promises-1.2.0.tgz", + "integrity": "sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "license": "ISC" + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compressible/node_modules/mime-db": { + "version": "1.53.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.53.0.tgz", + "integrity": "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.5.tgz", + "integrity": "sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.0.2", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" + }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "license": "MIT", + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "node_modules/configstore": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-6.0.0.tgz", + "integrity": "sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==", + "license": "BSD-2-Clause", + "dependencies": { + "dot-prop": "^6.0.1", + "graceful-fs": "^4.2.6", + "unique-string": "^3.0.0", + "write-file-atomic": "^3.0.3", + "xdg-basedir": "^5.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/yeoman/configstore?sponsor=1" + } + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/consola": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.2.3.tgz", + "integrity": "sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==", + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "license": "MIT" + }, + "node_modules/copy-text-to-clipboard": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.0.tgz", + "integrity": "sha512-RnJFp1XR/LOBDckxTib5Qjr/PMfkatD0MUCQgdpqS8MdKiNUzBjAQBEN6oUy+jW7LI93BBG3DtMB2KOOKpGs2Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/copy-webpack-plugin": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", + "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", + "license": "MIT", + "dependencies": { + "fast-glob": "^3.2.11", + "glob-parent": "^6.0.1", + "globby": "^13.1.1", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/globby": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", + "license": "MIT", + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/copy-webpack-plugin/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/core-js": { + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.39.0.tgz", + "integrity": "sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==", + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat": { + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.39.0.tgz", + "integrity": "sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.24.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-pure": { + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.39.0.tgz", + "integrity": "sha512-7fEcWwKI4rJinnK+wLTezeg2smbFFdSBP6E2kQZNbnzM2s1rpKQ6aaRteZSSg7FLU3P0HGGVo/gbpfanU36urg==", + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "license": "MIT", + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cross-spawn": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.5.tgz", + "integrity": "sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", + "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", + "license": "MIT", + "dependencies": { + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/crypto-random-string/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/css-declaration-sorter": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz", + "integrity": "sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==", + "license": "ISC", + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/css-loader": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", + "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==", + "license": "MIT", + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-minimizer-webpack-plugin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-5.0.1.tgz", + "integrity": "sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==", + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "cssnano": "^6.0.1", + "jest-worker": "^29.4.3", + "postcss": "^8.4.24", + "schema-utils": "^4.0.1", + "serialize-javascript": "^6.0.1" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@parcel/css": { + "optional": true + }, + "@swc/css": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "lightningcss": { + "optional": true + } + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", + "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", + "license": "MIT", + "dependencies": { + "cssnano-preset-default": "^6.1.2", + "lilconfig": "^3.1.1" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-preset-advanced": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-6.1.2.tgz", + "integrity": "sha512-Nhao7eD8ph2DoHolEzQs5CfRpiEP0xa1HBdnFZ82kvqdmbwVBUr2r1QuQ4t1pi+D1ZpqpcO4T+wy/7RxzJ/WPQ==", + "license": "MIT", + "dependencies": { + "autoprefixer": "^10.4.19", + "browserslist": "^4.23.0", + "cssnano-preset-default": "^6.1.2", + "postcss-discard-unused": "^6.0.5", + "postcss-merge-idents": "^6.0.3", + "postcss-reduce-idents": "^6.0.3", + "postcss-zindex": "^6.0.2" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-preset-default": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz", + "integrity": "sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "css-declaration-sorter": "^7.2.0", + "cssnano-utils": "^4.0.2", + "postcss-calc": "^9.0.1", + "postcss-colormin": "^6.1.0", + "postcss-convert-values": "^6.1.0", + "postcss-discard-comments": "^6.0.2", + "postcss-discard-duplicates": "^6.0.3", + "postcss-discard-empty": "^6.0.3", + "postcss-discard-overridden": "^6.0.2", + "postcss-merge-longhand": "^6.0.5", + "postcss-merge-rules": "^6.1.1", + "postcss-minify-font-values": "^6.1.0", + "postcss-minify-gradients": "^6.0.3", + "postcss-minify-params": "^6.1.0", + "postcss-minify-selectors": "^6.0.4", + "postcss-normalize-charset": "^6.0.2", + "postcss-normalize-display-values": "^6.0.2", + "postcss-normalize-positions": "^6.0.2", + "postcss-normalize-repeat-style": "^6.0.2", + "postcss-normalize-string": "^6.0.2", + "postcss-normalize-timing-functions": "^6.0.2", + "postcss-normalize-unicode": "^6.1.0", + "postcss-normalize-url": "^6.0.2", + "postcss-normalize-whitespace": "^6.0.2", + "postcss-ordered-values": "^6.0.2", + "postcss-reduce-initial": "^6.1.0", + "postcss-reduce-transforms": "^6.0.2", + "postcss-svgo": "^6.0.3", + "postcss-unique-selectors": "^6.0.4" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-utils": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz", + "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "license": "MIT", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "license": "CC0-1.0" + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", + "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "license": "BSD-2-Clause", + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/del": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", + "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", + "license": "MIT", + "dependencies": { + "globby": "^11.0.1", + "graceful-fs": "^4.2.4", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.2", + "p-map": "^4.0.0", + "rimraf": "^3.0.2", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "license": "MIT" + }, + "node_modules/detect-port": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.6.1.tgz", + "integrity": "sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==", + "license": "MIT", + "dependencies": { + "address": "^1.0.1", + "debug": "4" + }, + "bin": { + "detect": "bin/detect-port.js", + "detect-port": "bin/detect-port.js" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/detect-port-alt": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", + "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", + "license": "MIT", + "dependencies": { + "address": "^1.0.1", + "debug": "^2.6.0" + }, + "bin": { + "detect": "bin/detect-port", + "detect-port": "bin/detect-port" + }, + "engines": { + "node": ">= 4.2.1" + } + }, + "node_modules/detect-port-alt/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/detect-port-alt/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "license": "MIT", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "license": "MIT", + "dependencies": { + "utila": "~0.4" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/dot-prop": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "license": "MIT", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dot-prop/node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "license": "MIT" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.55", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.55.tgz", + "integrity": "sha512-6maZ2ASDOTBtjt9FhqYPRnbvKU5tjG0IN9SztUOWYw2AzNDNpKJYLJmlK0/En4Hs/aiWnB+JZ+gW19PIGszgKg==", + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/emojilib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", + "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", + "license": "MIT" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/emoticon": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/emoticon/-/emoticon-4.1.0.tgz", + "integrity": "sha512-VWZfnxqwNcc51hIy/sbOdEem6D+cVtpPzEEtVAFdaas30+1dgkyaOQ4sQ6Bp0tOMqWO1v+HQfYaoodOkdhK6SQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "license": "MIT" + }, + "node_modules/esast-util-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/esast-util-from-estree/-/esast-util-from-estree-2.0.0.tgz", + "integrity": "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/esast-util-from-js": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esast-util-from-js/-/esast-util-from-js-2.0.1.tgz", + "integrity": "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "acorn": "^8.0.0", + "esast-util-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-goat": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-4.0.0.tgz", + "integrity": "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-util-attach-comments": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", + "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-build-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", + "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-walker": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-scope": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/estree-util-scope/-/estree-util-scope-1.0.0.tgz", + "integrity": "sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-to-js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", + "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "astring": "^1.8.0", + "source-map": "^0.7.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-value-to-estree": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.2.1.tgz", + "integrity": "sha512-Vt2UOjyPbNQQgT5eJh+K5aATti0OjCIAGc9SgMdOFYbohuifsWclR74l0iZTJwePMgWYdX1hlVS+dedH9XV8kw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/remcohaszing" + } + }, + "node_modules/estree-util-visit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", + "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eta": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/eta/-/eta-2.2.0.tgz", + "integrity": "sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "url": "https://github.com/eta-dev/eta?sponsor=1" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eval": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eval/-/eval-0.1.8.tgz", + "integrity": "sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==", + "dependencies": { + "@types/node": "*", + "require-like": ">= 0.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/express": { + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.10", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/express/node_modules/path-to-regexp": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", + "license": "MIT" + }, + "node_modules/express/node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz", + "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==", + "license": "BSD-3-Clause" + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fault": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", + "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", + "license": "MIT", + "dependencies": { + "format": "^0.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/feed": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/feed/-/feed-4.2.2.tgz", + "integrity": "sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==", + "license": "MIT", + "dependencies": { + "xml-js": "^1.6.11" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/file-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/file-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/file-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "license": "MIT" + }, + "node_modules/file-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/filesize": { + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", + "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/find-cache-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", + "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", + "license": "MIT", + "dependencies": { + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "license": "MIT", + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/fork-ts-checker-webpack-plugin": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", + "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@types/json-schema": "^7.0.5", + "chalk": "^4.1.0", + "chokidar": "^3.4.2", + "cosmiconfig": "^6.0.0", + "deepmerge": "^4.2.2", + "fs-extra": "^9.0.0", + "glob": "^7.1.6", + "memfs": "^3.1.2", + "minimatch": "^3.0.4", + "schema-utils": "2.7.0", + "semver": "^7.3.2", + "tapable": "^1.0.0" + }, + "engines": { + "node": ">=10", + "yarn": ">=1.0.0" + }, + "peerDependencies": { + "eslint": ">= 6", + "typescript": ">= 2.7", + "vue-template-compiler": "*", + "webpack": ">= 4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + }, + "vue-template-compiler": { + "optional": true + } + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "license": "MIT" + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/form-data-encoder": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", + "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", + "license": "MIT", + "engines": { + "node": ">= 14.17" + } + }, + "node_modules/format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs-monkey": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", + "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==", + "license": "Unlicense" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "license": "ISC" + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/github-slugger": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", + "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==", + "license": "ISC" + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "license": "BSD-2-Clause" + }, + "node_modules/global-dirs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", + "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", + "license": "MIT", + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/global-dirs/node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "license": "MIT", + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "license": "MIT", + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", + "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.8", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/got/node_modules/@sindresorhus/is": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", + "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/gray-matter": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", + "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "license": "MIT", + "dependencies": { + "js-yaml": "^3.13.1", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/gray-matter/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/gray-matter/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "license": "MIT", + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-yarn": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-3.0.0.tgz", + "integrity": "sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz", + "integrity": "sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^8.0.0", + "property-information": "^6.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.0.4.tgz", + "integrity": "sha512-LHE65TD2YiNsHD3YuXcKPHXPLuYh/gjp12mOfU8jxSrm1f/yJpsb0F/KKljS6U9LJoP0Ux+tCe8iJ2AsPzTdgA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-estree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.0.tgz", + "integrity": "sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-attach-comments": "^3.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^0.4.0", + "unist-util-position": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-estree/node_modules/inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==", + "license": "MIT" + }, + "node_modules/hast-util-to-estree/node_modules/style-to-object": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", + "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.1.1" + } + }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.2.tgz", + "integrity": "sha512-1ngXYb+V9UT5h+PxNRa1O1FYguZK/XL+gkeqvp7EdHlB9oHUG0eYRo/vY5inBdcqo3RkPMC58/H94HvkbfGdyg==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-parse5": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", + "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", + "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-entities": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "license": "MIT" + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "license": "MIT" + }, + "node_modules/html-minifier-terser": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", + "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", + "license": "MIT", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "~5.3.2", + "commander": "^10.0.0", + "entities": "^4.4.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.15.1" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": "^14.13.1 || >=16.0.0" + } + }, + "node_modules/html-minifier-terser/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/html-tags": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/html-webpack-plugin": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.3.tgz", + "integrity": "sha512-QSf1yjtSAsmf7rYBV7XX86uua4W/vkhIt0xNXKbsi2foEeW7vjJQz4bhnpL3xH+l1ryl1680uNv968Z+X6jSYg==", + "license": "MIT", + "dependencies": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/html-webpack-plugin" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.20.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/html-webpack-plugin/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/html-webpack-plugin/node_modules/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "license": "MIT", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "license": "BSD-2-Clause" + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "license": "MIT" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "license": "MIT" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-middleware": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", + "license": "MIT", + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/http-proxy-middleware/node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/http2-wrapper": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "license": "MIT", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/image-size": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.1.1.tgz", + "integrity": "sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==", + "license": "MIT", + "dependencies": { + "queue": "6.0.2" + }, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=16.x" + } + }, + "node_modules/immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/infima": { + "version": "0.2.0-alpha.45", + "resolved": "https://registry.npmjs.org/infima/-/infima-0.2.0-alpha.45.tgz", + "integrity": "sha512-uyH0zfr1erU1OohLk0fT4Rrb94AOhguWNOcD9uGrSpRvNB+6gZXUoJX5J0NtvzBO10YZ9PgvA4NFgt+fYg8ojw==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/inline-style-parser": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz", + "integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==", + "license": "MIT" + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "license": "MIT", + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "license": "MIT", + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-npm": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.0.0.tgz", + "integrity": "sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-root": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", + "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "license": "MIT" + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-yarn-global": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz", + "integrity": "sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/joi": { + "version": "17.13.3", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", + "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.5", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/latest-version": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", + "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", + "license": "MIT", + "dependencies": { + "package-json": "^8.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/launch-editor": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.9.1.tgz", + "integrity": "sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==", + "license": "MIT", + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/lilconfig": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "license": "MIT", + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "license": "MIT", + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "license": "MIT" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "license": "MIT" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "license": "MIT" + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/markdown-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", + "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-directive": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.0.0.tgz", + "integrity": "sha512-JUpYOqKI4mM3sZcNxmF/ox04XYFFkNwr0CFlrQIkCwbvH0xzMCqkMqAde9wRd80VAhaUrwFwKm2nxretdT1h7Q==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz", + "integrity": "sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/mdast-util-frontmatter": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", + "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "escape-string-regexp": "^5.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-frontmatter/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz", + "integrity": "sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz", + "integrity": "sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", + "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", + "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.3.tgz", + "integrity": "sha512-bfOjvNt+1AcbPLTFMFWY149nJz0OjmewJs3LQQ5pIyVGxP4CdOqNVJL6kTaM5c68p8q82Xv3nCyFfUnuEcH3UQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", + "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "license": "CC0-1.0" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "license": "Unlicense", + "dependencies": { + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromark": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", + "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz", + "integrity": "sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-directive": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.2.tgz", + "integrity": "sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "parse-entities": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-frontmatter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz", + "integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==", + "license": "MIT", + "dependencies": { + "fault": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.0.tgz", + "integrity": "sha512-Ub2ncQv+fwD70/l4ou27b4YzfNaCJOvyX4HxXU15m7mpYY+rjuWzsLIPZHJL253Z643RpbcP1oeIJlQ/SKW67g==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-mdx-expression": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.0.tgz", + "integrity": "sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-mdx-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.1.tgz", + "integrity": "sha512-vNuFb9czP8QCtAQcEJn0UJQJZA8Dk6DXKBqx+bg/w0WGuSxDxNr7hErW89tHUY31dUW4NqEOWwmEUNhjTFmHkg==", + "license": "MIT", + "dependencies": { + "@types/acorn": "^4.0.0", + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-mdx-md": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", + "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", + "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", + "license": "MIT", + "dependencies": { + "acorn": "^8.0.0", + "acorn-jsx": "^5.0.0", + "micromark-extension-mdx-expression": "^3.0.0", + "micromark-extension-mdx-jsx": "^3.0.0", + "micromark-extension-mdx-md": "^2.0.0", + "micromark-extension-mdxjs-esm": "^3.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", + "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", + "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-destination/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-destination/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-label": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", + "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-mdx-expression": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.2.tgz", + "integrity": "sha512-5E5I2pFzJyg2CtemqAbcyCktpHXuJbABnsb32wX2U8IQKhhVFBqkcZR5LRm1WVoFqa4kTueZK4abep7wdo9nrw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-space": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", + "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-space/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-title": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", + "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", + "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-character/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", + "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", + "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", + "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", + "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", + "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", + "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-events-to-acorn": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.2.tgz", + "integrity": "sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/acorn": "^4.0.0", + "@types/estree": "^1.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-util-events-to-acorn/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", + "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", + "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-normalize-identifier/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", + "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", + "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz", + "integrity": "sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", + "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "license": "MIT", + "dependencies": { + "mime-db": "~1.33.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz", + "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==", + "license": "MIT", + "dependencies": { + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mrmime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "license": "MIT", + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "license": "MIT" + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "license": "MIT", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-emoji": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", + "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^4.6.0", + "char-regex": "^1.0.2", + "emojilib": "^2.4.0", + "skin-tone": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz", + "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nprogress": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", + "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==", + "license": "MIT" + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/null-loader": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/null-loader/-/null-loader-4.0.1.tgz", + "integrity": "sha512-pxqVbi4U6N26lq+LmgIbB5XATP0VdZKOG25DhHi8btMmJJefGArFyDg1yc4U3hWCJbMqSrw0qyrz1UQX+qYXqg==", + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/null-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/null-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/null-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "license": "MIT" + }, + "node_modules/null-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "license": "MIT" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "license": "(WTFPL OR MIT)", + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/p-cancelable": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "license": "MIT", + "engines": { + "node": ">=12.20" + } + }, + "node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "license": "MIT", + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "license": "MIT", + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz", + "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==", + "license": "MIT", + "dependencies": { + "got": "^12.1.0", + "registry-auth-token": "^5.0.1", + "registry-url": "^6.0.0", + "semver": "^7.3.7" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-entities": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz", + "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-numeric-range": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", + "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==", + "license": "ISC" + }, + "node_modules/parse5": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", + "license": "MIT", + "dependencies": { + "entities": "^4.5.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", + "license": "(WTFPL OR MIT)" + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-to-regexp": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", + "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", + "license": "MIT", + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "license": "MIT", + "dependencies": { + "find-up": "^6.3.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "license": "MIT", + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-up/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "license": "MIT", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "license": "MIT", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-up/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "license": "MIT", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss": { + "version": "8.4.48", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.48.tgz", + "integrity": "sha512-GCRK8F6+Dl7xYniR5a4FYbpBzU8XnZVeowqsQFYdcXuSbChgiks7qybSkbvnaeqv0G0B+dd9/jJgH8kkLDQeEA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-calc": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", + "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.11", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.2" + } + }, + "node_modules/postcss-colormin": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.1.0.tgz", + "integrity": "sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0", + "colord": "^2.9.3", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-convert-values": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.1.0.tgz", + "integrity": "sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-comments": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.2.tgz", + "integrity": "sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.3.tgz", + "integrity": "sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-empty": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.3.tgz", + "integrity": "sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.2.tgz", + "integrity": "sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-unused": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-6.0.5.tgz", + "integrity": "sha512-wHalBlRHkaNnNwfC8z+ppX57VhvS+HWgjW508esjdaEYr3Mx7Gnn2xA4R/CKf5+Z9S5qsqC+Uzh4ueENWwCVUA==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-loader": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.4.tgz", + "integrity": "sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A==", + "license": "MIT", + "dependencies": { + "cosmiconfig": "^8.3.5", + "jiti": "^1.20.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + } + }, + "node_modules/postcss-merge-idents": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-6.0.3.tgz", + "integrity": "sha512-1oIoAsODUs6IHQZkLQGO15uGEbK3EAl5wi9SS8hs45VgsxQfMnxvt+L+zIr7ifZFIH14cfAeVe2uCTa+SPRa3g==", + "license": "MIT", + "dependencies": { + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-merge-longhand": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.5.tgz", + "integrity": "sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^6.1.1" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-merge-rules": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.1.1.tgz", + "integrity": "sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^4.0.2", + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.1.0.tgz", + "integrity": "sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.3.tgz", + "integrity": "sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==", + "license": "MIT", + "dependencies": { + "colord": "^2.9.3", + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-params": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.1.0.tgz", + "integrity": "sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.4.tgz", + "integrity": "sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", + "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", + "license": "MIT", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", + "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "license": "ISC", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.2.tgz", + "integrity": "sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.2.tgz", + "integrity": "sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-positions": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.2.tgz", + "integrity": "sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.2.tgz", + "integrity": "sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-string": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.2.tgz", + "integrity": "sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.2.tgz", + "integrity": "sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-unicode": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.1.0.tgz", + "integrity": "sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-url": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.2.tgz", + "integrity": "sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-whitespace": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.2.tgz", + "integrity": "sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-ordered-values": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.2.tgz", + "integrity": "sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==", + "license": "MIT", + "dependencies": { + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-reduce-idents": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-6.0.3.tgz", + "integrity": "sha512-G3yCqZDpsNPoQgbDUy3T0E6hqOQ5xigUtBQyrmq3tn2GxlyiL0yyl7H+T8ulQR6kOcHJ9t7/9H4/R2tv8tJbMA==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.1.0.tgz", + "integrity": "sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.2.tgz", + "integrity": "sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-sort-media-queries": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-5.2.0.tgz", + "integrity": "sha512-AZ5fDMLD8SldlAYlvi8NIqo0+Z8xnXU2ia0jxmuhxAU+Lqt9K+AlmLNJ/zWEnE9x+Zx3qL3+1K20ATgNOr3fAA==", + "license": "MIT", + "dependencies": { + "sort-css-media-queries": "2.2.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.4.23" + } + }, + "node_modules/postcss-svgo": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.3.tgz", + "integrity": "sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "svgo": "^3.2.0" + }, + "engines": { + "node": "^14 || ^16 || >= 18" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.4.tgz", + "integrity": "sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "license": "MIT" + }, + "node_modules/postcss-zindex": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-6.0.2.tgz", + "integrity": "sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/pretty-error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", + "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "node_modules/pretty-time": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", + "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/prism-react-renderer": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.4.0.tgz", + "integrity": "sha512-327BsVCD/unU4CNLZTWVHyUHKnsqcvj2qbPlQ8MiBE2eq2rgctjigPA1Gp9HLF83kZ20zNN6jgizHJeEsyFYOw==", + "license": "MIT", + "dependencies": { + "@types/prismjs": "^1.26.0", + "clsx": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.0.0" + } + }, + "node_modules/prismjs": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/property-information": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "license": "ISC" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pupa": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.1.0.tgz", + "integrity": "sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==", + "license": "MIT", + "dependencies": { + "escape-goat": "^4.0.0" + }, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", + "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", + "license": "MIT", + "dependencies": { + "inherits": "~2.0.3" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dev-utils": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", + "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.16.0", + "address": "^1.1.2", + "browserslist": "^4.18.1", + "chalk": "^4.1.2", + "cross-spawn": "^7.0.3", + "detect-port-alt": "^1.1.6", + "escape-string-regexp": "^4.0.0", + "filesize": "^8.0.6", + "find-up": "^5.0.0", + "fork-ts-checker-webpack-plugin": "^6.5.0", + "global-modules": "^2.0.0", + "globby": "^11.0.4", + "gzip-size": "^6.0.0", + "immer": "^9.0.7", + "is-root": "^2.1.0", + "loader-utils": "^3.2.0", + "open": "^8.4.0", + "pkg-up": "^3.1.0", + "prompts": "^2.4.2", + "react-error-overlay": "^6.0.11", + "recursive-readdir": "^2.2.2", + "shell-quote": "^1.7.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/react-dev-utils/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/node_modules/loader-utils": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", + "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/react-dev-utils/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/react-dev-utils/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-error-overlay": { + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", + "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==", + "license": "MIT" + }, + "node_modules/react-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", + "license": "MIT" + }, + "node_modules/react-helmet-async": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.3.0.tgz", + "integrity": "sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "invariant": "^2.2.4", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.2.0", + "shallowequal": "^1.1.0" + }, + "peerDependencies": { + "react": "^16.6.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/react-json-view-lite": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-1.5.0.tgz", + "integrity": "sha512-nWqA1E4jKPklL2jvHWs6s+7Na0qNgw9HCP6xehdQJeg6nPBTFZgGwyko9Q0oj+jQWKTTVRS30u0toM5wiuL3iw==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-loadable": { + "name": "@docusaurus/react-loadable", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz", + "integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==", + "license": "MIT", + "dependencies": { + "@types/react": "*" + }, + "peerDependencies": { + "react": "*" + } + }, + "node_modules/react-loadable-ssr-addon-v5-slorber": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz", + "integrity": "sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.3" + }, + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "react-loadable": "*", + "webpack": ">=4.41.1 || 5.x" + } + }, + "node_modules/react-router": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", + "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.13", + "history": "^4.9.0", + "hoist-non-react-statics": "^3.1.0", + "loose-envify": "^1.3.1", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.2", + "react-is": "^16.6.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/react-router-config": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/react-router-config/-/react-router-config-5.1.1.tgz", + "integrity": "sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.1.2" + }, + "peerDependencies": { + "react": ">=15", + "react-router": ">=5" + } + }, + "node_modules/react-router-dom": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", + "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.13", + "history": "^4.9.0", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-router": "5.3.4", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/reading-time": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/reading-time/-/reading-time-1.5.0.tgz", + "integrity": "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==", + "license": "MIT" + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/recma-build-jsx": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz", + "integrity": "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-build-jsx": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-jsx": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-jsx/-/recma-jsx-1.0.0.tgz", + "integrity": "sha512-5vwkv65qWwYxg+Atz95acp8DMu1JDSqdGkA2Of1j6rCreyFUE/gp15fC8MnGEuG1W68UKjM6x6+YTWIh7hZM/Q==", + "license": "MIT", + "dependencies": { + "acorn-jsx": "^5.0.0", + "estree-util-to-js": "^2.0.0", + "recma-parse": "^1.0.0", + "recma-stringify": "^1.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-parse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-parse/-/recma-parse-1.0.0.tgz", + "integrity": "sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "esast-util-from-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-stringify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-stringify/-/recma-stringify-1.0.0.tgz", + "integrity": "sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-to-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "license": "MIT", + "dependencies": { + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", + "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regexpu-core": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.1.1.tgz", + "integrity": "sha512-k67Nb9jvwJcJmVpw0jPttR1/zVfnKf8Km0IPatrU/zJ5XeG3+Slx0xLXs9HByJSzXzrlz5EDvN6yLNMDc2qdnw==", + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.0", + "regjsgen": "^0.8.0", + "regjsparser": "^0.11.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/registry-auth-token": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", + "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", + "license": "MIT", + "dependencies": { + "@pnpm/npm-conf": "^2.1.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/registry-url": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", + "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", + "license": "MIT", + "dependencies": { + "rc": "1.2.8" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.11.2.tgz", + "integrity": "sha512-3OGZZ4HoLJkkAZx/48mTXJNlmqTGOzc0o9OWQPuWpkOlXXPbyN6OafCcoXUnBqE2D3f/T5L+pWc1kdEmnfnRsA==", + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~3.0.2" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/rehype-raw": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-recma": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rehype-recma/-/rehype-recma-1.0.0.tgz", + "integrity": "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "hast-util-to-estree": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/remark-directive": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.0.tgz", + "integrity": "sha512-l1UyWJ6Eg1VPU7Hm/9tt0zKtReJQNOA4+iDMAxTyZNWnJnFlbS/7zhiel/rogTLQ2vMYwDzSJa4BiVNqGlqIMA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-directive": "^3.0.0", + "micromark-extension-directive": "^3.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-emoji": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-emoji/-/remark-emoji-4.0.1.tgz", + "integrity": "sha512-fHdvsTR1dHkWKev9eNyhTo4EFwbUvJ8ka9SgeWkMPYFX4WoI7ViVBms3PjlQYgw5TLvNQso3GUB/b/8t3yo+dg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.2", + "emoticon": "^4.0.1", + "mdast-util-find-and-replace": "^3.0.1", + "node-emoji": "^2.1.0", + "unified": "^11.0.4" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/remark-frontmatter": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz", + "integrity": "sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-frontmatter": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz", + "integrity": "sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-mdx": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.1.0.tgz", + "integrity": "sha512-Ngl/H3YXyBV9RcRNdlYsZujAmhsxwzxpDzpDEhFBVAGthS4GDgnctpDjgFl/ULx5UEDzqtW1cyBSNKqYYrqLBA==", + "license": "MIT", + "dependencies": { + "mdast-util-mdx": "^3.0.0", + "micromark-extension-mdxjs": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.1.tgz", + "integrity": "sha512-g/osARvjkBXb6Wo0XvAeXQohVta8i84ACbenPpoSsxTOQH/Ae0/RGP4WZgnMH5pMLpsj4FG7OHmcIcXxpza8eQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/renderkid": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", + "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", + "license": "MIT", + "dependencies": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.1" + } + }, + "node_modules/renderkid/node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/renderkid/node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-like": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", + "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", + "engines": { + "node": "*" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "license": "MIT" + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==", + "license": "MIT" + }, + "node_modules/responselike": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", + "license": "MIT", + "dependencies": { + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rtl-detect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/rtl-detect/-/rtl-detect-1.1.2.tgz", + "integrity": "sha512-PGMBq03+TTG/p/cRB7HCLKJ1MgDIi07+QU1faSjiYRfmY5UsAttV9Hs08jDAHVwcOwmVLcSJkpwyfXszVjWfIQ==", + "license": "BSD-3-Clause" + }, + "node_modules/rtlcss": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.3.0.tgz", + "integrity": "sha512-FI+pHEn7Wc4NqKXMXFM+VAYKEj/mRIcW4h24YVwVtyjI+EqGrLc2Hx/Ny0lrZ21cBWU2goLy36eqMcNj3AQJig==", + "license": "MIT", + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0", + "postcss": "^8.4.21", + "strip-json-comments": "^3.1.1" + }, + "bin": { + "rtlcss": "bin/rtlcss.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "license": "ISC" + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/search-insights": { + "version": "2.17.2", + "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.2.tgz", + "integrity": "sha512-zFNpOpUO+tY2D85KrxJ+aqwnIfdEGi06UH2+xEb+Bp9Mwznmauqc9djbnBibJO5mpfUPPa8st6Sx65+vbeO45g==", + "license": "MIT", + "peer": true + }, + "node_modules/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "license": "MIT" + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "license": "MIT", + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", + "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-handler": { + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.6.tgz", + "integrity": "sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==", + "license": "MIT", + "dependencies": { + "bytes": "3.0.0", + "content-disposition": "0.5.2", + "mime-types": "2.1.18", + "minimatch": "3.1.2", + "path-is-inside": "1.0.2", + "path-to-regexp": "3.3.0", + "range-parser": "1.2.0" + } + }, + "node_modules/serve-handler/node_modules/path-to-regexp": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz", + "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==", + "license": "MIT" + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "license": "ISC" + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "license": "ISC" + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "license": "BSD-3-Clause", + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" + }, + "node_modules/sirv": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", + "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT" + }, + "node_modules/sitemap": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.2.tgz", + "integrity": "sha512-ARCqzHJ0p4gWt+j7NlU5eDlIO9+Rkr/JhPFZKKQ1l5GCus7rJH4UdrlVAh0xC/gDS/Qir2UMxqYNHtsKr2rpCw==", + "license": "MIT", + "dependencies": { + "@types/node": "^17.0.5", + "@types/sax": "^1.2.1", + "arg": "^5.0.0", + "sax": "^1.2.4" + }, + "bin": { + "sitemap": "dist/cli.js" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.6.0" + } + }, + "node_modules/sitemap/node_modules/@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", + "license": "MIT" + }, + "node_modules/skin-tone": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", + "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", + "license": "MIT", + "dependencies": { + "unicode-emoji-modifier-base": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "license": "MIT", + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/sort-css-media-queries": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.2.0.tgz", + "integrity": "sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==", + "license": "MIT", + "engines": { + "node": ">= 6.3.0" + } + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "license": "BSD-3-Clause" + }, + "node_modules/srcset": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz", + "integrity": "sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/std-env": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz", + "integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==", + "license": "MIT" + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "license": "BSD-2-Clause", + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-to-object": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.8.tgz", + "integrity": "sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.2.4" + } + }, + "node_modules/stylehacks": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.1.1.tgz", + "integrity": "sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", + "license": "MIT" + }, + "node_modules/svgo": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", + "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", + "license": "MIT", + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^5.1.0", + "css-tree": "^2.3.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/svgo/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.36.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.36.0.tgz", + "integrity": "sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==", + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/terser-webpack-plugin/node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "license": "MIT" + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser-webpack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "license": "MIT" + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "license": "MIT" + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "license": "MIT" + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", + "license": "MIT" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "license": "MIT", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-emoji-modifier-base": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", + "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", + "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unique-string": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", + "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", + "license": "MIT", + "dependencies": { + "crypto-random-string": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", + "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/update-notifier": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-6.0.2.tgz", + "integrity": "sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==", + "license": "BSD-2-Clause", + "dependencies": { + "boxen": "^7.0.0", + "chalk": "^5.0.1", + "configstore": "^6.0.0", + "has-yarn": "^3.0.0", + "import-lazy": "^4.0.0", + "is-ci": "^3.0.1", + "is-installed-globally": "^0.4.0", + "is-npm": "^6.0.0", + "is-yarn-global": "^0.4.0", + "latest-version": "^7.0.0", + "pupa": "^3.1.0", + "semver": "^7.3.7", + "semver-diff": "^4.0.0", + "xdg-basedir": "^5.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/yeoman/update-notifier?sponsor=1" + } + }, + "node_modules/update-notifier/node_modules/boxen": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", + "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", + "license": "MIT", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^7.0.1", + "chalk": "^5.2.0", + "cli-boxes": "^3.0.0", + "string-width": "^5.1.2", + "type-fest": "^2.13.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-notifier/node_modules/camelcase": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", + "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-notifier/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-loader": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", + "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "mime-types": "^2.1.27", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "file-loader": "*", + "webpack": "^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "file-loader": { + "optional": true + } + } + }, + "node_modules/url-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/url-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/url-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "license": "MIT" + }, + "node_modules/url-loader/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/url-loader/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/url-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", + "license": "MIT" + }, + "node_modules/utility-types": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", + "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/value-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==", + "license": "MIT" + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/watchpack": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "license": "MIT", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "license": "MIT", + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/webpack": { + "version": "5.96.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.96.1.tgz", + "integrity": "sha512-l2LlBSvVZGhL4ZrPwyr8+37AunkcYj5qh8o6u2/2rzoPc8gxFJkLj1WxNgooi9pnoc06jh0BjuXnamM4qlujZA==", + "license": "MIT", + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-bundle-analyzer": { + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz", + "integrity": "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==", + "license": "MIT", + "dependencies": { + "@discoveryjs/json-ext": "0.5.7", + "acorn": "^8.0.4", + "acorn-walk": "^8.0.0", + "commander": "^7.2.0", + "debounce": "^1.2.1", + "escape-string-regexp": "^4.0.0", + "gzip-size": "^6.0.0", + "html-escaper": "^2.0.2", + "opener": "^1.5.2", + "picocolors": "^1.0.0", + "sirv": "^2.0.3", + "ws": "^7.3.1" + }, + "bin": { + "webpack-bundle-analyzer": "lib/bin/analyzer.js" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/webpack-bundle-analyzer/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/webpack-dev-middleware": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", + "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", + "license": "MIT", + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^3.4.3", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/webpack-dev-middleware/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-middleware/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-middleware/node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-server": { + "version": "4.15.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz", + "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", + "license": "MIT", + "dependencies": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.5", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.4", + "ws": "^8.13.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.37.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/webpack-merge": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", + "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/webpack/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "license": "MIT" + }, + "node_modules/webpack/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpackbar": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-6.0.1.tgz", + "integrity": "sha512-TnErZpmuKdwWBdMoexjio3KKX6ZtoKHRVvLIU0A47R0VVBDtx3ZyOJDktgYixhoJokZTYTt1Z37OkO9pnGJa9Q==", + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "consola": "^3.2.3", + "figures": "^3.2.0", + "markdown-table": "^2.0.0", + "pretty-time": "^1.1.0", + "std-env": "^3.7.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=14.21.3" + }, + "peerDependencies": { + "webpack": "3 || 4 || 5" + } + }, + "node_modules/webpackbar/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/webpackbar/node_modules/markdown-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", + "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", + "license": "MIT", + "dependencies": { + "repeat-string": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/webpackbar/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/webpackbar/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/widest-line": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", + "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", + "license": "MIT", + "dependencies": { + "string-width": "^5.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xdg-basedir": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", + "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/xml-js": { + "version": "1.6.11", + "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", + "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", + "license": "MIT", + "dependencies": { + "sax": "^1.2.4" + }, + "bin": { + "xml-js": "bin/cli.js" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "license": "ISC" + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yocto-queue": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/leetcode_101/package.json b/leetcode_101/package.json new file mode 100644 index 00000000..153a4db7 --- /dev/null +++ b/leetcode_101/package.json @@ -0,0 +1,47 @@ +{ + "name": "leetcode-101", + "version": "0.0.0", + "private": true, + "scripts": { + "docusaurus": "docusaurus", + "start": "docusaurus start", + "build": "docusaurus build", + "swizzle": "docusaurus swizzle", + "deploy": "docusaurus deploy", + "clear": "docusaurus clear", + "serve": "docusaurus serve", + "write-translations": "docusaurus write-translations", + "write-heading-ids": "docusaurus write-heading-ids", + "typecheck": "tsc" + }, + "dependencies": { + "@docusaurus/core": "3.6.1", + "@docusaurus/preset-classic": "3.6.1", + "@mdx-js/react": "^3.0.0", + "clsx": "^2.0.0", + "prism-react-renderer": "^2.3.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "devDependencies": { + "@docusaurus/module-type-aliases": "3.6.1", + "@docusaurus/tsconfig": "3.6.1", + "@docusaurus/types": "3.6.1", + "typescript": "~5.6.2" + }, + "browserslist": { + "production": [ + ">0.5%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 3 chrome version", + "last 3 firefox version", + "last 5 safari version" + ] + }, + "engines": { + "node": ">=18.0" + } +} diff --git a/leetcode_101/sidebars.ts b/leetcode_101/sidebars.ts new file mode 100644 index 00000000..574ed394 --- /dev/null +++ b/leetcode_101/sidebars.ts @@ -0,0 +1,33 @@ +import type { SidebarsConfig } from "@docusaurus/plugin-content-docs"; + +// This runs in Node.js - Don't use client-side code here (browser APIs, JSX...) + +/** + * Creating a sidebar enables you to: + - create an ordered group of docs + - render a sidebar for each doc of that group + - provide next/previous navigation + + The sidebars can be generated from the filesystem, or explicitly defined here. + + Create as many sidebars as you want. + */ +const sidebars: SidebarsConfig = { + // By default, Docusaurus generates a sidebar from the docs folder structure + tutorialSidebar: [{ type: "autogenerated", dirName: "." }], + + // But you can create a sidebar manually + /* + tutorialSidebar: [ + 'intro', + 'hello', + { + type: 'category', + label: 'Tutorial', + items: ['tutorial-basics/create-a-document'], + }, + ], + */ +}; + +export default sidebars; diff --git a/leetcode_101/src/components/HomepageFeatures/index.tsx b/leetcode_101/src/components/HomepageFeatures/index.tsx new file mode 100644 index 00000000..50a9e6f4 --- /dev/null +++ b/leetcode_101/src/components/HomepageFeatures/index.tsx @@ -0,0 +1,70 @@ +import clsx from 'clsx'; +import Heading from '@theme/Heading'; +import styles from './styles.module.css'; + +type FeatureItem = { + title: string; + Svg: React.ComponentType>; + description: JSX.Element; +}; + +const FeatureList: FeatureItem[] = [ + { + title: 'Easy to Use', + Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default, + description: ( + <> + Docusaurus was designed from the ground up to be easily installed and + used to get your website up and running quickly. + + ), + }, + { + title: 'Focus on What Matters', + Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default, + description: ( + <> + Docusaurus lets you focus on your docs, and we'll do the chores. Go + ahead and move your docs into the docs directory. + + ), + }, + { + title: 'Powered by React', + Svg: require('@site/static/img/undraw_docusaurus_react.svg').default, + description: ( + <> + Extend or customize your website layout by reusing React. Docusaurus can + be extended while reusing the same header and footer. + + ), + }, +]; + +function Feature({title, Svg, description}: FeatureItem) { + return ( +
+
+ +
+
+ {title} +

{description}

+
+
+ ); +} + +export default function HomepageFeatures(): JSX.Element { + return ( +
+
+
+ {FeatureList.map((props, idx) => ( + + ))} +
+
+
+ ); +} diff --git a/leetcode_101/src/components/HomepageFeatures/styles.module.css b/leetcode_101/src/components/HomepageFeatures/styles.module.css new file mode 100644 index 00000000..b248eb2e --- /dev/null +++ b/leetcode_101/src/components/HomepageFeatures/styles.module.css @@ -0,0 +1,11 @@ +.features { + display: flex; + align-items: center; + padding: 2rem 0; + width: 100%; +} + +.featureSvg { + height: 200px; + width: 200px; +} diff --git a/leetcode_101/src/css/custom.css b/leetcode_101/src/css/custom.css new file mode 100644 index 00000000..2bc6a4cf --- /dev/null +++ b/leetcode_101/src/css/custom.css @@ -0,0 +1,30 @@ +/** + * Any CSS included here will be global. The classic template + * bundles Infima by default. Infima is a CSS framework designed to + * work well for content-centric websites. + */ + +/* You can override the default Infima variables here. */ +:root { + --ifm-color-primary: #2e8555; + --ifm-color-primary-dark: #29784c; + --ifm-color-primary-darker: #277148; + --ifm-color-primary-darkest: #205d3b; + --ifm-color-primary-light: #33925d; + --ifm-color-primary-lighter: #359962; + --ifm-color-primary-lightest: #3cad6e; + --ifm-code-font-size: 95%; + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); +} + +/* For readability concerns, you should choose a lighter palette in dark mode. */ +[data-theme='dark'] { + --ifm-color-primary: #25c2a0; + --ifm-color-primary-dark: #21af90; + --ifm-color-primary-darker: #1fa588; + --ifm-color-primary-darkest: #1a8870; + --ifm-color-primary-light: #29d5b0; + --ifm-color-primary-lighter: #32d8b4; + --ifm-color-primary-lightest: #4fddbf; + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); +} diff --git a/leetcode_101/src/pages/index.module.css b/leetcode_101/src/pages/index.module.css new file mode 100644 index 00000000..9f71a5da --- /dev/null +++ b/leetcode_101/src/pages/index.module.css @@ -0,0 +1,23 @@ +/** + * CSS files with the .module.css suffix will be treated as CSS modules + * and scoped locally. + */ + +.heroBanner { + padding: 4rem 0; + text-align: center; + position: relative; + overflow: hidden; +} + +@media screen and (max-width: 996px) { + .heroBanner { + padding: 2rem; + } +} + +.buttons { + display: flex; + align-items: center; + justify-content: center; +} diff --git a/leetcode_101/src/pages/markdown-page.md b/leetcode_101/src/pages/markdown-page.md new file mode 100644 index 00000000..9756c5b6 --- /dev/null +++ b/leetcode_101/src/pages/markdown-page.md @@ -0,0 +1,7 @@ +--- +title: Markdown page example +--- + +# Markdown page example + +You don't need React to write simple standalone pages. diff --git a/leetcode_101/static/.nojekyll b/leetcode_101/static/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/leetcode_101/static/img/docusaurus-social-card.jpg b/leetcode_101/static/img/docusaurus-social-card.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ffcb448210e1a456cb3588ae8b396a597501f187 GIT binary patch literal 55746 zcmbq(by$^M)9+14OPA6h5)#tgAkrW$rF5rshja^@6p-$cZlt9Iq*J;!NH?5&>+^i? zd%l0pA7}Qy_I1b1tTi)h&HByS>tW_$1;CblCG!e^g989K@B=)|13|!}zl4PJ2n7Wh z1qB@q6%`E~2jemL!Fh^}hYfz85|I!R5RwovP?C~TGO*Io(y{V!aPUb>O6%!)!~Op% zc=!h3pup!KRwBSr0q{6*2sm&L-2e})oA3y5u+IKNa7f6Ak5CX$;b9M9ul{`jn)3(= z0TCG<li6i8=o)3kSrx^3DjJi7W8(8t_%PJ~8lVjC z2VTPD&_&_>060+qq1c&?u#iAbP9wbT2jg5_aX>LlOOXw|dQJ8p&2XYYDc|J+YUT?3|Fxm{f?d*1vFWPGwXt8P3T#_TQB*NSP3+0+ndOe%v- zTZotCfofsS06&ki{<`Cj8{s5jFZc&1dl<{IBW%#V_!JjOm6+#&aRi;8ODL(?0fENIOtiNXjMhdO24CeDB#rNcC*<=TwpueFfx=2=r z-lt`qW^;vEFji%7kO25#YkwjKyZ93WFbbY!Q6-@Jz!9kqj>xgp2VhEYyMJwMYyHZV zG;7!MV>54LS*F?==$6(Z9S zfrEy``J-iu6G?#+q=$58MlrE}+C~G-hEMn#CuNuuVV;8#FHuD_feqmtfw~Ran|V#C zy+f^&q>|d(X{ubCVWs3Ai;Fz>-kAk`yX{^Qj_xV#NEV8oxtfCsq3%uYN0U4+Kcu%j z?Rzr+fnu%QVSgx7Z8;iqDfklVK3tl(C|B5~_ywyQf&|IJgyoV|q( z<1`6^2G=2%pTX$m#~!Q-7f>sA;n6 zsy{fJ>o;yxpRCMtZFb#E)dl;n&K%g;H?#HaC_HvnHuqN*d+9vB7ZNpfqqTsk*(((>8<~)=+HX!*Ss3~|# zShAf@XL@`g)$G$rAA9cU; zk+0v$7Rl=PDs_rN&*@^DQ<3}LIqeDu_8cvBZoZQK#xaB*@qDhG^d_fYSBG@Y_wC5B zy{FTF=4jI`H0PRGXlulcwJ$*KBs^);$y@AfTWB!przp%+gn+%ZU2qD$Eml|2m?K;y zsAx49(J!Aq5lqX4u5Rlh{1hD6V?uI0-0}%=eSBZT$;aWCJrM*G=&(~P~7QxUJFlHF+63{SfFhWU%gt&D(4Z~X54CH?JsJEHzO9{;5# z5f-P_*$Y>=CXYL(i4Vw1)$Y&DwihU}jeLyuS2hQ>zS%^7!rET)y)?ZI;W^c(neZ5; zcYHr@l=i48ImXZ(y)o<7>Av^Nw!8t!KDn{67gef*G5f-&iZ;`G@ej`@uBTkn0_QVc zw|RGr%!y|LdrjWk$H6iyi9+o%)D%pY)DHt@e}~ z-ryeSdskl$jkA%Gje(z=CvGUb4lqb$@>K02q8; zBpGv48m)G3Jz8nD`*7z;ch+s~JId9q{~KmJV4qG#VyhtwGh1U7ZW~XgF&CHVcfjI@4|IAMzt7B{D4ttmRhW76WO-cP6HX>7cPSIon_Pic=YB^cwH;qqm2b=+@OjfH55;lLt@>%R&7MejNBW98rLJXZZQtF zmm<7wrV(U^X%O}rZp($;Nb;(nTO##-Fk_K%y2c4)Yt?EsKDLVz&SyIxmRvPYUf)~A zkMkfE4X%Dz8*f>*I$-5J)wLSdUUaV&xP%U!WXidR7*F!E3|fu1supvKyq>T*84`M& z=Dt)zp4h*&a^3bbAWSy|{$~mRt znU?J9X@W)z1+)2SKH;RDEk{C{F~PxzePOC4k2I22=OxAKZEhYTo#jZLnzJRvL-#I` z%_%U{YhbA5LxSuc7mb|<#t0l8BZHy-cvj?r(|M5YOMU0wJ}PLj6z+91PP@u~sUN(0 zoPkUiqj+}m^;#5WI-p1sl3!d`><`0$1U4*Tus{#@{oJ~C_^ll&fIY{RWHLB)Iw~-5 z_trhoc*;Xx|5u&|7Q=~%>SU9dJXt>XnSP z$}G4aR=bB#EC~i5U_z8$Olb|B1Ec2J6a`$P64P%*8UxnscnAmYxki;vGRSH!M<=El z7AwT}?l;S3Ju)fk9NDaW<~K*9J6DCaimLP@Zry38*StONeVaYg4GMSV1sb;$0#63E znXJh6$=|17p)3iget{zQI-ZcSA4kztpbVusXh9 z97)P(^GVx?9}T_w+?VG}Hu2dxs!PdI;c!Skm{8crbnUpgGsmO6Y~0f~`3af#=;}JO zs+>jl(}Ww@TF9nIIp*io9|Ar+SXKeoJ2p0xqq^dDIUaz_3UMRe!*?g>RKH02EKY^8E=Ov%mKqCKc_O8|58B$F z2nPy$8uP`nq5-GE>)_IseB*$*+;W_EcowmS_|Q%w=6aW(&AB z%OtxG-1&Xrq>E%{bjzK4kBw z>Fssz$u`@4(H4(yPd(wlj>oT~6v>IV?P zZDj-meBV3Xh&lOz7Q@p@Wg;VMtEtz0tWmBTlY%+n#pR{sF{)xA5u*BuDd zu~BvH^44yI-2poCTSulFIMHH|6$HIN2!U|l513rs>o5b7&T060H4stH!Rj6uhJ>*c z|EXULN z@Ms{ehhc57nJbz5tP(eS6gqwNx4;1P!wL~Xzd!0hhz^)}wUrh90P!E%NrcHnd5moayrW^mwAO&F9eVphr}#sl@u5#&@cZG3Pef_5ki2d4No`s`w>3E)~NzQq~(%!wQ~iX zS=!>QgW*;6d%-30eCYi-s{}L5+4xRvjRMVc-|_!cJZOOW|D`V>G$9BAul9zT%D`1W z9M}_f^IBfCT+$nV07$(ZMgM6Q>awY7HarX62K->7rWiZ>Plf%@Tc$X)SUE~YSzKHO zOo@t904vq~)2~8z9N~Y(5ghjQaweijSq9}$13ISo#S19Gyn+S8<}IqydMB*M2Fv(F;m*Z^NjCKA@hf(byh~F_Wz8Y|LB9G zj>CREj|u0+^+~|!q^Z4wYAm~DH8vU0K5hJLx;^WW) zn1WdmfwUxh0&F)Ge zJJ$CZ;Gif2pJe@g3jR{7X$9eG;iwp*gh^4;#?q$usU`sYWi;VGk9zUsuxLCqS?i4> zU*!nKB+RzHh&TF;OaYU1boXkFHseTZ9^7*ClUf6WeOAm2`Zgc?XVxs@; z3fyjS*rbEGB3x27NK$sQDLqTsoYX+=I47hKrjQhxw>;|F(o#M)1Zs3=vHf+{4*=lU zQU(~L2n)P!C zOzn-%j;-zdo*A78MJ(b}aNl*Pd%bH4<%$K3cP@a%?zXvnXr7tnRf8PyxM=h2%x6XV zGm+MfF#t#t=FVq6y^o&};nl4gZ1=OgS0W6oT4??aAn_EswVeD=G?0*F3Ky5X?YMg! z*>m;`U68Bw-j3*NS)Xv59AyM$#IrAaBLy!3%T~RztCkOyD`0Oh)~c45m`f(fWkn+8 zFDQ?ehB?iesKfXr>kR(d+^nK;|$bJ0BgK9l#= zSZkY0hNH`T%pTpu&S<)sN$BmKep32<*GjviX5<~dm2S)BRn}Za<=11?iR0CbzUy=Y zs!S!r=YBKN!Hvrz2HB~apVp)gQ@jZ_C@MZHwF>*RQt`RvqEl`)rFXy;*9O;aJ^+IS zAuxBFkwxDhrD+zs6}YE;!WWE7N;x=xxy(hv8tOrT%;~evWtP_;i-tw#{=|s|_1gD} z+$ZPC>;C15y?f=k!B)}XV?@W+W5Jl7E#au2n|eXFYo52!7iV_nr>%rHTLnmp5t__ zeQ~n3Y!)Mwq>pgU`A+DOtI(5{uM`!T&#y7{XqPhrZyx}q50{b`55VTpH9@&go43WC zqZc?IJ_ikEfm4 zqiap;*teY3XjF&M`E)w#v0j2fK8>&^=3ARl7X5?sL7($cGUyT(&GjZ}T7K}UWUq6o zgZIm=(`C|a=eg_1ZeQ8aAv^V`3$rbeo%f|J-#teM&do=aJ4+|bCGzXl53;$~hV*A0ZA5ycpm&br> z1s-woGI3ag*H2HL@1`7`+#zk!nQo^`L}FmXBF9_OVvslb3Qd{^lg7NlT6j-eh)ldq zIsckeM z_udDHz~0vrwpZ3KkTG;-vI!dRfSCp$d>Y)?cj8N5Tr%KDYlI~&_w+W~Esn4I>jEK8 zFVT=y$0H**Z{;PZsC?US7QBb(=tZKtCHDjvqV8L^j>>H?^4A4kTvR^*B7Ecb4?qFk z;I3A-%I#4)i|WCd)!jLZw1itTxsZ$F`MsNa(gzoB&z!Z262^le=~~4I&U`Eb`C+z^ z-VqlxQ;MGC=e90n>dE>aoHV5TkqviF0s?l+z${VoH%t8KFvbH=8^6e$^AlVGU~39o z`MtfitBvEM13&NqqE=`^fHwS_HEw#UDbHmBR+1A|sO+c44k$ zHR9{S!q-(m1a+=}nRGQkrWg-S#Cg;_7%!4Ry2VnE5r>E(^0Gl4^r-P`1z2qO@^9(pRjEp!;DAe7B)FZP$pa4?IWYcn*v>YZ(G2ETw zy|C4)s}8H`Ddud6ogaW9O%*z&O_X=V^6P+mS%uG2EcbTZmk$RT3*(0o4D%(Ts3kn3 zR^3eYF*}KjX-S8m()tqnj4;!Sp!Ho z(7&2M@h1HM;%Et+(u{~Toh0sg@7K`vuJ8O(-mWug9HRvjKP2RmGqWQF%DK(bM_*a0 z>f3#KhBt~#=bL&FWEC}JiXdh?Q9fn5e)7$+{?1Bdf8>;*vDW!BMGjU0?$JBadm(AQ zHAmi$WF|HJ@r5-F$f^VPE+X>suAfbT1DUvi%}6k2#y?ZFyltx!?p zAr?D|oG4gh_c+U9sb>u3LP&?IzmiCo$x4%SP!Q8Q(jEtG(-GPNIhRV_K5L z7Q77k6Jdl2*V9zOs=X@?=vUZ(27Ngc&%L;RjmxGl273=|7++0XC*K z9Zp<^Y~Pm)w3D*jwEo<^OkS4Y<#>lqUb=O)W%Fa5t!Yi<%z$TRIO#_Z7Q3QZ2H5BD@(x_63h;Y($5taTf_%0;ZvK_v)P3}%^YaRF4ri60UEoVB z9tvN{)Jtntfs9Z(yp!blwx06#5$P9W8ouO?r4Ila4@;@S!F4qL>h!`rvxwm8$-&c` zq^<(9nR=GK@B4e0qjX45ZoSs3?|jeZ@13@KMK0R)%1IlSsLp0DH)BFK20FoEM2kwW zSasI{O!BwCJ+a#u@A3ot$06uqU?n&`1G^@J*u|t@Fqwmwe+Wf0fpg%{_PCq6A2+)j z2hE=ehK9p~efCY}}Fj~mMr1Qr~qOdueZ6a_2SDwHZ*lG#r|D%`UFa~RYpuWgUN;*|PxsXBBeqTj`RJnU2 z9PE7zrU|}#_j#k%TQeT63k<&b?|z^RNGOSfltB4MjA|mxqLrdoZ?;jS1BSRxcR{3 z&%l5U(~v7ESy(7pNhyb$1x}p^+*ny$*~6KoZMdfentT6QH1Dr`Dd@U^^%MTqyRNen zJ1b!yKUiiizxRn-n~&g}YvqM*{G%USoM1&>P*AuSldPnqET|FpU!M=af1wNq_3z-J zu56ng_&fk$SpR2Tg&VxTY(oJPP3gAh>wSjZ5#J1#nHbkU`Cof;dA1dQz?$+;E7aQf zK?$L1IL6d(9>vPMi+iISD+SJz*W!e)X$i&Pwc(XN-;gZPke+O!zgm29u4?v!xUP9C zcK48Y@K`NN;M7x{1@te z=@S`oF&M(3^!G8wji3Z4u|IZUp?p~QVc?q&l}!U>SAWC+@B3Q=M8Gx8SMIb+e*r+q z{Yg@g$}_Sz-mgRV1*RA!0Rj$rc-W8!5u7m!h@?;r;RvN(6Nx9m1}wb6UV=69pH!1u4ND1C3^0#GV9Vk5v%jLF1iBkM+~_oe#(k6e04;|1 zqVxcTK}B~<8@cW$rb+NWw4LZ7KVGkN-UHS;bD^cK+2-3`Rj^V98<9f`kPTuKt;S`5 z?|)V)15P$Dy~TG^p+BRJpbTIN2fb57!5|jT#s_X^pnNi>exLT+xuR}kI zLTF>DrKH5As1d;xUMq}JD`rE#xm<3PV^bKt~*|K(@>_s$+l6?PG9c;I$Y$I9Wx zA;xF_MZf_#OaTl`qJ^-80rMXYZnX;yHMnC5N`v2j=zq5Pz&RPG92*Z}aj95Z+R(pq z5>Xr9FJ8qsGy#`dMOy$X4%|!w<&^&whNI5zri}lV6#?4!$Ljbv_f0<2-3Nu?974eOh|NodBrc6s{g264H^#+vv zkI(-F!??JN@B<(iW`KcV-0ngu+-@)j;0A>UFo`kAQKI6|7gl5B1rI>b2tj!?@U%?! zpFY4#g}oL@l|*Hrm#l)1qwa_0RO)Vc;oKlpABihvuq26}r$$LgB-%uwqRxuRrpyG- z63Ji#aENg52nfiiNRQwVk-^yt-aSGBkWsL4aPbK7DcQKVMb!z2h+ndEs=YI%qUPWc zQ>IZ-)zB2Te@6Q%>$!xa)SLHy;OQb1@YE3;2Jiq}T8Nyd)7_1XLd)Qqf~l-gf<mu~bv_xL2)jRuX@t1;#}dEe+$KYBs8Ozc8vKSmQMe zW+znS+=sB{$!eWdtEK&;U{CqQ65Mz$g8{KO3091K?+PmZnxe)Uj z+Qa!s1zBptH)^y=Y^r;+YwUV(!nv}S<^CwP->`OJJ9$f5gUG$;btdeT%D1lTQVA%c1zi!li^! zRC4P;e}Vde23*`#o$}dkJ+39wA!C@gdHJNz_ROozn%~qZ35{gxr zfiN+FJmv8BeiZfN4}PZY+~4(EHI@`4GB%VeN^dL-nxv{!>bS=G=d1&YuW4g(RYo?9 z1bQp@-L75k9jgsahz$6&S+Al>N$6|(Uspyh?G^CV(>yb-uEMv?{QHK7y|JZHbV$py z%-C#HQ^wHzF5_m4mG%K(t4T}wM0ZA{r9PYV^B7{;x3r!Xhwb>CR?<2{=4)iW>-lFp zYAZW-ff6Srzcmf>ey26kFp~2&CwAle919+v=b#GbfQ_k(^GDH^U5h6Ij_hJl+$cY7 z`$l|J9)NY0%G=H3-AiTp4`ibZCebLFOx0X*^9LW5S-jM98V1l7TC$z>H_cy3Z}AyT z7cVLl@}RT$dt1%R4$rYgTUqZJB_<@D5gGBnLzk|&Ap3rHOWJjl)n=4BT|4ZgqT{Y# zt8otJt6vZPNdUZ->2VQc|t#}@1f$zuiGu7Z`2Eq_iUO7kLfvf z3+3l;rJH=!P82eCED=AEqW3F^^w0nBW|fbIo$+A)nzK!N%82P?SXGa`4vSNK00<2u zG?U_{jq8ikbd8p@c-wd;R3TJ+v(c9o9< z15te~^)#o6%yp?zaR-=9=hVgU2)|jpPHt`JGmCnIB+qepbmFikm>#nfBmU{7vA8^z zhTK~#rjjnUOtV*azuR=2pq%=qDo}!HCW$#qTWyAliZ8Xa(cAZ0uV^tvuLjr-#E|<6 zgACc9`oD!F+lpA=rLNEf$nCx{x6Vg$hB|ia>mt1(@zkT4(zdKQrNiynVbyP`+<(GC zZSyg_F+eKZ$i9krPDP!?9!-GQV7-#k7*{YGhxdf%D@)yd=P%=c?r60bP2qytty%-G zh7;7A?%TTQIkk;cPgbW*m6aq{m1>`^R}`Bmi$Y$X?QaEJ3_Auk*q^L1i~N3dGM6CL zP<_JeZDBHK(^_7!@i}$(_U*t}@%hy|H{~Q{;gP|bU)fn%xGdctI%`>elX|Q^@vKaK z!d+`Jp@j=)v%^wXH{7|-__X;}-BP#uIY3=_0IGNc zu~4o%m8|B~5EtZ$^}=3sv!lGEYU+H?Y3%_wM6P8#*6#HJvT!3ul#<{n9ja- zRGu5okTwJ1Zmk}BqcGi4_;~IURanbdr+P5iXG<{exUhhs+*pLQ^{jA#EZ#>o0{+2Mh|5& za#ugek0I`(zQL#5eLDARVY*Xa(DwdUqkel}vhN3?;f0iO-H(xqufvN&!zQI78i>uE z8>&m)ewHaoGgtXPku_dEb6PORWr~;1cC<+G5K=KBl%`A&gp6C>lB)v5Ri$FsN;P4>0AbJz7kC<~Dg6Mg7fXVHmZhEHpA*eA&u za?3ON*{!W8PYLPoTR+cR&PxuH$lp`AWkTjWWz)Zkn3TIiCEofih+Lm=9GE(9)!Yfc zt(H1<`s=^*222e=?7hC0lh4e7B}PtVI_{cAdxGNtdfZX}Ca>Ti9YS^NB6cCtzFtR} zgaj!>#THZKLuuFqeb58ou+VPMIV94Az9}?pq(nm5%Nr@`CDh7dQqUo_(1Ka~Jk;oawETtB8>b`mRyBtgh zO#hV*Tx!lPBM`YD{&wUnqnt2DkRmgRC{h$?KYyR zNy|HI%;HhKQrs~er!LN>c2+qWT)k%E+~E5H9eFKV;EhkieNbfqMTavz)YO`;;q)r^ zRKcAY}gLEwaGA zNB*t;%C<*Y+tgCdcJX-=MUjGgyz~ESiO9#&b61{-h<+|2 zO;mjRZ}0|pCLmN$E}rD#(9h}~)QpVO*=OQA z#Y%e{>N&D?0uC{dY5L(<8J1$SoXTWsj~6x5e9=~^#nEWa^lWqnid)H7wg`B&H>nuf zicIgRBoFD2ii?SfJ43AUH&TVFO^DDYcT;;?zvOP%hwr9IDk(8n^Rrc$KG_W$S^CCU zJn=ZugG;lxxPrOnJdw}Typ5n~t5&$I{si5!MLacZa-r_WCh{j~l7-Op=$9TV5idhN zglm&=R)0UNEvq|kz+%&#x}Q{2@c3ZLBldp!yX7N~c^eZPht|o%1isQe*+RisbVF_% zc)4$!;>pF);4JrP4@@UX#!&8hI;B{0l7;+j>*r10Q|es&1NFKQ)-tV2$Om$A@O-## zCLqC6viD-87K8StG^Ws5ct0&olMkYox>$?+Dv3O{NlG}G;g5QSmf4?q;BsuQo`^U|{x}>ACKXRkdd^tU`U+|LS znWy0^S2)LcB@0!EdDt(Vij$36^78r3tM}C?KI}e^X9-D}*M!iFT%zNr0Gf&Ck7!`A>(uLE(OdeRwb4qX3EiMVz=vWC3?2PE%-wA%a1ap0C zl~rRJyzSkY8Ag$Lm-Lq^*t1^}+zs%@8si;z!Aaw5c$|~Vez}RpL6m1>KPeiGJ-kE2 zbc5&X&fJgVtRw*RtiMc#4#s3H)KgHzHqg{R3E#R(bk3b8<&|L5d#($dxdtH$sL)Ko zW+BbDfPQKTs#e36Joca~N!pf`_Le7~Lv03)(7sml@e{h^6)?B<b% z4<^3n;sOFVdZ|+>M(^LPJA^2T?>N`FCB!o7f5xo^osCpJG~aJR*pRaJ`|hF>b2{X( z4aKEJ#QV2I?XR1|0J3}|ZH&ySn!Nm=`P+m<#hI$;xz?{pkF56P+%fUR#QbB?5vU@D z`>PliKDIXEyl0$1ZZC5zk$jU4dGg+)S}VQJ{2eA&|CmIoN#1+}`@$?!Mu3F2+9T02 ze0p5ot83?2=!y%bJ6DW(u9o4&WO$pZ4(odr6?FoB7XL4e)f!oeU;7hCto!x9u^3y2 z_p)OlA3aa{6K=F7$1_8Kool5Rz84;b!W+-X$m#2JgTdGR`~%<5^BB{h$tmHspv zRGNoo-aTFhEpL1CiLM*gJ|XE30ntfqZ6RW8RmFz7r7ZSdo2F`+dbIqX^P95F?^XML zEd;Je?~!LW2b^bUTSOUq6$IdZfuOEh#~DDY>}8&v?k$U}JNqeWBw+k5RaOv)s}jE= zQ}Q=>D-=P$ONyT$s*Ds6LSFrpWZV z9vm@*jijy=tPX3=aU<`d%SuI}+t_(ucyRkiyAE)B^U$L7DbCd`ZfC1GSJ8C#vU2#vSFtvhw(~TDanF;rn!a zWgH2WF*ekmAnI0Qm{vS{Le0(+uM5o()7|2IRkMwT_#?fPo-fNKuG}%_?WB5XSGAlb zor5}ub|f^JD<-m8x~AHfvW<5`F`lhl67hM38YaG)q~vy{D&^Yntrm?>4z^ZOsgY#Q z1rH+LbV>KeLE_&Mx4guoLMo);;h{zA@6Vg{<*=;A?ow0;2nhIdN=lYmb%EU~F+?HH zLaoso&FKfglw9l+vgl0wD}L>5CraD=W3%oYoYELRdWj9p+A0?Z!6LgiDg#Eu>Ssf0 z&g1y!IZG_R=3hb@lHbRp(1j)&W)S7%^q<5B2`lgE5Sih9hn&%pLfAg~&g4O!dAzEw zr6}!RX6}Ey-TL;=D!pNqHJX2g5o#)RC9PgCs$st=+TNbHeB0ziMr46BDXhn3@+9lb zakzM5tAy8y(qP%tE{ZSGapnb4Z^LN!*_y7=s>e||+mVpl^pnes7OO}vC4KH*VY&(u zBMQ9fD2JG^z22EVkkJ~(SO;UACk7d9{ug7_|C8~{@mt)aT#ZU+DQOUbF#6axF}^Fd zmhtBwd{#Y3lNT?|FIsK&gZ~-#n-Y__6Paff`W5$GI_?&4)>Y6wNn%X>=Sz?np7Qyo zZH9g7Vq#S+Wke2_L1>5intVG>$_RV=;j_%`e4O#OwWIFnFw^vf``;Nw$R9Y&G7L@Q zEpjyn?t&uTR?$ToG6e_w*elUbNC~oP3@8{6T6R7*{BS$ppthlyGy84Q%jeFbF-1n> zO)SGM6LD+T;r0urWn8w~gEyVb*0_W98_BXWEHC7aW9+`WLmR`7N+r~9=L(~xq$Jgb zc0`M~DlkIF1Q$x214|&HJK67p$TCg(T6J$4SH->xR%+&~^((0Nxq2lp^|OY^7-4i; zBL#gyG5+ECIpe3%Ik#hK5FP>?%G+Pa7_Z}b`G(asWH1;##`0)}=0g~DiAQ%12Cj5i z28T%p_C$R@L_1|{@r`H-3@utWDI40LfR4i!SA32m0qYI@45{@x~z)w#KlJvgXw}%|m zRo=DGsu9QXI-g+Tl7VIjr}mX;4fZ(YL6iQz z`lznb+}yW8^|YL;n26~KwXN#Dv2^Jf8J;RGE5MC0?77MSdMq!OZES zr@rC*vXhutbr*g#pI;TJ7-h(_N3>Ax$cW*Hvendxf#T2KHpKfFv0s*GVYIHa#ER76 zH)fn1{!z7-v31;4FFC;np`(vIh~mi%Kk6K0qRrbY_10$&xciNpno*F#wFH=MCWkdaFgK=U$FHh6#XJ6e393;9h_D1Zj72KeX!pg_>9E<8*a-g z^}Kf2k*_7=T(WO~W~`LQ`#b^ur_5KjDOs!UUZE)a4ErIxiW)A?ryWE_hQ{K-z66() zy-hd_Wf6g>qeoGlrK;PChpG^jPZRHd1~2MDVv*}eCafA~rLyFEm7f|EuG-#T2SgA< zQulXvo;0LIo^229Q9ItQ+RBrWH?~QpcDh9k(_=n;aXhtJh!9kR$kCNj9kJ=~BEU51 ziIB~(jdq=S3*TzWE4mQ!!I|ecuJydbjIPp*Xw5Ghu@wSqzc$S6Ix+3baF**T>Mt41 zK!k+2I%~h$4?s4Ot~MGVS3+Ob?$pC%AG>el2v|PfPf#)JsHx(Ctgl_0O>zUrPSn=nDj;t;8OUo=NMf=eZW`H&)xh@0RbL zug`wD9%>dDMf!g1Mmbzz7-EO^Yys;ref6{S7=chPEbgzvK3Ygwd;HLVo?}5(#ACVb zWsLd8mLOML?j@oEu`Ybe-Ndygs{ANWu zTYi}_YQ<948Jzmju!q^KwWli0(I_g&4zh3T`JS8oyS-JxRIlxlOkv13y^u$ebFvDyZKo49C5A{;Tr}MGMfceW3vqv{k;$^5ymBa8D>MecFsutjT zA|2ncpoEfZ3}EUt@Ng34X@75@l=LMd z^xZ7gESH4|2|k980z_jCp=#YZA)wxX8X~1diHoFqFvh?^Q;)oZcQ^W-l}yf5-ITM^aKZ zdfcjKlYl-&+8kEemP6lOR$P)7OO`b%yP(T25cq|hroP0p;{1@NydW2?&Uu!(^E(fD z#^%)iOUjTB^}P|c>sOo(_ivgq!yorSoV_H}q{tDvSL(K+bRbh52yrU?;o;#a1$BI; zG0RiGi1qO#MDdZ{{&bK@3)dmD(0ps&@XAgmQ$@l-h4Gx@t|NQC$u0q^d(ku>t~*n- zd~721PFdAKA^EX@ux5Tar!^~Q?kN4Q#)8B>%mcd&9luSEH|o>s^4tryTublkdEEI{ zKR#&=Y~)FcH*t4`M?g&TY~~}M>#}&vt3FYW)XMt2n{6+LCM@Vc2}fP)OONUg_(3`R zRab{`pOc0H4Vwb&4_9$Hs=7gmE~%pp$%I+QRt~Z=N*)eeji{_PhDB=gEL1PPqQmXj ziAC29F0k*5&JI!cBe@oy3-j>BSk^9W)qi|x9siuq!?B_AiaL9Ia3GgP?P`@aa0sC%Vx~ z4_H;|sIZ_baSi_@V?ArUq-+ig)fyk1eXqmTJP^R3h2&8I=PKcQB=1Si$Yi>2^`ec` zWhT-zHa%mNK+fB?4Hfg(dl$9ssVh57orM0LPj=M|2|5Z33$ZS1MD#ToTy?*a5E<)o zZ^vgVRHt{{s?S|cu9e|pBs<_KW^^?c+z zVk*-fa)Av4H$i8mAsYz;V>N#~@y4qSwKG%ox#ZW_-xaK$Fo)u_7H+~xDQI%!Bh|re zEIa^~TT?%8*jT^u!yxl1>%qYTu)I_Iwf#Cm!)=kQd!PDS6W_)FgT0q+ohn_P|7b-8%kc;m zg1^9mPpG^{HSkKoxNcleZ|3O*V?9Y(hvnWYam7N)*3PotcW%Kd$xrtzn4cx+@DGp{ zFPwjuW6B=Zy)W%}`8}SIrnZJ4SEixC`5nMMSLxD`jCML$)Oa|F+)t9}6J=&fRyZ_^ z*(>evV$1-$K&$Aa2X9j!@6ZDeqAYa1l-8b9FTg}aF(uUeG0nO9eI}>KD(22{Y3iez z8sj(PllCVvngk!res$*`DI4Nz8|c28;b3g=9C+P-zJQd-I3R2Rjn*zpn2l7K`Dk-4 zq4GHFR>DRKlZC)XE(X!Rv+KEpkgX@Ph)0`3j~T?RfLQbFSRt^V`+L0ShrurdA)6#R zbvLEIWqYfi#>&qP=f_x+*)14zkd8ci08%!rf(xnWtQ7*>#*Q3lqkb5ZF8F>;{gl*e(oha^!C7JqB6_d~123dt*fdvJq(?6p*0LOR6U zl~o@(cjQPyT3~|OL^gOFW$f2uVn7?jn#?#D74*G0zSOzzEpH3+v@4X!>%a#ZdTNAo z02SDS+U^x)AN~i#!qbx+7~#+diA%C-494h3`5HW7V|SpXT!d-y6K;E6??0eZ_5aM0iGa7jgD1?z-2)tt(?%)HrV0P2IbUwxg)d%!3 z4(Qq8t4L!w^x)eVTb&7NdkTc^eWb9hI4uNo=4Vx(!X0`ZmUUTkqhL%zXoLtLh)Z5V zt{c8kL1$SYHBbFM)7D;w($|K!o|>Tg+asAc(_eT~?!65~_r`GLc;t~??0R+=C$8+% zSU9dXJbLgR#?h~h;~9v{d|1ty%Q<2)Xi_iT>Z%Bt?C^@A1-{?xP6+qny4pNWax8sr zh$_z;Rh0)xfA?_O?hY?gv-D6ddJNR4@Y&jc|MeC)wpLV5P2%7;{EV$#ZcqAzo!qmx z?ntfHdsSvdZRqSGv5P*ec0FDX*}Bmbt}B=gb58YCcP~YrMboq0D&KRi(a*1$I=D`) z(2;{aX$+9#~ce9s7Dc;AlEy)1ge>u4P`ls#tV!AH}{Mrf3Ev0g>k_on;O1VUFJ zja5^PD~MNp_xa--s%kd#tw&d-JDVyx?UVu)d+29O8LvL)y+8u|%P4{5!jguGKBVVX zp!?(Q-W+--0V4ud;Ga3@%BC&Ar4xVyW%TLQs?ySqbxoXLB9 zegDO|`1jpj(`&Du>guZMs^_U@SzO2wiCx{s6}xlc&#oh~?+TXf7P=r0OSNAfr7?9= z+=L&!eF>@TAe>!T(a=TM0@E)Zl#UnR35M&^|&$%M!ToyO7X*>OO8DdjGdIhHXPX z?svWHw5|YD^yy!Ed6saf6-1ZQANVTlA1J0y8BhWitD!fgc0O*ZogU?W{Bt5=|3G*4 z0jq4((3_~e7hRJuRM`){U|z**Fm`udnq^RoEE9-!$k5NS%TzM(uPX~_hfO9JTpe|K z%R@gT`}pR!(lNGD0G4yAhj zMEi$N{5aLE!7mDWy`(!%x!PN3{hv3%S)|U`OK02zn;mkigLW|8Cqk||nYC#RM3piP z1hL@Q<|b|GXjZHE1wYf7mwb8HTsHNp&aOo8IRTPw{J4rdTvT7LGO=6`h|uC8t^tE^ z2nXn^x%`~8UdLhe>F%x^KudaWuj^CIgH|`GNqTS1huhCeAzR|zcVN*+D^GZvg@t6{ zt%Jlv;t+k^cO{`*Oyu4vy&A6z3MJqkIX9c1AKljGEZooh3;N(+_BT<651L-I+e8z) zJj{Ug6s~`2z968B!3)qy`JqVw0XcMz?Z)C-ni;Puf&MR5s_EUj`9^N zc;)D0ekKK2F19`-g_u62@O@lqzi$?uQmFd1QaNobI;MW=A>yG|U2xA+(&{n4;JspG zJ-vAO_MWK+!A_SoceK(e*pjJyX<)UFz?T`Y9-H}d$jADsFSt4t`-_TXMgbZ8=s-uI zN}uEaz=#(l8|*5;4k$FC@p&!SWuo}TbavOrfL;Xic}AxxdwTfr^OtTM9$#(&gBgL1 zCgRm~-OP9kaZ(%GS-8HpsZuFAHf+g8Ui_asA_>2N z{}WoY+y{;)wte$I9;{JE2LYtY*L*^DeR{mjQxi_YwYJXSbXjlVYbWV!4!n?iElyk& zy^M>mx?ICf@W0anrFqwS(ZZjxm2p{Ct18%;%=`5whuQRB?n4Dp#-@jXfH)`T4>T}@ z(>zL!clT~7L2ehKJ&TDg2W)5kvy+LcyuryarP5q}=lE*g1$Wvc=HHClGs`X=cHYVQ zV}5aV#pFaKx{*62j~+E^{o=!<`%)BcQ1;0AmTT>}S>h0q=-1Jorgo9}7wS1Vyu?Kz`8EX1p_-4{J;lNJ2x?N3deQ?__Q4X`u)~;kVttI`SSwqY})U zf!AS6{dh$TKArl?Vs+3KubJMLAtooil(z? zH&-|YJnm*^mH@3dxDfSU*-TRgaxN1LCP6qu6!CF@J3Oh0=h9*XU1M@+6Ladmu>#JL zivIKXm3}!-e;8OYA`>woR4Cl#xB3fxB-`Hfqdc^pNib+J^$P$`DP<2hsrEp}I zQ_(``<1Ijf%natpKc5HM-Rbhu=J%eJL$8^zKwH{4agt`@cU1m zpuThV^OMMoOu|w6wC==YEgygQfoIad0O`QgblvY9_mqR|jApUcdy(Lkr*{YU$F~Ua zvVw5Wf>5GNfOcC6tG6U_>qy0qoKn(JYXY~@{Ms4=6*zcF8aRn@6ME~GsrJ;*92N6^ zY&>yh34%;EV*Zw;eUAUiZ&wupmR#g{_0^$e6Jn*c<*U&c;U$E65sQ5)%m&SUYzMv% zL@{=a8s{6R;#~Aq!_0ZP+Tc)HXZ5ttQ41tW7Sc)-6RcWb|JVmk8IeRFVEm!eAw1hE z38h>Y8j7T!0u5>#PY-3{)X9)G95$Wv?EN>(`ptIATg601g<1x!fptG-rH!E8_D@^y z1dNbQ@fN$x9!1XHW+PoaRWA7IS^)5E@W13I|A?-6U)7!w%dBI^uO*pI%56K)#`Thv z-ykObUb-b&0wAUMakr6}NE zsL^B24*0tdMdL@1LP5fH`2~=$lzpVC69|=}~RgpfhWupn~ZWk?Y`?*YnkT_6$PAm99BukW^KI)qfJ>l z7gXMiPUofoC9Bro+CW7mC0xY!TbAfh0b1`nTbEap3tQFSf^P~N%gc}L-aK4q7FyV7 z-@5mo0)~jBS5zmee1R-;UOJh> z6|SRB=#IA`W&$$?_C^Vd&&Iv7(>d?yU;US>%S-BE#sGTl9D^{`XhF(sl)+s)nO|&? ze4$V+tST@VS}vAD#eC`K%Zkygf8sG>Pkk)Z^}zOVizMU#CQ8@4t$~e;W)dyD-enef^M{H?8TfvnQ52E(dj(=QWa6&O0Hv@R6& zpj@3*{UYB9a;QNv9v$&h2&FMY3{H@X_2m2D0qm|zED*}8veH-axyoutqwF+`s)m|j zar8t1hZeL@p<%kzlZ}vgS;u%!PwYlakwmV{6rHdH6q~lQx|_r;Y%Ugs)4647*q_6- zwwzIk*Nalst^J^^%Bw8uzG*yzsz3`;;iL@i*opd5c?gEWnV1H?)A63{rHAr_EeJa! zvLVTlcpd~f@!0}a1uC}NP)0oLH_psD)Bjj%z?;CVe~Ob-vUkv+@w|UkHrAF6MB^bW zXERG#+UDPn6}LdfiHN*L4Y63-QVWLf!d<@>3DgG5QHbSQ0JwNPO~03wt&=#W40a`s znR6ty-#LlsAr&j8WQN5p%Z(NJ26hwHL~*DZ#|M_0tKqlLJC0TPJ6p-04~_mvsh2yJ zcF|vIuCXa-`NLj43JP}KqP;}qDCMonly(h@e*0Mh66D5NoA6m#T_!NLI=5w|`!(Ki0SOZ$ zAkviwBa7y?yDKq$8j(Iryu&3z*5dMo_^O$^eVtYvG5y>wBjjSkU=jo>qer@qPsa{4_M z(Xibqwva-z)kVxKEJq4Xr}L8~Cea8ByVGjJxFPv1my_RMIXt})#m?ixGH;vQLnGs& z(%FW1e$SO?YtGfHiyh}F)3FgT*q%X`S4URO%=#xn@3tOVYJ8{~sR?|^irvM{_V*at zT}D$9Hho10>?JS#r@W#HExX0O;Wi%j-mV4;`RymI_fb#wWcsYLnJnWd4+R zQTCq409!kbtSIN$TtcWjf>tL_i%h(cneO6VujA%+V$YUuQNPitngyJsBYmT?m*Ew)fQL(Vb{TWhqd;;-aCMu8Jqy zw2Yd4`Iz-T{h?>b=3Q-OxR>m>!p8lX-+x@r`JYI8mIyx0sOg>cvh<4&)gh4hba2An zmR(mU>;-6VwQc7Xa@K?Gzs5RDL)+B7sH@|A+w)j!YwDZLn}&KJI*N59c#fg7>AE=i zINsqY>+;Z6qnqY*iv1VLEcom0AhDH{^4ovv?*(W=TKE((gi)J1#w**@D^sPqAJ0Z^ z$j~1H?&D{nlhjt!m+STEj0Qt@%!(D8{b_$=V*B5$ zHD`O^3SIt%ifHf~oz})(b3JpS2zs40H@I9~Uii*uhH}v@Y~*(dvxFpw zA+1~<>mw=oBLbi^HIV`mbpE*1zc|AKIGkV{vP6dakoiot8>A z4!wuo%14@qFmIw*7bgnXj!kmRyL%p#H&@EfeAD#S@6H6OJ&LhiV{HA!) zQ8Y`L$Bq9Tg)GEP$gy?S^oPqB1^qt zJMHL~Uk18aQ&>09jAbl$r2d*J!NI)XdVmo{RWDpYz_TPN^D#*p!zvS2^PUf-Z`G5nB9L zSnclzT+*fn7R5oMKo14@r@pE`I ze3}FQ5~U+Xv;woLD?&R1@SMdKn`3N0%}d>SwkoGzP}bmzboU+(ZNONteR?hP#JA9zYRE}5ryhmi9r+hJ}$VsJ66eF~hT_rk;{+D>g#GN`L(iD)H$%URv4H-v_z zS8NRLobH1LD(Vn>O8?W?juDIdbm`_;YC+B)1Uot(VJV@yVyEpYT*ztMXMPbjVW8}s zm5yBhVX3%jNNmB6FX15?X~x&$8R~&CKro?`7e;CJVecI@#=9J?J&k1Q^zj%F84qTP zbPUJI4atIQxEPyO2mpT|-1O;d9>CnVUAH11ws;v8$ccDV}ac2<q3&_&!wTy->U&lk5cVKJxb9R0Iig(AXDxJKGq4N#1xnY{BZl`vUHL;ndgi>@XYSTCgUxaNIFXF0C@0)X7TNicC_GjvQ ztr@xX9n#fJzpT7HS-e#ry?SurQZh;zH%PMWs>_Q+ei|7D16dA89Ot^8%zgP*V-v;V z=UU|U2G|-D8cN~^u(ut)Rh_yuZ}zoAT;cspnTQ{#fT*Eg*#53NQJgvbq0%VMGSDbB zpb12ox#9fUH9M8l()~6kFyoVTD4>7o((h*{n^hL83_%gyHLpBs2$HvORIcz zeCP>s?ytt!8_cs@Kg(fmNgZDKmHV0dwaV7N6|UkBG!>1)20n)#j(JYa%t$>0zji+} za(I*i?l~5PWHk;{KLKT^rnEG~8l^h^YHg=X0+8S;iFhD;M&s5W?zLD*NAI+~f6yf} zKsOhU;09vj)lK8lKuBOASqSsTD7D-#En9kwA@-+-bRERwB3TUftK_4_Gm?`W+rJ!c z8V*JIk;*wSu&`-(aKZz7DE<=O?H%1}`%`rBr zj`aar@#AMRq6?B}^4GFhz(Rlf(G}q@E_-E(N2^4H4!m)stH`W-#k?bK%{74=H4{x? zB6Sf18yibRl+kUyIyX#xSlTo!%M^xGb_^_!6y?X^k$#TFQI(WqH{T2PZMF2=p?MaK z2f!Y}ERcH7vn^|tZDLR;0H-Q^tbyZ?G?7UlIkYr6KLrPnMT&w8A=at-$*^CUQv$la zp*9NVcNaT)Z4*HU@}|f)v~;r1TiNK{CzI(r&Ce|YW^v0?QWB=GA|{?GZx%-c9-R17 zFIQ(Ho+B8)3+Qc6%zd&1h6YkP-6YVeQyuPFU$C)p3rLVssmFk34c79jC=rG=fH_L} z^Y#K1?Mb0x)=!J||1f;^50rWdxXAD`3LnH{VPjo8ZIU;CtkU)`gRuK(SmaFPNsB?h0arwM+5SUmvL&Q%t z85E>Z5&~)b2YQ3}A8^Anl4O#Q@7JY9uv|(8MfPz@rOe0;uCAy?;gwAQjVi0yGES_p z?h;`bIU-*q3wf!=5{2HAS(DdEVOAT5ktuKFsN8)J)Y{zvD( zr(Est_{Q#>jx-F`7Sx_j`{92xv^}bPxiykDTFQ7~dhc4A)ww_DiR`WAxzl>{`o9N( z23n=16>qh~Uek0wAtr-93J#q}{)OT_uu%z*yL|am1DU7rKoo%Cg8&XS^;dh8k40{m zE=(7&Eip3z6LBvq!&2ENm480+ewx!>8(vQr6mXVD_?ehccU1DFeJ7Q2ad{f(;^Fkv z_~G?yb;CeO%B=tU3D!-NNs+Yg+aH!2&dZYQMC~r|yH+W)S$rG*8rtKGb#O3CEpl^1 zSh5~E6-$!GS;vmz1S#jKVxJn_e|1i^#X3hK|2)_+Kg3m46!vITR(~Ad3(8S4wzuY( zA;t(*RNzdUbA{*q60*myOKCfZ zSSAEwT-~zu*X>h2S~ZU{TrIutUC)Y4){tO$t$tCTRF~NRP*E=~Y~GJ|U90UU14#;S zGlsxY?~zzZ-Q~ECZxsCiarmZ3iQd5$o&UJZ{ze1gP*l`P|}5>3^b#oXr3*IAUlL2je^D^~`l@z_vZ0u{S%M$&)aS*Ij! z-hNtY`2m7T{0c%9|7%sFe=RsVD`#s|FqQD7t3d;di(Lj|YHU}Qc*d$<$J=VPXT>6B z3OU;=WJVhDIq*|VAFqnsn}13D!LHm&D&u8PG(5yyF{(^`e(D=p=Oq90U*n3qEJ&2G zpti}lu$a4dBmQsh1T1Hdtcc{D~%)d5FjW%D3q_w1^wDc{5;~1iM3c$bb ziJQs-Loo06jkNuWrh>(DsmpA1L12D+XMxS{ERq)f@ZtAINzybplW5i2;}=KW_=G3* z#>w(6BIiecp~@#>B+daN?Ao??)o#UGYVLxg&$*(b>wsS7=$Wd=@Z7&p@^8}U3e}2I z&g_oikS81WguVK^CTR-3(7l#(1>}LSVCd>55Y_z~W@bYElp0Mq%K~P51c>4+RYI}# zpHXYgig7oHso2kqR5CT>4Vog>TkDZ1;`D_O$+AiB30ftzWGbmUT>wr5G@@Rc3$vp% zwdPLsKfcn3JmVIMPKP(X+q4WaR%_kR*l_QkFEq(l06CN)lu03-g|Ut+8I`MPPiltK zUwhM@^z=`bUARfFT!x4ff^N_3hREaZ#Iedfq2eVISz$jaT$2!k3k*Sw^Pq(Ou-M_EdYrJSmwf?&JJNH!_h z-&nn%za86-q5g$ZFcdR-`E&#G7iw-Pp71@j%fI)|O_)H9>d{R@v1Bk4E3&^lL&z65 z`3F^p>MQ_bmEhhsR+N8LEp|bjUJVh#-Cctu^UNw-{z9>z=PvyT{0n6dp>%6tLBT-7 zKyHLUMngn^hlhsrkbr@O!iK}b!KDO>Nd?+E=P?XvLpD4QvuD;_jeuoU_ zdTp8HsN%CkkDWX31pK(5KTPPoK)qkZ`gd|CNDHIW1XVYb9qXU(_}v9vU!H=*47UB$ z*$cZhOzSf#glqL0HAK2;FZCmX%5-pt!mg?>kr_5M^hu1!>8{L`ol;qZV_Sc_sY|nNi*)U(D*Xv7rj{`V!YA62maFW)Vpu|rqFC}$p5&0|Kpp+-+8Wlgw7 zAQZzc&Ci8mdQQset|dG**wvXDu|ml7hKXO9efs42=9dusiH~G#^M#Gy=eC?4R@ov1 zJ4fKK+_7vJ^)Y9!;xZ1Q*AJQ^e%i3HQ>76`>C+u*zSGf7?4W9w6AiS z{*B=>e%(MRyo{x>>`#_6pxkvxuG8H92y^(dkWbd2AiqI5D9!~#X1t&74A4Q;@x!ag zp(~3(KLdM(*s1MVeb+jg%F1G^u=x|=$zPwK)g zuZVuc^RjBB{duk~!{6{nx4v0l@&8dulgc(YTL!P)2I^c*(#Sy)T}E_xO={>vLE9fo zDS4r6X);W{Vubd45iK6*n)ezQ{>a`P{wico?6@lm<1yl1o3|Ird6>Eiwa>$xDl8fA zjFw0y=?Jh2N4W_EjGemBg!I%smb8Z&vox@8d5*|s339AStKf9EMUadr{cmY}9+3(N zB&YiZ2dLxFALeEIWAE3eLmUBq0k!jVfbnGdUU*0dtk+NxCF>hZYhmMrhX35)&ki5< zRKD=;(}eFDD6zICwOjjo4(3+Z*o*>q=Yy{~=hZp+cPw}Xfbu`v?hL+OCj}}k3%CN^ za&G0;z4*D?xv86kMhJE3+F1A(Y@h56I#S7q>L}JoPw^k#(hfA^eKQp)8ctVr;tQX5n(wuC4>kK@S(aHHUirpOekHpjGJxdjR!jmLzfy*fo- z{YS#~|0H|~_wJGwD7lOeKu`C~?!x~wqfY|UO?@^=h36)OWMaxhtSi22FgnLc9Q@^A zd@C#cd(B!UK~Dqc&Nzx^p`@+1GFUDZtKdv-1(Cld;55%WQWuXVQu81wyEm8a`^$|r z?Ipi{w-@&=Mfk^jBH$!fn64N-@Z8Lik7PGy(9K+WT7BmMe-ehgUTh67LNl(+e8(86 z28`2V&HTG8o{C|uf(1dE(9#qNHaR2FS*?|Wr1p4xkn)3``BsuUh5?#^Ro5J!p)xv~ z64E&ugeoFvk8wDxv0+UE(YQFf|DkZ13t0&&sP%UT?*fV;+c`sJtj(WV4rR7S*OR!} ze4;W@_5(1%`E^C|MShYGaWHW$zgFPjV?ys|zw^u)|mp zzZW@8AK3(#)WH~G<;aq4UyCnJPZjD`|KPIx3zcGfApP~X&2xa+8MM(ojn(Popz(Qh z7LG&zWPViDV}{J>c)!JXK3RV9G|@|#S6)(M^44FdY@Zo?KI^^N>16@>h=gV5YxNKC zt%4U8djc{e>f-tJ=JpK#?4uW9#L)@1iZN!!>c`KH41fNk0y}{qA^&mO_5+Xn-sN;{16^U3|i^_$7(e>3CjR*S7Qh z-mmCR%`tAs|zS#Rkr16}7&uyK*XNwU$%GAwx$C8-|d_cgGnyx0WU(pT3CT!&mTp zWBoGJqLPYmBJ>c^8d`?a<_E??^-Ti@hT)~TYLICauV8jGC#<8)4ii}I{b#p$82XoN z%5mXx5|{dBy}@jMw$WV230l~>3h42FD;|c-XS_dbGEtfX$+wxY21XHsb5V68*q&geyI&{ zy*^xJUJ9U{Q$06$n$w_}=ecFqIxIwAw2+E_F(m=sH< zPMV=Un^53GazGVHYZQPz>+7va$>6C6!_XiuUQee(~nJ_cz!L9acq+1SWfk&Z+1iAR*D_6J*f1! zQPQ7tK(uHUane||)U8SSB$Dfl2s{4q4Hd=-x1B;G@JI4@f-V%60@uF_Q2$0>Qimm zs5YcBp${DH<$NXM=zy(r?kI7@oD~dpszm+>%BXCTSm$U3u4j)`1j1Ua9P_ms^?zzAxdspPHo>g%$ZYb`dF-ZNrrx^6Mt4KiV>?b0pL)nYE~_ zP$NYeGJGE%|B*; z360 z=oF>sY+arM$80X*tGzsw7EB*>n+4SniQp>A$lxp75~+-xSL~p^JiDx2V-V3xY@;$O z%NdIb#SY#8v#?`ld6Tg{OmAq?i@GwZP~S=LWiP-DO2 zfPQfik0+e)UhF2jS_}+b2F1xi5y*zbJ#vULGVD8G8!5#cpJ{*>FEGjEQ~`dQ zcOU0y^v1QfPn5adbKorrTEV`n1jZ+_CsbJ?7Kr{!{MaVr<5I+;lH8( zlWWm?@-3xS25%g{URt*s)5O45P+KHTQmBiS5l41G*l2XM69dicDjS8R&7MI?rhX$| z9OeEVX^1FAvg=?cGlm5GH&pt&yd*=Av8$S^(AY%ltYRug)@W2>D^WA(SW;|dj#Bb* zPY9}ZL!MjVzPnal92|C{3IUIgvC$FM07?EV&8XVOsA2{>=keTXV!WOswB5r0g)(sH`pxVp$E*LSx0bY$^ho1gZ(Ce+BX zgV-v@;O*LCgouh%LTJjh>6fNe1i)!k?_(K>@#hAJi=BY zGE;k|p=-ghx5_WRZ|zIf2wi`nNO=!AA^h@IFVd>=cc9tAO;Z$>jb7>?tb6ny`W{KE z@4c#}i7OkeEN~Kt%gx{BlP5$=yT6^}6F42x4XRhqN%6t?;^?rmV5dyeoKLqcsOHK2 zbb#$ru$;PP7F>-8@AY=H`&w$0QopRgaXn7;V8}$bm*lMCBkc85YEVhMoV!yFW|9fq zOOmzYH%4z?uXN91iF#K}mflTpD~cK^sdvEd|BV->>NLNJv8A%AlG31C6zsX}U(Y-$ zZwF~!_}FM_&U^rCK^~wXBnkagUjoVFg9|^`O?Sx!Zea>pf;c8<%({Q|nH^JacOn1z zeADz)ALFn#kY)z$^0QBF!@D0pPDEp@pW1(>)BE4M#(XVf)^jdx86Y`CCpVU>tB zuWv)APNSav7T`?DGY-4Nv|7{Snoz5!!&0eVGg@vN53J3Ee_3g#hG{28yjf!D{fT1E zpg%UfmE;4?O=&gw@ZDbf3Hai_OYc~H3~3&%p!09Y^Dod7$$qC>#(szjxJE8nhoW^b zyHTy4i$#2Ft$oO_M0HjPEsBbN7v4b>>76ZMU^64jzyQgDIvRU(8vw zWPJAM{3hPn^}8Sq7x3jCh>#A0#0LkcK;;6~LD|#%`NK@4|3rICT1gYuQz2?o{Y!3t{~rZg8TZEN4}C z0NFhS4PVz}Y>K%r9px4qj2)fe-bF0^YHjv9n(WTJK5}pczXS&VM!l-6Fb>;jtTbAc zK>wvDj2JFDuA*@Qh}BhoWY_h{4$zT9GX>R%Nz*M!2arbiK*p^`yCvbGMUsmhg)T~` zogo2NWbfPXr~}*^P`(nPi=GphNo*`lsV|mWNcALV zT9G=LCo(Lc$(c{p)vLpUgeC#3E!-5SI2<4q|L5aG>&KDQ6FuD;dD&Is2 zkhb{2IeyUMrXlL3Ba;z9Ch9BN|Oh{&lpP3T)V)to~umT2O}(UETHGV#M=KbH!v$e0++(+CsN zSl4jZIVZ1@nNopF65IvlxKhF>5$T-|oFbj-96=Jh9ctiE1@X35d7DPBaSD)+;H0*g6&q6ycF7_o7Ecw|X6Ib0dkC_CeD&2k z4?8=&aA-}O)<}TCveL}yP3kxGgUUoI;yiH&aiWuC5M_T*)_gbr}=-st| zZJZ9OO_)~7+%}NDF!kg;Xf>^I7$qw`T-gJy4AHH+g(f9~Yxw(2pl-SRg!wfr8=mMO zCV?;L;%ft?iQ)j@x|yb=-9tNF>u8~|kQNpK7`dl5y417E$Ynes8{9URCTU895-IJ5 zXfeN$gmepw!q10Mxeweej^snobY3zU8wjP`Z4wJ<@b@jSL5`$!bslp5J**O@Yq>%d z_0hQbLdi?M!t9H9mHsEW9WxV>jiGKMeQ!=g11Yf_90%3xV6v_G>rUWzaJ=|>#w6Gt z!7>DF1j_a~&rQ84Qn+njH9Y0@^rEgU;RTPsTLbVLq$5sDYi4iv7pfSYk zd_X9gsDx|AO^DW24B~@?;DVWf=pZLF6g$J!A2^X~-$QzCY`9=kG+Yy0qnw*_=_~EN zmvYy&A-eT751Sl#79(PY&mVc)jF^}V$sWk(4;x?qGTBP>v}D_%V|3P5Q`KS5v8b{c=sf7;8 zFqg%9AX3{CQ8=vcoli2JJISLN>1js61v%7CNzMThI}#;JFoE~YZVWlH2&RkFfePwL zBC^c9cfypX9rvfb?57aJ6EZ_D5mra$NvyCy!xp?Lb-5yfL}CO8w=pD8^(npBqbtWe z0xUCvv>QNXDu@&m73$6t98wT%g8dU~(ucaHlfk$P7=<%SWg&vjyO`+Hl9|^Z7$A zOeO(-ugx8&LSF<0ZU{UYi$(r=E)z>S{3BcrF%?<<@A04krSP9aY&X{NJ*GFAU~Q`F zNp2ioI&(wWsc32Nd<&ggwXsqM(GTlAYEbad$|0uUnUksjzg3*x5Yc&Xb8vjKnM?>! zeF#^==usY-oz_FiVY|77gsk8r|G95&P2beFjv@L;uh@|)xJzj4aebFyE>LydpS;AD7Kmxcxl$Oc>#b9|?L=2Rh2C6xE zG!vK>JSXB`qb3?siIObloPr!}Ofs{EC#G+aQ~>t#!QGX!-OA zf#wb~D}+LF_GHM{J#CA8gfsC=llm~MJPCZ*5_RI6@5?mIa_Wiw4B5Dv}6#;FrRVu8jR zQ|+?GOQ9jvK@6*Cv+GW&!C8o4Q56s=%jKop=|6|B&CB5mKC>W1A3vz>k1ILtRO+cr;txw^|Xo7o4;1vI6I zA&x~YuD~?WRJ`lK*kG?PX+sv)HOUaUsmtw& z{ctGOOL3U4rz&j>uVP`l3tM8SEILA*^pL?ZaA@R_k_V?32mH)j0@U@J+?Gx!(Wd^w zI{)2K(vy=Us;57#LIjbWB|e)O+E#;H%DNrEe{_@$K&(}{)-vmwp^>XD?2CyX6{Lhy za!(R2Q$+KF-6fUr?s({!w4@$2Dggwpg`!?@Us5R)ic z08>>Z7#koZArTNXuS$mrlK>S+4a8m-{t3dHnKQk{ovDKfN3}$BhGK7s_R6T|S7ZMR z#d>?Gs$3g5+|N0|MJDBs7#%NfIJ8Lr?{*!TV+aK(mQIFwGKUd}%}YnaYZcDHmUls; zS#KH5QZE}E@72DIWZ zPDrZtVaRC?ff+sIP+_6#|j?V(2=p@p+rvTQt+G`62yXR5@5@B(b$-7-lj3+#&Deo1XCzPC>y*N3}&uX0<*I5PeO-4)iJc@c~< zx)tZNom4Dw^Nm(2y^EI>Gu^J&4&|cOwGd=fnl$LGy!#_PD3YeTk~BID%?Yi2hm{%b z2i4A&VXyz|$~)|>Ep7~d{0=UXUY-KDajD~JQ-3~tbfC}oRS+rn^3#ZiGBl2>aXSy3 z=kE{c+u4kIqR2Y}4Sj#O;urUZsUhW=y&vVEt*0_`OwyDc*JT?t%Au`m4bn+-N)kSv zK91 {ReJKDzsq0S-SERkON=-c09|2#}%+_b0t3Ya`yJPygodggISBkbAcyLjE*Yb3t~UOjgkC_x9x z0%ciuS;!aTIaZoh3#Ky z{Mn*dN(JR&aE6UjX}(iKdiHtp)?Dn+DT-#nTL!|b0~qQwX}hrXNf8(CFUUz3Ck@ZO zJr(~a$g9DPz8~o<709L)cO9H&>>POetiuW*8k;I$=Ny)+Qs(gZi0C>6uk}eX-yo2u z_Q?nPbZb&5ZAQ%xm3P5`a##*2TCphkfJs_WqJZj*G(~2M8EXJEwmy^-`Ohh+P)o8d z32-I3#1_iA1go*xr0xoVszj#v7K+l0sS|8GX(C^BPqg!rz>xH+2_DDrF2nbthIsV< zH#H9BPA2g(B$J;T3)c(AivPyJfRi z+O=6D@RCc02uj|UQPXi!$ED@sxGcSV0|n% zESt|!TTYS4n&=IT7>A!CxHRwu+mfH3gAvO8qtFqES*XOFv7wd=(p#vB_9p|lJGH#< zpqSTvztq@Vj38pJ1E@?*IZalBhiY7qD8lr9he#B2TuHSjNRe7gSNXyK0PN+vgGpJs zkbLPNQfDEW2OTT{tZkrJ@nZ(^`bK0RxEf-n_Qzz3q-$Mdh=Fz>d(I~bjhXwkwAbE#ajxzb1>IY4l z^bvM+z;j4T3J$DIIy7VdwwZsMK|r*zVIa~_TNNHxo0tP0S2=I_2a(-eij8|P=HCyvL?}NiRhz4V3H4+rb))2ccB9ciWLS?WQN^W zPT(mTz8B~sAx80&B>sLON)#-(m#)9@TmbJyu#(!n`HrE>x_o5LGmLwS=iWUCJ z$va2Lku;fU^K=pV9ZU+GEgLg3-USwpMBrAY=I;WH;6Yi0ua;BiM1;*Za$JT2 zc${@R6iaXXO$zt4A$&3Y+u%vBVd)u=eplj0mn}wMdkiGxc9f9m>u^Lp+UW{zO)C4HEw?2#b*6zx8Zr=L62x~jL8Fw9ewU#DT6 z2*_z8*r)u>2`PabRe88wRb&m|lG7)<>6lSQFjIkaL9Q23Uzt>(=JC^`hy_&9mX3S3g ze17Fpzc(+phd*xqX+PyJRJCh^kJjAyxsC#TvjI!a!vE8&T6n(QgS`~w2z%4=KOB=O zOc^0f#tPmk7=p}tBKZ9L2|iK0{8##~GllmA*&iR^$fziT2@EISxQ zGLAN1)CgHfd88>D^ZAr(@ERBCxbY(--zfXMfN5Buyr+Gu)4y(Soad?6Z8R#)^yd-d1Gau#{Ee~Msa8J!f(4)&Iuag*7dFBY{{PO+n0{8c6LZW zXc0MwtoFq-a*0id_%Bpyoo9GGkr%%MVY0J2^%QkbqN@4u?s?hn+AH`F13?4^#A;Mb>1;*iQ3? zWVEXstG~!WJRHWQDK;f|Fk)?ICjzhBxTBHAdvK6uhENYbMuF6@1MTCxZvsw3zrQ$J zOz5FIQ%d)e#61y$oe{ac&>Lpoui@i13&d%*oI~2`;BF^@9lE)TaSd!h)6Zmvnvkzv0aQ!JPe2 zQYfgY&U8F5gc)97Dyo>h3{uNTN;HUU=Ks(RQ>BZpSyX6Z0_y8r-Rw;uq9K7`?XU-A zN&TrP0B4W#eMpL3Z2WUCwyS)=%^hu6L{T=aXqbHpi8DML_%mjFVMj_&iaJhG)D@fl zqo#;3tB55bT78Boy=Cx(j zo3jc`p8rPKTR_F}E&ZZ{Cb+u>cOTr{-Q8_)Cj@tQm*DR1?(QDkEl7Ys2)UF0Ip25B zefPa@t+!Us(0g{%T~)hk_m-+(&9K%l1z=o53Xca5dU8UBr(u%i*&Tki4>N}JEuo5N zC)XxjPCN}pufXoP=W3PQ&0n}ZgqpJ4D34aE8(!8Psn%03 z=)^oHDl?{M#*$Lz#s)xnQ-!BRVF|X9F5H(Wt6i$v1kg=7eB>LzqO~iUP2*|&}=PoYMg6(K!GRgs+J#QqOoi;Sa7Q;5Co|fI_S}ucxvP=_qicnw#6kW@3 zkp{zDnL_T3_or*9ODt z)x^)|EDIxq5q1-Ul-hD}%ES%rB~f;2FMx;d_CZAv8I*Y@WU_m9Dcb7ng$K)r#ymf* zI8#4L@%SVu%SJZZ$>31FO?neEFnH-NaEu^j-s}fO4J+jH`q<>B1PPl4Kq8r%B>A1f zai{)={(nNQCWh?fO zr|<&7Sx$3Wb%jBIFqi^ko)!m~=5g}@VHJg6q+EkZR;06zVq92iQDQG;7oLS`b)TU+ zjjnfkmIptt)LjYP98~MrQP7jbywS>2e#pU%vVb`Vhqa7F$uWQ{KUD7{wr-WD&nQ$F zt}XSKsR(mZ5eL|Po0c=OSA>fkZ-VU7sDhnDi@(`5{-Im%U?#DxZ)*u;oMs&{9+66s zgHqF{XSq!cPg*Tsk_)GHxiYVXdpoJWu}rM-;SXRc=uT+C!&kRxqT#Kj^F)>I%8)7d zm8@U)gs%V*7_@Awv5**8Z!o;HHo3wF(93^F|Aa#vKs$jZMHI{eyG9W#JK0#=%Fr>| zAH=8=rpo0h{az8703Fi#bn>9fYGeaU<4fo z+M?-Xb7oo)%YES`ZN)L{Tu;J3dSb%=pKiO;V}AGG-o@yjK0CO>F;WCEj6IK1yzXEI zml$D+C()I-XLI!PknLXM?%a}~uhEC1ho7=qowQGOuH~KxD4Bl%GmJhZ*#4PduTy0% zXqsBIxQn=+Nh4kQ?JKP+V6kE6n8^;F@FtWaVUcwm*%w+!qq|{if{&K$LwJJbS+PoF z!_Eh+nDa);R&W;PQ#a3U0zO)RKLA1Rxf)IcvD4d-THHSXEAh1&Y@u4Z`90p_qHTTu za@%Jyq)S-CLs`~|1+S#2n_gr)W~xNkRC**K$ncrLSiIMD3^lPKR$or?p@w4-i#kuA z0-qn(hNsk<_f<;43*MXVwP;)$^MdY9UmSHc<2!!4thEy@KB5?2m;elX|rt;kR12=94?mIjUMAP zOg4QW=h2+RjQ$pJSf*D6<$ltKTb76jX+5MJxX*U#JdX|V+!plLGTfKBJec|xGeaJm zXqsrJ{<5c>dORc-3U3+EyV8^jLq{9(AV@Z-^UVViH33u0HA%YOPO`$84ROdpT=z!W zt05xj%Bikeh{LjBGBR!m%91CY=FE?6RS*M~8Y5;}G*PhZBRR9dXsYwi%r@AF9g0(C zgNf0!9HjYKcDaSf{NeqaRGk7J^fs(-{#Qw|50N>=otYS0HDr&g2%J9Fnx?m9mjEr; zKyr+bcob-gDo4?X&JokwI(!rAA?O(Pc!sP|`G)+1L$mQBof3flz4^@q@+_xB6y$7J zl2$qbC-$hc>r(+3V|10+fG_ikGS47r9}YsZUWSSUQt7z~y!Mu!h~2FH-d-gUaGBOK zI`%oO&W&ZK-eOq%b^>pGf^^2@9JVX`o7~_PkTvusM)J{F)wEraBlmXbRfhT0{AK`I z-!2**CYNAtON9@tv@B{AJSWHS9ePnilhnQfAxrWQkl-gum=t=kK*z66Q7(M*M%8jH z%R*ElJFvGBOsN*vCDg>qDE(}>7u*qQrZUPTnIcC%7|<0PK)2SJp`_dLJN);y#t^|u zn|Gu~8uqt+g47@QA(kT)n$%oQpCZa3&w(9@Fh9f*Zum4O{w% z;;7-1J8)V@84Inu%($l(UhDej9k?!_lhP@$G`@Td_Va%I(+Iy}QBJffXT2wy99+UF zsz?JMP&=Ve?2bakv0D}0G>HXHdGrX?IziVP%^jjceWy?q!8+A7=L!%&A56SrHM9&0 zl3UT|L%D=uV~dwAUk_7j#sU_wp$}tGO1G21#|`R)$H@@ z;lO?X1(A?oKhb=ZO*%DCc{BqE0StHo(^#{hl7om5=q?{KL$N@8tL)Lb(_9Wc-<)Fob6JDKd z?^EL=JS+VT<4mX`c*h%urcs`z^N(bBxMC>9Qp%)pG^WZCQJn$Gobde&gTx;wY@C60 zxy4dHTjI6Fx7nn31_`#fBqQ&t@WRqj$Ui|0%9gf`%O~Zt?>`lsxr{5u$dQ%0 zx1OA$`6v(cXKa9X*VjYZeBL#!qXUqmku zPL#k85!YCT3@nFG8(o+}j3Oe!)vkg9a|(_>ASf>HHA%qGeq+e6xm#-gA{i%Qin8f*G*!VAOR`Bly{6&{#s?qMH^)GH&P^Du_aFb$f5S1zN$R@JJ8ro9m6k=!1e8=?Jg>Qqy_%Hf7s3;6)Dh z=Qb#9p9=7+0>>h7E)VU7Sb?km!>dB}uU7>pQ3B!O<`nI{$lqyY*jQW0AAsS2)@uAu z{2|2&Shva(_j+DcoRI@4Dr`6lTzAt_yA^85k4QBYhe#9%RJjScBa=0bQg2AYPnMjF zvMlgDl-Z)(RQW3hLEE?c#(#DlS+FU+&J`lahDpLk3sg91pb|7j-Ne61SD>;zka&Zq zm$v3K1|I9z4d3)!hX}vd7RmoS;xmw(_m-M8krZ_bxBLtNa{WH}MSHZ(!9=bhpgaDw zZRjpU*69sONb0@3uE<}oH}>uImFwa1Y#txVKJWa&^hpKmI#~tsi_D zOKpL;&rA^S`xVZa5T*$`j8-27IWSwC{>mv=8$aDz^+iCMcK;;wxFvRmIiA4QXCQpDaY}!G^hp-#`q#Y5y;gC0FC_f=u zlPn$-v%BA6wgS#Y2-y67_lr%x6CKCs3G`8*U6SinzZE+l^Vtj0T1FAvfXZwFUi}txH8QiGXsoL-_^E$5FG~n??LUN{{}|KN#6T zO+__B%BLbZ@}j&~MUN1Kd?>!1zk27d@zYC?u*~>~&@ybPCm!!PiT`8Zs`t-OqF|S} zPx5w^g-2P~tYXblliPiCvm0df(DyYi$pl)sS(chRv;q1Ck-k;B8M3#zti;f~jt z@@PD8xb+{v1wA+dixUkTfdvHt4F?Ge1%LtvVEq$;1r37+4#8rB#UlO0!paU*#u3KE zCgTthB^NWMbV~SF22Dr^h>zfr>s1&vkqHy$%x>jf^LmaM60%egD_e7#VoVG;W8>|* zqiw^whg&)!eDpfl*{yzO#Z0HV>0qQo{T%cinKJdU=Z#F8I+Qw0J5PI)mLj%q-wAw) z0rOG)MsPQX?`Nyk{=WI?VuM#E8=^rnT&%=mBQEsEMP0ifI3^3}qP9U@@uFx!>`4v2 zbk4=i$pslPBuimnVr$&$o)nQ(REzbYSwd^vrn>gU7A|~v&bqEmiNSgXgx8badJxp4 zJ>!qXT6;t>Z`)1G6ds$JBI%7#5%h_k9tyNdR(PNVR=+ITy}emX!p62U795 zM66??@Z~c%n6cXQdu=>pRaFlw+_FZM-5wHPhGs{T18d{IPr2m74(d>;UsPcoj_U?cPs;H^i8*FRcAKrB1=Uz#>Xj* zoE(BG&mvzdtx(;Yy+W|`{QpXC=&$sKNp7X-?lJh0qbA2?>)UhHX&9#6EfSYfPtt^; z79q<6b|3yjh+Kb#*l1RD-Y9gfH0c4)CsGKk`S33Z8vK=DSNql{13ID72~d%lyfbhS zdkO#0N-8e>NTr$#ycJkfq(*dJA`p74JNHCv!B@AeN9T?4O1xThWrz=azZe7%9z1^+EGo-qn^-d{$SNrTJGuuUZYME7aa@9;)JZ(<-1kAAi(jg2Gdgddm^&z(CX{{~L;7TC5IT19E;a6pj8J&|USY-=JzA-sECEIeCcdN_h;b+eZ~E4ptm^Vx|NsjPoFyW&HlS?N8+@HZpooFP1F zSl-}w2~w0Qt}krV;p>i@{l(G|5{tchgxZgmFezdht2+50eJ^14J#W}9?J_$%k=_8)k+nyVRQew~Q&F=icqwTq=X%B7kK5{?s1Y7k=~TKKIkJD%+-t#g4G^&5uqr@*q9@>Y<|sHe zz8^pA*S2)fXy|mL9M%5{9PWG4S0~TnBk;;J@Y6jsR9#wlK3aJDeSP^3R47-#Yo_j{%W?rwh`H-ZYVeaZJK(nwekV{igcgP!FswRKQ!1v zu*QPYPVEK~Rjc!94OTW6Sl0Vtix$DFY^oo1K(ZpLcv#6pE!OS%Y*S2{D1984^1Wc5 z{JUCjxUk~Gr)zjjB#aWM8mJu!&~6Pze*U-LS8kYum%Dq0{qxgfgDt%J{eA~V2bsdM z)Y>D^1Sz=}gN0DN>B}7XIJ}_*ubNrX9AM8gwmNTC6n2>cQ|Wn`?IQ2lVjI#ccuf8? z@3myDr+mK0f@zS_ioyvDXBHB{>uO;0QvZZL)pvjwX)0+%G5Tnn;HJ^R*Mzm#5oFo; ziAv@Z@cnbH#a1|cRgA7HloCqt0km2^x@c!2-=(OvScj$eaSlC4Dq2@PfNkHO$(C3 z5fZwdh~mfj1MZ(8Zyl8{#+Aq|%#1WJ zTDtR~8f$tHT@>DV@6})fkeg&ie&P`d^_zdwDY@L>Lq_UtZO?-)MF|(;N7t*7i)U86Jb` zTv~#r&8?=^C8($LL1WoQ2m*fgj3FvNi3p#k9jA_Jl0D=28CvY8Zl%IJ^mhm1G_o9L+b`ZO zsREn&1mSuihjP4mm(HL5}(0?X$mJ5kX8u{`_JrecCzqt`C(I_KsMi=Lm_T)p#l z@74-{Gm!m%{z$&XF%#AWtSd3|IZLpy$54Vuh=9VK%ojE{g<-Xq*jF;?pw<& zZZdE4%WVzq?X6=9udCyRjxf%|)3cCFGHS=N#~<&#U)Ppi6S-Y@HHq-`OOhy4yK0`1 zm6{3sbHk_YGHmmgTHJ;{aUOwkx6AkTGXZ&^95*9VLyrD!b3+1vMye+Q{og2Fd!DeD(O@ z#GMAiLz^bdVqMU^w-moue{+t$XpPoCtO!aqxe_LeP&jXIO@R0lCffc{Vl>=Io)*( z(P^-Lj8J8L>m46P?LK*cXwaeS&_Vq@udb{1e>{p}yWT14`y?n`a21oyDPa0&-NOFs zQ*`F%y$(C(=HLVU$?k3n0$m0S^&1Xe)RP+d0{~A;h0wtBP)Hb9L>MUOe`cis2mmA$ z8Y&nSLf=m7gYJljwf5 zhXXsg2_7$JR1ZPn|G!@AowaipoK|iZUM<0g zjesU`D(WF(hOwD9jsl;?Od?JfGQ@aO84;L}Wxhaa)jR{oS9llrQ429V6qEz_E?U|Q z(N6nC3ogk4UgAih7E8$#3yrMChJ3&n$C75*alzK7YL^*MgN1Y~;mnPpqR9;R1bIs+Y5cWOst;kSP>7p`vlaQ~{h=U6SwboDT z9Ha0wE&jR!4{#?i6)O5$1Xb6RJBYIy@@fP>RyXgm`3a%K`bId2iH<%18(^NJ_~V`n z^Io`ce!l)+Pl;|atA6?yYb5xq%t8`hw0t3Zt}%_^2BU-DQw*PpB@vo1ZMn``1lFb@ zh?ZG+(4B3b^5s(w6e05q0;~s2Y1iwuW05vsVw7zCr0pF8l3q;G{fge`3p)(ZnhlVa z4c8W`y>XeQRmyh@m!BoY@j~|2c9yOc;%ne15(*x;;aB#sf`-)^j2rL?8WC{wmXXcb zh~F<^uvuV{kKJ^B2Gjufeq=6~nS{L;y)ma2|Ag@-A6D7qe#T#$eQFynPwbZ3K-V2h zpl&e63L}}%uLUqFeKwSHmu=|BiquxXv(U6&L4b+SRtp-ob{MCru^M7(Hf=W(^WaDV zrxbK<8MEbI5_P2Rg&es3P7iH3xWwD4GvLPPflEczZufHAmdxbgi z+B2{qv_Fy`DZLbRREKYdgniZ-C4A1ch zU1-#JBel800)sTv7%#R!jz&xKBVv#=(eC`~vF_?x&zD&k!$qw8pu!i~=wmwOl=5EH zB5&E)|9uMnl`Exus2lBZi8CxIPo%Gc*rcKis?FD%ci>Ca+E)GTHhXb=RJX`#fG9+)YDz z!=}8$C0#~XWK1rIO{0t|0*xw6ikeT#J{XwEzlsjH$lBC*HI(^K39@ne`^a=)oiZ@edc`tiBOeM3p#bohJrt9Gr#uNH&dF~6A5IC*KH%{hEw)7uy~+GHtg zVrRNfd`wElk?XH#ZoP*9z?`RbzBQPKrkjE{D!iEoU_JEnm80WKqE3 zhsMPw{D{6N5XM9+#S#98YwK~Bfa9=(;=5)K_7QShYYui}|3ZVJHGV{2`ClPsdC1{Y z$(Mrp1+PD$iu(|xh)3JLpVPQlZ^9pPiGf}Q(ZW**POxh^e+W^I?t~w;Z_U4@6MQB~ zB0Xx4j7Chzju8gPf1n`D2cf6ycfhz{Ed=K4R?`pf^9If&_1h0 zQ~e~eGB}rTElFg?*0Rf_q@StzYQ|P&K-{j~8+~$|tYeF;y=?7G3-k34AnM?&(Vf29 z~%e(~sow#P{}S4R?r z$V3=)|KtanXDljM@WgN|I#z@H6Dl@F$VJv^Z{JHbU%$SiT7b|GKe^Z*lnLjyf)^$* ze-t7U&KTHug(5QqKP$4i*pmOX%N1#;GaKZ_&tJTK6EA4=9n+B z#Pbey+X&?jD?_*!?=N%L(XeL`-IeedE&Mm-0Ja?Y&>)au^p5nR<*0&Ns3L(zhr`^+ zPY0(o^)d>c8UEPM1jz}2iN((aL)ZNQhzn2DnR5jW!7wJweJOZ4deN$ldvd% z84!7Z`7n+7|9Xl8?K%r_MWTv>b2Q{A5yT+WdGH6IN%D({`O)MLpz+^@kLzYQ;wG=? z1qwIk{0R}RH~sz*egE1~fPjVsK*4-~hWOXm4H^vU1_OXaMFXN^V6w1dVUx0P2rGYL zr4xUd(LF%mnW_6V06rl^(I|BHM8M9ON(0OZZ zw%h#dp6cK{J$)(NWi#{M7N0I1oyHz>J1HlM46(omdCTc9-wpTd(i09$ zNOs2*5`iyG#7!wdO*p`&6tyk*!*|b&8#$N;G;E^9BCb2a)^P|Zq9IinDYui5{T^?0WGBxO>`Em}0X3DYC7tC1IYFYle z(6nq@19>^_ggU6YM|Gb>zwRaS3@FXXK(Y@PSE+|jx9x_Kada}vYfEs@Q zDm61%eplGyUpx17&*bsS74i}E_4a4nLW5?hjv6^>iW3*d&&`vh=9kz;j5wZ`l|$jt z>50#F)>>)NwF?tT9{PZaX*aOGCOT!la5^2*mDG`0gq|}BIxLfd*nGoOUL<9c zbv0?g?NhBR1|Au`Yq7)75m1Y3%$fF6N4zUh>1171Vs!WCJ(yZSZzeV?&9WLD|!cQk@3N5yA!LvX8%>3kPsoHU_A z*DSS}>50FBTSe|~tHjQ!u>*~?yEltZq!W+DX$3Ou^tV1q#K_e1@D+|GGacPj#(KhQ zqkit+Ok?>OAQvf+ZjlTwL+`h^w7@gj{t=O*EY& z4mv-!kny!+!z!frdtXyCYaSil4G9SP9?@^{dJ^{>2dHP? zR(SQ=@g74hbAM1;?$LES%Q(P0oA5OQ6*qQz5=cVOKGsigj5$zBpK_4Z*eOVevdg@R zxq3bJ&wy$nhCaX0vqe{H9)DG+->)X4#PUaaUakh$Xx{Gjz;72{VtI2Y)-?62Vd$0Fos^iH{g>KMorU%iiJbaKM!D5Fb3F~A+S9$RsN9hd z+n*pKT=YxW-VtzO*S!pI+Ub>@F1p0(uv)U?1_{9Th5a>zmNokSGK5|N$@*W^Uh@&e z&gR->GpZwx&rsCcn~xamnlCf^Zn_^4yJ)F60!kT#8o)gy6G>V#GJT+owVChlFw5%UlQn@z7Qtnh1|<>2ukCZCE68d@rDn z4MlPfHms%k5G6h@B>Va43NQVhA^k&#+a6h#Dnc?tD)#WB0`)o4%;8$yB%UgL)G3oA zJK3BOvdUxBcGGz)Auuo0XvkOTapf4Z0%-)a#&w=(qz4JM>0ZJGjI1QwQZQazE2v)m zSpp7YmDVg#@L;PvGZou;wbR|_DI>9Jo#Ox{y*mr{EB}J{c#$2e6oE&%k61Jt>rIrT z^n6^vLM9(`yvgVvz+q8vUo#p@`4{10v8bq=1@~<3OpKsxi>5GELJFf^1RN)pJCo|0 z7&`vK7JD6LFd{muIoe@pmgjtGws^>h4Y`^&Flgh+LPN5!ax-DDS|03206aCJGAOg$ z9O9_h_?8W;O+e)3noPc3=bF>0v`COWZChQNj(^HJ<0G+kNlb1|wm2xqZb|#Yz_g9w z)jk}_szB>@mrNt5RbN80k`AV0rJIVsDw=wWgjKQl66oFRIU(t~4+iG=ZC)(MM>jxi z`D(5Jt-|7!X0sRhj~oWPK<*cHYUWcAUyQ{?;v_(+RYMv`x*Jm-Mz96z3R9t^wiXFj z`;9S0o3b~k!!IXMR3sQC+~b*l`>%G`+88r}c>Z&;8>6g#St5Pg-{tN>J6cE3@(eX; zPz;JfO$X9}htog57XSX#(GpRjE_-t8lp7T>>5ijaGbNa9GNf~+@y6MJ*{RCM&rf2S zJ<6M0t+6jw-w;9cFhIIA16_n~?BE)fWmA^8s8AkIrXP3wE1D%H;XZH9>T9Hd@$pdr zC|O{}JI2h+OnVlmxl#HVn?6yuGOnhaYEbfsWei$ngji3LZQ5ZJ^V6sChB?4PDwz}v zqZ;Ug;i{pAkG%PnEdT9zgG|k$9A<=#rp79|cFvP+(JZ%ltILOoa>^h*SuuJFPyV7c zDke=uT{1Ekg|Gs97~2sB)&6HGrYk%K-Zq> znhLf>ODW_T9ddel3HYqWNqXJq3F9?>sEj#tJYvLU0jYw%|zYRUir8~$++-)D8M*WlNiz);jY>+s%E|N z>DZ}y$O8{gTD_+J0AM5}PRC!c#ikM&u5yj%Uq)Rs^@Y84K>@k<#j2fnW~mkas^yv2 zuQ^Y@6@C251p3tSb}Qx_mrvU+*tZ^eu3uxo6%y`R?1?pR!{6PU(OP%+K72R5lKqsmCR{)xUu)dZkXHvg7h;oC#Hpv$sH_hc@lqOZGMc6 z?wacSY9+fia1S`Q0tv=UZHoR1yALsi9_|pW)Rx0;eW3JT5M!p2e4J^$4kV zc08;a^=Oh@rRBl5o_V$~^EyKuB^6p#s*@_VZkc`6BI!snjt86945Re*D--Eus@uLs z+@ZM(l~nRBD<`y(1R3;~yI`AnL0b%ZWb#b|8<|vSlUN=U^4BXmU!c<7z%X z?%CZ`CD}`2mnq^7^|^1Uz=pT#Fq&Sa4jb}bZ&F7Rbl!v_-}f;C_|ej~36RDONSEdc z)63ZEoBaC)p81T+%X34@vxesSP}@c_HMZt@>COGx{<;DuQDxr8Udo?XYH2RNd0yJA zq;(n_zGRh>Uj<1#ERDA`h85#Qrzre5Vyx60a|LRcQ+;%}x3k4Zv8bnSDcwLQ*F(p< zgCX+kxA8%1iT60uXVYud{k9_&Z2SPst&bMd$BS7S2_Di3@rb`lGENP;1x zOB@@;CGU?#d z{T7=viWw{Fn6ySuxW=KgseC)T+xiDUT3EcIG}EZ*)9zXyR%yLgt0h0Y@+p}k#mI7p zPiU-9$ttC9=9*pYUCA>592?8d;Gg#aJdte&WgiFCJ69DI*U3&cz)TW(uYqGvHEbMe z>TySwR`441M!U!twnFKsvECcBu$-NR>?Dq(UrU)M!Or`mT*tFJ|R={uh5Nn6vFj$Rxsm7+sM zeI^BOS8V5cS##dG+*+&7Br%UX-D}R^9V@Hr^T=Lbp{ZX*^eYwfROD+L!S7Nsa_?GJ z?+1Bt$%lIn-ZM=gu-DBJ2d9kaTeW|)4=`EK`e{OKIUa=OD^drVN=#&*4a%#wS&s0W zjYd}20@w?%gOfbfIZNx-lOE;{vylc7Yt0~tfpxzP=LpF zHt5=j0D4$*1YDKi$WOTSkOI{QPAd}TM5hQB}A)j1;A$TyZAS$cbg2xGnV7ftz^5iw zKjH-Hk3J(`$MvL90A71adzZ@)h%ZgxsQcOJYCg1K$plYtF#PT1UYb8CT4eOBh5LDV zp8owhu=s}na2~jp?UG-PmlzmW-X}lw@~fg?bE~{~KiV~}F3NChw(fs!M5>c84@o=Z zuueS$CFe>3i&_SB>}!cJH!akuF+M4!D0y=>nIwn^eA|L0=KDk`WXHfARpZy=Z@7As zdWZOhqP4UZKTzHJ%M|i%JbT-59gd6Ji_j&}FT zFT1|Bb$sTvp=N4&M+49$3WO}b8oc9IYqKJ1$+CvEN%%KkNmop(x;4G3?{p3t*beYM zR&(N3^r!Kq5W9(siz_u5(*F8O1XqCpP@jV1x&Sdhtc?*w5wBS3fz#Za`YXm4yu1%{C;K7E_4JwWAQeduPZDwF62*>o4ULj_eP^q9 zyK?Jh=oxJUM$mO{iB=q{!l4^~ZM|IKVHj>2)spWo=~G}`8qzUsZNT!UY?kfi_9#)g zu18C<2zMOI+P%c`~_RU z>P>%VbIcQvjQ_LxPCL_op_<$FyQ^Jl#S3F@Pd0X4Mjt#`-C0&YI+XU#bKLm*$fwI8 zO?dGn)7=-wS|%lAqlTq?9YzxBq4wFt6;6Iwrnd#tx00We3U-xwrf>MxppWe6--BIP zsd&+{tD+k7&e!g3!HIbFl!*-W4j*tLAQX)C$;J86qM?-~h96Ao&{Zw+Y~;vfjO0Hw z4Vn?Xhy?@Ggr!71(W?^Sple_Up^D-@glY?w4P} zb(<5<)|OVGRM3m~em3<*^Zjfz-6Fu6ZX+>n&+Iu??Cm$)I0b{-)PWb#B>uYPLPEg6 zBSJ%efcP)BTr_lO@D8X71{s@(s+x&&!vZ;ru&A<2U}8aG;{d68(jaC~(LM~jv1vkb zlbG4R*VO*m1yn zNUS(Z?+ZH40x;@vlM?YXtv~)&tTU1|*va`ywlU6%4pg`DV&<&#(|*wo{mEH`4M(W~ zqKu8z!*uGZc`EP06_S9ltD;djxWG9S5N#a1n>=DO(X*{4M&+@S^Fyj~**@|CCXH#@ z;Uwm8e)3f}8DKbzHE(Dlu*5y}zdwLoJLiM3Fr_?@UIqv}b4aS85C_!qMwE?V23>q9 z%Kmiz% zBI#^-ld_G?4{6`$Ijs)=Iz5$nKCem4+vK%KFsg7niRqqZ8bibV3{#%eiWqL2#kV0M zwn?u_Yqm`DEjOCDNo!kq9ij+B*#wuA7sJO$1=DU)LulJtPnXYf4%@EMq3W?2|KdvEj*4U($6&Z7v{_58Y$(b@ z)+l{o$2Wng6ZmVsK~>}u(|;;A;DYquY$pE)oBap~UAeOKOgiHB9;z8$HAOPD@_n|a zf@54viUUSj(HB@XF5Vw6hq9?;ta6>dEpuY=2K0!N$4L&5F$EB4leM3!|MuDKOL+)u zrQQ`{zSa+|<7C?{-?|n(Bqo3Bx*AerBXP)jpcK0Sj%N6)3}t{~crJY(8K=b8r4*Vq zMTCA^rc_na6r-6kFzOfS|MEcGzI<8}`Xyn@0&!zzbbPLLhRFEY-Oa>l(gDd_xjV)| zCxy#iJc5%3ps9eF*9m)Fok?zmZQ3jh&`;LK$=vuHS?lGY#reCiL*Ylxmc{Ruxe`A^ zqv8{S^CPO?a6Nb(Y`?2=1j7HDy%!slb|a1e3sfrDm`hSyvV0x0VFCo(_Ud5jm{Kt-w59*5 zb$tA)=pg4S#r0R~!s}0tC)Vj7RD4C-nL?FRunVjrC%GCUp>4^E->E*;nD6`GXBW)h zCR_=s&El_r{qpY9N4HLD&- z>9G{s7#}1`TnT;4`L@TGd2UE&f55~=pnWluj645w?){Qq=vp7)4w*E2N}{=VJ|dfN&_(5b&gH(HuQ`=r};x=%Hpvku^QPCjsP z9yZA4D`vLGK*Ce%F(l63ob@2^>=LG0yJ!G_XgLOsHOWY+_m9(Kx zadThtSgElE4ez>^mgPOsR(O;Qo9_;z`efN9Qn2VR7h+FQr=ssQH}=+Xr!V6qwx^4I z%*>0fE(8}m9c=HLD_!}&B{y0^6X#m{wN46O!@lHFD#S5sp-QjAV|+oX*1iJPXtO+d zD{@E4Cnpan;k*Y83#4i-HreSa`A4A3)aA8vkhA z9{_qgfn+7QSJy&IdniGY3~&y4@_>!@X?>xI7MdtTtx*xj7gyE6e@k>dHr1OB2>%~K z=w3_oSN?Dh@8QjC(Z<)s5_4-4^Smytgtjah@EqIM{gbwNlGpJ6RsV z7=d*CffvhMaFR9W8j^6R+ss?_(D9W(Yx|*UUfXKeSw^m0v+M?+VA3=F=6o6542*r3! zspTVpk5SNQ)%dCjFNF^Dcz_ygSp8%yS5T> z#_YE$<<6e#kZAmv3a9~c&||DQj~KnuCuqrGRNed}PImnds>RVr&23V8Xwrr#oXQ+} zWhOId^0^9w^$p3t!1fkVt5!?|QfcJP#sVh+VPn%Cw-vB*NGHltx9mszf0^ z`4PE92Kzi8zMeFA6iIR}8C{ker+$3}4bJyRh@-lu978n1=6GmajpfQaNlGEZq)rwU z0A6)^UK#*-l+^N$lj^_tdxe0!vSlR@+A*%)6##~-UY36$C-`5LU1>NJY}+2$daa3J z9!trLWsqv@j3t?2EMbVoIzsj>#A68+VT>`Dq>^Pu4Tdab>&Z?=v`CZe4U)0TGI`NA zy~q3g|Gt0casRuH`@HV!Jns8G&Xb&)Xe8_)t2<+f+(eE9E8TYxBAcD@>C*M#SkMX& zI!HmY8?|fzTrcyGetZe8SASt6a~|S}{V%Z>f%z})W&f&X#8K0W-a&oGZ;GV;0F4$? zxYm;+9i5_RE-B zj&jqfkP zX(b)A#Ga`oyt(VkO7Ot&R4jpEqyg~bmbhn|`4u^zhuQ*ty@ab&=*-C;FS!Z% zP00}ekL^c<-zClw7}6GmMI#NkEX_maIqI)%cMD0MBlki%Th}}bugJ~G#fs0KW*2WH zzF&W0Iy3~q!Y7WYC;h5$5~;fAh7Miqgo6mVM(@4rt-RR;kU5&6U;FRV0_N)R90FEBWm}huS0^1RH!+Ql>)Dd)-k!nz{Y;?mU(Ll;)4vng|hhX?kp*8nw^rGH;-=Q$fz7Eixxn6FY7;?n1! zm$H@(k^hEWjORKKGudEUuQg4RE_`cd4t}@vVkbsc=hpmfsmncRcPFz*EdGT!vvt9E zE?GtDxNenpqnuf3#(ZCM7ncyZG~Wy=lvkdOC8-YD_GM7L+vjB7M_8(NFCdGL5zn0^ z64xST;(HL4;0p_A>WxmOB>xq}@pQ0;qbbH!~>^>dJ{hCjTp0>F9>XOOg#lj0>ED3 zQg6vafv^X(s~S%o`=MZ%JfCx9f;dH`LSXp7pl!wbLPr6CUrh?RJYtcx=#()0Pw5YT z;=qn6cT*{%L}~Kv0N<}oS*1l9X5@1sZ9K0ZrSK%Ly>W}c{;dBaM}I>mv#Etj~Ewh%m_!Gu$?c;G*lAl z5J{~Ru37T3f$LLxXYa7|yFrP1=M2m|LWB#+!QbKi@t~LE) zT$LN_07xkKqJP@Erg4`+@7Mtz{RWgb^=*HFc5IN_i|PmX6=OsL%Q~F?dGabyo0K6f zWbg^Nev9bERIsIIcD1_hNlv&ck(!V2!wl8M$ldw1K zyMH;vvYbH(K&4iD3#u&ESFeY5 z71fX|XPe^lh4z-i#NHdJ6zi00Ewnsf(eo^XsqBo$uy5`gwHfhp-s`Qct-w4pWrKy| z+$CXc^fQ_`S9D5C^JNY^0vC5)U^NSRB&W~Uu7nMJD1)s2$?p}VGjoHYGo5hTsTi15 z>Et!(wkn>i3*SrYX!rHa9@Sn*a7J*$FPew=pzSqsB{tm#L^F*=lvHq^OG_Y&@Y|7M zm@AvWKC0N>vwm;9Bd{hR9^|QiwN2ME51#*cyRCX48itr^MYbiq@% z4=(ktY`;>~lh<4L4M>(EjXNvOgJjnU_Ow^~;Zu(PnwLCg2=hFuEAv*Eo)9TF5%)&8 z)l=H8&gLB`@V>7g{P)P1E4R;-k?^KHnw;5;Lgs3g>Rk#NIcqldK_My5h3%)}*DeDM_3+e-(|7+*K~X1G(iFaCtRA?39O|vA6_50Zd_Fh{38*N_DdmOK zmxU-ebBi`(p9y6AXGNWwMpMF`-+6K#>Otm3kO9Se7@)*Ee;aQAh!h^&^zaQtq*Mst zxk}E)BlFCDxf9j>OzRZ(*Mh|@4~~DrEd7wcc<4oT9FN{X4-y0#;dg}qs!VunMV`J^ zK|kMtfQx7zQ^ZnIZv{~aaS}nl1L(?`vp>7!=DKg0bmTauLxEE*1<=0>7&Euu$j+ND2K8G0TYxmgMx(@$vZ8xZ1?{SGOusNl(auW*Aqp5YVDJ+06E1ch!KR^K@QHMe!ZO+s%u-(u8yt=7~Xu>#Gz zG1hB0!u&;y>+J`bP^S8pmF!(-PP+CDPR6O~ScgYQ;mgFR|K*It14@*i)Um}04*kU2 z8_uzmlYH3@mhEi0By+~)a%bD0<3k9#+l~NX&fy@)1aGl9)KWaxfEzF4LDsZELHBzD zwz`tKL-(roRVBqSCtctt>sesRcKE^84P$=J^r$baw0)wpAylw`A6YmB;nT2TWNt6q`#w zbji@}RbsG|ibh~gY#7({&YjEO#bll;Ak~c4C(u?LX%uTFiUmTb-3}Vx&)z$sTTWLE zz({#C$(7?!nm8>&?F27MXAPwnc0SPE@EqFaxp3WGd2XL1UB1*~Y*L|Xad|~7dV$Vy zbP$z>%hvwU8K=~WPpSF;S6aNQEdjpE9uCU?hE7zqOG9l`8UvMkblzKUH2be^y8jp& zbC771OK}nw)19PaBi-tbjGh$wS@7`7cC0f?gaQ@E#vY0K`GKBBT^l>z`6{-Xat;i` z-hwr^^5L^=@N3$Nr7jJ9y-uOal1a*MD(gUzn!@E~>N?MZHOw!oj7G@~qZOVq@^E@^gVoL`1~+`zrg4GH=q zhUR8rZV6ybF}5Kn|Ijy1xVyqnCbXR|s(F&j6nTT2I&B@6U)Momn zl~40vbNl+;CPGgwrXWGeRz#vo^va=%#z!&v-QX>;r?CzDmF&wICs&t^gjb+HbyAlu zMj$fEW+#&V8gGY(KVE`c>Cwx4@n%%k0e}1*(>b4BUJnY1Zgl-#TGDp0Kkn<2!w5~g zvI66hkuJCqL^qCJr{ynR-v56Ayn?5WKTl%wvo~rR^I$L2G3XIr$!y>eANg-P#SqaU fgzs%Vr*-jYG(YMS<ttdtee# literal 0 HcmV?d00001 diff --git a/leetcode_101/static/img/docusaurus.png b/leetcode_101/static/img/docusaurus.png new file mode 100644 index 0000000000000000000000000000000000000000..f458149e3c8f53335f28fbc162ae67f55575c881 GIT binary patch literal 5142 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 F{0H{b<4^zq literal 0 HcmV?d00001 diff --git a/leetcode_101/static/img/favicon.ico b/leetcode_101/static/img/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..c01d54bcd39a5f853428f3cd5aa0f383d963c484 GIT binary patch literal 3626 zcmb`Je@s(X6vrR`EK3%b%orErlDW({vnABqA zcfaS{d+xbU5JKp0*;0YOg+;Fl!eT)XRuapIwFLL`=imZCSon$`se`_<%@MB=M~KG+ z=EW^FL`w|Bo>*ktlaS^(fut!95`iG5u=SZ8nfDHO#GaTlH1-XG^;vsjUb^gWTVz0+ z^=WR1wv9-2oeR=_;fL0H7rNWqAzGtO(D;`~cX(RcN0w2v24Y8)6t`cS^_ghs`_ho? z{0ka~1Dgo8TfAP$r*ua?>$_V+kZ!-(TvEJ7O2f;Y#tezt$&R4 zLI}=-y@Z!grf*h3>}DUL{km4R>ya_I5Ag#{h_&?+HpKS!;$x3LC#CqUQ8&nM?X))Q zXAy2?`YL4FbC5CgJu(M&Q|>1st8XXLZ|5MgwgjP$m_2Vt0(J z&Gu7bOlkbGzGm2sh?X`){7w69Y$1#@P@7DF{ZE=4%T0NDS)iH`tiPSKpDNW)zmtn( zw;4$f>k)4$LBc>eBAaTZeCM2(iD+sHlj!qd z2GjRJ>f_Qes(+mnzdA^NH?^NB(^o-%Gmg$c8MNMq&`vm@9Ut;*&$xSD)PKH{wBCEC z4P9%NQ;n2s59ffMn8*5)5AAg4-93gBXBDX`A7S& zH-|%S3Wd%T79fk-e&l`{!?lve8_epXhE{d3Hn$Cg!t=-4D(t$cK~7f&4s?t7wr3ZP z*!SRQ-+tr|e1|hbc__J`k3S!rMy<0PHy&R`v#aJv?`Y?2{avK5sQz%=Us()jcNuZV z*$>auD4cEw>;t`+m>h?f?%VFJZj8D|Y1e_SjxG%J4{-AkFtT2+ZZS5UScS~%;dp!V>)7zi`w(xwSd*FS;Lml=f6hn#jq)2is4nkp+aTrV?)F6N z>DY#SU0IZ;*?Hu%tSj4edd~kYNHMFvS&5}#3-M;mBCOCZL3&;2obdG?qZ>rD|zC|Lu|sny76pn2xl|6sk~Hs{X9{8iBW zwiwgQt+@hi`FYMEhX2 \ No newline at end of file diff --git a/leetcode_101/static/img/undraw_docusaurus_mountain.svg b/leetcode_101/static/img/undraw_docusaurus_mountain.svg new file mode 100644 index 00000000..af961c49 --- /dev/null +++ b/leetcode_101/static/img/undraw_docusaurus_mountain.svg @@ -0,0 +1,171 @@ + + Easy to Use + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/leetcode_101/static/img/undraw_docusaurus_react.svg b/leetcode_101/static/img/undraw_docusaurus_react.svg new file mode 100644 index 00000000..94b5cf08 --- /dev/null +++ b/leetcode_101/static/img/undraw_docusaurus_react.svg @@ -0,0 +1,170 @@ + + Powered by React + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/leetcode_101/static/img/undraw_docusaurus_tree.svg b/leetcode_101/static/img/undraw_docusaurus_tree.svg new file mode 100644 index 00000000..d9161d33 --- /dev/null +++ b/leetcode_101/static/img/undraw_docusaurus_tree.svg @@ -0,0 +1,40 @@ + + Focus on What Matters + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/leetcode_101/tsconfig.json b/leetcode_101/tsconfig.json new file mode 100644 index 00000000..314eab8a --- /dev/null +++ b/leetcode_101/tsconfig.json @@ -0,0 +1,7 @@ +{ + // This file is not used in compilation. It is here just for a nice editor experience. + "extends": "@docusaurus/tsconfig", + "compilerOptions": { + "baseUrl": "." + } +} From 3d57f39f83dde643c192c5de3e52717b7433af40 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Mon, 11 Nov 2024 21:40:35 +0100 Subject: [PATCH 02/49] add github action --- .github/workflows/deploy.yml | 39 +++++++++++++++++++++++++++++++ leetcode_101/docusaurus.config.ts | 3 ++- 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/deploy.yml diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 00000000..f2b7369c --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,39 @@ +name: Deploy Docusaurus Site + +on: + push: + branches: + - main + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: "18" + + - name: Install dependencies + run: npm install + working-directory: ./leetcode_101 + + - name: Configure Git + run: | + git config --global user.name "github-actions[bot]" + git config --global user.email "github-actions[bot]@users.noreply.github.com" + + - name: Build Docusaurus site + run: npm run build + working-directory: ./leetcode_101 + + - name: Deploy to GitHub Pages + env: + GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} + GIT_USER: ${{ secrets.GH_TOKEN }} + run: npm run deploy + working-directory: ./leetcode_101 diff --git a/leetcode_101/docusaurus.config.ts b/leetcode_101/docusaurus.config.ts index 6c5f4812..1575e848 100644 --- a/leetcode_101/docusaurus.config.ts +++ b/leetcode_101/docusaurus.config.ts @@ -51,7 +51,8 @@ const config: Config = { sidebarPath: "./sidebars.ts", // Please change this to your repo. // Remove this to remove the "edit this page" links. - editUrl: "https://github.com/noworneverev/leetcode_101", + editUrl: + "https://github.com/noworneverev/leetcode_101/tree/master/leetcode_101", }, blog: false, theme: { From 891e46bcb7ec5d3ded28f4d7a3421a97dd28095d Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Mon, 11 Nov 2024 21:46:46 +0100 Subject: [PATCH 03/49] fix config --- leetcode_101/docusaurus.config.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/leetcode_101/docusaurus.config.ts b/leetcode_101/docusaurus.config.ts index 1575e848..dff9de8b 100644 --- a/leetcode_101/docusaurus.config.ts +++ b/leetcode_101/docusaurus.config.ts @@ -10,15 +10,15 @@ const config: Config = { favicon: "img/favicon.ico", // Set the production url of your site here - url: "https://your-docusaurus-site.example.com", + url: "https://noworneverev.github.io/", // Set the // pathname under which your site is served // For GitHub pages deployment, it is often '//' - baseUrl: "/", + baseUrl: "/leetcode_101/", // GitHub pages deployment config. // If you aren't using GitHub pages, you don't need these. - organizationName: "facebook", // Usually your GitHub org/user name. - projectName: "docusaurus", // Usually your repo name. + organizationName: "noworneverev", // Usually your GitHub org/user name. + projectName: "leetcode_101", // Usually your repo name. onBrokenLinks: "throw", onBrokenMarkdownLinks: "warn", From 419e0f63daa06d8a421b9511f886a2288fafeae4 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Mon, 11 Nov 2024 21:50:17 +0100 Subject: [PATCH 04/49] correct branch name --- .github/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index f2b7369c..36b22ef8 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -3,7 +3,7 @@ name: Deploy Docusaurus Site on: push: branches: - - main + - master jobs: deploy: From 9db658be8f5c2757d9b923be97e58efca6d3ba08 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Tue, 12 Nov 2024 21:58:51 +0100 Subject: [PATCH 05/49] chapter 1 - 3 --- .../1-2-assignment-problems.md | 5 - .../1-2-assignment-problems.mdx | 143 ++++++++++ .../1-3-interval-problems.md | 5 - .../1-3-interval-problems.mdx | 74 +++++ .../docs/1-greedy-algorithms/1-4-exercises.md | 35 +++ .../docs/1-greedy-algorithms/_category_.json | 2 +- .../docs/12-linked-lists/_category_.json | 2 +- .../2-1-algorithm-explanation.md | 16 ++ .../2-two-pointer-techniques/2-2-two-sum.md | 5 - .../2-two-pointer-techniques/2-2-two-sum.mdx | 72 +++++ .../2-3-merge-sorted-arrays.md | 5 - .../2-3-merge-sorted-arrays.mdx | 71 +++++ .../2-4-sliding-window.md | 5 - .../2-4-sliding-window.mdx | 108 +++++++ .../2-5-fast-slow-pointers.md | 5 - .../2-5-fast-slow-pointers.mdx | 100 +++++++ .../2-two-pointer-techniques/2-6-exercises.md | 20 ++ .../2-two-pointer-techniques/_category_.json | 2 +- .../3-1-algorithm-explanation.md | 10 + .../3-2-square-root.md | 5 - .../3-2-square-root.mdx | 104 +++++++ .../3-3-interval-search.md | 5 - .../3-3-interval-search.mdx | 107 +++++++ .../3-4-peak-finding.md | 5 - .../3-4-peak-finding.mdx | 85 ++++++ .../3-5-rotated-array-search.md | 5 - .../3-5-rotated-array-search.mdx | 99 +++++++ .../3-6-exercises.md | 16 ++ .../_category_.json | 2 +- .../4-sorting-algorithms/4-2-quick-select.md | 3 + .../4-sorting-algorithms/4-3-bucket-sort.md | 3 + .../5-2-depth-first-search.md | 3 + .../5-3-backtracking.md | 3 + .../5-4-breadth-first-search.md | 3 + .../6-dynamic-programming/6-2-basic-dp-1d.md | 3 + .../6-dynamic-programming/6-3-basic-dp-2d.md | 3 + leetcode_101/docusaurus.config.ts | 20 +- leetcode_101/package-lock.json | 270 +++++++++++++++++- leetcode_101/package.json | 4 +- .../src/components/MDXProviderWrapper.tsx | 17 ++ leetcode_101/src/theme/Root.tsx | 8 + 41 files changed, 1397 insertions(+), 61 deletions(-) delete mode 100644 leetcode_101/docs/1-greedy-algorithms/1-2-assignment-problems.md create mode 100644 leetcode_101/docs/1-greedy-algorithms/1-2-assignment-problems.mdx delete mode 100644 leetcode_101/docs/1-greedy-algorithms/1-3-interval-problems.md create mode 100644 leetcode_101/docs/1-greedy-algorithms/1-3-interval-problems.mdx delete mode 100644 leetcode_101/docs/2-two-pointer-techniques/2-2-two-sum.md create mode 100644 leetcode_101/docs/2-two-pointer-techniques/2-2-two-sum.mdx delete mode 100644 leetcode_101/docs/2-two-pointer-techniques/2-3-merge-sorted-arrays.md create mode 100644 leetcode_101/docs/2-two-pointer-techniques/2-3-merge-sorted-arrays.mdx delete mode 100644 leetcode_101/docs/2-two-pointer-techniques/2-4-sliding-window.md create mode 100644 leetcode_101/docs/2-two-pointer-techniques/2-4-sliding-window.mdx delete mode 100644 leetcode_101/docs/2-two-pointer-techniques/2-5-fast-slow-pointers.md create mode 100644 leetcode_101/docs/2-two-pointer-techniques/2-5-fast-slow-pointers.mdx delete mode 100644 leetcode_101/docs/3-binary-search-techniques/3-2-square-root.md create mode 100644 leetcode_101/docs/3-binary-search-techniques/3-2-square-root.mdx delete mode 100644 leetcode_101/docs/3-binary-search-techniques/3-3-interval-search.md create mode 100644 leetcode_101/docs/3-binary-search-techniques/3-3-interval-search.mdx delete mode 100644 leetcode_101/docs/3-binary-search-techniques/3-4-peak-finding.md create mode 100644 leetcode_101/docs/3-binary-search-techniques/3-4-peak-finding.mdx delete mode 100644 leetcode_101/docs/3-binary-search-techniques/3-5-rotated-array-search.md create mode 100644 leetcode_101/docs/3-binary-search-techniques/3-5-rotated-array-search.mdx create mode 100644 leetcode_101/src/components/MDXProviderWrapper.tsx create mode 100644 leetcode_101/src/theme/Root.tsx diff --git a/leetcode_101/docs/1-greedy-algorithms/1-2-assignment-problems.md b/leetcode_101/docs/1-greedy-algorithms/1-2-assignment-problems.md deleted file mode 100644 index c915c37d..00000000 --- a/leetcode_101/docs/1-greedy-algorithms/1-2-assignment-problems.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 2 ---- - -# 1.2 分配问题 diff --git a/leetcode_101/docs/1-greedy-algorithms/1-2-assignment-problems.mdx b/leetcode_101/docs/1-greedy-algorithms/1-2-assignment-problems.mdx new file mode 100644 index 00000000..aef59bf4 --- /dev/null +++ b/leetcode_101/docs/1-greedy-algorithms/1-2-assignment-problems.mdx @@ -0,0 +1,143 @@ +--- +sidebar_position: 2 +--- + +# 1.2 分配问题 + +## [455. Assign Cookies](https://leetcode.com/problems/assign-cookies/) + +### 题目描述 + +有一群孩子和一堆饼干,每个孩子有一个饥饿度,每个饼干都有一个饱腹度。每个孩子只能吃一个饼干,且只有饼干的饱腹度不小于孩子的饥饿度时,这个孩子才能吃饱。求解最多有多少孩子可以吃饱。 + +### 输入输出样例 + +输入两个数组,分别代表孩子的饥饿度和饼干的饱腹度。输出可以吃饱的孩子的最大数量。 + +``` +Input: [1,2], [1,2,3] +Output: 2 +``` + +在这个样例中,我们可以给两个孩子喂 [1,2]、[1,3]、[2,3] 这三种组合的任意一种。 + +### 题解 + +因为饥饿度最小的孩子最容易吃饱,所以我们先考虑这个孩子。为了尽量使得剩下的饼干可以满足饥饿度更大的孩子,所以我们应该把大于等于这个孩子饥饿度的、且大小最小的饼干给这个孩子。满足了这个孩子之后,我们采取同样的策略,考虑剩下孩子里饥饿度最小的孩子,直到没有满足条件的饼干存在。 + +简而言之,这里的贪心策略是,给剩余孩子里最小饥饿度的孩子分配最小的能饱腹的饼干。至于具体实现,因为我们需要获得大小关系,一个便捷的方法就是把孩子和饼干分别排序。这样我们就可以从饥饿度最小的孩子和饱腹度最小的饼干出发,计算有多少个对子可以满足条件。 + +:::warning + +对数组或字符串排序是常见的操作,方便之后的大小比较。排序顺序默认是从小到大。 + +::: + +:::warning + +在之后的讲解中,若我们谈论的是对连续空间的变量进行操作,我们并不会明确区分数组和字符串,因为他们本质上都是在连续空间上的有序变量集合。一个字符串“abc”可以被看作一个数组 [‘a’,‘b’,‘c’]。 + +::: + + + + +```cpp +int findContentChildren(vector &children, vector &cookies) { + sort(children.begin(), children.end()); + sort(cookies.begin(), cookies.end()); + int child_i = 0, cookie_i = 0; + int n_children = children.size(), n_cookies = cookies.size(); + while (child_i < n_children && cookie_i < n_cookies) { + if (children[child_i] <= cookies[cookie_i]) { + ++child_i; + } + ++cookie_i; + } + return child_i; +} +``` + + + + +```py +def findContentChildren(children: List[int], cookies: List[int]) -> int: + children.sort() + cookies.sort() + child_i, cookie_i = 0, 0 + n_children, n_cookies = len(children), len(cookies) + while child_i < n_children and cookie_i < n_cookies: + if children[child_i] <= cookies[cookie_i]: + child_i += 1 + cookie_i += 1 + return child_i +``` + + + + + +## [135. Candy](https://leetcode.com/problems/candy/) + +### 题目描述 + +一群孩子站成一排,每一个孩子有自己的评分。现在需要给这些孩子发糖果,规则是如果一个孩子的评分比自己身旁的一个孩子要高,那么这个孩子就必须得到比身旁孩子更多的糖果。所有孩子至少要有一个糖果。求解最少需要多少个糖果。 + +### 输入输出样例 + +输入是一个数组,表示孩子的评分。输出是最少糖果的数量。 + +``` +Input: [1,0,2] +Output: 5 +``` +在这个样例中,最少的糖果分法是 [2,1,2]。 + + +### 题解 + +存在比较关系的贪心策略并不一定需要排序。虽然这一道题也是运用贪心策略,但我们只需要简单的两次遍历即可:把所有孩子的糖果数初始化为 1;先从左往右遍历一遍,如果右边孩子的评分比左边的高,则右边孩子的糖果数更新为左边孩子的糖果数加 1;再从右往左遍历一遍,如果左边孩子的评分比右边的高,且左边孩子当前的糖果数不大于右边孩子的糖果数,则左边孩子的糖果数更新为右边孩子的糖果数加 1。通过这两次遍历,分配的糖果就可以满足题目要求了。这里的贪心策略即为,在每次遍历中,只考虑并更新相邻一侧的大小关系。 + +在样例中,我们初始化糖果分配为 [1,1,1],第一次遍历更新后的结果为 [1,1,2],第二次遍历更新后的结果为 [2,1,2]。 + + + + +```cpp +int candy(vector& ratings) { + int n = ratings.size(); + vector candies(n, 1); + for (int i = 1; i < n; ++i) { + if (ratings[i] > ratings[i - 1]) { + candies[i] = candies[i - 1] + 1; + } + } + for (int i = n - 1; i > 0; --i) { + if (ratings[i] < ratings[i - 1]) { + candies[i - 1] = max(candies[i - 1], candies[i] + 1); + } + } + return accumulate(candies.begin(), candies.end(), 0); +} +``` + + + + +```py +def candy(ratings_list: List[int]) -> int: + n = len(ratings_list) + candies = [1] * n + for i in range(1, n): + if ratings_list[i] > ratings_list[i - 1]: + candies[i] = candies[i - 1] + 1 + for i in range(n - 1, 0, -1): + if ratings_list[i] < ratings_list[i - 1]: + candies[i - 1] = max(candies[i - 1], candies[i] + 1) + return sum(candies) +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/1-greedy-algorithms/1-3-interval-problems.md b/leetcode_101/docs/1-greedy-algorithms/1-3-interval-problems.md deleted file mode 100644 index 3ce16f57..00000000 --- a/leetcode_101/docs/1-greedy-algorithms/1-3-interval-problems.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 3 ---- - -# 1.3 区间问题 diff --git a/leetcode_101/docs/1-greedy-algorithms/1-3-interval-problems.mdx b/leetcode_101/docs/1-greedy-algorithms/1-3-interval-problems.mdx new file mode 100644 index 00000000..ad2ec4e4 --- /dev/null +++ b/leetcode_101/docs/1-greedy-algorithms/1-3-interval-problems.mdx @@ -0,0 +1,74 @@ +--- +sidebar_position: 3 +--- + +# 1.3 区间问题 + +## [435. Non-overlapping Intervals](https://leetcode.com/problems/non-overlapping-intervals/) + +### 题目描述 + +给定多个区间,计算让这些区间互不重叠所需要移除区间的最少个数。起止相连不算重叠。 + +### 输入输出样例 + +输入是一个数组,包含多个长度固定为 2 的子数组,表示每个区间的开始和结尾。输出一个整数,表示需要移除的区间数量。 + +``` +Input: [[1,2], [2,4], [1,3]] +Output: 1 +``` +在这个样例中,我们可以移除区间 [1,3],使得剩余的区间 [[1,2], [2,4]] 互不重叠。 + + +### 题解 + +求最少的移除区间个数,等价于尽量多保留不重叠的区间。在选择要保留区间时,区间的结尾十分重要:选择的区间结尾越小,余留给其它区间的空间就越大,就越能保留更多的区间。因此,我们采取的贪心策略为,优先保留结尾小且不相交的区间。 + +具体实现方法为,先把区间按照结尾的大小进行增序排序(利用 lambda 函数),每次选择结尾最小且和前一个选择的区间不重叠的区间。 + +在样例中,排序后的数组为 [[1,2], [1,3], [2,4]]。按照我们的贪心策略,首先初始化为区间[1,2];由于 [1,3] 与 [1,2] 相交,我们跳过该区间;由于 [2,4] 与 [1,2] 不相交,我们将其保留。因此最终保留的区间为 [[1,2], [2,4]]。 + +:::warning + +需要根据实际情况判断按区间开头排序还是按区间结尾排序。 + +::: + + + + +```cpp +int eraseOverlapIntervals(vector>& intervals) { + sort(intervals.begin(), intervals.end(), + [](vector& a, vector& b) { return a[1] < b[1]; }); + int removed = 0, prev_end = intervals[0][1]; + for (int i = 1; i < intervals.size(); ++i) { + if (intervals[i][0] < prev_end) { + ++removed; + } else { + prev_end = intervals[i][1]; + } + } + return removed; +} +``` + + + + +```py +def eraseOverlapIntervals(intervals: List[List[int]]) -> int: + intervals.sort(key=lambda x: x[1]) + removed, prev_end = 0, intervals[0][1] + for i in range(1, len(intervals)): + if prev_end > intervals[i][0]: + removed += 1 + else: + prev_end = intervals[i][1] + return removed +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/1-greedy-algorithms/1-4-exercises.md b/leetcode_101/docs/1-greedy-algorithms/1-4-exercises.md index db7a7831..5432be4e 100644 --- a/leetcode_101/docs/1-greedy-algorithms/1-4-exercises.md +++ b/leetcode_101/docs/1-greedy-algorithms/1-4-exercises.md @@ -3,3 +3,38 @@ sidebar_position: 4 --- # 1.4 练习 + +## 基础难度 + +### [605. Can Place Flowers](https://leetcode.com/problems/can-place-flowers/) + +采取什么样的贪心策略,可以种植最多的花朵呢? + +### [452. Minimum Number of Arrows to Burst Balloons](https://leetcode.com/problems/minimum-number-of-arrows-to-burst-balloons/) + +这道题和题目 435 十分类似,但是稍有不同,具体是哪里不同呢? + +### [763. Partition Labels](https://leetcode.com/problems/partition-labels/) + +为了满足你的贪心策略,是否需要一些预处理? + +:::warning + +在处理数组前,统计一遍信息(如频率、个数、第一次出现位置、最后一次出现位置等)可以使题目难度大幅降低。 + +::: + +### [122. Best Time to Buy and Sell Stock II](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/) + +股票交易题型里比较简单的题目,在不限制交易次数的情况下,怎样可以获得最大利润呢? + +## 进阶难度 + +### [406. Queue Reconstruction by Height](https://leetcode.com/problems/queue-reconstruction-by-height/) + +温馨提示,这道题可能同时需要排序和插入操作。 + + +### [665. Non-decreasing Array](https://leetcode.com/problems/non-decreasing-array/) + +需要仔细思考你的贪心策略在各种情况下,是否仍然是最优解。 \ No newline at end of file diff --git a/leetcode_101/docs/1-greedy-algorithms/_category_.json b/leetcode_101/docs/1-greedy-algorithms/_category_.json index 39fa7a85..4119cb25 100644 --- a/leetcode_101/docs/1-greedy-algorithms/_category_.json +++ b/leetcode_101/docs/1-greedy-algorithms/_category_.json @@ -3,6 +3,6 @@ "position": 1, "link": { "type": "generated-index", - "description": "最易懂的贪心算法" + "description": "第 1 章 最易懂的贪心算法" } } diff --git a/leetcode_101/docs/12-linked-lists/_category_.json b/leetcode_101/docs/12-linked-lists/_category_.json index 982d29f5..0e2d1b87 100644 --- a/leetcode_101/docs/12-linked-lists/_category_.json +++ b/leetcode_101/docs/12-linked-lists/_category_.json @@ -1,6 +1,6 @@ { "label": "12. 指针三剑客之一:链表", - "position": 2, + "position": 12, "link": { "type": "generated-index", "description": "5 minutes to learn the most important Docusaurus concepts." diff --git a/leetcode_101/docs/2-two-pointer-techniques/2-1-algorithm-explanation.md b/leetcode_101/docs/2-two-pointer-techniques/2-1-algorithm-explanation.md index 8b093962..5c853023 100644 --- a/leetcode_101/docs/2-two-pointer-techniques/2-1-algorithm-explanation.md +++ b/leetcode_101/docs/2-two-pointer-techniques/2-1-algorithm-explanation.md @@ -3,3 +3,19 @@ sidebar_position: 5 --- # 2.1 算法解释 + +双指针主要用于遍历数组,两个指针指向不同的元素,从而协同完成任务。也可以延伸到多个数组的多个指针。 + +若两个指针指向同一数组,遍历方向相同且不会相交,则也称为滑动窗口(两个指针包围的区域即为当前的窗口),经常用于区间搜索。 + +若两个指针指向同一数组,但是遍历方向相反,则可以用来进行搜索,待搜索的数组往往是排好序的。 + +在 C++ 中,要注意 const 的位置对指针效果的影响: + +```cpp +int x; +int * p1 = &x; // 指针可以被修改,值也可以被修改 +const int * p2 = &x; // 指针可以被修改,值不可以被修改(const int) +int * const p3 = &x; // 指针不可以被修改(* const),值可以被修改 +const int * const p4 = &x; // 指针不可以被修改,值也不可以被修改 +``` diff --git a/leetcode_101/docs/2-two-pointer-techniques/2-2-two-sum.md b/leetcode_101/docs/2-two-pointer-techniques/2-2-two-sum.md deleted file mode 100644 index 60a6542c..00000000 --- a/leetcode_101/docs/2-two-pointer-techniques/2-2-two-sum.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 6 ---- - -# 2.2 Two Sum diff --git a/leetcode_101/docs/2-two-pointer-techniques/2-2-two-sum.mdx b/leetcode_101/docs/2-two-pointer-techniques/2-2-two-sum.mdx new file mode 100644 index 00000000..f9a8eecc --- /dev/null +++ b/leetcode_101/docs/2-two-pointer-techniques/2-2-two-sum.mdx @@ -0,0 +1,72 @@ +--- +sidebar_position: 6 +--- + +# 2.2 Two Sum + +## [167. Two Sum II - Input array is sorted](https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/) + +### 题目描述 + +在一个增序的整数数组里找到两个数,使它们的和为给定值。已知有且只有一对解。 + +### 输入输出样例 + +输入是一个数组(numbers)和一个给定值(target)。输出是两个数的位置,从 1 开始计数。 + +``` +Input: numbers = [2,7,11,15], target = 9 +Output: [1,2] +``` + +在这个样例中,第一个数字(2)和第二个数字(7)的和等于给定值(9)。 + +### 题解 + +因为数组已经排好序,我们可以采用方向相反的双指针来寻找这两个数字,一个初始指向最小的元素,即数组最左边,向右遍历;一个初始指向最大的元素,即数组最右边,向左遍历。 + +如果两个指针指向元素的和等于给定值,那么它们就是我们要的结果。如果两个指针指向元素的和小于给定值,我们把左边的指针右移一位,使得当前的和增加一点。如果两个指针指向元素的和大于给定值,我们把右边的指针左移一位,使得当前的和减少一点。 + +可以证明,对于排好序且有解的数组,双指针一定能遍历到最优解。证明方法如下:假设最优解的两个数的位置分别是 l 和 r。我们假设在左指针在 l 左边的时候,右指针已经移动到了 r;此时两个指针指向值的和小于给定值,因此左指针会一直右移直到到达 l。同理,如果我们假设在右指针在 r 右边的时候,左指针已经移动到了 l;此时两个指针指向值的和大于给定值,因此右指针会一直左移直到到达 r。所以双指针在任何时候都不可能处于 (l,r) 之间,又因为不满足条件时指针必须移动一个,所以最终一定会收敛在 l 和 r。 + + + + +```cpp +vector twoSum(vector& numbers, int target) { + int l = 0, r = numbers.size() - 1, two_sum; + while (l < r) { + two_sum = numbers[l] + numbers[r]; + if (two_sum == target) { + break; + } + if (two_sum < target) { + ++l; + } else { + --r; + } + } + return vector{l + 1, r + 1}; +} +``` + + + + +```py +def twoSum(numbers: List[int], target: int) -> List[int]: + l, r = 0, len(numbers) - 1 + while l < r: + two_sum = numbers[l] + numbers[r] + if two_sum == target: + break + if two_sum < target: + l += 1 + else: + r -= 1 + return [l + 1, r + 1] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/2-two-pointer-techniques/2-3-merge-sorted-arrays.md b/leetcode_101/docs/2-two-pointer-techniques/2-3-merge-sorted-arrays.md deleted file mode 100644 index 2d890bdf..00000000 --- a/leetcode_101/docs/2-two-pointer-techniques/2-3-merge-sorted-arrays.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 7 ---- - -# 2.3 归并两个有序数组 diff --git a/leetcode_101/docs/2-two-pointer-techniques/2-3-merge-sorted-arrays.mdx b/leetcode_101/docs/2-two-pointer-techniques/2-3-merge-sorted-arrays.mdx new file mode 100644 index 00000000..aee9087d --- /dev/null +++ b/leetcode_101/docs/2-two-pointer-techniques/2-3-merge-sorted-arrays.mdx @@ -0,0 +1,71 @@ +--- +sidebar_position: 7 +--- + +# 2.3 归并两个有序数组 + +## [88. Merge Sorted Array](https://leetcode.com/problems/merge-sorted-array/) + +### 题目描述 + +给定两个有序数组,把两个数组合并为一个。 + +### 输入输出样例 + +输入是两个数组和它们分别的长度 m 和 n。其中第一个数组的长度被延长至 m +n,多出的 +n 位被 0 填补。题目要求把第二个数组归并到第一个数组上,不需要开辟额外空间。 + +``` +Input: nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3 +Output: nums1 = [1,2,2,3,5,6] +``` + + + +### 题解 + +因为这两个数组已经排好序,我们可以把两个指针分别放在两个数组的末尾,即 nums1 的 m − 1 位和 nums2 的 n − 1 位。每次将较大的那个数字复制到 nums1 的后边,然后向前移动一位。 +因为我们也要定位 nums1 的末尾,所以我们还需要第三个指针,以便复制。 + +在以下的代码里,我们直接利用 m 和 n 当作两个数组的指针,再额外创立一个 pos 指针,起始位置为 m +n − 1。每次向左移动 m 或 n 的时候,也要向左移动 pos。这里需要注意,如果 nums1 +的数字已经复制完,不要忘记把 nums2 的数字继续复制;如果 nums2 的数字已经复制完,剩余 nums1 的数字不需要改变,因为它们已经被排好序。 + +在 C++ 题解里我们使用了 ++和--的小技巧:a++和 ++a都是将 a加 1,但是 a++返回值为 a,而 ++a返回值为 a+1。如果只是希望增加 a的值,而不需要返回值,则两个写法都可以(++a在未经编译器优化的情况下运行速度会略快一些)。 + + + + +```cpp +void merge(vector& nums1, int m, vector& nums2, int n) { + int pos = m-- + n-- - 1; + while (m >= 0 && n >= 0) { + nums1[pos--] = nums1[m] > nums2[n] ? nums1[m--] : nums2[n--]; + } + while (n >= 0) { + nums1[pos--] = nums2[n--]; + } +} +``` + + + + +```py +def merge(nums1: List[int], m: int, nums2: List[int], n: int) -> None: + pos = m + n - 1 + m -= 1 + n -= 1 + while m >= 0 and n >= 0: + if nums1[m] > nums2[n]: + nums1[pos] = nums1[m] + m -= 1 + else: + nums1[pos] = nums2[n] + n -= 1 + pos -= 1 + nums1[: n + 1] = nums2[: n + 1] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/2-two-pointer-techniques/2-4-sliding-window.md b/leetcode_101/docs/2-two-pointer-techniques/2-4-sliding-window.md deleted file mode 100644 index 9fd45f2b..00000000 --- a/leetcode_101/docs/2-two-pointer-techniques/2-4-sliding-window.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 8 ---- - -# 2.4 滑动窗口 diff --git a/leetcode_101/docs/2-two-pointer-techniques/2-4-sliding-window.mdx b/leetcode_101/docs/2-two-pointer-techniques/2-4-sliding-window.mdx new file mode 100644 index 00000000..a7923d02 --- /dev/null +++ b/leetcode_101/docs/2-two-pointer-techniques/2-4-sliding-window.mdx @@ -0,0 +1,108 @@ +--- +sidebar_position: 8 +--- + +# 2.4 滑动窗口 + +## [76. Minimum Window Substring](https://leetcode.com/problems/minimum-window-substring/) + +### 题目描述 + +给定两个字符串 s 和 t,求 s 中包含 t 所有字符的最短连续子字符串的长度,同时要求时间复杂度不得超过 O(n)。 + +### 输入输出样例 + +输入是两个字符串 s 和 t,输出是一个 S 字符串的子串。如果不存在解,则输出一个空字符串。 + +``` +Input: s = "ADOBECODEBANC", t = "ABC" +Output: "BANC" +``` + +在这个样例中,s 中同时包含一个 A、一个 B、一个 C 的最短子字符串是“BANC”。 + +### 题解 + +本题使用滑动窗口求解,即两个指针 l 和 r 都是从最左端向最右端移动,且 l 的位置一定在 r 的左边或重合。C++ 题解中使用了两个长度为 128 的数组,valid 和 freq,来映射字符(ASCII +只包含 128 个字符)。其中 valid 表示每个字符在 t 中是否存在,而 freq 表示目前 t 中每个字符在 s 的滑动窗口中缺少的数量:如果为正,则说明还缺少;如果为负,则说明有盈余。Python 题解 +则直接使用 Counter 数据结构同时统计 t 中存在的字符和其缺少的数量(也可以用 dict 替代)。注意本题虽然在 for 循环里出现了一个 while 循环,但是因为 while 循环负责移动 l 指针,且 l 只会 +从左到右移动一次,因此总时间复杂度仍然是 O(n)。 + + + + +```cpp +string minWindow(string s, string t) { + vector valid(128, false); + vector freq(128, 0); + // 统计t中的字符情况。 + for (int i = 0; i < t.length(); ++i) { + valid[t[i]] = true; + ++freq[t[i]]; + } + // 移动滑动窗口,不断更改统计数据。 + int count = 0; + int min_l = -1, min_length = -1; + for (int l = 0, r = 0; r < s.length(); ++r) { + if (!valid[s[r]]) { + continue; + } + // 把r位置的字符加入频率统计,并检查是否补充了t中缺失的字符。 + if (--freq[s[r]] >= 0) { + ++count; + } + // 滑动窗口已包含t中全部字符,尝试右移l,在不影响结果的情况下寻找最短串。 + while (count == t.length()) { + if (min_length == -1 || r - l + 1 < min_length) { + min_l = l; + min_length = r - l + 1; + } + // 把l位置的字符移除频率统计,并检查t中对应字符是否重新缺失。 + if (valid[s[l]] && ++freq[s[l]] > 0) { + --count; + } + ++l; + } + } + return min_length == -1 ? "" : s.substr(min_l, min_length); +} +``` + + + + +```py +def minWindow(s: str, t: str) -> str: + # 统计t中的字符情况,等价于: + # freq = dict() + # for c in t: + # freq[c] = freq.get(c, 0) + 1 + freq = Counter(t) + # 移动滑动窗口,不断更改统计数据。 + count = 0 + min_l, min_length = None, None + l = 0 + for r in range(len(s)): + if s[r] not in freq: + continue + # 把r位置的字符加入频率统计,并检查是否补充了t中缺失的字符。 + freq[s[r]] -= 1 + if freq[s[r]] >= 0: + count += 1 + # 滑动窗口已包含t中全部字符,尝试右移l,在不影响结果的情况下寻找最短串。 + while count == len(t): + if min_length == None or r - l + 1 < min_length: + min_l = l + min_length = r - l + 1 + # 把l位置的字符移除频率统计,并检查t中对应字符是否重新缺失。 + if s[l] in freq: + freq[s[l]] += 1 + if freq[s[l]] > 0: + count -= 1 + l += 1 + return "" if min_length is None else s[min_l: min_l + min_length] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/2-two-pointer-techniques/2-5-fast-slow-pointers.md b/leetcode_101/docs/2-two-pointer-techniques/2-5-fast-slow-pointers.md deleted file mode 100644 index 6b5e3404..00000000 --- a/leetcode_101/docs/2-two-pointer-techniques/2-5-fast-slow-pointers.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 9 ---- - -# 2.5 快慢指针 diff --git a/leetcode_101/docs/2-two-pointer-techniques/2-5-fast-slow-pointers.mdx b/leetcode_101/docs/2-two-pointer-techniques/2-5-fast-slow-pointers.mdx new file mode 100644 index 00000000..26de16b5 --- /dev/null +++ b/leetcode_101/docs/2-two-pointer-techniques/2-5-fast-slow-pointers.mdx @@ -0,0 +1,100 @@ +--- +sidebar_position: 9 +--- + +# 2.5 快慢指针 + +## [142. Linked List Cycle II](https://leetcode.com/problems/linked-list-cycle-ii/) + +### 题目描述 + +给定一个链表,如果有环路,找出环路的开始点。 + +### 输入输出样例 + +输入是一个链表,输出是链表的一个节点。如果没有环路,返回一个空指针。 +在这个样例中,值为 2 的节点即为环路的开始点。 +如果没有特殊说明,LeetCode 采用如下的数据结构表示链表。 + +![alt](https://assets.leetcode.com/uploads/2018/12/07/circularlinkedlist.png) + +```cpp +struct ListNode { + int val; + ListNode *next; + ListNode(int x) : val(x), next(nullptr) {} +}; +``` + +```py +class ListNode: + def __init__(self, x): + self.val = x + self.next = None # or a ListNode +``` + +### 题解 + +对于链表找环路的问题,有一个通用的解法——快慢指针(Floyd 判圈法)。给定两个指针,分别命名为 slow 和 fast,起始位置在链表的开头。每次 fast 前进两步,slow 前进一步。如果 fast +可以走到尽头,那么说明没有环路;如果 fast 可以无限走下去,那么说明一定有环路,且一定存在一个时刻 slow 和 fast 相遇。当 slow 和 fast 第一次相遇时,我们将 fast 重新移动到链表开头,并 +让 slow 和 fast 每次都前进一步。当 slow 和 fast 第二次相遇时,相遇的节点即为环路的开始点。 + +:::warning + +对于某些只需要判断是否存在环路的题目,也可以通过建造哈希表来查重。 + +::: + + + + + +```cpp +ListNode *detectCycle(ListNode *head) { + ListNode *slow = head, *fast = head; + bool is_first_cycle = true; + // 检查环路。 + while (fast != slow || is_first_cycle) { + if (fast == nullptr || fast->next == nullptr) { + return nullptr; + } + fast = fast->next->next; + slow = slow->next; + is_first_cycle = false; + } + // 寻找节点。 + fast = head; + while (fast != slow) { + slow = slow->next; + fast = fast->next; + } + return fast; +} +``` + + + + +```py +def detectCycle(head: Optional[ListNode]) -> Optional[ListNode]: + slow = head + fast = head + is_first_cycle = True + # 检查环路。 + while fast != slow or is_first_cycle: + if fast is None or fast.next is None: + return None + fast = fast.next.next + slow = slow.next + is_first_cycle = False + # 寻找节点。 + fast = head + while fast != slow: + fast = fast.next + slow = slow.next + return fast +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/2-two-pointer-techniques/2-6-exercises.md b/leetcode_101/docs/2-two-pointer-techniques/2-6-exercises.md index 2ed1860c..00003ee8 100644 --- a/leetcode_101/docs/2-two-pointer-techniques/2-6-exercises.md +++ b/leetcode_101/docs/2-two-pointer-techniques/2-6-exercises.md @@ -3,3 +3,23 @@ sidebar_position: 10 --- # 2.6 练习 + +## 基础难度 + +### [633. Sum of Square Numbers](https://leetcode.com/problems/sum-of-square-numbers/) + +Two Sum 题目的变形题之一。 + +### [680. Valid Palindrome II](https://leetcode.com/problems/valid-palindrome-ii/) + +Two Sum 题目的变形题之二。 + +### [524. Longest Word in Dictionary through Deleting](https://leetcode.com/problems/longest-word-in-dictionary-through-deleting/) + +归并两个有序数组的变形题。 + +## 进阶难度 + +### [340. Longest Substring with At Most K Distinct Characters](https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/) + +需要利用其它数据结构方便统计当前的字符状态。 \ No newline at end of file diff --git a/leetcode_101/docs/2-two-pointer-techniques/_category_.json b/leetcode_101/docs/2-two-pointer-techniques/_category_.json index 856cde5b..23d4e78a 100644 --- a/leetcode_101/docs/2-two-pointer-techniques/_category_.json +++ b/leetcode_101/docs/2-two-pointer-techniques/_category_.json @@ -3,6 +3,6 @@ "position": 2, "link": { "type": "generated-index", - "description": "5 minutes to learn the most important Docusaurus concepts." + "description": "第 2 章 玩转双指针" } } diff --git a/leetcode_101/docs/3-binary-search-techniques/3-1-algorithm-explanation.md b/leetcode_101/docs/3-binary-search-techniques/3-1-algorithm-explanation.md index 9f3919b8..7a908171 100644 --- a/leetcode_101/docs/3-binary-search-techniques/3-1-algorithm-explanation.md +++ b/leetcode_101/docs/3-binary-search-techniques/3-1-algorithm-explanation.md @@ -3,3 +3,13 @@ sidebar_position: 11 --- # 3.1 算法解释 + +`二分查找`也常被称为`二分法`或者`折半查找` (binary search, bisect),每次查找时通过将待查找的单调区间分成两部分并只取一部分继续查找,将查找的复杂度大大减少。对于一个长度为 $O(n)$ 的数组,二分查找的时间复杂度为 $O(\log n)$。 + +举例来说,给定一个排好序的数组 $\{3,4,5,6,7\}$,我们希望查找 4 在不在这个数组内。第一次折半时考虑中位数 5,因为 5 大于 4, 所以如果 4 存在于这个数组,那么其必定存在于 5 左边这一半。于是我们的查找区间变成了 $\{3,4,5\}$。(注意,根据具体情况和您的刷题习惯,这里的 5 可以保留也可以不保留,并不影响时间复杂度的级别。)第二次折半时考虑新的中位数 4,正好是我们需要查找的数字。于是我们发现,对于一个长度为 5 的数组,我们只进行了 2 次查找。如果是遍历数组,最坏的情况则需要查找 5 次。 + +我们也可以用更加数学的方式定义二分查找。给定一个在 $[a, b]$ 区间内的单调函数 $f(t)$,若 $f(a)$ 和 $f(b)$ 正负性相反,那么必定存在一个解 $c$,使得 $f(c) = 0$。在上个例子中,$f(t)$ 是离散函数 $f(t) = t + 2$,查找 4 是否存在等价于求 $f(t) - 4 = 0$ 是否有离散解。因为 $f(1) - 4 = 3 - 4 = -1 < 0$、$f(5) - 4 = 7 - 4 = 3 > 0$,且函数在区间内单调递增,因此我们可以利用二分查找求解。如果最后二分到了不能再分的情况,如只剩一个数字,且剩余区间里不存在满足条件的解,则说明不存在离散解,即 4 不在这个数组内。 + +具体到代码上,二分查找时区间的左右端取开区间还是闭区间在绝大多数时候都可以,因此有些初学者会容易搞不清楚如何定义区间开闭性。这里笔者提供两个小诀窍,第一是尝试熟练使用一种写法,比如左闭右开(满足 C++、Python 等语言的习惯)或左闭右闭(便于处理边界条件),尽量只保持这一种写法;第二是在刷题时思考如果最后区间只剩下一个数或者两个数,自己的写法是否会陷入死循环,如果某种写法无法跳出死循环,则考虑尝试另一种写法。 + +二分查找也可以看作双指针的一种特殊情况,但我们一般会将二者区分。双指针类型的题,指针通常是一步一步移动的,而在二分查找里,指针通常每次移动半个区间长度。 diff --git a/leetcode_101/docs/3-binary-search-techniques/3-2-square-root.md b/leetcode_101/docs/3-binary-search-techniques/3-2-square-root.md deleted file mode 100644 index 8f394714..00000000 --- a/leetcode_101/docs/3-binary-search-techniques/3-2-square-root.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 12 ---- - -# 3.2 求开方 diff --git a/leetcode_101/docs/3-binary-search-techniques/3-2-square-root.mdx b/leetcode_101/docs/3-binary-search-techniques/3-2-square-root.mdx new file mode 100644 index 00000000..8d0f4aab --- /dev/null +++ b/leetcode_101/docs/3-binary-search-techniques/3-2-square-root.mdx @@ -0,0 +1,104 @@ +--- +sidebar_position: 12 +--- + +# 3.2 求开方 + +## [69. Sqrt(x)](https://leetcode.com/problems/sqrtx/) + +### 题目描述 + +给定一个非负整数 x,求它的开方,向下取整。 + +### 输入输出样例 + +输入一个整数,输出一个整数。 + +``` +Input: 8 +Output: 2 +``` + +8 的开方结果是 2.82842...,向下取整即是 2。 + + +### 题解 + +我们可以把这道题想象成,给定一个非负整数 x,求 $f (t) =t^2 − x =0$ 的解。因为我们只考虑 $t ≥ 0$,所以 $f (t)$ 在定义域上是单调递增的。考虑到 $f (0) =−x ≤ 0$, $f (x) = x^2 − x ≥ 0$,我们可以对 $[0, x]$ 区间使用二分法找到 $f (t) =0$ 的解。这里笔者使用了左闭右闭的写法。 + +在 C++ 题解中,$mid = (l +r)/2$ 可能会因为 $l +r$ 溢出而错误,因而采用 $mid = l +(r − l)/2$的写法;直接计算 $mid ∗ mid$ 也有可能溢出,因此我们比较 $mid$ 和 $x/mid$。 + + + + +```cpp +int mySqrt(int x) { + int l = 1, r = x, mid, x_div_mid; + while (l <= r) { + mid = l + (r - l) / 2; + x_div_mid = x / mid; + if (mid == x_div_mid) { + return mid; + } + if (mid < x_div_mid) { + l = mid + 1; + } else { + r = mid - 1; + } + } + return r; +} +``` + + + + +```py +def mySqrt(x: int) -> int: + l, r = 1, x + while l <= r: + mid = (l + r) // 2 + mid_sqr = mid**2 + if mid_sqr == x: + return mid + if mid_sqr < x: + l = mid + 1 + else: + r = mid - 1 + return r +``` + + + + + +另外,这道题还有一种更快的算法——`牛顿迭代法`,其公式为 $t_{n+1} = t_n - \frac{f(t_n)}{f'(t_n)} +$。给定$f (t) =t2 − x =0$,这里的迭代公式为 $t_{n+1} = \frac{t_n + \frac{x}{t_n}}{2}$。 + + + + +```cpp +int mySqrt(int x) { + long t = x; + while (t * t > x) { + t = (t + x / t) / 2; + } + return t; +} +``` + + + + +```py +def mySqrt(x: int) -> int: + t = x + while t**2 > x: + t = (t + x // t) // 2 + return t +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/3-binary-search-techniques/3-3-interval-search.md b/leetcode_101/docs/3-binary-search-techniques/3-3-interval-search.md deleted file mode 100644 index 05b11d5f..00000000 --- a/leetcode_101/docs/3-binary-search-techniques/3-3-interval-search.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 13 ---- - -# 3.3 查找区间 diff --git a/leetcode_101/docs/3-binary-search-techniques/3-3-interval-search.mdx b/leetcode_101/docs/3-binary-search-techniques/3-3-interval-search.mdx new file mode 100644 index 00000000..e1a28794 --- /dev/null +++ b/leetcode_101/docs/3-binary-search-techniques/3-3-interval-search.mdx @@ -0,0 +1,107 @@ +--- +sidebar_position: 13 +--- + +# 3.3 查找区间 + +## [34. Find First and Last Position of Element in Sorted Array](https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/) + +### 题目描述 + +给定一个增序的整数数组和一个值,查找该值第一次和最后一次出现的位置。 + +### 输入输出样例 + +输入是一个数组和一个值,输出为该值第一次出现的位置和最后一次出现的位置(从 0 开始);如果不存在该值,则两个返回值都设为-1。 + +``` +Input: nums = [5,7,7,8,8,10], target = 8 +Output: [3,4] +``` + +数字 8 在第 3 位第一次出现,在第 4 位最后一次出现。 + +### 题解 + +这道题可以看作是自己实现 C++ 里的 lower_bound和 upper_bound函数,或者 Python 里的 bisect_left 和 bisect_right 函数。这里我们尝试使用左闭右开的写法,当然左闭右闭也可以。 + + + + +```cpp +int lowerBound(vector &nums, int target) { + int l = 0, r = nums.size(), mid; + while (l < r) { + mid = l + (r - l) / 2; + if (nums[mid] < target) { + l = mid + 1; + } else { + r = mid; + } + } + return l; +} + +int upperBound(vector &nums, int target) { + int l = 0, r = nums.size(), mid; + while (l < r) { + mid = l + (r - l) / 2; + if (nums[mid] <= target) { + l = mid + 1; + } else { + r = mid; + } + } + return l; +} + +vector searchRange(vector &nums, int target) { + if (nums.empty()) { + return vector{-1, -1}; + } + int lower = lowerBound(nums, target); + int upper = upperBound(nums, target) - 1; + if (lower == nums.size() || nums[lower] != target) { + return vector{-1, -1}; + } + return vector{lower, upper}; +} +``` + + + + +```py +def lowerBound(nums: List[int], target: int) -> int: + l, r = 0, len(nums) + while l < r: + mid = (l + r) // 2 + if nums[mid] < target: + l = mid + 1 + else: + r = mid + return l + +def upperBound(nums: List[int], target: int) -> int: + l, r = 0, len(nums) + while l < r: + mid = (l + r) // 2 + if nums[mid] <= target: + l = mid + 1 + else: + r = mid + return l + +def searchRange(nums: List[int], target: int) -> List[int]: + if not nums: + return [-1, -1] + lower = lowerBound(nums, target) + upper = upperBound(nums, target) - 1 + if lower == len(nums) or nums[lower] != target: + return [-1, -1] + return [lower, upper] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/3-binary-search-techniques/3-4-peak-finding.md b/leetcode_101/docs/3-binary-search-techniques/3-4-peak-finding.md deleted file mode 100644 index 139a99d3..00000000 --- a/leetcode_101/docs/3-binary-search-techniques/3-4-peak-finding.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 14 ---- - -# 3.4 查找峰值 diff --git a/leetcode_101/docs/3-binary-search-techniques/3-4-peak-finding.mdx b/leetcode_101/docs/3-binary-search-techniques/3-4-peak-finding.mdx new file mode 100644 index 00000000..0baa1256 --- /dev/null +++ b/leetcode_101/docs/3-binary-search-techniques/3-4-peak-finding.mdx @@ -0,0 +1,85 @@ +--- +sidebar_position: 14 +--- + +# 3.4 查找峰值 + +## [162. Find Peak Element](https://leetcode.com/problems/find-peak-element/) + +### 题目描述 + +给定一个数组,定义峰值为比所有两边都大的数字,求峰值的位置。一个数组里可能存在多个峰值,返回任意一个即可。时间复杂度要求为 $O(\log n)$。 + +### 输入输出样例 + +输入是一个数组,输出为峰值的位置。 + +``` +Input: nums = [1,2,3,1] +Output: 2 +``` + +峰值 3 出现在位置 2。 + + +### 题解 + +要实现 $O(\log n)$ 时间复杂度,我们可以对数组进行二分查找。在确保两端不是峰值后,若当前中点不是峰值,那么其左右一侧一定有一个峰值。 + + + + +```cpp +int findPeakElement(vector& nums) { + int n = nums.size(); + if (n == 1) { + return 0; + } + if (nums[0] > nums[1]) { + return 0; + } + if (nums[n - 1] > nums[n - 2]) { + return n - 1; + } + int l = 1, r = n - 2, mid; + while (l <= r) { + mid = l + (r - l) / 2; + if (nums[mid] > nums[mid + 1] && nums[mid] > nums[mid - 1]) { + return mid; + } else if (nums[mid] > nums[mid - 1]) { + l = mid + 1; + } else { + r = mid - 1; + } + } + return -1; +} +``` + + + + +```py +def findPeakElement(self, nums: List[int]) -> int: + n = len(nums) + if n == 1: + return 0 + if nums[0] > nums[1]: + return 0 + if nums[n - 1] > nums[n - 2]: + return n - 1 + l, r = 1, n - 2 + while l <= r: + mid = (l + r) // 2 + if nums[mid] > nums[mid + 1] and nums[mid] > nums[mid - 1]: + return mid + elif nums[mid] > nums[mid - 1]: + l = mid + 1 + else: + r = mid - 1 + return -1 +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/3-binary-search-techniques/3-5-rotated-array-search.md b/leetcode_101/docs/3-binary-search-techniques/3-5-rotated-array-search.md deleted file mode 100644 index 18413b49..00000000 --- a/leetcode_101/docs/3-binary-search-techniques/3-5-rotated-array-search.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 15 ---- - -# 3.5 旋转数组查找数字 diff --git a/leetcode_101/docs/3-binary-search-techniques/3-5-rotated-array-search.mdx b/leetcode_101/docs/3-binary-search-techniques/3-5-rotated-array-search.mdx new file mode 100644 index 00000000..c7b7b413 --- /dev/null +++ b/leetcode_101/docs/3-binary-search-techniques/3-5-rotated-array-search.mdx @@ -0,0 +1,99 @@ +--- +sidebar_position: 15 +--- + +# 3.5 旋转数组查找数字 + +## [81. Search in Rotated Sorted Array II](https://leetcode.com/problems/search-in-rotated-sorted-array-ii/) + +### 题目描述 + +一个原本增序的数组被首尾相连后按某个位置断开(如 [1,2,2,3,4,5] → [2,3,4,5,1,2],在第一位和第二位断开),我们称其为旋转数组。给定一个值,判断这个值是否存在于这个旋转数组中。 + +### 输入输出样例 + +输入是一个数组和一个值,输出是一个布尔值,表示数组中是否存在该值。 + +``` +Input: nums = [2,5,6,0,0,1,2], target = 0 +Output: true +``` + +即使数组被旋转过,我们仍然可以利用这个数组的递增性,使用二分查找。对于当前的中点,如果它指向的值小于等于右端,那么说明右区间是排好序的;反之,那么说明左区间是排好序的。如果目标值位于排好序的区间内,我们可以对这个区间继续二分查找;反之,我们对于另一半区 +间继续二分查找。本题我们采用左闭右闭的写法。 + +### 题解 + + + + + + +```cpp +bool search(vector& nums, int target) { + int l = 0, r = nums.size() - 1; + while (l <= r) { + int mid = l + (r - l) / 2; + if (nums[mid] == target) { + return true; + } + if (nums[mid] == nums[l]) { + // 无法判断哪个区间是增序的,但l位置一定不是target。 + ++l; + } else if (nums[mid] == nums[r]) { + // 无法判断哪个区间是增序的,但r位置一定不是target。 + --r; + } else if (nums[mid] < nums[r]) { + // 右区间是增序的。 + if (target > nums[mid] && target <= nums[r]) { + l = mid + 1; + } else { + r = mid - 1; + } + } else { + // 左区间是增序的。 + if (target >= nums[l] && target < nums[mid]) { + r = mid - 1; + } else { + l = mid + 1; + } + } + } + return false; +} +``` + + + + +```py +def search(nums: List[int], target: int) -> bool: + l, r = 0, len(nums) - 1 + while l <= r: + mid = (l + r) // 2 + if nums[mid] == target: + return True + if nums[mid] == nums[l]: + # 无法判断哪个区间是增序的,但l位置一定不是target。 + l += 1 + elif nums[mid] == nums[r]: + # 无法判断哪个区间是增序的,但r位置一定不是target。 + r -= 1 + elif nums[mid] < nums[r]: + # 右区间是增序的。 + if nums[mid] < target <= nums[r]: + l = mid + 1 + else: + r = mid - 1 + else: + # 左区间是增序的。 + if nums[l] <= target < nums[mid]: + r = mid - 1 + else: + l = mid + 1 + return False +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/3-binary-search-techniques/3-6-exercises.md b/leetcode_101/docs/3-binary-search-techniques/3-6-exercises.md index d05876c5..c44e816e 100644 --- a/leetcode_101/docs/3-binary-search-techniques/3-6-exercises.md +++ b/leetcode_101/docs/3-binary-search-techniques/3-6-exercises.md @@ -3,3 +3,19 @@ sidebar_position: 16 --- # 3.6 练习 + +## 基础难度 + +### [154. Find Minimum in Rotated Sorted Array II](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array-ii/) + +旋转数组的变形题之一。 + +### [540. Single Element in a Sorted Array](https://leetcode.com/problems/single-element-in-a-sorted-array/) + +在出现独立数之前和之后,奇偶位数的值发生了什么变化? + +## 进阶难度 + +### [4. Median of Two Sorted Arrays](https://leetcode.com/problems/median-of-two-sorted-arrays/) + +需要对两个数组同时进行二分搜索。 \ No newline at end of file diff --git a/leetcode_101/docs/3-binary-search-techniques/_category_.json b/leetcode_101/docs/3-binary-search-techniques/_category_.json index e3e4daa5..89e9fd2f 100644 --- a/leetcode_101/docs/3-binary-search-techniques/_category_.json +++ b/leetcode_101/docs/3-binary-search-techniques/_category_.json @@ -3,6 +3,6 @@ "position": 3, "link": { "type": "generated-index", - "description": "5 minutes to learn the most important Docusaurus concepts." + "description": "第 3 章 居合斩!二分查找" } } diff --git a/leetcode_101/docs/4-sorting-algorithms/4-2-quick-select.md b/leetcode_101/docs/4-sorting-algorithms/4-2-quick-select.md index 92d00bab..e28e0d6d 100644 --- a/leetcode_101/docs/4-sorting-algorithms/4-2-quick-select.md +++ b/leetcode_101/docs/4-sorting-algorithms/4-2-quick-select.md @@ -2,4 +2,7 @@ sidebar_position: 18 --- +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + # 4.2 快速选择 diff --git a/leetcode_101/docs/4-sorting-algorithms/4-3-bucket-sort.md b/leetcode_101/docs/4-sorting-algorithms/4-3-bucket-sort.md index 65cf9814..d1bd77c7 100644 --- a/leetcode_101/docs/4-sorting-algorithms/4-3-bucket-sort.md +++ b/leetcode_101/docs/4-sorting-algorithms/4-3-bucket-sort.md @@ -2,4 +2,7 @@ sidebar_position: 19 --- +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + # 4.3 桶排序 diff --git a/leetcode_101/docs/5-searching-algorithms/5-2-depth-first-search.md b/leetcode_101/docs/5-searching-algorithms/5-2-depth-first-search.md index af6c4914..82989a4c 100644 --- a/leetcode_101/docs/5-searching-algorithms/5-2-depth-first-search.md +++ b/leetcode_101/docs/5-searching-algorithms/5-2-depth-first-search.md @@ -2,4 +2,7 @@ sidebar_position: 22 --- +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + # 5.2 深度优先搜索 diff --git a/leetcode_101/docs/5-searching-algorithms/5-3-backtracking.md b/leetcode_101/docs/5-searching-algorithms/5-3-backtracking.md index 5f7dc393..81abdf4e 100644 --- a/leetcode_101/docs/5-searching-algorithms/5-3-backtracking.md +++ b/leetcode_101/docs/5-searching-algorithms/5-3-backtracking.md @@ -2,4 +2,7 @@ sidebar_position: 23 --- +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + # 5.3 回溯法 diff --git a/leetcode_101/docs/5-searching-algorithms/5-4-breadth-first-search.md b/leetcode_101/docs/5-searching-algorithms/5-4-breadth-first-search.md index 7e7f672d..ac39e533 100644 --- a/leetcode_101/docs/5-searching-algorithms/5-4-breadth-first-search.md +++ b/leetcode_101/docs/5-searching-algorithms/5-4-breadth-first-search.md @@ -2,4 +2,7 @@ sidebar_position: 24 --- +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + # 5.4 广度优先搜索 diff --git a/leetcode_101/docs/6-dynamic-programming/6-2-basic-dp-1d.md b/leetcode_101/docs/6-dynamic-programming/6-2-basic-dp-1d.md index fa5059f4..5a74efdf 100644 --- a/leetcode_101/docs/6-dynamic-programming/6-2-basic-dp-1d.md +++ b/leetcode_101/docs/6-dynamic-programming/6-2-basic-dp-1d.md @@ -2,4 +2,7 @@ sidebar_position: 27 --- +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + # 6.2 基本动态规划:一维 diff --git a/leetcode_101/docs/6-dynamic-programming/6-3-basic-dp-2d.md b/leetcode_101/docs/6-dynamic-programming/6-3-basic-dp-2d.md index f8e965f6..35b57ebe 100644 --- a/leetcode_101/docs/6-dynamic-programming/6-3-basic-dp-2d.md +++ b/leetcode_101/docs/6-dynamic-programming/6-3-basic-dp-2d.md @@ -2,4 +2,7 @@ sidebar_position: 28 --- +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + # 6.3 基本动态规划:二维 diff --git a/leetcode_101/docusaurus.config.ts b/leetcode_101/docusaurus.config.ts index dff9de8b..788a0bbc 100644 --- a/leetcode_101/docusaurus.config.ts +++ b/leetcode_101/docusaurus.config.ts @@ -1,4 +1,6 @@ import { themes as prismThemes } from "prism-react-renderer"; +import remarkMath from 'remark-math'; +import rehypeKatex from 'rehype-katex'; import type { Config } from "@docusaurus/types"; import type * as Preset from "@docusaurus/preset-classic"; @@ -48,11 +50,11 @@ const config: Config = { { docs: { routeBasePath: "/", - sidebarPath: "./sidebars.ts", - // Please change this to your repo. - // Remove this to remove the "edit this page" links. + sidebarPath: "./sidebars.ts", editUrl: "https://github.com/noworneverev/leetcode_101/tree/master/leetcode_101", + remarkPlugins: [remarkMath], + rehypePlugins: [rehypeKatex], }, blog: false, theme: { @@ -61,7 +63,15 @@ const config: Config = { } satisfies Preset.Options, ], ], - + stylesheets: [ + { + href: 'https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css', + type: 'text/css', + integrity: + 'sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM', + crossorigin: 'anonymous', + }, + ], themeConfig: { docs: { sidebar: { @@ -141,7 +151,7 @@ const config: Config = { }, prism: { theme: prismThemes.github, - darkTheme: prismThemes.dracula, + darkTheme: prismThemes.vsDark, }, } satisfies Preset.ThemeConfig, }; diff --git a/leetcode_101/package-lock.json b/leetcode_101/package-lock.json index 25d32ad9..c6006127 100644 --- a/leetcode_101/package-lock.json +++ b/leetcode_101/package-lock.json @@ -14,7 +14,9 @@ "clsx": "^2.0.0", "prism-react-renderer": "^2.3.0", "react": "^18.0.0", - "react-dom": "^18.0.0" + "react-dom": "^18.0.0", + "rehype-katex": "^7.0.1", + "remark-math": "^6.0.0" }, "devDependencies": { "@docusaurus/module-type-aliases": "3.6.1", @@ -3688,6 +3690,12 @@ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "license": "MIT" }, + "node_modules/@types/katex": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz", + "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==", + "license": "MIT" + }, "node_modules/@types/mdast": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", @@ -7594,6 +7602,55 @@ "node": ">= 0.4" } }, + "node_modules/hast-util-from-dom": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/hast-util-from-dom/-/hast-util-from-dom-5.0.0.tgz", + "integrity": "sha512-d6235voAp/XR3Hh5uy7aGLbM3S4KamdW0WEgOaU1YoewnuYw4HXb5eRtv9g65m/RFGEfUY1Mw4UqCc5Y8L4Stg==", + "license": "ISC", + "dependencies": { + "@types/hast": "^3.0.0", + "hastscript": "^8.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-html": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz", + "integrity": "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.1.0", + "hast-util-from-parse5": "^8.0.0", + "parse5": "^7.0.0", + "vfile": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-html-isomorphic": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hast-util-from-html-isomorphic/-/hast-util-from-html-isomorphic-2.0.0.tgz", + "integrity": "sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-from-dom": "^5.0.0", + "hast-util-from-html": "^2.0.0", + "unist-util-remove-position": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-from-parse5": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz", @@ -7614,6 +7671,19 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-parse-selector": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", @@ -7741,6 +7811,22 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-to-text": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", + "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "unist-util-find-after": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-whitespace": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", @@ -8728,6 +8814,31 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/katex": { + "version": "0.16.11", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.11.tgz", + "integrity": "sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==", + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "license": "MIT", + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/katex/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -9198,6 +9309,25 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdast-util-math": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-3.0.0.tgz", + "integrity": "sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "longest-streak": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.1.0", + "unist-util-remove-position": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdast-util-mdx": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", @@ -9997,6 +10127,81 @@ ], "license": "MIT" }, + "node_modules/micromark-extension-math": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz", + "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==", + "license": "MIT", + "dependencies": { + "@types/katex": "^0.16.0", + "devlop": "^1.0.0", + "katex": "^0.16.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-math/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-math/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-math/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, "node_modules/micromark-extension-mdx-expression": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.0.tgz", @@ -13387,6 +13592,25 @@ "regjsparser": "bin/parser" } }, + "node_modules/rehype-katex": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-7.0.1.tgz", + "integrity": "sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/katex": "^0.16.0", + "hast-util-from-html-isomorphic": "^2.0.0", + "hast-util-to-text": "^4.0.0", + "katex": "^0.16.0", + "unist-util-visit-parents": "^6.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/rehype-raw": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", @@ -13492,6 +13716,22 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/remark-math": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/remark-math/-/remark-math-6.0.0.tgz", + "integrity": "sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-math": "^3.0.0", + "micromark-extension-math": "^3.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/remark-mdx": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.1.0.tgz", @@ -15039,6 +15279,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/unist-util-find-after": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", + "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/unist-util-is": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", @@ -15078,6 +15332,20 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/unist-util-remove-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", + "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/unist-util-stringify-position": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", diff --git a/leetcode_101/package.json b/leetcode_101/package.json index 153a4db7..427f10a7 100644 --- a/leetcode_101/package.json +++ b/leetcode_101/package.json @@ -21,7 +21,9 @@ "clsx": "^2.0.0", "prism-react-renderer": "^2.3.0", "react": "^18.0.0", - "react-dom": "^18.0.0" + "react-dom": "^18.0.0", + "rehype-katex": "^7.0.1", + "remark-math": "^6.0.0" }, "devDependencies": { "@docusaurus/module-type-aliases": "3.6.1", diff --git a/leetcode_101/src/components/MDXProviderWrapper.tsx b/leetcode_101/src/components/MDXProviderWrapper.tsx new file mode 100644 index 00000000..7091c43b --- /dev/null +++ b/leetcode_101/src/components/MDXProviderWrapper.tsx @@ -0,0 +1,17 @@ +import React from "react"; +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; +import { MDXProvider } from "@mdx-js/react"; + +const components = { + Tabs, + TabItem, +}; + +const MDXProviderWrapper: React.FC<{ children: React.ReactNode }> = ({ + children, +}) => { + return {children}; +}; + +export default MDXProviderWrapper; diff --git a/leetcode_101/src/theme/Root.tsx b/leetcode_101/src/theme/Root.tsx new file mode 100644 index 00000000..771fa55a --- /dev/null +++ b/leetcode_101/src/theme/Root.tsx @@ -0,0 +1,8 @@ +import React from "react"; +import MDXProviderWrapper from "../components/MDXProviderWrapper"; + +function Root({ children }: { children: React.ReactNode }) { + return {children}; +} + +export default Root; From c0bdc6c4e0437ec390ebcafe601c9d8a98bf6d31 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Wed, 13 Nov 2024 10:06:30 +0100 Subject: [PATCH 06/49] chapter 4 --- .../4-1-common-sorting-algorithms.md | 5 - .../4-1-common-sorting-algorithms.mdx | 147 ++++++++++++++++++ .../4-sorting-algorithms/4-2-quick-select.md | 8 - .../4-sorting-algorithms/4-2-quick-select.mdx | 81 ++++++++++ .../4-sorting-algorithms/4-3-bucket-sort.md | 8 - .../4-sorting-algorithms/4-3-bucket-sort.mdx | 84 ++++++++++ .../4-sorting-algorithms/4-4-exercises.md | 12 ++ .../docs/4-sorting-algorithms/_category_.json | 2 +- 8 files changed, 325 insertions(+), 22 deletions(-) delete mode 100644 leetcode_101/docs/4-sorting-algorithms/4-1-common-sorting-algorithms.md create mode 100644 leetcode_101/docs/4-sorting-algorithms/4-1-common-sorting-algorithms.mdx delete mode 100644 leetcode_101/docs/4-sorting-algorithms/4-2-quick-select.md create mode 100644 leetcode_101/docs/4-sorting-algorithms/4-2-quick-select.mdx delete mode 100644 leetcode_101/docs/4-sorting-algorithms/4-3-bucket-sort.md create mode 100644 leetcode_101/docs/4-sorting-algorithms/4-3-bucket-sort.mdx diff --git a/leetcode_101/docs/4-sorting-algorithms/4-1-common-sorting-algorithms.md b/leetcode_101/docs/4-sorting-algorithms/4-1-common-sorting-algorithms.md deleted file mode 100644 index dc8c3741..00000000 --- a/leetcode_101/docs/4-sorting-algorithms/4-1-common-sorting-algorithms.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 17 ---- - -# 4.1 常用排序算法 diff --git a/leetcode_101/docs/4-sorting-algorithms/4-1-common-sorting-algorithms.mdx b/leetcode_101/docs/4-sorting-algorithms/4-1-common-sorting-algorithms.mdx new file mode 100644 index 00000000..439287d5 --- /dev/null +++ b/leetcode_101/docs/4-sorting-algorithms/4-1-common-sorting-algorithms.mdx @@ -0,0 +1,147 @@ +--- +sidebar_position: 17 +--- + +# 4.1 常用排序算法 + +虽然在 C++ 和 Python 里都可以通过 sort 函数排序,而且刷题时很少需要自己手写排序算法,但是熟习各种排序算法可以加深自己对算法的基本理解,以及解出由这些排序算法引申出来的题目。这里我们展示两种复杂度为 $O(n \log n)$ 的排序算法:`快速排序`和`归并排序`,其中前者实际速度较快,后者可以保证相同值的元素在数组中的相对位置不变(即“稳定排序”)。 + +## 快速排序(Quicksort) + +快速排序的原理并不复杂:对于当前一个未排序片段,我们先随机选择一个位置当作中枢点,然后通过遍历操作,将所有比中枢点小的数字移动到其左侧,再将所有比中枢点大的数字移动到其右侧。操作完成后,我们再次对中枢点左右侧的片段再次进行快速排序即可。可证明,如果中枢点选取是随机的,那么该算法的平均复杂度可以达到 $O(n \log n)$,最差情况下复杂度则为 $O(n^2)$。 + +我们采用左闭右闭的二分写法,初始化条件为 $l =0,r =n − 1$。 + + + + +```cpp +void quickSort(vector &nums, int l, int r) { + if (l >= r) { + return; + } + // 在当前的[l, r]区间中,随机选择一个位置当作pivot。 + int pivot = l + (rand() % (r - l + 1)); + int pivot_val = nums[pivot]; + // 将pivot与l交换。 + swap(nums[l], nums[pivot]); + // 从[l+1, r]两端向内遍历,查找是否有位置不满足递增关系。 + int i = l + 1, j = r; + while (true) { + while (i < j && nums[j] >= pivot_val) { + --j; + } + while (i < j && nums[i] <= pivot_val) { + ++i; + } + if (i == j) { + break; + } + // i位置的值大于pivot值,j位置的值小于pivot值,将二者交换。 + swap(nums[i], nums[j]); + } + // i和j相遇的位置即为新的pivot,我们将pivot与l重新换回来。 + // 此时相遇位置左侧一定比pivot值小,右侧一定比pivot值大。 + int new_pivot = nums[i] <= nums[l] ? i : i - 1; + swap(nums[l], nums[new_pivot]); + quickSort(nums, l, new_pivot - 1); + quickSort(nums, new_pivot + 1, r); +} +``` + + + + +```py +def quickSort(nums: List[int], l: int, r: int) -> bool: + if l >= r: + return + # 在当前的[l, r]区间中,随机选择一个位置当作pivot。 + pivot = random.randint(l, r) + pivot_val = nums[pivot] + # 将pivot与l交换。 + nums[l], nums[pivot] = nums[pivot], nums[l] + # 从[l+1, r]两端向内遍历,查找是否有位置不满足递增关系。 + i, j = l + 1, r + while True: + while i < j and nums[j] >= pivot_val: + j -= 1 + while i < j and nums[i] <= pivot_val: + i += 1 + if i == j: + break + # i位置的值大于pivot值,j位置的值小于pivot值,将二者交换。 + nums[i], nums[j] = nums[j], nums[i] + # i和j相遇的位置即为新的pivot,我们将pivot与l重新换回来。 + # 此时相遇位置左侧一定比pivot值小,右侧一定比pivot值大。 + new_pivot = i if nums[i] <= nums[l] else i - 1 + nums[l], nums[new_pivot] = nums[new_pivot], nums[l] + quickSort(nums, l, new_pivot - 1) + quickSort(nums, new_pivot + 1, r) +``` + + + + + +## 归并排序(Merge Sort) + +归并排序是典型的分治法,我们在之后的章节会展开讲解。简单来讲,对于一个未排序片段,我们可以先分别排序其左半侧和右半侧,然后将两侧重新组合(“治”);排序每个半侧时可以通过递归再次把它切分成两侧(“分”)。 + +我们采用左闭右闭的二分写法,初始化条件为 $l =0,r = n − 1$,另外提前建立一个和 nums 大小相同的数组 cache,用来存储临时结果。 + + + + +```cpp +void mergeSort(vector &nums, vector &cache, int l, int r) { + if (l >= r) { + return; + } + // 分。 + int mid = l + (r - l) / 2; + mergeSort(nums, cache, l, mid); + mergeSort(nums, cache, mid + 1, r); + // 治。 + // i和j同时向右前进,i的范围是[l, mid],j的范围是[mid+1, r]。 + int i = l, j = mid + 1; + for (int pos = l; pos <= r; ++pos) { + if (j > r || (i <= mid && nums[i] <= nums[j])) { + cache[pos] = nums[i++]; + } else { + cache[pos] = nums[j++]; + } + } + for (int pos = l; pos <= r; ++pos) { + nums[pos] = cache[pos]; + } +} +``` + + + + +```py +def mergeSort(nums: List[int], cache: List[int], l: int, r: int) -> bool: + if l >= r: + return + # 分。 + mid = (l + r) // 2 + mergeSort(nums, cache, l, mid) + mergeSort(nums, cache, mid + 1, r) + # 治。 + # i和j同时向右前进,i的范围是[l, mid],j的范围是[mid+1, r]。 + i, j = l, mid + 1 + for pos in range(l, r + 1): + if j > r or (i <= mid and nums[i] <= nums[j]): + cache[pos] = nums[i] + i += 1 + else: + cache[pos] = nums[j] + j += 1 + nums[l:r+1] = cache[l:r+1] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/4-sorting-algorithms/4-2-quick-select.md b/leetcode_101/docs/4-sorting-algorithms/4-2-quick-select.md deleted file mode 100644 index e28e0d6d..00000000 --- a/leetcode_101/docs/4-sorting-algorithms/4-2-quick-select.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -sidebar_position: 18 ---- - -import Tabs from "@theme/Tabs"; -import TabItem from "@theme/TabItem"; - -# 4.2 快速选择 diff --git a/leetcode_101/docs/4-sorting-algorithms/4-2-quick-select.mdx b/leetcode_101/docs/4-sorting-algorithms/4-2-quick-select.mdx new file mode 100644 index 00000000..01ab69ce --- /dev/null +++ b/leetcode_101/docs/4-sorting-algorithms/4-2-quick-select.mdx @@ -0,0 +1,81 @@ +--- +sidebar_position: 18 +--- + +# 4.2 快速选择 + +## [215. Kth Largest Element in an Array](https://leetcode.com/problems/kth-largest-element-in-an-array/) + +### 题目描述 + +在一个未排序的数组中,找到第 $k$ 大的数字。 + +### 输入输出样例 + +输入一个数组和一个目标值 $k$,输出第 $k$ 大的数字。题目默认一定有解。 + +``` +Input: [3,2,1,5,6,4] and k = 2 +Output: 5 +``` + + + +### 题解 + +`快速选择`一般用于求解 k-th Element 问题,可以在平均 $O(n)$ 时间复杂度,$O(1)$ 空间复杂度完成求解工作。快速选择的实现和快速排序相似,不过只需要找到第 $k$ 大的枢(pivot)即可,不需 +要对其左右再进行排序。与快速排序一样,快速选择一般需要先打乱数组,否则最坏情况下时间复杂度为 $O(n^2)$。 + +这道题如果直接用上面的快速排序原代码运行,会导致在 LeetCode 上接近超时。我们可以用空间换取时间,直接存储比中枢点小和大的值,尽量避免进行交换位置的操作。 + + + + +```cpp +int findKthLargest(vector nums, int k) { + int pivot = rand() % nums.size(); + int pivot_val = nums[pivot]; + vector larger, equal, smaller; + for (int num : nums) { + if (num > pivot_val) { + larger.push_back(num); + } else if (num < pivot_val) { + smaller.push_back(num); + } else { + equal.push_back(num); + } + } + if (k <= larger.size()) { + return findKthLargest(larger, k); + } + if (k > larger.size() + equal.size()) { + return findKthLargest(smaller, k - larger.size() - equal.size()); + } + return pivot_val; +} +``` + + + + +```py +def findKthLargest(nums: List[int], k: int) -> int: + pivot_val = random.choice(nums) + larger, equal, smaller = [], [], [] + for num in nums: + if num > pivot_val: + larger.append(num) + elif num < pivot_val: + smaller.append(num) + else: + equal.append(num) + if k <= len(larger): + return findKthLargest(larger, k) + if k > len(larger) + len(equal): + return findKthLargest(smaller, k - len(larger) - len(equal)) + return pivot_val +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/4-sorting-algorithms/4-3-bucket-sort.md b/leetcode_101/docs/4-sorting-algorithms/4-3-bucket-sort.md deleted file mode 100644 index d1bd77c7..00000000 --- a/leetcode_101/docs/4-sorting-algorithms/4-3-bucket-sort.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -sidebar_position: 19 ---- - -import Tabs from "@theme/Tabs"; -import TabItem from "@theme/TabItem"; - -# 4.3 桶排序 diff --git a/leetcode_101/docs/4-sorting-algorithms/4-3-bucket-sort.mdx b/leetcode_101/docs/4-sorting-algorithms/4-3-bucket-sort.mdx new file mode 100644 index 00000000..180d2d6f --- /dev/null +++ b/leetcode_101/docs/4-sorting-algorithms/4-3-bucket-sort.mdx @@ -0,0 +1,84 @@ +--- +sidebar_position: 19 +--- + +# 4.3 桶排序 + +## [347. Top K Frequent Elements](https://leetcode.com/problems/top-k-frequent-elements/) + +### 题目描述 + +给定一个数组,求前 $k$ 个最频繁的数字。 + +### 输入输出样例 + +输入是一个数组和一个目标值 $k$。输出是一个长度为 $k$ 的数组。 + +``` +Input: nums = [1,1,1,1,2,2,3,4], k = 2 +Output: [1,2] +``` + +在这个样例中,最频繁的两个数是 1 和 2。 + +### 题解 + +顾名思义,`桶排序`的意思是为每个值设立一个桶,桶内记录这个值出现的次数(或其它属性),然后对桶进行排序。针对样例来说,我们先通过桶排序得到四个桶 [1,2,3,4],它们的值分别 +为 [4,2,1,1],表示每个数字出现的次数。 + +紧接着,我们对桶的频次进行排序,前 $k$ 大个桶即是前 $k$ 个频繁的数。这里我们可以使用各种排序算法,甚至可以再进行一次桶排序,把每个旧桶根据频次放在不同的新桶内。针对样例来说,因为目前最大的频次是 4,我们建立 [1,2,3,4] 四个新桶,它们分别放入的旧桶为 [[3,4],[2],[],[1]],表示不同数字出现的频率。最后,我们从后往前遍历,直到找到 k 个旧桶。 + +我们可以使用 C++ 中的 unordered_map 或 Python 中的 dict 实现哈希表。 + + + + +```cpp +vector topKFrequent(vector& nums, int k) { + unordered_map counts; + for (int num : nums) { + ++counts[num]; + } + unordered_map> buckets; + for (auto [num, count] : counts) { + buckets[count].push_back(num); + } + vector top_k; + for (int count = nums.size(); count >= 0; --count) { + if (buckets.contains(count)) { + for (int num : buckets[count]) { + top_k.push_back(num); + if (top_k.size() == k) { + return top_k; + } + } + } + } + return top_k; +} +``` + + + + +```py +def topKFrequent(nums: List[int], k: int) -> List[int]: + counts = Counter(nums) + buckets = dict() + for num, count in counts.items(): + if count in buckets: + buckets[count].append(num) + else: + buckets[count] = [num] + top_k = [] + for count in range(len(nums), 0, -1): + if count in buckets: + top_k += buckets[count] + if len(top_k) >= k: + return top_k[:k] + return top_k[:k] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/4-sorting-algorithms/4-4-exercises.md b/leetcode_101/docs/4-sorting-algorithms/4-4-exercises.md index e8aecf4f..5688eb44 100644 --- a/leetcode_101/docs/4-sorting-algorithms/4-4-exercises.md +++ b/leetcode_101/docs/4-sorting-algorithms/4-4-exercises.md @@ -3,3 +3,15 @@ sidebar_position: 20 --- # 4.4 练习 + +## 基础难度 + +### [451. Sort Characters By Frequency](https://leetcode.com/problems/sort-characters-by-frequency/) + +桶排序的变形题。 + +## 进阶难度 + +### [75. Sort Colors](https://leetcode.com/problems/sort-colors/) + +很经典的荷兰国旗问题,考察如何对三个重复且打乱的值进行排序。 \ No newline at end of file diff --git a/leetcode_101/docs/4-sorting-algorithms/_category_.json b/leetcode_101/docs/4-sorting-algorithms/_category_.json index 3065ccba..4aad536a 100644 --- a/leetcode_101/docs/4-sorting-algorithms/_category_.json +++ b/leetcode_101/docs/4-sorting-algorithms/_category_.json @@ -3,6 +3,6 @@ "position": 4, "link": { "type": "generated-index", - "description": "5 minutes to learn the most important Docusaurus concepts." + "description": "第 4 章 千奇百怪的排序算法" } } From 2e83571b5e6228c00c45ca08333629c3a2a789a4 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Wed, 13 Nov 2024 20:58:41 +0100 Subject: [PATCH 07/49] chapter 5 --- .../5-1-algorithm-explanation.md | 2 + .../5-2-depth-first-search.md | 8 - .../5-2-depth-first-search.mdx | 372 ++++++++++++++ .../5-3-backtracking.md | 8 - .../5-3-backtracking.mdx | 375 +++++++++++++++ .../5-4-breadth-first-search.md | 8 - .../5-4-breadth-first-search.mdx | 454 ++++++++++++++++++ .../5-searching-algorithms/5-5-exercises.md | 28 ++ .../5-searching-algorithms/_category_.json | 2 +- .../docs/5-searching-algorithms/n-queens.png | Bin 0 -> 20347 bytes 10 files changed, 1232 insertions(+), 25 deletions(-) delete mode 100644 leetcode_101/docs/5-searching-algorithms/5-2-depth-first-search.md create mode 100644 leetcode_101/docs/5-searching-algorithms/5-2-depth-first-search.mdx delete mode 100644 leetcode_101/docs/5-searching-algorithms/5-3-backtracking.md create mode 100644 leetcode_101/docs/5-searching-algorithms/5-3-backtracking.mdx delete mode 100644 leetcode_101/docs/5-searching-algorithms/5-4-breadth-first-search.md create mode 100644 leetcode_101/docs/5-searching-algorithms/5-4-breadth-first-search.mdx create mode 100644 leetcode_101/docs/5-searching-algorithms/n-queens.png diff --git a/leetcode_101/docs/5-searching-algorithms/5-1-algorithm-explanation.md b/leetcode_101/docs/5-searching-algorithms/5-1-algorithm-explanation.md index 594616f1..1841acf6 100644 --- a/leetcode_101/docs/5-searching-algorithms/5-1-algorithm-explanation.md +++ b/leetcode_101/docs/5-searching-algorithms/5-1-algorithm-explanation.md @@ -3,3 +3,5 @@ sidebar_position: 21 --- # 5.1 算法解释 + +`深度优先搜索`和`广度优先搜索`是两种最常见的优先搜索方法,它们被广泛地运用在图和树等结构中进行搜索。 \ No newline at end of file diff --git a/leetcode_101/docs/5-searching-algorithms/5-2-depth-first-search.md b/leetcode_101/docs/5-searching-algorithms/5-2-depth-first-search.md deleted file mode 100644 index 82989a4c..00000000 --- a/leetcode_101/docs/5-searching-algorithms/5-2-depth-first-search.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -sidebar_position: 22 ---- - -import Tabs from "@theme/Tabs"; -import TabItem from "@theme/TabItem"; - -# 5.2 深度优先搜索 diff --git a/leetcode_101/docs/5-searching-algorithms/5-2-depth-first-search.mdx b/leetcode_101/docs/5-searching-algorithms/5-2-depth-first-search.mdx new file mode 100644 index 00000000..60ba3e14 --- /dev/null +++ b/leetcode_101/docs/5-searching-algorithms/5-2-depth-first-search.mdx @@ -0,0 +1,372 @@ +--- +sidebar_position: 22 +--- + +# 5.2 深度优先搜索 + +`深度优先搜索`(depth-first search,DFS)在搜索到一个新的节点时,立即对该新节点进行遍历;因此遍历需要用`先入后出的栈(stack)`来实现,也可以通过与栈等价的`递归`来实现。对于树结构而言,由于总是对新节点调用遍历,因此看起来是向着“深”的方向前进。在 Python 中,我们可以用 collections.deque 来实现 C++ 中的 stack。但是通常情况下,我们还是会选用 C++ 中的 vector 或 Python 中的 list 来实现栈,因为它们既是先入后出的数据结构,又能支持随机查找。 + +考虑如下一颗简单的树,我们从 1 号节点开始遍历。假如遍历顺序是从左子节点到右子节点,那么按照优先向着“深”的方向前进的策略,则遍历过程为 1(起始节点)->2(遍历更深一层的左子节点)->4(遍历更深一层的左子节点)->2(无子节点,返回父结点)->1(子节点均已完成遍历,返回父结点)->3(遍历更深一层的右子节点)->1(无子节点,返回父结点)-> 结束程序(子节点均已完成遍历)。如果我们使用栈实现,我们的栈顶元素的变化过程为 1->2->4->3。 + +``` + 1 + / \ + 2 3 + / +4 +``` + +深度优先搜索也可以用来`检测环路`:记录每个遍历过的节点的父节点,若一个节点被再次遍历且父节点不同,则说明有环。我们也可以用之后会讲到的拓扑排序判断是否有环路,若最后存在入度不为零的点,则说明有环。 + +有时我们可能会需要对已经搜索过的节点进行标记,以防止在遍历时重复搜索某个节点,这种做法叫做`状态记录`或`记忆化`(memoization)。 + +## [695. Max Area of Island](https://leetcode.com/problems/max-area-of-island/) + +### 题目描述 + +给定一个二维的 0-1 矩阵,其中 0 表示海洋,1 表示陆地。单独的或相邻的陆地可以形成岛屿,每个格子只与其上下左右四个格子相邻。求最大的岛屿面积。 + +### 输入输出样例 + +输入是一个二维数组,输出是一个整数,表示最大的岛屿面积。 + +``` +Input: +[[1,0,1,1,0,1,0,1], +[1,0,1,1,0,1,1,1], +[0,0,0,0,0,0,0,1]] +Output: 6 +``` + +最大的岛屿面积为 6,位于最右侧。 + +### 题解 + +此题是十分标准的搜索题,我们可以拿来练手深度优先搜索。一般来说,深度优先搜索类型的题可以分为主函数和辅函数,主函数用于遍历所有的搜索位置,判断是否可以开始搜索,如果可以即在辅函数进行搜索。辅函数则负责深度优先搜索的递归调用。当然,我们也可以使用栈(stack)实现深度优先搜索,但因为栈与递归的调用原理相同,而递归相对便于实现,因此刷题时笔者推荐使用递归式写法,同时也方便进行回溯(见下节)。不过在实际工程上,直接使用栈可能才是最好的选择,一是因为便于理解,二是更不易出现递归栈满的情况。 + +我们先展示使用栈的写法。这里我们使用了一个小技巧,对于四个方向的遍历,可以创造一个数组 [-1, 0, 1, 0, -1],每相邻两位即为上下左右四个方向之一。当然您也可以显式写成 [-1, 0]、[1, 0]、[0, 1] 和 [0, -1],以便理解。 + + + + +```cpp +int maxAreaOfIsland(vector>& grid) { + vector direction{-1, 0, 1, 0, -1}; + int m = grid.size(), n = grid[0].size(), max_area = 0; + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (grid[i][j] == 1) { + stack> island; + // 初始化第第一个节点。 + int local_area = 1; + grid[i][j] = 0; + island.push({i, j}); + // DFS. + while (!island.empty()) { + auto [r, c] = island.top(); + island.pop(); + for (int k = 0; k < 4; ++k) { + int x = r + direction[k], y = c + direction[k + 1]; + // 放入满足条件的相邻节点。 + if (x >= 0 && x < m && y >= 0 && y < n && + grid[x][y] == 1) { + ++local_area; + grid[x][y] = 0; + island.push({x, y}); + } + } + } + max_area = max(max_area, local_area); + } + } + } + return max_area; +} +``` + + + + +```py +def maxAreaOfIsland(grid: List[List[int]]) -> int: + direction = [-1, 0, 1, 0, -1] + m, n, max_area = len(grid), len(grid[0]), 0 + for i in range(m): + for j in range(n): + if grid[i][j] == 1: + island = [] + # 初始化第第一个节点。 + local_area = 1 + grid[i][j] = 0 + island.append((i, j)) + # DFS. + while len(island) > 0: + r, c = island.pop() + for k in range(4): + x, y = r + direction[k], c + direction[k + 1] + # 放入满足条件的相邻节点。 + if 0 <= x < m and 0 <= y < n and grid[x][y] == 1: + local_area += 1 + grid[x][y] = 0 + island.append((x, y)) + max_area = max(max_area, local_area) + return max_area +``` + + + + + +下面我们展示递归写法,注意进行递归搜索时,一定要检查边界条件。可以在每次调用辅函数之前检查,也可以在辅函数的一开始进行检查。这里我们没有利用 [-1, 0, 1, 0, -1] 数组进行上下左右四个方向的搜索,而是直接显式地写出来四种不同的递归函数。两种写法都可以,读者可以掌握任意一种。 + + + + +```cpp +// 辅函数。 +int dfs(vector>& grid, int r, int c) { + if (r < 0 || r >= grid.size() || c < 0 || c >= grid[0].size() || + grid[r][c] == 0) { + return 0; + } + grid[r][c] = 0; + return (1 + dfs(grid, r + 1, c) + dfs(grid, r - 1, c) + + dfs(grid, r, c + 1) + dfs(grid, r, c - 1)); +} + +// 主函数。 +int maxAreaOfIsland(vector>& grid) { + int max_area = 0; + for (int i = 0; i < grid.size(); ++i) { + for (int j = 0; j < grid[0].size(); ++j) { + max_area = max(max_area, dfs(grid, i, j)); + } + } + return max_area; +} +``` + + + + +```py +# 辅函数。 +def dfs(grid: List[List[int]], r: int, c: int) -> int: + if r < 0 or r >= len(grid) or c < 0 or c >= len(grid[0]) or grid[r][c] == 0: + return 0 + grid[r][c] = 0 + return (1 + dfs(grid, r + 1, c) + dfs(grid, r - 1, c) + + dfs(grid, r, c + 1) + dfs(grid, r, c - 1)) + +# 主函数。 +def maxAreaOfIsland(grid: List[List[int]]) -> int: + max_area = 0 + for i in range(len(grid)): + for j in range(len(grid[0])): + max_area = max(max_area, dfs(grid, i, j)) + return max_area +``` + + + + + +## [547. Number of Provinces](https://leetcode.com/problems/number-of-provinces/) + +### 题目描述 + +给定一个二维的 0-1 矩阵,如果第 (i, j) 位置是 1,则表示第 i 个城市和第 j 个城市处于同一城市圈。已知城市的相邻关系是可以传递的,即如果 a 和 b 相邻,b 和 c 相邻,那么 a 和 c 也相邻,换言之这三个城市处于同一个城市圈之内。求一共有多少个城市圈。 + +### 输入输出样例 + +输入是一个二维数组,输出是一个整数,表示城市圈数量。因为城市相邻关系具有对称性,该二维数组为对称矩阵。同时,因为自己也处于自己的城市圈,对角线上的值全部为 1。 + +``` +Input: +[[1,1,0], +[1,1,0], +[0,0,1]] +Output: 2 +``` + +在这个样例中,[1,2] 处于一个城市圈,[3] 处于一个城市圈。 + +### 题解 + +在上一道题目中,图的表示方法是,每个位置代表一个节点,每个节点与上下左右四个节点相邻。而在这一道题里面,每一行(列)表示一个节点,它的每列(行)表示是否存在一个相邻节点。上一道题目拥有 m × n 个节点,每个节点有 4 条边;而本题拥有 n 个节点,每个节点最多有 n 条边,表示和所有城市都相邻,最少可以有 1 条边,表示当前城市圈只有自己。当清楚了图的表示方法后,这道题目与上一道题目本质上是同一道题:搜索城市圈(岛屿圈)的个数。我们这里采用递归的写法。 + +:::warning + +对于节点连接类问题,我们也可以利用并查集来进行快速的连接和搜索。我们将会在之后的章节讲解。 + +::: + + + + +```cpp +// 辅函数。 +void dfs(vector>& isConnected, int i, vector& visited) { + visited[i] = true; + for (int j = 0; j < isConnected.size(); ++j) { + if (isConnected[i][j] == 1 && !visited[j]) { + dfs(isConnected, j, visited); + } + } +} + +// 主函数。 +int findCircleNum(vector>& isConnected) { + int n = isConnected.size(), count = 0; + // 防止重复搜索已被搜索过的节点。 + vector visited(n, false); + for (int i = 0; i < n; ++i) { + if (!visited[i]) { + dfs(isConnected, i, visited); + ++count; + } + } + return count; +} +``` + + + + +```py +# 辅函数。 +def dfs(isConnected: List[List[int]], city: int, visited: Set[int]): + visited.add(city) + for i in range(len(isConnected)): + if isConnected[city][i] == 1 and i not in visited: + dfs(isConnected, i, visited) + +# 主函数。 +def findCircleNum(isConnected: List[List[int]]) -> int: + count = 0 + # 防止重复搜索已被搜索过的节点。 + visited = set() + for i in range(len(isConnected)): + if i not in visited: + dfs(isConnected, i, visited) + count += 1 + return count +``` + + + + + + +## [417. Pacific Atlantic Water Flow](https://leetcode.com/problems/pacific-atlantic-water-flow/) + +### 题目描述 + +给定一个二维的非负整数矩阵,每个位置的值表示海拔高度。假设左边和上边是太平洋,右边和下边是大西洋,求从哪些位置向下流水,可以流到太平洋和大西洋。水只能从海拔高的位置流到海拔低或相同的位置。 + +### 输入输出样例 + +输入是一个二维的非负整数数组,表示海拔高度。输出是一个二维的数组,其中第二个维度大小固定为 2,表示满足条件的位置坐标。 + + +``` +Input: + 太平洋 ~ ~ ~ ~ ~ + ~ 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 * + * * * * * 大西洋 +Output: [[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]] +``` + +在这个样例中,有括号的区域为满足条件的位置。 + +### 题解 + +虽然题目要求的是满足向下流能到达两个大洋的位置,如果我们对所有的位置进行搜索,那么在不剪枝的情况下复杂度会很高。因此我们可以反过来想,从两个大洋开始向上流,这样我们只需要对矩形四条边进行搜索。搜索完成后,只需遍历一遍矩阵,两个大洋向上流都能到达的位置即为满足条件的位置。 + + + + +```cpp +vector direction{-1, 0, 1, 0, -1}; +// 辅函数。 +void dfs(const vector>& heights, vector>& can_reach, + int r, int c) { + if (can_reach[r][c]) { + return; + } + can_reach[r][c] = true; + for (int i = 0; i < 4; ++i) { + int x = r + direction[i], y = c + direction[i + 1]; + if (x >= 0 && x < heights.size() && y >= 0 && y < heights[0].size() && + heights[r][c] <= heights[x][y]) { + dfs(heights, can_reach, x, y); + } + } +} + +// 主函数。 +vector> pacificAtlantic(vector>& heights) { + int m = heights.size(), n = heights[0].size(); + vector> can_reach_p(m, vector(n, false)); + vector> can_reach_a(m, vector(n, false)); + vector> can_reach_p_and_a; + for (int i = 0; i < m; ++i) { + dfs(heights, can_reach_p, i, 0); + dfs(heights, can_reach_a, i, n - 1); + } + for (int i = 0; i < n; ++i) { + dfs(heights, can_reach_p, 0, i); + dfs(heights, can_reach_a, m - 1, i); + } + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (can_reach_p[i][j] && can_reach_a[i][j]) { + can_reach_p_and_a.push_back({i, j}); + } + } + } + return can_reach_p_and_a; +} +``` + + + + +```py +direction = [-1, 0, 1, 0, -1] + +# 辅函数。 +def dfs(heights: List[List[int]], can_reach: List[List[int]], r: int, c: int): + if can_reach[r][c]: + return + can_reach[r][c] = True + for i in range(4): + x, y = r + direction[i], c + direction[i + 1] + if (x >= 0 and x < len(heights) and y >= 0 and y < len(heights[0]) and + heights[x][y] >= heights[r][c]): + dfs(heights, can_reach, x, y) + +# 主函数。 +def pacificAtlantic(heights: List[List[int]]) -> List[List[int]]: + m, n = len(heights), len(heights[0]) + can_reach_p = [[False for _ in range(n)] for _ in range(m)] + can_reach_a = [[False for _ in range(n)] for _ in range(m)] + for i in range(m): + dfs(heights, can_reach_p, i, 0) + dfs(heights, can_reach_a, i, n - 1) + for j in range(n): + dfs(heights, can_reach_p, 0, j) + dfs(heights, can_reach_a, m - 1, j) + return [ + [i, j] for i in range(m) for j in range(n) + if can_reach_p[i][j] and can_reach_a[i][j] + ] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/5-searching-algorithms/5-3-backtracking.md b/leetcode_101/docs/5-searching-algorithms/5-3-backtracking.md deleted file mode 100644 index 81abdf4e..00000000 --- a/leetcode_101/docs/5-searching-algorithms/5-3-backtracking.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -sidebar_position: 23 ---- - -import Tabs from "@theme/Tabs"; -import TabItem from "@theme/TabItem"; - -# 5.3 回溯法 diff --git a/leetcode_101/docs/5-searching-algorithms/5-3-backtracking.mdx b/leetcode_101/docs/5-searching-algorithms/5-3-backtracking.mdx new file mode 100644 index 00000000..8711e78a --- /dev/null +++ b/leetcode_101/docs/5-searching-algorithms/5-3-backtracking.mdx @@ -0,0 +1,375 @@ +--- +sidebar_position: 23 +--- + +# 5.3 回溯法 + +`回溯法`(backtracking)是优先搜索的一种特殊情况,又称为试探法,常用于需要记录节点状态的深度优先搜索。通常来说,排列、组合、选择类问题使用回溯法比较方便。 + +顾名思义,回溯法的核心是回溯。在搜索到某一节点的时候,如果我们发现目前的节点(及其子节点)并不是需求目标时,我们回退到原来的节点继续搜索,并且`把在目前节点修改的状态还原`。这样的好处是我们可以始终只对图的总状态进行修改,而非每次遍历时新建一个图来储存状态。在具体的写法上,它与普通的深度优先搜索一样,都有 [修改当前节点状态]→[递归子节点] 的步骤,只是多了回溯的步骤,变成了 [修改当前节点状态]→[递归子节点]→[回改当前节点状态]。 + +没有接触过回溯法的读者可能会不明白我在讲什么,这也完全正常,希望以下几道题可以让您理解回溯法。如果还是不明白,可以记住两个小诀窍,`一是按引用传状态,二是所有的状态修改在递归完成后回改`。 + +回溯法修改一般有两种情况,一种是修改最后一位输出,比如排列组合;一种是修改访问标记,比如矩阵里搜字符串。 + +## [46. Permutations](https://leetcode.com/problems/permutations/) + +### 题目描述 + +给定一个无重复数字的整数数组,求其所有的排列方式。 + +### 输入输出样例 + +输入是一个一维整数数组,输出是一个二维数组,表示输入数组的所有排列方式。 + +``` +Input: [1,2,3] +Output: [[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,2,1], [3,1,2]] +``` + +可以以任意顺序输出,只要包含了所有排列方式即可。 + +### 题解 + +怎样输出所有的排列方式呢?对于每一个当前位置 i,我们可以将其于之后的任意位置交换,然后继续处理位置 i+1,直到处理到最后一位。为了防止我们每此遍历时都要新建一个子数组储存位置 i 之前已经交换好的数字,我们可以利用回溯法,只对原数组进行修改,在递归完成后再修改回来。 + +我们以样例 [1,2,3] 为例,按照这种方法,我们输出的数组顺序为 [[1,2,3], [1,3,2], [2,1,3], [2,3,1],[3,2,1], [3,1,2]],可以看到所有的排列在这个算法中都被考虑到了。 + + + + +```cpp +// 辅函数。 +void backtracking(vector &nums, int level, + vector> &permutations) { + if (level == nums.size() - 1) { + permutations.push_back(nums); + return; + } + for (int i = level; i < nums.size(); ++i) { + swap(nums[i], nums[level]); // 修改当前节点状态 + backtracking(nums, level + 1, permutations); // 递归子节点 + swap(nums[i], nums[level]); // 回改当前节点状态 + } +} +// 主函数。 +vector> permute(vector &nums) { + vector> permutations; + backtracking(nums, 0, permutations); + return permutations; +} +``` + + + + +```py +# 辅函数。 +def backtracking(nums: List[int], level: int, permutations: List[List[int]]): + if level == len(nums) - 1: + permutations.append(nums[:]) # int为基本类型,可以浅拷贝 + return + for i in range(level, len(nums)): + nums[i], nums[level] = nums[level], nums[i] # 修改当前节点状态 + backtracking(nums, level + 1, permutations) # 递归子节点 + nums[i], nums[level] = nums[level], nums[i] # 回改当前节点状态 + +# 主函数。 +def permute(nums: List[int]) -> List[List[int]]: + permutations = [] + backtracking(nums, 0, permutations) + return permutations +``` + + + + + +## [77. Combinations](https://leetcode.com/problems/combinations/) + +### 题目描述 + +给定一个整数 n 和一个整数 k,求在 1 到 n 中选取 k 个数字的所有组合方法。 + +### 输入输出样例 + +输入是两个正整数 n 和 k,输出是一个二维数组,表示所有组合方式。 + +``` +Input: n = 4, k = 2 +Output: [[2,4], [3,4], [2,3], [1,2], [1,3], [1,4]] +``` + +这里二维数组的每个维度都可以以任意顺序输出。 + +### 题解 + +类似于排列问题,我们也可以进行回溯。排列回溯的是交换的位置,而组合回溯的是是否把当前的数字加入结果中。 + + + + +```cpp +// 辅函数。 +void backtracking(vector>& combinations, vector& pick, int pos, + int n, int k) { + if (pick.size() == k) { + combinations.push_back(pick); + return; + } + for (int i = pos; i <= n; ++i) { + pick.push_back(i); // 修改当前节点状态 + backtracking(combinations, pick, i + 1, n, k); // 递归子节点 + pick.pop_back(); // 回改当前节点状态 + } +} + +// 主函数。 +vector> combine(int n, int k) { + vector> combinations; + vector pick; + backtracking(combinations, pick, 1, n, k); + return combinations; +} +``` + + + + +```py +# 辅函数。 +def backtracking( + combinations: List[List[int]], pick: List[int], pos: int, n: int, k: int +): + if len(pick) == k: + combinations.append(pick[:]) # int为基本类型,可以浅拷贝 + return + for i in range(pos, n + 1): + pick.append(i) # 修改当前节点状态 + backtracking(combinations, pick, i + 1, n, k) # 递归子节点 + pick.pop() # 回改当前节点状态 + +# 主函数。 +def combine(n: int, k: int) -> List[List[int]]: + combinations = [] + pick = [] + backtracking(combinations, pick, 1, n, k) + return combinations +``` + + + + + +## [79. Word Search](https://leetcode.com/problems/word-search/) + +### 题目描述 + +给定一个字母矩阵,所有的字母都与上下左右四个方向上的字母相连。给定一个字符串,求字符串能不能在字母矩阵中寻找到。 + +### 输入输出样例 + +输入是一个二维字符数组和一个字符串,输出是一个布尔值,表示字符串是否可以被寻找到。 + +``` +Input: word = "ABCCED", board = +[[’A’,’B’,’C’,’E’], + [’S’,’F’,’C’,’S’], + [’A’,’D’,’E’,’E’]] +Output: true +``` + +从左上角的’A’ 开始,我们可以先向右、再向下、最后向左,找到连续的"ABCCED"。 + +### 题解 + +不同于排列组合问题,本题采用的并不是修改输出方式,而是修改访问标记。在我们对任意位置进行深度优先搜索时,我们先标记当前位置为已访问,以避免重复遍历(如防止向右搜索后又向左返回);在所有的可能都搜索完成后,再回改当前位置为未访问,防止干扰其它位置搜索到当前位置。使用回溯法时,我们可以只对一个二维的访问矩阵进行修改,而不用把每次的搜索状态作为一个新对象传入递归函数中。 + + + + + +```cpp +// 辅函数。 +bool backtracking(vector>& board, string& word, + vector>& visited, int i, int j, int word_pos) { + if (i < 0 || i >= board.size() || j < 0 || j >= board[0].size() || + visited[i][j] || board[i][j] != word[word_pos]) { + return false; + } + if (word_pos == word.size() - 1) { + return true; + } + visited[i][j] = true; // 修改当前节点状态 + if (backtracking(board, word, visited, i + 1, j, word_pos + 1) || + backtracking(board, word, visited, i - 1, j, word_pos + 1) || + backtracking(board, word, visited, i, j + 1, word_pos + 1) || + backtracking(board, word, visited, i, j - 1, word_pos + 1)) { + return true; // 递归子节点 + } + visited[i][j] = false; // 回改当前节点状态 + return false; +} + +// 主函数。 +bool exist(vector>& board, string word) { + int m = board.size(), n = board[0].size(); + vector> visited(m, vector(n, false)); + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (backtracking(board, word, visited, i, j, 0)) { + return true; + } + } + } + return false; +} +``` + + + + +```py +# 辅函数。 +def backtracking(board: List[List[str]], word: str, + visited: List[List[bool]], i: int, j: int, word_pos: int): + if (i < 0 or i >= len(board) or j < 0 or j >= len(board[0]) + or visited[i][j] or board[i][j] != word[word_pos]): + return False + if word_pos == len(word) - 1: + return True + visited[i][j] = True # 修改当前节点状态 + if (backtracking(board, word, visited, i + 1, j, word_pos + 1) or + backtracking(board, word, visited, i - 1, j, word_pos + 1) or + backtracking(board, word, visited, i, j + 1, word_pos + 1) or + backtracking(board, word, visited, i, j - 1, word_pos + 1)): + return True # 递归子节点 + visited[i][j] = False # 回改当前节点状态 + return False + +# 主函数。 +def exist(board: List[List[str]], word: str) -> bool: + m, n = len(board), len(board[0]) + visited = [[False for _ in range(n)] for _ in range(m)] + return any([ + backtracking(board, word, visited, i, j, 0) + for i in range(m) for j in range(n) + ]) +``` + + + + + +## [51. N-Queens](https://leetcode.com/problems/n-queens/) + +### 题目描述 + +给定一个大小为 n 的正方形国际象棋棋盘,求有多少种方式可以放置 n 个皇后并使得她们互不攻击,即每一行、列、左斜、右斜最多只有一个皇后。 + +
+![](n-queens.png) +
题目 51 - 八皇后的一种解法
+
+ +### 输入输出样例 + +输入是一个整数 n,输出是一个二维字符串数组,表示所有的棋盘表示方法。 + +``` +Input: 4 +Output: [ + [".Q..", // Solution 1 + "...Q", + "Q...", + "..Q."], + ["..Q.", // Solution 2 + "Q...", + "...Q", + ".Q.."] +] +``` + +在这个样例中,点代表空白位置,Q 代表皇后。 + +### 题解 + +类似于在矩阵中寻找字符串,本题也是通过修改状态矩阵来进行回溯。不同的是,我们需要对每一行、列、左斜、右斜建立访问数组,来记录它们是否存在皇后。这里如果我们通过对每一行/列遍历来插入皇后,我们就不需要对行/列建立访问数组了。 + + + + +```cpp +// 辅函数。 +void backtracking(vector> &solutions, vector &board, + vector &column, vector &ldiag, + vector &rdiag, int row) { + int n = board.size(); + if (row == n) { + solutions.push_back(board); + return; + } + for (int i = 0; i < n; ++i) { + if (column[i] || ldiag[n - row + i - 1] || rdiag[row + i]) { + continue; + } + // 修改当前节点状态。 + board[row][i] = ’Q’; + column[i] = ldiag[n - row + i - 1] = rdiag[row + i] = true; + // 递归子节点。 + backtracking(solutions, board, column, ldiag, rdiag, row + 1); + // 回改当前节点状态。 + board[row][i] = ’.’; + column[i] = ldiag[n - row + i - 1] = rdiag[row + i] = false; + } +} + +// 主函数。 +vector> solveNQueens(int n) { + vector> solutions; + vector board(n, string(n, ’.’)); + vector column(n, false); + vector ldiag(2 * n - 1, false); + vector rdiag(2 * n - 1, false); + backtracking(solutions, board, column, ldiag, rdiag, 0); + return solutions; +} +``` + + + + +```py +# 辅函数。 +def backtracking(solutions: List[List[str]], board: List[List[str]], + column: List[bool], ldiag: List[bool], rdiag: List[bool], row: int): + n = len(board) + if row == n: + solutions.append(["".join(row) for row in board]) + return + for i in range(n): + if column[i] or ldiag[n - row + i - 1] or rdiag[row + i]: + continue + # 修改当前节点状态。 + board[row][i] = "Q" + column[i] = ldiag[n - row + i - 1] = rdiag[row + i] = True + # 递归子节点。 + backtracking(solutions, board, column, ldiag, rdiag, row + 1) + # 回改当前节点状态。 + board[row][i] = "." + column[i] = ldiag[n - row + i - 1] = rdiag[row + i] = False + +# 主函数。 +def solveNQueens(n: int) -> List[List[str]]: + solutions = [] + board = [["." for _ in range(n)] for _ in range(n)] + column = [False] * n + ldiag = [False] * (2 * n - 1) + rdiag = [False] * (2 * n - 1) + backtracking(solutions, board, column, ldiag, rdiag, 0) + return solutions +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/5-searching-algorithms/5-4-breadth-first-search.md b/leetcode_101/docs/5-searching-algorithms/5-4-breadth-first-search.md deleted file mode 100644 index ac39e533..00000000 --- a/leetcode_101/docs/5-searching-algorithms/5-4-breadth-first-search.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -sidebar_position: 24 ---- - -import Tabs from "@theme/Tabs"; -import TabItem from "@theme/TabItem"; - -# 5.4 广度优先搜索 diff --git a/leetcode_101/docs/5-searching-algorithms/5-4-breadth-first-search.mdx b/leetcode_101/docs/5-searching-algorithms/5-4-breadth-first-search.mdx new file mode 100644 index 00000000..bb14e881 --- /dev/null +++ b/leetcode_101/docs/5-searching-algorithms/5-4-breadth-first-search.mdx @@ -0,0 +1,454 @@ +--- +sidebar_position: 24 +--- + +# 5.4 广度优先搜索 + +`广度优先搜索`(breadth-first search,BFS)不同与深度优先搜索,它是一层层进行遍历的,因此`需要用先入先出的队列 (queue)` 而非先入后出的栈 (stack) 进行遍历。由于是按层次进行遍历,广度优先搜索时按照“广”的方向进行遍历的,也常常用来处理最短路径等问题。在 Python 中,我们可以用 collections.deque 来实现 C++ 中的 queue。 + +``` + 1 + / \ + 2 3 + / +4 +``` + +这里要注意,深度优先搜索和广度优先搜索都可以处理`可达性`问题,即从一个节点开始是否能达到另一个节点。因为深度优先搜索可以利用递归快速实现,很多人会习惯使用深度优先搜索刷此类题目。实际软件工程中,笔者很少见到递归的写法,因为一方面难以理解,另一方面可能产生栈溢出的情况;而用栈实现的深度优先搜索和用队列实现的广度优先搜索在写法上并没有太大差异,因此使用哪一种搜索方式需要根据实际的功能需求来判断。另外,如果需要自定义搜索优先级,我们可以利用优先队列,这个我们会在数据结构的章节讲到。 + +## [1091. Shortest Path in Binary Matrix](https://leetcode.com/problems/shortest-path-in-binary-matrix/) + +### 题目描述 + +给定一个二维 0-1 矩阵,其中 1 表示障碍,0 表示道路,每个位置与周围八个格子相连。求从左上角到右下角的最短到达距离。如果没有可以到达的方法,返回-1。 + +### 输入输出样例 + +输入是一个二维整数数组,输出是一个整数,表示最短距离。 + +``` +Input: +[[0,0,1], + [1,1,0], + [1,1,0]] +Output: 4 +``` + +最短到达方法为先向右,拐弯之后再向下。 + +### 题解 + +利用队列,我们可以很直观地利用广度优先搜索,搜索最少扩展层数,即最短到达目的地的距离。注意不要重复搜索相同位置。 + + + + +```cpp +int shortestPathBinaryMatrix(vector>& grid) { + if (grid[0][0] == 1) { + return -1; + } + int m = grid.size(), n = grid[0].size(); + int dist = 0, count; + queue> q; + q.push({0, 0}); + grid[0][0] = -1; // -1表示visited + count = q.size(); + while (count > 0) { + ++dist; + while (count--) { + auto [r, c] = q.front(); + q.pop(); + if (r == m - 1 && c == n - 1) { + return dist; + } + for (int dx = -1; dx <= 1; ++dx) { + for (int dy = -1; dy <= 1; ++dy) { + if (dx == 0 && dy == 0) { + continue; + } + int x = r + dx, y = c + dy; + if (x < 0 || y < 0 || x >= m || y >= n || grid[x][y] != 0) { + continue; + } + grid[x][y] = -1; + q.push({x, y}); + } + } + } + count = q.size(); + } + return -1; +} +``` + + + + +```py +def shortestPathBinaryMatrix(grid: List[List[int]]) -> int: + if grid[0][0] == 1: + return -1 + m, n = len(grid), len(grid[0]) + dist = 0 + q = collections.deque() + q.append((0, 0)) + grid[0][0] = -1 # -1表示visited + count = len(q) + while count > 0: + dist += 1 + while count > 0: + count -= 1 + r, c = q.popleft() + if r == m - 1 and c == n - 1: + return dist + for dx in range(-1, 2): + for dy in range(-1, 2): + if dx == 0 and dy == 0: + continue + x, y = r + dx, c + dy + if x < 0 or y < 0 or x >= m or y >= n or grid[x][y] != 0: + continue + grid[x][y] = -1 + q.append((x, y)) + count = len(q) + return -1 +``` + + + + + +## [934. Shortest Bridge](https://leetcode.com/problems/shortest-bridge/) + +### 题目描述 + +给定一个二维 0-1 矩阵,其中 1 表示陆地,0 表示海洋,每个位置与上下左右相连。已知矩阵中有且只有两个岛屿,求最少要填海造陆多少个位置才可以将两个岛屿相连。 + +### 输入输出样例 + +输入是一个二维整数数组,输出是一个非负整数,表示需要填海造陆的位置数。 + +``` +Input: +[[1,1,1,1,1], + [1,0,0,0,1], + [1,0,1,0,1], + [1,0,0,0,1], + [1,1,1,1,1]] +Output: 1 +``` + +### 题解 + +本题实际上是求两个岛屿间的最短距离,因此我们可以先通过任意搜索方法找到其中一个岛屿,然后利用广度优先搜索,查找其与另一个岛屿的最短距离。这里我们展示利用深度优先搜索查找第一个岛屿。 + + + + + +```cpp +vector direction{-1, 0, 1, 0, -1}; +// 辅函数。 + +void dfs(queue>& points, vector>& grid, int i, + int j) { + int m = grid.size(), n = grid[0].size(); + if (i < 0 || i >= m || j < 0 || j >= n || grid[i][j] == 2) { + return; + } + if (grid[i][j] == 0) { + points.push({i, j}); + return; + } + grid[i][j] = 2; + for (int k = 0; k < 4; ++k) { + dfs(points, grid, i + direction[k], j + direction[k + 1]); + } +} + +// 主函数。 +int shortestBridge(vector>& grid) { + int m = grid.size(), n = grid[0].size(); + queue> points; + // DFS寻找第一个岛屿,并把1全部赋值为2。 + bool flipped = false; + for (int i = 0; i < m && !flipped; ++i) { + for (int j = 0; j < n && !flipped; ++j) { + if (grid[i][j] == 1) { + dfs(points, grid, i, j); + flipped = true; + } + } + } + // BFS寻找第二个岛屿,并把过程中经过的0赋值为2。 + int level = 0; + while (!points.empty()) { + ++level; + int n_points = points.size(); + while (n_points--) { + auto [r, c] = points.front(); + points.pop(); + grid[r][c] = 2; + for (int k = 0; k < 4; ++k) { + int x = r + direction[k], y = c + direction[k + 1]; + if (x >= 0 && x < m && y >= 0 && y < n) { + if (grid[x][y] == 2) { + continue; + } + if (grid[x][y] == 1) { + return level; + } + grid[x][y] = 2; + points.push({x, y}); + } + } + } + } + return 0; +} +``` + + + + +```py +direction = [-1, 0, 1, 0, -1] + +# 辅函数。 +def dfs(points: Deque[Tuple[int, int]], grid: List[List[int]], i: int, j: int): + m, n = len(grid), len(grid[0]) + if i < 0 or i >= m or j < 0 or j >= n or grid[i][j] == 2: + return + if grid[i][j] == 0: + points.append((i, j)) + return + grid[i][j] = 2 + for k in range(4): + dfs(points, grid, i + direction[k], j + direction[k + 1]) + +def shortestBridge(grid: List[List[int]]) -> int: + m, n = len(grid), len(grid[0]) + points = collections.deque() + # DFS寻找第一个岛屿,并把1全部赋值为2。 + flipped = False + for i in range(m): + if flipped: + break + for j in range(n): + if grid[i][j] == 1: + dfs(points, grid, i, j) + flipped = True + break + # BFS寻找第二个岛屿,并把过程中经过的0赋值为2。 + level = 0 + while len(points) > 0: + level += 1 + points_at_current_level = len(points) + for _ in range(points_at_current_level): + r, c = points.popleft() + grid[r][c] = 2 + for k in range(4): + x, y = r + direction[k], c + direction[k + 1] + if x >= 0 and x < m and y >= 0 and y < n: + if grid[x][y] == 2: + continue + if grid[x][y] == 1: + return level + grid[x][y] = 2 + points.append((x, y)) + return level +``` + + + + + +## [126. Word Ladder II](https://leetcode.com/problems/word-ladder-ii/) + +### 题目描述 + +给定一个起始字符串和一个终止字符串,以及一个单词表,求是否可以将起始字符串每次改一个字符,直到改成终止字符串,且所有中间的修改过程表示的字符串都可以在单词表里找到。若存在,输出需要修改次数最少的所有更改方式。 + +### 输入输出样例 + +输入是两个字符串,输出是一个二维字符串数组,表示每种字符串修改方式。 + +``` +Input: beginWord = "hit", endWord = "cog", +wordList = ["hot","dot","dog","lot","log","cog"] +Output: +[["hit","hot","dot","dog","cog"], + ["hit","hot","lot","log","cog"]] +``` + +### 题解 + + +我们可以把起始字符串、终止字符串、以及单词表里所有的字符串想象成节点。若两个字符串只有一个字符不同,那么它们相连。因为题目需要输出修改次数最少的所有修改方式,因此我们可以使用广度优先搜索,求得起始节点到终止节点的最短距离。 + +我们同时还使用了一个小技巧:我们并不是直接从起始节点进行广度优先搜索,直到找到终止节点为止;而是从起始节点和终止节点分别进行广度优先搜索,每次只延展当前层节点数最少的那一端,这样我们可以减少搜索的总结点数。举例来说,假设最短距离为 4,如果我们只从一端搜索 4 层,总遍历节点数最多是 $1 + 2 + 4 + 8 + 16 = 31$;而如果我们从两端各搜索两层,总遍历节点数最多只有 $2 × (1 + 2 + 4) =14$。 + +在搜索结束后,我们还需要通过回溯法来重建所有可能的路径。 + +这道题略微复杂,需要读者耐心思考和实现代码。LeetCode 对于本题的时间要求非常严格,即使是官方题解也经常容易超时,可以尝试多次提交。 + + + + +```cpp +// 辅函数。 +void backtracking(const string &src, const string &dst, + unordered_map> &next_words, + vector &path, vector> &ladder) { + if (src == dst) { + ladder.push_back(path); + return; + } + if (!next_words.contains(src)) { + return; + } + for (const auto &w : next_words[src]) { + path.push_back(w); // 修改当前节点状态 + backtracking(w, dst, next_words, path, ladder); // 递归子节点 + path.pop_back(); // 回改当前节点状态 + } +} + +// 主函数。 +vector> findLadders(string beginWord, string endWord, + vector &wordList) { + vector> ladder; + // 用哈希集合存储字典,方便查找。 + unordered_set word_dict; + for (const auto &w : wordList) { + word_dict.insert(w); + } + if (!word_dict.contains(endWord)) { + return ladder; + } + word_dict.erase(beginWord); + word_dict.erase(endWord); + // 建立两个queue,从beginWord和endWord同时延展,每次延展最小的。 + // 因为之后的去重操作需要遍历queue,我们这里用哈希表实现它, + // 只要保证是分层次遍历即可。 + unordered_set q_small{beginWord}, q_large{endWord}; + unordered_map> next_words; + bool reversed_path = false, found_path = false; + while (!q_small.empty()) { + unordered_set q; + for (const auto &w : q_small) { + string s = w; + for (int i = 0; i < s.size(); ++i) { + for (int j = 0; j < 26; ++j) { + s[i] = j + ’a’; + if (q_large.contains(s)) { + reversed_path ? next_words[s].push_back(w) + : next_words[w].push_back(s); + found_path = true; + } + if (word_dict.contains(s)) { + reversed_path ? next_words[s].push_back(w) + : next_words[w].push_back(s); + q.insert(s); + } + } + s[i] = w[i]; + } + } + if (found_path) { + break; + } + // 环路一定不是最短解,所以这里需要去重和避免无限循环。 + for (const auto &w : q) { + word_dict.erase(w); + } + // 更新两个queue,并维持大小关系。 + if (q.size() <= q_large.size()) { + q_small = q; + } else { + reversed_path = !reversed_path; + q_small = q_large; + q_large = q; + } + } + if (found_path) { + vector path{beginWord}; + backtracking(beginWord, endWord, next_words, path, ladder); + } + return ladder; +} +``` + + + + +```py +# 辅函数。 +def backtracking(src: str, dst: str, next_words: Dict[str, List[str]], + path: List[str], ladder: List[List[str]]): + if src == dst: + ladder.append(path[:]) + return + if src not in next_words: + return + for w in next_words[src]: + path.append(w) # 修改当前节点状态 + backtracking(w, dst, next_words, path, ladder) # 递归子节点 + path.pop() # 回改当前节点状态 + +# 主函数。 +def findLadders(beginWord: str, endWord: str, + wordList: List[str]) -> List[List[str]]: + ladder = [] + # 用哈希集合存储字典,方便查找。 + word_dict = set(wordList) + if endWord not in word_dict: + return ladder + word_dict = word_dict.difference(set([beginWord, endWord])) + # 建立两个queue,从beginWord和endWord同时延展,每次延展最小的。 + # 因为之后的去重操作需要遍历queue,我们这里用哈希表实现它, + # 只要保证是分层次遍历即可。 + q_small, q_large = set([beginWord]), set([endWord]) + next_words = dict() + reversed_path, found_path = False, False + while len(q_small) > 0: + q = set() + for w in q_small: + for i in range(len(w)): + for j in range(26): + s = w[:i] + chr(ord("a") + j) + w[i + 1:] + if s in q_large: + if reversed_path: + next_words[s] = next_words.get(s, []) + [w] + else: + next_words[w] = next_words.get(w, []) + [s] + found_path = True + if s in word_dict: + if reversed_path: + next_words[s] = next_words.get(s, []) + [w] + else: + next_words[w] = next_words.get(w, []) + [s] + q.add(s) + if found_path: + break + # 环路一定不是最短解,所以这里需要去重和避免无限循环。 + word_dict = word_dict.difference(q) + # 更新两个queue,并维持大小关系。 + if len(q) <= len(q_large): + q_small = q + else: + reversed_path = not reversed_path + q_small = q_large + q_large = q + + if found_path: + path = [beginWord] + backtracking(beginWord, endWord, next_words, path, ladder) + return ladder + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/5-searching-algorithms/5-5-exercises.md b/leetcode_101/docs/5-searching-algorithms/5-5-exercises.md index 0a9bdce0..1922b36d 100644 --- a/leetcode_101/docs/5-searching-algorithms/5-5-exercises.md +++ b/leetcode_101/docs/5-searching-algorithms/5-5-exercises.md @@ -3,3 +3,31 @@ sidebar_position: 25 --- # 5.5 练习 + +## 基础难度 + +### [130. Surrounded Regions](https://leetcode.com/problems/surrounded-regions/) + +先从最外侧填充,然后再考虑里侧。 + +### [257. Binary Tree Paths](https://leetcode.com/problems/binary-tree-paths/) + +输出二叉树中所有从根到叶子的路径,回溯法使用与否有什么区别? + +## 进阶难度 + +### [47. Permutations II](https://leetcode.com/problems/permutations-ii/) + +排列题的 follow-up,如何处理重复元素? + +### [40. Combination Sum II](https://leetcode.com/problems/combination-sum-ii/) + +组合题的 follow-up,如何处理重复元素? + +### [37. Sudoku Solver](https://leetcode.com/problems/sudoku-solver/) + +十分经典的数独题,可以利用回溯法求解。事实上对于数独类型的题,有很多进阶的搜索方法和剪枝策略可以提高速度,如启发式搜索。 + +### [310. Minimum Height Trees](https://leetcode.com/problems/minimum-height-trees/) + +如何将这道题转为搜索类型题?是使用深度优先还是广度优先呢? \ No newline at end of file diff --git a/leetcode_101/docs/5-searching-algorithms/_category_.json b/leetcode_101/docs/5-searching-algorithms/_category_.json index ccb8696c..0943e8c5 100644 --- a/leetcode_101/docs/5-searching-algorithms/_category_.json +++ b/leetcode_101/docs/5-searching-algorithms/_category_.json @@ -3,6 +3,6 @@ "position": 5, "link": { "type": "generated-index", - "description": "5 minutes to learn the most important Docusaurus concepts." + "description": "第 5 章 一切皆可搜索" } } diff --git a/leetcode_101/docs/5-searching-algorithms/n-queens.png b/leetcode_101/docs/5-searching-algorithms/n-queens.png new file mode 100644 index 0000000000000000000000000000000000000000..f6ea07555d6478e73b50fe428dcee9ab366cbd98 GIT binary patch literal 20347 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 literal 0 HcmV?d00001 From 815f79f74db6522c9fdb7348c51d26303b51fde8 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Wed, 13 Nov 2024 21:05:35 +0100 Subject: [PATCH 08/49] add cover pic --- leetcode_101/docs/index.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/leetcode_101/docs/index.md b/leetcode_101/docs/index.md index 4acbcaa1..676d12f9 100644 --- a/leetcode_101/docs/index.md +++ b/leetcode_101/docs/index.md @@ -4,6 +4,8 @@ sidebar_position: 0 # 0. LeetCode 101: 力扣刷题指南 (第二版) +![](https://github.com/changgyhub/leetcode_101/blob/master/misc/cover.jpg?raw=true) + 作者:高畅 Chang Gao 语言:C++ & Python From 0e13c07437535d313ba3b36115eb1a52ba99b129 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Wed, 13 Nov 2024 22:34:57 +0100 Subject: [PATCH 09/49] chapter 6 --- .../6-1-algorithm-explanation.md | 8 + .../6-dynamic-programming/6-2-basic-dp-1d.md | 8 - .../6-dynamic-programming/6-2-basic-dp-1d.mdx | 236 ++++++++++ .../6-dynamic-programming/6-3-basic-dp-2d.md | 8 - .../6-dynamic-programming/6-3-basic-dp-2d.mdx | 307 +++++++++++++ .../6-4-partition-problems.md | 5 - .../6-4-partition-problems.mdx | 347 +++++++++++++++ .../6-5-subsequence-problems.md | 5 - .../6-5-subsequence-problems.mdx | 189 ++++++++ .../6-6-knapsack-problem.md | 5 - .../6-6-knapsack-problem.mdx | 421 ++++++++++++++++++ .../6-7-string-editing.md | 5 - .../6-7-string-editing.mdx | 132 ++++++ .../6-8-stock-trading.md | 5 - .../6-8-stock-trading.mdx | 183 ++++++++ .../6-dynamic-programming/6-9-exercises.md | 40 ++ .../docs/6-dynamic-programming/6.1.png | Bin 0 -> 34632 bytes .../docs/6-dynamic-programming/6.3.png | Bin 0 -> 24349 bytes .../docs/6-dynamic-programming/6.4.png | Bin 0 -> 38325 bytes .../docs/6-dynamic-programming/6.5.png | Bin 0 -> 49000 bytes .../6-dynamic-programming/_category_.json | 2 +- 21 files changed, 1864 insertions(+), 42 deletions(-) delete mode 100644 leetcode_101/docs/6-dynamic-programming/6-2-basic-dp-1d.md create mode 100644 leetcode_101/docs/6-dynamic-programming/6-2-basic-dp-1d.mdx delete mode 100644 leetcode_101/docs/6-dynamic-programming/6-3-basic-dp-2d.md create mode 100644 leetcode_101/docs/6-dynamic-programming/6-3-basic-dp-2d.mdx delete mode 100644 leetcode_101/docs/6-dynamic-programming/6-4-partition-problems.md create mode 100644 leetcode_101/docs/6-dynamic-programming/6-4-partition-problems.mdx delete mode 100644 leetcode_101/docs/6-dynamic-programming/6-5-subsequence-problems.md create mode 100644 leetcode_101/docs/6-dynamic-programming/6-5-subsequence-problems.mdx delete mode 100644 leetcode_101/docs/6-dynamic-programming/6-6-knapsack-problem.md create mode 100644 leetcode_101/docs/6-dynamic-programming/6-6-knapsack-problem.mdx delete mode 100644 leetcode_101/docs/6-dynamic-programming/6-7-string-editing.md create mode 100644 leetcode_101/docs/6-dynamic-programming/6-7-string-editing.mdx delete mode 100644 leetcode_101/docs/6-dynamic-programming/6-8-stock-trading.md create mode 100644 leetcode_101/docs/6-dynamic-programming/6-8-stock-trading.mdx create mode 100644 leetcode_101/docs/6-dynamic-programming/6.1.png create mode 100644 leetcode_101/docs/6-dynamic-programming/6.3.png create mode 100644 leetcode_101/docs/6-dynamic-programming/6.4.png create mode 100644 leetcode_101/docs/6-dynamic-programming/6.5.png diff --git a/leetcode_101/docs/6-dynamic-programming/6-1-algorithm-explanation.md b/leetcode_101/docs/6-dynamic-programming/6-1-algorithm-explanation.md index 221ac667..48055183 100644 --- a/leetcode_101/docs/6-dynamic-programming/6-1-algorithm-explanation.md +++ b/leetcode_101/docs/6-dynamic-programming/6-1-algorithm-explanation.md @@ -3,3 +3,11 @@ sidebar_position: 26 --- # 6.1 算法解释 + +这里我们引用一下维基百科的描述:“`动态规划`(Dynamic Programming, DP)在查找有很多`重叠子问题`的情况的最优解时有效。它将问题重新组合成子问题。为了避免多次解决这些子问题,它们的结果都逐渐被计算并被保存,从简单的问题直到整个问题都被解决。因此,动态规划保存递归时的结果,因而不会在解决同样的问题时花费时间 · · · · · · 动态规划只能应用于有`最优子结构`的问题。最优子结构的意思是局部最优解能决定全局最优解(对有些问题这个要求并不能完全满足,故有时需要引入一定的近似)。简单地说,问题能够分解成子问题来解决。” + +通俗一点来讲,动态规划和其它遍历算法(如深/广度优先搜索)都是将原问题拆成多个子问题然后求解,他们之间最本质的区别是,动态规划`保存子问题的解,避免重复计算`。解决动态规划问题的关键是找到`状态转移方程`,这样我们可以通过计算和储存子问题的解来求解最终问题。 + +同时,我们也可以对动态规划进行`空间压缩`,起到节省空间消耗的效果。这一技巧笔者将在之后的题目中介绍。 + +在一些情况下,动态规划可以看成是带有`状态记录`(memoization)的优先搜索。状态记录的意思为,如果一个子问题在优先搜索时已经计算过一次,我们可以把它的结果储存下来,之后遍历到该子问题的时候可以直接返回储存的结果。动态规划是自下而上的,即先解决子问题,再解决父问题;而用带有状态记录的优先搜索是自上而下的,即从父问题搜索到子问题,若重复搜索到同一个子问题则进行状态记录,防止重复计算。如果题目需求的是最终状态,那么使用动态搜索比较方便;如果题目需要输出所有的路径,那么使用带有状态记录的优先搜索会比较方便。 \ No newline at end of file diff --git a/leetcode_101/docs/6-dynamic-programming/6-2-basic-dp-1d.md b/leetcode_101/docs/6-dynamic-programming/6-2-basic-dp-1d.md deleted file mode 100644 index 5a74efdf..00000000 --- a/leetcode_101/docs/6-dynamic-programming/6-2-basic-dp-1d.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -sidebar_position: 27 ---- - -import Tabs from "@theme/Tabs"; -import TabItem from "@theme/TabItem"; - -# 6.2 基本动态规划:一维 diff --git a/leetcode_101/docs/6-dynamic-programming/6-2-basic-dp-1d.mdx b/leetcode_101/docs/6-dynamic-programming/6-2-basic-dp-1d.mdx new file mode 100644 index 00000000..e5d96da3 --- /dev/null +++ b/leetcode_101/docs/6-dynamic-programming/6-2-basic-dp-1d.mdx @@ -0,0 +1,236 @@ +--- +sidebar_position: 27 +--- + +# 6.2 基本动态规划:一维 + +## [70. Climbing Stairs](https://leetcode.com/problems/climbing-stairs/) + +### 题目描述 + +给定 $n$ 节台阶,每次可以走一步或走两步,求一共有多少种方式可以走完这些台阶。 + +### 输入输出样例 + +输入是一个数字,表示台阶数量;输出是爬台阶的总方式。 + +``` +Input: 3 +Output: 3 +``` + +在这个样例中,一共有三种方法走完这三节台阶:每次走一步;先走一步,再走两步;先走两步,再走一步。 + +### 题解 + +这是十分经典的斐波那契数列题。定义一个数组 dp,dp[i] 表示走到第 i 阶的方法数。因为我们每次可以走一步或者两步,所以第 i 阶可以从第 i-1 或 i-2 阶到达。换句话说,走到第 i 阶的方法数即为走到第 i-1 阶的方法数加上走到第 i-2 阶的方法数。这样我们就得到了状态转移方程 dp[i] = dp[i-1] + dp[i-2]。注意边界条件的处理。 + +:::warning + +有的时候为了方便处理边界情况,我们可以在构造 dp 数组时多留一个位置,用来处理初始状态。本题即多留了一个第 0 阶的初始位置。 + +::: + + + + +```cpp +int climbStairs(int n) { + vector dp(n + 1, 1); + for (int i = 2; i <= n; ++i) { + dp[i] = dp[i - 1] + dp[i - 2]; + } + return dp[n]; +} +``` + + + + +```py +def climbStairs(n: int) -> int: + dp = [1] * (n + 1) + for i in range(2, n + 1): + dp[i] = dp[i - 1] + dp[i - 2] + return dp[n] +``` + + + + + +进一步的,我们可以对动态规划进行空间压缩。因为 dp[i] 只与 dp[i-1] 和 dp[i-2] 有关,因此可以只用两个变量来存储 dp[i-1] 和 dp[i-2],使得原来的 $O(n)$ 空间复杂度优化为 $O(1)$ 复杂度。 + + + + +```cpp +int climbStairs(int n) { + int prev_prev = 1, prev = 1, cur = 1; + for (int i = 2; i <= n; ++i) { + cur = prev_prev + prev; + prev_prev = prev; + prev = cur; + } + return cur; +} +``` + + + + +```py +def climbStairs(n: int) -> int: + prev_prev = prev = cur = 1 + for _ in range(2, n + 1): + cur = prev_prev + prev + prev_prev = prev + prev = cur + return cur +``` + + + + + + +## [198. House Robber](https://leetcode.com/problems/house-robber/) + +### 题目描述 + +假如你是一个劫匪,并且决定抢劫一条街上的房子,每个房子内的钱财数量各不相同。如果你抢了两栋相邻的房子,则会触发警报机关。求在不触发机关的情况下最多可以抢劫多少钱。 + +### 输入输出样例 + +输入是一个一维数组,表示每个房子的钱财数量;输出是劫匪可以最多抢劫的钱财数量。 + +``` +Input: [2,7,9,3,1] +Output: 12 +``` + +在这个样例中,最多的抢劫方式为抢劫第 1、3、5 个房子。 + +### 题解 + +定义一个数组 dp,dp[i] 表示抢劫到第 i 个房子时,可以抢劫的最大数量。我们考虑 dp[i],此时可以抢劫的最大数量有两种可能,一种是我们选择不抢劫这个房子,此时累计的金额即为 dp[i-1];另一种是我们选择抢劫这个房子,那么此前累计的最大金额只能是 dp[i-2],因为我们不能够抢劫第 i-1 个房子,否则会触发警报机关。因此本题的状态转移方程为 dp[i] = max(dp[i-1], nums[i-1] + dp[i-2])。 + + + + +```cpp +int rob(vector& nums) { + int n = nums.size(); + vector dp(n + 1, 0); + dp[1] = nums[0]; + for (int i = 2; i <= n; ++i) { + dp[i] = max(dp[i - 1], nums[i - 1] + dp[i - 2]); + } + return dp[n]; +} +``` + + + + +```py +def rob(nums: List[int]) -> int: + n = len(nums) + dp = [0] * (n + 1) + dp[1] = nums[0] + for i in range(2, n + 1): + dp[i] = max(dp[i - 1], nums[i - 1] + dp[i - 2]) + return dp[n] +``` + + + + + +同样的,我们可以像题目 70 那样,对空间进行压缩。 + + + + +```cpp +int rob(vector& nums) { + int prev_prev = 0, prev = 0, cur = 0; + for (int i = 0; i < nums.size(); ++i) { + cur = max(prev_prev + nums[i], prev); + prev_prev = prev; + prev = cur; + } + return cur; +} +``` + + + + +```py +def rob(nums: List[int]) -> int: + prev_prev = prev = cur = 0 + for i in range(len(nums)): + cur = max(prev_prev + nums[i], prev) + prev_prev = prev + prev = cur + return cur +``` + + + + + +## [413. Arithmetic Slices](https://leetcode.com/problems/arithmetic-slices/) + +### 题目描述 + +给定一个数组,求这个数组中连续且等差的子数组一共有多少个。 + +### 输入输出样例 + +输入是一个一维数组,输出是满足等差条件的连续子数组个数。 + +``` +Input: nums = [1,2,3,4] +Output: 3 +``` + +在这个样例中,等差数列有 [1,2,3]、[2,3,4] 和 [1,2,3,4]。 + +### 题解 + +因为要求是等差数列,可以很自然地想到子数组必定满足 num[i] - num[i-1] = num[i-1] - num[i-2]。这里我们对于 dp 数组的定义是以 i 结尾的,满足该条件的子数组数量。因为等差子数组可以在任意一个位置终结,所以我们需要对 dp 数组求和进行子数组统计。 + + + + +```cpp +int numberOfArithmeticSlices(vector& nums) { + int n = nums.size(); + vector dp(n, 0); + for (int i = 2; i < n; ++i) { + if (nums[i] - nums[i - 1] == nums[i - 1] - nums[i - 2]) { + dp[i] = dp[i - 1] + 1; + } + } + return accumulate(dp.begin(), dp.end(), 0); +} +``` + + + + +```py +def numberOfArithmeticSlices(nums: List[int]) -> int: + n = len(nums) + dp = [0] * n + for i in range(2, n): + if nums[i] - nums[i - 1] == nums[i - 1] - nums[i - 2]: + dp[i] = dp[i - 1] + 1 + return sum(dp) +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/6-dynamic-programming/6-3-basic-dp-2d.md b/leetcode_101/docs/6-dynamic-programming/6-3-basic-dp-2d.md deleted file mode 100644 index 35b57ebe..00000000 --- a/leetcode_101/docs/6-dynamic-programming/6-3-basic-dp-2d.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -sidebar_position: 28 ---- - -import Tabs from "@theme/Tabs"; -import TabItem from "@theme/TabItem"; - -# 6.3 基本动态规划:二维 diff --git a/leetcode_101/docs/6-dynamic-programming/6-3-basic-dp-2d.mdx b/leetcode_101/docs/6-dynamic-programming/6-3-basic-dp-2d.mdx new file mode 100644 index 00000000..02a85a91 --- /dev/null +++ b/leetcode_101/docs/6-dynamic-programming/6-3-basic-dp-2d.mdx @@ -0,0 +1,307 @@ +--- +sidebar_position: 28 +--- + +# 6.3 基本动态规划:二维 + +## [64. Minimum Path Sum](https://leetcode.com/problems/minimum-path-sum/) + +### 题目描述 + +给定一个 $m × n$ 大小的非负整数矩阵,求从左上角开始到右下角结束的、经过的数字的和最 +小的路径。每次只能向右或者向下移动。 + +### 输入输出样例 + +输入是一个二维数组,输出是最优路径的数字和。 + +``` +Input: +[[1,3,1], + [1,5,1], + [4,2,1]] +Output: 7 +``` + +在这个样例中,最短路径为 1->3->1->1->1。 + +### 题解 + +我们可以定义一个同样是二维的 dp 数组,其中 dp[i][j] 表示从左上角开始到 (i, j) 位置的最优路径的数字和。因为每次只能向下或者向右移动,我们可以很直观地得到状态转移方程 dp[i][j] = grid[i][j] + min(dp[i-1][j], dp[i][j-1]),其中 grid 表示原数组。 + +:::warning + +Python 语言中,多维数组多初始化比较特殊,直接初始化为 [[val] * n] * m 会导致只是创造了 m 个 [[val] * n] 的引用。正确的初始化方法为 [[val for _ in range(n)] for _ in range(m)]。 + +::: + + + + +```cpp +int minPathSum(vector>& grid) { + int m = grid.size(), n = grid[0].size(); + vector> dp(m, vector(n, 0)); + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (i == 0 && j == 0) { + dp[i][j] = grid[i][j]; + } else if (i == 0) { + dp[i][j] = grid[i][j] + dp[i][j - 1]; + } else if (j == 0) { + dp[i][j] = grid[i][j] + dp[i - 1][j]; + } else { + dp[i][j] = grid[i][j] + min(dp[i - 1][j], dp[i][j - 1]); + } + } + } + return dp[m - 1][n - 1]; +} +``` + + + + +```py +def minPathSum(grid: List[List[int]]) -> int: + m, n = len(grid), len(grid[0]) + dp = [[0 for _ in range(n)] for _ in range(m)] + for i in range(m): + for j in range(n): + if i == j == 0: + dp[i][j] = grid[i][j] + elif i == 0: + dp[i][j] = grid[i][j] + dp[i][j - 1] + elif j == 0: + dp[i][j] = grid[i][j] + dp[i - 1][j] + else: + dp[i][j] = grid[i][j] + min(dp[i][j - 1], dp[i - 1][j]) + return dp[m - 1][n - 1] +``` + + + + + +因为 dp 矩阵的每一个值只和左边和上面的值相关,我们可以使用空间压缩将 dp 数组压缩为一维。对于第 i 行,在遍历到第 j 列的时候,因为第 j-1 列已经更新过了,所以 dp[j-1] 代表 dp[i][j-1]的值;而 dp[j] 待更新,当前存储的值是在第 i-1 行的时候计算的,所以代表 dp[i-1][j] 的值。 + +:::warning + +如果不是很熟悉空间压缩技巧,笔者推荐您优先尝试写出非空间压缩的解法,如果时间充裕且力所能及再进行空间压缩。 + +::: + + + + + + +```cpp +int minPathSum(vector>& grid) { + int m = grid.size(), n = grid[0].size(); + vector dp(n, 0); + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (i == 0 && j == 0) { + dp[j] = grid[i][j]; + } else if (i == 0) { + dp[j] = grid[i][j] + dp[j - 1]; + } else if (j == 0) { + dp[j] = grid[i][j] + dp[j]; + } else { + dp[j] = grid[i][j] + min(dp[j], dp[j - 1]); + } + } + } + return dp[n - 1]; +} +``` + + + + +```py +def minPathSum(grid: List[List[int]]) -> int: + m, n = len(grid), len(grid[0]) + dp = [0 for _ in range(n)] + for i in range(m): + for j in range(n): + if i == j == 0: + dp[j] = grid[i][j] + elif i == 0: + dp[j] = grid[i][j] + dp[j - 1] + elif j == 0: + dp[j] = grid[i][j] + dp[j] + else: + dp[j] = grid[i][j] + min(dp[j - 1], dp[j]) + return dp[n - 1] +``` + + + + + + +## [542. 01 Matrix](https://leetcode.com/problems/01-matrix/) + +### 题目描述 + +给定一个由 0 和 1 组成的二维矩阵,求每个位置到最近的 0 的距离。 + +### 输入输出样例 + +输入是一个二维 0-1 数组,输出是一个同样大小的非负整数数组,表示每个位置到最近的 0 的距离。 + +``` +Input: +[[0,0,0], + [0,1,0], + [1,1,1]] + +Output: +[[0,0,0], + [0,1,0], + [1,2,1]] +``` + +### 题解 + +一般来说,因为这道题涉及到四个方向上的最近搜索,所以很多人的第一反应可能会是广度优先搜索。但是对于一个大小 $O(mn)$ 的二维数组,对每个位置进行四向搜索,最坏情况的时间复杂度(即全是 1)会达到恐怖的 $O(m^2n^2)$。一种办法是使用一个二维布尔值数组做 memoization,使得广度优先搜索不会重复遍历相同位置;另一种更简单的方法是,我们从左上到右下进行一次动态搜索,再从右下到左上进行一次动态搜索。两次动态搜索即可完成四个方向上的查找。 + + + + + +```cpp +vector> updateMatrix(vector>& matrix) { + int m = matrix.size(), n = matrix[0].size(); + vector> dp(m, vector(n, numeric_limits::max() - 1)); + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (matrix[i][j] != 0) { + if (i > 0) { + dp[i][j] = min(dp[i][j], dp[i - 1][j] + 1); + } + if (j > 0) { + dp[i][j] = min(dp[i][j], dp[i][j - 1] + 1); + } + } else { + dp[i][j] = 0; + } + } + } + for (int i = m - 1; i >= 0; --i) { + for (int j = n - 1; j >= 0; --j) { + if (matrix[i][j] != 0) { + if (i < m - 1) { + dp[i][j] = min(dp[i][j], dp[i + 1][j] + 1); + } + if (j < n - 1) { + dp[i][j] = min(dp[i][j], dp[i][j + 1] + 1); + } + } + } + } + return dp; +} +``` + + + + +```py +def updateMatrix(matrix: List[List[int]]) -> List[List[int]]: + m, n = len(matrix), len(matrix[0]) + dp = [[sys.maxsize - 1 for _ in range(n)] for _ in range(m)] + for i in range(m): + for j in range(n): + if matrix[i][j] != 0: + if i > 0: + dp[i][j] = min(dp[i][j], dp[i - 1][j] + 1) + if j > 0: + dp[i][j] = min(dp[i][j], dp[i][j - 1] + 1) + else: + dp[i][j] = 0 + for i in range(m - 1, -1, -1): # m-1 to 0, reversed + for j in range(n - 1, -1, -1): # n-1 to 0, reversed + if matrix[i][j] != 0: + if i < m - 1: + dp[i][j] = min(dp[i][j], dp[i + 1][j] + 1) + if j < n - 1: + dp[i][j] = min(dp[i][j], dp[i][j + 1] + 1) + return dp +``` + + + + + +## [221. Maximal Square](https://leetcode.com/problems/maximal-square/) + +### 题目描述 + +给定一个二维的 0-1 矩阵,求全由 1 构成的最大正方形面积。 + +### 输入输出样例 + +输入是一个二维 0-1 数组,输出是最大正方形面积。 + +``` +Input: +[["1","0","1","0","0"], + ["1","0","1","1","1"], + ["1","1","1","1","1"], + ["1","0","0","1","0"]] +Output: 4 +``` + +### 题解 + +对于在矩阵内搜索正方形或长方形的题型,一种常见的做法是定义一个二维 dp 数组,其中 dp[i][j] 表示满足题目条件的、以 (i, j) 为右下角的正方形或者长方形的属性。对于本题,则表示以 (i, j) 为右下角的全由 1 构成的最大正方形边长。如果当前位置是 0,那么 dp[i][j] 即为 0;如果当前位置是 1,我们假设 dp[i][j] = k,其充分条件为 dp[i-1][j-1]、dp[i][j-1] 和 dp[i-1][j] 的值必须都不小于 k − 1,否则 (i, j) 位置不可以构成一个面积为 $k^2$ 的正方形。同理,如果这三个值中的的最小值为 k − 1,则 (i, j) 位置一定且最大可以构成一个面积为 $k^2$ 的正方形。 + + +

+ + ![](6.1.png) + +
图 6.1: 题目 542 - 左边为一个 0-1 矩阵,右边为其对应的 dp 矩阵,我们可以发现最大的正方形边长为 3
+
+ + + + +```cpp +int maximalSquare(vector>& matrix) { + int m = matrix.size(), n = matrix[0].size(); + int max_side = 0; + vector> dp(m + 1, vector(n + 1, 0)); + for (int i = 1; i <= m; ++i) { + for (int j = 1; j <= n; ++j) { + if (matrix[i - 1][j - 1] == ’1’) { + dp[i][j] = + min(dp[i - 1][j - 1], min(dp[i][j - 1], dp[i - 1][j])) + 1; + } + max_side = max(max_side, dp[i][j]); + } + } + return max_side * max_side; +} +``` + + + + +```py +def maximalSquare(matrix: List[List[str]]) -> int: + m, n = len(matrix), len(matrix[0]) + dp = [[0 for _ in range(n + 1)] for _ in range(m + 1)] + for i in range(1, m + 1): + for j in range(1, n + 1): + if matrix[i - 1][j - 1] == "1": + dp[i][j] = min(dp[i - 1][j - 1], dp[i][j - 1], dp[i - 1][j]) + 1 + return max(max(row) for row in dp) ** 2 +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/6-dynamic-programming/6-4-partition-problems.md b/leetcode_101/docs/6-dynamic-programming/6-4-partition-problems.md deleted file mode 100644 index 0d35ede6..00000000 --- a/leetcode_101/docs/6-dynamic-programming/6-4-partition-problems.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 29 ---- - -# 6.4 分割类型题 diff --git a/leetcode_101/docs/6-dynamic-programming/6-4-partition-problems.mdx b/leetcode_101/docs/6-dynamic-programming/6-4-partition-problems.mdx new file mode 100644 index 00000000..59d3b6b9 --- /dev/null +++ b/leetcode_101/docs/6-dynamic-programming/6-4-partition-problems.mdx @@ -0,0 +1,347 @@ +--- +sidebar_position: 29 +--- + +# 6.4 分割类型题 + +## [279. Perfect Squares](https://leetcode.com/problems/perfect-squares/) + +### 题目描述 + +给定一个正整数,求其最少可以由几个完全平方数相加构成。 + +### 输入输出样例 + +输入是给定的正整数,输出也是一个正整数,表示输入的数字最少可以由几个完全平方数相加构成。 + +``` +Input: n = 13 +Output: 2 +``` + +在这个样例中,13 的最少构成方法为 4+9。 + +### 题解 + +对于分割类型题,动态规划的状态转移方程通常并不依赖相邻的位置,而是依赖于满足分割条件的位置。我们定义一个一维矩阵 dp,其中 dp[i] 表示数字 i 最少可以由几个完全平方数相加构成。在本题中,位置 i 只依赖 $i - j^2$ 的位置,如 i - 1、i - 4、i - 9 等等,才能满足完全平方分割的条件。因此 dp[i] 可以取的最小值即为 1+ min(dp[i-1], dp[i-4], dp[i-9] · · · )。注意边界条件的处理。 + + + + +```cpp +int numSquares(int n) { + vector dp(n + 1, numeric_limits::max()); + dp[0] = 0; + for (int i = 1; i <= n; ++i) { + for (int j = 1; j * j <= i; ++j) { + dp[i] = min(dp[i], dp[i - j * j] + 1); + } + } + return dp[n]; +} +``` + + + + +```py +def numSquares(n: int) -> int: + dp = [0] + [sys.maxsize] * n + for i in range(1, n + 1): + for j in range(1, int(floor(sqrt(i))) + 1): + dp[i] = min(dp[i], dp[i - j * j] + 1) + return dp[n] +``` + + + + + +## [91. Decode Ways](https://leetcode.com/problems/decode-ways/) + +### 题目描述 + +已知字母 A-Z 可以表示成数字 1-26。给定一个数字串,求有多少种不同的字符串等价于这个数字串。 + +### 输入输出样例 + +输入是一个由数字组成的字符串,输出是满足条件的解码方式总数。 + +``` +Input: "226" +Output: 3 +``` + +在这个样例中,有三种解码方式:BZ(2 26)、VF(22 6) 或 BBF(2 2 6)。 + +### 题解 + +这是一道很经典的动态规划题,难度不大但是十分考验耐心。这是因为只有 1-26 可以表示字母,因此对于一些特殊情况,比如数字 0 或者当相邻两数字大于 26 时,需要有不同的状态转移方程,详见如下代码。 + + + + +```cpp +int numDecodings(string s) { + int n = s.length(); + int prev = s[0] - ’0’; + if (prev == 0) { + return 0; + } + if (n == 1) { + return 1; + } + vector dp(n + 1, 1); + for (int i = 2; i <= n; ++i) { + int cur = s[i - 1] - ’0’; + if ((prev == 0 || prev > 2) && cur == 0) { + // 00, 30, 40, ..., 90, 非法。 + return 0; + } + if ((prev < 2 && prev > 0) || (prev == 2 && cur <= 6)) { + // 10, 11, ..., 25, 26. + if (cur == 0) { + // 10, 20,只能连续解码两位。 + dp[i] = dp[i - 2]; + } else { + // 可以解码当前位,也可以连续解码两位。 + dp[i] = dp[i - 2] + dp[i - 1]; + } + } else { + // 合法,但只能解码当前位。 + dp[i] = dp[i - 1]; + } + prev = cur; + } + return dp[n]; +} +``` + + + + +```py +def numDecodings(s: str) -> int: + n = len(s) + prev = ord(s[0]) - ord("0") + if prev == 0: + return 0 + if n == 1: + return 1 + dp = [1] * (n + 1) + for i in range(2, n + 1): + cur = ord(s[i - 1]) - ord("0") + if (prev == 0 or prev > 2) and cur == 0: + # 00, 30, 40, ..., 90, 非法。 + return 0 + if 0 < prev < 2 or (prev == 2 and cur <= 6): + # 10, 11, ..., 25, 26. + if cur == 0: + # 10, 20,只能连续解码两位。 + dp[i] = dp[i - 2] + else: + # 可以解码当前位,也可以连续解码两位。 + dp[i] = dp[i - 2] + dp[i - 1] + else: + # 合法,但只能解码当前位。 + dp[i] = dp[i - 1] + prev = cur + return dp[n] +``` + + + + + +## [139. Word Break](https://leetcode.com/problems/word-break/) + +### 题目描述 + +给定一个字符串和一个字符串集合,求是否存在一种分割方式,使得原字符串分割后的子字符串都可以在集合内找到。 + +### 输入输出样例 + +``` +Input: s = "applepenapple", wordDict = ["apple", "pen"] +Output: true +``` + +在这个样例中,字符串可以被分割为 [“apple”,“pen”,“apple”]。 + +### 题解 + +类似于完全平方数分割问题,这道题的分割条件由集合内的字符串决定,因此在考虑每个分割位置时,需要遍历字符串集合,以确定当前位置是否可以成功分割。注意对于位置 0,需要初始化值为真。 + + + + +```cpp +bool wordBreak(string s, vector& wordDict) { + int n = s.length(); + vector dp(n + 1, false); + dp[0] = true; + for (int i = 1; i <= n; ++i) { + for (const string& word : wordDict) { + int m = word.length(); + if (i >= m && s.substr(i - m, m) == word) { + dp[i] = dp[i - m]; + } + // 提前剪枝,略微加速运算。 + // 如果不剪枝,上一行代码需要变更为 dp[i] = dp[i] || dp[i - m]; + if (dp[i]) { + break; + } + } + } + return dp[n]; +} +``` + + + + +```py +def wordBreak(s: str, wordDict: List[str]) -> bool: + n = len(s) + dp = [True] + [False] * n + for i in range(1, n + 1): + for word in wordDict: + m = len(word) + if i >= m and s[i - m : i] == word: + dp[i] = dp[i - m] + # 提前剪枝,略微加速运算。 + # 如果不剪枝,上一行代码需要变更为 dp[i] = dp[i] or dp[i-m] + if dp[i]: + break + return dp[n] +``` + + + + + +## [1105. Filling Bookcase Shelves](https://leetcode.com/problems/filling-bookcase-shelves/) + +### 题目描述 + +给定一个数组,每个元素代表一本书的厚度和高度。问对于一个固定宽度的书架,如果按照数组中书的顺序从左到右、从上到下摆放,最小总高度是多少。 + +### 输入输出样例 + + +``` +Input: books = [[1,1],[2,3],[2,3],[1,1],[1,1],[1,1],[1,2]], shelfWidth = 4 +Output: 6 +``` + + +
+ + ![](https://assets.leetcode.com/uploads/2019/06/24/shelves.png) + +
图 6.2: 书架摆放问题 - 样例图解
+
+ +### 题解 + +令 dp[i] 表示放置第 i 本书时的最小总高度,则 dp[i] 可以是在第 i-1 本书下面重新放一排,也可以是在满足不超过前一排宽度的情况下放在前一排。 + + + + +```cpp +int minHeightShelves(vector>& books, int shelfWidth) { + int n = books.size(); + vector dp(n + 1, 0); + for (int i = 1; i <= n; ++i) { + int w = books[i - 1][0], h = books[i - 1][1]; + dp[i] = dp[i - 1] + h; + for (int j = i - 1; j > 0; --j) { + int prev_w = books[j - 1][0], prev_h = books[j - 1][1]; + w += prev_w; + if (w > shelfWidth) { + break; + } + h = max(h, prev_h); + dp[i] = min(dp[i], dp[j - 1] + h); + } + } + return dp[n]; +} +``` + + + + +```py +def minHeightShelves(books: List[List[int]], shelfWidth: int) -> int: + n = len(books) + dp = [0] * (n + 1) + for i, (w, h) in enumerate(books, 1): + dp[i] = dp[i - 1] + h + for j in range(i - 1, 0, -1): + prev_w, prev_h = books[j - 1] + w += prev_w + if w > shelfWidth: + break + h = max(h, prev_h) + dp[i] = min(dp[i], dp[j - 1] + h) + return dp[n] +``` + + + + + +## [377. Combination Sum IV](https://leetcode.com/problems/combination-sum-iv/) + +### 题目描述 + +给定一个不重复数字的数组和一个目标数,求加起来是目标数的所有排列的总数量。(虽然这道题叫做 Combination Sum,但是不同顺序的组合会被当作不同答案,因此本质上是排列。) + +### 输入输出样例 + +``` +Input: nums = [1,2,3], target = 4 +Output: 7 +``` + +七种不同的排列为 (1, 1, 1, 1)、(1, 1, 2)、(1, 2, 1)、(1, 3)、(2, 1, 1)、(2, 2) 和 (3, 1)。 + + +### 题解 + +令 dp[i] 表示加起来和为 i 时,满足条件的排列数量。在内循环中我们可以直接对所有合法数字进行拿取。这里注意,在 C++ 题解中,因为求和时很容易超过 int 上界,我们这里用 double 存储 dp 数组。 + + + + +```cpp +int combinationSum4(vector& nums, int target) { + vector dp(target + 1, 0); + dp[0] = 1; + for (int i = 1; i <= target; ++i) { + for (int num : nums) { + if (num <= i) { + dp[i] += dp[i - num]; + } + } + } + return dp[target]; +} +``` + + + + +```py +def combinationSum4(nums: List[int], target: int) -> int: + dp = [1] + [0] * target + for i in range(1, target + 1): + dp[i] = sum(dp[i - num] for num in nums if i >= num) + return dp[target] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/6-dynamic-programming/6-5-subsequence-problems.md b/leetcode_101/docs/6-dynamic-programming/6-5-subsequence-problems.md deleted file mode 100644 index 8cbb387e..00000000 --- a/leetcode_101/docs/6-dynamic-programming/6-5-subsequence-problems.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 30 ---- - -# 6.5 子序列问题 diff --git a/leetcode_101/docs/6-dynamic-programming/6-5-subsequence-problems.mdx b/leetcode_101/docs/6-dynamic-programming/6-5-subsequence-problems.mdx new file mode 100644 index 00000000..f61fbdbb --- /dev/null +++ b/leetcode_101/docs/6-dynamic-programming/6-5-subsequence-problems.mdx @@ -0,0 +1,189 @@ +--- +sidebar_position: 30 +--- + +# 6.5 子序列问题 + +## [300. Longest Increasing Subsequence](https://leetcode.com/problems/longest-increasing-subsequence/) + +### 题目描述 + +给定一个未排序的整数数组,求最长的递增子序列。 + +:::warning + +按照 LeetCode 的习惯,子序列(subsequence)不必连续,子数组(subarray)或子字符串(substring)必须连续。 + +::: + +### 输入输出样例 + +输入是一个一维数组,输出是一个正整数,表示最长递增子序列的长度。 + +``` +Input: [10,9,2,5,3,7,101,4] +Output: 4 +``` + +在这个样例中,最长递增子序列之一是 [2,3,7,101]。 + +### 题解 + +对于子序列问题,第一种动态规划方法是,定义一个 dp 数组,其中 dp[i] 表示以 i 结尾的子序列的性质。在处理好每个位置后,统计一遍各个位置的结果即可得到题目要求的结果。 + +在本题中,dp[i] 可以表示以 i 结尾的、最长子序列长度。对于每一个位置 i,如果其之前的某个位置 j 所对应的数字小于位置 i 所对应的数字,则我们可以获得一个以 i 结尾的、长度为 dp[j] + 1 的子序列。为了遍历所有情况,我们需要 i 和 j 进行两层循环,其时间复杂度为 $O(n^2)$。 + + + + +```cpp +int lengthOfLIS(vector& nums) { + int max_len = 0, n = nums.size(); + vector dp(n, 1); + for (int i = 0; i < n; ++i) { + for (int j = 0; j < i; ++j) { + if (nums[i] > nums[j]) { + dp[i] = max(dp[i], dp[j] + 1); + } + } + max_len = max(max_len, dp[i]); + } + return max_len; +} +``` + + + + +```py +def lengthOfLIS(nums: List[int]) -> int: + n = len(nums) + dp = [1] * n + for i in range(n): + for j in range(i): + if nums[i] > nums[j]: + dp[i] = max(dp[i], dp[j] + 1) + return max(dp) +``` + + + + + +本题还可以使用二分查找将时间复杂度降低为 $O(n \log n)$。我们定义一个 dp 数组,其中 dp[k] 存储长度为 k+1 的最长递增子序列的最后一个数字。我们遍历每一个位置 i,如果其对应的数字大于 dp 数组中所有数字的值,那么我们把它放在 dp 数组尾部,表示最长递增子序列长度加 1;如果我们发现这个数字在 dp 数组中比数字 a 大、比数字 b 小,则我们将 b 更新为此数字,使得之后构成递增序列的可能性增大。以这种方式维护的 dp 数组永远是递增的,因此可以用二分查找加速搜索。 + +以样例为例,对于数组 [10,9,2,5,3,7,101,4],我们每轮的更新查找情况为: + +``` +num dp +10 [10] +9 [9] +2 [2] +5 [2,5] +3 [2,3] +7 [2,3,7] +101 [2,3,7,101] +4 [2,3,4,101] +``` + +最终我们知道最长递增子序列的长度是 4。注意 dp 数组最终的形式并不一定是合法的排列形式,如 [2,3,4,101] 并不是子序列;但之前覆盖掉的 [2,3,7,101] 是最优解之一。 + +类似的,对于其他题目,如果状态转移方程的结果递增或递减,且需要进行插入或查找操作,我们也可以使用二分法进行加速。 + + + + +```cpp +int lengthOfLIS(vector& nums) { + vector dp{nums[0]}; + for (int num : nums) { + if (dp.back() < num) { + dp.push_back(num); + } else { + *lower_bound(dp.begin(), dp.end(), num) = num; + } + } + return dp.size(); +} +``` + + + + +```py +def lengthOfLIS(nums: List[int]) -> int: + dp = [nums[0]] + for num in nums: + if dp[-1] < num: + dp.append(num) + else: + dp[bisect.bisect_left(dp, num, 0, len(dp))] = num + return len(dp) +``` + + + + + +## [1143. Longest Commom Subsequence](https://leetcode.com/problems/longest-common-subsequence/) + +### 题目描述 + +给定两个字符串,求它们最长的公共子序列长度。 + +### 输入输出样例 + +输入是两个字符串,输出是一个整数,表示它们满足题目条件的长度。 + +``` +Input: text1 = "abcde", text2 = "ace" +Output: 3 +``` + +在这个样例中,最长公共子序列是“ace”。 + +### 题解 + +对于子序列问题,第二种动态规划方法是,定义一个 dp 数组,其中 dp[i] 表示到位置 i 为止的子序列的性质,并不必须以 i 结尾。这样 dp 数组的最后一位结果即为题目所求,不需要再对每个位置进行统计。 + +在本题中,我们可以建立一个二维数组 dp,其中 dp[i][j] 表示到第一个字符串位置 i 为止、到第二个字符串位置 j 为止、最长的公共子序列长度。这样一来我们就可以很方便地分情况讨论这两个位置对应的字母相同与不同的情况了。 + + + + +```cpp +int longestCommonSubsequence(string text1, string text2) { + int m = text1.length(), n = text2.length(); + vector> dp(m + 1, vector(n + 1, 0)); + for (int i = 1; i <= m; ++i) { + for (int j = 1; j <= n; ++j) { + if (text1[i - 1] == text2[j - 1]) { + dp[i][j] = dp[i - 1][j - 1] + 1; + } else { + dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); + } + } + } + return dp[m][n]; +} +``` + + + + +```py +def longestCommonSubsequence(text1: str, text2: str) -> int: + m, n = len(text1), len(text2) + dp = [[0 for _ in range(n + 1)] for _ in range(m + 1)] + for i in range(1, m + 1): + for j in range(1, n + 1): + if text1[i - 1] == text2[j - 1]: + dp[i][j] = dp[i - 1][j - 1] + 1 + else: + dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + return dp[m][n] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/6-dynamic-programming/6-6-knapsack-problem.md b/leetcode_101/docs/6-dynamic-programming/6-6-knapsack-problem.md deleted file mode 100644 index e469aeb4..00000000 --- a/leetcode_101/docs/6-dynamic-programming/6-6-knapsack-problem.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 31 ---- - -# 6.6 背包问题 diff --git a/leetcode_101/docs/6-dynamic-programming/6-6-knapsack-problem.mdx b/leetcode_101/docs/6-dynamic-programming/6-6-knapsack-problem.mdx new file mode 100644 index 00000000..49107bec --- /dev/null +++ b/leetcode_101/docs/6-dynamic-programming/6-6-knapsack-problem.mdx @@ -0,0 +1,421 @@ +--- +sidebar_position: 31 +--- + +# 6.6 背包问题 + +`背包问题(knapsack problem)`是一种组合优化的 NP 完全问题:有 n 个物品和载重为 w 的背包,每个物品都有自己的重量 weight 和价值 value,求拿哪些物品可以使得背包所装下物品的总价值最大。如果限定每种物品只能选择 0 个或 1 个,则问题称为 `0-1 背包问题(0-1 knapsack)`;如果不限定每种物品的数量,则问题称为`无界背包问题或完全背包问题(unbounded knapsack)`。 + +我们可以用动态规划来解决背包问题。以 0-1 背包问题为例。我们可以定义一个二维数组 dp存储最大价值,其中 dp[i][j] 表示前 i 件物品重量不超过 j 的情况下能达到的最大价值。在我们遍历到第 i 件物品时,在当前背包总载重为 j 的情况下,如果我们不将物品 i 放入背包,那么 dp[i][j] = dp[i-1][j],即前 i 个物品的最大价值等于只取前 i-1 个物品时的最大价值;如果我们将物品 i 放入背包,假设第 i 件物品重量为 weight,价值为 value,那么我们得到 dp[i][j] = dp[i-1][j-weight] + value。我们只需在遍历过程中对这两种情况取最大值即可,总时间复杂度和空间复杂度都为 $O(nw)$。 + + + + + +```cpp +int knapsack(vector weights, vector values, int n, int w) { + vector> dp(n + 1, vector(w + 1, 0)); + for (int i = 1; i <= n; ++i) { + int weight = weights[i - 1], value = values[i - 1]; + for (int j = 1; j <= w; ++j) { + if (j >= weight) { + dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight] + value); + } else { + dp[i][j] = dp[i - 1][j]; + } + } + } + return dp[n][w]; +} +``` + + + + +```py +def knapsack(weights: List[int], values: List[int], n: int, w: int) -> int: + dp = [[0 for _ in range(w + 1)] for _ in range(n + 1)] + for i in range(1, n + 1): + weight, value = weights[i - 1], values[i - 1] + for j in range(1, w + 1): + if j >= weight: + dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight] + value) + else: + dp[i][j] = dp[i - 1][j] + return dp[n][w] +``` + + + + + +
+ + ![](6.3.png) + +
图 6.3: 0-1 背包问题 - 状态转移矩阵样例
+
+ +我们可以进一步对 0-1 背包进行空间优化,将空间复杂度降低为 O(w)。如图所示,假设我们目前考虑物品 i = 2,且其重量为 weight = 2,价值为 value = 3;对于背包载重 j,我们可以得到 dp[2][j] = max(dp[1][j], dp[1][j-2] + 3)。这里可以发现我们永远只依赖于上一排 i = 1 的信息,之前算过的其他物品都不需要再使用。因此我们可以去掉 dp 矩阵的第一个维度,在考虑物品 i 时变成 dp[j] = max(dp[j], dp[j-weight] + value)。这里要注意我们在遍历每一行的时候必须`逆向遍历`,这样才能够调用上一行物品 i-1 时 dp[j-weight] 的值;若按照从左往右的顺序进行正向遍历,则dp[j-weight] 的值在遍历到 j 之前就已经被更新成物品 i 的值了。 + + + + +```cpp +int knapsack(vector weights, vector values, int n, int w) { + vector dp(w + 1, 0); + for (int i = 1; i <= n; ++i) { + int weight = weights[i - 1], value = values[i - 1]; + for (int j = w; j >= weight; --j) { + dp[j] = max(dp[j], dp[j - weight] + value); + } + } + return dp[w]; +} +``` + + + + +```py +def knapsack(weights: List[int], values: List[int], n: int, w: int) -> int: + dp = [0] * (w + 1) + for i in range(1, n + 1): + weight, value = weights[i - 1], values[i - 1] + for j in range(w, weight - 1, -1): + dp[j] = max(dp[j], [j - weight] + value) + return dp[w] +``` + + + + + +在完全背包问题中,一个物品可以拿多次。如图上半部分所示,假设我们遍历到物品 i = 2,且其重量为 weight = 2,价值为 value = 3;对于背包载重 j = 5,最多只能装下 2 个该物品。那么我们的状态转移方程就变成了 dp[2][5] = max(dp[1][5], dp[1][3] + 3, dp[1][1] + 6)。如果采用这种方法,假设背包载重无穷大而物体的重量无穷小,我们这里的比较次数也会趋近于无穷大,远超$O(nw)$ 的时间复杂度。 + +
+ + ![](6.4.png) + +
图 6.4: 完全背包问题 - 状态转移矩阵样例
+
+ +怎么解决这个问题呢?我们发现在 dp[2][3] 的时候我们其实已经考虑了 dp[1][3] 和 dp[2][1] 的情况,而在时 dp[2][1] 也已经考虑了 dp[1][1] 的情况。因此,如图下半部分所示,对于拿多个物品的情况,我们只需考虑 dp[2][3] 即可,即 dp[2][5] = max(dp[1][5], dp[2][3] + 3)。这样,我们就得到了完全背包问题的状态转移方程:dp[i][j] = max(dp[i-1][j], dp[i][j-w] + v),其与 0-1 背包问题的差别仅仅是把状态转移方程中的第二个 i-1 变成了 i。 + + + + +```cpp +int knapsack(vector weights, vector values, int n, int w) { + vector> dp(n + 1, vector(w + 1, 0)); + for (int i = 1; i <= n; ++i) { + int weight = weights[i - 1], value = values[i - 1]; + for (int j = 1; j <= w; ++j) { + if (j >= weight) { + dp[i][j] = max(dp[i - 1][j], dp[i][j - weight] + value); + } else { + dp[i][j] = dp[i - 1][j]; + } + } + } + return dp[n][w]; +} +``` + + + + +```py +def knapsack(weights: List[int], values: List[int], n: int, w: int) -> int: + dp = [[0 for _ in range(w + 1)] for _ in range(n + 1)] + for i in range(1, n + 1): + weight, value = weights[i - 1], values[i - 1] + for j in range(1, w + 1): + if j >= weight: + dp[i][j] = max(dp[i - 1][j], dp[i][j - weight] + value) + else: + dp[i][j] = dp[i - 1][j] + return dp[n][w] +``` + + + + + +同样的,我们也可以利用空间压缩将时间复杂度降低为 $O(w)$。这里要注意我们在遍历每一行的时候必须`正向遍历`,因为我们需要利用当前物品在第 j-weight 列的信息。 + + + + +```cpp +int knapsack(vector weights, vector values, int n, int w) { + vector dp(w + 1, 0); + for (int i = 1; i <= n; ++i) { + int weight = weights[i - 1], value = values[i - 1]; + for (int j = weight; j <= w; ++j) { + dp[j] = max(dp[j], dp[j - weight] + value); + } + } + return dp[w]; +} +``` + + + + +```py +def knapsack(weights: List[int], values: List[int], n: int, w: int) -> int: + dp = [0] * (w + 1) + for i in range(1, n + 1): + weight, value = weights[i - 1], values[i - 1] + for j in range(weight, w + 1): + dp[j] = max(dp[j], [j - weight] + value) + return dp[w] +``` + + + + + +:::warning + +压缩空间时到底需要正向还是逆向遍历呢?物品和重量哪个放在外层,哪个放在内层呢?这取决于状态转移方程的依赖关系。在思考空间压缩前,不妨将状态转移矩阵画出来,方便思考如何进行空间压缩,以及压缩哪个维度更省空间。 + +::: + +## [416. Partition Equal Subset Sum](https://leetcode.com/problems/partition-equal-subset-sum/) + +### 题目描述 + +给定一个正整数数组,求是否可以把这个数组分成和相等的两部分。 + +### 输入输出样例 + +输入是一个一维正整数数组,输出时一个布尔值,表示是否可以满足题目要求。 + +``` +Input: [1,5,11,5] +Output: true +``` + +在这个样例中,满足条件的分割方法是 [1,5,5] 和 [11]。 + +### 题解 + +本题等价于 0-1 背包问题,设所有数字和为 sum,我们的目标是选取一部分物品,使得它们的总和为 sum/2。这道题不需要考虑价值,因此我们只需要通过一个布尔值矩阵来表示状态转移矩阵。注意边界条件的处理。 + + + + +```cpp +bool canPartition(vector &nums) { + int nums_sum = accumulate(nums.begin(), nums.end(), 0); + if (nums_sum % 2 != 0) { + return false; + } + int target = nums_sum / 2, n = nums.size(); + vector> dp(n + 1, vector(target + 1, false)); + dp[0][0] = true; + for (int i = 1; i <= n; ++i) { + for (int j = 0; j <= target; ++j) { + if (j < nums[i - 1]) { + dp[i][j] = dp[i - 1][j]; + } else { + dp[i][j] = dp[i - 1][j] || dp[i - 1][j - nums[i - 1]]; + } + } + } + return dp[n][target]; +} +``` + + + + +```py +def canPartition(nums: List[int]) -> bool: + nums_sum = sum(nums) + if nums_sum % 2 != 0: + return False + target, n = nums_sum // 2, len(nums) + dp = [[False for _ in range(target + 1)] for _ in range(n + 1)] + dp[0][0] = True + for i in range(1, n + 1): + for j in range(target + 1): + if j < nums[i - 1]: + dp[i][j] = dp[i - 1][j] + else: + dp[i][j] = dp[i - 1][j] or dp[i - 1][j - nums[i - 1]] + return dp[n][target] +``` + + + + + +同样的,我们也可以对本题进行空间压缩。注意对数字和的遍历需要逆向。 + + + + +```cpp +bool canPartition(vector &nums) { + int nums_sum = accumulate(nums.begin(), nums.end(), 0); + if (nums_sum % 2 != 0) { + return false; + } + int target = nums_sum / 2, n = nums.size(); + vector dp(target + 1, false); + dp[0] = true; + for (int i = 1; i <= n; ++i) { + for (int j = target; j >= nums[i - 1]; --j) { + dp[j] = dp[j] || dp[j - nums[i - 1]]; + } + } + return dp[target]; +} +``` + + + + +```py +def canPartition(nums: List[int]) -> bool: + nums_sum = sum(nums) + if nums_sum % 2 != 0: + return False + target, n = nums_sum // 2, len(nums) + dp = [True] + [False] * target + for i in range(1, n + 1): + for j in range(target, nums[i - 1] - 1, -1): + dp[j] = dp[j] or dp[j - nums[i - 1]] + return dp[target] +``` + + + + + +## [474. Ones and Zeroes](https://leetcode.com/problems/ones-and-zeroes/) + +### 题目描述 + +给定 $m$ 个数字 0 和 $n$ 个数字 1,以及一些由 0-1 构成的字符串,求利用这些数字最多可以构成多少个给定的字符串,字符串只可以构成一次。 + +### 输入输出样例 + +输入两个整数 $m$ 和 $n$,表示 0 和 1 的数量,以及一个一维字符串数组,表示待构成的字符串; +输出是一个整数,表示最多可以生成的字符串个数。 + +``` +Input: Array = {"10", "0001", "111001", "1", "0"}, m = 5, n = 3 +Output: 4 +``` + +在这个样例中,我们可以用 5 个 0 和 3 个 1 构成 [“10”, “0001”, “1”, “0”]。 + +### 题解 + +这是一个多维费用的 0-1 背包问题,有两个背包大小,0 的数量和 1 的数量。我们在这里直接展示三维空间压缩到二维后的写法。 + + + + +```cpp +int findMaxForm(vector& strs, int m, int n) { + vector> dp(m + 1, vector(n + 1, 0)); + for (const string& s : strs) { + int zeros = 0, ones = 0; + for (char c : s) { + if (c == ’0’) { + ++zeros; + } else { + ++ones; + } + } + for (int i = m; i >= zeros; --i) { + for (int j = n; j >= ones; --j) { + dp[i][j] = max(dp[i][j], dp[i - zeros][j - ones] + 1); + } + } + } + return dp[m][n]; +} +``` + + + + +```py +def findMaxForm(strs: List[str], m: int, n: int) -> int: + dp = [[0 for _ in range(n + 1)] for _ in range(m + 1)] + for s in strs: + zeros = len(list(filter(lambda c: c == "0", s))) + ones = len(s) - zeros + for i in range(m, zeros - 1, -1): + for j in range(n, ones - 1, -1): + dp[i][j] = max(dp[i][j], dp[i - zeros][j - ones] + 1) + return dp[m][n] +``` + + + + + +## [322. Coin Change](https://leetcode.com/problems/coin-change/) + +### 题目描述 + +给定一些硬币的面额,求最少可以用多少颗硬币组成给定的金额。 + +### 输入输出样例 + +输入一个一维整数数组,表示硬币的面额;以及一个整数,表示给定的金额。输出一个整数,表示满足条件的最少的硬币数量。若不存在解,则返回-1。 + +``` +Input: coins = [1, 2, 5], amount = 11 +Output: 3 +``` + +在这个样例中,最少的组合方法是 11 = 5 + 5 + 1。 + +### 题解 + +因为每个硬币可以用无限多次,这道题本质上是完全背包。我们直接展示二维空间压缩为一维的写法。 + +这里注意,我们把 dp 数组初始化为 amount + 1 而不是-1 的原因是,在动态规划过程中有求最小值的操作,如果初始化成-1 则会导致结果始终为-1。至于为什么取这个值,是因为 i 最大可以取 amount,而最多的组成方式是只用 1 元硬币,因此 amount + 1 一定大于所有可能的组合方式,取最小值时一定不会是它。在动态规划完成后,若结果仍然是此值,则说明不存在满足条件的组合方法,返回-1。 + + + + +```cpp +int coinChange(vector& coins, int amount) { + vector dp(amount + 1, amount + 1); + dp[0] = 0; + for (int i = 1; i <= amount; ++i) { + for (int coin : coins) { + if (i >= coin) { + dp[i] = min(dp[i], dp[i - coin] + 1); + } + } + } + return dp[amount] != amount + 1 ? dp[amount] : -1; +} +``` + + + + +```py +def coinChange(coins: List[int], amount: int) -> int: + dp = [0] + [amount + 1] * amount + for i in range(1, amount + 1): + for coin in coins: + if i >= coin: + dp[i] = min(dp[i], dp[i - coin] + 1) + return dp[amount] if dp[amount] != amount + 1 else -1 +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/6-dynamic-programming/6-7-string-editing.md b/leetcode_101/docs/6-dynamic-programming/6-7-string-editing.md deleted file mode 100644 index b70a7c3c..00000000 --- a/leetcode_101/docs/6-dynamic-programming/6-7-string-editing.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 32 ---- - -# 6.7 字符串编辑 diff --git a/leetcode_101/docs/6-dynamic-programming/6-7-string-editing.mdx b/leetcode_101/docs/6-dynamic-programming/6-7-string-editing.mdx new file mode 100644 index 00000000..8db6b323 --- /dev/null +++ b/leetcode_101/docs/6-dynamic-programming/6-7-string-editing.mdx @@ -0,0 +1,132 @@ +--- +sidebar_position: 32 +--- + +# 6.7 字符串编辑 + +## [72. Edit Distance](https://leetcode.com/problems/edit-distance/) + +### 题目描述 + +给定两个字符串,已知你可以删除、替换和插入任意字符串的任意字符,求最少编辑几步可以将两个字符串变成相同。 + +### 输入输出样例 + +输入是两个字符串,输出是一个整数,表示最少的步骤。 + +``` +Input: word1 = "horse", word2 = "ros" +Output: 3 +``` + +在这个样例中,一种最优编辑方法是 horse -> rorse -> rose -> ros。 + +### 题解 + +类似于题目 1143,我们使用一个二维数组 dp[i][j],表示将第一个字符串到位置 i 为止,和第二个字符串到位置 j 为止,最多需要几步编辑。当第 i 位和第 j 位对应的字符相同时,dp[i][j] 等于 dp[i-1][j-1];当二者对应的字符不同时,修改的消耗是 dp[i-1][j-1]+1,插入 i 位置/删除 j 位置的消耗是 dp[i][j-1] + 1,插入 j 位置/删除 i 位置的消耗是 dp[i-1][j] + 1。 + + + + +```cpp +int minDistance(string word1, string word2) { + int m = word1.length(), n = word2.length(); + vector> dp(m + 1, vector(n + 1, 0)); + for (int i = 0; i <= m; ++i) { + for (int j = 0; j <= n; ++j) { + if (i == 0 || j == 0) { + dp[i][j] = i + j; + } else { + dp[i][j] = dp[i - 1][j - 1] + (word1[i - 1] != word2[j - 1]); + dp[i][j] = min(dp[i][j], dp[i - 1][j] + 1); + dp[i][j] = min(dp[i][j], dp[i][j - 1] + 1); + } + } + } + return dp[m][n]; +} +``` + + + + +```py +def minDistance(word1: str, word2: str) -> int: + m, n = len(word1), len(word2) + dp = [[0 for _ in range(n + 1)] for _ in range(m + 1)] + for i in range(m + 1): + for j in range(n + 1): + if i == 0 or j == 0: + dp[i][j] = i + j + else: + dp[i][j] = min( + dp[i - 1][j - 1] + int(word1[i - 1] != word2[j - 1]), + dp[i][j - 1] + 1, + dp[i - 1][j] + 1, + ) + return dp[m][n] +``` + + + + + +## [650. 2 Keys Keyboard](https://leetcode.com/problems/2-keys-keyboard/) + +### 题目描述 + +给定一个字母 A,已知你可以每次选择复制全部字符,或者粘贴之前复制的字符,求最少需要几次操作可以把字符串延展到指定长度。 + +### 输入输出样例 + +输入是一个正整数,代表指定长度;输出是一个整数,表示最少操作次数。 + +``` +Input: 3 +Output: 3 +``` + +在这个样例中,一种最优的操作方法是先复制一次,再粘贴两次。 + +### 题解 + +不同于以往通过加减实现的动态规划,这里需要乘除法来计算位置,因为粘贴操作是倍数增加的。我们使用一个一维数组 dp,其中位置 i 表示延展到长度 i 的最少操作次数。对于每个位置 j,如果 j 可以被 i 整除,那么长度 i 就可以由长度 j 操作得到,其操作次数等价于把一个长度为 j 的 A 延展到长度为 i/j。因此我们可以得到递推公式 dp[i] = dp[j] + dp[i/j]。 + + + + +```cpp +int minSteps(int n) { + vector dp(n + 1, 0); + for (int i = 2; i <= n; ++i) { + dp[i] = i; + for (int j = 2; j * j <= i; ++j) { + if (i % j == 0) { + dp[i] = dp[j] + dp[i / j]; + // 提前剪枝,因为j从小到大,因此操作数量一定最小。 + break; + } + } + } + return dp[n]; +} +``` + + + + +```py +def minSteps(n: int) -> int: + dp = [0] * 2 + list(range(2, n + 1)) + for i in range(2, n + 1): + for j in range(2, floor(sqrt(i)) + 1): + if i % j == 0: + dp[i] = dp[j] + dp[i // j] + # 提前剪枝,因为j从小到大,因此操作数量一定最小。 + break + return dp[n] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/6-dynamic-programming/6-8-stock-trading.md b/leetcode_101/docs/6-dynamic-programming/6-8-stock-trading.md deleted file mode 100644 index 474a73d2..00000000 --- a/leetcode_101/docs/6-dynamic-programming/6-8-stock-trading.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 33 ---- - -# 6.8 股票交易 diff --git a/leetcode_101/docs/6-dynamic-programming/6-8-stock-trading.mdx b/leetcode_101/docs/6-dynamic-programming/6-8-stock-trading.mdx new file mode 100644 index 00000000..e4c7b4f8 --- /dev/null +++ b/leetcode_101/docs/6-dynamic-programming/6-8-stock-trading.mdx @@ -0,0 +1,183 @@ +--- +sidebar_position: 33 +--- + +# 6.8 股票交易 + +`股票交易`类问题通常可以用动态规划来解决。对于稍微复杂一些的股票交易类问题,比如需要冷却时间或者交易费用,则可以用通过动态规划实现的`状态机`来解决。 + +## [121. Best Time to Buy and Sell Stock](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/) + +### 题目描述 + +给定一段时间内每天某只股票的固定价格,已知你只可以买卖各一次,求最大的收益。 + +### 输入输出样例 + +输入一个一维整数数组,表示每天的股票价格;输出一个整数,表示最大的收益。 + +``` +Input: [7,1,5,3,6,4] +Output: 5 +``` + +在这个样例中,最大的利润为在第二天价格为 1 时买入,在第五天价格为 6 时卖出。 + +### 题解 + +我们可以遍历一遍数组,在每一个位置 i 时,记录 i 位置之前所有价格中的最低价格,然后将当前的价格作为售出价格,查看当前收益是不是最大收益即可。注意本题中以及之后题目中的buy 和 sell 表示买卖操作时,用户账户的收益。因此买时为负,卖时为正。 + + + + +```cpp +int maxProfit(vector& prices) { + int buy = numeric_limits::lowest(), sell = 0; + for (int price : prices) { + buy = max(buy, -price); + sell = max(sell, buy + price); + } + return sell; +} +``` + + + + +```py +def maxProfit(prices: List[int]) -> int: + buy, sell = -sys.maxsize, 0 + for price in prices: + buy = max(buy, -price) + sell = max(sell, buy + price) + return sell +``` + + + + + +## [188. Best Time to Buy and Sell Stock IV](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/) + +### 题目描述 + +给定一段时间内每天某只股票的固定价格,已知你只可以买卖各 $k$ 次,且每次只能拥有一支股票,求最大的收益。 + +### 输入输出样例 + +输入一个一维整数数组,表示每天的股票价格;以及一个整数,表示可以买卖的次数 $k$。输出一个整数,表示最大的收益。 + +``` +Input: [3,2,6,5,0,3], k = 2 +Output: 7 +``` + +在这个样例中,最大的利润为在第二天价格为 2 时买入,在第三天价格为 6 时卖出;再在第五天价格为 0 时买入,在第六天价格为 3 时卖出。 + +### 题解 + +类似地,我们可以建立两个动态规划数组 buy 和 sell,对于每天的股票价格,buy[j] 表示在第 j 次买入时的最大收益,sell[j] 表示在第 j 次卖出时的最大收益。 + + + + + +```cpp +int maxProfit(int k, vector& prices) { + int days = prices.size(); + vector buy(k + 1, numeric_limits::lowest()), sell(k + 1, 0); + for (int i = 0; i < days; ++i) { + for (int j = 1; j <= k; ++j) { + buy[j] = max(buy[j], sell[j - 1] - prices[i]); + sell[j] = max(sell[j], buy[j] + prices[i]); + } + } + return sell[k]; +} +``` + + + + +```py +def maxProfit(k: int, prices: List[int]) -> int: + days = len(prices) + buy, sell = [-sys.maxsize] * (k + 1), [0] * (k + 1) + for i in range(days): + for j in range(1, k + 1): + buy[j] = max(buy[j], sell[j - 1] - prices[i]) + sell[j] = max(sell[j], buy[j] + prices[i]) + return sell[k] +``` + + + + + +## [309. Best Time to Buy and Sell Stock with Cooldown](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/) + +### 题目描述 + +给定一段时间内每天某只股票的固定价格,已知每次卖出之后必须冷却一天,且每次只能拥有一支股票,求最大的收益。 + +### 输入输出样例 + +输入一个一维整数数组,表示每天的股票价格;输出一个整数,表示最大的收益。 + +``` +Input: [1,2,3,0,2] +Output: 3 +``` + +在这个样例中,最大的利润获取操作是买入、卖出、冷却、买入、卖出。 + +### 题解 + +我们可以使用状态机来解决这类复杂的状态转移问题,通过建立多个状态以及它们的转移方式,我们可以很容易地推导出各个状态的转移方程。如图所示,我们可以建立四个状态来表示带有冷却的股票交易,以及它们的之间的转移方式。 + +
+ + ![](6.5.png) + +
图 6.5: 题目 309 - 状态机状态转移
+
+ + + + +```cpp +int maxProfit(vector& prices) { + int n = prices.size(); + vector buy(n), sell(n), s1(n), s2(n); + s1[0] = buy[0] = -prices[0]; + sell[0] = s2[0] = 0; + for (int i = 1; i < n; ++i) { + buy[i] = s2[i - 1] - prices[i]; + s1[i] = max(buy[i - 1], s1[i - 1]); + sell[i] = max(buy[i - 1], s1[i - 1]) + prices[i]; + s2[i] = max(s2[i - 1], sell[i - 1]); + } + return max(sell[n - 1], s2[n - 1]); +} +``` + + + + +```py +def maxProfit(prices: List[int]) -> int: + n = len(prices) + buy, sell, s1, s2 = [0] * n, [0] * n, [0] * n, [0] * n + s1[0] = buy[0] = -prices[0] + sell[0] = s2[0] = 0 + for i in range(1, n): + buy[i] = s2[i - 1] - prices[i] + s1[i] = max(buy[i - 1], s1[i - 1]) + sell[i] = max(buy[i - 1], s1[i - 1]) + prices[i] + s2[i] = max(s2[i - 1], sell[i - 1]) + return max(sell[n - 1], s2[n - 1]) +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/6-dynamic-programming/6-9-exercises.md b/leetcode_101/docs/6-dynamic-programming/6-9-exercises.md index e279ca9d..edb73762 100644 --- a/leetcode_101/docs/6-dynamic-programming/6-9-exercises.md +++ b/leetcode_101/docs/6-dynamic-programming/6-9-exercises.md @@ -3,3 +3,43 @@ sidebar_position: 34 --- # 6.9 练习 + +## 基础难度 + +### [213. House Robber II](https://leetcode.com/problems/house-robber-ii/) + +强盗抢劫题目的 follow-up,如何处理环形数组呢? + +### [53. Maximum Subarray](https://leetcode.com/problems/maximum-subarray/) + +经典的一维动态规划题目,试着把一维空间优化为常量吧。 + +### [343. Integer Break](https://leetcode.com/problems/integer-break/) + +分割类型题,先尝试用动态规划求解,再思考是否有更简单的解法。 + +### [583. Delete Operation for Two Strings](https://leetcode.com/problems/delete-operation-for-two-strings/) + +最长公共子序列的变种题。 + +## 进阶难度 + +### [646. Maximum Length of Pair Chain](https://leetcode.com/problems/maximum-length-of-pair-chain/) + +最长递增子序列的变种题,同样的,尝试用二分进行加速。 + +### [10. Regular Expression Matching](https://leetcode.com/problems/regular-expression-matching/) + +正则表达式匹配,非常考验耐心。需要根据正则表达式的不同情况,即字符、星号,点号等,分情况讨论。 + +### [376. Wiggle Subsequence](https://leetcode.com/problems/wiggle-subsequence/) + +最长摆动子序列,通项公式比较特殊,需要仔细思考。 + +### [494. Target Sum](https://leetcode.com/problems/target-sum/) + +如果告诉你这道题是 0-1 背包,你是否会有一些思路? + +### [714. Best Time to Buy and Sell Stock with Transaction Fee](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/) + +建立状态机,股票交易类问题就会迎刃而解。 \ No newline at end of file diff --git a/leetcode_101/docs/6-dynamic-programming/6.1.png b/leetcode_101/docs/6-dynamic-programming/6.1.png new file mode 100644 index 0000000000000000000000000000000000000000..6b075633b568d5d942aa5c48465c6d9405570cd8 GIT binary patch literal 34632 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 b`8TOCn|H(_jP^6`fPb*(ROPc}jlBK?n+e1I literal 0 HcmV?d00001 diff --git a/leetcode_101/docs/6-dynamic-programming/6.3.png b/leetcode_101/docs/6-dynamic-programming/6.3.png new file mode 100644 index 0000000000000000000000000000000000000000..4ff0572c706140bae1f5106077d11faa558e1657 GIT binary patch literal 24349 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 IqZWSu1}%@5q5uE@ literal 0 HcmV?d00001 diff --git a/leetcode_101/docs/6-dynamic-programming/6.4.png b/leetcode_101/docs/6-dynamic-programming/6.4.png new file mode 100644 index 0000000000000000000000000000000000000000..4acc447e937b7a5c5a0b1776104bb02828a9db0e GIT binary patch literal 38325 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 literal 0 HcmV?d00001 diff --git a/leetcode_101/docs/6-dynamic-programming/6.5.png b/leetcode_101/docs/6-dynamic-programming/6.5.png new file mode 100644 index 0000000000000000000000000000000000000000..97774d350a26134d09ee8c80275c1678f4c363b8 GIT binary patch literal 49000 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 Date: Thu, 14 Nov 2024 10:05:44 +0100 Subject: [PATCH 10/49] chapter 7 --- .../7-1-algorithm-explanation.md | 17 ++ .../7-2-expression-problems.md | 5 - .../7-2-expression-problems.mdx | 154 ++++++++++++++++++ .../7-divide-and-conquer/7-3-exercises.md | 12 ++ .../docs/7-divide-and-conquer/_category_.json | 2 +- 5 files changed, 184 insertions(+), 6 deletions(-) delete mode 100644 leetcode_101/docs/7-divide-and-conquer/7-2-expression-problems.md create mode 100644 leetcode_101/docs/7-divide-and-conquer/7-2-expression-problems.mdx diff --git a/leetcode_101/docs/7-divide-and-conquer/7-1-algorithm-explanation.md b/leetcode_101/docs/7-divide-and-conquer/7-1-algorithm-explanation.md index 770e8d78..8c1f25c4 100644 --- a/leetcode_101/docs/7-divide-and-conquer/7-1-algorithm-explanation.md +++ b/leetcode_101/docs/7-divide-and-conquer/7-1-algorithm-explanation.md @@ -3,3 +3,20 @@ sidebar_position: 35 --- # 7.1 算法解释 + +顾名思义,`分治问题`由“分”(divide)和“治”(conquer)两部分组成,通过把原问题分为子问题,再将子问题进行处理合并,从而实现对原问题的求解。我们在排序章节展示的归并排序就是典型的分治问题,其中“分”即为把大数组平均分成两个小数组,通过递归实现,最终我们会得到多个长度为 1 的子数组;“治”即为把已经排好序的两个小数组合成为一个排好序的大数组从长度为 1 的子数组开始,最终合成一个大数组。 + +我们也使用数学表达式来表示这个过程。定义 $T(n)$ 表示处理一个长度为 $n$ 的数组的时间复杂度,则归并排序的时间复杂度递推公式为 $T(n) =2T(n/2) +O(n)$。其中 $2T(n/2)$ 表示我们分成了两个长度减半的子问题,$O(n)$ 则为合并两个长度为 $n/2$ 数组的时间复杂度。 + +:::info 定理 7.1. 主定理 + +考虑 $T(n) =aT(n/b) + f (n)$,定义 $k =\log_{b} a$ +1. 如果 $f (n) =O(n^p)$ 且 $p < k$,那么 $T(n) =O(n^K)$ +2. 如果存在 $c ≥ 0$ 满足 $f (n) =O(n^k \log^c n)$,那么 $T(n) = O(n^k \log^{c+1} n)$ +3. 如果 $f (n) =O(n^p)$ 且 $p > k$,那么 $T(n) =O( f (n))$ + +::: + +通过主定理我们可以知道,归并排序属于第二种情况,且时间复杂度为 $O(n \log n)$。其他的分治问题也可以通过主定理求得时间复杂度。 + +另外,自上而下的分治可以和 memoization 结合,避免重复遍历相同的子问题。如果方便推导,也可以换用自下而上的动态规划方法求解。 \ No newline at end of file diff --git a/leetcode_101/docs/7-divide-and-conquer/7-2-expression-problems.md b/leetcode_101/docs/7-divide-and-conquer/7-2-expression-problems.md deleted file mode 100644 index 78ebe320..00000000 --- a/leetcode_101/docs/7-divide-and-conquer/7-2-expression-problems.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 36 ---- - -# 7.2 表达式问题 diff --git a/leetcode_101/docs/7-divide-and-conquer/7-2-expression-problems.mdx b/leetcode_101/docs/7-divide-and-conquer/7-2-expression-problems.mdx new file mode 100644 index 00000000..7d89be26 --- /dev/null +++ b/leetcode_101/docs/7-divide-and-conquer/7-2-expression-problems.mdx @@ -0,0 +1,154 @@ +--- +sidebar_position: 36 +--- + +# 7.2 表达式问题 + +## [241. Different Ways to Add Parentheses](https://leetcode.com/problems/different-ways-to-add-parentheses/) + +### 题目描述 + +给定一个只包含加、减和乘法的数学表达式,求通过加括号可以得到多少种不同的结果。 + +### 输入输出样例 + +输入是一个字符串,表示数学表达式;输出是一个数组,存储所有不同的加括号结果。 + +``` +Input: "2-1-1" +Output: [0, 2] +``` + +在这个样例中,有两种加括号结果:((2-1)-1) = 0 和 (2-(1-1)) = 2。 + +### 题解 + +利用分治思想,我们可以把加括号转化为,对于每个运算符号,先执行处理两侧的数学表达式,再处理此运算符号。注意边界情况,即字符串内无运算符号,只有数字。 + + + + +```cpp +vector diffWaysToCompute(string expression) { + vector ways; + unordered_map> op_funcs; + op_funcs[’+’] = [](int x, int y) { return x + y; }; + op_funcs[’-’] = [](int x, int y) { return x - y; }; + op_funcs[’*’] = [](int x, int y) { return x * y; }; + for (int i = 0; i < expression.length(); ++i) { + char c = expression[i]; + if (!op_funcs.contains(c)) { + continue; + } + auto left = diffWaysToCompute(expression.substr(0, i)); + auto right = diffWaysToCompute(expression.substr(i + 1)); + for (int l : left) { + for (int r : right) { + ways.push_back(op_funcs[c](l, r)); + } + } + } + return ways.empty() ? vector{stoi(expression)} : ways; +} +``` + + + + +```py +def diffWaysToCompute(expression: str) -> List[int]: + ways = [] + op_funcs = { + "+": (lambda x, y: x + y), + "-": (lambda x, y: x - y), + "*": (lambda x, y: x * y), + } + for i, c in enumerate(expression): + if c not in op_funcs: + continue + left = diffWaysToCompute(expression[:i]) + right = diffWaysToCompute(expression[i + 1 :]) + ways += [op_funcs[c](l, r) for l in left for r in right] + return [int(expression)] if len(ways) == 0 else ways +``` + + + + + +我们发现,某些被 divide 的子字符串可能重复出现多次,因此我们可以用 memoization 来去重。比如建立一个哈希表,key 是 (l, r),value 是 ways。每次遇到相同的 (l, r),我们可以直接返回已经计算过的 ways。或者与其我们从上到下用分治处理 +memoization,不如直接从下到上用动态规划处理。 + + + + +```cpp +vector diffWaysToCompute(string expression) { + // 利用istringstream, 将数字和操作符进行分词。 + vector nums; + vector ops; + int num = 0; + char op = ’ ’; + istringstream ss(expression); + while (ss >> num) { + nums.push_back(num); + if (ss >> op) { + ops.push_back(op); + } + } + int n = nums.size(); + vector>> dp(n, vector>(n, vector())); + unordered_map> op_funcs; + op_funcs[’+’] = [](int a, int b) { return a + b; }; + op_funcs[’-’] = [](int a, int b) { return a - b; }; + op_funcs[’*’] = [](int a, int b) { return a * b; }; + for (int i = 0; i < n; ++i) { + for (int j = i; j >= 0; --j) { + if (i == j) { + dp[j][i].push_back(nums[i]); + continue; + } + for (int k = j; k < i; ++k) { + for (auto l : dp[j][k]) { + for (auto r : dp[k + 1][i]) { + dp[j][i].push_back(op_funcs[ops[k]](l, r)); + } + } + } + } + } + return dp[0][n - 1]; +} +``` + + + + +```py +def diffWaysToCompute(expression: str) -> List[int]: + # re.split可以将操作符(\D)和数字直接分开。 + sections = re.split(r"(\D)", expression) + nums = [int(num) for num in sections if num.isdigit()] + ops = [op for op in sections if not op.isdigit()] + n = len(nums) + dp = [[[] for _ in range(n)] for _ in range(n)] + op_funcs = { + "+": (lambda x, y: x + y), + "-": (lambda x, y: x - y), + "*": (lambda x, y: x * y), + } + for i in range(n): + for j in range(i, -1, -1): + if i == j: + dp[j][i].append(nums[i]) + continue + for k in range(j, i): + dp[j][i] += [op_funcs[ops[k]](l, r) + for l in dp[j][k] for r in dp[k + 1][i]] + + return dp[0][n - 1] + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/7-divide-and-conquer/7-3-exercises.md b/leetcode_101/docs/7-divide-and-conquer/7-3-exercises.md index 62624b22..a52cf92b 100644 --- a/leetcode_101/docs/7-divide-and-conquer/7-3-exercises.md +++ b/leetcode_101/docs/7-divide-and-conquer/7-3-exercises.md @@ -3,3 +3,15 @@ sidebar_position: 37 --- # 7.3 练习 + +## 基础难度 + +### [932. Beautiful Array](https://leetcode.com/problems/beautiful-array/) + +试着用从上到下的分治(递归)写法求解,最好加上 memoization;再用从下到上的动态规划写法求解。 + +## 进阶难度 + +### [312. Burst Balloons](https://leetcode.com/problems/burst-balloons/) + +试着用从上到下的分治(递归)写法求解,最好加上 memoization;再用从下到上的动态规划写法求解。 \ No newline at end of file diff --git a/leetcode_101/docs/7-divide-and-conquer/_category_.json b/leetcode_101/docs/7-divide-and-conquer/_category_.json index f24bf92c..2535d2d4 100644 --- a/leetcode_101/docs/7-divide-and-conquer/_category_.json +++ b/leetcode_101/docs/7-divide-and-conquer/_category_.json @@ -3,6 +3,6 @@ "position": 7, "link": { "type": "generated-index", - "description": "5 minutes to learn the most important Docusaurus concepts." + "description": "第 7 章 化繁为简的分治法" } } From cf8afe577711c487575117a75e3270d5ab4a752a Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Thu, 14 Nov 2024 10:30:33 +0100 Subject: [PATCH 11/49] chapter 8 --- .../8-1-introduction.md | 2 + .../8-mathematical-solutions/8-2-lcm-gcd.md | 5 - .../8-mathematical-solutions/8-2-lcm-gcd.mdx | 72 ++++ .../8-3-prime-numbers.md | 5 - .../8-3-prime-numbers.mdx | 138 ++++++++ .../8-4-number-processing.md | 5 - .../8-4-number-processing.mdx | 318 ++++++++++++++++++ .../8-5-random-sampling.md | 5 - .../8-5-random-sampling.mdx | 228 +++++++++++++ .../8-mathematical-solutions/8-6-exercises.md | 32 ++ .../8-mathematical-solutions/_category_.json | 2 +- 11 files changed, 791 insertions(+), 21 deletions(-) delete mode 100644 leetcode_101/docs/8-mathematical-solutions/8-2-lcm-gcd.md create mode 100644 leetcode_101/docs/8-mathematical-solutions/8-2-lcm-gcd.mdx delete mode 100644 leetcode_101/docs/8-mathematical-solutions/8-3-prime-numbers.md create mode 100644 leetcode_101/docs/8-mathematical-solutions/8-3-prime-numbers.mdx delete mode 100644 leetcode_101/docs/8-mathematical-solutions/8-4-number-processing.md create mode 100644 leetcode_101/docs/8-mathematical-solutions/8-4-number-processing.mdx delete mode 100644 leetcode_101/docs/8-mathematical-solutions/8-5-random-sampling.md create mode 100644 leetcode_101/docs/8-mathematical-solutions/8-5-random-sampling.mdx diff --git a/leetcode_101/docs/8-mathematical-solutions/8-1-introduction.md b/leetcode_101/docs/8-mathematical-solutions/8-1-introduction.md index 108afbcf..d753971e 100644 --- a/leetcode_101/docs/8-mathematical-solutions/8-1-introduction.md +++ b/leetcode_101/docs/8-mathematical-solutions/8-1-introduction.md @@ -3,3 +3,5 @@ sidebar_position: 38 --- # 8.1 引言 + +对于 LeetCode 上数量不少的数学题,我们尽量将其按照类型划分讲解。然而很多数学题的解法并不通用,我们也很难一口气把所有的套路讲清楚,因此我们只选择了几道经典或是典型的题目,供大家参考。 \ No newline at end of file diff --git a/leetcode_101/docs/8-mathematical-solutions/8-2-lcm-gcd.md b/leetcode_101/docs/8-mathematical-solutions/8-2-lcm-gcd.md deleted file mode 100644 index 5bbdc1a7..00000000 --- a/leetcode_101/docs/8-mathematical-solutions/8-2-lcm-gcd.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 39 ---- - -# 8.2 公倍数与公因数 diff --git a/leetcode_101/docs/8-mathematical-solutions/8-2-lcm-gcd.mdx b/leetcode_101/docs/8-mathematical-solutions/8-2-lcm-gcd.mdx new file mode 100644 index 00000000..58dda1b8 --- /dev/null +++ b/leetcode_101/docs/8-mathematical-solutions/8-2-lcm-gcd.mdx @@ -0,0 +1,72 @@ +--- +sidebar_position: 39 +--- + +# 8.2 公倍数与公因数 + +利用`辗转相除法`,我们可以很方便地求得两个数的最大公因数(greatest common divisor,GCD);将两个数相乘再除以最大公因数即可得到最小公倍数(least common multiple, LCM)。 + + + + + +```cpp +int gcd(int a, int b) { + return b == 0 ? a : gcd(b, a % b); +} + +int lcm(int a, int b) { + return a * b / gcd(a, b); +} +``` + + + + +```py +def gcd(a: int, b: int) -> int: + return a if b == 0 else gcd(b, a % b) + +def lcm(a: int, b: int) -> int: + return (a * b) // gcd(a, b) +``` + + + + + +进一步地,我们也可以通过扩展欧几里得算法(extended gcd)在求得 a 和 b 最大公因数的同时,也得到它们的系数 x 和 y,从而使 ax + by = gcd(a, b)。因为 Python 中 int 只能按值传递,我们可以用一个长度固定为 1 的 list() 来进行传递引用的操作。 + + + + +```cpp +int xGCD(int a, int b, int &x, int &y) { + if (b == 0) { + x = 1, y = 0; + return a; + } + int x_inner, y_inner; + int gcd = xGCD(b, a % b, x_inner, y_inner); + x = y_inner, y = x_inner - (a / b) * y_inner; + return gcd; +} +``` + + + + +```py +def xGCD(a: int, b: int, x: List[int], y: List[int]) -> int: + if b == 0: + x[0], y[0] = 1, 0 + return a + x_inner, y_inner = [0], [0] + gcd = xGCD(b, a % b, x_inner, y_inner) + x[0], y[0] = y_inner, x_inner - (a / b) * y_inner + return gcd +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/8-mathematical-solutions/8-3-prime-numbers.md b/leetcode_101/docs/8-mathematical-solutions/8-3-prime-numbers.md deleted file mode 100644 index 4347ee4f..00000000 --- a/leetcode_101/docs/8-mathematical-solutions/8-3-prime-numbers.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 40 ---- - -# 8.3 质数 diff --git a/leetcode_101/docs/8-mathematical-solutions/8-3-prime-numbers.mdx b/leetcode_101/docs/8-mathematical-solutions/8-3-prime-numbers.mdx new file mode 100644 index 00000000..fc8855f8 --- /dev/null +++ b/leetcode_101/docs/8-mathematical-solutions/8-3-prime-numbers.mdx @@ -0,0 +1,138 @@ +--- +sidebar_position: 40 +--- + +# 8.3 质数 + +质数又称素数,指的是指在大于 1 的自然数中,除了 1 和它本身以外不再有其他因数的自然数。值得注意的是,每一个数都可以分解成质数的乘积。 + + +## [204. Count Primes](https://leetcode.com/problems/count-primes/) + +### 题目描述 + +给定一个数字 n,求小于 n 的质数的个数。 + +### 输入输出样例 + +输入一个整数,输出也是一个整数,表示小于输入数的质数的个数。 + +``` +Input: 10 +Output: 4 +``` + +在这个样例中,小于 10 的质数只有 [2,3,5,7]。 + +### 题解 + +`埃拉托斯特尼筛法`(Sieve of Eratosthenes,简称埃氏筛法)是非常常用的,判断一个整数是否是质数的方法。并且它可以在判断一个整数 n 时,同时判断所小于 n 的整数,因此非常适合这道题。其原理也十分易懂:从 1 到 n 遍历,假设当前遍历到 m,则把所有小于 n 的、且是 m 的倍数的整数标为和数;遍历完成后,没有被标为和数的数字即为质数。 + + + + +```cpp +int countPrimes(int n) { + if (n <= 2) { + return 0; + } + vector primes(n, true); + int count = n - 2; // 去掉不是质数的1 + for (int i = 2; i < n; ++i) { + if (primes[i]) { + for (int j = 2 * i; j < n; j += i) { + if (primes[j]) { + primes[j] = false; + --count; + } + } + } + } + return count; +} +``` + + + + +```py +def countPrimes(n: int) -> int: + if n <= 2: + return 0 + primes = [True for _ in range(n)] + count = n - 2 # 去掉不是质数的1 + for i in range(2, n): + if primes[i]: + for j in range(2 * i, n, i): + if primes[j]: + primes[j] = False + count -= 1 + return count +``` + + + + + +利用质数的一些性质,我们可以进一步优化该算法。 + + + + + +```cpp +int countPrimes(int n) { + if (n <= 2) { + return 0; + } + vector primes(n, true); + int sqrtn = sqrt(n); + int count = n / 2; // 偶数一定不是质数 + int i = 3; + // 最小质因子一定小于等于开方数。 + while (i <= sqrtn) { + // 向右找倍数,注意避免偶数和重复遍历。 + for (int j = i * i; j < n; j += 2 * i) { + if (primes[j]) { + --count; + primes[j] = false; + } + } + i += 2; + // 向右前进查找位置,注意避免偶数和重复遍历。 + while (i <= sqrtn && !primes[i]) { + i += 2; + } + } + return count; +} +``` + + + + +```py +def countPrimes(n: int) -> int: + if n <= 2: + return 0 + primes = [True for _ in range(n)] + sqrtn = sqrt(n) + count = n // 2 # 偶数一定不是质数 + i = 3 + # 最小质因子一定小于等于开方数。 + while i <= sqrtn: + # 向右找倍数,注意避免偶数和重复遍历。 + for j in range(i * i, n, 2 * i): + if primes[j]: + count -= 1 + primes[j] = False + i += 2 + # 向右前进查找位置,注意避免偶数和重复遍历。 + while i <= sqrtn and not primes[i]: + i += 2 + return count +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/8-mathematical-solutions/8-4-number-processing.md b/leetcode_101/docs/8-mathematical-solutions/8-4-number-processing.md deleted file mode 100644 index 1248062e..00000000 --- a/leetcode_101/docs/8-mathematical-solutions/8-4-number-processing.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 41 ---- - -# 8.4 数字处理 diff --git a/leetcode_101/docs/8-mathematical-solutions/8-4-number-processing.mdx b/leetcode_101/docs/8-mathematical-solutions/8-4-number-processing.mdx new file mode 100644 index 00000000..67853aa2 --- /dev/null +++ b/leetcode_101/docs/8-mathematical-solutions/8-4-number-processing.mdx @@ -0,0 +1,318 @@ +--- +sidebar_position: 41 +--- + +# 8.4 数字处理 + +## [504. Base 7](https://leetcode.com/problems/base-7/) + +### 题目描述 + +给定一个十进制整数,求它在七进制下的表示。 + +### 输入输出样例 + +输入一个整数,输出一个字符串,表示其七进制。 + +``` +Input: 100 +Output: "202" +``` + +在这个样例中,100 的七进制表示法来源于 101 = 2 * 49 + 0 * 7 + 2 * 1。 + +### 题解 + +`进制转换`类型的题,通常是利用除法和取模(mod)来进行计算,同时也要注意一些细节,如负数和零。如果输出是数字类型而非字符串,则也需要考虑是否会超出整数上下界。 + + + + +```cpp +string convertToBase7(int num) { + if (num == 0) { + return "0"; + } + string base7; + bool is_negative = num < 0; + num = abs(num); + while (num) { + int quotient = num / 7, remainder = num % 7; + base7 = to_string(remainder) + base7; + num = quotient; + } + return is_negative ? "-" + base7 : base7; +} +``` + + + + +```py +def convertToBase7(num: int) -> str: + if num == 0: + return "0" + base7 = "" + is_negative = num < 0 + num = abs(num) + while num: + quotient, remainder = num // 7, num % 7 + base7 = str(remainder) + base7 + num = quotient + return "-" + base7 if is_negative else base7 +``` + + + + + +## [172. Factorial Trailing Zeroes](https://leetcode.com/problems/factorial-trailing-zeroes/) + +### 题目描述 + +给定一个非负整数,判断它的阶乘结果的结尾有几个 0。 + +### 输入输出样例 + +输入一个非负整数,输出一个非负整数,表示输入的阶乘结果的结尾有几个 0。 + +``` +Input: 12 +Output: 2 +``` + +在这个样例中,12 != 479001600 的结尾有两个 0。 + +### 题解 + +每个尾部的 0 由 2 × 5 =10 而来,因此我们可以把阶乘的每一个元素拆成质数相乘,统计有多少个 2 和 5。明显的,质因子 2 的数量远多于质因子 5 的数量,因此我们可以只统计阶乘结果里有多少个质因子 5。 + + + + +```cpp +int trailingZeroes(int n) { + return n == 0 ? 0 : n / 5 + trailingZeroes(n / 5); +} +``` + + + + +```py +def trailingZeroes(n: int) -> int: + return 0 if n == 0 else n // 5 + trailingZeroes(n // 5) +``` + + + + + +## [415. Add Strings](https://leetcode.com/problems/add-strings/) + +### 题目描述 + +给定两个由数字组成的字符串,求它们相加的结果。 + +### 输入输出样例 + +输入是两个字符串,输出是一个整数,表示输入的数字和。 + +``` +Input: num1 = "99", num2 = "1" +Output: 100 +``` + +因为相加运算是从后往前进行的,所以可以先翻转字符串,再逐位计算。这种类型的题考察的是细节,如进位、位数差等等。 + +### 题解 + + + + + + +```cpp +string addStrings(string num1, string num2) { + string added_str; + reverse(num1.begin(), num1.end()); + reverse(num2.begin(), num2.end()); + int len1 = num1.length(), len2 = num2.length(); + if (len1 <= len2) { + swap(num1, num2); + swap(len1, len2); + } + int add_bit = 0; + for (int i = 0; i < len1; ++i) { + int cur_sum = + (num1[i] - ’0’) + (i < len2 ? num2[i] - ’0’ : 0) + add_bit; + added_str += to_string(cur_sum % 10); + add_bit = cur_sum >= 10; + } + if (add_bit) { + added_str += "1"; + } + reverse(added_str.begin(), added_str.end()); + return added_str; +} +``` + + + + +```py +def addStrings(num1: str, num2: str) -> str: + added_str = "" + num1 = num1[::-1] + num2 = num2[::-1] + len1, len2 = len(num1), len(num2) + if len1 <= len2: + num1, num2 = num2, num1 + len1, len2 = len2, len1 + add_bit = 0 + for i in range(len1): + cur_sum = int(num1[i]) + (int(num2[i]) if i < len2 else 0) + add_bit + added_str += str(cur_sum % 10) + add_bit = int(cur_sum >= 10) + if add_bit: + added_str += "1" + return added_str[::-1] +``` + + + + + + +## [326. Power of Three](https://leetcode.com/problems/power-of-three/) + +### 题目描述 + +判断一个数字是否是 3 的次方。 + +### 输入输出样例 + +输入一个整数,输出一个布尔值。 + +``` +Input: n = 27 +Output: true +``` + +### 题解 + +有两种方法,一种是利用对数。设 log3 n =m,如果 n 是 3 的整数次方,那么 m 一定是整数。 + + + + +```cpp +bool isPowerOfThree(int n) { + return fmod(log10(n) / log10(3), 1) == 0; +} +``` + + + + +```py +def isPowerOfThree(n: int) -> bool: + return n > 0 and math.fmod(math.log10(n) / math.log10(3), 1) == 0 +``` + + + + + +另一种方法是,因为在 C++ int 范围内 3 的最大次方是 $3^{19} = 1162261467$,如果 n 是 3 的整数次方,那么 1162261467 除以 n 的余数一定是零;反之亦然。然而对于 Python 来说,因为 int 理论上可以取无穷大,我们只能循环判断。 + + + + +```cpp +bool isPowerOfThree(int n) { + return n > 0 && 1162261467 % n == 0; +} +``` + + + + +```py +def isPowerOfThree(n: int) -> bool: + if n <= 0: + return False + while n % 3 == 0: + n //= 3 + return n == 1 +``` + + + + + +## [50. Pow(x, n)](https://leetcode.com/problems/powx-n/) + +### 题目描述 + +计算 x 的 n 次方。 + +### 输入输出样例 + +输入一个浮点数表示 x 和一个整数表示 n,输出一个浮点数表示次方结果。 + +``` +Input: x = 2.00000, n = 10 +Output: 1024.00000 +``` + +### 题解 + + +利用递归,我们可以较为轻松地解决本题。注意边界条件的处理。 + + + + +```cpp +double myPow(double x, int n) { + if (n == 0) { + return 1; + } + if (x == 0) { + return 0; + } + if (n == numeric_limits::min()) { + return 1 / (x * myPow(x, numeric_limits::max())); + } + if (n < 0) { + return 1 / myPow(x, -n); + } + if (n % 2 != 0) { + return x * myPow(x, n - 1); + } + double myPowSqrt = myPow(x, n >> 1); + return myPowSqrt * myPowSqrt; +} +``` + + + + +```py +def myPow(x: float, n: int) -> float: + if n == 0: + return 1 + if x == 0: + return 0 + if n < 0: + return 1 / myPow(x, -n) + if n % 2 != 0: + return x * myPow(x, n - 1) + myPowSqrt = myPow(x, n >> 1) + return myPowSqrt * myPowSqrt +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/8-mathematical-solutions/8-5-random-sampling.md b/leetcode_101/docs/8-mathematical-solutions/8-5-random-sampling.md deleted file mode 100644 index e850b084..00000000 --- a/leetcode_101/docs/8-mathematical-solutions/8-5-random-sampling.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 42 ---- - -# 8.5 随机与取样 diff --git a/leetcode_101/docs/8-mathematical-solutions/8-5-random-sampling.mdx b/leetcode_101/docs/8-mathematical-solutions/8-5-random-sampling.mdx new file mode 100644 index 00000000..d2b4c716 --- /dev/null +++ b/leetcode_101/docs/8-mathematical-solutions/8-5-random-sampling.mdx @@ -0,0 +1,228 @@ +--- +sidebar_position: 42 +--- + +# 8.5 随机与取样 + +## [384. Shuffle an Array](https://leetcode.com/problems/shuffle-an-array/) + +### 题目描述 + +给定一个数组,要求实现两个指令函数。第一个函数“shuffle”可以随机打乱这个数组,第二个函数“reset”可以恢复原来的顺序。 + +### 输入输出样例 + +输入是一个存有整数数字的数组,和一个包含指令函数名称的数组。输出是一个二维数组,表示每个指令生成的数组。 + +``` +Input: nums = [1,2,3], actions: ["shuffle","shuffle","reset"] +Output: [[2,1,3],[3,2,1],[1,2,3]] +``` + +在这个样例中,前两次打乱的结果只要是随机生成即可。 + +### 题解 + +我们采用经典的 `Fisher-Yates 洗牌算法`,原理是通过随机交换位置来实现随机打乱,有正向和反向两种写法,且实现非常方便。注意这里“reset”函数以及 Solution 类的构造函数的实现细节。 + + + + +```cpp +class Solution { + public: + Solution(vector nums) : nums_(nums) {} + + vector reset() { return nums_; } + + vector shuffle() { + vector shuffled(nums_); + int n = nums_.size(); + // 可以使用反向或者正向洗牌,效果相同。 + // 反向洗牌: + for (int i = n - 1; i >= 0; --i) { + swap(shuffled[i], shuffled[rand() % (i + 1)]); + } + // 正向洗牌: + // for (int i = 0; i < n; ++i) { + // int pos = rand() % (n - i); + // swap(shuffled[i], shuffled[i+pos]); + // } + return shuffled; + } + + private: + vector nums_; +}; +``` + + + + +```py +class Solution: + def __init__(self, nums: List[int]): + self.base = nums[:] + + def reset(self) -> List[int]: + return self.base[:] + + def shuffle(self) -> List[int]: + shuffled = self.base[:] + n = len(self.base) + # 可以使用反向或者正向洗牌,效果相同。 + # 反向洗牌: + for i in range(n - 1, -1, -1): + j = random.randint(0, i) + shuffled[i], shuffled[j] = shuffled[j], shuffled[i] + # 正向洗牌: + # for i in range(n): + # j = i + random.randint(0, n - i - 1) + # shuffled[i], shuffled[j] = shuffled[j], shuffled[i] + return shuffled +``` + + + + + +## [528. Random Pick with Weight](https://leetcode.com/problems/random-pick-with-weight/) + +### 题目描述 + +给定一个数组,数组每个位置的值表示该位置的权重,要求按照权重的概率去随机采样。 + +### 输入输出样例 + +输入是一维正整数数组,表示权重;和一个包含指令字符串的一维数组,表示运行几次随机采样。输出是一维整数数组,表示随机采样的整数在数组中的位置。 + +``` +Input: weights = [1,3], actions: ["pickIndex","pickIndex","pickIndex"] +Output: [0,1,1] +``` + +在这个样例中,每次选择的位置都是不确定的,但选择第 0 个位置的期望为 1/4,选择第 1 个位置的期望为 3/4。 + +### 题解 + +我们可以先使用 partial_sum求前缀和(即到每个位置为止之前所有数字的和),这个结果对于正整数数组是单调递增的。每当需要采样时,我们可以先随机产生一个数字,然后使用二分法查找其在前缀和中的位置,以模拟加权采样的过程。这里的二分法可以用 lower_bound 实现。 + +以样例为例,权重数组 [1,3] 的前缀和为 [1,4]。如果我们随机生成的数字为 1,那么 lower_bound 返回的位置为 0;如果我们随机生成的数字是 2、3、4,那么 lower_bound 返回的位置为 1。 + +关于前缀和的更多技巧,我们将在接下来的章节中继续深入讲解。 + + + + +```cpp +class Solution { + public: + Solution(vector weights) : cumsum_(weights) { + partial_sum(cumsum_.begin(), cumsum_.end(), cumsum_.begin()); + } + + int pickIndex() { + int val = (rand() % cumsum_.back()) + 1; + return lower_bound(cumsum_.begin(), cumsum_.end(), val) - + cumsum_.begin(); + } + + private: + vector cumsum_; +}; +``` + + + + +```py +class Solution: + def __init__(self, weights: List[int]): + self.cumsum = weights[:] + for i in range(1, len(weights)): + self.cumsum[i] += self.cumsum[i - 1] + + def pickIndex(self) -> int: + val = random.randint(1, self.cumsum[-1]) + return bisect.bisect_left(self.cumsum, val, 0, len(self.cumsum)) +``` + + + + + +## [382. Linked List Random Node](https://leetcode.com/problems/linked-list-random-node/) + +### 题目描述 + +给定一个单向链表,要求设计一个算法,可以随机取得其中的一个数字。 + +### 输入输出样例 + +输入是一个单向链表,输出是一个数字,表示链表里其中一个节点的值。 + +``` +Input: 1->2->3->4->5 +Output: 3 +``` + +在这个样例中,我们有均等的概率得到任意一个节点,比如 3。 + +### 题解 + +不同于数组,在未遍历完链表前,我们无法知道链表的总长度。这里我们就可以使用水库采样:遍历一次链表,在遍历到第 m 个节点时,有 $\frac{1}{m}$ 的概率选择这个节点覆盖掉之前的节点选择。 + +我们提供一个简单的,对于水库算法随机性的证明。对于长度为 n 的链表的第 m 个节点,最后被采样的充要条件是它被选择,且之后的节点都没有被选择。这种情况发生的概率为 $\frac{1}{m} × \frac{m}{m+1} × \frac{m}{m+2} × · · · × \frac{n−1}{n} = \frac{1}{n}$。因此每个点都有均等的概率被选择。 + +当然,这道题我们也可以预处理链表,遍历一遍之后把它转化成数组。 + + + + +```cpp +class Solution { + public: + Solution(ListNode* node) : head_(node) {} + + int getRandom() { + int pick = head_->val; + ListNode* node = head_->next; + int i = 2; + while (node) { + if (rand() % i == 0) { + pick = node->val; + } + ++i; + node = node->next; + } + return pick; + } + + private: + ListNode* head_; +}; +``` + + + + +```py +class Solution: + def __init__(self, head: Optional[ListNode]): + self.head = head + + def getRandom(self) -> int: + pick = self.head.val + node = self.head.next + i = 2 + while node is not None: + if random.randint(0, i - 1) == 0: + pick = node.val + i += 1 + node = node.next + return pick +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/8-mathematical-solutions/8-6-exercises.md b/leetcode_101/docs/8-mathematical-solutions/8-6-exercises.md index e7069897..5d4495c3 100644 --- a/leetcode_101/docs/8-mathematical-solutions/8-6-exercises.md +++ b/leetcode_101/docs/8-mathematical-solutions/8-6-exercises.md @@ -3,3 +3,35 @@ sidebar_position: 43 --- # 8.6 练习 + +## 基础难度 + +### [168. Excel Sheet Column Title](https://leetcode.com/problems/excel-sheet-column-title/) + +7 进制转换的变种题,需要注意的一点是从 1 开始而不是 0。 + +### [67. Add Binary](https://leetcode.com/problems/add-binary/) + +字符串加法的变种题。 + +### [238. Product of Array Except Self](https://leetcode.com/problems/product-of-array-except-self/) + +你可以不使用除法做这道题吗?我们很早之前讲过的题目 135 或许能给你一些思路。 + +## 进阶难度 + +### [462. Minimum Moves to Equal Array Elements II](https://leetcode.com/problems/minimum-moves-to-equal-array-elements-ii/) + +这道题是笔者最喜欢的 LeetCode 题目之一,需要先推理出怎么样移动是最优的,再考虑如何进行移动。你或许需要一些前些章节讲过的算法。 + +### [169. Majority Element](https://leetcode.com/problems/majority-element/) + +如果想不出简单的解决方法,搜索一下 Boyer-Moore Majority Vote 算法吧。 + +### [470. Implement Rand10() Using Rand7()](https://leetcode.com/problems/implement-rand10-using-rand7/) + +如何用一个随机数生成器生成另一个随机数生成器?你可能需要利用原来的生成器多次。 + +### [202. Happy Number](https://leetcode.com/problems/happy-number/) + +你可以简单的用一个 while 循环解决这道题,但是有没有更好的解决办法?如果我们把每个数字想象成一个节点,是否可以转化为环路检测? \ No newline at end of file diff --git a/leetcode_101/docs/8-mathematical-solutions/_category_.json b/leetcode_101/docs/8-mathematical-solutions/_category_.json index e366176e..5fb8df9e 100644 --- a/leetcode_101/docs/8-mathematical-solutions/_category_.json +++ b/leetcode_101/docs/8-mathematical-solutions/_category_.json @@ -3,6 +3,6 @@ "position": 8, "link": { "type": "generated-index", - "description": "5 minutes to learn the most important Docusaurus concepts." + "description": "第 8 章 巧解数学问题" } } From 3f245395b46457bfa59852c61a50f24b9ec3392d Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Thu, 14 Nov 2024 10:43:17 +0100 Subject: [PATCH 12/49] chapter 9 --- .../9-1-common-techniques.md | 19 ++ .../9-2-basic-bitwise-problems.md | 5 - .../9-2-basic-bitwise-problems.mdx | 181 ++++++++++++++++++ .../9-3-binary-properties.md | 5 - .../9-3-binary-properties.mdx | 123 ++++++++++++ .../9-bitwise-operations/9-4-exercises.md | 20 ++ .../docs/9-bitwise-operations/_category_.json | 2 +- 7 files changed, 344 insertions(+), 11 deletions(-) delete mode 100644 leetcode_101/docs/9-bitwise-operations/9-2-basic-bitwise-problems.md create mode 100644 leetcode_101/docs/9-bitwise-operations/9-2-basic-bitwise-problems.mdx delete mode 100644 leetcode_101/docs/9-bitwise-operations/9-3-binary-properties.md create mode 100644 leetcode_101/docs/9-bitwise-operations/9-3-binary-properties.mdx diff --git a/leetcode_101/docs/9-bitwise-operations/9-1-common-techniques.md b/leetcode_101/docs/9-bitwise-operations/9-1-common-techniques.md index 8cd22e0e..30f955ca 100644 --- a/leetcode_101/docs/9-bitwise-operations/9-1-common-techniques.md +++ b/leetcode_101/docs/9-bitwise-operations/9-1-common-techniques.md @@ -3,3 +3,22 @@ sidebar_position: 44 --- # 9.1 常用技巧 + +`位运算`是算法题里比较特殊的一种类型,它们利用二进制位运算的特性进行一些奇妙的优化和计算。常用的位运算符号包括: + +- `∧`:按位异或 +- `&`:按位与 +- `|`:按位或 +- `~`:取反 +- `<<`:算术左移 +- `>>`:算术右移 + +以下是一些常见的位运算特性,其中 `0s` 和 `1s` 分别表示只由 `0` 或 `1` 构成的二进制数字。 + +``` +x ^ 0s = x x & 0s = 0 x | 0s = x +x ^ 1s = ~x x & 1s = x x | 1s = 1s +x ^ x = 0 x & x = x x | x = x +``` + +除此之外,n & (n - 1) 可以去除 n 的位级表示中最低的那一位,例如对于二进制表示 11110100,减去 1 得到 11110011,这两个数按位与得到 11110000。n & (-n) 可以得到 n 的位级表示中最低的那一位,例如对于二进制表示 11110100,取负得到 00001100,这两个数按位与得到 00000100。还有更多的并不常用的技巧,若读者感兴趣可以自行研究,这里不再赘述。 \ No newline at end of file diff --git a/leetcode_101/docs/9-bitwise-operations/9-2-basic-bitwise-problems.md b/leetcode_101/docs/9-bitwise-operations/9-2-basic-bitwise-problems.md deleted file mode 100644 index 9ac4630e..00000000 --- a/leetcode_101/docs/9-bitwise-operations/9-2-basic-bitwise-problems.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 45 ---- - -# 9.2 位运算基础问题 diff --git a/leetcode_101/docs/9-bitwise-operations/9-2-basic-bitwise-problems.mdx b/leetcode_101/docs/9-bitwise-operations/9-2-basic-bitwise-problems.mdx new file mode 100644 index 00000000..743a16ac --- /dev/null +++ b/leetcode_101/docs/9-bitwise-operations/9-2-basic-bitwise-problems.mdx @@ -0,0 +1,181 @@ +--- +sidebar_position: 45 +--- + +# 9.2 位运算基础问题 + +## [461. Hamming Distance](https://leetcode.com/problems/hamming-distance/) + +### 题目描述 + +给定两个十进制数字,求它们二进制表示的汉明距离(Hamming distance,即不同位的个数)。 + +### 输入输出样例 + +输入是两个十进制整数,输出是一个十进制整数,表示两个输入数字的汉明距离。 + +``` +Input: x = 1, y = 4 +Output: 2 +``` + +在这个样例中,1 的二进制是 0001,4 的二进制是 0100,一共有两位不同。 + +### 题解 + +对两个数进行按位异或操作,统计有多少个 1 即可。 + + + + +```cpp +int hammingDistance(int x, int y) { + int diff = x ^ y, dist = 0; + while (diff != 0) { + dist += diff & 1; + diff >>= 1; + } + return dist; +} +``` + + + + +```py +def hammingDistance(x: int, y: int) -> int: + diff = x ^ y + dist = 0 + while diff != 0: + dist += diff & 1 + diff = diff >> 1 + return dist +``` + + + + + +## [190. Reverse Bits](https://leetcode.com/problems/reverse-bits/) + +### 题目描述 + +给定一个十进制正整数,输出它在二进制下的翻转结果。 + +### 输入输出样例 + +输入和输出都是十进制正整数。 + +``` +Input: 43261596 (00000010100101000001111010011100) +Output: 964176192 (00111001011110000010100101000000) +``` + +使用算术左移和右移,可以很轻易地实现二进制的翻转。 + +### 题解 + + + + + + +```cpp +uint32_t reverseBits(uint32_t n) { + uint32_t m = 0; + for (int i = 0; i < 32; ++i) { + m <<= 1; + m += n & 1; + n >>= 1; + } + return m; +} +``` + + + + +```py +def reverseBits(n: int) -> int: + m = 0 + for _ in range(32): + m = m << 1 + m += n & 1 + n = n >> 1 + return m +``` + + + + + +## [136. Single Number](https://leetcode.com/problems/single-number/) + +### 题目描述 + +给定一个整数数组,这个数组里只有一个数次出现了一次,其余数字出现了两次,求这个只出现一次的数字。 + +### 输入输出样例 + +输入是一个一维整数数组,输出是该数组内的一个整数。 + +``` +Input: [4,1,2,1,2] +Output: 4 +``` + +### 题解 + +我们可以利用 x ∧ x = 0 和 x ∧ 0 = x 的特点,将数组内所有的数字进行按位异或。出现两次的所有数字按位异或的结果是 0,0 与出现一次的数字异或可以得到这个数字本身。 + + + + +```cpp +int singleNumber(vector& nums) { + int single = 0; + for (int num : nums) { + single ^= num; + } + return single; +} +``` + + + + +```py +def singleNumber(nums: List[int]) -> int: + single = 0 + for num in nums: + single = single ^ num + return single +``` + + + + + +这里我们也可以直接使用 reduce 函数: + + + + +```cpp +int singleNumber(vector& nums) { + return reduce(nums.begin(), nums.end(), 0, + [](int x, int y) { return x ^ y; }); +} +``` + + + + +```py +def singleNumber(nums: List[int]) -> int: + return functools.reduce(lambda x, y: x ^ y, nums) +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/9-bitwise-operations/9-3-binary-properties.md b/leetcode_101/docs/9-bitwise-operations/9-3-binary-properties.md deleted file mode 100644 index 823ef77b..00000000 --- a/leetcode_101/docs/9-bitwise-operations/9-3-binary-properties.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 46 ---- - -# 9.3 二进制特性 diff --git a/leetcode_101/docs/9-bitwise-operations/9-3-binary-properties.mdx b/leetcode_101/docs/9-bitwise-operations/9-3-binary-properties.mdx new file mode 100644 index 00000000..51d3b410 --- /dev/null +++ b/leetcode_101/docs/9-bitwise-operations/9-3-binary-properties.mdx @@ -0,0 +1,123 @@ +--- +sidebar_position: 46 +--- + +# 9.3 二进制特性 + +利用二进制的一些特性,我们可以把位运算使用到更多问题上。 + +例如,我们可以利用二进制和位运算输出一个数组的所有子集。假设我们有一个长度为 $n$ 的数组,我们可以生成长度为 $n$ 的所有二进制,1 表示选取该数字,0 表示不选取。这样我们就获得了 $2^n$ 个子集。 + +## [318. Maximum Product of Word Lengths](https://leetcode.com/problems/maximum-product-of-word-lengths/) + +### 题目描述 + +给定多个字母串,求其中任意两个字母串的长度乘积的最大值,且这两个字母串不能含有相同字母。 + +### 输入输出样例 + +输入一个包含多个字母串的一维数组,输出一个整数,表示长度乘积的最大值。 + +``` +Input: ["a","ab","abc","d","cd","bcd","abcd"] +Output: 4 +``` + +在这个样例中,一种最优的选择是“ab”和“cd”。 + +### 题解 + +怎样快速判断两个字母串是否含有重复数字呢?可以为每个字母串建立一个长度为 26 的二进制数字,每个位置表示是否存在该字母。如果两个字母串含有重复数字,那它们的二进制表示的按位与不为 0。同时,我们可以建立一个哈希表来存储二进制数字到最长子母串长度的映射关系,比如 ab 和 aab 的二进制数字相同,但是 aab 更长。 + + + + +```cpp +int maxProduct(vector& words) { + unordered_map cache; + int max_prod = 0; + for (const string& word : words) { + int mask = 0, w_len = word.length(); + for (char c : word) { + mask |= 1 << (c - ’a’); + } + cache[mask] = max(cache[mask], w_len); + for (auto [h_mask, h_len] : cache) { + if ((mask & h_mask) == 0) { + max_prod = max(max_prod, w_len * h_len); + } + } + } + return max_prod; +} +``` + + + + +```py +def maxProduct(words: List[str]) -> int: + cache = dict() + max_prod = 0 + for word in words: + mask, w_len = 0, len(word) + for c in word: + mask = mask | (1 << (ord(c) - ord("a"))) + cache[mask] = max(cache.get(mask, 0), w_len) + for h_mask, h_len in cache.items(): + if (mask & h_mask) == 0: + max_prod = max(max_prod, w_len * h_len) + return max_prod +``` + + + + + +## [338. Counting Bits](https://leetcode.com/problems/counting-bits/) + +### 题目描述 + +给定一个非负整数 n,求从 0 到 n 的所有数字的二进制表达中,分别有多少个 1。 + +### 输入输出样例 + +输入是一个非负整数 n,输出是长度为 n +1 的非负整数数组,每个位置 m 表示 m 的二进制里有多少个 1。 + +``` +Input: 5 +Output: [0,1,1,2,1,2] +``` + +### 题解 + +本题可以利用动态规划和位运算进行快速的求解。定义一个数组 dp,其中 dp[i] 表示数字 i 的二进制含有 1 的个数。对于第 i 个数字,如果它二进制的最后一位为 1,那么它含有 1 的个数则为 dp[i-1] + 1;如果它二进制的最后一位为 0,那么它含有 1 的个数和其算术右移结果相同,即 dp[i>>1]。 + + + + +```cpp +vector countBits(int n) { + vector dp(n + 1, 0); + for (int i = 1; i <= n; ++i) + // 等价于:dp[i] = dp[i & (i - 1)] + 1; + dp[i] = i & 1 ? dp[i - 1] + 1 : dp[i >> 1]; + return dp; +} +``` + + + + +```py +def countBits(n: int) -> List[int]: + dp = [0] * (n + 1) + for i in range(1, n + 1): + # 等价于:dp[i] = dp[i & (i - 1)] + 1 + dp[i] = dp[i - 1] + 1 if i & 1 else dp[i >> 1] + return dp +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/9-bitwise-operations/9-4-exercises.md b/leetcode_101/docs/9-bitwise-operations/9-4-exercises.md index 704d4fdb..b813d8a1 100644 --- a/leetcode_101/docs/9-bitwise-operations/9-4-exercises.md +++ b/leetcode_101/docs/9-bitwise-operations/9-4-exercises.md @@ -3,3 +3,23 @@ sidebar_position: 47 --- # 9.4 练习 + +## 基础难度 + +### [268. Missing Number](https://leetcode.com/problems/missing-number/) + +Single Number 的变种题。除了利用二进制,也可以使用高斯求和公式。 + +### [693. Binary Number with Alternating Bits](https://leetcode.com/problems/binary-number-with-alternating-bits/) + +利用位运算判断一个数的二进制是否会出现连续的 0 和 1。 + +### [476. Number Complement](https://leetcode.com/problems/number-complement/) + +二进制翻转的变种题。 + +## 进阶难度 + +### [260. Single Number III](https://leetcode.com/problems/single-number-iii/) + +Single Number 的 follow-up,需要认真思考如何运用位运算求解。 \ No newline at end of file diff --git a/leetcode_101/docs/9-bitwise-operations/_category_.json b/leetcode_101/docs/9-bitwise-operations/_category_.json index 9b1495a0..dc298905 100644 --- a/leetcode_101/docs/9-bitwise-operations/_category_.json +++ b/leetcode_101/docs/9-bitwise-operations/_category_.json @@ -3,6 +3,6 @@ "position": 9, "link": { "type": "generated-index", - "description": "5 minutes to learn the most important Docusaurus concepts." + "description": "第 9 章 神奇的位运算" } } From 5e8cf7a8e2d07fc6c4fe677401b5eb72b9735100 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Thu, 14 Nov 2024 11:42:02 +0100 Subject: [PATCH 13/49] chapter 10 --- .../docs/10-data-structures/10-1-cpp-stl.md | 25 ++ .../10-10-prefix-sum-integral-image.md | 5 - .../10-10-prefix-sum-integral-image.mdx | 226 ++++++++++++++ .../10-data-structures/10-11-exercises.md | 48 +++ .../10-2-python-data-structures.md | 17 + .../docs/10-data-structures/10-3-arrays.md | 5 - .../docs/10-data-structures/10-3-arrays.mdx | 250 +++++++++++++++ .../10-4-stack-and-queue.md | 5 - .../10-4-stack-and-queue.mdx | 257 +++++++++++++++ .../10-5-monotonic-stack.md | 5 - .../10-5-monotonic-stack.mdx | 72 +++++ .../10-data-structures/10-6-priority-queue.md | 5 - .../10-6-priority-queue.mdx | 295 ++++++++++++++++++ .../docs/10-data-structures/10-7-deque.md | 5 - .../docs/10-data-structures/10-7-deque.mdx | 82 +++++ .../10-data-structures/10-8-hash-table.md | 5 - .../10-data-structures/10-8-hash-table.mdx | 232 ++++++++++++++ .../10-9-multisets-and-maps.md | 5 - .../10-9-multisets-and-maps.mdx | 87 ++++++ leetcode_101/docs/10-data-structures/10.1.png | Bin 0 -> 37020 bytes leetcode_101/docs/10-data-structures/10.2.png | Bin 0 -> 109141 bytes leetcode_101/docs/10-data-structures/10.3.png | Bin 0 -> 72740 bytes leetcode_101/docs/10-data-structures/10.4.png | Bin 0 -> 39987 bytes leetcode_101/docs/10-data-structures/10.5.png | Bin 0 -> 42518 bytes .../docs/10-data-structures/_category_.json | 2 +- 25 files changed, 1592 insertions(+), 41 deletions(-) delete mode 100644 leetcode_101/docs/10-data-structures/10-10-prefix-sum-integral-image.md create mode 100644 leetcode_101/docs/10-data-structures/10-10-prefix-sum-integral-image.mdx delete mode 100644 leetcode_101/docs/10-data-structures/10-3-arrays.md create mode 100644 leetcode_101/docs/10-data-structures/10-3-arrays.mdx delete mode 100644 leetcode_101/docs/10-data-structures/10-4-stack-and-queue.md create mode 100644 leetcode_101/docs/10-data-structures/10-4-stack-and-queue.mdx delete mode 100644 leetcode_101/docs/10-data-structures/10-5-monotonic-stack.md create mode 100644 leetcode_101/docs/10-data-structures/10-5-monotonic-stack.mdx delete mode 100644 leetcode_101/docs/10-data-structures/10-6-priority-queue.md create mode 100644 leetcode_101/docs/10-data-structures/10-6-priority-queue.mdx delete mode 100644 leetcode_101/docs/10-data-structures/10-7-deque.md create mode 100644 leetcode_101/docs/10-data-structures/10-7-deque.mdx delete mode 100644 leetcode_101/docs/10-data-structures/10-8-hash-table.md create mode 100644 leetcode_101/docs/10-data-structures/10-8-hash-table.mdx delete mode 100644 leetcode_101/docs/10-data-structures/10-9-multisets-and-maps.md create mode 100644 leetcode_101/docs/10-data-structures/10-9-multisets-and-maps.mdx create mode 100644 leetcode_101/docs/10-data-structures/10.1.png create mode 100644 leetcode_101/docs/10-data-structures/10.2.png create mode 100644 leetcode_101/docs/10-data-structures/10.3.png create mode 100644 leetcode_101/docs/10-data-structures/10.4.png create mode 100644 leetcode_101/docs/10-data-structures/10.5.png diff --git a/leetcode_101/docs/10-data-structures/10-1-cpp-stl.md b/leetcode_101/docs/10-data-structures/10-1-cpp-stl.md index 5a52eaa5..2ec42832 100644 --- a/leetcode_101/docs/10-data-structures/10-1-cpp-stl.md +++ b/leetcode_101/docs/10-data-structures/10-1-cpp-stl.md @@ -3,3 +3,28 @@ sidebar_position: 48 --- # 10.1 C++ STL + +在刷题时,我们几乎一定会用到各种数据结构来辅助我们解决问题,因此我们必须熟悉各种数据结构的特点。C++ STL 提供的数据结构包括(实际底层细节可能因编译器而异): + +1. Sequence Containers:维持顺序的容器。 + 1. vector:`动态数组`,是我们最常使用的数据结构之一,用于 $O(1)$ 的随机读取。因为大部分算法的时间复杂度都会大于 $O(n)$,因此我们经常新建 vector 来存储各种数据或中间变量。因为在尾部增删的复杂度是 $O(1)$,我们也可以把它当作 stack 来用。 + 2. list:`双向链表`,也可以当作 stack 和 queue 来使用。由于 LeetCode 的题目多用 Node 来表示链表,且链表不支持快速随机读取,因此我们很少用到这个数据结构。一个例外是经典的 LRU 问题,我们需要利用链表的特性来解决,我们在后文会遇到这个问题。 + 3. deque:双端队列,这是一个非常强大的数据结构,既支持 $O(1)$ 随机读取,又支持 $O(1)$ 时间的头部增删和尾部增删(因此可以当作 stack 和 queue 来使用),不过有一定的额外开销。也可以用来近似一个双向链表来使用。 + 4. array:固定大小的数组,一般在刷题时我们不使用。 + 5. forward_list:单向链表,一般在刷题时我们不使用。 +2. Container Adaptors:基于其它容器实现的容器。 + 1. stack:`后入先出(LIFO)的数据结构`,默认基于 deque 实现。stack 常用于深度优先搜索、一些字符串匹配问题以及单调栈问题。 + 2. `先入先出(FIFO)的数据结构`,默认基于 deque 实现。queue 常用于广度优先搜索。 + 3. priority_queue:`优先队列(最大值先出的数据结构)`,默认基于 vector 实现堆结构。它可以在 $O(n \log n)$ 的时间排序数组,$O(\log n)$ 的时间插入任意值,$O(1)$ 的时间获得最大值,$O(\log n)$ 的时间删除最大值。priority_queue 常用于维护数据结构并快速获取最大值,并且可以自定义比较函数;比如通过存储负值或者更改比小函数为比大函数,即可实现最小值先出。 +3. Ordered Associative Containers:有序关联容器。 + 1. set:有序集合,元素不可重复,底层实现默认为红黑树,即一种特殊的二叉查找树(BST)。它可以在 $O(n \log n)$ 的时间排序数组,$O(\log n)$ 的时间插入、删除、查找任意值,$O(\log n)$ 的时间获得最小或最大值。这里注意,set 和 priority_queue 都可以用于维护数据结构并快速获取最大最小值,但是它们的时间复杂度和功能略有区别,如 priority_queue 默认不支持删除任意值,而 set 获得最大或最小值的时间复杂度略高,具体使用哪个根据需求而定。 + 2. multiset:支持重复元素的 set。 + 3. map:`有序映射或有序表`,在 set 的基础上加上映射关系,可以对每个元素 key 存一个值 value。 + 4. multimap:支持重复元素的 map。 +4. Unordered Associative Containers:无序关联容器。 + 1. unordered_set:`哈希集合`,可以在 $O(1)$ 的时间快速插入、查找、删除元素,常用于快速的查询一个元素是否在这个容器内。 + 2. unordered_multiset:支持重复元素的 unordered_set。 + 3. unordered_map:`哈希映射或哈希表`,在 unordered_set 的基础上加上映射关系,可以对每一个元素 key 存一个值 value。在某些情况下,如果 key 的范围已知且较小,我们也可以用 vector 代替 unordered_map,用位置表示 key,用每个位置的值表示 value。 + 4. unordered_multimap:支持重复元素的 unordered_map。 + +因为这并不是一本讲解 C++ 原理的书,更多的 STL 细节请读者自行搜索。只有理解了这些数据结构的原理和使用方法,才能够更加游刃有余地解决算法和数据结构问题。 diff --git a/leetcode_101/docs/10-data-structures/10-10-prefix-sum-integral-image.md b/leetcode_101/docs/10-data-structures/10-10-prefix-sum-integral-image.md deleted file mode 100644 index 41c32ba8..00000000 --- a/leetcode_101/docs/10-data-structures/10-10-prefix-sum-integral-image.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 57 ---- - -# 10.10 前缀和与积分图 diff --git a/leetcode_101/docs/10-data-structures/10-10-prefix-sum-integral-image.mdx b/leetcode_101/docs/10-data-structures/10-10-prefix-sum-integral-image.mdx new file mode 100644 index 00000000..16e8f7cd --- /dev/null +++ b/leetcode_101/docs/10-data-structures/10-10-prefix-sum-integral-image.mdx @@ -0,0 +1,226 @@ +--- +sidebar_position: 57 +--- + +# 10.10 前缀和与积分图 + +一维的前缀和(cumulative sum, cumsum),二维的积分图(summed-area table, image integral)都是把每个位置之前的一维线段或二维矩形预先存储,方便加速计算。如果需要对前缀和或积分图的值做寻址,则要存入哈希表;如果要对每个位置记录前缀和或积分图的值,则可以储存到一维或二维数组里,也常常伴随着动态规划。 + +## [303. Range Sum Query - Immutable](https://leetcode.com/problems/range-sum-query-immutable/) + +### 题目描述 + +设计一个数据结构,使得其能够快速查询给定数组中,任意两个位置间所有数字的和。 + +### 输入输出样例 + +以下是数据结构的调用样例。 + +``` +vector nums{-2,0,3,-5,2,-1}; +NumArray num_array = new NumArray(nums); +num_array.sumRange(0,2); // Result = -2+0+3 = 1. +num_array.sunRange(1,5); // Result = 0+3-5+2-1 = -1. +``` + +### 题解 + +对于一维的数组,我们可以使用前缀和来解决此类问题。先建立一个与数组 nums 长度相同的新数组 cumsum,表示 nums 每个位置之前前所有数字的和。cumsum 数组可以通过 C++ 自带的 partial_sum 函数建立,也可以直接遍历一遍 nums 数组,并利用状态转移方程 cumsum[i] = cumsum[i-1] + nums[i] 完成统计。如果我们需要获得位置 i 和 j 之间的数字和,只需计算 cum - sum[j+1] - cumsum[i] 即可。 + + + + +```cpp +class NumArray { + public: + NumArray(vector nums) : cumsum_(nums.size() + 1, 0) { + partial_sum(nums.begin(), nums.end(), cumsum_.begin() + 1); + } + + int sumRange(int left, int right) { + return cumsum_[right + 1] - cumsum_[left]; + } + + private: + vector cumsum_; +}; +``` + + + + +```py +class NumArray: + def __init__(self, nums: List[int]): + self.cumsum = [0] + nums[:] + for i in range(2, len(self.cumsum)): + self.cumsum[i] += self.cumsum[i - 1] + + def sumRange(self, left: int, right: int) -> int: + return self.cumsum[right + 1] - self.cumsum[left] +``` + + + + + +## [304. Range Sum Query 2D - Immutable](https://leetcode.com/problems/range-sum-query-2d-immutable/) + +### 题目描述 + +设计一个数据结构,使得其能够快速查询给定矩阵中,任意两个位置包围的长方形中所有数字的和。 + +### 输入输出样例 + +以下是数据结构的调用样例。其中 sumRegion 函数的四个输入分别是第一个点的横、纵坐标,和第二个点的横、纵坐标。 + +``` +vector matrix{{3,0,1,4,2}, + {5,6,3,2,1}, + {1,2,0,1,5}, + {4,1,0,1,7}, + {1,0,3,0,5} +}; +NumMatrix num_matrix = new NumMatrix(matrix); +num_matrix.sumRegion(2,1,4,3); // Result = 8. +num_matrix.sumRegion(1,1,2,2); // Result = 11. +``` + +### 题解 + +类似于前缀和,我们可以把这种思想拓展到二维,即积分图(summed-area table, image integral)。我们可以先建立一个 sat 矩阵,sat[i][j] 表示以位置 (0, 0) 为左上角、位置 (i-1, j-1) 为右下角的长方形中所有数字的和。 + +
+ + ![](10.4.png) + +
图 10.4: 题目 304 - 图 1 - 左边为给定矩阵,右边为积分图结果,右下角位置的积分图值为 5+48+45− 40 =58
+
+ + +
+ + ![](10.5.png) + +
图 10.5: 题目 304 - 图 2 - 左边为给定矩阵,右边为积分图结果,长方形 E 的数字和等于 58 − 11 − 13 +3 =37
+
+ +如图 1 所示,我们可以用动态规划来计算 sat 矩阵:sat[i][j] = matrix[i-1][j-1] + sat[i-1][j] + sat[i][j-1] - sat[i-1][j-1],即当前坐标的数字 + 上面长方形的数字和 + 左边长方形的数字和 - 上面长方形和左边长方形重合面积(即左上一格的长方形)中的数字和。 + +如图 2 所示,假设我们要查询长方形 E 的数字和,因为 E = D − B − C + A,我们发现 E 其实可以由四个位置的积分图结果进行加减运算得到。因此这个算法在预处理时的时间复杂度为 $O(mn)$,而在查询时的时间复杂度仅为 $O(1)$。 + + + + +```cpp +class NumMatrix { + public: + NumMatrix(vector> matrix) { + int m = matrix.size(), n = matrix[0].size(); + sat_ = vector>(m + 1, vector(n + 1, 0)); + for (int i = 1; i <= m; ++i) { + for (int j = 1; j <= n; ++j) { + sat_[i][j] = matrix[i - 1][j - 1] + sat_[i - 1][j] + + sat_[i][j - 1] - sat_[i - 1][j - 1]; + } + } + } + + int sumRegion(int row1, int col1, int row2, int col2) { + return sat_[row2 + 1][col2 + 1] - sat_[row2 + 1][col1] - + sat_[row1][col2 + 1] + sat_[row1][col1]; + } + + private: + vector> sat_; +}; +``` + + + + +```py +class NumMatrix: + def __init__(self, matrix: List[List[int]]): + m, n = len(matrix), len(matrix[0]) + self.sat = [[0 for _ in range(n + 1)] for _ in range(m + 1)] + + for i in range(1, m + 1): + for j in range(1, n + 1): + self.sat[i][j] = ( + matrix[i - 1][j - 1] + + self.sat[i - 1][j] + + self.sat[i][j - 1] + - self.sat[i - 1][j - 1] + ) + + def sumRegion(self, row1: int, col1: int, row2: int, col2: int) -> int: + return ( + self.sat[row2 + 1][col2 + 1] + - self.sat[row2 + 1][col1] + - self.sat[row1][col2 + 1] + + self.sat[row1][col1] + ) + +``` + + + + + +## [560. Subarray Sum Equals K](https://leetcode.com/problems/subarray-sum-equals-k/) + +### 题目描述 + +给定一个数组,寻找和为 k 的连续区间个数。 + +### 输入输出样例 + +输入一个一维整数数组和一个整数值 k;输出一个整数,表示满足条件的连续区间个数。 + +``` +Input: nums = [1,1,1], k = 2 +Output: 2 +``` + +在这个样例中,我们可以找到两个 [1,1] 连续区间满足条件。 + +### 题解 + +本题同样是利用前缀和,不同的是这里我们使用一个哈希表 cache,其键是前缀和,而值是该前缀和出现的次数。在我们遍历到位置 i 时,假设当前的前缀和是 cumsum,那么 cache[cumsum-k] 即为以当前位置结尾、满足条件的区间个数。 + + + + +```cpp +int subarraySum(vector& nums, int k) { + int count = 0, cumsum = 0; + unordered_map cache; // + cache[0] = 1; + for (int num : nums) { + cumsum += num; + count += cache[cumsum - k]; + ++cache[cumsum]; + } + return count; +} +``` + + + + +```py +def subarraySum(nums: List[int], k: int) -> int: + count, cur_sum = 0, 0 + cache = {0: 1} # + for num in nums: + cur_sum += num + count += cache.get(cur_sum - k, 0) + cache[cur_sum] = cache.get(cur_sum, 0) + 1 + return count +``` + + + + + diff --git a/leetcode_101/docs/10-data-structures/10-11-exercises.md b/leetcode_101/docs/10-data-structures/10-11-exercises.md index ee870329..778cbf90 100644 --- a/leetcode_101/docs/10-data-structures/10-11-exercises.md +++ b/leetcode_101/docs/10-data-structures/10-11-exercises.md @@ -3,3 +3,51 @@ sidebar_position: 58 --- # 10.11 练习 + +## 基础难度 + +### [566. Reshape the Matrix](https://leetcode.com/problems/reshape-the-matrix/) + +没有什么难度,只是需要一点耐心。 + +### [225. Implement Stack using Queues](https://leetcode.com/problems/implement-stack-using-queues/) + +利用相似的方法,我们也可以用 queue 实现 stack。 + +### [503. Next Greater Element II](https://leetcode.com/problems/next-greater-element-ii/) + +Daily Temperature 的变种题。 + +### [217. Contains Duplicate](https://leetcode.com/problems/contains-duplicate/) + +使用什么数据结构可以快速判断重复呢? + +### [697. Degree of an Array](https://leetcode.com/problems/degree-of-an-array/) + +如何对数组进行预处理才能正确并快速地计算子数组的长度? + +### [594. Longest Harmonious Subsequence](https://leetcode.com/problems/longest-harmonious-subsequence/) + +最长连续序列的变种题。 + +### [15. 3Sum](https://leetcode.com/problems/3sum/) + +因为排序的复杂度是 $O(n \log n) < O(n^2)$,因此我们既可以排序后再进行 $O(n^2)$ 的指针搜索,也可以直接利用哈希表进行 $O(n^2)$ 的搜索。 + +## 进阶难度 + +### [287. Find the Duplicate Number](https://leetcode.com/problems/find-the-duplicate-number/) + +寻找丢失数字的变种题。除了标负位置,你还有没有其它算法可以解决这个问题? + +### [313. Super Ugly Number](https://leetcode.com/problems/super-ugly-number/) + +尝试使用优先队列解决这一问题。 + +### [870. Advantage Shuffle](https://leetcode.com/problems/advantage-shuffle/) + +如果我们需要比较大小关系,而且同一数字可能出现多次,那么应该用什么数据结构呢? + +### [307. Range Sum Query - Mutable](https://leetcode.com/problems/range-sum-query-mutable/) + +前缀和的变种题。好吧我承认,这道题可能有些超纲,你或许需要搜索一下什么是线段树。 \ No newline at end of file diff --git a/leetcode_101/docs/10-data-structures/10-2-python-data-structures.md b/leetcode_101/docs/10-data-structures/10-2-python-data-structures.md index e1b45ecf..b4221a27 100644 --- a/leetcode_101/docs/10-data-structures/10-2-python-data-structures.md +++ b/leetcode_101/docs/10-data-structures/10-2-python-data-structures.md @@ -3,3 +3,20 @@ sidebar_position: 49 --- # 10.2 Python 常用数据结构 + +类似于 C++ STL,Python 也提供了类似的数据结构(实际底层细节可能因编译器而异): + +1. Sequence Containers:维持顺序的容器。 + 1. list:`动态数组`,是我们最常使用的数据结构之一,用于 $O(1)$ 的随机读取。因为大部分算法的时间复杂度都会大于 $O(n)$,因此我们经常新建 list 来存储各种数据或中间变量。因为在尾部增删的复杂度是 $O(1)$,我们也可以把它当作 stack 来用。 + 2. tuple: `元组`,immutable list,不可改变其中元素或总长度。 + 3. collections.deque:`双端队列`,这是一个非常强大的数据结构,既支持 $O(1)$ 随机读取,又支持 $O(1)$ 时间的头部增删和尾部增删(因此可以当作 stack 和 queue 来使用),不过有一定的额外开销。也可以用来近似一个双向链表来使用。 +2. Container Adaptors:基于其它容器实现的容器。 + 1. heapq:`最小堆(最小值先出的数据结构)`,默认基于 list 实现堆结构。它可以在 $O(n \log n)$ 的时间排序数组,$O(\log n)$ 的时间插入任意值,$O(1)$ 的时间获得最小值,$O(\log n)$ 的时间删除最小值。heapq 常用于维护数据结构并快速获取最小值,但不支持自定义比较函数。所以通常我们需要提前算好自定义值,再把 (自定义值,位置) 的 tuple 存进 heapq。这样进行比较时就会默认从左到右比较 tuple 中的元素,即先比较自定义值,再比较元素的插入次序。 +3. Ordered Associative Containers:有序关联容器。 + 1. collections.OrderedDict:`顺序映射或顺序表`,注意这里的 Ordered 不同于 C++ 中 map的按大小排序,而是按照插入的先后次序排序。OrderedDict 很适合用来做 LRU。 +4. Unordered Associative Containers:无序关联容器。 + 1. set:`哈希集合`,可以在 O(1) 的时间快速插入、查找、删除元素,常用于快速的查询一个元素是否在这个容器内。 + 2. dict:`哈希映射或哈希表`,在 set 的基础上加上映射关系,可以对每一个元素 key 存一个值 value。在某些情况下,如果 key 的范围已知且较小,我们也可以用 list 代替 dict,用位置表示 key,用每个位置的值表示 value。 + 3. collections.Counter:`计数器`,是 dict 的一个特殊版本,可以直接传入一个 list,并对其中的每一个元素进行计数统计,key 是元素值,value 是元素出现的频次。可以用来当作多重集合。 + +同样的,因为这并不是一本讲解 Python 原理的书,更多的数据结构细节请读者自行搜索。只有理解了这些数据结构的原理和使用方法,才能够更加游刃有余地解决算法和数据结构问题。 \ No newline at end of file diff --git a/leetcode_101/docs/10-data-structures/10-3-arrays.md b/leetcode_101/docs/10-data-structures/10-3-arrays.md deleted file mode 100644 index a04b6aa2..00000000 --- a/leetcode_101/docs/10-data-structures/10-3-arrays.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 50 ---- - -# 10.3 数组 diff --git a/leetcode_101/docs/10-data-structures/10-3-arrays.mdx b/leetcode_101/docs/10-data-structures/10-3-arrays.mdx new file mode 100644 index 00000000..11741a06 --- /dev/null +++ b/leetcode_101/docs/10-data-structures/10-3-arrays.mdx @@ -0,0 +1,250 @@ +--- +sidebar_position: 50 +--- + +# 10.3 数组 + +## [448. Find All Numbers Disappeared in an Array](https://leetcode.com/problems/find-all-numbers-disappeared-in-an-array/) + +### 题目描述 + +给定一个长度为 n 的数组,其中包含范围为 1 到 n 的整数,有些整数重复了多次,有些整数没有出现,求 1 到 n 中没有出现过的整数。 + +### 输入输出样例 + +输入是一个一维整数数组,输出也是一个一维整数数组,表示输入数组内没出现过的数字。 + +``` +Input: [4,3,2,7,8,2,3,1] +Output: [5,6] +``` + +利用数组这种数据结构建立 n 个桶,把所有重复出现的位置进行标记,然后再遍历一遍数组,即可找到没有出现过的数字。进一步地,我们可以直接对原数组进行标记:把重复出现的数字-1在原数组的位置设为负数(这里-1 的目的是把 1 到 n 的数字映射到 0 到 n-1 的位置),最后仍然为正数的位置 +1 即为没有出现过的数。 + +### 题解 + + + + + + +```cpp +vector findDisappearedNumbers(vector& nums) { + vector disappeared; + for (int num : nums) { + int pos = abs(num) - 1; + if (nums[pos] > 0) { + nums[pos] = -nums[pos]; + } + } + for (int i = 0; i < nums.size(); ++i) { + if (nums[i] > 0) { + disappeared.push_back(i + 1); + } + } + return disappeared; +} +``` + + + + +```py +def findDisappearedNumbers(nums: List[int]) -> List[int]: + for num in nums: + pos = abs(num) - 1 + if nums[pos] > 0: + nums[pos] = -nums[pos] + return [i + 1 for i in range(len(nums)) if nums[i] > 0] +``` + + + + + +## [48. Rotate Image](https://leetcode.com/problems/rotate-image/) + +### 题目描述 + +给定一个 n × n 的矩阵,求它顺时针旋转 90 度的结果,且必须在原矩阵上修改(in-place)。怎样能够尽量不创建额外储存空间呢? + +### 输入输出样例 + +输入和输出都是一个二维整数矩阵。 + +``` +Input: +[[1,2,3], + [4,5,6], + [7,8,9]] +Output: +[[7,4,1], + [8,5,2], + [9,6,3]] +``` + +### 题解 + +每次只考虑四个间隔 90 度的位置,可以进行 O(1) 额外空间的旋转。 + +
+ + ![](10.1.png) + +
图 10.1: 题目 48 - $O(1)$ 空间旋转样例,相同颜色代表四个互相交换的位置
+
+ + + + +```cpp +void rotate(vector>& matrix) { + int pivot = 0, n = matrix.size() - 1; + for (int i = 0; i <= n / 2; ++i) { + for (int j = i; j < n - i; ++j) { + pivot = matrix[j][n - i]; + matrix[j][n - i] = matrix[i][j]; + matrix[i][j] = matrix[n - j][i]; + matrix[n - j][i] = matrix[n - i][n - j]; + matrix[n - i][n - j] = pivot; + } + } +} +``` + + + + +```py +def rotate(matrix: List[List[int]]) -> None: + n = len(matrix) - 1 + for i in range(n // 2 + 1): + for j in range(i, n - i): + pivot = matrix[j][n - i] + matrix[j][n - i] = matrix[i][j] + matrix[i][j] = matrix[n - j][i] + matrix[n - j][i] = matrix[n - i][n - j] + matrix[n - i][n - j] = pivot +``` + + + + + +## [240. Search a 2D Matrix II](https://leetcode.com/problems/search-a-2d-matrix-ii/) + +### 题目描述 + +给定一个二维矩阵,已知每行和每列都是增序的,尝试设计一个快速搜索一个数字是否在矩阵中存在的算法。 + +### 输入输出样例 + +输入是一个二维整数矩阵,和一个待搜索整数。输出是一个布尔值,表示这个整数是否存在于矩阵中。 + +``` +Input: matrix = +[ [1, 4, 7, 11, 15], + [2, 5, 8, 12, 19], + [3, 6, 9, 16, 22], + [10, 13, 14, 17, 24], + [18, 21, 23, 26, 30]], target = 5 +Output: true +``` + +### 题解 + +这道题有一个简单的技巧:我们可以从右上角开始查找,若当前值大于待搜索值,我们向左移动一位;若当前值小于待搜索值,我们向下移动一位。如果最终移动到左下角时仍不等于待搜索值,则说明待搜索值不存在于矩阵中。 + + + + +```cpp +bool searchMatrix(vector>& matrix, int target) { + int m = matrix.size(), n = matrix[0].size(); + int i = 0, j = n - 1; + while (i < m && j >= 0) { + if (matrix[i][j] == target) { + return true; + } else if (matrix[i][j] < target) { + ++i; + } else { + --j; + } + } + return false; +} +``` + + + + +```py +def searchMatrix(matrix: List[List[int]], target: int) -> bool: + m, n = len(matrix), len(matrix[0]) + i, j = 0, n - 1 + while i < m and j >= 0: + if matrix[i][j] == target: + return True + if matrix[i][j] < target: + i += 1 + else: + j -= 1 + return False +``` + + + + + +## [769. Max Chunks To Make Sorted](https://leetcode.com/problems/max-chunks-to-make-sorted/) + +### 题目描述 + +给定一个含有 0 到 n 整数的数组,每个整数只出现一次,求这个数组最多可以分割成多少个子数组,使得对每个子数组进行增序排序后,原数组也是增序的。 + +### 输入输出样例 + +输入一个一维整数数组,输出一个整数,表示最多的分割数。 + +``` +Input: [1,0,2,3,4] +Output: 4 +``` + +在这个样例中,最多分割是 [1, 0], [2], [3], [4]。 + +### 题解 + +从左往右遍历,同时记录当前的最大值,每当当前最大值等于数组位置时,我们可以多一次分割。 + +为什么可以通过这个算法解决问题呢?如果当前最大值大于数组位置,则说明右边一定有小于数组位置的数字,需要把它也加入待排序的子数组;又因为数组只包含不重复的 0 到 n,所以当前最大值一定不会小于数组位置。所以每当当前最大值等于数组位置时,假设为 p,我们可以成功完成一次分割,并且其与上一次分割位置 q 之间的值一定是 q +1 到 p 的所有数字。 + + + + +```cpp +int maxChunksToSorted(vector& arr) { + int chunks = 0, cur_max = 0; + for (int i = 0; i < arr.size(); ++i) { + cur_max = max(cur_max, arr[i]); + chunks += cur_max == i; + } + return chunks; +} +``` + + + + +```py +def maxChunksToSorted(arr: List[int]) -> int: + chunks, cur_max = 0, 0 + for i, num in enumerate(arr): + cur_max = max(cur_max, num) + chunks += cur_max == i + return chunks +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/10-data-structures/10-4-stack-and-queue.md b/leetcode_101/docs/10-data-structures/10-4-stack-and-queue.md deleted file mode 100644 index e8803cc1..00000000 --- a/leetcode_101/docs/10-data-structures/10-4-stack-and-queue.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 51 ---- - -# 10.4 栈和队列 diff --git a/leetcode_101/docs/10-data-structures/10-4-stack-and-queue.mdx b/leetcode_101/docs/10-data-structures/10-4-stack-and-queue.mdx new file mode 100644 index 00000000..403a3c5a --- /dev/null +++ b/leetcode_101/docs/10-data-structures/10-4-stack-and-queue.mdx @@ -0,0 +1,257 @@ +--- +sidebar_position: 51 +--- + +# 10.4 栈和队列 + +## [232. Implement Queue using Stacks](https://leetcode.com/problems/implement-queue-using-stacks/) + +### 题目描述 + +尝试使用栈(stack)来实现队列(queue)。 + +### 输入输出样例 + +以下是数据结构的调用样例。 + +``` +MyQueue queue = new MyQueue(); +queue.push(1); +queue.push(2); +queue.peek(); // returns 1 +queue.pop(); // returns 1 +queue.empty(); // returns false +``` + +### 题解 + +我们可以用两个栈来实现一个队列:因为我们需要得到先入先出的结果,所以必定要通过一个额外栈翻转一次数组。这个翻转过程既可以在插入时完成,也可以在取值时完成。我们这里展示在取值时完成的写法。 + + + + +```cpp +class MyQueue { + public: + MyQueue() {} + + void push(int x) { s_in_.push(x); } + + int pop() { + in2out(); + int x = s_out_.top(); + s_out_.pop(); + return x; + } + + int peek() { + in2out(); + return s_out_.top(); + } + + bool empty() { return s_in_.empty() && s_out_.empty(); } + + private: + void in2out() { + if (!s_out_.empty()) { + return; + } + while (!s_in_.empty()) { + int x = s_in_.top(); + s_in_.pop(); + s_out_.push(x); + } + } + + stack s_in_, s_out_; +}; +``` + + + + +```py +class MyQueue: + def __init__(self): + self.s_in = [] + self.s_out = [] + + def _in2out(self): + if len(self.s_out) > 0: + return + while len(self.s_in) > 0: + self.s_out.append(self.s_in.pop()) + + def push(self, x: int) -> None: + self.s_in.append(x) + + def pop(self) -> int: + self._in2out() + return self.s_out.pop() + + def peek(self) -> int: + self._in2out() + return self.s_out[-1] + + def empty(self) -> bool: + return len(self.s_in) == 0 and len(self.s_out) == 0 +``` + + + + + +## [155. Min Stack](https://leetcode.com/problems/min-stack/) + +### 题目描述 + +设计一个最小栈,除了需要支持常规栈的操作外,还需要支持在 $O(1)$ 时间内查询栈内最小值的功能。 + +### 输入输出样例 + +以下是数据结构的调用样例。 + +``` +MinStack minStack = new MinStack(); +minStack.push(-2); +minStack.push(0); +minStack.push(-3); +minStack.getMin(); // Returns -3. +minStack.pop(); +minStack.top(); // Returns 0. +minStack.getMin(); // Returns -2. +``` + +### 题解 + +我们可以额外建立一个新栈,栈顶表示原栈里所有值的最小值。每当在原栈里插入一个数字时,若该数字小于等于新栈栈顶,则表示这个数字在原栈里是最小值,我们将其同时插入新栈内。每当从原栈里取出一个数字时,若该数字等于新栈栈顶,则表示这个数是原栈里的最小值之一,我们同时取出新栈栈顶的值。 + +一个写起来更简单但是时间复杂度略高的方法是,我们每次插入原栈时,都向新栈插入一次原栈里所有值的最小值(新栈栈顶和待插入值中小的那一个);每次从原栈里取出数字时,同样取出新栈的栈顶。这样可以避免判断,但是每次都要插入和取出。我们这里只展示第一种写法。 + + + + +```cpp +class MinStack { + public: + MinStack() {} + + void push(int x) { + s_.push(x); + if (min_s_.empty() || min_s_.top() >= x) { + min_s_.push(x); + } + } + + void pop() { + if (!min_s_.empty() && min_s_.top() == s_.top()) { + min_s_.pop(); + } + s_.pop(); + } + + int top() { return s_.top(); } + + int getMin() { return min_s_.top(); } + + private: + stack s_, min_s_; +}; +``` + + + + +```py +class MinStack: + def __init__(self): + self.s = [] + self.min_s = [] + + def push(self, x: int) -> None: + self.s.append(x) + if len(self.min_s) == 0 or self.min_s[-1] >= x: + self.min_s.append(x) + + def pop(self) -> None: + if len(self.min_s) != 0 and self.s[-1] == self.min_s[-1]: + self.min_s.pop() + self.s.pop() + + def top(self) -> int: + return self.s[-1] + + def getMin(self) -> int: + return self.min_s[-1] +``` + + + + + + +## [20. Valid Parentheses](https://leetcode.com/problems/valid-parentheses/) + +### 题目描述 + +给定一个只由左右圆括号、花括号和方括号组成的字符串,求这个字符串是否合法。合法的定义是每一个类型的左括号都有一个右括号一一对应,且括号内的字符串也满足此要求。 + +### 输入输出样例 + +输入是一个字符串,输出是一个布尔值,表示字符串是否合法。 + +``` +Input: "{[]}()" +Output: true +``` + +### 题解 + +括号匹配是典型的使用栈来解决的问题。我们从左往右遍历,每当遇到左括号便放入栈内,遇到右括号则判断其和栈顶的括号是否是统一类型,是则从栈内取出左括号,否则说明字符串不合法。 + + + + +```cpp +bool isValid(string s) { + stack parsed; + unordered_map matches{{’(’, ’)’}, {’{’, ’}’}, {’[’, ’]’}}; + for (char c : s) { + if (matches.contains(c)) { + parsed.push(c); + continue; + } + if (parsed.empty()) { + return false; + } + if (c != matches[parsed.top()]) { + return false; + } + parsed.pop(); + } + return parsed.empty(); +} +``` + + + + +```py +def isValid(s: str) -> bool: + parsed = [] + matches = {"{": "}", "(": ")", "[": "]"} + for c in s: + if c in matches.keys(): + parsed.append(c) + continue + if len(parsed) == 0: + return False + if c != matches[parsed[-1]]: + return False + parsed.pop() + return len(parsed) == 0 +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/10-data-structures/10-5-monotonic-stack.md b/leetcode_101/docs/10-data-structures/10-5-monotonic-stack.md deleted file mode 100644 index 6956dadf..00000000 --- a/leetcode_101/docs/10-data-structures/10-5-monotonic-stack.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 52 ---- - -# 10.5 单调栈 diff --git a/leetcode_101/docs/10-data-structures/10-5-monotonic-stack.mdx b/leetcode_101/docs/10-data-structures/10-5-monotonic-stack.mdx new file mode 100644 index 00000000..a9dc695b --- /dev/null +++ b/leetcode_101/docs/10-data-structures/10-5-monotonic-stack.mdx @@ -0,0 +1,72 @@ +--- +sidebar_position: 52 +--- + +# 10.5 单调栈 + +`单调栈`通过维持栈内值的单调递增(递减)性,在整体 $O(n)$ 的时间内处理需要大小比较的问题。 + +## [739. Daily Temperatures](https://leetcode.com/problems/daily-temperatures/) + +### 题目描述 + +给定每天的温度,求对于每一天需要等几天才可以等到更暖和的一天。如果该天之后不存在更暖和的天气,则记为 0。 + +### 输入输出样例 + +输入是一个一维整数数组,输出是同样长度的整数数组,表示对于每天需要等待多少天。 + +``` +Input: [73, 74, 75, 71, 69, 72, 76, 73] +Output: [1, 1, 4, 2, 1, 1, 0, 0] +``` + +### 题解 + +我们可以维持一个单调递减的栈,表示每天的温度;为了方便计算天数差,我们这里存放位置(即日期)而非温度本身。我们从左向右遍历温度数组,对于每个日期 p,如果 p 的温度比栈顶存储位置 q 的温度高,则我们取出 q,并记录 q 需要等待的天数为 p − q;我们重复这一过程,直到 p 的温度小于等于栈顶存储位置的温度(或空栈)时,我们将 p 插入栈顶,然后考虑下一天。在这个过程中,栈内数组永远保持单调递减,避免了使用排序进行比较。最后若栈内剩余一些日期,则说明它们之后都没有出现更暖和的日期。 + + + + +```cpp +vector dailyTemperatures(vector& temperatures) { + int n = temperatures.size(); + vector days_to_wait(n, 0); + stack mono_stack; + for (int i = 0; i < n; ++i) { + while (!mono_stack.empty()) { + int j = mono_stack.top(); + if (temperatures[i] <= temperatures[j]) { + break; + } + mono_stack.pop(); + days_to_wait[j] = i - j; + } + mono_stack.push(i); + } + return days_to_wait; +} +``` + + + + +```py +def dailyTemperatures(temperatures: List[int]) -> List[int]: + n = len(temperatures) + days_to_wait = [0] * n + mono_stack = [] + for i in range(n): + while len(mono_stack) > 0: + j = mono_stack[-1] + if temperatures[i] <= temperatures[j]: + break + mono_stack.pop() + days_to_wait[j] = i - j + mono_stack.append(i) + return days_to_wait +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/10-data-structures/10-6-priority-queue.md b/leetcode_101/docs/10-data-structures/10-6-priority-queue.md deleted file mode 100644 index ee6bc912..00000000 --- a/leetcode_101/docs/10-data-structures/10-6-priority-queue.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 53 ---- - -# 10.6 优先队列 diff --git a/leetcode_101/docs/10-data-structures/10-6-priority-queue.mdx b/leetcode_101/docs/10-data-structures/10-6-priority-queue.mdx new file mode 100644 index 00000000..85ded21f --- /dev/null +++ b/leetcode_101/docs/10-data-structures/10-6-priority-queue.mdx @@ -0,0 +1,295 @@ +--- +sidebar_position: 53 +--- + +# 10.6 优先队列 + +`优先队列`(priority queue)可以在 O(1) 时间内获得最大值,并且可以在 O(log n) 时间内取出最大值或插入任意值。 + +
+ + ![](10.2.png) + +
图 10.2: (最大)堆,维护的是数据结构中的大于关系
+
+ +优先队列常常用堆(heap)来实现。堆是一个完全二叉树,其每个节点的值总是大于等于子节点的值。实际实现堆时,我们通常用一个数组而不是用指针建立一个树。这是因为堆是完全二叉树,所以用数组表示时,位置 i 的节点的父节点位置一定为 (i-1)/2,而它的两个子节点的位置又一定分别为 2i+1 和 2i+2。 + +以下是堆的实现方法,其中最核心的两个操作是上浮和下沉:如果一个节点比父节点大,那么需要交换这个两个节点;交换后还可能比它新的父节点大,因此需要不断地进行比较和交换操作,我们称之为上浮;类似地,如果一个节点比父节小,也需要不断地向下进行比较和交换操作我们称之为下沉。如果一个节点有两个子节点,我们总是交换最大的子节点。 + + + + + +```cpp +class Heap { + public: + Heap() {} + // 上浮。 + void swim(int pos) { + int next_pos = (pos - 1) / 2; + while (pos > 0 && heap_[next_pos] < heap_[pos]) { + swap(heap_[next_pos], heap_[pos]); + pos = next_pos; + next_pos = (pos - 1) / 2; + } + } + // 下沉。 + void sink(int pos) { + int n = heap_.size(); + int next_pos = 2 * pos + 1; + while (next_pos < n) { + if (next_pos < n - 1 && heap_[next_pos] < heap_[next_pos + 1]) { + ++next_pos; + } + if (heap_[pos] >= heap_[next_pos]) { + break; + } + swap(heap_[next_pos], heap_[pos]); + pos = next_pos; + next_pos = 2 * pos + 1; + } + } + // 插入任意值:把新的数字放在最后一位,然后上浮。 + void push(int k) { + heap_.push_back(k); + swim(heap_.size() - 1); + } + // 删除最大值:把最后一个数字挪到开头,然后下沉。 + void pop() { + heap_[0] = heap_.back(); + heap_.pop_back(); + sink(0); + } + // 获得最大值。 + int top() { return heap_[0]; } + + private: + vector heap_; +}; +``` + + + + +```py +class Heap: + def __init__(self): + self.heap = [] + + # 上浮。 + def swim(self, pos: int): + next_pos = (pos - 1) // 2 + while pos > 0 and self.heap[next_pos] < self.heap[pos]: + self.heap[next_pos], self.heap[pos] = self.heap[pos], self.heap[next_pos] + pos = next_pos + next_pos = (pos - 1) // 2 + + # 下沉。 + def sink(self, pos: int): + n = len(self.heap) + next_pos = 2 * pos + 1 + while next_pos < n: + if next_pos < n - 1 and self.heap[next_pos] < self.heap[next_pos + 1]: + next_pos += 1 + if self.heap[pos] >= self.heap[next_pos]: + break + self.heap[next_pos], self.heap[pos] = self.heap[pos], self.heap[next_pos] + pos = next_pos + next_pos = 2 * pos + 1 + + # 插入任意值:把新的数字放在最后一位,然后上浮。 + def push(self, k: int): + self.heap.append(k) + self.swim(len(self.heap) - 1) + + # 删除最大值:把最后一个数字挪到开头,然后下沉。 + def pop(self): + self.heap[0] = self.heap.pop() + self.sink(0) + + # 获得最大值。 + def top(self) -> int: + return self.heap[0] + +``` + + + + + +通过将算法中的大于号和小于号互换,我们也可以得到一个快速获得最小值的优先队列。 + +## [23. Merge k Sorted Lists](https://leetcode.com/problems/merge-k-sorted-lists/) + +### 题目描述 + +给定 k 个增序的链表,试将它们合并成一条增序链表。 + +### 输入输出样例 + +输入是一个一维数组,每个位置存储链表的头节点;输出是一条链表。 + +``` +Input: +[1->4->5, + 1->3->4, + 2->6] +Output: 1->1->2->3->4->4->5->6 +``` + +### 题解 + +本题可以有很多中解法,比如类似于归并排序进行两两合并。我们这里展示一个速度比较快的方法,即把所有的链表存储在一个优先队列中,每次提取所有链表头部节点值最小的那个节点,直到所有链表都被提取完为止。 + +因为 C++ priority_queue 的比较函数默认是对最大堆进行比较并维持递增关系,如果我们想要获取最小的节点值,我们则需要实现一个最小堆。因此堆的比较函数应该维持递减关系,即 lambda 函数中返回时用大于号而不是递增关系时的小于号进行比较。 + + + + +```cpp +ListNode* mergeKLists(vector& lists) { + auto comp = [](ListNode* l1, ListNode* l2) { return l1->val > l2->val; }; + priority_queue, decltype(comp)> pq; + for (ListNode* l : lists) { + if (l) { + pq.push(l); + } + } + ListNode *dummy = new ListNode(0), *cur = dummy; + while (!pq.empty()) { + cur->next = pq.top(); + pq.pop(); + cur = cur->next; + if (cur->next) { + pq.push(cur->next); + } + } + return dummy->next; +} +``` + + + + +```py +def mergeKLists(lists: List[Optional[ListNode]]) -> Optional[ListNode]: + pq = [] + for idx, l in enumerate(lists): + if l is not None: + # ListNode不可被哈希,所以这里我们直接记录它在lists中的位置。 + pq.append((l.val, idx)) + heapq.heapify(pq) + + dummy = ListNode() + cur = dummy + + while len(pq) > 0: + _, l_idx = heapq.heappop(pq) + cur.next = lists[l_idx] + cur = cur.next + if cur.next is not None: + lists[l_idx] = lists[l_idx].next + heapq.heappush(pq, (cur.next.val, l_idx)) + + return dummy.next + +``` + + + + + +## [218. The Skyline Problem](https://leetcode.com/problems/the-skyline-problem/) + +### 题目描述 + +给定建筑物的起止位置和高度,返回建筑物轮廓(天际线)的拐点。 + +### 输入输出样例 + +输入是一个二维整数数组,表示每个建筑物的 [左端, 右端, 高度];输出是一个二维整数数组,表示每个拐点的横纵坐标。 + +
+ + ![](10.3.png) + +
图 10.3: 题目 218 - 建筑物及其天际线样例
+
+ +``` +Input: [[2 9 10], [3 7 15], [5 12 12], [15 20 10], [19 24 8]] +Output: [[2 10], [3 15], [7 12], [12 0], [15 10], [20 8], [24, 0]] +``` + +### 题解 + +我们可以使用优先队列储存每个建筑物的高度和右端(这里使用 pair,其默认比较函数是先比较第一个值,如果相等则再比较第二个值),从而获取目前会拔高天际线、且妨碍到前一个建筑物(的右端端点)的下一个建筑物。 + +因为 Python 中 heapq 是最小堆,所以我们在存值的时候可以存负值,这样就变成了最大堆。 + +这道题比较复杂,如果实在难以理解,建议读者暂时跳过此题,或者在纸上举例子画一画。 + + + + +```cpp +vector> getSkyline(vector>& buildings) { + vector> skyline; + priority_queue> pq; // <高度, 右端> + int i = 0, n = buildings.size(); + int cur_x, cur_h; + while (i < n || !pq.empty()) { + if (pq.empty() || (i < n && buildings[i][0] <= pq.top().second)) { + cur_x = buildings[i][0]; + while (i < n && cur_x == buildings[i][0]) { + pq.emplace(buildings[i][2], buildings[i][1]); + ++i; + } + } else { + cur_x = pq.top().second; + while (!pq.empty() && cur_x >= pq.top().second) { + pq.pop(); + } + } + cur_h = pq.empty() ? 0 : pq.top().first; + if (skyline.empty() || cur_h != skyline.back()[1]) { + skyline.push_back({cur_x, cur_h}); + } + } + return skyline; +} +``` + + + + +```py +def getSkyline(buildings: List[List[int]]) -> List[List[int]]: + skyline = [] + pq = [] # <负高度,右端> + heapq.heapify(pq) + i, n = 0, len(buildings) + + while i < n or len(pq) > 0: + if len(pq) == 0 or (i < n and buildings[i][0] <= pq[0][1]): + cur_x = buildings[i][0] + while i < n and cur_x == buildings[i][0]: + heapq.heappush(pq, (-buildings[i][2], buildings[i][1])) + i += 1 + else: + cur_x = pq[0][1] + while len(pq) > 0 and cur_x >= pq[0][1]: + heapq.heappop(pq) + + cur_h = -pq[0][0] if len(pq) > 0 else 0 + if len(skyline) == 0 or cur_h != skyline[-1][1]: + skyline.append([cur_x, cur_h]) + + return skyline + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/10-data-structures/10-7-deque.md b/leetcode_101/docs/10-data-structures/10-7-deque.md deleted file mode 100644 index 6ac26532..00000000 --- a/leetcode_101/docs/10-data-structures/10-7-deque.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 54 ---- - -# 10.7 双端队列 diff --git a/leetcode_101/docs/10-data-structures/10-7-deque.mdx b/leetcode_101/docs/10-data-structures/10-7-deque.mdx new file mode 100644 index 00000000..7b9091a4 --- /dev/null +++ b/leetcode_101/docs/10-data-structures/10-7-deque.mdx @@ -0,0 +1,82 @@ +--- +sidebar_position: 54 +--- + +# 10.7 双端队列 + +## [239. Sliding Window Maximum](https://leetcode.com/problems/sliding-window-maximum/) + +### 题目描述 + +给定一个整数数组和一个滑动窗口大小,求在这个窗口的滑动过程中,每个时刻其包含的最大值。 + +### 输入输出样例 + +输入是一个一维整数数组,和一个表示滑动窗口大小的整数;输出是一个一维整数数组,表示每个时刻时的窗口内最大值。 + +``` +Input: nums = [1,3,-1,-3,5,3,6,7], k = 3 +Output: [3,3,5,5,6,7] +``` + +在这个样例中,滑动窗口在每个位置的最大包含值取法如下: + +``` + Window position Max +------------------------- ----- +[1 3 -1] -3 5 3 6 7 3 + 1 [3 -1 -3] 5 3 6 7 3 + 1 3 [-1 -3 5] 3 6 7 5 + 1 3 -1 [-3 5 3] 6 7 5 + 1 3 -1 -3 [5 3 6] 7 6 + 1 3 -1 -3 5 [3 6 7] 7 +``` + +### 题解 + +我们可以利用双端队列进行操作:每当向右移动时,把窗口左端的值从双端队列左端剔除,把双端队列右边小于窗口右端的值全部剔除。这样双端队列的最左端永远是当前窗口内的最大值。另外,这道题也是单调栈的一种延申:该双端队列利用从左到右递减来维持大小关系。 + + + + +```cpp +vector maxSlidingWindow(vector& nums, int k) { + deque dq; + vector swm; + for (int i = 0; i < nums.size(); ++i) { + if (!dq.empty() && dq.front() == i - k) { + dq.pop_front(); + } + while (!dq.empty() && nums[dq.back()] < nums[i]) { + dq.pop_back(); + } + dq.push_back(i); + if (i >= k - 1) { + swm.push_back(nums[dq.front()]); + } + } + return swm; +} +``` + + + + +```py +def maxSlidingWindow(nums: List[int], k: int) -> List[int]: + dq = collections.deque() + swm = [] + for i, num in enumerate(nums): + if len(dq) > 0 and dq[0] == i - k: + dq.popleft() + while len(dq) > 0 and nums[dq[-1]] < num: + dq.pop() + dq.append(i) + if i >= k - 1: + swm.append(nums[dq[0]]) + return swm +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/10-data-structures/10-8-hash-table.md b/leetcode_101/docs/10-data-structures/10-8-hash-table.md deleted file mode 100644 index 14afb6b0..00000000 --- a/leetcode_101/docs/10-data-structures/10-8-hash-table.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 55 ---- - -# 10.8 哈希表 diff --git a/leetcode_101/docs/10-data-structures/10-8-hash-table.mdx b/leetcode_101/docs/10-data-structures/10-8-hash-table.mdx new file mode 100644 index 00000000..36531124 --- /dev/null +++ b/leetcode_101/docs/10-data-structures/10-8-hash-table.mdx @@ -0,0 +1,232 @@ +--- +sidebar_position: 55 +--- + +# 10.8 哈希表 + +`哈希表(hash table, hash map)`,又称散列表,使用 $O(n)$ 空间复杂度存储数据,通过哈希函数(hash function)映射位置,从而实现近似 O(1) 时间复杂度的插入、查找、删除等操作。哈希表可以用来统计频率,记录内容等等。 + +如果元素有穷,并且范围不大,那么可以用一个固定大小的数组来存储或统计元素。例如我们需要统计一个字符串中所有字母的出现次数,则可以用一个长度为 26 的数组来进行统计,其哈希函数即为字母在字母表的位置,这样空间复杂度就可以降低为常数。 + +## [1. Two Sum](https://leetcode.com/problems/two-sum/) + +### 题目描述 + +给定一个(未排序的)整数数组,已知有且只有两个数的和等于给定值,求这两个数的位置。 + +### 输入输出样例 + +输入一个一维整数数组和一个目标值,输出是一个大小为 2 的一维数组,表示满足条件的两个数字的位置。 + +``` +Input: nums = [2, 7, 15, 11], target = 9 +Output: [0, 1] +``` + +在这个样例中,第 0 个位置的值 2 和第 1 个位置的值 7 的和为 9。 + +### 题解 + +我们可以利用哈希表存储遍历过的值以及它们的位置,每次遍历到位置 i 的时候,查找哈希表里是否存在 target - nums[i],若存在,则说明这两个值的和为 target。 + + + + +```cpp +vector twoSum(vector& nums, int target) { + unordered_map cache; // <值,位置> + for (int i = 0; i < nums.size(); ++i) { + int num1 = nums[i], num2 = target - num1; + if (cache.contains(num2)) { + return vector{cache[num2], i}; + } + cache[num1] = i; + } + return {}; +} +``` + + + + +```py +def twoSum(nums: List[int], target: int) -> List[int]: + cache = dict() # <值,位置> + for i, num1 in enumerate(nums): + num2 = target - num1 + if num2 in cache: + return [cache[num2], i] + cache[num1] = i + return [] +``` + + + + + +## [128. Longest Consecutive Sequence](https://leetcode.com/problems/longest-consecutive-sequence/) + +### 题目描述 + +给定一个整数数组,求这个数组中的数字可以组成的最长连续序列有多长。 + +### 输入输出样例 + +输入一个整数数组,输出一个整数,表示连续序列的长度。 + +``` +Input: [100, 4, 200, 1, 3, 2] +Output: 4 +``` + +在这个样例中,最长连续序列是 [1,2,3,4]。 + +### 题解 + +我们可以把所有数字放到一个哈希表,然后不断地从哈希表中任意取一个值,并删除掉其之前之后的所有连续数字,然后更新目前的最长连续序列长度。重复这一过程,我们就可以找到所有的连续数字序列。 + + + + +```cpp +int longestConsecutive(vector& nums) { + unordered_set cache(nums.begin(), nums.end()); + int max_len = 0; + while (!cache.empty()) { + int cur = *(cache.begin()); + cache.erase(cur); + int l = cur - 1, r = cur + 1; + while (cache.contains(l)) { + cache.erase(l--); + } + while (cache.contains(r)) { + cache.erase(r++); + } + max_len = max(max_len, r - l - 1); + } + return max_len; +} +``` + + + + +```py +def longestConsecutive(nums: List[int]) -> int: + cache = set(nums) + max_len = 0 + + while len(cache) > 0: + cur = next(iter(cache)) + cache.remove(cur) + + l, r = cur - 1, cur + 1 + while l in cache: + cache.remove(l) + l -= 1 + while r in cache: + cache.remove(r) + r += 1 + + max_len = max(max_len, r - l - 1) + + return max_len + +``` + + + + + +## [149. Max Points on a Line](https://leetcode.com/problems/max-points-on-a-line/) + +### 题目描述 + +给定一些二维坐标中的点,求同一条线上最多有多少点。 + +### 输入输出样例 + +输入是一个二维整数数组,表示每个点的横纵坐标;输出是一个整数,表示满足条件的最多点数。 + +``` +Input: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]] +^ +| +| o +| o o +| o +| o o ++-------------------> +0 1 2 3 4 5 6 +Output: 4 +``` + +这个样例中,$y =5 − x$ 上有四个点。 + +### 题解 + +对于每个点,我们对其它点建立哈希表,统计同一斜率的点一共有多少个。这里利用的原理是,一条线可以由一个点和斜率而唯一确定。另外也要考虑斜率不存在和重复坐标的情况。 + +本题也利用了一个小技巧:在遍历每个点时,对于数组中位置 i 的点,我们只需要考虑 i 之后的点即可,因为 i 之前的点已经考虑过 i 了。 + + + + +```cpp +int maxPoints(vector>& points) { + int max_count = 0, n = points.size(); + for (int i = 0; i < n; ++i) { + unordered_map cache; // <斜率, 点个数> + int same_xy = 1, same_y = 1; + for (int j = i + 1; j < n; ++j) { + if (points[i][1] == points[j][1]) { + ++same_y; + if (points[i][0] == points[j][0]) { + ++same_xy; + } + } else { + double dx = points[i][0] - points[j][0], + dy = points[i][1] - points[j][1]; + ++cache[dx / dy]; + } + } + max_count = max(max_count, same_y); + for (auto item : cache) { + max_count = max(max_count, same_xy + item.second); + } + } + return max_count; +} +``` + + + + +```py +def maxPoints(points: List[List[int]]) -> int: + max_count, n = 0, len(points) + + for i, point1 in enumerate(points): + cache = dict() # <斜率, 点个数> + same_xy, same_y = 1, 1 + + for point2 in points[i + 1:]: + if point1[1] == point2[1]: + same_y += 1 + if point1[0] == point2[0]: + same_xy += 1 + else: + dx, dy = point1[0] - point2[0], point1[1] - point2[1] + cache[dx / dy] = cache.get(dx / dy, 0) + 1 + + max_count = max(max_count, same_y) + for count in cache.values(): + max_count = max(max_count, same_xy + count) + + return max_count + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/10-data-structures/10-9-multisets-and-maps.md b/leetcode_101/docs/10-data-structures/10-9-multisets-and-maps.md deleted file mode 100644 index d5c01fe5..00000000 --- a/leetcode_101/docs/10-data-structures/10-9-multisets-and-maps.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 56 ---- - -# 10.9 多重集合和映射 diff --git a/leetcode_101/docs/10-data-structures/10-9-multisets-and-maps.mdx b/leetcode_101/docs/10-data-structures/10-9-multisets-and-maps.mdx new file mode 100644 index 00000000..b0b85827 --- /dev/null +++ b/leetcode_101/docs/10-data-structures/10-9-multisets-and-maps.mdx @@ -0,0 +1,87 @@ +--- +sidebar_position: 56 +--- + +# 10.9 多重集合和映射 + +## [332. Reconstruct Itinerary](https://leetcode.com/problems/reconstruct-itinerary/) + +### 题目描述 + +给定一个人坐过的一些飞机的起止机场,已知这个人从 JFK 起飞,那么这个人是按什么顺序飞的;如果存在多种可能性,返回字母序最小的那种。 + +### 输入输出样例 + +输入是一个二维字符串数组,表示多个起止机场对子;输出是一个一维字符串数组,表示飞行顺序。 + +``` +Input: [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]] +Output: ["JFK", "MUC", "LHR", "SFO", "SJC"] +``` + +### 题解 + +本题可以先用哈希表记录起止机场,其中键是起始机场,值是一个多重(有序)集合,表示对应的终止机场。因为一个人可能坐过重复的线路,所以我们需要使用多重集合储存重复值。储存完成之后,我们可以利用栈/DFS 来恢复从终点到起点飞行的顺序,再将结果逆序得到从起点到终点的顺序。 + +因为 Python 没有默认的多重(有序)集合实现,我们可以直接存储一个数组,然后进行排序。也可以使用 Counter 结构,每次查找下一个机场时,返回 key 值最小的那个。 + + + + +```cpp +vector findItinerary(vector>& tickets) { + vector itinerary; + unordered_map> cache; + for (const auto& ticket : tickets) { + cache[ticket[0]].insert(ticket[1]); + } + stack s; + s.push("JFK"); + while (!s.empty()) { + string t = s.top(); + if (cache[t].empty()) { + itinerary.push_back(t); + s.pop(); + } else { + s.push(*cache[t].begin()); + cache[t].erase(cache[t].begin()); + } + } + reverse(itinerary.begin(), itinerary.end()); + return itinerary; +} +``` + + + + +```py +def findItinerary(tickets: List[List[str]]) -> List[str]: + itinerary = [] + cache = dict() + + for ticket in tickets: + if ticket[0] not in cache: + cache[ticket[0]] = [] + cache[ticket[0]].append(ticket[1]) + + for ticket in cache.keys(): + cache[ticket].sort(reverse=True) + + s = ["JFK"] + while len(s) > 0: + t = s[-1] + if t not in cache or len(cache[t]) == 0: + itinerary.append(t) + s.pop() + else: + t_next = cache[t].pop() + s.append(t_next) + + return list(reversed(itinerary)) + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/10-data-structures/10.1.png b/leetcode_101/docs/10-data-structures/10.1.png new file mode 100644 index 0000000000000000000000000000000000000000..a0f0fc5153f985107a58dc37c2bb7ec47f4e7a17 GIT binary patch literal 37020 zcmb?@cRbZ!9QXIy+qJW=l~sz25H7AQ*&-t&8KKO`xMW;=lbyYal08dgWk$*>D>GX* z&(ZH$zh6E7J+D_%_nv#s`F_^B5R;=sT_$R8pEf7`<4 z)|)UEvT#jZi2zbmp2|7~7Y@hGx4iP@6*1qJ@+PrVSJ*-3lc{$OUni~NSJ$pxJ37nS zW?DZ{uKu|8@p!9oy^%_mAOHdWuxX%*vf#3C9PkJF{fl!Bh6MkmPI4Hpj#bPxFW1PB zc;rNcdiVQftIU^oYU1=u-AXYSf?t#bya)BGBh5Zf)_Q|GZ$RgBy0G{iKg!~E7WdC( zzYase&3=FGLWS+8i$hDU+PoAO=KV1zK4EsFWz5Y^7-|SC&57f=GpIDF(Uz#7bar~O zG}9jbVs|F|iv9&ou#5IRfsfc|u-pCED*Mqm)AI6%q4AFQ-U{A*3mxu#^JC_M-e#Pg ztou2ZcbPum-b%0CWi)oqi~6l@{-(^2 z^EgpqZ|CNd&3+NHm+2WBe>|a$`7H^~OWSX;$z$H#jp?SL`^6S_w?DFWxukTlHHbKh zlG|QH@ow8Gi<##+(Hw}<4G)MARaLj%d^Dk9RYpT(g<%l3iD48TCL{B^ zy0u(do@CEhACOm6gaKQF5kUb6%yNbEys8jGq_(6?%(Dxk4=!ZL_%$2TL=9}sb7`Nv-&yNFzSS9X{zQRbT`FmXQ zy`H4lE~~f_ArmtHD3^sk6|P`B_`%z@)4GHp3K)f}d;V>VXQ;aB||yuH->zIu-7*xBeilB2W8HVv8{?o zIA*Tx;!;Q|u70Dxi<b^?Y{q>l^LR&~W9)a&s?hrueAX%D!DeqomKLGw%w(CGN&0)0+Jd zi7f#q5B$P*_-owh$Za=*nd9K#;7e-6?_uvkS~f1o_%_bsJT<3jGmB{4?vwPj*+%{$Vj}NxH?5ZSGUwqRX3pH;IBy|1pk-qq9V}LF-$0?$XjAFA12PMY{p@Jwp zl3k^~;Fq@X1rul+{pd|wpu2uiBYhFVAMnSa1iRzcT5sAjEr!G7&DRH_ zkLm}EuPkMWM+wrN| zAOu^~K-HD&359Y&5n%yV{h3nPQEtnzf71La>`WuIDCyV67*b~EB?tGsug1#WjmGgZx$7k`F?Tep_QJvE$I zHG{d6y>EM=@T1KJ!#CCwSM>B?$N=h1g(^SWcDn1s5d1w`8UE2--SKLNlVD5{otd}b z?KDP0bL;-hpZn@3OOGeq#~mR29D+d1Y-+h9hF>vN)S>&tS&stZd`t1OzNn}u##O@9 z@5D{Qb1QF@Qc~v?$3@pV>H9~&eyaI2SqSBP5zRqU+`ISrg<({G*$c-GW{-*KUroqD zY%T4!*E-%#Jpq_6bWm(JE>wIsRoHgsI-(&-W&<9d<^3-E25=}{YEEWJ_Z>!#ewniy zdumGFRzE(b_-4xwXLw8zK17r}?L0j>>IuXYrKdBkCBLYJ5Hx5dS6A0MNhS;L&9+b~ z?JiQXcbI2ixTfq4;jb-G4|KHprS_P>RK^?AS8lZ3zr5D#kFX2BZW_MsVS7FzofUqD zjoy#_5XmU15i_6C&t~*^IxuPo!CsN4btlk^`z?b@IW*YqySfDnwiZ^d~FJAnhHLuXIIopv>WZ;?*O!3-8!eh;NS(G~2 zCG6+v$7}r$TjpN<^u|aIddY{JG(U%v{IA?2|z=xGbjuv+v1e zT$y70qqgMROidcxcL^yFock%#KJ|>XP1Ba$3A{-BfPFOPI$Z)T#Uo$Y32gK+-R3+G z`Hj=lBPZAESk#Y}(!OL)A=m{xvE>4ipRCn&@Lykb8#VDz$s(0tA<&jUwfSn(qAV;e z2Pqz@+{WhQ=T|$F!|)Navij`A?%-nI2q2GjoUHeBm0QjF^y!uibDII&bQ7NyjUSM} z%0A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 literal 0 HcmV?d00001 diff --git a/leetcode_101/docs/10-data-structures/10.2.png b/leetcode_101/docs/10-data-structures/10.2.png new file mode 100644 index 0000000000000000000000000000000000000000..9a10d41c365f9d47dc2f7f80b4e2e66c4af6696e GIT binary patch literal 109141 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
2~|66qSaf3sOSPl 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%0A@sDIkZYs5DQ1SxzeQulieq@yf#sRZ=trPH^Z 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

?fA? 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

ls9~ejzoq+X~!1MR}eUp}1 zSf6%&4KfyMk9T0r2a9s*TFdDQ%`q(E2Xcck7~-@I@*Ld~jXaWT*#R76DZNY!s5MPS zrybvnvyNN4z1A}FeZZMa;DA$j6Y)s&VWCmOZn)#8AicBvtBn9S+5j|L6QWu(7ZdwCEy) zjaqi}%0Q~%&S{z3y86y3%BBnWNX&xl-xZ*2mi?E52|R=sngLA6X|l`=cITPTO{TI8 zH*ccW_*?UI-@dV_#R}(l3#2dCe^Xdl&sF}84MKru%1zxkruJZ8A3%V2eoh0~r;2n7 z0QSsckcch5C86I2R0z6bfUT_qYQ*_}rlTNr-RbJ$bpFf;*!tDhx?b*QoNfYa|6f0P zU{NW0bqtFQ8-ebxSu!!v*femdUrPTU=jjs?2vt$v*o(vdQKI{&cL*H5@@_N@SIQ%|*6B z;~pL9ZP(7e1o~Q#JUQ>zUp;W?HC16X?>7K1C$Mi}%0s)D+Sd2C_`8~~&NjDUsrkz} z_e7e9wjWq+D^-=u;MBw?Xx=6DRdvQV)2DAbAEb4F{lHgujfdqe$KFMJ9Uh;G-EI6pG|Ok$<9o_mt}Ss5?zok z-1GQ0I~d58c8ffQP3WNF9A?mf)*c^77oWKVd7@4L-4J}`Guh--`BHBMD><8*XA*cY zM7(6T9)m~tJlY(s4L@3w%_%LbE{)4NW;%(KWuUXs2zRhf%BC4#1{(RhwN&tw;?=h> zj;8tN4_Hb?k;%r0oGi#RH3{jG`qk_6gr<_GR-q_urV_sC{SDt12A z2tQ(+;HIN}srP!*rf>fSBN@BJ`2jj-4`C%gLQG-mYP|2LQBC{LoWkpm!FMQw);~4? zaALFXLFJHyD`2)9N`J`~>T|s|Y4j*&_0*WnF6(q{2UWWvTz))*lq?mZbJloY>)H$T z{m%A&?p+PyrtA8o;n!}#)z_+Dr=IuifM(yRKK`-(xGh{uQ(Ldraq6c!7D-Fd*{<^? zEMozg(sPxM=mGMs1WZM4Hi+65Z|#pxRTz#$h5ctZ^NU%>-s)5@Gn@cLv^!9Pl(61YbLPe`=THMOzTZaS za9Z)udKdf z0=BOO;OM{%7)XGJ1JK64p+1+y52a?H5k67wmr3~MURck&-aBl3KZsPg<$*`-A6Ah> zZQ#!2;tiDe%{7l}Fkz5J`netW=ll{MT~^Yw#O}2ppPB`j_2Z^mzADWavMfxaEn23O z{iOFeDAsb0vpRfUR#cju?!hKq@WnEIDwpLb{f64qeXA{z%jb*P8V*LlHLZD^v4#Sc zVHHmAlcp*>5xwK)ucrIS8{~I5?N%J=zFw&uB<`lyuUUv@F?PM&4B+BR-mghCa+LX! ze0q9nz$P-{^(65(AjMG>Rgs+P?E@Eo;6l zL7B4#E3eX)!U4mQB6&;E&6pM>4;$Z6F*csJ-aPm33s*?(RjFf{hJCf-*#ayHz&&YkRFB*PeA zuQI=*rB($|J#u@ym-+yJwMsF9R!OW6^zKYP7tKgTtj5RO2xbLQnw~U8<-`Kg>t>4W zh*b#%PoA3wZy!hemSpfZU^YApa6--fT-sT6r^~CW$VzCF6|phQ!HoQZ4-8(e2FrE1XgXjI**CmcqR&QklP&Tw_7Gks}KpjbPDecEZFiw80>sUcYUj zd145X^_=Z?M9WIcK2O2T3Tf`|q^Lp)Ve`(^5riVp~-?+7_(QlUN0 z5->RSXn1&X`9N|N7+~!4iLMJ(lCG&yLUWUYkHJr|bohV-ke-TpmwACW9+P>p5+Pw{ zfX+5v5-`YuhQgL%mPq12pP`tmD3f|I+$$+Fbx@4Nw?Y(leS7-)X6(0z^Y8Ozy$x=XEiqvjPP-`}euB?g z;u+Ne?*>39^&iv^w7RroQpj>P8Bda7#R9`-pS`Xlgt^vX(W{Z?k-4|x19U> z^JN^-E7i12{C&+*z2L$qqitsJVnK;Dub{yS zk5BRBuI~W{5X5iCUavu&^l1q_ODzrta=u;ec4mdR-F!)La$8QqM%+z4uJFJ#uA&Ql z?D$o%s$}o>w{gNMX+Sv88Qk7-v)nt+ca4*3vRZNET|Fg&^z{w0Kx?zdRkANVRr>7V zxYfG&hM-Bi&C$cKGZ0Gvd&JdKBZQdlqD{$R%g{9{%~jVe<^$-Aw@~Q`!F%Fq6hMM` z?BWQJh(x7EECzff9&rFo;)N3cl!z0sgv^n1)+yH5Nl;KbIN+C*?;#@%8=|D}ocjBq zwtmzEfDeD5+V210x_2!qauKl$h?u{K-jt0;4sjXeXNAo+;70r$EEmH@$<+|>mDK}` z_B>WpyDJN^HXA-0>fq8;8hwGjuRA+sp8{&`kEHM_j|Z(wb|E%iBcQu2N|QX&Bc_8t zmO9RQW%7)Y;2>4KH#>IOVxYWf;i(cPAz1~8_H)q4^+oh}PGW8{D>x!Y@*-*YEae8P zF_=35?{N;8QT|-Uos_Qd|C8z6MCbO&NV6I({P~-V<@s^Gx^Q7na+`EuHIQmAsBpx1 z0g(E2z{774*gL-?8)9?0w!``5k&r@l>hrzw3Aq4sQShOQs}W)zY}%SU>fcM8^%NU7 zi;O8UBO)|?{LhYec2<{p5B6D8hU?x}-@@XlnVyjmQJtQB!}V~0U8^8&1}N{EJf6Hw zF2ubwIZ5X-Y8Xvvngk)W>452I_k&h!Hp5^g0ia9Q&))(F7(0m@$u@2s;8K8KKl|O~j-)MIo06_N@ z70y}v*zVF=SJF9M7Zm~q>D#J99N|84NZ^7Mrt>8k0EP{9S3Bs z1XYzB)UKnVDc$tI_HTJU$GN`bX2{MMj7k95u@xoC8qW__(49xCe+L;hjhwi^>Gw10 zl{4socapCMFR&wo8fr`^XR`uNEduUaV3`#Raw@zgZGAJ*ao7(o5jdvP+OfInOhlvZ|M zsGLjl8e#vqLuvmA96jXV`W@{LQHDF=5D17FSr*!pWXocD{E*s|Ucy$HS(6VupO}7r zRLSos%|p_#Gu5TTq}ul5iB3+T>n}^lWdD0t-)$a5EUQWaXC>(g;F`<==*9|s3PS(x zx@Kd$?PxxP?w$J$%5Tr{mhUF8_qQ%tc>rrGCty%HJx$P-_5f@~OR-`Zt2(j1H~U3a zQ*Y6#<*2V!vMDI&-J!{!18vVc;=Pa%R~ z7YneYJZOvfzQppmXf=o{$|r-*Dx5n%xc~3^$Q-OAQ)2J$>-%LH%LApFkC^p_(7G*y z1MIv4VL>4gKY|XEo%+=~JNukE)=O<0+^z?@bJYns6p%4*K1+V*x+xbvqw#~HOKXt_ zy$Sa>BSUnql$M?*p7lgCH6KsB<-fpMBzCP%Bw<&V526ev8j8FRpKRBFO~Ur5hKf6Y z4ae(a6X;bL*Ewf30@R&hAU08*4ib&`7Rn1MkWF1?n$rbGmH229nvD>3N7+$>`(^{E z$MKY${F*n}ul1hLb`R_|IgViRqM_EIjg3ss;ddJX9^Ni~epdo-DFGj0#Q07S+s6&= zd~%nQr{J9D!Z2+DjTX-|QHZgY^vOy6Bmv5(ztF<-07$vFp1r?wpY_>|E-YsShWvyF z^xsqCQhBFm+vhrFb@f}bdD##hw~X^RLzS-qucyaVKB7IOQ*>qV0hI%oTUPZKthcVI zX6{n@Hy7rrg3H{;O&ivTCp4QAr8~gART(LjfPN>U#cB=wlsh;mv8o({=+-zTg@uaZvh4&&st@!Z>ZwAzrOS@AR*VV6U5s~5$6Gvj z0)pMld2a?NzXRH8sy$Yr+N@X?;M+5Q4(?Z0!t_NGCF_`<2PKF;{ezo}sO#ON#cm(3 zDJ*H|<&=)do+||AHJifvU^BfOp<4+VIx%Wj9diEwkv2XqeP$ZkyIjxe)pYMyBl`(F zCM7kQ=H>t_IR6(m4dP)lPqS9$LijL_Ap!{*uOhd2X;*f^365umo|+gS?Q}Q@uKZ?; zlC0gmVEPrRD?%M1mSXND7$D;)yIh8)+@xt%aMC{43N{lvzO`-l$;;nPo4!?eA#KYL z^Ez9OldQC66qrvN!Av4>1k(A}j;bHe57;mL;~qumrV2=?GJ=SLoLlUkJNoXe&O*Re zolAL>D<9ZNQYZ-2h($9XQt-X8X#h1dn}?CB-$G3h`f%%2{H_7qlzMQEsS=B=fr4$G zf!cR9Lf6f_*?Pzc|J}`cnaTOVb&J|c-(qm$WsE%tj(d3a3X-x$wg9cg1%$$fIQ(1> zWoh}#@0o|SXU2tPGqD?&Z(VfJAphEn{rcB&!WgJTdyX%IF!*>emD#>nH0|mHCOCIW=vgwPY2(2VhNo2~Jtb zCU%}fI?$vNV*=aV)1%X@PslA;OKHVYfZ!FM#`ALeS!JD~d=f~JQ}`@&+@79NDikw| zdLIhVDjMYb{Q|gS-Ygvs0+Cid!_&7XZ38L&c0YQ#dak-ySrgds_xs2A@lj_mY8&+8 zK^lR(!+}7!-vB$C?@cL%5CybBM^U8Z7psBo=B@-+v)+3Z($T*|nWCJ5Y5f-#ynH+w zK_@r({0VlWH!?Q9lXfc>VXHWRI@6l0lyfUxN#4B;_0`j-0$iqXW4#;+%wm%X{-dNf{Ss7RA=YGI@!uAI5-NUS3`^llmz8D?mxCTF+Vk`vALD z8@PH8_19sd(x*?PZ>V9Q1_*tvIni0E!4$+Z*7sQY+vq94Y#V}bIVrI_bFvgIm2~O% z2Qto=ra#Q-p`iyO72v4YIGwTcX0%_CVg0Z;kVBU|3B+#8B1GIIFAp;PQNa{|=cZrd zFfkYjtQW@U9d5{cH5coHBO}|}Wfux73tRS^M#`X^p-){4j}Q{OC=7AV#)8UqqBKfJ z!LrC5o5q~+_)zBX#m7F_b7F+IBw&U$SSJf=em;|1nGk`@*i0Xk^3_6TM(vvPaZ zeq(zB&h-kwuxJFQ65jxxTxg75?M5JMH8xL8x2(G5as4K}ZnDOVY9DB?1hqi~irijMxFB*0<3s=EM& z>23)%eFpfZ zq1CrT!gTFrdzC$E!m>1y13P>G#XK+f>=XMOKkGn>j{~PZJ z{o%9nkzo$L5P;ur07tN=Ub_DJoz2Ffp}8Im(S%K;Mwq7Bu*n$^XE%>iM(c48Jh14h z1DomL+;88kcQAz7x!YV^ECs1bM36^@nrg}Aqg(9`$+UY1XHtJu@xy77w>gc?7}I(WuIWcYskJ+s1Ju=7~IJ7 z??QjY0;;{YsuKm(4eE80zkyqhWq?uorI5h&EpmsBrrUsXv1+j^A1<&X-9?jh*i8c! zu{~))yWxBFf_$VRE8t4$fh74WtN?GWQBn1;F|kbEnMpsWP;M)1MlU)kTr4cv0J``k z*ti$}dMFGM%08>IF7|)E*_q71s=bX`JyC)L#sL|KtWd9sG#P6EgZ8@{u%U1%Mpiq{ zJVii?s$cQ@O5--wL0;vq*#td`G0LD7?ApW*O)Q-n+kk$5ZFQ~)%^4%0>$Rdi@4>U= zTa0(ac!?~=GHy8_n-3FaX>Roc;^#5|$x3yP--KfC->Y#7iv46B8vC@kE4jY57IRm? z0H@I%Bo}~73Qd1Z8MG|YJs?bP;5KSFDGsu5>@^(taKtFg?=r$Z0IV|HmNEduUZl^4 z_u&nn-8P&O0EqSDWH3rRL^OBXUnZK~59-0Y4N-TaP_QKvaE#QTNFlTV9`hvtdT8Qebi#X0PUWt*`}=$( z#?B>ZyCi9202Wa-Q)Q=7Ao<1|=L9VJ%}XL~6O)hMo*WS=DNFIDxY_3~v9zwhQ%ttQxt72?djJSM zJ9~7eW8mJz&RvGHoy9TQ2S zD-MFaU?t<7$pYRxzH$DoC!zlYEb$dFl+eH3?XTCi>%+NU{EQ={QZ3t?$X3#!B#V%g zGqqGovqViJP1h84fp|CK;3(it(n}^G?Xe5^ybZA`5>u_1{?MYF(VI$qYbGMIO?jAO z37hY3yiaBOnglhl0W|Mmv+tvTRj%*i{mBf8?nkl62RAaD-*^JAn0wkbQ$a7RlOO!- z#1=Ai96Daqlc=~`{3e!^v5@C8$ph9eV0oC&i2=(={+Zr={AjTLcEaJXU*@?pRP6XG zV$A98d3k`=>9ZH+bGK|#m%xo;Np-T!uAZd%SKNuuYD^L|2@tj8rv`VtL7$}8!x*Tq zV0EjfajI)`khw9{0dG?QGh+#-;Tn7KVP8eWa>Wr(wTrbS)y1t00@DuoE*FMjYWj=G zFi1^^&Q-qiG#e!dKtg{KQF_K+x>BJ6wbo)@>P6bZ#be?xSkk-Sqy? z4`rW|FU?5+7B5DwIqCUmv3WD^JR~Wk8+Wz&W75=5Lr44*^T|X{}ang>tY4mizEW4f?PU&A- zT9Jhea7ga_p$m{cLi)hhkKm>ZTd>6r>~xQ*i-X#}1QBA6Ge3H{*5?st^m1+trsDRt z^hR?PfoL}Z{a64h#SnTJrdWo#{WmKH?}LLV0Ji{3pu~;$32bkh({9;-L&fF!tM?S2 zZ{O3)yqS!buh81N?&f%3<4DWN(hP(--dDSCm&euAc)p7i!K2kd7zZ^Bw&SlDGHJhY zxmYkRJ;9;-y}!R-Gx@dLcPr+$BQv2gUl`%*xX}2^U7Kr6&ISO~_JC)lKDRY)tBAj_ zH!zqXcO*`Kll}AlSn3FA1T8rWGBNta!7b2sR>+zOCNq{xzbS zr&l0x0`?8c3P!dY+;67F8GJe;f8Y=a%lZ(L#Q zxrDXj3R|RmJG?UiCy$?NyWmq>WaQqlYXD&|wHoh9%LqcJ!t&b|)P=ET`LCrC)mLf^ z)k}@Vj{yeT;q*7;qs$HbYv||8e&8#6-&+TBe(1Zv#Hi!bMT^cfl6K7sr#X=wb74Sx zg&|0U{bXROdS51j~c~zdHqWo08YH?pzc@nYn`@kKeGQ#?Q8_HC6MSQ zU@OqXfOBEfKu#mzxJE4gS9Jm;eY^xd3*JLGHTpI`&!gGEnUn`G5KZ-G^TR}4;TgV( zFO8Pi751eJ2nOigUCf;9c@;q6{~gxe|Lqeb26#5IODW0EX^H<2OIN`V)$_G?kwyt= z0hR9l0SkgOqJ)6N(o1)@fUHsiiXuvvNT}43(ku;vgh+QwN=e5%*Z=zgl)ZQ6&YW|e zYGpA5WmSEUSg~*wW=Ilys8TFnEPQzh&HpE_46RSVYQ`-6)#2hTZb%zyi8e;x7PWn4 zW&3g2#LSI!!yk{QlEy~hJYc3ntlj^mZsu}~=Kvv|D{0CpSdeM(;WGJ5Yt!}PA>N0E zKd-NsCLRfa+m}F_ZPKBW;5L6JfP`I3SFLt%pm|y?Fc129596tzb9H&aG|4npW=*g0 z(HxviUU3ZqQt{ar4eftH8i9FDc0^(d*ukkGvyWh_6K%p*?~HieALeWFX#HCB-UXoQ zSu2C9IIX@29zYDc=*Ct&$k4+O*9jc;0-lri3%*<@w=2McefY=p?e8%A*~SKg^yOut zLB)@_g)I(ZbL}%>3RTgSRf^lL+6s5Yq9y#Ykh{JBT&;2{uIcbHux7cQA^0_h+Y|`F z4*#}=M0~MjfWr9}XRtJ0FbSAFod;2D@90|+-r&PS0ob#J#z&l@f|B7kSP8h^F@hS; z6)=9d--&gQtV5uO$}2kU&&5m5v=}bAeHqc_O9PUl85zyzJR%%&*7!l&8N?_`0%7f) zAJ)y$fos5}ss19e1<`+}_aHm|J!zlPsA(}FGOV})z%Gfi60GtZF#C7b%?|-{{^hIZ zWMzNoW}X52W@##JQ9FgrrZtVDSA9c%_O z-dB5JxTl3ppV^PhRZ-`VKOm(-4c7frO~gFzXnla!EZiik#N;OCH_ja~$M+%m z3r}S``u4i1(g1s%RlMO7f+L-}7MKLqBPUQvq1wpE7H1kvtn{8LPQq2YbS*Rvb();k_LRq_NVsK;jyM#*dIPU` zHE6^}t8e?xO?H%?PrP(lJl>+p+M=iqJO$Uf=tjIS5o7JOIe6;*TSaqJ$-$ho3E;jH zm(gDu(JHjaZ9wE*s$w4%PV_3OdI0S2>UM;oF~j^2Y(nMBRM_ACp70Opw5ZGTSv*Yo z$7PUh;W5sF+V#?u&wCip0pgu~XY8)tKhgAHv=l~RVgFc(iAxa52^z8m`mZ#r=Gel>9U9iO z1Fj;-q$Ygm-ys>>C^7y6mIbiM+x`Kss0WbmN%?FeFrJ3G=Dp_&2f3I(G4ijRPf#>+ z9vJNxtZF)TLr^OTa8g#(Ml;r%hkXps?3Y{V81QKmT=`qd?!M3#HKSXZ>ee_u_?m`yBXU7B|MM<+2EWkt6iIU` zQTTNNcdf3E2qUK#xZ4ZnbvC^Z>mrIyy$xuoEpTWES_V$!ERqtrHLoomJgzGDK#@$N zsPvE3=dboM>E+JB96X>Yk%e~DsnDwhs=JB2?%mwHt%l7`EfYElTnWyL-d*gh1IK0N z?C8xNX_urd5;aO9QLBc1yJN2W6<{bQwiv?+7G}FtxU9HQ+6+cbMz$Dcy2fa+9&v>TR9PLUL+XxZv8hWh28LY#C zqGqSc!zX2=tNfNp?O^sfhO$=0dFjv*b^+gHY7NijE8Jx7|LT5y)2zjPWg#iT@E0jd z)nPCo6=u*q8L(p_i*(M-nVZd$5B;o3QLBphnbIW7Fn6ZB+lPBpn(&(Dj~3tadp;Y9 z%8?f5K|22Dps0y4!S3bbd*1D$HZYkd5~qq-BUHsF?gY_BM`3)mm;T&ue4}JGF|AWz z&}+qWmc5d zPHSf;Uc8C93_*OhTIo&BP#eypIE`IXGDY5+xf`bH7 zx&K+CppZm3WrzRWn^$DSIN%4@$(BhS#6)f`(0q)!Sv$;UY!$o3WD#jeG_|Ik=14I2 zghmySmdll1PxTyWEd`D0Ah;Q#TlUvfe=0OAf?Dy$2y#$;=-9hlOms3v6u`Z%PD*Fsqg-hfQm*yD}JVdg>#w+eD0m7^EV zFTiWKRE z;G5{-tClbYy8O&N7KW-0t}YO&@Cl0(2rjtu8m%$R$f_Ys;5B(xs|hl$___w0djH?X z7!3v=0!DXqs%!{&=%jD-;0cs)MnW=E`7nk(vZH5kJU#@#1C8R`$O_G2&Q?yU9^v7% zVa}A85dZ}(?+iFlAIg+kW_-muKcne=+KU-oWZ{w6C9MHB)0^raBs)}6j8JQAN&7@J zJdX8&RK!X|kyUNE|4APWD1PQD#V3zC7dn~osH&9*i)YJL-cEK^1+Cn%5t$-!t68Qo zXbd_T@afoxi<%QFfG1f3-p2a`!iBIMj52Om4aTxYq~h7o;|?2e-qxQr6!9DRj&` zZ;!5zhSIbX`p$4W-eYhui9CI3FC_X-5-}KN`79HU8T@?6#Tpi!92%(X;ODX+ZxDvk|a14!d59;zo( zJcKoDC=V8%{Q*AmObYmg0m z!7s#~{Zog{q2nwaup@{!0P2YR&HW^z0N*rmx~dG|oxP9|utJ}x5d`4iVyDsK^UEq2 z9X?97k|J+7yy`s>B?*H5?fm-q&&KaWkro@T`o92y0PXMoAMEg$z%$VMZrYh#;?1R? zVf+Rvwi(L-_;m@H1~fDY0;cPp&;r;|lFpT`j?dCCJbC*fzHbj4TQyk;N7trGYF2K! zEjdcX^W)HX75NXu(x?OuD$@qYcYleHBo;5SXF*f)5vUnTjK2wiZ{wi=1plF)+!L?* zLFBfc=Js{t{=%0{fHo{J**FW$)MppfU=v?n3l#}e*toPzsc1I$CY(!cr-Po^{hXWX-90baw>m*2wev zA4%*}6*>+XL{6o7*_mMndmx<#Xn(+{O1S7B)C5K~3Yi*!+q=)GHjX=)DhL=ZSApj+ zISJ^spW0Ag&|C&VsUC&hC06%dy$-+Xrw#X|SpY{65i*`bV=qGuHj)Bscw<6Ozg3lU zcNYp{-|Um#S5GWZ#hwbLsYn8Sz*S@EM4yi%E12(kUk*24;m- zGKl}^pJxi<+nWQzyy582X2o47wsAQSetb*LP4d5?uLxz@AFbfedA}i0wS940@V7;v z9h8HZCYI;~O02fAfv6%H3XC}z7(4Pl%Cw}6+*DtxkldE2i3TU9!s_|?$vzW-PckYv z71xPbDbMYxGl_BACZVmsuFktY>riw%`NVCRr^mESS0|R?)=+8=K!608=p0qAB?G2A9YG$l$5&a1Y zp+6ThAWf*ni)*On@?hw3U84E3aj!2w9VFdm>MI2CFF`4|4a}Gin>s!8dta@7*D}_A znz3x??5LO@1e&>WSCp!VDwa61zXVLT&f0(H7ts}oD=;gm=-bz~kw@K2mkb=}LBQc^J;kuakP^uD*akM(`hRwkUP}Wd)W5mZ(J3doM|W7GU_sXy z_NQFS6NGcrI(taX07Xi%NsZ@~p;OvtKj3XnjkqV0fNuBdgo;04Nxe7LJOO&F~3zx9(&ENUHc?U*Q0_1+5 zmO|OjoDH_`ii1Xr@5N zq}W7I^|Ti#A96{Y@69hynazg6NaK1~>;$ldRZSh4GE9tX2Q}*LwYi^OY@{>GM65;eufL>62_4I<7 zA3Ux4HycUHyQY9FR4?6OqKu>O-Fym?j~9(*ug`gT{Z=vlvx_eQ2;-0TOOEAkwP?xe zQ%macOm~B=7JGwO!GhLI-}}KUx;TCL(;$BRN)Ow6+wa?$4Thpc&T!P{=S?p+*Y0P< z-<|w;<^eQ5;Ik-T6zr6k_KufWekDMnU%Q4S45abc0T-9a91t@lC2YsEyr_v{947@X z8peydK8qR>KmRLl@iFit*a-%#nFfmWWKvO+u|54N=W*cV4n-gX>Rcku)k!!%3h&6L zidNJ=L;m~P%^_^JH5A8iC6$kZFm+L;H+IhMaxatJO`zoPq9#HPMw;V_{P|ryC5xF^ zOkd_zqDreUAYs<2UDL)sy^d|7(&H-5xtA<}x^d_JRNZkz!?UV8J1wc2E@{%vfXNYe z>9mxS&1%KyS-EC2idS74epU+#>Oh(U=g1=2d!B~58_|k%T)x6=lBw;yE%nS^_Qj=^ zFU^NFD)^a^!^0n|cfco&|At_Pw_Vp(%m$DU3wIASYneU~buhkC(B_!N<-3Y8^Z@Z+ zDXT1#KsBQ#79{R5QL4d_N{W)Z>7s0bQ=vL-m?0Zqek}QkRXo+SY4K8c1pkxahG-=|j3?4X$DX8#9Vj_{t4 zBF2}^KJlcIi6HB7FS1*xb^9IHhJ-fUC}$f~d_8#QuS!!bAB-x1uAcWP#T<~wEE~;| zqN;9KM{^=OJ=Fo7^E)FA6(%DeJq!SBoXAWX&SXB+1t7)D%(HA(8h{wlR8$2k^-}f% zgmqv0I<7gw-^^1q5hh}cU1-n2L-!w_ELp3s$lBb)qsCMhbISqwP`+#TJ9fiA^?M&v z+rq*%65?n}z7|x4El^^fUP~GT@V20{Eak^*NyXMQ&*&0vR~;sawl{b^Nbj-0(N7k! zk@iR#x?$Kgzky=t13ZD%<;g*905b^+CdPys(yiS76VQx9Q*QqZ=#&y25lq9xj^(iH zWq(thNfQ{~f1$-Vroh&qeCxEng7;`@8PYHc!b8Rsf;lu{vlM-21ui&x9x>7A{xV-) zx~Y#R%Dl)CkH@FUx_FR{8SOidg;KF{S)m*`^W5NmPd%1`if-qpj+EciNQ5{wpEdV$ zihBR#PUW9AA`FPL9U*T|18C$-9o1voW%@GrLNHoZ2{E^?bZCdjVc~ z0P`kmoZE;iAo+)$aM-)((W;kC7+Q*?UG4GQ+QnX@NaU=Y+}PVZ)+27 zxRljoc))gTS|)!+oaje7Q(fp9TKxu+kB36=`H3ko*+e6rCdAA?d9V$yqDZJPBWhS4 zqoh0DZ4?iVHS?}ao&^xvby=p6AV0wv8$weva0?G;G3O*0+(Mj}h9u?rn(i zK^P~4_$Wb?OB4%=ePe(se6e^&61>i6gWe@;HCGUUq%cY!(jXM6Ru6LJ|7C=Mkj#it z&u+QnN~ckdzjj(vw`8BygS5nrdi5TA#oOl&9zc_z`^cDx8>RPEx0@DIJRuJ^3JhGw z<;$omev4*@^CqBu0BCUBpV_{GA@fq_yt!1IV8N_ZO6iT%GVzz^4^!?3-Q33Elvn>} zy(J)_6L*=6WicXrBQTf83FqBsWaPh~X#szem(w%dEO1NA?I~)B);I#HvqtOu+ypm( zT2sFmjC4M}sJLp6VV;Z`(@)w|Mm#wN7yb+WFvU;0K9nBzjyEml>k7_WNBP2ui9Y$;$6ca66e-EJZMoTep#2*1YZ=10)t5V}64J}39X z-|b74=+C{EJf_e^%qxfm6)IuyG?W!()O7Tm{79lGTuV}-W_~VJbX9fHSyx19on=mqmO8B))H^v3}?Mzgz( z{OJD^??=73lqn;UmH$GFdhdvh^!_ODeoo>qFZbKC^?5?X!QV}W3GimY_z7&*@%S!H z1QzU~&nS%DpsQkj=iKv$*eI^zl(7m$p;#2aHV;Wjh>>ru9Up-}gG0WvHBAm;WN(!t zAeH@QP8jY7ER{+v5$R|irNp8)hfmG%2P$DM_>Egg7yM)&xUJ2$)#avPjTJ-Tv3Wk> zWTIKXGW8z?jR*Q;UQsSe*Iib^@0pq=;DxuC0MX=0a53E7?|l`n1`A(fLUvZ&sS>Pd z8;YrdWOvEnB#W6I_^8+*cYvvEtLLby5Dny~+*|f{us&M>i16*xi}wPi6O_$Q;sm?w z294bsmYWh}VJ1m(0-RK~vn=D#2r?BUUkKUtF(z(XXQLqiunrV`VT~(*v=tcn+FRz;KFWoZGkkg*`tz71StC{^@j~u6(V<&$Qq2mpR*-rO;SG6BXuX-QZf-kvvM4M%t#4TM zAp0q(P#&bqb=c7w`<8WwD<2txZt3`fALjl<)mWjz%rVTR^56DUPLJ1YQGrL0}h0+hf4Cg=Cl0+HDA$S zZ85}6xi4E32w_Uq!7~WF&U*H^aS!$l=dZz)ww+Ae}PX_kocL z$PE*m8{YLTZe$R`6F>W zfCMc$wmAupfXZ$Geq8P!9(a%G{Tf0Ey+FNRLuWx=WrjrFJN^BsLE&*;v_WJ1IL>>; zX`9}>hwVix$3bxErSZ)Cy)E5SUS0k61(&hMzk=1cqA01cIl`}! z7$NY92w7=Gi2S#dx>(B(zW2$5dqu}F7NKf(A^?Sh?}A(TuR>aDUOa^Fn_(=a_CeiN z4H+BE9tb?ja*XfFVPWzVWmSxntuu!40s7un4C2h z%XB)=PVoj&5JweqeHs>R*R(72dB^>=(G=ZnkqDqyQbT2o-xM&IQMtn$g$H7aWKK+|1$qP@@ zfx%-|$#=7osdGKm;DfjqE}v#PW2f4PBALwl1WBni{L#OlA0)3m9M|kU5@vvCP0}Bm z^KQw&v(j-3D*)mtbg&wx8m;^#$(xqLY;c%Ct$rO)Q}m+@tikAF=7{M~rX25EHIt|_ z_d=jE<&#w$x->NUgK9+j;o&bLWZ)PZax`0+q(oVQHV#dFc@C)_C$S5w3Guxm&0rbudl=wPb34{8f&0y5ljV#=uzs#m5a*Z)8$hvP zfTO=cgmnIK{|44K!sl_4Q1dbi0AqT-f8aF*B#w*vI&){bc&J(EAVIEPLv}bI09i$I zL;RyUIc6-Po2M+C;VR!0O&jIyHq3U;R{;|GLbm*rzD#sI|1gcCeX1nZIdNWVRz;+3V=F@)CI2q{3|ZI0kd=U*{V%rq ze~$tdbh??~PH$x+1$Giz5&%hG%(Arr9PC~ZCxz_`bh{!#v82_ERWJys{Ci#=z63+S zX)))qwS$$s-OIpvELctPP8F6|8c51VwqCc-`Gs-1J{B&MN&yN?+Y*^?}FI= z0z)4|Lt}3`39jI_l(V67bFUSAS!Sr2X$Y(XNpU&3{yw0)@K-Uvmu(-+; z)I4Dlwp1#8eAilq6a7ORJ+D=Kk>s)&;{(Pqx zLCR+XjsX!BtYuZRHGa*k|Ke*XY}sS&Q7s8lx)3m{!Y`{Qu7Y+4j==-fsH16hd%93D z&GfK|P2d|!giMwQcc(oYe_W(rlmeL1qdzA;COiIi|JYgvYFh2d$fnbE-o!O`wj+q# z6k-l&Ii@hU+7rSUGpwcXyp;aTJrJYX2$bR#R3$SZSHXh6r5WY}h5UC=4`@xs0_E)5 zAaJy>Br3$bK)>kt=<3=WH|2dx4QAb!fu|%$z0I047Fnk>>69WT9vZOg0y$1V&m9Wi z1_wGcZg`cZfE*T}bc2lz0HRt&U(G{5c+3aV+t>Le)-z(~dxKoN`q;r3etYk2 z*e8DM^y~rYOJ)?F;O7*DBqkjFK$z9Vp@HT&<-B?tVh}P&G6SEj=sM_$G|tkRm9k>q zw_H2A4tw(efq2m$*+p)DbwW;qWBUD&tJDfdzXls#l~S{~GH_v#rkSbKRshO=>4J9N z+HuJX-iexU;cL$Pe0{2Ln(-uayVzHfFjpb?Miw2;$hL4E`QCmWci0*;YM0TMU)C6O zi+zz*-4JcULN1RnM((JDB2a4@@T0r$XrwHZ?2|p z*HjG>mBE5S+@i%my2DdMSxSvg8tnbH)=MXF*IrHBDRT}N*Jh--%rg*-MK7Cc4J#yN zgb^Y2G=luYhgRrtPa$rWy7l_6FEcw~*(sOZJvgD;pKiE)HmNC-crKJ~TtOKQ9~d!{ z?&nCV)DXh0b$!Kc3(Bj<*stW|m|C3U7sV*4!Wcz9OMA&kYNb?h)!lW-qY2Dgz8mdE zE8o>z-vstFcM>i$1v99@DcfjyM`Ra!jqJF@;wJh@Q7)G{0Mp-v6Cpord2zsb#WrNr zu?yoHxK+_xz=$ftKg9`5_055%ZTm6FjPp?2q%sADSmfXh&G6rVd`v>VgvU;WH|D zjBL*&jL!uW;Tv~wpB`}UF@iQ9!eC5xqXn|O$xDv; zjzQ@&ovj>0T;%>>^jc;-zy|hBd#_Hi)#97~@;Op-2I(7K4s-N0N%2LahuI>~?foCX zY=L1y>j!Rhl=qk^_!tF7-=hCs&F#Mm@Ou@4IWMSF#4UW$@!YJkl$l^$_B~II{Th>{fr&@B6*(7~0!)+41KH+85&gjf z9F*lEdtZ$|JQFch@}A9UZ5K7{lf4QmsZ6x^4gzT77$iM&&cF#=Pcej7Q@tmHqMe#PVPgq7PK&0?% zdeJ=9d{ddjF)L{3(M`A;T@MhgjLG8^r{dkqD~K<)|5!eQi0@qc?m~{XCQEEW;Bs9F z7~^MH-Y8z3>0_(_e=D)Xf*$<<&Ulj?(<0*W0!JT{%cX<;iB34Mr(Y>Qa;VDR6RidW z&qOt_jY0-opuysCf0~VNtW%<#gmOKCyaq_m9iCKvafnP7Be?CKB|+R+Z8VMeumNZr zkAC-bR7F0U20|O6D@kd4T8^NS-;kpiw`-lk*SJtT@7k-1*&? zBI%XKt9i`0c;vL*E$dwCUXhTkl=p7eD=#7Yz{BLU{rCR(UjK`A(8w%_Fcq&VjW#XI zgg*l{4DY;bq~?}-WINLtk-?LAxO;$M|ROvLvqlu zDTPwfdgZ@=ffj>i{RlfErx`#@;87*ED*DoEqKVzkzMvYn-d83V5BW`#>xWqT#WcpU~Pokwjh7zku zGqKkiA*OUW9(nueXTL9i^PBSB~~P8!5=d894KWcZXFKI({I;D zD^%Ya{-g3gOYQ@rIHS$}IHjsGkyGqXByQaL&mBU_C-4^^NOd2Ve+xZ!gPlg2Xi;`|X>~c-5+h3) zQ|xe(zQ5f|G<(YJVube9#qxX=lqw;WTq5tE{y-G}fbuzkWlz7w*_`o8pEO%+=qGtb zf(JEnT!pyXOsVQL{H?`}8mVXBz?eii!77m-M_)S_K>2;C^<8O$3(iajM~7~WCmkTF z`CW+(9y;H-#kme~k`Sdyr~lc@5qG1jJm|)mWFuDQ)yR{FhB(34lm=f8g`y}w1HwOKl6$30n ziIB^nL?R({;;@C&oggBt2OQ2jf~Q9svq^zz;Yc2?An7BZs)nGel5~N1U}PIp)aLC9 zshJE}%_vra$MKQ~76RekTv?&46G&Ggq_SvEZbBu+WlLcdet*o;7s(5=v<=gwTK``6c|-Wc4?hX z6-kAe&Rms)4kB)L=OHlklY#Zx9NT+nu=WBF>|-3L56CV8eP;sf1Q%oC>qOuYV?U*S z=nKO}C-P`{S*=RgL`A&ie}IOR%Y7fmi?&s6Tmdq_qc+wwv)BP8HV8YN2#}=X7@#?& zRd%)|1f-?m8LcQ?6WthMVvkaVRC8NWC2)Y72L(a)-Y)@>5x zr5dvh5wfGg>xzvk>~}-@!*pdt4c|%wHR#1!XeR9UEzTx^WTI?hA5Fnd_I`_WgnxJo z_oTU~LrJU>j=m>mauKl2k3>U9;r;{B8r@W%tZq1K)isf4k45QM?iN%8j?LRr8Y?Gl z>He~=Mf-qpos{j3unU>`-(IZUxLo=oJ8|%G!0|`$chg)m2hF49T{y2-XqHnd>mLGQ zu{VG>t5Oq#fWOUV@Nz;Zzlrbk$Hs`S+#eK-klpXMz@K4HG+B`3E3=qDu~Bkr9+=n^ zu9wTS?|CiFbukjK3$iETAbVc`JH{r{-*H)+EF9cNq$(5&Ge9L(wYa&2g`cvLPWZ4FtFa=+W-?0#{Oie!Kj0H^{GmS zpari5WnLF>iQxZaVviU8;tJBbnWG zYVzNjQ;xw`&ATu-@kwSy67=t#k2fkB%mdw6rf@t)xp_X|)vh34wW0p$d~CuSBdK7scECxNFT zS-JkJD-$K}3?3%Ar4RTo=v?elD-&j3fPm|RDF+xxE&;SkA_U^5!^467kM<_?gN*Ne z_^50SOet+78mwojC`}N}8fIOu=b=zsN`W}tE+KZ{= zc2>Flg+1~~HHdA01UM=iitQAS z-K(Vg!L_t5uj@}oqYwfQE76}1<$kb z*6u860GNiN6Nm8T9>YdA=fbOu-Y>kznHpjx;N1jh z_NpFCd=pg1;QuQQHVK8k4HFyUc zQ9>?&b$rOx_?JNgy&`%+r1^dmSi>d8v6VdzS|Pu!at($gKQ{kwgxP%iJHxu(*;o z4v)5C`N(BPr`w}F3+xRW&!QK7edK?*+?1gT6yUSvKlp#Hj~TU=b^r4uN_|NW3M?_K zweaGz6&1W7ix#!5>}f|+0yCX8K|Ya`f742&oAq7bygM`@SgbYrNhEc4pbqUsZ<2Iv z!G+0Mi&5vpvXaKruZQb=PShEIIdpIR^QWMr;eJ@GhI>Q77+Y9Zt;UYeRuE?;Q19&88tEy*6 zkEa7%;Bu*15S~Wqc{lbbNc8}R4_6qB4jj`60M?l{8M81YUqk_b+^wMF(!=eF z7CX7psN=!ohv$^B(U_ezUg=~YIH_e#z}U76uKJ(cKmIn}#BRZl^yH_0O7)O1|4dL4 zZ+PlU6o6h#l&t&>=BhwUMI%S?&f-miOF2DO4W`M{@^4#)aFJ40PfjYeyapN*4@wU8 z0d@q*T(uABABfK>J2r3D(-`dw*IYTtic(o)mfLUn$$%wuz9$J-R6bvRylV&sQ@mKb zPM`*h?r*}W=F3U{jEQ~%_Oe^^gly0Lco0$fbwl@BpbYz^9mihO0+4$T2rBR2TU0O9 ztQyNX=LPJqxAq@={qF4qb?P%4>E>&suE_kSywb8h8O53L`>5yfHDDso8iP^bh4bFS zbB(5=^|IuaRfEJp#?|f?Uu9=33FgW#!1&N3lF^ee^F}Hx2sT%ND~SEx^qtW_MJBL# zw)?A$6;6i#0ul9R5yo0nX5hA@0T`%+?6eTVO!d;fN5w|_+XZB7%ndb}WjnD1P}mjwbfEdlG^1G;(w2t>_`1`*){pMAcqakp14XeT7 z%DLF58|dM9bZ9;DXApM37jk^8@v=Jtx?@MTek}xdifj{P>+NTy4s)-H>UX@;tNBi{ zr~G(~77Nia-65NAfL<_X~oBju;c;@bb^N{0DN60CTY5gOFnSPsTK_F^kBP=B*~>wB`6H9PNZ6a+Xi3 zd5?P3x_4oDI~D;4gAeM!SD;Z8M*q7QvHbqY6d-^0YPboYo%lb?8nvrzh1NVQi?k%B z4GnOxv^fG3AU_fsKGnaSrfh37s0|eG6gY7nYr&esRv&nnv!~`$6f_`nY%lOhbg9_y z(zs7H|EF^G=9hQ ze=qJSDi4xwPQi=xGHkOJE`OYPKO^w5HU2AmsEjcMI??JG2_wyAVc&!|BkP&!{&mqB zfYQZDpQwDTuA-h8WeRvIQ!go4r+~#u>iTNU%hr`2sndYgvkma_-sl@!9hq=MIhvY5 z<4*4n@f`n1%V=88YsV>xTt<_!fVe4`FP|e3L&NV0ird5Xtq{JU%{I1agYG2*dtire zA8L5{wM)zfEkad~!B<^w*QY~p6N{qI-6?}o9`Tg>Nz+tIT2o_rbG=-UDT>((&c_*i zoDWh~&4dYZ!9D$qe3Mf@o$U6@cn8@>|ACz!+Ft%Fo?C18MD?|>`W}4%=o8WBo+Kk#{E{crD65pSFQ2x1lsuid+c*uBvv^&yJ$KKmU zgsjia!d&44?0ts!Q_gq>A1+Ki0Q`NIqR!nik#j{?*7E!-B9t*eu&3IhC@Xh!xglHc zd%#8he2O=Ayg|YptMMzCy2O&wSAN+}&00L_c66u!-?L{CpvzGk2A$y+5GfbvFaBo@ zh9a&&tdddfGCUOpD<-Ozxanc8+%xo3_T94`JB89y zF!;t>Ds9=QQ5nWTy` z|MSvp1QL*9;4%1Yd-yR7Kbe7b>@@ZB8IRe2=&AT|PNYPI-AQh5tL5c9gmQ9dqyW(V z+e>#Nox(=Y`JXHN=T&mQO#I59&PJNQwD=Z7h>Ex#&#&vnl9ZFHJCuf4*BlLrS<;DYKnd`i=U?Yd>vmi$NKr# zz@u$fV4fFEtQuNne#!XsaI^b4UvG0V0V+w7^OMcIQq?7Rl{&trhlC@gCdk)Y`z;9- zVri}qRxg2{m(GQUUyXp-;K`$W8}J1Lm!3+%42+ni;>v?qwhQcwE*3TvNn1@RN%hAjlbQIAgkfrrepLfR9lBYnGgl9di~YDu^}{Mh79@oRo>s7e zO*&=p^uD#(^XL~VpPWTO+C)8P2Bg06w9J*O&-Net=4LKi?n;kNgs0tNzW;#4^^KUn z{C2@q(rw0)xnI4+KVPMeApxhxul0t6zv0*H5k^xq4T9EP!3T^;432dDD!p%V+L3PBzWv21X@rTFrb?2Nqmbh!K)`8Eb z3~C;Tz)PE>!YqPL2NUQ8woA>fVXyPnDz` zpmraP&DvS*b+>5e(c0bL{STen+cmE{Nkqv}4MqYECp1qc=b#Jc^k8i<#(>vZXURdh zZ58DnSTQo&)l340*ZpQp1#?uALG6B~;#GF%MEX->ZN<^R;7M~UtewlO$h2-eqTT@I%z%t&SnpZ?`*A)lZVWe*Ugn! zkEwtxm$wVUTfXE(1$`>Dyf-E1c+Pmf5#5en)L<*Tlq zzJiux+hRWJx)Sbla!oF8`wB{mD$4_}d(>%AFuq*wQ_oa$DZ}F-PVX;sc^!{|?kox5 zpYhm)LYY9Y9Aa#50MHK*NvKBuc*5K!sSviAatm|{>;H~Rlgl`PQ&q_LYG(3aH$&L}s5 zu?@KgS1b+Tmidc-f!bl*5&lA<`@r=kMhnZb- zR|)eHp^#9iFzG>Ul$4c}J;B8CA(VR>NooZGIHW1CoV{&d!DI}Oj`yK^d{|FgNx;FD zU|-t$`IdA~KYYhsuAWD|RBB{NzNQ5DS3j)(u2E5c{p#KK$W=pMZKKZ6Z741VqIp*` zQtd^6e2AtR-je#C!-al6q~;(C=@?2A;JgKk{i?CqaH zfqhZ|EXe|JHi2#Q@-IFm#M3iiFL9K{&?`{p5L*Ar#Imozzvw}!5dpjFs_XN0uAa7( z&buD754(F3xfr=t_Ai1!{W#4W$+%!{OAGh!-czYlMsUV^=s)Ob(cW-#rA}L@5eTM; zvFj#7q`y5QJc8Dv&84QcR93zw?KgvY9c0j}mZ;gBz> z-+^Qm#E8MTZv&i>nhxaixleT_;OwDvz=+Ya?+> zfb9Np7Nm z*bx&{9-xwlQgcM+Rwc`*zo~jC8DpsIJY8GKAZ!_yIG$rt_@XrE#PbM@Pir9GR1ur+ z$9=>hDPzLgZ3S}?w1(-gSBh1a&;{M0H4h5)bNo+kHLD59hS0+36ys8BqyTd*`V4R+ zskY7Jj@6fQn!(!i_Y7bX7EXYLuz~Xt4nmYQpOk~u^^CwWYI4o*%k&@)_0f9gp_~%aj-@^>x-@B(d?~^5m9I1QaWF;rK{RSdj$|`&YiSGBbS>cM56NTQ zk3bt)12nqqAq742J$xijz$YH-mu$27VtF{&Dj-3|>fhEVTkw*Wh`<-L9yPq5u_5wP zjHzbk-kAH{sw=nouog9enl^xN``s*xN3W&??5_l@rU9WC@C5uefBnwb-9qpql7>Vw zkW3>|pShbAUZ&OOMCdtMN%EhE3KUe%mfE}&x31-<(>ev!^yjU+q-p9c50$Q46&qE4 zbra37g}(`A0ru)`1xgb2s(#A<)s?mtOtBVHbMu+An%RufmewYB{g{f>0F{du#1`-q z`ai0!GAydDYo7rD0m&gHltDTLX;48*1SDh_xk$N)tq8*7y}HP9H5Lb zsk|~P#K3Nhm-;NKoKhjW*Uaf$l zJc0YVi=XcC^l6RD%?E*Q60SR%Vd{c1)nQW%|V; zR;-o$@Jo|3?T!MrXR+K=W9B2^P_6=QKaxA$cQYgA+izm?#hGg^l~#$X4p0FkPTNrA znnG|CH;g(c*vgdGr?*Ixj*}cQ;1UbZzyK^Mum^k|dxo^Ar^xu@>L|-3&kT@9WLI|s3me&XP?8y zA9Ek*6I!G$up0bM9t(6$ETj5$&Xg}kef+Vp-wK-;7?JZtCu(#T`m3M$uvXl8;vjV` zc}K>*WbZ7Od>ds!h`ZxxTcnQ_SL zG7exMoxp78vfdLF_0RS|XKE<^3Lp`!@LJbTh}lZ21VSDMU?8y)a7T(S622^4zYtMy z_Kur{%!LrgP&`*_MYKEhNeZBp3^BF~MWK0+rp$PPFX9j>&&PmN+$n!qlYM?UwbN*6 z$MLU~CQ~#foQS$IPz=Ke5%8rXOk0Vn))JNfjF8}%16@O=u5NUbe9ul1(PwF!G{m%; zyM^Q2of%kqFIlqZzFO5NfBUO*jCPItrd}FAX5lbAJ008S@pOHlXz-YYFk08l@mEyz z0BG53=Y`4UC}3(dq$zS=7!__*5cMdI+5w8rxiV^@Cq7_HBEf1|#1xr)s!s8UtDKkN z+G_OA?WHq@x*d`{=25y)4n8j>If-^D8S`XVIL)_r{a*&`2OS7B)&2kkukIUQ3)4xj zM38>J_N>M@K%%b7m?i7oV0Q?z@9hh`X&m@EN>|p#8f)i-A;-FH7YkqD7`e56f8V!e zIBcK_kRuy-O#p-^5N@l2w+zX~@jOoUM7nSdA|~?#%=~$#4BIyCPA#G>&=Z7+8Hvdw zN2C($Rx0;s%(MyT7R=cE;;%K0hcZeR)>?Kvoh*C>lMjQFbX|!rimEfwRbCGjW+WC8 zEn;1H8!nF_8_pq*_)GVH$rJZGQo86zlpVGqa|a|j!`g2iyY}6s804qo+huo~n`=IF zs(I-9D&pR>_u6p3yP-z=r^O6!$$U=3%S+Ko*U&E(7QPk?Zq-R#zOSNI+Ict8hdQt9 zVjRis#&y(Fd7he%Xbi!~(y?33*^)dLZP2N!EuW)cRjdSjuLJIuR&$)ri`Ig43Al_- zfYrkrMp{Vt*z?*)&Vr#}2LiI@a5iH=2*d3v<-OxdS@$&}3X``k?3-KG#>b_Z*;0;A za=sEUm{!9GdLXnWWuHT_i|X8b`~?p_l5X1^lS@uW-a63;+cJF8>A<_qy`1uJNafPD zgqU*HMI&MLK&!+^&y0YpzUTm)hD#gT(w**8)j&Q#nk6PY(P2C{pp7~_7qpWmQ+;Nm zU`aCB2j6obCsA)Z%U4|ed(0lj3X*)yqbCc`0j0ROFUD+LE-p!|U!M1Bq0$#KGwO~a z8q4bY2_i&#@U+d)jWj-by$`QLX2-#-_dKC4qpVYGZk6?AV~gJ>VPzzW%uX>{wb29T zv)+YfX1tilc*a`H#Pu?AfZK)Q!w6}JG`SPNl*fB(%!_{m!&Hr(?U~EZ_-LoduATJ3 zb6}Hr8LCM_A2QUG78#)YD?^G~g5YO6%cdsvw>ZX4;Jvq0z=p1sco(a6FI<|n@*oG4 zfPMBNeqe@HS_!N^#s!7=skX20v?p>4K750x>zo@x7ACQUbwBlxX^*2c6IBMIC{8ot zwmIUt{|o>8PTSQwKODRjThySe7xTKaUc3XVaVL;Oy)0P_(=qnOC6eT|NO$gzZ-XX9 z4a@-xa(1Tumu5;T2!>IY>pLgk$zq%s1{H!zo3TsscyGKkN?0& zU>sgV=Rn^}c@w;`p0<2sHGBr;9=gW9Z~Q?qRmYg3+SQRc7EQ1R8k$pM?MbT^c_Cem ziGU8#-EiAQs?nh>XjpvRseEL;ec=kQFFG%(eCB2?Wt4HqoP4k-QUMS2s0*c#7DvpTh9rIqAhoB1o{HW?vTDbFA)<+~# z{2a&ey+{w^R(ESqaHXQBF@Q;zf~PX@=PgHuniSWDhBw3qgkn zRwSTb`jolc#bp5&MA<<=AB$aHNNqd6@XR+~`&?y;%v40hQ+lVP&M7 zhG%UKX((3fUYB*&5t$MlTrQ^(1ykJamp%Y6k?{dyj2Miz>`$PjZCv_3r+QDWq+Sz$ z@+rD!*WqRHX5l&HdsbpKDU`8-yS@q*crE$qf_I=LvYu=i{jp#4U|*O0YoF&p8}lT= znCymDal_RsX8)ma)|^U^y@zxC_KaVBX|dy^BCTY1+DC z^bEIT-$vo))YRHWAyJR0)Q|mW@$rqw5)=sVX!|><)KY$gq-ZZOJmLm#<&N@3WxnE7t?W#7k zjj#SidO0I>9Bk{QDH57hIf-C!?i>3-5|gPgLS${QpE~{AYDMN(MfYeSC9F1PX_nnR67>5Vbqg-hYi%1((d9V`}asgQ`3&aCaG%rI|Ws1p} z)Ie2;aJ z$!o&l?|ol=X$xMH+!|7rEz-se?D8qIW9B-TMmMX@CsJ>h6?pOGvfYJ$JT z8XS%dDPC{_Jgn|uB*+`|DtFlrG&#)~gmQD~=KOLRPh;+BZmTbe{weK-_C6OQt=2NIzHJ`+?=~tBejEc=NgFZl898$cMn?-^X zK==vXp84~&&b2*0h`#;qTj}&+aFfJDhDX%)Ndr(7w168w#C-->|9M(>r74HJ&v7<~ zwsM|uHsFs2gZ3F;v>boQoi&^1xM+?Sn%sP}OeRcW6H|u#UiiRkSoVP2zwd%g=Fr&w z6n~*g&XWH0{e&c>hh%^Mb*XDNsJS@%30qIFP1Th}KJ44K|= zQgaz95cS4|zq1r5>4?-Na-@~gdZOOqOP{y=b#kz^Y|!|}>ng#a62Wd+#T3OrF!oXd zI9A$XNa&@!uoaJmq+&ABW{Wn58}DIR2AGXyvMP9jNt&aNgH6DTAU7DIZ@wL)mL_)@3{d=Zx48@3m>J`l2rKZefwbAT2RJb zSacBda3RppE-$$4QsD@b)9>G&?pC}dp{@_;9*kM0Qd1VlOGaa&?szwoeta;x`zqPW zS=##5rnUp07UyUWBWd}z)>gLE4m{c(W+R!2xofq`LRRGAaJeKlmh0*TPQ~q!h8tJX z$xcLwOaX{$Uv7To{j5TQb{i}t$gi`g@0->zRuZ*C+%aX(zT;Mziw z7CL%{XG)>&tA0ZLWe$-E+MMvU^~TIQ8kNx;(hsP!pSqfdMd^Mjr84vP!~|Liq0q&d zWhNeW&a1(Qr3$_6MFM1K)itMGygX2+OpPfCR4=0n&bAP?jN4RA75k{hCD|OVe98Ge zFY=;RGnH zNa|Jroxf+I3pM+lHg~;`-0*&`sl^VcZz|4Tc?OCF2T*GN6hkH}j)ls^g*s(D8E7O8 z{n?eY7ozu!Lyz-_NXo&F;I{q?E{Dq;OEBhs$C}e66|`3;Wj(>6B-3{MHgZJ?5Ayi{>$zZAX)yOX?O>z=1`&#+(R zYf>W0NbF`aI6rx1F;N$x$Ud5lU_Ka>gyym2m+bN;gb>Vc@2}~Zh8)lYF}Z6|8a<;* z=5#9BQK`Ty;s3#FS}2)LaxOy#^pa{#R>vv|Rsq!qinnRY@PHYQLT$lc1 zk+3%zJ)IbZoKV(i^GSw;D``fl}FjjjFjAy zm0yh~Oj(c`32ZC#h@j3%FYTB&Nq#HRy+6|GC2DMcyj6atXJ^$h$i!N1K$V9w$T`+= z@$OaAk(U8PmAXpE{HD=RVtw29aTz{u>VTLF<1(qMKQ%fF-&ajVT(( z#5r}_%Ap@TvB4dhk7DOFa&8)YRz5f->Uwm`pXOnOO|#hjrDmJ`bH2@KTn+}c$Oe%? zN;-Bl9$8})bJ%M_-MIWmK72|YUY>oiUW1(gIB#fsa%i6k`!n@G9v%Pp+ zs^Lb~Y{pTRgMLDQEfa-CDdfn?epMF52A-weC-B(H zV8{zWqKinR);>~}#FiHHlv8*TGRoDA+3%3$H8$H}1%ljTr27<|Jfe(MLxD*v>zd!I zC9nOih;pmsi}ZQZ`A+#ou4>mAL{_IGToPk@$E3Uz6; zyYu7PcKq;Mz$j;F#yzsf!x5njM9|&h3(_)dnF^MveB+&ygI!YFjn{AQT@2$*UAzw)k;TuCltr0U!m~yW&5Y;!!lNxg06og^Z^Ald1&%oE(0AB*u3_lTC)r!~l(v^mj$(d!Z&um$s-+em)3yaBFU<*xI{F zVyIjXzg6b!{L@Qs8wN z6}z@aG_T5q=WPC-h3!;ol|=TNkI}YTXCi^T-?K=aQPL_}J)a|dVzUXE#!x3AIrKa} zo!9iEateI1`nY8C(t_#DN8{5cYWyI2dX(&vRq*j9*rej!-Y+_6n_A1%vHMDMNvNut zq5IVEny;irStNGM4f~dEY|$fqXVku5WMns_o)^TbCcqDtbTK55UMsu`ke;AL+TlK8IOWP^{3Y#b`r7>a3`d$|yJ|S8qPg)&EJ%%|o z{(1w0*Ig2)h(=tOtu^8R2d|%a&>Hs%lwRZS|8Ku6GOV*h;r97lBj5O_v~5S4#o%zqd*Zq1K>HN?lvto z!}v_+w}IzRjfE<_%W!$|c8d|6_|%8(bE^bcyU&;Pu7277hCz7(ghrMIQ>Q0&0XaZ4 zXFi!}zL&WmT6dR0w>H$NG{(+lmv}UeRUmhpwASpwczR-(%heFRcitCG_hZV%NV8h4OlG6_DHU=?=%P=&JqaQsZhqq8> z`Kl6P^0Grtf#)bB_0j78v3dM|ZNBi5YK7f=-L{`gtKBZ;zP~3H$773k>SC-5^`I;T z@N!HI@bb&|hOd&l5PMb-xc(=k>J>erDn^mjL`CbFF__KIh`DJ$+yiU0k%S*BRAQ16 z>R8*|b8UQQl^^Pau=s)vlj#^fSvwx`q_sum?u_px`kE2T;rIeXl5PNA`gC#ylq?(v2eObyJJ>aNv5V>!Fgx zS*IJZInXcvpSY+%G*D!y%YEfkRhD^&e({4}3-j0hVi2d`xB~p#SMQPcG|AXmR1J?!&IFf1)&|bL z?;?SF5UFQTOStV4ORceUTjP<{#Su(R&xq}iGagbO9`8RIo(@Si#6IGWi@EDkLd@(` z02M+FicsjF4tR4N>b@Ji#e;vPlQBm5U$@&MSxvF4C5=DjB1Z5?lEHdF=?g!vS8)8^nQl zWF>LQhP98J4se{jPTUm{!_c&Uaz@jEMm|p*5A6&nTh=e7k@S;xnDsvJ>5V7^v2cX) zp6D5}Mze%TpG+_58SX(dOo9o>F&?Ecj#pT6(WGnZ{n1)rL!G#V6^G(BoUpbEIT(eN zYQ0k32T@&B9DmU#J3{li6$~)0}7RU*Dv&Gbz9h2U#^eF23(z3phJM#kf*ZnvwTmt(z@V{7SX2XJQz(ca5x8lQ;?Oh|Ko#eBjlUpjJLnWdN_m;>IT+iq!FS9R>gMA8E&y}!CrtQRI@ z|CS98rrK|~U_tUd_?=Ry#vk`6-;OfbsF1tU#GkxDh1m1j$4LPeH`(@RX+{oK4<)Hf zZT?p;9XmwUu0774sEGfEl0CCV21LLrC0l-%WFJ42l&A62}b2bs|#c9 z_Gwbsmq?K}oat=x>v!lIJ*SXQsAu)`o~XRkr3W$>p8AT)U%l|H#rNvhNVgR=`LFRV zY(hruqg+Y{`|UAUMqShxCpOa~dt)FDRmKSF-#Eps#(VV=1@VyhC+4r=WruiUWWayq zNo)H>o6c*BwoL1;KPhORn)`il>e>p-c1Vd+4;peVK1fr?Y7DaTtVmZykKdZtUXU?Ny}udyJHRD0h8@F((r2p~xg6CmU@@T|6tpfFkR75wko(&SkE|9Bjc9@{FQvp^~bqG|>I7Gc78)c~aQ1fRyKI zo5AKU{UJZV(|zSW*%k#fh?7V%ZR&4IOD(I5&Lo(eekHau%^-b(FV<@L;l2C_93{6j zlDis3lbYA@phd*6De~f>WLP^jFm#LLCGcZG)e?E&5b1q(uvK^dJr7UvftQh`0{^ov z{ob%TeN-8_oFyGVDOYraRtzgXaiSgk`wT_q5ac1zFYjOJwB;Ra?p%Df3h^|{-l`4e z>}dOA_waTR@VhdZp3cc!;HGYZ!!LLUf7end`G{9zcUGNI<_q$Uf<4vY+_Fi~{0q$( z@S+NS1hL}|3xtQqXPqbekXm$TM5Bl9k3i7|pDHo`z!@fmc0cTW-tZmQ)A| z^(TzARKR___`{ZNREdM=`M@*^jna(*PYOGIl2rL%j733gxd}%NQ0W89=w&m3XAl(A zz3pD4!~c1`>3lf_Sl5jtm)$HtQa_wJ1DuvLTCnjwC;yuhdTD3A)Oy_IJ1u;va+co^ zBSE6iBX=D*jUqvm#x4Bq@T5~Ea(>8Ja($gLC7g4-PO>2K;9D`_#(-?23Jz>T&OPX! zV_v8Q;)=3G!u9!AVs63@r6DD!STi^k|5yrhbZK456sK&s1dSo2ZRhTP*|TAlf6w*J z=0>814p6Hhukz~P+o&@Nc|qPUW8(9Js-)`9SO*kGxkgtG&!*AgInzF}8N3 z7Z!QzxE|crcgw)5+O_#E_fl#;j2u+Yr+*MpOZsjIFAY#aM%~-2pNY|N_+!1cR`@ml zbIsF5Qz!^$7=PLo68X-Y&G!g;h$y6QAb|Eo%z)zVpPQlV-$AC8YL&^j8F}pEZ)9i@ zi8jwr0%tTN1_YGk4(<^teIjUW3&oXGrqh zp7y`HjeN|9K9mnO7C>uvGvnJCtAQ+_sZ=ll^mU*Y=*Itf{SmpF&=7<{n2H2zBc9*d zi=n)!eZD~h;z962eYn@@>mL6#Sy(&%%S3k@hTw{Y@eW(k;)@4)gIdEH{6Hf4k6A54 z?U$~)8}s4z4FsxLvL8bDxEOPF-s%-Eb#UK*_Zg-bg?@Y)*L{rp_Em-O+}$&#Z~(bl zc=st)`QKZeWf6+qfg*4*1k(Z#fxVm2AVAL@ifZo2K`*p^hWz(3A~|oQgt+e(8q(Pl zwI(S;)Z&`50vXLxd=1oq0N7*vxfDguiGCz>e@++bzT{%bREOv)yne8XxO01t_`h$a z{9GEc!SspYVedoS-_|=NxkoQGl|k7!%ULv7EGvquj-8oaP;Gizg3itOW&;LDAo-Pm3b>(2- z8DzKY_=z6qQPKnItpGO@TJ z|L+6sKq&~*C_+pE^!9B9n~mAn^ezxWNF2GDm-X*y$|9c7!;(SS@<;20KEPLvVsSv- zak7c4p_~3+zt19CWH7=577aqA5M`tUGD_UO3y~o(gr>~F%)tlt|87U#+A|5UCx2Nq za<}LRU^7K*AbE-H#e*Y`9RB%3X638bi_B0if|sCAho6CBrl*F!K@0kgsXXrSd+^V{ zG*iGA$*w9$JEL*Kxjr)Ea&Rx?fG3P}@xW_nD)K)aj&|8Yq#4{CFCg&J~fkWBBO=g)|KXAOI}f`S%kQMo9O| z%18roO>ZO1!XgQB?x>gd{q{$E9k5aQcTqTrdrbbBEiz!#?|2&O&LzrEK0^@*3?6LM z{r|CPxZ>;J&_$V3i$1;oUz48uuMrA|2^%ILG%f~_kvuM(8O;9ykY|?lYF?=N@n3^t zN^u0i;=he}n_q#Zdh!vvTEbX%;1F%~VN&g%t=7&;;raklc4!yDh$VD0C#Y(1D;&fX zpUS2J7dV`vT zFnmqA6e80I!q-DMZ?h|O{#l`;i7@mhuS+t{;2W^;9jU_4jNzL=e@rU!Ki6q7Gz`&{ z%OD!k*zE{4F&=n=BN4dc#2NWlE&jQmGF3StDbCho3Crac?wpF-R6=0gpEIQnu7W_u z{_nz%yww~mycj?{5r3>gg_mM?m}h0?I%~Hpu)$B@d2ZZogdl%bG*ux(tp-3$la8pwsu~ zs_mdV_*-d&XTLyetO!{u;Q&OJAYxA+8u*UxH&u5wR&n2 zI*&Wt8R&Q$+JnB96Z!mFhghhPDR{RYz_Lyy4`E@bPw{-Kuvq;m4bgEK;Crm0WK%hr+9bQ@2yM{@7tvtV zU2|!J%e`juaWhm|3?mN%j7X<1K=z35C4$~8TC()WF!adMZ(C$C(Ohrd-4HE%WE7Xs zHN>>Gz0rx7+t0ohp+Ex*Xb zjNRq>^X*Z$xEx8J{8THf9yO%Z&Ku~dsojw?D6v+n02B8$;OM>*msGr=?CzJ3u$J~l zJL_W)c=Tj-qNV~q_mcuV=Hr0qVHKvlJyneT#FbMCi>${oNmZ9Sj#Yz!>pnml)dh$u z`v&q1hTu^!0P^Mbk@&^XU;}O7xd;V|4)(~4VFD2!+VBx=oyUWp-rg!xW=jb?%nM*o zFYC1}PVbPm#~W`>(Vz-)CfGuNRVV5$j$>^yiw0Bwcw=N3*IkslyZhZfv%NZrOz9;BponS+Ms1{vRw7wr zUErx0?{U`$Fa+Wl&>xJ?cRZVD3MYm~hR1=xj}gjYvUUU@C!4x~qQD~tv7S1ZW*-QJ zYyd#2H<0bcayV%Yj{*p3EpbKF)#dMrR+;Aw$jFL11AUPtvqq6C5Iv6RBZ

    ZfB0 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 literal 0 HcmV?d00001 diff --git a/leetcode_101/docs/10-data-structures/10.3.png b/leetcode_101/docs/10-data-structures/10.3.png new file mode 100644 index 0000000000000000000000000000000000000000..bc65f388c9b7d8665823983cad678183c87adf75 GIT binary patch literal 72740 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

    + + ![](13.1.png) + +
    图 13.1: 字典树,存储了单词 A、to、tea、ted、ten、i、in 和 inn,以及它们的频率
    +
    + +为什么需要用字典树解决这类问题呢?假如我们有一个储存了近万个单词的字典,即使我们使用哈希,在其中搜索一个单词的实际开销也是非常大的,且无法轻易支持搜索单词前缀。然而由于一个英文单词的长度 n 通常在 10 以内,如果我们使用字典树,则可以在 $O(n)$——近似 $O(1)$ 的时间内完成搜索,且额外开销非常小。 + +## [208. Implement Trie (Prefix Tree)](https://leetcode.com/problems/implement-trie-prefix-tree/) + +### 题目描述 + +尝试建立一个字典树,支持快速插入单词、查找单词、查找单词前缀的功能。 + +### 输入输出样例 + +以下是数据结构的调用样例。 + +``` +Trie trie = new Trie(); +trie.insert("apple"); +trie.search("apple"); // true +trie.search("app"); // false +trie.startsWith("app"); // true +trie.insert("app"); +trie.search("app"); // true +``` + +### 题解 + +以下是字典树的典型实现方法。 + + + + +```cpp +struct TrieNode { + bool word_ends; + vector children; + TrieNode() : word_ends(false), children(26, nullptr) {} +}; + +class Trie { + public: + Trie() : root_(new TrieNode()) {} + + void insert(string word) { + TrieNode* node = root_; + for (char c : word) { + int pos = c - ’a’; + if (node->children[pos] == nullptr) { + node->children[pos] = new TrieNode(); + } + node = node->children[pos]; + } + node->word_ends = true; + } + + bool search(string word) { + TrieNode* node = root_; + for (char c : word) { + if (node == nullptr) { + break; + } + node = node->children[c - ’a’]; + } + return node != nullptr && node->word_ends; + } + + bool startsWith(string prefix) { + TrieNode* node = root_; + for (char c : prefix) { + if (node == nullptr) { + break; + } + node = node->children[c - ’a’]; + } + return node != nullptr; + } + + private: + TrieNode* root_; +}; +``` + + + + +```py +class TrieNode: + def __init__(self): + self.word_ends = False + self.children = [None] * 26 + +class Trie: + def __init__(self): + self.root = TrieNode() + + def insert(self, word: str) -> None: + node = self.root + for c in word: + pos = ord(c) - ord("a") + if node.children[pos] is None: + node.children[pos] = TrieNode() + node = node.children[pos] + node.word_ends = True + + def search(self, word: str) -> bool: + node = self.root + for c in word: + if node is None: + break + node = node.children[ord(c) - ord("a")] + return node is not None and node.word_ends + + def startsWith(self, prefix: str) -> bool: + node = self.root + for c in prefix: + if node is None: + break + node = node.children[ord(c) - ord("a")] + return node is not None + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/13-trees/13-7-exercises.md b/leetcode_101/docs/13-trees/13-7-exercises.md index b96a6ac6..1b672f7b 100644 --- a/leetcode_101/docs/13-trees/13-7-exercises.md +++ b/leetcode_101/docs/13-trees/13-7-exercises.md @@ -3,3 +3,79 @@ sidebar_position: 74 --- # 13.7 练习 + +## 基础难度 + +### [226. Invert Binary Tree](https://leetcode.com/problems/invert-binary-tree/) + +巧用递归,你可以在五行内完成这道题。 + +### [617. Merge Two Binary Trees](https://leetcode.com/problems/merge-two-binary-trees/) + +同样的,利用递归可以轻松搞定。 + +### [572. Subtree of Another Tree](https://leetcode.com/problems/subtree-of-another-tree/) + +子树是对称树的姊妹题,写法也十分类似。 + +### [404. Sum of Left Leaves](https://leetcode.com/problems/sum-of-left-leaves/) + +怎么判断一个节点是不是左节点呢?一种可行的方法是,在辅函数里多传一个参数,表示当前节点是不是父节点的左节点。 + +### [513. Find Bottom Left Tree Value](https://leetcode.com/problems/find-bottom-left-tree-value/) + +最左下角的节点满足什么条件?针对这种条件,我们该如何找到它? + +### [538. Convert BST to Greater Tree](https://leetcode.com/problems/convert-bst-to-greater-tree/) + +尝试利用某种遍历方式来解决此题,每个节点只需遍历一次。 + +### [235. Lowest Common Ancestor of a Binary Search Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/) + +利用 BST 的独特性质,这道题可以很轻松完成。 + +### [530. Minimum Absolute Difference in BST](https://leetcode.com/problems/minimum-absolute-difference-in-bst/) + +还记得我们所说的,对于 BST 应该利用哪种遍历吗? + +## 进阶难度 + +### [1530. Number of Good Leaf Nodes Pairs](https://leetcode.com/problems/number-of-good-leaf-nodes-pairs/) + +题目 543 的变种题,注意在辅函数中,每次更新的全局变量是左右两边距离之和满足条件的数量,而返回的是左右两边所有(长度不溢出的)子节点的高度 +1。 + +### [889. Construct Binary Tree from Preorder and Postorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-postorder-traversal/) + +给定任意两种遍历结果,我们都可以重建树的结构。 + +### [106. Construct Binary Tree from Inorder and Postorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/) + +给定任意两种遍历结果,我们都可以重建树的结构。 + +### [94. Binary Tree Inorder Traversal](https://leetcode.com/problems/binary-tree-inorder-traversal/) + +因为前中序后遍历是用递归实现的,而递归的底层实现是栈操作,因此我们总能用栈实现。 + +### [145. Binary Tree Postorder Traversal](https://leetcode.com/problems/binary-tree-postorder-traversal/) + +因为前中序后遍历是用递归实现的,而递归的底层实现是栈操作,因此我们总能用栈实现。 + +### [236. Lowest Common Ancestor of a Binary Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/) + +现在不是 BST,而是普通的二叉树了,该怎么办? + +### [109. Convert Sorted List to Binary Search Tree](https://leetcode.com/problems/convert-sorted-list-to-binary-search-tree/) + +把排好序的链表变成 BST。为了使得 BST 尽量平衡,我们需要寻找链表的中点。 + +### [897. Increasing Order Search Tree](https://leetcode.com/problems/increasing-order-search-tree/) + +把 BST 压成一个链表,务必考虑清楚指针操作的顺序,否则可能会出现环路。 + +### [653. Two Sum IV - Input is a BST](https://leetcode.com/problems/two-sum-iv-input-is-a-bst/) + +啊哈,这道题可能会把你骗到。 + +### [450. Delete Node in a BST](https://leetcode.com/problems/delete-node-in-a-bst/) + +当寻找到待删节点时,你可以分情况考虑——当前节点是叶节点、只有一个子节点和有两个子节点。建议同时回收内存。 \ No newline at end of file diff --git a/leetcode_101/docs/13-trees/13.1.png b/leetcode_101/docs/13-trees/13.1.png new file mode 100644 index 0000000000000000000000000000000000000000..06c168c6cc9b678d71b1481c04f3f3cb8e2ba56e GIT binary patch literal 49070 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⋙uQjBTmL--5X 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 a_JlStNm}@B)9VWe_)$?*SE!OR5B@*1_9g8A literal 0 HcmV?d00001 diff --git a/leetcode_101/docs/13-trees/_category_.json b/leetcode_101/docs/13-trees/_category_.json index a9c87d8a..db81316e 100644 --- a/leetcode_101/docs/13-trees/_category_.json +++ b/leetcode_101/docs/13-trees/_category_.json @@ -3,6 +3,6 @@ "position": 13, "link": { "type": "generated-index", - "description": "5 minutes to learn the most important Docusaurus concepts." + "description": "第 13 章 指针三剑客之二:树" } } From 8228f23419b104ace4a20ff8aa961de501f548fb Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Thu, 14 Nov 2024 16:42:28 +0100 Subject: [PATCH 17/49] chapter 14 --- .../14-1-data-structure-introduction.md | 5 - .../14-1-data-structure-introduction.mdx | 16 +++ .../docs/14-graphs/14-2-bipartite-graph.md | 5 - .../docs/14-graphs/14-2-bipartite-graph.mdx | 90 ++++++++++++++++ .../14-graphs/14-3-topological-sorting.md | 5 - .../14-graphs/14-3-topological-sorting.mdx | 97 ++++++++++++++++++ leetcode_101/docs/14-graphs/14-4-exercises.md | 16 +++ leetcode_101/docs/14-graphs/14.1.png | Bin 0 -> 103164 bytes leetcode_101/docs/14-graphs/_category_.json | 2 +- 9 files changed, 220 insertions(+), 16 deletions(-) delete mode 100644 leetcode_101/docs/14-graphs/14-1-data-structure-introduction.md create mode 100644 leetcode_101/docs/14-graphs/14-1-data-structure-introduction.mdx delete mode 100644 leetcode_101/docs/14-graphs/14-2-bipartite-graph.md create mode 100644 leetcode_101/docs/14-graphs/14-2-bipartite-graph.mdx delete mode 100644 leetcode_101/docs/14-graphs/14-3-topological-sorting.md create mode 100644 leetcode_101/docs/14-graphs/14-3-topological-sorting.mdx create mode 100644 leetcode_101/docs/14-graphs/14.1.png diff --git a/leetcode_101/docs/14-graphs/14-1-data-structure-introduction.md b/leetcode_101/docs/14-graphs/14-1-data-structure-introduction.md deleted file mode 100644 index 09106d6f..00000000 --- a/leetcode_101/docs/14-graphs/14-1-data-structure-introduction.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 75 ---- - -# 14.1 数据结构介绍 diff --git a/leetcode_101/docs/14-graphs/14-1-data-structure-introduction.mdx b/leetcode_101/docs/14-graphs/14-1-data-structure-introduction.mdx new file mode 100644 index 00000000..8e592d82 --- /dev/null +++ b/leetcode_101/docs/14-graphs/14-1-data-structure-introduction.mdx @@ -0,0 +1,16 @@ +--- +sidebar_position: 75 +--- + +# 14.1 数据结构介绍 + +作为指针三剑客之三,图是树的升级版。`图`通常分为有向(directed)或无向(undirected),有循环(cyclic)或无循环(acyclic),所有节点相连(connected)或不相连(disconnected)。树即是一个相连的无向无环图,而另一种很常见的图是`有向无环图`(Directed Acyclic Graph,DAG)。 + +
    + + ![](14.1.png) + +
    图 14.1: 有向无环图样例
    +
    + +图通常有两种表示方法。假设图中一共有 n 个节点、m 条边。第一种表示方法是`邻接矩阵`(adjacency matrix):我们可以建立一个 n × n 的矩阵 G,如果第 i 个节点连向第 j 个节点,则 G[i][j] = 1,反之为 0;如果图是无向的,则这个矩阵一定是对称矩阵,即 G[i][j] = G[j][i]。第二种表示方法是`邻接链表`(adjacency list):我们可以建立一个大小为 n 的数组,每个位置 i 储存一个数组或者链表,表示第 i 个节点连向的其它节点。邻接矩阵空间开销比邻接链表大,但是邻接链表不支持快速查找 i 和 j 是否相连,因此两种表示方法可以根据题目需要适当选择。除此之外,我们也可以直接用一个 m × 2 的矩阵储存所有的边。 \ No newline at end of file diff --git a/leetcode_101/docs/14-graphs/14-2-bipartite-graph.md b/leetcode_101/docs/14-graphs/14-2-bipartite-graph.md deleted file mode 100644 index 54cb3b66..00000000 --- a/leetcode_101/docs/14-graphs/14-2-bipartite-graph.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 76 ---- - -# 14.2 二分图 diff --git a/leetcode_101/docs/14-graphs/14-2-bipartite-graph.mdx b/leetcode_101/docs/14-graphs/14-2-bipartite-graph.mdx new file mode 100644 index 00000000..27ce77fd --- /dev/null +++ b/leetcode_101/docs/14-graphs/14-2-bipartite-graph.mdx @@ -0,0 +1,90 @@ +--- +sidebar_position: 76 +--- + +# 14.2 二分图 + +`二分图`算法也称为`染色法`,是一种广度优先搜索。如果可以用两种颜色对图中的节点进行着色,并且保证相邻的节点颜色不同,那么图为二分。 + +## [785. Is Graph Bipartite?](https://leetcode.com/problems/is-graph-bipartite/) + +### 题目描述 + +给定一个图,判断其是否可以二分。 + +### 输入输出样例 + +输入是邻接链表表示的图(如位置 0 的邻接链表为 [1,3],表示 0 与 1、0 与 3 相连);输出是一个布尔值,表示图是否二分。 + +``` +Input: [[1,3], [0,2], [1,3], [0,2]] +0----1 +| | +| | +3----2 +Output: true +``` + +在这个样例中,我们可以把 {0,2} 分为一组,把 {1,3} 分为另一组。 + +### 题解 + +利用队列和广度优先搜索,我们可以对未染色的节点进行染色,并且检查是否有颜色相同的相邻节点存在。注意在代码中,我们用 0 表示未检查的节点,用 1 和 2 表示两种不同的颜色。 + + + + +```cpp +bool isBipartite(vector>& graph) { + int n = graph.size(); + vector color(n, 0); + queue q; + for (int i = 0; i < n; ++i) { + if (color[i] == 0) { + q.push(i); + color[i] = 1; + } + while (!q.empty()) { + int node = q.front(); + q.pop(); + for (int j : graph[node]) { + if (color[j] == 0) { + q.push(j); + color[j] = color[node] == 2 ? 1 : 2; + } else if (color[j] == color[node]) { + return false; + } + } + } + } + return true; +} +``` + + + + +```py +def isBipartite(graph: List[List[int]]) -> bool: + n = len(graph) + color = [0] * n + q = collections.deque() + + for i in range(n): + if color[i] == 0: + q.append(i) + color[i] = 1 + while len(q) > 0: + node = q.popleft() + for j in graph[node]: + if color[j] == 0: + q.append(j) + color[j] = 1 if color[node] == 2 else 2 + elif color[j] == color[node]: + return False + return True +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/14-graphs/14-3-topological-sorting.md b/leetcode_101/docs/14-graphs/14-3-topological-sorting.md deleted file mode 100644 index 24f0ee63..00000000 --- a/leetcode_101/docs/14-graphs/14-3-topological-sorting.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 77 ---- - -# 14.3 拓扑排序 diff --git a/leetcode_101/docs/14-graphs/14-3-topological-sorting.mdx b/leetcode_101/docs/14-graphs/14-3-topological-sorting.mdx new file mode 100644 index 00000000..02473beb --- /dev/null +++ b/leetcode_101/docs/14-graphs/14-3-topological-sorting.mdx @@ -0,0 +1,97 @@ +--- +sidebar_position: 77 +--- + +# 14.3 拓扑排序 + +`拓扑排序`(topological sort)是一种常见的,对有向无环图排序的算法。给定有向无环图中的 $N$ 个节点,我们把它们排序成一个线性序列;若原图中节点 i 指向节点 j,则排序结果中 i 一定在 j 之前。拓扑排序的结果不是唯一的,只要满足以上条件即可。 + +## [210. Course Schedule II](https://leetcode.com/problems/course-schedule-ii/) + +### 题目描述 + +给定 N 个课程和这些课程的前置必修课,求可以一次性上完所有课的顺序。 + +### 输入输出样例 + +输入是一个正整数,表示课程数量,和一个二维矩阵,表示所有的有向边(如 [1,0] 表示上课程 1 之前必须先上课程 0)。输出是一个一维数组,表示拓扑排序结果。 + +``` +Input: numCourses = 4, prerequisites = [[1,0],[2,0],[3,1],[3,2]] +Output: [0,1,2,3] +``` + +在这个样例中,另一种可行的顺序是 [0,2,1,3]。 + +### 题解 + +我们可以先建立一个邻接矩阵表示图,方便进行直接查找。这里注意我们将所有的边反向,使得如果课程 i 指向课程 j,那么课程 i 需要在课程 j 前面先修完。这样更符合我们的直观理解。 + +拓扑排序也可以被看成是广度优先搜索的一种情况:我们先遍历一遍所有节点,把入度为 0 的节点(即没有前置课程要求)放在队列中。在每次从队列中获得节点时,我们将该节点放在目前排序的末尾,并且把它指向的课程的入度各减 1;如果在这个过程中有课程的所有前置必修课都已修完(即入度为 0),我们把这个节点加入队列中。当队列的节点都被处理完时,说明所有的节点都已排好序,或因图中存在循环而无法上完所有课程。 + + + + +```cpp +vector findOrder(int numCourses, vector>& prerequisites) { + vector> graph(numCourses, vector()); + vector indegree(numCourses, 0), schedule; + for (const auto& pr : prerequisites) { + graph[pr[1]].push_back(pr[0]); + ++indegree[pr[0]]; + } + queue q; + for (int i = 0; i < indegree.size(); ++i) { + if (indegree[i] == 0) { + q.push(i); + } + } + while (!q.empty()) { + int u = q.front(); + q.pop(); + schedule.push_back(u); + for (int v : graph[u]) { + --indegree[v]; + if (indegree[v] == 0) { + q.push(v); + } + } + } + for (int i = 0; i < indegree.size(); ++i) { + if (indegree[i] != 0) { + return vector(); + } + } + return schedule; +} +``` + + + + +```py +def findOrder(numCourses: int, prerequisites: List[List[int]]) -> List[int]: + graph = [[] for _ in range(numCourses)] + indegree = [0] * numCourses + schedule = [] + + for pr_from, pr_to in prerequisites: + graph[pr_to].append(pr_from) + indegree[pr_from] += 1 + + q = collections.deque([i for i, deg in enumerate(indegree) if deg == 0]) + + while len(q) > 0: + u = q.popleft() + schedule.append(u) + for v in graph[u]: + indegree[v] -= 1 + if indegree[v] == 0: + q.append(v) + + return schedule if all(deg == 0 for deg in indegree) else [] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/14-graphs/14-4-exercises.md b/leetcode_101/docs/14-graphs/14-4-exercises.md index b507c7b4..83809992 100644 --- a/leetcode_101/docs/14-graphs/14-4-exercises.md +++ b/leetcode_101/docs/14-graphs/14-4-exercises.md @@ -3,3 +3,19 @@ sidebar_position: 78 --- # 14.4 练习 + +## 基础难度 + +### [1059. All Paths from Source Lead to Destination](https://leetcode.com/problems/all-paths-from-source-lead-to-destination/) + +虽然使用深度优先搜索可以解决大部分的图遍历问题,但是注意判断是否陷入了环路。 + +## 进阶难度 + +### [1135. Connecting Cities With Minimum Cost](https://leetcode.com/problems/connecting-cities-with-minimum-cost/) + +笔者其实已经把这道题的题解写好了,才发现这道题是需要解锁才可以看的题目。为了避免版权纠纷,故将其移至练习题内。本题考察最小生成树(minimum spanning tree, MST)的求法,通常可以用两种方式求得:Prim’s Algorithm,利用优先队列选择最小的消耗;以及 Kruskal’s Algorithm,排序后使用并查集。 + +### [882. Reachable Nodes In Subdivided Graph](https://leetcode.com/problems/reachable-nodes-in-subdivided-graph/) + +这道题笔者考虑了很久,最终决定把它放在练习题而非详细讲解。本题是经典的节点最短距离问题,常用的算法有 Bellman-Ford 单源最短路算法,以及 Dijkstra 无负边单源最短路算法。虽然经典,但是 LeetCode 很少有相关的题型,因此这里仅供读者自行深入学习。 \ No newline at end of file diff --git a/leetcode_101/docs/14-graphs/14.1.png b/leetcode_101/docs/14-graphs/14.1.png new file mode 100644 index 0000000000000000000000000000000000000000..46ebed1b401557b94a5c6f1d46e362ffa38deb69 GIT binary patch literal 103164 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 Date: Thu, 14 Nov 2024 16:42:45 +0100 Subject: [PATCH 18/49] chapter 15 --- .../15-1-introduction.md | 2 + .../15-2-union-find.md | 5 - .../15-2-union-find.mdx | 140 ++++++++++ .../15-3-composite-data-structures.md | 5 - .../15-3-composite-data-structures.mdx | 257 ++++++++++++++++++ .../15-4-exercises.md | 16 ++ .../docs/15-advanced-data-structures/15.1.png | Bin 0 -> 29206 bytes .../_category_.json | 2 +- 8 files changed, 416 insertions(+), 11 deletions(-) delete mode 100644 leetcode_101/docs/15-advanced-data-structures/15-2-union-find.md create mode 100644 leetcode_101/docs/15-advanced-data-structures/15-2-union-find.mdx delete mode 100644 leetcode_101/docs/15-advanced-data-structures/15-3-composite-data-structures.md create mode 100644 leetcode_101/docs/15-advanced-data-structures/15-3-composite-data-structures.mdx create mode 100644 leetcode_101/docs/15-advanced-data-structures/15.1.png diff --git a/leetcode_101/docs/15-advanced-data-structures/15-1-introduction.md b/leetcode_101/docs/15-advanced-data-structures/15-1-introduction.md index 63c1d61b..26e5cdac 100644 --- a/leetcode_101/docs/15-advanced-data-structures/15-1-introduction.md +++ b/leetcode_101/docs/15-advanced-data-structures/15-1-introduction.md @@ -3,3 +3,5 @@ sidebar_position: 75 --- # 15.1 引言 + +目前为止,我们接触了大量的数据结构,包括利用指针实现的三剑客和 C++ 自带的 STL 等。对于一些题目,我们不仅需要利用多个数据结果解决问题,还需要把这些数据结构进行嵌套和联动,进行更为复杂、更为快速的操作。 \ No newline at end of file diff --git a/leetcode_101/docs/15-advanced-data-structures/15-2-union-find.md b/leetcode_101/docs/15-advanced-data-structures/15-2-union-find.md deleted file mode 100644 index 3480ed30..00000000 --- a/leetcode_101/docs/15-advanced-data-structures/15-2-union-find.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 76 ---- - -# 15.2 并查集 diff --git a/leetcode_101/docs/15-advanced-data-structures/15-2-union-find.mdx b/leetcode_101/docs/15-advanced-data-structures/15-2-union-find.mdx new file mode 100644 index 00000000..5034a49a --- /dev/null +++ b/leetcode_101/docs/15-advanced-data-structures/15-2-union-find.mdx @@ -0,0 +1,140 @@ +--- +sidebar_position: 76 +--- + +# 15.2 并查集 + +`并查集`(union-find, disjoint set)可以动态地连通两个点,并且可以非常快速地判断两个点是否连通。假设存在 n 个节点,我们先将所有节点的父节点标为自己;每次要连接节点 i 和 j 时,我们可以将秩较小一方的父节点标为另一方(按秩合并);每次要查询两个节点是否相连时,我们可以查找 i 和 j 的祖先是否最终为同一个人,并减少祖先层级(路径压缩)。 + +

    + + ![](15.1.png) + +
    图 15.1: 并查集样例,其中 union 操作可以将两个集合按秩合并,find 操作可以查找节点的祖先并压缩路径。
    +
    + +## [684. Redundant Connection](https://leetcode.com/problems/redundant-connection/) + +### 题目描述 + +在无向图找出一条边,移除它之后该图能够成为一棵树(即无向无环图)。如果有多个解,返回在原数组中位置最靠后的那条边。 + +### 输入输出样例 + +输入是一个二维数组,表示所有的边(对应的两个节点);输出是一个一维数组,表示需要移除的边(对应的两个节点)。 + +``` +Input: [[1,2], [1,3], [2,3]] + 1 + / \ +2 - 3 +Output: [2,3] +``` + +### 题解 + +因为需要判断是否两个节点被重复连通,所以我们可以使用并查集来解决此类问题。具体实现算法如下所示。 + + + + +```cpp +class Solution { + public: + vector findRedundantConnection(vector>& edges) { + n_ = edges.size(); + id_ = vector(n_); + depth_ = vector(n_, 1); + for (int i = 0; i < n_; ++i) { + id_[i] = i; + } + for (auto& edge : edges) { + int i = edge[0], j = edge[1]; + if (linked(i - 1, j - 1)) { + return vector{i, j}; + } + connect(i - 1, j - 1); + } + return vector(); + } + + private: + int find(int i) { + // 路径压缩。 + while (i != id_[i]) { + id_[i] = id_[id_[i]]; + i = id_[i]; + } + return i; + } + + void connect(int i, int j) { + i = find(i), j = find(j); + if (i == j) { + return; + } + // 按秩合并。 + if (depth_[i] <= depth_[j]) { + id_[i] = j; + depth_[j] = max(depth_[j], depth_[i] + 1); + } else { + id_[j] = i; + depth_[i] = max(depth_[i], depth_[j] + 1); + } + } + + bool linked(int i, int j) { return find(i) == find(j); } + + int n_; + vector id_; + vector depth_; +}; +``` + + + + +```py +class Solution: + def __init__(self): + self.n = 0 + self.id = None + self.depth = None + + def find(self, i: int) -> int: + # 路径压缩。 + while i != self.id[i]: + self.id[i] = self.id[self.id[i]] + i = self.id[i] + return i + + def connect(self, i: int, j: int): + i = self.find(i) + j = self.find(j) + if i == j: + return + # 按秩合并。 + if self.depth[i] <= self.depth[j]: + self.id[i] = j + self.depth[j] = max(self.depth[j], self.depth[i] + 1) + else: + self.id[j] = i + self.depth[i] = max(self.depth[i], self.depth[j] + 1) + + def linked(self, i: int, j: int) -> bool: + return self.find(i) == self.find(j) + + def findRedundantConnection(self, edges: List[List[int]]) -> List[int]: + self.n = len(edges) + self.id = list(range(self.n)) + self.depth = [1] * self.n + for i, j in edges: + if self.linked(i - 1, j - 1): + return [i, j] + self.connect(i - 1, j - 1) + return [] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/15-advanced-data-structures/15-3-composite-data-structures.md b/leetcode_101/docs/15-advanced-data-structures/15-3-composite-data-structures.md deleted file mode 100644 index 5f3a4609..00000000 --- a/leetcode_101/docs/15-advanced-data-structures/15-3-composite-data-structures.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 77 ---- - -# 15.3 复合数据结构 diff --git a/leetcode_101/docs/15-advanced-data-structures/15-3-composite-data-structures.mdx b/leetcode_101/docs/15-advanced-data-structures/15-3-composite-data-structures.mdx new file mode 100644 index 00000000..bada3aea --- /dev/null +++ b/leetcode_101/docs/15-advanced-data-structures/15-3-composite-data-structures.mdx @@ -0,0 +1,257 @@ +--- +sidebar_position: 77 +--- + +# 15.3 复合数据结构 + +这一类题通常采用哈希表或有序表辅助记录,从而加速寻址;再配上数组或者链表进行连续的数据储存,从而加速连续选址或删除值。 + +## [146. LRU Cache](https://leetcode.com/problems/lru-cache/) + +### 题目描述 + +设计一个固定大小的,最近最少使用缓存 (least recently used cache, LRU)。每次将信息插入未满的缓存的时候,以及更新或查找一个缓存内存在的信息的时候,将该信息标为最近使用。在缓存满的情况下将一个新信息插入的时候,需要移除最旧的信息,插入新信息,并将该新信息标为最近使用。 + +### 输入输出样例 + +以下是数据结构的调用样例。给定一个大小为 n 的缓存,利用最近最少使用策略储存数据。 + +``` +LRUCache cache = new LRUCache( 2 /* capacity */ ); +cache.put(1, 1); +cache.put(2, 2); +cache.get(1); // 输出 value 1 +cache.put(3, 3); // 移除 key 2 +cache.get(2); // 输出 value -1 (未找到) +cache.put(4, 4); // 移除 key 1 +cache.get(1); // 输出 value -1 (未找到) +cache.get(3); // 输出 value 3 +cache.get(4); // 输出 value 4 +``` + +### 题解 + +我们采用一个链表来储存信息的 key 和 value,链表的链接顺序即为最近使用的新旧顺序,最新的信息在链表头节点。同时我们需要一个哈希表进行查找,键是信息的 key,值是其在链表中的对应指针/迭代器。每次查找成功(cache hit)时,需要把指针/迭代器对应的节点移动到链表的头节点。 + + + + +```cpp +class LRUCache { + public: + LRUCache(int capacity) : n_(capacity) {} + + int get(int key) { + auto it = key_to_cache_it_.find(key); + if (it == key_to_cache_it_.end()) { + return -1; + } + cache_.splice(cache_.begin(), cache_, it->second); + return it->second->second; + } + + void put(int key, int value) { + auto it = key_to_cache_it_.find(key); + if (it != key_to_cache_it_.end()) { + it->second->second = value; + return cache_.splice(cache_.begin(), cache_, it->second); + } + cache_.insert(cache_.begin(), make_pair(key, value)); + key_to_cache_it_[key] = cache_.begin(); + if (cache_.size() > n_) { + key_to_cache_it_.erase(cache_.back().first); + cache_.pop_back(); + } + } + + private: + list> cache_; + unordered_map>::iterator> key_to_cache_it_; + int n_; +}; +``` + + + + +```py +class Node: + def __init__(self, key=-1, val=-1): + self.key = key + self.val = val + self.prev = None + self.next = None + +class LinkedList: + def __init__(self): + self.dummy_start = Node() + self.dummy_end = Node() + self.dummy_start.next = self.dummy_end + self.dummy_end.prev = self.dummy_start + + def appendleft(self, node) -> Node: + left, right = self.dummy_start, self.dummy_start.next + node.next = right + right.prev = node + left.next = node + node.prev = left + return node + + def remove(self, node) -> Node: + left, right = node.prev, node.next + left.next = right + right.prev = left + return node + + def move_to_start(self, node): + return self.appendleft(self.remove(node)) + + def pop(self): + return self.remove(self.dummy_end.prev) + + def peek(self): + return self.dummy_end.prev.val + +class LRUCache: + def __init__(self, capacity: int): + self.n = capacity + self.key_to_node = dict() + self.cache_nodes = LinkedList() + + def get(self, key: int) -> int: + if key not in self.key_to_node: + return -1 + node = self.key_to_node[key] + self.cache_nodes.move_to_start(node) + return node.val + + def put(self, key: int, value: int) -> None: + if key in self.key_to_node: + node = self.cache_nodes.remove(self.key_to_node[key]) + node.val = value + else: + node = Node(key, value) + self.key_to_node[key] = node + self.cache_nodes.appendleft(node) + if len(self.key_to_node) > self.n: + self.key_to_node.pop(self.cache_nodes.pop().key) +``` + + + + + +对于 Python 而言,我们还可以直接利用 OrderedDict 函数实现 LRU,这将大大简化题目难度。这里笔者希望读者还是仔细研读一下以上题解,了解 LRU 实现的核心原理。 + + +```py +class LRUCache: + def __init__(self, capacity: int): + self.n = capacity + self.cache = {} + + def get(self, key: int) -> int: + if key not in self.cache: + return -1 + self.cache[key] = self.cache.pop(key) + return self.cache[key] + + def put(self, key: int, value: int) -> None: + if key in self.cache: + self.cache.pop(key) + self.cache[key] = value + if len(self.cache) > self.n: + self.cache.pop(next(iter(self.cache))) +``` + +## [380. Insert Delete GetRandom O(1)](https://leetcode.com/problems/insert-delete-getrandom-o1/) + +### 题目描述 + +设计一个插入、删除和随机取值均为 $O(1)$ 时间复杂度的数据结构。 + +### 输入输出样例 + +以下是数据结构的调用样例。 + +``` +RandomizedSet randomizedSet = new RandomizedSet(); +randomizedSet.insert(1); +randomizedSet.remove(2); +randomizedSet.insert(2); +randomizedSet.getRandom(); // 50% 1, 50% 2 +randomizedSet.remove(1); +randomizedSet.insert(2); +randomizedSet.getRandom(); // 100% 2 +``` + +### 题解 + +我们采用一个数组存储插入的数字,同时利用一个哈希表查找位置。每次插入数字时,直接加入数组,且将位置记录在哈希表中。每次删除数字时,将当前数组最后一位与删除位互换,并更新哈希表。随机取值时,则可以在数组内任意选取位置。 + + + + +```cpp +class RandomizedSet { + public: + bool insert(int val) { + if (v_to_k_.contains(val)) { + return false; + } + v_to_k_[val] = nums_.size(); + nums_.push_back(val); + return true; + } + + bool remove(int val) { + if (!v_to_k_.contains(val)) { + return false; + } + v_to_k_[nums_.back()] = v_to_k_[val]; + nums_[v_to_k_[val]] = nums_.back(); + v_to_k_.erase(val); + nums_.pop_back(); + return true; + } + + int getRandom() { return nums_[rand() % nums_.size()]; } + + private: + unordered_map v_to_k_; + vector nums_; +}; +``` + + + + +```py +class RandomizedSet: + def __init__(self): + self.nums = [] + self.v_to_k = {} + + def insert(self, val: int) -> bool: + if val in self.v_to_k: + return False + self.v_to_k[val] = len(self.nums) + self.nums.append(val) + return True + + def remove(self, val: int) -> bool: + if val not in self.v_to_k: + return False + self.v_to_k[self.nums[-1]] = self.v_to_k[val] + self.nums[self.v_to_k[val]] = self.nums[-1] + del self.v_to_k[val] + self.nums.pop() + return True + + def getRandom(self) -> int: + return self.nums[random.randint(0, len(self.nums) - 1)] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/15-advanced-data-structures/15-4-exercises.md b/leetcode_101/docs/15-advanced-data-structures/15-4-exercises.md index 9e3ac210..71084880 100644 --- a/leetcode_101/docs/15-advanced-data-structures/15-4-exercises.md +++ b/leetcode_101/docs/15-advanced-data-structures/15-4-exercises.md @@ -3,3 +3,19 @@ sidebar_position: 78 --- # 15.4 练习 + +## 基础难度 + +### [1135. Connecting Cities With Minimum Cost](https://leetcode.com/problems/connecting-cities-with-minimum-cost/) + +使用并查集,按照 Kruskal’s Algorithm 把这道题再解决一次吧。 + +## 进阶难度 + +### [432. All O`one Data Structure](https://leetcode.com/problems/all-oone-data-structure/) + +设计一个 increaseKey,decreaseKey,getMaxKey,getMinKey 均为 O(1) 时间复杂度的数据结构。 + +### [716. Max Stack](https://leetcode.com/problems/max-stack/) + +设计一个支持 push,pop,top,getMax 和 popMax 的 stack。可以用类似 LRU 的方法降低时间复杂度,但是因为想要获得的是最大值,我们应该把 unordered_map 换成哪一种数据结构呢? \ No newline at end of file diff --git a/leetcode_101/docs/15-advanced-data-structures/15.1.png b/leetcode_101/docs/15-advanced-data-structures/15.1.png new file mode 100644 index 0000000000000000000000000000000000000000..6a2df359fca0c73d0ff823d313a1bac31d9af9cd GIT binary patch literal 29206 zcmcHhbx@mM7%qyoK+)pv?(XjH?p`PqZ*ZqTarZW8aVc)aO9@_}I6;fMTk-SdxA)AM zb7t=Bz31Nh2a^yIK3QwM>vhkm6halfXDGyui%`J5rJpr+TZJd z2b7OW#vZR;VL)I%uQOONNMF4I4Jpe>>-pv!uOOw{>Ng9Xp}cj76yn*UBc`Jzj*%S~ z?&I3}H>5;F7mX}NkIJN!NJBg=p&ABY0+MZ{B@5l2& zd&|2K!v=Go75*jbDDnnbOmRNZqq@F^T<=BZrJ&oD#;z2M|wq@acIlzgc^ETEk5c3<1tJ04jdF zoR&Z?Djv75g&$Kvs~<|hjZu7%iV7Ngoem|vGdpWnZq0%M-8P(vxpuLY{lZSi_&b@k=5Xb zdZNza-RdM>R**~6F)pm=R zdd=!L0;9y}#BfBzm>=kVGs0SHn;&#zd~+J|(sAIcP6X%DJZk`*2zkDA=91E1aO-($ zD9iI_5r;T#-UQ@d`iXX&3gX_bg@m+hXPPqn`qJ|pKY!_ax1BY8Suf0oCUB*1U`*cu z4C3_S?|D#L{m$XWW|HJMN9Wlu=aLMA$^;=`g1R=CtEsg~>R~Vp%Qh2LsE@tE4t%53OOBl({bze*2?h%4A&Ap+;7<%vQLnv4-zIWX$K1~rK!BrB-CMlgbb$Sc8 zA0|`FHpFpu3n~BU9#BPUAr(-4x&vlpzTSx7T43Xu*aO8yj{6AnzJCG&imd$OCgqC} z?r_Lu_F6Ij`)3F4qrX)(?UmnB2Xh+Uq_oVTS9rRjgho*Y|Ii%fExx6Bm`n;z*9$Gg z9?J+|7~iFG?en?-yjq-_$)j&u2vEuoYMN{Vtoos_upvEcIP zfq-%2hbyg>#Ba2VnRcuYU74KiEK3OoYPZgF1#jS1+Gd%#E3XWy9M(}o)#6f1JzYVe z=}n0bbcwl6H&A=c)l?PC%a$cq)yRqo4gOg@=uir68hr1#+dKz;98t$ss;XVj^L6dv ziOc0HqB1d?i~&;>vbc<>kD+e}hDw2QK!@F?z29RMe-a+Lz~q*#zIE1zIWZ0_hf2&j z@djQ)QG}OjopoP>-)^o?VXj`z;K}__$U;*4Y=&DdlOQg!$10Xn{by&X2sqRp3Kj&=j{E)LMW7WRu2j7Fe~Yq2Z}e7x4dE>_Gpa;o*A(Y>%M8OrI(q--5?JO zn+>ZifqV@(X-ng)CmKjt;y?b&aQrtMQ=>*n>SH}heX7FW?6pTboQJMlypprG8j?>} zeBFV)+Ty>dA9O#agj%3Z{DPCb-zz#4v9OMGX1^doh*%E>bn6)^;DibahDj6=;D?Z7oDNTVTNqAEAm5|-(R?KaR<>+ zUtwF$MsM;uhi)c{a#ZjW5Z9s%+qjpbm82c{iy4%#OiEe%$Q#6!E&8g)$R^YYCv$i^ z)2uw`Q5$35`5rG5R7U%XTd#+l2CS)~l}`PDIs;c}Pm;Zo6#G>&d%0`Ll=n<@-s{Q# zJyG-o*H%SF#=ygE&x^R|ZKubyZ;Cxo=Jtt;b~VP1)XC&XBXnpY9U<#)3a7R))2TDd zVz=Iz_$#?>G}AwQ)>cwaSM4d^}Z3dzgcXJzc6w+rgMZz3@!c8iAz};lE87(bm=Xy>R)0y^-}SJYF8ok1r>1w zzVyBr-e=1xp$k*;dpk$Gl?}d1ZonOZj}f{a2}?Gyq4=#x{|M}+FBoV(uugVKV381Xv3`R#6lV?xaIwZh{Gce;XZpV zcl3lB+voB>NjrkeD~E@M^%8{$N{Lju^!U-rqAL|lQsW71UDH6)Iv|ymEN^`5Cmo(y z_!)xAba{j0b(5wgmsazn+a#nRG13P_Qs*=JT9b;(ozofklQl6t-P!Jc8*y@B0E%i= zyr%a1QQ}g*9ld#Xry;(fDFC8qcdP{0>&!!vRc3iM$5y6xh$vO8gM2AwIw>}Mk>5T! zLe3Q_10L(0uV)Q4U3Efi535@>T4Yb$kK%;na-svf-qCuSAADl+W{1?%ax3%~U|AA0 z$p7xsXUQb)D>muk^=Ic0H3%^q@Rk%H!0~wJ`(?oSXol2L!|lv@lHy>y*R}&$dm;3J zcUAIfUvuBs1CglK>z8=v)s*V3GFb~5qoz3A_*~}0ZD3Vz$Ri+`{rBDp>n0)4f;bkcSVhqbnuxt0xj9K<&n=tz(i+%laWXBQ zp2%!?>iqNWK^#OTfUy?P#UPG^iF5re5Bpt#=;aI){}5#=E2tNH3R%dAaiv(&(T@G2 zxW~r*H3DYtoz>PnE^KM)tc}TcS)~ySR{CHOF_wQQ(MX~$x&J;C(xvI4(zf1P$w2HF zLH^T~9#LO2dd|bi096YEK>#aTFJva)M9Q3CsM;qIk=Z&lj&&9{N&LoWisZoW5we&u z%h_L+M|EAYeC8b-BV-g&?YZc`ouTdHo5Gf}W6ZX;b+z4c#JuWO<7b65CT00xVv#j)i7JS8MM)t`#Kh-HB3e@(`N6jx zWp-;1t04m4Z^G}AGk!*_ao3EX&0h-bmM z+vnXqwQs*N2*0!T1(59xzdhq)$nd`vx>?nqhV}~>QUO_FAqK= z`Whuv$7E--b9hJhwv~kkzSs3UCZVVN9V(g@r&f>u&Y52&N^SF$jrACzKSZNgac7Du zEg&0(V~m|g4rit5Ta0&P+oMOX1p%N(-Kkth!MC49&>K}Y?&{W?~A4tBeAeHKTWkmYJMPOZnA zqp7g=D7G`H8gK|4aAY@~-XXN!(vL;bUrMf=)9;f**w`t)w5IDbU_o?)*F?+jT=_`l zg?jL2^ZJt#ehUHj7zURGPE6hj^$q?bncCJHn!V|FJYu%aRGT-ozF%&ix|Ogq6yk3i zCnQuaKS+#K-SJyox~z`%?EdxRGlkz5H*lIJX*Q@fcA7V;e($un*fLOk{T$z1s*=Yr zBHO3Hi94kdS1WjdqgApwrpndK13dF94L4*>dRPmJpYOzMp{teqw`x;8+numD`G3}< zgOS^`Srjt^_}ldr3xbh1_^=Z(mA-iSR^O`9*f+oP51o_7DjSBR=q(WHm7#1jVTK8* z%VCvyU_l&c!h~|esWfo0A^T(qAaFF5#x7O#bOZ#HZWQF4*BMHY81V9RtJ^Cxn2Mxx zGThtXP7fl-HO#LyIlr}|fxT0j!0Q*eAH~rA%7nxN8~OgK=d`+RMqa2H8VD~?yQe@9 z^hiEyHLFtP!@OFEywSuA!Xwr;`o$VWL!qL;jP{*1Oan)S$9SP~uiPM=u$C!9NU2yL z`vk5M!2w#99K(ChGQG!B2qm~p9*f8OmV`_k84+m8G>{U z23=wznn)Ue8#F2^(e|ZCQs^q%(s2}p*;nY4DBlPM8tjU1r!H_5qs8=%pNWdUZ&`G# z(wkLaHWg4_RbtFBgCZj>3?* z=c5`f7-Q=nP47FhUiMzHZI2&44 z|I?_1yQZHN&*`4peZ6Mj#I3U20ikkQ7WE1G8o$CCufXQnMdKPVrTv?Z3aB~#y$n_v z8hpX^FMth6eJ4wo`oeRRdSe;=*9H>0G6_D-K$S~51jW`IX zF*a^lf><(G>lP}<+<|#onr#2;GYYh_ss^lc&f4ooGMq4V7tU9mkSwH5qZu6kgUpYN zFjI$yv1*Zf^XFe+6zP(w+}jO+7Cl|U5_MM-Zyx#jdk|2*8n!^)2!0oRMyT(FkT$RE z%I%NCsm7_2qu@Ucj!oJWQ@hBBJ8>d_5GR**_-NfslS`klAjEV+VZ!tzDXTR<3&>PZInyY(sbFCB2oBSIZ}R8&5V=_miYHK zTvrvbn!ah^aE1RzMkwCAxsSP{VLi~8+C3aKYPM6}!q~-xqyfc^g8{PrpEb9))k@3XGto6Mao@y>Y5 zF|>~rIY7>luGJ>r^`0EoWf1cC-5HnoA2-#uA5?nE8J*%ElbewH^$^(GUbW2FOg(+@ zNolP-n~GijCBueUX5v$C@M)lxAYnk)dwn-AfMX?Yj`(CuyxkB@v&a;>c)$9ujr{ES z;j~P{#XsyozEUyi;jl|USx-EaZ1W>qmxT)!E6$+C)?-IR;SfS(7VGz1!nGT!a?p}% zhl@F}h1(ZT&Vx9|e{w->0UkeppHw&Jt!5F>6*jYAMc5TMfg@~=wlRkN^6}*9riM?B z1GQK;XALdYQ*{)DvU9x*HAc_X_}`QobMf-EPkpMgh7b$7n)$zyulz&%H8*ZC&4mZk(@IPu0LIEzMrfE9+j}|e4CgSXtW4kB+ocv#NNJm@ zQ4*o0ajdAMD#l5bl$2*SJ0lASt2;%#B~Eo|7-raC9hZ1GYT*Bih(`AekgBNy-#g`P zs_XKw6F2RtQg>A$lS;Fn9V$is1TzlV?9xz}_MSD>l~aQu7&D=vV$Q|D?Bs=FhNH)= z7&W1M*N@G_QS{*_%?-|;lV1JdU3b13a7vFfn-uc6`Kx%?+FW-G)=cl8Mgg7WnW zyV=^dQlS8go7c`YU7@P4nLSD!MV9(@y!Wbw7zsr>=zD3NuvaA}W>gYlYYv>isLqDg zgv;B`gigKiu6>wlpmIQWYS&!N0;_ce04b)O5a`v|bKw|djx5w0gZ-6?qO zV2ym*d)X)q^;%`dTt0T1@g$u+hyB%~Kj9IBlp$gXp&(0?6Y@!5ao#)sJ6ngsNHvGD zT!Cz0!A$o6G*~Ls3#sFDNA$EaO~uI^)Q^uZX@9xV`Sqd7!(LaNU*9Bc1f#?7aK_Hs zX2LoR6e5uL8e6f-In7jEzTvwuciz;kt0~$J>`+<^)((%)FM^0)8(gY&lcV(_()Rsy{hin(#4`I{^?ikg z81+haLT{jN;z^u>l<6M8WzqKQ5s`m?8?GsFM+ddqu+QM5K8zL5RGotH7{aB#QNkUa zyQ}z36SX$%T=YL$l;>q2>+iAt9%>%E1tm@L{^pYPM~1AY>uP*uSVgM}AS5JgW^iPO z*uh(;WPkpS&{KxlfnXv-qkox938D_le6ZkO9zlKDBSm`_gC5Sbgn-md3E3I zJm7%-X7xP2PyIF1+xrtBxW9y*3hb%Wz5e5Q!LOuFD(r6SpHVYb8@SDiTdkgr6gFF# zc!L!M^7|u=q~GioJqGAr!sx$jS$7?KVSWX@97ew zJ5Pr-$=-H8oOBG|NL_gZm1IOSia%F3rt#)2*iFPMlsZtrQv-GVQ(@kmM7ka}U#nUZXwAzU*K zv-7GR4~aGh{gXx|b_E-s4l1Pn#K{Zm3Tsfl&8e!wF@D|H?kl}I4}XHGNjG5;uOQb0 z4TgcPgNjSOU8s2E!Yn}x`cL}`hm$^8DnGsD9Q!;!9THWyS`w~?3e}*enn^6#hBM;3 z*^>m%Mc>VY>8^SQ7^2^5T9-Z=6@GPr%l^H0B-IyaOK{hfyHtjb@hL2Cd*{xNGJ)f6 z?ZZTrwAl7RiU74M@zTDUjuSAMWJI*hJ0hLgXjz(-z|k>g(pe6E|EoQ`(*lmI)N;-Z zqaU51aO_j6Lgk!iC4>Q{;a_RC^9{1oS?cY%6XUa_o*%a=wyquUAPnWhGyRTSxA9NF z4lV*M5kS-+cfD~JNR0pJctiPo7Uj%!2FPfPguE4o=yYhz{^v=Y8WG1Ulx3g1+J3^J z(S==M?9q&$be!g$G-83wKIN%;8eUc!n{htvmo#B@kRj% z@m_WH1ZH)8;e1q+PH%zDO`7POK;(Vb#mG@)ysGGvRGI=3+yPP& zs_ADE157Py4dLx{xq)71)NNxF92$)-vyCB{#V@tJ5|a=8FLrN`7e~^*BbDcMetV}U zuXn`xUXeF=9w;zZuMpdbxcmS`Mq{4jXc)bra$@#vI+C5sJ96^i4bS2 znf%Pc?PEE+Rx8(}sJuRBDJ>V3JCQjYotS;8Zm7FRkiN<}Fq-Mx4PGY9j^SQW`3LBF zX`Z|Bpo>N(hwsXHYoVVpNAg~IX^WKnwXQCV_iuT+St=nf%uv#Gyi!^Jn{Y7NWu`6; z=-aZ5fI#Z_XZrX7&XiSCyMmv}Nf#Sga{aR#daP4d&sGX5P*$$7sFP?~pD;w7C9Nv> zi@`H>m*3lV!23kaf9-`u`{6xkQ|XTPFbtY$98?Hn-Y`784n4Bk&LNx;!S)ySOVnJ}r11qMe4W9ra zv;D4E(C(N)D%udr9Y!xj^1YLj84Hm*m@2@)i&UgX{=IffnEG`7n@B9U=&&D<)(4N; zld*Ni+pYC~Ft8p1!?Iv|+;!LN%aOAzdVZv4&T8we@vubXNT@k_8mBkagDeO|o zK^&9g*U7~fIlj&ufEj`BoQ|C{Cs!r%qlJ1&u1V!mXL%ZchA4FtsX0@3w^x^G_uuIj z8zTp{_SqSt9>(AIZw{~(;44pnLg<*1s2W2@R9?;SN|}4mYj&_V$EUB`*>TPkNl3H4 z+K&kYrHH-8F&6ozQZY8swLrI=9pG6To`J39wnYrzgnY~RXq_vdBFbbY3f`l=S(0`^ zK{!bG|BW}}e_`UV!%}38c{uHnTmpcbZi!~exAc+Y&njG@Qsyy5>B*U^FvYu)s1{rT z7i4iD%ZgkUwhME29I&+N9@k41P(vo;9ROgZDUa+$VbD3QdTh=q$@;Bw3{sM10glCU zloKIxfx?GoQjPyR-_(6CC(e!Ur)%0~w%*%GQwr`bPCIce>7s)Vt)WW1alMyh30lf# zb7ZZWt;*z!neOmpnLPpg6Kd)Kh>g0&RDbj~KJ?buHMI8yDHE*(c;(EM7)@SuJ7Vb0 z3Sr!=_^i>zz=b9e2uucn+2t&aafrFx=^sw29YX9;|nK?W9n+s?oiG8_pguju3= ze5B(3p8pvLaCWvfOTCW`j;sif0i=w^Rww1oZs-KnR>^_Uu5FdqCdQ5x^thog6?f*3 zQnt(AmN{RQ7r<^)6kSw51zcDT$@Pp3nIlOnZ>m|~xjb}6S2K5&5@kr-~h5ftFb<;f_S} zqf~W?yRH48l|>cvKW5AKJT0mob5aGCkhY_SQ5sW@?c=(Vr47HP{dG z29)U|V0)~2*m&;e3{E))_*UjPDy%)B4IvyUo~@H@f9XJEYCsX5ZnqG``hc=wv;YX{ zir#<-KBs=5wf>`RE%0)zlEsSZPYZN%%0^(tbJ}yNAG%(DAnE<*`iRXD}klv4ce?P%PBt|RFsvX3as6Y z`%Hb!y_}Ggd=FPHNtF?4?)eLa(H7_(gKl7sk%RAVL`a@0s}$Vpj1h!VhQ9G3$bcKi zMObGUe*l)9G}&)H15#9fV#?c6%XD+xx~>gwfZfSHuzA?|{<7S*?|_}a!Z|-*!8qV1jg&|KhvU|eeR@i*M9Ttk;6)x#`uYLdqBJ6C z5#W3n0IF9QMlng}j00RUS`2Nt`LXD+AtE^EKmD5AJDuBdV)NXek38h@e4lJVp3po! zv8o9tOvqe`49%>l7ADF{DN0EIrZ7({?R^{b!NafAr_rdIn=pHoo>=6ioOq7`@W0i8 zdQ{hvW+9xDB?9mq({P)M5`aCak+tRrjp)S?Z6j@>5Y6#ww9E!fp@#04<>wJ}_^-z9 zp0=(9SB#{<$Dn@yaQADoEbzQ}-XeQoZx>*vn9ZZ~K9*~{pvW^_g6Q-KUN+8dZOD@oOX{h<$;(n0y)w-4 zq(?jP&a;?2hL5LZf!$ScgIy;I4;%2Ic`MO1Y2p9AHD>h7y)t(nrq|u91NtbYAUD|G z?CU9l|E)U%&9$oB>t^P3_~{hQM(!>7rlLfV%0j*i@p+SgYPn~gW4NCXME2v2H z&Coz#TpA6eu*%?Lib4sMrMf_WlRf`rE4>r}Ry+W90X8;LhZMm0m*+5F7M!A1*`CTn zX!cRM1@NT3=j^)DX-`~p0VrQ(c^k$Q)HXS8hHA4%^Ld*3JfORkD^+2kj)^LOHGeim zDwT;%XTQ)GH~w+VsvAn`G~;7I_N_LwIxc8#o!`jSH)i1shIu9c1e9wbs^W}*O~!FS zp4=*y+M6Qa2n-$9bEdk2pf|UdDheiDTdC-5zNw|)=}&mV=MY@ndXKtZB{j%v99Nhg ze7k`9AMvY4_RiGk>dtli0a7y*BOAMw5jhjP7boPXTo>A@qDoy=<#Xb<%dnBmRg9EO zvE>NSF4Y~<1^}<=6HWcml9UkO z)=m8g?>WI9GJc(4$*dTNK+S37BFQ6 zdt7hJFkrx2{??g9k& zeUs>24?RWwWF`9iA~>Ea)lj|40g{eW=-aD!bHMM0BOR25uu;tQ-{mB13bp(5-ayHp zw`HD>-9oa9lgQU-M!Sr2UO5xCU^f{3eRk8Pk+*n8qsA+gBS8bZtiQBXmed~B0v4s2 zhW=}yten!3yVvg{kq8;pjZ@6M_&S7JyE}H z1V*UxY^VK%Lp zXmjBGe>TdWuaSz=|G8s-g!Tj{eQ@ugQ&bsv+r$98E7Gjy>2^)BWI^=75~Z?Dsme!+ zO=)@&D1I?wt;_DJI@2R5it4WhqjKw09`HZ70H=)bwGZ$gI;M&N`|!^!x&#lFZ+Xoy zku6iqnS4u|9+7OhFi+Tl_`vvqDw-F03&cjG?Ylyz>OHgY^SZJbWWTH$p9pjiv9l+D9juv2L#4Qnz;) zcR=3BYlr2u0FR`TS@A_04Mh;q9dVVPVRGqqD?=}NBt(Z+U5%&xv_j|BAS5((VB3CZgn^}E=FYXa#e-gD6#Fl^YwlU9#H8Ex8W<8?@nS3e++7(b% zKhs;2GuT2L%MdQI_DtK_PZRQ18~Dh!VOs97I)*}dY6m3%N3T&EQ z9j_A5b$rV-?=H(lNrgNv3Rpv@m9Ds?6DDZx=c5{+yK*m?z81AMR_ zy@4vtKr8H{&f6l4Cq$Iq>q4*W#I`)r6mwYH(_P5hXI5vgq)ECDqf3qf3aX-xX7&j1 zn<`H1;%W0m4K1Lrws2za!YJYzC0rAS(4}vLMpmKDBg|#L6%t4?)Om*K0Pa^kbBueC z3_54(mP?_rA7(A56Hy*qP3Kk4JTOqACSu@78a%6S_#S`>4()@(jQL`uBAy@GU%ckc z1=(wK_J0kvztaP z*D!~>t*0P~o)To8n@y18_LI@!_ePEO9zd^UhqY~KZQ(~O*$lt5@*V7_wCps6x^p11M6 zMp#jvOl30dnE4+0eUa#@5a_!&b{q$>KERyK(Ip88#0-U7>nKiPco!CB_C#uOWN~1< zI;u+cBcNMhOK~2i&r-uJ&*+C4-M>yUj`*-V6+q2C6 z64zdU)mOz4RXLn(_9upw>X}G$SlUk_h-JL8Rb%SPt_P`eowR=@j0>#NrX~|J#g(SRXBU!P-KG%V^p}CDB75%8;iH z^dJs8tt;M3#f9lOgEaUb(hlcP5gX0*bCiF!qy~l4vAFJ_4UUf*R3SPtEB<0{T}@qX z2}k!{1PrU-0lLj19FVQ_0#S_HisdjS0~5)T0j zD0l=*iV0x@nL5M2!wb+h_W8;LS3PZ1ZE=xDRs%29m8&z4wJ`F=fW{=h3G=q&Zx~uB zI;ZA0z*n1;svFV1yXrxOVR{CzRj26s9+!E>!cY#l6>6nceai@B~NMt;?7hP8sIa4wQfx@>5M298-5_8!8~ZMX<*Ds4Akq08h^UuZ!W zyanVbrnzkfY+1k8$;2KHr8Chd{uPc`-}-aZ_!MN z5G!9G8rrG~@i#ARw$rop2XRmjd)01$6S+851%!FNCn z1gk1yijZ5{-hlgyZGwGDY;O zzq+vlIyB}KnLAC>l)@z6#u=3Zu|`P){Cv2WccCnXa4{p+0;;14M(Qkv@@dvPp5)Ji zWPVi1P1cIdQwr8>19Asu0N(OS5dq>4FKIKL9!!e089cIJFu8j523=ipWyz{uAE{e+ zO5)$CTjhEK6FK4HtUoKYod+XLrWkS=O+_Afb(av3vs^Wz4Ud4$7QW3Pe!u<8p`6v> zS6L6}>@JASlfzC_S^I)YJ-GPO_*!i7F!e-i+Fux*G@e4UwXRxra=0Okc{BS=*ZtuO6L2U?NwZbLG#!E71M}1 zXHqq}BPLbcrI6XhQJM+HYS8_DnS<`wZdC@3v1#GXtDZ-|#Ql`6;qfx@a_VVoNk?2?G!%N!d!I}`1fN>k20Z&rv~E*#*m(aP7mvO_j6Tj=E(-9PI9Va{ z?H*JY;uuR1<}qA}rfw!mzsN4${-SlK)B(`oBH=dYXXR8_L0=sO{?N{cql@#Rcn^*~8it^Q33s=l=40-%1FQ+RH&|N{+Rw5wzER3b|s-0$) z_Zrmr?q1}as**7xx1Zv_xL@`@>G2{(@2-IqH6963imW+uc3MZ%M4i8RW*~_&{}_Oz z6>jCX>2W$U8dbkS37jaM7Z9#m^=2(W67ncsW`BmI&H3dYW=N+Aw9xJJ-AulT+Z04Z z7Y!A(c(Hhz$hG_JUzf9HtyS#pm3XFRVT@GStjcZ zIVqk6o8iYiJ$+Tv6t68FP2^eBYAAfT5?MmZQM;ztIV6ij1{#_Kq|b`G%WoDsV#`Ke z78{pRpmN7j6!gKI?R$lKn55SCHa$#2ClX#Z1~^~ZW5u-V>VW*jFRd{?^n)r4zF%s9 zuv5|3l-pKo4&9&*I)YSB6?Ty|88A8k*0dVit6QJ%Gc5q>5cOKK2zk1m?lk|`ho;+C znk;6nK;|!&L|ma==a-w!oob*2l!Y`F)u6`KOX@)1rY z&-tNQ~oBj}6H#%}<$ zKml4ZWkVPU!uXoV>1v95UGQzYtTo5{!I9hDH$WvxB{{<3&UWAA2}XPY0*e_iTL5&~ zV zlK?Vn3Naa15i#Nc$Sj0az*UfFM>w^I#}vs^ik3)L0`~wokB;;!<(2w!g(QmqnEYiq z47gC4%7mjZ1FA&%M4_WB6~xY)AmoYt-q*imnfBtG^|&?QG*VU})InqW34$wM%+7%` z!^jvdEZ5)AvTRxPKXeA7a}xxx4hCjJ0erMsVfiJi!f~}3Vc(pSo|VWp32Uui+U#$K zYHS))1OV&FY*r3D)h3N{&XTKokS;vA3R!3ejX+}2o2x*yp>b9Hw7nRrl9u=@a$Cm? zDW<_UFiQnT;!sgu-08C@pj3CCcWR*99#wglM`mCxv;W#KWhS%hWDrUnT@8@S$1 zy;9!s*$VWO=6JTErbB*0e~2v#y9B5GOb1FMab#C{d3>z`UR@ zhITmRdEBUm5kz*s5#)q#=!wB-*q>(`5OOB%m*rWVY#|4RewI-`gxk<6g7pCD;(s2P zq_u}gtdvw`9h%MfZ<$`}izHlS`zw)$TBXJ}N&hxjWP(Hgok)P62yhiEDsFbK3C&CVn4oHw4=y=-lRFd#91I7E|Z(IeJh09O+M1LoAw z?1r)9b)WNu*rl5HWIrMOJg8a`&7EqPHc2d%4*gOwjoO~6faH#D63}>#h9a+PXfk>QFQ8o}Wi%hoo zp7_^05;1#%oRIC0+lr`*=&1342!t+9idaj^OsBEg?fZ9`bDzdlzU2M%P*7SP?q1+k zM-A9K3sN7AaLvZ#m@^OL_mWq${N1df5l9DmM9x~%TTtNz#_`QnXXLvlnz!#j^{Un1 zz|Cp4=x=4{Cwx|e7%Oa-M~kuh!1k3ECx-^%>U~dbn#}w_FjmhUe1;?9gS#j3w%ps3 z>QD9mdCvU*sb%7R3rnU&*|yMFL|g>SqYN98&zq7B^)`d0eV@840jdq~5sZ;(SiOSj z6VaPeW|mq!LebL_uwVa&T=D-T4fka>%F(}_#cF`ytFeLP?jtQe>tu5W_BG+m${dR9 zw?PA#-!`V`N3n&{NFe%Wq5P0%KNd50!2DC|j!ArBd}D*Q@=g{nZ>{ z=o@NM?iyUc-nS?mZocNJm%)wcPz-IX-B2V7rRL2?OMJ@NSiHP>YiV?sga~}InZYZ7 zxf+H^0(z$76G@WKzV~^E)+1rZz&0no9jr_>o0L9tAv*TseyL{lM-zk(v7|NlBJFT` z?GLXvkc83Te}Iv#0`!Tg9e})GSbmqxhVp)zG=lm zCqFhDfTVRk{;8t62>oFEABqxm z`q<)9XC}A4%rMg@lACAD0f|&@{A~M|a-;U+mZegaYNfJ?iqkfXn3hQe(vqHUh5Pr1 zwfQDrKdn6k+;>(+s<5Q$z#6X`;AO*3N*zsFj*wCN6nQslol!4-1|T}Vooee0*!o4% zg;=WZh23}yKS>mFHK+ok_6Tdvi`6kwA+8~F#`Y!mYuU~X%9 z;Yhn{L7RMvr|!C(I2(WSR3Q4$Q=KuF<)k8Kt8xnH1-t0$UmKMKx4?x7xu}ro%dx9K zhS3Aj^l3M9gkYi02GUP>(s+($mJq;VWz#K}!#g3ui*4UHCUB_TjF+(n1b|Zy#=o)7K9|f|`M>E|xAkVNpOpuu4{rw4s9yiiAOu00d=p?xy!F(T!s~Enhe+e) zwE+-A^eJebrXMe>_0uT!E>IOmTmh?`T+XtSg2>+DPehu8$M|Jf=phwhYOHtd&v~t& z68^#R571^Rf}Gtk=lg`+7F^Q`{S9GYQYLO1Er^+Td%ZYz{jw^XtCLTrPpamsX||bs zP5Sjm#Zx}`eQU_xH>Bwk*H90-t&{QDl;o~S>@`}B?H|_YzFx0D z%Xp;MPx0wTMcr0r8#3K-Ty!MNkxj*G0Ak74n}G>D|M}yAS)A+7P;Z04QWa{VqyiGX zC5#>$9Y7!NUuA(+1Hc~-3lS-kdlNVqR=cqbE9j)yK1G}&54j5^+ri{M+(`$>>qHc9 zTpynz9oKU25@Ho}M~%}|PWAu@)wj{|J+2t#_A44N*iiWL3)wr>K239$Z$9>IL6A>@uFWIAO!rPP`t zOm<)#0F)}*;Z55Tyt^DR44;aljlYJ;rGSN=nC?PIwD$RnE*K;H+KYwfPdoC)TR1XF zyGx<4qw0+o?l+roUVYK5g<4t{@6rfN1?|og!e`UN$6x0-`aDh(`44x0zlqjz4yshL@Z&3Nr2r4sS=TfWGK z-Ve;tZ-ZR8W-QEKC9~!0LPoOxBATQNP3?)Z>Bv8Hnj8^UQyhI6DhhdDPHgOmzE=*n z|E-~CpuM?#MHqy>=P6e%Lj#85($q9};ckt$L| zlu$yGB1jPgiBu^7x9oyw!(s}?#PGDOfLRS6R^!`u$G z!gpG;Y~1(zMpweO-~l-%ga)aW?wz1~4%J46*nJ9*xjV4Buf-49gu#Kk=-U9AK%UA2 zD%MDVD)3Cdpk#!6%WLhw!r^E0biW~GqTU(H=GMFOOq-SMM75q+wa9xosDZ@>I> zZeS)aU@#jgDe`CnXf|smr)u=#cS00bhPt9NG_z7&&%{zf_sFt!0Of*i(kd6)4c54K z2n`1|q?=%rG{Xzmd-tS>PeKD+9%~bx2I`m8-fh-*T8vm>tFGoMgq=D7^1H@m5GEM? zXc_7S?s^1>5VHb28L7xu4=kdFe$|P0__QsrEZt-d^5%?_RJ!$ZKE_^}qtz+N13w9< z0wc+dkd_LK&0%xF1Hiq~0_QxG*@Ii!)Bni_wVybqF>=UG>y7kX#i08G7kf7i?$uAG zoPr214fFR!iXD84o`YZmg6q_$K+f)O9-<+hkvbB|Kiff*E98#pbh3dfo>IDPp(?dzfatM^;)+>m#A+Z`tA6f{mu z#(;*NqrVy}gGDb^s_N#_$sp~0iyUjpQ|{x(<4|HzPNqs;(hFGBN6^?yGd>F({vs)J zv3w}T6MFYPhv<|nvC)meHsHbKl0|T^*XPx4N$=X~IYmZff_mnhIxrh$$1b#_?&N=; zS=vzZB8cUyW-}Hc<+_h8*fd9|70OY>nUgj5dbU7Jj*NwANcj#zT67XjU5U&eZ1m@9 zV@V9V$Ol;>MP{oFO%tfgPZNi!=k|S?Zx@vmjlKagCQ`D;_AI8caP9Oh;KR8fx^pG% z$2hGmRL)>2q5A`Bqk~=6cH0;4XqJokG>Ute>;V0J62$yxq-q-T{(Mr5gEyV~>~i9f z{eXJ9zgV$ZlsYMD@>B?-e5Ou)K~DELLitDCBSEFz{8TE8V{S6Uc_qE`UKvb~f=d3* zPvFO6w4AzX%S6?OB?@!Jluk&j=S@d`qm3I_nGcz3;9yfCHkvb>E}vAdf1`+}v83Cd zFjKpOmiD-BAih>b8jv5<#Jgn8`UPD z&l+iAv7W+!E5*-TIo+TitRk{X-O11S8qoCz!{7W>SWIpG>r7Z_l9PlWfy1~?E}lDe zs$W-V)!*TZCdUcEKiRo;Cqq*Vq6#z8^P*>1cC&8Qq+|4Z?y8JrQu-Uoh2O9V`NzH$ zczl8yQ@HU8eec42OVgV!%|>bz?*nDoE$;6eWM`9F`ET!b*%~BHTrT3x$FNdi*tq*% z5!%a_wwZJaT>Z3Sz|2F(A0h^{apg>zKedupHU5dp;_b%$} zjWia~d0Q+)my?;7USk>ADcBU`Ev+>t;sfH{IRw&du)NoJ7MKVuZukpfZoNr; zvD&X(EjYEN{OdH#g~wQoqA)8~{d$w@E7ZRXIs+_s55;coTK}S}JbKp8#B>S{d4vt;rZ=%M9m=zSpS)agJBZ4Rhilp9P zXD9#K#RaCWI7v2}sihQ|^Ba2nIt6ZVx>KcBbl;YZyCSW+YiLzF&Tr78(@^o+Daf)~ z>OMR-dI+38S&9P}0H!eMv9j5>?~R1X(j>E&HhXM=%tWk6s8>8e<(X*Aru+g|gIR%F ztnQmqKiwk#@5Nl*xkjS4epRo^!Z!>V(RnDQQ7rU|%(NH3R%vqyuN_-RK|&xf2WnCp zvdGGi9jPzlP9H;MexU$PT;%)s*ENH39il{o*-L5)M%o{2AzB?la=uRrp`KE_<;jCov)cO>ENh&DO6nN^*`h6g{8j7nS_FLG&&xD zqdc^%7$e>Juk8-%Cx6_KmcKa5ek+L9REk4HCr-x4BQB$vM+396rlfIx;Og6#7)O{TkOoTZWmE&l1a+;u-kDM5Y1)@!<2&)^R?y z)1V8+EC2rLn>W+o%WM^?u|2lESLu)J;yV6Ep&JO^TZ-Mni6=s_63aJ|J{>ac9EH&S z{hg(4nA(OpyYPEK;5Am-swp$`!q`<#p#!VeTO;P$e*ztDB7CRjuPYqd_*!(r%K1&s zbCj4R)j4`^KmiwZ9vhz4xi_pMf1(W)EqI86RHYm;n#DCk5os$vrfY4gywh~)Abc6O zJy*ns&ShtJNxkRpnlNUykU4M{)3)Orr5PE)W%&N{$cK&A8`sJn1aIixXEVZ^x@h@u z#*0QeHgl?^YhE=(?DVIn2U}Ai_r|e%jpq#Sv;6+JoLRQk_&UoaLcN|#JeyOmA(H4%UX9j0mw#T5^rk+l zQ*!t!B^2Dc>p&t!Qz6fo6-eD>9|+YQ$N#B^|MCw|G4JD8k+Ujb)C8=aFN7mI-{!4$ z+u|1z<~CXsYAD1aYRrXU7IdgtG-kX1`tMz$`Z)Xcqjoqn&PqVnF_ zt+PC3oXmGIP{=R%)2$zwL5wGOtIFGi_xubp4n?SzIzv!4A{XGT>P*#URLI3rq;NwY z#3i!Uq8G_kBkp?r`73I}5|pRS6W)jE8JCP<-}R0}XG;LOPTT0Qt-X_~5cQYDXkA?@ z!^m3#CGT^q?^WD;k>{=79ng-33c0|%wmL(7RMzo3#dE9aOEp7SZ0GSwka;@Hbg?sr zeX6s#)$P*?jB}ZVit0BkryIlY>w&8@nTs@Yi4TxvS4l*Q#Zl>a8E-tG{9Yd8dQ zw^bRx+P{|_4?ZzH@GX>yE>aJMk4;?psJMQbsM6|@k&d>y=n0s5|9D_v%Ga_Ce$g0z zUijQJ69_xUbK}QX#rh(R5h#@OL?~CR|ttc3fLz6$s?dv9KRq-!4eh z659^Op38(MEEI0$s|U;}wOpXRrIY3@r}5>L zR`B`^IGcZEr-&^^_aR-J4BbKD1MLm_lt5sU^m~FmyX&)G7_VS;QDQVEi#sO14q(!}ASz_POvne8@AQ0F80p7ubeOJRdZc+~g@94$ z1mPrzXhc|fN!lw6dj-F+5n_D57u^+kDlp-5jP`-6KZ{CvTXv@xf76TX$lzP)OvYjA z4)6y%iwLtAOxBa`r&X6uH8EB&g&rNf|76{8)=Q`EdimKU@_ol1n{tUI9bqZn+i5CO zPvE$Mmf=-qiz=rC10OqbOocWERl`kVBzu-o@}-IMM+O1Ml%r*0xd)q6(O%Q%zd+H6 zzvETVkV6;mTP?KJC~*`T<>?}|@XTY#&ph1@1mOcaYv~VIcLf#kNEW*PBKtfdL`vS# zeD>TZ8!cD+U-Yq1=uK?uFr%6oBWQJqS%Bm3WF8eF^Z z=!|%17d>|7u8PR(!ek-s-ld~bGBS}->?Zv1=WEGfAwi6jszyzE{wp`BxOX%(rrH`k zGRp>e1`h0U)~6phYPEW&VTzUn4?(K>p%O{D9=*F!k@8oPz2wam`&H(^E7Im2`Ul#b zpHki4-%wx?*~V81giK+D<ygHn+ zwKV^*rwjkMrxa!gd>YFGAyPSIAx0|P41%NrCmB#ufpZLDQi=b6{-8=C8L!!=EmvC# zqk@U*aaj_gK~VZBZGFLFT;X6YB0v5F0#{zU3Kep5+;E>tu^JL`Hl-6cTQZti*c8z@ zsEtxEfx401-n1Ql&dpig=qgaDiZ3+&U6#Im>$QE2&42H~-cu6v37XSUVM~w;FbM^> zVxMhQ7B}7^yW@?mCwcMXw+;;j{+v9V*}0w7%ui42qzmJ|t7rMpetGbSa}H=JCP6jz zkH_yH0lCsdwf3$iDD7|<6}C6qNfI6&1z)(bS^>glDBXYA^&VeXY@q<6#n9Yxd@T9wEAPl;$wB$&uhOXUtzj=@$a*>;|ft zDG(PX!!|3kfP49U@;B?dCrN^5p8<=sRGDrk*G~LtEdx3k1#q+8X~?P557UuS_p69d z{0mBaK}G)lfAc@MN%cd87b)-iY(h$0#L}A(J~a(J6-iGkstZe-1F<|av9le6{s_Jk z*^L8Gx=)Ig43Zu@L-`?laRl(+O}I{k13Fh?X0X&uhOhDrlk6G4ws~{ z|94LFG6;gFw_K_Yoc4ZcIv6#JtoyvhX7r)Hvx&KmM)$8vVa5e$+fK5P9E7?F_qRvd~AUy&`~I;wxaZvY;_ei zMw{8B>L;Lj-77{0OEi(5GH=OxC^Jl?5Px6tORqWYZ2h2cxJvH5 z^+M^#hA`t=On9MNEFEpeRprEAM-%AG_J_UZ5Byp5e#;EkP-sfdkqKA|on5phRX~!q;2^VZ=K(l9r%NmUVkAe|=I|adpg{Qe||grw)90mqOFcI-wbr3uNV+ zN?UI|4$?3Lfk^9B-^P515xdpA`Fyk2jg=lG`M!Wg6}o5w7DTn|?O6>ijEZ{?kGn1O zhuREO7Ih7fx~uEt&^XnyIvZa5;9MCD%O0o(F8QVnX=%n#h|fy^jpre#SCygV*CQT7 zdIJL`1e3m;;sv=WuD8r|mtOLe@NV&0t%3Ar59De}d88mVN*VC__FS@@r2_v)lpH7F z9Pw*8qs#j9vI_oR=|`fmZS|2`vdwhCkL#ccXS8~Ub~_SomL9kG(ZYqZl>Pq#9rZt@ z@fT-_F!sMt^GeuFZb!cVa%hFag9MGG)tgq%1j`@l3Z{v@V~)6Qg2DqRgM;v)XSvFH9i2Z=iwTWX?_GZ5n6shpIbG4B~I2H*Nrc5dkW` zP>6}Y@6d5z^#vopS{a6eO|9vZACsV#AZ=8_CZIYH)H-gu9C;VzT~Q|YYZKLoX4z<4 zriiNonilm^^-nHwSw_A@3Op0bcRL(}mQ8IVvFU*3fH0EuQ0bgl0`L;lb2_Jx53CAlluI}38QoY(f6q9fF@(=ZANuK0rN^`<4L?AA?v^2bBvRK z%RISw@@K!xQCe5AjBfIiKU-dLCu8Y)8bQ+416*-l9~3|b;|#IXZHuQ7l#h6b)C67H zGDnWrk{+jigSAR42qew|NIj4b7oWS-2yig9Nouo=F(|5rlx_FZ%b-=Hw6GQw1_|`W z+63;`hQ;+C9OPR7@nG~P_Q5N&2IcdbUcc&ZLX4qasFx|WP@V0VYqQBuPi#&^kr;vq zz!bx3TMymjAac%w3CHYpznd~zyVR)Ut=3R>Ln=hlX&5nI3lul+}tu`gy%5=*Cya#niT)3#-%ZfFK4JD zsB-b~ko6)2Q?PlJ8h`(hRLXIusAA|{<$2E`r?!BOjXZgaLEB^(G=ii?pn6~&b|(7Y zPXQpUfyGFV*0%5bPw=@|SsEhdAktqD4^(5(;FNtH(&w#^S)4`<1^RBS@*qmG1%#36 zd~^Yq>6*X-eHk!%{^wQozkTgUPCeedj5F)fL9f%2B<0orRxI_ejgA5bM};#g1(Mp4 z05$|!l9wBLBod^2ZCz0N@03S(0CHi4041f>-9EPdZ;#1m1>D<=V}=kNt}6MeQY<4c zkl+>G`F&beRa8~cP;4FX>F?2x(beX&iX%SYUoh`=`{PD(HEEN%RbKyS-ML4?@c@gA zi92S>pmqstRO50${>Ln(I0>o~Dgt3ZPfW^6Q*y}a;X3Tve*nrvqj}v1DJ!2^oXc@1 zh$RYjm!3I;#T|8p|C;vyJDCZf?AIBj-Bevh^49O3IEPiu7G>^9NMUqfP0rHzTJkt< zReIA=eeRWKa3Lq9w^olu4nq&pxHr-g zy9mNhOq>`7U?;`Z9V zN(+;XFTDft)rzm*8yFQlv-Jd+0o1cC{|>UgH0T&J4zle`@lien?K!CXX_1#W zz!I&U{-=;f$ne1jP%r)q+}PYGiUSPjizT#mEZdHwf@ykzYzNM$53 zO?Mr)>*fE}1SZULxd6qJ=2;CInEc~66> zzaVsM46{6P>(ZBW%Vw~&ctOz$s22@*HHRUkMVOo;Y#rwB73C2Zo02VK_%AL>fDZS@ zB;>9;n<&)VgbnRrpNz2c2-TAX98N}6i6`^2{lRS+WM1*tsu1#gBrbC9X2?I=4agkk zJlddhQxsF6s$PPTEA^$Sjv&tXRqJAZ;b$uD(Gnc;S#6VUDR;vHZmz#APPMZ&hE?I_ zqa{GF9-HY(*|fK2wy9PfcU0Djg%pOSoY0Yp(-OnWvASO8)=BBLpN_u2WN%CV+zz?@ zkHMGEf>hY;50PGUYSd2CtoYHmxeQr??cJRe0JNU8%d0rmvanF zXI*`J_4zW=Pik7yJL%>@Ab;t|*IS8RIPK<5T9?Dt+nYqRZa{d*j=}z>=NG@v$7GH&jIw z%khHqF~X!%>}6(^hDjHe{@wKl`DR~q-N`9_Te!G2rgZK=SGWc?^tx27@_HQI-~v+> zQCR?xdMySTRlvsFE9gJBxxek!M%I4$#lRYp88Vm%p7ySdd?p{)xnB>GnbJnPpc6J$ z(O@~`4sX1#l8fs35E9#uP36iW+j`fj`}-y=tFzgk2oxnsdHbK%h>*Ww>UUvQh|5P! zezgqwi)rz2ZvqHCLlB9;xcm7K*vP@ndEfi}DS3zTSp8|E%>wp#3 z;NvDV;+1E8m*-rtr=S7*G|u9Of5XY4!InP&N3MaNL@@ zL&kP7DzeK@_q>)u!LoPUOZNp?0W1h|7$Dp-^>#kq2%+;bpmMA$Noz}=9 zk#FEitHjOBgoQ@N;9UV==jj2N9%wUo@3463(S^2?FB$okaAKuHwK^dt_vjTta+}wu z^x-=V3%2#+BLvVPm&0CSrJn&$CGj2G@-z_pJP0@Ua>J^n6gwnEhH*1W$?Q!qgrWsR zO<Ot*!@5W9F^Yh$P-@5NNlG; zaNGyybH$dV8mRK@K8k$iOraq%PLAs24|b%ONwEJQw&HWg(ovxid9w=OAjXi>F!8OC zcIbs~=Ud~fjm1ht=(dx@A7g}7j~UCWHXw+Yh`d2p@z5y|-Kobad+$gcRFNbJ4(zF* z+Os{QZGt0%B%;!=P?AAGDkbuj?bTB6?KtsmW8pt&RS`U|uqn*%mKNf!=5|bjWOCr` zN?6#q>UG0~JLhBi1QMy8;1}ATJL$7Ximo3|Kqx+v?~@RQs&!kLV?w_X`yw4EG_me3B$| zVd0p0?rW##5;r3iB{)Xb3`d^;vC{y?xyZH2+&h|c%?RL83WDaY*mc7Q3rkDyMHQvY zH(jyvX$F70MjF^=jA1D`lCKqdM&~J(&4$mpr88dHi0?Yr=c_b@6~|e>&zJs&r*Zw= zr{C*omuvF$P2`7cF(#>d!X~$S-154v&+h;F@ptY1OcZ6eT2qSE1^=3M(oDI z*xhJTN$s?m*VBJ{%TVVWNFA5ouR-4H5WHRD+D_4Vr2TvT1TGTyqvX*OiHKyjX=w$F zX;vW8dd~dVDBY=<4uuJ@MiirYa3?x2vRiI0Dp&R5R=(9hDO8JwJ ze2gU-ySGk7Q)x@E1J~t36Lr-u4n&S!n!Bgs9N_(%e!uKx2Qj z6U-Ki3PzzDoh6%7QxVHH!XsEo2YO52OAol8=u7YkWGZtGB^QV#k$5 ze}CjbM3F zJawEcp_}6=ttt3IKa9JrY^W7Bt$;SCc_M){thmG9Jz?!Kr`DOMvkfH{yFIS*B-(_{(x$H7xJ_y;@% zGU^z@cnmEu8O)e3y!tD<$Oru1z9?T4VZpm1pB3l}g zNbeVK+(NS3Ryqi$smoj%Xw7;OI&B=ch=HHZJHOjZjCon9Lzz$ehjiPvVlJZWVnU{% zhq(~ajAV@NsqRf+j|!xSN5D3`_OmJ`j}14&RHlGVrj0aYg(|rH(4K8T`|od~*7erW z{dTz*$rqEN?+wZ&&5R?{ucEZw6a`Y=)rV>-4%U$_>!f(f+tqUXr{(w)ps60CD zgZB?c0z}@i#U)E6zxBO(m|h7UnDgD@s33^r5%9f64)bWIjz2W6142@{>ts9DsBCw^ zmiF!?aZWdgRA|*+r=21`Fa2n!TIdB~jPJsofeug4 zyR6hy6d@C!5}Q01EKd864K6%}N*0F_A03<3>GeYsV2;=6RUR(1Rr2qDIdn8le>(Fi zt+`7vH@jwr2^$vFo}^{Pyb=gWt&5QAXPu|e4d$O5h3a^}e zVG@6qk4x2-0Z&ZXg#|&A`rZDP#l*7_19yyc5Q1^jSxMH$u;d(!Xk2IM%1DK+t=lNv z^+t*!8PSjFU9wuVZwgEu`3^#7vwo&yv9%DJckhJt`;?FCP+WMMpZ)mF< zfwYpm^W|gjm`(lfIx1dF$8CiR29)RK|Mp#sY_HpRP^+Xl1S%`M@b;=hsmTM07E3j{ zeawXt7l3X#378Q1{LVPi%r~k3YGZ_hu51EL8%q@0O*#r`6I`@0oIOY6B$fiTLsMw2 zRrFX@%vYrcBGPBotr`=J8jcd57$bC}WT`9lK+=@5HBYNtjk>5#bbPRC`jj(G)nXOJ z@%Ra;^ksjVY!9t>;C+?x+I#jp6a%ZY4E;QVH@}3xo3tj>k4m^(`;i%iF);Ki*mFG1 zu)};oX3o_l|K*iNz^bz1eBsb+TIu%@(|o&7KG8}|=l=!)RIDzgm0nVH5!Q?_iH5;?^^3CyfPSPNEvb4zq(1i{<})DO>#{>MdX@A zu*#5t?!_0O1xvfblo;Xl`=8krFC}~=4}~Q@;Y|sgtUweV%Jt@~G1Tkrg1W4dyTlu_!5!wE09| z?-+@me*>=In$K=qfxPEv`ZQ#!I)iu;Xzw?e#qKZZ%=X_c^AEqyoGx@tin18BdjILXDWW*coealW|b z$JXacJD52<0hp0@=qVkV`6Ds#|8v=?rpAstwCKpSz%fC;hSB==PXiI-dN4RQZBoeu+ z;nm5ph-C`&+g`&Ii2gr4`tW~NQs60L$$uHSq8{e3z>UVigC36=>6__Qoxc+GzW}}p B6H@>H literal 0 HcmV?d00001 diff --git a/leetcode_101/docs/15-advanced-data-structures/_category_.json b/leetcode_101/docs/15-advanced-data-structures/_category_.json index 531df2cd..cbe6af2e 100644 --- a/leetcode_101/docs/15-advanced-data-structures/_category_.json +++ b/leetcode_101/docs/15-advanced-data-structures/_category_.json @@ -3,6 +3,6 @@ "position": 15, "link": { "type": "generated-index", - "description": "5 minutes to learn the most important Docusaurus concepts." + "description": "第 15 章 更加复杂的数据结构" } } From efde52e67689a8da299076b37bc569c30735c546 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Thu, 14 Nov 2024 16:43:09 +0100 Subject: [PATCH 19/49] acknowledgments --- leetcode_101/docs/acknowledgments.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 leetcode_101/docs/acknowledgments.md diff --git a/leetcode_101/docs/acknowledgments.md b/leetcode_101/docs/acknowledgments.md new file mode 100644 index 00000000..8dca8d96 --- /dev/null +++ b/leetcode_101/docs/acknowledgments.md @@ -0,0 +1,16 @@ +--- +sidebar_position: 79 +--- + +# 鸣谢名单 + +## 官方唯一指定最强王者赞助 +Yudi Zhang + +## 友情赞助 +排名不分先后:Yujia Chen、Chaoyu Wang、Chunyan Bai、Haoshuo Huang、Wenting Ye、Yuting Wang、Bill Liu、Zhiyu Min、Xuyang Cheng、Keyi Xian、Yihan Zhang、Rui Yan、Mao Cheng、Michael +Wang 等。 + +## GitHub 用户 + +排名不分先后:quweikoala、szlghl1、mag1cianag、woodpenker、yangCoder96、cluckl、shaoshuai-luo、KivenGood、alicegong、hitYunhongXu、shengchen1998、jihchi、hapoyige、hitYunhongXu、h82258652、conan81412B、Mirrorigin、Light-young、XiangYG、xnervwang、sabaizzz、PhoenixChen98、zhang-wang997、corbg118、tracyqwerty、yorhaha、DeckardZ46、Ricardo-609、namu-guwal、hkulyc、jacklanda、View0、HelloYJohn、Corezcy、MoyuST、lutengda、fengshansi 等。 \ No newline at end of file From 7fe259fc96ede7b56be5d68599918bf01a1acd27 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Fri, 15 Nov 2024 15:49:06 +0100 Subject: [PATCH 20/49] i18n chapter 1 - 5 --- .../1-1-algorithm-explanation.md | 3 +- .../2-3-merge-sorted-arrays.mdx | 5 +- .../2-4-sliding-window.mdx | 4 +- .../4-sorting-algorithms/4-2-quick-select.mdx | 3 +- .../current.json | 118 ++++- .../1-1-algorithm-explanation.md | 11 + .../1-2-assignment-problems.mdx | 146 ++++++ .../1-3-interval-problems.mdx | 75 +++ .../1-greedy-algorithms/1-4-exercises.md | 42 ++ .../1-greedy-algorithms/_category_.json | 2 +- .../current/1-greedy-algorithms/greddy.md | 7 - .../10-data-structures/10-1-cpp-stl.md | 30 ++ .../10-10-prefix-sum-integral-image.mdx | 226 +++++++++ .../10-data-structures/10-11-exercises.md | 53 ++ .../10-2-python-data-structures.md | 22 + .../10-data-structures/10-3-arrays.mdx | 250 ++++++++++ .../10-4-stack-and-queue.mdx | 257 ++++++++++ .../10-5-monotonic-stack.mdx | 72 +++ .../10-6-priority-queue.mdx | 295 +++++++++++ .../current/10-data-structures/10-7-deque.mdx | 82 +++ .../10-data-structures/10-8-hash-table.mdx | 232 +++++++++ .../10-9-multisets-and-maps.mdx | 87 ++++ .../current/10-data-structures/10.1.png | Bin 0 -> 37020 bytes .../current/10-data-structures/10.2.png | Bin 0 -> 109141 bytes .../current/10-data-structures/10.3.png | Bin 0 -> 72740 bytes .../current/10-data-structures/10.4.png | Bin 0 -> 39987 bytes .../current/10-data-structures/10.5.png | Bin 0 -> 42518 bytes .../10-data-structures/_category_.json | 8 + .../11-1-introduction.md | 7 + .../11-2-string-comparison.mdx | 339 +++++++++++++ .../11-3-string-interpretation.mdx | 129 +++++ .../11-4-string-matching.mdx | 106 ++++ .../11-string-manipulation/11-5-exercises.md | 26 + .../11-string-manipulation/_category_.json | 8 + .../12-1-data-structure-introduction.md | 40 ++ .../12-2-basic-linked-list-operations.mdx | 270 ++++++++++ .../12-3-other-linked-list-techniques.mdx | 140 ++++++ .../current/12-linked-lists/12-4-exercises.md | 25 + .../current/12-linked-lists/_category_.json | 8 + .../13-1-data-structure-introduction.mdx | 37 ++ .../current/13-trees/13-2-tree-recursion.mdx | 469 ++++++++++++++++++ .../13-trees/13-3-level-order-traversal.mdx | 92 ++++ ...4-preorder-inorder-postorder-traversal.mdx | 250 ++++++++++ .../13-trees/13-5-binary-search-tree.mdx | 185 +++++++ .../current/13-trees/13-6-trie.mdx | 137 +++++ .../current/13-trees/13-7-exercises.md | 81 +++ .../current/13-trees/13.1.png | Bin 0 -> 49070 bytes .../current/13-trees/_category_.json | 8 + .../14-1-data-structure-introduction.mdx | 16 + .../14-graphs/14-2-bipartite-graph.mdx | 90 ++++ .../14-graphs/14-3-topological-sorting.mdx | 97 ++++ .../current/14-graphs/14-4-exercises.md | 21 + .../current/14-graphs/14.1.png | Bin 0 -> 103164 bytes .../current/14-graphs/_category_.json | 8 + .../15-1-introduction.md | 7 + .../15-2-union-find.mdx | 140 ++++++ .../15-3-composite-data-structures.mdx | 257 ++++++++++ .../15-4-exercises.md | 21 + .../15-advanced-data-structures/15.1.png | Bin 0 -> 29206 bytes .../_category_.json | 8 + .../2-1-algorithm-explanation.md | 21 + .../2-two-pointer-techniques/2-2-two-sum.mdx | 73 +++ .../2-3-merge-sorted-arrays.mdx | 68 +++ .../2-4-sliding-window.mdx | 110 ++++ .../2-5-fast-slow-pointers.mdx | 98 ++++ .../2-two-pointer-techniques/2-6-exercises.md | 25 + .../2-two-pointer-techniques/_category_.json | 8 + .../3-1-algorithm-explanation.md | 15 + .../3-2-square-root.mdx | 103 ++++ .../3-3-interval-search.mdx | 109 ++++ .../3-4-peak-finding.mdx | 87 ++++ .../3-5-rotated-array-search.mdx | 99 ++++ .../3-6-exercises.md | 21 + .../_category_.json | 8 + .../4-1-common-sorting-algorithms.mdx | 148 ++++++ .../4-sorting-algorithms/4-2-quick-select.mdx | 78 +++ .../4-sorting-algorithms/4-3-bucket-sort.mdx | 83 ++++ .../4-sorting-algorithms/4-4-exercises.md | 17 + .../4-sorting-algorithms/_category_.json | 8 + .../5-1-algorithm-explanation.md | 7 + .../5-2-depth-first-search.mdx | 375 ++++++++++++++ .../5-3-backtracking.mdx | 379 ++++++++++++++ .../5-4-breadth-first-search.mdx | 454 +++++++++++++++++ .../5-searching-algorithms/5-5-exercises.md | 33 ++ .../5-searching-algorithms/_category_.json | 8 + .../5-searching-algorithms/n-queens.png | Bin 0 -> 20347 bytes .../6-1-algorithm-explanation.md | 13 + .../6-dynamic-programming/6-2-basic-dp-1d.mdx | 236 +++++++++ .../6-dynamic-programming/6-3-basic-dp-2d.mdx | 307 ++++++++++++ .../6-4-partition-problems.mdx | 347 +++++++++++++ .../6-5-subsequence-problems.mdx | 189 +++++++ .../6-6-knapsack-problem.mdx | 421 ++++++++++++++++ .../6-7-string-editing.mdx | 132 +++++ .../6-8-stock-trading.mdx | 183 +++++++ .../6-dynamic-programming/6-9-exercises.md | 45 ++ .../current/6-dynamic-programming/6.1.png | Bin 0 -> 34632 bytes .../current/6-dynamic-programming/6.3.png | Bin 0 -> 24349 bytes .../current/6-dynamic-programming/6.4.png | Bin 0 -> 38325 bytes .../current/6-dynamic-programming/6.5.png | Bin 0 -> 49000 bytes .../6-dynamic-programming/_category_.json | 8 + .../7-1-algorithm-explanation.md | 22 + .../7-2-expression-problems.mdx | 154 ++++++ .../7-divide-and-conquer/7-3-exercises.md | 17 + .../7-divide-and-conquer/_category_.json | 8 + .../8-1-introduction.md | 7 + .../8-mathematical-solutions/8-2-lcm-gcd.mdx | 72 +++ .../8-3-prime-numbers.mdx | 138 ++++++ .../8-4-number-processing.mdx | 318 ++++++++++++ .../8-5-random-sampling.mdx | 228 +++++++++ .../8-mathematical-solutions/8-6-exercises.md | 37 ++ .../8-mathematical-solutions/_category_.json | 8 + .../9-1-common-techniques.md | 24 + .../9-2-basic-bitwise-problems.mdx | 181 +++++++ .../9-3-binary-properties.mdx | 123 +++++ .../9-bitwise-operations/9-4-exercises.md | 25 + .../9-bitwise-operations/_category_.json | 8 + .../current/index.md | 7 - .../en/docusaurus-theme-classic/footer.json | 36 -- leetcode_101/i18n/zh-TW/code.json | 16 +- .../current.json | 128 ++++- .../1-1-algorithm-explanation.md | 11 + .../1-2-assignment-problems.mdx | 143 ++++++ .../1-3-interval-problems.mdx | 75 +++ .../1-greedy-algorithms/1-4-exercises.md | 40 ++ .../1-greedy-algorithms/_category_.json | 2 +- .../current/1-greedy-algorithms/greddy.md | 7 - .../10-data-structures/10-1-cpp-stl.md | 30 ++ .../10-10-prefix-sum-integral-image.mdx | 226 +++++++++ .../10-data-structures/10-11-exercises.md | 53 ++ .../10-2-python-data-structures.md | 22 + .../10-data-structures/10-3-arrays.mdx | 250 ++++++++++ .../10-4-stack-and-queue.mdx | 257 ++++++++++ .../10-5-monotonic-stack.mdx | 72 +++ .../10-6-priority-queue.mdx | 295 +++++++++++ .../current/10-data-structures/10-7-deque.mdx | 82 +++ .../10-data-structures/10-8-hash-table.mdx | 232 +++++++++ .../10-9-multisets-and-maps.mdx | 87 ++++ .../current/10-data-structures/10.1.png | Bin 0 -> 37020 bytes .../current/10-data-structures/10.2.png | Bin 0 -> 109141 bytes .../current/10-data-structures/10.3.png | Bin 0 -> 72740 bytes .../current/10-data-structures/10.4.png | Bin 0 -> 39987 bytes .../current/10-data-structures/10.5.png | Bin 0 -> 42518 bytes .../10-data-structures/_category_.json | 8 + .../11-1-introduction.md | 7 + .../11-2-string-comparison.mdx | 339 +++++++++++++ .../11-3-string-interpretation.mdx | 129 +++++ .../11-4-string-matching.mdx | 106 ++++ .../11-string-manipulation/11-5-exercises.md | 26 + .../11-string-manipulation/_category_.json | 8 + .../12-1-data-structure-introduction.md | 40 ++ .../12-2-basic-linked-list-operations.mdx | 270 ++++++++++ .../12-3-other-linked-list-techniques.mdx | 140 ++++++ .../current/12-linked-lists/12-4-exercises.md | 25 + .../current/12-linked-lists/_category_.json | 8 + .../13-1-data-structure-introduction.mdx | 37 ++ .../current/13-trees/13-2-tree-recursion.mdx | 469 ++++++++++++++++++ .../13-trees/13-3-level-order-traversal.mdx | 92 ++++ ...4-preorder-inorder-postorder-traversal.mdx | 250 ++++++++++ .../13-trees/13-5-binary-search-tree.mdx | 185 +++++++ .../current/13-trees/13-6-trie.mdx | 137 +++++ .../current/13-trees/13-7-exercises.md | 81 +++ .../current/13-trees/13.1.png | Bin 0 -> 49070 bytes .../current/13-trees/_category_.json | 8 + .../14-1-data-structure-introduction.mdx | 16 + .../14-graphs/14-2-bipartite-graph.mdx | 90 ++++ .../14-graphs/14-3-topological-sorting.mdx | 97 ++++ .../current/14-graphs/14-4-exercises.md | 21 + .../current/14-graphs/14.1.png | Bin 0 -> 103164 bytes .../current/14-graphs/_category_.json | 8 + .../15-1-introduction.md | 7 + .../15-2-union-find.mdx | 140 ++++++ .../15-3-composite-data-structures.mdx | 257 ++++++++++ .../15-4-exercises.md | 21 + .../15-advanced-data-structures/15.1.png | Bin 0 -> 29206 bytes .../_category_.json | 8 + .../2-1-algorithm-explanation.md | 21 + .../2-two-pointer-techniques/2-2-two-sum.mdx | 72 +++ .../2-3-merge-sorted-arrays.mdx | 68 +++ .../2-4-sliding-window.mdx | 108 ++++ .../2-5-fast-slow-pointers.mdx | 98 ++++ .../2-two-pointer-techniques/2-6-exercises.md | 25 + .../2-two-pointer-techniques/_category_.json | 8 + .../3-1-algorithm-explanation.md | 15 + .../3-2-square-root.mdx | 103 ++++ .../3-3-interval-search.mdx | 109 ++++ .../3-4-peak-finding.mdx | 86 ++++ .../3-5-rotated-array-search.mdx | 98 ++++ .../3-6-exercises.md | 21 + .../_category_.json | 8 + .../4-1-common-sorting-algorithms.mdx | 150 ++++++ .../4-sorting-algorithms/4-2-quick-select.mdx | 78 +++ .../4-sorting-algorithms/4-3-bucket-sort.mdx | 83 ++++ .../4-sorting-algorithms/4-4-exercises.md | 17 + .../4-sorting-algorithms/_category_.json | 8 + .../5-1-algorithm-explanation.md | 7 + .../5-2-depth-first-search.mdx | 375 ++++++++++++++ .../5-3-backtracking.mdx | 378 ++++++++++++++ .../5-4-breadth-first-search.mdx | 456 +++++++++++++++++ .../5-searching-algorithms/5-5-exercises.md | 33 ++ .../5-searching-algorithms/_category_.json | 8 + .../5-searching-algorithms/n-queens.png | Bin 0 -> 20347 bytes .../6-1-algorithm-explanation.md | 13 + .../6-dynamic-programming/6-2-basic-dp-1d.mdx | 236 +++++++++ .../6-dynamic-programming/6-3-basic-dp-2d.mdx | 307 ++++++++++++ .../6-4-partition-problems.mdx | 347 +++++++++++++ .../6-5-subsequence-problems.mdx | 189 +++++++ .../6-6-knapsack-problem.mdx | 421 ++++++++++++++++ .../6-7-string-editing.mdx | 132 +++++ .../6-8-stock-trading.mdx | 183 +++++++ .../6-dynamic-programming/6-9-exercises.md | 45 ++ .../current/6-dynamic-programming/6.1.png | Bin 0 -> 34632 bytes .../current/6-dynamic-programming/6.3.png | Bin 0 -> 24349 bytes .../current/6-dynamic-programming/6.4.png | Bin 0 -> 38325 bytes .../current/6-dynamic-programming/6.5.png | Bin 0 -> 49000 bytes .../6-dynamic-programming/_category_.json | 8 + .../7-1-algorithm-explanation.md | 22 + .../7-2-expression-problems.mdx | 154 ++++++ .../7-divide-and-conquer/7-3-exercises.md | 17 + .../7-divide-and-conquer/_category_.json | 8 + .../8-1-introduction.md | 7 + .../8-mathematical-solutions/8-2-lcm-gcd.mdx | 72 +++ .../8-3-prime-numbers.mdx | 138 ++++++ .../8-4-number-processing.mdx | 318 ++++++++++++ .../8-5-random-sampling.mdx | 228 +++++++++ .../8-mathematical-solutions/8-6-exercises.md | 37 ++ .../8-mathematical-solutions/_category_.json | 8 + .../9-1-common-techniques.md | 24 + .../9-2-basic-bitwise-problems.mdx | 181 +++++++ .../9-3-binary-properties.mdx | 123 +++++ .../9-bitwise-operations/9-4-exercises.md | 25 + .../9-bitwise-operations/_category_.json | 8 + .../current/index.md | 7 - .../docusaurus-theme-classic/footer.json | 36 -- 233 files changed, 21415 insertions(+), 151 deletions(-) create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-1-algorithm-explanation.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-2-assignment-problems.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-3-interval-problems.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-4-exercises.md delete mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/greddy.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-1-cpp-stl.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-10-prefix-sum-integral-image.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-11-exercises.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-2-python-data-structures.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-3-arrays.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-4-stack-and-queue.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-5-monotonic-stack.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-6-priority-queue.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-7-deque.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-8-hash-table.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-9-multisets-and-maps.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10.1.png create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10.2.png create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10.3.png create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10.4.png create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10.5.png create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/_category_.json create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-1-introduction.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-2-string-comparison.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-3-string-interpretation.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-4-string-matching.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-5-exercises.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/_category_.json create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-1-data-structure-introduction.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-2-basic-linked-list-operations.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-3-other-linked-list-techniques.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-4-exercises.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/_category_.json create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-1-data-structure-introduction.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-2-tree-recursion.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-3-level-order-traversal.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-4-preorder-inorder-postorder-traversal.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-5-binary-search-tree.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-6-trie.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-7-exercises.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13.1.png create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/_category_.json create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-1-data-structure-introduction.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-2-bipartite-graph.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-3-topological-sorting.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-4-exercises.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14.1.png create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/_category_.json create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-1-introduction.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-2-union-find.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-3-composite-data-structures.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-4-exercises.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15.1.png create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/_category_.json create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-1-algorithm-explanation.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-2-two-sum.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-3-merge-sorted-arrays.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-4-sliding-window.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-5-fast-slow-pointers.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-6-exercises.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/_category_.json create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-1-algorithm-explanation.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-2-square-root.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-3-interval-search.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-4-peak-finding.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-5-rotated-array-search.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-6-exercises.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/_category_.json create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-1-common-sorting-algorithms.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-2-quick-select.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-3-bucket-sort.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-4-exercises.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/4-sorting-algorithms/_category_.json create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-1-algorithm-explanation.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-2-depth-first-search.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-3-backtracking.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-4-breadth-first-search.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-5-exercises.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/_category_.json create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/n-queens.png create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-1-algorithm-explanation.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-2-basic-dp-1d.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-3-basic-dp-2d.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-4-partition-problems.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-5-subsequence-problems.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-6-knapsack-problem.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-7-string-editing.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-8-stock-trading.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-9-exercises.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6.1.png create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6.3.png create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6.4.png create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6.5.png create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/_category_.json create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-1-algorithm-explanation.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-2-expression-problems.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-3-exercises.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/_category_.json create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-1-introduction.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-2-lcm-gcd.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-3-prime-numbers.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-4-number-processing.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-5-random-sampling.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-6-exercises.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/_category_.json create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-1-common-techniques.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-2-basic-bitwise-problems.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-3-binary-properties.mdx create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-4-exercises.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/_category_.json delete mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/index.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-1-algorithm-explanation.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-2-assignment-problems.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-3-interval-problems.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-4-exercises.md delete mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/greddy.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-1-cpp-stl.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-10-prefix-sum-integral-image.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-11-exercises.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-2-python-data-structures.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-3-arrays.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-4-stack-and-queue.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-5-monotonic-stack.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-6-priority-queue.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-7-deque.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-8-hash-table.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-9-multisets-and-maps.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10.1.png create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10.2.png create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10.3.png create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10.4.png create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10.5.png create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/_category_.json create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-1-introduction.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-2-string-comparison.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-3-string-interpretation.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-4-string-matching.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-5-exercises.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/_category_.json create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-1-data-structure-introduction.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-2-basic-linked-list-operations.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-3-other-linked-list-techniques.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-4-exercises.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/_category_.json create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-1-data-structure-introduction.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-2-tree-recursion.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-3-level-order-traversal.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-4-preorder-inorder-postorder-traversal.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-5-binary-search-tree.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-6-trie.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-7-exercises.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13.1.png create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/_category_.json create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-1-data-structure-introduction.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-2-bipartite-graph.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-3-topological-sorting.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-4-exercises.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14.1.png create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/_category_.json create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-1-introduction.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-2-union-find.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-3-composite-data-structures.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-4-exercises.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15.1.png create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/_category_.json create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-1-algorithm-explanation.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-2-two-sum.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-3-merge-sorted-arrays.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-4-sliding-window.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-5-fast-slow-pointers.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-6-exercises.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/_category_.json create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-1-algorithm-explanation.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-2-square-root.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-3-interval-search.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-4-peak-finding.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-5-rotated-array-search.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-6-exercises.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/_category_.json create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-1-common-sorting-algorithms.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-2-quick-select.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-3-bucket-sort.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-4-exercises.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/_category_.json create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-1-algorithm-explanation.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-2-depth-first-search.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-3-backtracking.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-4-breadth-first-search.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-5-exercises.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/_category_.json create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/n-queens.png create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-1-algorithm-explanation.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-2-basic-dp-1d.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-3-basic-dp-2d.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-4-partition-problems.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-5-subsequence-problems.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-6-knapsack-problem.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-7-string-editing.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-8-stock-trading.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-9-exercises.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6.1.png create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6.3.png create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6.4.png create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6.5.png create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/_category_.json create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-1-algorithm-explanation.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-2-expression-problems.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-3-exercises.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/_category_.json create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-1-introduction.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-2-lcm-gcd.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-3-prime-numbers.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-4-number-processing.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-5-random-sampling.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-6-exercises.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/_category_.json create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-1-common-techniques.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-2-basic-bitwise-problems.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-3-binary-properties.mdx create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-4-exercises.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/_category_.json delete mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/index.md diff --git a/leetcode_101/docs/1-greedy-algorithms/1-1-algorithm-explanation.md b/leetcode_101/docs/1-greedy-algorithms/1-1-algorithm-explanation.md index f524ffd0..bb5e2321 100644 --- a/leetcode_101/docs/1-greedy-algorithms/1-1-algorithm-explanation.md +++ b/leetcode_101/docs/1-greedy-algorithms/1-1-algorithm-explanation.md @@ -6,7 +6,6 @@ sidebar_position: 1 顾名思义,`贪心算法或贪心思想` (greedy algorithm) 采用贪心的策略,`保证每次操作都是局部最优的`,从而使最后得到的结果是`全局最优的`。 -举一个最简单的例子:小明和小王喜欢吃苹果,小明可以吃五个,小王可以吃三个。已知苹果园里有吃不完的苹果,求小明和小王一共最多吃多少个苹果。在这个例子中,我们可以选用的贪心策略为,每个人吃自己能吃的最多数量的苹果,这在每个人身上都是局部最优的。又因为全 -局结果是局部结果的简单求和,且局部结果互不相干,因此局部最优的策略同样是全局最优的。 +举一个最简单的例子:小明和小王喜欢吃苹果,小明可以吃五个,小王可以吃三个。已知苹果园里有吃不完的苹果,求小明和小王一共最多吃多少个苹果。在这个例子中,我们可以选用的贪心策略为,每个人吃自己能吃的最多数量的苹果,这在每个人身上都是局部最优的。又因为全局结果是局部结果的简单求和,且局部结果互不相干,因此局部最优的策略同样是全局最优的。 证明一道题能用贪心算法解决,有时远比用贪心算法解决该题更复杂。一般情况下,在简单操作后,具有明显的从局部到整体的递推关系,或者可以通过数学归纳法推测结果时,我们才会使用贪心算法。 diff --git a/leetcode_101/docs/2-two-pointer-techniques/2-3-merge-sorted-arrays.mdx b/leetcode_101/docs/2-two-pointer-techniques/2-3-merge-sorted-arrays.mdx index aee9087d..29969e7f 100644 --- a/leetcode_101/docs/2-two-pointer-techniques/2-3-merge-sorted-arrays.mdx +++ b/leetcode_101/docs/2-two-pointer-techniques/2-3-merge-sorted-arrays.mdx @@ -12,16 +12,13 @@ sidebar_position: 7 ### 输入输出样例 -输入是两个数组和它们分别的长度 m 和 n。其中第一个数组的长度被延长至 m +n,多出的 -n 位被 0 填补。题目要求把第二个数组归并到第一个数组上,不需要开辟额外空间。 +输入是两个数组和它们分别的长度 m 和 n。其中第一个数组的长度被延长至 m +n,多出的 n 位被 0 填补。题目要求把第二个数组归并到第一个数组上,不需要开辟额外空间。 ``` Input: nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3 Output: nums1 = [1,2,2,3,5,6] ``` - - ### 题解 因为这两个数组已经排好序,我们可以把两个指针分别放在两个数组的末尾,即 nums1 的 m − 1 位和 nums2 的 n − 1 位。每次将较大的那个数字复制到 nums1 的后边,然后向前移动一位。 diff --git a/leetcode_101/docs/2-two-pointer-techniques/2-4-sliding-window.mdx b/leetcode_101/docs/2-two-pointer-techniques/2-4-sliding-window.mdx index a7923d02..c9d26f59 100644 --- a/leetcode_101/docs/2-two-pointer-techniques/2-4-sliding-window.mdx +++ b/leetcode_101/docs/2-two-pointer-techniques/2-4-sliding-window.mdx @@ -8,7 +8,7 @@ sidebar_position: 8 ### 题目描述 -给定两个字符串 s 和 t,求 s 中包含 t 所有字符的最短连续子字符串的长度,同时要求时间复杂度不得超过 O(n)。 +给定两个字符串 s 和 t,求 s 中包含 t 所有字符的最短连续子字符串的长度,同时要求时间复杂度不得超过 $O(n)$。 ### 输入输出样例 @@ -26,7 +26,7 @@ Output: "BANC" 本题使用滑动窗口求解,即两个指针 l 和 r 都是从最左端向最右端移动,且 l 的位置一定在 r 的左边或重合。C++ 题解中使用了两个长度为 128 的数组,valid 和 freq,来映射字符(ASCII 只包含 128 个字符)。其中 valid 表示每个字符在 t 中是否存在,而 freq 表示目前 t 中每个字符在 s 的滑动窗口中缺少的数量:如果为正,则说明还缺少;如果为负,则说明有盈余。Python 题解 则直接使用 Counter 数据结构同时统计 t 中存在的字符和其缺少的数量(也可以用 dict 替代)。注意本题虽然在 for 循环里出现了一个 while 循环,但是因为 while 循环负责移动 l 指针,且 l 只会 -从左到右移动一次,因此总时间复杂度仍然是 O(n)。 +从左到右移动一次,因此总时间复杂度仍然是 $O(n)$。 diff --git a/leetcode_101/docs/4-sorting-algorithms/4-2-quick-select.mdx b/leetcode_101/docs/4-sorting-algorithms/4-2-quick-select.mdx index 01ab69ce..f6927984 100644 --- a/leetcode_101/docs/4-sorting-algorithms/4-2-quick-select.mdx +++ b/leetcode_101/docs/4-sorting-algorithms/4-2-quick-select.mdx @@ -23,8 +23,7 @@ Output: 5 ### 题解 -`快速选择`一般用于求解 k-th Element 问题,可以在平均 $O(n)$ 时间复杂度,$O(1)$ 空间复杂度完成求解工作。快速选择的实现和快速排序相似,不过只需要找到第 $k$ 大的枢(pivot)即可,不需 -要对其左右再进行排序。与快速排序一样,快速选择一般需要先打乱数组,否则最坏情况下时间复杂度为 $O(n^2)$。 +`快速选择`一般用于求解 k-th Element 问题,可以在平均 $O(n)$ 时间复杂度,$O(1)$ 空间复杂度完成求解工作。快速选择的实现和快速排序相似,不过只需要找到第 $k$ 大的枢(pivot)即可,不需要对其左右再进行排序。与快速排序一样,快速选择一般需要先打乱数组,否则最坏情况下时间复杂度为 $O(n^2)$。 这道题如果直接用上面的快速排序原代码运行,会导致在 LeetCode 上接近超时。我们可以用空间换取时间,直接存储比中枢点小和大的值,尽量避免进行交换位置的操作。 diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current.json index a20ddb42..e518f75d 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current.json +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current.json @@ -4,31 +4,123 @@ "description": "The label for version current" }, "sidebar.tutorialSidebar.category.1. 最易懂的贪心算法": { - "message": "1. greedy", + "message": "1. The Easiest Greedy Algorithm", "description": "The label for category 1. 最易懂的贪心算法 in sidebar tutorialSidebar" }, "sidebar.tutorialSidebar.category.1. 最易懂的贪心算法.link.generated-index.description": { - "message": "5 minutes to learn the most important Docusaurus concepts.", + "message": "Chapter 1: The Easiest Greedy Algorithm", "description": "The generated-index page description for category 1. 最易懂的贪心算法 in sidebar tutorialSidebar" }, "sidebar.tutorialSidebar.category.2. 玩转双指针": { - "message": "2. 玩转双指针", + "message": "2. Mastering Two Pointers", "description": "The label for category 2. 玩转双指针 in sidebar tutorialSidebar" }, "sidebar.tutorialSidebar.category.2. 玩转双指针.link.generated-index.description": { - "message": "5 minutes to learn the most important Docusaurus concepts.", + "message": "Chapter 2: Mastering Two Pointers", "description": "The generated-index page description for category 2. 玩转双指针 in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.Tutorial - Basics": { - "message": "Tutorial - Basics", - "description": "The label for category Tutorial - Basics in sidebar tutorialSidebar" + "sidebar.tutorialSidebar.category.3. 居合斩!二分查找": { + "message": "3. Iaido! Binary Search", + "description": "The label for category 3. 居合斩!二分查找 in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.Tutorial - Basics.link.generated-index.description": { - "message": "5 minutes to learn the most important Docusaurus concepts.", - "description": "The generated-index page description for category Tutorial - Basics in sidebar tutorialSidebar" + "sidebar.tutorialSidebar.category.3. 居合斩!二分查找.link.generated-index.description": { + "message": "Chapter 3: Iaido! Binary Search", + "description": "The generated-index page description for category 3. 居合斩!二分查找 in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.Tutorial - Extras": { - "message": "Tutorial - Extras", - "description": "The label for category Tutorial - Extras in sidebar tutorialSidebar" + "sidebar.tutorialSidebar.category.4. 千奇百怪的排序算法": { + "message": "4. Peculiar Sorting Algorithms", + "description": "The label for category 4. 千奇百怪的排序算法 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.4. 千奇百怪的排序算法.link.generated-index.description": { + "message": "Chapter 4: Peculiar Sorting Algorithms", + "description": "The generated-index page description for category 4. 千奇百怪的排序算法 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.5. 一切皆可搜索": { + "message": "5. Everything is Searchable", + "description": "The label for category 5. 一切皆可搜索 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.5. 一切皆可搜索.link.generated-index.description": { + "message": "Chapter 5: Everything is Searchable", + "description": "The generated-index page description for category 5. 一切皆可搜索 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.6. 深入浅出动态规划": { + "message": "6. Dynamic Programming Made Simple", + "description": "The label for category 6. 深入浅出动态规划 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.6. 深入浅出动态规划.link.generated-index.description": { + "message": "Chapter 6: Dynamic Programming Made Simple", + "description": "The generated-index page description for category 6. 深入浅出动态规划 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.7. 化繁为简的分治法": { + "message": "7. Simplifying with Divide and Conquer", + "description": "The label for category 7. 化繁为简的分治法 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.7. 化繁为简的分治法.link.generated-index.description": { + "message": "Chapter 7: Simplifying with Divide and Conquer", + "description": "The generated-index page description for category 7. 化繁为简的分治法 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.8. 巧解数学问题 ": { + "message": "8. Clever Math Problem Solving", + "description": "The label for category 8. 巧解数学问题 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.8. 巧解数学问题 .link.generated-index.description": { + "message": "Chapter 8: Clever Math Problem Solving", + "description": "The generated-index page description for category 8. 巧解数学问题 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.9. 神奇的位运算 ": { + "message": "9. Magical Bit Manipulation", + "description": "The label for category 9. 神奇的位运算 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.9. 神奇的位运算 .link.generated-index.description": { + "message": "Chapter 9: Magical Bit Manipulation", + "description": "The generated-index page description for category 9. 神奇的位运算 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.10. 妙用数据结构 ": { + "message": "10. Ingenious Use of Data Structures", + "description": "The label for category 10. 妙用数据结构 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.10. 妙用数据结构 .link.generated-index.description": { + "message": "Chapter 10: Ingenious Use of Data Structures", + "description": "The generated-index page description for category 10. 妙用数据结构 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.11. 令人头大的字符串 ": { + "message": "11. Tricky String Problems", + "description": "The label for category 11. 令人头大的字符串 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.11. 令人头大的字符串 .link.generated-index.description": { + "message": "Chapter 11: Tricky String Problems", + "description": "The generated-index page description for category 11. 令人头大的字符串 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.12. 指针三剑客之一:链表": { + "message": "12. The Three Musketeers of Pointers: Linked Lists", + "description": "The label for category 12. 指针三剑客之一:链表 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.12. 指针三剑客之一:链表.link.generated-index.description": { + "message": "Chapter 12: The Three Musketeers of Pointers: Linked Lists", + "description": "The generated-index page description for category 12. 指针三剑客之一:链表 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.13. 指针三剑客之二:树": { + "message": "13. The Three Musketeers of Pointers: Trees", + "description": "The label for category 13. 指针三剑客之二:树 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.13. 指针三剑客之二:树.link.generated-index.description": { + "message": "Chapter 13: The Three Musketeers of Pointers: Trees", + "description": "The generated-index page description for category 13. 指针三剑客之二:树 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.14. 指针三剑客之三:图": { + "message": "14. The Three Musketeers of Pointers: Graphs", + "description": "The label for category 14. 指针三剑客之三:图 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.14. 指针三剑客之三:图.link.generated-index.description": { + "message": "Chapter 14: The Three Musketeers of Pointers: Graphs", + "description": "The generated-index page description for category 14. 指针三剑客之三:图 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.15. 更加复杂的数据结构 ": { + "message": "15. More Complex Data Structures", + "description": "The label for category 15. 更加复杂的数据结构 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.15. 更加复杂的数据结构 .link.generated-index.description": { + "message": "Chapter 15: More Complex Data Structures", + "description": "The generated-index page description for category 15. 更加复杂的数据结构 in sidebar tutorialSidebar" } } diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-1-algorithm-explanation.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-1-algorithm-explanation.md new file mode 100644 index 00000000..fdd5acb0 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-1-algorithm-explanation.md @@ -0,0 +1,11 @@ +--- +sidebar_position: 1 +--- + +# 1.1 Algorithm Explanation + +As the name implies, a `greedy algorithm or greedy strategy` adopts a greedy approach, `ensuring that each step is locally optimal`, thereby resulting in a `globally optimal` solution. + +Let’s take the simplest example: Xiaoming and Xiaowang love apples. Xiaoming can eat five, and Xiaowang can eat three. Given that the orchard has an unlimited supply of apples, calculate the maximum number of apples Xiaoming and Xiaowang can eat together. In this example, the greedy strategy is for each person to eat the maximum number of apples they can. This strategy is locally optimal for each person. Since the global result is the simple sum of local results, and the local results are independent of each other, the locally optimal strategy is also globally optimal. + +Proving that a problem can be solved using a greedy algorithm is sometimes far more complex than actually solving it with the greedy algorithm. Generally, we use greedy algorithms when, after simple operations, there is a clear recursive relationship from local to global, or when the result can be deduced using mathematical induction. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-2-assignment-problems.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-2-assignment-problems.mdx new file mode 100644 index 00000000..69f20bcf --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-2-assignment-problems.mdx @@ -0,0 +1,146 @@ +--- +sidebar_position: 2 +--- + +# 1.2 Distribution Problem + +## [455. Assign Cookies](https://leetcode.com/problems/assign-cookies/) + +### Problem Description + +There is a group of children and a pile of cookies. Each child has a hunger level, and each cookie has a fullness level. Each child can only eat one cookie, and only if the cookie's fullness level is greater than or equal to the child's hunger level can the child be satisfied. Find the maximum number of children that can be satisfied. + + +### Input and Output Example + +Input two arrays representing the hunger levels of the children and the fullness levels of the cookies. Output the maximum number of children that can be satisfied. + + +``` +Input: [1,2], [1,2,3] +Output: 2 +``` + +In this example, we can feed the two children with any of the combinations [1,2], [1,3], or [2,3]. + + +### Solution Explanation + +Since the child with the lowest hunger level is the easiest to satisfy, we start with this child. To make sure the remaining cookies can satisfy children with higher hunger levels, we should give this child the smallest cookie that meets or exceeds their hunger level. After satisfying this child, we repeat the strategy for the next hungriest child until there are no suitable cookies left. + +In short, the greedy strategy here is to allocate the smallest sufficient cookie to the child with the smallest hunger level among the remaining children. For implementation, since we need to compare sizes, a convenient method is to sort the children and cookies separately. This way, we can start from the child with the smallest hunger and the cookie with the smallest fullness, counting how many pairs meet the requirements. + +:::warning + +Sorting arrays or strings is a common operation to facilitate subsequent size comparisons. The default sorting order is ascending. + +::: + +:::warning + +In later explanations, when we discuss operations on variables in continuous spaces, we will not explicitly distinguish between arrays and strings, as they are essentially ordered sets of variables in continuous space. A string "abc" can be viewed as an array ['a', 'b', 'c']. + +::: + + + + +```cpp +int findContentChildren(vector &children, vector &cookies) { + sort(children.begin(), children.end()); + sort(cookies.begin(), cookies.end()); + int child_i = 0, cookie_i = 0; + int n_children = children.size(), n_cookies = cookies.size(); + while (child_i < n_children && cookie_i < n_cookies) { + if (children[child_i] <= cookies[cookie_i]) { + ++child_i; + } + ++cookie_i; + } + return child_i; +} +``` + + + + +```py +def findContentChildren(children: List[int], cookies: List[int]) -> int: + children.sort() + cookies.sort() + child_i, cookie_i = 0, 0 + n_children, n_cookies = len(children), len(cookies) + while child_i < n_children and cookie_i < n_cookies: + if children[child_i] <= cookies[cookie_i]: + child_i += 1 + cookie_i += 1 + return child_i +``` + + + + + +## [135. Candy](https://leetcode.com/problems/candy/) + +### Problem Description + +A group of children is standing in a row, and each child has a rating. We need to distribute candies to these children, with the rule that if a child has a higher rating than their neighbor, they must receive more candies than that neighbor. Every child must receive at least one candy. Find the minimum number of candies needed. + +### Input and Output Example + +The input is an array representing the ratings of the children. The output is the minimum number of candies required. + +``` +Input: [1,0,2] +Output: 5 +``` +In this example, the minimum distribution of candies is [2,1,2]. + + +### Solution Explanation + +A greedy strategy involving comparative relationships does not always require sorting. Although this problem also uses a greedy strategy, we only need two simple traversals: initialize each child’s candy count to 1; first traverse from left to right, and if a child’s rating is higher than the left neighbor, update the child’s candy count to be one more than the neighbor’s; then traverse from right to left, and if a child’s rating is higher than the right neighbor’s, and the current candy count is not greater than the neighbor’s, update the candy count to be one more than the neighbor’s. With these two passes, the candy distribution will meet the requirements. The greedy strategy here is to consider and update only the relationship with the adjacent side in each pass. + +In the example, we initialize the candy distribution as [1,1,1]. After the first traversal, the result is [1,1,2]. After the second traversal, the result is [2,1,2]. + + + + +```cpp +int candy(vector& ratings) { + int n = ratings.size(); + vector candies(n, 1); + for (int i = 1; i < n; ++i) { + if (ratings[i] > ratings[i - 1]) { + candies[i] = candies[i - 1] + 1; + } + } + for (int i = n - 1; i > 0; --i) { + if (ratings[i] < ratings[i - 1]) { + candies[i - 1] = max(candies[i - 1], candies[i] + 1); + } + } + return accumulate(candies.begin(), candies.end(), 0); +} +``` + + + + +```py +def candy(ratings_list: List[int]) -> int: + n = len(ratings_list) + candies = [1] * n + for i in range(1, n): + if ratings_list[i] > ratings_list[i - 1]: + candies[i] = candies[i - 1] + 1 + for i in range(n - 1, 0, -1): + if ratings_list[i] < ratings_list[i - 1]: + candies[i - 1] = max(candies[i - 1], candies[i] + 1) + return sum(candies) +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-3-interval-problems.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-3-interval-problems.mdx new file mode 100644 index 00000000..db7b0b05 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-3-interval-problems.mdx @@ -0,0 +1,75 @@ +--- +sidebar_position: 3 +--- + +# 1.3 Interval Problem + +## [435. Non-overlapping Intervals](https://leetcode.com/problems/non-overlapping-intervals/) + +### Problem Description + +Given multiple intervals, calculate the minimum number of intervals that need to be removed to make the remaining intervals non-overlapping. Adjacent intervals that meet at endpoints are not considered overlapping. + + +### Input and Output Example + +The input is an array containing multiple subarrays, each with a fixed length of 2, representing the start and end of each interval. The output is an integer indicating the number of intervals that need to be removed. + +``` +Input: [[1,2], [2,4], [1,3]] +Output: 1 +``` +In this example, we can remove the interval [1,3] so that the remaining intervals [[1,2], [2,4]] are non-overlapping. + + +### Solution Explanation + +Finding the minimum number of intervals to remove is equivalent to maximizing the number of non-overlapping intervals we can retain. When selecting intervals to keep, the end point of each interval is critical: the smaller the chosen interval’s end, the more space is left for other intervals, allowing more intervals to be retained. Thus, the greedy strategy we use is to prioritize retaining intervals with smaller end points that do not overlap. + +The specific implementation involves first sorting the intervals in ascending order by their end points (using a lambda function) and then selecting the interval with the smallest end point that does not overlap with the previously chosen interval. + +In the example, the sorted array is [[1,2], [1,3], [2,4]]. According to our greedy strategy, we initialize with the interval [1,2]; since [1,3] overlaps with [1,2], we skip this interval; since [2,4] does not overlap with [1,2], we keep it. Therefore, the final retained intervals are [[1,2], [2,4]]. + +:::warning + +It is necessary to determine whether to sort by the start or end of the intervals based on the specific requirements. + +::: + + + + +```cpp +int eraseOverlapIntervals(vector>& intervals) { + sort(intervals.begin(), intervals.end(), + [](vector& a, vector& b) { return a[1] < b[1]; }); + int removed = 0, prev_end = intervals[0][1]; + for (int i = 1; i < intervals.size(); ++i) { + if (intervals[i][0] < prev_end) { + ++removed; + } else { + prev_end = intervals[i][1]; + } + } + return removed; +} +``` + + + + +```py +def eraseOverlapIntervals(intervals: List[List[int]]) -> int: + intervals.sort(key=lambda x: x[1]) + removed, prev_end = 0, intervals[0][1] + for i in range(1, len(intervals)): + if prev_end > intervals[i][0]: + removed += 1 + else: + prev_end = intervals[i][1] + return removed +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-4-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-4-exercises.md new file mode 100644 index 00000000..8b0c7be3 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-4-exercises.md @@ -0,0 +1,42 @@ +--- +sidebar_position: 4 +--- + +# 1.4 Exercises + +## Basic Difficulty + +### [605. Can Place Flowers](https://leetcode.com/problems/can-place-flowers/) + +What kind of greedy strategy can be used to plant the maximum number of flowers? + +### [452. Minimum Number of Arrows to Burst Balloons](https://leetcode.com/problems/minimum-number-of-arrows-to-burst-balloons/) + +This problem is very similar to problem 435, but what is the subtle difference? + +### [763. Partition Labels](https://leetcode.com/problems/partition-labels/) + +To satisfy your greedy strategy, do you need some preprocessing? + +:::warning + +Counting information (such as frequency, count, first appearance position, last appearance position, etc.) before processing the array can significantly reduce the difficulty of the problem. + + +::: + +### [122. Best Time to Buy and Sell Stock II](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/) + +Among stock trading problems, this is a relatively simple one. Without restricting the number of transactions, how can you achieve the maximum profit? + + +## Advanced Difficulty + +### [406. Queue Reconstruction by Height](https://leetcode.com/problems/queue-reconstruction-by-height/) + +Friendly reminder, this problem may require both sorting and insertion operations. + + +### [665. Non-decreasing Array](https://leetcode.com/problems/non-decreasing-array/) + +Carefully consider whether your greedy strategy remains optimal in all scenarios. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/_category_.json index e91e9e1e..4119cb25 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/_category_.json +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/_category_.json @@ -3,6 +3,6 @@ "position": 1, "link": { "type": "generated-index", - "description": "5 minutes to learn the most important Docusaurus concepts." + "description": "第 1 章 最易懂的贪心算法" } } diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/greddy.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/greddy.md deleted file mode 100644 index 7544d612..00000000 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/greddy.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 6 ---- - -# 贪心! - -english greddy diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-1-cpp-stl.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-1-cpp-stl.md new file mode 100644 index 00000000..2ec42832 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-1-cpp-stl.md @@ -0,0 +1,30 @@ +--- +sidebar_position: 48 +--- + +# 10.1 C++ STL + +在刷题时,我们几乎一定会用到各种数据结构来辅助我们解决问题,因此我们必须熟悉各种数据结构的特点。C++ STL 提供的数据结构包括(实际底层细节可能因编译器而异): + +1. Sequence Containers:维持顺序的容器。 + 1. vector:`动态数组`,是我们最常使用的数据结构之一,用于 $O(1)$ 的随机读取。因为大部分算法的时间复杂度都会大于 $O(n)$,因此我们经常新建 vector 来存储各种数据或中间变量。因为在尾部增删的复杂度是 $O(1)$,我们也可以把它当作 stack 来用。 + 2. list:`双向链表`,也可以当作 stack 和 queue 来使用。由于 LeetCode 的题目多用 Node 来表示链表,且链表不支持快速随机读取,因此我们很少用到这个数据结构。一个例外是经典的 LRU 问题,我们需要利用链表的特性来解决,我们在后文会遇到这个问题。 + 3. deque:双端队列,这是一个非常强大的数据结构,既支持 $O(1)$ 随机读取,又支持 $O(1)$ 时间的头部增删和尾部增删(因此可以当作 stack 和 queue 来使用),不过有一定的额外开销。也可以用来近似一个双向链表来使用。 + 4. array:固定大小的数组,一般在刷题时我们不使用。 + 5. forward_list:单向链表,一般在刷题时我们不使用。 +2. Container Adaptors:基于其它容器实现的容器。 + 1. stack:`后入先出(LIFO)的数据结构`,默认基于 deque 实现。stack 常用于深度优先搜索、一些字符串匹配问题以及单调栈问题。 + 2. `先入先出(FIFO)的数据结构`,默认基于 deque 实现。queue 常用于广度优先搜索。 + 3. priority_queue:`优先队列(最大值先出的数据结构)`,默认基于 vector 实现堆结构。它可以在 $O(n \log n)$ 的时间排序数组,$O(\log n)$ 的时间插入任意值,$O(1)$ 的时间获得最大值,$O(\log n)$ 的时间删除最大值。priority_queue 常用于维护数据结构并快速获取最大值,并且可以自定义比较函数;比如通过存储负值或者更改比小函数为比大函数,即可实现最小值先出。 +3. Ordered Associative Containers:有序关联容器。 + 1. set:有序集合,元素不可重复,底层实现默认为红黑树,即一种特殊的二叉查找树(BST)。它可以在 $O(n \log n)$ 的时间排序数组,$O(\log n)$ 的时间插入、删除、查找任意值,$O(\log n)$ 的时间获得最小或最大值。这里注意,set 和 priority_queue 都可以用于维护数据结构并快速获取最大最小值,但是它们的时间复杂度和功能略有区别,如 priority_queue 默认不支持删除任意值,而 set 获得最大或最小值的时间复杂度略高,具体使用哪个根据需求而定。 + 2. multiset:支持重复元素的 set。 + 3. map:`有序映射或有序表`,在 set 的基础上加上映射关系,可以对每个元素 key 存一个值 value。 + 4. multimap:支持重复元素的 map。 +4. Unordered Associative Containers:无序关联容器。 + 1. unordered_set:`哈希集合`,可以在 $O(1)$ 的时间快速插入、查找、删除元素,常用于快速的查询一个元素是否在这个容器内。 + 2. unordered_multiset:支持重复元素的 unordered_set。 + 3. unordered_map:`哈希映射或哈希表`,在 unordered_set 的基础上加上映射关系,可以对每一个元素 key 存一个值 value。在某些情况下,如果 key 的范围已知且较小,我们也可以用 vector 代替 unordered_map,用位置表示 key,用每个位置的值表示 value。 + 4. unordered_multimap:支持重复元素的 unordered_map。 + +因为这并不是一本讲解 C++ 原理的书,更多的 STL 细节请读者自行搜索。只有理解了这些数据结构的原理和使用方法,才能够更加游刃有余地解决算法和数据结构问题。 diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-10-prefix-sum-integral-image.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-10-prefix-sum-integral-image.mdx new file mode 100644 index 00000000..70062d7a --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-10-prefix-sum-integral-image.mdx @@ -0,0 +1,226 @@ +--- +sidebar_position: 57 +--- + +# 10.10 前缀和与积分图 + +一维的前缀和(cumulative sum, cumsum),二维的积分图(summed-area table, image integral)都是把每个位置之前的一维线段或二维矩形预先存储,方便加速计算。如果需要对前缀和或积分图的值做寻址,则要存入哈希表;如果要对每个位置记录前缀和或积分图的值,则可以储存到一维或二维数组里,也常常伴随着动态规划。 + +## [303. Range Sum Query - Immutable](https://leetcode.com/problems/range-sum-query-immutable/) + +### Problem Description + +设计一个数据结构,使得其能够快速查询给定数组中,任意两个位置间所有数字的和。 + +### Input and Output Example + +以下是数据结构的调用样例。 + +``` +vector nums{-2,0,3,-5,2,-1}; +NumArray num_array = new NumArray(nums); +num_array.sumRange(0,2); // Result = -2+0+3 = 1. +num_array.sunRange(1,5); // Result = 0+3-5+2-1 = -1. +``` + +### Solution Explanation + +对于一维的数组,我们可以使用前缀和来解决此类问题。先建立一个与数组 nums 长度相同的新数组 cumsum,表示 nums 每个位置之前前所有数字的和。cumsum 数组可以通过 C++ 自带的 partial_sum 函数建立,也可以直接遍历一遍 nums 数组,并利用状态转移方程 cumsum[i] = cumsum[i-1] + nums[i] 完成统计。如果我们需要获得位置 i 和 j 之间的数字和,只需计算 cum - sum[j+1] - cumsum[i] 即可。 + + + + +```cpp +class NumArray { + public: + NumArray(vector nums) : cumsum_(nums.size() + 1, 0) { + partial_sum(nums.begin(), nums.end(), cumsum_.begin() + 1); + } + + int sumRange(int left, int right) { + return cumsum_[right + 1] - cumsum_[left]; + } + + private: + vector cumsum_; +}; +``` + + + + +```py +class NumArray: + def __init__(self, nums: List[int]): + self.cumsum = [0] + nums[:] + for i in range(2, len(self.cumsum)): + self.cumsum[i] += self.cumsum[i - 1] + + def sumRange(self, left: int, right: int) -> int: + return self.cumsum[right + 1] - self.cumsum[left] +``` + + + + + +## [304. Range Sum Query 2D - Immutable](https://leetcode.com/problems/range-sum-query-2d-immutable/) + +### Problem Description + +设计一个数据结构,使得其能够快速查询给定矩阵中,任意两个位置包围的长方形中所有数字的和。 + +### Input and Output Example + +以下是数据结构的调用样例。其中 sumRegion 函数的四个输入分别是第一个点的横、纵坐标,和第二个点的横、纵坐标。 + +``` +vector matrix{{3,0,1,4,2}, + {5,6,3,2,1}, + {1,2,0,1,5}, + {4,1,0,1,7}, + {1,0,3,0,5} +}; +NumMatrix num_matrix = new NumMatrix(matrix); +num_matrix.sumRegion(2,1,4,3); // Result = 8. +num_matrix.sumRegion(1,1,2,2); // Result = 11. +``` + +### Solution Explanation + +类似于前缀和,我们可以把这种思想拓展到二维,即积分图(summed-area table, image integral)。我们可以先建立一个 sat 矩阵,sat[i][j] 表示以位置 (0, 0) 为左上角、位置 (i-1, j-1) 为右下角的长方形中所有数字的和。 + +
    + + ![](10.4.png) + +
    图 10.4: 题目 304 - 图 1 - 左边为给定矩阵,右边为积分图结果,右下角位置的积分图值为 5+48+45− 40 =58
    +
    + + +
    + + ![](10.5.png) + +
    图 10.5: 题目 304 - 图 2 - 左边为给定矩阵,右边为积分图结果,长方形 E 的数字和等于 58 − 11 − 13 +3 =37
    +
    + +如图 1 所示,我们可以用动态规划来计算 sat 矩阵:sat[i][j] = matrix[i-1][j-1] + sat[i-1][j] + sat[i][j-1] - sat[i-1][j-1],即当前坐标的数字 + 上面长方形的数字和 + 左边长方形的数字和 - 上面长方形和左边长方形重合面积(即左上一格的长方形)中的数字和。 + +如图 2 所示,假设我们要查询长方形 E 的数字和,因为 E = D − B − C + A,我们发现 E 其实可以由四个位置的积分图结果进行加减运算得到。因此这个算法在预处理时的时间复杂度为 $O(mn)$,而在查询时的时间复杂度仅为 $O(1)$。 + + + + +```cpp +class NumMatrix { + public: + NumMatrix(vector> matrix) { + int m = matrix.size(), n = matrix[0].size(); + sat_ = vector>(m + 1, vector(n + 1, 0)); + for (int i = 1; i <= m; ++i) { + for (int j = 1; j <= n; ++j) { + sat_[i][j] = matrix[i - 1][j - 1] + sat_[i - 1][j] + + sat_[i][j - 1] - sat_[i - 1][j - 1]; + } + } + } + + int sumRegion(int row1, int col1, int row2, int col2) { + return sat_[row2 + 1][col2 + 1] - sat_[row2 + 1][col1] - + sat_[row1][col2 + 1] + sat_[row1][col1]; + } + + private: + vector> sat_; +}; +``` + + + + +```py +class NumMatrix: + def __init__(self, matrix: List[List[int]]): + m, n = len(matrix), len(matrix[0]) + self.sat = [[0 for _ in range(n + 1)] for _ in range(m + 1)] + + for i in range(1, m + 1): + for j in range(1, n + 1): + self.sat[i][j] = ( + matrix[i - 1][j - 1] + + self.sat[i - 1][j] + + self.sat[i][j - 1] + - self.sat[i - 1][j - 1] + ) + + def sumRegion(self, row1: int, col1: int, row2: int, col2: int) -> int: + return ( + self.sat[row2 + 1][col2 + 1] + - self.sat[row2 + 1][col1] + - self.sat[row1][col2 + 1] + + self.sat[row1][col1] + ) + +``` + + + + + +## [560. Subarray Sum Equals K](https://leetcode.com/problems/subarray-sum-equals-k/) + +### Problem Description + +给定一个数组,寻找和为 k 的连续区间个数。 + +### Input and Output Example + +输入一个一维整数数组和一个整数值 k;输出一个整数,表示满足条件的连续区间个数。 + +``` +Input: nums = [1,1,1], k = 2 +Output: 2 +``` + +在这个样例中,我们可以找到两个 [1,1] 连续区间满足条件。 + +### Solution Explanation + +本题同样是利用前缀和,不同的是这里我们使用一个哈希表 cache,其键是前缀和,而值是该前缀和出现的次数。在我们遍历到位置 i 时,假设当前的前缀和是 cumsum,那么 cache[cumsum-k] 即为以当前位置结尾、满足条件的区间个数。 + + + + +```cpp +int subarraySum(vector& nums, int k) { + int count = 0, cumsum = 0; + unordered_map cache; // + cache[0] = 1; + for (int num : nums) { + cumsum += num; + count += cache[cumsum - k]; + ++cache[cumsum]; + } + return count; +} +``` + + + + +```py +def subarraySum(nums: List[int], k: int) -> int: + count, cur_sum = 0, 0 + cache = {0: 1} # + for num in nums: + cur_sum += num + count += cache.get(cur_sum - k, 0) + cache[cur_sum] = cache.get(cur_sum, 0) + 1 + return count +``` + + + + + diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-11-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-11-exercises.md new file mode 100644 index 00000000..ed345083 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-11-exercises.md @@ -0,0 +1,53 @@ +--- +sidebar_position: 58 +--- + +# 10.11 Exercises + +## Basic Difficulty + +### [566. Reshape the Matrix](https://leetcode.com/problems/reshape-the-matrix/) + +没有什么难度,只是需要一点耐心。 + +### [225. Implement Stack using Queues](https://leetcode.com/problems/implement-stack-using-queues/) + +利用相似的方法,我们也可以用 queue 实现 stack。 + +### [503. Next Greater Element II](https://leetcode.com/problems/next-greater-element-ii/) + +Daily Temperature 的变种题。 + +### [217. Contains Duplicate](https://leetcode.com/problems/contains-duplicate/) + +使用什么数据结构可以快速判断重复呢? + +### [697. Degree of an Array](https://leetcode.com/problems/degree-of-an-array/) + +如何对数组进行预处理才能正确并快速地计算子数组的长度? + +### [594. Longest Harmonious Subsequence](https://leetcode.com/problems/longest-harmonious-subsequence/) + +最长连续序列的变种题。 + +### [15. 3Sum](https://leetcode.com/problems/3sum/) + +因为排序的复杂度是 $O(n \log n) < O(n^2)$,因此我们既可以排序后再进行 $O(n^2)$ 的指针搜索,也可以直接利用哈希表进行 $O(n^2)$ 的搜索。 + +## Advanced Difficulty + +### [287. Find the Duplicate Number](https://leetcode.com/problems/find-the-duplicate-number/) + +寻找丢失数字的变种题。除了标负位置,你还有没有其它算法可以解决这个问题? + +### [313. Super Ugly Number](https://leetcode.com/problems/super-ugly-number/) + +尝试使用优先队列解决这一问题。 + +### [870. Advantage Shuffle](https://leetcode.com/problems/advantage-shuffle/) + +如果我们需要比较大小关系,而且同一数字可能出现多次,那么应该用什么数据结构呢? + +### [307. Range Sum Query - Mutable](https://leetcode.com/problems/range-sum-query-mutable/) + +前缀和的变种题。好吧我承认,这道题可能有些超纲,你或许需要搜索一下什么是线段树。 \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-2-python-data-structures.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-2-python-data-structures.md new file mode 100644 index 00000000..b4221a27 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-2-python-data-structures.md @@ -0,0 +1,22 @@ +--- +sidebar_position: 49 +--- + +# 10.2 Python 常用数据结构 + +类似于 C++ STL,Python 也提供了类似的数据结构(实际底层细节可能因编译器而异): + +1. Sequence Containers:维持顺序的容器。 + 1. list:`动态数组`,是我们最常使用的数据结构之一,用于 $O(1)$ 的随机读取。因为大部分算法的时间复杂度都会大于 $O(n)$,因此我们经常新建 list 来存储各种数据或中间变量。因为在尾部增删的复杂度是 $O(1)$,我们也可以把它当作 stack 来用。 + 2. tuple: `元组`,immutable list,不可改变其中元素或总长度。 + 3. collections.deque:`双端队列`,这是一个非常强大的数据结构,既支持 $O(1)$ 随机读取,又支持 $O(1)$ 时间的头部增删和尾部增删(因此可以当作 stack 和 queue 来使用),不过有一定的额外开销。也可以用来近似一个双向链表来使用。 +2. Container Adaptors:基于其它容器实现的容器。 + 1. heapq:`最小堆(最小值先出的数据结构)`,默认基于 list 实现堆结构。它可以在 $O(n \log n)$ 的时间排序数组,$O(\log n)$ 的时间插入任意值,$O(1)$ 的时间获得最小值,$O(\log n)$ 的时间删除最小值。heapq 常用于维护数据结构并快速获取最小值,但不支持自定义比较函数。所以通常我们需要提前算好自定义值,再把 (自定义值,位置) 的 tuple 存进 heapq。这样进行比较时就会默认从左到右比较 tuple 中的元素,即先比较自定义值,再比较元素的插入次序。 +3. Ordered Associative Containers:有序关联容器。 + 1. collections.OrderedDict:`顺序映射或顺序表`,注意这里的 Ordered 不同于 C++ 中 map的按大小排序,而是按照插入的先后次序排序。OrderedDict 很适合用来做 LRU。 +4. Unordered Associative Containers:无序关联容器。 + 1. set:`哈希集合`,可以在 O(1) 的时间快速插入、查找、删除元素,常用于快速的查询一个元素是否在这个容器内。 + 2. dict:`哈希映射或哈希表`,在 set 的基础上加上映射关系,可以对每一个元素 key 存一个值 value。在某些情况下,如果 key 的范围已知且较小,我们也可以用 list 代替 dict,用位置表示 key,用每个位置的值表示 value。 + 3. collections.Counter:`计数器`,是 dict 的一个特殊版本,可以直接传入一个 list,并对其中的每一个元素进行计数统计,key 是元素值,value 是元素出现的频次。可以用来当作多重集合。 + +同样的,因为这并不是一本讲解 Python 原理的书,更多的数据结构细节请读者自行搜索。只有理解了这些数据结构的原理和使用方法,才能够更加游刃有余地解决算法和数据结构问题。 \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-3-arrays.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-3-arrays.mdx new file mode 100644 index 00000000..8aa59501 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-3-arrays.mdx @@ -0,0 +1,250 @@ +--- +sidebar_position: 50 +--- + +# 10.3 数组 + +## [448. Find All Numbers Disappeared in an Array](https://leetcode.com/problems/find-all-numbers-disappeared-in-an-array/) + +### Problem Description + +给定一个长度为 n 的数组,其中包含范围为 1 到 n 的整数,有些整数重复了多次,有些整数没有出现,求 1 到 n 中没有出现过的整数。 + +### Input and Output Example + +输入是一个一维整数数组,输出也是一个一维整数数组,表示输入数组内没出现过的数字。 + +``` +Input: [4,3,2,7,8,2,3,1] +Output: [5,6] +``` + +利用数组这种数据结构建立 n 个桶,把所有重复出现的位置进行标记,然后再遍历一遍数组,即可找到没有出现过的数字。进一步地,我们可以直接对原数组进行标记:把重复出现的数字-1在原数组的位置设为负数(这里-1 的目的是把 1 到 n 的数字映射到 0 到 n-1 的位置),最后仍然为正数的位置 +1 即为没有出现过的数。 + +### Solution Explanation + + + + + + +```cpp +vector findDisappearedNumbers(vector& nums) { + vector disappeared; + for (int num : nums) { + int pos = abs(num) - 1; + if (nums[pos] > 0) { + nums[pos] = -nums[pos]; + } + } + for (int i = 0; i < nums.size(); ++i) { + if (nums[i] > 0) { + disappeared.push_back(i + 1); + } + } + return disappeared; +} +``` + + + + +```py +def findDisappearedNumbers(nums: List[int]) -> List[int]: + for num in nums: + pos = abs(num) - 1 + if nums[pos] > 0: + nums[pos] = -nums[pos] + return [i + 1 for i in range(len(nums)) if nums[i] > 0] +``` + + + + + +## [48. Rotate Image](https://leetcode.com/problems/rotate-image/) + +### Problem Description + +给定一个 n × n 的矩阵,求它顺时针旋转 90 度的结果,且必须在原矩阵上修改(in-place)。怎样能够尽量不创建额外储存空间呢? + +### Input and Output Example + +输入和输出都是一个二维整数矩阵。 + +``` +Input: +[[1,2,3], + [4,5,6], + [7,8,9]] +Output: +[[7,4,1], + [8,5,2], + [9,6,3]] +``` + +### Solution Explanation + +每次只考虑四个间隔 90 度的位置,可以进行 O(1) 额外空间的旋转。 + +
    + + ![](10.1.png) + +
    图 10.1: 题目 48 - $O(1)$ 空间旋转样例,相同颜色代表四个互相交换的位置
    +
    + + + + +```cpp +void rotate(vector>& matrix) { + int pivot = 0, n = matrix.size() - 1; + for (int i = 0; i <= n / 2; ++i) { + for (int j = i; j < n - i; ++j) { + pivot = matrix[j][n - i]; + matrix[j][n - i] = matrix[i][j]; + matrix[i][j] = matrix[n - j][i]; + matrix[n - j][i] = matrix[n - i][n - j]; + matrix[n - i][n - j] = pivot; + } + } +} +``` + + + + +```py +def rotate(matrix: List[List[int]]) -> None: + n = len(matrix) - 1 + for i in range(n // 2 + 1): + for j in range(i, n - i): + pivot = matrix[j][n - i] + matrix[j][n - i] = matrix[i][j] + matrix[i][j] = matrix[n - j][i] + matrix[n - j][i] = matrix[n - i][n - j] + matrix[n - i][n - j] = pivot +``` + + + + + +## [240. Search a 2D Matrix II](https://leetcode.com/problems/search-a-2d-matrix-ii/) + +### Problem Description + +给定一个二维矩阵,已知每行和每列都是增序的,尝试设计一个快速搜索一个数字是否在矩阵中存在的算法。 + +### Input and Output Example + +输入是一个二维整数矩阵,和一个待搜索整数。输出是一个布尔值,表示这个整数是否存在于矩阵中。 + +``` +Input: matrix = +[ [1, 4, 7, 11, 15], + [2, 5, 8, 12, 19], + [3, 6, 9, 16, 22], + [10, 13, 14, 17, 24], + [18, 21, 23, 26, 30]], target = 5 +Output: true +``` + +### Solution Explanation + +这道题有一个简单的技巧:我们可以从右上角开始查找,若当前值大于待搜索值,我们向左移动一位;若当前值小于待搜索值,我们向下移动一位。如果最终移动到左下角时仍不等于待搜索值,则说明待搜索值不存在于矩阵中。 + + + + +```cpp +bool searchMatrix(vector>& matrix, int target) { + int m = matrix.size(), n = matrix[0].size(); + int i = 0, j = n - 1; + while (i < m && j >= 0) { + if (matrix[i][j] == target) { + return true; + } else if (matrix[i][j] < target) { + ++i; + } else { + --j; + } + } + return false; +} +``` + + + + +```py +def searchMatrix(matrix: List[List[int]], target: int) -> bool: + m, n = len(matrix), len(matrix[0]) + i, j = 0, n - 1 + while i < m and j >= 0: + if matrix[i][j] == target: + return True + if matrix[i][j] < target: + i += 1 + else: + j -= 1 + return False +``` + + + + + +## [769. Max Chunks To Make Sorted](https://leetcode.com/problems/max-chunks-to-make-sorted/) + +### Problem Description + +给定一个含有 0 到 n 整数的数组,每个整数只出现一次,求这个数组最多可以分割成多少个子数组,使得对每个子数组进行增序排序后,原数组也是增序的。 + +### Input and Output Example + +输入一个一维整数数组,输出一个整数,表示最多的分割数。 + +``` +Input: [1,0,2,3,4] +Output: 4 +``` + +在这个样例中,最多分割是 [1, 0], [2], [3], [4]。 + +### Solution Explanation + +从左往右遍历,同时记录当前的最大值,每当当前最大值等于数组位置时,我们可以多一次分割。 + +为什么可以通过这个算法解决问题呢?如果当前最大值大于数组位置,则说明右边一定有小于数组位置的数字,需要把它也加入待排序的子数组;又因为数组只包含不重复的 0 到 n,所以当前最大值一定不会小于数组位置。所以每当当前最大值等于数组位置时,假设为 p,我们可以成功完成一次分割,并且其与上一次分割位置 q 之间的值一定是 q +1 到 p 的所有数字。 + + + + +```cpp +int maxChunksToSorted(vector& arr) { + int chunks = 0, cur_max = 0; + for (int i = 0; i < arr.size(); ++i) { + cur_max = max(cur_max, arr[i]); + chunks += cur_max == i; + } + return chunks; +} +``` + + + + +```py +def maxChunksToSorted(arr: List[int]) -> int: + chunks, cur_max = 0, 0 + for i, num in enumerate(arr): + cur_max = max(cur_max, num) + chunks += cur_max == i + return chunks +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-4-stack-and-queue.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-4-stack-and-queue.mdx new file mode 100644 index 00000000..5e5ea5f2 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-4-stack-and-queue.mdx @@ -0,0 +1,257 @@ +--- +sidebar_position: 51 +--- + +# 10.4 栈和队列 + +## [232. Implement Queue using Stacks](https://leetcode.com/problems/implement-queue-using-stacks/) + +### Problem Description + +尝试使用栈(stack)来实现队列(queue)。 + +### Input and Output Example + +以下是数据结构的调用样例。 + +``` +MyQueue queue = new MyQueue(); +queue.push(1); +queue.push(2); +queue.peek(); // returns 1 +queue.pop(); // returns 1 +queue.empty(); // returns false +``` + +### Solution Explanation + +我们可以用两个栈来实现一个队列:因为我们需要得到先入先出的结果,所以必定要通过一个额外栈翻转一次数组。这个翻转过程既可以在插入时完成,也可以在取值时完成。我们这里展示在取值时完成的写法。 + + + + +```cpp +class MyQueue { + public: + MyQueue() {} + + void push(int x) { s_in_.push(x); } + + int pop() { + in2out(); + int x = s_out_.top(); + s_out_.pop(); + return x; + } + + int peek() { + in2out(); + return s_out_.top(); + } + + bool empty() { return s_in_.empty() && s_out_.empty(); } + + private: + void in2out() { + if (!s_out_.empty()) { + return; + } + while (!s_in_.empty()) { + int x = s_in_.top(); + s_in_.pop(); + s_out_.push(x); + } + } + + stack s_in_, s_out_; +}; +``` + + + + +```py +class MyQueue: + def __init__(self): + self.s_in = [] + self.s_out = [] + + def _in2out(self): + if len(self.s_out) > 0: + return + while len(self.s_in) > 0: + self.s_out.append(self.s_in.pop()) + + def push(self, x: int) -> None: + self.s_in.append(x) + + def pop(self) -> int: + self._in2out() + return self.s_out.pop() + + def peek(self) -> int: + self._in2out() + return self.s_out[-1] + + def empty(self) -> bool: + return len(self.s_in) == 0 and len(self.s_out) == 0 +``` + + + + + +## [155. Min Stack](https://leetcode.com/problems/min-stack/) + +### Problem Description + +设计一个最小栈,除了需要支持常规栈的操作外,还需要支持在 $O(1)$ 时间内查询栈内最小值的功能。 + +### Input and Output Example + +以下是数据结构的调用样例。 + +``` +MinStack minStack = new MinStack(); +minStack.push(-2); +minStack.push(0); +minStack.push(-3); +minStack.getMin(); // Returns -3. +minStack.pop(); +minStack.top(); // Returns 0. +minStack.getMin(); // Returns -2. +``` + +### Solution Explanation + +我们可以额外建立一个新栈,栈顶表示原栈里所有值的最小值。每当在原栈里插入一个数字时,若该数字小于等于新栈栈顶,则表示这个数字在原栈里是最小值,我们将其同时插入新栈内。每当从原栈里取出一个数字时,若该数字等于新栈栈顶,则表示这个数是原栈里的最小值之一,我们同时取出新栈栈顶的值。 + +一个写起来更简单但是时间复杂度略高的方法是,我们每次插入原栈时,都向新栈插入一次原栈里所有值的最小值(新栈栈顶和待插入值中小的那一个);每次从原栈里取出数字时,同样取出新栈的栈顶。这样可以避免判断,但是每次都要插入和取出。我们这里只展示第一种写法。 + + + + +```cpp +class MinStack { + public: + MinStack() {} + + void push(int x) { + s_.push(x); + if (min_s_.empty() || min_s_.top() >= x) { + min_s_.push(x); + } + } + + void pop() { + if (!min_s_.empty() && min_s_.top() == s_.top()) { + min_s_.pop(); + } + s_.pop(); + } + + int top() { return s_.top(); } + + int getMin() { return min_s_.top(); } + + private: + stack s_, min_s_; +}; +``` + + + + +```py +class MinStack: + def __init__(self): + self.s = [] + self.min_s = [] + + def push(self, x: int) -> None: + self.s.append(x) + if len(self.min_s) == 0 or self.min_s[-1] >= x: + self.min_s.append(x) + + def pop(self) -> None: + if len(self.min_s) != 0 and self.s[-1] == self.min_s[-1]: + self.min_s.pop() + self.s.pop() + + def top(self) -> int: + return self.s[-1] + + def getMin(self) -> int: + return self.min_s[-1] +``` + + + + + + +## [20. Valid Parentheses](https://leetcode.com/problems/valid-parentheses/) + +### Problem Description + +给定一个只由左右圆括号、花括号和方括号组成的字符串,求这个字符串是否合法。合法的定义是每一个类型的左括号都有一个右括号一一对应,且括号内的字符串也满足此要求。 + +### Input and Output Example + +输入是一个字符串,输出是一个布尔值,表示字符串是否合法。 + +``` +Input: "{[]}()" +Output: true +``` + +### Solution Explanation + +括号匹配是典型的使用栈来解决的问题。我们从左往右遍历,每当遇到左括号便放入栈内,遇到右括号则判断其和栈顶的括号是否是统一类型,是则从栈内取出左括号,否则说明字符串不合法。 + + + + +```cpp +bool isValid(string s) { + stack parsed; + unordered_map matches{{’(’, ’)’}, {’{’, ’}’}, {’[’, ’]’}}; + for (char c : s) { + if (matches.contains(c)) { + parsed.push(c); + continue; + } + if (parsed.empty()) { + return false; + } + if (c != matches[parsed.top()]) { + return false; + } + parsed.pop(); + } + return parsed.empty(); +} +``` + + + + +```py +def isValid(s: str) -> bool: + parsed = [] + matches = {"{": "}", "(": ")", "[": "]"} + for c in s: + if c in matches.keys(): + parsed.append(c) + continue + if len(parsed) == 0: + return False + if c != matches[parsed[-1]]: + return False + parsed.pop() + return len(parsed) == 0 +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-5-monotonic-stack.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-5-monotonic-stack.mdx new file mode 100644 index 00000000..0ddb3ec8 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-5-monotonic-stack.mdx @@ -0,0 +1,72 @@ +--- +sidebar_position: 52 +--- + +# 10.5 单调栈 + +`单调栈`通过维持栈内值的单调递增(递减)性,在整体 $O(n)$ 的时间内处理需要大小比较的问题。 + +## [739. Daily Temperatures](https://leetcode.com/problems/daily-temperatures/) + +### Problem Description + +给定每天的温度,求对于每一天需要等几天才可以等到更暖和的一天。如果该天之后不存在更暖和的天气,则记为 0。 + +### Input and Output Example + +输入是一个一维整数数组,输出是同样长度的整数数组,表示对于每天需要等待多少天。 + +``` +Input: [73, 74, 75, 71, 69, 72, 76, 73] +Output: [1, 1, 4, 2, 1, 1, 0, 0] +``` + +### Solution Explanation + +我们可以维持一个单调递减的栈,表示每天的温度;为了方便计算天数差,我们这里存放位置(即日期)而非温度本身。我们从左向右遍历温度数组,对于每个日期 p,如果 p 的温度比栈顶存储位置 q 的温度高,则我们取出 q,并记录 q 需要等待的天数为 p − q;我们重复这一过程,直到 p 的温度小于等于栈顶存储位置的温度(或空栈)时,我们将 p 插入栈顶,然后考虑下一天。在这个过程中,栈内数组永远保持单调递减,避免了使用排序进行比较。最后若栈内剩余一些日期,则说明它们之后都没有出现更暖和的日期。 + + + + +```cpp +vector dailyTemperatures(vector& temperatures) { + int n = temperatures.size(); + vector days_to_wait(n, 0); + stack mono_stack; + for (int i = 0; i < n; ++i) { + while (!mono_stack.empty()) { + int j = mono_stack.top(); + if (temperatures[i] <= temperatures[j]) { + break; + } + mono_stack.pop(); + days_to_wait[j] = i - j; + } + mono_stack.push(i); + } + return days_to_wait; +} +``` + + + + +```py +def dailyTemperatures(temperatures: List[int]) -> List[int]: + n = len(temperatures) + days_to_wait = [0] * n + mono_stack = [] + for i in range(n): + while len(mono_stack) > 0: + j = mono_stack[-1] + if temperatures[i] <= temperatures[j]: + break + mono_stack.pop() + days_to_wait[j] = i - j + mono_stack.append(i) + return days_to_wait +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-6-priority-queue.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-6-priority-queue.mdx new file mode 100644 index 00000000..d4f19248 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-6-priority-queue.mdx @@ -0,0 +1,295 @@ +--- +sidebar_position: 53 +--- + +# 10.6 优先队列 + +`优先队列`(priority queue)可以在 O(1) 时间内获得最大值,并且可以在 O(log n) 时间内取出最大值或插入任意值。 + +
    + + ![](10.2.png) + +
    图 10.2: (最大)堆,维护的是数据结构中的大于关系
    +
    + +优先队列常常用堆(heap)来实现。堆是一个完全二叉树,其每个节点的值总是大于等于子节点的值。实际实现堆时,我们通常用一个数组而不是用指针建立一个树。这是因为堆是完全二叉树,所以用数组表示时,位置 i 的节点的父节点位置一定为 (i-1)/2,而它的两个子节点的位置又一定分别为 2i+1 和 2i+2。 + +以下是堆的实现方法,其中最核心的两个操作是上浮和下沉:如果一个节点比父节点大,那么需要交换这个两个节点;交换后还可能比它新的父节点大,因此需要不断地进行比较和交换操作,我们称之为上浮;类似地,如果一个节点比父节小,也需要不断地向下进行比较和交换操作我们称之为下沉。如果一个节点有两个子节点,我们总是交换最大的子节点。 + + + + + +```cpp +class Heap { + public: + Heap() {} + // 上浮。 + void swim(int pos) { + int next_pos = (pos - 1) / 2; + while (pos > 0 && heap_[next_pos] < heap_[pos]) { + swap(heap_[next_pos], heap_[pos]); + pos = next_pos; + next_pos = (pos - 1) / 2; + } + } + // 下沉。 + void sink(int pos) { + int n = heap_.size(); + int next_pos = 2 * pos + 1; + while (next_pos < n) { + if (next_pos < n - 1 && heap_[next_pos] < heap_[next_pos + 1]) { + ++next_pos; + } + if (heap_[pos] >= heap_[next_pos]) { + break; + } + swap(heap_[next_pos], heap_[pos]); + pos = next_pos; + next_pos = 2 * pos + 1; + } + } + // 插入任意值:把新的数字放在最后一位,然后上浮。 + void push(int k) { + heap_.push_back(k); + swim(heap_.size() - 1); + } + // 删除最大值:把最后一个数字挪到开头,然后下沉。 + void pop() { + heap_[0] = heap_.back(); + heap_.pop_back(); + sink(0); + } + // 获得最大值。 + int top() { return heap_[0]; } + + private: + vector heap_; +}; +``` + + + + +```py +class Heap: + def __init__(self): + self.heap = [] + + # 上浮。 + def swim(self, pos: int): + next_pos = (pos - 1) // 2 + while pos > 0 and self.heap[next_pos] < self.heap[pos]: + self.heap[next_pos], self.heap[pos] = self.heap[pos], self.heap[next_pos] + pos = next_pos + next_pos = (pos - 1) // 2 + + # 下沉。 + def sink(self, pos: int): + n = len(self.heap) + next_pos = 2 * pos + 1 + while next_pos < n: + if next_pos < n - 1 and self.heap[next_pos] < self.heap[next_pos + 1]: + next_pos += 1 + if self.heap[pos] >= self.heap[next_pos]: + break + self.heap[next_pos], self.heap[pos] = self.heap[pos], self.heap[next_pos] + pos = next_pos + next_pos = 2 * pos + 1 + + # 插入任意值:把新的数字放在最后一位,然后上浮。 + def push(self, k: int): + self.heap.append(k) + self.swim(len(self.heap) - 1) + + # 删除最大值:把最后一个数字挪到开头,然后下沉。 + def pop(self): + self.heap[0] = self.heap.pop() + self.sink(0) + + # 获得最大值。 + def top(self) -> int: + return self.heap[0] + +``` + + + + + +通过将算法中的大于号和小于号互换,我们也可以得到一个快速获得最小值的优先队列。 + +## [23. Merge k Sorted Lists](https://leetcode.com/problems/merge-k-sorted-lists/) + +### Problem Description + +给定 k 个增序的链表,试将它们合并成一条增序链表。 + +### Input and Output Example + +输入是一个一维数组,每个位置存储链表的头节点;输出是一条链表。 + +``` +Input: +[1->4->5, + 1->3->4, + 2->6] +Output: 1->1->2->3->4->4->5->6 +``` + +### Solution Explanation + +本题可以有很多中解法,比如类似于归并排序进行两两合并。我们这里展示一个速度比较快的方法,即把所有的链表存储在一个优先队列中,每次提取所有链表头部节点值最小的那个节点,直到所有链表都被提取完为止。 + +因为 C++ priority_queue 的比较函数默认是对最大堆进行比较并维持递增关系,如果我们想要获取最小的节点值,我们则需要实现一个最小堆。因此堆的比较函数应该维持递减关系,即 lambda 函数中返回时用大于号而不是递增关系时的小于号进行比较。 + + + + +```cpp +ListNode* mergeKLists(vector& lists) { + auto comp = [](ListNode* l1, ListNode* l2) { return l1->val > l2->val; }; + priority_queue, decltype(comp)> pq; + for (ListNode* l : lists) { + if (l) { + pq.push(l); + } + } + ListNode *dummy = new ListNode(0), *cur = dummy; + while (!pq.empty()) { + cur->next = pq.top(); + pq.pop(); + cur = cur->next; + if (cur->next) { + pq.push(cur->next); + } + } + return dummy->next; +} +``` + + + + +```py +def mergeKLists(lists: List[Optional[ListNode]]) -> Optional[ListNode]: + pq = [] + for idx, l in enumerate(lists): + if l is not None: + # ListNode不可被哈希,所以这里我们直接记录它在lists中的位置。 + pq.append((l.val, idx)) + heapq.heapify(pq) + + dummy = ListNode() + cur = dummy + + while len(pq) > 0: + _, l_idx = heapq.heappop(pq) + cur.next = lists[l_idx] + cur = cur.next + if cur.next is not None: + lists[l_idx] = lists[l_idx].next + heapq.heappush(pq, (cur.next.val, l_idx)) + + return dummy.next + +``` + + + + + +## [218. The Skyline Problem](https://leetcode.com/problems/the-skyline-problem/) + +### Problem Description + +给定建筑物的起止位置和高度,返回建筑物轮廓(天际线)的拐点。 + +### Input and Output Example + +输入是一个二维整数数组,表示每个建筑物的 [左端, 右端, 高度];输出是一个二维整数数组,表示每个拐点的横纵坐标。 + +
    + + ![](10.3.png) + +
    图 10.3: 题目 218 - 建筑物及其天际线样例
    +
    + +``` +Input: [[2 9 10], [3 7 15], [5 12 12], [15 20 10], [19 24 8]] +Output: [[2 10], [3 15], [7 12], [12 0], [15 10], [20 8], [24, 0]] +``` + +### Solution Explanation + +我们可以使用优先队列储存每个建筑物的高度和右端(这里使用 pair,其默认比较函数是先比较第一个值,如果相等则再比较第二个值),从而获取目前会拔高天际线、且妨碍到前一个建筑物(的右端端点)的下一个建筑物。 + +因为 Python 中 heapq 是最小堆,所以我们在存值的时候可以存负值,这样就变成了最大堆。 + +这道题比较复杂,如果实在难以理解,建议读者暂时跳过此题,或者在纸上举例子画一画。 + + + + +```cpp +vector> getSkyline(vector>& buildings) { + vector> skyline; + priority_queue> pq; // <高度, 右端> + int i = 0, n = buildings.size(); + int cur_x, cur_h; + while (i < n || !pq.empty()) { + if (pq.empty() || (i < n && buildings[i][0] <= pq.top().second)) { + cur_x = buildings[i][0]; + while (i < n && cur_x == buildings[i][0]) { + pq.emplace(buildings[i][2], buildings[i][1]); + ++i; + } + } else { + cur_x = pq.top().second; + while (!pq.empty() && cur_x >= pq.top().second) { + pq.pop(); + } + } + cur_h = pq.empty() ? 0 : pq.top().first; + if (skyline.empty() || cur_h != skyline.back()[1]) { + skyline.push_back({cur_x, cur_h}); + } + } + return skyline; +} +``` + + + + +```py +def getSkyline(buildings: List[List[int]]) -> List[List[int]]: + skyline = [] + pq = [] # <负高度,右端> + heapq.heapify(pq) + i, n = 0, len(buildings) + + while i < n or len(pq) > 0: + if len(pq) == 0 or (i < n and buildings[i][0] <= pq[0][1]): + cur_x = buildings[i][0] + while i < n and cur_x == buildings[i][0]: + heapq.heappush(pq, (-buildings[i][2], buildings[i][1])) + i += 1 + else: + cur_x = pq[0][1] + while len(pq) > 0 and cur_x >= pq[0][1]: + heapq.heappop(pq) + + cur_h = -pq[0][0] if len(pq) > 0 else 0 + if len(skyline) == 0 or cur_h != skyline[-1][1]: + skyline.append([cur_x, cur_h]) + + return skyline + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-7-deque.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-7-deque.mdx new file mode 100644 index 00000000..72e2b2e5 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-7-deque.mdx @@ -0,0 +1,82 @@ +--- +sidebar_position: 54 +--- + +# 10.7 双端队列 + +## [239. Sliding Window Maximum](https://leetcode.com/problems/sliding-window-maximum/) + +### Problem Description + +给定一个整数数组和一个滑动窗口大小,求在这个窗口的滑动过程中,每个时刻其包含的最大值。 + +### Input and Output Example + +输入是一个一维整数数组,和一个表示滑动窗口大小的整数;输出是一个一维整数数组,表示每个时刻时的窗口内最大值。 + +``` +Input: nums = [1,3,-1,-3,5,3,6,7], k = 3 +Output: [3,3,5,5,6,7] +``` + +在这个样例中,滑动窗口在每个位置的最大包含值取法如下: + +``` + Window position Max +------------------------- ----- +[1 3 -1] -3 5 3 6 7 3 + 1 [3 -1 -3] 5 3 6 7 3 + 1 3 [-1 -3 5] 3 6 7 5 + 1 3 -1 [-3 5 3] 6 7 5 + 1 3 -1 -3 [5 3 6] 7 6 + 1 3 -1 -3 5 [3 6 7] 7 +``` + +### Solution Explanation + +我们可以利用双端队列进行操作:每当向右移动时,把窗口左端的值从双端队列左端剔除,把双端队列右边小于窗口右端的值全部剔除。这样双端队列的最左端永远是当前窗口内的最大值。另外,这道题也是单调栈的一种延申:该双端队列利用从左到右递减来维持大小关系。 + + + + +```cpp +vector maxSlidingWindow(vector& nums, int k) { + deque dq; + vector swm; + for (int i = 0; i < nums.size(); ++i) { + if (!dq.empty() && dq.front() == i - k) { + dq.pop_front(); + } + while (!dq.empty() && nums[dq.back()] < nums[i]) { + dq.pop_back(); + } + dq.push_back(i); + if (i >= k - 1) { + swm.push_back(nums[dq.front()]); + } + } + return swm; +} +``` + + + + +```py +def maxSlidingWindow(nums: List[int], k: int) -> List[int]: + dq = collections.deque() + swm = [] + for i, num in enumerate(nums): + if len(dq) > 0 and dq[0] == i - k: + dq.popleft() + while len(dq) > 0 and nums[dq[-1]] < num: + dq.pop() + dq.append(i) + if i >= k - 1: + swm.append(nums[dq[0]]) + return swm +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-8-hash-table.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-8-hash-table.mdx new file mode 100644 index 00000000..13e29371 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-8-hash-table.mdx @@ -0,0 +1,232 @@ +--- +sidebar_position: 55 +--- + +# 10.8 哈希表 + +`哈希表(hash table, hash map)`,又称散列表,使用 $O(n)$ 空间复杂度存储数据,通过哈希函数(hash function)映射位置,从而实现近似 O(1) 时间复杂度的插入、查找、删除等操作。哈希表可以用来统计频率,记录内容等等。 + +如果元素有穷,并且范围不大,那么可以用一个固定大小的数组来存储或统计元素。例如我们需要统计一个字符串中所有字母的出现次数,则可以用一个长度为 26 的数组来进行统计,其哈希函数即为字母在字母表的位置,这样空间复杂度就可以降低为常数。 + +## [1. Two Sum](https://leetcode.com/problems/two-sum/) + +### Problem Description + +给定一个(未排序的)整数数组,已知有且只有两个数的和等于给定值,求这两个数的位置。 + +### Input and Output Example + +输入一个一维整数数组和一个目标值,输出是一个大小为 2 的一维数组,表示满足条件的两个数字的位置。 + +``` +Input: nums = [2, 7, 15, 11], target = 9 +Output: [0, 1] +``` + +在这个样例中,第 0 个位置的值 2 和第 1 个位置的值 7 的和为 9。 + +### Solution Explanation + +我们可以利用哈希表存储遍历过的值以及它们的位置,每次遍历到位置 i 的时候,查找哈希表里是否存在 target - nums[i],若存在,则说明这两个值的和为 target。 + + + + +```cpp +vector twoSum(vector& nums, int target) { + unordered_map cache; // <值,位置> + for (int i = 0; i < nums.size(); ++i) { + int num1 = nums[i], num2 = target - num1; + if (cache.contains(num2)) { + return vector{cache[num2], i}; + } + cache[num1] = i; + } + return {}; +} +``` + + + + +```py +def twoSum(nums: List[int], target: int) -> List[int]: + cache = dict() # <值,位置> + for i, num1 in enumerate(nums): + num2 = target - num1 + if num2 in cache: + return [cache[num2], i] + cache[num1] = i + return [] +``` + + + + + +## [128. Longest Consecutive Sequence](https://leetcode.com/problems/longest-consecutive-sequence/) + +### Problem Description + +给定一个整数数组,求这个数组中的数字可以组成的最长连续序列有多长。 + +### Input and Output Example + +输入一个整数数组,输出一个整数,表示连续序列的长度。 + +``` +Input: [100, 4, 200, 1, 3, 2] +Output: 4 +``` + +在这个样例中,最长连续序列是 [1,2,3,4]。 + +### Solution Explanation + +我们可以把所有数字放到一个哈希表,然后不断地从哈希表中任意取一个值,并删除掉其之前之后的所有连续数字,然后更新目前的最长连续序列长度。重复这一过程,我们就可以找到所有的连续数字序列。 + + + + +```cpp +int longestConsecutive(vector& nums) { + unordered_set cache(nums.begin(), nums.end()); + int max_len = 0; + while (!cache.empty()) { + int cur = *(cache.begin()); + cache.erase(cur); + int l = cur - 1, r = cur + 1; + while (cache.contains(l)) { + cache.erase(l--); + } + while (cache.contains(r)) { + cache.erase(r++); + } + max_len = max(max_len, r - l - 1); + } + return max_len; +} +``` + + + + +```py +def longestConsecutive(nums: List[int]) -> int: + cache = set(nums) + max_len = 0 + + while len(cache) > 0: + cur = next(iter(cache)) + cache.remove(cur) + + l, r = cur - 1, cur + 1 + while l in cache: + cache.remove(l) + l -= 1 + while r in cache: + cache.remove(r) + r += 1 + + max_len = max(max_len, r - l - 1) + + return max_len + +``` + + + + + +## [149. Max Points on a Line](https://leetcode.com/problems/max-points-on-a-line/) + +### Problem Description + +给定一些二维坐标中的点,求同一条线上最多有多少点。 + +### Input and Output Example + +输入是一个二维整数数组,表示每个点的横纵坐标;输出是一个整数,表示满足条件的最多点数。 + +``` +Input: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]] +^ +| +| o +| o o +| o +| o o ++-------------------> +0 1 2 3 4 5 6 +Output: 4 +``` + +这个样例中,$y =5 − x$ 上有四个点。 + +### Solution Explanation + +对于每个点,我们对其它点建立哈希表,统计同一斜率的点一共有多少个。这里利用的原理是,一条线可以由一个点和斜率而唯一确定。另外也要考虑斜率不存在和重复坐标的情况。 + +本题也利用了一个小技巧:在遍历每个点时,对于数组中位置 i 的点,我们只需要考虑 i 之后的点即可,因为 i 之前的点已经考虑过 i 了。 + + + + +```cpp +int maxPoints(vector>& points) { + int max_count = 0, n = points.size(); + for (int i = 0; i < n; ++i) { + unordered_map cache; // <斜率, 点个数> + int same_xy = 1, same_y = 1; + for (int j = i + 1; j < n; ++j) { + if (points[i][1] == points[j][1]) { + ++same_y; + if (points[i][0] == points[j][0]) { + ++same_xy; + } + } else { + double dx = points[i][0] - points[j][0], + dy = points[i][1] - points[j][1]; + ++cache[dx / dy]; + } + } + max_count = max(max_count, same_y); + for (auto item : cache) { + max_count = max(max_count, same_xy + item.second); + } + } + return max_count; +} +``` + + + + +```py +def maxPoints(points: List[List[int]]) -> int: + max_count, n = 0, len(points) + + for i, point1 in enumerate(points): + cache = dict() # <斜率, 点个数> + same_xy, same_y = 1, 1 + + for point2 in points[i + 1:]: + if point1[1] == point2[1]: + same_y += 1 + if point1[0] == point2[0]: + same_xy += 1 + else: + dx, dy = point1[0] - point2[0], point1[1] - point2[1] + cache[dx / dy] = cache.get(dx / dy, 0) + 1 + + max_count = max(max_count, same_y) + for count in cache.values(): + max_count = max(max_count, same_xy + count) + + return max_count + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-9-multisets-and-maps.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-9-multisets-and-maps.mdx new file mode 100644 index 00000000..a923c443 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-9-multisets-and-maps.mdx @@ -0,0 +1,87 @@ +--- +sidebar_position: 56 +--- + +# 10.9 多重集合和映射 + +## [332. Reconstruct Itinerary](https://leetcode.com/problems/reconstruct-itinerary/) + +### Problem Description + +给定一个人坐过的一些飞机的起止机场,已知这个人从 JFK 起飞,那么这个人是按什么顺序飞的;如果存在多种可能性,返回字母序最小的那种。 + +### Input and Output Example + +输入是一个二维字符串数组,表示多个起止机场对子;输出是一个一维字符串数组,表示飞行顺序。 + +``` +Input: [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]] +Output: ["JFK", "MUC", "LHR", "SFO", "SJC"] +``` + +### Solution Explanation + +本题可以先用哈希表记录起止机场,其中键是起始机场,值是一个多重(有序)集合,表示对应的终止机场。因为一个人可能坐过重复的线路,所以我们需要使用多重集合储存重复值。储存完成之后,我们可以利用栈/DFS 来恢复从终点到起点飞行的顺序,再将结果逆序得到从起点到终点的顺序。 + +因为 Python 没有默认的多重(有序)集合实现,我们可以直接存储一个数组,然后进行排序。也可以使用 Counter 结构,每次查找下一个机场时,返回 key 值最小的那个。 + + + + +```cpp +vector findItinerary(vector>& tickets) { + vector itinerary; + unordered_map> cache; + for (const auto& ticket : tickets) { + cache[ticket[0]].insert(ticket[1]); + } + stack s; + s.push("JFK"); + while (!s.empty()) { + string t = s.top(); + if (cache[t].empty()) { + itinerary.push_back(t); + s.pop(); + } else { + s.push(*cache[t].begin()); + cache[t].erase(cache[t].begin()); + } + } + reverse(itinerary.begin(), itinerary.end()); + return itinerary; +} +``` + + + + +```py +def findItinerary(tickets: List[List[str]]) -> List[str]: + itinerary = [] + cache = dict() + + for ticket in tickets: + if ticket[0] not in cache: + cache[ticket[0]] = [] + cache[ticket[0]].append(ticket[1]) + + for ticket in cache.keys(): + cache[ticket].sort(reverse=True) + + s = ["JFK"] + while len(s) > 0: + t = s[-1] + if t not in cache or len(cache[t]) == 0: + itinerary.append(t) + s.pop() + else: + t_next = cache[t].pop() + s.append(t_next) + + return list(reversed(itinerary)) + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10.1.png b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10.1.png new file mode 100644 index 0000000000000000000000000000000000000000..a0f0fc5153f985107a58dc37c2bb7ec47f4e7a17 GIT binary patch literal 37020 zcmb?@cRbZ!9QXIy+qJW=l~sz25H7AQ*&-t&8KKO`xMW;=lbyYal08dgWk$*>D>GX* z&(ZH$zh6E7J+D_%_nv#s`F_^B5R;=sT_$R8pEf7`<4 z)|)UEvT#jZi2zbmp2|7~7Y@hGx4iP@6*1qJ@+PrVSJ*-3lc{$OUni~NSJ$pxJ37nS zW?DZ{uKu|8@p!9oy^%_mAOHdWuxX%*vf#3C9PkJF{fl!Bh6MkmPI4Hpj#bPxFW1PB zc;rNcdiVQftIU^oYU1=u-AXYSf?t#bya)BGBh5Zf)_Q|GZ$RgBy0G{iKg!~E7WdC( zzYase&3=FGLWS+8i$hDU+PoAO=KV1zK4EsFWz5Y^7-|SC&57f=GpIDF(Uz#7bar~O zG}9jbVs|F|iv9&ou#5IRfsfc|u-pCED*Mqm)AI6%q4AFQ-U{A*3mxu#^JC_M-e#Pg ztou2ZcbPum-b%0CWi)oqi~6l@{-(^2 z^EgpqZ|CNd&3+NHm+2WBe>|a$`7H^~OWSX;$z$H#jp?SL`^6S_w?DFWxukTlHHbKh zlG|QH@ow8Gi<##+(Hw}<4G)MARaLj%d^Dk9RYpT(g<%l3iD48TCL{B^ zy0u(do@CEhACOm6gaKQF5kUb6%yNbEys8jGq_(6?%(Dxk4=!ZL_%$2TL=9}sb7`Nv-&yNFzSS9X{zQRbT`FmXQ zy`H4lE~~f_ArmtHD3^sk6|P`B_`%z@)4GHp3K)f}d;V>VXQ;aB||yuH->zIu-7*xBeilB2W8HVv8{?o zIA*Tx;!;Q|u70Dxi<b^?Y{q>l^LR&~W9)a&s?hrueAX%D!DeqomKLGw%w(CGN&0)0+Jd zi7f#q5B$P*_-owh$Za=*nd9K#;7e-6?_uvkS~f1o_%_bsJT<3jGmB{4?vwPj*+%{$Vj}NxH?5ZSGUwqRX3pH;IBy|1pk-qq9V}LF-$0?$XjAFA12PMY{p@Jwp zl3k^~;Fq@X1rul+{pd|wpu2uiBYhFVAMnSa1iRzcT5sAjEr!G7&DRH_ zkLm}EuPkMWM+wrN| zAOu^~K-HD&359Y&5n%yV{h3nPQEtnzf71La>`WuIDCyV67*b~EB?tGsug1#WjmGgZx$7k`F?Tep_QJvE$I zHG{d6y>EM=@T1KJ!#CCwSM>B?$N=h1g(^SWcDn1s5d1w`8UE2--SKLNlVD5{otd}b z?KDP0bL;-hpZn@3OOGeq#~mR29D+d1Y-+h9hF>vN)S>&tS&stZd`t1OzNn}u##O@9 z@5D{Qb1QF@Qc~v?$3@pV>H9~&eyaI2SqSBP5zRqU+`ISrg<({G*$c-GW{-*KUroqD zY%T4!*E-%#Jpq_6bWm(JE>wIsRoHgsI-(&-W&<9d<^3-E25=}{YEEWJ_Z>!#ewniy zdumGFRzE(b_-4xwXLw8zK17r}?L0j>>IuXYrKdBkCBLYJ5Hx5dS6A0MNhS;L&9+b~ z?JiQXcbI2ixTfq4;jb-G4|KHprS_P>RK^?AS8lZ3zr5D#kFX2BZW_MsVS7FzofUqD zjoy#_5XmU15i_6C&t~*^IxuPo!CsN4btlk^`z?b@IW*YqySfDnwiZ^d~FJAnhHLuXIIopv>WZ;?*O!3-8!eh;NS(G~2 zCG6+v$7}r$TjpN<^u|aIddY{JG(U%v{IA?2|z=xGbjuv+v1e zT$y70qqgMROidcxcL^yFock%#KJ|>XP1Ba$3A{-BfPFOPI$Z)T#Uo$Y32gK+-R3+G z`Hj=lBPZAESk#Y}(!OL)A=m{xvE>4ipRCn&@Lykb8#VDz$s(0tA<&jUwfSn(qAV;e z2Pqz@+{WhQ=T|$F!|)Navij`A?%-nI2q2GjoUHeBm0QjF^y!uibDII&bQ7NyjUSM} z%0A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 literal 0 HcmV?d00001 diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10.2.png b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10.2.png new file mode 100644 index 0000000000000000000000000000000000000000..9a10d41c365f9d47dc2f7f80b4e2e66c4af6696e GIT binary patch literal 109141 zcmeFZi9gg`+&->^khG0NNTD)F3$iDbhKgjyz9svpJlFw((d7tZjUDx|MUT8f~<6z@qV_;z5fZe^N&A@OV zhk=37_aHO)H{9m6ir^Pkm%IAz3=D_A(!ch_K@amXFa$HeZmH<_q|8v5-ofEi8m;XR zh4Ku|eHWT>=6R%eFNLpn*23ExTGadEF}q&+V{?YH+M=D5oSmMEAp0O1X;#U)wK)Yg zK$wX)jv1q`zBbN}w2y`j<-`>Q450oMbLgk>x`NT?;D zK&$gHOhZ^arl3|Cafg4n%5YBE=>_`s&RW~sYqvWaP;)UJN$6Q&siCMtd(Vg2!TJ%M zw^1eu*ZNrQYXlrDH0bn$Nd)M8(W>df8}=01{`}@S_3OvVpN=|5BE`#zI!p9MQdd0< z9Sh^8$tC&I?H@wydviWub+S5X+a|P}3B%Dk3I9|kl-0V{G&8IWX7^p-AA!`cz0zaqR2#}V7o(}CwHg`%=)cNjZO6s1UQPi z*D?68O7&?t>^#hFn#8?t_YJh(bj257Iq@Rv@k-cW18WEzZ&2t)ohu`hEq>#rLKCNnd*9(h5foV_m{fN)zs}oE;cCdt+v)T{jN?Cltk=uCZQm& z-3~e1Ulzvht={esHNvFppTRB4YLjK-wTcy{CTN8>M<@`oBAa;2Qe*S&j; zy-QR=m`gu`jb?(4If$PfJovx^)yO_K0nD%yKQzx$ABl@K9_Bq=) zCIxAs?WZjKE-~jdy)@#*F2dswOy(bw!<>V5Ha`2Wbm>wC{O4!wx-gK#LByK*kHUP@ z5x;c*nsbSV?=7zI_u9lc6#v_0Yi^@H2dwpbUy*};I7l1jUE^`~VFca)q7#E$s9~wO z|3dm_6N|p|#IzzTM7ZnK0e$nAf_vX15(Wh)FzHE1AK3Xnert2H?|nvI3|UphL3QIN z?XdTHC#)GK#J}@gejLiH;FE(jsqpJHSWiHIK>2MXn#Hl^{rf%yW0z=j)RxPtr}XGl zIIq(|113ik9be9DZTORxB&jA2Ug>7~d6JNk@vab9RWj);K_wl1vbTpPDvD4}@z;L# zk4<&srypD&KCspzGkAc=8c#&jJUgI|@LeT2SC!ZkD!LuZ7rzbT!`QdXsDXj)iV*$1 z=j&U!r+CFJSE4Pw^3yqNg62vl$mPCE&xU8#Y5LLDs?*9FzmF5=E2*WTaExAbp?YT& zD*Ue9475+|`{Q2u-EVS3uq(miO`2z6Dfp0c%Re=}M;oFB&ybjwCJ zvA3pZb4Le%jm_q9>8`9t4IHPge7&D?{j$vq)f)Y-B#Mp?z_kd*0et3y4D94xyPHy6 zduuR&+nl%yQ|=WH0jJ$XhU}txq_q9YyNdYQ`j;om%>!oO9_RhuNGj zq+FVmfX%Yz?v=}qseiv~rK1bQi{v;l;5UswQ+{(XTn}tas{Bk&olzJYB*poBc?V6Kt?0 zfG=YbmFth`&8HTtZ3EDF4s;ezUgz@MFg>Vn#Ti?u=?i$2`re1q;@3~^%SDOke$g`D zrgtEb2PuEL@rJsc`W(k_rd0zisq#I>?k!TSwRd3bLX=_XpV}i$P8ZPsy(#au5Yo&& zj`{HEKX;<|`N#ngolUj%KVr_8#XOMv0S8_9ChiBSHTKu_`_Jpmymwb#OQaCB99)>; zIn&!ghwYja;n+ZWhx&NuHCsd}Ndc!RG%J|(Fw(15^z9MoXLQx#-Zo!(*rz+Y1qWx( zdt)r2Y-4F6!9yY>K(E9t)Bo>}^Tx^2j$&U8BqlGzlC6$B9y|7Ux1NIY%z_F1`a$0X zBZ^G}H^M&5TDtJZbC9ZL@|ujmffN6_sY*w$J2!EqZ;xP;ICDie|DD?OUwOf!PWF5= zotZEF!6Os>;o%eJ^fGj6PggOAerUPMdm-xuXYQ2RO&pKX*SsnDf7PO8*SGcYqr-wX z080u)*Jv1=9KBB2Lu@tU@rv8aKS4Y0=6WoS^7xGIW)(z;3p|Fe2*$V6WgOeXi&(j2 z7>`w#9Cao?iVD!umQRcY9~!j1k{~}{zGUR&H0K8!72=b~O61Jt**t=M!{98ibn?-6xxmP`~E&k1jGW>Y8sts$f~?P#7LYiA{jus)nS_I{k0K#uaVE; zZ4r7fRmvXJsE55r4K#!H7__z6P?q)R^D+Lob1%8X-DC!QK7x)>8m3ouS59A>U3m%T zTH6wO$dhIFshN@RexozCCZ8Xql3!k`XzY zxhKQ<5^-~{8ZwIFuaT{U=#aL(y*4PEN=!c}W?D(6QiJkRPPF<6hH043$`f$WtzdgY-g5U28DUdo#i8pkbl=GVTT)tSCiit{7&FGF})0hfI&*lmqkefvwaTb;WiF6Rz9F8b-*?%Jj6%?eLWTeT#W zfOq(g*UuMeTd??n60SL&Nu946rKD9ignppJ~}my%KY-I)hCAmufmytHLutF9?>Y_4L>#QW<}wPMi3N&!k1gOw=*5LiMclh0_u z{EU3Z;1+^DbU+%6lj_4BE|y+4`bIv|Qo0wg3-ZS(r73Vy z;6rOhScJHB-MVw-hLsE;p|J!hKwa{= z1mfX|*0AuTHS9c96qgg1V~dWHv`v@a_pd2v%c9<(mXkT0gNDOS?hwYBMZIgQ8~cC$ zJ+2oQ&d_x8lSPzbcNge+T7p_z4?o`F@a{E_C=m!;7o48&>pu;?{qJ-?(d79Ouqt!G zjE7yoW;%{c-w7|d6z7qKUae%qS|&Z6Glw8<|A%|AxTJ9|7 zpx1;rqJN3h-|)r&#{>LzBNt)15_^r@&m#WBpfbQWku%2u(Q{vha-yI$(@$A?y&MQT zr|;2%a~l(BoL2teX___4rU8q$y}R|TnPj#ysVNSt357-yM#VYp^L@-CgT51~Dp-rs zHFA-oq4!kQ=Tg9knDQHI*S3HrVsVT}cCPg8Uo#>)8GC~jWG3?50feztajE&LN_{Gt z74;zDm$Y=dqA`Rk|KB^lWzvh#*zBrJnRxF%XDZV@1~Jo5PNtYx3r2?tNcUD;JD}%W zzIexl-PA|Jbj!RZzQWr6bH4c`SAXB>3+%2lX@IyN+^L`pc@OwbWFCr}*^u{~IuQyB zlY0F1x!Lys%$kFFVj)-HQj3gAp$_;bh{s9O09Q$6XqW$hLw*bSk*4BG+S&qGg0fWa zfj%XmpZ$eAzo)aky;#85B88Isw8yBvK<~-;G8}u!mcW-FW`=V{kI_ijqj5dN!6*OZSe^zMiMdqA7Zz;UN{Y3)kuu;{HS;aemo6?-K&H7-?LTUYoPXEoW|&^O^fTiC-~r99~?PWJorA%bn| zy{X@%aL)(Th_4gbk3K)pVzN>(2pm}2+F077bx$=N?6 zs`Dj!o&T`H!i}|QLY39&17S0x=K;Zbqwx3p*NMWO{M8@IJL~5L=leu^aZ?w&{Q0lh zXh}|B&dmG%{rzJu^!S6j8}B*g{+w9@$V{7FD_`k096pUdg_2lv40ZgeW8M|7qpA&u z#eMk)lYO|#JTJm=q3zsyF2iD76W@9W0=!LK1gE#6-}2o6B-X_b^zA`B0#0K21NXw~U%Alw(isl=^w2ePb4O2ck%h$vPu!MoXbEUy-=_S;{g zu0ViJEwH@_K|F%Jeq2Y+`uF_XS7=i_FsL^m-n8Z_QTu(}7&w;9Awxb=RJA=}?v8O# zLYV7?!7-7a07^4mtwv-UB`z-MOIpS`OWFOp8}K0cktJLw46mNQVE}70EwqDsul8Bf zrWI+Ro>kBt77mY%-(%Qb{?FFWhA84|Mb4jZFm|nnH~|Kc z4IVmQvG#tNQszBk?+nDT3f4sW)oIzzmH9#CMNb@Z5vbti^%A9>b&DRN^WfKsyx|S! zs% znk)je0!q~hUyh!;L+_mZgf^5%D!SzuCg(5D_ygX594p62K=SmZ$+Z?~67EJ_gT|v^ z%d084NU=$gD)l(g5^&TCszcgGXMCMXCqE7OjuI>#y(d!KAKY=z!NJ?!pPy9J#p!jV z`p=cuHd)S2NXMt*zYISZY zAvcRTmA7*4vFKg3YQ8ILRN=ccu8)>RWoMl1Pa3Li%pq4^p zb@~F@E|o7lBl(QJK5hyYca^GJ*z@(pamqtAKFg{ilTHm(DV22a5r_Nd*L!N~Nd>YU z^Ta8-pgY_L5bPdHx#~^8xG6(5A&**p{Kn#R^EUke>3%camv22XJ)74g;WX2m>#NiN z8ZmbPtB7I)m!ZS(d*JinDknIV)~g-!TclqQh;@hMi!W8KkI
    2~|66qSaf3sOSPl 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%0A@sDIkZYs5DQ1SxzeQulieq@yf#sRZ=trPH^Z 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

    ?fA? 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

    ls9~ejzoq+X~!1MR}eUp}1 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

      ZfB0 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 literal 0 HcmV?d00001 diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10.3.png b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10.3.png new file mode 100644 index 0000000000000000000000000000000000000000..bc65f388c9b7d8665823983cad678183c87adf75 GIT binary patch literal 72740 zcmeFac{tSj9|vlwREkPP3GGe`k|fIvofehtltS5xBH7Ydhe35pSu179GKwfd5|d$O zS}b+Qj4it*%_p`kB*X#X0*MBoL zTsVK_d=U|mg$EDpJt86^K@$-XUp;pYd=mI+5(EF4cmBX}_^(ts@=Ns27AbiVkx-F? zdv_o8Paf=)NU%9Wni%C-gc5$Hf!;|-CIL{sn76xn)LMTAX``#R%+0)V#)SI99?5{Qja?IQ0`Wtvzc#S zGJCpq#WGj|@{d8}Q|Yh26EQH5`1-rh@Oj>Uezu4v`t^4oHf{X&+rPh;mGJFHL_`(- z{E1Wtv2VYf_3bJC|BpWq-;f@IUa2(kLc)Pf;zrX2BGqpYUEu~C=P8GGwpJBn`?elqK0!{ z*ZPFl?u5?ecwS>xHvU1peQ-ccg8FO4`@i^g1vm!@M)5J?QoB~Gmh|3AK;y8(CYPd( zswN-A+nrG0;`xKlITVTC?k0JXwb6o+n5sbfRM*5LH6%3pXqN%g?-!65pIvupO@H^f=3 zwG;B1t1e5U&*~pePLI~v9CzZ}BmZ}_h5mNs4$33>q+#x6>K46C>C z>+~t$kGEHqUzh25)?gYzCX+joW??3(?FCCp+2p{ju=^%zqcT3IUh)3GgPv&({G_o@ z2j$~J&uj9YW$N6GFSl9R1)OmsPxckGoy)0stBiMp{pt%RsRcvD?UnPlJpQfX;4dSu zYw~eJu8ueNEq@fnfuaMJSOCR-YkyuLHZlcLIurpN0Z@p#B}x@!q+S42L}z7jn=}ScyA2RN3OiJr0|-M zKXJ136{^)JLBR^CvU`G?ZT)iBF1p0 zv+?4$pPTvo-EvxKY^bTi+?l`s`w?nOXphAI`Z?tDB$YHjWziI!Mc=&|d4%2ipO>U% zZNN4a)A3oI_T8)D5u^h@FUg}gv@7M%JZ9AXb&8;I&l#zK4sFj|)OYPlIHQ|shF3%m z0l8Oo*Y}Uz+7aPCHg*5@kpINTupIVbH3<%9EK6T^CGZlj_=di-#~u5Mj%9V{jr8Wy#hOAs;`7ejd*~se&A+^CH*l*w1uZuoh3fUla;mUj7+WNXu$&eWrBPj(!2Y z_k0zv^wvP~Hg`iT#r&0TMl<1_=}lK%SPzxlm)IrKcdNMPrlDd0Z%n1R;HIEf$|pRz z{iYo|tax3sPeiL2)^9UBP_}P~Kqu>bEcyIOvd~tpboxtm&jz)CgKi+zBh(OqM!S4` zOfVEQ6dwOtMz@<>f{l@!q@}qN$+p^oD zUGqvdwpTn`B8J6^bKeulMZDGmHhHQN>>Yb+`^~Nwq#gzK!{T+eFAfQH!@O(|q!QerA%zThA|hC{qiqh57Xc@=3DjjAu4?!RB> zQ95Kn%Im!)NF{%{lmGbAG3>i{Yi!R88ne*L)Nm}Lp0WH8+_GOT9FX;Ipf~xvKc2N@hrnqvs0A$Ko0oinY`y6iHIXuU6Q`WX(`cgFh4m=y5` z&5yi?x_gv_{>7LvI)B)2NLn&K|(z%FhFCOuvpyK>fK7ndvx2I$maL6u^wATNVk zRHfi&Ge#bc@(glZ=7Bk&lzl*7w|;5}@fWRY_YmLvcVAbwX!mM46?Ufdx&5!OpnHf- z&Kd2A((2k}ik|F+Q?9LUC~AJDz~a3vYPL%{qg!9_`A&Y&1ER-GJIf2UgaaX3^(E8@ z`|0i$P|2JD9XOzdlC!+v3ZKI?k@AVc-xk@6JH-liQ)GT~iNCpZ48#t*kt+ufnCg+GOzevrN&q94bp%A_qVcH<9A=$Ytv2Iy z#7SBEAg`?ju&#u|0Y0>fI6wN3RTc7p!kidJ7NG zS#08I1@^|A^wt!==-o$W{i)-RpLd5h(ObQ}RySu|ZHPFG9o=!}kK6t4%=0LPn<6vu z3NE_AlhyW45g8k1aX5bKQa*1j`~0fOcN*^QO|b&_e8(aMR<{A~^Fb+A?^@f_DLY(_ zjJMJgK zuTdd!56J3bY-xe)K)N+a!bny-~Z~JuLOAcD!c87_+ta)Vhve^yVzhP4jwck`t?F+vI&NV+^6j~#LFX?3Nt{^Z-g#c?37)T3A~KKiY9baI|`hIAK$ z_&%X_UW4|9w&)#Jaa(NS!3dR{U1^Z8%gezhI(ZL~oOnNgSetP7U>>GmDXl?*7!Q$8 z{|VETZ{Dm)iO(7x1wR3PLq~Zl*gqfWbKJ$jj1eD|8#?ReC4z; ze=~o9(H`59;&lsOsTS63ZxS464#ms}-Yqd+c23@jy#{8o67>=0wV{GqKXM^Y5?{Q| zdFC_8U+?NHp|NvR6|-df;f@jGR*4|5-StC zM`y%XSr3t@Oq~?}Pf|>mB^%tsLIp<+>`z@;maS`;aq{kf!&~dFFL73|vLPV~KIGwKp-FHl<}ri}gt{Ssp4ZTqg+4 zO%xnjyJzrdQsErVj>P!l9urTjIlLE<%%%XB@C7W@mD=LiwrFp^dmW-ETm6F{cfpC| z7rN*cw|kVPN;6%;IYs$6_pwtM$?*482b(7>PPjZ6L{n?HygOBdz=x16P8x-zt8 zQW4b|^$Uso0Monbh*s%jUs6u+o#3l*I-7d4_-oP#o{eG?DB{&nw6ZA9RE(D_!xZCb z%;IQ+M_fc>tWTpJGzhsGYS%Z57%Er*U)cz<4qyB38}Zr~RnzqM7^q>yY?1H&`6PJA zY%_z9$DJOgz7krO@*h zLybz*=eyMK2J9Wr&tiXA`_F~`cqZfz@aMJ2x?npqXEU>%f8D1}@47VS1->9f z$~~X{lHl8WvyRXdS4a4AsE*L_RNW`>LC?rRnVymBGTqlV#X9yst=>!jQoWDf=DJ^~ z=o!w+N?ln9DH7^U5vE-^jk^1vr?rR{MybWlL9P!LA!%m@QDIFI_#9cUx_z=0S7hzv zW;|(q#zFOSjSu~W5?%HvX=VQCO*B{>>ZYN>iU?KW*{#Jb z4kMq`LbQV+_IGNHMnWI#uyI?okWUxBD^_4lYDubE;P3-qvTdUkkwRS8U2kzU8jFv*qOFbGnFMa0_v6DEwr{xi5Q6 zc2|SMDl(VE{?r=X6P+9En=v%;IZQvGNDVkuaF4B4ek7k9?kSdd5Nz2GK15t9Dep0v*WWa7DBAtNz>Pgp*TIMEw6JzB znkZLB--MTKrM&QK}ET^GqxE!hVN?ZKsP`JOD)WM+QLGprdAk_9R^ z@QD(iY3MbOOR$iwNZY}BKF!b<9#_a>`I}S)V5M(HPnqm&T~D5%*w=jFs-*-DQG|jf zU$f zjlJ(#UtW^GDK=eg_L$1fh^ZL<(dpq=l0Ds0Lowcp6Wy|uU2%3;R)3Lh6?c6u1R|>M ztsJAy=}PVT5W2PfMi*ffmU*vfDj~j%vtcArMn4wfr>VBit|!)GWRKjU=5QG_=GVBP ziApWf^~fHku||rL1GLT=f?C zl`l3t%D61E(fAr1phmmzDxb!~O}>xIzWg!r$Wi~!kc}G~H=YO1abOoqXMgn2f&6t- z!vs%=KavNn={yT~ZNDYu#8B8X1+{>;Mo--hb!1JNW9v1^wtk(OAnpUG&<%xt@T_4!ioAqU(0L!*;0JdsvhAEN zq$GKijZ`+3uyXAA{af3&aTHM`Ei>d+JxbwluuV`0uo=tY=#)Ycz^Pq{wQ_e`^fP_* zg>0eNkM;>W+`?H_#S=~e0`y1$;$@yD0xFJ7r zq<9^J8ttr<&SHaX%fZ?gY7^Gsq#+|a)Eb?fU&x}`F3R^bQY|?>cIrOZi0r$oLXQ}y z=xFAFLii6@(@)rPR`8~@I2d*ARL2rXBTM$^$LNgRE#W=)@@iZXQALltyUI*e^Gw(M zfI`iHBYMv{N4!Qdt{03>j1>4wj2mKY{l{JXqS+*Wq&LUZF+2=;RGapZLC0sehu#E4s!l&{ZuO0>+tGLvz5doPGjtEiXw%r}<1 z*L=m=<9d>6$$G&^W@pdKrM1e%vbBtB%-D@bsfQ@8?=-vFO8m1OUl{sRWGu<=$Mv0G zu+(=!2S{*}qy5#5yoR1)%p#g$RQPDEZa$WLJiYG8p!g4`_vc~KK01D=l=qC(B9BCg z=~RFV?5IQ1wcw4BE?dd8t&Y(9e;#WYto3xAZ~vOY7UN4}0Z zFiIM`%l`9D{<@-Hm~siIK;IySE`2f0D8T@-+tD1)xlrIu;X-t}&mapT9YUvX4*K(M zhNdF+7pG)@2Tty@ZZT=b>-V=0)=_!}96rQTBG2v!3KSJdTLh&Z@>D1Ly?$DjT5pJu z8`2}LG+_W4?K-IXv~ZeD@Msj+-RDTci1#BwG9MGBh<*5pU6?kP39k*9%OtHyX|{(9 z+zXQKawK0(*y(=4^h#WjMEMW~=LDPZ9PCH$HkZqHeZJZshojoExPg#_Ahq>S)eUKWloc9I z<+EjN79karnE>WyOi;#|iD1b3yJhebd&dSW>~Ui);A8LFskOM~lez~BsXH%rMKv(= zd51af=t~U@GqZbYG7Zw`maoe>+#D)krpHtsv$Q>idV%A1`i1bcyD^eXeJENZp+G_7 z5u=KCTJ%*o9L~g&_`teN+vB5@hzKoZ7H9Z&Eu(=mZWjC{cJsA-$n2YD$Bgt;>3bRo zn<;{2o*`51Iri}$J;8JwSCeFS!=n?8>8pvhSAz)n>B<u=lQjK zeB^vjTtuW*vwtP6p|CdI=EB?l@|~T(s^CONm(Zx->dqa(rTDyGadX~i$;blaT=ZZS z9H>C7MG^_CpplB13bLwi#=vaY1T28wt>PJAGyEQHsffZv9f7sZ`^2jOtKFxT_l z5^4kX0;udw$LQ;UY+?>}I;{yc^`R?}ojZK~rs^v(k>8}Fh;uk%~8@&nLf5x zLL^Obr4QILZ6_-EN?QOUMazt8K*vx~IcmOev{8r#5f@HF*l3eWpYGE_0D(y6!Kd>$ zSpP3?m3s`~_RH8fb_7ys8i8V3(^KiI3gU)Az1PmQZQvXKfh$-j5?UfdD>dgm2_i;K z(Z((f4S`Y&5JxOETj|*$F#eA_L_&nKZFsb>9;##-NSz^35D+UK5 z60?Ff@GPv*)&_VTuU~D5EfXzgIm~`u9I~5^=UxR=^i(-gXSigjDI$VeLBkJRl2lD_ zH87)^gtS)MS>OtwbZ3Mh1?r$wh#k+q<1vo{HT7eIBOySiY&SWH@IenJ)ZaW^;srd+)*iSKDqu z^bu4!bfp9bV2$+LDqaSr)0P*jO((KWlE>a#TN1q6os!(M6>hxmeH)w8 zUi8jrF9oU~+3lsIi3+vU{5!>d%!Ngvc9{@zZQI#;IyMWRG+H5Wu%HRk&`@H3SI$I~ubCfUQZ`JH(RUo=SJztPtZ8IEzy&LrY=!eK}#qdx68|PJ)~dCxX@1 zT)<2huoria271KTsx;WX3kPBCJ`mo=lEl3=vOCflu2NC=$UMtJI0;XrU{w$EaP^~g z0zjQ=$A0%`E*~5Xl+SXe+*?kozWwW29lO*i{?ozB7F936RaoIpN{EE=W^taimF)Ax z8e7dTYJ_dLiW#o*+N-%q2WoKV>h%O=M^qEFaV@`W#29V{-f`I7M&m4F`R8>|rXf!a zpL;r8qd|?-=d;Yzw{824PrP?W;D?ps9Whcl#y2oX@nMsh+Tr;dl0!xF)GFu@BAdeQBL(=i^PNdfs?WL z=?r4{N!v|;JIB2f54{ZeOKZgBuB%n5eiLKUDG&io!m%Wnl|=Dbnj{8BpK!y5IxRoh8j6la$a!XCv7gNiibph|e|Rava;?yDZ6YH7`C zX%tMy{gHQXW4i}8#pWt@N$5r@$Vc1-XZ;XoV0P~d{J>k%!PE1Zqib#DpF>jY7;o$Q zDAgpm_oksm>_EzPZ%Kc`d3M=LR)b?7fxH5zW{2W!G^u&2h~Kq_tPyPUc!QH4f88ju zSKe%nQVm0;rTv((ff-bgllzPNS=>W}vof?m>zq)*&5Gp_)$z6)g9|&JT1c}mYpIl- zkCcULK6lW7y-;#9mG`#$L(=mvbq9?_8U#ctYyPgFm zhg7Z@$@RolXOEzF@i`5EX!sj0`(rk&0eg;f#6XDTXrzmL$o@EGgyz8J(k>7?YfqBT zn9BuG5}{~5(@?e8YWiI3nV$Yn@r77_rNK36AP8}xUGjY!(x8MeHZl?uQg(N<8CAv8 zM`1NeiN7r0e;<-4det9PK1S#sSc>>V@=$TYco!FdMV$O&r3NzgL`|~#Iwz~5E(w-% zO*47C$m+t|4amaoA`3J77zDMKsAZNm1=u*NLi^Dd;?m_;2j;W9Jmo!~df9l7 z>{B4wtxk)1{8BmfTB1Gg2q*VR5bTIjU8{cno#wjfV-52F9M0KTr)-?C8rkmA^msAe zLamNP=9$Kif^F~aH9N&=rKqN?rXV)Ez_F?_<6vxe8{NLWF81SI12ueTs{WDqvYESH zLJNFdHj6XGrcj6*0(qKhfvweup9=?jRlAtlFd0ZRx8-Sut-5dkDK)TWLOjWR@O^L$v^ds)S<;G@ruJ)*sq z(%rhV-K|hg%fn_&h=W>EG^-&?k~x<-d+(2Dg$C@t|NT&YVCR4XQj)nZOL}I1}q z>}zKHd0?u?nwfE-f^;SR!*B*`d;kz6vxd(pg5$iSlUZQqtb!*$<-~S-e<_{lj<6Ia z3b-p>A1}^I@jWqiaMaWcue^~~?JR~0$xscLdD@0F?p4HrHI@6%|G>h&h&4lN4>o6v z3U{1=Plb9&c+%fmft1pgbv7IlqB`qTuT13RlZm|0;H>-=bD8VZaAwZ@NopO1jb0~9 zYd*2XDQLW0E*Xt_ZE38G^vsJ{Djn77 z+pZ#o?)|Wfk&MYU%Zw@Som?bJ3KGK#4%mJ{0~v`T)@N`MP~|grP0E zN>s}e>X{1Ivo(TdO7=W|;$=k4L!vwY1Mb!AM62L-V{~sS@QPUF{^#h8o5@+%N4<}r z)P#ad>(k=R45&(vjO@g8L=15Akc6iv3&X!R7Q~p|L-9R%GA;b1%L!C2hu)ws|8`)u z7*?@K{qsbR`e=@Q6j`&GX`_eN+r;yuqvi-Es^kVg_lU?HN1nykByLD+z7uMP7XAK; z%(si8FncN7t^~m+HA8y!PMgmoL6e{Ehs2;9K3G!1UtYWzX}>9DMwRUM7*LIV){sq! zp{dO$iPkS=%*tydRjt6Cni1Ufdp{)jRI8X(Uymy^3)_%Z0wgZrMN?;LruT_G<-)z36Ov^v9iXocZ0&yoB&Osi9k4_i() z9qSoTPFZ?c!x^pVrJBrL@ZT2=a_;W+`K3hF!^7zg9E=6e8MFzT?Azv2q7}Pf#-zE< zWrBA8Xnu7z$j}C4Xh|xfB)|W<=6Dl>tY!aw3Gs`0b@;VhoDNFL*q3;U9^kcv@>5|7%jvxLgl-7+ zNoif8|9Az5^a(N;xt^++m@CUqoNZYN#J<62qoyMeH`hihh>9V4{q5@3yBtE&6*ufK zefR`W1sn??P<65}sCweNQB9>WLt?3%e^Q%xHbacx<5t++O{K4$hXH6&Gu?N_H|F*j>$D)tBzEx&@nPV4Emo+9(og~0pN9H*iKClw z^Mhhg;}69qJ4~@iD)k%^Vu$nRX;Q(YBZT$c8g=Sl(N?{7VZ7h{Q1Pap%`Z*NbRv}5fV2SDU}2bAYVAawf$-cIP} z?Jm4V298$M9ZNe_k~)4Cr{)LO+gAY$Q5oIAC$FE#v^QDWqsHkW!WJlAbylK)`iFSs zKhLahISpaWQn{vwVz9tB6R=P$^{Q3o{M2`XWTa%2Nn^x@ro#IEjw@bt08y?SxQ|OA zjqZOU)5dWbVTTB(3YzT#D_RO1852UltK{&LHO|>AADulv+_&i*&YDg4v)%+kbawLZ#{J82?p$i=al`feRc4EI;wSxX<=)5kB=92Kdn}E#wNZT3GW$rWJBywV8sRTFRWn)2}R=; z_eRrQAAirnd!}a6%(Oq@tWLN)u4-DN_ z9f+?TkQ%J-lG2Lh*5yD99L@54mx@*oey7>IgY@Zc`*XkOAJ1Qb)`0f`zS(@HfA(+dkDS7l zE{-VQ2gI=@jN5F3dG{QOCP91pF8{oI4RLXCFCHta3i2fN!P5ar?#0*b`8>;}w=IPa zTsTM-y#SzLsVP5%m%VGWMk7b&{PI;l=->YBX;}u<9qC-3fTMC-=J;&JUAv00vw;)FDQ7DpA zP5>KnDR2cpKGAmuJS7s!lD^S~RqE`YW#}%DHiKpIu}wKwQ(hodDzB~p#xeXNPoGP^ zU6YIoU@>bA(mTC?X5!Zjq*D9PA701wHZVJ^hgv?2aOd0r=4}ca#`B#K753`zs;c0y z8gLqY|FA2VF)r6qIlCI<_le9WB&!3ghRER0nm||{EpR1pb3b}(C{mMwMP}ibmxRBQ z>KBaALcq1#nn9(kM~6ctKp5b6 z0(67;t`uZB^#`#->coc_Q&0yU3Ci^@9p_x+1L7e)g#(V^$gYVSmvgw;tnuL*{eP%V z>d6P(33>Ntb)fJ??@w$&AfRVuxT&&^NbLjB4AaJhQzjxng^N<3QFRg;*kBBbJunD&5hIvgGafkLXEY#Il` z$wq{?dX%b@j{6~ms4+6Izp=$u*ZV>A=6J753|hfDqVQ9=GgOlKfWarM8g$91OSUG7fyu;)$&UE z?rs**5dJKKR}nA6%EBwULP;JDZsE?BnTCr1a@2{tM}%+9f|o#t#pDyZD+o+vwQ6aN zdxxyZ588DBctc^F__E#&BhV{=P7V5UkRCa?{%2R+3+3JjacR9LI>&Lt^9B*#&U3K# z_P=p}nk-a+;wSe>`*XFT#v@4KtR!j*PUZXfZWJm$(G*r@QYFIbo3uj+N{&K4HwO49 zr&|<0UmdoKA3n>yZWi?GUcA}Q0nQ#E&(X_s?8dTBDd(|DK4m3e_(M{vi|QxO1?%^G z{@^piA3P{Sl8Mw*0Nz6%Ye}V#L3N}YdRe|=+@yQ0odZ|%41>locpqKvc)&AVV4 ziW~CFOB+s{xpS;L0l+W3fRi;+i08YdTJpvWm2lo=05vF%2O=yEFV=(j+EJB{F3@7| zUDQ@Gn}gJQ-Psx5VWmq0%zpy_aG+m z?XwAE(K|(PLhmi3O0|$lBYJ|Y!A}|7>U}MUjf2?!-eQEUFpM~SJ%F9b^G2b?CeuQlH{;cH257 zp6NzJXBvEMIMNhE2EW<448RSCWp(%|=f@xz@TNIGzG*h+;>C-ILk#050{$LFAdlse z)zw0O^02gah%d8Sf~SUZTs|{W(>zFH??CN=luTQg9N&dG4!}pg#6k)W4|HM zxrj3%?fv2OfB}l1>R?>uCnD^>F>0dUPbz4@zN_hKksS2pt%>sM1|1GL+=vGoSfdD~O8_LmqXc{VMfGe9Aj=g9 z_l?s#b!}brd3nS_d}qoGqC*jw9swkB3`wXds!>d`wPTcKcdag)6BQu(lRk%b?eOVu zMEHD*A)GaCi2Z1)7e5Vs2oVT+t?t!b{*mBC56D758CfR2S@K8KW6cC5&p%$3cYx&i z9FL&@@$a#d&RsvNGD+Uf5Aq(Xv-hrCO-V)^#t7g_ffw<~nXv>6Rafi1t!L+{kiH1u zK~8|Pv$K81xPnun1HaB<>O92c5r8RG45!O|mv=5;Zb}6fO-QtYZ_7O%DXEjp2YS+o zSm_?S{Ife&j&!nv32kAlHmY>+=gV8$)i(pk|6LM93#>oL_%oR_ZD=QCG42atO#^S< zy38kop&39#yE5{+A7!eu3DX*IYRcRo>*(L_H-#{sbn5-%<4E39aojm&8DKkOPpk=9 zn!bZAEdcQM03~wFB;evd&KyBpjuv1cX_oW7a97YePdS-Z5ZeHbw+!1AP}u(56YxPV zpsq|Eodga3?s{K(7~MBLHS zt)0*w_MJHc54I=vBa%bAK9K&LMbBzw<1Kiaj1)h+B89T^KWnGwLBauDRz|D?bPc&< zFJYl|@+jdjySK37$g_il>rjpk8P2K>69o1BsFOefNwHzQ79d4ZB&!KWIu*4X(f^RH zPc!}>`Z*!A)*4*zlXxcXy1A+LgC3a=tXI=B*a$TCbySi}eh8R)=QCLr!;od~nFeNC zo}y^;TWPLe>HhS^NUIKB(Q4wQbnuNcy8HLV{7@mrRzsVO9JKpj8f2Ps30*qDlR5Uj z)2$AySrgFhaL}jJpWx*g^Mid^r$AFSOI-!TU0kwPzT3Ub2&FlFxw6gCaxgL#%n@7&6pLl1R-u+q1{ zMk8IT=t17gOD6!}fi|+^wlme2?9njq>T%PMhZM^l#y{0)IdKTyd~+JCOoC%45LS@Z zzKX%tLc_u1gPU$;>2pikfio3zRH%>nF|(z0_JE7k8BE6Q&hxhYa9ug|VcxO149U2k z+=9s1hVO+MK%#9I|36aX{a?lVFAMp<^8a@x^Zx~hkqA&>0s=ry3a8D2PF}C*Nw`ua zWo;NGFKZv%InZ4P@cx{ssi6ZRp<4naDr588c4m^MI@L!5=@FHDZdT4S-_0ThYkqQvf5D70w1ab; zYpxv+;h7r?-x%HxsaCn~S#&JjlLb)YpKN~52g}kuUoUiQgI4<*CBe3pW@wixF_EQd zr^Nmpc5I!+QPkQc7gePclc+zjo5OyJ;p7qzaZFNocz!HvJrP{OY!50-02Zb?6xmJE z#YIlP|Ic_5d&FOW7nVn=1+C#}wXWyI9mfh@Phyno0r}2U@cylaIIOc+L1gv1pByiO zUw;(_PFFOeL4P!n8OSnfOVaTyvU_&H$H)))A*KKFLyge6kr43ycpYJwD2YziSH5qi zKlmiegCQmI;+o7)@nhOo024|_Y}937oxV^DUd(SNWoyJTsJ3c2mzrH4C(i0ko*q^M zgq5*FPy9b0oyIOXq{Amufs@Cy_7z2q1}Uaq@1hKCaRf9qKv75J#oYh$c9qNKS(P=I z+UtOO%O(1wp8@8OspS3Jj$w*ER~4ALn-{~5d-Sk|BRt=qbt|N z!0iUF;l-`E=Zx11Sk99vC8HI2e0I-E38iO)m!nsSBV}T!Z1f5S=7?1M*Qd3@0Ez~n z)TH_gLIyJLSVX21TGrYDOW10Bw_)@}q+o%ypCzKV@6Wsvt+z5Hh(t zJl_s=R|87G+YQ~FK)Z)bt!QQoNVl;KFbqqCL{S6vl^g#=z^N;!YA3LdS^{qFb4aX9 zcYO8mFp5%%R!+^jW2(0iq8B5TqT6SbmijHokoFJaq$@=sGb^|;mLhMyRTns2>H~LO z?|ZhpLpz~$yv^D!E#JW>1JZH0Cuz|aVX0bq(23g-(kYTA_l+vRgTBU$c`^>Ib?GS? z+6OTU8Ykoq;I~qsmDmB|>ynUiF$0Tlfg4v!6eZMt+%$=M0y#+)lD-3r@pH&GtAd%s zp+et=@lsk!nfArpG4&f8>q4N5x2h&l10%dPJM{6l6o#z;{1S{+&gj%h1ZzV&r|qWN znk}j|>O`47e@W(SZ{>5Q7NtXSNJA=+nm4FJR?wmEAi8?Xw`eOcEHqWP>ix<@+%~70 zge?4Z^2<5${u^~fP`Td#a6BOt?OSnJUGOR0p&&|S>V^7m_3GQ4SclcmtpULP?&3e| z4-KG5vA(G&!D_Jsu**2R+W^}ByYWwSKzdW6jn|_~1f_+pBo5V3Ae7uyPE#YeaVVn- z>OEb7$gGGs9Bo|vGbA9Dz?uKe4J~ zkQu-k8?$0noEWI zP8yL|A!&IbR7ja-i*bn$WG8w9=zu)ccm@{|&y-mc8s`1@n18vGu!Z|L1Nkv5CDgf> zC>h+9Pw7Gv&+v=*>AiYc=|7&Q>Pg8KAM_mKG;sshzbwY{rF9Z>9L9$TRW%y5*96UF zP6B*HYG$og%j(P!PP+O)OvvNzvbPwWgFhZ@iTJ}aN{C{u`1YvS1+}RPQHDxU$D8fs zHP8S8Lu~}OdQHqEJ?W1KEz2|FonxDX{zPNrWT&6yVMQI2AD{Uzm!*R-PN&{o78Rxx z-3n=?xU67XCjNX7hte}t$Gxj?HCKQdzvd$37bFDqB_h@}bv~mZD@n(>9M-n&TPf_{ zbjURyAEa?#v2R)0Y&X%; z+Nw}c-?P9a`kL~m<^6cb{}fuC-zIIT6tXfjP>#uW?kFJH<5;+Ej^df~CvctPrGhqk=@7(s4vIC-o&f?U)b?BxD@H^+18 zj|AwiQy;pq$DwjlR{3KH_+}BJ#W&KsYMNw=m~TpqsLV`q zgRsOOzWR0kEDiGKD@?$1(%EO^_tV3-?4|b}tkZIF7`P)4eu~c*3lz%J7ipja9W;xy zc47L&rUY}DNFZ|M_fZO8B{O6sLfxI)iRT%#e5pnWUE65`?enWGcjMZG?dzP9y>H!+ zqOJK8@%T9iLn+WCByy~aq;3398Mg=KGp+qnm`U3MhELsVJ%K%>Nz!r`@*O^ON2HHT z^hlnTne7d+7N=$e=5IOn!B~cdu8B&fHRC~@)|o$o$YhmcB(!P!=sWdMUHbKxE)5rg z&xqJ&eJgztLw|~X2U>5Ey%qB}%PN<*=zT2+Cc-&V}S$xEYdvvS0l=x^ERPpQk()CJ5v zBh!V-`{`HZYlV%Iqb39H#Dg^xbRll@eF8MrfJ9Q$>aJCyxaAx(+;-m1uCv22YZLRE z2_}v_;dIP3sVBgm`FG=aTx||#X_0f#r{4b7Jjoqf^#ULKA`G`IuW6vPy&vlMdTPc5 zcVVAaI{SgE-|(2qzR87J*H$>|ZcmY3;FA0NSL47cU5EGfg6;N6TW78~=5ua4Jc$~nOBzi@;H;{_Z=J@&jI1;38PRjV+@ZY7`M3V?o436x};+<4O9 z832j{%K>^+EOe$S-i&qlx~1>)1MXF%P100{m4N_@ivi*c8oM`TfedJT4$O+|^CaM% zRBg_Ae8g7G3gJ2c*DM0*_C|&lV)nw`juTuIVNY2l}GkGhlCqpTFv5{_?ca9YmPTP2vYC_6 z)qi>?zbz)HcU=KO!(C#uburQ+xhi<#<47@qq=NJ?BCLdL=%>2BIV~2dGQ?1olg*QI z+b&9p{tKc@3;OAR5SFgi>Fwd)Q408EgINrw?mO6 z1igKZGc~$3gzw5>KkIozE`Cr{Q(q_Kr8th~5~69Ak~AFBVs4&g8U>sl&yghh^hNd#vX3}MJ}l`3FZ>mr1!fsCSUV&4qL>8PW|8qM+1Ok~uTBd{10Vwlh(rkp0p z{LY1A{q6#(6ltHk4#J^|Od9fUNa|WDqih-pJQkQ2U>5rc89A2o8yO+EO)~KI{6cSC zE<&P0+QyFx?TJaYcaNC)!Mhn;qLqxws>bmo2lqEa;}Q1t3z zn&EzcZXI}8=sS!e_xkb#;+I1s<$-jW81&~C;1~-BFUvx`j$8exV7Jz}M$NR4esg>{ z3>vyWpXrhdoNLTNrpqmVW^>Bk4LdZ|^x zSjmd5TTp9P+qwk|&l}09jE>q<858lkGKT%AsQQ&;)$@(Ab2oYrek)_5B&#-uS&zRo zuX=ILaO*00Ji)5$%iVb++4|uhHqru$cT|kS(B$o=K);4P#NoE(SG@rK{87|S7N|0F zqBHSi2H1p6DEu^Z()#nTyNS!D5cHn0kckYO9(z2>IY3yN+u+`g&&khMLvu^0#~5Ki zI6jV04~Ch|bz4MnAD&i2<=nDQ66VoVo&l2tLnhApkj~mQzmin5u{|II0n=idt|t`n zoNRrLadL~C$n!WbosB9J7ip>T^vze12|&%M4;+BIdUoy{EebhJs?W>WvNf7%S=YaC z_GOygCJ<49SaF0xaExNf+dKKVL{EH6=W=pN``u(HJU5NDG-$0(Y4p=+X*LO$L^um$ zkyGCCq*bn0mRX#|9x3xD_Pl&}xWG6jcOG<_GdGIjI7`wU2Dihnr*XK?jp|Q6e@S=f z-Xa?wk1w%u3mlpi%klVFD?G?nQ6*1w_wy^y<>bZI7E&BppVU>e3m$E|*#-Z4y0Tszm?fC!p_|Kko9R@Ux{mmB3J&cv4fz6ohmFF2&n* zfQh-nfZ%M%s?g%xFqKXkL8Tw zj31m$MY}b>6UCixd-m0l_HRBe{@Om?O0Ns;TO)?Ehq~8;B{W?#1HZgZ$!6;#zZolS zHff%xCzIkK%}n1P6%H&HESWk~zfSsynd;6o;CJ4X)JwC69*Y8KHl}iOP3jBZhxvjy zYIg!rrC^vifaZ&eBV(l+N9C+8B-Is6#>6e6&Gr^h_ei6bB22?&>oGz;KoVf$kbwwI zxgGbcVNj*WZFHF~h2hKEvvFpSliKx3n02Y{2{U4b#DHd5>&J$XM~tZi?6}IS(w%8$ zDJwN7oCi$n;F30&t@QB?GAMlHqI6K&2_!xmJD?L-Lxh{| zu22gu2(^15dGCzUGt7dmg7Cuyts5Xds9hx5No^#O^D>>29=t##*?f_SEUu5+p<2<% zS#z>~1x*boRxM}Kqn4jF2!ZiH-5nTe3fr+i*E7&nv#Fs;6jvGf73Up4Q6$Y&ga3O# zH}uHl=N)`-C(k8AcR=*^egn21Kwy(Onir;4FTAz@D&nywJ7ER}ar?{!3E$Q;@yKol zkN~PglnyFpA4ych!q}$&l5Rk#=5Id%^pA_o<|LsypTE za+{Xuep3-sJb3wW)r+aBkYC=*7ruOQ%|i?kcUJLbkC$Dgq9|0U7ZAto(%?NpFw)tj zYrTC8%#?Njx%$3mQZ4|Tc(tAAVvo@gFNj-Y#juQpQVYr-L-56WZ?mr5wLMlwxqJ-T zkdu}zvdHaf0fePfkrwj#veN0+=*7@$9`K13VN5+U0bct(r#YkD)g8Lkn%F)cN~I!O z3!M#>=P}jv($w_M~W7<`z8?%kBu@NO2TYnvK`H~m11rC|RL_TD?H$@7mJ zF2hnMRVp|bDhet~KtMKiQ5B(T*-J%0nL=0r0;si06%dg<1=u6M4w(hUX9szPc7vEG>U+i!l`N5 z$4iFEGDEW~?m@7Y1H$;MnO+G?EnuxXwYxPRn7DK30|>#eeKYlNgJ%-3>)u`s=*3wj-d5TO#$)lUd==Z)Bs3;GtRTAoiN)tB+V3GnyqeY(sJ8n&Nnq} zgZR898J|S2l<1fiSbvm3$vsoXV-)Pjj1CNRaPLF){UDRaV#x^ z^P^GrPH(KR|H}!uj-;j&91DO54MKq{>pU8EaGqd21&yt$2;C_0lQG|*c+|9)g8O!T zqbcZb@W3$uNC%$F9Hnz#(KNPw&*I_ccJmJWs1KqSt0<)l>JdiJ$F~CX?UM{ywV7bI zfd}tlI!z-1rVovWct>XGLO!62+||9#cc!>0|NT!`PF4i;-;k7#u&R~}DA-lLyS-U< zycvJAZ!ndD#hLn-Mlqqc-)MM3<~yRZ20)2np&tdA4sR7Ek~8@McOO_==a)pJ7CRa< zPvReRKxaR-Pkez2S(aF$?asto`J8^G!BC1}S`~tl6}pY{C$w%rp#({ZBuEE844ib6 z+SXGzns{y9&j>j?V9$ApHIKNfQ^Ry%KZ4E@>GobNx6_&2j7^Z;LTjvfy3e_v^zz;w zSw}qX{4_y{+PnG-(W6=-FS-h#y~QYZXNUUZOr1Jt{&l7gTmUc0Xn6yWW$%;d;$0z< ztXQWy{QW{F!fZn6%(()>jIBr@C{^!n3LiP#z~phvVSf*^v2XZjkmE70Ej0j{Tm=EW zIJ6-#0-QPHEp~uz26iRw7>f!_kK;>nQ#)C}=^aHGEriY)HxcO&Fa@R+pf$8{%&SWE z11uPys!Ra}h|+|<4-`L7F)ZJLv(Hq>zH%-s$ch3gqDuf3j^{TaVs1EVX<0wt;Q7G0 zMIdN+s7pmAa5FU_R&15_cTvib8-9#+lmi^e&)jNTU<%7VdE%&fLgZ?hFF7EV&;#~?N>5||i4Fa2l3x_{ocO>SEB~p1Gpne{e_Z_GA4D6A^Z@9`V$YfWkhdpgXf*=Vlu*^j0?j=-cI5$3y4|xJM_S@XfJ|y?LZrq9@4bmB z)%zSxrqbG>PKmT;RkjKw>jW;Edjwvwv=F{V#HfAYCJMqlYjyF$T#=UixXkWk`h@S} zJxvHW1%iwFaSfc{4Pw8g2V}jEIk8s9>0UT9pJ4ihUil)TwL6hLKw!Vp-M=KGXlkyp zT=O(H1Nxs62G29w0BxY|FR66Jf)~&$S`I5|`wnZ3#jh6G!~f9!OW-qN)T!`WpbC|C zkR<}gRso=BJ|xFF|BMJBtQqa&Q1sfrq8F8uv8~Zf0O5eTmzdtqi&A+vqXEPYkS)sM z6ON;C0U9q)r+$~|OvQ`fOr2Yrym~1Ju5A8MgiaiE&YFJis)cOZ}J@5hF2!Fc0-^Gu^s}87U-Yep1ti zQwojJV7Sn{g!Y0B@wF*OxdmkJjQOl?Zg2IkXiToGU5T&01_a2|1z1<-riU+f`#9ID z&BUR;{E8VJ201d-uRNL>Cz`;eeo~7l*aY2WM+ zjX*hXaT|g|crSh-o#-jTVg6iN{avh9N+k4!(+s&-InGp#aXP;0*)`r^sB*`!pYF3h z&PXr!)A1qtoPQ@!{>ZP7F~`N&%c1UkSj2aJViWM)qo&Jdj`V#wls~~zRA#kW$|U1v z56OX;Fj4$k;FhISmRI*vGXF#c`1x=Nn17SwT(}GHrzhjN=0P7l@e9+ z0Ju$|$lOJT(#C@=LtVmFRTUcWI`&poF^fXb{w9G+WH?NjO5g-evAz`5LA%@%%(fNO zZN7b*%?qD6%(TWdAd@iney(&yS7r$n*4tgaIF)$-cH>mjt`r3u5Td#8_R%KDVSIpw z=|a1Iqta@?nEJ&U(Zt9B6kwnVq+WSh5UydU3u$K|(}_{S!yD+}SW;8zjR}zMT{SzU z0zesR2wALg=v#QMH>Eg)ep zzmm2voGMzNHYoSe)#!h>`1iXPLYe%{i~f0B;sVw+3Uid|EO{#pD12;9{L`rh6u;iT zd6ByR*9f4d?*D~AV{r&{QX+-NPbM~>SZZ}Ci6?Rahf@a3n84QQU#(TK#J_vdKdhsb zGy>pXM%Fjhfo~JCZ~8Y|-`~Gz`7wbS)<18l%a7@QyUgD#jK7Z&msivBruWAHWqCC% zuckkQ<;!Q&atQHBp8Ee*q?bH3Q>CP*sU9Jyu(x%S!d^wMRufMMzWwfBKYt7K-RH(i zm1dG(a&AZ9X~=^Aw&aCm-eUP0IXWRg2U&>ku3eKo;Am10DyB4cgXafcAj124Hy!z4 zO5zV%T^Zuzjq`-0=?%p8l}}PDl5FGF=Qx$fZV6G3Sao4E^9xEW!rVg)pP+dYkp~hq z1He)g+S^Z0@Xmr4)~+SA`X_H#ec5keN|prt=}SIi8*!!%!XfEJc53_1)p+@S_>mU7 ze_}uZIdoiv|1Q_|M-@#RZDL0#Ro!MU8m*b{7jFU``fkg$^#V(@h5ry>Z*tg=s&KOO zt$jBa*)0F2nY+2vn`HVkF}>SmK!;j1bQX~h*3__BAj>2-J&ym$7EzJ^xuC$!pm4hd zOn*hQ2D!Hv@4!7{uGQ3vgM6v8`0m#&4{6he~eK5^wq6KML`=ekMT)id{mRa1xT`XGzRPfPpap-G)F&>$$kf z-hcCvLHzIMlX&Ed7cZccqNOuO(@t_GhpX@r0n>3pKa7?G7$pYJT=JP`zomWua>|I` z0&E|+0&IqAEF-W?e^Lb3atC3_35%RwI4EEhot zUzSut*SY`Sud9y11WFJCEDeitSvR3oCjlS;rR%y)|1QB-<`6>qgwfn?**bVONd#bD z>k~BmTfbo;j}N7U^S|BMzfC+v9WPhj-UM}D8kCaMIB;;c zuRX=hH`(gV>PEN^-n9%#uPT!RA|W3%bG^OOL6vI)b?iVP=xCjW7i$xeY_kG;-%~*3 z_``N(dwA_S1X6k6PgDn(2-v|jfE8Rh_-BD3h9kNr)=;Jh=(QVva!r3q_Q9#ocVeD; zCgWz3fToy-nO9`H_i&zZE5$1Bw)Ih&tx4KJ38IO5aR+4cz+k5xoVz9G-VIp21EbGJ z4VRD*<0H`}qSx;Uvi#jIw+2Nm5dDw#iEXt7$A%vDb2aT##%)4rqa8d*C3NEPO!d8)aPa#orzste-v6oin*Jv;8mw;TLkB)NzXE?*uVB%rt zCGl9uc0aE#&;T~kr#X5kYxog48&5Nuez98lOMVbMo2|Fi;6s=(z?A$kmn+@WC=&Pd zg0FX4KyOgn*`p!C=D7B<26&St?(ARep>7<2t@PhvE7cAq_d~#-`NMOvCHf8WkEUka zRY>fUhf`GrtDq~?C^() z1rc5Ftr)I)et%3@piW9A@zr-i*n$+>Gte#IgK8y|=^)cjFOU!@)6|k+ER)B5gZ&cL+jNOg( zpLZ^oP_AvtP(!~FD*8!Xtl_(@I{7Z;bE7n$g&{gO16=j4)XB^Qjd5~%+pYxD&wZSK zs@DSd6O0MYp3o9G&xvGEf1hVzug?1WBjF>Osmt}yAZneY&;sCp_6z&9E0wJV0LU)D zHNJwT!Dmf9#3mgQgks;T>h+&IZt)v0j*24E9Aj)MBJ>tDO#Db6;7;prNguZwFPkuj zwz4EldXb}luGj-5(|hqNXw4kbSt=|4e(JbxM#c=F``(m4ASTM!xFkc5{0DsMl}drb z`(LkdD5p^byAvsXHsufQjfb0-+S_?54U9b`fD$}=k3nxywUu2Z~NUl>)uQj;HY-n7;09m-tE7k~o@4gP=&vX5suKuvD zr4S8dvj%{+z9e6un2=d;Pyvg2D2DmBQ;L7T?aw2#rCmkjiWCR#=1L^V{z*wycKt$w zs#WFVl%svAdFjcOU8|^P#I*aohbkE%f`B(iveo5% zGm%Gc{9j%Csndt?3KG!ns6l@Mr*~^;glwc`#8~_U@&>k?SL>p-+tM~avBTy5~ z6ca@2yHpjmcx9#vAn#jHHt^*f%hg}OE$Tnt-OuX=KoSkXI=%$Ym?)PIfwCmPln&e| zRZT7h{`JV6YgUyh8k^;H4`|pVc-XBmb2(C9Hk7f{M{1Qn_`ezO7iT>11Vf%j1ZY%n z|1pM0;g`it4{wT7QP=`vr(hSLZUc6H$b8`eXbZ{C_J=*dg2EE``}~*f10kb-d$xaS zX8_uVF~1(-`WsP8G}hl642atCAJ-WoFZ^GucEsiQkIMzoF#a#rEN~Ql+c7_HUc!(9 zS01(M_JNq@@97Pq-uyP;e`>74f=STiH05M{&4;+Kzn=t%-dCCfPzW4oi+$EIf$bIO zH>kcvq3^&xaL_|s_PlL7w^ zN7ScJ_j7mx>~+sGFwpf|C#wB71OBH{JnXq(*70;#BCqTfM0fh@r~7%>i#R8LaTAyylpKO-Pr_)mOyu6&2m($KALgsR?hhR0I#vaST z-coeE9PBOUPAivm2!2aemvg7zHp}JQ>Aw~pKgo>$ZRPIMWc5$2?Y}P{E(d!{{l!lP zd^y-#4)&IVz29s1OTpeQ4jf3kPJm&9tRHlsDnUe~*VPlI~HygTz42a80Jh>U0A>(%U^Lkw*Hv{;+i80y{>9q?^Hn|q zm_(b@z1@&&_mVw``JSh25Yt%SD8J$F8)Yf6>Jt@wF7>ii705^qc(@nRvTOIA%oIpN zt$Sp33|>ez!A>E6@wSN2))F{AJ3%6Wa(@sqLKsj1qmn0K=khNT0Vwo2#pKh572N^J zDj*#ceXTwq<$pk)?#)9hK+B-*1L#AU*T*U6B&mM?d5!V}Cky#(Acv191N6|SefX_J z1it>;ifX)*2N+jWfOCT>j&|a1Wq@s2{>5TsTjvgxUu4Xn zz5hw<|LOX{zpkpzVmjLhXk#CcXAj8RsExuM4SK%--xhuI_5=m{)|-xhdPoA?3&|tRBSw5|+hSi;uj6tlwxuL$PD-i%e=2 z5`%C&!x|fyA?^8x4ym)^mBonsl3m~y_Y)$7Q)36z?s^|THxK#%frwyf!Fm%}S*0-z z41R%fBXvG?bD7!aJQ`mkubmG-qSsdgUL75DPlR{}3ZnX~1`(qixmLAI6apFlHBwC8 zG55gje}oS$^Qq%nnqwvO&cPS-xpTw7apnbJlDk}7SvxZSGB9^+_4(4(jxfN2vJXKaUhheXld~KGmz3Kew)_?C+wmakiS(*xJXCFa(JcCaJI9bT@6A&p;W0+#F6wMv10kHrW z2&o7YyT^mK;z1v}WB`5~D*u`n@Ys+oE-LHaUrJWndtbQ&zc;eR^0|Byp3bpRaoY zsNVPi5y;>Sbx)cI+)x&%Dj8N)i^V!@Ko)YTRWH@?ZtDktYa26WwRgezkVt{jl|^u? z{uK_DnBl!WF@#l~dCreGBBm4dHL~6U@c@uP3PgUaAmCO!m^U)8RRwtBd++kDS@VN{ z-kX(^1umo~dww3X9A7Bxy*j2;&O8Y;?{zI>%9{3I^^~enxGj+vjEz2{V*c9e7^AFY zSVx-Y#Z1TdVTu{|htYmH6ItPVJl~p)WV14{1p6o2Wnfro42)CndJ_}0H^qSrZdQwd zseapD}#0%q;FLf+>;@iyXPG8arv} z$s7dh9`oEcHO@H$llu?iA9!?bo*OB*ocielGr1AJ;L|`#B$=0}_bBibO8l^1ZY~DyizoH9n=>NuGYWCHNtquz?8KIXk@DH z>?u<}c|FB6?-#xM#1X~Ok=ggW{+qy6?rA{pkAK(cE{_#&oB=VHy>SO6208&6$!fNf zQ|rmv_L`yVcku(TMYT(&(w#Rp;t&0X{1AGS3L*fS;DeLxpe@Ux&Kxu>HyOFjAe6x{ zu3+f=nUo6MrC+yFcmVFGT|@IFO=%&pe_p zOW%Fyd@;3V5;-yJYgu9l3Z}h-xNl{z`~}SN_eNmPJS)yA)e{6KG{)Qm7;M;t8f3AP z{Yy@*I2=x>OYGAgKMK#KzoJ>f4*0}0{TEaEFJUAb@rr?IdpKV0-B-^r9#1mLS1{E6 z=?0N)fPs!`9^Z=3nsmk6 z5>tFyLbfVpcpvQptc5A=^n8bl+UrS%S`MP47m2WsiR0fkg}txf_Wm<9_4n?sTPm19 zKW06}71@kivZpLjXqB~!a_EhJIV^_{>SI_votXW5JUYS53n;-VMJGS+(VBnVi0tW> z+}e1`oPobS0Un}DjO)RjvxBLb!8r{o65w)Z_!^9rKPY5kPgddm6TU)B`G2fU{G^6r z8Ner1!Y>g<(gA|rwEHgT^hC~u$Uf`?Y>GiBewcuxsDPz_w8KpX ztk_Tc zL_^cfSMS~Rb4BKEdt(#H?Q^HUI`Z?XBOUpY{wKb>u+R~v9_Vo7rr+s%X&tAttpjb7 zZAuq2$7-SzY)5^PFO3$C4aM2^jI0+>8l?9phLES!e9m7+tZ@j4-{@%L@-#IdH1WRv`ou z&sVgmYmW$?+Y;MAJAyR~Tz51NdjJNqLPZDs6#;a*Zwp6hEOf|0n`HT>mY>w}^jlt2 z%Nxb=mcD#WEg!zi5yf(tv>ebbN9m|%zMOh2=Tpl`;&M8_T%%YnyewCf5L0To?zddb zT&~bAmz|eu>C0V@kuw%kcv?)fe^vX{H_%aDU*aL6*^Wf{h^j7|D~6L9qv zzl^jYA>OoXwvZT3Xf@AI%cI; zpJPtR_?=ShyZp*EXM0t+drr^zPvq731&7RFiCg?qd+{K@dxA9rQk@Hv9lndJ{%!H7 zt>?q*TXi3>^x6mh^GWq{Ok!POm9VMB(@_=jlv2UB%=%6xlk9k}q^%K3-S566@5(QA zWDf9X8u2eogji4bFP`C-F=|YuHEDCIG!~O;udcA3*l2j~dN~_cINTpr7rHgg(xQwK zBOfe*FKb#`=VG6(zs_XtD47Q&_ly}gH1EA;FM1lQ`TJ2rByMptijd)HIC!>yJQTORMLr7_6-BRSZAmpb3}5owt%ECDAw_ zhlmM6?@V@HmNfZ+-`o!yJ@Z&E{4tN(Su$4@!?F2fZJf5o1IYtJY1v*4ak`bk8sH(T zD`J=p6P4mW*JVApKEz0&Dtv9L#F^q@Gm8I+J;AD{*u%_tXJXr~M48xsfx4_~tDtKx zJT{wZ@Qire<(Ol)ql(c&Qynv-#CtusS@tvBvZ2C+uicY+Rq{Q#+yx=S5f^fKYE!1# zXhFjf#t}|$b52(F5{A4lQ}*l%?*${L72cXlj@uTRoL$_Eh>bM2=q23c)A{NwnzO%z zp^(3CbkS70A+G;oUq~4#*t++ac=&5Wi-D@FpTDAMfnc$|VK~-u{(N*1A%diwF+a0M z+^~!!WY`zivK~#yrNJHIITbsm1y30~jXIVLqCpan$kDgTElO}{WX~#3%>OJ=TM~kE zXvtI)+0aDoCXHJ64x~iBUM;{1P2+^+QR7v1_Sq*52Ma+mX8oKNL>{i877HZ;aaZfju+mjQra$p(ot*ATLm zHYNHLG&qf~H0+D!jZ$*9CQAS3bf~%?!ShK0vS6pJ|}m zcPW+~iKf%E!>X<*Am6p?j(C(mX=~qZ#AEBQ z#p7a_SGm?5NGyT-mC>B*AlB*|nk$4dIX@2U_rWIu1u=N~aLwUhk1k3cxwfsmOfo^U zFU0yVT<@-vqVcNv_3D(U8ev04qw;#?*>{xWr=9%iPGElevX9x|S-Sv4If|th(1Z4D zb$I%%F$g2q#n@+b%u~UazAH^v04-t!wEx@n6D^JTLcr43MVS(1RSRHcb0@c?t>M70 z%It9RC2dve>h&2j2a`DG@D+SsX^9`ldUvQ5_^U-e?s8IRHfGI@TE8dywFb6a#fc?y znVaIu-lb?to#}E^?I0b`>vAyWkHhFrk!l~bNF`bVyXT}@dGAz4o7vYQp4~3ww`cUE z#(etbY5}Tm=5+bm*8S@jkZtr~VS>#Hv?%@_iJa4cZ2u_7+)W*G_4x?+@gK$Sh4?X& z$PdGG_ude6{jS58PKdp^_$);|-3)wst?=OWcmrhUBks0P1uV@d!rrugQSIVY3u~Qe z^{V!B$F+D=L{o{GMNjH+Jwt&dfzzbo>Gg-e+R95_3>C&){gP(B<62Q0;$c7kV;*Y_P4VK1XwKjD@wx{p%7 zuXCB}xEU<4HVIUDbcnOuhyyR zXz>(H%ub8M8zw7urCDh8_48Zz0^w@P$0(iCTUvu&Mo-g1R|~5g zf6tiTOrvGaUhI!^wcHG!dyY=5UtH&66VB0vHgO4U;WF)+%_0BPR%~T#6*NSgmG=n~ zYTKz^iCdQ4-8$tk1MVSfLM}_)gwr!X^vmw<7gO59>)m**7IA>G{H}Zi z=Ifvn-_<(3YIxCeZlq}FUSwLall+X6Y2nz}g{d~@gsWC7RK7PAj`wQ`6gN=M=$9SE zNNBoSH4T2#$hUe@CVFLp$O29KkYObCs#i+9hh5nn#QBvhi15tspV>st+K*?}+r|{P z(b=9K0>u^mgUCD#h1LRNzNR)4Qm+Q4h1>TZnc#0Z%4`GV=f=9#* zNK%?>=VO4pnq5MVACpA3@g071Be9-IGJ2JVDqq(IKSoqnLNi@XLuC5t4F!pJ>tUg{ zmaykLZv3!TNC3P7$z*#%NpMzr=h$=6?kmTP)toJ&=VIF4uBAaNM^T#yB+RuJZ)im1 z@sPLI3_Z%u?%+_*QeofS>iFyw6Zm=M^}KThRq7dmc_H3!lQI+%Ay#7Bjq2##v5X!8 zrWl4^?ZvTB#O)S4_I%U6FK=Htg@_kDYiMX3&#qy(uc?m+SOg2+0$cCzt?#t&MS zKX0UcAum-j{!%WtYE=JFmGw|}iJ%WevqPTmy4~`eI92xTxdn&hnGo+EdIHK8y{+wt z>M?Ei+;%0F14Y*a-rTL<+T6-xM zR2N~JuA=zVJ~SH%`{v`F+0<>Swt7(pHqbHsnX@_Cvvi2C4w}EgbBG2I*JsZE}2?ufdN7LmSB=+!aK|8kLB`rOgdjFk62HrZ> zYI%BTIh+eyfX?O|>scYTb4?fGeYpaAGL6B#QLE2wdm{dFQG3P-QlHqCn7bb-kvGm+Bnna&(;@i zSI(UiXdx~zToWyed$!u@+@%JfC6$U_-tG+aoz zbp+MRPAaB(abf+leZqZ{gHdB}gNtSz`CGUupU+l3w~h?=*I?Y&50PLSJNHb6r04IA zWHVA)Dt-CCwLa%jY^h5$@31dE%&4#OR7}*QM-$D+9O_|*3+=ZFbV=lt&hC=2$X>M| z?OAxD!)L5CR{L3pjUNwIrgWqClwP+(8JE>rkK0#tDo24l9jqX9ptqMKJaf@cIJfFY zg6G*ao4As0Uoj*0`<6~?xLfCeUO;Xk$F{aDFj(5ync}|EH*Fr&cuxx%!}pk60x{uYn#2ycczVg>nPkstM z(N>7XlGe8EZNpfU)@G!;&i8?)#FG#iG@FeUDxZsr%)gtQI;r^B+l)B_yKJ+QUrzRn zaIxW>@EdzJ)qgRiLp-x|x|0mP_Y<&9{UVA2nVz*Yk-7FN1FV*azL;?W z_Gvy@`5i$sXJqMHGp8{Q&+tjpn?_zzqx`Il2smxS#k6Nt;l2qi3z&YkCkx*p?He3p zwV&NLvMHTun5k2m8zfc{z=)kl-Jck; zq+`I>gv0_U8215UA7kOX;WQVMC>>|%LB_l-Q(SuE;SA-Y#g~T@7M1OSn;gt%1yA6e zJ9mgw>FpPTo#!>|JSCHr_L+CHPWfbHt%fT>H$kh#hj-GC!K+3l(of)% zT5YRauVbEO_y)uF1HYjm$mxe(SJGBP^$fEtNXie13L84@bG#kwDjn6kt8syv2;0LQGR%x=C#K{K&rH=%?-d!O~|0u3@ zu11Tv>IFJePAvBB%tv|#1oMqd!NTU!R%$!gtjAtSxaQ`k$Rl`JE1Za^^a><#JSjB9 z_d+f)3!+~oyy%#F9YH`r<4|5#?{pr)Gpj}{cE4)K7W}zB+>F#v1{}jjbAFc3y!2>7 z862oHZ4OG{Nf3_vU~A7LoF2hkSYhNRjn4Aag=pM6E|G%%(gy6?x6KLD&-UU;>pTk% zVK!iInRY+uz_)ElGM2iR6&jmAX+hY67xh0%w^hK4hKQw4*(#FcLegq9hBv~sgT zwWlcR<4nOBNTKS^;8}0?;zd38QFcn=Ng!qJoJ$Oq4JF}(cio#wZJk}CoIq}1#rZpe zQ8c0O`*fm9Y*%+OQ_!=7B$SE^o)_%Y%;|{SMSD9d$m>7*DwZB}yD6rsL(mlCTem1$ z6}1Jw-L&kQZ*ZJXf0QXnUX59!=k&n5@}h>efleDsaC0nEu*)ImBt(3|XULfTI0&|t zoGUL*TTA$?^8hIZ#ncecnyAgPoNF>KM@I$bVO*OC#HIvy)*HDS;~?RZtbEiVzsG}c zl0}MeVTNb={(_}?R@zr$6K3zY_z#)(6{&q#AM$9DDpU1ianFbofm+a#?xa70=~qLl z2e=%~T7Mh%4Y^xMc6ZQi^^h2O(i)8YCOl;suy%9vk{sS zOnFm#hki`=REDSdq^%-dB{$fa$tF^(jnb!-U8Q31+7t>#=rl?Gf}cG7K(uZBM0#tk zk%sp4d$|0v5#YkNG`w(i?98}{em<@gT)8`ZgC*Ay7E3Fs)yjsd&Y^y1Nb=99v=M4` z3A#gz@IvbCCP7FwBF|*u)*{Z7=#K2uB%PnoXa8J1`DMX_P z`_M;<4{V{nx#W47J>$<-+Mh@j>K_Rl36(jJEooNpRL7*38Xi{d`%{TXZl&!_#BC*r zWY3?gi=U!XiJ6niW#iXn_K)#b*Sth(3KX#$TU_tduXNO?S|MQe{Rs80rv&9)RF!tW z(3;$Sb3bOzz15@=(~O_ezOKD+X`K$p#rWoG+t?f&0-Y9Xy6yA`Sb;HNdYh9mz7PXC zP76gpnr+Q5(;p!Yw}A^V* zw$Hsap`NW@r);THU(Gz7QTUV4ElPcKbKIEiK~<%hx3lt5E|4#jmu;Sju7EP8znNWi zZd+_GBbkEfkJ%UUBy$Q=_t0Sa79_{jjax;;-b1Es!siFq#d>bS=U^M>auj2Ah~nxR zWOgD$o3DY-E(BB^_TsnuTcGld5>h2hWYXuz(JSDlsOtkIJP`TuEt^1{5iA-OzgduCjL`^}T z5Jz4&ZvRry784YQW!6un4<|j=4##A~@!1NCzjziAmqfKG73_lnI8@XDYCrU3OY6SS zN9Ec4GG;~;JVrOVh-@>pgC({#GF4Xt`wLs>%@~|6di(ti zd}3Jo1bg?i!Nj`a0gbRZ?3lTe@Ueg=E|`aZe2E7SBm3ehAOtt9H;ovSO^9Mk6cHv7y;bV8>a{@-!k4lAH#@C2;XTD!QDi6g11+|wru|IxG zNBF(p+K=BdZgJ(qWnd<0uR%H@DO$5Ssh01JeCWbefs#b5gRSr@U*tIy4P~W24A5dg z8PuBP*k|y2&zL$XcT{IV`qkhxb4hqgb=9wr`Pcj3#Kn4W#QH^u-w(-o9X6933$6Kk z>AIS@hs5&lwJZz6!YU?Wp*C=$SNo3V4)TRPp3$~v$>(Q5)XO^j*88WNI5CMv+ib{| zAXS3|QpX_C^3^Ivbea~vW);KU=!!eS-d-zOxx(qUd2wtMu!3F$o;NKtLby%jsE4D$CF zmJM6~QXi}IrV5$^pUjUCnM9=!m-4|UuH>#hi)6*_vsY7zO1sbKd7oZ)PZT$Q9g-hZ z&8=OpE!ec?VcJpRb(h|A5quGIy)$LxtE;6S@e}`Xk^FD=xY^_&moo7Gv9vQtv<=>d zSz(`9>LKrW8TR+GKnUIG_*9(6AMeKQ>qhomLC*@P2}E~VQ)^1+VE>j`EmL%{p9snd zpR7<3D=qfeUdDB(7AB8+_SFa)qCQK{fUflmCN*Tf16EH`{KGhqXCgxd%9DO^G_q{? z7cywC*-QUuUrCo$a(0-IA~{Y#SM* z*!hSlC}81rE*D>S|Aw%MVy_ozvb{=ZVl!bYb)9XDHJ_CUsVddeq*k@K^ z&8?u*f@;?LL$GP@(W&TJ@Jgr_RS?UdO0r)(O2HS@QXHm*n1Zlk@}J;>rMVd>uO{E; z#a+xXxdc*g(gNvMZ`Fn`2!?o7h{g~n*o%Ga)V%Y9DAX>5Y}G;$q{${B@yUu#%-CMV z_UWZ35VEHG!}Kzym5V07ngOw|yp9_vTp@R3i0S+p^dAx-1kvr#8E?5m8U$&ecHdxu zQrZ!Mvhi9?80k7Lk=f@q4i_vv;1Ee`ZdE0shtv~7S4^8`(qZ(?YAF3=%P^twJO6A3{)Z_3SBi3#d% zAia&D4bFYP?sP3+HwUt5BcM8(-(xvWi5`i`cOvR3th%<8f{ZRSt_oY zyklReC|`c=OLyH2P#~01;<+|_)2`>;oxs3~dEa0ilea9v=-u_yY7U>?n<3hRK3c?0 zCwDh&B5)g~$Evw*h;<2Fjn{bxKgCq;@0XHj!n{8jqb3R7ST<~HEuj>;=yoZ`MaZNEbbayJ9I@}zBYYx~!Y#zJ6aM2!&-n=`(7 zhu&lIUS$sN%hMrZ%{CgM^au*L!i=jXa6?%jI1B=QC(0JA`#PF(mELTPvVQ}{UP`MP zYZe@>oLM)2B%K&)AB2aUf`D~uD7H7}(`5@5UV7F_r5)5FPF>E>mOm=*f7gCWe@BQb zyBS{_o~fRUy)kUWS@q>miNZnLnCY%iQ91q%esa#Cq~qyXq3k|0Q7Q&$wq?Rf z-q4uCTQ_rugqya`T}-=>An&gW5zUZ^BwloG+&8%X{##b`GbL|I!Cm6%Aq#qNcZEt%4{G7HX!l#hu}EXrP3Yc4rY_EKSr2BYDvU{pC|`ESyA++% zW|2CaH6j@spxd^RmU`(hUbDP@uGX;jZRwbPGVIU{uLP^+b*gFERe5^iiNw>KD&YP2 z$(z7i=BR9F9N^-J&oGtZWcf=aKu3=~>RA`Z#VdIxzl$jPWQs3|vfDnU;p;93iiI#PJU3PVHxkI?xZjd9ZXTRW`ygJ^=7E4_V_X4(k7+C8@ z-}3`F!@6O$#rMe`-C6LInUf(BffVKG;b&ISnDH0Zy_;?C$yK%)OT)Gx{&B!nmR>*b z@sqL8uNRx{!GZH0FBp81J?>d9K?l9odiB9aa@0L~d(QBBe;?iXUf0?#GQKVjPQ-d_ zB>*5I%bwNGRVvj!DDmkcb&Bh1r3`VqMF<-5OH1B@ZUIFsT~L*xwlH9AhsR}TWOQS1 z$W2viM=0|MeoqnfGb$WhZMplFbgA2ps__5g9BENZ5JR=VnH3IaXJyD)3UlBhSR@g)Q67j@x-JY^mdAO02qf@sDWbf)#w(3lLUpL4 zx){UfK#NKWR(XQlGOa_@r+1?q*4|%m(|A!^X@&y?gVvzQCLs5*D|boODO2Ol zjDkRDqWxuf1=Gu7Ga)z%mn_R|~c zX@#NOMU;AZqGa)K_K8A*qth7(%{|{P9@w`(aSTec)}S9MRV9eI?R-=BONRPPcTO7M zR0u{3Cla{75L!dC&nUF%KnFC^s_PV4Y4e>S!Pj182pxhp?_Dj^Pt9?;9b0#ErA9s! zX=)#*BB9cIHX1{y6xZPo^)wJawU`rqvBsEtvPRD@+W{o&$fzR7gh+t`Z_Y1e@RyPt zb$i8Xel+OspkArR1Q0{_?PfEt1HH`(P)Tu~zP~xCu(*5EFSno!^K0VvNzM5ps${=!=hkxZQsJq96tuNFV=fOXT|a#q*XlEuLS$`M+0W z*sM_b^?P6a_KM325{(=mzp3@xD*{rDudMs^2RT_S{4$Vj!WNMMB|tgbhB%u#f3&OA zeVHq1^6XK4ysBqSyIHFT=nZa8)p`5!`s&y$Wx#~k3;8hTm{XfmMxq?q9k*TPj4Kt6 zV${m>WQ!Qe&$IJ3ZXSC2VD9BW)%3<55y}{~?Ihcl?n9p0uV}2_>5|9rbHQ3kvFl5) z^bB{+m_GS(9>%dsU)9R41?NS1cGqI0^ljoV#I-*;GUt@3*N+7ghQ$s0+xtdsQ$on| zDRi?+^`l*~`6aTQ!DM??VrgC_V_zuGN1016qaj94#_=d^=!e` z;F*hija@mXx@O7z*)mp3X2c<0)n}+`xqEInM^Ab7&b2zw@;xnGKJV&sh9yoaMYn3diF=p6}zm49_#toVWBc==m#P4x*m}{fu?c@{A;x}CPQud zV*RD(ng!WJ(9fQPSDiR)yL05o$gW7U(j-9;4U18I9|s-M(_f&< zJhmG(_aci$)FH601NT!l^H@`H&6MThWF$F$%-0rMyQp`ma?($)GqYrX;A}TN5UqEa zk1w}>mJLhLwML;eJI~Aq2g%*!wevf&_2!}9YSIfyVgwc7bYxoq)wudQHeh5*8E+sQ z58&dxSUF4*W*0zJjs8`%^HaRFen``>ro7=eSUu;&`7bi-=5wRDyxNL;-P7qSI*8I^ zGgs`lh80%Udd-20ujM-L)^AT#wk8QrJ#wuG)xIa+a3E>romZ6Aot5qoX-6W_WP)a7 z#Q573ja;<1li`+2x2hRg(@jvr0y|=FscI!s06L-(sH#pzRng~0b()^2|01sTeq~)x zh)q56^Nwd7ONZn~vtTJ9d-{r3LJ8`Eb%35|nWsWW!5pDs?hQflkbDdhXC@pg7k8<& z^zZOY3R1MIw5lX$=iN{rK1W!wO6Po^vVuZOce@LudnNPb>=|~%=8bfF`i#X~QCoy* z&!7RpPjRk&*k0ZVJ^4t`doNZVH|eQ+BA8To+3WpkOQWU!3ep}`zGB*%NjTOA3h|w{ ztH>j^NFz1^(%5?5pToC=71oR(Db=O!`vic6dM;LCZKp$gMssbMoo!``mrupr3hAaz zfGliD#~7-kIxKd~3vbTP2N+T8t=n-tQDzscttVBks0rjkA7%8ml}DvnWhZ1QXL@HV zm81(b?5wl*36$8UWgRsJ@!QBkkp(=PiJ!bK~*%Lj7n_R|Wxp&7-epF}hk~ z0TRl9fG6~3%yyoCm!$rLr~(F!G4*6~h(6fL2#*yrp9RDTO!D&>6O&%bEE?oSRr z*Jau}8DVqe>)UkQ>S3iE&3Zpq(4BXf4y^-a(kW#tWJZPx}?uki_KMY%l8 z_IOM{Tx>7I2lkaPVTS$3AW~46Yg6rhzmD9DUv!gSJZC+9e<@XSiC7tVQnBM9_RY5m zC7~`;2tczrzc8@}G|OXZq6et)RDhge$FGTWcfZSmIVO$Kj9GATin*py?RVgmxRMWr zc;w*s3EL)74~i+D1<0fQa|{rD*C4|VQ>3r{gG4A{WF)AfM%;}YxDxwv3FnpFpfa?7uBBe6zs4hdJ_kE^zS5Jz7m+JM z7z-8mbE~lvYRoykBkU0KKIQz5FfGTDn!WeUe!Nii3`!MiyA?RX?o32wVZ&m(A4V6{ z2-$pp$e^!(w41xa?3@0xkvM8Ds6~&;c`|G)W4O*)9BUjsLEn_8XhyjpE$+!=UkMN0 zs_F*`^?q?o;nxjEE~_4m6llauj3Y!%VYOGy35)D{OP-`^ZUXFdvy_8LYo($KqBZ<5 z?_HosnWs##E$_5wr<_0Vf`XbwIo^^=+jBDs)r(!|7lV)XBQLpL6GYD<+3o7plLp z(0EU#R4rdvCk|7|0!(6e+@b!7OspK2>oLW!?ffrF(|U)AyxB{1~V9SYrJo>R4f` z4++1i=jbR{qcCm&FF4~p)m9$At@8CJ6?Hk^RnW3}abc~V3^0~*kC-csnEa$J|vz;u8FuTrSdi4R zAM0F(g-xT_zpJ?E+>u=ow!YT4DWz7g3<7P_g#70x2&7KAD^WACS+u zqCz-;9UxSnK5M&ED_xKA$HqHoIn-??hlYbDbO!Dg8&Se|dbo zfX57$-x%|EM>;ez)B3EoTevVe&)qLW?Nz%SXE?LR?)@pi%T8;|d$=BZ<0A0KJ6>oG zvZ#8_JU~;2oGpKR(8GWZ=L`PE`%fQZee=tA1uE%RDI6zxdP098o$+szH_|x$fNC+8$rCs;P+B zXD&Ykq^+`dbyRhYn5jP+=A>QjMQ;PNI{GS0*qb7UNl!Oq$OW{8G`dOq&F!QqxJ2_9 z%Ouq)JDcAnOhoIw|FnPLrT6U0fgB5U7^O2J+&`f;Pg152uAa&ezTITaL|1cPBcHV0 z7z;%1B(J>a>bwB%2PDm7ubQuiZQq@?Rn3^a-+C41Ktu8~#&gfWv*dM`7Y&~D!mc~i zMk2iH%x|13yGtzQbr7XW9hfX#{p~V=EXXYnTO$F6g!)`v9<%n)q@GF#K_wx@=w)T| ztfN=p2GBY-+FtM~Vz90ACvCe{>X;LV!7&GmIoTxC)A&NXoV16!7DP zBgQ6KSt#s5O3o)m}4k@)b`xa4T09B##XX zRNCQ>mi*&!8?-U-ShI`waM123*;X%=^~>`!^3nD570x}|3FoO?I{ zhxHU+W6lo&S0zX<7|3FxnSLUEOZHkphOa-#;fpBCp>R|?e_JcPaDSXRBzX32+AC-S z$(|WrH~fHahd1=h^C?r(*Bvm5`-ocrSAQV(qF#*2PLjQU;8p|z-_s0bz4Pdyof%&L zd#|uYT64&N=$H6j-^X|=Lds4tCH~_4D(U+XEib|BH#FbZC6iP7xfTr50Elh*h9XnP zr@T@Vye+kyu%SNa`XFa@I4vO4xPbFsuim z3C#yGqF`cmzP-cQ;vYh^BP@hQJm#Xq8;R-V2%zBnjHy@*ca6Cx{x(vVAj>t*Nc1|NvM z(k($#`2tjSor8HrkQ8n*e?ai0rK3p{fSGS{eg3bBkH)fVqO~l z>@dK!Y1h2HM&vt_;-i%0&g&(5`6u_V!=!&n`81TpK(?_Px^(f zW2xBScp5s4RnrvyhB?oC^i5ra&hM%+X4~CJKkxcHO%MBtvWxSbJa`N5_TL|5fKZZTGym> z4vo!*$R81&T|6I9`FhlTn0pjAZ{80}oBtP*dfFzNGR`1|yckXhaGSm%UzH*i`BW zrr@+qlQ{ciOXK|5C#n!SMobh9Xz@1+$5LPnE7pa_W7NpJT%XH1bcULtOA+VCnFyTo zMV_zl-yb5!VtkuuLj!Y$7EhC1Ez_1MJqhs{xtDGj0?pu+3a@dpnrN}P)f6|@pjjdL zO89i?><9x&fG=-@^Z$At^$iD*tnDtxbwkk}NQ?trNUjfpq04FddDsMbVb(aHIg zoQm-+aYKLF2t!^t_KVN$Dd~8hMpI_`-$6e>M{-jRs=Q~+0C}pKvpFYyK>pd%BN34ex&=&G{eW!s>$L5FbR&W|}#zd~ZOF-qzod zcZ(K-3{ya%i@%E5jzp#5E+Zrggm%Xz1}p@{Iz{>TPZ(!&QWof_|Cs->+=u~+Bmz`O zzD|GhFt)Bsn5ny)!tb4`?2?Z6iGuPwt^1WgXPg8E+QId07|HYHkR(dUwUYd&q9MWFSw2pk<`}50K;tcUZ}GI;K{taLDY! z_X6wG6uf_={C1CTMB^;P$G8P-2wZ_*N_fHRfcB=t>sQFi#i#L_A+Lk7rv#Ire1Y4~ zdojfwJa}H**x)f@#U8G%iS%I!Rg6Vs+t;Q7ST88{c+cyf0f}2kBCb?_g(dMBkK-+; zgFo6Z)Kd)Upd!nYr$V%noxtwxL85$986oTB_2r5OhR3qhE zd(Xo^dNS* zDDGaMM&NT7K^%Ty=&61E;oE66*;moSoW+WtFI^50yJ*_!{KX(SozQ7>9w)%#mDz9^ zDuosM%@IO-xYkHt+4mz&r2%((2-{B5PUSBK-xVw5mV*FR z7*r)aO4bC#9EXIV8-=N#N#VoUql_;Z9T+p?^l|C5EK$5>p4n$6tC^L+WjLy8@4vS| zOC12cz7gYLz=WyMSS7P65`E7~PcIvYUz%0~ycM*?py#zXg620-adrC&OBD`zk4o!s zl#OuUQcW?xv>N&C<<$EK=U%B0p)q*9Y{BzMtD4=N&uVT2`{AFN7FAmEFsRMvpGGSIjF)WXz*W(DWery_C>*r*SF!=GrO@$!7Jx>P{RDCUG?0D?^i_!;WQf;XPhNa+d=IO8b@R>nWzHrCx9?O7fN*03sJG zzJ_djp5wa!sRhZ5;CWd7k3Rje-o#bj{9V~R)-1uW}=mhma?KJuI(u8~fT z7lxh(WuH;!((#Hlu2WmaVQjb1?JdZ}xP7_QsAHlnhaC@cKHq%_rVLJ4>p$_$;dS$< zp{&yaJ7nz~Xu{uTOa=|7>dEK~TW6cVY?)`iPeL%hdrQM-^ zK@rnHoOmN8vUuBwcQv>b7czm4PovfA-;L<0d|gkxVP@Q2+~5H(H?^~b z7(1=JldnfE^%j{h}|~;bD+1%cj~(4sELY ztrfpNKP3}?iJ7gB_qymk=&6so2$>hD_B0~q%$k`v27Zx{eLmupU?!1;q!~{Y?w2UQ z-Avh3J+GmTd?&Yhrb++3%=A4t>6iE&x21Kj?ZL)AQrsHpojM_!BHzjUg8JtPyaj2^ z=Nwa?T}+vIn{v^<@hcnmCTV`G_JSU-q4}x<$DO;@TY;by&E1|jo9L3*+mTl>w54_U zgpJTa1XCeUjM@$Dl$ln}^uk1~#(Z84OkE?cgXw}FTNjNpbW0@S2s=3)#4NNa9GQH2 zYb&GDjGKmW|3Z4iKO$89 ze&j?JMB?G5Ok6Suys!pak8Ikn0-UrcB6rL#T3&in%&iL&_%4HKfUO!M6EKYerk4>i zmJc4NV}|Hf9boVBmwzT~=RcKoFZ}S1`}92QS=%xGtsiCDcQ+3BtjJlsAPCH_U3OAE z@s7v;qggYKs=co0*CDlfv^E=UFTgAB06HplDZM!VXA|$Q-%O@+)v4#Uu1KCEM5HX% zRDP09EAN5_G3k{Mw+?t%V#Bas^2&u+CA0Z@IKxGV`S{$91Imu>0??sv@k2=hGob5b zJe7cA$}j7>VloVY&$4z9W|7EZgO!EM2q-AfvMD{ty?k>Hr34cUY%n9213K|%V^bxf)Q_fZxaC3p&oBvT0jrYIM`7r5I9`O%C^XqSy#>S5^h_1goyFVLa=i#t#!B*yP9 zdW(;VVX@*tppBGGrEP2Q*wZ{K(#W68r({W2y)SDHVny{Q_1Z!&3>pXOJel#4vituq zCoq>1K^(>qFk|1=E#lQKfNEm9o51@&| zzw`wOn9BBriLkt)LnPGh%XaYHEQz3C?wBb{$eFxd{3+wYEr!n4S?>FDE>t=>s#wIp?e`s&nGUD~pxi{I{=S&u(O{7{p z`(zvA_jCZ2orxr166Fj=aAm_VU9%Le!dA|ePW2v9Lci0$#Sp+6PyhnLxYPp1BOq&pj!ton_E|eF_1d? z?Is+OMGL*uSdDWZYv%&iPBppniBG5Fy;>rhx7q=GaLJ5R1ZS=AlYZ3pGH`OglsIUi z9k{Ce0=}vs+wzC%~n%L6tmtn7qZ_ZCK zZHgQJ%5N#kXoIhCbn&&3ea&AT9|siA!t^6SG$&;RMXU>M?uC7RT)Rai4xkRfKF!&= zn|p{*K{4k$Q~l5YYQP-zfniJr{rwruiFkYbUyA^2INJw^ag;JutqE<Ko!oZSIVG~{V;cd{2+ALVbq-S+;pWCquM|eeIirA$Jw-4*tC!L1P=YZ;>hE=wo;srE7nPM6+3oY2_Eg1{ z77%WzgDP2G=fqzN?AJiQyu3%ea_!8P)=zP>I2{~8rG~MGGhl?@%+vLej?jzwp{7x- zPF_M=^J-1k7#rcWFvFnyAI?J+HN3~wqHhH^$yeE!HL}%4Nwz-&few=ypPA#k*JIMUej3*Y83Ot@dl54~lQ znkoB4wGMbsE>AtM7mZ>oZ&gMBi$b?6*eJ1wTZq4w(P@BdNs$-$-w9^LR=(ew7e&{u z*f(~Y9jt(k^ZuB~RgN{u12iB%my!ik?IhvVCB>Yg*xq1HVwvx3i`zj|_v@G}C`Ww= z$#R|YG-x{La+kc67|{5*NS&Put*OH-8oJQAOn0q~sZ(wCiFU^N4Z@@krCQJ5_?tG5 z%Pk=WM;E_DcH{dB^VCU7mZPl?6a&sA$ls6YuaSD*GxQh(s`@cP@s-yCq}bWFF)N)& zedd(9VW*?#IF5Ippv5m->0@yWZ^Jt(pe2s?h{|+nNC)(HOW-$#x&DPSa~{_?+m~|i z$xf-D!Rt2{?YC=f8Q+g*)&d{B#YvOk_&xkW;wR|AZR~0a@T=^8{(yl>Lx*s+$uZg0 ztC)lH;NZO*FF3(jGDcx{J=?XTlAY)9uFNglH;S{HzpqdJe7{<$+LN)rf}E`vqa_Lz z&)^}a{M(WGhmL{rPw^n>PR9k$mfP%`W`v5f_1fXhLrNB-t(d_hnDPs~ZkxrOYdjp# z$;*_RY)thxpc60I`~B%eyY(F$+KptD;|9f6$M8Os++1|kW+C~01bc z7sG(m?Z8(yJRp9f{`FJcJI#*i-t;@ezC8)7nm7u@RORwhB= zE5LVx$2v#Ne7hm+&Idgd}=SnH5bOCEV@Op#sU zZ3NOuXx%@{pMA9!K|KXZya^A2;P~&$(`QzIrJ* z{OYH=<-`9AN`VR3|4lW01p$Nq0j1K?{zE#s(G~um(W?KzSYG^f|6#fQZywPmcp+7n Ws}P;(_NW&A#twGQM=KAXyZm2yJXjcu|dB*SF@7eo3`#t}h-*tZHTxb8`HGuP}^;yre*1GR|tq;#s>Uam7(y&*{t=(k8;cv$33{)Mw7TIiv7YO3OWYErlpS zOJ=`f$jHd)qivT51%-?S-|_XEwp~Jt?}YAge7=7#|Ev?~ec5MH7b&iH9I)F;8d02I zX!`a}>g$GwZH1>pxKkFcYj-!h4)29r6u+;G?a&&^^P2dknRPPtj{M1G#&_iRh>pJ> z5&iY^lORO~)b&4qelm9s9rm|x+>wX=?aL@h7}H-r{=67P4UPuieF|^yYzbeV5hk8c zj~|tUe^Nba;5VsxHu6jE&-rho7>BJTUU?bWoZs^kUOKO)cGu`{|M&TaJoMgWDwk{$ zn>4b&E^=KY3UT?ZtdWhs{_pdDU7|k>bNtXg3UOrM&r{}iBni%s=EX)~2xtE+KA&mo zDQ)5VkntURR-Jd`oGjtb0`I}+FXq1;PX#`oM*nqwbz8!x%Dq32`81Cad_MZ{*Fj|g z|H}uJVnXR9Ch!Nd;TA^J#G^&OcefpU5As)smXF}n-bYJW>$r`2ow2*S;oTCa7&tcN z$YIuXN$}|SvzPZKQ6tC1{!Lb8$4T#uZ{m~fW6@Jk zi9{9bB^UUN?a<76WR`;;Zq{FK&0h0;WPSb!9t~>@e2B$3#l!QkJ(D5lkf=ojTi=Qc zMa6eRr_OoaGNnCSz-Zl)tKNKaSn&E*{qf|s4K6v%2%H|(POX`x>T<`(IkH9bi+ILX z|GJO%SkBtYp^XOg0aD_4nryvt_M?;AgohQ{7BA;||Ef2%er3PdIBNxK?>J%+k2+jH zbkq7CZ>s2fL z`)=A;;mwBgwe`%0(lAP-Z_P#>?zlroT3Wh9C-8f-wROE}qSm%RRT9+y^=u2O`L;m^ z3C-i4tl+OH--dLI;d{?37LshMsyFJ!@VLoS?J>5|g}Hc7it$-BAK~K9Ydgm~-PK`` ziD8KtHkIB3^-i2mQ_yv22zR+-ys>9?J9RyN9}$npH>$4EG4_zbI#b{%qSNt5drk=Z z@BedHTF&sk#POzo_5P@BZGSy>!pjE7QI2o=aC4jlf|-ibHM@cx&@stgqy9Fu zf6yj?FJR|}kcl6BLhzZ(qKV|qQPv3)J%VcAgr`hSkK%FdCMPp=p1&C(7Hzjy=(F;t z&K?idpA3w9ZPbc4+#cY(zxm@DZ{n{pQx`fvo$s|foUM~lm_~Hi&CL%8W zn4ne{+l*bwuUCcLWQw8|VTLTpL$^cbWJ|#Y0)BIqhpt9oo`%k~kfK$DqY%enW!n1@ zehZ`h^M&h7s3K`t^v5~YdU@zm0|vrx=7E2{-t_0#bS4y->_s-^FhJ7zZAy)svK;VLHopR^VhPUZ13wCp%5fDVsAgGT4JpTVFViP8wxvXHEt) za#nm-#@7)hR2{yPx&?I($KPTR#Q*tP>DC#(A4NaeSi64J*BAa4cbjPF*ePm`73}f< z;RV1JAMO&~JHnY6@|ppK4)_N@0FH7`mhk3TY0)Y)^3dWxFZwS}ARH3(=jj#XU^j`P z5O)7~d2oo?A4ltr#5DQMu~PpZd`Xx4kox?-E_~Gjm4(r)j&3Ks=J+(^PVK~Yoc&NZ?9E4#2aYaPkyy$%`J_=IUdSf9m3}1C7|G0 zB(zb&0X1NS=bN{FT#qw=zV6FZX&3xFaQ&Yxr5Om@X}@=^+GGKt^Cyy%;u=bc=#^=u znIZFx|Ksbpyz87zvYZDZw|@BlXjX=vz6`;y72*siYq5X6j=9_;7(c!ii`i8Zx84@s z9IU_?L+~Yz_@n8A{({cFy{#Q4BV6-sCuwNqca@VV_zp5FHNPT&)WsmbJc-)5Qvj;L z4=F)Y&M+Rj`r#Z}7NCPShcY5aSIvqAGtf@nM(ceso^t zOfd9tJ{~(HIA%B7CA`9goeAL`?D+nsi~&+mcl6C+rKfA&*ecZ{6L+*yV3gZmjPc(5 zPPD$+NamJPP*>%!Lbtf*h*UeMG27rpvHQ5!g21sJrNr}EWVO(LgTM5!jk932e8SWA z6zlL2UZS#Yf>!aFUsy!?y7Ja<7q7q-94cl%id4A_>SaA}&99j7TyHo}<_wwiF2T)3 zs~K`XvxPM#oc1d5qUgjtE7vL}C-REhINt9&OxD$k%mguEKsZ`!9UaaVKqZQL6nlZE z!Pi!`^Hkp&P3e9Cg5PFQqf@uoqK)71oMl@K`^lo7ec6CFqTF_E+m*+FN)R%?x zGDX7o*+oxP#SdRvDe%l)%3c~N$%;>uxvkgK$=6B)T}ZUrmvE~*IbM{g_E<=4<*qxJ zS^vot?rh?{_5M`SEc5oiz?p!xE?axu@XdpjG1b5yfdIKQ!(A?d_XN6_Y;I8{vGKoUp#0o~f2l z%2`t3-wcx{J6$3L4ySV^A^TR|Mlbv>Vn%HX);zK6YZ4W@*%YYh6YrJ0ikhDEGCWsF z$IL8AOTRRkSU-ICmmH6!StK>#AZ=II6hBiW>qk&)+XfI*&b0Qo zJn8F~aa6_pLOCsdy~uV6#pr{Y3FfSM&^7qVa2nObp{LZUIm2B1nH)dYLG8{X;n8&YeqXI1-cQrV5 zl)bEIqnrhiQKT+SB%eXYCrI+JXrrm9eLUg3|c zGG_(-p62#GxjGQ_JuECSatwL+TGkJ%$T1ihz5b|JHJGah36>2ecEbB#Ua0Z59C4IxbW~;?m zyq9&{xa&T|{fxm?p1K3GQ?Khv5FfCLFU~E12i(mOWJ`8@>oxuU4xvz3@()Z8;wy}* zDhJlO(`i$ZF7bNi=^f58R!A$oZw+p@Ppy_Xrb?HUTP`l|>qV5QP-2G3rTmEUCz4N- zE|5J$tBgsG_FSU2n`(`sbsPO9wl#MX`s3XdAFi~52PfXxakurNRyrqI5mzp%-HK5g z&iajl8z8Y`fhcPw!}mv^_`M-FkTlkk{k|L&WiD~{ny*|>MGKYfts{!1!62vHCLRc; z!VU9U&a~MwAGH7jiD(5i1e#3tO!}&b@Aj!E0#r!HPei{X(>0srS7AF~$EgAfH|xP+ zXd$_d_x^}gT^`Ee1I2G#Xim8J(JLuOawTmZxsNnUW=)FFgSt?c+`)IQGIz0K4icwW z?pSK^Yb{-2f}=k>!Fk_zzv*8UhaXjv(hAE%Im%#-4c)S=!tm@jiIiuc$#csp#E6>h zdl0r1=O|yvML*!h`-$A;!)A4Bl&|E&J~f=r$;)MyhmKwnq`G-v==lAj&#FQ-M4{{j zg%Ij(<3VF%{$JKO_P*e$OwRbTbM1=7!Y;5nuYRr2(eE!t1Oq4s7xVIzvYDUGhD)R# zQEpnbxsr`=`{lZ za)(~*&$^@srf;bqy?PchA7C|Z5pSd&;mLZo(jh4RZuHNH-Zm9#EhWy23-r*>jtWqH zLTdP}g#nT-AHgB>;ugo*sC)NO*3=QVuSOk%vQ?bHo>cIs>)L49s}9p03zi7XoD#J7 zglEXu%U+%JNym~pLy5I^cm@t1z-_;(~-`C{F|k z60Cw38^u%xPxb7l6SKa*EEPt=iIRGhu*m?AwWoZ^!>2F?Hpq-x0a#-&%X?bV$5UsJ zst2HiIOqpBv(I{t)mZ1g7TVJ0hdaJNptLXQ~JdoFHd zS$)eyi{oHVJ6$x%jVJn#IA17pU7*ruhosHz@OO*OUgTg;i=viBF&YJKCrqud;^T=HcNLMYP(9rs-wV~S_`O^zv|5j{Magv9I&RGr@n);ym)6@C-esrpH zSWVpcD@%6{vO28UoVoU1bgoc6(b*56N7-tqY3~Qx)=ys3XglnWyO~H_qvI@US9ztw z;S=B$+k1qmRs*5^*O2f3TwRWKPoyXyeTwxNGYg~Q#Iq3-x45;9ZEG0w6jU6`f>tnonYMVpWrjU+7xBcot$?>6p{ zj!|b4AyzruKNF?Q#G?H|b3am!ZYey;{a`u}etKoCd*`rbrz^xvyAC81$gtu?G{xO- z`IfQNX5?m(!@xTusZrC5>9=N=a|(3$vO*mZ{ej8^40E#ta5RwS%Z*B2xNN6+gvxy;Ef zO9|qhdVFLQ5S_f7du2PR%`f}|xZh8-?97g&FPp%P&$eO)r>qn3JlF!@6I?)${x&#L5KVq@ak7AEd*? zak)*;vfpjL0r5S+*ZsA6Z)B(Q9N*3Z)%?}X)7@;{ofsAZ$e<`KY!}aCbTvmX`KtM`g7Nf{vq>o zG3rK^&5P!?K#(XS(CRNrSP-b10YFcIGxZIoxNMs~U-HvIdI+{Om797gxExi&n|zxt=W+jA%u7`E zeIfY?cUTGQJioc2R5Zb36#|_~qGDqzhux%w^)ob0Ss;foh=tya%UTMvjO3W|m2w&W z@faSSGM(?iz)yS6qJO`zU}z#z{z*dlut}}w`kQFh=BsvDswu&#=G1nDe$|VqUWTE- zVWRRez49Va@cHFaD+wcR42(jb2vbK{Yi8T)jFRiFkW%{t{jP6SaK0 zXTHgrFmq-#*v$)zK};X-$2^$-oOBD$1rFixfyZh#C&d{|Yr?)v%bg%9<<+t}$g zUs;@aX3s4MGU=$CxYg#2yX_!xS?oLC*lhJ3W!hxx&8k&!4NlK!VZlwPLHlDdXCQ7c z1tg^($QlpyiiUq8FlPon4?El(J&n;+-6}ByyEyhP?_zTkgIbiRC` zmJ^k2g1XYZaE+(((|x1B^X6BG&6!+LjPv2kR;JAXvFG2eln!XmTr~R-ttO7@*!Rlc?O!kt7(Hh`u-!fqGi!THLqJ-VRiST|AEIrj-6r8~i1e`1 zIL`<~9ULc{c>6x#vgW*k!2KLhXZI)GQ4sNv9;BOD5RwRb_->?HJgI%9s1Tih?}gRcP8m!0Ma z-Mo?c_FQbBX1g>sy>pKgMV=xXs^|_i*lC!;VT~`PGaDd3EL6+DpYtg~j8kR`m^6igusf?5nvWCJCuo?g8{ z85)6k@TEC>Oo|H~ZDG#3L{XF$OTe;DuT#Gj;4C_eR)M#ZSXCEgi;1@1SLq;j4ebsF zR$cUc*lgWQq2o-*hex(9SX4IJvU8A+y)*)eMV-pXn&ab#Z>8s}Y{F1_0OeBOfk|h# zfURIM{uLJmGt;$|g8Dk&%kRGb{`%!(@IC_?IPuM5-uh$MspI`vWau!c4`1-ipB=^;FN@bxb;v$9hvgr#LkXYu;EUNW~U~*9lNp%;@ z0m|=vMMIS`^ReVBwR2*l@qtwBdkRIS0U_NigXQs*1kqCqp2iGXfD?>jj3+jU{xAy?<RS z+y}}ic2%~fERLXIA_S}zo;>^KjyHJ>OOPDx385$5LkyM zsaXZV)zyQMA$R|Ah3x>rWLX5D64ODB#JH$EVNgiHg{`!KFDEcMSR(?jNtv}23;ZcV zZ=GYvWB0ghmwoM!u{K_1l`lLSR4zG?++dKD7|C!x&fvKabl~5Af93vnkRqYB z-gP-@0&j5@TDf(Je)D=n7r+~2`13lT8z41Z5B4>jCgWlL8RF8MsXfPfnUsG5;Jq#c zI7;Mrvk}kFfHIRbEb4i3?J!25>y>mskc1gr76kZ+Ww~W~ub=x9UJjEB=%T2Ew~waG z!^H;20bb`bCe@Msiti_h-q|K|Zn!vi@y~njwK`hNZ&?>{!%bK#c~`vj{+NPQa+WucckSeC)v7L>?Y3lHPP%%A5G=3QckQh9sY&eFr`kD~T{XLA z7OEdfWs6D^vo47fM^4BKEq)kIyz(ZljFR>vu<(F-^Ve92(ML{O1o#KC!v&Qa-N9PnUMId4CKU9 z^O?On?ABBp%Bz@Ijx+J`a636%tOjIA%kkoeC1Lm9>@ryQQ!6O@VN!Pm&g&QcWWV`N zme1PWkjci$(NKLAV5Zx{XhwDq(rimb7PHAhTAIZhTg$49@@x0?hw9*7f2j=GI$Nk6 zRyQ2>(w4{N)FkkwD}#9m15m||r?^dI6VwD`)Pfx;uA|makg4zUy+4BQjiwGyhw^th zhHw=JQ42eN9rbbE8}$LD_Iiw_nnFC{%1zb-Uqiqk7=gq_(Rf9y#z=jt4_fPzbX-M$ z!;e%auxv;b-hEnq+WtB4K$zN2Yp`2mWeCKQ1X}ou$^T{7??6 zI}p)tIyqw@yXK>GT)wXtVadaa{c zj~BDEa@3IG;+5iCO*hBKJ9j%hYxaE(5SIP+9ZA|=*J`wJ{GqNa90 z+6w~;iGsro>Xm`DGzfUTPITU=fsK(8D>ZuJ`PcK7qovj-SObUJJxoTtvCYZhK%dK^ zkz18NsqoJ{kay-gO!m&c&u=UHPV0u5{`h$2as>v~ewgsY-k|nGX0^d7l$b_4WMChw zlSi@{3lPd0XZ=wE=U`Q*XheHyL-*FfvGDv5@a%Y*+dNlYGgXrlj#9_O_v?us4>c(e zsBgpBmM|wkgC(3s_?#SC{h>5Lpd640qD*EL?1QXq2_I${18zMU`H|}|$pkxD@Y@F| z>iA-LC@NTXxrZS8U{wJuJg&vlXs?A=W_G4_LqKfM5+(0DZWhAry@?zuE&ZFQr1^L! zCu;?uE6xN}&lo5Gj(ucT2rMe7qb9Nt52IC-P4PSZeKN-#PNC1+0mayMyqKtOHT2(= zB$J;sgIi#I4{FoU1-4ueepVGlcz1r-oMmrmuY?@kGpVy8TF)40DQ*Rwr?~Z#P?D#; zJ?HxM(;Hfj`!52&Wyt)8rsFZFwf<4H00{s8uIeBKaMXXuApVoC;w{bYm^ICaBX&%Hm}Bm(e7 z2yu8-NXqd10-%ju3Dt}`wNOfr(z_$nrewXu?h#d)F z0iJC)gDG6J*9eAYf&PqOTnEAhSec|90J;wVV}DSduF@^Kql{e`hP3;Lbdjyx(JnkdTn91GMWkVEn#{fU4)JeGAytJik=~Gynsz+jgIN>%Ppxg6`3M zB0Bd^D?Ey(Yq^S?-dx8ot@;Jp~ zCnt>n$KDlXh$iu0kRqa;6C8KeB*X$#qE+h1>FTt;^DmikD%;%Y@<|^rw;>}pRJLYT zRRSm>FP}uOjYZj}dMuzH6+REqj|AlOVGG$XL4aXkn^)#dkFySgSaWaxwfG~FOU z_>lrA&2^AnY@Ii@jlewWu6#Xv>>pE3hHONh9$QIF0jc0vz6Pjh*&v|;%3UcSLPFcQ zE1Yu*imD6%!3LNKxb>i()n4~|faP{8fh?VwWbmC^|PZO3rc6H$y@^%lw(S0KYL&g+oDq{qVV^8KK7>fnO{m}$pe*={pX7XJDJOPnLM zLru}06d)zZX`Wn}4y5153wwu4;Fr{(@kXw%8`}<}Ia)j?9owq8nmf z`_3VFi=xT0(~lzSy1zc@6VMMvd4`4wpyn9A7s916IQ&6!XOB#D^G!(N-MIkW0M}91 zG5c{)i5vHS6m1WB-F8udfcf!DtR%R9bM3KWgk0Fm4Siie$fH=sEHV=;tzJuJK}Aqg-Q7{U<3<8&Clo zI|PJEWc^_FxQ&D?oSc|%_F%*cS$5#11nr&ns{^p=(f-1OijQ~{wE?g=5W#kZNAA*| zyZH78SheF4)j(&=LjV!ocJp4oc*1cxJG;n?9U>}{cudIheDAz_{sd}?uotA4kJ~vm zpYh+#t!XE*eg$0ADlIS3+0rF6R(90yjXPG%70ai)?exMT(3e*S8npOR_kPxz!Uv{K zegNeGS%QS@g|shW3V|&FC@II+f)VSn{xloc2{!W>OE(U1UG2>XsRsKWzL9g6!e@O88H)9%B#UEs+|E@Jie!XZ zBZ2CY1dn+1CgNj@KS;C6fmrp)Dopy+bfc9cCwImlqD@JDHq}T$VQS+*ETQx=R>GR? zf_jk|3*dkGjaR8xsVEmvZ z4~Uw5-Xd!~(uo4ZD)=osHjAju8KV0X*!Ap+nv;xb8B=}0#x@Q(DD9sZ#{3r-=PCjT`y9Xt6U1oZ3Dn~nJf_D^ViScuve>F+njFv zg2CM?!91wsU%A0dt7j_9VLxU0ta|xdPVigC-Vt&9Zr^RVFIuHiI(&qT&wcZS z#Mb9n#N!}s;vEGRaLhf~7)dJ9u`It>Tb;DFZjJ<~|59 zx`JZ7IStkjtjLTJ;!QvI8tk-tTT1#b)aoV0KU|CgsO!TRCI~?gg6#N6aSg?o`uS5Q zAnyC@&LRjpGWP_0W!l<@&Pv`SuMNURMBW&=FRL7we#0&L9$;1?Fol=|WdSB#o-*W{ zPBqM}X@Lt2vEP`VD{Qkuax)`^DMnK)mIl-1268Z=RAOyq23bbG6fLr2Zhhk@s=BG| zAWuXi=II<#S3kFaB`=J0ZArg!UV`7ORLJ^m)Sm|~mW+@ZwSL$f9D~#?ib4dUUfL&|IBn95X_O7((6r{yfvF|y=KE8imJvRLI1!VkE{5ESOJavz6gxgM}=rs zlv5Q_^Oe`j_qazSGtadBbtBC=FZU|T-trCqsQ~4uTx3mzHa?_rHRNbs4W#$EKN{Ge zkt~x~=NU~+$7320z~I?*r3@#XTUby3?Ei{H%@SyD#iwfEIP!e!HI{DH<*e zLSv@yLGx2UaEPi1p1e<#{TBBu?(yJG0H9%dIif6RMGhOnF6b3LH+=SA_o=uKBx ze|wGReyP~jBX&#cLPyEaajnegxy-jPX(+6?pO*St`?yHo7dbMMdFGn9`Q^dXQ*~?b z#5BV380zNLGl)?$7E6?A-|ONT8tO~!evi&}xn3?1S=;S9_A3Wu%rO}$4-{g(#sLcK6Q;0;UGI=9A%S2bUYPWJ7NFaXp8t53 z7lb#?{n#1|BtSXRq9y61teitdDuDBFP{ezpRV0%nx7;C&!Pe|Uw0`wJr^}&utYJgvFlwrD(!1C z@U!NE5WkEG>Ij}&@P#v{R}{mfs~9qjK^M+UTHJg<=!Le$Vnr{^>sE@ZB@BY;2T@d% z=FQz85n)vr*=RpyEBF#FK8jR-DtiTypO*?8mjug9;Sk*_{XnlDgC99arrtM#K)tkk zD8onMW!2B;)Yje}=v6Euq$sO6@#kGX=nPX$S1CGSL00AJxvf2{yZ`iwxes|O52T=GThTO}=uX-E6{sRU`GV}RY80Yv z*S4)b;NCecoT)%DUlhXqD_|n*ytmP8@a#qMTw2G5vnMaTw22l|+>Chzl(@@c#sCh2 zuQgfQ5h;$cLS2zle0NHE#}C4}S_AQ8iuMd0A7HgaS$|77v*<4{gp7to5AJL2+#^X< zIP=Z(HR-RPkxWKnKn=tM7iEVN(K<)?YX7?P3c~Zy`W5}v3#FHU_HRCb?1L(euyb7J zuPDTFgLKlv)%c7GWK^pDPq5P3)NyGx#0)j?q@+LghHxEGKKGJV9|F&a}!9Jgm(4Q`pAk}5utgy2`&a{*5{wI0~m z$O;?oijjt{VNfL|QlW=f^cT#g9RWo&37gIp+n3}+HMsy9=f|Gk4il^c-!rU8xwHAbjR76?;C!Q@#4IzPNEZ4~-Tre_&U& zl=&D;@7XsCZo+)*_3ugC7Ho%z(oYIk#UYj?q@|Pj2cUzRYU=IvgrgGa|So^ znC_F@SrSR67_^R7eSd|ChlB0mhpl1raFi|}p5GO{IWMIUt(ZT$?fpfIC#ydCZ6}BH zL)wHlIDn6F;D&=m+ep@=8Izyg4ZI~@Of~_^gJK={E3aT%W{aTm#S#X2Hj%(0Paxdn zEfwo-Gjba*v+;7|nhy~41ax3rt7KxRc3J5y(D(PNjJ^~; zZIdwJ3TuoqfOV5lx3-Za$HoorKk$l57MeB;h)d2flUjwHFJ)0Wi0OP85TTMN${cmr zzS^30gG7opwl<1Pk96-CRHF}lCp~%YH-vJQ80IEKTJ~nC(bu1{lKf?fbg2g&__hxI zW@o|Qg;LYTmTI#gogVx~^4(s6Za$MHNbYjO;dnIX<68{w_8qqQbbwrEPb6Z@iw}_= z0MOS-aD|wc=Q@zret!I})`q6oF#O_0%Z`NUG34rbGooIT=;qWQ`k)+x;y^V{!ln`T zE9$#poJP;;MFmnpE|%7EVU2c9h}N_s-6*>8ylD{X*eMUK0`owAPYOI=Qrpqx$j84A zbd)%~7neNF32XF6QJgb~DljR4Nk>RhJ$-Ec3hWO1_;jG%+j_PFi@uPyaH4uCD5i&n zmP2;=IrN;C(w9P2n8Ov$jXhRKdJJD(iQ>)Cw++Y-73Cbk-*;Yzi|yanU#bDRX+yC# z74u)yhiYSNcdqDLDk z%UcFcYKA-A3IKJ)pW5K>^4av?uYV{*=QZ&&8uM70!Ff-|v4$uy0l(75s(JLa>$CGzCMaINF^b$B<->N2(;E2@}WQZL+yFx^V&#Ig=lFJ(4wf01zi+!Y~jF8$tX$R zt0fj0-+I&43t;?q2Zf(w3kHpo`5Qu^U=j9LU^a0Wz~TBdv+iaC8Sjt9kyhE-b`nl| zVt=^n`fnw?W_|SVCKC9tCF(b(WH{TS*?uipk1 za>&N=?8E!px{*4lw2$zIGQqtW+$tBp>Y%2lpUQA((6rSGyDV$Pw8(A+ZaUZzJ9Jip z_7_>OV4R>o=pOL+R198rGEm>(goJfB>jC8loC-cM&l*Hxkr-{(IMHkqq!Ogi1t6Fw zW6=sv6deVCh&=J3MeyV)#b{tCwRk};&{f}uG@$Fz{-Rf8l`6US}RCw|NA#l1IrTy4?ix6mqwAnGu>qNbH^?Kc-m zL^??-qR*LY&i0LGA5k)SL{WDYn1-KY_sjSw$k0H~Zy7oUG*BVuy!XenY@ZA~fsWcV zUy}N?HsWAp!+G|mdDB}tdbsnn)fD-2(#m{o(dYI+FBm8xhPh+?Voa7jQ#o;lGq;$C z3v=zIK$r(yd0~Sam0bwxF~=DP-P&ojt~~~d;9F%3+@Obeb0Do8pjJO*-A>XkOXbdh z?j3*fT+n4CQ+7;fiA`cZHB^E*joDYAfOO+%yZgd5;$+iUf3LS;%XWg9miTkmP8_B_ zd-M4l+lt@(k0(U|{14B30ata|hu(ejtb`A1pB$<}C?y3?4S2NOj!)8vNS`kU-blM~WYk0^wNl>lZtbZWkRbC(!ABm29=Fb^H=>a>qO^K=dcclkPJuFcJT| zOZPAI?(Ur@6YT+2l&jB|*SZ69sSIDuT`SAj%$1;Rp!tvt>=uDEfr~e1@8>-1@YZyH zixb9-U2p?s%RtA%6sw$j4|)T(sPGnL{0*n?C+K&$`tIM zOxU!O;3KrM;>taW*Qotpr2_EfBsU2*8Tg!OJ<=v5>^&x;_ImHxXd)*;x6Vg>%03-w zYEE5xPCafT*T#CgA8~PL`5XRJAx}1K4Dhfvb$zF@W@^bPbhCvRqSPG2`ccmgxX5pM z)7x*JzXi2?nT<)H0C?+&bp@m8@11o;bBQXY5_lv(ud478Gw+FLKL<-v6kX;p9nI3A1G+@<_XWwd&uSoi>b7$Wxh37-6h#1j8{{-py|>``hRu^rNURd0lcGP1?Om$HAxlsXYYK06GoVSpvPHzl-m>TypY( zTAD^2C=!7ey*<5y0?mr}#fRPpo586~+=R}n3wI%?3KQ=o87$~RtRx5=9UXR*&Fg82 zHlsYqSB7teU<%1VDFvS-@%S7!$Lc`P1%WnYKun6yvxYb6KKo=`DBe_(n*Cm*$3x~H z8qfbtPa^(J!v33t{j*dE0`$LkLuI zZV2y{c5$3{r_-P^)qO4!C`N30u=zWmkXMI3F{;HK3vD|R`g5Uv7jHXSA>rkq^DW|! zIEc`T8V9&3w-!pPO1Y#Z#Gd;a=WVfbR{A ze_%`fO$RSs+L9h3cU%6laVsoDjNa?Zz#5_M1R7S6zbk_Xt&o3H29b&FMu=?xWEuzE zr1MAEjRJx)NCFT?e`cd_<`%vUXYVHrBq5VHE)Q43X_1E4Dv>`j`>CxJG}d#oE^?c$lw>IsQq07xXhM(>aFZmwMXK$e98z(8mns7#N z`#*{=G0)x2^Sz9LG&4tgD^@2!oZgRR@Yt| ziQj~ER!XM0Rx>VWU>G1B19^bwT<_rT)*90(TGI<7C|}1x_xzIi)v%O-H7ud;8kuYU zL*Cx^`SYhH#N)tf340v@lPtJqP!kl(yFy&t=JG<-@oWf+|q zdm^;`W*;-0CI(r0)vZDU{t1>YwveuYK_y<$)t*#pf{x~Y^Mne`q$PgK%Aq>s!up|O zaJ3U=?$mHY#TD!GsJT{T3o@kfKauEUJ|gL}s?=;bo+6{a=iRMKR_1t#R=N>oAoo`zyHPPju=@OXq@|k2vYph zLGz!-erQsm!{#zWq4zl6|ErN9D%Q-9D8$364_|Nn%W)$akr?^^pDw_w?c812miy0%v;~7&8aiIrp=piSP6T9V&x_Z*B(7UuV*8gH8%16&w1SNREysRo} zv2ltfBE*Q{xo*ety&)7~h?9)3$w58R=Lmf|3;Jk&*H_*G8n)k~WTSPC0?H1rwpV=g zUYcUty?1WsQ%199)L9L+2Kz?-ZED89n!%FkVR^h8jqn6RnU*C^BA09`_w^xb8SzQ* z4R9ycz+KWz9%;$gRaOxnExAef|5tv}oA|3|DpTyV24|7Y62dyxUUgEOfNHG}Z}AnJcI3EiGN$ z+O1crI~ny=g`Jl;gbSFi{TFj@5YCp$Da%x;KBM^J1C!$RPP33I1v%OQyRo4XOiV}@ zO1-SKSR~{Xn6L7mCgva(61VVf&^DPnD0ZvV$fYFD?}z!Ob3ZL74PgKGt_)_#|KhSt z$_B1DYkb&je|VtAL%HZ6_VRP}Zi+&FMn?i)qmdilWu46TK>F9@os$jF6uNy1qB_|T zFOLkUZL9YE%Xtk+`lx|&*W|Wdrcf0IZ|4>y zG?Ai0kWqJTBpGFgjr^54F*RMv%4q0P^Gk zdqBxS0g{h}XZEqCU`m+u*%&Vbh!UxZtUV%(&p5zZ5I+XZJVs)`;6i?D;OtADpsx=I z%%)2W$_3>hdv_LcE00Htdik3;jgb`XWTPAx0FMP6Vbdr$G3+#Lv7Bn~qc8~02k5>PK}doDfcC1$>)t6Ai2XGKjPw z>KI7p`E}#;7zK8X>U#W|!-;7Fv7VA9GohJod=%)-u9;uSiN5gd0*}aAX|#!u<$P|@ z6#oe^<->HdS&&(|&INQQ`$)H4DoMQTFw0k*0h6}5yp)Mq%%u~gc+vj_;|-X^e4PU0 z_s^;3EQ^|N@0c@Smw@1I5%3PX)q(^ypW$R3+#sf^eKEAA_z7K0z}!1cz{;?z%ResC z)6G+8QxJkRdi@!j2?jiIUFO_qRGbHV-@=AJ)5pg@)_@P62;Ep0NDT*0p06gAD+fjj zfl*Q$PqD;Y#8*x z8pD(t17r=sP^OyBdeB5EV{O&ZR2bT#LeYDsvQW*k&OH4#KuxLkZ<9X`Oyn4imwNw( z_X0*AOiqyvy*o{xF170MYy))K`2;Kj5h-s+%qE*q*QyW`?Hfwt?QMf6;IaIe&qM6% zwmCSf{Yk}t5|RD9hg}8QjoPM7^69iV;$$%WvM~7K-6+Ip1a*u2e{1f|!>MfFzV8Mp zA{3dYLJ38Nl}t&L*<~h?Aw;ZmbrRIG^>ka0JS}Nf)fYb^#C{+swK#y}$Nog-89$=u zs3(@WTe)bk~Pi- z(VI>@yRm3MG6L;2Hd1BHeGTng9^)Wu{8i_8Q%M%CpGP8D3>X~|1{}sH=YlWPz%rF# zm?nWpehk-Q`!1Jc@51r)S31p3eYkGp^29;w)U{_%|H?5y*kT8uh5MWI;~A;|@H*mrhV6{RTW8%n|zx%!PUzmhh? zg4mln1Zg}#rm|LTH4Yr#PoQN^>NY)>l)pxn+I`@W*|m#wk$guQwEKGA$O{-hrdXFcP8pW>T1AO!Jpf}x#FxfeqkE;uk@C7%D-S_trTbY z9$CP6`N7?mulgECVQ9A5a^;A?yE)86=(g^YXB`KPFx^hnTqXA|v_BQ>(tdqc4z3PX zU-1x&IL4xd#f**AG@Z{~O*7>z4MSqU6!vua^%x*+e`kX410`+{*O8#R-biY%Vu=HqGD^@IF+OB|>5OIy4p-qX`;IcyU(6hM&#d{R?2P{(Vh487J08Z~r8Q?p|D zP)9xieQUDz=wkZWJ0{jtOsn#m=xm*1QqFuRl51&VGn(X=ZAm8%zIsK@%7J)CJf|~N zNYCQXhWofM%vB)0>e$IH&fK>+{CjTo2$G?QL1HQYRny5jIW`UQ|>ZbQQf zVX@7WNql|msaC%#fhKQKU-1UO>W88!_x*g_B<3(Xrm*HraVzC!rVj^aMD9*BUsCkO zv7y6#E)#uLMuXr0!WwkiL#nh7W}9L2H@O%&8TDs+{L~J3k;7LTxoll1H{A^@zn0Gt z{Y#`y8oP|VO87Ei;fM9rPAuGyts>?IC;-|Xj-3c6l(M!z^3yEVzHZ)EZK$&g^oj{Q zX?~2OO35+Ue!fGu?%@>WFx{0g%(}NT1ND#Pl0WGoIdDzax<30c9CJ_qU9Iz-uT8o4 z!?;+zz^gi9Gl{jAc80}I+%jWCZ14P2Prt9{i@%@pG%-XD{IT$CFP2v6WzE9SRYrqx zo>H&gu}-%+m?GYVWhl-*|N5Z>@f6LeI6WXS=&3G&)&_G^YK z8&m5c>3qtaXm;d3f_Mi!E~VB^RA)NNyOun#jYP1RawLyQU;XDOZ)+`A)%J z*bHRTbiQ3tL#l@uN!d0e>ebFmZ({?P=vU`$%#D9p$&~6&aHGb3o3|e3)to$p65tj3 z2BiTsdA_apXwAMP>zuW-G-Xq;@e@Td2U-Dzzak<)ldYR?aEq)?G$%d9 z$Wa$JVngF+(NluaGtsZRjaPRO@O$%bTt2i`)U@hRD?|H&IyG>{AHr;-dOt(HBXs`FSM$z8ua>+Tz@oMt-mb zDLM`8W%2|kjqiK@0L#3f!5veg&kR~n-_^rn@r3WX6ZT~>UEI_T%M79}!KYo^?hWOyz(uZ2Nv z@;mZpT^WR|6pNBxl0VZ9px~2;&R`e3{WwPq7lAGGX=o|c_Pasq)DqksWbi(yXvq;! zL?@u~Xpi0KOz0X~H;|*gHFc^yN$Roy9SfX9p_flkbk`gSeVUS$rR;Bgn-EOy1L6b; zLdJ|^HLOjP$!WaZGOxT>qKZEinx%*106 z9_*M=R@VFs8+225(^uR_&InsYf6V=y4O|{#)O%VNXX+DBE0fzFep#MF-@1pC)6AA~ zbp=ErgT$;=AY&RsqnVGT6}b+EpBw-K*KZb1g~t^u8Tj~eUxj#%tbPy`DZPqz*xwkc zEwiDcRU|gFo9s)q$ZH+rKG*Y-K&_(T8R5-4BY#`*nKsLTI*UrC9%iKdYGN<(#q0o# zq}Q=Tf7zgb!@O3x6br+YGQ#UaOQ$XA#2GJZUmh8~QWi^bITHKHnoUxGPF zl+ie1zJv@ThH-z6aL4}0fSKb*ihowIaGH(!48Q!EG5b0PmYjFfrGRd#t{-H$mch$~ zieVq4{?(P?I=DL3!?*0n^yvW3^smRB9$@fNk@u#*wdQ1yA+#PmwmK%+KJ~b)6xBO{ zpTG9@JG>u3gU06^HK)UvI@8PXE7Bx0k;RQH51zNv5Pe;s7XDiGFT@H>8Pjk@;pw%p zJCjWsQHdA7k34KvQ&t*PLVuFw;jNCB^bP!Vq5l;-_y8eSUJNGXC`?~;y6PO`ZFLqQ zb;kl`0M|JMp3{o82A>H&^7$=6qc*6TeuSU4^-zgSRvAXl)o!$kn1~%|2#DKu?2$8M zT4mgvWwBYdd~_tOUK*6(7+D3-sVmjyFsZ%g19sZ4W-^RQ;xCk9iZZ zRDxkMB($-lo}8o86f(r*!}U*-=0`UF?6rQ1w3x+Bs3B0P=7{_~cPXO3AI?RyLyOvP zY55SnQ5UP*Op)g+5oMbFK9v*3TK1R|$3)Up9D9QscQYd7(Jr3LxLoyMCD{|vCD*wa zo1?0uKpifW)OfUTsA9Hao45;y(4{wSzUNV2Tlg=AUyfL%gBs-rWO1A~a(Ymalb=EL0%AwL@g)a(wWdSAh->pRHVM$mC;uZ0TY4 z5&y4|R9FDnyQ#=6)7JRwrI|@R#dykffEn0xr3RPRjeYfXe|9a_$5z#7X8b;JB3cTjX`=?c%=^gn)#F90-|agwj~5sgY@Hrx@@nh!v`7)Gp&n6Y2ir@QMOc&1L`l=d-_ zA2Th-3bg1fA!okBacvwSW z@KVuqd4y==qI))ocN26mm-$dJ)XcYc(Kzl^P#%yS;d=V=9l>9cP66R`1AXY0Fm`MlqW`+|Wwv_k6cL@hiYLV3avm#NW&Of({PT zoZXiaz-Gv`40WYvHa2jau-DV$Iy=LDR!@WB?)u|;n--~%yu!yY8G*aggEN*%S9jBv z%(HgdY8;!-;L55jL8$p95zAy$M7B5Of)68^SyV#ry`bKGtD+}fBPN{&^mWdcj-JV7 zc;aPlFSx0?$b}+VUeZ|UC6CD#>tsP$3JfbI=F|}b(3d#=r{bI?I!DXfPmOgpJcQ!nR z|InewRz{1pI;|>EMcpitHR9g{4F;w^YpFl%sU3wy+`VQEjmJH4;7Of(cig`>GmQ_G zT2Uq{Du9C0tnJ6CqvMRc@_JJaYN_5vorRPB9ui0dLogyT2fl|&^?+aaF5;`b>Ap}J znM(Kor9W@HGi8aMfRuLe;CMQ3k?H&N7iM6^k1QLN(YfzQ;dKzhY++jac)xtsy|gtdb!Ccy?-lKix{dK(tV^{O z&Af**Z3#(JVB#0K{IIJ}MlSE+f$9Ze^Dupx0H^yHmqiVvAFI{#sefOL5Bg^K3EiVt zWq1zx$VvW~gsC{-a2-jEY2*(Yq)w8=ayLj4CVj!_#u-y;=4=s7yC1N9SuNJ@)FCsC zMWp&#CK$OMZOyN~z2Qy`>$g?(W89L&oF`Ppf$8K!UHO?IP);bmJ0|hNCZVrse-3A+ zW&I1qOos`z8yT-I-z>`>n~+DRt0&FrZJ(WGeV54ag5gQ-8Lj{Z=0IFfwaoUCmI-OX zQn|$xGw*Uwa{4&wk;nQkRM1b%4h4v?Dp6xDN{k=m6%SnFkOOuU)qnSN4UYFsbg7{M zRK+>vpNgT~_iS=M%aG=QvSnw^hN0PPYrxC|w_nV#I6{iWn0aG|(JEm?+2Yf?(sgLO z&*ASMF=@yihfc4K3$;ZWY$q09AVl8BhKI2FTex$vt(v;+%ZeLtxXm3@GCRXZJw-$n zc-Xg8q!R!RuGwVjR8uVJn>;_%Q}#c-OPw2|Rd@I!*ZhkBMVn88)3?z25w`cdsOV*F zZSXbF3GgR4#42La#i!*r4o}L9_}>p|3672BNl!j98=;3&jHN{X@S`ZR^mmrSLycv97-Kq|2tTIkigFodjE9id} z2!89+zH_Rx>^A$YivkjD?}dvEnR5h){(aj`_pf{jzMmLggx(loy$kTh?)IW?B- zXx|oFoh!jhzx&KVf9H^EVG(2K;hQ0{S^}+>d>^D z~p`yU)a$UIX}2t@P(e0QPetm8l=Sqm*P=>uunyBBnn8f zMr}To?WONX>Qj_#gVMW+Ac0k|v~f##m?7Oj?sfiu%5n+4CM%o10X3k*9#=5kl6$T1 ze~79ej0tiR#QDJiRVI-ec3SUue(s3sy?w1~ z^ij%fB7RP9x#QIv+)wtyZ^zthjVhW5J>?c|YS26z-Q2D_to0!rY!K=m&h&mnG6T?H zaMY(D^6}iirwWN+UMt%rOKZr$usLz&KZhjACTA$yY1sci`nN1OTznON5WP6}cG^0f z^4;#{(7~T%=`e0+aJ(M zUbifuB%ReL?Q>~trr|buo%2Ji0{W=~ATR!YzG~s>Ds&WcUS{{|p>g9U%eNNW-hzT3 zPsuKAWS4Xo>+7Fj^dQV+d#QuYZm&PSyliU37C>^sCWWf4Tkqc^vV0 z9LjTZ79|slbl>MDuzcUF9*Pc;!W++V&j$l>B!hl*{z|r4k}Jqh2eL8}r*sYPaf7^M zbuT)s@fgqxl{X=JZ2&mS{5M|j9@&KzB)GS>q>Wnw1LySe^22kkWnM0CU)5%GTc+)u zjy__Kg+!0&8r-4#T4a8`Op9)_6$vSscy4}dXoW;>>h-P-mU6@P)`Kv6_k~@ZQV(h@ z(nyvG*_WzXVnn8+RAMmNDtO(S?ShqKQW!%oYqG#^M}g!=a5QL zfM=%$l1CtRe&nDxr$33bVjM?Dht(A1aa?4=yDzZM{EHrODdWE3AkF?!GP%wu!q;a>I%EaC=W zu?)y3re+8fl-o~QfsxOCQ&`=6Yu zD3d?OJrZp7n*kh+!v3hK8c*L{D9tA?s|#sK+RC5h{xdA>&mZ-7rgG9!=uFGGY9}~b z;#p(k)&jrsk9W?$61CQ;`CCFWPyX@p_$PLa*-Z$X2&xSGK`!OI3bqsFW)G-AX$J90 zEeZ`w_vW^}ye5pd=LA+4QTA)oJ@y|eoq3))M|oji{HWghWq)ULdE(+X4Bb%69r=~5 zw!XX<3bJFETSCe9erMm>qs7&^VfqUW%#?jO3n9~jE>`73-yH`ePI%R*7l9-aUTOb) z&-(22e!A^)?Az;v=&z`aZJby^{)Fe| z%8trBH!cE^A0UBvpoo?JGdOPwEEsOzR6@7^H{SyPG;F^C^0CQ^?SR zz>I&+FkN-GBXs+x$=m`x-uZB-WLclhyp{T0O+!#sx6BG|HAfc6Z1}OEzsFtJ1oLYc zDgSz&^Q`*6I=|&D$ou7XFKbEkktu36${5{L%Fd1Yj~iJG6Vks8<|ML@Oh%dz#EXeQgcORcvUpH!iM9A(lUfHE0X=(BQ^^pD|>@j+_hTd{& z8Y|+a>Uu{2b?0-v>W#Jo=vF>2f%T27UBck@%J$ffo7(0=?yJ@3D}7$AF+BgV_-*|2xkcQ4P(bmhc^naI{uI8e4&Qn>$p) zB4G}ki=Cs+sGpx+4fHmQ#3Ghqh!Nv%JMz98crIj4Znq0P1RT`1dRMs*gcv4&A*QFK z)NL;`P|bl81_sHpN|{|}sh~%ks=dH;C8K-;=ADF1VAKX+uXanMDcaEk76UuRyx=+D zIqvTkyBS%;Bl#M!YHOcwkm^wU4z@38ZipEW__{;RNDV5 z&o^8GUzHcH^yav7d0&^uz=p50Qe&}1gt7*U3w)WU3 z;2V%O9^tHSZ-0p-aERiiRuiVd0dBg#EC+FEBe%m(7J}To62XcFfF?t4t^JJmnNANU zT-vkc($O_YLjw2^S$z6Fn0;k%BYh2y50}1woC5{p!#&#vW-Pig3o(_89}K891*?ZS zaNBqM!0Mdv?e6PP0`Ovn-|e9u@Yd@j8+e7xK~Ll739r2BT^mKT&zcA5C3eIg!5w@H z+SFu0g-(zrqLHi-4-ot3FKnMu7F2Ku=px*oWSt8<9kyV{n&?rribzY4$TMd!Xxkjd zUllZuX6|2un%7E^?DrfnzRmdt62EQXY;hO1U;J2L1}=tHd+q#6+TM&C{otQ8Fg`yp zd5p>9**B|eC@)sQMeVP@^1c!Dv^+zM(Sdmtcs+enzjl0vAH8w!5MSD0lF$>f{d2sd zQvk{hmD{_po6RH8o-rbSRP4}CY!S3u+na$VyOnbz_-!t-TTXk3=*j}BSgCIPumUnxc zCX{U30KQb#p%MY9_6^?)2b-x=PPf}LRF%ops6T^o48aaJ9?ShLan%@+ zw1Ccc_|EG@0Al@w3grTh)!1av=^1^LNm5$gj8eOtB|ml{NmjH7LW7>LL(l1C87zC- z$G9aaSsn|8w0vfD>P^XAz4icbHzI%(e%a3?!0Mjj1)QdFR^rf3yg)Q4LZT7XNTX5wN7L4>^3$tYtFFG!r5$5NX^fUOU3q-V?BNqYZ zgtv&SmA?2<`W)z=99xn#V@j1DfT6cjT|bTN zAK2}wuXOKhwLIY)5_YE?inCI3oPPKZA_NK_918+QZipej*v3UlE$hNf`G?;#9V7o9@(T0gluk6oerbIaOPs+74T2?ad|Qv8^hQiM8~iD@CKbcMO0DU(9Q}f zY3?hnN~@5gYA#LF;GvWHwFOUU?4P(Lw46yq!knEsOS}tafo`6sT0V=Cj5|^l|2SRX zuCr#=&2y-wUD!3g%PorY4A6(G>o6bJEseZbO57p?cjE1sI?K&nFZSr zKk<1m+_iIK7P`e6qPP&~34iILkC5v3t_a;}BiC0R_h01@kk&N|XCBR0T0jb+@1GE# zQZs7ETEEz+qTw;?C9>68+bJSfL|B4~oT>Wr?YbFjOi*GlU7~*XYj9KK7c{SLHz=M} zrZkI%M_DpN?lKcEZ|-O+JFi+dJkGW6rnyhyFqq*{V(mRg|?y)DvxP;*drTC5QIU9vgrg0G6jh?Sw(u_mp z68(Q-TSyKFX~s~$5G-mK#KyL&p1e^)K6Z%SPQ!Z4A+L=Rp8zeq!C(?z?~c03I?swO zX_W&)_rKDnj^~16!LRh(r%`3agJ$ym>Xdn)nHX7i`J;!viLwW^u(8mmI@81x$+D47_D8LFZQx!!>*D2RuWch zhXt0XwtPvE%*;4h{k6pQ!6@>WR6|U|IRTyeDZm`ABs5s4UldCYeeoic4T2Ck-@nws zBCavHioM-xGI=g#~(~D1!OGC4}R9hHiiKs^-=ke1w)X59>QfNURIz1(ezI&7Stlc~OUSW^!&2_h{7%d5m zFr>IAWyeP|uk=ShqFiJ*mYX^=Ii&4d8O59}%cV!P<`50uOB$T#T+bg-UJ@`6%{&Pd z5wlqo?=j+BoRZ?v!XKivC$9)X#?r_3ArsKiWyzbJJ!A)lrxH+H(&H2ejZOwD&VoLV z%V4k5u5?C^TA$8p?1A}R;m#9BO+E;RN~w=uNs|<-{dM`1Z(oKM75KoOdM4?7SC6OX zss=wUixn3yX7}QP#&Mp^bxG*4^?v^BY|$KEY@$roX<>Spt=$0iMhUjsWj8?mu%B#G z@t8O1SFguDHm5>#ekSfR0Cg4fCGPOX#Rdxx1 z_2hdluUz=)rX~8U!4jIa{lId$a+fIF5H{z(XLLv;_sd_rD0hJ(+cHg|X*G23=Q#ee zR|c&_tqNeU9pQ3G{!2d8TU5LKwnm1#$a=XD`zxkjtsNjJolp*Ya}5navpS_k&ktTH zIY}2zpl$1@JIp@Q?Rlg>lD=&|^=NVS$%d)IPoJi)qrclreq;EM8GX|7CRzWF0)tLN zc)5-k57_T+KmF9SX8VGCF7nO|0-uoL5KQymrc_t{%obUsn= zM*1{<`a+oALgid;(Z`a_S!<#&a+5rhQB5?Q<=?07EL^Yig?kuV_2r642d4iTbMsQn&?TG1uR z_bbk(PCO}DUNg*2i;0v^jL<$s!8|n$&x4*=Sin&HVt+zMbSl6~n`iL$%A^Es9>n2k zJ6=sC-B88i0|zQaDsoq*TSa&s@2k{6zf@KGftn>)^BKwFPGc&I239gPifq61&`mTh zO{40`708-YKCb^QF>|*B>(jaKK6Sy`1w6X#C4FuNoe;x#K71# zQOvd;DnXRdR)0{60yYRO2lw%G;8POSM%IdT7ZjE^LcLc zWk{D@Ao+UJzNBo|z>p7BdZzE___OMe?gW8ro8?QxQ$UuG---Dq?X@;P*|5Ky*7e+V z2N!=KUC!{9UnxxGo2@yyGi>hPWvygyHB%luhF$fk{`8%|B2>^1jYp0k3Z;$#NhFey z>IjngRzu4q_d*SFKR?*7&X9Wlb5U_F4u0>z4Mz+%0&O6!=|@q z?tBXT`6laUT+0kF5+ozAW_Q=obKobEip$oSq3HM3oH* ziqjlEaD#Rz1NMcg&m>B=Tu(ZiLQ0>GLa@HXDyHFZC<~X&HEG)wpT;U{EuiaeH~7mQ z`=K&;1<~@GY*5gd)yroeJ1qWw3%dGH@Y%957h*1hqNaU1(Lq{MDDjm+dUYt+?v0Tyq?Z?@7Q#@{zrQBBL zy(_bFp8F`RsPp|H$M2>WdpmOo)OwuGBfa}q0yLY`c@0mYWE0nBj^sxLq%6iqDqb~o z2j$Fm-=mhFaY=r(S=O_4unid=OlK0X>vJh{>i5F4R8G&m-I5m8ExWo|h_VM2;Zl+^ zlgmEiTA||!12MKYEuw_Z#OEuJwnL1V5?kucdzcF-{=+9M0-7cca@2@@@s+Uo3;k&g zu&jaPI$y&1w{xRbx9fBKYtH0o@wK2O}7_{)UH zrTu%uUscwjz9ej$G=#n-+Sc+e+4t#nYV`vSt)CMiWZuuo^g#6IA5Bqo9RuHxK8V+w z2z0Db8s*gn5A}r#5Y(-c)oSPmKv44=FfKeHGa^ab|JYOYjRH6L{82OLQf79>Ml11@ zw~5o|$Bw5PA@*3S&4rcB{Q=umjby6c2RV2NZKj`|$gC4?xXD|`e?FbV$-C3&sjZeX z;p%{kWe!Qa^QN#bj%oqP;^I!R@ivUZa;ZzMKY50%)@k)6;QP zG(-2Lvc#6Q!sAYpFP+mpJ#MzD4mX5J^D7-qogcby^}|;W=D~V=vo)IYrERPM0V)YU zUR2r#(uF@KKH0}7)pD?}Vf(!`>kn^JQ}4+^P(%&QWNUD@z{^0C{TM=W&x2w!^- z^gN1S9#)}4FA`N7E!P;j51K>rE%89%vMzu^gA+_>4aikI!o4^1?E=~`vr9=C7)I9oG0yB3rxDMa}}>Io5d^RQcjWL9?ROg zr#;InU&$d6BK@>{3Pn+zo64P|BJ^D>Kl%7USO-zbvpq|p>?<`y?_ODud(Y-$*LapM z5*vG{NUx!GhFFbBboM?lJdQ_Qw)-)qjD%`;<8EMby16twRO{MWg3#;XL!_#rA-$m< zOk2!3H-R<0m4iwt`QVF}b`SGAY1mBPpNU**#8}y_9+~s}m7EoOGt^@63!;q<<7y$1 zolRg3rQCGneQN&;0{DAj!?lds_{3aen7O%A@AsDaH-S)d!+J*-e1@>7grj*}b-Y*5CVSWb5Ju zsP?VI@urJ(0`6XBQA8fw1J2}cwT}jan?+jQQSz=GZ3S~*_cgX$f)prf^AU$fmH3PA zSHn`>AIuMKJ7c;l!uJVX$6=x*x#D85O7x-4d4$5CyrSOEi%(Vanmf)UxsR?=cKuW? z6J|}2j#lX~9lG&lN~GtMCC(c}t?8Lng1$7cgqo~vrJh4dZRx_pS2|TJXzNjp^x66vxjU_Qc1s#4)Gta~1 zB<2K^Lxz$lKc|H6<2$h=V-{;20lBfyYSNxX4F8(k?wh79cCD9<>FJ-mX@~piG53Le zi{x%rcCGM^8}*s{JiJpQ!pZtHeVmGGl@`|Qvx-eO#D{!i$}RkKN8ceEN4d$Ah=$}2 zTd|UULgN;5oqSd><2(cRSxCISZJwNNU-%;|o9n@f#Ya+4G^vZF(xnzDgOlMbL=2ub zQw$1=Iunktj^=tc{5xaKaJ-&9jStg!yX_=b2*xJ`t zI~Yvdh6?7#J*sPIP?&k)^IV%h5$Mk7ijl%2hJfsV6)V%nkrVe0m++j??sNVHHfd{< zEc5giue*5dVDWzVoK4)o(E`quVM5B@)m^B)sJGZKLP6%E8SB}Gs~E}gn7GD9^!I%M zxuZb~?IoQ{Nr!WUY#GL0G2s!QV3nDx`(vihRW?k>tnpFI!S=>TnFNZ2h?56W5d(s9 z8S!PvG!vk`KfM3#&c<|kX84t4D3*$iOH%YlMir0=ZbBcO{dfvqYa_aZHS-7iN}t2e z+sRxHY;tx>Xr%Y9F6bJ`?cSF6*31d5@&788n3mo;f`q7N+Fm0U+pN4H ze6(Q9h;A^9?gf$4gM{1SvUZ7Kk{?0P{|uF+B?Xt@dDQvgt1Qd~U6B)w7Bp^hmva20 zQ9Sc-TIbqi{b%SE^P_1j94qdWfhna1(+e|-kzW?C$P@wTm^?bGzW+cX>(XYSncPg> zub)uM&zoW!f@{CZ_<`by^aqlq_th6xtVaA+7(uBJcC=G^a^}^x+Q>97`A6DD*^C5? z(#S$52cP6*;AY^YigtS4GR6?8O($aW zf{xaw-ZJOBE$>fPf*JBH^05l)d1?pB0c{ta=;B6qcL6@J02a)Ro?v=|T*A_i?lavL z3jw=oRUc(OHIfGI8c>dPbrQ+d#OaS;Bl`|Mv~OIQ!TS$k=ylsVpom6&XCE_EOf@jZ zhckpOR5jOo@^H6Db6pV2q#+2^7V14=KKq3Z3#Z6&DVMZRk*;M#_60c3&^?LNig!IL z*wE9@^b01Y+SXnWs!yLZalbFa+^pi#+eUkS?jYN~_K*naW)-yPuNf@#^-rS`E<_QU zha&gA{kd}~@o?@rL0nyhQlcalGC_~7d(C<2x)>CtDVdbv^@<~zmA>*&3D~vBXLIQA zL{XpMJWANj4HQlMetV0%;u_bwt-iSZkDVq6F4;ciD#(>J-O@eB-05#CU(R1iA4a_*U&uR7WUTl0y!55i!WOASo z!#J4qZg6dTox(@%|-r`86YtcEit>t&5(7Z1)5F2eq zO*X^SZ6k2!eOD#UE1%LqqpB;)8`OG^5!WHKH%ji$he8L+%LqmZxCPi+iyI{#4ap(! zB@D<4Cb|pIeXM*qJ)xD$pW38}X1FfaXA!0Qo;2E)N8gqLPx1+$c}a2Q#$x;jN8jj7 z*vPkswSh1X)l81(871+tO*9GB9hm{0h%a-hKqaSrbuhd(D%ZohIbk zZsoDbTK*QveaZ;%TQM;8quY8y#%FMFo?Soovk3QJxwi+Qqa_{XeV?aFCSKekaKXr; zfc-@FNsw?7;|(LQl6yQURDFVoJntZU)n}PAaapAu6Xk53Li@lt;*aiq|1~IO745+v zNRuB>j(_^tTG$)^KpN0RhlcQf$$lU(+P^3i;4th?{exWm-PisHGelUENM^ph56tYf zng7+B{{uCF!$7|EpTxU#F~nNxH}(OC@h|WPc9x%cA_13yY@6SQ0pI#BG~xg1$r1I@ z@79)WR%eOx56hA%jhR;~Z<_U_4X{!Tj7ul2rS%s+-M-ssb9%r8g`Pyeo7Y|K3p2@_ zJz?j#6+B5lFs81~0C~_qpo{3hD&h11>_dXFVs?fj^UQ-%y{e4jdLtWu^FG)AyoIXI ze)F;%LjWmiG5=4uP}U(62*x&#S`{>p(Y&R~wvt}FUDrY#nfxqjkA~VrVpq=Js;q#} zvd`n8LtK9YFnXM^C!Wj2>2|GVbR5Ts}JLx|8Egiod?0zUrQ?aZh{Y8%a#RJj#Qk>G_Y* zsQQekpnXh7xkRq#6WrGu=>7v~X?=Sm@!tm4wX>-Cq~Y|ciV&c`_PfP0y_WiK*e~Xf zD>u;BZo+fEH;VqnLH$0t)BOkj;DCQ~RllE#KPlaRo&y;5a9DwFuKdk!{OjrY{q_G9 zgZcN+ekJf9kj1|SGkg~u1`YIc{{Ef+JOaPZ_76zy^J9YKLhV6BP`7iaGP|3U-F?A( zv(02@l+ArX7UjBVQRYUsIS7r5xxF-3aMfAcujBzpBRg>d!3rQ04w6dWYy)L6|F3ok zf>1gm@pU!3+w-X|M_P7ELcn_&IGDr1^$Ww6}O zmQ{mf${{9z(8iZ2^Pv02W^zv#?YZ^y`feD+5xqnrsPoUg+3(#1>0+b#H9L=1VW+*v z3xZ9?eI&4TFE0<;a(l!hh>05Vfh5d_bkjM=%G>iAjBlKR&Di;I|AVFx*xl(ZueqO` zVL2u`MJ7l^3{kf`A{%NqXpenf(Xrh`mR`$q1K;w%lTkW7b7D1r)do-lPySob_9noO zn(q7xDJYo++CV7|3n8|j5kDg|$RE1ybdi>B!*U}3jo!DfI_%FuMDux`^4ku$*EqVG z!(kYs*S2#vou!N=KYU(svMacxW+!u<)i^|4@u_x(+v*&8VYsf6qJJ2WSBKRhubTeB zy>Jd(BSSBL>e?onV{swyQ zubxoju3%38{$ul@Nao)^c

      R;qT92yon0G{}=%n3_U}LNX{T#B8qg3ARPh{($d|X!q7+~ppt@$bayI}0s=~RNr!Zv z8-3sJd%yqw@3YQXd+&4BESJN~{XEZ|zqqdJH(|<(QUtiSaIamvMj#_Cp>plob>y{c zXdfV0;1esFCpF+d9D8Xkr)$>;KVSVrOJpOYymrn1nv8_Fn){oLRP1Cm$sfVP=fn4( zHNWA`44`9W4u3A$x#W+_8j5y3Tnk3lb}cJ395hS=W_|daOj`UZaXTY{`xvL5FzpBZ5S0P{OWQjQhFf+0{in8fh`&O`=(H0erDuf z_x~B*|JKZpJzD*lA$2jqpV!ea)+5){9Ko)u3p*t~w514ZYGPYo|MP0Bd=5+XV>Um# zy1iN^g!`xAOgC>ccqu=#@xSW9=O@faeE*vmWxwzDyL%E*=#u8`m8o&5iJw{p3@HD+ zq-zN9SNY=Et~%4ofvl;ia~7olgYM^ENZtC~MI_o)pF{0_-vovEd(hLrM}&j-dx(wV zS5rcK<9BQC-xF|~{demltgB0A-K9UCXzgpLGEQoFaf0s>oDOsvj)DQOcmjc z{N5&!Bu-sczq1{wuKm6_eQI|7Mx7r8+U){Q%r)3F3KQ;I{V3ifTlM|5^ffLuH8mDd zZZXKHRbfdso`|e#{Z;?04fjU_a?*(Ell!|JJE;ab--lH1&-t^SzU0!^^M(arP`l4O zSNW)xo6zNVQt+}H%hp(?jF6CjC(?V(>GJ&W0mJtbvz;PB%|p+PFqfiJ_NJXLloU)z zLD%&d*Nw3f(M2BW8i%-ZmNk*CoDoF1@44r3)8(nC#Z-Nb_t{SSK%PbsQm%mOG6RE5 z9HY)#z@Vyjy+1RM%6q$IcP5ZX_Hc7D{)cdcpUd`cH&^#gJ1y7Yv|p3++K(45lm@4k zleHBI9NOxewQHO!-`--ci8R;xT^uhj_VDy2RN9Qoz6(=URE(-WSynIV7QQ;;`aKd9bl`(2< zAO~-)QN!MaNZ(>0JM3(pmV2M27Gh|DgBYrFv+L~Yy30Zmlqe8bb4!gB_O#OCur^iD zt&qy8hkM|?67BJ?KG8pexMTDMKUcFPYj1sYFnh4rHqc5xo>3vr^7}`b;X+-L@k*Qg z(`#$KttcFoGE;>z$GBXCT9KY`3a`zr@hAQpxDFESQPeq}`>VU>htp-7*YmyPP2Dyp zv{;{fG=7E~WzzCp_*uy1#bFa;ly-yX{WTH6>RKtRX0NTL>({THi#yqn ze%5`7Uq|aScZXUO=pQf)4Sp=B8{Wv0jOe*ORHQFD+UVnTLNCg4SM+Q2+rD$9^=i4n)oNQbn#3|FP~Oenv_Fy9oootC*7tk{N6~Hm~`I&Gv~G- zdU+guwl}CWM$4pPKup$hG-{S^^9+}mO1sMTeqLtie6dC-Mth-dUAEjXr){XRy5cN0 zw?v|LV-}Vua z79KPHcT)rd+TYiM25^7G0`K2VrDeqax*j}08Il31A^5xL|NK$RW9w%tOrxIDKBYMm z6s3!w@A@UOCYpGi9>mr8`ovBrUG?X8hck&Y3(Q_7aWJLc3@=?foNnX#M~|7uj1O1n zwFyP#E2*3f>Z!bAtQ%HkN3|m9+gbh^#tMuTHs-kZI4rgB6NB4#)*ZZm3@e;>G~GLH zYow||Pj{5x$Mc^LCWVJXSs4EwWfp-X^RK^WO#+5!L;cl59337FQac|$!#Ig)d| z)V2D-_qg(nH?itG0{5@E$TWWl>k|4iw~z|R#>p=whaiskX-HT&^MCt{1rpNCpUA&v zmU&DWb@$Kmf#-;b!@@cL-&~Xl4O32?eUWnzdL~yeTh*yW`#nyssXn)P*uC52`Y_`< z?4$5pAyU6-Gjssw)V}bz^s(%vBGlvG|u- zCYx4$k2Y5KVL6VYF~N?uMJJ9c@ zaNf>c%ECb(OY>>qMdn1&h5g z1@F_<%|{(ucaHU$eMd5vNWUA4Htlz@8MklG*7;!Refap-1_SFHD@l1YE1VY*`n8~a8Y<(RF=~_Lx97gFNf!0m+)1JI;B7MqH(Dz`|^?UVxKB8 zm)g0{4p(D?TVQP1{=L&^m%0Yiv56GNvlJ%TstaM`mEgsz<+#{R$ zzk5hjDWPkdMPH_(HmO5BV5+`!C1s+GTZ*Q3y^XzteJ8 zW!+{LM3VH%>SRuiHuB_kP!KE=)IU1mdd-|G2HV96S9Z?4GDN$;aJ=~t-e0Kj+PHn( zuKOi@G_wQ6m}e(LoUr49ZTj57xtC7{ zy}Q2~(Z-CwuYAc{CK^Y}%g(;tz>IW2uz}E`bgfU6!R`2Nr*3U|f81oQ>P3K)7C|SC zz`d2e5%l_=6iVs9sv<7d_`rDcR_f9Zbx~Z$XG`sUgXqrv!Kl zQ$_mncbRoKmI-RrKN48b?Y9fjQ7<3FGHClvZ(Kb%ixs)j?Dg0A&7AD)>U_yKU9WQ+ zR%<&qSjzK2O657?@6%4dinwQVE>vUHXj8XY<0YLoZAg{$Cj$CJEM7( zOPdF;BqMHga<@~_pP%ff5k9p-MZ6XV&Wk`r;u=3wgAIg{(Qj*U#iCtW2( zouP@-j6)2P%!HE6{G^#ZzuRB=3V%exekW7uB8tRy+Q9R~;<#}N33H_UyyQ?ri z-+TJ?-##igOt~p%KKmm1)TpS&a^m6LXJi^E+<^abA3E3=zg?O&i$>v$AlYVvhU0^U zrkaR<-=qKZmq{Rf=7#@!|DpD%pJ=c7Ac z8bw82_T;{o-Rw#{ZhRowVe{Js;F4!9j{oR5#cPaV`yymODAPQxe>baS@2SuPmBMP! ze;K8ev84I&?&7XiQ{O_b;8ubhXN`m+{~{^>N_M<_u69*nx%H^ZJH^yjyRr4166R}U z`zGC)A!qxC?Nl86zm__GIQ4N`IPeN{t~FgI>S|Y+=0m;0EUyBD!!<*c-Wo=Qrv=_xtMp&y@h*^fu>4D?d`@_;fxMcFFNgz;M z9m=KO(6eGHGyNKukFH{@DlBqZYWQMd_3>e{%4MG5;(%e5bfWlha#JAGr`SFwf9#^& zc1se5`yOI5Rj>6<;WcAX!@(;H4YPC~*ZeJ^!wIJxnRv$C*$~<;yQcG{wI(^(3EtlE zwC`y_x$WfB!p0Lz{*Cg%XZ!j!jwXXmz)07EQylnzbLDKSF5YIHYJ`O3`)4rk!7x(K<+BNF&kh=IbP@0*Q`0ZRFjpL3nLX zTA7j64Gmt0n~p7*q{Exi_l#%nIa43UP~iUN--tE?>)r8yL* z_rM10@Vod$d%W^K{qvL3vNDsUo|Jce66Z$N56`{YIfq0~h6i%wH^D z)*Qa|k&;jHxCXOm=fqRwz5X~<3J3-yBNDC z{{427t(*KRm2Wf|FPz$G=xf;2jq@RsPJP0qmlvn+IgswsXK7y}OCj*;YLGa6l@Obf z@&EFIGUVCPUH0GElE+mx1ETMj4Tn>LIR{Z_%ipAE6=Z_L9WyN}-~OkG5w`@577E7Brw8^ig?_-v$rf zT?l}{eLdC+s(Q>u1eKZs9B}gNBsY|rE-$>|ZGvRbwrUt`xn;7j1%>thI7ut7ekl98yjmAHJgafu(Wl1~ z?w%9k*s?#cY1d!UB!wYR*yz-@=^{RHH$sE+npBe|%s0j=7^^>-aWK1QL5{nRcIFiX zKDen9SlHV&9>22~cgLdfJu)mqrn>d7fQ%AHet<0V(07GJj<+Z@k?ZA)q%W%aF(1=D z5d%+|Ds*q-eo6(raX=P^8x1+XINjPEQdMe0UmsKw)lGAs!=VsxHn(PfC=0#7C*CCZ zvLkqYG#@?3Y6#8bcUnrOaH3?QqbpJ`cojwq-OjxDX1je!dCwf`MSX%Mv_|W*7h4^= zhCnS7ue3?CRodKgiO!GJYw%1V6YzfU(~TPqQ>(P-;rjENpP$^5gglGBm}|x3x|gNW zk1<(g5e~&L`ugg=DFbOdZ)nc1MlMNa0~m7I?`LL6*Fz#<q3W-qsdRIm)7y&y32j3NsjADN|6n~57NL| zv%i2-ZFP|0yfOA2!_Qo5s#5^t!4c1%++uf9bOl?s_Z56F$66QxO&gCEz2K`PMsXJy zehR)zbn07W`$7SIzUk=l=Iilt3zB&F*EU z$BTzIjW+P<+vQ9j3lf(NdGmJhFb0uy>C7!2ys2~cJ6g#$wTSWp1Po+y zwlyM>mdk?3XvTqn?K@4wDmAy(4yD0&o9(ycBZL)d+&GKt?BoK=p-W*sl!anBFZa#>d|)`?orrwMy8TDvr-agu){ zhJUV5SEE}=(sfPQ+nSzchu~B36?Y&|C4{X;OxNzD3IFQhF>NFDAx^UkkJ-(2=xmM* zAfU2g35VD;ED(>XoXkuP%(2(;+Qbzsl5CNWO=Ug|V1JC7U<5YhIpqe$O2$ZaG+ozb zu6S|#P<0$yKp+`iJ|n$52Y&WX&nCPC<5PYWGWZ?)W8)gr^@lXDT18KeTcoF6R|bxG zaymyYi4$jKDp}HvY*-TV{DI=@eOZOlzAzlkZ0hlJ{>!spUw>`h;*5Zv3~)6bA=E?o zu3@lI1nuX=z#;E-ZK`%LQd|f)U;zmRjub%kG3P|k;&I2ngT1M6CSOn zv>gUbCjzhmhAz#toz@&*2uUfgj#rAh^r*0mt8?A36|LKkV!R6C=8Ed(!coJ24RDCU z`B}2~mrf2nko5a+VdlMKU;v@*VZ7xh+pvbhFB)#I&L7?gS2hiYHs@DA`1Bm1<_y)G zmv+=n8qwGR@c`)wPfYk#oN*Qz!IW9cj_lBDo|4rLVR~a95J@8}u+nEZu+_0ty1;7)h38+8CJ@TP9IuyCV|?(9=nweHwvc*! zzWA}^t5MR&tO=20ij-Pc*L4>V6_dg-1VGH=YOO-l{=;&5JXR*xp}GtUTY?M=-7a5Z z_%ov|8CSs*%EDqdjf?q=5j2&Dif}s1T zLrKx_!%jR&=GzF=pk9oUB_-O+Ry@HL7Eus2PkDp|#6Q}3*Zya+)ozl)A2h>uq;>ZQ zh4>Ksy0DM@XS_AOJw7Fliy!J11`G)n>&1t^=&5?C@vM{?C-6(RAYonduvSaVgWOTq zAo&m_(Q`GOHWyeciugd$pon3WB!tyaAM*fh5nIJ5-C|#UeVc(wB{1C$2KJg)gpJ^r z7VHtbIQ%-P?h7jQMb>^`D5k+BaHR!2A5`u*!VtEu7cI*hDnzzl4z*on%HdF^zJMx|dSJ z1{47R18ePkBaPR(^7J4BLprt_`#U(~m3rFc<}fdH2Wm7CF2%6D05xMOC)*sHJQ!EQ zUYuRh*drNK%p6u`xr^_FLwjelcrFgZSnMJ6RozyjwhqWmUT;c@GWaqX=dDM!=Zgb9A9U5;^m4~E%+Cli7R!oF|T zyLx-2VXbYB(k#vE$yF2HzrHeV7>pDf_UZ{Fk%NRNvFAt-1tpGN#9PVHu107w4ms#J+{?0cb%N;{aLYmGZ8# z8s^NIw(Ag_W{6~<7r3M=BsPU1U*UbZE<|$VyB?-|bI=}n+c#b9iy22N9rCBuwzVgb zf>^%4bAjpCS1Fq4l&21lvkUyF)CX%_te8wsKQSW@$~-h&?RT7O5h!_DZ@WSO?a;>| zPzr9<{&_kzjwRQq#QA$4R6Q3EsIV$(_|elbhbHeDtpH}laiS!QJm+AYr4ARC@aFiJ ziQK3v$&}GJ9#^vJ;@!un`UiMkc)P>g_A_oRm@XjuaM23|>639d#Bk}RTkMDzRZQ^q zl-CxSXBbb%Xd=B;Wl@s;r4D1ng^r4t7Hhv{zI3!_eQI5%Ml#->S&EbIb* z8gC#?=OrE3x!j8nroBnzxFzZy;fLU)7;oV8K_r=lOH*zojUrI>Dj2tpG3P4ZxJ`L1 znLc|{nYcbO?k(A&9mW6D(N8zQ-r7~Kc(-gnn9{i0FyxD0p{z;SFte%zWZyy+Lxsg$ zE?M%^Ijd%g6WP_eBaksP7)q5JMn%xECo#%bL-5#wbQKxwQ?qUOoa}M0NEVXZfT90% zvY*C{qCU`*-{2VO9youy8MMjmikTz{nK3uh*|S)?p`upuOw#FQ$6Q;4QPC$oU1<{2 zV{Q@mBIInivZb*q>aI4*eiihHTK(tDbM3d>Z-W)_b7?yrJ@LpgDQ#mW_SfQl3vD*W zKu){+uKh*Q>yV3Bz`D#+VB_C3P_(9aVEd-$)&1^l@{AeV*S3?jDfLzhkG(V^w}od8 z9q$*t0_TJ=6gprY(`u{{81pK^?DnW-%=GUO#RMO0jJJ;|`eNphX_|;0j2JDxvMQ8W z=`d7iy^Vz2xMF0S#5tY?pRM|VgfWh%E7kD8vc}!mHCY1UGpC{N!(h^tAd`GYc(4DV zLVhqA;`K_PQ7KH&eXB1ElB38g$y_E038Yf@?C9bHsJU19AiYrINQ zB_vTqv$WPNNtfjfw#<;#*79Kn30sy#(WH-*y~LdjL1VtqGFbUJtf963ykuGW{i3Eq^>eqc8Jt1@`LiL zWVVj_!wfM9<(^@E#;HEUa^ud4(+b!ES-${j=Dp5$5R*y>83qP=>i9&B(_*5AUKl2m zt2%b7lXzUL2Fj69K4xOHjNx!O-DLR7i=cOHTE!vEZc{>?=Ntn^@wlpQ& z^b*Xe*!E-P7N)`NbuhB5)w!)lU{pN_)CDnnV8R@6a)tU%$P#lw7VHrw~r z@0A*2-Kjvo$+s0>fbmt_MnOLUL?{WL!7wJXsmG2o0MD{iZFoi<;F4{*zxusIGmAK+gn3M@3vE%*~ zb?_KPC!Q+c5?5-{{pG;b;O%{Np};Bfg&;&i3c@(hZ9;!ufua^LbMnxYTVNZg4-{j! z6=KYWT4T&%7R=4{!O4Ed1e+z#o|6g;L*gMhgVS?+TH1#rCwEM`NFA=GfHV^+hOG|b zE!0=n)Ts?)n*4fY)EPF@&J09F`;bU@FNXhT>+jwup!(hDI=b1!`M$}WCc6W`EgWjv zCwh72V>Zb>Vc2Pu1Z04CmT zc9aZiT^7o#QO76_u)-PyMsdqTp>f7cc56noIZ++BF%jW|5*JO7G9|1*L(V5W*9ve% zBhEWGV?m0$gHNKw`(kIaZtDj5ZJ?baPevh%$jN8lIYOlR!A^k$LW0Btu1PXGNkUlKs@uOrneg=<7uId6Ovc}M z1h`P^l+irPH5k)tgvR-Z=y(THP;N=OfDD*z8=eIrQ~VT6kn=Ev(A3Gc)Z5ZpsLi2hisTdw z$YXgomjiH2I^>xF1GAoon;R4U@>kjXK1gETs0Cj#%8^%|KDB>bv7vO89hE(wkOYxw zD0-CjfnwCNe58D=yhOU!1;3MbrEqJFN%zaSTfmw9bSv2nOyCntS>3gS0%8Ql0&B&w z|LGsYblyQ9Ej`_L^2)@<&LAp^T*?R;Q12B;D7b#745_AEED2+!>Oswpbjc>NrWk2E z?VZ zqWfQE&Ypm4|0?X3yiur8l$K(A3%IVDPhSG^XdXr0gcAvE``4Vb9K1i`&&R59M}H5X zhH5MyLe8Vg{V?ZGx9(eZVAFaVFz#$0qbVk};S$fm*Y7{VH}rewxY%_UP|^+rAV#n` zNHI&}j=x6hdz4vY*I(%&RCeT*k3L)NXdJ7FgPaJdgTpBcuN;O7VqqiH-kSj{7N8@O zLVJ}4OE;u=y})oJKxP;GO8@DbW9xdU56XA0TPSrukC{Wica~D%7D{|zG#embH~BEY zzBKm7BrBNR`1kTJDJdtC`+wN%ObJDI3wI~7RgGJ1*VR-8z_4Jg{_73N6h1hF*IMLF zK4Oa7LPJo%|I#C?pEe)FYnu2Q%uDdur9aI?Vh;9srrTwI{$8Lxj4@lN$X>&ayyiCS zyfrnMf5)9mR&v7M9o-0Rl{VfNU=0r(f~$y{d0yZ>(Uq5T)mM(>?I-MN3zIO?K15xWNqA;Sr zE0OK1r77$Fi|fR9TEg9jTyO?R;Z$6NFqYLL=b7i&OQ&y;dqA@7m|(q5^|s|WXu8w0vSTV@E2W$7*ZXoVuZ2Klqu)tg}ZAZy_RMBhY;w{E&@Zm^Z8 zpgK2!*L(e>3Sf48sf5b_%CwadQXkq`0eX<=oWP}xx4}fTdSDvZFCK+FK+g@74vQI9 zxUrj0R_empdGlb`8eJjmG{&YsJFwmRTfo(hRtQD!qsH(?Y<5ujsvh$ua=3^*7B3-iZPd@i%SsukZh+3j+}gw4{KA`iE*m8ucpD5BW;oTWH#G zZA5Aza+vESTa!7f0^`EvExQ`)nOf8*;#*4QT0hq=`Q~E4AFp0m$L>u-KIXGK8Mm5w z{p>#V@!EPCm~?w+uwY(qYUBO`zx@m~@3p%%s}b)UPmkJ%*63w(TDDIYC)}*M$X*^M#~(bZHccF51rAVarenA()T)Q!6|ic zNcU{?c{%qor=9lI_Ne9lhmCQsOS73Ql;_90#knV2-B(P0$2zYVY%bT~);}ioKgoKi zr1bUQ>+vb!EDw=+L>~Xh16s?ih7QGg8skNFhwheDFZV7|A~m{ z|3kgh|G`If-GNySzI#D&`@MXMig~WEy-#bD158-C6aTvE_)uczE5?1 zwGOyJ$5tGs;?3)Yr>aWAPY%ZIMEN(X=ZD6{N!J?Ha#bGPysLn6T_1s8;e%B6&1g%< zKML2F$>go6oYuLoxX5lmo)%tsWT`11{**f$HKXO9kL0;J(ztWHL&9^_xMZv!{L*A$ zY=B+N7e$nte!WGHj21chkfQK&xJW-U=SPy?ZH%LaQv&G|p2zGOel@I_X|?;5_2X7k zK8Lz2K)sTCdWE)LEkgap$=aiUr{(7Gbno4;ljSfKacGpm3IN6uMSM=cbC}8UMU1w4 zKa*tw9VH+W>z}DJj8)kc=?y<-r9C{+e8p?S3c|P~LTZ6Ot($?+RbEkOM}kDv{Oa=0 zgdi(V51WrM$vXEqk^IoCv01ZB9G@|&IZj#_5`ZP{KcY)uZ?8!ESj+R@*Uv)O+o<*Emp8D794tV?1Q?P*| zX+`xcf8?_OC(%7JR1I*0PN1_LS`(1P{H@qr9FXHm+-f{kyxLiS9H(VmB;#2KWhuYX zHG$l5vFY->=!&N=1whPxUm5+g#fHP_Um7R_jhdPo8SK~fh=fGdZ7(SbnwK-YLhRy1 zG%qu-iR9=Q(1_&v149^owtOPq1IniVb(!P;!D9=ei2uLDoBvxz#cToV(%TL-zVzmi zgRL2C40+zo8iehxbwn7SMiXd8qgCd7kGJgp+1uW6W=JmmWBs+}p~w%L-ZAl@1IqtF z#VY$0MF1NEnK|P9bsT_Ao;rm<$A}sv{do~ zg9fMLLhMAfzW7}vTWjx7tZ_6~@|ekbS&XjBAAjr%jBD_`w$^ylB}Mp@u@G|pFNy4* z=mRO%k4UIZtzq zf`7$S|B~|_gWePVB}@G)=0aZkTbXnQwpGYK94+YIzmLHM5T5=m7XB^HCC!A2{iWFY zZ{pj(#lX?b5z3pv-{Km!A9r5lILI=XeU~a_^U{63CG|hO-{TvZsZABJ`JEvQ6X&X$ zooR0A3%1&7+owA;nSiMJGi`t3;lGCsvw%H4lIS8fmN55q>YQw>o;iFAY5T{TU1`q# zrB7DYadtgZ)^_Fel5+IjdTrNv?i9S3SK?zIMVckVL%R`gFgQ5qTw}0coO`p2s5D;HJ&F$ZiMyK&~niJ^AYgb}#S5;2`eV zPVjl`eUmbp{v>=jVRVvKVKw}&LMoIE`Hd952NJX%Zkr{Laq?`mSLS$aHE8I0ZQQ5e zwNB30Yk1n~Z-qcL+Fz-LI3K^~(5_6-Dl^SF`volfU57adi-~H7r}LAkZc{9iwJ!0@ zVal$qmF!xj5?Dku>|FKR$o$^zX{I#y*1cb%7e_{2TOr(NMM_nhukTqPs0CdUn8To} zmcXYk@z7n^?78XE**?_vKHncUY5k0|bj(f|`X1H}zi2)MDzA-!8Yi=Fw@VQy!b*$5 zcaEJ5NgZKKY0Q@=!%gxGBaTP2A#yd2iwnSsB>=c{#M$&Im@#qEdN5z0u7c$lNKM-A z0~F8dM}BP8l&9QP;(S#iK;`fmRtl6!Usm0k&JW^A6!}_0CG*q^7M9cfT=h6xIgw7w zUlXqcSO?R7mm`PUTYi_?wsjl4DZ*Z^nWA#A@JdK#QH#VBC_dl<-tpf26CfH;INhnt zc^f4l+beviQv<|k3Sve4FN0)I{pmfgAM{}aC9-L}Y&aO}90~ppfL= z?p~kY1y8{aA$MoRupZlEC>+v%cKqvw_fVdG-`Qyhji-5jFQ7q)_-FjDFC?fc#)7JV zt9lFL)%z4z5-BwAT9@eIbU-l?W5SS=(ZFSH0`9S9Z$M6gn*QQkDy=fK&jrZKlB@Yg zN7P1|_S?wylU-jNUEd-ws|EpsWW02E|K7@Aj_>(NNfd|HRe;j-@o{ayEO`nY(k#ux zv_uku$#bI+B>t~J^@R`+#5n@`GsWzlmN2dBh~Yr7;X~DFPP|9S02aj#V8{6Av39wd zSM)N4$Lz+*FCbnIhoXmz2V%**xOLwZ?

      + + ![](13.1.png) + +
      图 13.1: 字典树,存储了单词 A、to、tea、ted、ten、i、in 和 inn,以及它们的频率
      +
      + +为什么需要用字典树解决这类问题呢?假如我们有一个储存了近万个单词的字典,即使我们使用哈希,在其中搜索一个单词的实际开销也是非常大的,且无法轻易支持搜索单词前缀。然而由于一个英文单词的长度 n 通常在 10 以内,如果我们使用字典树,则可以在 $O(n)$——近似 $O(1)$ 的时间内完成搜索,且额外开销非常小。 + +## [208. Implement Trie (Prefix Tree)](https://leetcode.com/problems/implement-trie-prefix-tree/) + +### Problem Description + +尝试建立一个字典树,支持快速插入单词、查找单词、查找单词前缀的功能。 + +### Input and Output Example + +以下是数据结构的调用样例。 + +``` +Trie trie = new Trie(); +trie.insert("apple"); +trie.search("apple"); // true +trie.search("app"); // false +trie.startsWith("app"); // true +trie.insert("app"); +trie.search("app"); // true +``` + +### Solution Explanation + +以下是字典树的典型实现方法。 + + + + +```cpp +struct TrieNode { + bool word_ends; + vector children; + TrieNode() : word_ends(false), children(26, nullptr) {} +}; + +class Trie { + public: + Trie() : root_(new TrieNode()) {} + + void insert(string word) { + TrieNode* node = root_; + for (char c : word) { + int pos = c - ’a’; + if (node->children[pos] == nullptr) { + node->children[pos] = new TrieNode(); + } + node = node->children[pos]; + } + node->word_ends = true; + } + + bool search(string word) { + TrieNode* node = root_; + for (char c : word) { + if (node == nullptr) { + break; + } + node = node->children[c - ’a’]; + } + return node != nullptr && node->word_ends; + } + + bool startsWith(string prefix) { + TrieNode* node = root_; + for (char c : prefix) { + if (node == nullptr) { + break; + } + node = node->children[c - ’a’]; + } + return node != nullptr; + } + + private: + TrieNode* root_; +}; +``` + + + + +```py +class TrieNode: + def __init__(self): + self.word_ends = False + self.children = [None] * 26 + +class Trie: + def __init__(self): + self.root = TrieNode() + + def insert(self, word: str) -> None: + node = self.root + for c in word: + pos = ord(c) - ord("a") + if node.children[pos] is None: + node.children[pos] = TrieNode() + node = node.children[pos] + node.word_ends = True + + def search(self, word: str) -> bool: + node = self.root + for c in word: + if node is None: + break + node = node.children[ord(c) - ord("a")] + return node is not None and node.word_ends + + def startsWith(self, prefix: str) -> bool: + node = self.root + for c in prefix: + if node is None: + break + node = node.children[ord(c) - ord("a")] + return node is not None + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-7-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-7-exercises.md new file mode 100644 index 00000000..b8e9846c --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-7-exercises.md @@ -0,0 +1,81 @@ +--- +sidebar_position: 74 +--- + +# 13.7 Exercises + +## Basic Difficulty + +### [226. Invert Binary Tree](https://leetcode.com/problems/invert-binary-tree/) + +巧用递归,你可以在五行内完成这道题。 + +### [617. Merge Two Binary Trees](https://leetcode.com/problems/merge-two-binary-trees/) + +同样的,利用递归可以轻松搞定。 + +### [572. Subtree of Another Tree](https://leetcode.com/problems/subtree-of-another-tree/) + +子树是对称树的姊妹题,写法也十分类似。 + +### [404. Sum of Left Leaves](https://leetcode.com/problems/sum-of-left-leaves/) + +怎么判断一个节点是不是左节点呢?一种可行的方法是,在辅函数里多传一个参数,表示当前节点是不是父节点的左节点。 + +### [513. Find Bottom Left Tree Value](https://leetcode.com/problems/find-bottom-left-tree-value/) + +最左下角的节点满足什么条件?针对这种条件,我们该如何找到它? + +### [538. Convert BST to Greater Tree](https://leetcode.com/problems/convert-bst-to-greater-tree/) + +尝试利用某种遍历方式来解决此题,每个节点只需遍历一次。 + +### [235. Lowest Common Ancestor of a Binary Search Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/) + +利用 BST 的独特性质,这道题可以很轻松完成。 + +### [530. Minimum Absolute Difference in BST](https://leetcode.com/problems/minimum-absolute-difference-in-bst/) + +还记得我们所说的,对于 BST 应该利用哪种遍历吗? + +## Advanced Difficulty + +### [1530. Number of Good Leaf Nodes Pairs](https://leetcode.com/problems/number-of-good-leaf-nodes-pairs/) + +题目 543 的变种题,注意在辅函数中,每次更新的全局变量是左右两边距离之和满足条件的数量,而返回的是左右两边所有(长度不溢出的)子节点的高度 +1。 + +### [889. Construct Binary Tree from Preorder and Postorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-postorder-traversal/) + +给定任意两种遍历结果,我们都可以重建树的结构。 + +### [106. Construct Binary Tree from Inorder and Postorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/) + +给定任意两种遍历结果,我们都可以重建树的结构。 + +### [94. Binary Tree Inorder Traversal](https://leetcode.com/problems/binary-tree-inorder-traversal/) + +因为前中序后遍历是用递归实现的,而递归的底层实现是栈操作,因此我们总能用栈实现。 + +### [145. Binary Tree Postorder Traversal](https://leetcode.com/problems/binary-tree-postorder-traversal/) + +因为前中序后遍历是用递归实现的,而递归的底层实现是栈操作,因此我们总能用栈实现。 + +### [236. Lowest Common Ancestor of a Binary Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/) + +现在不是 BST,而是普通的二叉树了,该怎么办? + +### [109. Convert Sorted List to Binary Search Tree](https://leetcode.com/problems/convert-sorted-list-to-binary-search-tree/) + +把排好序的链表变成 BST。为了使得 BST 尽量平衡,我们需要寻找链表的中点。 + +### [897. Increasing Order Search Tree](https://leetcode.com/problems/increasing-order-search-tree/) + +把 BST 压成一个链表,务必考虑清楚指针操作的顺序,否则可能会出现环路。 + +### [653. Two Sum IV - Input is a BST](https://leetcode.com/problems/two-sum-iv-input-is-a-bst/) + +啊哈,这道题可能会把你骗到。 + +### [450. Delete Node in a BST](https://leetcode.com/problems/delete-node-in-a-bst/) + +当寻找到待删节点时,你可以分情况考虑——当前节点是叶节点、只有一个子节点和有两个子节点。建议同时回收内存。 \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13.1.png b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13.1.png new file mode 100644 index 0000000000000000000000000000000000000000..06c168c6cc9b678d71b1481c04f3f3cb8e2ba56e GIT binary patch literal 49070 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⋙uQjBTmL--5X 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 a_JlStNm}@B)9VWe_)$?*SE!OR5B@*1_9g8A literal 0 HcmV?d00001 diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/_category_.json new file mode 100644 index 00000000..db81316e --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "13. 指针三剑客之二:树", + "position": 13, + "link": { + "type": "generated-index", + "description": "第 13 章 指针三剑客之二:树" + } +} diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-1-data-structure-introduction.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-1-data-structure-introduction.mdx new file mode 100644 index 00000000..8e592d82 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-1-data-structure-introduction.mdx @@ -0,0 +1,16 @@ +--- +sidebar_position: 75 +--- + +# 14.1 数据结构介绍 + +作为指针三剑客之三,图是树的升级版。`图`通常分为有向(directed)或无向(undirected),有循环(cyclic)或无循环(acyclic),所有节点相连(connected)或不相连(disconnected)。树即是一个相连的无向无环图,而另一种很常见的图是`有向无环图`(Directed Acyclic Graph,DAG)。 + +
      + + ![](14.1.png) + +
      图 14.1: 有向无环图样例
      +
      + +图通常有两种表示方法。假设图中一共有 n 个节点、m 条边。第一种表示方法是`邻接矩阵`(adjacency matrix):我们可以建立一个 n × n 的矩阵 G,如果第 i 个节点连向第 j 个节点,则 G[i][j] = 1,反之为 0;如果图是无向的,则这个矩阵一定是对称矩阵,即 G[i][j] = G[j][i]。第二种表示方法是`邻接链表`(adjacency list):我们可以建立一个大小为 n 的数组,每个位置 i 储存一个数组或者链表,表示第 i 个节点连向的其它节点。邻接矩阵空间开销比邻接链表大,但是邻接链表不支持快速查找 i 和 j 是否相连,因此两种表示方法可以根据题目需要适当选择。除此之外,我们也可以直接用一个 m × 2 的矩阵储存所有的边。 \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-2-bipartite-graph.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-2-bipartite-graph.mdx new file mode 100644 index 00000000..ce5ee08d --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-2-bipartite-graph.mdx @@ -0,0 +1,90 @@ +--- +sidebar_position: 76 +--- + +# 14.2 二分图 + +`二分图`算法也称为`染色法`,是一种广度优先搜索。如果可以用两种颜色对图中的节点进行着色,并且保证相邻的节点颜色不同,那么图为二分。 + +## [785. Is Graph Bipartite?](https://leetcode.com/problems/is-graph-bipartite/) + +### Problem Description + +给定一个图,判断其是否可以二分。 + +### Input and Output Example + +输入是邻接链表表示的图(如位置 0 的邻接链表为 [1,3],表示 0 与 1、0 与 3 相连);输出是一个布尔值,表示图是否二分。 + +``` +Input: [[1,3], [0,2], [1,3], [0,2]] +0----1 +| | +| | +3----2 +Output: true +``` + +在这个样例中,我们可以把 {0,2} 分为一组,把 {1,3} 分为另一组。 + +### Solution Explanation + +利用队列和广度优先搜索,我们可以对未染色的节点进行染色,并且检查是否有颜色相同的相邻节点存在。注意在代码中,我们用 0 表示未检查的节点,用 1 和 2 表示两种不同的颜色。 + + + + +```cpp +bool isBipartite(vector>& graph) { + int n = graph.size(); + vector color(n, 0); + queue q; + for (int i = 0; i < n; ++i) { + if (color[i] == 0) { + q.push(i); + color[i] = 1; + } + while (!q.empty()) { + int node = q.front(); + q.pop(); + for (int j : graph[node]) { + if (color[j] == 0) { + q.push(j); + color[j] = color[node] == 2 ? 1 : 2; + } else if (color[j] == color[node]) { + return false; + } + } + } + } + return true; +} +``` + + + + +```py +def isBipartite(graph: List[List[int]]) -> bool: + n = len(graph) + color = [0] * n + q = collections.deque() + + for i in range(n): + if color[i] == 0: + q.append(i) + color[i] = 1 + while len(q) > 0: + node = q.popleft() + for j in graph[node]: + if color[j] == 0: + q.append(j) + color[j] = 1 if color[node] == 2 else 2 + elif color[j] == color[node]: + return False + return True +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-3-topological-sorting.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-3-topological-sorting.mdx new file mode 100644 index 00000000..d49ee4ad --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-3-topological-sorting.mdx @@ -0,0 +1,97 @@ +--- +sidebar_position: 77 +--- + +# 14.3 拓扑排序 + +`拓扑排序`(topological sort)是一种常见的,对有向无环图排序的算法。给定有向无环图中的 $N$ 个节点,我们把它们排序成一个线性序列;若原图中节点 i 指向节点 j,则排序结果中 i 一定在 j 之前。拓扑排序的结果不是唯一的,只要满足以上条件即可。 + +## [210. Course Schedule II](https://leetcode.com/problems/course-schedule-ii/) + +### Problem Description + +给定 N 个课程和这些课程的前置必修课,求可以一次性上完所有课的顺序。 + +### Input and Output Example + +输入是一个正整数,表示课程数量,和一个二维矩阵,表示所有的有向边(如 [1,0] 表示上课程 1 之前必须先上课程 0)。输出是一个一维数组,表示拓扑排序结果。 + +``` +Input: numCourses = 4, prerequisites = [[1,0],[2,0],[3,1],[3,2]] +Output: [0,1,2,3] +``` + +在这个样例中,另一种可行的顺序是 [0,2,1,3]。 + +### Solution Explanation + +我们可以先建立一个邻接矩阵表示图,方便进行直接查找。这里注意我们将所有的边反向,使得如果课程 i 指向课程 j,那么课程 i 需要在课程 j 前面先修完。这样更符合我们的直观理解。 + +拓扑排序也可以被看成是广度优先搜索的一种情况:我们先遍历一遍所有节点,把入度为 0 的节点(即没有前置课程要求)放在队列中。在每次从队列中获得节点时,我们将该节点放在目前排序的末尾,并且把它指向的课程的入度各减 1;如果在这个过程中有课程的所有前置必修课都已修完(即入度为 0),我们把这个节点加入队列中。当队列的节点都被处理完时,说明所有的节点都已排好序,或因图中存在循环而无法上完所有课程。 + + + + +```cpp +vector findOrder(int numCourses, vector>& prerequisites) { + vector> graph(numCourses, vector()); + vector indegree(numCourses, 0), schedule; + for (const auto& pr : prerequisites) { + graph[pr[1]].push_back(pr[0]); + ++indegree[pr[0]]; + } + queue q; + for (int i = 0; i < indegree.size(); ++i) { + if (indegree[i] == 0) { + q.push(i); + } + } + while (!q.empty()) { + int u = q.front(); + q.pop(); + schedule.push_back(u); + for (int v : graph[u]) { + --indegree[v]; + if (indegree[v] == 0) { + q.push(v); + } + } + } + for (int i = 0; i < indegree.size(); ++i) { + if (indegree[i] != 0) { + return vector(); + } + } + return schedule; +} +``` + + + + +```py +def findOrder(numCourses: int, prerequisites: List[List[int]]) -> List[int]: + graph = [[] for _ in range(numCourses)] + indegree = [0] * numCourses + schedule = [] + + for pr_from, pr_to in prerequisites: + graph[pr_to].append(pr_from) + indegree[pr_from] += 1 + + q = collections.deque([i for i, deg in enumerate(indegree) if deg == 0]) + + while len(q) > 0: + u = q.popleft() + schedule.append(u) + for v in graph[u]: + indegree[v] -= 1 + if indegree[v] == 0: + q.append(v) + + return schedule if all(deg == 0 for deg in indegree) else [] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-4-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-4-exercises.md new file mode 100644 index 00000000..7ea74b28 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-4-exercises.md @@ -0,0 +1,21 @@ +--- +sidebar_position: 78 +--- + +# 14.4 Exercises + +## Basic Difficulty + +### [1059. All Paths from Source Lead to Destination](https://leetcode.com/problems/all-paths-from-source-lead-to-destination/) + +虽然使用深度优先搜索可以解决大部分的图遍历问题,但是注意判断是否陷入了环路。 + +## Advanced Difficulty + +### [1135. Connecting Cities With Minimum Cost](https://leetcode.com/problems/connecting-cities-with-minimum-cost/) + +笔者其实已经把这道题的题解写好了,才发现这道题是需要解锁才可以看的题目。为了避免版权纠纷,故将其移至练习题内。本题考察最小生成树(minimum spanning tree, MST)的求法,通常可以用两种方式求得:Prim’s Algorithm,利用优先队列选择最小的消耗;以及 Kruskal’s Algorithm,排序后使用并查集。 + +### [882. Reachable Nodes In Subdivided Graph](https://leetcode.com/problems/reachable-nodes-in-subdivided-graph/) + +这道题笔者考虑了很久,最终决定把它放在练习题而非详细讲解。本题是经典的节点最短距离问题,常用的算法有 Bellman-Ford 单源最短路算法,以及 Dijkstra 无负边单源最短路算法。虽然经典,但是 LeetCode 很少有相关的题型,因此这里仅供读者自行深入学习。 \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14.1.png b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14.1.png new file mode 100644 index 0000000000000000000000000000000000000000..46ebed1b401557b94a5c6f1d46e362ffa38deb69 GIT binary patch literal 103164 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 + + ![](15.1.png) + +

      图 15.1: 并查集样例,其中 union 操作可以将两个集合按秩合并,find 操作可以查找节点的祖先并压缩路径。
      + + +## [684. Redundant Connection](https://leetcode.com/problems/redundant-connection/) + +### Problem Description + +在无向图找出一条边,移除它之后该图能够成为一棵树(即无向无环图)。如果有多个解,返回在原数组中位置最靠后的那条边。 + +### Input and Output Example + +输入是一个二维数组,表示所有的边(对应的两个节点);输出是一个一维数组,表示需要移除的边(对应的两个节点)。 + +``` +Input: [[1,2], [1,3], [2,3]] + 1 + / \ +2 - 3 +Output: [2,3] +``` + +### Solution Explanation + +因为需要判断是否两个节点被重复连通,所以我们可以使用并查集来解决此类问题。具体实现算法如下所示。 + + + + +```cpp +class Solution { + public: + vector findRedundantConnection(vector>& edges) { + n_ = edges.size(); + id_ = vector(n_); + depth_ = vector(n_, 1); + for (int i = 0; i < n_; ++i) { + id_[i] = i; + } + for (auto& edge : edges) { + int i = edge[0], j = edge[1]; + if (linked(i - 1, j - 1)) { + return vector{i, j}; + } + connect(i - 1, j - 1); + } + return vector(); + } + + private: + int find(int i) { + // 路径压缩。 + while (i != id_[i]) { + id_[i] = id_[id_[i]]; + i = id_[i]; + } + return i; + } + + void connect(int i, int j) { + i = find(i), j = find(j); + if (i == j) { + return; + } + // 按秩合并。 + if (depth_[i] <= depth_[j]) { + id_[i] = j; + depth_[j] = max(depth_[j], depth_[i] + 1); + } else { + id_[j] = i; + depth_[i] = max(depth_[i], depth_[j] + 1); + } + } + + bool linked(int i, int j) { return find(i) == find(j); } + + int n_; + vector id_; + vector depth_; +}; +``` + + + + +```py +class Solution: + def __init__(self): + self.n = 0 + self.id = None + self.depth = None + + def find(self, i: int) -> int: + # 路径压缩。 + while i != self.id[i]: + self.id[i] = self.id[self.id[i]] + i = self.id[i] + return i + + def connect(self, i: int, j: int): + i = self.find(i) + j = self.find(j) + if i == j: + return + # 按秩合并。 + if self.depth[i] <= self.depth[j]: + self.id[i] = j + self.depth[j] = max(self.depth[j], self.depth[i] + 1) + else: + self.id[j] = i + self.depth[i] = max(self.depth[i], self.depth[j] + 1) + + def linked(self, i: int, j: int) -> bool: + return self.find(i) == self.find(j) + + def findRedundantConnection(self, edges: List[List[int]]) -> List[int]: + self.n = len(edges) + self.id = list(range(self.n)) + self.depth = [1] * self.n + for i, j in edges: + if self.linked(i - 1, j - 1): + return [i, j] + self.connect(i - 1, j - 1) + return [] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-3-composite-data-structures.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-3-composite-data-structures.mdx new file mode 100644 index 00000000..b9b28338 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-3-composite-data-structures.mdx @@ -0,0 +1,257 @@ +--- +sidebar_position: 77 +--- + +# 15.3 复合数据结构 + +这一类题通常采用哈希表或有序表辅助记录,从而加速寻址;再配上数组或者链表进行连续的数据储存,从而加速连续选址或删除值。 + +## [146. LRU Cache](https://leetcode.com/problems/lru-cache/) + +### Problem Description + +设计一个固定大小的,最近最少使用缓存 (least recently used cache, LRU)。每次将信息插入未满的缓存的时候,以及更新或查找一个缓存内存在的信息的时候,将该信息标为最近使用。在缓存满的情况下将一个新信息插入的时候,需要移除最旧的信息,插入新信息,并将该新信息标为最近使用。 + +### Input and Output Example + +以下是数据结构的调用样例。给定一个大小为 n 的缓存,利用最近最少使用策略储存数据。 + +``` +LRUCache cache = new LRUCache( 2 /* capacity */ ); +cache.put(1, 1); +cache.put(2, 2); +cache.get(1); // 输出 value 1 +cache.put(3, 3); // 移除 key 2 +cache.get(2); // 输出 value -1 (未找到) +cache.put(4, 4); // 移除 key 1 +cache.get(1); // 输出 value -1 (未找到) +cache.get(3); // 输出 value 3 +cache.get(4); // 输出 value 4 +``` + +### Solution Explanation + +我们采用一个链表来储存信息的 key 和 value,链表的链接顺序即为最近使用的新旧顺序,最新的信息在链表头节点。同时我们需要一个哈希表进行查找,键是信息的 key,值是其在链表中的对应指针/迭代器。每次查找成功(cache hit)时,需要把指针/迭代器对应的节点移动到链表的头节点。 + + + + +```cpp +class LRUCache { + public: + LRUCache(int capacity) : n_(capacity) {} + + int get(int key) { + auto it = key_to_cache_it_.find(key); + if (it == key_to_cache_it_.end()) { + return -1; + } + cache_.splice(cache_.begin(), cache_, it->second); + return it->second->second; + } + + void put(int key, int value) { + auto it = key_to_cache_it_.find(key); + if (it != key_to_cache_it_.end()) { + it->second->second = value; + return cache_.splice(cache_.begin(), cache_, it->second); + } + cache_.insert(cache_.begin(), make_pair(key, value)); + key_to_cache_it_[key] = cache_.begin(); + if (cache_.size() > n_) { + key_to_cache_it_.erase(cache_.back().first); + cache_.pop_back(); + } + } + + private: + list> cache_; + unordered_map>::iterator> key_to_cache_it_; + int n_; +}; +``` + + + + +```py +class Node: + def __init__(self, key=-1, val=-1): + self.key = key + self.val = val + self.prev = None + self.next = None + +class LinkedList: + def __init__(self): + self.dummy_start = Node() + self.dummy_end = Node() + self.dummy_start.next = self.dummy_end + self.dummy_end.prev = self.dummy_start + + def appendleft(self, node) -> Node: + left, right = self.dummy_start, self.dummy_start.next + node.next = right + right.prev = node + left.next = node + node.prev = left + return node + + def remove(self, node) -> Node: + left, right = node.prev, node.next + left.next = right + right.prev = left + return node + + def move_to_start(self, node): + return self.appendleft(self.remove(node)) + + def pop(self): + return self.remove(self.dummy_end.prev) + + def peek(self): + return self.dummy_end.prev.val + +class LRUCache: + def __init__(self, capacity: int): + self.n = capacity + self.key_to_node = dict() + self.cache_nodes = LinkedList() + + def get(self, key: int) -> int: + if key not in self.key_to_node: + return -1 + node = self.key_to_node[key] + self.cache_nodes.move_to_start(node) + return node.val + + def put(self, key: int, value: int) -> None: + if key in self.key_to_node: + node = self.cache_nodes.remove(self.key_to_node[key]) + node.val = value + else: + node = Node(key, value) + self.key_to_node[key] = node + self.cache_nodes.appendleft(node) + if len(self.key_to_node) > self.n: + self.key_to_node.pop(self.cache_nodes.pop().key) +``` + + + + + +对于 Python 而言,我们还可以直接利用 OrderedDict 函数实现 LRU,这将大大简化题目难度。这里笔者希望读者还是仔细研读一下以上题解,了解 LRU 实现的核心原理。 + + +```py +class LRUCache: + def __init__(self, capacity: int): + self.n = capacity + self.cache = {} + + def get(self, key: int) -> int: + if key not in self.cache: + return -1 + self.cache[key] = self.cache.pop(key) + return self.cache[key] + + def put(self, key: int, value: int) -> None: + if key in self.cache: + self.cache.pop(key) + self.cache[key] = value + if len(self.cache) > self.n: + self.cache.pop(next(iter(self.cache))) +``` + +## [380. Insert Delete GetRandom O(1)](https://leetcode.com/problems/insert-delete-getrandom-o1/) + +### Problem Description + +设计一个插入、删除和随机取值均为 $O(1)$ 时间复杂度的数据结构。 + +### Input and Output Example + +以下是数据结构的调用样例。 + +``` +RandomizedSet randomizedSet = new RandomizedSet(); +randomizedSet.insert(1); +randomizedSet.remove(2); +randomizedSet.insert(2); +randomizedSet.getRandom(); // 50% 1, 50% 2 +randomizedSet.remove(1); +randomizedSet.insert(2); +randomizedSet.getRandom(); // 100% 2 +``` + +### Solution Explanation + +我们采用一个数组存储插入的数字,同时利用一个哈希表查找位置。每次插入数字时,直接加入数组,且将位置记录在哈希表中。每次删除数字时,将当前数组最后一位与删除位互换,并更新哈希表。随机取值时,则可以在数组内任意选取位置。 + + + + +```cpp +class RandomizedSet { + public: + bool insert(int val) { + if (v_to_k_.contains(val)) { + return false; + } + v_to_k_[val] = nums_.size(); + nums_.push_back(val); + return true; + } + + bool remove(int val) { + if (!v_to_k_.contains(val)) { + return false; + } + v_to_k_[nums_.back()] = v_to_k_[val]; + nums_[v_to_k_[val]] = nums_.back(); + v_to_k_.erase(val); + nums_.pop_back(); + return true; + } + + int getRandom() { return nums_[rand() % nums_.size()]; } + + private: + unordered_map v_to_k_; + vector nums_; +}; +``` + + + + +```py +class RandomizedSet: + def __init__(self): + self.nums = [] + self.v_to_k = {} + + def insert(self, val: int) -> bool: + if val in self.v_to_k: + return False + self.v_to_k[val] = len(self.nums) + self.nums.append(val) + return True + + def remove(self, val: int) -> bool: + if val not in self.v_to_k: + return False + self.v_to_k[self.nums[-1]] = self.v_to_k[val] + self.nums[self.v_to_k[val]] = self.nums[-1] + del self.v_to_k[val] + self.nums.pop() + return True + + def getRandom(self) -> int: + return self.nums[random.randint(0, len(self.nums) - 1)] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-4-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-4-exercises.md new file mode 100644 index 00000000..4be6947c --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-4-exercises.md @@ -0,0 +1,21 @@ +--- +sidebar_position: 78 +--- + +# 15.4 Exercises + +## Basic Difficulty + +### [1135. Connecting Cities With Minimum Cost](https://leetcode.com/problems/connecting-cities-with-minimum-cost/) + +使用并查集,按照 Kruskal’s Algorithm 把这道题再解决一次吧。 + +## Advanced Difficulty + +### [432. All O`one Data Structure](https://leetcode.com/problems/all-oone-data-structure/) + +设计一个 increaseKey,decreaseKey,getMaxKey,getMinKey 均为 O(1) 时间复杂度的数据结构。 + +### [716. Max Stack](https://leetcode.com/problems/max-stack/) + +设计一个支持 push,pop,top,getMax 和 popMax 的 stack。可以用类似 LRU 的方法降低时间复杂度,但是因为想要获得的是最大值,我们应该把 unordered_map 换成哪一种数据结构呢? \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15.1.png b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15.1.png new file mode 100644 index 0000000000000000000000000000000000000000..6a2df359fca0c73d0ff823d313a1bac31d9af9cd GIT binary patch literal 29206 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 B6H@>H literal 0 HcmV?d00001 diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/_category_.json new file mode 100644 index 00000000..cbe6af2e --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "15. 更加复杂的数据结构 ", + "position": 15, + "link": { + "type": "generated-index", + "description": "第 15 章 更加复杂的数据结构" + } +} diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-1-algorithm-explanation.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-1-algorithm-explanation.md new file mode 100644 index 00000000..9746f6c7 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-1-algorithm-explanation.md @@ -0,0 +1,21 @@ +--- +sidebar_position: 5 +--- + +# 2.1 算法解释 + +The two-pointer technique is primarily used for traversing arrays, where two pointers point to different elements to collaborate on a task. It can also be extended to multiple pointers across multiple arrays. + +If two pointers point to the same array and move in the same direction without intersecting, this is also known as a sliding window (the area between the two pointers represents the current window), often used for interval searching. + +If two pointers point to the same array but move in opposite directions, they can be used for searching, especially when the array is sorted. + +In C++, pay attention to the position of `const` as it affects the pointer’s behavior: + +```cpp +int x; +int * p1 = &x; // The pointer and the value can both be modified +const int * p2 = &x; // The pointer can be modified, but the value cannot (const int) +int * const p3 = &x; // The pointer cannot be modified (* const), but the value can +const int * const p4 = &x; // Neither the pointer nor the value can be modified +``` diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-2-two-sum.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-2-two-sum.mdx new file mode 100644 index 00000000..b13d8cd6 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-2-two-sum.mdx @@ -0,0 +1,73 @@ +--- +sidebar_position: 6 +--- + +# 2.2 Two Sum + +## [167. Two Sum II - Input array is sorted](https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/) + +### Problem Description + +Find two numbers in an ascending integer array such that their sum equals a given value. There is exactly one solution. + + +### Input and Output Example + +The input is an array (`numbers`) and a target value (`target`). The output is the positions of the two numbers, starting from 1. + +``` +Input: numbers = [2,7,11,15], target = 9 +Output: [1,2] +``` + +In this example, the sum of the first number (2) and the second number (7) equals the target value (9). + +### Solution Explanation + +Since the array is sorted, we can use a two-pointer approach with pointers moving in opposite directions to find these two numbers. One pointer starts at the smallest element, on the far left of the array, moving right; the other starts at the largest element, on the far right of the array, moving left. + +If the sum of the elements pointed to by the two pointers equals the target, then they are the solution. If the sum is less than the target, we move the left pointer one position to the right to increase the sum. If the sum is greater than the target, we move the right pointer one position to the left to decrease the sum. + +It can be proven that for a sorted array with a solution, the two-pointer approach will always reach the optimal solution. Here’s the proof: Assume the positions of the solution are `l` and `r`. If the left pointer is to the left of `l` and the right pointer has already moved to `r`, the sum of the two values will be less than the target, so the left pointer will continue moving right until it reaches `l`. Similarly, if the right pointer is to the right of `r` and the left pointer has already moved to `l`, the sum will be greater than the target, so the right pointer will move left until it reaches `r`. Thus, the two pointers will converge at `l` and `r`, as no other scenario prevents this convergence. + + + + +```cpp +vector twoSum(vector& numbers, int target) { + int l = 0, r = numbers.size() - 1, two_sum; + while (l < r) { + two_sum = numbers[l] + numbers[r]; + if (two_sum == target) { + break; + } + if (two_sum < target) { + ++l; + } else { + --r; + } + } + return vector{l + 1, r + 1}; +} +``` + + + + +```py +def twoSum(numbers: List[int], target: int) -> List[int]: + l, r = 0, len(numbers) - 1 + while l < r: + two_sum = numbers[l] + numbers[r] + if two_sum == target: + break + if two_sum < target: + l += 1 + else: + r -= 1 + return [l + 1, r + 1] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-3-merge-sorted-arrays.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-3-merge-sorted-arrays.mdx new file mode 100644 index 00000000..0c2c3dbf --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-3-merge-sorted-arrays.mdx @@ -0,0 +1,68 @@ +--- +sidebar_position: 7 +--- + +# 2.3 Merging Two Sorted Arrays + +## [88. Merge Sorted Array](https://leetcode.com/problems/merge-sorted-array/) + +### Problem Description + +Given two sorted arrays, merge them into one array. + +### Input and Output Example + +The input consists of two arrays and their respective lengths `m` and `n`. The length of the first array is extended to `m + n`, with the extra `n` positions filled with `0`s. The task is to merge the second array into the first array without allocating additional space. + + +``` +Input: nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3 +Output: nums1 = [1,2,2,3,5,6] +``` + + +### Solution Explanation + +Since both arrays are already sorted, we can place two pointers at the end of each array: at the `(m - 1)` position of `nums1` and the `(n - 1)` position of `nums2`. Each time, copy the larger number to the end of `nums1` and move the pointer one position to the left. + +To keep track of `nums1`'s end position, we also need a third pointer for copying. In the following code, we use `m` and `n` as pointers for the two arrays and create an additional pointer, `pos`, initially set to `m + n - 1`. Each time we move `m` or `n` to the left, we also move `pos` to the left. Note that if all numbers from `nums1` have been copied, don't forget to continue copying numbers from `nums2`; if all numbers from `nums2` have been copied, the remaining numbers in `nums1` do not need to change as they are already sorted. + +In the C++ solution, we use the `++` and `--` shorthand: both `a++` and `++a` increment `a` by 1, but `a++` returns the original value of `a`, while `++a` returns `a + 1`. If you only want to increase `a` without needing a return value, either syntax is fine (`++a` is slightly faster in unoptimized code). + + + + +```cpp +void merge(vector& nums1, int m, vector& nums2, int n) { + int pos = m-- + n-- - 1; + while (m >= 0 && n >= 0) { + nums1[pos--] = nums1[m] > nums2[n] ? nums1[m--] : nums2[n--]; + } + while (n >= 0) { + nums1[pos--] = nums2[n--]; + } +} +``` + + + + +```py +def merge(nums1: List[int], m: int, nums2: List[int], n: int) -> None: + pos = m + n - 1 + m -= 1 + n -= 1 + while m >= 0 and n >= 0: + if nums1[m] > nums2[n]: + nums1[pos] = nums1[m] + m -= 1 + else: + nums1[pos] = nums2[n] + n -= 1 + pos -= 1 + nums1[: n + 1] = nums2[: n + 1] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-4-sliding-window.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-4-sliding-window.mdx new file mode 100644 index 00000000..9376d1de --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-4-sliding-window.mdx @@ -0,0 +1,110 @@ +--- +sidebar_position: 8 +--- + +# 2.4 Sliding Window + +## [76. Minimum Window Substring](https://leetcode.com/problems/minimum-window-substring/) + +### Problem Description + +Given two strings `s` and `t`, find the length of the shortest contiguous substring in `s` that contains all characters of `t`. The solution must have a time complexity of no more than $O(n)$. + + +### Input and Output Example + +The input consists of two strings `s` and `t`, and the output is a substring of `s`. If no solution exists, return an empty string. + + +``` +Input: s = "ADOBECODEBANC", t = "ABC" +Output: "BANC" +``` + +In this example, the shortest substring in `s` that contains one `A`, one `B`, and one `C` is "BANC". + + +### Solution Explanation + +This problem can be solved using the sliding window technique. Two pointers, `l` and `r`, both move from the leftmost to the rightmost position, with `l` always positioned at or before `r`. In the C++ solution, two arrays of length 128, `valid` and `freq`, are used to map characters (ASCII contains only 128 characters). The `valid` array indicates whether a character exists in `t`, and the `freq` array indicates the number of characters in `t` that are still missing in the sliding window of `s`: a positive value indicates missing characters, while a negative value indicates surplus characters. In the Python solution, the `Counter` data structure is used to simultaneously track characters in `t` and their missing quantities (a dictionary can also be used instead). + +Even though the solution contains a `while` loop nested inside a `for` loop, the `while` loop moves the `l` pointer from left to right only once, so the total time complexity remains $O(n)$. + + + + +```cpp +string minWindow(string s, string t) { + vector valid(128, false); + vector freq(128, 0); + // Count characters in t. + for (int i = 0; i < t.length(); ++i) { + valid[t[i]] = true; + ++freq[t[i]]; + } + // Move the sliding window and update statistics. + int count = 0; + int min_l = -1, min_length = -1; + for (int l = 0, r = 0; r < s.length(); ++r) { + if (!valid[s[r]]) { + continue; + } + // Add the character at position r to frequency stats and check if t's missing characters are filled. + if (--freq[s[r]] >= 0) { + ++count; + } + // If the sliding window contains all characters from t, try to move l to find the shortest substring. + while (count == t.length()) { + if (min_length == -1 || r - l + 1 < min_length) { + min_l = l; + min_length = r - l + 1; + } + // Remove the character at position l from stats and check if t's corresponding character is missing again. + if (valid[s[l]] && ++freq[s[l]] > 0) { + --count; + } + ++l; + } + } + return min_length == -1 ? "" : s.substr(min_l, min_length); +} +``` + + + + +```py +def minWindow(s: str, t: str) -> str: + # Count characters in t. Equivalent to: + # freq = dict() + # for c in t: + # freq[c] = freq.get(c, 0) + 1 + freq = Counter(t) + # Move the sliding window and update statistics. + count = 0 + min_l, min_length = None, None + l = 0 + for r in range(len(s)): + if s[r] not in freq: + continue + # Add the character at position r to frequency stats and check if t's missing characters are filled. + freq[s[r]] -= 1 + if freq[s[r]] >= 0: + count += 1 + # If the sliding window contains all characters from t, try to move l to find the shortest substring. + while count == len(t): + if min_length is None or r - l + 1 < min_length: + min_l = l + min_length = r - l + 1 + # Remove the character at position l from stats and check if t's corresponding character is missing again. + if s[l] in freq: + freq[s[l]] += 1 + if freq[s[l]] > 0: + count -= 1 + l += 1 + return "" if min_length is None else s[min_l: min_l + min_length] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-5-fast-slow-pointers.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-5-fast-slow-pointers.mdx new file mode 100644 index 00000000..9ef4a08f --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-5-fast-slow-pointers.mdx @@ -0,0 +1,98 @@ +--- +sidebar_position: 9 +--- + +# 2.5 Fast and Slow Pointers + +## [142. Linked List Cycle II](https://leetcode.com/problems/linked-list-cycle-ii/) + +### Problem Description + +Given a linked list, if there is a cycle, find the starting point of the cycle. + +### Input and Output Example + +The input is a linked list, and the output is a node in the linked list. If there is no cycle, return a null pointer. +In this example, the node with the value 2 is the starting point of the cycle. +If not otherwise specified, LeetCode uses the following data structure to represent a linked list. + +![alt](https://assets.leetcode.com/uploads/2018/12/07/circularlinkedlist.png) + +```cpp +struct ListNode { + int val; + ListNode *next; + ListNode(int x) : val(x), next(nullptr) {} +}; +``` + +```py +class ListNode: + def __init__(self, x): + self.val = x + self.next = None # or a ListNode +``` + +### Solution Explanation + +For the problem of detecting cycles in a linked list, there is a universal solution—the fast and slow pointer method (Floyd’s Cycle Detection Algorithm). Given two pointers, named slow and fast, both start at the head of the list. Each time, fast moves two steps, and slow moves one step. If fast reaches the end, it means there is no cycle. If fast can move indefinitely, it means there is a cycle, and slow and fast will eventually meet. When slow and fast meet for the first time, move fast back to the head of the list, and let both slow and fast move one step at a time. When slow and fast meet for the second time, the meeting node is the starting point of the cycle. + +:::warning + +For problems where you only need to determine the presence of a cycle, you can also use a hash table to check for duplicates. + +::: + + + + + +```cpp +ListNode *detectCycle(ListNode *head) { + ListNode *slow = head, *fast = head; + bool is_first_cycle = true; + // Detect the cycle. + while (fast != slow || is_first_cycle) { + if (fast == nullptr || fast->next == nullptr) { + return nullptr; + } + fast = fast->next->next; + slow = slow->next; + is_first_cycle = false; + } + // Find the node. + fast = head; + while (fast != slow) { + slow = slow->next; + fast = fast->next; + } + return fast; +} +``` + + + + +```py +def detectCycle(head: Optional[ListNode]) -> Optional[ListNode]: + slow = head + fast = head + is_first_cycle = True + # Detect the cycle. + while fast != slow or is_first_cycle: + if fast is None or fast.next is None: + return None + fast = fast.next.next + slow = slow.next + is_first_cycle = False + # Find the node. + fast = head + while fast != slow: + fast = fast.next + slow = slow.next + return fast +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-6-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-6-exercises.md new file mode 100644 index 00000000..fbd60062 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-6-exercises.md @@ -0,0 +1,25 @@ +--- +sidebar_position: 10 +--- + +# 2.6 Exercises + +## Basic Difficulty + +### [633. Sum of Square Numbers](https://leetcode.com/problems/sum-of-square-numbers/) + +A variation of the Two Sum problem. + +### [680. Valid Palindrome II](https://leetcode.com/problems/valid-palindrome-ii/) + +Another variation of the Two Sum problem. + +### [524. Longest Word in Dictionary through Deleting](https://leetcode.com/problems/longest-word-in-dictionary-through-deleting/) + +A variation of the Merge Sorted Array problem. + +## Advanced Difficulty + +### [340. Longest Substring with At Most K Distinct Characters](https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/) + +Requires the use of additional data structures to facilitate tracking the current character states. \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/_category_.json new file mode 100644 index 00000000..23d4e78a --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "2. 玩转双指针", + "position": 2, + "link": { + "type": "generated-index", + "description": "第 2 章 玩转双指针" + } +} diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-1-algorithm-explanation.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-1-algorithm-explanation.md new file mode 100644 index 00000000..651e3f75 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-1-algorithm-explanation.md @@ -0,0 +1,15 @@ +--- +sidebar_position: 11 +--- + +# 3.1 Algorithm Explanation + +`Binary search`, also known as `bisection` or `halving search` (binary search, bisect), reduces the complexity of a search operation by dividing the search interval into two parts at each step and only proceeding with one part. For an array of length $O(n)$, the time complexity of binary search is $O(\log n)$. + +For example, given a sorted array $\{3,4,5,6,7\}$, we want to find out if 4 is in this array. During the first bisection, we consider the median 5. Since 5 is greater than 4, if 4 exists in this array, it must be in the left half of the array. Thus, our search interval becomes $\{3,4,5\}$. (Note: Depending on the specific case and your problem-solving habits, 5 may or may not be included, but this does not affect the time complexity.) In the second bisection, the new median 4 is exactly the number we are looking for. Therefore, for an array of length 5, we only performed 2 searches. In contrast, a linear search might require up to 5 checks in the worst-case scenario. + +Binary search can also be mathematically defined. Given a monotonic function $f(t)$ in the interval $[a, b]$, if $f(a)$ and $f(b)$ have opposite signs, there must be a solution $c$ such that $f(c) = 0$. In the earlier example, $f(t)$ is a discrete function $f(t) = t + 2$, and checking if 4 exists is equivalent to solving $f(t) - 4 = 0$. Since $f(1) - 4 = 3 - 4 = -1 < 0$ and $f(5) - 4 = 7 - 4 = 3 > 0$, and the function is monotonically increasing in this interval, we can use binary search to solve the problem. If the interval is reduced to a single number and no solution exists in that interval, it means there is no discrete solution, i.e., 4 is not in the array. + +In implementation, whether the interval is defined as open or closed at the ends does not matter in most cases. Beginners may find it tricky to decide this. Here are two tips: first, try to consistently use one approach, such as left-closed-right-open (commonly used in C++, Python, etc.) or left-closed-right-closed (convenient for boundary handling). Second, while solving problems, think about whether your method will lead to an infinite loop when the interval is reduced to one or two elements. If it does, consider switching to another approach. + +Binary search can also be viewed as a special case of the two-pointer technique, but we usually differentiate the two. In two-pointer problems, the pointers typically move step by step, whereas in binary search, the pointers move by halving the interval at each step. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-2-square-root.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-2-square-root.mdx new file mode 100644 index 00000000..758cfd0a --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-2-square-root.mdx @@ -0,0 +1,103 @@ +--- +sidebar_position: 12 +--- + +# 3.2 Calculating Square Root + +## [69. Sqrt(x)](https://leetcode.com/problems/sqrtx/) + +### Problem Description + +Given a non-negative integer `x`, calculate its square root and round it down to the nearest integer. + +### Input and Output Example + +The input is an integer, and the output is also an integer. + +``` +Input: 8 +Output: 2 +``` + +The square root of 8 is 2.82842..., and rounding it down gives 2. + + +### Solution Explanation + +We can think of this problem as: given a non-negative integer `x`, find the solution to $f(t) = t^2 − x = 0$. Since we only consider $t ≥ 0$, $f(t)$ is monotonically increasing in its domain. Given that $f(0) = −x ≤ 0$ and $f(x) = x^2 − x ≥ 0$, we can use binary search on the interval $[0, x]$ to find the solution where $f(t) = 0$. Here, we adopt a left-closed, right-closed approach. + +In the C++ solution, using $mid = (l + r) / 2$ might result in overflow due to $l + r$, so we use $mid = l + (r − l) / 2$ instead. Directly calculating $mid ∗ mid$ might also overflow, so we compare $mid$ with $x / mid$ instead. + + + + +```cpp +int mySqrt(int x) { + int l = 1, r = x, mid, x_div_mid; + while (l <= r) { + mid = l + (r - l) / 2; + x_div_mid = x / mid; + if (mid == x_div_mid) { + return mid; + } + if (mid < x_div_mid) { + l = mid + 1; + } else { + r = mid - 1; + } + } + return r; +} +``` + + + + +```py +def mySqrt(x: int) -> int: + l, r = 1, x + while l <= r: + mid = (l + r) // 2 + mid_sqr = mid**2 + if mid_sqr == x: + return mid + if mid_sqr < x: + l = mid + 1 + else: + r = mid - 1 + return r +``` + + + + + +Additionally, this problem can be solved using a faster algorithm—`Newton's Iterative Method`. The formula is $t_{n+1} = t_n - \frac{f(t_n)}{f'(t_n)}$. For $f(t) = t^2 − x = 0$, the iteration formula becomes $t_{n+1} = \frac{t_n + \frac{x}{t_n}}{2}$. + + + + +```cpp +int mySqrt(int x) { + long t = x; + while (t * t > x) { + t = (t + x / t) / 2; + } + return t; +} +``` + + + + +```py +def mySqrt(x: int) -> int: + t = x + while t**2 > x: + t = (t + x // t) // 2 + return t +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-3-interval-search.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-3-interval-search.mdx new file mode 100644 index 00000000..3d4fec5c --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-3-interval-search.mdx @@ -0,0 +1,109 @@ +--- +sidebar_position: 13 +--- + +# 3.3 Find Range + +## [34. Find First and Last Position of Element in Sorted Array](https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/) + +### Problem Description + +Given a sorted integer array and a target value, find the first and last positions where the target value appears. + +### Input and Output Example + +The input is an array and a value, and the output is the positions of the first and last appearances of the target value (starting from 0). If the value does not exist in the array, both return values should be -1. + +``` +Input: nums = [5,7,7,8,8,10], target = 8 +Output: [3,4] +``` + +The number 8 first appears at position 3 and last appears at position 4. + + +### Solution Explanation + +This problem can be seen as implementing C++'s `lower_bound` and `upper_bound` functions or Python's `bisect_left` and `bisect_right` functions. Here, we use a left-closed, right-open interval approach, but a left-closed, right-closed interval would also work. + + + + + +```cpp +int lowerBound(vector &nums, int target) { + int l = 0, r = nums.size(), mid; + while (l < r) { + mid = l + (r - l) / 2; + if (nums[mid] < target) { + l = mid + 1; + } else { + r = mid; + } + } + return l; +} + +int upperBound(vector &nums, int target) { + int l = 0, r = nums.size(), mid; + while (l < r) { + mid = l + (r - l) / 2; + if (nums[mid] <= target) { + l = mid + 1; + } else { + r = mid; + } + } + return l; +} + +vector searchRange(vector &nums, int target) { + if (nums.empty()) { + return vector{-1, -1}; + } + int lower = lowerBound(nums, target); + int upper = upperBound(nums, target) - 1; + if (lower == nums.size() || nums[lower] != target) { + return vector{-1, -1}; + } + return vector{lower, upper}; +} +``` + + + + +```py +def lowerBound(nums: List[int], target: int) -> int: + l, r = 0, len(nums) + while l < r: + mid = (l + r) // 2 + if nums[mid] < target: + l = mid + 1 + else: + r = mid + return l + +def upperBound(nums: List[int], target: int) -> int: + l, r = 0, len(nums) + while l < r: + mid = (l + r) // 2 + if nums[mid] <= target: + l = mid + 1 + else: + r = mid + return l + +def searchRange(nums: List[int], target: int) -> List[int]: + if not nums: + return [-1, -1] + lower = lowerBound(nums, target) + upper = upperBound(nums, target) - 1 + if lower == len(nums) or nums[lower] != target: + return [-1, -1] + return [lower, upper] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-4-peak-finding.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-4-peak-finding.mdx new file mode 100644 index 00000000..e495cf1b --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-4-peak-finding.mdx @@ -0,0 +1,87 @@ +--- +sidebar_position: 14 +--- + +# 3.4 Find Maximum + +## [162. Find Peak Element](https://leetcode.com/problems/find-peak-element/) + +### Problem Description + +Given an array, a maximum is defined as a number that is greater than both of its neighbors. Find the position of any maximum. There may be multiple maxima in the array, and you can return any of them. The required time complexity is $O(\log n)$. + +### Input and Output Example + +The input is an array, and the output is the position of a maximum. + + +``` +Input: nums = [1,2,3,1] +Output: 2 +``` + +The maximum 3 appears at position 2. + + +### Solution Explanation + +To achieve $O(\log n)$ time complexity, we can use binary search on the array. If the endpoints are not maxima, and the current midpoint is not a maximum, then one of its sides must contain a maximum. + + + + + +```cpp +int findPeakElement(vector& nums) { + int n = nums.size(); + if (n == 1) { + return 0; + } + if (nums[0] > nums[1]) { + return 0; + } + if (nums[n - 1] > nums[n - 2]) { + return n - 1; + } + int l = 1, r = n - 2, mid; + while (l <= r) { + mid = l + (r - l) / 2; + if (nums[mid] > nums[mid + 1] && nums[mid] > nums[mid - 1]) { + return mid; + } else if (nums[mid] > nums[mid - 1]) { + l = mid + 1; + } else { + r = mid - 1; + } + } + return -1; +} +``` + + + + +```py +def findPeakElement(self, nums: List[int]) -> int: + n = len(nums) + if n == 1: + return 0 + if nums[0] > nums[1]: + return 0 + if nums[n - 1] > nums[n - 2]: + return n - 1 + l, r = 1, n - 2 + while l <= r: + mid = (l + r) // 2 + if nums[mid] > nums[mid + 1] and nums[mid] > nums[mid - 1]: + return mid + elif nums[mid] > nums[mid - 1]: + l = mid + 1 + else: + r = mid - 1 + return -1 +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-5-rotated-array-search.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-5-rotated-array-search.mdx new file mode 100644 index 00000000..93668f56 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-5-rotated-array-search.mdx @@ -0,0 +1,99 @@ +--- +sidebar_position: 15 +--- + +# 3.5 Search in Rotated Array + +## [81. Search in Rotated Sorted Array II](https://leetcode.com/problems/search-in-rotated-sorted-array-ii/) + +### Problem Description + +An originally sorted array is connected end-to-end and then broken at some position (e.g., [1,2,2,3,4,5] → [2,3,4,5,1,2], broken between the first and second positions). We call this a rotated array. Given a target value, determine whether this value exists in the rotated array. + +### Input and Output Example + +The input is an array and a value, and the output is a boolean indicating whether the target exists in the array. + +``` +Input: nums = [2,5,6,0,0,1,2], target = 0 +Output: true +``` + +Even though the array is rotated, we can still use its sorted property to perform binary search. At the current midpoint, if its value is less than or equal to the right endpoint, the right interval is sorted. Otherwise, the left interval is sorted. If the target value is in the sorted interval, continue the binary search in that interval. Otherwise, proceed with the other interval. Here, we adopt a left-closed, right-closed interval approach. + + +### Solution Explanation + + + + + + +```cpp +bool search(vector& nums, int target) { + int l = 0, r = nums.size() - 1; + while (l <= r) { + int mid = l + (r - l) / 2; + if (nums[mid] == target) { + return true; + } + if (nums[mid] == nums[l]) { + // Cannot determine which interval is sorted, but l cannot be target. + ++l; + } else if (nums[mid] == nums[r]) { + // Cannot determine which interval is sorted, but r cannot be target. + --r; + } else if (nums[mid] < nums[r]) { + // Right interval is sorted. + if (target > nums[mid] && target <= nums[r]) { + l = mid + 1; + } else { + r = mid - 1; + } + } else { + // Left interval is sorted. + if (target >= nums[l] && target < nums[mid]) { + r = mid - 1; + } else { + l = mid + 1; + } + } + } + return false; +} +``` + + + + +```py +def search(nums: List[int], target: int) -> bool: + l, r = 0, len(nums) - 1 + while l <= r: + mid = (l + r) // 2 + if nums[mid] == target: + return True + if nums[mid] == nums[l]: + # Cannot determine which interval is sorted, but l cannot be target. + l += 1 + elif nums[mid] == nums[r]: + # Cannot determine which interval is sorted, but r cannot be target. + r -= 1 + elif nums[mid] < nums[r]: + # Right interval is sorted. + if nums[mid] < target <= nums[r]: + l = mid + 1 + else: + r = mid - 1 + else: + # Left interval is sorted. + if nums[l] <= target < nums[mid]: + r = mid - 1 + else: + l = mid + 1 + return False +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-6-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-6-exercises.md new file mode 100644 index 00000000..1ebf4db6 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-6-exercises.md @@ -0,0 +1,21 @@ +--- +sidebar_position: 16 +--- + +# 3.6 Exercises + +## Basic Difficulty + +### [154. Find Minimum in Rotated Sorted Array II](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array-ii/) + +A variation of the rotated array problem. + +### [540. Single Element in a Sorted Array](https://leetcode.com/problems/single-element-in-a-sorted-array/) + +What changes occur in the parity (odd/even positions) of values before and after the unique element? + +## Advanced Difficulty + +### [4. Median of Two Sorted Arrays](https://leetcode.com/problems/median-of-two-sorted-arrays/) + +Requires binary search on both arrays simultaneously. \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/_category_.json new file mode 100644 index 00000000..89e9fd2f --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "3. 居合斩!二分查找", + "position": 3, + "link": { + "type": "generated-index", + "description": "第 3 章 居合斩!二分查找" + } +} diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-1-common-sorting-algorithms.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-1-common-sorting-algorithms.mdx new file mode 100644 index 00000000..fb119c89 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-1-common-sorting-algorithms.mdx @@ -0,0 +1,148 @@ +--- +sidebar_position: 17 +--- + +# 4.1 Common Sorting Algorithms + +Although sorting can be achieved in C++ and Python using the `sort` function and it is rare to write sorting algorithms manually during coding challenges, understanding various sorting algorithms helps deepen your knowledge of basic algorithms and solve problems derived from these algorithms. Here, we introduce two sorting algorithms with a time complexity of $O(n \log n)$: `Quick Sort` and `Merge Sort`. The former is generally faster, while the latter ensures that elements with the same value maintain their relative order in the array (i.e., it is a "stable sort"). + + +## Quicksort + +The principle of Quick Sort is straightforward: for an unsorted segment, we randomly choose a position as the pivot and rearrange the elements such that all numbers smaller than the pivot are moved to its left and all numbers larger than the pivot are moved to its right. After this operation, we recursively perform Quick Sort on the segments to the left and right of the pivot. It can be proven that if the pivot is chosen randomly, the average complexity of this algorithm is $O(n \log n)$, while the worst-case complexity is $O(n^2)$. + +We use a left-closed, right-closed interval approach, initializing with $l = 0, r = n - 1$. + + + + +```cpp +void quickSort(vector &nums, int l, int r) { + if (l >= r) { + return; + } + // Randomly choose a pivot within the current [l, r] interval. + int pivot = l + (rand() % (r - l + 1)); + int pivot_val = nums[pivot]; + // Swap the pivot with the first element. + swap(nums[l], nums[pivot]); + // Traverse inward from both ends of [l+1, r] to find misplaced elements. + int i = l + 1, j = r; + while (true) { + while (i < j && nums[j] >= pivot_val) { + --j; + } + while (i < j && nums[i] <= pivot_val) { + ++i; + } + if (i == j) { + break; + } + // Swap the misplaced elements. + swap(nums[i], nums[j]); + } + // Swap the pivot back to its correct position. + int new_pivot = nums[i] <= nums[l] ? i : i - 1; + swap(nums[l], nums[new_pivot]); + quickSort(nums, l, new_pivot - 1); + quickSort(nums, new_pivot + 1, r); +} +``` + + + + +```py +def quickSort(nums: List[int], l: int, r: int) -> None: + if l >= r: + return + # Randomly choose a pivot within the current [l, r] interval. + pivot = random.randint(l, r) + pivot_val = nums[pivot] + # Swap the pivot with the first element. + nums[l], nums[pivot] = nums[pivot], nums[l] + # Traverse inward from both ends of [l+1, r] to find misplaced elements. + i, j = l + 1, r + while True: + while i < j and nums[j] >= pivot_val: + j -= 1 + while i < j and nums[i] <= pivot_val: + i += 1 + if i == j: + break + # Swap the misplaced elements. + nums[i], nums[j] = nums[j], nums[i] + # Swap the pivot back to its correct position. + new_pivot = i if nums[i] <= nums[l] else i - 1 + nums[l], nums[new_pivot] = nums[new_pivot], nums[l] + quickSort(nums, l, new_pivot - 1) + quickSort(nums, new_pivot + 1, r) +``` + + + + + +## Merge Sort + +Merge Sort is a classic divide-and-conquer algorithm, which we will elaborate on in later sections. In short, for an unsorted segment, we first sort its left and right halves separately and then merge the two halves ("conquer"). Sorting each half can be achieved recursively by further splitting each half into two parts ("divide"). + +We use a left-closed, right-closed interval approach, initializing with $l = 0, r = n - 1$, and pre-allocate an array cache of the same size as nums to store intermediate results. + + + + +```cpp +void mergeSort(vector &nums, vector &cache, int l, int r) { + if (l >= r) { + return; + } + // Divide. + int mid = l + (r - l) / 2; + mergeSort(nums, cache, l, mid); + mergeSort(nums, cache, mid + 1, r); + // Conquer. + // Use two pointers, i and j, to traverse the left [l, mid] and right [mid+1, r] halves. + int i = l, j = mid + 1; + for (int pos = l; pos <= r; ++pos) { + if (j > r || (i <= mid && nums[i] <= nums[j])) { + cache[pos] = nums[i++]; + } else { + cache[pos] = nums[j++]; + } + } + // Copy the sorted elements back to nums. + for (int pos = l; pos <= r; ++pos) { + nums[pos] = cache[pos]; + } +} +``` + + + + +```py +def mergeSort(nums: List[int], cache: List[int], l: int, r: int) -> None: + if l >= r: + return + # Divide. + mid = (l + r) // 2 + mergeSort(nums, cache, l, mid) + mergeSort(nums, cache, mid + 1, r) + # Conquer. + # Use two pointers, i and j, to traverse the left [l, mid] and right [mid+1, r] halves. + i, j = l, mid + 1 + for pos in range(l, r + 1): + if j > r or (i <= mid and nums[i] <= nums[j]): + cache[pos] = nums[i] + i += 1 + else: + cache[pos] = nums[j] + j += 1 + # Copy the sorted elements back to nums. + nums[l:r+1] = cache[l:r+1] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-2-quick-select.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-2-quick-select.mdx new file mode 100644 index 00000000..0b5e669d --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-2-quick-select.mdx @@ -0,0 +1,78 @@ +--- +sidebar_position: 18 +--- + +# 4.2 Quick Select + +## [215. Kth Largest Element in an Array](https://leetcode.com/problems/kth-largest-element-in-an-array/) + +### Problem Description + +In an unsorted array, find the $k$-th largest element. + +### Input and Output Example + +Input an array and a target value $k$, output the $k$-th largest element. The problem guarantees there is always a solution. + +``` +Input: [3,2,1,5,6,4] and k = 2 +Output: 5 +``` + +### Solution Explanation + +`Quick Select` is commonly used to solve k-th element problems, achieving an average time complexity of $O(n)$ and space complexity of $O(1)$. Its implementation is similar to Quick Sort, but it only focuses on finding the $k$-th largest pivot without sorting the rest of the elements. Like Quick Sort, Quick Select generally requires shuffling the array first to avoid a worst-case time complexity of $O(n^2)$. + +If we directly use the Quick Sort code above, it may approach the time limit on LeetCode. Instead, we can trade space for time by directly storing elements greater than, less than, and equal to the pivot to minimize swaps. + + + + +```cpp +int findKthLargest(vector nums, int k) { + int pivot = rand() % nums.size(); + int pivot_val = nums[pivot]; + vector larger, equal, smaller; + for (int num : nums) { + if (num > pivot_val) { + larger.push_back(num); + } else if (num < pivot_val) { + smaller.push_back(num); + } else { + equal.push_back(num); + } + } + if (k <= larger.size()) { + return findKthLargest(larger, k); + } + if (k > larger.size() + equal.size()) { + return findKthLargest(smaller, k - larger.size() - equal.size()); + } + return pivot_val; +} +``` + + + + +```py +def findKthLargest(nums: List[int], k: int) -> int: + pivot_val = random.choice(nums) + larger, equal, smaller = [], [], [] + for num in nums: + if num > pivot_val: + larger.append(num) + elif num < pivot_val: + smaller.append(num) + else: + equal.append(num) + if k <= len(larger): + return findKthLargest(larger, k) + if k > len(larger) + len(equal): + return findKthLargest(smaller, k - len(larger) - len(equal)) + return pivot_val +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-3-bucket-sort.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-3-bucket-sort.mdx new file mode 100644 index 00000000..1650c126 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-3-bucket-sort.mdx @@ -0,0 +1,83 @@ +--- +sidebar_position: 19 +--- + +# 4.3 Bucket Sort + +## [347. Top K Frequent Elements](https://leetcode.com/problems/top-k-frequent-elements/) + +### Problem Description + +Given an array, find the top $k$ most frequent elements. + +### Input and Output Example + +Input is an array and a target value $k$. Output is an array of length $k$. + +``` +Input: nums = [1,1,1,1,2,2,3,4], k = 2 +Output: [1,2] +``` + +In this example, the two most frequent numbers are 1 and 2. + +### Solution Explanation + +As the name suggests, `bucket sort` involves creating a bucket for each value, where the bucket records the frequency of that value (or other attributes), and then sorting the buckets. For this example, we first use bucket sort to obtain four buckets [1,2,3,4], with values [4,2,1,1], representing the frequency of each number. + +Next, we sort the buckets by frequency, and the top $k$ buckets are the top $k$ most frequent elements. We can use any sorting algorithm here or even perform another bucket sort, placing each old bucket into new buckets based on frequency. For this example, since the maximum frequency is 4, we create four new buckets [1,2,3,4], which contain the old buckets as follows: [[3,4],[2],[],[1]]. Finally, we iterate from the end to the beginning until we find $k$ old buckets. + +We can use `unordered_map` in C++ or `dict` in Python to implement a hash table. + + + + +```cpp +vector topKFrequent(vector& nums, int k) { + unordered_map counts; + for (int num : nums) { + ++counts[num]; + } + unordered_map> buckets; + for (auto [num, count] : counts) { + buckets[count].push_back(num); + } + vector top_k; + for (int count = nums.size(); count >= 0; --count) { + if (buckets.contains(count)) { + for (int num : buckets[count]) { + top_k.push_back(num); + if (top_k.size() == k) { + return top_k; + } + } + } + } + return top_k; +} +``` + + + + +```py +def topKFrequent(nums: List[int], k: int) -> List[int]: + counts = Counter(nums) + buckets = dict() + for num, count in counts.items(): + if count in buckets: + buckets[count].append(num) + else: + buckets[count] = [num] + top_k = [] + for count in range(len(nums), 0, -1): + if count in buckets: + top_k += buckets[count] + if len(top_k) >= k: + return top_k[:k] + return top_k[:k] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-4-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-4-exercises.md new file mode 100644 index 00000000..85ea25bb --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-4-exercises.md @@ -0,0 +1,17 @@ +--- +sidebar_position: 20 +--- + +# 4.4 Exercises + +## Basic Difficulty + +### [451. Sort Characters By Frequency](https://leetcode.com/problems/sort-characters-by-frequency/) + +A variant of the bucket sort problem. + +## Advanced Difficulty + +### [75. Sort Colors](https://leetcode.com/problems/sort-colors/) + +A classic Dutch National Flag problem, testing how to sort three repeated and unordered values. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/4-sorting-algorithms/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/4-sorting-algorithms/_category_.json new file mode 100644 index 00000000..4aad536a --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/4-sorting-algorithms/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "4. 千奇百怪的排序算法", + "position": 4, + "link": { + "type": "generated-index", + "description": "第 4 章 千奇百怪的排序算法" + } +} diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-1-algorithm-explanation.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-1-algorithm-explanation.md new file mode 100644 index 00000000..19af5419 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-1-algorithm-explanation.md @@ -0,0 +1,7 @@ +--- +sidebar_position: 21 +--- + +# 5.1 算法解释 + +`Depth First Search (DFS)` and `Breadth First Search (BFS)` are two of the most common priority search methods. They are widely used for searching in structures such as graphs and trees. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-2-depth-first-search.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-2-depth-first-search.mdx new file mode 100644 index 00000000..8daa29db --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-2-depth-first-search.mdx @@ -0,0 +1,375 @@ +--- +sidebar_position: 22 +--- + +# 5.2 Depth First Search + +`Depth First Search (DFS)` is a search method where, upon encountering a new node, you immediately traverse that new node. Therefore, traversal requires a `Last In, First Out (LIFO) stack`, which can also be implemented using `recursion`, equivalent to using a stack. In a tree structure, since traversal always invokes the new node, it appears as if progressing in the "depth" direction. In Python, collections.deque can be used to implement the stack in C++. However, in most cases, using vector in C++ or list in Python is preferred as these structures not only support LIFO but also allow random access. + +Consider the following simple tree, starting traversal from node 1. If the traversal order is from the left child to the right child, the process follows the strategy of moving "deeper" first: 1 (starting node) → 2 (deeper left child) → 4 (deeper left child) → 2 (no children, return to parent) → 1 (all children traversed, return to parent) → 3 (deeper right child) → 1 (no children, return to parent) → end (all children traversed). If implemented with a stack, the stack's top element evolves as follows: 1 → 2 → 4 → 3. + + +``` + 1 + / \ + 2 3 + / +4 +``` + +DFS can also be used to `detect cycles`: Record the parent node of each traversed node. If a node is revisited with a different parent, a cycle is detected. Alternatively, topological sorting can identify cycles: if a node has a non-zero in-degree at the end, a cycle exists. + +Sometimes, it is necessary to mark already traversed nodes to avoid redundant searches. This technique is called `state recording` or `memoization`. + +## [695. Max Area of Island](https://leetcode.com/problems/max-area-of-island/) + +### Problem Description + +Given a 2D binary grid where `0` represents water and `1` represents land, islands are formed by connected land cells. Each cell is connected only to its adjacent cells (up, down, left, right). Find the maximum area of an island. + + +### Input and Output Example + +Input: a 2D grid; Output: the maximum area of an island. + + +``` +Input: +[[1,0,1,1,0,1,0,1], +[1,0,1,1,0,1,1,1], +[0,0,0,0,0,0,0,1]] +Output: 6 +``` + +The maximum area of an island is 6, located at the far right. + +### Solution Explanation + +This is a standard search problem, ideal for practicing DFS. Typically, DFS problems are divided into a main function for traversing all positions and a helper function for the recursive DFS. While DFS can also be implemented using a stack, recursion is often more convenient for competitive programming due to easier implementation and backtracking. However, in real-world engineering, a stack may be preferable to avoid recursion stack overflow and for easier understanding. + +Below is the stack implementation. A small trick is used for traversal directions: an array `[-1, 0, 1, 0, -1]` represents the four directions (up, down, left, right). You can also explicitly write `[-1, 0]`, `[1, 0]`, `[0, 1]`, `[0, -1]` for clarity. + + + + +```cpp +int maxAreaOfIsland(vector>& grid) { + vector direction{-1, 0, 1, 0, -1}; + int m = grid.size(), n = grid[0].size(), max_area = 0; + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (grid[i][j] == 1) { + stack> island; + // Initialize the first node. + int local_area = 1; + grid[i][j] = 0; + island.push({i, j}); + // DFS using stack. + while (!island.empty()) { + auto [r, c] = island.top(); + island.pop(); + for (int k = 0; k < 4; ++k) { + int x = r + direction[k], y = c + direction[k + 1]; + // Add neighboring nodes that meet the conditions. + if (x >= 0 && x < m && y >= 0 && y < n && + grid[x][y] == 1) { + ++local_area; + grid[x][y] = 0; + island.push({x, y}); + } + } + } + max_area = max(max_area, local_area); + } + } + } + return max_area; +} +``` + + + + +```py +def maxAreaOfIsland(grid: List[List[int]]) -> int: + direction = [-1, 0, 1, 0, -1] + m, n, max_area = len(grid), len(grid[0]), 0 + for i in range(m): + for j in range(n): + if grid[i][j] == 1: + island = [] + # Initialize the first node. + local_area = 1 + grid[i][j] = 0 + island.append((i, j)) + # DFS using stack. + while island: + r, c = island.pop() + for k in range(4): + x, y = r + direction[k], c + direction[k + 1] + # Add neighboring nodes that meet the conditions. + if 0 <= x < m and 0 <= y < n and grid[x][y] == 1: + local_area += 1 + grid[x][y] = 0 + island.append((x, y)) + max_area = max(max_area, local_area) + return max_area +``` + + + + + +Below, we present the recursive implementation. Be sure to check the boundary conditions when performing recursive searches. This can be done either before calling the auxiliary function or at the beginning of the auxiliary function itself. In this example, we do not use the array [-1, 0, 1, 0, -1] for searching in four directions (up, down, left, and right). Instead, we explicitly write four different recursive functions. Either approach works, and readers can choose to master either one. + + + + + +```cpp +// Auxiliary function. +int dfs(vector>& grid, int r, int c) { + if (r < 0 || r >= grid.size() || c < 0 || c >= grid[0].size() || + grid[r][c] == 0) { + return 0; + } + grid[r][c] = 0; + return (1 + dfs(grid, r + 1, c) + dfs(grid, r - 1, c) + + dfs(grid, r, c + 1) + dfs(grid, r, c - 1)); +} + +// Main function. +int maxAreaOfIsland(vector>& grid) { + int max_area = 0; + for (int i = 0; i < grid.size(); ++i) { + for (int j = 0; j < grid[0].size(); ++j) { + max_area = max(max_area, dfs(grid, i, j)); + } + } + return max_area; +} +``` + + + + +```py +# Auxiliary function +def dfs(grid: List[List[int]], r: int, c: int) -> int: + if r < 0 or r >= len(grid) or c < 0 or c >= len(grid[0]) or grid[r][c] == 0: + return 0 + grid[r][c] = 0 + return (1 + dfs(grid, r + 1, c) + dfs(grid, r - 1, c) + + dfs(grid, r, c + 1) + dfs(grid, r, c - 1)) + +# Main function +def maxAreaOfIsland(grid: List[List[int]]) -> int: + max_area = 0 + for i in range(len(grid)): + for j in range(len(grid[0])): + max_area = max(max_area, dfs(grid, i, j)) + return max_area +``` + + + + + +## [547. Number of Provinces](https://leetcode.com/problems/number-of-provinces/) + +### Problem Description + +Given a 2D 0-1 matrix, if position (i, j) is 1, it means city i and city j belong to the same province. The adjacency relationship between cities is transitive; for example, if city a is connected to city b, and city b is connected to city c, then city a and city c are also connected, meaning they are part of the same province. The task is to calculate the total number of provinces. + +### Input and Output Example + +The input is a 2D matrix, and the output is an integer representing the number of provinces. Since the adjacency relationship is symmetric, the 2D matrix is symmetric. Additionally, each city is part of its own province, so the diagonal values are all 1. + +``` +Input: +[[1,1,0], +[1,1,0], +[0,0,1]] +Output: 2 +``` + +In this example, cities [1, 2] are in one province, and city [3] is in another province. + +### Solution Explanation + +In the previous problem, the graph was represented such that each position represented a node, and each node was adjacent to its top, bottom, left, and right neighbors. In this problem, each row (or column) represents a node, and each column (or row) indicates whether there is an adjacent node. The previous problem had 𝑚 × 𝑛 nodes, each with 4 edges; in this problem, there are 𝑛 nodes, and each node can have up to 𝑛 edges if it is connected to all other cities, or a minimum of 1 edge if it is its own province. Once the graph representation is understood, this problem is essentially the same as the previous one: finding the number of provinces (or clusters of connected nodes). Here, we use a recursive approach. + +:::warning + +For problems involving connected nodes, we can also use the Union-Find algorithm to quickly manage connections and searches. This will be discussed in later sections. + +::: + + + + +```cpp +// Auxiliary function +void dfs(vector>& isConnected, int i, vector& visited) { + visited[i] = true; + for (int j = 0; j < isConnected.size(); ++j) { + if (isConnected[i][j] == 1 && !visited[j]) { + dfs(isConnected, j, visited); + } + } +} + +// Main function +int findCircleNum(vector>& isConnected) { + int n = isConnected.size(), count = 0; + // Prevent revisiting already searched nodes + vector visited(n, false); + for (int i = 0; i < n; ++i) { + if (!visited[i]) { + dfs(isConnected, i, visited); + ++count; + } + } + return count; +} +``` + + + + +```py +# Auxiliary function +def dfs(isConnected: List[List[int]], city: int, visited: Set[int]): + visited.add(city) + for i in range(len(isConnected)): + if isConnected[city][i] == 1 and i not in visited: + dfs(isConnected, i, visited) + +# Main function +def findCircleNum(isConnected: List[List[int]]) -> int: + count = 0 + # Prevent revisiting already searched nodes + visited = set() + for i in range(len(isConnected)): + if i not in visited: + dfs(isConnected, i, visited) + count += 1 + return count +``` + + + + + + +## [417. Pacific Atlantic Water Flow](https://leetcode.com/problems/pacific-atlantic-water-flow/) + +### Problem Description + +Given a 2D matrix of non-negative integers, each position represents the elevation height. Assume that the left and top edges are the Pacific Ocean, and the right and bottom edges are the Atlantic Ocean. Determine the positions from which water can flow down to both the Pacific and Atlantic Oceans. Water can only flow from a higher or equal elevation to a lower or equal elevation. + +### Input and Output Example + +The input is a 2D array of non-negative integers representing the elevation heights. The output is a 2D array where the second dimension has a fixed size of 2, representing the coordinates of positions that satisfy the conditions. + +``` +Input: +Pacific ~ ~ ~ ~ ~ + ~ 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 * + * * * * * Atlantic +Output: [[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]] +``` + +In this example, the areas marked with parentheses are the positions satisfying the condition. + +### Solution Explanation + +The problem requires determining positions from which water can flow to both oceans. If we attempt to search all positions, the complexity could become very high without pruning. Instead, we can reverse the perspective: starting from both oceans and simulating water flowing upwards. By doing so, we only need to search the four edges of the matrix. After completing the search, we iterate through the matrix to identify positions that can be reached from both the Pacific and Atlantic Oceans. + + + + +```cpp +vector direction{-1, 0, 1, 0, -1}; +// Auxiliary function +void dfs(const vector>& heights, vector>& can_reach, + int r, int c) { + if (can_reach[r][c]) { + return; + } + can_reach[r][c] = true; + for (int i = 0; i < 4; ++i) { + int x = r + direction[i], y = c + direction[i + 1]; + if (x >= 0 && x < heights.size() && y >= 0 && y < heights[0].size() && + heights[r][c] <= heights[x][y]) { + dfs(heights, can_reach, x, y); + } + } +} + +// Main function +vector> pacificAtlantic(vector>& heights) { + int m = heights.size(), n = heights[0].size(); + vector> can_reach_p(m, vector(n, false)); + vector> can_reach_a(m, vector(n, false)); + vector> can_reach_p_and_a; + for (int i = 0; i < m; ++i) { + dfs(heights, can_reach_p, i, 0); + dfs(heights, can_reach_a, i, n - 1); + } + for (int i = 0; i < n; ++i) { + dfs(heights, can_reach_p, 0, i); + dfs(heights, can_reach_a, m - 1, i); + } + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (can_reach_p[i][j] && can_reach_a[i][j]) { + can_reach_p_and_a.push_back({i, j}); + } + } + } + return can_reach_p_and_a; +} +``` + + + + +```py +direction = [-1, 0, 1, 0, -1] + +# Auxiliary function +def dfs(heights: List[List[int]], can_reach: List[List[int]], r: int, c: int): + if can_reach[r][c]: + return + can_reach[r][c] = True + for i in range(4): + x, y = r + direction[i], c + direction[i + 1] + if (x >= 0 and x < len(heights) and y >= 0 and y < len(heights[0]) and + heights[x][y] >= heights[r][c]): + dfs(heights, can_reach, x, y) + +# Main function +def pacificAtlantic(heights: List[List[int]]) -> List[List[int]]: + m, n = len(heights), len(heights[0]) + can_reach_p = [[False for _ in range(n)] for _ in range(m)] + can_reach_a = [[False for _ in range(n)] for _ in range(m)] + for i in range(m): + dfs(heights, can_reach_p, i, 0) + dfs(heights, can_reach_a, i, n - 1) + for j in range(n): + dfs(heights, can_reach_p, 0, j) + dfs(heights, can_reach_a, m - 1, j) + return [ + [i, j] for i in range(m) for j in range(n) + if can_reach_p[i][j] and can_reach_a[i][j] + ] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-3-backtracking.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-3-backtracking.mdx new file mode 100644 index 00000000..ecc21bf4 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-3-backtracking.mdx @@ -0,0 +1,379 @@ +--- +sidebar_position: 23 +--- + +# 5.3 Backtracking + +`Backtracking` is a special case of priority search, also known as the trial-and-error method. It is commonly used in depth-first search when the state of nodes needs to be recorded. Typically, problems involving permutations, combinations, or selections are more conveniently solved using backtracking. + +As the name suggests, the core of backtracking is to backtrack. When reaching a certain node, if we find that the current node (and its child nodes) do not meet the target requirements, we backtrack to the previous node and continue the search, while `restoring the state modified at the current node`. The benefit is that we can modify only the global state of the graph without creating a new graph to store states during each traversal. In terms of implementation, backtracking is similar to regular depth-first search, involving steps like [modifying the current node state]→[recursing into child nodes], but it adds an extra backtracking step, turning it into [modifying the current node state]→[recursing into child nodes]→[restoring the current node state]. + +For readers unfamiliar with backtracking, this explanation might be unclear, which is entirely normal. The following problems are intended to help you understand backtracking. If it’s still confusing, remember two simple principles: `1. Pass states by reference, and 2. Restore all state changes after recursion`. + +There are generally two cases for backtracking modifications: one involves modifying the last output, such as in permutations and combinations, and the other involves modifying visit markers, such as searching for strings in a matrix. + + +## [46. Permutations](https://leetcode.com/problems/permutations/) + +### Problem Description + +Given an array of distinct integers, return all possible permutations. + +### Input and Output Example + +The input is a one-dimensional integer array, and the output is a two-dimensional array representing all permutations of the input array. + +``` +Input: [1,2,3] +Output: [[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,2,1], [3,1,2]] +``` + +The order of output does not matter as long as all permutations are included. + +### Solution Explanation + +To generate all permutations, for each position \(i\), we can swap it with any subsequent position, then process position \(i+1\), and so on until the last position is processed. Instead of creating a new array to store the partially swapped numbers at each step, we use backtracking to modify the original array directly. Once recursion is complete, we restore the original state. + +For example, using the input `[1,2,3]`, this method outputs permutations in the order: `[[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,2,1], [3,1,2]]`, ensuring all possible permutations are covered. + + + + + +```cpp +// Helper function. +void backtracking(vector &nums, int level, + vector> &permutations) { + if (level == nums.size() - 1) { + permutations.push_back(nums); // Save the current permutation. + return; + } + for (int i = level; i < nums.size(); ++i) { + swap(nums[i], nums[level]); // Modify current state. + backtracking(nums, level + 1, permutations); // Recur to next level. + swap(nums[i], nums[level]); // Revert current state. + } +} + +// Main function. +vector> permute(vector &nums) { + vector> permutations; + backtracking(nums, 0, permutations); + return permutations; +} +``` + + + + +```py +# Helper function. +def backtracking(nums: List[int], level: int, permutations: List[List[int]]): + if level == len(nums) - 1: + permutations.append(nums[:]) # Save current permutation via shallow copy. + return + for i in range(level, len(nums)): + nums[i], nums[level] = nums[level], nums[i] # Modify current state. + backtracking(nums, level + 1, permutations) # Recur to next level. + nums[i], nums[level] = nums[level], nums[i] # Revert current state. + +# Main function. +def permute(nums: List[int]) -> List[List[int]]: + permutations = [] + backtracking(nums, 0, permutations) + return permutations +``` + + + + + +## [77. Combinations](https://leetcode.com/problems/combinations/) + +### Problem Description + +Given an integer `n` and an integer `k`, find all combinations of `k` numbers chosen from the range `1` to `n`. + +### Input and Output Example + +The input consists of two positive integers `n` and `k`. The output is a two-dimensional array representing all possible combinations. + +``` +Input: n = 4, k = 2 +Output: [[2,4], [3,4], [2,3], [1,2], [1,3], [1,4]] +``` + +The order of the dimensions in the two-dimensional array can be arbitrary. + +### Solution Explanation + +Similar to permutation problems, we can use backtracking. In permutations, backtracking swaps positions, while in combinations, it determines whether to include the current number in the result. + + + + + +```cpp +// Auxiliary function +void backtracking(vector>& combinations, vector& pick, int pos, + int n, int k) { + if (pick.size() == k) { + combinations.push_back(pick); + return; + } + for (int i = pos; i <= n; ++i) { + pick.push_back(i); // Modify the current node state + backtracking(combinations, pick, i + 1, n, k); // Recurse to child nodes + pick.pop_back(); // Restore the current node state + } +} + +// Main function +vector> combine(int n, int k) { + vector> combinations; + vector pick; + backtracking(combinations, pick, 1, n, k); + return combinations; +} +``` + + + + +```py +# Auxiliary function +def backtracking( + combinations: List[List[int]], pick: List[int], pos: int, n: int, k: int +): + if len(pick) == k: + combinations.append(pick[:]) # int is a basic type, shallow copy is sufficient + return + for i in range(pos, n + 1): + pick.append(i) # Modify the current node state + backtracking(combinations, pick, i + 1, n, k) # Recurse to child nodes + pick.pop() # Restore the current node state + +# Main function +def combine(n: int, k: int) -> List[List[int]]: + combinations = [] + pick = [] + backtracking(combinations, pick, 1, n, k) + return combinations +``` + + + + + +## [79. Word Search](https://leetcode.com/problems/word-search/) + +### Problem Description + +Given a grid of letters, where all letters are connected to adjacent letters in four directions (up, down, left, right), determine whether a given word can be found in the grid. + +### Input and Output Example + +The input consists of a 2D character array and a string. The output is a boolean indicating whether the word can be found. + +``` +Input: word = "ABCCED", board = +[[’A’,’B’,’C’,’E’], + [’S’,’F’,’C’,’S’], + [’A’,’D’,’E’,’E’]] +Output: true +``` + +Starting from the top-left corner 'A', we can move right, then down, and finally left to find the continuous sequence "ABCCED". + +### Solution Explanation + +Unlike permutation and combination problems, this problem modifies the visited state. During a depth-first search from any position, we mark the current position as visited to prevent revisiting (e.g., avoid moving right and then back left). After all possibilities are explored, we revert the current position to unvisited to avoid interfering with other searches. Using backtracking, we only need to modify a 2D visited matrix without passing the state as a new object to the recursive function. + + + + + +```cpp +// Auxiliary function +bool backtracking(vector>& board, string& word, + vector>& visited, int i, int j, int word_pos) { + if (i < 0 || i >= board.size() || j < 0 || j >= board[0].size() || + visited[i][j] || board[i][j] != word[word_pos]) { + return false; + } + if (word_pos == word.size() - 1) { + return true; + } + visited[i][j] = true; // Modify the current node state + if (backtracking(board, word, visited, i + 1, j, word_pos + 1) || + backtracking(board, word, visited, i - 1, j, word_pos + 1) || + backtracking(board, word, visited, i, j + 1, word_pos + 1) || + backtracking(board, word, visited, i, j - 1, word_pos + 1)) { + return true; // Recurse to child nodes + } + visited[i][j] = false; // Restore the current node state + return false; +} + +// Main function +bool exist(vector>& board, string word) { + int m = board.size(), n = board[0].size(); + vector> visited(m, vector(n, false)); + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (backtracking(board, word, visited, i, j, 0)) { + return true; + } + } + } + return false; +} +``` + + + + +```py +# Auxiliary function +def backtracking(board: List[List[str]], word: str, + visited: List[List[bool]], i: int, j: int, word_pos: int): + if (i < 0 or i >= len(board) or j < 0 or j >= len(board[0]) + or visited[i][j] or board[i][j] != word[word_pos]): + return False + if word_pos == len(word) - 1: + return True + visited[i][j] = True # Modify the current node state + if (backtracking(board, word, visited, i + 1, j, word_pos + 1) or + backtracking(board, word, visited, i - 1, j, word_pos + 1) or + backtracking(board, word, visited, i, j + 1, word_pos + 1) or + backtracking(board, word, visited, i, j - 1, word_pos + 1)): + return True # Recurse to child nodes + visited[i][j] = False # Restore the current node state + return False + +# Main function +def exist(board: List[List[str]], word: str) -> bool: + m, n = len(board), len(board[0]) + visited = [[False for _ in range(n)] for _ in range(m)] + return any([ + backtracking(board, word, visited, i, j, 0) + for i in range(m) for j in range(n) + ]) +``` + + + + + +## [51. N-Queens](https://leetcode.com/problems/n-queens/) + +### Problem Description + +Given an n x n chessboard, determine all possible ways to place n queens so that no two queens attack each other. A queen can attack another queen on the same row, column, or diagonals. + +
      +![](n-queens.png) +
      Problem 51 - An example solution to the 8-Queens problem
      +
      + +### Input and Output Example + +Input is an integer n, output is a 2D list of strings representing all valid chessboard configurations. + +``` +Input: 4 +Output: [ + [".Q..", // Solution 1 + "...Q", + "Q...", + "..Q."], + ["..Q.", // Solution 2 + "Q...", + "...Q", + ".Q.."] +] +``` + +In this example, dots represent empty squares, and 'Q' represents queens. + +### Solution Explanation + +Similar to finding words in a matrix, this problem involves modifying the state matrix during backtracking. The difference here is that we need to track visited columns, left diagonals, and right diagonals. If we traverse by rows to place queens, we don't need to maintain a separate visited array for rows. + + + + +```cpp +// Auxiliary function +void backtracking(vector> &solutions, vector &board, + vector &column, vector &ldiag, + vector &rdiag, int row) { + int n = board.size(); + if (row == n) { + solutions.push_back(board); + return; + } + for (int i = 0; i < n; ++i) { + if (column[i] || ldiag[n - row + i - 1] || rdiag[row + i]) { + continue; + } + // Modify the current node state + board[row][i] = 'Q'; + column[i] = ldiag[n - row + i - 1] = rdiag[row + i] = true; + // Recurse to child nodes + backtracking(solutions, board, column, ldiag, rdiag, row + 1); + // Restore the current node state + board[row][i] = '.'; + column[i] = ldiag[n - row + i - 1] = rdiag[row + i] = false; + } +} + +// Main function +vector> solveNQueens(int n) { + vector> solutions; + vector board(n, string(n, ’.’)); + vector column(n, false); + vector ldiag(2 * n - 1, false); + vector rdiag(2 * n - 1, false); + backtracking(solutions, board, column, ldiag, rdiag, 0); + return solutions; +} +``` + + + + +```py +# Auxiliary function +def backtracking(solutions: List[List[str]], board: List[List[str]], + column: List[bool], ldiag: List[bool], rdiag: List[bool], row: int): + n = len(board) + if row == n: + solutions.append(["".join(row) for row in board]) + return + for i in range(n): + if column[i] or ldiag[n - row + i - 1] or rdiag[row + i]: + continue + # Modify the current node state + board[row][i] = "Q" + column[i] = ldiag[n - row + i - 1] = rdiag[row + i] = True + # Recurse to child nodes + backtracking(solutions, board, column, ldiag, rdiag, row + 1) + # Restore the current node state + board[row][i] = "." + column[i] = ldiag[n - row + i - 1] = rdiag[row + i] = False + +# Main function +def solveNQueens(n: int) -> List[List[str]]: + solutions = [] + board = [["." for _ in range(n)] for _ in range(n)] + column = [False] * n + ldiag = [False] * (2 * n - 1) + rdiag = [False] * (2 * n - 1) + backtracking(solutions, board, column, ldiag, rdiag, 0) + return solutions +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-4-breadth-first-search.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-4-breadth-first-search.mdx new file mode 100644 index 00000000..7952b382 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-4-breadth-first-search.mdx @@ -0,0 +1,454 @@ +--- +sidebar_position: 24 +--- + +# 5.4 Breadth-First Search + +`Breadth-First Search` (BFS) differs from Depth-First Search in that it traverses level by level, so it `requires a first-in, first-out queue` instead of the last-in, first-out stack used in DFS. Since BFS processes nodes by levels, it explores nodes in a "broad" manner and is often used for solving shortest path problems. In Python, we can use `collections.deque` to implement the `queue` used in C++. + + +``` + 1 + / \ + 2 3 + / +4 +``` + +It’s important to note that both DFS and BFS can solve `reachability` problems, such as determining if one node is reachable from another. Many people prefer DFS for such problems because it can be quickly implemented using recursion. However, in practical software engineering, recursive implementations are rarely used because they are harder to understand and may cause stack overflow. Since iterative DFS (using a stack) and BFS (using a queue) have similar implementations, the choice between them depends on the specific requirements of the task. Additionally, if custom traversal priorities are needed, we can use priority queues, which will be discussed in the data structures section. + + +## [1091. Shortest Path in Binary Matrix](https://leetcode.com/problems/shortest-path-in-binary-matrix/) + +### Problem Description + +Given a 2D binary matrix where `1` represents obstacles and `0` represents open paths, each position is connected to its eight neighbors. Find the shortest path from the top-left corner to the bottom-right corner. If there is no valid path, return `-1`. + +### Input and Output Example + +Input is a 2D integer array, and the output is an integer representing the shortest distance. + +``` +Input: +[[0,0,1], + [1,1,0], + [1,1,0]] +Output: 4 +``` + +The shortest path is to move right first, then turn and move downward. + +### Solution Explanation + +Using a queue, we can intuitively apply Breadth-First Search (BFS) to determine the minimum number of layers to expand, i.e., the shortest path to the destination. Be careful not to revisit previously searched positions. + + + + + +```cpp +int shortestPathBinaryMatrix(vector>& grid) { + if (grid[0][0] == 1) { + return -1; + } + int m = grid.size(), n = grid[0].size(); + int dist = 0, count; + queue> q; + q.push({0, 0}); + grid[0][0] = -1; // -1 indicates visited + count = q.size(); + while (count > 0) { + ++dist; + while (count--) { + auto [r, c] = q.front(); + q.pop(); + if (r == m - 1 && c == n - 1) { + return dist; + } + for (int dx = -1; dx <= 1; ++dx) { + for (int dy = -1; dy <= 1; ++dy) { + if (dx == 0 && dy == 0) { + continue; + } + int x = r + dx, y = c + dy; + if (x < 0 || y < 0 || x >= m || y >= n || grid[x][y] != 0) { + continue; + } + grid[x][y] = -1; + q.push({x, y}); + } + } + } + count = q.size(); + } + return -1; +} +``` + + + + +```py +def shortestPathBinaryMatrix(grid: List[List[int]]) -> int: + if grid[0][0] == 1: + return -1 + m, n = len(grid), len(grid[0]) + dist = 0 + q = collections.deque() + q.append((0, 0)) + grid[0][0] = -1 # -1 indicates visited + count = len(q) + while count > 0: + dist += 1 + while count > 0: + count -= 1 + r, c = q.popleft() + if r == m - 1 and c == n - 1: + return dist + for dx in range(-1, 2): + for dy in range(-1, 2): + if dx == 0 and dy == 0: + continue + x, y = r + dx, c + dy + if x < 0 or y < 0 or x >= m or y >= n or grid[x][y] != 0: + continue + grid[x][y] = -1 + q.append((x, y)) + count = len(q) + return -1 +``` + + + + + +## [934. Shortest Bridge](https://leetcode.com/problems/shortest-bridge/) + +### Problem Description + +Given a 2D binary grid where `1` represents land and `0` represents water, each position is connected to its four neighbors. There are exactly two islands in the grid. Find the minimum number of water cells to convert into land to connect the two islands. + +### Input and Output Example + +Input is a 2D integer grid, and the output is a non-negative integer representing the number of water cells to fill. + +``` +Input: +[[1,1,1,1,1], + [1,0,0,0,1], + [1,0,1,0,1], + [1,0,0,0,1], + [1,1,1,1,1]] +Output: 1 +``` + +### Solution Explanation + +This problem can be solved by finding the shortest distance between the two islands. First, identify one of the islands using any search method, then use Breadth-First Search (BFS) to find the shortest distance to the other island. Below is the implementation using Depth-First Search (DFS) to find the first island. + + + + + +```cpp +vector direction{-1, 0, 1, 0, -1}; +// Auxiliary function + +void dfs(queue>& points, vector>& grid, int i, + int j) { + int m = grid.size(), n = grid[0].size(); + if (i < 0 || i >= m || j < 0 || j >= n || grid[i][j] == 2) { + return; + } + if (grid[i][j] == 0) { + points.push({i, j}); + return; + } + grid[i][j] = 2; + for (int k = 0; k < 4; ++k) { + dfs(points, grid, i + direction[k], j + direction[k + 1]); + } +} + +// Main function +int shortestBridge(vector>& grid) { + int m = grid.size(), n = grid[0].size(); + queue> points; + // DFS to find the first island, and change all 1s to 2 + bool flipped = false; + for (int i = 0; i < m && !flipped; ++i) { + for (int j = 0; j < n && !flipped; ++j) { + if (grid[i][j] == 1) { + dfs(points, grid, i, j); + flipped = true; + } + } + } + // BFS to find the second island, and change all 0s encountered to 2 + int level = 0; + while (!points.empty()) { + ++level; + int n_points = points.size(); + while (n_points--) { + auto [r, c] = points.front(); + points.pop(); + grid[r][c] = 2; + for (int k = 0; k < 4; ++k) { + int x = r + direction[k], y = c + direction[k + 1]; + if (x >= 0 && x < m && y >= 0 && y < n) { + if (grid[x][y] == 2) { + continue; + } + if (grid[x][y] == 1) { + return level; + } + grid[x][y] = 2; + points.push({x, y}); + } + } + } + } + return 0; +} +``` + + + + +```py +direction = [-1, 0, 1, 0, -1] + +# Auxiliary function +def dfs(points: Deque[Tuple[int, int]], grid: List[List[int]], i: int, j: int): + m, n = len(grid), len(grid[0]) + if i < 0 or i >= m or j < 0 or j >= n or grid[i][j] == 2: + return + if grid[i][j] == 0: + points.append((i, j)) + return + grid[i][j] = 2 + for k in range(4): + dfs(points, grid, i + direction[k], j + direction[k + 1]) + +def shortestBridge(grid: List[List[int]]) -> int: + m, n = len(grid), len(grid[0]) + points = collections.deque() + # DFS to find the first island, and change all 1s to 2 + flipped = False + for i in range(m): + if flipped: + break + for j in range(n): + if grid[i][j] == 1: + dfs(points, grid, i, j) + flipped = True + break + # BFS to find the second island, and change all 0s encountered to 2 + level = 0 + while len(points) > 0: + level += 1 + points_at_current_level = len(points) + for _ in range(points_at_current_level): + r, c = points.popleft() + grid[r][c] = 2 + for k in range(4): + x, y = r + direction[k], c + direction[k + 1] + if x >= 0 and x < m and y >= 0 and y < n: + if grid[x][y] == 2: + continue + if grid[x][y] == 1: + return level + grid[x][y] = 2 + points.append((x, y)) + return level +``` + + + + + +## [126. Word Ladder II](https://leetcode.com/problems/word-ladder-ii/) + +### Problem Description + +Given a start string, an end string, and a word list, determine if you can transform the start string into the end string by changing one character at a time, where every intermediate string must exist in the word list. If possible, output all transformation sequences with the minimum number of changes. + +### Input and Output Example + +Input consists of two strings and a word list, and the output is a 2D string array representing all transformation sequences. + +``` +Input: beginWord = "hit", endWord = "cog", +wordList = ["hot","dot","dog","lot","log","cog"] +Output: +[["hit","hot","dot","dog","cog"], + ["hit","hot","lot","log","cog"]] +``` + +### Solution Explanation + +We can think of the start string, the end string, and all strings in the word list as nodes. If two strings differ by exactly one character, they are connected. Since the problem requires outputting all transformation sequences with the minimum number of changes, we can use breadth-first search (BFS) to compute the shortest path from the start node to the end node. + +We also use a small optimization: instead of performing BFS only from the start node until the end node is found, we perform BFS from both the start node and the end node simultaneously. Each time, we extend the smaller frontier to minimize the total number of nodes explored. For example, if the shortest distance is 4, performing BFS from one end would explore up to $1 + 2 + 4 + 8 + 16 = 31$ nodes, while performing BFS from both ends for two levels would explore only $2 × (1 + 2 + 4) = 14$ nodes. + +After completing the search, we use backtracking to reconstruct all possible paths. + +This problem is somewhat complex and requires careful thought and implementation. LeetCode's time constraints for this problem are very strict, so even the official solutions may sometimes time out. Multiple submissions may be necessary. + + + + + +```cpp +// Auxiliary function +void backtracking(const string &src, const string &dst, + unordered_map> &next_words, + vector &path, vector> &ladder) { + if (src == dst) { + ladder.push_back(path); + return; + } + if (!next_words.contains(src)) { + return; + } + for (const auto &w : next_words[src]) { + path.push_back(w); // Modify the current node state + backtracking(w, dst, next_words, path, ladder); // Recursively process child nodes + path.pop_back(); // Revert the current node state + } +} + +// Main function +vector> findLadders(string beginWord, string endWord, + vector &wordList) { + vector> ladder; + // Use a hash set to store the dictionary for quick lookups. + unordered_set word_dict; + for (const auto &w : wordList) { + word_dict.insert(w); + } + if (!word_dict.contains(endWord)) { + return ladder; + } + word_dict.erase(beginWord); + word_dict.erase(endWord); + // Create two queues for bidirectional BFS from beginWord and endWord, + // expanding the smaller queue each time. + unordered_set q_small{beginWord}, q_large{endWord}; + unordered_map> next_words; + bool reversed_path = false, found_path = false; + while (!q_small.empty()) { + unordered_set q; + for (const auto &w : q_small) { + string s = w; + for (int i = 0; i < s.size(); ++i) { + for (int j = 0; j < 26; ++j) { + s[i] = j + 'a'; + if (q_large.contains(s)) { + reversed_path ? next_words[s].push_back(w) + : next_words[w].push_back(s); + found_path = true; + } + if (word_dict.contains(s)) { + reversed_path ? next_words[s].push_back(w) + : next_words[w].push_back(s); + q.insert(s); + } + } + s[i] = w[i]; + } + } + if (found_path) { + break; + } + // Avoid revisiting nodes and infinite loops. + for (const auto &w : q) { + word_dict.erase(w); + } + // Update the two queues and maintain size relationship. + if (q.size() <= q_large.size()) { + q_small = q; + } else { + reversed_path = !reversed_path; + q_small = q_large; + q_large = q; + } + } + if (found_path) { + vector path{beginWord}; + backtracking(beginWord, endWord, next_words, path, ladder); + } + return ladder; +} +``` + + + + +```py +# Auxiliary function +def backtracking(src: str, dst: str, next_words: Dict[str, List[str]], + path: List[str], ladder: List[List[str]]): + if src == dst: + ladder.append(path[:]) + return + if src not in next_words: + return + for w in next_words[src]: + path.append(w) # Modify the current node state + backtracking(w, dst, next_words, path, ladder) # Recurse to child nodes + path.pop() # Revert the current node state + +# Main function +def findLadders(beginWord: str, endWord: str, + wordList: List[str]) -> List[List[str]]: + ladder = [] + # Use a hash set to store the dictionary for quick lookups. + word_dict = set(wordList) + if endWord not in word_dict: + return ladder + word_dict = word_dict.difference(set([beginWord, endWord])) + # Create two queues for bidirectional BFS from beginWord and endWord, + # expanding the smaller queue each time. + q_small, q_large = set([beginWord]), set([endWord]) + next_words = dict() + reversed_path, found_path = False, False + while len(q_small) > 0: + q = set() + for w in q_small: + for i in range(len(w)): + for j in range(26): + s = w[:i] + chr(ord("a") + j) + w[i + 1:] + if s in q_large: + if reversed_path: + next_words[s] = next_words.get(s, []) + [w] + else: + next_words[w] = next_words.get(w, []) + [s] + found_path = True + if s in word_dict: + if reversed_path: + next_words[s] = next_words.get(s, []) + [w] + else: + next_words[w] = next_words.get(w, []) + [s] + q.add(s) + if found_path: + break + # Avoid revisiting nodes and infinite loops. + word_dict = word_dict.difference(q) + # Update the two queues and maintain size relationships. + if len(q) <= len(q_large): + q_small = q + else: + reversed_path = not reversed_path + q_small = q_large + q_large = q + + if found_path: + path = [beginWord] + backtracking(beginWord, endWord, next_words, path, ladder) + return ladder +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-5-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-5-exercises.md new file mode 100644 index 00000000..8217d877 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-5-exercises.md @@ -0,0 +1,33 @@ +--- +sidebar_position: 25 +--- + +# 5.5 Exercises + +## Basic Difficulty + +### [130. Surrounded Regions](https://leetcode.com/problems/surrounded-regions/) + +Start by filling from the outer edges, then consider the inner regions. + +### [257. Binary Tree Paths](https://leetcode.com/problems/binary-tree-paths/) + +Output all paths from the root to the leaves in a binary tree. What is the difference if backtracking is used? + +## Advanced Difficulty + +### [47. Permutations II](https://leetcode.com/problems/permutations-ii/) + +A follow-up to the permutations problem. How to handle duplicate elements? + +### [40. Combination Sum II](https://leetcode.com/problems/combination-sum-ii/) + +A follow-up to the combination problem. How to handle duplicate elements? + +### [37. Sudoku Solver](https://leetcode.com/problems/sudoku-solver/) + +A very classic Sudoku problem that can be solved using backtracking. In fact, there are many advanced search methods and pruning strategies, such as heuristic search, to improve speed for Sudoku-related problems. + +### [310. Minimum Height Trees](https://leetcode.com/problems/minimum-height-trees/) + +How can this problem be transformed into a search problem? Should depth-first search or breadth-first search be used? \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/_category_.json new file mode 100644 index 00000000..0943e8c5 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "5. 一切皆可搜索", + "position": 5, + "link": { + "type": "generated-index", + "description": "第 5 章 一切皆可搜索" + } +} diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/n-queens.png b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/n-queens.png new file mode 100644 index 0000000000000000000000000000000000000000..f6ea07555d6478e73b50fe428dcee9ab366cbd98 GIT binary patch literal 20347 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 literal 0 HcmV?d00001 diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-1-algorithm-explanation.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-1-algorithm-explanation.md new file mode 100644 index 00000000..48055183 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-1-algorithm-explanation.md @@ -0,0 +1,13 @@ +--- +sidebar_position: 26 +--- + +# 6.1 算法解释 + +这里我们引用一下维基百科的描述:“`动态规划`(Dynamic Programming, DP)在查找有很多`重叠子问题`的情况的最优解时有效。它将问题重新组合成子问题。为了避免多次解决这些子问题,它们的结果都逐渐被计算并被保存,从简单的问题直到整个问题都被解决。因此,动态规划保存递归时的结果,因而不会在解决同样的问题时花费时间 · · · · · · 动态规划只能应用于有`最优子结构`的问题。最优子结构的意思是局部最优解能决定全局最优解(对有些问题这个要求并不能完全满足,故有时需要引入一定的近似)。简单地说,问题能够分解成子问题来解决。” + +通俗一点来讲,动态规划和其它遍历算法(如深/广度优先搜索)都是将原问题拆成多个子问题然后求解,他们之间最本质的区别是,动态规划`保存子问题的解,避免重复计算`。解决动态规划问题的关键是找到`状态转移方程`,这样我们可以通过计算和储存子问题的解来求解最终问题。 + +同时,我们也可以对动态规划进行`空间压缩`,起到节省空间消耗的效果。这一技巧笔者将在之后的题目中介绍。 + +在一些情况下,动态规划可以看成是带有`状态记录`(memoization)的优先搜索。状态记录的意思为,如果一个子问题在优先搜索时已经计算过一次,我们可以把它的结果储存下来,之后遍历到该子问题的时候可以直接返回储存的结果。动态规划是自下而上的,即先解决子问题,再解决父问题;而用带有状态记录的优先搜索是自上而下的,即从父问题搜索到子问题,若重复搜索到同一个子问题则进行状态记录,防止重复计算。如果题目需求的是最终状态,那么使用动态搜索比较方便;如果题目需要输出所有的路径,那么使用带有状态记录的优先搜索会比较方便。 \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-2-basic-dp-1d.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-2-basic-dp-1d.mdx new file mode 100644 index 00000000..30d4d627 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-2-basic-dp-1d.mdx @@ -0,0 +1,236 @@ +--- +sidebar_position: 27 +--- + +# 6.2 基本动态规划:一维 + +## [70. Climbing Stairs](https://leetcode.com/problems/climbing-stairs/) + +### Problem Description + +给定 $n$ 节台阶,每次可以走一步或走两步,求一共有多少种方式可以走完这些台阶。 + +### Input and Output Example + +输入是一个数字,表示台阶数量;输出是爬台阶的总方式。 + +``` +Input: 3 +Output: 3 +``` + +在这个样例中,一共有三种方法走完这三节台阶:每次走一步;先走一步,再走两步;先走两步,再走一步。 + +### Solution Explanation + +这是十分经典的斐波那契数列题。定义一个数组 dp,dp[i] 表示走到第 i 阶的方法数。因为我们每次可以走一步或者两步,所以第 i 阶可以从第 i-1 或 i-2 阶到达。换句话说,走到第 i 阶的方法数即为走到第 i-1 阶的方法数加上走到第 i-2 阶的方法数。这样我们就得到了状态转移方程 dp[i] = dp[i-1] + dp[i-2]。注意边界条件的处理。 + +:::warning + +有的时候为了方便处理边界情况,我们可以在构造 dp 数组时多留一个位置,用来处理初始状态。本题即多留了一个第 0 阶的初始位置。 + +::: + + + + +```cpp +int climbStairs(int n) { + vector dp(n + 1, 1); + for (int i = 2; i <= n; ++i) { + dp[i] = dp[i - 1] + dp[i - 2]; + } + return dp[n]; +} +``` + + + + +```py +def climbStairs(n: int) -> int: + dp = [1] * (n + 1) + for i in range(2, n + 1): + dp[i] = dp[i - 1] + dp[i - 2] + return dp[n] +``` + + + + + +进一步的,我们可以对动态规划进行空间压缩。因为 dp[i] 只与 dp[i-1] 和 dp[i-2] 有关,因此可以只用两个变量来存储 dp[i-1] 和 dp[i-2],使得原来的 $O(n)$ 空间复杂度优化为 $O(1)$ 复杂度。 + + + + +```cpp +int climbStairs(int n) { + int prev_prev = 1, prev = 1, cur = 1; + for (int i = 2; i <= n; ++i) { + cur = prev_prev + prev; + prev_prev = prev; + prev = cur; + } + return cur; +} +``` + + + + +```py +def climbStairs(n: int) -> int: + prev_prev = prev = cur = 1 + for _ in range(2, n + 1): + cur = prev_prev + prev + prev_prev = prev + prev = cur + return cur +``` + + + + + + +## [198. House Robber](https://leetcode.com/problems/house-robber/) + +### Problem Description + +假如你是一个劫匪,并且决定抢劫一条街上的房子,每个房子内的钱财数量各不相同。如果你抢了两栋相邻的房子,则会触发警报机关。求在不触发机关的情况下最多可以抢劫多少钱。 + +### Input and Output Example + +输入是一个一维数组,表示每个房子的钱财数量;输出是劫匪可以最多抢劫的钱财数量。 + +``` +Input: [2,7,9,3,1] +Output: 12 +``` + +在这个样例中,最多的抢劫方式为抢劫第 1、3、5 个房子。 + +### Solution Explanation + +定义一个数组 dp,dp[i] 表示抢劫到第 i 个房子时,可以抢劫的最大数量。我们考虑 dp[i],此时可以抢劫的最大数量有两种可能,一种是我们选择不抢劫这个房子,此时累计的金额即为 dp[i-1];另一种是我们选择抢劫这个房子,那么此前累计的最大金额只能是 dp[i-2],因为我们不能够抢劫第 i-1 个房子,否则会触发警报机关。因此本题的状态转移方程为 dp[i] = max(dp[i-1], nums[i-1] + dp[i-2])。 + + + + +```cpp +int rob(vector& nums) { + int n = nums.size(); + vector dp(n + 1, 0); + dp[1] = nums[0]; + for (int i = 2; i <= n; ++i) { + dp[i] = max(dp[i - 1], nums[i - 1] + dp[i - 2]); + } + return dp[n]; +} +``` + + + + +```py +def rob(nums: List[int]) -> int: + n = len(nums) + dp = [0] * (n + 1) + dp[1] = nums[0] + for i in range(2, n + 1): + dp[i] = max(dp[i - 1], nums[i - 1] + dp[i - 2]) + return dp[n] +``` + + + + + +同样的,我们可以像题目 70 那样,对空间进行压缩。 + + + + +```cpp +int rob(vector& nums) { + int prev_prev = 0, prev = 0, cur = 0; + for (int i = 0; i < nums.size(); ++i) { + cur = max(prev_prev + nums[i], prev); + prev_prev = prev; + prev = cur; + } + return cur; +} +``` + + + + +```py +def rob(nums: List[int]) -> int: + prev_prev = prev = cur = 0 + for i in range(len(nums)): + cur = max(prev_prev + nums[i], prev) + prev_prev = prev + prev = cur + return cur +``` + + + + + +## [413. Arithmetic Slices](https://leetcode.com/problems/arithmetic-slices/) + +### Problem Description + +给定一个数组,求这个数组中连续且等差的子数组一共有多少个。 + +### Input and Output Example + +输入是一个一维数组,输出是满足等差条件的连续子数组个数。 + +``` +Input: nums = [1,2,3,4] +Output: 3 +``` + +在这个样例中,等差数列有 [1,2,3]、[2,3,4] 和 [1,2,3,4]。 + +### Solution Explanation + +因为要求是等差数列,可以很自然地想到子数组必定满足 num[i] - num[i-1] = num[i-1] - num[i-2]。这里我们对于 dp 数组的定义是以 i 结尾的,满足该条件的子数组数量。因为等差子数组可以在任意一个位置终结,所以我们需要对 dp 数组求和进行子数组统计。 + + + + +```cpp +int numberOfArithmeticSlices(vector& nums) { + int n = nums.size(); + vector dp(n, 0); + for (int i = 2; i < n; ++i) { + if (nums[i] - nums[i - 1] == nums[i - 1] - nums[i - 2]) { + dp[i] = dp[i - 1] + 1; + } + } + return accumulate(dp.begin(), dp.end(), 0); +} +``` + + + + +```py +def numberOfArithmeticSlices(nums: List[int]) -> int: + n = len(nums) + dp = [0] * n + for i in range(2, n): + if nums[i] - nums[i - 1] == nums[i - 1] - nums[i - 2]: + dp[i] = dp[i - 1] + 1 + return sum(dp) +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-3-basic-dp-2d.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-3-basic-dp-2d.mdx new file mode 100644 index 00000000..989c9333 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-3-basic-dp-2d.mdx @@ -0,0 +1,307 @@ +--- +sidebar_position: 28 +--- + +# 6.3 基本动态规划:二维 + +## [64. Minimum Path Sum](https://leetcode.com/problems/minimum-path-sum/) + +### Problem Description + +给定一个 $m × n$ 大小的非负整数矩阵,求从左上角开始到右下角结束的、经过的数字的和最 +小的路径。每次只能向右或者向下移动。 + +### Input and Output Example + +输入是一个二维数组,输出是最优路径的数字和。 + +``` +Input: +[[1,3,1], + [1,5,1], + [4,2,1]] +Output: 7 +``` + +在这个样例中,最短路径为 1->3->1->1->1。 + +### Solution Explanation + +我们可以定义一个同样是二维的 dp 数组,其中 dp[i][j] 表示从左上角开始到 (i, j) 位置的最优路径的数字和。因为每次只能向下或者向右移动,我们可以很直观地得到状态转移方程 dp[i][j] = grid[i][j] + min(dp[i-1][j], dp[i][j-1]),其中 grid 表示原数组。 + +:::warning + +Python 语言中,多维数组多初始化比较特殊,直接初始化为 [[val] * n] * m 会导致只是创造了 m 个 [[val] * n] 的引用。正确的初始化方法为 [[val for _ in range(n)] for _ in range(m)]。 + +::: + + + + +```cpp +int minPathSum(vector>& grid) { + int m = grid.size(), n = grid[0].size(); + vector> dp(m, vector(n, 0)); + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (i == 0 && j == 0) { + dp[i][j] = grid[i][j]; + } else if (i == 0) { + dp[i][j] = grid[i][j] + dp[i][j - 1]; + } else if (j == 0) { + dp[i][j] = grid[i][j] + dp[i - 1][j]; + } else { + dp[i][j] = grid[i][j] + min(dp[i - 1][j], dp[i][j - 1]); + } + } + } + return dp[m - 1][n - 1]; +} +``` + + + + +```py +def minPathSum(grid: List[List[int]]) -> int: + m, n = len(grid), len(grid[0]) + dp = [[0 for _ in range(n)] for _ in range(m)] + for i in range(m): + for j in range(n): + if i == j == 0: + dp[i][j] = grid[i][j] + elif i == 0: + dp[i][j] = grid[i][j] + dp[i][j - 1] + elif j == 0: + dp[i][j] = grid[i][j] + dp[i - 1][j] + else: + dp[i][j] = grid[i][j] + min(dp[i][j - 1], dp[i - 1][j]) + return dp[m - 1][n - 1] +``` + + + + + +因为 dp 矩阵的每一个值只和左边和上面的值相关,我们可以使用空间压缩将 dp 数组压缩为一维。对于第 i 行,在遍历到第 j 列的时候,因为第 j-1 列已经更新过了,所以 dp[j-1] 代表 dp[i][j-1]的值;而 dp[j] 待更新,当前存储的值是在第 i-1 行的时候计算的,所以代表 dp[i-1][j] 的值。 + +:::warning + +如果不是很熟悉空间压缩技巧,笔者推荐您优先尝试写出非空间压缩的解法,如果时间充裕且力所能及再进行空间压缩。 + +::: + + + + + + +```cpp +int minPathSum(vector>& grid) { + int m = grid.size(), n = grid[0].size(); + vector dp(n, 0); + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (i == 0 && j == 0) { + dp[j] = grid[i][j]; + } else if (i == 0) { + dp[j] = grid[i][j] + dp[j - 1]; + } else if (j == 0) { + dp[j] = grid[i][j] + dp[j]; + } else { + dp[j] = grid[i][j] + min(dp[j], dp[j - 1]); + } + } + } + return dp[n - 1]; +} +``` + + + + +```py +def minPathSum(grid: List[List[int]]) -> int: + m, n = len(grid), len(grid[0]) + dp = [0 for _ in range(n)] + for i in range(m): + for j in range(n): + if i == j == 0: + dp[j] = grid[i][j] + elif i == 0: + dp[j] = grid[i][j] + dp[j - 1] + elif j == 0: + dp[j] = grid[i][j] + dp[j] + else: + dp[j] = grid[i][j] + min(dp[j - 1], dp[j]) + return dp[n - 1] +``` + + + + + + +## [542. 01 Matrix](https://leetcode.com/problems/01-matrix/) + +### Problem Description + +给定一个由 0 和 1 组成的二维矩阵,求每个位置到最近的 0 的距离。 + +### Input and Output Example + +输入是一个二维 0-1 数组,输出是一个同样大小的非负整数数组,表示每个位置到最近的 0 的距离。 + +``` +Input: +[[0,0,0], + [0,1,0], + [1,1,1]] + +Output: +[[0,0,0], + [0,1,0], + [1,2,1]] +``` + +### Solution Explanation + +一般来说,因为这道题涉及到四个方向上的最近搜索,所以很多人的第一反应可能会是广度优先搜索。但是对于一个大小 $O(mn)$ 的二维数组,对每个位置进行四向搜索,最坏情况的时间复杂度(即全是 1)会达到恐怖的 $O(m^2n^2)$。一种办法是使用一个二维布尔值数组做 memoization,使得广度优先搜索不会重复遍历相同位置;另一种更简单的方法是,我们从左上到右下进行一次动态搜索,再从右下到左上进行一次动态搜索。两次动态搜索即可完成四个方向上的查找。 + + + + + +```cpp +vector> updateMatrix(vector>& matrix) { + int m = matrix.size(), n = matrix[0].size(); + vector> dp(m, vector(n, numeric_limits::max() - 1)); + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (matrix[i][j] != 0) { + if (i > 0) { + dp[i][j] = min(dp[i][j], dp[i - 1][j] + 1); + } + if (j > 0) { + dp[i][j] = min(dp[i][j], dp[i][j - 1] + 1); + } + } else { + dp[i][j] = 0; + } + } + } + for (int i = m - 1; i >= 0; --i) { + for (int j = n - 1; j >= 0; --j) { + if (matrix[i][j] != 0) { + if (i < m - 1) { + dp[i][j] = min(dp[i][j], dp[i + 1][j] + 1); + } + if (j < n - 1) { + dp[i][j] = min(dp[i][j], dp[i][j + 1] + 1); + } + } + } + } + return dp; +} +``` + + + + +```py +def updateMatrix(matrix: List[List[int]]) -> List[List[int]]: + m, n = len(matrix), len(matrix[0]) + dp = [[sys.maxsize - 1 for _ in range(n)] for _ in range(m)] + for i in range(m): + for j in range(n): + if matrix[i][j] != 0: + if i > 0: + dp[i][j] = min(dp[i][j], dp[i - 1][j] + 1) + if j > 0: + dp[i][j] = min(dp[i][j], dp[i][j - 1] + 1) + else: + dp[i][j] = 0 + for i in range(m - 1, -1, -1): # m-1 to 0, reversed + for j in range(n - 1, -1, -1): # n-1 to 0, reversed + if matrix[i][j] != 0: + if i < m - 1: + dp[i][j] = min(dp[i][j], dp[i + 1][j] + 1) + if j < n - 1: + dp[i][j] = min(dp[i][j], dp[i][j + 1] + 1) + return dp +``` + + + + + +## [221. Maximal Square](https://leetcode.com/problems/maximal-square/) + +### Problem Description + +给定一个二维的 0-1 矩阵,求全由 1 构成的最大正方形面积。 + +### Input and Output Example + +输入是一个二维 0-1 数组,输出是最大正方形面积。 + +``` +Input: +[["1","0","1","0","0"], + ["1","0","1","1","1"], + ["1","1","1","1","1"], + ["1","0","0","1","0"]] +Output: 4 +``` + +### Solution Explanation + +对于在矩阵内搜索正方形或长方形的题型,一种常见的做法是定义一个二维 dp 数组,其中 dp[i][j] 表示满足题目条件的、以 (i, j) 为右下角的正方形或者长方形的属性。对于本题,则表示以 (i, j) 为右下角的全由 1 构成的最大正方形边长。如果当前位置是 0,那么 dp[i][j] 即为 0;如果当前位置是 1,我们假设 dp[i][j] = k,其充分条件为 dp[i-1][j-1]、dp[i][j-1] 和 dp[i-1][j] 的值必须都不小于 k − 1,否则 (i, j) 位置不可以构成一个面积为 $k^2$ 的正方形。同理,如果这三个值中的的最小值为 k − 1,则 (i, j) 位置一定且最大可以构成一个面积为 $k^2$ 的正方形。 + + +

      + + ![](6.1.png) + +
      图 6.1: 题目 542 - 左边为一个 0-1 矩阵,右边为其对应的 dp 矩阵,我们可以发现最大的正方形边长为 3
      +
      + + + + +```cpp +int maximalSquare(vector>& matrix) { + int m = matrix.size(), n = matrix[0].size(); + int max_side = 0; + vector> dp(m + 1, vector(n + 1, 0)); + for (int i = 1; i <= m; ++i) { + for (int j = 1; j <= n; ++j) { + if (matrix[i - 1][j - 1] == ’1’) { + dp[i][j] = + min(dp[i - 1][j - 1], min(dp[i][j - 1], dp[i - 1][j])) + 1; + } + max_side = max(max_side, dp[i][j]); + } + } + return max_side * max_side; +} +``` + + + + +```py +def maximalSquare(matrix: List[List[str]]) -> int: + m, n = len(matrix), len(matrix[0]) + dp = [[0 for _ in range(n + 1)] for _ in range(m + 1)] + for i in range(1, m + 1): + for j in range(1, n + 1): + if matrix[i - 1][j - 1] == "1": + dp[i][j] = min(dp[i - 1][j - 1], dp[i][j - 1], dp[i - 1][j]) + 1 + return max(max(row) for row in dp) ** 2 +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-4-partition-problems.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-4-partition-problems.mdx new file mode 100644 index 00000000..8942200f --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-4-partition-problems.mdx @@ -0,0 +1,347 @@ +--- +sidebar_position: 29 +--- + +# 6.4 分割类型题 + +## [279. Perfect Squares](https://leetcode.com/problems/perfect-squares/) + +### Problem Description + +给定一个正整数,求其最少可以由几个完全平方数相加构成。 + +### Input and Output Example + +输入是给定的正整数,输出也是一个正整数,表示输入的数字最少可以由几个完全平方数相加构成。 + +``` +Input: n = 13 +Output: 2 +``` + +在这个样例中,13 的最少构成方法为 4+9。 + +### Solution Explanation + +对于分割类型题,动态规划的状态转移方程通常并不依赖相邻的位置,而是依赖于满足分割条件的位置。我们定义一个一维矩阵 dp,其中 dp[i] 表示数字 i 最少可以由几个完全平方数相加构成。在本题中,位置 i 只依赖 $i - j^2$ 的位置,如 i - 1、i - 4、i - 9 等等,才能满足完全平方分割的条件。因此 dp[i] 可以取的最小值即为 1+ min(dp[i-1], dp[i-4], dp[i-9] · · · )。注意边界条件的处理。 + + + + +```cpp +int numSquares(int n) { + vector dp(n + 1, numeric_limits::max()); + dp[0] = 0; + for (int i = 1; i <= n; ++i) { + for (int j = 1; j * j <= i; ++j) { + dp[i] = min(dp[i], dp[i - j * j] + 1); + } + } + return dp[n]; +} +``` + + + + +```py +def numSquares(n: int) -> int: + dp = [0] + [sys.maxsize] * n + for i in range(1, n + 1): + for j in range(1, int(floor(sqrt(i))) + 1): + dp[i] = min(dp[i], dp[i - j * j] + 1) + return dp[n] +``` + + + + + +## [91. Decode Ways](https://leetcode.com/problems/decode-ways/) + +### Problem Description + +已知字母 A-Z 可以表示成数字 1-26。给定一个数字串,求有多少种不同的字符串等价于这个数字串。 + +### Input and Output Example + +输入是一个由数字组成的字符串,输出是满足条件的解码方式总数。 + +``` +Input: "226" +Output: 3 +``` + +在这个样例中,有三种解码方式:BZ(2 26)、VF(22 6) 或 BBF(2 2 6)。 + +### Solution Explanation + +这是一道很经典的动态规划题,难度不大但是十分考验耐心。这是因为只有 1-26 可以表示字母,因此对于一些特殊情况,比如数字 0 或者当相邻两数字大于 26 时,需要有不同的状态转移方程,详见如下代码。 + + + + +```cpp +int numDecodings(string s) { + int n = s.length(); + int prev = s[0] - ’0’; + if (prev == 0) { + return 0; + } + if (n == 1) { + return 1; + } + vector dp(n + 1, 1); + for (int i = 2; i <= n; ++i) { + int cur = s[i - 1] - ’0’; + if ((prev == 0 || prev > 2) && cur == 0) { + // 00, 30, 40, ..., 90, 非法。 + return 0; + } + if ((prev < 2 && prev > 0) || (prev == 2 && cur <= 6)) { + // 10, 11, ..., 25, 26. + if (cur == 0) { + // 10, 20,只能连续解码两位。 + dp[i] = dp[i - 2]; + } else { + // 可以解码当前位,也可以连续解码两位。 + dp[i] = dp[i - 2] + dp[i - 1]; + } + } else { + // 合法,但只能解码当前位。 + dp[i] = dp[i - 1]; + } + prev = cur; + } + return dp[n]; +} +``` + + + + +```py +def numDecodings(s: str) -> int: + n = len(s) + prev = ord(s[0]) - ord("0") + if prev == 0: + return 0 + if n == 1: + return 1 + dp = [1] * (n + 1) + for i in range(2, n + 1): + cur = ord(s[i - 1]) - ord("0") + if (prev == 0 or prev > 2) and cur == 0: + # 00, 30, 40, ..., 90, 非法。 + return 0 + if 0 < prev < 2 or (prev == 2 and cur <= 6): + # 10, 11, ..., 25, 26. + if cur == 0: + # 10, 20,只能连续解码两位。 + dp[i] = dp[i - 2] + else: + # 可以解码当前位,也可以连续解码两位。 + dp[i] = dp[i - 2] + dp[i - 1] + else: + # 合法,但只能解码当前位。 + dp[i] = dp[i - 1] + prev = cur + return dp[n] +``` + + + + + +## [139. Word Break](https://leetcode.com/problems/word-break/) + +### Problem Description + +给定一个字符串和一个字符串集合,求是否存在一种分割方式,使得原字符串分割后的子字符串都可以在集合内找到。 + +### Input and Output Example + +``` +Input: s = "applepenapple", wordDict = ["apple", "pen"] +Output: true +``` + +在这个样例中,字符串可以被分割为 [“apple”,“pen”,“apple”]。 + +### Solution Explanation + +类似于完全平方数分割问题,这道题的分割条件由集合内的字符串决定,因此在考虑每个分割位置时,需要遍历字符串集合,以确定当前位置是否可以成功分割。注意对于位置 0,需要初始化值为真。 + + + + +```cpp +bool wordBreak(string s, vector& wordDict) { + int n = s.length(); + vector dp(n + 1, false); + dp[0] = true; + for (int i = 1; i <= n; ++i) { + for (const string& word : wordDict) { + int m = word.length(); + if (i >= m && s.substr(i - m, m) == word) { + dp[i] = dp[i - m]; + } + // 提前剪枝,略微加速运算。 + // 如果不剪枝,上一行代码需要变更为 dp[i] = dp[i] || dp[i - m]; + if (dp[i]) { + break; + } + } + } + return dp[n]; +} +``` + + + + +```py +def wordBreak(s: str, wordDict: List[str]) -> bool: + n = len(s) + dp = [True] + [False] * n + for i in range(1, n + 1): + for word in wordDict: + m = len(word) + if i >= m and s[i - m : i] == word: + dp[i] = dp[i - m] + # 提前剪枝,略微加速运算。 + # 如果不剪枝,上一行代码需要变更为 dp[i] = dp[i] or dp[i-m] + if dp[i]: + break + return dp[n] +``` + + + + + +## [1105. Filling Bookcase Shelves](https://leetcode.com/problems/filling-bookcase-shelves/) + +### Problem Description + +给定一个数组,每个元素代表一本书的厚度和高度。问对于一个固定宽度的书架,如果按照数组中书的顺序从左到右、从上到下摆放,最小总高度是多少。 + +### Input and Output Example + + +``` +Input: books = [[1,1],[2,3],[2,3],[1,1],[1,1],[1,1],[1,2]], shelfWidth = 4 +Output: 6 +``` + + +
      + + ![](https://assets.leetcode.com/uploads/2019/06/24/shelves.png) + +
      图 6.2: 书架摆放问题 - 样例图解
      +
      + +### Solution Explanation + +令 dp[i] 表示放置第 i 本书时的最小总高度,则 dp[i] 可以是在第 i-1 本书下面重新放一排,也可以是在满足不超过前一排宽度的情况下放在前一排。 + + + + +```cpp +int minHeightShelves(vector>& books, int shelfWidth) { + int n = books.size(); + vector dp(n + 1, 0); + for (int i = 1; i <= n; ++i) { + int w = books[i - 1][0], h = books[i - 1][1]; + dp[i] = dp[i - 1] + h; + for (int j = i - 1; j > 0; --j) { + int prev_w = books[j - 1][0], prev_h = books[j - 1][1]; + w += prev_w; + if (w > shelfWidth) { + break; + } + h = max(h, prev_h); + dp[i] = min(dp[i], dp[j - 1] + h); + } + } + return dp[n]; +} +``` + + + + +```py +def minHeightShelves(books: List[List[int]], shelfWidth: int) -> int: + n = len(books) + dp = [0] * (n + 1) + for i, (w, h) in enumerate(books, 1): + dp[i] = dp[i - 1] + h + for j in range(i - 1, 0, -1): + prev_w, prev_h = books[j - 1] + w += prev_w + if w > shelfWidth: + break + h = max(h, prev_h) + dp[i] = min(dp[i], dp[j - 1] + h) + return dp[n] +``` + + + + + +## [377. Combination Sum IV](https://leetcode.com/problems/combination-sum-iv/) + +### Problem Description + +给定一个不重复数字的数组和一个目标数,求加起来是目标数的所有排列的总数量。(虽然这道题叫做 Combination Sum,但是不同顺序的组合会被当作不同答案,因此本质上是排列。) + +### Input and Output Example + +``` +Input: nums = [1,2,3], target = 4 +Output: 7 +``` + +七种不同的排列为 (1, 1, 1, 1)、(1, 1, 2)、(1, 2, 1)、(1, 3)、(2, 1, 1)、(2, 2) 和 (3, 1)。 + + +### Solution Explanation + +令 dp[i] 表示加起来和为 i 时,满足条件的排列数量。在内循环中我们可以直接对所有合法数字进行拿取。这里注意,在 C++ 题解中,因为求和时很容易超过 int 上界,我们这里用 double 存储 dp 数组。 + + + + +```cpp +int combinationSum4(vector& nums, int target) { + vector dp(target + 1, 0); + dp[0] = 1; + for (int i = 1; i <= target; ++i) { + for (int num : nums) { + if (num <= i) { + dp[i] += dp[i - num]; + } + } + } + return dp[target]; +} +``` + + + + +```py +def combinationSum4(nums: List[int], target: int) -> int: + dp = [1] + [0] * target + for i in range(1, target + 1): + dp[i] = sum(dp[i - num] for num in nums if i >= num) + return dp[target] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-5-subsequence-problems.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-5-subsequence-problems.mdx new file mode 100644 index 00000000..9e83bdcb --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-5-subsequence-problems.mdx @@ -0,0 +1,189 @@ +--- +sidebar_position: 30 +--- + +# 6.5 子序列问题 + +## [300. Longest Increasing Subsequence](https://leetcode.com/problems/longest-increasing-subsequence/) + +### Problem Description + +给定一个未排序的整数数组,求最长的递增子序列。 + +:::warning + +按照 LeetCode 的习惯,子序列(subsequence)不必连续,子数组(subarray)或子字符串(substring)必须连续。 + +::: + +### Input and Output Example + +输入是一个一维数组,输出是一个正整数,表示最长递增子序列的长度。 + +``` +Input: [10,9,2,5,3,7,101,4] +Output: 4 +``` + +在这个样例中,最长递增子序列之一是 [2,3,7,101]。 + +### Solution Explanation + +对于子序列问题,第一种动态规划方法是,定义一个 dp 数组,其中 dp[i] 表示以 i 结尾的子序列的性质。在处理好每个位置后,统计一遍各个位置的结果即可得到题目要求的结果。 + +在本题中,dp[i] 可以表示以 i 结尾的、最长子序列长度。对于每一个位置 i,如果其之前的某个位置 j 所对应的数字小于位置 i 所对应的数字,则我们可以获得一个以 i 结尾的、长度为 dp[j] + 1 的子序列。为了遍历所有情况,我们需要 i 和 j 进行两层循环,其时间复杂度为 $O(n^2)$。 + + + + +```cpp +int lengthOfLIS(vector& nums) { + int max_len = 0, n = nums.size(); + vector dp(n, 1); + for (int i = 0; i < n; ++i) { + for (int j = 0; j < i; ++j) { + if (nums[i] > nums[j]) { + dp[i] = max(dp[i], dp[j] + 1); + } + } + max_len = max(max_len, dp[i]); + } + return max_len; +} +``` + + + + +```py +def lengthOfLIS(nums: List[int]) -> int: + n = len(nums) + dp = [1] * n + for i in range(n): + for j in range(i): + if nums[i] > nums[j]: + dp[i] = max(dp[i], dp[j] + 1) + return max(dp) +``` + + + + + +本题还可以使用二分查找将时间复杂度降低为 $O(n \log n)$。我们定义一个 dp 数组,其中 dp[k] 存储长度为 k+1 的最长递增子序列的最后一个数字。我们遍历每一个位置 i,如果其对应的数字大于 dp 数组中所有数字的值,那么我们把它放在 dp 数组尾部,表示最长递增子序列长度加 1;如果我们发现这个数字在 dp 数组中比数字 a 大、比数字 b 小,则我们将 b 更新为此数字,使得之后构成递增序列的可能性增大。以这种方式维护的 dp 数组永远是递增的,因此可以用二分查找加速搜索。 + +以样例为例,对于数组 [10,9,2,5,3,7,101,4],我们每轮的更新查找情况为: + +``` +num dp +10 [10] +9 [9] +2 [2] +5 [2,5] +3 [2,3] +7 [2,3,7] +101 [2,3,7,101] +4 [2,3,4,101] +``` + +最终我们知道最长递增子序列的长度是 4。注意 dp 数组最终的形式并不一定是合法的排列形式,如 [2,3,4,101] 并不是子序列;但之前覆盖掉的 [2,3,7,101] 是最优解之一。 + +类似的,对于其他题目,如果状态转移方程的结果递增或递减,且需要进行插入或查找操作,我们也可以使用二分法进行加速。 + + + + +```cpp +int lengthOfLIS(vector& nums) { + vector dp{nums[0]}; + for (int num : nums) { + if (dp.back() < num) { + dp.push_back(num); + } else { + *lower_bound(dp.begin(), dp.end(), num) = num; + } + } + return dp.size(); +} +``` + + + + +```py +def lengthOfLIS(nums: List[int]) -> int: + dp = [nums[0]] + for num in nums: + if dp[-1] < num: + dp.append(num) + else: + dp[bisect.bisect_left(dp, num, 0, len(dp))] = num + return len(dp) +``` + + + + + +## [1143. Longest Commom Subsequence](https://leetcode.com/problems/longest-common-subsequence/) + +### Problem Description + +给定两个字符串,求它们最长的公共子序列长度。 + +### Input and Output Example + +输入是两个字符串,输出是一个整数,表示它们满足题目条件的长度。 + +``` +Input: text1 = "abcde", text2 = "ace" +Output: 3 +``` + +在这个样例中,最长公共子序列是“ace”。 + +### Solution Explanation + +对于子序列问题,第二种动态规划方法是,定义一个 dp 数组,其中 dp[i] 表示到位置 i 为止的子序列的性质,并不必须以 i 结尾。这样 dp 数组的最后一位结果即为题目所求,不需要再对每个位置进行统计。 + +在本题中,我们可以建立一个二维数组 dp,其中 dp[i][j] 表示到第一个字符串位置 i 为止、到第二个字符串位置 j 为止、最长的公共子序列长度。这样一来我们就可以很方便地分情况讨论这两个位置对应的字母相同与不同的情况了。 + + + + +```cpp +int longestCommonSubsequence(string text1, string text2) { + int m = text1.length(), n = text2.length(); + vector> dp(m + 1, vector(n + 1, 0)); + for (int i = 1; i <= m; ++i) { + for (int j = 1; j <= n; ++j) { + if (text1[i - 1] == text2[j - 1]) { + dp[i][j] = dp[i - 1][j - 1] + 1; + } else { + dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); + } + } + } + return dp[m][n]; +} +``` + + + + +```py +def longestCommonSubsequence(text1: str, text2: str) -> int: + m, n = len(text1), len(text2) + dp = [[0 for _ in range(n + 1)] for _ in range(m + 1)] + for i in range(1, m + 1): + for j in range(1, n + 1): + if text1[i - 1] == text2[j - 1]: + dp[i][j] = dp[i - 1][j - 1] + 1 + else: + dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + return dp[m][n] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-6-knapsack-problem.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-6-knapsack-problem.mdx new file mode 100644 index 00000000..72f98236 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-6-knapsack-problem.mdx @@ -0,0 +1,421 @@ +--- +sidebar_position: 31 +--- + +# 6.6 背包问题 + +`背包问题(knapsack problem)`是一种组合优化的 NP 完全问题:有 n 个物品和载重为 w 的背包,每个物品都有自己的重量 weight 和价值 value,求拿哪些物品可以使得背包所装下物品的总价值最大。如果限定每种物品只能选择 0 个或 1 个,则问题称为 `0-1 背包问题(0-1 knapsack)`;如果不限定每种物品的数量,则问题称为`无界背包问题或完全背包问题(unbounded knapsack)`。 + +我们可以用动态规划来解决背包问题。以 0-1 背包问题为例。我们可以定义一个二维数组 dp存储最大价值,其中 dp[i][j] 表示前 i 件物品重量不超过 j 的情况下能达到的最大价值。在我们遍历到第 i 件物品时,在当前背包总载重为 j 的情况下,如果我们不将物品 i 放入背包,那么 dp[i][j] = dp[i-1][j],即前 i 个物品的最大价值等于只取前 i-1 个物品时的最大价值;如果我们将物品 i 放入背包,假设第 i 件物品重量为 weight,价值为 value,那么我们得到 dp[i][j] = dp[i-1][j-weight] + value。我们只需在遍历过程中对这两种情况取最大值即可,总时间复杂度和空间复杂度都为 $O(nw)$。 + + + + + +```cpp +int knapsack(vector weights, vector values, int n, int w) { + vector> dp(n + 1, vector(w + 1, 0)); + for (int i = 1; i <= n; ++i) { + int weight = weights[i - 1], value = values[i - 1]; + for (int j = 1; j <= w; ++j) { + if (j >= weight) { + dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight] + value); + } else { + dp[i][j] = dp[i - 1][j]; + } + } + } + return dp[n][w]; +} +``` + + + + +```py +def knapsack(weights: List[int], values: List[int], n: int, w: int) -> int: + dp = [[0 for _ in range(w + 1)] for _ in range(n + 1)] + for i in range(1, n + 1): + weight, value = weights[i - 1], values[i - 1] + for j in range(1, w + 1): + if j >= weight: + dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight] + value) + else: + dp[i][j] = dp[i - 1][j] + return dp[n][w] +``` + + + + + +
      + + ![](6.3.png) + +
      图 6.3: 0-1 背包问题 - 状态转移矩阵样例
      +
      + +我们可以进一步对 0-1 背包进行空间优化,将空间复杂度降低为 O(w)。如图所示,假设我们目前考虑物品 i = 2,且其重量为 weight = 2,价值为 value = 3;对于背包载重 j,我们可以得到 dp[2][j] = max(dp[1][j], dp[1][j-2] + 3)。这里可以发现我们永远只依赖于上一排 i = 1 的信息,之前算过的其他物品都不需要再使用。因此我们可以去掉 dp 矩阵的第一个维度,在考虑物品 i 时变成 dp[j] = max(dp[j], dp[j-weight] + value)。这里要注意我们在遍历每一行的时候必须`逆向遍历`,这样才能够调用上一行物品 i-1 时 dp[j-weight] 的值;若按照从左往右的顺序进行正向遍历,则dp[j-weight] 的值在遍历到 j 之前就已经被更新成物品 i 的值了。 + + + + +```cpp +int knapsack(vector weights, vector values, int n, int w) { + vector dp(w + 1, 0); + for (int i = 1; i <= n; ++i) { + int weight = weights[i - 1], value = values[i - 1]; + for (int j = w; j >= weight; --j) { + dp[j] = max(dp[j], dp[j - weight] + value); + } + } + return dp[w]; +} +``` + + + + +```py +def knapsack(weights: List[int], values: List[int], n: int, w: int) -> int: + dp = [0] * (w + 1) + for i in range(1, n + 1): + weight, value = weights[i - 1], values[i - 1] + for j in range(w, weight - 1, -1): + dp[j] = max(dp[j], [j - weight] + value) + return dp[w] +``` + + + + + +在完全背包问题中,一个物品可以拿多次。如图上半部分所示,假设我们遍历到物品 i = 2,且其重量为 weight = 2,价值为 value = 3;对于背包载重 j = 5,最多只能装下 2 个该物品。那么我们的状态转移方程就变成了 dp[2][5] = max(dp[1][5], dp[1][3] + 3, dp[1][1] + 6)。如果采用这种方法,假设背包载重无穷大而物体的重量无穷小,我们这里的比较次数也会趋近于无穷大,远超$O(nw)$ 的时间复杂度。 + +
      + + ![](6.4.png) + +
      图 6.4: 完全背包问题 - 状态转移矩阵样例
      +
      + +怎么解决这个问题呢?我们发现在 dp[2][3] 的时候我们其实已经考虑了 dp[1][3] 和 dp[2][1] 的情况,而在时 dp[2][1] 也已经考虑了 dp[1][1] 的情况。因此,如图下半部分所示,对于拿多个物品的情况,我们只需考虑 dp[2][3] 即可,即 dp[2][5] = max(dp[1][5], dp[2][3] + 3)。这样,我们就得到了完全背包问题的状态转移方程:dp[i][j] = max(dp[i-1][j], dp[i][j-w] + v),其与 0-1 背包问题的差别仅仅是把状态转移方程中的第二个 i-1 变成了 i。 + + + + +```cpp +int knapsack(vector weights, vector values, int n, int w) { + vector> dp(n + 1, vector(w + 1, 0)); + for (int i = 1; i <= n; ++i) { + int weight = weights[i - 1], value = values[i - 1]; + for (int j = 1; j <= w; ++j) { + if (j >= weight) { + dp[i][j] = max(dp[i - 1][j], dp[i][j - weight] + value); + } else { + dp[i][j] = dp[i - 1][j]; + } + } + } + return dp[n][w]; +} +``` + + + + +```py +def knapsack(weights: List[int], values: List[int], n: int, w: int) -> int: + dp = [[0 for _ in range(w + 1)] for _ in range(n + 1)] + for i in range(1, n + 1): + weight, value = weights[i - 1], values[i - 1] + for j in range(1, w + 1): + if j >= weight: + dp[i][j] = max(dp[i - 1][j], dp[i][j - weight] + value) + else: + dp[i][j] = dp[i - 1][j] + return dp[n][w] +``` + + + + + +同样的,我们也可以利用空间压缩将时间复杂度降低为 $O(w)$。这里要注意我们在遍历每一行的时候必须`正向遍历`,因为我们需要利用当前物品在第 j-weight 列的信息。 + + + + +```cpp +int knapsack(vector weights, vector values, int n, int w) { + vector dp(w + 1, 0); + for (int i = 1; i <= n; ++i) { + int weight = weights[i - 1], value = values[i - 1]; + for (int j = weight; j <= w; ++j) { + dp[j] = max(dp[j], dp[j - weight] + value); + } + } + return dp[w]; +} +``` + + + + +```py +def knapsack(weights: List[int], values: List[int], n: int, w: int) -> int: + dp = [0] * (w + 1) + for i in range(1, n + 1): + weight, value = weights[i - 1], values[i - 1] + for j in range(weight, w + 1): + dp[j] = max(dp[j], [j - weight] + value) + return dp[w] +``` + + + + + +:::warning + +压缩空间时到底需要正向还是逆向遍历呢?物品和重量哪个放在外层,哪个放在内层呢?这取决于状态转移方程的依赖关系。在思考空间压缩前,不妨将状态转移矩阵画出来,方便思考如何进行空间压缩,以及压缩哪个维度更省空间。 + +::: + +## [416. Partition Equal Subset Sum](https://leetcode.com/problems/partition-equal-subset-sum/) + +### Problem Description + +给定一个正整数数组,求是否可以把这个数组分成和相等的两部分。 + +### Input and Output Example + +输入是一个一维正整数数组,输出时一个布尔值,表示是否可以满足题目要求。 + +``` +Input: [1,5,11,5] +Output: true +``` + +在这个样例中,满足条件的分割方法是 [1,5,5] 和 [11]。 + +### Solution Explanation + +本题等价于 0-1 背包问题,设所有数字和为 sum,我们的目标是选取一部分物品,使得它们的总和为 sum/2。这道题不需要考虑价值,因此我们只需要通过一个布尔值矩阵来表示状态转移矩阵。注意边界条件的处理。 + + + + +```cpp +bool canPartition(vector &nums) { + int nums_sum = accumulate(nums.begin(), nums.end(), 0); + if (nums_sum % 2 != 0) { + return false; + } + int target = nums_sum / 2, n = nums.size(); + vector> dp(n + 1, vector(target + 1, false)); + dp[0][0] = true; + for (int i = 1; i <= n; ++i) { + for (int j = 0; j <= target; ++j) { + if (j < nums[i - 1]) { + dp[i][j] = dp[i - 1][j]; + } else { + dp[i][j] = dp[i - 1][j] || dp[i - 1][j - nums[i - 1]]; + } + } + } + return dp[n][target]; +} +``` + + + + +```py +def canPartition(nums: List[int]) -> bool: + nums_sum = sum(nums) + if nums_sum % 2 != 0: + return False + target, n = nums_sum // 2, len(nums) + dp = [[False for _ in range(target + 1)] for _ in range(n + 1)] + dp[0][0] = True + for i in range(1, n + 1): + for j in range(target + 1): + if j < nums[i - 1]: + dp[i][j] = dp[i - 1][j] + else: + dp[i][j] = dp[i - 1][j] or dp[i - 1][j - nums[i - 1]] + return dp[n][target] +``` + + + + + +同样的,我们也可以对本题进行空间压缩。注意对数字和的遍历需要逆向。 + + + + +```cpp +bool canPartition(vector &nums) { + int nums_sum = accumulate(nums.begin(), nums.end(), 0); + if (nums_sum % 2 != 0) { + return false; + } + int target = nums_sum / 2, n = nums.size(); + vector dp(target + 1, false); + dp[0] = true; + for (int i = 1; i <= n; ++i) { + for (int j = target; j >= nums[i - 1]; --j) { + dp[j] = dp[j] || dp[j - nums[i - 1]]; + } + } + return dp[target]; +} +``` + + + + +```py +def canPartition(nums: List[int]) -> bool: + nums_sum = sum(nums) + if nums_sum % 2 != 0: + return False + target, n = nums_sum // 2, len(nums) + dp = [True] + [False] * target + for i in range(1, n + 1): + for j in range(target, nums[i - 1] - 1, -1): + dp[j] = dp[j] or dp[j - nums[i - 1]] + return dp[target] +``` + + + + + +## [474. Ones and Zeroes](https://leetcode.com/problems/ones-and-zeroes/) + +### Problem Description + +给定 $m$ 个数字 0 和 $n$ 个数字 1,以及一些由 0-1 构成的字符串,求利用这些数字最多可以构成多少个给定的字符串,字符串只可以构成一次。 + +### Input and Output Example + +输入两个整数 $m$ 和 $n$,表示 0 和 1 的数量,以及一个一维字符串数组,表示待构成的字符串; +输出是一个整数,表示最多可以生成的字符串个数。 + +``` +Input: Array = {"10", "0001", "111001", "1", "0"}, m = 5, n = 3 +Output: 4 +``` + +在这个样例中,我们可以用 5 个 0 和 3 个 1 构成 [“10”, “0001”, “1”, “0”]。 + +### Solution Explanation + +这是一个多维费用的 0-1 背包问题,有两个背包大小,0 的数量和 1 的数量。我们在这里直接展示三维空间压缩到二维后的写法。 + + + + +```cpp +int findMaxForm(vector& strs, int m, int n) { + vector> dp(m + 1, vector(n + 1, 0)); + for (const string& s : strs) { + int zeros = 0, ones = 0; + for (char c : s) { + if (c == ’0’) { + ++zeros; + } else { + ++ones; + } + } + for (int i = m; i >= zeros; --i) { + for (int j = n; j >= ones; --j) { + dp[i][j] = max(dp[i][j], dp[i - zeros][j - ones] + 1); + } + } + } + return dp[m][n]; +} +``` + + + + +```py +def findMaxForm(strs: List[str], m: int, n: int) -> int: + dp = [[0 for _ in range(n + 1)] for _ in range(m + 1)] + for s in strs: + zeros = len(list(filter(lambda c: c == "0", s))) + ones = len(s) - zeros + for i in range(m, zeros - 1, -1): + for j in range(n, ones - 1, -1): + dp[i][j] = max(dp[i][j], dp[i - zeros][j - ones] + 1) + return dp[m][n] +``` + + + + + +## [322. Coin Change](https://leetcode.com/problems/coin-change/) + +### Problem Description + +给定一些硬币的面额,求最少可以用多少颗硬币组成给定的金额。 + +### Input and Output Example + +输入一个一维整数数组,表示硬币的面额;以及一个整数,表示给定的金额。输出一个整数,表示满足条件的最少的硬币数量。若不存在解,则返回-1。 + +``` +Input: coins = [1, 2, 5], amount = 11 +Output: 3 +``` + +在这个样例中,最少的组合方法是 11 = 5 + 5 + 1。 + +### Solution Explanation + +因为每个硬币可以用无限多次,这道题本质上是完全背包。我们直接展示二维空间压缩为一维的写法。 + +这里注意,我们把 dp 数组初始化为 amount + 1 而不是-1 的原因是,在动态规划过程中有求最小值的操作,如果初始化成-1 则会导致结果始终为-1。至于为什么取这个值,是因为 i 最大可以取 amount,而最多的组成方式是只用 1 元硬币,因此 amount + 1 一定大于所有可能的组合方式,取最小值时一定不会是它。在动态规划完成后,若结果仍然是此值,则说明不存在满足条件的组合方法,返回-1。 + + + + +```cpp +int coinChange(vector& coins, int amount) { + vector dp(amount + 1, amount + 1); + dp[0] = 0; + for (int i = 1; i <= amount; ++i) { + for (int coin : coins) { + if (i >= coin) { + dp[i] = min(dp[i], dp[i - coin] + 1); + } + } + } + return dp[amount] != amount + 1 ? dp[amount] : -1; +} +``` + + + + +```py +def coinChange(coins: List[int], amount: int) -> int: + dp = [0] + [amount + 1] * amount + for i in range(1, amount + 1): + for coin in coins: + if i >= coin: + dp[i] = min(dp[i], dp[i - coin] + 1) + return dp[amount] if dp[amount] != amount + 1 else -1 +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-7-string-editing.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-7-string-editing.mdx new file mode 100644 index 00000000..328bc9eb --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-7-string-editing.mdx @@ -0,0 +1,132 @@ +--- +sidebar_position: 32 +--- + +# 6.7 字符串编辑 + +## [72. Edit Distance](https://leetcode.com/problems/edit-distance/) + +### Problem Description + +给定两个字符串,已知你可以删除、替换和插入任意字符串的任意字符,求最少编辑几步可以将两个字符串变成相同。 + +### Input and Output Example + +输入是两个字符串,输出是一个整数,表示最少的步骤。 + +``` +Input: word1 = "horse", word2 = "ros" +Output: 3 +``` + +在这个样例中,一种最优编辑方法是 horse -> rorse -> rose -> ros。 + +### Solution Explanation + +类似于题目 1143,我们使用一个二维数组 dp[i][j],表示将第一个字符串到位置 i 为止,和第二个字符串到位置 j 为止,最多需要几步编辑。当第 i 位和第 j 位对应的字符相同时,dp[i][j] 等于 dp[i-1][j-1];当二者对应的字符不同时,修改的消耗是 dp[i-1][j-1]+1,插入 i 位置/删除 j 位置的消耗是 dp[i][j-1] + 1,插入 j 位置/删除 i 位置的消耗是 dp[i-1][j] + 1。 + + + + +```cpp +int minDistance(string word1, string word2) { + int m = word1.length(), n = word2.length(); + vector> dp(m + 1, vector(n + 1, 0)); + for (int i = 0; i <= m; ++i) { + for (int j = 0; j <= n; ++j) { + if (i == 0 || j == 0) { + dp[i][j] = i + j; + } else { + dp[i][j] = dp[i - 1][j - 1] + (word1[i - 1] != word2[j - 1]); + dp[i][j] = min(dp[i][j], dp[i - 1][j] + 1); + dp[i][j] = min(dp[i][j], dp[i][j - 1] + 1); + } + } + } + return dp[m][n]; +} +``` + + + + +```py +def minDistance(word1: str, word2: str) -> int: + m, n = len(word1), len(word2) + dp = [[0 for _ in range(n + 1)] for _ in range(m + 1)] + for i in range(m + 1): + for j in range(n + 1): + if i == 0 or j == 0: + dp[i][j] = i + j + else: + dp[i][j] = min( + dp[i - 1][j - 1] + int(word1[i - 1] != word2[j - 1]), + dp[i][j - 1] + 1, + dp[i - 1][j] + 1, + ) + return dp[m][n] +``` + + + + + +## [650. 2 Keys Keyboard](https://leetcode.com/problems/2-keys-keyboard/) + +### Problem Description + +给定一个字母 A,已知你可以每次选择复制全部字符,或者粘贴之前复制的字符,求最少需要几次操作可以把字符串延展到指定长度。 + +### Input and Output Example + +输入是一个正整数,代表指定长度;输出是一个整数,表示最少操作次数。 + +``` +Input: 3 +Output: 3 +``` + +在这个样例中,一种最优的操作方法是先复制一次,再粘贴两次。 + +### Solution Explanation + +不同于以往通过加减实现的动态规划,这里需要乘除法来计算位置,因为粘贴操作是倍数增加的。我们使用一个一维数组 dp,其中位置 i 表示延展到长度 i 的最少操作次数。对于每个位置 j,如果 j 可以被 i 整除,那么长度 i 就可以由长度 j 操作得到,其操作次数等价于把一个长度为 j 的 A 延展到长度为 i/j。因此我们可以得到递推公式 dp[i] = dp[j] + dp[i/j]。 + + + + +```cpp +int minSteps(int n) { + vector dp(n + 1, 0); + for (int i = 2; i <= n; ++i) { + dp[i] = i; + for (int j = 2; j * j <= i; ++j) { + if (i % j == 0) { + dp[i] = dp[j] + dp[i / j]; + // 提前剪枝,因为j从小到大,因此操作数量一定最小。 + break; + } + } + } + return dp[n]; +} +``` + + + + +```py +def minSteps(n: int) -> int: + dp = [0] * 2 + list(range(2, n + 1)) + for i in range(2, n + 1): + for j in range(2, floor(sqrt(i)) + 1): + if i % j == 0: + dp[i] = dp[j] + dp[i // j] + # 提前剪枝,因为j从小到大,因此操作数量一定最小。 + break + return dp[n] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-8-stock-trading.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-8-stock-trading.mdx new file mode 100644 index 00000000..0c27000b --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-8-stock-trading.mdx @@ -0,0 +1,183 @@ +--- +sidebar_position: 33 +--- + +# 6.8 股票交易 + +`股票交易`类问题通常可以用动态规划来解决。对于稍微复杂一些的股票交易类问题,比如需要冷却时间或者交易费用,则可以用通过动态规划实现的`状态机`来解决。 + +## [121. Best Time to Buy and Sell Stock](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/) + +### Problem Description + +给定一段时间内每天某只股票的固定价格,已知你只可以买卖各一次,求最大的收益。 + +### Input and Output Example + +输入一个一维整数数组,表示每天的股票价格;输出一个整数,表示最大的收益。 + +``` +Input: [7,1,5,3,6,4] +Output: 5 +``` + +在这个样例中,最大的利润为在第二天价格为 1 时买入,在第五天价格为 6 时卖出。 + +### Solution Explanation + +我们可以遍历一遍数组,在每一个位置 i 时,记录 i 位置之前所有价格中的最低价格,然后将当前的价格作为售出价格,查看当前收益是不是最大收益即可。注意本题中以及之后题目中的buy 和 sell 表示买卖操作时,用户账户的收益。因此买时为负,卖时为正。 + + + + +```cpp +int maxProfit(vector& prices) { + int buy = numeric_limits::lowest(), sell = 0; + for (int price : prices) { + buy = max(buy, -price); + sell = max(sell, buy + price); + } + return sell; +} +``` + + + + +```py +def maxProfit(prices: List[int]) -> int: + buy, sell = -sys.maxsize, 0 + for price in prices: + buy = max(buy, -price) + sell = max(sell, buy + price) + return sell +``` + + + + + +## [188. Best Time to Buy and Sell Stock IV](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/) + +### Problem Description + +给定一段时间内每天某只股票的固定价格,已知你只可以买卖各 $k$ 次,且每次只能拥有一支股票,求最大的收益。 + +### Input and Output Example + +输入一个一维整数数组,表示每天的股票价格;以及一个整数,表示可以买卖的次数 $k$。输出一个整数,表示最大的收益。 + +``` +Input: [3,2,6,5,0,3], k = 2 +Output: 7 +``` + +在这个样例中,最大的利润为在第二天价格为 2 时买入,在第三天价格为 6 时卖出;再在第五天价格为 0 时买入,在第六天价格为 3 时卖出。 + +### Solution Explanation + +类似地,我们可以建立两个动态规划数组 buy 和 sell,对于每天的股票价格,buy[j] 表示在第 j 次买入时的最大收益,sell[j] 表示在第 j 次卖出时的最大收益。 + + + + + +```cpp +int maxProfit(int k, vector& prices) { + int days = prices.size(); + vector buy(k + 1, numeric_limits::lowest()), sell(k + 1, 0); + for (int i = 0; i < days; ++i) { + for (int j = 1; j <= k; ++j) { + buy[j] = max(buy[j], sell[j - 1] - prices[i]); + sell[j] = max(sell[j], buy[j] + prices[i]); + } + } + return sell[k]; +} +``` + + + + +```py +def maxProfit(k: int, prices: List[int]) -> int: + days = len(prices) + buy, sell = [-sys.maxsize] * (k + 1), [0] * (k + 1) + for i in range(days): + for j in range(1, k + 1): + buy[j] = max(buy[j], sell[j - 1] - prices[i]) + sell[j] = max(sell[j], buy[j] + prices[i]) + return sell[k] +``` + + + + + +## [309. Best Time to Buy and Sell Stock with Cooldown](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/) + +### Problem Description + +给定一段时间内每天某只股票的固定价格,已知每次卖出之后必须冷却一天,且每次只能拥有一支股票,求最大的收益。 + +### Input and Output Example + +输入一个一维整数数组,表示每天的股票价格;输出一个整数,表示最大的收益。 + +``` +Input: [1,2,3,0,2] +Output: 3 +``` + +在这个样例中,最大的利润获取操作是买入、卖出、冷却、买入、卖出。 + +### Solution Explanation + +我们可以使用状态机来解决这类复杂的状态转移问题,通过建立多个状态以及它们的转移方式,我们可以很容易地推导出各个状态的转移方程。如图所示,我们可以建立四个状态来表示带有冷却的股票交易,以及它们的之间的转移方式。 + +
      + + ![](6.5.png) + +
      图 6.5: 题目 309 - 状态机状态转移
      +
      + + + + +```cpp +int maxProfit(vector& prices) { + int n = prices.size(); + vector buy(n), sell(n), s1(n), s2(n); + s1[0] = buy[0] = -prices[0]; + sell[0] = s2[0] = 0; + for (int i = 1; i < n; ++i) { + buy[i] = s2[i - 1] - prices[i]; + s1[i] = max(buy[i - 1], s1[i - 1]); + sell[i] = max(buy[i - 1], s1[i - 1]) + prices[i]; + s2[i] = max(s2[i - 1], sell[i - 1]); + } + return max(sell[n - 1], s2[n - 1]); +} +``` + + + + +```py +def maxProfit(prices: List[int]) -> int: + n = len(prices) + buy, sell, s1, s2 = [0] * n, [0] * n, [0] * n, [0] * n + s1[0] = buy[0] = -prices[0] + sell[0] = s2[0] = 0 + for i in range(1, n): + buy[i] = s2[i - 1] - prices[i] + s1[i] = max(buy[i - 1], s1[i - 1]) + sell[i] = max(buy[i - 1], s1[i - 1]) + prices[i] + s2[i] = max(s2[i - 1], sell[i - 1]) + return max(sell[n - 1], s2[n - 1]) +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-9-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-9-exercises.md new file mode 100644 index 00000000..a4fe5a77 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-9-exercises.md @@ -0,0 +1,45 @@ +--- +sidebar_position: 34 +--- + +# 6.9 Exercises + +## Basic Difficulty + +### [213. House Robber II](https://leetcode.com/problems/house-robber-ii/) + +强盗抢劫题目的 follow-up,如何处理环形数组呢? + +### [53. Maximum Subarray](https://leetcode.com/problems/maximum-subarray/) + +经典的一维动态规划题目,试着把一维空间优化为常量吧。 + +### [343. Integer Break](https://leetcode.com/problems/integer-break/) + +分割类型题,先尝试用动态规划求解,再思考是否有更简单的解法。 + +### [583. Delete Operation for Two Strings](https://leetcode.com/problems/delete-operation-for-two-strings/) + +最长公共子序列的变种题。 + +## Advanced Difficulty + +### [646. Maximum Length of Pair Chain](https://leetcode.com/problems/maximum-length-of-pair-chain/) + +最长递增子序列的变种题,同样的,尝试用二分进行加速。 + +### [10. Regular Expression Matching](https://leetcode.com/problems/regular-expression-matching/) + +正则表达式匹配,非常考验耐心。需要根据正则表达式的不同情况,即字符、星号,点号等,分情况讨论。 + +### [376. Wiggle Subsequence](https://leetcode.com/problems/wiggle-subsequence/) + +最长摆动子序列,通项公式比较特殊,需要仔细思考。 + +### [494. Target Sum](https://leetcode.com/problems/target-sum/) + +如果告诉你这道题是 0-1 背包,你是否会有一些思路? + +### [714. Best Time to Buy and Sell Stock with Transaction Fee](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/) + +建立状态机,股票交易类问题就会迎刃而解。 \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6.1.png b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6.1.png new file mode 100644 index 0000000000000000000000000000000000000000..6b075633b568d5d942aa5c48465c6d9405570cd8 GIT binary patch literal 34632 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 b`8TOCn|H(_jP^6`fPb*(ROPc}jlBK?n+e1I literal 0 HcmV?d00001 diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6.3.png b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6.3.png new file mode 100644 index 0000000000000000000000000000000000000000..4ff0572c706140bae1f5106077d11faa558e1657 GIT binary patch literal 24349 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 IqZWSu1}%@5q5uE@ literal 0 HcmV?d00001 diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6.4.png b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6.4.png new file mode 100644 index 0000000000000000000000000000000000000000..4acc447e937b7a5c5a0b1776104bb02828a9db0e GIT binary patch literal 38325 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 literal 0 HcmV?d00001 diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6.5.png b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6.5.png new file mode 100644 index 0000000000000000000000000000000000000000..97774d350a26134d09ee8c80275c1678f4c363b8 GIT binary patch literal 49000 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 k$,那么 $T(n) =O( f (n))$ + +::: + +通过主定理我们可以知道,归并排序属于第二种情况,且时间复杂度为 $O(n \log n)$。其他的分治问题也可以通过主定理求得时间复杂度。 + +另外,自上而下的分治可以和 memoization 结合,避免重复遍历相同的子问题。如果方便推导,也可以换用自下而上的动态规划方法求解。 \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-2-expression-problems.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-2-expression-problems.mdx new file mode 100644 index 00000000..1a13bec4 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-2-expression-problems.mdx @@ -0,0 +1,154 @@ +--- +sidebar_position: 36 +--- + +# 7.2 表达式问题 + +## [241. Different Ways to Add Parentheses](https://leetcode.com/problems/different-ways-to-add-parentheses/) + +### Problem Description + +给定一个只包含加、减和乘法的数学表达式,求通过加括号可以得到多少种不同的结果。 + +### Input and Output Example + +输入是一个字符串,表示数学表达式;输出是一个数组,存储所有不同的加括号结果。 + +``` +Input: "2-1-1" +Output: [0, 2] +``` + +在这个样例中,有两种加括号结果:((2-1)-1) = 0 和 (2-(1-1)) = 2。 + +### Solution Explanation + +利用分治思想,我们可以把加括号转化为,对于每个运算符号,先执行处理两侧的数学表达式,再处理此运算符号。注意边界情况,即字符串内无运算符号,只有数字。 + + + + +```cpp +vector diffWaysToCompute(string expression) { + vector ways; + unordered_map> op_funcs; + op_funcs[’+’] = [](int x, int y) { return x + y; }; + op_funcs[’-’] = [](int x, int y) { return x - y; }; + op_funcs[’*’] = [](int x, int y) { return x * y; }; + for (int i = 0; i < expression.length(); ++i) { + char c = expression[i]; + if (!op_funcs.contains(c)) { + continue; + } + auto left = diffWaysToCompute(expression.substr(0, i)); + auto right = diffWaysToCompute(expression.substr(i + 1)); + for (int l : left) { + for (int r : right) { + ways.push_back(op_funcs[c](l, r)); + } + } + } + return ways.empty() ? vector{stoi(expression)} : ways; +} +``` + + + + +```py +def diffWaysToCompute(expression: str) -> List[int]: + ways = [] + op_funcs = { + "+": (lambda x, y: x + y), + "-": (lambda x, y: x - y), + "*": (lambda x, y: x * y), + } + for i, c in enumerate(expression): + if c not in op_funcs: + continue + left = diffWaysToCompute(expression[:i]) + right = diffWaysToCompute(expression[i + 1 :]) + ways += [op_funcs[c](l, r) for l in left for r in right] + return [int(expression)] if len(ways) == 0 else ways +``` + + + + + +我们发现,某些被 divide 的子字符串可能重复出现多次,因此我们可以用 memoization 来去重。比如建立一个哈希表,key 是 (l, r),value 是 ways。每次遇到相同的 (l, r),我们可以直接返回已经计算过的 ways。或者与其我们从上到下用分治处理 +memoization,不如直接从下到上用动态规划处理。 + + + + +```cpp +vector diffWaysToCompute(string expression) { + // 利用istringstream, 将数字和操作符进行分词。 + vector nums; + vector ops; + int num = 0; + char op = ’ ’; + istringstream ss(expression); + while (ss >> num) { + nums.push_back(num); + if (ss >> op) { + ops.push_back(op); + } + } + int n = nums.size(); + vector>> dp(n, vector>(n, vector())); + unordered_map> op_funcs; + op_funcs[’+’] = [](int a, int b) { return a + b; }; + op_funcs[’-’] = [](int a, int b) { return a - b; }; + op_funcs[’*’] = [](int a, int b) { return a * b; }; + for (int i = 0; i < n; ++i) { + for (int j = i; j >= 0; --j) { + if (i == j) { + dp[j][i].push_back(nums[i]); + continue; + } + for (int k = j; k < i; ++k) { + for (auto l : dp[j][k]) { + for (auto r : dp[k + 1][i]) { + dp[j][i].push_back(op_funcs[ops[k]](l, r)); + } + } + } + } + } + return dp[0][n - 1]; +} +``` + + + + +```py +def diffWaysToCompute(expression: str) -> List[int]: + # re.split可以将操作符(\D)和数字直接分开。 + sections = re.split(r"(\D)", expression) + nums = [int(num) for num in sections if num.isdigit()] + ops = [op for op in sections if not op.isdigit()] + n = len(nums) + dp = [[[] for _ in range(n)] for _ in range(n)] + op_funcs = { + "+": (lambda x, y: x + y), + "-": (lambda x, y: x - y), + "*": (lambda x, y: x * y), + } + for i in range(n): + for j in range(i, -1, -1): + if i == j: + dp[j][i].append(nums[i]) + continue + for k in range(j, i): + dp[j][i] += [op_funcs[ops[k]](l, r) + for l in dp[j][k] for r in dp[k + 1][i]] + + return dp[0][n - 1] + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-3-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-3-exercises.md new file mode 100644 index 00000000..348cff97 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-3-exercises.md @@ -0,0 +1,17 @@ +--- +sidebar_position: 37 +--- + +# 7.3 Exercises + +## Basic Difficulty + +### [932. Beautiful Array](https://leetcode.com/problems/beautiful-array/) + +试着用从上到下的分治(递归)写法求解,最好加上 memoization;再用从下到上的动态规划写法求解。 + +## Advanced Difficulty + +### [312. Burst Balloons](https://leetcode.com/problems/burst-balloons/) + +试着用从上到下的分治(递归)写法求解,最好加上 memoization;再用从下到上的动态规划写法求解。 \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/_category_.json new file mode 100644 index 00000000..2535d2d4 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "7. 化繁为简的分治法", + "position": 7, + "link": { + "type": "generated-index", + "description": "第 7 章 化繁为简的分治法" + } +} diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-1-introduction.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-1-introduction.md new file mode 100644 index 00000000..d753971e --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-1-introduction.md @@ -0,0 +1,7 @@ +--- +sidebar_position: 38 +--- + +# 8.1 引言 + +对于 LeetCode 上数量不少的数学题,我们尽量将其按照类型划分讲解。然而很多数学题的解法并不通用,我们也很难一口气把所有的套路讲清楚,因此我们只选择了几道经典或是典型的题目,供大家参考。 \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-2-lcm-gcd.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-2-lcm-gcd.mdx new file mode 100644 index 00000000..58dda1b8 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-2-lcm-gcd.mdx @@ -0,0 +1,72 @@ +--- +sidebar_position: 39 +--- + +# 8.2 公倍数与公因数 + +利用`辗转相除法`,我们可以很方便地求得两个数的最大公因数(greatest common divisor,GCD);将两个数相乘再除以最大公因数即可得到最小公倍数(least common multiple, LCM)。 + + + + + +```cpp +int gcd(int a, int b) { + return b == 0 ? a : gcd(b, a % b); +} + +int lcm(int a, int b) { + return a * b / gcd(a, b); +} +``` + + + + +```py +def gcd(a: int, b: int) -> int: + return a if b == 0 else gcd(b, a % b) + +def lcm(a: int, b: int) -> int: + return (a * b) // gcd(a, b) +``` + + + + + +进一步地,我们也可以通过扩展欧几里得算法(extended gcd)在求得 a 和 b 最大公因数的同时,也得到它们的系数 x 和 y,从而使 ax + by = gcd(a, b)。因为 Python 中 int 只能按值传递,我们可以用一个长度固定为 1 的 list() 来进行传递引用的操作。 + + + + +```cpp +int xGCD(int a, int b, int &x, int &y) { + if (b == 0) { + x = 1, y = 0; + return a; + } + int x_inner, y_inner; + int gcd = xGCD(b, a % b, x_inner, y_inner); + x = y_inner, y = x_inner - (a / b) * y_inner; + return gcd; +} +``` + + + + +```py +def xGCD(a: int, b: int, x: List[int], y: List[int]) -> int: + if b == 0: + x[0], y[0] = 1, 0 + return a + x_inner, y_inner = [0], [0] + gcd = xGCD(b, a % b, x_inner, y_inner) + x[0], y[0] = y_inner, x_inner - (a / b) * y_inner + return gcd +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-3-prime-numbers.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-3-prime-numbers.mdx new file mode 100644 index 00000000..5712ce64 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-3-prime-numbers.mdx @@ -0,0 +1,138 @@ +--- +sidebar_position: 40 +--- + +# 8.3 质数 + +质数又称素数,指的是指在大于 1 的自然数中,除了 1 和它本身以外不再有其他因数的自然数。值得注意的是,每一个数都可以分解成质数的乘积。 + + +## [204. Count Primes](https://leetcode.com/problems/count-primes/) + +### Problem Description + +给定一个数字 n,求小于 n 的质数的个数。 + +### Input and Output Example + +输入一个整数,输出也是一个整数,表示小于输入数的质数的个数。 + +``` +Input: 10 +Output: 4 +``` + +在这个样例中,小于 10 的质数只有 [2,3,5,7]。 + +### Solution Explanation + +`埃拉托斯特尼筛法`(Sieve of Eratosthenes,简称埃氏筛法)是非常常用的,判断一个整数是否是质数的方法。并且它可以在判断一个整数 n 时,同时判断所小于 n 的整数,因此非常适合这道题。其原理也十分易懂:从 1 到 n 遍历,假设当前遍历到 m,则把所有小于 n 的、且是 m 的倍数的整数标为和数;遍历完成后,没有被标为和数的数字即为质数。 + + + + +```cpp +int countPrimes(int n) { + if (n <= 2) { + return 0; + } + vector primes(n, true); + int count = n - 2; // 去掉不是质数的1 + for (int i = 2; i < n; ++i) { + if (primes[i]) { + for (int j = 2 * i; j < n; j += i) { + if (primes[j]) { + primes[j] = false; + --count; + } + } + } + } + return count; +} +``` + + + + +```py +def countPrimes(n: int) -> int: + if n <= 2: + return 0 + primes = [True for _ in range(n)] + count = n - 2 # 去掉不是质数的1 + for i in range(2, n): + if primes[i]: + for j in range(2 * i, n, i): + if primes[j]: + primes[j] = False + count -= 1 + return count +``` + + + + + +利用质数的一些性质,我们可以进一步优化该算法。 + + + + + +```cpp +int countPrimes(int n) { + if (n <= 2) { + return 0; + } + vector primes(n, true); + int sqrtn = sqrt(n); + int count = n / 2; // 偶数一定不是质数 + int i = 3; + // 最小质因子一定小于等于开方数。 + while (i <= sqrtn) { + // 向右找倍数,注意避免偶数和重复遍历。 + for (int j = i * i; j < n; j += 2 * i) { + if (primes[j]) { + --count; + primes[j] = false; + } + } + i += 2; + // 向右前进查找位置,注意避免偶数和重复遍历。 + while (i <= sqrtn && !primes[i]) { + i += 2; + } + } + return count; +} +``` + + + + +```py +def countPrimes(n: int) -> int: + if n <= 2: + return 0 + primes = [True for _ in range(n)] + sqrtn = sqrt(n) + count = n // 2 # 偶数一定不是质数 + i = 3 + # 最小质因子一定小于等于开方数。 + while i <= sqrtn: + # 向右找倍数,注意避免偶数和重复遍历。 + for j in range(i * i, n, 2 * i): + if primes[j]: + count -= 1 + primes[j] = False + i += 2 + # 向右前进查找位置,注意避免偶数和重复遍历。 + while i <= sqrtn and not primes[i]: + i += 2 + return count +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-4-number-processing.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-4-number-processing.mdx new file mode 100644 index 00000000..765acb36 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-4-number-processing.mdx @@ -0,0 +1,318 @@ +--- +sidebar_position: 41 +--- + +# 8.4 数字处理 + +## [504. Base 7](https://leetcode.com/problems/base-7/) + +### Problem Description + +给定一个十进制整数,求它在七进制下的表示。 + +### Input and Output Example + +输入一个整数,输出一个字符串,表示其七进制。 + +``` +Input: 100 +Output: "202" +``` + +在这个样例中,100 的七进制表示法来源于 101 = 2 * 49 + 0 * 7 + 2 * 1。 + +### Solution Explanation + +`进制转换`类型的题,通常是利用除法和取模(mod)来进行计算,同时也要注意一些细节,如负数和零。如果输出是数字类型而非字符串,则也需要考虑是否会超出整数上下界。 + + + + +```cpp +string convertToBase7(int num) { + if (num == 0) { + return "0"; + } + string base7; + bool is_negative = num < 0; + num = abs(num); + while (num) { + int quotient = num / 7, remainder = num % 7; + base7 = to_string(remainder) + base7; + num = quotient; + } + return is_negative ? "-" + base7 : base7; +} +``` + + + + +```py +def convertToBase7(num: int) -> str: + if num == 0: + return "0" + base7 = "" + is_negative = num < 0 + num = abs(num) + while num: + quotient, remainder = num // 7, num % 7 + base7 = str(remainder) + base7 + num = quotient + return "-" + base7 if is_negative else base7 +``` + + + + + +## [172. Factorial Trailing Zeroes](https://leetcode.com/problems/factorial-trailing-zeroes/) + +### Problem Description + +给定一个非负整数,判断它的阶乘结果的结尾有几个 0。 + +### Input and Output Example + +输入一个非负整数,输出一个非负整数,表示输入的阶乘结果的结尾有几个 0。 + +``` +Input: 12 +Output: 2 +``` + +在这个样例中,12 != 479001600 的结尾有两个 0。 + +### Solution Explanation + +每个尾部的 0 由 2 × 5 =10 而来,因此我们可以把阶乘的每一个元素拆成质数相乘,统计有多少个 2 和 5。明显的,质因子 2 的数量远多于质因子 5 的数量,因此我们可以只统计阶乘结果里有多少个质因子 5。 + + + + +```cpp +int trailingZeroes(int n) { + return n == 0 ? 0 : n / 5 + trailingZeroes(n / 5); +} +``` + + + + +```py +def trailingZeroes(n: int) -> int: + return 0 if n == 0 else n // 5 + trailingZeroes(n // 5) +``` + + + + + +## [415. Add Strings](https://leetcode.com/problems/add-strings/) + +### Problem Description + +给定两个由数字组成的字符串,求它们相加的结果。 + +### Input and Output Example + +输入是两个字符串,输出是一个整数,表示输入的数字和。 + +``` +Input: num1 = "99", num2 = "1" +Output: 100 +``` + +因为相加运算是从后往前进行的,所以可以先翻转字符串,再逐位计算。这种类型的题考察的是细节,如进位、位数差等等。 + +### Solution Explanation + + + + + + +```cpp +string addStrings(string num1, string num2) { + string added_str; + reverse(num1.begin(), num1.end()); + reverse(num2.begin(), num2.end()); + int len1 = num1.length(), len2 = num2.length(); + if (len1 <= len2) { + swap(num1, num2); + swap(len1, len2); + } + int add_bit = 0; + for (int i = 0; i < len1; ++i) { + int cur_sum = + (num1[i] - ’0’) + (i < len2 ? num2[i] - ’0’ : 0) + add_bit; + added_str += to_string(cur_sum % 10); + add_bit = cur_sum >= 10; + } + if (add_bit) { + added_str += "1"; + } + reverse(added_str.begin(), added_str.end()); + return added_str; +} +``` + + + + +```py +def addStrings(num1: str, num2: str) -> str: + added_str = "" + num1 = num1[::-1] + num2 = num2[::-1] + len1, len2 = len(num1), len(num2) + if len1 <= len2: + num1, num2 = num2, num1 + len1, len2 = len2, len1 + add_bit = 0 + for i in range(len1): + cur_sum = int(num1[i]) + (int(num2[i]) if i < len2 else 0) + add_bit + added_str += str(cur_sum % 10) + add_bit = int(cur_sum >= 10) + if add_bit: + added_str += "1" + return added_str[::-1] +``` + + + + + + +## [326. Power of Three](https://leetcode.com/problems/power-of-three/) + +### Problem Description + +判断一个数字是否是 3 的次方。 + +### Input and Output Example + +输入一个整数,输出一个布尔值。 + +``` +Input: n = 27 +Output: true +``` + +### Solution Explanation + +有两种方法,一种是利用对数。设 log3 n =m,如果 n 是 3 的整数次方,那么 m 一定是整数。 + + + + +```cpp +bool isPowerOfThree(int n) { + return fmod(log10(n) / log10(3), 1) == 0; +} +``` + + + + +```py +def isPowerOfThree(n: int) -> bool: + return n > 0 and math.fmod(math.log10(n) / math.log10(3), 1) == 0 +``` + + + + + +另一种方法是,因为在 C++ int 范围内 3 的最大次方是 $3^{19} = 1162261467$,如果 n 是 3 的整数次方,那么 1162261467 除以 n 的余数一定是零;反之亦然。然而对于 Python 来说,因为 int 理论上可以取无穷大,我们只能循环判断。 + + + + +```cpp +bool isPowerOfThree(int n) { + return n > 0 && 1162261467 % n == 0; +} +``` + + + + +```py +def isPowerOfThree(n: int) -> bool: + if n <= 0: + return False + while n % 3 == 0: + n //= 3 + return n == 1 +``` + + + + + +## [50. Pow(x, n)](https://leetcode.com/problems/powx-n/) + +### Problem Description + +计算 x 的 n 次方。 + +### Input and Output Example + +输入一个浮点数表示 x 和一个整数表示 n,输出一个浮点数表示次方结果。 + +``` +Input: x = 2.00000, n = 10 +Output: 1024.00000 +``` + +### Solution Explanation + + +利用递归,我们可以较为轻松地解决本题。注意边界条件的处理。 + + + + +```cpp +double myPow(double x, int n) { + if (n == 0) { + return 1; + } + if (x == 0) { + return 0; + } + if (n == numeric_limits::min()) { + return 1 / (x * myPow(x, numeric_limits::max())); + } + if (n < 0) { + return 1 / myPow(x, -n); + } + if (n % 2 != 0) { + return x * myPow(x, n - 1); + } + double myPowSqrt = myPow(x, n >> 1); + return myPowSqrt * myPowSqrt; +} +``` + + + + +```py +def myPow(x: float, n: int) -> float: + if n == 0: + return 1 + if x == 0: + return 0 + if n < 0: + return 1 / myPow(x, -n) + if n % 2 != 0: + return x * myPow(x, n - 1) + myPowSqrt = myPow(x, n >> 1) + return myPowSqrt * myPowSqrt +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-5-random-sampling.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-5-random-sampling.mdx new file mode 100644 index 00000000..0d9386c8 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-5-random-sampling.mdx @@ -0,0 +1,228 @@ +--- +sidebar_position: 42 +--- + +# 8.5 随机与取样 + +## [384. Shuffle an Array](https://leetcode.com/problems/shuffle-an-array/) + +### Problem Description + +给定一个数组,要求实现两个指令函数。第一个函数“shuffle”可以随机打乱这个数组,第二个函数“reset”可以恢复原来的顺序。 + +### Input and Output Example + +输入是一个存有整数数字的数组,和一个包含指令函数名称的数组。输出是一个二维数组,表示每个指令生成的数组。 + +``` +Input: nums = [1,2,3], actions: ["shuffle","shuffle","reset"] +Output: [[2,1,3],[3,2,1],[1,2,3]] +``` + +在这个样例中,前两次打乱的结果只要是随机生成即可。 + +### Solution Explanation + +我们采用经典的 `Fisher-Yates 洗牌算法`,原理是通过随机交换位置来实现随机打乱,有正向和反向两种写法,且实现非常方便。注意这里“reset”函数以及 Solution 类的构造函数的实现细节。 + + + + +```cpp +class Solution { + public: + Solution(vector nums) : nums_(nums) {} + + vector reset() { return nums_; } + + vector shuffle() { + vector shuffled(nums_); + int n = nums_.size(); + // 可以使用反向或者正向洗牌,效果相同。 + // 反向洗牌: + for (int i = n - 1; i >= 0; --i) { + swap(shuffled[i], shuffled[rand() % (i + 1)]); + } + // 正向洗牌: + // for (int i = 0; i < n; ++i) { + // int pos = rand() % (n - i); + // swap(shuffled[i], shuffled[i+pos]); + // } + return shuffled; + } + + private: + vector nums_; +}; +``` + + + + +```py +class Solution: + def __init__(self, nums: List[int]): + self.base = nums[:] + + def reset(self) -> List[int]: + return self.base[:] + + def shuffle(self) -> List[int]: + shuffled = self.base[:] + n = len(self.base) + # 可以使用反向或者正向洗牌,效果相同。 + # 反向洗牌: + for i in range(n - 1, -1, -1): + j = random.randint(0, i) + shuffled[i], shuffled[j] = shuffled[j], shuffled[i] + # 正向洗牌: + # for i in range(n): + # j = i + random.randint(0, n - i - 1) + # shuffled[i], shuffled[j] = shuffled[j], shuffled[i] + return shuffled +``` + + + + + +## [528. Random Pick with Weight](https://leetcode.com/problems/random-pick-with-weight/) + +### Problem Description + +给定一个数组,数组每个位置的值表示该位置的权重,要求按照权重的概率去随机采样。 + +### Input and Output Example + +输入是一维正整数数组,表示权重;和一个包含指令字符串的一维数组,表示运行几次随机采样。输出是一维整数数组,表示随机采样的整数在数组中的位置。 + +``` +Input: weights = [1,3], actions: ["pickIndex","pickIndex","pickIndex"] +Output: [0,1,1] +``` + +在这个样例中,每次选择的位置都是不确定的,但选择第 0 个位置的期望为 1/4,选择第 1 个位置的期望为 3/4。 + +### Solution Explanation + +我们可以先使用 partial_sum求前缀和(即到每个位置为止之前所有数字的和),这个结果对于正整数数组是单调递增的。每当需要采样时,我们可以先随机产生一个数字,然后使用二分法查找其在前缀和中的位置,以模拟加权采样的过程。这里的二分法可以用 lower_bound 实现。 + +以样例为例,权重数组 [1,3] 的前缀和为 [1,4]。如果我们随机生成的数字为 1,那么 lower_bound 返回的位置为 0;如果我们随机生成的数字是 2、3、4,那么 lower_bound 返回的位置为 1。 + +关于前缀和的更多技巧,我们将在接下来的章节中继续深入讲解。 + + + + +```cpp +class Solution { + public: + Solution(vector weights) : cumsum_(weights) { + partial_sum(cumsum_.begin(), cumsum_.end(), cumsum_.begin()); + } + + int pickIndex() { + int val = (rand() % cumsum_.back()) + 1; + return lower_bound(cumsum_.begin(), cumsum_.end(), val) - + cumsum_.begin(); + } + + private: + vector cumsum_; +}; +``` + + + + +```py +class Solution: + def __init__(self, weights: List[int]): + self.cumsum = weights[:] + for i in range(1, len(weights)): + self.cumsum[i] += self.cumsum[i - 1] + + def pickIndex(self) -> int: + val = random.randint(1, self.cumsum[-1]) + return bisect.bisect_left(self.cumsum, val, 0, len(self.cumsum)) +``` + + + + + +## [382. Linked List Random Node](https://leetcode.com/problems/linked-list-random-node/) + +### Problem Description + +给定一个单向链表,要求设计一个算法,可以随机取得其中的一个数字。 + +### Input and Output Example + +输入是一个单向链表,输出是一个数字,表示链表里其中一个节点的值。 + +``` +Input: 1->2->3->4->5 +Output: 3 +``` + +在这个样例中,我们有均等的概率得到任意一个节点,比如 3。 + +### Solution Explanation + +不同于数组,在未遍历完链表前,我们无法知道链表的总长度。这里我们就可以使用水库采样:遍历一次链表,在遍历到第 m 个节点时,有 $\frac{1}{m}$ 的概率选择这个节点覆盖掉之前的节点选择。 + +我们提供一个简单的,对于水库算法随机性的证明。对于长度为 n 的链表的第 m 个节点,最后被采样的充要条件是它被选择,且之后的节点都没有被选择。这种情况发生的概率为 $\frac{1}{m} × \frac{m}{m+1} × \frac{m}{m+2} × · · · × \frac{n−1}{n} = \frac{1}{n}$。因此每个点都有均等的概率被选择。 + +当然,这道题我们也可以预处理链表,遍历一遍之后把它转化成数组。 + + + + +```cpp +class Solution { + public: + Solution(ListNode* node) : head_(node) {} + + int getRandom() { + int pick = head_->val; + ListNode* node = head_->next; + int i = 2; + while (node) { + if (rand() % i == 0) { + pick = node->val; + } + ++i; + node = node->next; + } + return pick; + } + + private: + ListNode* head_; +}; +``` + + + + +```py +class Solution: + def __init__(self, head: Optional[ListNode]): + self.head = head + + def getRandom(self) -> int: + pick = self.head.val + node = self.head.next + i = 2 + while node is not None: + if random.randint(0, i - 1) == 0: + pick = node.val + i += 1 + node = node.next + return pick +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-6-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-6-exercises.md new file mode 100644 index 00000000..1d7ac01a --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-6-exercises.md @@ -0,0 +1,37 @@ +--- +sidebar_position: 43 +--- + +# 8.6 Exercises + +## Basic Difficulty + +### [168. Excel Sheet Column Title](https://leetcode.com/problems/excel-sheet-column-title/) + +7 进制转换的变种题,需要注意的一点是从 1 开始而不是 0。 + +### [67. Add Binary](https://leetcode.com/problems/add-binary/) + +字符串加法的变种题。 + +### [238. Product of Array Except Self](https://leetcode.com/problems/product-of-array-except-self/) + +你可以不使用除法做这道题吗?我们很早之前讲过的题目 135 或许能给你一些思路。 + +## Advanced Difficulty + +### [462. Minimum Moves to Equal Array Elements II](https://leetcode.com/problems/minimum-moves-to-equal-array-elements-ii/) + +这道题是笔者最喜欢的 LeetCode 题目之一,需要先推理出怎么样移动是最优的,再考虑如何进行移动。你或许需要一些前些章节讲过的算法。 + +### [169. Majority Element](https://leetcode.com/problems/majority-element/) + +如果想不出简单的解决方法,搜索一下 Boyer-Moore Majority Vote 算法吧。 + +### [470. Implement Rand10() Using Rand7()](https://leetcode.com/problems/implement-rand10-using-rand7/) + +如何用一个随机数生成器生成另一个随机数生成器?你可能需要利用原来的生成器多次。 + +### [202. Happy Number](https://leetcode.com/problems/happy-number/) + +你可以简单的用一个 while 循环解决这道题,但是有没有更好的解决办法?如果我们把每个数字想象成一个节点,是否可以转化为环路检测? \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/_category_.json new file mode 100644 index 00000000..5fb8df9e --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "8. 巧解数学问题 ", + "position": 8, + "link": { + "type": "generated-index", + "description": "第 8 章 巧解数学问题" + } +} diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-1-common-techniques.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-1-common-techniques.md new file mode 100644 index 00000000..30f955ca --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-1-common-techniques.md @@ -0,0 +1,24 @@ +--- +sidebar_position: 44 +--- + +# 9.1 常用技巧 + +`位运算`是算法题里比较特殊的一种类型,它们利用二进制位运算的特性进行一些奇妙的优化和计算。常用的位运算符号包括: + +- `∧`:按位异或 +- `&`:按位与 +- `|`:按位或 +- `~`:取反 +- `<<`:算术左移 +- `>>`:算术右移 + +以下是一些常见的位运算特性,其中 `0s` 和 `1s` 分别表示只由 `0` 或 `1` 构成的二进制数字。 + +``` +x ^ 0s = x x & 0s = 0 x | 0s = x +x ^ 1s = ~x x & 1s = x x | 1s = 1s +x ^ x = 0 x & x = x x | x = x +``` + +除此之外,n & (n - 1) 可以去除 n 的位级表示中最低的那一位,例如对于二进制表示 11110100,减去 1 得到 11110011,这两个数按位与得到 11110000。n & (-n) 可以得到 n 的位级表示中最低的那一位,例如对于二进制表示 11110100,取负得到 00001100,这两个数按位与得到 00000100。还有更多的并不常用的技巧,若读者感兴趣可以自行研究,这里不再赘述。 \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-2-basic-bitwise-problems.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-2-basic-bitwise-problems.mdx new file mode 100644 index 00000000..3cf64a91 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-2-basic-bitwise-problems.mdx @@ -0,0 +1,181 @@ +--- +sidebar_position: 45 +--- + +# 9.2 位运算基础问题 + +## [461. Hamming Distance](https://leetcode.com/problems/hamming-distance/) + +### Problem Description + +给定两个十进制数字,求它们二进制表示的汉明距离(Hamming distance,即不同位的个数)。 + +### Input and Output Example + +输入是两个十进制整数,输出是一个十进制整数,表示两个输入数字的汉明距离。 + +``` +Input: x = 1, y = 4 +Output: 2 +``` + +在这个样例中,1 的二进制是 0001,4 的二进制是 0100,一共有两位不同。 + +### Solution Explanation + +对两个数进行按位异或操作,统计有多少个 1 即可。 + + + + +```cpp +int hammingDistance(int x, int y) { + int diff = x ^ y, dist = 0; + while (diff != 0) { + dist += diff & 1; + diff >>= 1; + } + return dist; +} +``` + + + + +```py +def hammingDistance(x: int, y: int) -> int: + diff = x ^ y + dist = 0 + while diff != 0: + dist += diff & 1 + diff = diff >> 1 + return dist +``` + + + + + +## [190. Reverse Bits](https://leetcode.com/problems/reverse-bits/) + +### Problem Description + +给定一个十进制正整数,输出它在二进制下的翻转结果。 + +### Input and Output Example + +输入和输出都是十进制正整数。 + +``` +Input: 43261596 (00000010100101000001111010011100) +Output: 964176192 (00111001011110000010100101000000) +``` + +使用算术左移和右移,可以很轻易地实现二进制的翻转。 + +### Solution Explanation + + + + + + +```cpp +uint32_t reverseBits(uint32_t n) { + uint32_t m = 0; + for (int i = 0; i < 32; ++i) { + m <<= 1; + m += n & 1; + n >>= 1; + } + return m; +} +``` + + + + +```py +def reverseBits(n: int) -> int: + m = 0 + for _ in range(32): + m = m << 1 + m += n & 1 + n = n >> 1 + return m +``` + + + + + +## [136. Single Number](https://leetcode.com/problems/single-number/) + +### Problem Description + +给定一个整数数组,这个数组里只有一个数次出现了一次,其余数字出现了两次,求这个只出现一次的数字。 + +### Input and Output Example + +输入是一个一维整数数组,输出是该数组内的一个整数。 + +``` +Input: [4,1,2,1,2] +Output: 4 +``` + +### Solution Explanation + +我们可以利用 x ∧ x = 0 和 x ∧ 0 = x 的特点,将数组内所有的数字进行按位异或。出现两次的所有数字按位异或的结果是 0,0 与出现一次的数字异或可以得到这个数字本身。 + + + + +```cpp +int singleNumber(vector& nums) { + int single = 0; + for (int num : nums) { + single ^= num; + } + return single; +} +``` + + + + +```py +def singleNumber(nums: List[int]) -> int: + single = 0 + for num in nums: + single = single ^ num + return single +``` + + + + + +这里我们也可以直接使用 reduce 函数: + + + + +```cpp +int singleNumber(vector& nums) { + return reduce(nums.begin(), nums.end(), 0, + [](int x, int y) { return x ^ y; }); +} +``` + + + + +```py +def singleNumber(nums: List[int]) -> int: + return functools.reduce(lambda x, y: x ^ y, nums) +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-3-binary-properties.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-3-binary-properties.mdx new file mode 100644 index 00000000..773acd9d --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-3-binary-properties.mdx @@ -0,0 +1,123 @@ +--- +sidebar_position: 46 +--- + +# 9.3 二进制特性 + +利用二进制的一些特性,我们可以把位运算使用到更多问题上。 + +例如,我们可以利用二进制和位运算输出一个数组的所有子集。假设我们有一个长度为 $n$ 的数组,我们可以生成长度为 $n$ 的所有二进制,1 表示选取该数字,0 表示不选取。这样我们就获得了 $2^n$ 个子集。 + +## [318. Maximum Product of Word Lengths](https://leetcode.com/problems/maximum-product-of-word-lengths/) + +### Problem Description + +给定多个字母串,求其中任意两个字母串的长度乘积的最大值,且这两个字母串不能含有相同字母。 + +### Input and Output Example + +输入一个包含多个字母串的一维数组,输出一个整数,表示长度乘积的最大值。 + +``` +Input: ["a","ab","abc","d","cd","bcd","abcd"] +Output: 4 +``` + +在这个样例中,一种最优的选择是“ab”和“cd”。 + +### Solution Explanation + +怎样快速判断两个字母串是否含有重复数字呢?可以为每个字母串建立一个长度为 26 的二进制数字,每个位置表示是否存在该字母。如果两个字母串含有重复数字,那它们的二进制表示的按位与不为 0。同时,我们可以建立一个哈希表来存储二进制数字到最长子母串长度的映射关系,比如 ab 和 aab 的二进制数字相同,但是 aab 更长。 + + + + +```cpp +int maxProduct(vector& words) { + unordered_map cache; + int max_prod = 0; + for (const string& word : words) { + int mask = 0, w_len = word.length(); + for (char c : word) { + mask |= 1 << (c - ’a’); + } + cache[mask] = max(cache[mask], w_len); + for (auto [h_mask, h_len] : cache) { + if ((mask & h_mask) == 0) { + max_prod = max(max_prod, w_len * h_len); + } + } + } + return max_prod; +} +``` + + + + +```py +def maxProduct(words: List[str]) -> int: + cache = dict() + max_prod = 0 + for word in words: + mask, w_len = 0, len(word) + for c in word: + mask = mask | (1 << (ord(c) - ord("a"))) + cache[mask] = max(cache.get(mask, 0), w_len) + for h_mask, h_len in cache.items(): + if (mask & h_mask) == 0: + max_prod = max(max_prod, w_len * h_len) + return max_prod +``` + + + + + +## [338. Counting Bits](https://leetcode.com/problems/counting-bits/) + +### Problem Description + +给定一个非负整数 n,求从 0 到 n 的所有数字的二进制表达中,分别有多少个 1。 + +### Input and Output Example + +输入是一个非负整数 n,输出是长度为 n +1 的非负整数数组,每个位置 m 表示 m 的二进制里有多少个 1。 + +``` +Input: 5 +Output: [0,1,1,2,1,2] +``` + +### Solution Explanation + +本题可以利用动态规划和位运算进行快速的求解。定义一个数组 dp,其中 dp[i] 表示数字 i 的二进制含有 1 的个数。对于第 i 个数字,如果它二进制的最后一位为 1,那么它含有 1 的个数则为 dp[i-1] + 1;如果它二进制的最后一位为 0,那么它含有 1 的个数和其算术右移结果相同,即 dp[i>>1]。 + + + + +```cpp +vector countBits(int n) { + vector dp(n + 1, 0); + for (int i = 1; i <= n; ++i) + // 等价于:dp[i] = dp[i & (i - 1)] + 1; + dp[i] = i & 1 ? dp[i - 1] + 1 : dp[i >> 1]; + return dp; +} +``` + + + + +```py +def countBits(n: int) -> List[int]: + dp = [0] * (n + 1) + for i in range(1, n + 1): + # 等价于:dp[i] = dp[i & (i - 1)] + 1 + dp[i] = dp[i - 1] + 1 if i & 1 else dp[i >> 1] + return dp +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-4-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-4-exercises.md new file mode 100644 index 00000000..9d4dd835 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-4-exercises.md @@ -0,0 +1,25 @@ +--- +sidebar_position: 47 +--- + +# 9.4 Exercises + +## Basic Difficulty + +### [268. Missing Number](https://leetcode.com/problems/missing-number/) + +Single Number 的变种题。除了利用二进制,也可以使用高斯求和公式。 + +### [693. Binary Number with Alternating Bits](https://leetcode.com/problems/binary-number-with-alternating-bits/) + +利用位运算判断一个数的二进制是否会出现连续的 0 和 1。 + +### [476. Number Complement](https://leetcode.com/problems/number-complement/) + +二进制翻转的变种题。 + +## Advanced Difficulty + +### [260. Single Number III](https://leetcode.com/problems/single-number-iii/) + +Single Number 的 follow-up,需要认真思考如何运用位运算求解。 \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/_category_.json new file mode 100644 index 00000000..dc298905 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "9. 神奇的位运算 ", + "position": 9, + "link": { + "type": "generated-index", + "description": "第 9 章 神奇的位运算" + } +} diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/index.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/index.md deleted file mode 100644 index e019d6cd..00000000 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/index.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 0 ---- - -# preface - -english preface diff --git a/leetcode_101/i18n/en/docusaurus-theme-classic/footer.json b/leetcode_101/i18n/en/docusaurus-theme-classic/footer.json index b753f2a6..7a748fc1 100644 --- a/leetcode_101/i18n/en/docusaurus-theme-classic/footer.json +++ b/leetcode_101/i18n/en/docusaurus-theme-classic/footer.json @@ -1,40 +1,4 @@ { - "link.title.Docs": { - "message": "Docs", - "description": "The title of the footer links column with title=Docs in the footer" - }, - "link.title.Community": { - "message": "Community", - "description": "The title of the footer links column with title=Community in the footer" - }, - "link.title.More": { - "message": "More", - "description": "The title of the footer links column with title=More in the footer" - }, - "link.item.label.Tutorial": { - "message": "Tutorial", - "description": "The label of footer link with label=Tutorial linking to /docs/intro" - }, - "link.item.label.Stack Overflow": { - "message": "Stack Overflow", - "description": "The label of footer link with label=Stack Overflow linking to https://stackoverflow.com/questions/tagged/docusaurus" - }, - "link.item.label.Discord": { - "message": "Discord", - "description": "The label of footer link with label=Discord linking to https://discordapp.com/invite/docusaurus" - }, - "link.item.label.X": { - "message": "X", - "description": "The label of footer link with label=X linking to https://x.com/docusaurus" - }, - "link.item.label.Blog": { - "message": "Blog", - "description": "The label of footer link with label=Blog linking to /blog" - }, - "link.item.label.GitHub": { - "message": "GitHub", - "description": "The label of footer link with label=GitHub linking to https://github.com/facebook/docusaurus" - }, "copyright": { "message": "Copyright © 2024 My Project, Inc. Built with Docusaurus.", "description": "The footer copyright" diff --git a/leetcode_101/i18n/zh-TW/code.json b/leetcode_101/i18n/zh-TW/code.json index 87ac7e0d..a1fe4ce6 100644 --- a/leetcode_101/i18n/zh-TW/code.json +++ b/leetcode_101/i18n/zh-TW/code.json @@ -134,10 +134,6 @@ "message": "標籤:", "description": "The label alongside a tag list" }, - "theme.AnnouncementBar.closeButtonAriaLabel": { - "message": "關閉", - "description": "The ARIA label for close button of announcement bar" - }, "theme.admonition.caution": { "message": "警告", "description": "The default label used for the Caution admonition (:::caution)" @@ -162,6 +158,10 @@ "message": "注意", "description": "The default label used for the Warning admonition (:::warning)" }, + "theme.AnnouncementBar.closeButtonAriaLabel": { + "message": "關閉", + "description": "The ARIA label for close button of announcement bar" + }, "theme.blog.sidebar.navAriaLabel": { "message": "最近部落格文章導覽", "description": "The ARIA label for recent posts in the blog sidebar" @@ -194,10 +194,6 @@ "message": "主導航", "description": "The ARIA label for the main navigation" }, - "theme.navbar.mobileLanguageDropdown.label": { - "message": "選擇語言", - "description": "The label for the mobile language switcher dropdown" - }, "theme.NotFound.p1": { "message": "我們沒有您要找的頁面。", "description": "The first paragraph of the 404 page" @@ -206,6 +202,10 @@ "message": "請聯絡原始連結來源網站的所有者,並通知他們連結已毀損。", "description": "The 2nd paragraph of the 404 page" }, + "theme.navbar.mobileLanguageDropdown.label": { + "message": "選擇語言", + "description": "The label for the mobile language switcher dropdown" + }, "theme.TOCCollapsible.toggleButtonLabel": { "message": "本頁導覽", "description": "The label used by the button on the collapsible TOC component" diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current.json index 4eca2e3e..f086ff67 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current.json +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current.json @@ -1,34 +1,126 @@ { "version.label": { "message": "Next", - "description": "The label for version current" + "description": "當前版本的標籤" }, "sidebar.tutorialSidebar.category.1. 最易懂的贪心算法": { - "message": "1. 最易懂的貪心算法", - "description": "The label for category 1. 最易懂的贪心算法 in sidebar tutorialSidebar" + "message": "1. 最易懂的貪心演算法", + "description": "The label for category 1. 最易懂的貪心演算法 in sidebar tutorialSidebar" }, "sidebar.tutorialSidebar.category.1. 最易懂的贪心算法.link.generated-index.description": { - "message": "5 minutes to learn the most important Docusaurus concepts.", - "description": "The generated-index page description for category 1. 最易懂的贪心算法 in sidebar tutorialSidebar" + "message": "第 1 章 最易懂的貪心演算法", + "description": "The generated-index page description for category 1. 最易懂的貪心演算法 in sidebar tutorialSidebar" }, "sidebar.tutorialSidebar.category.2. 玩转双指针": { - "message": "2. 玩转双指针", - "description": "The label for category 2. 玩转双指针 in sidebar tutorialSidebar" + "message": "2. 玩轉雙指標", + "description": "The label for category 2. 玩轉雙指標 in sidebar tutorialSidebar" }, "sidebar.tutorialSidebar.category.2. 玩转双指针.link.generated-index.description": { - "message": "5 minutes to learn the most important Docusaurus concepts.", - "description": "The generated-index page description for category 2. 玩转双指针 in sidebar tutorialSidebar" + "message": "第 2 章 玩轉雙指標", + "description": "The generated-index page description for category 2. 玩轉雙指標 in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.Tutorial - Basics": { - "message": "Tutorial - Basics", - "description": "The label for category Tutorial - Basics in sidebar tutorialSidebar" + "sidebar.tutorialSidebar.category.3. 居合斩!二分查找": { + "message": "3. 居合斬!二分搜尋", + "description": "The label for category 3. 居合斬!二分搜尋 in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.Tutorial - Basics.link.generated-index.description": { - "message": "5 minutes to learn the most important Docusaurus concepts.", - "description": "The generated-index page description for category Tutorial - Basics in sidebar tutorialSidebar" + "sidebar.tutorialSidebar.category.3. 居合斩!二分查找.link.generated-index.description": { + "message": "第 3 章 居合斬!二分搜尋", + "description": "The generated-index page description for category 3. 居合斬!二分搜尋 in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.Tutorial - Extras": { - "message": "Tutorial - Extras", - "description": "The label for category Tutorial - Extras in sidebar tutorialSidebar" + "sidebar.tutorialSidebar.category.4. 千奇百怪的排序算法": { + "message": "4. 千奇百怪的排序演算法", + "description": "The label for category 4. 千奇百怪的排序演算法 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.4. 千奇百怪的排序算法.link.generated-index.description": { + "message": "第 4 章 千奇百怪的排序演算法", + "description": "The generated-index page description for category 4. 千奇百怪的排序演算法 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.5. 一切皆可搜索": { + "message": "5. 一切皆可搜尋", + "description": "The label for category 5. 一切皆可搜尋 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.5. 一切皆可搜索.link.generated-index.description": { + "message": "第 5 章 一切皆可搜尋", + "description": "The generated-index page description for category 5. 一切皆可搜尋 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.6. 深入浅出动态规划": { + "message": "6. 深入淺出的動態規劃", + "description": "The label for category 6. 深入淺出的動態規劃 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.6. 深入浅出动态规划.link.generated-index.description": { + "message": "第 6 章 深入淺出的動態規劃", + "description": "The generated-index page description for category 6. 深入淺出的動態規劃 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.7. 化繁为简的分治法": { + "message": "7. 化繁為簡的分治法", + "description": "The label for category 7. 化繁為簡的分治法 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.7. 化繁为简的分治法.link.generated-index.description": { + "message": "第 7 章 化繁為簡的分治法", + "description": "The generated-index page description for category 7. 化繁為簡的分治法 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.8. 巧解数学问题 ": { + "message": "8. 巧解數學問題", + "description": "The label for category 8. 巧解數學問題 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.8. 巧解数学问题 .link.generated-index.description": { + "message": "第 8 章 巧解數學問題", + "description": "The generated-index page description for category 8. 巧解數學問題 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.9. 神奇的位运算 ": { + "message": "9. 神奇的位元運算", + "description": "The label for category 9. 神奇的位元運算 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.9. 神奇的位运算 .link.generated-index.description": { + "message": "第 9 章 神奇的位元運算", + "description": "The generated-index page description for category 9. 神奇的位元運算 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.10. 妙用数据结构 ": { + "message": "10. 巧用資料結構", + "description": "The label for category 10. 巧用資料結構 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.10. 妙用数据结构 .link.generated-index.description": { + "message": "第 10 章 巧用資料結構", + "description": "The generated-index page description for category 10. 巧用資料結構 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.11. 令人头大的字符串 ": { + "message": "11. 頭痛的字串處理", + "description": "The label for category 11. 頭痛的字串處理 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.11. 令人头大的字符串 .link.generated-index.description": { + "message": "第 11 章 頭痛的字串處理", + "description": "The generated-index page description for category 11. 頭痛的字串處理 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.12. 指针三剑客之一:链表": { + "message": "12. 指標三劍客之一:鏈結串列", + "description": "The label for category 12. 指標三劍客之一:鏈結串列 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.12. 指针三剑客之一:链表.link.generated-index.description": { + "message": "第 12 章 指標三劍客之一:鏈結串列", + "description": "The generated-index page description for category 12. 指標三劍客之一:鏈結串列 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.13. 指针三剑客之二:树": { + "message": "13. 指標三劍客之二:樹", + "description": "The label for category 13. 指標三劍客之二:樹 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.13. 指针三剑客之二:树.link.generated-index.description": { + "message": "第 13 章 指標三劍客之二:樹", + "description": "The generated-index page description for category 13. 指標三劍客之二:樹 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.14. 指针三剑客之三:图": { + "message": "14. 指標三劍客之三:圖", + "description": "The label for category 14. 指標三劍客之三:圖 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.14. 指针三剑客之三:图.link.generated-index.description": { + "message": "第 14 章 指標三劍客之三:圖", + "description": "The generated-index page description for category 14. 指標三劍客之三:圖 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.15. 更加复杂的数据结构 ": { + "message": "15. 更加複雜的資料結構", + "description": "The label for category 15. 更加複雜的資料結構 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.15. 更加复杂的数据结构 .link.generated-index.description": { + "message": "第 15 章 更加複雜的資料結構", + "description": "The generated-index page description for category 15. 更加複雜的資料結構in sidebar tutorialSidebar" } } diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-1-algorithm-explanation.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-1-algorithm-explanation.md new file mode 100644 index 00000000..fed844c7 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-1-algorithm-explanation.md @@ -0,0 +1,11 @@ +--- +sidebar_position: 1 +--- + +# 1.1 算法解釋 + +顧名思義,`貪心算法或貪心思想`(greedy algorithm)採用貪心的策略,`保證每次操作都是局部最優的`,從而使最後得到的結果是`全局最優的`。 + +舉一個最簡單的例子:小明和小王喜歡吃蘋果,小明可以吃五個,小王可以吃三個。已知蘋果園裡有吃不完的蘋果,求小明和小王一共最多吃多少個蘋果。在這個例子中,我們可以選用的貪心策略為,每個人吃自己能吃的最多數量的蘋果,這在每個人身上都是局部最優的。又因為全局結果是局部結果的簡單求和,且局部結果互不相干,因此局部最優的策略同樣是全局最優的。 + +證明一道題能用貪心算法解決,有時遠比用貪心算法解決該題更複雜。一般情況下,在簡單操作後,具有明顯的從局部到整體的遞推關係,或者可以通過數學歸納法推測結果時,我們才會使用貪心算法。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-2-assignment-problems.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-2-assignment-problems.mdx new file mode 100644 index 00000000..23722515 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-2-assignment-problems.mdx @@ -0,0 +1,143 @@ +--- +sidebar_position: 2 +--- + +# 1.2 分配問題 + +## [455. Assign Cookies](https://leetcode.com/problems/assign-cookies/) + +### 題目描述 + +有一群孩子和一堆餅乾,每個孩子有一個飢餓度,每個餅乾都有一個飽腹度。每個孩子只能吃一個餅乾,且只有餅乾的飽腹度不小於孩子的飢餓度時,這個孩子才能吃飽。求解最多有多少孩子可以吃飽。 + +### 輸入輸出範例 + +輸入兩個數組,分別代表孩子的飢餓度和餅乾的飽腹度。輸出可以吃飽的孩子的最大數量。 + +``` +Input: [1,2], [1,2,3] +Output: 2 +``` + +在這個範例中,我們可以給兩個孩子餵 [1,2]、[1,3]、[2,3] 這三種組合的任意一種。 + +### 題解 + +因為飢餓度最小的孩子最容易吃飽,所以我們先考慮這個孩子。為了盡量使得剩下的餅乾可以滿足飢餓度更大的孩子,我們應該把大於等於這個孩子飢餓度的、且大小最小的餅乾給這個孩子。滿足了這個孩子之後,我們採取同樣的策略,考慮剩下孩子裡飢餓度最小的孩子,直到沒有滿足條件的餅乾存在。 + +簡而言之,這裡的貪心策略是,給剩餘孩子裡最小飢餓度的孩子分配最小的能飽腹的餅乾。至於具體實現,因為我們需要獲得大小關係,一個便捷的方法就是把孩子和餅乾分別排序。這樣我們就可以從飢餓度最小的孩子和飽腹度最小的餅乾出發,計算有多少個配對可以滿足條件。 + +:::warning + +對數組或字符串排序是常見的操作,方便之後的大小比較。排序順序默認是從小到大。 + +::: + +:::warning + +在之後的講解中,若我們談論的是對連續空間的變量進行操作,我們並不會明確區分數組和字符串,因為它們本質上都是在連續空間上的有序變量集合。一個字符串 "abc" 可以被看作一個數組 ['a', 'b', 'c']。 + +::: + + + + +```cpp +int findContentChildren(vector &children, vector &cookies) { + sort(children.begin(), children.end()); + sort(cookies.begin(), cookies.end()); + int child_i = 0, cookie_i = 0; + int n_children = children.size(), n_cookies = cookies.size(); + while (child_i < n_children && cookie_i < n_cookies) { + if (children[child_i] <= cookies[cookie_i]) { + ++child_i; + } + ++cookie_i; + } + return child_i; +} +``` + + + + +```py +def findContentChildren(children: List[int], cookies: List[int]) -> int: + children.sort() + cookies.sort() + child_i, cookie_i = 0, 0 + n_children, n_cookies = len(children), len(cookies) + while child_i < n_children and cookie_i < n_cookies: + if children[child_i] <= cookies[cookie_i]: + child_i += 1 + cookie_i += 1 + return child_i +``` + + + + + +## [135. Candy](https://leetcode.com/problems/candy/) + +### 題目描述 + +一群孩子站成一排,每一個孩子有自己的評分。現在需要給這些孩子發糖果,規則是如果一個孩子的評分比自己身旁的一個孩子要高,那麼這個孩子就必須得到比身旁孩子更多的糖果。所有孩子至少要有一個糖果。求解最少需要多少個糖果。 + +### 輸入輸出範例 + +輸入是一個數組,表示孩子的評分。輸出是最少糖果的數量。 + +``` +Input: [1,0,2] +Output: 5 +``` +在這個範例中,最少的糖果分配方式是 [2,1,2]。 + + +### 題解 + +存在比較關係的貪心策略並不一定需要排序。雖然這一道題也是運用貪心策略,但我們只需要簡單的兩次遍歷即可:把所有孩子的糖果數初始化為 1;先從左往右遍歷一遍,如果右邊孩子的評分比左邊的高,則右邊孩子的糖果數更新為左邊孩子的糖果數加 1;再從右往左遍歷一遍,如果左邊孩子的評分比右邊的高,且左邊孩子當前的糖果數不大於右邊孩子的糖果數,則左邊孩子的糖果數更新為右邊孩子的糖果數加 1。通過這兩次遍歷,分配的糖果就可以滿足題目要求了。這裡的貪心策略即為,在每次遍歷中,只考慮並更新相鄰一側的大小關係。 + +在範例中,我們初始化糖果分配為 [1,1,1],第一次遍歷更新後的結果為 [1,1,2],第二次遍歷更新後的結果為 [2,1,2]。 + + + + +```cpp +int candy(vector& ratings) { + int n = ratings.size(); + vector candies(n, 1); + for (int i = 1; i < n; ++i) { + if (ratings[i] > ratings[i - 1]) { + candies[i] = candies[i - 1] + 1; + } + } + for (int i = n - 1; i > 0; --i) { + if (ratings[i] < ratings[i - 1]) { + candies[i - 1] = max(candies[i - 1], candies[i] + 1); + } + } + return accumulate(candies.begin(), candies.end(), 0); +} +``` + + + + +```py +def candy(ratings_list: List[int]) -> int: + n = len(ratings_list) + candies = [1] * n + for i in range(1, n): + if ratings_list[i] > ratings_list[i - 1]: + candies[i] = candies[i - 1] + 1 + for i in range(n - 1, 0, -1): + if ratings_list[i] < ratings_list[i - 1]: + candies[i - 1] = max(candies[i - 1], candies[i] + 1) + return sum(candies) +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-3-interval-problems.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-3-interval-problems.mdx new file mode 100644 index 00000000..6c0587f2 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-3-interval-problems.mdx @@ -0,0 +1,75 @@ +--- +sidebar_position: 3 +--- + +# 1.3 區間問題 + +## [435. Non-overlapping Intervals](https://leetcode.com/problems/non-overlapping-intervals/) + +### 題目描述 + +給定多個區間,計算讓這些區間互不重疊所需要移除的最少區間數量。起止相連的區間不算重疊。 + +### 輸入輸出範例 + +輸入是一個數組,包含多個長度固定為 2 的子數組,表示每個區間的開始和結束。輸出是一個整數,表示需要移除的區間數量。 + + +``` +Input: [[1,2], [2,4], [1,3]] +Output: 1 +``` +在這個範例中,我們可以移除區間 [1,3],使得剩餘的區間 [[1,2], [2,4]] 互不重疊。 + + +### 題解 + +求最少移除的區間數量等同於盡量多保留不重疊的區間。在選擇要保留的區間時,區間的結尾非常重要:選擇的區間結尾越小,留給其他區間的空間就越大,這樣就能保留更多的區間。因此,我們的貪心策略是優先保留結尾小且不相交的區間。 + +具體實現方法為,先把區間按照結尾的大小進行增序排序(利用 lambda 函數),每次選擇結尾最小且與前一個選擇的區間不重疊的區間。 + +在範例中,排序後的數組為 [[1,2], [1,3], [2,4]]。按照我們的貪心策略,首先初始化為區間 [1,2];由於 [1,3] 與 [1,2] 相交,我們跳過該區間;由於 [2,4] 與 [1,2] 不相交,我們將其保留。因此,最終保留的區間為 [[1,2], [2,4]]。 + +:::warning + +需要根據實際情況判斷按區間開頭排序還是按區間結尾排序。 + +::: + + + + +```cpp +int eraseOverlapIntervals(vector>& intervals) { + sort(intervals.begin(), intervals.end(), + [](vector& a, vector& b) { return a[1] < b[1]; }); + int removed = 0, prev_end = intervals[0][1]; + for (int i = 1; i < intervals.size(); ++i) { + if (intervals[i][0] < prev_end) { + ++removed; + } else { + prev_end = intervals[i][1]; + } + } + return removed; +} +``` + + + + +```py +def eraseOverlapIntervals(intervals: List[List[int]]) -> int: + intervals.sort(key=lambda x: x[1]) + removed, prev_end = 0, intervals[0][1] + for i in range(1, len(intervals)): + if prev_end > intervals[i][0]: + removed += 1 + else: + prev_end = intervals[i][1] + return removed +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-4-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-4-exercises.md new file mode 100644 index 00000000..569182af --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-4-exercises.md @@ -0,0 +1,40 @@ +--- +sidebar_position: 4 +--- + +# 1.4 練習 + +## 基礎難度 + +### [605. Can Place Flowers](https://leetcode.com/problems/can-place-flowers/) + +採取什麼樣的貪心策略,可以種植最多的花朵呢? + +### [452. Minimum Number of Arrows to Burst Balloons](https://leetcode.com/problems/minimum-number-of-arrows-to-burst-balloons/) + +這道題和題目 435 十分類似,但是稍有不同,具體是哪里不同呢? + +### [763. Partition Labels](https://leetcode.com/problems/partition-labels/) + +為了滿足你的貪心策略,是否需要一些預處理? + +:::warning + +在處理數組前,統計一遍信息(如頻率、個數、第一次出現位置、最後一次出現位置等)可以使題目難度大幅降低。 + +::: + +### [122. Best Time to Buy and Sell Stock II](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/) + +股票交易題型裡比較簡單的題目,在不限制交易次數的情況下,怎樣可以獲得最大利潤呢? + +## 進階難度 + +### [406. Queue Reconstruction by Height](https://leetcode.com/problems/queue-reconstruction-by-height/) + +溫馨提示,這道題可能同時需要排序和插入操作。 + + +### [665. Non-decreasing Array](https://leetcode.com/problems/non-decreasing-array/) + +需要仔細思考你的貪心策略在各種情況下,是否仍然是最優解。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/_category_.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/_category_.json index e91e9e1e..4119cb25 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/_category_.json +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/_category_.json @@ -3,6 +3,6 @@ "position": 1, "link": { "type": "generated-index", - "description": "5 minutes to learn the most important Docusaurus concepts." + "description": "第 1 章 最易懂的贪心算法" } } diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/greddy.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/greddy.md deleted file mode 100644 index ee4a0092..00000000 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/greddy.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 6 ---- - -# 贪心! - -繁體中文版貪心 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-1-cpp-stl.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-1-cpp-stl.md new file mode 100644 index 00000000..2ec42832 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-1-cpp-stl.md @@ -0,0 +1,30 @@ +--- +sidebar_position: 48 +--- + +# 10.1 C++ STL + +在刷题时,我们几乎一定会用到各种数据结构来辅助我们解决问题,因此我们必须熟悉各种数据结构的特点。C++ STL 提供的数据结构包括(实际底层细节可能因编译器而异): + +1. Sequence Containers:维持顺序的容器。 + 1. vector:`动态数组`,是我们最常使用的数据结构之一,用于 $O(1)$ 的随机读取。因为大部分算法的时间复杂度都会大于 $O(n)$,因此我们经常新建 vector 来存储各种数据或中间变量。因为在尾部增删的复杂度是 $O(1)$,我们也可以把它当作 stack 来用。 + 2. list:`双向链表`,也可以当作 stack 和 queue 来使用。由于 LeetCode 的题目多用 Node 来表示链表,且链表不支持快速随机读取,因此我们很少用到这个数据结构。一个例外是经典的 LRU 问题,我们需要利用链表的特性来解决,我们在后文会遇到这个问题。 + 3. deque:双端队列,这是一个非常强大的数据结构,既支持 $O(1)$ 随机读取,又支持 $O(1)$ 时间的头部增删和尾部增删(因此可以当作 stack 和 queue 来使用),不过有一定的额外开销。也可以用来近似一个双向链表来使用。 + 4. array:固定大小的数组,一般在刷题时我们不使用。 + 5. forward_list:单向链表,一般在刷题时我们不使用。 +2. Container Adaptors:基于其它容器实现的容器。 + 1. stack:`后入先出(LIFO)的数据结构`,默认基于 deque 实现。stack 常用于深度优先搜索、一些字符串匹配问题以及单调栈问题。 + 2. `先入先出(FIFO)的数据结构`,默认基于 deque 实现。queue 常用于广度优先搜索。 + 3. priority_queue:`优先队列(最大值先出的数据结构)`,默认基于 vector 实现堆结构。它可以在 $O(n \log n)$ 的时间排序数组,$O(\log n)$ 的时间插入任意值,$O(1)$ 的时间获得最大值,$O(\log n)$ 的时间删除最大值。priority_queue 常用于维护数据结构并快速获取最大值,并且可以自定义比较函数;比如通过存储负值或者更改比小函数为比大函数,即可实现最小值先出。 +3. Ordered Associative Containers:有序关联容器。 + 1. set:有序集合,元素不可重复,底层实现默认为红黑树,即一种特殊的二叉查找树(BST)。它可以在 $O(n \log n)$ 的时间排序数组,$O(\log n)$ 的时间插入、删除、查找任意值,$O(\log n)$ 的时间获得最小或最大值。这里注意,set 和 priority_queue 都可以用于维护数据结构并快速获取最大最小值,但是它们的时间复杂度和功能略有区别,如 priority_queue 默认不支持删除任意值,而 set 获得最大或最小值的时间复杂度略高,具体使用哪个根据需求而定。 + 2. multiset:支持重复元素的 set。 + 3. map:`有序映射或有序表`,在 set 的基础上加上映射关系,可以对每个元素 key 存一个值 value。 + 4. multimap:支持重复元素的 map。 +4. Unordered Associative Containers:无序关联容器。 + 1. unordered_set:`哈希集合`,可以在 $O(1)$ 的时间快速插入、查找、删除元素,常用于快速的查询一个元素是否在这个容器内。 + 2. unordered_multiset:支持重复元素的 unordered_set。 + 3. unordered_map:`哈希映射或哈希表`,在 unordered_set 的基础上加上映射关系,可以对每一个元素 key 存一个值 value。在某些情况下,如果 key 的范围已知且较小,我们也可以用 vector 代替 unordered_map,用位置表示 key,用每个位置的值表示 value。 + 4. unordered_multimap:支持重复元素的 unordered_map。 + +因为这并不是一本讲解 C++ 原理的书,更多的 STL 细节请读者自行搜索。只有理解了这些数据结构的原理和使用方法,才能够更加游刃有余地解决算法和数据结构问题。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-10-prefix-sum-integral-image.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-10-prefix-sum-integral-image.mdx new file mode 100644 index 00000000..8878d9c8 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-10-prefix-sum-integral-image.mdx @@ -0,0 +1,226 @@ +--- +sidebar_position: 57 +--- + +# 10.10 前缀和与积分图 + +一维的前缀和(cumulative sum, cumsum),二维的积分图(summed-area table, image integral)都是把每个位置之前的一维线段或二维矩形预先存储,方便加速计算。如果需要对前缀和或积分图的值做寻址,则要存入哈希表;如果要对每个位置记录前缀和或积分图的值,则可以储存到一维或二维数组里,也常常伴随着动态规划。 + +## [303. Range Sum Query - Immutable](https://leetcode.com/problems/range-sum-query-immutable/) + +### 題目描述 + +设计一个数据结构,使得其能够快速查询给定数组中,任意两个位置间所有数字的和。 + +### 輸入輸出範例 + +以下是数据结构的调用样例。 + +``` +vector nums{-2,0,3,-5,2,-1}; +NumArray num_array = new NumArray(nums); +num_array.sumRange(0,2); // Result = -2+0+3 = 1. +num_array.sunRange(1,5); // Result = 0+3-5+2-1 = -1. +``` + +### 題解 + +对于一维的数组,我们可以使用前缀和来解决此类问题。先建立一个与数组 nums 长度相同的新数组 cumsum,表示 nums 每个位置之前前所有数字的和。cumsum 数组可以通过 C++ 自带的 partial_sum 函数建立,也可以直接遍历一遍 nums 数组,并利用状态转移方程 cumsum[i] = cumsum[i-1] + nums[i] 完成统计。如果我们需要获得位置 i 和 j 之间的数字和,只需计算 cum - sum[j+1] - cumsum[i] 即可。 + + + + +```cpp +class NumArray { + public: + NumArray(vector nums) : cumsum_(nums.size() + 1, 0) { + partial_sum(nums.begin(), nums.end(), cumsum_.begin() + 1); + } + + int sumRange(int left, int right) { + return cumsum_[right + 1] - cumsum_[left]; + } + + private: + vector cumsum_; +}; +``` + + + + +```py +class NumArray: + def __init__(self, nums: List[int]): + self.cumsum = [0] + nums[:] + for i in range(2, len(self.cumsum)): + self.cumsum[i] += self.cumsum[i - 1] + + def sumRange(self, left: int, right: int) -> int: + return self.cumsum[right + 1] - self.cumsum[left] +``` + + + + + +## [304. Range Sum Query 2D - Immutable](https://leetcode.com/problems/range-sum-query-2d-immutable/) + +### 題目描述 + +设计一个数据结构,使得其能够快速查询给定矩阵中,任意两个位置包围的长方形中所有数字的和。 + +### 輸入輸出範例 + +以下是数据结构的调用样例。其中 sumRegion 函数的四个输入分别是第一个点的横、纵坐标,和第二个点的横、纵坐标。 + +``` +vector matrix{{3,0,1,4,2}, + {5,6,3,2,1}, + {1,2,0,1,5}, + {4,1,0,1,7}, + {1,0,3,0,5} +}; +NumMatrix num_matrix = new NumMatrix(matrix); +num_matrix.sumRegion(2,1,4,3); // Result = 8. +num_matrix.sumRegion(1,1,2,2); // Result = 11. +``` + +### 題解 + +类似于前缀和,我们可以把这种思想拓展到二维,即积分图(summed-area table, image integral)。我们可以先建立一个 sat 矩阵,sat[i][j] 表示以位置 (0, 0) 为左上角、位置 (i-1, j-1) 为右下角的长方形中所有数字的和。 + +
      + + ![](10.4.png) + +
      图 10.4: 题目 304 - 图 1 - 左边为给定矩阵,右边为积分图结果,右下角位置的积分图值为 5+48+45− 40 =58
      +
      + + +
      + + ![](10.5.png) + +
      图 10.5: 题目 304 - 图 2 - 左边为给定矩阵,右边为积分图结果,长方形 E 的数字和等于 58 − 11 − 13 +3 =37
      +
      + +如图 1 所示,我们可以用动态规划来计算 sat 矩阵:sat[i][j] = matrix[i-1][j-1] + sat[i-1][j] + sat[i][j-1] - sat[i-1][j-1],即当前坐标的数字 + 上面长方形的数字和 + 左边长方形的数字和 - 上面长方形和左边长方形重合面积(即左上一格的长方形)中的数字和。 + +如图 2 所示,假设我们要查询长方形 E 的数字和,因为 E = D − B − C + A,我们发现 E 其实可以由四个位置的积分图结果进行加减运算得到。因此这个算法在预处理时的时间复杂度为 $O(mn)$,而在查询时的时间复杂度仅为 $O(1)$。 + + + + +```cpp +class NumMatrix { + public: + NumMatrix(vector> matrix) { + int m = matrix.size(), n = matrix[0].size(); + sat_ = vector>(m + 1, vector(n + 1, 0)); + for (int i = 1; i <= m; ++i) { + for (int j = 1; j <= n; ++j) { + sat_[i][j] = matrix[i - 1][j - 1] + sat_[i - 1][j] + + sat_[i][j - 1] - sat_[i - 1][j - 1]; + } + } + } + + int sumRegion(int row1, int col1, int row2, int col2) { + return sat_[row2 + 1][col2 + 1] - sat_[row2 + 1][col1] - + sat_[row1][col2 + 1] + sat_[row1][col1]; + } + + private: + vector> sat_; +}; +``` + + + + +```py +class NumMatrix: + def __init__(self, matrix: List[List[int]]): + m, n = len(matrix), len(matrix[0]) + self.sat = [[0 for _ in range(n + 1)] for _ in range(m + 1)] + + for i in range(1, m + 1): + for j in range(1, n + 1): + self.sat[i][j] = ( + matrix[i - 1][j - 1] + + self.sat[i - 1][j] + + self.sat[i][j - 1] + - self.sat[i - 1][j - 1] + ) + + def sumRegion(self, row1: int, col1: int, row2: int, col2: int) -> int: + return ( + self.sat[row2 + 1][col2 + 1] + - self.sat[row2 + 1][col1] + - self.sat[row1][col2 + 1] + + self.sat[row1][col1] + ) + +``` + + + + + +## [560. Subarray Sum Equals K](https://leetcode.com/problems/subarray-sum-equals-k/) + +### 題目描述 + +给定一个数组,寻找和为 k 的连续区间个数。 + +### 輸入輸出範例 + +输入一个一维整数数组和一个整数值 k;输出一个整数,表示满足条件的连续区间个数。 + +``` +Input: nums = [1,1,1], k = 2 +Output: 2 +``` + +在这个样例中,我们可以找到两个 [1,1] 连续区间满足条件。 + +### 題解 + +本题同样是利用前缀和,不同的是这里我们使用一个哈希表 cache,其键是前缀和,而值是该前缀和出现的次数。在我们遍历到位置 i 时,假设当前的前缀和是 cumsum,那么 cache[cumsum-k] 即为以当前位置结尾、满足条件的区间个数。 + + + + +```cpp +int subarraySum(vector& nums, int k) { + int count = 0, cumsum = 0; + unordered_map cache; // + cache[0] = 1; + for (int num : nums) { + cumsum += num; + count += cache[cumsum - k]; + ++cache[cumsum]; + } + return count; +} +``` + + + + +```py +def subarraySum(nums: List[int], k: int) -> int: + count, cur_sum = 0, 0 + cache = {0: 1} # + for num in nums: + cur_sum += num + count += cache.get(cur_sum - k, 0) + cache[cur_sum] = cache.get(cur_sum, 0) + 1 + return count +``` + + + + + diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-11-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-11-exercises.md new file mode 100644 index 00000000..ecdbafb5 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-11-exercises.md @@ -0,0 +1,53 @@ +--- +sidebar_position: 58 +--- + +# 10.11 練習 + +## 基礎難度 + +### [566. Reshape the Matrix](https://leetcode.com/problems/reshape-the-matrix/) + +没有什么难度,只是需要一点耐心。 + +### [225. Implement Stack using Queues](https://leetcode.com/problems/implement-stack-using-queues/) + +利用相似的方法,我们也可以用 queue 实现 stack。 + +### [503. Next Greater Element II](https://leetcode.com/problems/next-greater-element-ii/) + +Daily Temperature 的变种题。 + +### [217. Contains Duplicate](https://leetcode.com/problems/contains-duplicate/) + +使用什么数据结构可以快速判断重复呢? + +### [697. Degree of an Array](https://leetcode.com/problems/degree-of-an-array/) + +如何对数组进行预处理才能正确并快速地计算子数组的长度? + +### [594. Longest Harmonious Subsequence](https://leetcode.com/problems/longest-harmonious-subsequence/) + +最长连续序列的变种题。 + +### [15. 3Sum](https://leetcode.com/problems/3sum/) + +因为排序的复杂度是 $O(n \log n) < O(n^2)$,因此我们既可以排序后再进行 $O(n^2)$ 的指针搜索,也可以直接利用哈希表进行 $O(n^2)$ 的搜索。 + +## 進階難度 + +### [287. Find the Duplicate Number](https://leetcode.com/problems/find-the-duplicate-number/) + +寻找丢失数字的变种题。除了标负位置,你还有没有其它算法可以解决这个问题? + +### [313. Super Ugly Number](https://leetcode.com/problems/super-ugly-number/) + +尝试使用优先队列解决这一问题。 + +### [870. Advantage Shuffle](https://leetcode.com/problems/advantage-shuffle/) + +如果我们需要比较大小关系,而且同一数字可能出现多次,那么应该用什么数据结构呢? + +### [307. Range Sum Query - Mutable](https://leetcode.com/problems/range-sum-query-mutable/) + +前缀和的变种题。好吧我承认,这道题可能有些超纲,你或许需要搜索一下什么是线段树。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-2-python-data-structures.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-2-python-data-structures.md new file mode 100644 index 00000000..b4221a27 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-2-python-data-structures.md @@ -0,0 +1,22 @@ +--- +sidebar_position: 49 +--- + +# 10.2 Python 常用数据结构 + +类似于 C++ STL,Python 也提供了类似的数据结构(实际底层细节可能因编译器而异): + +1. Sequence Containers:维持顺序的容器。 + 1. list:`动态数组`,是我们最常使用的数据结构之一,用于 $O(1)$ 的随机读取。因为大部分算法的时间复杂度都会大于 $O(n)$,因此我们经常新建 list 来存储各种数据或中间变量。因为在尾部增删的复杂度是 $O(1)$,我们也可以把它当作 stack 来用。 + 2. tuple: `元组`,immutable list,不可改变其中元素或总长度。 + 3. collections.deque:`双端队列`,这是一个非常强大的数据结构,既支持 $O(1)$ 随机读取,又支持 $O(1)$ 时间的头部增删和尾部增删(因此可以当作 stack 和 queue 来使用),不过有一定的额外开销。也可以用来近似一个双向链表来使用。 +2. Container Adaptors:基于其它容器实现的容器。 + 1. heapq:`最小堆(最小值先出的数据结构)`,默认基于 list 实现堆结构。它可以在 $O(n \log n)$ 的时间排序数组,$O(\log n)$ 的时间插入任意值,$O(1)$ 的时间获得最小值,$O(\log n)$ 的时间删除最小值。heapq 常用于维护数据结构并快速获取最小值,但不支持自定义比较函数。所以通常我们需要提前算好自定义值,再把 (自定义值,位置) 的 tuple 存进 heapq。这样进行比较时就会默认从左到右比较 tuple 中的元素,即先比较自定义值,再比较元素的插入次序。 +3. Ordered Associative Containers:有序关联容器。 + 1. collections.OrderedDict:`顺序映射或顺序表`,注意这里的 Ordered 不同于 C++ 中 map的按大小排序,而是按照插入的先后次序排序。OrderedDict 很适合用来做 LRU。 +4. Unordered Associative Containers:无序关联容器。 + 1. set:`哈希集合`,可以在 O(1) 的时间快速插入、查找、删除元素,常用于快速的查询一个元素是否在这个容器内。 + 2. dict:`哈希映射或哈希表`,在 set 的基础上加上映射关系,可以对每一个元素 key 存一个值 value。在某些情况下,如果 key 的范围已知且较小,我们也可以用 list 代替 dict,用位置表示 key,用每个位置的值表示 value。 + 3. collections.Counter:`计数器`,是 dict 的一个特殊版本,可以直接传入一个 list,并对其中的每一个元素进行计数统计,key 是元素值,value 是元素出现的频次。可以用来当作多重集合。 + +同样的,因为这并不是一本讲解 Python 原理的书,更多的数据结构细节请读者自行搜索。只有理解了这些数据结构的原理和使用方法,才能够更加游刃有余地解决算法和数据结构问题。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-3-arrays.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-3-arrays.mdx new file mode 100644 index 00000000..9be3c06a --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-3-arrays.mdx @@ -0,0 +1,250 @@ +--- +sidebar_position: 50 +--- + +# 10.3 数组 + +## [448. Find All Numbers Disappeared in an Array](https://leetcode.com/problems/find-all-numbers-disappeared-in-an-array/) + +### 題目描述 + +给定一个长度为 n 的数组,其中包含范围为 1 到 n 的整数,有些整数重复了多次,有些整数没有出现,求 1 到 n 中没有出现过的整数。 + +### 輸入輸出範例 + +输入是一个一维整数数组,输出也是一个一维整数数组,表示输入数组内没出现过的数字。 + +``` +Input: [4,3,2,7,8,2,3,1] +Output: [5,6] +``` + +利用数组这种数据结构建立 n 个桶,把所有重复出现的位置进行标记,然后再遍历一遍数组,即可找到没有出现过的数字。进一步地,我们可以直接对原数组进行标记:把重复出现的数字-1在原数组的位置设为负数(这里-1 的目的是把 1 到 n 的数字映射到 0 到 n-1 的位置),最后仍然为正数的位置 +1 即为没有出现过的数。 + +### 題解 + + + + + + +```cpp +vector findDisappearedNumbers(vector& nums) { + vector disappeared; + for (int num : nums) { + int pos = abs(num) - 1; + if (nums[pos] > 0) { + nums[pos] = -nums[pos]; + } + } + for (int i = 0; i < nums.size(); ++i) { + if (nums[i] > 0) { + disappeared.push_back(i + 1); + } + } + return disappeared; +} +``` + + + + +```py +def findDisappearedNumbers(nums: List[int]) -> List[int]: + for num in nums: + pos = abs(num) - 1 + if nums[pos] > 0: + nums[pos] = -nums[pos] + return [i + 1 for i in range(len(nums)) if nums[i] > 0] +``` + + + + + +## [48. Rotate Image](https://leetcode.com/problems/rotate-image/) + +### 題目描述 + +给定一个 n × n 的矩阵,求它顺时针旋转 90 度的结果,且必须在原矩阵上修改(in-place)。怎样能够尽量不创建额外储存空间呢? + +### 輸入輸出範例 + +输入和输出都是一个二维整数矩阵。 + +``` +Input: +[[1,2,3], + [4,5,6], + [7,8,9]] +Output: +[[7,4,1], + [8,5,2], + [9,6,3]] +``` + +### 題解 + +每次只考虑四个间隔 90 度的位置,可以进行 O(1) 额外空间的旋转。 + +
      + + ![](10.1.png) + +
      图 10.1: 题目 48 - $O(1)$ 空间旋转样例,相同颜色代表四个互相交换的位置
      +
      + + + + +```cpp +void rotate(vector>& matrix) { + int pivot = 0, n = matrix.size() - 1; + for (int i = 0; i <= n / 2; ++i) { + for (int j = i; j < n - i; ++j) { + pivot = matrix[j][n - i]; + matrix[j][n - i] = matrix[i][j]; + matrix[i][j] = matrix[n - j][i]; + matrix[n - j][i] = matrix[n - i][n - j]; + matrix[n - i][n - j] = pivot; + } + } +} +``` + + + + +```py +def rotate(matrix: List[List[int]]) -> None: + n = len(matrix) - 1 + for i in range(n // 2 + 1): + for j in range(i, n - i): + pivot = matrix[j][n - i] + matrix[j][n - i] = matrix[i][j] + matrix[i][j] = matrix[n - j][i] + matrix[n - j][i] = matrix[n - i][n - j] + matrix[n - i][n - j] = pivot +``` + + + + + +## [240. Search a 2D Matrix II](https://leetcode.com/problems/search-a-2d-matrix-ii/) + +### 題目描述 + +给定一个二维矩阵,已知每行和每列都是增序的,尝试设计一个快速搜索一个数字是否在矩阵中存在的算法。 + +### 輸入輸出範例 + +输入是一个二维整数矩阵,和一个待搜索整数。输出是一个布尔值,表示这个整数是否存在于矩阵中。 + +``` +Input: matrix = +[ [1, 4, 7, 11, 15], + [2, 5, 8, 12, 19], + [3, 6, 9, 16, 22], + [10, 13, 14, 17, 24], + [18, 21, 23, 26, 30]], target = 5 +Output: true +``` + +### 題解 + +这道题有一个简单的技巧:我们可以从右上角开始查找,若当前值大于待搜索值,我们向左移动一位;若当前值小于待搜索值,我们向下移动一位。如果最终移动到左下角时仍不等于待搜索值,则说明待搜索值不存在于矩阵中。 + + + + +```cpp +bool searchMatrix(vector>& matrix, int target) { + int m = matrix.size(), n = matrix[0].size(); + int i = 0, j = n - 1; + while (i < m && j >= 0) { + if (matrix[i][j] == target) { + return true; + } else if (matrix[i][j] < target) { + ++i; + } else { + --j; + } + } + return false; +} +``` + + + + +```py +def searchMatrix(matrix: List[List[int]], target: int) -> bool: + m, n = len(matrix), len(matrix[0]) + i, j = 0, n - 1 + while i < m and j >= 0: + if matrix[i][j] == target: + return True + if matrix[i][j] < target: + i += 1 + else: + j -= 1 + return False +``` + + + + + +## [769. Max Chunks To Make Sorted](https://leetcode.com/problems/max-chunks-to-make-sorted/) + +### 題目描述 + +给定一个含有 0 到 n 整数的数组,每个整数只出现一次,求这个数组最多可以分割成多少个子数组,使得对每个子数组进行增序排序后,原数组也是增序的。 + +### 輸入輸出範例 + +输入一个一维整数数组,输出一个整数,表示最多的分割数。 + +``` +Input: [1,0,2,3,4] +Output: 4 +``` + +在这个样例中,最多分割是 [1, 0], [2], [3], [4]。 + +### 題解 + +从左往右遍历,同时记录当前的最大值,每当当前最大值等于数组位置时,我们可以多一次分割。 + +为什么可以通过这个算法解决问题呢?如果当前最大值大于数组位置,则说明右边一定有小于数组位置的数字,需要把它也加入待排序的子数组;又因为数组只包含不重复的 0 到 n,所以当前最大值一定不会小于数组位置。所以每当当前最大值等于数组位置时,假设为 p,我们可以成功完成一次分割,并且其与上一次分割位置 q 之间的值一定是 q +1 到 p 的所有数字。 + + + + +```cpp +int maxChunksToSorted(vector& arr) { + int chunks = 0, cur_max = 0; + for (int i = 0; i < arr.size(); ++i) { + cur_max = max(cur_max, arr[i]); + chunks += cur_max == i; + } + return chunks; +} +``` + + + + +```py +def maxChunksToSorted(arr: List[int]) -> int: + chunks, cur_max = 0, 0 + for i, num in enumerate(arr): + cur_max = max(cur_max, num) + chunks += cur_max == i + return chunks +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-4-stack-and-queue.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-4-stack-and-queue.mdx new file mode 100644 index 00000000..93150382 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-4-stack-and-queue.mdx @@ -0,0 +1,257 @@ +--- +sidebar_position: 51 +--- + +# 10.4 栈和队列 + +## [232. Implement Queue using Stacks](https://leetcode.com/problems/implement-queue-using-stacks/) + +### 題目描述 + +尝试使用栈(stack)来实现队列(queue)。 + +### 輸入輸出範例 + +以下是数据结构的调用样例。 + +``` +MyQueue queue = new MyQueue(); +queue.push(1); +queue.push(2); +queue.peek(); // returns 1 +queue.pop(); // returns 1 +queue.empty(); // returns false +``` + +### 題解 + +我们可以用两个栈来实现一个队列:因为我们需要得到先入先出的结果,所以必定要通过一个额外栈翻转一次数组。这个翻转过程既可以在插入时完成,也可以在取值时完成。我们这里展示在取值时完成的写法。 + + + + +```cpp +class MyQueue { + public: + MyQueue() {} + + void push(int x) { s_in_.push(x); } + + int pop() { + in2out(); + int x = s_out_.top(); + s_out_.pop(); + return x; + } + + int peek() { + in2out(); + return s_out_.top(); + } + + bool empty() { return s_in_.empty() && s_out_.empty(); } + + private: + void in2out() { + if (!s_out_.empty()) { + return; + } + while (!s_in_.empty()) { + int x = s_in_.top(); + s_in_.pop(); + s_out_.push(x); + } + } + + stack s_in_, s_out_; +}; +``` + + + + +```py +class MyQueue: + def __init__(self): + self.s_in = [] + self.s_out = [] + + def _in2out(self): + if len(self.s_out) > 0: + return + while len(self.s_in) > 0: + self.s_out.append(self.s_in.pop()) + + def push(self, x: int) -> None: + self.s_in.append(x) + + def pop(self) -> int: + self._in2out() + return self.s_out.pop() + + def peek(self) -> int: + self._in2out() + return self.s_out[-1] + + def empty(self) -> bool: + return len(self.s_in) == 0 and len(self.s_out) == 0 +``` + + + + + +## [155. Min Stack](https://leetcode.com/problems/min-stack/) + +### 題目描述 + +设计一个最小栈,除了需要支持常规栈的操作外,还需要支持在 $O(1)$ 时间内查询栈内最小值的功能。 + +### 輸入輸出範例 + +以下是数据结构的调用样例。 + +``` +MinStack minStack = new MinStack(); +minStack.push(-2); +minStack.push(0); +minStack.push(-3); +minStack.getMin(); // Returns -3. +minStack.pop(); +minStack.top(); // Returns 0. +minStack.getMin(); // Returns -2. +``` + +### 題解 + +我们可以额外建立一个新栈,栈顶表示原栈里所有值的最小值。每当在原栈里插入一个数字时,若该数字小于等于新栈栈顶,则表示这个数字在原栈里是最小值,我们将其同时插入新栈内。每当从原栈里取出一个数字时,若该数字等于新栈栈顶,则表示这个数是原栈里的最小值之一,我们同时取出新栈栈顶的值。 + +一个写起来更简单但是时间复杂度略高的方法是,我们每次插入原栈时,都向新栈插入一次原栈里所有值的最小值(新栈栈顶和待插入值中小的那一个);每次从原栈里取出数字时,同样取出新栈的栈顶。这样可以避免判断,但是每次都要插入和取出。我们这里只展示第一种写法。 + + + + +```cpp +class MinStack { + public: + MinStack() {} + + void push(int x) { + s_.push(x); + if (min_s_.empty() || min_s_.top() >= x) { + min_s_.push(x); + } + } + + void pop() { + if (!min_s_.empty() && min_s_.top() == s_.top()) { + min_s_.pop(); + } + s_.pop(); + } + + int top() { return s_.top(); } + + int getMin() { return min_s_.top(); } + + private: + stack s_, min_s_; +}; +``` + + + + +```py +class MinStack: + def __init__(self): + self.s = [] + self.min_s = [] + + def push(self, x: int) -> None: + self.s.append(x) + if len(self.min_s) == 0 or self.min_s[-1] >= x: + self.min_s.append(x) + + def pop(self) -> None: + if len(self.min_s) != 0 and self.s[-1] == self.min_s[-1]: + self.min_s.pop() + self.s.pop() + + def top(self) -> int: + return self.s[-1] + + def getMin(self) -> int: + return self.min_s[-1] +``` + + + + + + +## [20. Valid Parentheses](https://leetcode.com/problems/valid-parentheses/) + +### 題目描述 + +给定一个只由左右圆括号、花括号和方括号组成的字符串,求这个字符串是否合法。合法的定义是每一个类型的左括号都有一个右括号一一对应,且括号内的字符串也满足此要求。 + +### 輸入輸出範例 + +输入是一个字符串,输出是一个布尔值,表示字符串是否合法。 + +``` +Input: "{[]}()" +Output: true +``` + +### 題解 + +括号匹配是典型的使用栈来解决的问题。我们从左往右遍历,每当遇到左括号便放入栈内,遇到右括号则判断其和栈顶的括号是否是统一类型,是则从栈内取出左括号,否则说明字符串不合法。 + + + + +```cpp +bool isValid(string s) { + stack parsed; + unordered_map matches{{’(’, ’)’}, {’{’, ’}’}, {’[’, ’]’}}; + for (char c : s) { + if (matches.contains(c)) { + parsed.push(c); + continue; + } + if (parsed.empty()) { + return false; + } + if (c != matches[parsed.top()]) { + return false; + } + parsed.pop(); + } + return parsed.empty(); +} +``` + + + + +```py +def isValid(s: str) -> bool: + parsed = [] + matches = {"{": "}", "(": ")", "[": "]"} + for c in s: + if c in matches.keys(): + parsed.append(c) + continue + if len(parsed) == 0: + return False + if c != matches[parsed[-1]]: + return False + parsed.pop() + return len(parsed) == 0 +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-5-monotonic-stack.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-5-monotonic-stack.mdx new file mode 100644 index 00000000..a4de08f5 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-5-monotonic-stack.mdx @@ -0,0 +1,72 @@ +--- +sidebar_position: 52 +--- + +# 10.5 单调栈 + +`单调栈`通过维持栈内值的单调递增(递减)性,在整体 $O(n)$ 的时间内处理需要大小比较的问题。 + +## [739. Daily Temperatures](https://leetcode.com/problems/daily-temperatures/) + +### 題目描述 + +给定每天的温度,求对于每一天需要等几天才可以等到更暖和的一天。如果该天之后不存在更暖和的天气,则记为 0。 + +### 輸入輸出範例 + +输入是一个一维整数数组,输出是同样长度的整数数组,表示对于每天需要等待多少天。 + +``` +Input: [73, 74, 75, 71, 69, 72, 76, 73] +Output: [1, 1, 4, 2, 1, 1, 0, 0] +``` + +### 題解 + +我们可以维持一个单调递减的栈,表示每天的温度;为了方便计算天数差,我们这里存放位置(即日期)而非温度本身。我们从左向右遍历温度数组,对于每个日期 p,如果 p 的温度比栈顶存储位置 q 的温度高,则我们取出 q,并记录 q 需要等待的天数为 p − q;我们重复这一过程,直到 p 的温度小于等于栈顶存储位置的温度(或空栈)时,我们将 p 插入栈顶,然后考虑下一天。在这个过程中,栈内数组永远保持单调递减,避免了使用排序进行比较。最后若栈内剩余一些日期,则说明它们之后都没有出现更暖和的日期。 + + + + +```cpp +vector dailyTemperatures(vector& temperatures) { + int n = temperatures.size(); + vector days_to_wait(n, 0); + stack mono_stack; + for (int i = 0; i < n; ++i) { + while (!mono_stack.empty()) { + int j = mono_stack.top(); + if (temperatures[i] <= temperatures[j]) { + break; + } + mono_stack.pop(); + days_to_wait[j] = i - j; + } + mono_stack.push(i); + } + return days_to_wait; +} +``` + + + + +```py +def dailyTemperatures(temperatures: List[int]) -> List[int]: + n = len(temperatures) + days_to_wait = [0] * n + mono_stack = [] + for i in range(n): + while len(mono_stack) > 0: + j = mono_stack[-1] + if temperatures[i] <= temperatures[j]: + break + mono_stack.pop() + days_to_wait[j] = i - j + mono_stack.append(i) + return days_to_wait +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-6-priority-queue.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-6-priority-queue.mdx new file mode 100644 index 00000000..9a225ba9 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-6-priority-queue.mdx @@ -0,0 +1,295 @@ +--- +sidebar_position: 53 +--- + +# 10.6 优先队列 + +`优先队列`(priority queue)可以在 O(1) 时间内获得最大值,并且可以在 O(log n) 时间内取出最大值或插入任意值。 + +
      + + ![](10.2.png) + +
      图 10.2: (最大)堆,维护的是数据结构中的大于关系
      +
      + +优先队列常常用堆(heap)来实现。堆是一个完全二叉树,其每个节点的值总是大于等于子节点的值。实际实现堆时,我们通常用一个数组而不是用指针建立一个树。这是因为堆是完全二叉树,所以用数组表示时,位置 i 的节点的父节点位置一定为 (i-1)/2,而它的两个子节点的位置又一定分别为 2i+1 和 2i+2。 + +以下是堆的实现方法,其中最核心的两个操作是上浮和下沉:如果一个节点比父节点大,那么需要交换这个两个节点;交换后还可能比它新的父节点大,因此需要不断地进行比较和交换操作,我们称之为上浮;类似地,如果一个节点比父节小,也需要不断地向下进行比较和交换操作我们称之为下沉。如果一个节点有两个子节点,我们总是交换最大的子节点。 + + + + + +```cpp +class Heap { + public: + Heap() {} + // 上浮。 + void swim(int pos) { + int next_pos = (pos - 1) / 2; + while (pos > 0 && heap_[next_pos] < heap_[pos]) { + swap(heap_[next_pos], heap_[pos]); + pos = next_pos; + next_pos = (pos - 1) / 2; + } + } + // 下沉。 + void sink(int pos) { + int n = heap_.size(); + int next_pos = 2 * pos + 1; + while (next_pos < n) { + if (next_pos < n - 1 && heap_[next_pos] < heap_[next_pos + 1]) { + ++next_pos; + } + if (heap_[pos] >= heap_[next_pos]) { + break; + } + swap(heap_[next_pos], heap_[pos]); + pos = next_pos; + next_pos = 2 * pos + 1; + } + } + // 插入任意值:把新的数字放在最后一位,然后上浮。 + void push(int k) { + heap_.push_back(k); + swim(heap_.size() - 1); + } + // 删除最大值:把最后一个数字挪到开头,然后下沉。 + void pop() { + heap_[0] = heap_.back(); + heap_.pop_back(); + sink(0); + } + // 获得最大值。 + int top() { return heap_[0]; } + + private: + vector heap_; +}; +``` + + + + +```py +class Heap: + def __init__(self): + self.heap = [] + + # 上浮。 + def swim(self, pos: int): + next_pos = (pos - 1) // 2 + while pos > 0 and self.heap[next_pos] < self.heap[pos]: + self.heap[next_pos], self.heap[pos] = self.heap[pos], self.heap[next_pos] + pos = next_pos + next_pos = (pos - 1) // 2 + + # 下沉。 + def sink(self, pos: int): + n = len(self.heap) + next_pos = 2 * pos + 1 + while next_pos < n: + if next_pos < n - 1 and self.heap[next_pos] < self.heap[next_pos + 1]: + next_pos += 1 + if self.heap[pos] >= self.heap[next_pos]: + break + self.heap[next_pos], self.heap[pos] = self.heap[pos], self.heap[next_pos] + pos = next_pos + next_pos = 2 * pos + 1 + + # 插入任意值:把新的数字放在最后一位,然后上浮。 + def push(self, k: int): + self.heap.append(k) + self.swim(len(self.heap) - 1) + + # 删除最大值:把最后一个数字挪到开头,然后下沉。 + def pop(self): + self.heap[0] = self.heap.pop() + self.sink(0) + + # 获得最大值。 + def top(self) -> int: + return self.heap[0] + +``` + + + + + +通过将算法中的大于号和小于号互换,我们也可以得到一个快速获得最小值的优先队列。 + +## [23. Merge k Sorted Lists](https://leetcode.com/problems/merge-k-sorted-lists/) + +### 題目描述 + +给定 k 个增序的链表,试将它们合并成一条增序链表。 + +### 輸入輸出範例 + +输入是一个一维数组,每个位置存储链表的头节点;输出是一条链表。 + +``` +Input: +[1->4->5, + 1->3->4, + 2->6] +Output: 1->1->2->3->4->4->5->6 +``` + +### 題解 + +本题可以有很多中解法,比如类似于归并排序进行两两合并。我们这里展示一个速度比较快的方法,即把所有的链表存储在一个优先队列中,每次提取所有链表头部节点值最小的那个节点,直到所有链表都被提取完为止。 + +因为 C++ priority_queue 的比较函数默认是对最大堆进行比较并维持递增关系,如果我们想要获取最小的节点值,我们则需要实现一个最小堆。因此堆的比较函数应该维持递减关系,即 lambda 函数中返回时用大于号而不是递增关系时的小于号进行比较。 + + + + +```cpp +ListNode* mergeKLists(vector& lists) { + auto comp = [](ListNode* l1, ListNode* l2) { return l1->val > l2->val; }; + priority_queue, decltype(comp)> pq; + for (ListNode* l : lists) { + if (l) { + pq.push(l); + } + } + ListNode *dummy = new ListNode(0), *cur = dummy; + while (!pq.empty()) { + cur->next = pq.top(); + pq.pop(); + cur = cur->next; + if (cur->next) { + pq.push(cur->next); + } + } + return dummy->next; +} +``` + + + + +```py +def mergeKLists(lists: List[Optional[ListNode]]) -> Optional[ListNode]: + pq = [] + for idx, l in enumerate(lists): + if l is not None: + # ListNode不可被哈希,所以这里我们直接记录它在lists中的位置。 + pq.append((l.val, idx)) + heapq.heapify(pq) + + dummy = ListNode() + cur = dummy + + while len(pq) > 0: + _, l_idx = heapq.heappop(pq) + cur.next = lists[l_idx] + cur = cur.next + if cur.next is not None: + lists[l_idx] = lists[l_idx].next + heapq.heappush(pq, (cur.next.val, l_idx)) + + return dummy.next + +``` + + + + + +## [218. The Skyline Problem](https://leetcode.com/problems/the-skyline-problem/) + +### 題目描述 + +给定建筑物的起止位置和高度,返回建筑物轮廓(天际线)的拐点。 + +### 輸入輸出範例 + +输入是一个二维整数数组,表示每个建筑物的 [左端, 右端, 高度];输出是一个二维整数数组,表示每个拐点的横纵坐标。 + +
      + + ![](10.3.png) + +
      图 10.3: 题目 218 - 建筑物及其天际线样例
      +
      + +``` +Input: [[2 9 10], [3 7 15], [5 12 12], [15 20 10], [19 24 8]] +Output: [[2 10], [3 15], [7 12], [12 0], [15 10], [20 8], [24, 0]] +``` + +### 題解 + +我们可以使用优先队列储存每个建筑物的高度和右端(这里使用 pair,其默认比较函数是先比较第一个值,如果相等则再比较第二个值),从而获取目前会拔高天际线、且妨碍到前一个建筑物(的右端端点)的下一个建筑物。 + +因为 Python 中 heapq 是最小堆,所以我们在存值的时候可以存负值,这样就变成了最大堆。 + +这道题比较复杂,如果实在难以理解,建议读者暂时跳过此题,或者在纸上举例子画一画。 + + + + +```cpp +vector> getSkyline(vector>& buildings) { + vector> skyline; + priority_queue> pq; // <高度, 右端> + int i = 0, n = buildings.size(); + int cur_x, cur_h; + while (i < n || !pq.empty()) { + if (pq.empty() || (i < n && buildings[i][0] <= pq.top().second)) { + cur_x = buildings[i][0]; + while (i < n && cur_x == buildings[i][0]) { + pq.emplace(buildings[i][2], buildings[i][1]); + ++i; + } + } else { + cur_x = pq.top().second; + while (!pq.empty() && cur_x >= pq.top().second) { + pq.pop(); + } + } + cur_h = pq.empty() ? 0 : pq.top().first; + if (skyline.empty() || cur_h != skyline.back()[1]) { + skyline.push_back({cur_x, cur_h}); + } + } + return skyline; +} +``` + + + + +```py +def getSkyline(buildings: List[List[int]]) -> List[List[int]]: + skyline = [] + pq = [] # <负高度,右端> + heapq.heapify(pq) + i, n = 0, len(buildings) + + while i < n or len(pq) > 0: + if len(pq) == 0 or (i < n and buildings[i][0] <= pq[0][1]): + cur_x = buildings[i][0] + while i < n and cur_x == buildings[i][0]: + heapq.heappush(pq, (-buildings[i][2], buildings[i][1])) + i += 1 + else: + cur_x = pq[0][1] + while len(pq) > 0 and cur_x >= pq[0][1]: + heapq.heappop(pq) + + cur_h = -pq[0][0] if len(pq) > 0 else 0 + if len(skyline) == 0 or cur_h != skyline[-1][1]: + skyline.append([cur_x, cur_h]) + + return skyline + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-7-deque.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-7-deque.mdx new file mode 100644 index 00000000..a5a97fab --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-7-deque.mdx @@ -0,0 +1,82 @@ +--- +sidebar_position: 54 +--- + +# 10.7 双端队列 + +## [239. Sliding Window Maximum](https://leetcode.com/problems/sliding-window-maximum/) + +### 題目描述 + +给定一个整数数组和一个滑动窗口大小,求在这个窗口的滑动过程中,每个时刻其包含的最大值。 + +### 輸入輸出範例 + +输入是一个一维整数数组,和一个表示滑动窗口大小的整数;输出是一个一维整数数组,表示每个时刻时的窗口内最大值。 + +``` +Input: nums = [1,3,-1,-3,5,3,6,7], k = 3 +Output: [3,3,5,5,6,7] +``` + +在这个样例中,滑动窗口在每个位置的最大包含值取法如下: + +``` + Window position Max +------------------------- ----- +[1 3 -1] -3 5 3 6 7 3 + 1 [3 -1 -3] 5 3 6 7 3 + 1 3 [-1 -3 5] 3 6 7 5 + 1 3 -1 [-3 5 3] 6 7 5 + 1 3 -1 -3 [5 3 6] 7 6 + 1 3 -1 -3 5 [3 6 7] 7 +``` + +### 題解 + +我们可以利用双端队列进行操作:每当向右移动时,把窗口左端的值从双端队列左端剔除,把双端队列右边小于窗口右端的值全部剔除。这样双端队列的最左端永远是当前窗口内的最大值。另外,这道题也是单调栈的一种延申:该双端队列利用从左到右递减来维持大小关系。 + + + + +```cpp +vector maxSlidingWindow(vector& nums, int k) { + deque dq; + vector swm; + for (int i = 0; i < nums.size(); ++i) { + if (!dq.empty() && dq.front() == i - k) { + dq.pop_front(); + } + while (!dq.empty() && nums[dq.back()] < nums[i]) { + dq.pop_back(); + } + dq.push_back(i); + if (i >= k - 1) { + swm.push_back(nums[dq.front()]); + } + } + return swm; +} +``` + + + + +```py +def maxSlidingWindow(nums: List[int], k: int) -> List[int]: + dq = collections.deque() + swm = [] + for i, num in enumerate(nums): + if len(dq) > 0 and dq[0] == i - k: + dq.popleft() + while len(dq) > 0 and nums[dq[-1]] < num: + dq.pop() + dq.append(i) + if i >= k - 1: + swm.append(nums[dq[0]]) + return swm +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-8-hash-table.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-8-hash-table.mdx new file mode 100644 index 00000000..d9a6e5a0 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-8-hash-table.mdx @@ -0,0 +1,232 @@ +--- +sidebar_position: 55 +--- + +# 10.8 哈希表 + +`哈希表(hash table, hash map)`,又称散列表,使用 $O(n)$ 空间复杂度存储数据,通过哈希函数(hash function)映射位置,从而实现近似 O(1) 时间复杂度的插入、查找、删除等操作。哈希表可以用来统计频率,记录内容等等。 + +如果元素有穷,并且范围不大,那么可以用一个固定大小的数组来存储或统计元素。例如我们需要统计一个字符串中所有字母的出现次数,则可以用一个长度为 26 的数组来进行统计,其哈希函数即为字母在字母表的位置,这样空间复杂度就可以降低为常数。 + +## [1. Two Sum](https://leetcode.com/problems/two-sum/) + +### 題目描述 + +给定一个(未排序的)整数数组,已知有且只有两个数的和等于给定值,求这两个数的位置。 + +### 輸入輸出範例 + +输入一个一维整数数组和一个目标值,输出是一个大小为 2 的一维数组,表示满足条件的两个数字的位置。 + +``` +Input: nums = [2, 7, 15, 11], target = 9 +Output: [0, 1] +``` + +在这个样例中,第 0 个位置的值 2 和第 1 个位置的值 7 的和为 9。 + +### 題解 + +我们可以利用哈希表存储遍历过的值以及它们的位置,每次遍历到位置 i 的时候,查找哈希表里是否存在 target - nums[i],若存在,则说明这两个值的和为 target。 + + + + +```cpp +vector twoSum(vector& nums, int target) { + unordered_map cache; // <值,位置> + for (int i = 0; i < nums.size(); ++i) { + int num1 = nums[i], num2 = target - num1; + if (cache.contains(num2)) { + return vector{cache[num2], i}; + } + cache[num1] = i; + } + return {}; +} +``` + + + + +```py +def twoSum(nums: List[int], target: int) -> List[int]: + cache = dict() # <值,位置> + for i, num1 in enumerate(nums): + num2 = target - num1 + if num2 in cache: + return [cache[num2], i] + cache[num1] = i + return [] +``` + + + + + +## [128. Longest Consecutive Sequence](https://leetcode.com/problems/longest-consecutive-sequence/) + +### 題目描述 + +给定一个整数数组,求这个数组中的数字可以组成的最长连续序列有多长。 + +### 輸入輸出範例 + +输入一个整数数组,输出一个整数,表示连续序列的长度。 + +``` +Input: [100, 4, 200, 1, 3, 2] +Output: 4 +``` + +在这个样例中,最长连续序列是 [1,2,3,4]。 + +### 題解 + +我们可以把所有数字放到一个哈希表,然后不断地从哈希表中任意取一个值,并删除掉其之前之后的所有连续数字,然后更新目前的最长连续序列长度。重复这一过程,我们就可以找到所有的连续数字序列。 + + + + +```cpp +int longestConsecutive(vector& nums) { + unordered_set cache(nums.begin(), nums.end()); + int max_len = 0; + while (!cache.empty()) { + int cur = *(cache.begin()); + cache.erase(cur); + int l = cur - 1, r = cur + 1; + while (cache.contains(l)) { + cache.erase(l--); + } + while (cache.contains(r)) { + cache.erase(r++); + } + max_len = max(max_len, r - l - 1); + } + return max_len; +} +``` + + + + +```py +def longestConsecutive(nums: List[int]) -> int: + cache = set(nums) + max_len = 0 + + while len(cache) > 0: + cur = next(iter(cache)) + cache.remove(cur) + + l, r = cur - 1, cur + 1 + while l in cache: + cache.remove(l) + l -= 1 + while r in cache: + cache.remove(r) + r += 1 + + max_len = max(max_len, r - l - 1) + + return max_len + +``` + + + + + +## [149. Max Points on a Line](https://leetcode.com/problems/max-points-on-a-line/) + +### 題目描述 + +给定一些二维坐标中的点,求同一条线上最多有多少点。 + +### 輸入輸出範例 + +输入是一个二维整数数组,表示每个点的横纵坐标;输出是一个整数,表示满足条件的最多点数。 + +``` +Input: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]] +^ +| +| o +| o o +| o +| o o ++-------------------> +0 1 2 3 4 5 6 +Output: 4 +``` + +这个样例中,$y =5 − x$ 上有四个点。 + +### 題解 + +对于每个点,我们对其它点建立哈希表,统计同一斜率的点一共有多少个。这里利用的原理是,一条线可以由一个点和斜率而唯一确定。另外也要考虑斜率不存在和重复坐标的情况。 + +本题也利用了一个小技巧:在遍历每个点时,对于数组中位置 i 的点,我们只需要考虑 i 之后的点即可,因为 i 之前的点已经考虑过 i 了。 + + + + +```cpp +int maxPoints(vector>& points) { + int max_count = 0, n = points.size(); + for (int i = 0; i < n; ++i) { + unordered_map cache; // <斜率, 点个数> + int same_xy = 1, same_y = 1; + for (int j = i + 1; j < n; ++j) { + if (points[i][1] == points[j][1]) { + ++same_y; + if (points[i][0] == points[j][0]) { + ++same_xy; + } + } else { + double dx = points[i][0] - points[j][0], + dy = points[i][1] - points[j][1]; + ++cache[dx / dy]; + } + } + max_count = max(max_count, same_y); + for (auto item : cache) { + max_count = max(max_count, same_xy + item.second); + } + } + return max_count; +} +``` + + + + +```py +def maxPoints(points: List[List[int]]) -> int: + max_count, n = 0, len(points) + + for i, point1 in enumerate(points): + cache = dict() # <斜率, 点个数> + same_xy, same_y = 1, 1 + + for point2 in points[i + 1:]: + if point1[1] == point2[1]: + same_y += 1 + if point1[0] == point2[0]: + same_xy += 1 + else: + dx, dy = point1[0] - point2[0], point1[1] - point2[1] + cache[dx / dy] = cache.get(dx / dy, 0) + 1 + + max_count = max(max_count, same_y) + for count in cache.values(): + max_count = max(max_count, same_xy + count) + + return max_count + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-9-multisets-and-maps.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-9-multisets-and-maps.mdx new file mode 100644 index 00000000..aa08778c --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-9-multisets-and-maps.mdx @@ -0,0 +1,87 @@ +--- +sidebar_position: 56 +--- + +# 10.9 多重集合和映射 + +## [332. Reconstruct Itinerary](https://leetcode.com/problems/reconstruct-itinerary/) + +### 題目描述 + +给定一个人坐过的一些飞机的起止机场,已知这个人从 JFK 起飞,那么这个人是按什么顺序飞的;如果存在多种可能性,返回字母序最小的那种。 + +### 輸入輸出範例 + +输入是一个二维字符串数组,表示多个起止机场对子;输出是一个一维字符串数组,表示飞行顺序。 + +``` +Input: [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]] +Output: ["JFK", "MUC", "LHR", "SFO", "SJC"] +``` + +### 題解 + +本题可以先用哈希表记录起止机场,其中键是起始机场,值是一个多重(有序)集合,表示对应的终止机场。因为一个人可能坐过重复的线路,所以我们需要使用多重集合储存重复值。储存完成之后,我们可以利用栈/DFS 来恢复从终点到起点飞行的顺序,再将结果逆序得到从起点到终点的顺序。 + +因为 Python 没有默认的多重(有序)集合实现,我们可以直接存储一个数组,然后进行排序。也可以使用 Counter 结构,每次查找下一个机场时,返回 key 值最小的那个。 + + + + +```cpp +vector findItinerary(vector>& tickets) { + vector itinerary; + unordered_map> cache; + for (const auto& ticket : tickets) { + cache[ticket[0]].insert(ticket[1]); + } + stack s; + s.push("JFK"); + while (!s.empty()) { + string t = s.top(); + if (cache[t].empty()) { + itinerary.push_back(t); + s.pop(); + } else { + s.push(*cache[t].begin()); + cache[t].erase(cache[t].begin()); + } + } + reverse(itinerary.begin(), itinerary.end()); + return itinerary; +} +``` + + + + +```py +def findItinerary(tickets: List[List[str]]) -> List[str]: + itinerary = [] + cache = dict() + + for ticket in tickets: + if ticket[0] not in cache: + cache[ticket[0]] = [] + cache[ticket[0]].append(ticket[1]) + + for ticket in cache.keys(): + cache[ticket].sort(reverse=True) + + s = ["JFK"] + while len(s) > 0: + t = s[-1] + if t not in cache or len(cache[t]) == 0: + itinerary.append(t) + s.pop() + else: + t_next = cache[t].pop() + s.append(t_next) + + return list(reversed(itinerary)) + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10.1.png b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10.1.png new file mode 100644 index 0000000000000000000000000000000000000000..a0f0fc5153f985107a58dc37c2bb7ec47f4e7a17 GIT binary patch literal 37020 zcmb?@cRbZ!9QXIy+qJW=l~sz25H7AQ*&-t&8KKO`xMW;=lbyYal08dgWk$*>D>GX* z&(ZH$zh6E7J+D_%_nv#s`F_^B5R;=sT_$R8pEf7`<4 z)|)UEvT#jZi2zbmp2|7~7Y@hGx4iP@6*1qJ@+PrVSJ*-3lc{$OUni~NSJ$pxJ37nS zW?DZ{uKu|8@p!9oy^%_mAOHdWuxX%*vf#3C9PkJF{fl!Bh6MkmPI4Hpj#bPxFW1PB zc;rNcdiVQftIU^oYU1=u-AXYSf?t#bya)BGBh5Zf)_Q|GZ$RgBy0G{iKg!~E7WdC( zzYase&3=FGLWS+8i$hDU+PoAO=KV1zK4EsFWz5Y^7-|SC&57f=GpIDF(Uz#7bar~O zG}9jbVs|F|iv9&ou#5IRfsfc|u-pCED*Mqm)AI6%q4AFQ-U{A*3mxu#^JC_M-e#Pg ztou2ZcbPum-b%0CWi)oqi~6l@{-(^2 z^EgpqZ|CNd&3+NHm+2WBe>|a$`7H^~OWSX;$z$H#jp?SL`^6S_w?DFWxukTlHHbKh zlG|QH@ow8Gi<##+(Hw}<4G)MARaLj%d^Dk9RYpT(g<%l3iD48TCL{B^ zy0u(do@CEhACOm6gaKQF5kUb6%yNbEys8jGq_(6?%(Dxk4=!ZL_%$2TL=9}sb7`Nv-&yNFzSS9X{zQRbT`FmXQ zy`H4lE~~f_ArmtHD3^sk6|P`B_`%z@)4GHp3K)f}d;V>VXQ;aB||yuH->zIu-7*xBeilB2W8HVv8{?o zIA*Tx;!;Q|u70Dxi<b^?Y{q>l^LR&~W9)a&s?hrueAX%D!DeqomKLGw%w(CGN&0)0+Jd zi7f#q5B$P*_-owh$Za=*nd9K#;7e-6?_uvkS~f1o_%_bsJT<3jGmB{4?vwPj*+%{$Vj}NxH?5ZSGUwqRX3pH;IBy|1pk-qq9V}LF-$0?$XjAFA12PMY{p@Jwp zl3k^~;Fq@X1rul+{pd|wpu2uiBYhFVAMnSa1iRzcT5sAjEr!G7&DRH_ zkLm}EuPkMWM+wrN| zAOu^~K-HD&359Y&5n%yV{h3nPQEtnzf71La>`WuIDCyV67*b~EB?tGsug1#WjmGgZx$7k`F?Tep_QJvE$I zHG{d6y>EM=@T1KJ!#CCwSM>B?$N=h1g(^SWcDn1s5d1w`8UE2--SKLNlVD5{otd}b z?KDP0bL;-hpZn@3OOGeq#~mR29D+d1Y-+h9hF>vN)S>&tS&stZd`t1OzNn}u##O@9 z@5D{Qb1QF@Qc~v?$3@pV>H9~&eyaI2SqSBP5zRqU+`ISrg<({G*$c-GW{-*KUroqD zY%T4!*E-%#Jpq_6bWm(JE>wIsRoHgsI-(&-W&<9d<^3-E25=}{YEEWJ_Z>!#ewniy zdumGFRzE(b_-4xwXLw8zK17r}?L0j>>IuXYrKdBkCBLYJ5Hx5dS6A0MNhS;L&9+b~ z?JiQXcbI2ixTfq4;jb-G4|KHprS_P>RK^?AS8lZ3zr5D#kFX2BZW_MsVS7FzofUqD zjoy#_5XmU15i_6C&t~*^IxuPo!CsN4btlk^`z?b@IW*YqySfDnwiZ^d~FJAnhHLuXIIopv>WZ;?*O!3-8!eh;NS(G~2 zCG6+v$7}r$TjpN<^u|aIddY{JG(U%v{IA?2|z=xGbjuv+v1e zT$y70qqgMROidcxcL^yFock%#KJ|>XP1Ba$3A{-BfPFOPI$Z)T#Uo$Y32gK+-R3+G z`Hj=lBPZAESk#Y}(!OL)A=m{xvE>4ipRCn&@Lykb8#VDz$s(0tA<&jUwfSn(qAV;e z2Pqz@+{WhQ=T|$F!|)Navij`A?%-nI2q2GjoUHeBm0QjF^y!uibDII&bQ7NyjUSM} z%0A<*MT@E!q#(S7CV1S|-kum1g^f=(@Y=G2Dd>PHJ4jh2u+|;bc7JbJ=T^`LO|i?D z{7c@LJEf*Bgz%ss92?B@6}ijfS7MA1+2$+4J(WR>^UCVhN0 z+%Y!}=Hh`p(_}<9tT&I7PQ1krz#-#khEr~uDWRBp+E_nKCt)7ShU}wzmc0nPpMPSz z5{QX6k7kil4I+SRdwN4m1eC{7nCl%0c(GuKppgzZ#Ts*Tw9M(VC>AL`nhmyo%m~5H zEG^)jQquCTiP+%UqBlx(i`ggB@b{7MOpHs!^{9gYjDBh2uTKyCF?O)HloVc{nC6Ym zF77OdnW!DC)2yB*+KbJy=#3zdK}nzP&%Rm0_^HV)=e|DGd$MIk^Br4u zE-jqyO41l}xke6B98O8Tqev*Jf@@JVz1J4A<5BJ9_-UJDE`|txg zIq0sKx~8Y0?oZL7+UjmPgc9I;W5{V1HO<c(1f z2tt{+?(t^Ms0N0aZHAn`3W=hDWEZe0_AIZvF2)#O2m)6p>aINy9ReQL#L|c|z?me+ z(ZZ7>W0uh6Lk*+h?btXO4|i;T z?~jXOYt+n7h3kh%2`(FjozXP4K?9Q06%$FYg<%s&uqrFCX;ZSje*HQjAptdB z<768RVRI30}*iLJ8=>dDQX5u+oNNuSX6ZSVt9?kdQ}! zLGipi%Ko%8AzE!y&Vgy6sA>BZ98+6ctI9E#bjLA!ZqBNh<;kjG(ppEcPGP`dBS8Sq zEFb+#ta>&IRTeK8G6u<>CzJvACm$`<)Gs$>9$LfS@JCFig_}yS<+Mpz%`vq@s7o?; zoM&gss+I4-hsw=l$}?h?M@m0cJB)YlK7JoU?(ro3E*8ponv$M=>6bS!HnOp8HiDc9 zakfY+Z?Q>&e6l8pRrwX1-42|)^UJ;oOk{+#$hHAB74PRq{s?7T7rD8xnDb#6Tthe~ zoZ#SR&9@@Ivs0Fg7?30$?p}BwOuD`Ai-(N>LPpTYDkt*kDMy8BvP%z~Ah9y+%j!PN zKDp>_W?+6SII;;@;Y9Rdv6qn*6%{w?S%JSX z5qy1RE?*aH766L@(Z}oK(RI%)tG8MBvT(P#9IT7^iafv7FBcTkBhc`1T|ij{jgjof z^V)A8pCEUYf#Ya-aifwT3MxqLRFC&VC7hGG?$?<8$#MW@Iyvqtat~V;UgseP0;LLB zEHm=zPQb$jkXEsnz?~p^30Iqe5Hr*s2Ol31@B~@Dk*}A(;!-Rat)V)bjvj4%msNR4 zp#3$1MJm;9q=ai^ZL*W<`B?!Rb?}%pITMWP)JTu3JKO&4-!P{TVjSi65be-#r z)ipL&$HpUh?vIV1V^v8?L`+ytM%V2?zE<>PZ%x)mYIkMS z<4K=&Z)%Wtn(NQ8M59U@wv*%|$$+in2W`Gjf3laa2iJO)>6Pja-Q=8?X4^%~YO3RS z?B&iSUU|3XE9^9t&dzajxUnw9sH*z8RRyWD%Vlb++`_RgMZO1C*)vQBdgcY0TSDwi zBkVmF;uh2+T-I1^d4pqG)+?zwQq(V2TrAXjU`?TVaU5}xBkNLV6_2R?tvb)+qpRI@ zq(nr$)HL^!;5luj7L{yr%BbsZGN`usWZa;Ohl|fsd=Ezg;<`j1FVS$!&)Y72w%^&A z#v}G=c^`b}#OPf$qG)!*x43zV;qa%>o;AlviCM-_@T6M%N;9&{ijn$~Uz*)7Mzx^c zs>%gDjw9&^XUC^Ltk1XtF&Y?3=b1Lb=;?cpaG%@3W*pW+YK3{e#2Q(?yt#8^Mthk2 zf+yv{)2CUfMMe2Z)>Agmzhzbr$~@uF68efqK4G0#`Ozpr(4EHZ%ZV6xu;(KmoQnHK zbc*!sFZ&#)g!-^5ir4rfF^hqi=?h$Qe(Lgq4{i6oMkkd( z+7(Be@9&rT(%`Bl&v_zqU#LAjm{?VKH$Y6r}ST;RH}?iwoB8 zJ@3Q7daNE0d|ljaIYEgIWn5QcgU0AFscA^lsJ#mo`pcxp>j5~}Y!ul{Uc8~vCr5iB zl}Bt?=#BMsus1#+4kQpq2Q$=mCV=4yZ_6kp8d^Pm$}eOJe8qH+H&*tGx*u|mKI zt~m@-yGd#QM3q4WO)KF-t>gqy;8`s;I-!La3$6P%t?-GGa0u`bq6T2G?~-YP(gwTg z9*P-z(yj&bf3qy4bW$|PG{5lXt9lruY-*a>(Oq~UVEUWvoPI5%fQ&GB@bjnYV29eS z-S11+x`=Fxe4uLTOAI7~aOMZPWB5ltrRyN|I0sqvsYDp18`iIr!FL|EUvHK15No zo_Oc)nwbCLkFli`0<`o&nJ37P8 z2)|9_et%}743db5=*ADf=h&?+I-PY7>Hj4j)HK8^etbSX-1*AC#WEv&6t$J6tE*ax;eA8ahyIMxz31a+Y z->zbA>}}Y&>jLDV$8KK%hxyOl>E1Xy-i~gBvDd7H{Kem5-oj83zL;>$ZYl_cXQodb ze782%pY4LL=3N3ssSdd+@^@cC%-a+$CN2fwkRTKk6e_aL*aFBfH;7%3b9cbr`dfia zX7#UQbHd+Wg<)fEQ}pfzHST`CQ;~M|Hzzt*y+>cXIljSkKSd4oy)hi>@i*|{pB|FNQ(YT~%Y}w{;*URgt^fhLm z*t4o&D&&}x461ki3_YauO=+Y)^7$9*4BmQEoni~2@FKgk(xNp|;-b4tX~T{ytgGcU zjrkwgo|&D!8j!lSGn^B&UHduvX;jk70kw`BYoiNJK`ZbG{nC7Zw;Y`uEuwi|NgsYe zC6f+l*_8xGC`Qh{&w5;{G3H-qW>yQ$z3J7jzhCPg#%N!x;dZ&b!=}>;gNXc4CvT)q zp(~;q%9RMsw@g*a!(67H#d4S(v9G-;FvV3xGmzyEuod$VY8I{4T{lBPw?o!rd2~L zp^6!aF34BA?miW0)K!4jQulbSpvHg3Zw0DyEN8fr5d1z$Zyj-s=tt zms_o(7J(KOvhTz`zh+8AM}ulT%OLmC%bgIqy_KDsR$K)8LSM!E^%Uw*9E(m=!t2aI@+#B1bgM&%%!t7?PQ9%|KwNgwTc6czTW^RT>DzYXW~X zsG<;T!ABaS|I*0wyCp~)D;lvBLtT)*`(M@L9Y=KDtCOaD>?;fTB75`VrYtrhTbj+U zx{KXSrfmW45c#}RV%cWA$y#Cqqu1I+F6l7j*M8RG+8E0)GWgh4E-B&~pS1>%XPn!@ zMWK8v<&9VQBH3Q=7c@_EMvESwoN1+X_!U&&I#zWMJyBLDl_`kO;_uYw?)dp8v}81* zVtuUjRJxTAQP^i>d!&&oyu&X2bk2&Dl({TF{UU^kqsSRuc}gA=XVB7Fca)7nPdtu~ zqNL2Q%)w$YFwM_@IUYIehfZSWfW>HL#rRF!%ZL5k8RosE7JXA}P;C5x>&(4%nWIq` zQ6t}Q{~`N2j=AMN35i-QdJ{MojPw4XKv>thY}cgY^G4h&YVtzN?##P~ZyZ?9f`*g? zxGm*MW?cpq^s|Tgx!<%zKg8-xHcKm3x)nLQ4_qlJ({oDs02l1h`Skc;01IV1NzR3p z_Z-PT{hloP@_59~t_ST>d2pJN9q&avh;WziV7N4P=fIlLr}?XDhbiCDLd!SX+@7(e z$zSmWyCOR~a@QmUhVkHo^ER7rm2?}|)a+Wel~ZK0TCA?L)BSpwmTr`LM7p}pVGKFX zIT2sJWBc%!EitJe_Ow=FKa?KQx-CZrkMElECm#%pbxFXBX((J;`k|F9!Q%e-%bCL* z4>Od5me}^SfAfox1kjq(lYI3wSB(4 z31KEm7PFt~HuY%U$8WRAX7Kq?(Ngvh>g;bZv^l;k(XmlcJ2c-!F3>~{p*#tBkw!I+ zKLx>=73hwyh>sGldRXbNO__eAN=5RnGsk&hJ^RZ=W~Qugao)%wrLwzzCU*Fk{ik;0 zWE@sLd}628D-AZ@f15K|6M__~+uc)4=t zv;4EbZci+ylf}IR(M3l}@PU$2BJf3EYa+)r@ny!GVQQ2ostCu>RzfPdY!PO_err3_O2$%rESt z75!^S93fMmN%i8Y460k@j3wK(Av6+*ZhQ_I;n*m=sjK^`z{ty~Wx*cU1DznQym~uN|5Xx*{b>dzq~(NfHA&4O^3X8w zlAvh7TFVHkV{fBHR0NyTuZxlTTVvtq9op-vxonmeC9Z`NA3jy{TNAqHW6ibM@;gje zJ>TC~JCfgBUZc7NgS)xQw&C(OW1&0mcHkg~31jwHtCd}3jJdPI96OV5@mQ{f#KE*H ze^99|i8i{TF;Da_s9Rxfa@vE_Wx|$V{<3$_NmVHgBFo#l;Il(If2R9VNxlr3XUheM z8NTZ(>nf4apM{UKdS!`)SjNU&@S^uj@y~JSTT@!OXyoM>YG|aAc(hy0jQCl@8W(K7 z^+S4H|K{41+!6<^ruIVi(9LDz2DTY%SG}!z)t)++7T+ouO8rKLVBLJ;N<#vW`wR%uIh9ep8Ev4;Ece4+vMYdj1=S-`XmqL?1xw;q~z zZ#Gi*O1tNRh2Xm7X9A9s<2<2n$*IsxRIEIuuy*}7B!$sJlNZTrl>|{M+M^X6Vr26b z!A)T?1GOV*zLVV??3@V#;zoea_`1nrVZrlVWzMri>^LJB`^M`TS`Lwtmt0S$LZfZp zN9_D`XUy=)I1|A_aB0j*Mr(p6(o)xdy?sUWWmHKO0}|Xx?~#+^C8f^=;HwN{)t|oa@0B+vE*w=Q*ZL@yex_x({tyvl zDX=e2f(>l`A$?inX7;GUKwD`-B)NzOa+PZ>{mz?yn;L9uyb00PjboQ~+9KHO{6=%1w+?%TnDxEa^3wNQeT7*LCW!qab8wc{ zsCh`dk)}xX=Ey(+H_7Tc$Ppglqq^Q-`F&+7zKBi;jwTnoP2=UPl7iXI42>?sq${^lrD#3ag;@)8M}TTz6*Dm!4mM zJokR3Eba52?%|^YUtw!I@8dGVr>=2}aP(^% z;m`SxtDA0azVmXM26J|qH71u-uX0aLi@xrqN$?q^wL9AH2Z*QDRDCAcAyynfk^^rz>@;--s5o#p5qlb+WJI5A=@S9J=#xusDe$|D0mM;C1-sj(dz#}^G8 zQtsuIS9kguy5~cjPJ{N;W&J=e_NqQ5apNg=CZ62$>fd;Km*9z#>k6u@F06X? zGMGzUwt0fjn6h$t1rwLa8j{Bx4$u9%Fyk&df-wsS(cmS7cW)|HaJg3qAO`Q>pK#tCtp=!TjUsarq>c2 z%u@eJo!e~M@0J~;Jh&WP?3JADm=&(*gpgOq`f6vbsXNJ3%x*8n?qYFy$S|G%`Pin` z{Q+USs%iUQdsygaysVJc11z$bxXEZhJ8C_8e?@f_9l?;Bzxb@X_rev&{OtY~;WsUG zRghKRO}r8o)@NUjbwU`H`tQ%5_$Fe-{2D*YIc_i4ifp#*N-!Q>??+m`(sZ>J6k$4h zZn42ebbf=n5Kspzd;oe&&8BP-p(^yE7llf;B1OsP-Nd-F^e>{D~4ZMA=G408yr1*@|wtZL^+c zJ+`gdz7l?RO-+s6Wj(Ki%rjZ*h1?4BHj)eDI+BwniY%$1(wP}Ialy*}_J3NF; z`*cW**JF)%_`zqLD9UXlkwLQ(NR^B!wxwEMVmmLtNF?)iUfSQ?Dz!e`Kp#h&mj#h^ z;zB4==9q`PAjh0gjfDuGYF|Spm_nUFZ((_$M4;punhzXjZ~hOswI8hjVLk@m-SOJ1 zI?j5sCa$1?r1=Xfm4ig5%lKs`F#HA2dPfM&oF^3jMZ*H9pf;ty+)Ht|Axt#DR3y2f z)@ULC6~MuVAK^oU8W5cIFKe^Apj}r!_s&uptIN%w1(d!7;nn+p0~FvN#snltRa4mZ z&Zk@azbK6nJX*tf|rsRHl*_Gs*uXxH^A6TSZ#3I7A>S&_gu)$AC2DgLst90VGJ zujlpu;Snj*A%yf_pc&5VFeE6X_!C`wh=tz&8~*Se2im0gi;n#JTh30^q`Y?C-m9JZ z+d})3(L^t?hYD}84%rAt;eV-fDV(8Wqx#EJQ$F_IS^fG6o7IBilQRqz86Fe*H)R?J zQZ$k_?Y9D$g#GCi{%%!#84)clwadMYgUA*s2TPfyob>VU{^Jn|NrvG|TBa76B<(H)!bZ~dtS#Qjda>ox!s()qn73=26&!UCZ(H(Lm029AaGL!PT=`{wzx2pZ+j1d(|a3gK?Gt#z#lXr#IiVT zuq2WM@2OeK0u2JNA}$SBc=4JCEdzE}KEkF$@PhB|YXLCFP4_x%4ipIuml~7}8Z;cp!4UM;|}f_wZXhz!u_djaGy^4AuJ zfHXe#O@Fn5J|`50u0`y8x5Jid#^p+OxayZ3HFQl__*GL9OKmSQdeRaFka&{y?A#I+ zy&|Ip^8|5QsdL2qv~ym!s)$v@rYIXXd}sAH8K5uqyf6aqqOEfQ!!{_*c>F#0#s2i_(fDKE|rF6OCw@HCH)LFmGcRfHP5eI!YO zdbNMPmy{67An{jPW&J-)!}2Iy$2I2pA3x$4xHEt-M|%k_#uv*))3`%R1KHSL?L?mk zTdwDR@OW^(<6&0mkQXA$IsCu?gVu6T!m!!X?v{SG;Y@)y0QMw)#Nh+pxI zj=aOKs*`A=M22SHTsmhBj-0OPydP66o-K3tzHrLuRjl0VOs1@EO;P1F$M{RoIKhRH z`o-fA3kF*4Z;wcA2B#c%-oBGQ|D^1vieim;WriCZAtzPO)5q^lub32%7LoAv4Gt+q zKl{2slnpHUh*^}cPivGZ#>I5QT$q7Bf}8@vfydwmLhyr3V;J0%7GgKsDIz^j8{%ns zE_=3ze|=CkJd1@8x_*!Y!PnyH0hXBo(DdsNVv0N6>wU;REb>dH^Qwb69EMjiDLh2SrVI+-B5JtB(*ia=+#p0LSs6wl_zEEq-UuzXOyW z23f%nz^6Ju=PQFGx~$l6=hARfEpA@`>tG&}>`w##Z~ zh{(M$Rnk}^2M`iO-xuGX0%(|+89a;x;&?#w4*nb{?qb;>pq2iOvUkzpq90~`1cC7< z33}r_n=weNKhiH%g}GHUn%Fgfg1_fCu0U8&Cl(Uyq~<)0&BkseCl!I_KBinVZD4Wt z#>w3_CkK%u{t6K^Eu8{G9FNmO(;@P;u=63(4J@E+o1Vzpf5pz|Jn~9QX@>8IDSZgj|K!pDjvy&?=&p5;X$HKQ|f@N zBki(>AtA^RB4CCefalw~1kRJ}Y+-adsIuagexYyQ`TftWf$A3~Y42xc&4+fyiqS00 z!jCZ>$yDdSHH4&v}D=D;EO`fpPUZ*XZkO*0&o2BIzj!>(pJxvy)g2$Ud21r57_!1<6_`i zDuKqe5B-PXAl@+o4R#TObE6DW-p9(bTHs)R3sG#;{z$d=c9+JHuB~UehlN5Feu4q3 z6AV!^Cs1q-V!Pl8GTH>f7{Ky+x=ORNv-3zxHxG$Bh^Rrd4($M3+4T1|I#a8dcR}xY3ql z!6@dK$DR2&V2<{`2ApGhel201U-do)Wo`Fz-kWM^X;lP<08$J>5JSKXz5&r@0?|4{ zTVRAi$@V6Y;wM0C=Wo%mMBmuLyx9DGR{YDdhY0~+PVTqyXlHTIIh#X5!bmQJ@?5F^ zG07Z~b6Sd%lXE{P8YV4}y^Bj;ck?PK53=o9JOeGqdtm%u0Nr)V^xR=^k;CLMAap&M zc%-jR#4Kc`T&$LbBB2l}Zc^(S`Ph_Cu0M7Xu@N-#>=MF-IE@DIkrFhvE zwPy(^24>w0388E_A8PdHz?$YUi`)`He_17CW2Tp8Ev9^29+Hi?zm*Xrj&K(E2t3Ig zxWY<{cC?u$dtn`af}q}bXfXC-EnG4JQ6MJPfypzJ|_kDJE=-3jTDMv+v_|!(=8q| zHMw*6&GB}E+O+!R6c0*&or{hajLna2ZImdrbv2}_4hd1e}17d4XpYH&1faI z?M^U}i4u#MH$BbE(?GB%Y^46$x&qZGomSz>vbMDrmR>oXO7(3i+g*l^h3so~owS98 z2|GO9jyjQ!x1TBXO#SRS9UH-lc|IfrO2|#sdWXD5w)U!Tf7}CmA z%QlkV8~$=A=L*=|vlFQzW(2Y6imJgxro!%aNsP#t-=*qBgLvy3BmO75rMQS(0~+n# zk40z*rCSQC`uZ(?4BFauWb9?MeLg{Qd8zW$hYX8@)XvssMi1{$fsJ4jH>RSVEjBjR z^*yOrASsB8xUjZox6@{}>NQ7beU3};W?7z#rukaxIAQe-zrUgiy6Z(!Cd zN#kv}iB;89BI-u3f2%}4xlmhw1t;vK^~Fei`8tz0+vQ)?tLw6tp_EgrC(9xd8L6)7 zd>$f~!V3AitZN+g8f4wRe2YKFyIe%QHr#WEzdm$Lb*0diRFOCE7#hs8C(({&o11wvE9b%SOWY z)EI3wlx?}A^PTpd=R0{69?2~C`mzJ~jnBwJXhXz9tf2Gy!iJ&75ohW_L}N$?zzcG( zC=R7|UF>)jE=wnS`Aub|Uxt%9lb?88rioR-#oY|%__-1WBZ;Z!4CpTuTLbdsbt9J1 zQi{`X*Yi^u7nv{$qsRzPIl4DxFd&_+- zAF0%bo#f<=cC#C0l(=AX9VVjn^Lz_ANqUyT!uK%EAHPw#NM9s>bZYt_FZhE=nGOxI zRUE>Q#K6!zN(-8R73AaURuzmqdQdvf8TFyuvG24Va5;}~KgK=k(+FE2=bdkTx=|_64QA2;u6GmVHyt4H6C=*1$_csRk@SVw!0V)wk6ymx zmh<)LR{T^h7SleLe)h=4uPG2-FCSPikmgn?GE7}}L)JbK}#mjX9 zpHE+z>8I%`$W!4lOq2zS1A@t?X+-f;Fk_L%78g@03B|C4lG^%?mbSc<#&3ay4BBk)M<0+m0zB?VjCS> zi-8}HdP^OCh8z4L^^=-eV`MMn9m;BTO@c@BOAD+A9T>xDw&|)9fi!Na>T z8o@@S^KLISTuimeI1>T8hAaMRP*uKuWfD$Fm!Hj|AdxCIr0jI#Zb76++TzwPFIAP= zov&XmF)V*JR+IekY-x`FcpV!eG(O*U-tf?J=LNH;77SH+37KL#YsXTt_o@aOT}dbTHL7@+BAs$mxz3lP7kHZrdVJz4lP?xj_m61n zrz#$vRizS?=qt$Q;xF2+pU}2{m#3CMoPq>I61gmrOOQ;JB9kv@#8dW&u{*QEP;e5E zoq0u0m&J^SyCbq0NOPF%0}}K;+eqcpwW;yv@WI&ZurZ5B(q{?0CYv+QIzAOJOui{) zKC1*~~%DfsqWtrp8oG}>_$CYH-vTG;ha}X%8799Q<4~q2^VQLDn+htX% zI*cl)ADy~M&+$X&!%gD+5*b(8d{a?>%CIXO^4>RxY$myhl?oTM*3uV>PJYR+uFKzq zYzGUIMzITOnZ#aK>!l{}3H)5We*I=it0}MU<=$nRz41Gzq^TXBUPe>DX~}ws-Dz@X zT=SELiX(CKF8w%?B6+F=hRBI(gsVs{q!uX=XY{8HDU1t{_FlT+pvwe^wzKnm1cjeF z!eOSfc~~yscFmpHe`iIk4yn?C?BsDiiyhnUhmxZ70h%OLi96m$YiLUSh zc9;P0G5p9j6UUPjW4^V|V_OvrR-w*ox5SxC2IsivnwASvAt8stqly)a3kBO7^_8oW zEUV==e?sD$s+>*L-Euy6R(J&0TBenCaH>9j9%>a-9D8z>pEe|Qqn-1nu3Hf1Yf*Nq z`sGP6EqVf3d`>iESY?;kVPSQSwR0)*9FW6s4kRr<}E52K~v#)*$MXL`{2wq6< znZ^Q{sNf~4$nRjm#zo7o|jn7*ZMipnx#W2LT2USD6P3ilX=sH(7HCq?Ss3vNaegRRPJz9wx z4b1*o`_S6NIw5mRH$J3g&gEVoRY|*mrPej6q`6st<*Qk;5j14)>J#>22FG)BWo0nH zpkaTvVTN}7=9nZmGOXS!tnt>W9jr4_ZHqTM$>r;Ao^aYQ#k4QrvpYkRIcyhhys`YE zV7#k6aa%1*T3?hs3ea0#Zib z>iop0V^Ok=`fPo-WM|Y(0kXJiZ#y8hCH=Y-h9EXuQ8ft`Pd1@DbNE~*(d#wU(tk55 zpBjCOgAz6QXzVb16w#S|!p~5&bk@BbIYSUAgg08@AOe${)G-lSxtK=Fq@c*S&9q zqoyI5HG>s|eQfg=?%+hO0y2sQssG}3c35Z;VE=0=FA9l#`svc$?DKThKtYcZS+HiK zmZCt|w@XABA^gDcT8sW5^&Ug9sm#zkrRG67ZjLMZOR~vm!;ANEBYaw|h&_8^CG@cR z@Id#SWBksn{xO?Vo~JXA_Os%`ogG&OF-NA}XM#_Uh6^8{i|(0l3*{bdj!rWfHV#l6Zk6O{lA8Sh= zPcw%};E(oZB7STN+-G=f6ke=k=gRv|jr=OTtY4qgtzkfzrJE~UU~0X77-en4eGC5vQCF_V+M1T_#LI-`A{Ax_DXP{yksY_Vry5k8!hB# zsxI{M$>al}_QLDQj-$)GKgVn2sAb$dw@!?)Xv~l5wgNyL^9}Sj3$&4Yv5VmR<(1TyK0 z+1hKKub`DtUNuY`8rnz_vC=5xo-{5~jHb{%E8rS_JmzlKY{yC?wewnc=FHJ+-9^`_ zja_x^Dkfr+H*ZkltUjuLMK!2rs(?($EKofZN;y-d<6Aa(8ezR)X3e{sTh#NaeyE;u zZ`D!hP3BK!k98Y04%&HDW=enZBPpv(S`y2TO_)_T-Bp3K1_o|H_!elWrp0PJYE(ZVVmT@nk9qo?bB^Eih`kiEzLTN3ZFV@4pz%Ar$g+^8^p0gy$fv_jwb!AwDF3E z-`cS5VUMlkFOTXgF>hBT7#FMbvGZ=76F^75j?ECtHVnf(yCU>#+%dA_W-=*uINwSyq->%H`5H z@gbkA4Lyr51)p9CFHLdqQ#)^81JxgEls#qPK^E;@^DZ7AGw1`#f{XSNU|G$5U(qNI5wyhTi;!Y}Ev``5706#PXAKJZdW+w)%BV z*JDFibxru0Ma7-?Iz{;*hF-^UQ#zBxk0RH2rCTINmc^1P*1T7Tax5jID{{{ZfU0Ir zGKYNbw&i{J;6TOuy1LyVQTKJ9(u25IA)->vhSKGM4bM8^g?5dwMQ6c9N z@*f#s%o(ovH0e#1W*uT-Fv!k0F11EEPKgLfHgH+eXuc<#*Zvegua3pg!!aj7z&w=(fSI{fziLjb!3pKySq{D{BJX7ye8%Kq% zq$Umkt^W)B3KRqFWo=}!DcA1Djp>-9G4xGb4G2&^%~gjFO?TjdMu9CX0M7FRa30qY zoe%`C@{r>rId7!_b?m6JVStYv0DP?T%~e7@X6QAC73lC}Aqb6#&~@X^(}pOLsp_U! ztwCRN1#7S@paA|asFy&7dJZdQNP=yo)PTFH01OsP>kV55W!?XRDfhDx+-OYt4bP!m zDlEVzfpzCz2Dic^you#OT{OwNB60+K%kh@l7n1iljo9o0Y!ZH_H@ZX?(HoZMkhJGH zibw;%_y8uD^N<=H3SkABeeX+o0w@>1x;2{gTvoW~4JQL&C`78~?_zqbbDyj?B`2h#VOF3Zlf@+FQ{k=n2|%*` zM_O@^^YSonJ!n~%g6GU-KSRS%Z5FR<9n!}g8*aLv>;FH>1ZVsZJZD%#83_{tO_^Uk zWC2n60Em?v6xjPUfL0GpO$K0YoPvU}JQJ{)m!Jb;BWog2vzEl5IjHC1ykRYg*bNx_ zRtKx!V^>+wMlG*O{3oaKRQsQe%|=O1z~f?KkYLb%fN;uYAUweON!23&gUZFlwFptD zf(A6EF0NUfW{BDJOZ5aZV$j$q z)B~u_{V$Ixfkd?hv2amnSJ~-l%gJHE#ohig3LA+!JzTjGEr7XA%W(ag51|fY zo$E)9*sng*Wp;L!_tO88+uXcyEfJtWO7G4Y))ED?GC0F9o!Rms)T6-1{~(Vvg^(Kj zuZSsy(3m@fJ?7`2`5Yn3zqqw@D5p(8c>of!|9mOh6Ty8elM{6R{Kplai~c5|9GiCa z$pbMBBOx^4NppCdag=pWtP^VX-S~{Q3C}6nO({v<5=W|K;Yxv5tdEPgc z80oCkZn?wos)ZJCm+HPbB5oJb6#?SA^U;FCr)nhZyhUpkc5PmSL<$&7o@yc=XGb72 z(y01@%7H{fsoFthXpjCAprs5+633d6e1#dmc)6{B7J*Pb@3tm$jD%^5QYk&QF zg*lH~*{P(KMMgBFyS6WL*`#*PNA*Z9@)U>pk5xPLIA=fNj_cFY03^`mFD988NY^bL&L*!Utx8Eh;vVj97XbO zPUPy~cxmsB-<{udZy_y1v0<=2LqJMnzDO@Xs`s)F0%s^BErq9HE@gndS1M0E=tkw}11Y;L8u< zUNj)s@H>Z#bqqtyL8WgiAl95fc+G-AIhVe7!Vt~%2=EOWd9Prd;F~sX1e;%{_|t>N z{+aFiqnz;rF+ex9;vv|9iSHphL#enipfX2B^j|R!K>O@U(JZ7+XbehG@tk)a?5X-q z&A=nh`%nPciGxlTcL{c^o2RWYf2I<92XO3eHOx8c=#R73%`3nq%QkT9Q8l(A_Py-K6S zO-ho034<@RDZ<1ds(BT3Z2kKvko$+lu1LjiC4y6I{xA^>zFjT#>@P<^D=C8AqWNA| zsd;TZq5@m_RRiKriE$wNGNsf&3%85pf})aA2sg4V<5Bzdgq06)j{zD+-V1-~gXui# zQC35*Zz*36g$q(skp%t`njka^LS(Q0zurLoDP~9+2bxK3SgY^BW&_=FdBAdTaX@|P ze^d-1D57@HZ`HEq;`nWha&7stT;)*|lki8(F8BVhZ@F5m^XdX&uN|9Tp+yxq;IKdc zN&+%pnxH>-FiixnGbZG?19%4Kp361+tHA^qj0C8V_!bQcyZ)^OEQoTt`qEK%B0q0J ztO&B3A?{K8c_Mrq@RxZ>ej5KaE$XKv`^v;$D@JTDx)=C2?Bl?plNEl3aV_&7JLd(O>ZbAl^w&+%2FrG+LG{ zgIyjQk39Jv1sY=iPt6JbxPs!h$e?nMeA8SZo@y-$(7lv=k{7Nmjr?eR?WIu_pH+YP zGcrs~6!-!W(X?Lhy-T#Tz`5H%6~#A@amrvrD8skl64)n1{+@>x!6i6z1*Fga$tMUr z&=1Mq1J>x5o^CtyX?F=IIDU@Jj{WdCc24?lsvR`5fyUUxa64$m=_+C3e^M3*4l30h zn-8p$06uhnli&fAw9Ef4SFu|JiRbl4tqvD1{*TVy0;;P0@A_RdNNqp?$xSy%OLqv8 z(h^FCfFPY)6xbl8(u&d@(hVvgh$0Qr(k0z}f7}22jQc#t^WHn&*Kx+sqwH9Ft-XG0 zednB?DIoAl9ynuAju!AVSI@D*Rh1K1t%*?w5oz%Q+^~N>b(}hw1S;wX$X*8gP~Ix3 z?kn}RZE$@Rkr?GYVl}9-zk5v(NCV1t=JUZN|4YD)ezCXOEkUg=?5@PX<5S|4L-(Yk zWT8@D%VQM*Y6!^udB3L1#kUPC~je9 z!F(iZ+wTJXMEAXcNw?-;+}KKxubX2vuH&Gd0$Hh0-#z>uj|HsD(Gm{?w|_0p)b3*v zPb!lnQb&_JS;MLm4dyP~8smKxpJV;E@Y9$*s#+Km22#Jg5?0>wd8CubPOGm~t0Nb? z=CK&ho!ZdMQ-b^Jjy@q|yzOX6Rn8u}+o+$H&x!5O7~%Z0$&fJh$UR9-rbYHUn0>3x zbdHaeXJ2gX-6?j?`6NhP2|g(F?2DMTp}D8T1=C2Z>q&!&j8%RPjW_3BFMkTU@`OsP6ai5W$J=kgJiVQqvBtO`d+yypKdrTdiXA2#+^z3));*MNXt;; zYi>h*xwVkfRE?{y8Gdwq>j(K*|B0-Qp@)xYBegg#YS3excIOG>CxlbJNa?kQ!Nkz4 zPa36GYoa@bJQbx1&1ZZ`D-40YCbT{lb0g?npZ*|G+`MghSr?4_NwLl7Wmx-FFW5vL z%n(&zbd_3xed;}QT*}5?-v%F0()XNjY3MRi+my;RjU5BZ3~KhEw(2F7QZ#zx6x>hM zb3H{z^`DFWAMg|m_6ez#Qm-EDpux7ZyFeyrxW!RG zX~b#Cvr!)tu0%|ietcf)5}Uehz@Q8uc z=sgaQMC$08rWC*Gr{RqM?804}FwrVvy}7zEYFMi|} zXV@yPVYk%86_r)=w(L$68M1qXQP>ZU^uS*B8lo1?9(LjcgbKUtK~IP4H@zL|WcA!l zm_2Ds!<9?E=Q%Wv_ZQnq^i54n3=rbK(b++y>amQ?g~invj^>K-d0mr0a0fQxMEifh zs%~IRm~*;a8*v=vp{xPCFtbZzF&+m)Uxw0^^abiXn%b9nrGue%|IsX;3&WwupB)Rw zGesTlYF0T^i4RcnB%rHao+r_y_ZeHE^smDHJ>^0fM=W61R}wq=o&EjJdj1mP&h^*E ziXdiqWay%E}C7&3!tg0Nj~mLd5c-FMF# zQQFTvPLfGC#=th65#Q{kuI8;uXYgtqRM}cFok} zaUAvU$f#_om2#HvS?<_a7rnO-LvRO#dc4%n)>K)usa1V_SE;rm3#0OY7>|kHxWi=z z%gR)^(0h;+YVQSzGo&uG`)dPREynwDak#1_Y}&6+RQk8)Rf)3NoyV8vl^%qF`^bcg zi!NF?2AgOmCx@-5&wgu8h7g)Z`zzDJgqvW_!tIwu4Za7f$4+MFwcob=Y%~*_?7aOQ zM_5ukc&CznD6HSHx|&6Y?U+jt7ObPiI@v9#PNjcy?I{(K1t;{kjy6j5pR(2u4jkqh z7#%9yUdP;lkQ8u0sR+-k7_a-3Wn1>9V5f>!ukM^y4Sb5akVE~FU}4~a-s(=%rz~dq zicOy(=iAEPaUxu&@u3|-NEJ8pI>L17&a%i`fhW(OUi#$z9z6#^IB+6Y!M+G?!)d@B z7oPb~pu!!yE6!Lf-rT5zkdEufB6XjGH==|*#|rvc?xsE+xcvt6im@B{&VAvNo39)B5Cdqmq|&=SW7usYW<3|DeHSFi^)JnyO3K5B?p!_`0eQ3&lzI zoOg4XlRJz@4=G&`$k!uahU>EZ!O#ZH{bVD>1!?cE?_994#b@3g(SO-!nf&0m$rfNy zbY9cDYKU?>E_q(6!y(47Pr#R;Nj54m`;ZT6Kf-J6nQzq|^nag4L*Y~B#V1b~H+OKg zeE1epJ^AxJKvUHWJoee!%>H3{3uVyn8Apn{jZI&hgfj~oG^%^1d5A%h`@lChy-X1`-{64 zva*&b4?9H?p}2?gupD&jEer$kvxeZ-vvX3i;j-1YUuQV96y7_d%ie|rT(#_0vsaQQ zDU0$RJ~`idP<)bEC1(U+-C5Y1}o$10p0T#8~PR!PoMALoK;(5(MwD&=@x( z8*O{2uGs>^?A;>c2!`ZNJCJaqy9)BY634e0aYJX8VG1GY3ScZWk$?|+)g&w>+%63& zuzDHh*S&Xc`ML1Z!nx#x#XXe}LI@xN9+5N7V}q4P@52J20PBdCWS(^4wP6|`97s2& zqbrP%da0aoZM@ov!w8HkOqySKT6-A>KNzwRKXs@rk%t`KlFQM%K&VY}2qYQq_53lL z-w%KFMN+#(-RDfpQC3GkEeWT#S+^LRq>;|g7$~9kpc{9y?hrSoN%9Qq7JQAGf>gzJ zQPyvGyKSY;2XHR0B9G?RwtPzl_k6`<-!@cXC~`y9cUy#M*gXY<(LgECn-Kbp1{gte z=8T6k&V7vLCTdNRy)ut0&X^6{gpqZM6tpl1lQvF$DwZ6qBhL+z8ZAQZ_dOebbV>qo z*lE6##6vtkqlt^9E7#UEE1B3`v($)HvWnXOf#G$9;#ac_x+vu_x3VZ{9wiSSrn8Uf}}u!#~|(mT|`G)Iub z_x_l#c}wkjt3>st3fgL>c*ArMGZI`XD{4^N#%=D*iBm9-Q_0cpRSBKCOKCKX!-wNG z#n+PaGU9!rtrqo0)k;G^;78XD@sO00HKW^;2w8XE1t@jbC+ed2>bZ5|hjvVAHgTZ2 zU~ro~f9hKs{e@UadxLrF!?ppr6()#*#r4>b2;P;~H^gDi3lvU0S3IH162L-0@Cr=S z#fE!NUi`p3Yb}>WCUs5vd58blc7_Nd`7SF+Fq>(=!-sSr`NU{Z-BuCt?t;9Rn^E^k znefU+XkAf(AMqH5*dGhpLGgFeCT8WDd&`u7jD*cMu?C{04W z@$t$xtqjUrgIO>Z-UnZ1td}FWlrb`Gtt=j%%{m=w-T;4WM7iv>1 zvUiXJN+)?R`7Haz$rh=1bQl3YUcC6W=4vG6=24k7xJwZCyawSNiNSA_shq}Ct(i|Pm!IIw0q>lOwBLMR_OxV*{ zuIxYaX@qekZ?6~GIEUfeCGZGAIe&?vJO`9%*+3Xi` zIUw^778ssb+y_@-9-O-k;#-T1YmpNbt1ZNSX9s6{78~-R&5pO(ZmO(0^i}muzXq{L zFlB^bu|L8;h6_i&k}y@^84daoLj);4g;0!LmVo%CRD}l%v*Gk!@yV2ANHFi=E4y{C z;alJX@g>LAdnq$GCT?|UV1ZH~6}P3jG^O%zrr(iLMe zN|TNjR+dKWbY0)cpXEkroZ*qmb>QB`gl8#7zvA8FSl=C3{Fc=CRI&KJ#moGgaFl$0 z(Cl&DdGIzl{J!LfYOpld)ls1>!qm-?tg@v?f|zQF5K%m0j>BDAM&TuScT0%_198QFv0$Sh5XowQJa#loVmxh zQ7lg7cgDb#wzJ3E0I5C(dF0HI-l91X;)S(>v8wZ_fn~SvKDije>u>K;ZLnykG93&B zTe9-_=ixxRGa^80@$5w-Ikso^luqTuriYN9A>EtEx{-k#bpRNB1?`>*iiq#OEx9Wj z(AuWP#YR=&^(wLIsw9=l`9(U*e0=|fwm**b&YP)%o`eGHsuh~p{trs%(f;{ZC6hDX z*0;EQs<{qmXApDuxMODS@a4+n(-34X@U zZ;!lc(k}{Tg0IYWAd+LF+h0^GU4;g6S8e_5szY0*{Z=pe=Bn{MXeRA508&I~)e%F# ztkCV30zosu@ANE?9zB!lCWNccZ1ScZtB>@FX|S_Mb?;oLsR|En`)Wu9xqN*ymGh9y zH8yZ>H=uBsJyj@GeTo2BF2y!pt%Qa8dK|@g33-D>j~``5Wi92(G|w8~;NTh9c?<3_ z9BwO1s(|SgI6C|1L>qlC9{I&O{;Js$b-5qCIXT%qzudh>6;Tw~Bz1W#%)?&f88W|< zHAgsfk=sBg!`4#Cb>!P={lRf|{T%;g^-Pdz!+y2(BHx&LgmalYdOMXuL|VA-`CFsA z-zOSqH@s$DRah;;g1J*>3iiOuFD8EURiR6ZOXbbdzQ(fI&FqfS=~*nV|395=bL zB7dli%F_acQR&dIr3(+fXTB*vs@a?2B06-GKgs*`y4mnpLgkkg_FAWk&fbI890rYv z;UDYsFUTIuloPVoq)OzHIo;$W`3;xTy|lNK0>)_y4mvx^YqyxAZ6#?N zhP4(kh&OFj$kR{bKY zCz36|xwjv3JNEs$6zel^2}NQ6In*wCJBpm$EDSthj#XRb4|(M2{?_MKa+g6_N@wqI zy`O;1%uaHrRc+9395w2I*ax;DKmG=1l>R?~!mJzGwb3p_{{4}sLdbNi%frqsWfi{jtfa-B-(%gwua~AC%Mmmj* zeS>{Til1zDk9FpIQmxmW(t;0hsI=?njha5u=u5IPt|D4H^`ZwI|w3v2L?zwa>Pf~Cf)ayD-*|w3(3qO<0Gu$6{$jZsGpjn*3V`yk-BpTAg(%dyeCGV!gB|C=M z%!KT-263k~Z49Z$MNiF5TymNCc3Ta=B0WtZuG8w4GSp;Pa?LPl)^oMA#TMEw7V;j=l;q|6}laE{uu>= zZ$8idGh|gXX440vsvsmAj|GyPiwd_u1S@A{#lFmps648%t~CmwdayPO#v~9*dwz)0 zo=L&P9u1na=tFahSnuv zFw4gre;9itEkTP;bGVB|{1O1MeLQ4>P8KOTil0*f6T|lVK2%PI5V1Xv25~gwXQ~1C zG7^usWt-vGHqr-SEsN_D>=ehFB#!~rx? zetM^(AX)R@qdeORXb_$i;?YEnMrxm~$>@AxQ7I>dbQ9VFAn$sfQ~xE21L7E(qK5>g zxZ;Tk?^F!28?Cz%nCL%4p%3Ly8%hK=6oPc?^ReNX^Ex9vbEijJd}jWpIsw1OtG`)Y z;($!mM_C-j`v0Y08@A*metWEs5m&LzAWoO?G+gS=ojWeE6CkMEc}`3MLb6sE3b+27 zA`Z!ZhTwqN%T_t|yKdZY7 zf&dh|+J>kV#C!iC|3Zl4TAIe&t_|<*D_O~n02|Q-EG-sjRoIIsfPV^_3>Nv%!F1@a zw=!p;I4G+F?bLix@uj$4boXc;EB|ftFp(=k$#-+(JY>LI_mBY~<)wpV;CA?* zRsu+t6FW|}2LtamKpg&3o6B;YX_5QXc~47f@oDV9AK>L*I?mh(GoJ zmj`g7AV+4}=V?uj)9nOnnVXn@9*!LyA`JbpY$;T)2ZM<7O)5Z`9s+OB+K4okYcgC31FRouSW`3`TwN^1azV~PYZ2; zaV4a=9XAwT=?;#}Z!R5-58Ua3Nd99ILRNq?-4y`@vq1x-1p(Q1wQTHXaynBWo%~PR z2?PuEl8yg)0bBi9&SW#fKhWl#;&4WT50vu#k)1ivU4+g!Qcz zj)KTA0mlqrBUsC|&v%RpD;`llBR={AkZm|E9BIG(6}jc! z_iQZLPNSvq?;d8K(GLw;y&**T3F`Me^<>Nx^zR?$or>~hg^`V-ya=Qc1i8<%Z#T5$ z#n9DHptiBjHS_6dZ9ibvPywV?XA5!G+ldDqoKiV<$@zw5=GnP#7qL~p7MaICCkFEh zgMS0n4wR-Tm(X9l3nZXeoWx$uGSHs-PE~cPNp@z+0K5U`r}5FbgreF-BPOTEf@J>z z;=T{627f^gZkbgP?7k}s#{VSb0v63g6fx!R4fp~9NG_<&;qXH*1S`N_+}#xPg`6bwT?jdV ziXZ>|_*~TE!HIYPh2>Bq{+DM61t^z4-_F1I!HdL@?!O^7UNXo6gB(ca6STC?>eW#L zNQ!q`g59i3-7e20VJ#`t?^x~f8Q>J2aV`ZTQ54sI(t-g#hUZ@yw7Qo-^8MHCL|aHO zG?&9s#J2eLmWt{{H=UocZ$IYc~7kOOD|GHddAIRvm3fA7mmz-3tuMlFp0#KCX` zLvd>V#y1-)VDnC53K4B(U+9(oIe#obl6uP+t-S8-*&hjxbqfAXOq{wJ{+`F< zJic1DmxKs%s61igG`$pA>V&8(=TVB-v@!M&<;naU;dKI!?R!r`->Gas4y_k_jyu25 z)LI?*#~khMJvU%;ZcTpc1)yq+AEifu8jVtASsQsAqCgHe=S8Vnb!lB%5 z3;!iRF_NcxB)oHEy{s*%A`!}Nd>1rrCJk%aL4-D3ubT<^JX2_{uK;c#(cxDcoy&YC ztFa2?euutfW}ejs;v>k7cwGer^`v#Kz_+*kF9+xy@7JWP)JS*?kvWp_hxbrj^_pC(cZzV3=t}`?Y_~y@aLa zJ5CYqGqa8&*od)E^1*@PGNJJ~81o0qM8H~uS3PV`9dxsas`Idcb2lnr?teXE}UU!YQ!L(Er&#tn&yF~nO$$lJC^tKKi2QA71Fjx=>` zAjWNmu>0hEf_0t}9^!5RgQ}gPZjZ=*2LAW~*Ta?g^Q z6dgo5m!|*yn~!r@N*Lj&?%k-$bp|i;e(7QY*%}v7?G5oHx_cga?L=aJQT7T{_A}wi z;@c4s=2K4bm+~BsN?BeEH?IrKv8D;}F>|9;th3)JJ9|Z?;g_6AUCkQ(>Gw}w7EtnR&~&E8aAApFaZX3T7Lh=TjMY8g0;U#L8roBi34pj_+so0FBh? zMf%eX&#GD8EQ^DM0J6ZwDJsxpaSPU2+3cEP|J^9q|8%5%9My9C?BSoP;h<0a6g)$V%S;vH2*jq${s!~V=ox=jPa${Axym&{f$+} zE5JPya!C%Rn4Q1ZdNi!b6hx)Qvr>(6CgapW~X`PPJ17;$?Q%k119 z(`5{Mc42*mdf%jmk_0T|?V#rES6};2V8_VFfj-1HKH8aX@#&z8X5-Y?q-)M(yia7m z14=0leCGT?uHQkm%l68MhRT~-(-39Nm>ONk*ZX~hOVb?{Eg8G)*LK~PCuUma=r7iv zNbe?pDx1-#mR*}^`p&;#8Ln~w_I_nOpLW&+eMVP<1_lufz$*6=hpp9n&bNH63a0yv zhgJ@wQTx!C|F^)Z<1-0KDhG!(PwZ2V*P-N5{AlpI(8+>er4ZiG4Z5iYCxlXMUp=jS@zmDZMqzi&g6(c`b??-zSPH*_((QVXRGF;q094e7R zQ{B@)%XgHkRgW#|*Oqq+<}?C}%lDszh;y7ci+2_M8>3Y0V&)2=DVpHvX`$J51hQzk z!E;o*WJtYJ5G__F)>Pap;Oce#07PQAb>fMv+7F)D?(yEa`Ux~w8KAkI zcf6HS(VFn~3s=fVV;p~@#4}aa0884u3=}wrbissIjlMc0wI{G2jo2Rx0}kG!W`Usw zYvA3_IWb12q{1}*^k8_53vuud!CBw&(mAE~iue+hK=1%a%wvd=_8X?;n};p|X*D+GUd4d%wN z-Jn7cZ!#f#DgKe^%O46^OagTzG19HNHnbyOr#6BDIg*~S;CCH+>NY0>5 zXtH(BiXP}ykviT2te3~MGBz)lp8Qn*CC_cubb^Ob?UcvxE%=34gw1$|WB&WVPqi9= zId1vNA;5(#DIzcF&efasUU1!r6W9I|*CC@)zm{rhZI*-8&o3io`o2>F-BsE0BabCd zh}j5ygjZQ!&e2uh5k`!^09^NCw=q=uN=9(wtnaRCt9QY4;0$*O_eIYUd1A!A;}*gc zTp=EAPQCc{nCtap2xvTlz0?jpZPR8LwlD3Ll3Pt9ie~B8@)lo11W%+!9re?gFDc@CwkjKIyT}y@{*ar>% zv>W7kBoiOH4j1a@(2*(J;>1MOO&S)5n2da?s=FPs^kcN&TP8J!-|)v#=_yfHY1WX> znn9#y?~}Wd8qEQuH(Zaq=k5B@@OWgsdIay~elukcRx7?UAY`WQv?-(p7*Xi>aeSA( zcbzB1YQ1|*s2ZL`#*9}VZ9O5SbaU)7{ml-IKcMec?47_2btQC3^t5flx&XcQo+A87Oxo+QQZg(zR7i zPJVPdWaeNKRt;!!81Q;vslBP8^0O>@Nkl*IyXClvsG4yDe#tUsb+rq1oW3rj?m9QL z>WN)yh!F$vHh|?-%Y;i#;5s)-U_RY5_P%?5Sru(=?2v0SPdKoxu6u*f!R#>Yi)VF} zZy3kI6Zy}0@Hr!!a{GL9DZ*;!yqr}*k1CrtPeI23^Kj!?RMjPk6d_e{4wZ1487cqQ z7M;XIqA;Jcd_dIPnN#wcj}{FfjtdDvAF!XCFa_lud<87C5X|DB^C5oo)zgU0`#E{M zW>tD6sb^+xP9st2JzA8jim*{SJQV~|>Bny}EnyQWeW&2)s%wR1?^SS^s~`?7RJQqO z+B$trf66sd^usgh1qJ?DOjtQ)qtVhuPEs^DpgMYX=uE8QVw?|WNlnMQy1cULG`<7|5hYXe5eWy{)u5cXrUy@}{o~mihZ!5K8z(_XAY;mzAGzrY($YwLDM{k#Q z6Q0T$wm{Kjo2GCPn7Huw!4A12C213e1kI8cZ^5d1V^8W`;HL}!{-B<6fc`@k1VIf2m=xI&oY>IA)f;~(>k@M)A=u}>ktijMno#?a&MfjNoCv`=(X zD=$nN`E!VxrgpY8Y=7sD#0KFYZlNzs36rml4b-<9#KxwJiQa_bAoDN@kL10h4#F)F z$u(d)Y9Z#^ctQjp8STTtIbTo5%mhRj5IY7?<-*xI6FBk|iWw>z{>)am3_aSC`{FfIl8F*xAZS2B|;SL%dXs_PU zje|@%dKZXSODzS1h)k#p?h**7u~h?x=cKVqlQA2Q+7c!*Od4AjeE{vws(_x!j!+y_ zo^7jhXr=|hqaa@(3Hx0ai+x=%EL7z|11{Cjkw%SHW7nR|A6Z#3+5f(M6=d<QbVB5LL)j!fraLMlO?n;(E2Xt`s0ucN>i(%Xhn8+>p;ig5Yll8@Z zwbMdgLNRBAA-Un%R>q274|{`4%#2Nmd6I|ioB5OW3(H5s1GHD>Sx2fM;vx-w#)P@m zZzLMqs;PTPyUOJzzB8j47ZY%7xwbT9TvWx4xTs^koXAw=y4bS0C{149S+Qj^Z%+ua zqz>J^08A;0W`b5s5Ka+KtGoa?&0r!VqJ7!IWF=N1(Y?g+^ste2Ror)UIZe<)D?A1r z{uEMGx|THCO%0dXtmtnqB6LZbJ$zJ<1;7npm!c^SozW+AFnqGfbZrPbY%)2NjM)mR z>KlIcwwKmIUt!QL>`>VYP!SyX+W2@(s&IeKW5B_n*(j*l;U14hg9hJ5U3hE)=!>uWqQ2**pfo`3C;()b{WGQZOqeg4*j?guVS@@V0KiK3Eyz)-k2tcnI)v?u4KAHN<+IPXuJ;A^x_{|Y0n z)KS0~4{teRpgYUSTcAuH&x#>5f7%0 z9rZpvi?6jp)y!mva_%SV<*(CSF2Sj*bh!qGv}0p88w-!BurNYm=OYCk+Bne9>gyqs zD(Xr{g;-cxDs-mitdWca3xI7}*=P8r3V$ASgEBPAE-1>NWY%Z zR)3;GB^l(>drgqm|LcVtsw)J~P&{0>utQ0^ERibJJ?-7*n}zc!-z)+TXTy?C!gX#| zuyhsXq&@K+QJKZ=l3C^}8J*oQs(D=gZoJ0Rg|A3BMBH=0=lpGQ(axsyOxZ=!43F+| z`y($GZ?_I}uNtE%JvOPZ+cgnNHzd3U>iDKyhP99A#0#jw47BC!VYLZI-wqzE`Ul1= zw(9F#lUlN1CABEKOV9R;gBPvnr7g;QQ_CIp9<9CV4lL#`j0)@S*-4``Z%gOs{QXI_ zKwcAdAsbC2LImcqV&j9Vh<)Co1A}bw1&7rVoE~$nUoXk8jwn_!^JCN7ZxbGHj`Z)T zACue7Vb`>SxTXAS46>HX|0?!B06i!H$8i|4R5O*&GS`HQXk?>oyJ>=h7x{(O9U{MSH|*C@5$f}- zDV(U!5S)m-{HB(V-<))je$lL$dgo#Vs(_Rmu4w@R_O`qDClPjTZ@>V;*Yz@ z4@PDr;uezTfONgkP(uU&%!;VC37eu`u6=v6tADfY%Oa24qqU*>eFjoD)6+F-L5&nZ z$vvnZXxHo4DVGU5E^bfY<>#kbCH^oe$ukugdt}87H0`5#RL!v;YKV=uL-FJ@k6(B1 zs2ba4A>XA51`~-=I&HOv_WcXjmxvAHeE^@|A9V& zA~OxgXJC?g@*?sTj;!`B7OvVmNG=pd_L0c_K45436vO-i0}p_5fwr-$2t&2&q04fD z5^hwd*8gBSuON>9?XT6ax;kD^tTrD_1I6BiuT9B!1{>76{l5%n8m0u?xEJQz46Nx( z%gZ<$Vt+J^8-QEO1bhZKSWqTVKL#N8ethY6@dtBXsy^MVhulGn=jqJVrHUHSe{o@- zf-oc}Fs{jvhcd}(zP&yBH1>g)^f|gJh~r5mTFHRqJck%C8vGNE-h{yn5>P4Q&sHG_ zCVxj!PEY=&E*fLzXyc3%8c^!oi^@@eUTh$T=L0#MHfNtmH5=d^!XC!c{L36&e&9S7 z2*4KapszoE7z~3tl)tC@nE+Vf|NW|~rzZhNc1Q#?Rs5w(JePz>Z``<1vF8>F?Sf8Y z_CrUIp#Fyf@mxZd*Stv;4E$b;{%Kzgdk8cl6}7)#6J#MfZ-!f(V3n3_3!bYJ9 zz=mi1w+|dcme=o7IAxFnh^DGq0OtUzy$*u8SOYa79TYb{;f|M(MYUiP2MB=-_Ci_K zXXxa2W$$%g7J|R`A1GP@-OAa-(#Ib+0_bRIdv;CEu~lttb2&?&|0NJ<0uNj!MF2ZG z+_9b%BvbzZ{RVRctIil-;L2+Sjgik65B`q&sYMvPbfpN4OTUA*(tTU(1B48&p6ZV$?lJ*#_3m|}O zM9+0y5XbUee~3DGe;sI_K~ss%_(eWURxwIB%QD>ZFNKAS2ohV%IeYo~wL&D8s-Itj zB`VeWkFSW%e~vOx9vf$K1a=$=f686dL9*h=aaTUU^&x4YBtC$%$KD6o2_-%SzRa`! zIyWm_TG^Jyxn#!52oHj45^Yc* zTGnKn-4wtx+z`NcWBN!M+`3;w1;V|i9;ubQzx(0~UVW7L7m3jf4uWu%1q#`WtyprCgH{Zw*J z@awm4Rx?ZNN6vkq1$R|a&~b>p=7b)Hm`+brwmqh#{UIf$+|V0PIb2Ws`b*SJvVmop zz*8X}F@zBpYkvzft?gDEzH z3!T%0_2#)O>j++Mc*t{f`mwPw=1u?=0e*pll@Jg}XT4QM1b#FJDo?T>y#j~y3KITs z@C27qR38|i@08dst9*IBdV}r@*3GV~12QoV+#}}^n9ajasmWXt&*85GjT_RAB z`aSr5gNH*3RBi`cSp$nNFA4f_k>`Mr0k**9WWB8QdPFRsUjQ5k1YYa8(6r`h=9wG7 z&U|&e46nP<4pQ!tFx_T9Pn86$SMQ|!(HW7w8A*luMXz*GFUt!m={rnem~ua%&;0vy zgmB9rDtEMf6p&7!cwpnBs)K^ioLk&>59)jJkQhc%KKM|cGX$Q2q+H?=JF)_Fd2Z@f zW?5`vIurms!R4vByIjQpY%UUI4J$JP1A%}i{p!nY(&q#DI!xClh>)U)Uxi@D%Zr^e z0+tN0()Z5`n?LCh4wBh?ttHJN*Ir%PdU*oE6T{k$lgQ8I*9$0&eN}krP~T&?GP4a&dT{TRRM{sttsl;Q9u78#Kj*eiixy zpB{7u(AsS0--8s`0iEpmCe@CSzXP6Q!WlDZP29r)-(2y-dvZD04Ld+6pzFNxBZDFs znE2p;6kzUp7w0*AaTVB_*rnufR5!+}rNS&xhg)_geqcms5^!nNNzh-SXA7ZTQ?m04Lx53WQ~vPkWSQQi+%nVxD)*KrB_(AS7a!-6zokdpvVGfQB@STiWfq3} zPH@G*p^qmAV~$HBc0*5cI?Cck)Ojg1F=PYtmaJ;>VrHzcbbLTT$s=g4h%Dq=9}IH` zI~Fv<`*(!bEytVwnk_neDDuW(C|@V&qNPs4MNco@@Hx^M;i7s>RIix-Veb<*?B%QR z&H!+5sm;y5^WWU@yG8B^qV-*l&j5tuD+Wv-3nbIz2Y@&^u= zEb3EgHw0{g^&9k=>m>B_d^b9ym%6(_^(SqaR(va{$i*dTT`!?#gt;$tkrcDjvZfK2 z7;ptr3`G))AdvC#m)*Qf$nH%93``2srlB-1rdm&h|K->Pks*t81wfAx%D? z^H4bcg{q#8k03gGtPUvgHgL0A?Zj z;YkTNJ)<6b^P>VyvU*!5V7=5^TP9x18M+%9x7ngm3ytFMCBz*g4RtnMK&kH`pBo*xESL}SFO21cbSs$V_!Jcb zcRDCsEKI;~`RM1Y+k|s%LIjb-dH;d7CYxe_d5#>ae=264K~z}{BP<`dhnqjQaU5=y z)}l+xlMSP_-(Z~66&l^eVF9tTdXIusCo~r1_>;?X-_E0EZlCn|jB}K&Y=B?Kl+J8? zd9vUhTj!DdT}dMBTWWN!X6wU-7A21<+Ni~UFNb{o{29?ok$tYiBiqCxB{k&=5%WOOC zrSa!$sALXVg<=8)Q>OIE0-3{Sa&ac)zz2qw+EQV+xpskBhQrtOPnO+V1DKJx<@Cf# zC-|iG@v>p->)t%+3e$M%h&om#rmWADC*aD07RUVo=1U1l*1O5Sj=U#`Vtx0P+`uE- zeZl8vgY|L%!BALNM>#_h%K94|aoB`Zs;?_ezgfi7Ncw1}ez4&~V9tII#iyW|Q3{@Y zc#D!|#{VM*3CvB3Jn~!dGpwjroo1tsgSmv#1PRy>2UAK)$_@0dPcd*NWzpl|pVnOB z&)-E*$pkgcut5@%OTF)7iSc$)r2G%#uZ2b?Cf^TvZU?OVtXy10la%G7IP?Kf92~9V z3y6qxAJBSixc_we6oPfE2Nq*r;LfsCjCyTg%~-_lrf%ovaNi*`gGP}c54rVur9X>n za*2E!HZu$uFb|(G;xfK~;ApB|UNs(%y-Ol9v#p!YHX9KU*Z6hbQ3*Th<@7N)g0*+j zl@=@+JOD&I050Yo1`?gHuCZjc6DG7rCa~bslKH~hChVBj!l+$ve|mp3_iLV>Z)A1+ z`if=p4LW!rc<(UfNilv(O1BcxX&(&uL**~vI`G-<*y-mlyNllxb`nW2<Q%|1Z(#_ z1WpLt5g*F@h@|F-zzdtccKao@{z1t91GLhi1poj5 literal 0 HcmV?d00001 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10.2.png b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10.2.png new file mode 100644 index 0000000000000000000000000000000000000000..9a10d41c365f9d47dc2f7f80b4e2e66c4af6696e GIT binary patch literal 109141 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
      2~|66qSaf3sOSPl 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%0A@sDIkZYs5DQ1SxzeQulieq@yf#sRZ=trPH^Z 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

      ?fA? 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

      ls9~ejzoq+X~!1MR}eUp}1 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

        ZfB0 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 literal 0 HcmV?d00001 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10.3.png b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10.3.png new file mode 100644 index 0000000000000000000000000000000000000000..bc65f388c9b7d8665823983cad678183c87adf75 GIT binary patch literal 72740 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

        + + ![](13.1.png) + +
        图 13.1: 字典树,存储了单词 A、to、tea、ted、ten、i、in 和 inn,以及它们的频率
        +
        + +为什么需要用字典树解决这类问题呢?假如我们有一个储存了近万个单词的字典,即使我们使用哈希,在其中搜索一个单词的实际开销也是非常大的,且无法轻易支持搜索单词前缀。然而由于一个英文单词的长度 n 通常在 10 以内,如果我们使用字典树,则可以在 $O(n)$——近似 $O(1)$ 的时间内完成搜索,且额外开销非常小。 + +## [208. Implement Trie (Prefix Tree)](https://leetcode.com/problems/implement-trie-prefix-tree/) + +### 題目描述 + +尝试建立一个字典树,支持快速插入单词、查找单词、查找单词前缀的功能。 + +### 輸入輸出範例 + +以下是数据结构的调用样例。 + +``` +Trie trie = new Trie(); +trie.insert("apple"); +trie.search("apple"); // true +trie.search("app"); // false +trie.startsWith("app"); // true +trie.insert("app"); +trie.search("app"); // true +``` + +### 題解 + +以下是字典树的典型实现方法。 + + + + +```cpp +struct TrieNode { + bool word_ends; + vector children; + TrieNode() : word_ends(false), children(26, nullptr) {} +}; + +class Trie { + public: + Trie() : root_(new TrieNode()) {} + + void insert(string word) { + TrieNode* node = root_; + for (char c : word) { + int pos = c - ’a’; + if (node->children[pos] == nullptr) { + node->children[pos] = new TrieNode(); + } + node = node->children[pos]; + } + node->word_ends = true; + } + + bool search(string word) { + TrieNode* node = root_; + for (char c : word) { + if (node == nullptr) { + break; + } + node = node->children[c - ’a’]; + } + return node != nullptr && node->word_ends; + } + + bool startsWith(string prefix) { + TrieNode* node = root_; + for (char c : prefix) { + if (node == nullptr) { + break; + } + node = node->children[c - ’a’]; + } + return node != nullptr; + } + + private: + TrieNode* root_; +}; +``` + + + + +```py +class TrieNode: + def __init__(self): + self.word_ends = False + self.children = [None] * 26 + +class Trie: + def __init__(self): + self.root = TrieNode() + + def insert(self, word: str) -> None: + node = self.root + for c in word: + pos = ord(c) - ord("a") + if node.children[pos] is None: + node.children[pos] = TrieNode() + node = node.children[pos] + node.word_ends = True + + def search(self, word: str) -> bool: + node = self.root + for c in word: + if node is None: + break + node = node.children[ord(c) - ord("a")] + return node is not None and node.word_ends + + def startsWith(self, prefix: str) -> bool: + node = self.root + for c in prefix: + if node is None: + break + node = node.children[ord(c) - ord("a")] + return node is not None + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-7-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-7-exercises.md new file mode 100644 index 00000000..75690a1e --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-7-exercises.md @@ -0,0 +1,81 @@ +--- +sidebar_position: 74 +--- + +# 13.7 練習 + +## 基礎難度 + +### [226. Invert Binary Tree](https://leetcode.com/problems/invert-binary-tree/) + +巧用递归,你可以在五行内完成这道题。 + +### [617. Merge Two Binary Trees](https://leetcode.com/problems/merge-two-binary-trees/) + +同样的,利用递归可以轻松搞定。 + +### [572. Subtree of Another Tree](https://leetcode.com/problems/subtree-of-another-tree/) + +子树是对称树的姊妹题,写法也十分类似。 + +### [404. Sum of Left Leaves](https://leetcode.com/problems/sum-of-left-leaves/) + +怎么判断一个节点是不是左节点呢?一种可行的方法是,在辅函数里多传一个参数,表示当前节点是不是父节点的左节点。 + +### [513. Find Bottom Left Tree Value](https://leetcode.com/problems/find-bottom-left-tree-value/) + +最左下角的节点满足什么条件?针对这种条件,我们该如何找到它? + +### [538. Convert BST to Greater Tree](https://leetcode.com/problems/convert-bst-to-greater-tree/) + +尝试利用某种遍历方式来解决此题,每个节点只需遍历一次。 + +### [235. Lowest Common Ancestor of a Binary Search Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/) + +利用 BST 的独特性质,这道题可以很轻松完成。 + +### [530. Minimum Absolute Difference in BST](https://leetcode.com/problems/minimum-absolute-difference-in-bst/) + +还记得我们所说的,对于 BST 应该利用哪种遍历吗? + +## 進階難度 + +### [1530. Number of Good Leaf Nodes Pairs](https://leetcode.com/problems/number-of-good-leaf-nodes-pairs/) + +题目 543 的变种题,注意在辅函数中,每次更新的全局变量是左右两边距离之和满足条件的数量,而返回的是左右两边所有(长度不溢出的)子节点的高度 +1。 + +### [889. Construct Binary Tree from Preorder and Postorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-postorder-traversal/) + +给定任意两种遍历结果,我们都可以重建树的结构。 + +### [106. Construct Binary Tree from Inorder and Postorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/) + +给定任意两种遍历结果,我们都可以重建树的结构。 + +### [94. Binary Tree Inorder Traversal](https://leetcode.com/problems/binary-tree-inorder-traversal/) + +因为前中序后遍历是用递归实现的,而递归的底层实现是栈操作,因此我们总能用栈实现。 + +### [145. Binary Tree Postorder Traversal](https://leetcode.com/problems/binary-tree-postorder-traversal/) + +因为前中序后遍历是用递归实现的,而递归的底层实现是栈操作,因此我们总能用栈实现。 + +### [236. Lowest Common Ancestor of a Binary Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/) + +现在不是 BST,而是普通的二叉树了,该怎么办? + +### [109. Convert Sorted List to Binary Search Tree](https://leetcode.com/problems/convert-sorted-list-to-binary-search-tree/) + +把排好序的链表变成 BST。为了使得 BST 尽量平衡,我们需要寻找链表的中点。 + +### [897. Increasing Order Search Tree](https://leetcode.com/problems/increasing-order-search-tree/) + +把 BST 压成一个链表,务必考虑清楚指针操作的顺序,否则可能会出现环路。 + +### [653. Two Sum IV - Input is a BST](https://leetcode.com/problems/two-sum-iv-input-is-a-bst/) + +啊哈,这道题可能会把你骗到。 + +### [450. Delete Node in a BST](https://leetcode.com/problems/delete-node-in-a-bst/) + +当寻找到待删节点时,你可以分情况考虑——当前节点是叶节点、只有一个子节点和有两个子节点。建议同时回收内存。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13.1.png b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13.1.png new file mode 100644 index 0000000000000000000000000000000000000000..06c168c6cc9b678d71b1481c04f3f3cb8e2ba56e GIT binary patch literal 49070 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⋙uQjBTmL--5X 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 a_JlStNm}@B)9VWe_)$?*SE!OR5B@*1_9g8A literal 0 HcmV?d00001 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/_category_.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/_category_.json new file mode 100644 index 00000000..db81316e --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "13. 指针三剑客之二:树", + "position": 13, + "link": { + "type": "generated-index", + "description": "第 13 章 指针三剑客之二:树" + } +} diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-1-data-structure-introduction.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-1-data-structure-introduction.mdx new file mode 100644 index 00000000..8e592d82 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-1-data-structure-introduction.mdx @@ -0,0 +1,16 @@ +--- +sidebar_position: 75 +--- + +# 14.1 数据结构介绍 + +作为指针三剑客之三,图是树的升级版。`图`通常分为有向(directed)或无向(undirected),有循环(cyclic)或无循环(acyclic),所有节点相连(connected)或不相连(disconnected)。树即是一个相连的无向无环图,而另一种很常见的图是`有向无环图`(Directed Acyclic Graph,DAG)。 + +
        + + ![](14.1.png) + +
        图 14.1: 有向无环图样例
        +
        + +图通常有两种表示方法。假设图中一共有 n 个节点、m 条边。第一种表示方法是`邻接矩阵`(adjacency matrix):我们可以建立一个 n × n 的矩阵 G,如果第 i 个节点连向第 j 个节点,则 G[i][j] = 1,反之为 0;如果图是无向的,则这个矩阵一定是对称矩阵,即 G[i][j] = G[j][i]。第二种表示方法是`邻接链表`(adjacency list):我们可以建立一个大小为 n 的数组,每个位置 i 储存一个数组或者链表,表示第 i 个节点连向的其它节点。邻接矩阵空间开销比邻接链表大,但是邻接链表不支持快速查找 i 和 j 是否相连,因此两种表示方法可以根据题目需要适当选择。除此之外,我们也可以直接用一个 m × 2 的矩阵储存所有的边。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-2-bipartite-graph.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-2-bipartite-graph.mdx new file mode 100644 index 00000000..883bbc4e --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-2-bipartite-graph.mdx @@ -0,0 +1,90 @@ +--- +sidebar_position: 76 +--- + +# 14.2 二分图 + +`二分图`算法也称为`染色法`,是一种广度优先搜索。如果可以用两种颜色对图中的节点进行着色,并且保证相邻的节点颜色不同,那么图为二分。 + +## [785. Is Graph Bipartite?](https://leetcode.com/problems/is-graph-bipartite/) + +### 題目描述 + +给定一个图,判断其是否可以二分。 + +### 輸入輸出範例 + +输入是邻接链表表示的图(如位置 0 的邻接链表为 [1,3],表示 0 与 1、0 与 3 相连);输出是一个布尔值,表示图是否二分。 + +``` +Input: [[1,3], [0,2], [1,3], [0,2]] +0----1 +| | +| | +3----2 +Output: true +``` + +在这个样例中,我们可以把 {0,2} 分为一组,把 {1,3} 分为另一组。 + +### 題解 + +利用队列和广度优先搜索,我们可以对未染色的节点进行染色,并且检查是否有颜色相同的相邻节点存在。注意在代码中,我们用 0 表示未检查的节点,用 1 和 2 表示两种不同的颜色。 + + + + +```cpp +bool isBipartite(vector>& graph) { + int n = graph.size(); + vector color(n, 0); + queue q; + for (int i = 0; i < n; ++i) { + if (color[i] == 0) { + q.push(i); + color[i] = 1; + } + while (!q.empty()) { + int node = q.front(); + q.pop(); + for (int j : graph[node]) { + if (color[j] == 0) { + q.push(j); + color[j] = color[node] == 2 ? 1 : 2; + } else if (color[j] == color[node]) { + return false; + } + } + } + } + return true; +} +``` + + + + +```py +def isBipartite(graph: List[List[int]]) -> bool: + n = len(graph) + color = [0] * n + q = collections.deque() + + for i in range(n): + if color[i] == 0: + q.append(i) + color[i] = 1 + while len(q) > 0: + node = q.popleft() + for j in graph[node]: + if color[j] == 0: + q.append(j) + color[j] = 1 if color[node] == 2 else 2 + elif color[j] == color[node]: + return False + return True +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-3-topological-sorting.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-3-topological-sorting.mdx new file mode 100644 index 00000000..8a9dcb1d --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-3-topological-sorting.mdx @@ -0,0 +1,97 @@ +--- +sidebar_position: 77 +--- + +# 14.3 拓扑排序 + +`拓扑排序`(topological sort)是一种常见的,对有向无环图排序的算法。给定有向无环图中的 $N$ 个节点,我们把它们排序成一个线性序列;若原图中节点 i 指向节点 j,则排序结果中 i 一定在 j 之前。拓扑排序的结果不是唯一的,只要满足以上条件即可。 + +## [210. Course Schedule II](https://leetcode.com/problems/course-schedule-ii/) + +### 題目描述 + +给定 N 个课程和这些课程的前置必修课,求可以一次性上完所有课的顺序。 + +### 輸入輸出範例 + +输入是一个正整数,表示课程数量,和一个二维矩阵,表示所有的有向边(如 [1,0] 表示上课程 1 之前必须先上课程 0)。输出是一个一维数组,表示拓扑排序结果。 + +``` +Input: numCourses = 4, prerequisites = [[1,0],[2,0],[3,1],[3,2]] +Output: [0,1,2,3] +``` + +在这个样例中,另一种可行的顺序是 [0,2,1,3]。 + +### 題解 + +我们可以先建立一个邻接矩阵表示图,方便进行直接查找。这里注意我们将所有的边反向,使得如果课程 i 指向课程 j,那么课程 i 需要在课程 j 前面先修完。这样更符合我们的直观理解。 + +拓扑排序也可以被看成是广度优先搜索的一种情况:我们先遍历一遍所有节点,把入度为 0 的节点(即没有前置课程要求)放在队列中。在每次从队列中获得节点时,我们将该节点放在目前排序的末尾,并且把它指向的课程的入度各减 1;如果在这个过程中有课程的所有前置必修课都已修完(即入度为 0),我们把这个节点加入队列中。当队列的节点都被处理完时,说明所有的节点都已排好序,或因图中存在循环而无法上完所有课程。 + + + + +```cpp +vector findOrder(int numCourses, vector>& prerequisites) { + vector> graph(numCourses, vector()); + vector indegree(numCourses, 0), schedule; + for (const auto& pr : prerequisites) { + graph[pr[1]].push_back(pr[0]); + ++indegree[pr[0]]; + } + queue q; + for (int i = 0; i < indegree.size(); ++i) { + if (indegree[i] == 0) { + q.push(i); + } + } + while (!q.empty()) { + int u = q.front(); + q.pop(); + schedule.push_back(u); + for (int v : graph[u]) { + --indegree[v]; + if (indegree[v] == 0) { + q.push(v); + } + } + } + for (int i = 0; i < indegree.size(); ++i) { + if (indegree[i] != 0) { + return vector(); + } + } + return schedule; +} +``` + + + + +```py +def findOrder(numCourses: int, prerequisites: List[List[int]]) -> List[int]: + graph = [[] for _ in range(numCourses)] + indegree = [0] * numCourses + schedule = [] + + for pr_from, pr_to in prerequisites: + graph[pr_to].append(pr_from) + indegree[pr_from] += 1 + + q = collections.deque([i for i, deg in enumerate(indegree) if deg == 0]) + + while len(q) > 0: + u = q.popleft() + schedule.append(u) + for v in graph[u]: + indegree[v] -= 1 + if indegree[v] == 0: + q.append(v) + + return schedule if all(deg == 0 for deg in indegree) else [] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-4-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-4-exercises.md new file mode 100644 index 00000000..858cde06 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-4-exercises.md @@ -0,0 +1,21 @@ +--- +sidebar_position: 78 +--- + +# 14.4 練習 + +## 基礎難度 + +### [1059. All Paths from Source Lead to Destination](https://leetcode.com/problems/all-paths-from-source-lead-to-destination/) + +虽然使用深度优先搜索可以解决大部分的图遍历问题,但是注意判断是否陷入了环路。 + +## 進階難度 + +### [1135. Connecting Cities With Minimum Cost](https://leetcode.com/problems/connecting-cities-with-minimum-cost/) + +笔者其实已经把这道题的题解写好了,才发现这道题是需要解锁才可以看的题目。为了避免版权纠纷,故将其移至练习题内。本题考察最小生成树(minimum spanning tree, MST)的求法,通常可以用两种方式求得:Prim’s Algorithm,利用优先队列选择最小的消耗;以及 Kruskal’s Algorithm,排序后使用并查集。 + +### [882. Reachable Nodes In Subdivided Graph](https://leetcode.com/problems/reachable-nodes-in-subdivided-graph/) + +这道题笔者考虑了很久,最终决定把它放在练习题而非详细讲解。本题是经典的节点最短距离问题,常用的算法有 Bellman-Ford 单源最短路算法,以及 Dijkstra 无负边单源最短路算法。虽然经典,但是 LeetCode 很少有相关的题型,因此这里仅供读者自行深入学习。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14.1.png b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14.1.png new file mode 100644 index 0000000000000000000000000000000000000000..46ebed1b401557b94a5c6f1d46e362ffa38deb69 GIT binary patch literal 103164 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 + + ![](15.1.png) + +

        图 15.1: 并查集样例,其中 union 操作可以将两个集合按秩合并,find 操作可以查找节点的祖先并压缩路径。
        + + +## [684. Redundant Connection](https://leetcode.com/problems/redundant-connection/) + +### 題目描述 + +在无向图找出一条边,移除它之后该图能够成为一棵树(即无向无环图)。如果有多个解,返回在原数组中位置最靠后的那条边。 + +### 輸入輸出範例 + +输入是一个二维数组,表示所有的边(对应的两个节点);输出是一个一维数组,表示需要移除的边(对应的两个节点)。 + +``` +Input: [[1,2], [1,3], [2,3]] + 1 + / \ +2 - 3 +Output: [2,3] +``` + +### 題解 + +因为需要判断是否两个节点被重复连通,所以我们可以使用并查集来解决此类问题。具体实现算法如下所示。 + + + + +```cpp +class Solution { + public: + vector findRedundantConnection(vector>& edges) { + n_ = edges.size(); + id_ = vector(n_); + depth_ = vector(n_, 1); + for (int i = 0; i < n_; ++i) { + id_[i] = i; + } + for (auto& edge : edges) { + int i = edge[0], j = edge[1]; + if (linked(i - 1, j - 1)) { + return vector{i, j}; + } + connect(i - 1, j - 1); + } + return vector(); + } + + private: + int find(int i) { + // 路径压缩。 + while (i != id_[i]) { + id_[i] = id_[id_[i]]; + i = id_[i]; + } + return i; + } + + void connect(int i, int j) { + i = find(i), j = find(j); + if (i == j) { + return; + } + // 按秩合并。 + if (depth_[i] <= depth_[j]) { + id_[i] = j; + depth_[j] = max(depth_[j], depth_[i] + 1); + } else { + id_[j] = i; + depth_[i] = max(depth_[i], depth_[j] + 1); + } + } + + bool linked(int i, int j) { return find(i) == find(j); } + + int n_; + vector id_; + vector depth_; +}; +``` + + + + +```py +class Solution: + def __init__(self): + self.n = 0 + self.id = None + self.depth = None + + def find(self, i: int) -> int: + # 路径压缩。 + while i != self.id[i]: + self.id[i] = self.id[self.id[i]] + i = self.id[i] + return i + + def connect(self, i: int, j: int): + i = self.find(i) + j = self.find(j) + if i == j: + return + # 按秩合并。 + if self.depth[i] <= self.depth[j]: + self.id[i] = j + self.depth[j] = max(self.depth[j], self.depth[i] + 1) + else: + self.id[j] = i + self.depth[i] = max(self.depth[i], self.depth[j] + 1) + + def linked(self, i: int, j: int) -> bool: + return self.find(i) == self.find(j) + + def findRedundantConnection(self, edges: List[List[int]]) -> List[int]: + self.n = len(edges) + self.id = list(range(self.n)) + self.depth = [1] * self.n + for i, j in edges: + if self.linked(i - 1, j - 1): + return [i, j] + self.connect(i - 1, j - 1) + return [] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-3-composite-data-structures.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-3-composite-data-structures.mdx new file mode 100644 index 00000000..b981e52d --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-3-composite-data-structures.mdx @@ -0,0 +1,257 @@ +--- +sidebar_position: 77 +--- + +# 15.3 复合数据结构 + +这一类题通常采用哈希表或有序表辅助记录,从而加速寻址;再配上数组或者链表进行连续的数据储存,从而加速连续选址或删除值。 + +## [146. LRU Cache](https://leetcode.com/problems/lru-cache/) + +### 題目描述 + +设计一个固定大小的,最近最少使用缓存 (least recently used cache, LRU)。每次将信息插入未满的缓存的时候,以及更新或查找一个缓存内存在的信息的时候,将该信息标为最近使用。在缓存满的情况下将一个新信息插入的时候,需要移除最旧的信息,插入新信息,并将该新信息标为最近使用。 + +### 輸入輸出範例 + +以下是数据结构的调用样例。给定一个大小为 n 的缓存,利用最近最少使用策略储存数据。 + +``` +LRUCache cache = new LRUCache( 2 /* capacity */ ); +cache.put(1, 1); +cache.put(2, 2); +cache.get(1); // 输出 value 1 +cache.put(3, 3); // 移除 key 2 +cache.get(2); // 输出 value -1 (未找到) +cache.put(4, 4); // 移除 key 1 +cache.get(1); // 输出 value -1 (未找到) +cache.get(3); // 输出 value 3 +cache.get(4); // 输出 value 4 +``` + +### 題解 + +我们采用一个链表来储存信息的 key 和 value,链表的链接顺序即为最近使用的新旧顺序,最新的信息在链表头节点。同时我们需要一个哈希表进行查找,键是信息的 key,值是其在链表中的对应指针/迭代器。每次查找成功(cache hit)时,需要把指针/迭代器对应的节点移动到链表的头节点。 + + + + +```cpp +class LRUCache { + public: + LRUCache(int capacity) : n_(capacity) {} + + int get(int key) { + auto it = key_to_cache_it_.find(key); + if (it == key_to_cache_it_.end()) { + return -1; + } + cache_.splice(cache_.begin(), cache_, it->second); + return it->second->second; + } + + void put(int key, int value) { + auto it = key_to_cache_it_.find(key); + if (it != key_to_cache_it_.end()) { + it->second->second = value; + return cache_.splice(cache_.begin(), cache_, it->second); + } + cache_.insert(cache_.begin(), make_pair(key, value)); + key_to_cache_it_[key] = cache_.begin(); + if (cache_.size() > n_) { + key_to_cache_it_.erase(cache_.back().first); + cache_.pop_back(); + } + } + + private: + list> cache_; + unordered_map>::iterator> key_to_cache_it_; + int n_; +}; +``` + + + + +```py +class Node: + def __init__(self, key=-1, val=-1): + self.key = key + self.val = val + self.prev = None + self.next = None + +class LinkedList: + def __init__(self): + self.dummy_start = Node() + self.dummy_end = Node() + self.dummy_start.next = self.dummy_end + self.dummy_end.prev = self.dummy_start + + def appendleft(self, node) -> Node: + left, right = self.dummy_start, self.dummy_start.next + node.next = right + right.prev = node + left.next = node + node.prev = left + return node + + def remove(self, node) -> Node: + left, right = node.prev, node.next + left.next = right + right.prev = left + return node + + def move_to_start(self, node): + return self.appendleft(self.remove(node)) + + def pop(self): + return self.remove(self.dummy_end.prev) + + def peek(self): + return self.dummy_end.prev.val + +class LRUCache: + def __init__(self, capacity: int): + self.n = capacity + self.key_to_node = dict() + self.cache_nodes = LinkedList() + + def get(self, key: int) -> int: + if key not in self.key_to_node: + return -1 + node = self.key_to_node[key] + self.cache_nodes.move_to_start(node) + return node.val + + def put(self, key: int, value: int) -> None: + if key in self.key_to_node: + node = self.cache_nodes.remove(self.key_to_node[key]) + node.val = value + else: + node = Node(key, value) + self.key_to_node[key] = node + self.cache_nodes.appendleft(node) + if len(self.key_to_node) > self.n: + self.key_to_node.pop(self.cache_nodes.pop().key) +``` + + + + + +对于 Python 而言,我们还可以直接利用 OrderedDict 函数实现 LRU,这将大大简化题目难度。这里笔者希望读者还是仔细研读一下以上题解,了解 LRU 实现的核心原理。 + + +```py +class LRUCache: + def __init__(self, capacity: int): + self.n = capacity + self.cache = {} + + def get(self, key: int) -> int: + if key not in self.cache: + return -1 + self.cache[key] = self.cache.pop(key) + return self.cache[key] + + def put(self, key: int, value: int) -> None: + if key in self.cache: + self.cache.pop(key) + self.cache[key] = value + if len(self.cache) > self.n: + self.cache.pop(next(iter(self.cache))) +``` + +## [380. Insert Delete GetRandom O(1)](https://leetcode.com/problems/insert-delete-getrandom-o1/) + +### 題目描述 + +设计一个插入、删除和随机取值均为 $O(1)$ 时间复杂度的数据结构。 + +### 輸入輸出範例 + +以下是数据结构的调用样例。 + +``` +RandomizedSet randomizedSet = new RandomizedSet(); +randomizedSet.insert(1); +randomizedSet.remove(2); +randomizedSet.insert(2); +randomizedSet.getRandom(); // 50% 1, 50% 2 +randomizedSet.remove(1); +randomizedSet.insert(2); +randomizedSet.getRandom(); // 100% 2 +``` + +### 題解 + +我们采用一个数组存储插入的数字,同时利用一个哈希表查找位置。每次插入数字时,直接加入数组,且将位置记录在哈希表中。每次删除数字时,将当前数组最后一位与删除位互换,并更新哈希表。随机取值时,则可以在数组内任意选取位置。 + + + + +```cpp +class RandomizedSet { + public: + bool insert(int val) { + if (v_to_k_.contains(val)) { + return false; + } + v_to_k_[val] = nums_.size(); + nums_.push_back(val); + return true; + } + + bool remove(int val) { + if (!v_to_k_.contains(val)) { + return false; + } + v_to_k_[nums_.back()] = v_to_k_[val]; + nums_[v_to_k_[val]] = nums_.back(); + v_to_k_.erase(val); + nums_.pop_back(); + return true; + } + + int getRandom() { return nums_[rand() % nums_.size()]; } + + private: + unordered_map v_to_k_; + vector nums_; +}; +``` + + + + +```py +class RandomizedSet: + def __init__(self): + self.nums = [] + self.v_to_k = {} + + def insert(self, val: int) -> bool: + if val in self.v_to_k: + return False + self.v_to_k[val] = len(self.nums) + self.nums.append(val) + return True + + def remove(self, val: int) -> bool: + if val not in self.v_to_k: + return False + self.v_to_k[self.nums[-1]] = self.v_to_k[val] + self.nums[self.v_to_k[val]] = self.nums[-1] + del self.v_to_k[val] + self.nums.pop() + return True + + def getRandom(self) -> int: + return self.nums[random.randint(0, len(self.nums) - 1)] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-4-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-4-exercises.md new file mode 100644 index 00000000..b32a11f3 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-4-exercises.md @@ -0,0 +1,21 @@ +--- +sidebar_position: 78 +--- + +# 15.4 練習 + +## 基礎難度 + +### [1135. Connecting Cities With Minimum Cost](https://leetcode.com/problems/connecting-cities-with-minimum-cost/) + +使用并查集,按照 Kruskal’s Algorithm 把这道题再解决一次吧。 + +## 進階難度 + +### [432. All O`one Data Structure](https://leetcode.com/problems/all-oone-data-structure/) + +设计一个 increaseKey,decreaseKey,getMaxKey,getMinKey 均为 O(1) 时间复杂度的数据结构。 + +### [716. Max Stack](https://leetcode.com/problems/max-stack/) + +设计一个支持 push,pop,top,getMax 和 popMax 的 stack。可以用类似 LRU 的方法降低时间复杂度,但是因为想要获得的是最大值,我们应该把 unordered_map 换成哪一种数据结构呢? \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15.1.png b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15.1.png new file mode 100644 index 0000000000000000000000000000000000000000..6a2df359fca0c73d0ff823d313a1bac31d9af9cd GIT binary patch literal 29206 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 B6H@>H literal 0 HcmV?d00001 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/_category_.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/_category_.json new file mode 100644 index 00000000..cbe6af2e --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "15. 更加复杂的数据结构 ", + "position": 15, + "link": { + "type": "generated-index", + "description": "第 15 章 更加复杂的数据结构" + } +} diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-1-algorithm-explanation.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-1-algorithm-explanation.md new file mode 100644 index 00000000..4435a283 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-1-algorithm-explanation.md @@ -0,0 +1,21 @@ +--- +sidebar_position: 5 +--- + +# 2.1 算法解释 + +雙指針主要用於遍歷數組,兩個指針指向不同的元素,從而協同完成任務。也可以延伸到多個數組的多個指針。 + +若兩個指針指向同一數組,遍歷方向相同且不會相交,則也稱為滑動窗口(兩個指針包圍的區域即為當前的窗口),經常用於區間搜索。 + +若兩個指針指向同一數組,但是遍歷方向相反,則可以用來進行搜索,待搜索的數組往往是排好序的。 + +在 C++ 中,要注意 `const` 的位置對指針效果的影響: + +```cpp +int x; +int * p1 = &x; // 指针可以被修改,值也可以被修改 +const int * p2 = &x; // 指针可以被修改,值不可以被修改(const int) +int * const p3 = &x; // 指针不可以被修改(* const),值可以被修改 +const int * const p4 = &x; // 指针不可以被修改,值也不可以被修改 +``` diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-2-two-sum.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-2-two-sum.mdx new file mode 100644 index 00000000..7c51e67f --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-2-two-sum.mdx @@ -0,0 +1,72 @@ +--- +sidebar_position: 6 +--- + +# 2.2 Two Sum + +## [167. Two Sum II - Input array is sorted](https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/) + +### 題目描述 + +在一個增序的整數數組裡找到兩個數,使它們的和為給定值。已知有且只有一對解。 + +### 輸入輸出範例 + +輸入是一個數組(`numbers`)和一個給定值(`target`)。輸出是兩個數的位置,從 1 開始計數。 + +``` +Input: numbers = [2,7,11,15], target = 9 +Output: [1,2] +``` + +在這個範例中,第一個數字(2)和第二個數字(7)的和等於給定值(9)。 + +### 題解 + +因為數組已經排好序,我們可以採用方向相反的雙指針來尋找這兩個數字。一個指針初始指向最小的元素,即數組最左邊,向右遍歷;另一個指針初始指向最大的元素,即數組最右邊,向左遍歷。 + +如果兩個指針指向元素的和等於給定值,那麼它們就是我們要的結果。如果兩個指針指向元素的和小於給定值,我們把左邊的指針右移一位,使得當前的和增加一點。如果兩個指針指向元素的和大於給定值,我們把右邊的指針左移一位,使得當前的和減少一點。 + +可以證明,對於排好序且有解的數組,雙指針一定能遍歷到最優解。證明方法如下:假設最優解的兩個數的位置分別是 `l` 和 `r`。我們假設在左指針在 `l` 左邊的時候,右指針已經移動到了 `r`;此時兩個指針指向值的和小於給定值,因此左指針會一直右移直到到達 `l`。同理,如果我們假設在右指針在 `r` 右邊的時候,左指針已經移動到了 `l`;此時兩個指針指向值的和大於給定值,因此右指針會一直左移直到到達 `r`。所以雙指針在任何時候都不可能處於 `(l,r)` 之間,又因為不滿足條件時指針必須移動一個,所以最終一定會收斂在 `l` 和 `r`。 + + + + +```cpp +vector twoSum(vector& numbers, int target) { + int l = 0, r = numbers.size() - 1, two_sum; + while (l < r) { + two_sum = numbers[l] + numbers[r]; + if (two_sum == target) { + break; + } + if (two_sum < target) { + ++l; + } else { + --r; + } + } + return vector{l + 1, r + 1}; +} +``` + + + + +```py +def twoSum(numbers: List[int], target: int) -> List[int]: + l, r = 0, len(numbers) - 1 + while l < r: + two_sum = numbers[l] + numbers[r] + if two_sum == target: + break + if two_sum < target: + l += 1 + else: + r -= 1 + return [l + 1, r + 1] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-3-merge-sorted-arrays.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-3-merge-sorted-arrays.mdx new file mode 100644 index 00000000..a320fb5a --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-3-merge-sorted-arrays.mdx @@ -0,0 +1,68 @@ +--- +sidebar_position: 7 +--- + +# 2.3 合併兩個有序數組 + +## [88. Merge Sorted Array](https://leetcode.com/problems/merge-sorted-array/) + +### 題目描述 + +給定兩個有序數組,將它們合併為一個數組。 + +### 輸入輸出範例 + +輸入是兩個數組和它們分別的長度 `m` 和 `n`。其中第一個數組的長度被延長至 `m + n`,多出的 `n` 位被 `0` 填補。題目要求把第二個數組合併到第一個數組上,不需要開闢額外空間。 + +``` +Input: nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3 +Output: nums1 = [1,2,2,3,5,6] +``` + + +### 題解 + +因為這兩個數組已經排好序,我們可以將兩個指針分別放在兩個數組的末尾,即 `nums1` 的 `(m - 1)` 位和 `nums2` 的 `(n - 1)` 位。每次將較大的那個數字複製到 `nums1` 的後邊,然後向前移動一位。 + +我們也需要第三個指針來定位 `nums1` 的末尾,以便進行複製。在以下的代碼裡,我們直接利用 `m` 和 `n` 當作兩個數組的指針,再額外創建一個 `pos` 指針,起始位置為 `m + n - 1`。每次向左移動 `m` 或 `n` 的時候,也要向左移動 `pos`。注意,如果 `nums1` 的數字已經複製完,不要忘記繼續複製 `nums2` 的數字;如果 `nums2` 的數字已經複製完,剩下的 `nums1` 的數字不需要改變,因為它們已經排好序。 + +在 C++ 的題解中,我們使用了 `++` 和 `--` 的小技巧:`a++` 和 `++a` 都會將 `a` 加 1,但 `a++` 的返回值為 `a`,而 `++a` 的返回值為 `a + 1`。如果只希望增加 `a` 的值而不需要返回值,則兩種寫法都可以(`++a` 在未經編譯器優化的情況下運行速度會略快一些)。 + + + + + +```cpp +void merge(vector& nums1, int m, vector& nums2, int n) { + int pos = m-- + n-- - 1; + while (m >= 0 && n >= 0) { + nums1[pos--] = nums1[m] > nums2[n] ? nums1[m--] : nums2[n--]; + } + while (n >= 0) { + nums1[pos--] = nums2[n--]; + } +} +``` + + + + +```py +def merge(nums1: List[int], m: int, nums2: List[int], n: int) -> None: + pos = m + n - 1 + m -= 1 + n -= 1 + while m >= 0 and n >= 0: + if nums1[m] > nums2[n]: + nums1[pos] = nums1[m] + m -= 1 + else: + nums1[pos] = nums2[n] + n -= 1 + pos -= 1 + nums1[: n + 1] = nums2[: n + 1] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-4-sliding-window.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-4-sliding-window.mdx new file mode 100644 index 00000000..351e91bc --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-4-sliding-window.mdx @@ -0,0 +1,108 @@ +--- +sidebar_position: 8 +--- + +# 2.4 滑動窗口 + +## [76. Minimum Window Substring](https://leetcode.com/problems/minimum-window-substring/) + +### 題目描述 + +給定兩個字串 `s` 和 `t`,求 `s` 中包含 `t` 所有字符的最短連續子字串的長度,同時要求時間複雜度不得超過 $O(n)$。 + + +### 輸入輸出範例 + +輸入是兩個字串 `s` 和 `t`,輸出是 `s` 字串的一個子串。如果不存在解,則輸出一個空字串。 + +``` +Input: s = "ADOBECODEBANC", t = "ABC" +Output: "BANC" +``` + +在這個範例中,`s` 中同時包含一個 `A`、一個 `B`、一個 `C` 的最短子字串是 "BANC"。 + +### 題解 + +本題使用滑動窗口求解,即兩個指針 `l` 和 `r` 都是從最左端向最右端移動,且 `l` 的位置一定在 `r` 的左邊或重合。在 C++ 解法中,使用了兩個長度為 128 的數組,`valid` 和 `freq`,用來映射字符(ASCII 僅包含 128 個字符)。其中 `valid` 表示每個字符在 `t` 中是否存在,而 `freq` 表示目前 `t` 中每個字符在 `s` 的滑動窗口中缺少的數量:如果為正,則說明還缺少;如果為負,則說明有盈餘。在 Python 解法中,直接使用了 `Counter` 數據結構,同時統計 `t` 中存在的字符和其缺少的數量(也可以用 `dict` 替代)。 + +需要注意,本題雖然在 `for` 循環裡出現了一個 `while` 循環,但由於 `while` 循環負責移動 `l` 指針,且 `l` 只會從左到右移動一次,因此總時間複雜度仍然是 $O(n)$。 + + + + +```cpp +string minWindow(string s, string t) { + vector valid(128, false); + vector freq(128, 0); + // 統計 t 中的字符情況。 + for (int i = 0; i < t.length(); ++i) { + valid[t[i]] = true; + ++freq[t[i]]; + } + // 移動滑動窗口,更新統計數據。 + int count = 0; + int min_l = -1, min_length = -1; + for (int l = 0, r = 0; r < s.length(); ++r) { + if (!valid[s[r]]) { + continue; + } + // 將 r 位置的字符加入頻率統計,並檢查是否補充了 t 中缺失的字符。 + if (--freq[s[r]] >= 0) { + ++count; + } + // 滑動窗口已包含 t 中全部字符,嘗試右移 l,在不影響結果的情況下尋找最短子串。 + while (count == t.length()) { + if (min_length == -1 || r - l + 1 < min_length) { + min_l = l; + min_length = r - l + 1; + } + // 將 l 位置的字符移出頻率統計,並檢查 t 中對應字符是否重新缺失。 + if (valid[s[l]] && ++freq[s[l]] > 0) { + --count; + } + ++l; + } + } + return min_length == -1 ? "" : s.substr(min_l, min_length); +} +``` + + + + +```py +def minWindow(s: str, t: str) -> str: + # 統計 t 中的字符情況,等價於: + # freq = dict() + # for c in t: + # freq[c] = freq.get(c, 0) + 1 + freq = Counter(t) + # 移動滑動窗口,更新統計數據。 + count = 0 + min_l, min_length = None, None + l = 0 + for r in range(len(s)): + if s[r] not in freq: + continue + # 將 r 位置的字符加入頻率統計,並檢查是否補充了 t 中缺失的字符。 + freq[s[r]] -= 1 + if freq[s[r]] >= 0: + count += 1 + # 滑動窗口已包含 t 中全部字符,嘗試右移 l,在不影響結果的情況下尋找最短子串。 + while count == len(t): + if min_length is None or r - l + 1 < min_length: + min_l = l + min_length = r - l + 1 + # 將 l 位置的字符移出頻率統計,並檢查 t 中對應字符是否重新缺失。 + if s[l] in freq: + freq[s[l]] += 1 + if freq[s[l]] > 0: + count -= 1 + l += 1 + return "" if min_length is None else s[min_l: min_l + min_length] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-5-fast-slow-pointers.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-5-fast-slow-pointers.mdx new file mode 100644 index 00000000..eef1ba6f --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-5-fast-slow-pointers.mdx @@ -0,0 +1,98 @@ +--- +sidebar_position: 9 +--- + +# 2.5 快慢指針 + +## [142. Linked List Cycle II](https://leetcode.com/problems/linked-list-cycle-ii/) + +### 題目描述 + +給定一個鏈表,如果存在環路,找到環路的起始點。 + +### 輸入輸出範例 + +輸入是一個鏈表,輸出是鏈表中的一個節點。如果沒有環路,返回一個空指針。 +在這個範例中,值為 2 的節點即為環路的起始點。 +如果沒有特別說明,LeetCode 採用如下的數據結構表示鏈表。 + +![alt](https://assets.leetcode.com/uploads/2018/12/07/circularlinkedlist.png) + +```cpp +struct ListNode { + int val; + ListNode *next; + ListNode(int x) : val(x), next(nullptr) {} +}; +``` + +```py +class ListNode: + def __init__(self, x): + self.val = x + self.next = None # or a ListNode +``` + +### 題解 + +針對鏈表找環路的問題,有一個通用解法——快慢指針(Floyd 判圈法)。給定兩個指針,分別命名為 slow 和 fast,起始位置在鏈表的開頭。每次 fast 前進兩步,slow 前進一步。如果 fast 可以走到盡頭,則說明沒有環路;如果 fast 可以無限走下去,則說明一定有環路,且必然存在一個時刻 slow 和 fast 相遇。當 slow 和 fast 第一次相遇時,將 fast 重新移動到鏈表開頭,並 讓 slow 和 fast 每次都前進一步。當 slow 和 fast 第二次相遇時,相遇的節點即為環路的起始點。 + +:::warning + +針對某些只需要判斷是否存在環路的問題,也可以通過建立雜湊表來檢查重複。 + +::: + + + + + +```cpp +ListNode *detectCycle(ListNode *head) { + ListNode *slow = head, *fast = head; + bool is_first_cycle = true; + // 檢查環路。 + while (fast != slow || is_first_cycle) { + if (fast == nullptr || fast->next == nullptr) { + return nullptr; + } + fast = fast->next->next; + slow = slow->next; + is_first_cycle = false; + } + // 尋找節點。 + fast = head; + while (fast != slow) { + slow = slow->next; + fast = fast->next; + } + return fast; +} +``` + + + + +```py +def detectCycle(head: Optional[ListNode]) -> Optional[ListNode]: + slow = head + fast = head + is_first_cycle = True + # 檢查環路。 + while fast != slow or is_first_cycle: + if fast is None or fast.next is None: + return None + fast = fast.next.next + slow = slow.next + is_first_cycle = False + # 尋找節點。 + fast = head + while fast != slow: + fast = fast.next + slow = slow.next + return fast +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-6-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-6-exercises.md new file mode 100644 index 00000000..a14f93c1 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-6-exercises.md @@ -0,0 +1,25 @@ +--- +sidebar_position: 10 +--- + +# 2.6 練習 + +## 基礎難度 + +### [633. Sum of Square Numbers](https://leetcode.com/problems/sum-of-square-numbers/) + +Two Sum 題目的變形題之一。 + +### [680. Valid Palindrome II](https://leetcode.com/problems/valid-palindrome-ii/) + +Two Sum 題目的變形題之二。 + +### [524. Longest Word in Dictionary through Deleting](https://leetcode.com/problems/longest-word-in-dictionary-through-deleting/) + +合併兩個有序數組的變形題。 + +## 進階難度 + +### [340. Longest Substring with At Most K Distinct Characters](https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/) + +需要利用其他數據結構方便統計當前的字符狀態。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/_category_.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/_category_.json new file mode 100644 index 00000000..83ef1575 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "2. 玩轉雙指標", + "position": 2, + "link": { + "type": "generated-index", + "description": "第 2 章 玩轉雙指標" + } +} diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-1-algorithm-explanation.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-1-algorithm-explanation.md new file mode 100644 index 00000000..79446fff --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-1-algorithm-explanation.md @@ -0,0 +1,15 @@ +--- +sidebar_position: 11 +--- + +# 3.1 算法解釋 + +`二分搜尋` 也常被稱為 `二分法` 或 `折半搜尋` (binary search, bisect),每次搜尋時通過將待搜尋的單調區間分成兩部分並只取一部分繼續搜尋,將搜尋的複雜度大大減少。對於一個長度為 $O(n)$ 的數組,二分搜尋的時間複雜度為 $O(\log n)$。 + +舉例來說,給定一個排好序的數組 $\{3,4,5,6,7\}$,我們希望搜尋 4 是否在這個數組中。第一次折半時考慮中位數 5,因為 5 大於 4,所以如果 4 存在於這個數組,那麼它必定存在於 5 左邊這一半。於是我們的搜尋區間變成了 $\{3,4,5\}$。(注意,根據具體情況和您的解題習慣,這裡的 5 可以保留也可以不保留,這並不影響時間複雜度的等級。)第二次折半時考慮新的中位數 4,正好是我們需要搜尋的數字。於是我們發現,對於一個長度為 5 的數組,我們只進行了 2 次搜尋。如果是遍歷數組,最壞情況則需要搜尋 5 次。 + +我們也可以用更數學化的方式定義二分搜尋。給定一個在 $[a, b]$ 區間內的單調函數 $f(t)$,若 $f(a)$ 和 $f(b)$ 正負性相反,那麼必定存在一個解 $c$,使得 $f(c) = 0$。在上述例子中,$f(t)$ 是離散函數 $f(t) = t + 2$,搜尋 4 是否存在等價於求 $f(t) - 4 = 0$ 是否有離散解。因為 $f(1) - 4 = 3 - 4 = -1 < 0$、$f(5) - 4 = 7 - 4 = 3 > 0$,且函數在區間內單調遞增,因此我們可以利用二分搜尋求解。如果最後二分到了不能再分的情況,如只剩一個數字,且剩餘區間裡不存在滿足條件的解,則說明不存在離散解,即 4 不在這個數組中。 + +具體到代碼上,二分搜尋時區間的左右端取開區間還是閉區間在絕大多數情況下都可以,因此有些初學者會容易搞不清楚如何定義區間開閉性。這裡提供兩個小訣竅:第一是嘗試熟練使用一種寫法,比如左閉右開(滿足 C++、Python 等語言的習慣)或左閉右閉(便於處理邊界條件),盡量只保持這一種寫法;第二是在解題時思考如果最後區間只剩下一個數或者兩個數,自己的寫法是否會陷入死循環,如果某種寫法無法跳出死循環,則考慮嘗試另一種寫法。 + +二分搜尋也可以看作雙指針的一種特殊情況,但我們一般會將二者區分。雙指針類型的題,指針通常是一步一步移動的,而在二分搜尋中,指針通常每次移動半個區間長度。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-2-square-root.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-2-square-root.mdx new file mode 100644 index 00000000..b072e9fe --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-2-square-root.mdx @@ -0,0 +1,103 @@ +--- +sidebar_position: 12 +--- + +# 3.2 求平方根 + +## [69. Sqrt(x)](https://leetcode.com/problems/sqrtx/) + +### 題目描述 + +給定一個非負整數 `x`,求它的平方根並向下取整。 + +### 輸入輸出範例 + +輸入是一個整數,輸出也是一個整數。 + +``` +Input: 8 +Output: 2 +``` + +8 的平方根是 2.82842...,向下取整即為 2。 + + +### 題解 + +我們可以將這道題想像成:給定一個非負整數 `x`,求 $f(t) = t^2 − x = 0$ 的解。由於我們只考慮 $t ≥ 0$,因此 $f(t)$ 在定義域內是單調遞增的。考慮到 $f(0) = −x ≤ 0$,$f(x) = x^2 − x ≥ 0$,我們可以對 $[0, x]$ 區間使用二分搜尋找到 $f(t) = 0$ 的解。此處我們採用左閉右閉的寫法。 + +在 C++ 解法中,$mid = (l + r) / 2$ 可能會因為 $l + r$ 溢出而出錯,因此改為 $mid = l + (r − l) / 2$ 的寫法;直接計算 $mid ∗ mid$ 也可能溢出,因此我們比較 $mid$ 和 $x / mid$。 + + + + +```cpp +int mySqrt(int x) { + int l = 1, r = x, mid, x_div_mid; + while (l <= r) { + mid = l + (r - l) / 2; + x_div_mid = x / mid; + if (mid == x_div_mid) { + return mid; + } + if (mid < x_div_mid) { + l = mid + 1; + } else { + r = mid - 1; + } + } + return r; +} +``` + + + + +```py +def mySqrt(x: int) -> int: + l, r = 1, x + while l <= r: + mid = (l + r) // 2 + mid_sqr = mid**2 + if mid_sqr == x: + return mid + if mid_sqr < x: + l = mid + 1 + else: + r = mid - 1 + return r +``` + + + + + +此外,這道題還有一種更快的算法——`牛頓迭代法`,其公式為 $t_{n+1} = t_n - \frac{f(t_n)}{f'(t_n)}$。給定 $f(t) = t^2 − x = 0$,其迭代公式為 $t_{n+1} = \frac{t_n + \frac{x}{t_n}}{2}$。 + + + + +```cpp +int mySqrt(int x) { + long t = x; + while (t * t > x) { + t = (t + x / t) / 2; + } + return t; +} +``` + + + + +```py +def mySqrt(x: int) -> int: + t = x + while t**2 > x: + t = (t + x // t) // 2 + return t +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-3-interval-search.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-3-interval-search.mdx new file mode 100644 index 00000000..e15b91df --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-3-interval-search.mdx @@ -0,0 +1,109 @@ +--- +sidebar_position: 13 +--- + +# 3.3 搜尋範圍 + +## [34. Find First and Last Position of Element in Sorted Array](https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/) + +### 題目描述 + +給定一個遞增的整數數組和一個目標值,查找該值第一次和最後一次出現的位置。 + + +### 輸入輸出範例 + +輸入是一個數組和一個值,輸出為該值第一次出現的位置和最後一次出現的位置(從 0 開始);如果該值不存在,則兩個返回值都設為 -1。 + +``` +Input: nums = [5,7,7,8,8,10], target = 8 +Output: [3,4] +``` + +數字 8 在第 3 位第一次出現,在第 4 位最後一次出現。 + +### 題解 + +這道題可以看作是實現 C++ 的 `lower_bound` 和 `upper_bound` 函數,或者 Python 的 `bisect_left` 和 `bisect_right` 函數。我們這裡採用左閉右開的寫法,當然左閉右閉也可以。 + + + + + +```cpp +int lowerBound(vector &nums, int target) { + int l = 0, r = nums.size(), mid; + while (l < r) { + mid = l + (r - l) / 2; + if (nums[mid] < target) { + l = mid + 1; + } else { + r = mid; + } + } + return l; +} + +int upperBound(vector &nums, int target) { + int l = 0, r = nums.size(), mid; + while (l < r) { + mid = l + (r - l) / 2; + if (nums[mid] <= target) { + l = mid + 1; + } else { + r = mid; + } + } + return l; +} + +vector searchRange(vector &nums, int target) { + if (nums.empty()) { + return vector{-1, -1}; + } + int lower = lowerBound(nums, target); + int upper = upperBound(nums, target) - 1; + if (lower == nums.size() || nums[lower] != target) { + return vector{-1, -1}; + } + return vector{lower, upper}; +} +``` + + + + +```py +def lowerBound(nums: List[int], target: int) -> int: + l, r = 0, len(nums) + while l < r: + mid = (l + r) // 2 + if nums[mid] < target: + l = mid + 1 + else: + r = mid + return l + +def upperBound(nums: List[int], target: int) -> int: + l, r = 0, len(nums) + while l < r: + mid = (l + r) // 2 + if nums[mid] <= target: + l = mid + 1 + else: + r = mid + return l + +def searchRange(nums: List[int], target: int) -> List[int]: + if not nums: + return [-1, -1] + lower = lowerBound(nums, target) + upper = upperBound(nums, target) - 1 + if lower == len(nums) or nums[lower] != target: + return [-1, -1] + return [lower, upper] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-4-peak-finding.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-4-peak-finding.mdx new file mode 100644 index 00000000..77ce6558 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-4-peak-finding.mdx @@ -0,0 +1,86 @@ +--- +sidebar_position: 14 +--- + +# 3.4 搜尋最大值 + +## [162. Find Peak Element](https://leetcode.com/problems/find-peak-element/) + +### 題目描述 + +給定一個數組,定義最大值為比兩邊都大的數字,要求出任意一個最大值的位置。一個數組中可能存在多個最大值,返回任意一個即可。要求時間複雜度為 $O(\log n)$。 + +### 輸入輸出範例 + +輸入是一個數組,輸出為最大值的位置。 + +``` +Input: nums = [1,2,3,1] +Output: 2 +``` + +最大值 3 出現在位置 2。 + + +### 題解 + +為了實現 $O(\log n)$ 的時間複雜度,我們可以對數組進行二分搜尋。在確保數組兩端不是最大值後,若當前中點不是最大值,那麼其左右一側必定存在一個最大值。 + + + + + +```cpp +int findPeakElement(vector& nums) { + int n = nums.size(); + if (n == 1) { + return 0; + } + if (nums[0] > nums[1]) { + return 0; + } + if (nums[n - 1] > nums[n - 2]) { + return n - 1; + } + int l = 1, r = n - 2, mid; + while (l <= r) { + mid = l + (r - l) / 2; + if (nums[mid] > nums[mid + 1] && nums[mid] > nums[mid - 1]) { + return mid; + } else if (nums[mid] > nums[mid - 1]) { + l = mid + 1; + } else { + r = mid - 1; + } + } + return -1; +} +``` + + + + +```py +def findPeakElement(self, nums: List[int]) -> int: + n = len(nums) + if n == 1: + return 0 + if nums[0] > nums[1]: + return 0 + if nums[n - 1] > nums[n - 2]: + return n - 1 + l, r = 1, n - 2 + while l <= r: + mid = (l + r) // 2 + if nums[mid] > nums[mid + 1] and nums[mid] > nums[mid - 1]: + return mid + elif nums[mid] > nums[mid - 1]: + l = mid + 1 + else: + r = mid - 1 + return -1 +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-5-rotated-array-search.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-5-rotated-array-search.mdx new file mode 100644 index 00000000..7304132b --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-5-rotated-array-search.mdx @@ -0,0 +1,98 @@ +--- +sidebar_position: 15 +--- + +# 3.5 搜尋旋轉數組中的數字 + +## [81. Search in Rotated Sorted Array II](https://leetcode.com/problems/search-in-rotated-sorted-array-ii/) + +### 題目描述 + +一個原本遞增的數組被首尾相連後按某個位置斷開(如 [1,2,2,3,4,5] → [2,3,4,5,1,2],在第一位和第二位斷開),我們稱其為旋轉數組。給定一個值,判斷這個值是否存在於這個旋轉數組中。 + +### 輸入輸出範例 + +輸入是一個數組和一個值,輸出是一個布林值,表示數組中是否存在該值。 + +``` +Input: nums = [2,5,6,0,0,1,2], target = 0 +Output: true +``` + +即使數組被旋轉過,我們仍然可以利用這個數組的遞增性,使用二分搜尋。對於當前的中點,如果它指向的值小於等於右端,那麼說明右區間是排好序的;反之,那麼說明左區間是排好序的。如果目標值位於排好序的區間內,我們可以對這個區間繼續二分搜尋;反之,我們對於另一半區間繼續二分搜尋。本題我們採用左閉右閉的寫法。 + + +### 題解 + + + + + +```cpp +bool search(vector& nums, int target) { + int l = 0, r = nums.size() - 1; + while (l <= r) { + int mid = l + (r - l) / 2; + if (nums[mid] == target) { + return true; + } + if (nums[mid] == nums[l]) { + // 無法判斷哪個區間是遞增的,但 l 位置一定不是 target。 + ++l; + } else if (nums[mid] == nums[r]) { + // 無法判斷哪個區間是遞增的,但 r 位置一定不是 target。 + --r; + } else if (nums[mid] < nums[r]) { + // 右區間是遞增的。 + if (target > nums[mid] && target <= nums[r]) { + l = mid + 1; + } else { + r = mid - 1; + } + } else { + // 左區間是遞增的。 + if (target >= nums[l] && target < nums[mid]) { + r = mid - 1; + } else { + l = mid + 1; + } + } + } + return false; +} +``` + + + + +```py +def search(nums: List[int], target: int) -> bool: + l, r = 0, len(nums) - 1 + while l <= r: + mid = (l + r) // 2 + if nums[mid] == target: + return True + if nums[mid] == nums[l]: + # 無法判斷哪個區間是遞增的,但 l 位置一定不是 target。 + l += 1 + elif nums[mid] == nums[r]: + # 無法判斷哪個區間是遞增的,但 r 位置一定不是 target。 + r -= 1 + elif nums[mid] < nums[r]: + # 右區間是遞增的。 + if nums[mid] < target <= nums[r]: + l = mid + 1 + else: + r = mid - 1 + else: + # 左區間是遞增的。 + if nums[l] <= target < nums[mid]: + r = mid - 1 + else: + l = mid + 1 + return False +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-6-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-6-exercises.md new file mode 100644 index 00000000..dfce9bf4 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-6-exercises.md @@ -0,0 +1,21 @@ +--- +sidebar_position: 16 +--- + +# 3.6 練習 + +## 基礎難度 + +### [154. Find Minimum in Rotated Sorted Array II](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array-ii/) + +旋轉數組的變形題之一。 + +### [540. Single Element in a Sorted Array](https://leetcode.com/problems/single-element-in-a-sorted-array/) + +在出現單獨數之前和之後,奇數位與偶數位的值發生了什麼變化? + +## 進階難度 + +### [4. Median of Two Sorted Arrays](https://leetcode.com/problems/median-of-two-sorted-arrays/) + +需要對兩個數組同時進行二分搜尋。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/_category_.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/_category_.json new file mode 100644 index 00000000..89e9fd2f --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "3. 居合斩!二分查找", + "position": 3, + "link": { + "type": "generated-index", + "description": "第 3 章 居合斩!二分查找" + } +} diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-1-common-sorting-algorithms.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-1-common-sorting-algorithms.mdx new file mode 100644 index 00000000..8c1596c0 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-1-common-sorting-algorithms.mdx @@ -0,0 +1,150 @@ +--- +sidebar_position: 17 +--- + +# 4.1 常用排序算法 + +雖然在 C++ 和 Python 裡都可以通過 sort 函數排序,而且在刷題時很少需要自己手寫排序算法,但熟悉各種排序算法可以加深對算法的基本理解,並有助於解決由這些排序算法引申出的題目。這裡展示兩種時間複雜度為 $O(n \log n)$ 的排序算法:`快速排序` 和 `合併排序`。其中前者速度較快,後者能保證相同值的元素在數組中的相對位置不變(即“穩定排序”)。 + + +## 快速排序(Quicksort) + +快速排序的原理並不複雜:對於一個未排序片段,我們先隨機選擇一個位置作為樞軸,然後通過遍歷操作,將所有比樞軸小的數字移動到其左側,再將所有比樞軸大的數字移動到其右側。操作完成後,我們對樞軸左右側的片段再次進行快速排序即可。可證明,如果樞軸選取是隨機的,那麼該算法的平均複雜度可以達到 $O(n \log n)$,但最差情況下複雜度為 $O(n^2)$。 + +我們採用左閉右閉的二分寫法,初始化條件為 $l = 0, r = n - 1$。 + + + + +```cpp +void quickSort(vector &nums, int l, int r) { + if (l >= r) { + return; + } + // 在當前的 [l, r] 區間中,隨機選擇一個位置作為樞軸。 + int pivot = l + (rand() % (r - l + 1)); + int pivot_val = nums[pivot]; + // 將樞軸與 l 交換。 + swap(nums[l], nums[pivot]); + // 從 [l+1, r] 兩端向內遍歷,查找是否有位置不滿足遞增關係。 + int i = l + 1, j = r; + while (true) { + while (i < j && nums[j] >= pivot_val) { + --j; + } + while (i < j && nums[i] <= pivot_val) { + ++i; + } + if (i == j) { + break; + } + // i 位置的值大於樞軸值,j 位置的值小於樞軸值,將二者交換。 + swap(nums[i], nums[j]); + } + // i 和 j 相遇的位置即為新的樞軸,我們將樞軸與 l 重新交換回來。 + // 此時相遇位置左側一定比樞軸值小,右側一定比樞軸值大。 + int new_pivot = nums[i] <= nums[l] ? i : i - 1; + swap(nums[l], nums[new_pivot]); + quickSort(nums, l, new_pivot - 1); + quickSort(nums, new_pivot + 1, r); +} +``` + + + + +```py +def quickSort(nums: List[int], l: int, r: int) -> None: + if l >= r: + return + # 在當前的 [l, r] 區間中,隨機選擇一個位置作為樞軸。 + pivot = random.randint(l, r) + pivot_val = nums[pivot] + # 將樞軸與 l 交換。 + nums[l], nums[pivot] = nums[pivot], nums[l] + # 從 [l+1, r] 兩端向內遍歷,查找是否有位置不滿足遞增關係。 + i, j = l + 1, r + while True: + while i < j and nums[j] >= pivot_val: + j -= 1 + while i < j and nums[i] <= pivot_val: + i += 1 + if i == j: + break + # i 位置的值大於樞軸值,j 位置的值小於樞軸值,將二者交換。 + nums[i], nums[j] = nums[j], nums[i] + # i 和 j 相遇的位置即為新的樞軸,我們將樞軸與 l 重新交換回來。 + # 此時相遇位置左側一定比樞軸值小,右側一定比樞軸值大。 + new_pivot = i if nums[i] <= nums[l] else i - 1 + nums[l], nums[new_pivot] = nums[new_pivot], nums[l] + quickSort(nums, l, new_pivot - 1) + quickSort(nums, new_pivot + 1, r) +``` + + + + + +## 合併排序(Merge Sort) + +合併排序是典型的分治法,會在後續章節展開講解。簡單來說,對於一個未排序片段,我們可以先分別排序其左半側和右半側,然後將兩側重新合併(“治”);排序每個半側時可以通過遞歸再次將其切分為兩側(“分”)。 + +我們採用左閉右閉的二分寫法,初始化條件為 $l = 0, r = n - 1$,並提前建立一個與 nums 大小相同的數組 cache,用來存儲臨時結果。 + + + + +```cpp +void mergeSort(vector &nums, vector &cache, int l, int r) { + if (l >= r) { + return; + } + // 分。 + int mid = l + (r - l) / 2; + mergeSort(nums, cache, l, mid); + mergeSort(nums, cache, mid + 1, r); + // 治。 + // i 和 j 同時向右前進,i 的範圍是 [l, mid],j 的範圍是 [mid+1, r]。 + int i = l, j = mid + 1; + for (int pos = l; pos <= r; ++pos) { + if (j > r || (i <= mid && nums[i] <= nums[j])) { + cache[pos] = nums[i++]; + } else { + cache[pos] = nums[j++]; + } + } + // 將 cache 的數據複製回 nums。 + for (int pos = l; pos <= r; ++pos) { + nums[pos] = cache[pos]; + } +} +``` + + + + +```py +def mergeSort(nums: List[int], cache: List[int], l: int, r: int) -> None: + if l >= r: + return + # 分。 + mid = (l + r) // 2 + mergeSort(nums, cache, l, mid) + mergeSort(nums, cache, mid + 1, r) + # 治。 + # i 和 j 同時向右前進,i 的範圍是 [l, mid],j 的範圍是 [mid+1, r]。 + i, j = l, mid + 1 + for pos in range(l, r + 1): + if j > r or (i <= mid and nums[i] <= nums[j]): + cache[pos] = nums[i] + i += 1 + else: + cache[pos] = nums[j] + j += 1 + # 將 cache 的數據複製回 nums。 + nums[l:r+1] = cache[l:r+1] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-2-quick-select.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-2-quick-select.mdx new file mode 100644 index 00000000..fa401029 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-2-quick-select.mdx @@ -0,0 +1,78 @@ +--- +sidebar_position: 18 +--- + +# 4.2 快速選擇 + +## [215. Kth Largest Element in an Array](https://leetcode.com/problems/kth-largest-element-in-an-array/) + +### 題目描述 + +在一個未排序的數組中,找到第 $k$ 大的數字。 + +### 輸入輸出範例 + +輸入一個數組和一個目標值 $k$,輸出第 $k$ 大的數字。題目保證一定有解。 + +``` +Input: [3,2,1,5,6,4] and k = 2 +Output: 5 +``` + +### 題解 + +`快速選擇` 通常用於解決 k-th Element 問題,可以在平均 $O(n)$ 時間複雜度和 $O(1)$ 空間複雜度下完成求解。快速選擇的實現與快速排序相似,但只需要找到第 $k$ 大的中樞(pivot),不需要對中樞左右再進行排序。與快速排序一樣,快速選擇一般需要先將數組打亂,否則最壞情況下的時間複雜度為 $O(n^2)$。 + +如果直接使用上述快速排序的代碼運行,可能會在 LeetCode 平台上接近超時。我們可以使用空間換取時間,直接儲存比中樞值小和大的元素,盡量避免進行交換操作。 + + + + +```cpp +int findKthLargest(vector nums, int k) { + int pivot = rand() % nums.size(); + int pivot_val = nums[pivot]; + vector larger, equal, smaller; + for (int num : nums) { + if (num > pivot_val) { + larger.push_back(num); + } else if (num < pivot_val) { + smaller.push_back(num); + } else { + equal.push_back(num); + } + } + if (k <= larger.size()) { + return findKthLargest(larger, k); + } + if (k > larger.size() + equal.size()) { + return findKthLargest(smaller, k - larger.size() - equal.size()); + } + return pivot_val; +} +``` + + + + +```py +def findKthLargest(nums: List[int], k: int) -> int: + pivot_val = random.choice(nums) + larger, equal, smaller = [], [], [] + for num in nums: + if num > pivot_val: + larger.append(num) + elif num < pivot_val: + smaller.append(num) + else: + equal.append(num) + if k <= len(larger): + return findKthLargest(larger, k) + if k > len(larger) + len(equal): + return findKthLargest(smaller, k - len(larger) - len(equal)) + return pivot_val +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-3-bucket-sort.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-3-bucket-sort.mdx new file mode 100644 index 00000000..a8e42c52 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-3-bucket-sort.mdx @@ -0,0 +1,83 @@ +--- +sidebar_position: 19 +--- + +# 4.3 桶排序 + +## [347. Top K Frequent Elements](https://leetcode.com/problems/top-k-frequent-elements/) + +### 題目描述 + +給定一個數組,求前 $k$ 個最常出現的數字。 + +### 輸入輸出範例 + +輸入是一個數組和一個目標值 $k$。輸出是一個長度為 $k$ 的數組。 + +``` +Input: nums = [1,1,1,1,2,2,3,4], k = 2 +Output: [1,2] +``` + +在這個範例中,最常出現的兩個數字是 1 和 2。 + +### 題解 + +顧名思義,`桶排序` 的意思是為每個值設立一個桶,桶內記錄這個值出現的次數(或其他屬性),然後對桶進行排序。針對範例來說,我們先通過桶排序得到四個桶 [1,2,3,4],它們的值分別為 [4,2,1,1],表示每個數字出現的頻率。 + +接著,我們對桶的頻率進行排序,前 $k$ 大的桶即是前 $k$ 個最常出現的數字。這裡我們可以使用各種排序算法,甚至可以再進行一次桶排序,把每個舊桶根據頻率放在不同的新桶內。針對範例來說,因為目前最大的頻率是 4,我們建立 [1,2,3,4] 四個新桶,它們分別放入的舊桶為 [[3,4],[2],[],[1]],表示不同數字出現的頻率。最後,我們從後往前遍歷,直到找到 k 個舊桶。 + +我們可以使用 C++ 中的 `unordered_map` 或 Python 中的 `dict` 實現雜湊表。 + + + + +```cpp +vector topKFrequent(vector& nums, int k) { + unordered_map counts; + for (int num : nums) { + ++counts[num]; + } + unordered_map> buckets; + for (auto [num, count] : counts) { + buckets[count].push_back(num); + } + vector top_k; + for (int count = nums.size(); count >= 0; --count) { + if (buckets.contains(count)) { + for (int num : buckets[count]) { + top_k.push_back(num); + if (top_k.size() == k) { + return top_k; + } + } + } + } + return top_k; +} +``` + + + + +```py +def topKFrequent(nums: List[int], k: int) -> List[int]: + counts = Counter(nums) + buckets = dict() + for num, count in counts.items(): + if count in buckets: + buckets[count].append(num) + else: + buckets[count] = [num] + top_k = [] + for count in range(len(nums), 0, -1): + if count in buckets: + top_k += buckets[count] + if len(top_k) >= k: + return top_k[:k] + return top_k[:k] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-4-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-4-exercises.md new file mode 100644 index 00000000..570ece94 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-4-exercises.md @@ -0,0 +1,17 @@ +--- +sidebar_position: 20 +--- + +# 4.4 練習 + +## 基礎難度 + +### [451. Sort Characters By Frequency](https://leetcode.com/problems/sort-characters-by-frequency/) + +桶排序的變形題。 + +## 進階難度 + +### [75. Sort Colors](https://leetcode.com/problems/sort-colors/) + +非常經典的荷蘭國旗問題,考察如何對三個重複且混亂的值進行排序。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/_category_.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/_category_.json new file mode 100644 index 00000000..4aad536a --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "4. 千奇百怪的排序算法", + "position": 4, + "link": { + "type": "generated-index", + "description": "第 4 章 千奇百怪的排序算法" + } +} diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-1-algorithm-explanation.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-1-algorithm-explanation.md new file mode 100644 index 00000000..98562e8d --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-1-algorithm-explanation.md @@ -0,0 +1,7 @@ +--- +sidebar_position: 21 +--- + +# 5.1 算法解释 + +`深度優先搜尋 (DFS)` 和 `廣度優先搜尋 (BFS)` 是兩種最常見的優先搜尋方法,廣泛應用於圖與樹等結構的搜尋中。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-2-depth-first-search.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-2-depth-first-search.mdx new file mode 100644 index 00000000..1c320d88 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-2-depth-first-search.mdx @@ -0,0 +1,375 @@ +--- +sidebar_position: 22 +--- + +# 5.2 深度优先搜索 + +`深度優先搜尋 (DFS)` 是一種搜尋方法,在搜尋到一個新節點時,會立即對該節點進行遍歷。因此,遍歷需要使用 `先入後出 (LIFO) 的堆疊`,也可以透過與堆疊等價的 `遞迴` 來實現。對於樹結構而言,由於每次總是對新節點進行遍歷,因此看起來像是往“深”的方向前進。在 Python 中,我們可以使用 collections.deque 來實現 C++ 中的堆疊。然而,在大多數情況下,我們會選擇使用 C++ 的 vector 或 Python 的 list 來實現堆疊,因為它們不僅是先入後出的數據結構,還支持隨機存取。 + +考慮以下簡單的樹結構,從節點 1 開始進行遍歷。如果遍歷順序是從左子節點到右子節點,那麼按照優先往“深”的方向前進的策略,遍歷過程將是:1(起始節點)→ 2(更深層的左子節點)→ 4(更深層的左子節點)→ 2(無子節點,返回父節點)→ 1(所有子節點已完成遍歷,返回父節點)→ 3(更深層的右子節點)→ 1(無子節點,返回父節點)→ 結束程序(所有子節點已完成遍歷)。如果我們使用堆疊實現,堆疊頂部元素的變化過程將是:1 → 2 → 4 → 3。 + +``` + 1 + / \ + 2 3 + / +4 +``` + +深度優先搜尋也可以用來 `檢測迴路`:記錄每個遍歷過的節點的父節點,若某節點被再次遍歷且父節點不同,則說明存在迴路。另一種方法是利用拓撲排序判斷是否有迴路,若最後有節點的入度不為零,則說明存在迴路。 + +有時我們需要對已經搜尋過的節點進行標記,以防止重複搜索,這種做法稱為 `狀態記錄` 或 `記憶化 (memoization)`。 + +## [695. Max Area of Island](https://leetcode.com/problems/max-area-of-island/) + +### 題目描述 + +給定一個二維的 0-1 矩陣,其中 `0` 表示海洋,`1` 表示陸地。獨立的或相鄰的陸地可以形成島嶼,每個格子僅與其上下左右四個格子相鄰。求最大的島嶼面積。 + +### 輸入輸出範例 + +輸入是一個二維陣列,輸出是一個整數,表示最大的島嶼面積。 + +``` +Input: +[[1,0,1,1,0,1,0,1], +[1,0,1,1,0,1,1,1], +[0,0,0,0,0,0,0,1]] +Output: 6 +``` + +最大的島嶼面積為 6,位於最右側。 + +### 題解 + +此題是一個非常標準的搜索問題,我們可以用來練習深度優先搜索(DFS)。一般來說,深度優先搜索類型的題目可以分為主函數和輔函數兩部分。主函數負責遍歷所有的搜索位置,判斷是否可以開始搜索,如果可以則調用輔函數進行搜索。輔函數則負責深度優先搜索的遞歸調用。 + +當然,我們也可以使用堆疊(stack)來實現深度優先搜索,但由於堆疊與遞歸的運作原理相同,而遞歸相對來說實現起來更為方便,因此在刷題時建議使用遞歸的寫法,這樣也有利於進行回溯(見下節)。不過在實際工程中,直接使用堆疊可能才是更好的選擇,原因有二:一是更容易理解,二是不容易出現遞歸堆疊溢出的情況。 + +我們先展示使用堆疊的寫法。這裡我們使用了一個小技巧,對於四個方向的遍歷,可以創建一個數組 `[-1, 0, 1, 0, -1]`,每相鄰兩位即對應上下左右四個方向之一。當然,您也可以顯式地寫成 `[-1, 0]`、`[1, 0]`、`[0, 1]` 和 `[0, -1]`,以便於理解。 + + + + + +```cpp +int maxAreaOfIsland(vector>& grid) { + vector direction{-1, 0, 1, 0, -1}; + int m = grid.size(), n = grid[0].size(), max_area = 0; + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (grid[i][j] == 1) { + stack> island; + // 初始化第一個節點。 + int local_area = 1; + grid[i][j] = 0; + island.push({i, j}); + // 深度優先搜索 (DFS)。 + while (!island.empty()) { + auto [r, c] = island.top(); + island.pop(); + for (int k = 0; k < 4; ++k) { + int x = r + direction[k], y = c + direction[k + 1]; + // 將滿足條件的相鄰節點加入堆疊。 + if (x >= 0 && x < m && y >= 0 && y < n && + grid[x][y] == 1) { + ++local_area; + grid[x][y] = 0; + island.push({x, y}); + } + } + } + max_area = max(max_area, local_area); + } + } + } + return max_area; +} +``` + + + + +```py +def maxAreaOfIsland(grid: List[List[int]]) -> int: + direction = [-1, 0, 1, 0, -1] + m, n, max_area = len(grid), len(grid[0]), 0 + for i in range(m): + for j in range(n): + if grid[i][j] == 1: + island = [] + # 初始化第一個節點。 + local_area = 1 + grid[i][j] = 0 + island.append((i, j)) + # 深度優先搜索 (DFS)。 + while len(island) > 0: + r, c = island.pop() + for k in range(4): + x, y = r + direction[k], c + direction[k + 1] + # 將滿足條件的相鄰節點加入堆疊。 + if 0 <= x < m and 0 <= y < n and grid[x][y] == 1: + local_area += 1 + grid[x][y] = 0 + island.append((x, y)) + max_area = max(max_area, local_area) + return max_area +``` + + + + + +下面我們展示遞迴寫法,注意進行遞迴搜尋時,一定要檢查邊界條件。可以在每次呼叫輔助函式之前檢查,也可以在輔助函式的一開始進行檢查。這裡我們沒有利用 [-1, 0, 1, 0, -1] 陣列進行上下左右四個方向的搜尋,而是直接顯式地寫出來四種不同的遞迴函式。兩種寫法都可以,讀者可以掌握任意一種。 + + + + +```cpp +// 輔助函式。 +int dfs(vector>& grid, int r, int c) { + if (r < 0 || r >= grid.size() || c < 0 || c >= grid[0].size() || + grid[r][c] == 0) { + return 0; + } + grid[r][c] = 0; + return (1 + dfs(grid, r + 1, c) + dfs(grid, r - 1, c) + + dfs(grid, r, c + 1) + dfs(grid, r, c - 1)); +} + +// 主函式。 +int maxAreaOfIsland(vector>& grid) { + int max_area = 0; + for (int i = 0; i < grid.size(); ++i) { + for (int j = 0; j < grid[0].size(); ++j) { + max_area = max(max_area, dfs(grid, i, j)); + } + } + return max_area; +} +``` + + + + +```py +# 輔助函式。 +def dfs(grid: List[List[int]], r: int, c: int) -> int: + if r < 0 or r >= len(grid) or c < 0 or c >= len(grid[0]) or grid[r][c] == 0: + return 0 + grid[r][c] = 0 + return (1 + dfs(grid, r + 1, c) + dfs(grid, r - 1, c) + + dfs(grid, r, c + 1) + dfs(grid, r, c - 1)) + +# 主函式。 +def maxAreaOfIsland(grid: List[List[int]]) -> int: + max_area = 0 + for i in range(len(grid)): + for j in range(len(grid[0])): + max_area = max(max_area, dfs(grid, i, j)) + return max_area +``` + + + + + +## [547. Number of Provinces](https://leetcode.com/problems/number-of-provinces/) + +### 題目描述 + +給定一個二維的 0-1 矩陣,如果第 (i, j) 位置是 1,則表示第 i 個城市和第 j 個城市處於同一城市圈。已知城市的相鄰關係是可以傳遞的,即如果 a 和 b 相鄰,b 和 c 相鄰,那麼 a 和 c 也相鄰,換言之這三個城市處於同一個城市圈之內。求一共有多少個城市圈。 + +### 輸入輸出範例 + +輸入是一個二維數組,輸出是一個整數,表示城市圈數量。因為城市相鄰關係具有對稱性,該二維數組為對稱矩陣。同時,因為自己也處於自己的城市圈,對角線上的值全部為 1。 + +``` +Input: +[[1,1,0], +[1,1,0], +[0,0,1]] +Output: 2 +``` + +在這個範例中,[1,2] 處於一個城市圈,[3] 處於另一個城市圈。 + +### 題解 + +在上一道題目中,圖的表示方法是,每個位置代表一個節點,每個節點與上下左右四個節點相鄰。而在這一道題目裡面,每一行(列)表示一個節點,它的每列(行)表示是否存在一個相鄰節點。上一道題目擁有 $m \times n$ 個節點,每個節點有 4 條邊;而本題擁有 $n$ 個節點,每個節點最多有 $n$ 條邊,表示和所有城市都相鄰,最少可以有 1 條邊,表示當前城市圈只有自己。當清楚了圖的表示方法後,這道題目與上一道題目本質上是同一道題:搜索城市圈(島嶼圈)的個數。我們這裡採用遞迴的寫法。 + +:::warning + +對於節點連接類問題,我們也可以利用並查集來進行快速的連接和搜索。我們將會在之後的章節講解。 + +::: + + + + +```cpp +// 輔助函式。 +void dfs(vector>& isConnected, int i, vector& visited) { + visited[i] = true; + for (int j = 0; j < isConnected.size(); ++j) { + if (isConnected[i][j] == 1 && !visited[j]) { + dfs(isConnected, j, visited); + } + } +} + +// 主函式。 +int findCircleNum(vector>& isConnected) { + int n = isConnected.size(), count = 0; + // 防止重複搜索已被搜索過的節點 + vector visited(n, false); + for (int i = 0; i < n; ++i) { + if (!visited[i]) { + dfs(isConnected, i, visited); + ++count; + } + } + return count; +} +``` + + + + +```py +# 輔助函式。 +def dfs(isConnected: List[List[int]], city: int, visited: Set[int]): + visited.add(city) + for i in range(len(isConnected)): + if isConnected[city][i] == 1 and i not in visited: + dfs(isConnected, i, visited) + +# 主函式。 +def findCircleNum(isConnected: List[List[int]]) -> int: + count = 0 + # 防止重複搜索已被搜索過的節點 + visited = set() + for i in range(len(isConnected)): + if i not in visited: + dfs(isConnected, i, visited) + count += 1 + return count +``` + + + + + + +## [417. Pacific Atlantic Water Flow](https://leetcode.com/problems/pacific-atlantic-water-flow/) + +### 題目描述 + +給定一個二維的非負整數矩陣,每個位置的值表示海拔高度。假設左邊和上邊是太平洋,右邊和下邊是大西洋,求從哪些位置向下流水可以流到太平洋和大西洋。水只能從海拔高的位置流向海拔低或相同的位置。 + +### 輸入輸出範例 + +輸入是一個二維的非負整數矩陣,表示海拔高度。輸出是一個二維的數組,其中第二維大小固定為 2,表示滿足條件的位置坐標。 + +``` +Input: + 太平洋 ~ ~ ~ ~ ~ + ~ 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 * + * * * * * 大西洋 +Output: [[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]] +``` + +在此範例中,有括號的區域為滿足條件的位置。 + + +### 題解 + +雖然題目要求找到可以向下流到達兩個大洋的位置,如果對所有位置進行搜索,複雜度會非常高且無法剪枝。因此我們可以反向思考,從兩個大洋開始模擬水往上流,這樣只需要對矩形的四條邊進行搜索。完成搜索後,遍歷整個矩陣,找到兩個大洋向上流都能到達的位置,即為滿足條件的位置。 + + + + +```cpp +vector direction{-1, 0, 1, 0, -1}; +// 輔助函式。 +void dfs(const vector>& heights, vector>& can_reach, + int r, int c) { + if (can_reach[r][c]) { + return; + } + can_reach[r][c] = true; + for (int i = 0; i < 4; ++i) { + int x = r + direction[i], y = c + direction[i + 1]; + if (x >= 0 && x < heights.size() && y >= 0 && y < heights[0].size() && + heights[r][c] <= heights[x][y]) { + dfs(heights, can_reach, x, y); + } + } +} + +// 主函式。 +vector> pacificAtlantic(vector>& heights) { + int m = heights.size(), n = heights[0].size(); + vector> can_reach_p(m, vector(n, false)); + vector> can_reach_a(m, vector(n, false)); + vector> can_reach_p_and_a; + for (int i = 0; i < m; ++i) { + dfs(heights, can_reach_p, i, 0); + dfs(heights, can_reach_a, i, n - 1); + } + for (int i = 0; i < n; ++i) { + dfs(heights, can_reach_p, 0, i); + dfs(heights, can_reach_a, m - 1, i); + } + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (can_reach_p[i][j] && can_reach_a[i][j]) { + can_reach_p_and_a.push_back({i, j}); + } + } + } + return can_reach_p_and_a; +} +``` + + + + +```py +direction = [-1, 0, 1, 0, -1] + +# 輔助函式。 +def dfs(heights: List[List[int]], can_reach: List[List[int]], r: int, c: int): + if can_reach[r][c]: + return + can_reach[r][c] = True + for i in range(4): + x, y = r + direction[i], c + direction[i + 1] + if (x >= 0 and x < len(heights) and y >= 0 and y < len(heights[0]) and + heights[x][y] >= heights[r][c]): + dfs(heights, can_reach, x, y) + +# 主函式。 +def pacificAtlantic(heights: List[List[int]]) -> List[List[int]]: + m, n = len(heights), len(heights[0]) + can_reach_p = [[False for _ in range(n)] for _ in range(m)] + can_reach_a = [[False for _ in range(n)] for _ in range(m)] + for i in range(m): + dfs(heights, can_reach_p, i, 0) + dfs(heights, can_reach_a, i, n - 1) + for j in range(n): + dfs(heights, can_reach_p, 0, j) + dfs(heights, can_reach_a, m - 1, j) + return [ + [i, j] for i in range(m) for j in range(n) + if can_reach_p[i][j] and can_reach_a[i][j] + ] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-3-backtracking.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-3-backtracking.mdx new file mode 100644 index 00000000..112e331e --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-3-backtracking.mdx @@ -0,0 +1,378 @@ +--- +sidebar_position: 23 +--- + +# 5.3 回溯法 + +`回溯法`(backtracking)是優先搜索的一種特殊情況,又稱為試探法,常用於需要記錄節點狀態的深度優先搜索。通常來說,排列、組合、選擇類問題使用回溯法比較方便。 + +顧名思義,回溯法的核心是回溯。在搜索到某一節點的時候,如果我們發現目前的節點(及其子節點)並不是需求目標時,我們回退到原來的節點繼續搜索,並且`把在目前節點修改的狀態還原`。這樣的好處是我們可以始終只對圖的總狀態進行修改,而非每次遍歷時新建一個圖來儲存狀態。在具體的寫法上,它與普通的深度優先搜索一樣,都有 [修改當前節點狀態]→[遞迴子節點] 的步驟,只是多了回溯的步驟,變成了 [修改當前節點狀態]→[遞迴子節點]→[回復當前節點狀態]。 + +沒有接觸過回溯法的讀者可能會不明白我在講什麼,這也完全正常,希望以下幾道題可以讓您理解回溯法。如果還是不明白,可以記住兩個小訣竅,`一是按引用傳遞狀態,二是所有的狀態修改在遞迴完成後回復`。 + +回溯法修改一般有兩種情況,一種是修改最後一位輸出,比如排列組合;一種是修改訪問標記,比如矩陣裡搜尋字串。 + + +## [46. Permutations](https://leetcode.com/problems/permutations/) + +### 題目描述 + +給定一個無重複數字的整數數組,求其所有排列方式。 + +### 輸入輸出範例 + +輸入是一個一維整數陣列,輸出是一個二維陣列,表示輸入陣列的所有排列方式。 + +``` +Input: [1,2,3] +Output: [[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,2,1], [3,1,2]] +``` + +輸出的順序無需固定,只需包含所有排列即可。 + +### 題解 + +如何生成所有排列方式呢?對於每個位置 \(i\),我們可以將其與之後的任意位置交換,然後處理位置 \(i+1\),直到處理到最後一位。為了避免每次遍歷時新建一個數組存儲前 \(i\) 個已交換好的數字,我們可以利用回溯法,僅修改原數組,並在遞迴完成後復原。 + +以樣例 `[1,2,3]` 為例,按照此方法,我們的輸出順序為:`[[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,2,1], [3,1,2]]`,確保涵蓋所有排列。 + + + + + +```cpp +// 輔助函式。 +void backtracking(vector &nums, int level, + vector> &permutations) { + if (level == nums.size() - 1) { + permutations.push_back(nums); // 儲存當前排列。 + return; + } + for (int i = level; i < nums.size(); ++i) { + swap(nums[i], nums[level]); // 修改當前節點狀態。 + backtracking(nums, level + 1, permutations); // 遞迴子節點。 + swap(nums[i], nums[level]); // 回復當前節點狀態。 + } +} + +// 主函式。 +vector> permute(vector &nums) { + vector> permutations; + backtracking(nums, 0, permutations); + return permutations; +} +``` + + + + +```py +# 輔助函式。 +def backtracking(nums: List[int], level: int, permutations: List[List[int]]): + if level == len(nums) - 1: + permutations.append(nums[:]) # 使用淺拷貝保存當前排列。 + return + for i in range(level, len(nums)): + nums[i], nums[level] = nums[level], nums[i] # 修改當前節點狀態。 + backtracking(nums, level + 1, permutations) # 遞迴子節點。 + nums[i], nums[level] = nums[level], nums[i] # 回復當前節點狀態。 + +# 主函式。 +def permute(nums: List[int]) -> List[List[int]]: + permutations = [] + backtracking(nums, 0, permutations) + return permutations +``` + + + + + +## [77. Combinations](https://leetcode.com/problems/combinations/) + +### 題目描述 + +給定一個整數 n 和一個整數 k,求在 1 到 n 中選取 k 個數字的所有組合方法。 + +### 輸入輸出範例 + +輸入是兩個正整數 n 和 k,輸出是一個二維陣列,表示所有組合方式。 + +``` +Input: n = 4, k = 2 +Output: [[2,4], [3,4], [2,3], [1,2], [1,3], [1,4]] +``` + +這裡二維陣列的每個維度都可以以任意順序輸出。 + +### 題解 + +類似於排列問題,我們也可以進行回溯。排列回溯的是交換的位置,而組合回溯的是是否把當前的數字加入結果中。 + + + + +```cpp +// 輔助函式。 +void backtracking(vector>& combinations, vector& pick, int pos, + int n, int k) { + if (pick.size() == k) { + combinations.push_back(pick); + return; + } + for (int i = pos; i <= n; ++i) { + pick.push_back(i); // 修改當前節點狀態 + backtracking(combinations, pick, i + 1, n, k); // 遞迴子節點 + pick.pop_back(); // 回改當前節點狀態 + } +} + +// 主函式。 +vector> combine(int n, int k) { + vector> combinations; + vector pick; + backtracking(combinations, pick, 1, n, k); + return combinations; +} +``` + + + + +```py +# 輔助函式。 +def backtracking( + combinations: List[List[int]], pick: List[int], pos: int, n: int, k: int +): + if len(pick) == k: + combinations.append(pick[:]) # int為基本類型,可以淺拷貝 + return + for i in range(pos, n + 1): + pick.append(i) # 修改當前節點狀態 + backtracking(combinations, pick, i + 1, n, k) # 遞迴子節點 + pick.pop() # 回改當前節點狀態 + +# 主函式。 +def combine(n: int, k: int) -> List[List[int]]: + combinations = [] + pick = [] + backtracking(combinations, pick, 1, n, k) + return combinations +``` + + + + + +## [79. Word Search](https://leetcode.com/problems/word-search/) + +### 題目描述 + +給定一個字母矩陣,所有的字母都與上下左右四個方向上的字母相連。給定一個字串,求字串能不能在字母矩陣中尋找到。 + +### 輸入輸出範例 + +輸入是一個二維字元陣列和一個字串,輸出是一個布林值,表示字串是否可以被尋找到。 + +``` +Input: word = "ABCCED", board = +[[’A’,’B’,’C’,’E’], + [’S’,’F’,’C’,’S’], + [’A’,’D’,’E’,’E’]] +Output: true +``` + +從左上角的 ‘A’ 開始,我們可以先向右、再向下、最後向左,找到連續的 "ABCCED"。 + +### 題解 + +不同於排列組合問題,本題採用的並不是修改輸出方式,而是修改訪問標記。在我們對任意位置進行深度優先搜尋時,我們先標記當前位置為已訪問,以避免重複遍歷(如防止向右搜尋後又向左返回);在所有的可能都搜尋完成後,再回改當前位置為未訪問,防止干擾其他位置搜尋到當前位置。使用回溯法時,我們可以只對一個二維的訪問矩陣進行修改,而不用把每次的搜尋狀態作為一個新對象傳入遞迴函式中。 + + + + + +```cpp +// 輔助函式。 +bool backtracking(vector>& board, string& word, + vector>& visited, int i, int j, int word_pos) { + if (i < 0 || i >= board.size() || j < 0 || j >= board[0].size() || + visited[i][j] || board[i][j] != word[word_pos]) { + return false; + } + if (word_pos == word.size() - 1) { + return true; + } + visited[i][j] = true; // 修改當前節點狀態 + if (backtracking(board, word, visited, i + 1, j, word_pos + 1) || + backtracking(board, word, visited, i - 1, j, word_pos + 1) || + backtracking(board, word, visited, i, j + 1, word_pos + 1) || + backtracking(board, word, visited, i, j - 1, word_pos + 1)) { + return true; // 遞迴子節點 + } + visited[i][j] = false; // 回改當前節點狀態 + return false; +} + +// 主函式。 +bool exist(vector>& board, string word) { + int m = board.size(), n = board[0].size(); + vector> visited(m, vector(n, false)); + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (backtracking(board, word, visited, i, j, 0)) { + return true; + } + } + } + return false; +} +``` + + + + +```py +# 輔助函式。 +def backtracking(board: List[List[str]], word: str, + visited: List[List[bool]], i: int, j: int, word_pos: int): + if (i < 0 or i >= len(board) or j < 0 or j >= len(board[0]) + or visited[i][j] or board[i][j] != word[word_pos]): + return False + if word_pos == len(word) - 1: + return True + visited[i][j] = True # 修改當前節點狀態 + if (backtracking(board, word, visited, i + 1, j, word_pos + 1) or + backtracking(board, word, visited, i - 1, j, word_pos + 1) or + backtracking(board, word, visited, i, j + 1, word_pos + 1) or + backtracking(board, word, visited, i, j - 1, word_pos + 1)): + return True # 遞迴子節點 + visited[i][j] = False # 回改當前節點狀態 + return False + +# 主函式。 +def exist(board: List[List[str]], word: str) -> bool: + m, n = len(board), len(board[0]) + visited = [[False for _ in range(n)] for _ in range(m)] + return any([ + backtracking(board, word, visited, i, j, 0) + for i in range(m) for j in range(n) + ]) +``` + + + + + +## [51. N-Queens](https://leetcode.com/problems/n-queens/) + +### 題目描述 + +給定一個大小為 n 的正方形國際象棋棋盤,求有多少種方式可以放置 n 個皇后並使得她們互不攻擊,即每一行、列、左斜、右斜最多只有一個皇后。 + +
        +![](n-queens.png) +
        題目 51 - 八皇后的一種解法
        +
        + +### 輸入輸出範例 + +輸入是一個整數 n,輸出是一個二維字串陣列,表示所有的棋盤表示方法。 + +``` +Input: 4 +Output: [ + [".Q..", // Solution 1 + "...Q", + "Q...", + "..Q."], + ["..Q.", // Solution 2 + "Q...", + "...Q", + ".Q.."] +] +``` + +在這個範例中,點代表空白位置,Q 代表皇后。 + +### 題解 + +類似於在矩陣中尋找字串,本題也是透過修改狀態矩陣來進行回溯。不過不同的是,我們需要對每一行、列、左斜、右斜建立訪問陣列,用來記錄這些方向是否已經放置過皇后。如果我們按照每一行遍歷來插入皇后,就不需要為行方向建立訪問陣列。 + + + + +```cpp +// 輔助函式 +void backtracking(vector> &solutions, vector &board, + vector &column, vector &ldiag, + vector &rdiag, int row) { + int n = board.size(); + if (row == n) { + solutions.push_back(board); + return; + } + for (int i = 0; i < n; ++i) { + if (column[i] || ldiag[n - row + i - 1] || rdiag[row + i]) { + continue; + } + // 修改當前節點狀態 + board[row][i] = 'Q'; + column[i] = ldiag[n - row + i - 1] = rdiag[row + i] = true; + // 遞迴子節點 + backtracking(solutions, board, column, ldiag, rdiag, row + 1); + // 回改當前節點狀態 + board[row][i] = '.'; + column[i] = ldiag[n - row + i - 1] = rdiag[row + i] = false; + } +} + +// 主函式。 +vector> solveNQueens(int n) { + vector> solutions; + vector board(n, string(n, ’.’)); + vector column(n, false); + vector ldiag(2 * n - 1, false); + vector rdiag(2 * n - 1, false); + backtracking(solutions, board, column, ldiag, rdiag, 0); + return solutions; +} +``` + + + + +```py +# 輔助函式。 +def backtracking(solutions: List[List[str]], board: List[List[str]], + column: List[bool], ldiag: List[bool], rdiag: List[bool], row: int): + n = len(board) + if row == n: + solutions.append(["".join(row) for row in board]) + return + for i in range(n): + if column[i] or ldiag[n - row + i - 1] or rdiag[row + i]: + continue + # 修改當前節點狀態 + board[row][i] = "Q" + column[i] = ldiag[n - row + i - 1] = rdiag[row + i] = True + # 遞迴子節點 + backtracking(solutions, board, column, ldiag, rdiag, row + 1) + # 回改當前節點狀態 + board[row][i] = "." + column[i] = ldiag[n - row + i - 1] = rdiag[row + i] = False + +# 主函式。 +def solveNQueens(n: int) -> List[List[str]]: + solutions = [] + board = [["." for _ in range(n)] for _ in range(n)] + column = [False] * n + ldiag = [False] * (2 * n - 1) + rdiag = [False] * (2 * n - 1) + backtracking(solutions, board, column, ldiag, rdiag, 0) + return solutions +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-4-breadth-first-search.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-4-breadth-first-search.mdx new file mode 100644 index 00000000..59038699 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-4-breadth-first-search.mdx @@ -0,0 +1,456 @@ +--- +sidebar_position: 24 +--- + +# 5.4 廣度優先搜尋 + +`廣度優先搜尋`(breadth-first search,BFS)不同於深度優先搜尋,它是一層層進行遍歷的,因此`需要用先入先出的佇列 (queue)` 而非先入後出的堆疊 (stack) 進行遍歷。由於是按層次進行遍歷,廣度優先搜尋時按照「廣」的方向進行遍歷,也常常用來處理最短路徑等問題。在 Python 中,我們可以用 `collections.deque` 來實現 C++ 中的 `queue`。 + + +``` + 1 + / \ + 2 3 + / +4 +``` + +這裡要注意,深度優先搜尋和廣度優先搜尋都可以處理`可達性`問題,即從一個節點開始是否能達到另一個節點。因為深度優先搜尋可以利用遞迴快速實現,很多人會習慣使用深度優先搜尋解決此類問題。實際軟體工程中,筆者很少見到遞迴的寫法,因為一方面難以理解,另一方面可能產生堆疊溢出的情況;而用堆疊實現的深度優先搜尋和用佇列實現的廣度優先搜尋在寫法上並沒有太大差異,因此使用哪一種搜尋方式需要根據實際的功能需求來判斷。另外,如果需要自定義搜尋優先順序,我們可以利用優先佇列,這個我們會在資料結構的章節講到。 + +## [1091. Shortest Path in Binary Matrix](https://leetcode.com/problems/shortest-path-in-binary-matrix/) + +### 題目描述 + +給定一個二維 0-1 矩陣,其中 1 表示障礙,0 表示道路,每個位置與周圍八個格子相連。求從左上角到右下角的最短到達距離。如果沒有可到達的方法,返回 -1。 + +### 輸入輸出範例 + +輸入是一個二維整數陣列,輸出是一個整數,表示最短距離。 + +``` +Input: +[[0,0,1], + [1,1,0], + [1,1,0]] +Output: 4 +``` + +最短到達方法為先向右,轉彎之後再向下。 + +### 題解 + +利用佇列,我們可以很直觀地利用廣度優先搜尋,搜索最少擴展層數,即最短到達目的地的距離。注意不要重複搜索相同位置。 + + + + + +```cpp +int shortestPathBinaryMatrix(vector>& grid) { + if (grid[0][0] == 1) { + return -1; + } + int m = grid.size(), n = grid[0].size(); + int dist = 0, count; + queue> q; + q.push({0, 0}); + grid[0][0] = -1; // -1表示visited + count = q.size(); + while (count > 0) { + ++dist; + while (count--) { + auto [r, c] = q.front(); + q.pop(); + if (r == m - 1 && c == n - 1) { + return dist; + } + for (int dx = -1; dx <= 1; ++dx) { + for (int dy = -1; dy <= 1; ++dy) { + if (dx == 0 && dy == 0) { + continue; + } + int x = r + dx, y = c + dy; + if (x < 0 || y < 0 || x >= m || y >= n || grid[x][y] != 0) { + continue; + } + grid[x][y] = -1; + q.push({x, y}); + } + } + } + count = q.size(); + } + return -1; +} +``` + + + + +```py +def shortestPathBinaryMatrix(grid: List[List[int]]) -> int: + if grid[0][0] == 1: + return -1 + m, n = len(grid), len(grid[0]) + dist = 0 + q = collections.deque() + q.append((0, 0)) + grid[0][0] = -1 # -1表示visited + count = len(q) + while count > 0: + dist += 1 + while count > 0: + count -= 1 + r, c = q.popleft() + if r == m - 1 and c == n - 1: + return dist + for dx in range(-1, 2): + for dy in range(-1, 2): + if dx == 0 and dy == 0: + continue + x, y = r + dx, c + dy + if x < 0 or y < 0 or x >= m or y >= n or grid[x][y] != 0: + continue + grid[x][y] = -1 + q.append((x, y)) + count = len(q) + return -1 +``` + + + + + +## [934. Shortest Bridge](https://leetcode.com/problems/shortest-bridge/) + +### 題目描述 + +給定一個二維 0-1 矩陣,其中 1 表示陸地,0 表示海洋,每個位置與上下左右相連。已知矩陣中有且只有兩個島嶼,求最少需要填海造陸多少個位置,才能將兩個島嶼相連。 + +### 輸入輸出範例 + +輸入是一個二維整數矩陣,輸出是一個非負整數,表示需要填海造陸的位置數。 + +``` +Input: +[[1,1,1,1,1], + [1,0,0,0,1], + [1,0,1,0,1], + [1,0,0,0,1], + [1,1,1,1,1]] +Output: 1 +``` + +### 題解 + +本題的實際目的是求兩個島嶼間的最短距離。因此,我們可以先通過任意搜尋方法找到其中一個島嶼,然後利用廣度優先搜尋來查找其與另一個島嶼的最短距離。以下程式碼展示了如何利用深度優先搜尋找到第一個島嶼。 + + + + + +```cpp +vector direction{-1, 0, 1, 0, -1}; +// 輔助函式。 + +void dfs(queue>& points, vector>& grid, int i, + int j) { + int m = grid.size(), n = grid[0].size(); + if (i < 0 || i >= m || j < 0 || j >= n || grid[i][j] == 2) { + return; + } + if (grid[i][j] == 0) { + points.push({i, j}); + return; + } + grid[i][j] = 2; + for (int k = 0; k < 4; ++k) { + dfs(points, grid, i + direction[k], j + direction[k + 1]); + } +} + +// 主函式。 +int shortestBridge(vector>& grid) { + int m = grid.size(), n = grid[0].size(); + queue> points; + // DFS尋找第一個島嶼,並將1改為2 + bool flipped = false; + for (int i = 0; i < m && !flipped; ++i) { + for (int j = 0; j < n && !flipped; ++j) { + if (grid[i][j] == 1) { + dfs(points, grid, i, j); + flipped = true; + } + } + } + // BFS尋找第二個島嶼,並將過程中經過的0改為2 + int level = 0; + while (!points.empty()) { + ++level; + int n_points = points.size(); + while (n_points--) { + auto [r, c] = points.front(); + points.pop(); + grid[r][c] = 2; + for (int k = 0; k < 4; ++k) { + int x = r + direction[k], y = c + direction[k + 1]; + if (x >= 0 && x < m && y >= 0 && y < n) { + if (grid[x][y] == 2) { + continue; + } + if (grid[x][y] == 1) { + return level; + } + grid[x][y] = 2; + points.push({x, y}); + } + } + } + } + return 0; +} +``` + + + + +```py +direction = [-1, 0, 1, 0, -1] + +# 輔助函式。 +def dfs(points: Deque[Tuple[int, int]], grid: List[List[int]], i: int, j: int): + m, n = len(grid), len(grid[0]) + if i < 0 or i >= m or j < 0 or j >= n or grid[i][j] == 2: + return + if grid[i][j] == 0: + points.append((i, j)) + return + grid[i][j] = 2 + for k in range(4): + dfs(points, grid, i + direction[k], j + direction[k + 1]) + +def shortestBridge(grid: List[List[int]]) -> int: + m, n = len(grid), len(grid[0]) + points = collections.deque() + # DFS尋找第一個島嶼,並將1改為2 + flipped = False + for i in range(m): + if flipped: + break + for j in range(n): + if grid[i][j] == 1: + dfs(points, grid, i, j) + flipped = True + break + # BFS尋找第二個島嶼,並將過程中經過的0改為2 + level = 0 + while len(points) > 0: + level += 1 + points_at_current_level = len(points) + for _ in range(points_at_current_level): + r, c = points.popleft() + grid[r][c] = 2 + for k in range(4): + x, y = r + direction[k], c + direction[k + 1] + if x >= 0 and x < m and y >= 0 and y < n: + if grid[x][y] == 2: + continue + if grid[x][y] == 1: + return level + grid[x][y] = 2 + points.append((x, y)) + return level +``` + + + + + +## [126. Word Ladder II](https://leetcode.com/problems/word-ladder-ii/) + +### 題目描述 + +給定一個起始字串和一個終止字串,以及一個單詞表,求是否可以將起始字串每次改變一個字元,直到變成終止字串,且所有中間的修改過程表示的字串都可以在單詞表中找到。若存在,輸出需要修改次數最少的所有更改方式。 + + +### 輸入輸出範例 + +輸入是兩個字串,輸出是一個二維字串陣列,表示每種字串修改方式。 + +``` +Input: beginWord = "hit", endWord = "cog", +wordList = ["hot","dot","dog","lot","log","cog"] +Output: +[["hit","hot","dot","dog","cog"], + ["hit","hot","lot","log","cog"]] +``` + +### 題解 + + +我們可以把起始字串、終止字串,以及單詞表裡所有的字串想像成節點。若兩個字串只有一個字元不同,那麼它們相連。因為題目需要輸出修改次數最少的所有修改方式,因此我們可以使用廣度優先搜尋,求得起始節點到終止節點的最短距離。 + +我們同時還使用了一個小技巧:我們並不是直接從起始節點進行廣度優先搜尋,直到找到終止節點為止;而是從起始節點和終止節點分別進行廣度優先搜尋,每次只延展當前層節點數最少的那一端,這樣我們可以減少搜尋的總節點數。舉例來說,假設最短距離為 4,如果我們只從一端搜尋 4 層,總遍歷節點數最多是 $1 + 2 + 4 + 8 + 16 = 31$;而如果我們從兩端各搜尋兩層,總遍歷節點數最多只有 $2 × (1 + 2 + 4) = 14$。 + +在搜尋結束後,我們還需要通過回溯法來重建所有可能的路徑。 + +這道題略微複雜,需要讀者耐心思考和實現代碼。LeetCode 對此題的時間要求非常嚴格,即使是官方題解也經常容易超時,可以嘗試多次提交。 + + + + +```cpp +// 輔助函式。 +void backtracking(const string &src, const string &dst, + unordered_map> &next_words, + vector &path, vector> &ladder) { + if (src == dst) { + ladder.push_back(path); + return; + } + if (!next_words.contains(src)) { + return; + } + for (const auto &w : next_words[src]) { + path.push_back(w); // 修改當前節點狀態 + backtracking(w, dst, next_words, path, ladder); // 遞迴子節點 + path.pop_back(); // 回改當前節點狀態 + } +} + +// 主函式。 +vector> findLadders(string beginWord, string endWord, + vector &wordList) { + vector> ladder; + // 使用哈希集合儲存字典,方便查找。 + unordered_set word_dict; + for (const auto &w : wordList) { + word_dict.insert(w); + } + if (!word_dict.contains(endWord)) { + return ladder; + } + word_dict.erase(beginWord); + word_dict.erase(endWord); + // 建立兩個queue,從beginWord和endWord同時延展,每次延展最小的。 + // 因為之後的去重操作需要遍歷queue,我們這裡用哈希表實現它, + // 只要保證是分層次遍歷即可。 + unordered_set q_small{beginWord}, q_large{endWord}; + unordered_map> next_words; + bool reversed_path = false, found_path = false; + while (!q_small.empty()) { + unordered_set q; + for (const auto &w : q_small) { + string s = w; + for (int i = 0; i < s.size(); ++i) { + for (int j = 0; j < 26; ++j) { + s[i] = j + 'a'; + if (q_large.contains(s)) { + reversed_path ? next_words[s].push_back(w) + : next_words[w].push_back(s); + found_path = true; + } + if (word_dict.contains(s)) { + reversed_path ? next_words[s].push_back(w) + : next_words[w].push_back(s); + q.insert(s); + } + } + s[i] = w[i]; + } + } + if (found_path) { + break; + } + // 環路一定不是最短解,所以這裡需要去重和避免無限循環。 + for (const auto &w : q) { + word_dict.erase(w); + } + // 更新兩個queue,並維持大小關係。 + if (q.size() <= q_large.size()) { + q_small = q; + } else { + reversed_path = !reversed_path; + q_small = q_large; + q_large = q; + } + } + if (found_path) { + vector path{beginWord}; + backtracking(beginWord, endWord, next_words, path, ladder); + } + return ladder; +} +``` + + + + +```py +# 輔助函式。 +def backtracking(src: str, dst: str, next_words: Dict[str, List[str]], + path: List[str], ladder: List[List[str]]): + if src == dst: + ladder.append(path[:]) + return + if src not in next_words: + return + for w in next_words[src]: + path.append(w) # 修改當前節點狀態 + backtracking(w, dst, next_words, path, ladder) # 遞迴子節點 + path.pop() # 回改當前節點狀態 + +# 主函式。 +def findLadders(beginWord: str, endWord: str, + wordList: List[str]) -> List[List[str]]: + ladder = [] + # 使用哈希集合儲存字典,方便查找。 + word_dict = set(wordList) + if endWord not in word_dict: + return ladder + word_dict = word_dict.difference(set([beginWord, endWord])) + # 建立兩個queue,從beginWord和endWord同時延展,每次延展最小的。 + # 因為之後的去重操作需要遍歷queue,我們這裡用哈希表實現它, + # 只要保證是分層次遍歷即可。 + q_small, q_large = set([beginWord]), set([endWord]) + next_words = dict() + reversed_path, found_path = False, False + while len(q_small) > 0: + q = set() + for w in q_small: + for i in range(len(w)): + for j in range(26): + s = w[:i] + chr(ord("a") + j) + w[i + 1:] + if s in q_large: + if reversed_path: + next_words[s] = next_words.get(s, []) + [w] + else: + next_words[w] = next_words.get(w, []) + [s] + found_path = True + if s in word_dict: + if reversed_path: + next_words[s] = next_words.get(s, []) + [w] + else: + next_words[w] = next_words.get(w, []) + [s] + q.add(s) + if found_path: + break + # 環路一定不是最短解,所以這裡需要去重和避免無限循環。 + word_dict = word_dict.difference(q) + # 更新兩個queue,並維持大小關係。 + if len(q) <= len(q_large): + q_small = q + else: + reversed_path = not reversed_path + q_small = q_large + q_large = q + + if found_path: + path = [beginWord] + backtracking(beginWord, endWord, next_words, path, ladder) + return ladder +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-5-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-5-exercises.md new file mode 100644 index 00000000..62961584 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-5-exercises.md @@ -0,0 +1,33 @@ +--- +sidebar_position: 25 +--- + +# 5.5 練習 + +## 基礎難度 + +### [130. Surrounded Regions](https://leetcode.com/problems/surrounded-regions/) + +從最外側開始填充,然後再考慮內部區域。 + +### [257. Binary Tree Paths](https://leetcode.com/problems/binary-tree-paths/) + +輸出二元樹中所有從根節點到葉子節點的路徑。使用回溯法與否有什麼區別? + +## 進階難度 + +### [47. Permutations II](https://leetcode.com/problems/permutations-ii/) + +排列問題的進階版本,如何處理重複的元素? + +### [40. Combination Sum II](https://leetcode.com/problems/combination-sum-ii/) + +組合問題的進階版本,如何處理重複的元素? + +### [37. Sudoku Solver](https://leetcode.com/problems/sudoku-solver/) + +非常經典的數獨問題,可以利用回溯法解決。事實上,針對數獨類型的問題,有許多進階的搜索方法和剪枝策略可以提升求解速度,例如啟發式搜索。 + +### [310. Minimum Height Trees](https://leetcode.com/problems/minimum-height-trees/) + +如何將這道題轉化為搜索類型的問題?應該使用深度優先搜索還是廣度優先搜索? \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/_category_.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/_category_.json new file mode 100644 index 00000000..0943e8c5 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "5. 一切皆可搜索", + "position": 5, + "link": { + "type": "generated-index", + "description": "第 5 章 一切皆可搜索" + } +} diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/n-queens.png b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/n-queens.png new file mode 100644 index 0000000000000000000000000000000000000000..f6ea07555d6478e73b50fe428dcee9ab366cbd98 GIT binary patch literal 20347 zcmXt<1yoe;_w@xw7^FLep-Z~Eq`OnP8>EpMq`SMjyGuF+K^ml`TcqQE`TpK_v1VWm z1NW{w=RRkjy+2Qwl7b}idxH0G-n>DUminaf<_!!i@PGls0k0&iR6GOU5FDknzr1;a zGVuCDq$O@0yqoC52 zA=~sk@9a~NkOoTxk7v!qdT?LFIKqcq+O_SK>ibl;eSOC8+;4=oX*&_V{|;x%ivw(K zovW3vl^-uL2&p@MUXi@?zuXDE%P4V1o}oE4BaCTzD*2q-=#Hg76S#zw&0iF+s26CNm@>cqYG_7(v(JoW18* zB)9DJ2UGyJ_2nxyxg0xKdhK(uY7mA3+pkfq^`9TF4ZJ23=*JO`Fl7$=$oXkHTJpX{ zd_*{lX<5PJd_K>l*G+IdEmwG{PAvcVwEU?{`{A*QXC`rXvzP~oY^q$2JO%XkSk^2&bvwGV!`;J} z+ALWi+=!dsS(b84Elx!3N^T)8y$9MJ+!Aa)PdwSUV$x19ZA&~me{fZjWm?X+RE&Md z@CEjmV#N}Jyj+8=fQJi>7>BPy2=0rf)}j+7IF78V5qR?nC3 z;1D^`?Eqop`dnB^&D9h2;H`4*dJZuvGMV{N8Skdv%e9eYmhJTk72KS*(u(N4D1wN9o0(q7btdVRaRc#4tB1 z(7?y-D@B=pJUNMbWj_$RDMR!bMA~};#={?pdbefqvVK0!A zZ=7u_XmCoQ&SRE_j9fEOv9C5$L`mh5&7zr-RjZ4zA*Q#YgF205H5ks?EQdT6;*o<| zxj|MYkgi(e#vu4`%qB-hgEAtcu2Cv=a$oa7n(CY*MJ zZz{czbbszKbIOLJxI`AC!*`;flocv`Fcm?6oP83uT#|F)`nTBS)NC+TL80=#4ryHy zy5Un0y1EzRd38>TN+P&p<;J))MVyeOOA{YrhAY0)?J+jKH|6nodvSE*l_qPX9X)A~ zU&x(vY@z6T@{3JeBBj4n86&PnpC9w=@9o`}Y$0zEHy){LjPQ{u&tBE(97%rfi*Ts3 z&NdS*Errk?HdFSVik6@QsRs3XXM;bp^)Cw$I6D%5uuj^w|QV#TzXx zBt6|#<)vz)qWG+8*ki=df^i8$8{&~ zzC_eiPvJH0`n2*wkocaOcd>^0Yb&`(rlF;S?A?i-uJ=qmJ)nBr?&Eu^D& z?(h7@h8E`hr-RMqDoO(De-~#}Lql3`qp33LSVcozaujTd%^}zUYM_xa5p39AXf7j? zD=Re_g}+kDnkk%R9A_b0f8gg-ek-!+wWrbZv%Xbf2L1=@=^wdlA{r-4cqImhN26sT z#hC=>$+0}p@V8L)INnc-jZ{WT-pwdyWBIX+tyeR-E#mHa_xthKr3|O;tX2wv?FQQm zvQZz%k?_yv!}k4qkw|c4OB;A1L>m{;DyEnpng^DejC>-qK>-u!p|OzCjd0<(CqbO5 zQ1JDjnXthSuPfS(xK2~y^g<5C&kjoXp;SlHOnk;66PvG^aCn>r z7w%1A^>*XkpG?Rqb+^wpBV#(qm7i9eX-3uPpsFh9QfO+9XkT+o!*yG5T2b5v>Pzqo z;F@v2ytu4Sy4b5kkeWv=@hxjT8rT;{m8qZjfzK9HR@ZVYp;`I@SGqovtHSayAsd2K zwP)+Nx<`WFbeaIY5WaC1kb6F_SEl6sbZf&S=kIJ;xPAg*iXzs| zRr0KvgE3!Ig!l8yTlSw;cke#0%p2*)CMzKj3+Sl4WH5!+T9LnD<;q1|X6XLj_}MNQ zX%540&v+)ZczvEM*PTAjP)*-p7tBg;7oA&36H{VQY&f3_gG|6)T$Ii+?yELk4z$`( zm5Pw5*TtFSC-SzEpEtUcFWAa8_1Q#?l*P}WeWpQ5KyY{PtSz6_NNCt z|B;(H@;z2@;9J^=H`;K``0#H3YM^u#tciBNDK?gYXd=_`fWw_Vzw%-Srcc`X6zP3R zn);=Se^p~X(n+G82Y&Bs_-W4}Y~?C5Q*=ZKO*%xOpZn@B{d?KALIdc=S)g#-xmY_# zzgg^CVwA2y!|03s@klGx(918ynkjIRgy@skCoA~Ghav`95(6Qg3GwW~S~tY4=^Rww ze-p3xc7@eiGw3TqbK?VZ3u84=Z!mtBks>@Kg=_KfuMvgn41Z$8Dm4{ThEcRXG1jZO zZnU1qlJEE6%y|jRBr77T1&Mh23tK5SpWx+iM;g_|rCM{E#3teMx!aNpa)$F7%tEZ> zpfrsb1VrCknrvb@S%T*1Q%oH4BHG;Ohoa;SJ-!KUIP=L$jq7BJO?R3}-uiO|jc?J(HO=ee6ndX@Ch@3%eEam3oeT0gmOpK&w z2N*;)u1P#lXSiM>A!Io|u6$Ws`E(8&i67}4mNSJ2@)?|e8m6qL3#CmO8{3s?^aZ+a zw-D3093=XKkxP}gRdp(w^2I`~ucoagw$K<5pma&(j>abmU*pIkzchtu9?1CzVoa_HlL!{xTnnD`C~viiT)?D2q_eSmx&Ctv4Qgk3!5pa`$(y&E+EB zGKI-tYb1n~v9xk>-%N$RO zHxZ&9|Gr`eRvg4SslS8Jj0(wrEje?{bV@#cG_Gc-FFxow(RMm}cLyBX9-_qh)PJ(F zWxbFPgt%MhePa*vZDK;s{73p=BCV>Fyu8`rY}uBZh6YZBMwRi|TGvE2$J-L$p~6;| zo%7b0&n&X;xp$j~y`M7Q@-sZG+j^)Q*ORCM+ZKUbRG?Qa~Wf^Y3mLr~9d%`BXN8 zKePQR_t&pq_h*$qkVGUO%X@SoDnoO_DG(8}om_pGKXluRj^k8WE(vF_=$>83sHc$9 zH!as>2@NkbSnzmXzmIX&f51-0alWfP7S8?nAn#%~g{I3!C7(VLPboXFE$0vr$>rrbtW8QwqRQd~yV^4hf0a--KY1D1Es3pi zvds1?DIzvhFQ*Y&v6X?>m`v+mub^I7E5}-FQr!JV#9wAssf@Cs zuG(n%Vj8ua+9EZ6bS+5_Ny8~YNA+|nIUmTQ28u>7fKzzES3y@}6<5+x#R!!NA~W;z zuU`3(9SzN(f3*K?fQ+2O>Qx_}M-IGLi^UdI!dWCmZ})*tybQMLyVB)w$9X zRDLk^y9u4{AO;pz{c3Ml#V_em~YuYL- z2!E!T6fWQY?{6fPxq+YZ7uBY7zObFB&5%$IYv2HS3ivvYhVgN%L?AT&w}|sHjE#)| zTLvy9D>VkHJG(k&ntHXIqkw27;_`G1u7bkCHIk2GsJHapc)!cQU$+=m(`W+=4e>)6 zaYzZAv$ax^a4kbOeF419_R*=7+;_tv-iijnA^$uSI0~vrV~^Gv8r&M1z(ts>{dF;T z$-m9{j+L1Ni6SFJfbjSVMmr`j8~Ah+J+RnSeOcKmBEIZ8kl(>G+1!P<`BR?;3Mx@( zRJDl?swSZCbJfPQ^Dk*4E|84+Zc&Szu*wVm$K2n+wmEO-`#X#F3vlu2q$Ng8Hx1we zRLXst4RCE4knpfEp%L1u-6S@Bwg$+&To3PmbFSB!wdO4va`aauIEK#HTm&tKI3HN!=T>x)2zfv;Q)f5Y$;xFI+lBxID_7>z&! zXOP#`!gKO9vQ53uC(R4Lq6cem2+iB3<*jDez%YAYP5GxNvDku9tA$n>r7=7|@JZY- zALv`cVUOgr#(o{m&DUq?FPVQ$Q;gjyO5jw`O9?<@x$Eo`{*D>VmQ8m4`W4H43i`Ca zI2T)Ckb9mJO>tdeBGUxZzux@YOLeVe`bv>R6ktrLc^2Wvvh>t6xJu-QY`st(+$C*O z?CFN#c>6Ovw-6E{$tUq>M0DuNLFIgxb!i~@(bqXC5dJzs$3td?r#GGHWiH{sf;d+9 zYWR@iwTwx~By(+>G_d?jJjv5%%Z6NPCSgH&PkhG9>hLzd;f!4&OP?dM&4ambrY$^M zIU_<2bLWa-o+cWlznp!)Mi2IIu@QY@5<(yRjHRXajYve=3H=V0>4_KR=5%ecT^VQg zv4tbzY&TH|?0Ylim`IUD#U0H%^r1*bnRY4;5(~Lis(^csG}Pg;5kZh+Sg;_a)r0(H zrni3%fm&9exYZppB%O0>EULn)*jilr!v}Zoj8-%6@vuV zyWRB}g=-IHVoJs$SGnPR`(SHoXUblh`2~ZR`5GxMc3|%Q8rl8aL4ThO)2Lqrfs!at zxEo?nL-B9KVp;7CUjOK*6r}Q`10AICxq=aKCrzds`0l;D`2C(U=PEQ+_l|1t5}0K? zK3$#s{($_i*>=4<3O^wMp+%)47D7WixxEy$q%~V-^kdsSa^VuTH%ffoQfqQ+KB80Q z%Ug&4e=xC1L9zB0QCZmt``z8I_Xj17meZNlaB%FU200GhWr0OzOfIgjrP>8>C(BLZ ziUyj(n=1}IMGhpgE_}_#P}zs~2+;ga+(+gW4CJGrqFuPL4y74%N2Ch*bu)*iu~|g7R{4tt_``w*x#y?)@o^KVjuqL<{2??{ zH-kJ>sb3X-9tttyC-?LsJb>?;8EE0N6CUjUw+Qz#@h+!Wib4~3KP)%(PEExW7E%<; zW%V^4`~tmMYg{^L7<@{glE=tKpP$#*cefn5UtE6>*T6ypOYTq;UX&F~&awduDF4=D zHTkNq{;ftx0T=1(ph*I(Aoc5)%yw|;O_b~|rQApKbQ@6yriV=OFyABb*}mCj8slx7 zT1ZQs6&KC>RpLQtifcDu_S`-cB?^4%LDWtyjO@YF&MUqA9Q}7XP?zTXq}2uXi{kBbt!bJjLhLA zg|-e=w zIj%HXr^QHFKqkRgOEem9gigDw)QqIT3eB45EBvedY4RbGcP1Y-fJwX4KvS_p6H|ZMRA~J%uWvt38x+P*!!dhQC_R zHgU6tGBZDsQVQ?{09QaJo7^KsZ1zUFINxjf#>9Y6{7E~6CXGB+^=%Txf@xX(<-6W> zyS<(A-iN`2F3iCc)irr1h>EGVXN&hyf!a(CNy@v@LZPwp0J{4x7V@n!_g_rvYJg`y zlT6^*&I+P#e5ce-`qIRfaV7X@V_|J}UTXaQQf@h47Ois%=I`Hb+SN6|INT5m8MIR2 zdReqYVxW_ZAoHB<5V;jfvY4b2mS|GMe)*VHkr9vo!7}EHkO@xo-#>d@sv|-?A+kpa z+-+a6P;V5I!iAy!?mmF9@YV)yv2bBW<0UDKzF;(g*&KwrY&|`pXpV%yuoxr=FJ1gM zNB7A}nVpe%^hn~vZx3$}aVQ@U2LV~2f=-kGp~>LMh#yp^1T#9|4R^Av9Z!UAT?AMi zXAlO)G+;-gyaoTO{WBXr{a8zfPEyj1w|~IQG8DzfN6q3;$<`B0iRT4OWl(-UtaIB9DX929ObSNTbv)04j@P*+SmT_05lFeFZBOWgC zNe)%^o^9DME=M^F({w`SHh!i~ntw*uyU(s2u^dAoArHl@v}0kL=rAB8C&T{PydC1H z*iq3ma$wA$;{``g4E-MZR{ImpD-}P2t&R1@fTcHvQ~r=uz@C{2WeVdZB_j#Oz*i%S zlD2#6Iw9~^9p{PMS@j3*PD^f2YF4~MYqNFg_6#H9&8l$WN^0;yXq)q>s!~CqfT6i9}n?6dAMuUKn@@EbB&_x zeH!FGcGwf18G0yx+k0{KoNC3*Vsr|NQ{0wUvpJeBTcpWW9S%`iJ3F{xTjXSmjIJU; z+coZuSy6chUWM11QP<64VC!#dXGvpLf`x;(_&Hok{y~QWgC3Mof@=1u6_xYpqcq9MkNOMW z$S_1wMyhn_{;x|(=z~h`^hEHBtfWJMCbC=jyC(8a4mJrmCj;Z;HKc&fUFgY)5l2r{ z8mTCG2(_F`J{Q*EIdI?HuKD^eJOc?3{nK>(vRodRH!$kq`5+y zFk;NJ3q~UGF&+X4(4L#8uj~+-$v>k(R;ddvrmD1Wdsana{g~r98Md_A_+cd_y>0F6 zM!9d}JNsf#K{Bcu?~99yFpkfn3W{Jv))yn=MD6 zo@x1)QT3IJ>wU3}(wN{2SBs~{pX*)KnSk9+Lu{`R1;sWJ6a<~@{ThmB@J0P%@{yta%i|(T zv0V12f?(v4u?b*Yq+Zn0&8sLFeD?7koscSN@Y2mE6AgN+Xe{>zes@?JEwT6J?=%hc zG3BvwB8|Yc9gUqdA?Pn_8prH6lwGIe?iw<*Sv$elN)yx(Cc3=+lBm|EGRf7U;ZC~S zTj5$GYp`3gIX55Qbh$cxcZF_>ewUY#t*sm&4p=xi2IuCIc7LQ#w>p{JUmcL^xeC5K zerb0H5t!%%FkKcmT*Vmu$$N4ACp9_nIm8p=s z-9mconcaW1^qoTmS&-W0j=cV_kRTe3ZiMSx28-i{aD2jWSa>TUE~Dwi)?hv$Dk8Dz zHELZBW(>|$mmQ98z@~f*AS}WeQxXUF1GIc{SF!vlA^=4qYPK2FWAJz3zKbu0N zfl66d?G1D*1s8v%>#dmPXUdY?R4AJ&OO?aW@t3I)hWlILTwA7S;+YVL0V=2c>i0ac zkZ)%5Ls5i-d$(|~;iJXQ-hX$09RKb}0Vd@5I6*?{m9+=@WpOc=+d=+d_I3Rv7Bg)Ju1$+It)0m)yIQ%^O}}!o>swJ%6*S5PqG9*8Fa8J(v zUKF4{bRQ3X^^A!g5+F)$m{@;=wq}>xjEN?7Yhy8sN&}ohy*V*4??6uaKFqU6WJJzb z4g!NL7S78y)L93=N_v7tmre8Fh9dF%A(E2qu5+fpuGX0dWdM~x^zaLE`UwF1IsY z4T+uEjYV%cWC}1{Dp_jA{%CEeutFxch|#8BUC1*f;7Q;MSW}pYWwq9sb%I3jeS}C< zqc?m+>0q(_g_n@9w$DDr=D?GRJcHidq7z_zl2hZpaAJwX!x^q!w5$uDq2S*5x83`U zRDU#lteg$_R>A8rAd!Rr&Y53`JwXg{TbqYgN{@}%Au^@(6T5pPmv)$7{u^nHe6GJk zbTOV0!?@HBbyN)B=rdFX{){?XLqr_q=%8a+A3s+8$x7|7C}}V9P zA+R4Q=M?!NkPXCx3F1vhH;2ELC=vlTL$CQ*;IfqJwG&!Ra0J$R!c`D&GiF(a)lz)D0dxSJTioM-l?rQge1B9U_R4jvYp$BWX4*u{W*6)J#G4 z3fGlsL^O}AiZw(GUs;(d3F%+u&xom!*&C6yFrF<8mvxcke3}zS5_-~`8}mWq{EFyo zbNFZ`Lds71Xr>ReL^Zt4wh*;I6%;=OC|7YY6;k~H?Hfmj8`DlW7mKf=M7@&&1`DOJ zuQ$EYpqk_^c;W>P%*tKw0rFZVh?JJgEfJA)TK}Dua9+ojZ}n8;CyzpBam!?*E?FQ? z?)1>K^n+Qj>Y8cG=RVGxKZ{V8I(My@vaAgA=gDGt%GjVKHal(C&GfYJET3e=d6S9VYDXi~Zg$iNS=i|? zds6R#;VZn>eS`E%H2PT2mh#d}BVG0)bmp`L*EBol=j3T;?+(B4XW6C_{kifwy5keh zou!@VZVLKlFqG#f%zUwZbFQTh843bp9rDpe=85o-3rXz zP%BPdFwo;lw!B$mf4r8x{t>O5hnoPAwTX@raNe;6`;=>CgTQ?#|=6BzRJeQw;F}5AI21X~eox}IaVS7=xn^>aP z`Xe%5d`GKZt4iJHj(Jaumv4srE`PqnV<`=xq9cu*|D0eeIIF1ayd#riCL**}X^Tu$ zEB<)AyUhvjzy|Y}@0%H|V5Tk`oNCrJd!=s1gST(P!o~*(&4lMrz$b2_ODR1BE&@+T0=-1Rd?yRc+9^fQBAZPiHOq9IoE*MbtF8lC z=do7ZSDwEOtYEjp(fy48ibw(x+fU42B-+u>96}=gLU>!O$l_yPK7a;yx?9KCWjVIo z_#bMvYl%8hQ8A~r5cimcU;_ieC^E)VRYdRCR2r0C&8_m+>q~{ZKs~)a6Df|k_p8QR z6BbUJ*-Z{Mq+3X8ulWZH+wA83zoX;zo|NVvMpyM2ev{bQN&v$8e+ahrO zZuDC(Y4Okf23wzFOTE!C$t?+wj)f)aF+hPLq=F6(CuYdibVcTuq>fL_lyi1wS3X7L zeqfE6dH&BkFnQA(RfQRPPW=5)y#g;M^P5fsTqFVdRMtw%fxW#<#O@Ezi>-H((L{Me zC36?oM1B1^enW$!ac))VwU(Q($&C8Kkrp{Z@X#&(Z2h!=r5^V44>ghfPLZ;}kg(YreM5>ct;O_7*!SQ(bvnu3vn_Eq| zHoSMvWu&znP&xYggQ2BGdLy)GssZ`K5w%tay+cP#vOh5Yo05?r9z*{iZIqhX`&s$j=B82VzB{^Z z!pqN+7APbK*FuA3b_O=2mbp)~KlC!({Hk+1u{l_YQ8h4RcrSs~J~EbLG|Z+gKEc2` zUkRZM5P^bl;!5Y^tXoM@qgw92hJO4=ii||swB@k7XE$>ByHd<;R8&%ectg)eNY8JJ zBwJ%~7hNXeWJK(aQXJuwnwmN=aG~4!FL`gw3uN{+cXT}VW%>JEs_@U@PjBffe93Sj zL^V{3&+0HV@)tvDr>d7A1O$Yu=KW}Qzk-%X0B#=Q-cdq{!uy*FlF3I%q$3K6;6%27w^oCBl-B((%M~?S`DDm#hC$>27Q+<5cS~$m#^sLn_iV~~dLKCnv{MP|so7*+oxL0QbU7RiLGg27{4GW% z5sj^ZmkukyOW@WyW+cjCjc$}KlatSwm~E7nllh=H)>>CXqDb^(WRrz^>1yY^Z}Zjd z!T=@tSjT$v2Oeb%vvEyFG^X}agz&~Js2jY=z4tyKw&8O|5zv=S)de5w>Q3!YW zcrN!p^J5GJ3ROvu7gi&xPJ9edNt3b~qa2p`4HcTBPWzb11FH@=Akp7D^+e8Fbk$*c ze@9(x87BNk1A;xz07_6u9TxO{T1`aZz~^=W2s3(%!_Oq8eal7bWp%Fr@vy-FKao8x zaZF@2l1K6DhWBS7LODnzV9THu05!gAn8_&#HIi|s+YUWK>}L3R8_Ya3qa)c&{xZMa zI$qgc=-^0$(ILV!As4sb`PtlfHPR z5787E(tyf>h$!`n)-|z$@0nTB3fHI+_Iyw3|u7;bE{Xq+-m|kD@wKwHL1BA;AQoUc8zX+)bK*wd_ za<4}X=Y=MVbD=xn=3#frYCqZT@;g-H`-(cQUM>IcpDK{=PmUVcC(xqp2q_+R%3M|028S?n)|L&fbtiXgNIvV7yLYVLw1c2@y(1f&7D8-s;S*)Y7TuJib-Hg<~G3pEGoV!*jO5rVDYl25i^FSgZ?^HpQ z;_o`SJ7B5*o>`WAq4EDw>O`HaLveX5K_sNZ17nrdlw5P*{FX;(K9K9oA^@TXJON`o z(rd5QR8FI@TM!O|p43laOjxfLikbDG^H||vz9S5~g5ZkJs5+ch-`Q&>0cbPP=FB{Bn#ozQq;6(GHl~8y5Lwd!2ZG2@4~)^xLoc^T5uInh_vs7&Fk zUtZ~m|2{h!=vJSe{aKE1?U74#4qk~4U;-t)>#i=e?GV5I!+u3i0|ri<%;s9nd@5Zb z<@!f$OWn?4()hPv(B(!{1lIu)htsSx8Pt5Vqyg?Ej$*M>4CvPbaeEKBcI;hUJoy? ztpk>CXWb7d>%{Vlf_<+7%|9FjD~`Ow&nE&^aFr7nW)q|gn$dX^M83QB(=j>N{1K12w1cfdgl3Cx?%(G1A-`X2vBjMU$VvW$kocmV zvdO3~1;V4g$0aCAuPkNtzTByqO3O$JORMHBt3K?}W%+OTpeaQIAY85oP+CBMF%jJD z!xoQlOwCKl2RE^PEx)`>k@Fm7t$-3ZnT&%15vGDkz&;4$y_Au^3rnDiPfn&f{6X*f zXYj0NwS>QVb)iL(sn3qDj^p{p`oCZ`7uG+Q{edlM56ARc0-;JwEG9p zf1>)o*F=wmN=A;Dw=+)FW zS4kTvpT0F;^-j#Id8opjuajYA+iDu_=CsO@#b(Gbfy%?pq4#HZl{S7JJ)_MlS(lre zIQ2Reql0B^WG+;S{72V7TkrtWYStHw*|kywyu(?*DGrzX4!|(`E47 zm4z$lHQ&&NS07B%Noyz*^`ueY1>l8O%Ydr%onMPO_L&$0wEP|PY&ad9QW|*196(z| zYr&;{B?-;FihYFvnF0WKfo_ONJ3yy0Y#x`MM&@aFsrz$iv)!NG2#Ncm$>P%Kb5_B6va<1*~mkAjp)#<~w2J%=SHV5~Bc{oM@om2*<69gxA zVY7W@2NV5F+6a)?y0k0G7Atl2Zk*NKUaSiA|5pD(_B}t1IoRoVSvWDkfT&zHwt!Y4 z`WnQCSI@5}NfRW@_Zj*@K4@xZ)5)Aw((#bVSCUox*7vPsHNm4R+SeMb!GAVU5r2hO zKf|HVmL#PuF*WxR9!spW&nJDIfAg2_eh=X9C^ z>1AP`I-NKi7%?JQwNthK2`jmrF(cwmkkivgv}xOL-_Ydb$Is-@V~Y%Gg2wQ@J9Q;9 z9}Z0lSMb-fe*ln64}8P5fzf;(N(I@!Z_c5$8rv09vm!7Sn%HZ1u-HoF(=lr{eqId=atmhoY5Oa7 zI{IXZV=PwcLBYj(;r)8|;W3`o2tYdEHC8CbFh->j=90!oGEzlZ-q~?TAS*rmd#`{1 zonU<@A}vkoi5gwU+{(1<1IPNa7Y4q8_*Q{`;w?a6?)Pd0cMR44lVE%|sN_h6@PlCf zWA`2OQAG-nUp&I+yhfJa5|qVs<|}9!=hI0FrN1@M0{G|lLQ5CkK1=oPtw%fNfq5^0 zaTvq93`{76KqT2%zw)tJNm28%KWDCG^*sGHTg3pSnIS^AzUu26$X2dMT?;CWCH=YF z`Odto-eA!mfm$20u~dX`Rprn>g9xlaK&(-T+H5QB-L&hWbHF;5hg^3m5c(dGbnF)a z@ZsR$Fe^z-e*-f;dN)BHaRfw(nrhw(3U~^8I0l#>w)*465y39?xjiD7uw9?S5D>|Js+_pj099n(=ATb)+!Nxceqni zQoidE=}O&Ql7?=m-34yQhZ6NZYb|RKejiF9c>|)f?LT6(D<<-kv8VL|9L_f3T2{S~ z?5x9|&33xSwsv*R%|pGt0V08LVY^$bc&IU?t?lj4UOAVoQBla8obxWHs|Y?#OxgtH zlp>BYL6BU3zRrciR^d@iV~xb>8fm_O z(*D4~nxTrER*_d~yNd3BWMnQqJsku&*Owdgu}Ax$zZ&XJW^xui5w#j!Xvb$Hw(y(7 z2?2MT5~wF#qVm9uBDiN?!9I{V5bx9oKvY!4+isk;hgf_cJvLGET0hbHqK*CS>lekJ zt%zuS-VicSr9xyI#{mVk@h@?Ob*H;UYPBa8Mc~$1Zb@|(aFsDiI(n;qe0yRCB(28& zbDyHSMvAaj#Lxj=?N0dI%iWOPg|BRLZ;v|C=o{f|Wtyp}DYL~S(S<7h!{h;O|&nPt1&8Kz#L5to)GEh-9&^ZSP*r~O24 zo!`f|Od_$gBDvvgrJeV+$58v77Fub( zQ25(8Kw3EXB);+zc_o0rFg+V6hk=HhL+{=HgC^Ev*hM&AWQQ~2O&(}O&H?`-`$PJx zM-O0wZ!+@1YB1IauwM|MGboXd313iNPIon*I8E1<2na2Tuu*(V3no&2m3O;){& z+S)%GI`DsO|Mqk-B;aaMfP9HWWs^kO94k(2=>w<(z*>Nmf*?wh`$7O#QSv)slrOF~ z9O1c@j}Hx)#&h6 zkhs`HpsAjmFndXk8H=f66F!b=2Ye^fXKW1XWl%UxKH;Fz`Hf3U;Z@IzMI zk9Wq%u>*3y4QGDF`ox8-8i^Fee5{0fw7Jsu*qW=h(!j+71vr{8m!{lh>KDU>OiSnJ zB1E)TP_-+F(cMj9Yce`a3(w|P-DevVMm)xBHqOOt^Qa>>#(`*nI&n4`2c>hB2KsQx zv-pe%vg+=>+LpX%iAr)tYj!9_EjAzSOqDLj$G711=S3p1X2Uit-%l13Z zASFlsuxQs=yoMVDo}e>*4kb9J-!+0Jj_cKrtqe(jwtWyT{t6eE@I^Cx7~MU{`*z#9 zeQ-L~=k&bAlT4+vxT3@6lbZ2naQ}_2wV!_AKUL8Y!FvK&=Q-h1^4oo3rOe@mieCqR z<*AE_ABtR-sPo zCff}chvKdtG99=WYS9lS6r7)S)%%(D-c&SJ{ue?THeD2ms`8~Z&3MH*HJz-BjoDY>KcPj<>M;Agh_ zvx%WmC{9T@A^RZv-XP1=-7df zhe>IiAeVxU6+OnD3HrIqV<8bV_EPwxg=+JGb8Z*j=7E*|D9IS&ne}!ipx_YzqXI{P z*SbpQXLl6ALXClmtud@umhSeRz&BT$1&sZ9gJb?g$nC>xWSN#k43e?>TcUZ*va<3m zTaZ3TR0$uf|65=biuQrmCd%}sA+tq;pF`X~!`Av!W z4}ysdt{7xO&hy{y>(ecYBrNAy@H{F7LnRaGJPFDL5-hwP5O;Tl*I;SGL=!~WBWxI4 zLY4lR+VP%YiXIoOv)wyvO+qqT+ z8bbyNogo&SP&0sK*83&}9u`~9Ts!W+9At#cbnMgk6vAI?Bu|WvpcU0(mkK=3N8;SJHwe$LMI%uBWl`J@(_)X(-yfUyIF1)joKkqN0L@5c-cn!J)6e=T)-vf0d68!gqFiBd*> z;KSkK;?iNa`hHPFE?cEf@gJV5G%6g+(kHLyf3?y3Rz^mqO*k)6iOBt<_YD?yWTLY< zV7Gl4ihBUF7Lna5LGZX{18!3t>mtq%dXeS>X)7gX`zoV8YIvwsH zC=dxz5ewD&k?4!*Nt67!2q_Z#Pn0whi6kk3#`uNi$KQvn-CwaQ;r@H~QJ%f-ATPwn zfgJ9NbEvsQ&_}-Grx^cQ_Ve$i3w%SyW}Fm_YPtW{HBBKjRkW1D*+iL))+jXcWuFT5 zK5H$%50Jx2{*5mQ>>C2Mwn#y4JLG|O{W@va0)f9}aH?XGdk6o5`uE(KU=kiqb=Ix*q1)Ida)pHh;OK$ ztvr_XY*SjKybw{I$GJd|x4hbvMfd$MKAWF#ZYWXTedy&-$nu{4N~tb=I`k3uMf#K=yRttbsy zhR4{V82d8zeV5&P@&2Aq_s99&AMUxX|9Kw&W6Tep9{v?-k9kUT`sZvF3+oki*B9r| zl9^#oH6uL*+B>iSENp;7S*WuC#!amfb{Z@Bw?liSuC`j)fO#yG{wtFlRx#ONCSQj5 zHD&5EWG+!?kFH6S98B{$mnj@2Db{1oL22;cVkX%g{P_S@aP2b&S3SN+ve1E@5!Lf_ zp(6=$$H=5QQo_CJnI@Qje8C!CiVGuY|18i_ku|dzwMFR_8!~=iffXU@>T^UDH~Kxj z?Mo}&wIalAFy^d)tn|#m>>kixQzhT3{8%*X$UHEqmLNsQ;4%kqmUziLu)dbK}2 z|B11ck^ka$uQ5-+&Lw@@y4<;&Ub!iaBA06t)mWX&K$B`wBC4n=#EBwStqzg#5+t&= z5T|k@kIGAmlm1HVx@evL=cRfj;}HJkW<8jtX47ny`}W$Aw?itmN;035u>tcBe}p6L zO@JmYz9ZX@$=bAk=B(eI5!fhO2s=vW6~xL0WifubA5DM3XM81NtneLMRJ9LEm2j@a z-lx)|aSm00%{O`c#O-Lr4$jAVUOOVvZ*zsEi4oCI@W`ziEDhQ_=5$iNij~kk%^g>^ z%oc=(Qx#pu@dN01DvDS2V7a;$oqm=(_oCyP2QX@!;kfk&=Ujr*idc2rEqB)Ck$SK7 z8kfW~jjj49McaA0kYl+i-puqN+@171t>2EcDiM+n{d+e2fv$7U!;AB$#J_`Xj0^+M zs1H(Lhn$;nlwWnsnxe6HoB=F!)9LxeOpOLgS4V8tdEcD-TJ~E}BF}!C3Jd-l2^cy_ zRF8B3r;p&Dkyj8Mc2>S6op`kSKeByNE)6#&vbPuKgN^v1(9zvm+@Kg~e74!48zgf! zZKn7EtVzOge-BX9f|9Y{%#(XJ%YJqZK3BgmRfar}=aR{5I)%P%T^*=pVsgzU*gEn< zE%v><|C?GWx7jDXVGW&ElT##c6Th&0V&{j|UQ*W{1xt`FAq%$cCfLVIPuG@YU*)(m zCQ@J$!@-Qe?QUvuC`N3~_aL7ELcjfhqQ1vj=7<9hrWAv_Vj>;0()M5erJvzcmG#6op6RLzk0eL`%#FJYv$UKLX9PaOlbj%+vSN$i%A|6g8E%UzvZ#2v*bh%r z@UJUFbu=Kd6$3V2G{x{mj^LGouD_!MWLKgzLc==;^ixwTgf*Gint4FlFnR#SG2<=w zB%Wzvz~IA-5CG@oUUe-y3IZj2*`q7snXZ?

        A)gDUgjyKuJ@O&`S|hzwi8>d*YSX4PzwDyqv-s~N`Yjr2USvB!N01ipP?qpuaO zj0dk=Vq1G=%Ap;(8#N2yAv*E`j4PF6P@~2O6B)xoP4rh#mWd2@qsXoa+*v`XF5QUd z_q%)^1Qe~T7{#lUar5dxxw1!Xb|)>#h>}-pUi+b|b<`Tzy24~B+O=nP<`M4sRMYl= zKcuBS0}2Dh5u@FmeGbuEcZ$@d02U)``I&9Ls_>h6-G)zhf$BN6w7UKSm|&>ML*ye z+b}X?;<3CL1wE?0VR^er;uA^ch&(+YRYmAhZ|hn?60wbZu~- ztonav2VMBn%>^D(H|TG_W|O?bK>=5a>0>r0y)GoZJg1Nvs;(K&;_%lu_vHZ%-A(P5 zbD%wiKRF$=&xX_tI7Fw1gp3YaikF0%fu4gA%a+UJ;3u(*M*k@q28TGnDZ5`O4-Q!W zQr`>^*`2FFWHTwY>Af0PZ5Q5HY;9V*PDC*9eVF=B3X&7**!slN2#14dSM2YnBfddHj;$Qc zQ^_+OQr3^A4R{~xKp^T9iVC$|ok-aYy|I<`#EDC9oA%fYlM>quvy~BPYx|D3!I42=e41ueT_^Hr9bJsdI!%pU&Kq7zHi;J=n%1B|3QPz z^%m!XJA>YLcjsynaZFU4B#laM?Y6P9QPFf4o9oHbYUApjx%8g+AtlUFo@`7r{n5~C zb(#Fy1>cjEhK1c*Y<&UqVq!Cl^~J)q?*1w=h!ijIt&^~Yp}a1T0++0T!zd-EvXf$S zG=Vu>7S8+2(MtL4sJsac^h{8kO)D?3j{BVQmH2NDE@_x1E6ApYU$bF*KqafqBOPR# zKyu#MdYK7*2G@^t{JjX*rnhSC1X8{0zsfh?-x~2oHsm~3Xck8^J?lJgx4C+I!Xrwk zjA1)^n3RogS&D^;$dlA=+n=#}>$xio4Jc0V+jF`mE~jdKedtYwRO`jk#-_(Cdr#^P zsNy*7x{?o(UL-bZ2r))BmRaS!4K+8ccHA(MV{%N>mf}NNvEPG7*jU;ggd!_@?@wFy z)hIxSjB-_quWRR~TIK0JFQwTA>p$kon|&(>nl8Xz)E2P8`xXCYVb3y2Dm3Snpls+| zM%VMvSMlw^hn9be(7Uczv2D6Z#XAAto{v^E*HMW~nN>zl0`-rM#^e=zM2bBRQ2$Io zCNJ+yv$ITIQLh`cR}gJ-K(5ARI)rMB&fgA?qwLAGt%d5VrZ#zwPM4zjjIrr6WBxw6 zYuVxR4}w|n1IH4cMnX}r95iHXMrNU@%Yw8hY&jx9!%7=c5ok-?QBYQko?%N>bBl68x(UibdJ2=!&!FBd*La+>%0X_Wv!zPW>r zn!Ib(__@G`1ObAgA#fzEVfpuZ4A|Ao_Gzg9uN`V}bXlqSNCOJd5IXnP9JC@;qubGI z)Q)~^MZ)ORWbS!Y!wRoiqy&U`c0pUZ(R<>|{lg@~N6Qa90ptt#kyX+VV4tG=2@F(YC$5XFVmaW}as-Zfsd@D}Pdx|e)}M*nh=d-+d-NyXK`}=DU?u^^NicKz1 zWUR-vtov|x?hd7dp~XFq)-2zDu^5whVw$`p3LTS{qDiK3-%6xPv{_r|r~7BCL_on? z%G4%)a?jGivr$0mWQr}z!?les?Sp#{iRz;ZgW?{T7TVk!| z`rC%~ntySU-95f$3*8B}8lqfq7op)6eh+5lLD+5h%C(3k_iH5W6nCW^wI7I@8RGjN z7E|tbJ2Qi#{z~T#3*&z^Hqulr!J?v)I~X0S1O0GqtUa-jn=p z(rLJ^Z~98^Dq8Js(Ki@W7vm6l-FX73yS?KB&0+A0mKDV{J}+-H9btfRI?qfHLwaQ; zVpblECL)!#96r!*KhXTJTr##P!1t_i#cAv0KrU z?Q1ji`Q9&sbY61HbhvL^i_ir|xu^=YtwsCRi%#{*hpUW-J24&3nd7y)*YjxNL81}3 zOM~I01_SPlo*%AjQn5{UJhPAJ<5%~G`Fo3zxb3Tb6Da-|the!$lz!tTxEcaO9Utf; g{->*RSUI91^h_lwmFDmQo8Boc_4{g{RBc242dwAe#{d8T literal 0 HcmV?d00001 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-1-algorithm-explanation.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-1-algorithm-explanation.md new file mode 100644 index 00000000..48055183 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-1-algorithm-explanation.md @@ -0,0 +1,13 @@ +--- +sidebar_position: 26 +--- + +# 6.1 算法解释 + +这里我们引用一下维基百科的描述:“`动态规划`(Dynamic Programming, DP)在查找有很多`重叠子问题`的情况的最优解时有效。它将问题重新组合成子问题。为了避免多次解决这些子问题,它们的结果都逐渐被计算并被保存,从简单的问题直到整个问题都被解决。因此,动态规划保存递归时的结果,因而不会在解决同样的问题时花费时间 · · · · · · 动态规划只能应用于有`最优子结构`的问题。最优子结构的意思是局部最优解能决定全局最优解(对有些问题这个要求并不能完全满足,故有时需要引入一定的近似)。简单地说,问题能够分解成子问题来解决。” + +通俗一点来讲,动态规划和其它遍历算法(如深/广度优先搜索)都是将原问题拆成多个子问题然后求解,他们之间最本质的区别是,动态规划`保存子问题的解,避免重复计算`。解决动态规划问题的关键是找到`状态转移方程`,这样我们可以通过计算和储存子问题的解来求解最终问题。 + +同时,我们也可以对动态规划进行`空间压缩`,起到节省空间消耗的效果。这一技巧笔者将在之后的题目中介绍。 + +在一些情况下,动态规划可以看成是带有`状态记录`(memoization)的优先搜索。状态记录的意思为,如果一个子问题在优先搜索时已经计算过一次,我们可以把它的结果储存下来,之后遍历到该子问题的时候可以直接返回储存的结果。动态规划是自下而上的,即先解决子问题,再解决父问题;而用带有状态记录的优先搜索是自上而下的,即从父问题搜索到子问题,若重复搜索到同一个子问题则进行状态记录,防止重复计算。如果题目需求的是最终状态,那么使用动态搜索比较方便;如果题目需要输出所有的路径,那么使用带有状态记录的优先搜索会比较方便。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-2-basic-dp-1d.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-2-basic-dp-1d.mdx new file mode 100644 index 00000000..3fd95068 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-2-basic-dp-1d.mdx @@ -0,0 +1,236 @@ +--- +sidebar_position: 27 +--- + +# 6.2 基本动态规划:一维 + +## [70. Climbing Stairs](https://leetcode.com/problems/climbing-stairs/) + +### 題目描述 + +给定 $n$ 节台阶,每次可以走一步或走两步,求一共有多少种方式可以走完这些台阶。 + +### 輸入輸出範例 + +输入是一个数字,表示台阶数量;输出是爬台阶的总方式。 + +``` +Input: 3 +Output: 3 +``` + +在这个样例中,一共有三种方法走完这三节台阶:每次走一步;先走一步,再走两步;先走两步,再走一步。 + +### 題解 + +这是十分经典的斐波那契数列题。定义一个数组 dp,dp[i] 表示走到第 i 阶的方法数。因为我们每次可以走一步或者两步,所以第 i 阶可以从第 i-1 或 i-2 阶到达。换句话说,走到第 i 阶的方法数即为走到第 i-1 阶的方法数加上走到第 i-2 阶的方法数。这样我们就得到了状态转移方程 dp[i] = dp[i-1] + dp[i-2]。注意边界条件的处理。 + +:::warning + +有的时候为了方便处理边界情况,我们可以在构造 dp 数组时多留一个位置,用来处理初始状态。本题即多留了一个第 0 阶的初始位置。 + +::: + + + + +```cpp +int climbStairs(int n) { + vector dp(n + 1, 1); + for (int i = 2; i <= n; ++i) { + dp[i] = dp[i - 1] + dp[i - 2]; + } + return dp[n]; +} +``` + + + + +```py +def climbStairs(n: int) -> int: + dp = [1] * (n + 1) + for i in range(2, n + 1): + dp[i] = dp[i - 1] + dp[i - 2] + return dp[n] +``` + + + + + +进一步的,我们可以对动态规划进行空间压缩。因为 dp[i] 只与 dp[i-1] 和 dp[i-2] 有关,因此可以只用两个变量来存储 dp[i-1] 和 dp[i-2],使得原来的 $O(n)$ 空间复杂度优化为 $O(1)$ 复杂度。 + + + + +```cpp +int climbStairs(int n) { + int prev_prev = 1, prev = 1, cur = 1; + for (int i = 2; i <= n; ++i) { + cur = prev_prev + prev; + prev_prev = prev; + prev = cur; + } + return cur; +} +``` + + + + +```py +def climbStairs(n: int) -> int: + prev_prev = prev = cur = 1 + for _ in range(2, n + 1): + cur = prev_prev + prev + prev_prev = prev + prev = cur + return cur +``` + + + + + + +## [198. House Robber](https://leetcode.com/problems/house-robber/) + +### 題目描述 + +假如你是一个劫匪,并且决定抢劫一条街上的房子,每个房子内的钱财数量各不相同。如果你抢了两栋相邻的房子,则会触发警报机关。求在不触发机关的情况下最多可以抢劫多少钱。 + +### 輸入輸出範例 + +输入是一个一维数组,表示每个房子的钱财数量;输出是劫匪可以最多抢劫的钱财数量。 + +``` +Input: [2,7,9,3,1] +Output: 12 +``` + +在这个样例中,最多的抢劫方式为抢劫第 1、3、5 个房子。 + +### 題解 + +定义一个数组 dp,dp[i] 表示抢劫到第 i 个房子时,可以抢劫的最大数量。我们考虑 dp[i],此时可以抢劫的最大数量有两种可能,一种是我们选择不抢劫这个房子,此时累计的金额即为 dp[i-1];另一种是我们选择抢劫这个房子,那么此前累计的最大金额只能是 dp[i-2],因为我们不能够抢劫第 i-1 个房子,否则会触发警报机关。因此本题的状态转移方程为 dp[i] = max(dp[i-1], nums[i-1] + dp[i-2])。 + + + + +```cpp +int rob(vector& nums) { + int n = nums.size(); + vector dp(n + 1, 0); + dp[1] = nums[0]; + for (int i = 2; i <= n; ++i) { + dp[i] = max(dp[i - 1], nums[i - 1] + dp[i - 2]); + } + return dp[n]; +} +``` + + + + +```py +def rob(nums: List[int]) -> int: + n = len(nums) + dp = [0] * (n + 1) + dp[1] = nums[0] + for i in range(2, n + 1): + dp[i] = max(dp[i - 1], nums[i - 1] + dp[i - 2]) + return dp[n] +``` + + + + + +同样的,我们可以像题目 70 那样,对空间进行压缩。 + + + + +```cpp +int rob(vector& nums) { + int prev_prev = 0, prev = 0, cur = 0; + for (int i = 0; i < nums.size(); ++i) { + cur = max(prev_prev + nums[i], prev); + prev_prev = prev; + prev = cur; + } + return cur; +} +``` + + + + +```py +def rob(nums: List[int]) -> int: + prev_prev = prev = cur = 0 + for i in range(len(nums)): + cur = max(prev_prev + nums[i], prev) + prev_prev = prev + prev = cur + return cur +``` + + + + + +## [413. Arithmetic Slices](https://leetcode.com/problems/arithmetic-slices/) + +### 題目描述 + +给定一个数组,求这个数组中连续且等差的子数组一共有多少个。 + +### 輸入輸出範例 + +输入是一个一维数组,输出是满足等差条件的连续子数组个数。 + +``` +Input: nums = [1,2,3,4] +Output: 3 +``` + +在这个样例中,等差数列有 [1,2,3]、[2,3,4] 和 [1,2,3,4]。 + +### 題解 + +因为要求是等差数列,可以很自然地想到子数组必定满足 num[i] - num[i-1] = num[i-1] - num[i-2]。这里我们对于 dp 数组的定义是以 i 结尾的,满足该条件的子数组数量。因为等差子数组可以在任意一个位置终结,所以我们需要对 dp 数组求和进行子数组统计。 + + + + +```cpp +int numberOfArithmeticSlices(vector& nums) { + int n = nums.size(); + vector dp(n, 0); + for (int i = 2; i < n; ++i) { + if (nums[i] - nums[i - 1] == nums[i - 1] - nums[i - 2]) { + dp[i] = dp[i - 1] + 1; + } + } + return accumulate(dp.begin(), dp.end(), 0); +} +``` + + + + +```py +def numberOfArithmeticSlices(nums: List[int]) -> int: + n = len(nums) + dp = [0] * n + for i in range(2, n): + if nums[i] - nums[i - 1] == nums[i - 1] - nums[i - 2]: + dp[i] = dp[i - 1] + 1 + return sum(dp) +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-3-basic-dp-2d.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-3-basic-dp-2d.mdx new file mode 100644 index 00000000..7a889374 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-3-basic-dp-2d.mdx @@ -0,0 +1,307 @@ +--- +sidebar_position: 28 +--- + +# 6.3 基本动态规划:二维 + +## [64. Minimum Path Sum](https://leetcode.com/problems/minimum-path-sum/) + +### 題目描述 + +给定一个 $m × n$ 大小的非负整数矩阵,求从左上角开始到右下角结束的、经过的数字的和最 +小的路径。每次只能向右或者向下移动。 + +### 輸入輸出範例 + +输入是一个二维数组,输出是最优路径的数字和。 + +``` +Input: +[[1,3,1], + [1,5,1], + [4,2,1]] +Output: 7 +``` + +在这个样例中,最短路径为 1->3->1->1->1。 + +### 題解 + +我们可以定义一个同样是二维的 dp 数组,其中 dp[i][j] 表示从左上角开始到 (i, j) 位置的最优路径的数字和。因为每次只能向下或者向右移动,我们可以很直观地得到状态转移方程 dp[i][j] = grid[i][j] + min(dp[i-1][j], dp[i][j-1]),其中 grid 表示原数组。 + +:::warning + +Python 语言中,多维数组多初始化比较特殊,直接初始化为 [[val] * n] * m 会导致只是创造了 m 个 [[val] * n] 的引用。正确的初始化方法为 [[val for _ in range(n)] for _ in range(m)]。 + +::: + + + + +```cpp +int minPathSum(vector>& grid) { + int m = grid.size(), n = grid[0].size(); + vector> dp(m, vector(n, 0)); + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (i == 0 && j == 0) { + dp[i][j] = grid[i][j]; + } else if (i == 0) { + dp[i][j] = grid[i][j] + dp[i][j - 1]; + } else if (j == 0) { + dp[i][j] = grid[i][j] + dp[i - 1][j]; + } else { + dp[i][j] = grid[i][j] + min(dp[i - 1][j], dp[i][j - 1]); + } + } + } + return dp[m - 1][n - 1]; +} +``` + + + + +```py +def minPathSum(grid: List[List[int]]) -> int: + m, n = len(grid), len(grid[0]) + dp = [[0 for _ in range(n)] for _ in range(m)] + for i in range(m): + for j in range(n): + if i == j == 0: + dp[i][j] = grid[i][j] + elif i == 0: + dp[i][j] = grid[i][j] + dp[i][j - 1] + elif j == 0: + dp[i][j] = grid[i][j] + dp[i - 1][j] + else: + dp[i][j] = grid[i][j] + min(dp[i][j - 1], dp[i - 1][j]) + return dp[m - 1][n - 1] +``` + + + + + +因为 dp 矩阵的每一个值只和左边和上面的值相关,我们可以使用空间压缩将 dp 数组压缩为一维。对于第 i 行,在遍历到第 j 列的时候,因为第 j-1 列已经更新过了,所以 dp[j-1] 代表 dp[i][j-1]的值;而 dp[j] 待更新,当前存储的值是在第 i-1 行的时候计算的,所以代表 dp[i-1][j] 的值。 + +:::warning + +如果不是很熟悉空间压缩技巧,笔者推荐您优先尝试写出非空间压缩的解法,如果时间充裕且力所能及再进行空间压缩。 + +::: + + + + + + +```cpp +int minPathSum(vector>& grid) { + int m = grid.size(), n = grid[0].size(); + vector dp(n, 0); + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (i == 0 && j == 0) { + dp[j] = grid[i][j]; + } else if (i == 0) { + dp[j] = grid[i][j] + dp[j - 1]; + } else if (j == 0) { + dp[j] = grid[i][j] + dp[j]; + } else { + dp[j] = grid[i][j] + min(dp[j], dp[j - 1]); + } + } + } + return dp[n - 1]; +} +``` + + + + +```py +def minPathSum(grid: List[List[int]]) -> int: + m, n = len(grid), len(grid[0]) + dp = [0 for _ in range(n)] + for i in range(m): + for j in range(n): + if i == j == 0: + dp[j] = grid[i][j] + elif i == 0: + dp[j] = grid[i][j] + dp[j - 1] + elif j == 0: + dp[j] = grid[i][j] + dp[j] + else: + dp[j] = grid[i][j] + min(dp[j - 1], dp[j]) + return dp[n - 1] +``` + + + + + + +## [542. 01 Matrix](https://leetcode.com/problems/01-matrix/) + +### 題目描述 + +给定一个由 0 和 1 组成的二维矩阵,求每个位置到最近的 0 的距离。 + +### 輸入輸出範例 + +输入是一个二维 0-1 数组,输出是一个同样大小的非负整数数组,表示每个位置到最近的 0 的距离。 + +``` +Input: +[[0,0,0], + [0,1,0], + [1,1,1]] + +Output: +[[0,0,0], + [0,1,0], + [1,2,1]] +``` + +### 題解 + +一般来说,因为这道题涉及到四个方向上的最近搜索,所以很多人的第一反应可能会是广度优先搜索。但是对于一个大小 $O(mn)$ 的二维数组,对每个位置进行四向搜索,最坏情况的时间复杂度(即全是 1)会达到恐怖的 $O(m^2n^2)$。一种办法是使用一个二维布尔值数组做 memoization,使得广度优先搜索不会重复遍历相同位置;另一种更简单的方法是,我们从左上到右下进行一次动态搜索,再从右下到左上进行一次动态搜索。两次动态搜索即可完成四个方向上的查找。 + + + + + +```cpp +vector> updateMatrix(vector>& matrix) { + int m = matrix.size(), n = matrix[0].size(); + vector> dp(m, vector(n, numeric_limits::max() - 1)); + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (matrix[i][j] != 0) { + if (i > 0) { + dp[i][j] = min(dp[i][j], dp[i - 1][j] + 1); + } + if (j > 0) { + dp[i][j] = min(dp[i][j], dp[i][j - 1] + 1); + } + } else { + dp[i][j] = 0; + } + } + } + for (int i = m - 1; i >= 0; --i) { + for (int j = n - 1; j >= 0; --j) { + if (matrix[i][j] != 0) { + if (i < m - 1) { + dp[i][j] = min(dp[i][j], dp[i + 1][j] + 1); + } + if (j < n - 1) { + dp[i][j] = min(dp[i][j], dp[i][j + 1] + 1); + } + } + } + } + return dp; +} +``` + + + + +```py +def updateMatrix(matrix: List[List[int]]) -> List[List[int]]: + m, n = len(matrix), len(matrix[0]) + dp = [[sys.maxsize - 1 for _ in range(n)] for _ in range(m)] + for i in range(m): + for j in range(n): + if matrix[i][j] != 0: + if i > 0: + dp[i][j] = min(dp[i][j], dp[i - 1][j] + 1) + if j > 0: + dp[i][j] = min(dp[i][j], dp[i][j - 1] + 1) + else: + dp[i][j] = 0 + for i in range(m - 1, -1, -1): # m-1 to 0, reversed + for j in range(n - 1, -1, -1): # n-1 to 0, reversed + if matrix[i][j] != 0: + if i < m - 1: + dp[i][j] = min(dp[i][j], dp[i + 1][j] + 1) + if j < n - 1: + dp[i][j] = min(dp[i][j], dp[i][j + 1] + 1) + return dp +``` + + + + + +## [221. Maximal Square](https://leetcode.com/problems/maximal-square/) + +### 題目描述 + +给定一个二维的 0-1 矩阵,求全由 1 构成的最大正方形面积。 + +### 輸入輸出範例 + +输入是一个二维 0-1 数组,输出是最大正方形面积。 + +``` +Input: +[["1","0","1","0","0"], + ["1","0","1","1","1"], + ["1","1","1","1","1"], + ["1","0","0","1","0"]] +Output: 4 +``` + +### 題解 + +对于在矩阵内搜索正方形或长方形的题型,一种常见的做法是定义一个二维 dp 数组,其中 dp[i][j] 表示满足题目条件的、以 (i, j) 为右下角的正方形或者长方形的属性。对于本题,则表示以 (i, j) 为右下角的全由 1 构成的最大正方形边长。如果当前位置是 0,那么 dp[i][j] 即为 0;如果当前位置是 1,我们假设 dp[i][j] = k,其充分条件为 dp[i-1][j-1]、dp[i][j-1] 和 dp[i-1][j] 的值必须都不小于 k − 1,否则 (i, j) 位置不可以构成一个面积为 $k^2$ 的正方形。同理,如果这三个值中的的最小值为 k − 1,则 (i, j) 位置一定且最大可以构成一个面积为 $k^2$ 的正方形。 + + +

        + + ![](6.1.png) + +
        图 6.1: 题目 542 - 左边为一个 0-1 矩阵,右边为其对应的 dp 矩阵,我们可以发现最大的正方形边长为 3
        +
        + + + + +```cpp +int maximalSquare(vector>& matrix) { + int m = matrix.size(), n = matrix[0].size(); + int max_side = 0; + vector> dp(m + 1, vector(n + 1, 0)); + for (int i = 1; i <= m; ++i) { + for (int j = 1; j <= n; ++j) { + if (matrix[i - 1][j - 1] == ’1’) { + dp[i][j] = + min(dp[i - 1][j - 1], min(dp[i][j - 1], dp[i - 1][j])) + 1; + } + max_side = max(max_side, dp[i][j]); + } + } + return max_side * max_side; +} +``` + + + + +```py +def maximalSquare(matrix: List[List[str]]) -> int: + m, n = len(matrix), len(matrix[0]) + dp = [[0 for _ in range(n + 1)] for _ in range(m + 1)] + for i in range(1, m + 1): + for j in range(1, n + 1): + if matrix[i - 1][j - 1] == "1": + dp[i][j] = min(dp[i - 1][j - 1], dp[i][j - 1], dp[i - 1][j]) + 1 + return max(max(row) for row in dp) ** 2 +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-4-partition-problems.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-4-partition-problems.mdx new file mode 100644 index 00000000..a1a38cdf --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-4-partition-problems.mdx @@ -0,0 +1,347 @@ +--- +sidebar_position: 29 +--- + +# 6.4 分割类型题 + +## [279. Perfect Squares](https://leetcode.com/problems/perfect-squares/) + +### 題目描述 + +给定一个正整数,求其最少可以由几个完全平方数相加构成。 + +### 輸入輸出範例 + +输入是给定的正整数,输出也是一个正整数,表示输入的数字最少可以由几个完全平方数相加构成。 + +``` +Input: n = 13 +Output: 2 +``` + +在这个样例中,13 的最少构成方法为 4+9。 + +### 題解 + +对于分割类型题,动态规划的状态转移方程通常并不依赖相邻的位置,而是依赖于满足分割条件的位置。我们定义一个一维矩阵 dp,其中 dp[i] 表示数字 i 最少可以由几个完全平方数相加构成。在本题中,位置 i 只依赖 $i - j^2$ 的位置,如 i - 1、i - 4、i - 9 等等,才能满足完全平方分割的条件。因此 dp[i] 可以取的最小值即为 1+ min(dp[i-1], dp[i-4], dp[i-9] · · · )。注意边界条件的处理。 + + + + +```cpp +int numSquares(int n) { + vector dp(n + 1, numeric_limits::max()); + dp[0] = 0; + for (int i = 1; i <= n; ++i) { + for (int j = 1; j * j <= i; ++j) { + dp[i] = min(dp[i], dp[i - j * j] + 1); + } + } + return dp[n]; +} +``` + + + + +```py +def numSquares(n: int) -> int: + dp = [0] + [sys.maxsize] * n + for i in range(1, n + 1): + for j in range(1, int(floor(sqrt(i))) + 1): + dp[i] = min(dp[i], dp[i - j * j] + 1) + return dp[n] +``` + + + + + +## [91. Decode Ways](https://leetcode.com/problems/decode-ways/) + +### 題目描述 + +已知字母 A-Z 可以表示成数字 1-26。给定一个数字串,求有多少种不同的字符串等价于这个数字串。 + +### 輸入輸出範例 + +输入是一个由数字组成的字符串,输出是满足条件的解码方式总数。 + +``` +Input: "226" +Output: 3 +``` + +在这个样例中,有三种解码方式:BZ(2 26)、VF(22 6) 或 BBF(2 2 6)。 + +### 題解 + +这是一道很经典的动态规划题,难度不大但是十分考验耐心。这是因为只有 1-26 可以表示字母,因此对于一些特殊情况,比如数字 0 或者当相邻两数字大于 26 时,需要有不同的状态转移方程,详见如下代码。 + + + + +```cpp +int numDecodings(string s) { + int n = s.length(); + int prev = s[0] - ’0’; + if (prev == 0) { + return 0; + } + if (n == 1) { + return 1; + } + vector dp(n + 1, 1); + for (int i = 2; i <= n; ++i) { + int cur = s[i - 1] - ’0’; + if ((prev == 0 || prev > 2) && cur == 0) { + // 00, 30, 40, ..., 90, 非法。 + return 0; + } + if ((prev < 2 && prev > 0) || (prev == 2 && cur <= 6)) { + // 10, 11, ..., 25, 26. + if (cur == 0) { + // 10, 20,只能连续解码两位。 + dp[i] = dp[i - 2]; + } else { + // 可以解码当前位,也可以连续解码两位。 + dp[i] = dp[i - 2] + dp[i - 1]; + } + } else { + // 合法,但只能解码当前位。 + dp[i] = dp[i - 1]; + } + prev = cur; + } + return dp[n]; +} +``` + + + + +```py +def numDecodings(s: str) -> int: + n = len(s) + prev = ord(s[0]) - ord("0") + if prev == 0: + return 0 + if n == 1: + return 1 + dp = [1] * (n + 1) + for i in range(2, n + 1): + cur = ord(s[i - 1]) - ord("0") + if (prev == 0 or prev > 2) and cur == 0: + # 00, 30, 40, ..., 90, 非法。 + return 0 + if 0 < prev < 2 or (prev == 2 and cur <= 6): + # 10, 11, ..., 25, 26. + if cur == 0: + # 10, 20,只能连续解码两位。 + dp[i] = dp[i - 2] + else: + # 可以解码当前位,也可以连续解码两位。 + dp[i] = dp[i - 2] + dp[i - 1] + else: + # 合法,但只能解码当前位。 + dp[i] = dp[i - 1] + prev = cur + return dp[n] +``` + + + + + +## [139. Word Break](https://leetcode.com/problems/word-break/) + +### 題目描述 + +给定一个字符串和一个字符串集合,求是否存在一种分割方式,使得原字符串分割后的子字符串都可以在集合内找到。 + +### 輸入輸出範例 + +``` +Input: s = "applepenapple", wordDict = ["apple", "pen"] +Output: true +``` + +在这个样例中,字符串可以被分割为 [“apple”,“pen”,“apple”]。 + +### 題解 + +类似于完全平方数分割问题,这道题的分割条件由集合内的字符串决定,因此在考虑每个分割位置时,需要遍历字符串集合,以确定当前位置是否可以成功分割。注意对于位置 0,需要初始化值为真。 + + + + +```cpp +bool wordBreak(string s, vector& wordDict) { + int n = s.length(); + vector dp(n + 1, false); + dp[0] = true; + for (int i = 1; i <= n; ++i) { + for (const string& word : wordDict) { + int m = word.length(); + if (i >= m && s.substr(i - m, m) == word) { + dp[i] = dp[i - m]; + } + // 提前剪枝,略微加速运算。 + // 如果不剪枝,上一行代码需要变更为 dp[i] = dp[i] || dp[i - m]; + if (dp[i]) { + break; + } + } + } + return dp[n]; +} +``` + + + + +```py +def wordBreak(s: str, wordDict: List[str]) -> bool: + n = len(s) + dp = [True] + [False] * n + for i in range(1, n + 1): + for word in wordDict: + m = len(word) + if i >= m and s[i - m : i] == word: + dp[i] = dp[i - m] + # 提前剪枝,略微加速运算。 + # 如果不剪枝,上一行代码需要变更为 dp[i] = dp[i] or dp[i-m] + if dp[i]: + break + return dp[n] +``` + + + + + +## [1105. Filling Bookcase Shelves](https://leetcode.com/problems/filling-bookcase-shelves/) + +### 題目描述 + +给定一个数组,每个元素代表一本书的厚度和高度。问对于一个固定宽度的书架,如果按照数组中书的顺序从左到右、从上到下摆放,最小总高度是多少。 + +### 輸入輸出範例 + + +``` +Input: books = [[1,1],[2,3],[2,3],[1,1],[1,1],[1,1],[1,2]], shelfWidth = 4 +Output: 6 +``` + + +
        + + ![](https://assets.leetcode.com/uploads/2019/06/24/shelves.png) + +
        图 6.2: 书架摆放问题 - 样例图解
        +
        + +### 題解 + +令 dp[i] 表示放置第 i 本书时的最小总高度,则 dp[i] 可以是在第 i-1 本书下面重新放一排,也可以是在满足不超过前一排宽度的情况下放在前一排。 + + + + +```cpp +int minHeightShelves(vector>& books, int shelfWidth) { + int n = books.size(); + vector dp(n + 1, 0); + for (int i = 1; i <= n; ++i) { + int w = books[i - 1][0], h = books[i - 1][1]; + dp[i] = dp[i - 1] + h; + for (int j = i - 1; j > 0; --j) { + int prev_w = books[j - 1][0], prev_h = books[j - 1][1]; + w += prev_w; + if (w > shelfWidth) { + break; + } + h = max(h, prev_h); + dp[i] = min(dp[i], dp[j - 1] + h); + } + } + return dp[n]; +} +``` + + + + +```py +def minHeightShelves(books: List[List[int]], shelfWidth: int) -> int: + n = len(books) + dp = [0] * (n + 1) + for i, (w, h) in enumerate(books, 1): + dp[i] = dp[i - 1] + h + for j in range(i - 1, 0, -1): + prev_w, prev_h = books[j - 1] + w += prev_w + if w > shelfWidth: + break + h = max(h, prev_h) + dp[i] = min(dp[i], dp[j - 1] + h) + return dp[n] +``` + + + + + +## [377. Combination Sum IV](https://leetcode.com/problems/combination-sum-iv/) + +### 題目描述 + +给定一个不重复数字的数组和一个目标数,求加起来是目标数的所有排列的总数量。(虽然这道题叫做 Combination Sum,但是不同顺序的组合会被当作不同答案,因此本质上是排列。) + +### 輸入輸出範例 + +``` +Input: nums = [1,2,3], target = 4 +Output: 7 +``` + +七种不同的排列为 (1, 1, 1, 1)、(1, 1, 2)、(1, 2, 1)、(1, 3)、(2, 1, 1)、(2, 2) 和 (3, 1)。 + + +### 題解 + +令 dp[i] 表示加起来和为 i 时,满足条件的排列数量。在内循环中我们可以直接对所有合法数字进行拿取。这里注意,在 C++ 题解中,因为求和时很容易超过 int 上界,我们这里用 double 存储 dp 数组。 + + + + +```cpp +int combinationSum4(vector& nums, int target) { + vector dp(target + 1, 0); + dp[0] = 1; + for (int i = 1; i <= target; ++i) { + for (int num : nums) { + if (num <= i) { + dp[i] += dp[i - num]; + } + } + } + return dp[target]; +} +``` + + + + +```py +def combinationSum4(nums: List[int], target: int) -> int: + dp = [1] + [0] * target + for i in range(1, target + 1): + dp[i] = sum(dp[i - num] for num in nums if i >= num) + return dp[target] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-5-subsequence-problems.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-5-subsequence-problems.mdx new file mode 100644 index 00000000..873d6ea2 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-5-subsequence-problems.mdx @@ -0,0 +1,189 @@ +--- +sidebar_position: 30 +--- + +# 6.5 子序列问题 + +## [300. Longest Increasing Subsequence](https://leetcode.com/problems/longest-increasing-subsequence/) + +### 題目描述 + +给定一个未排序的整数数组,求最长的递增子序列。 + +:::warning + +按照 LeetCode 的习惯,子序列(subsequence)不必连续,子数组(subarray)或子字符串(substring)必须连续。 + +::: + +### 輸入輸出範例 + +输入是一个一维数组,输出是一个正整数,表示最长递增子序列的长度。 + +``` +Input: [10,9,2,5,3,7,101,4] +Output: 4 +``` + +在这个样例中,最长递增子序列之一是 [2,3,7,101]。 + +### 題解 + +对于子序列问题,第一种动态规划方法是,定义一个 dp 数组,其中 dp[i] 表示以 i 结尾的子序列的性质。在处理好每个位置后,统计一遍各个位置的结果即可得到题目要求的结果。 + +在本题中,dp[i] 可以表示以 i 结尾的、最长子序列长度。对于每一个位置 i,如果其之前的某个位置 j 所对应的数字小于位置 i 所对应的数字,则我们可以获得一个以 i 结尾的、长度为 dp[j] + 1 的子序列。为了遍历所有情况,我们需要 i 和 j 进行两层循环,其时间复杂度为 $O(n^2)$。 + + + + +```cpp +int lengthOfLIS(vector& nums) { + int max_len = 0, n = nums.size(); + vector dp(n, 1); + for (int i = 0; i < n; ++i) { + for (int j = 0; j < i; ++j) { + if (nums[i] > nums[j]) { + dp[i] = max(dp[i], dp[j] + 1); + } + } + max_len = max(max_len, dp[i]); + } + return max_len; +} +``` + + + + +```py +def lengthOfLIS(nums: List[int]) -> int: + n = len(nums) + dp = [1] * n + for i in range(n): + for j in range(i): + if nums[i] > nums[j]: + dp[i] = max(dp[i], dp[j] + 1) + return max(dp) +``` + + + + + +本题还可以使用二分查找将时间复杂度降低为 $O(n \log n)$。我们定义一个 dp 数组,其中 dp[k] 存储长度为 k+1 的最长递增子序列的最后一个数字。我们遍历每一个位置 i,如果其对应的数字大于 dp 数组中所有数字的值,那么我们把它放在 dp 数组尾部,表示最长递增子序列长度加 1;如果我们发现这个数字在 dp 数组中比数字 a 大、比数字 b 小,则我们将 b 更新为此数字,使得之后构成递增序列的可能性增大。以这种方式维护的 dp 数组永远是递增的,因此可以用二分查找加速搜索。 + +以样例为例,对于数组 [10,9,2,5,3,7,101,4],我们每轮的更新查找情况为: + +``` +num dp +10 [10] +9 [9] +2 [2] +5 [2,5] +3 [2,3] +7 [2,3,7] +101 [2,3,7,101] +4 [2,3,4,101] +``` + +最终我们知道最长递增子序列的长度是 4。注意 dp 数组最终的形式并不一定是合法的排列形式,如 [2,3,4,101] 并不是子序列;但之前覆盖掉的 [2,3,7,101] 是最优解之一。 + +类似的,对于其他题目,如果状态转移方程的结果递增或递减,且需要进行插入或查找操作,我们也可以使用二分法进行加速。 + + + + +```cpp +int lengthOfLIS(vector& nums) { + vector dp{nums[0]}; + for (int num : nums) { + if (dp.back() < num) { + dp.push_back(num); + } else { + *lower_bound(dp.begin(), dp.end(), num) = num; + } + } + return dp.size(); +} +``` + + + + +```py +def lengthOfLIS(nums: List[int]) -> int: + dp = [nums[0]] + for num in nums: + if dp[-1] < num: + dp.append(num) + else: + dp[bisect.bisect_left(dp, num, 0, len(dp))] = num + return len(dp) +``` + + + + + +## [1143. Longest Commom Subsequence](https://leetcode.com/problems/longest-common-subsequence/) + +### 題目描述 + +给定两个字符串,求它们最长的公共子序列长度。 + +### 輸入輸出範例 + +输入是两个字符串,输出是一个整数,表示它们满足题目条件的长度。 + +``` +Input: text1 = "abcde", text2 = "ace" +Output: 3 +``` + +在这个样例中,最长公共子序列是“ace”。 + +### 題解 + +对于子序列问题,第二种动态规划方法是,定义一个 dp 数组,其中 dp[i] 表示到位置 i 为止的子序列的性质,并不必须以 i 结尾。这样 dp 数组的最后一位结果即为题目所求,不需要再对每个位置进行统计。 + +在本题中,我们可以建立一个二维数组 dp,其中 dp[i][j] 表示到第一个字符串位置 i 为止、到第二个字符串位置 j 为止、最长的公共子序列长度。这样一来我们就可以很方便地分情况讨论这两个位置对应的字母相同与不同的情况了。 + + + + +```cpp +int longestCommonSubsequence(string text1, string text2) { + int m = text1.length(), n = text2.length(); + vector> dp(m + 1, vector(n + 1, 0)); + for (int i = 1; i <= m; ++i) { + for (int j = 1; j <= n; ++j) { + if (text1[i - 1] == text2[j - 1]) { + dp[i][j] = dp[i - 1][j - 1] + 1; + } else { + dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); + } + } + } + return dp[m][n]; +} +``` + + + + +```py +def longestCommonSubsequence(text1: str, text2: str) -> int: + m, n = len(text1), len(text2) + dp = [[0 for _ in range(n + 1)] for _ in range(m + 1)] + for i in range(1, m + 1): + for j in range(1, n + 1): + if text1[i - 1] == text2[j - 1]: + dp[i][j] = dp[i - 1][j - 1] + 1 + else: + dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + return dp[m][n] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-6-knapsack-problem.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-6-knapsack-problem.mdx new file mode 100644 index 00000000..3bf0fd5a --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-6-knapsack-problem.mdx @@ -0,0 +1,421 @@ +--- +sidebar_position: 31 +--- + +# 6.6 背包问题 + +`背包问题(knapsack problem)`是一种组合优化的 NP 完全问题:有 n 个物品和载重为 w 的背包,每个物品都有自己的重量 weight 和价值 value,求拿哪些物品可以使得背包所装下物品的总价值最大。如果限定每种物品只能选择 0 个或 1 个,则问题称为 `0-1 背包问题(0-1 knapsack)`;如果不限定每种物品的数量,则问题称为`无界背包问题或完全背包问题(unbounded knapsack)`。 + +我们可以用动态规划来解决背包问题。以 0-1 背包问题为例。我们可以定义一个二维数组 dp存储最大价值,其中 dp[i][j] 表示前 i 件物品重量不超过 j 的情况下能达到的最大价值。在我们遍历到第 i 件物品时,在当前背包总载重为 j 的情况下,如果我们不将物品 i 放入背包,那么 dp[i][j] = dp[i-1][j],即前 i 个物品的最大价值等于只取前 i-1 个物品时的最大价值;如果我们将物品 i 放入背包,假设第 i 件物品重量为 weight,价值为 value,那么我们得到 dp[i][j] = dp[i-1][j-weight] + value。我们只需在遍历过程中对这两种情况取最大值即可,总时间复杂度和空间复杂度都为 $O(nw)$。 + + + + + +```cpp +int knapsack(vector weights, vector values, int n, int w) { + vector> dp(n + 1, vector(w + 1, 0)); + for (int i = 1; i <= n; ++i) { + int weight = weights[i - 1], value = values[i - 1]; + for (int j = 1; j <= w; ++j) { + if (j >= weight) { + dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight] + value); + } else { + dp[i][j] = dp[i - 1][j]; + } + } + } + return dp[n][w]; +} +``` + + + + +```py +def knapsack(weights: List[int], values: List[int], n: int, w: int) -> int: + dp = [[0 for _ in range(w + 1)] for _ in range(n + 1)] + for i in range(1, n + 1): + weight, value = weights[i - 1], values[i - 1] + for j in range(1, w + 1): + if j >= weight: + dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight] + value) + else: + dp[i][j] = dp[i - 1][j] + return dp[n][w] +``` + + + + + +
        + + ![](6.3.png) + +
        图 6.3: 0-1 背包问题 - 状态转移矩阵样例
        +
        + +我们可以进一步对 0-1 背包进行空间优化,将空间复杂度降低为 O(w)。如图所示,假设我们目前考虑物品 i = 2,且其重量为 weight = 2,价值为 value = 3;对于背包载重 j,我们可以得到 dp[2][j] = max(dp[1][j], dp[1][j-2] + 3)。这里可以发现我们永远只依赖于上一排 i = 1 的信息,之前算过的其他物品都不需要再使用。因此我们可以去掉 dp 矩阵的第一个维度,在考虑物品 i 时变成 dp[j] = max(dp[j], dp[j-weight] + value)。这里要注意我们在遍历每一行的时候必须`逆向遍历`,这样才能够调用上一行物品 i-1 时 dp[j-weight] 的值;若按照从左往右的顺序进行正向遍历,则dp[j-weight] 的值在遍历到 j 之前就已经被更新成物品 i 的值了。 + + + + +```cpp +int knapsack(vector weights, vector values, int n, int w) { + vector dp(w + 1, 0); + for (int i = 1; i <= n; ++i) { + int weight = weights[i - 1], value = values[i - 1]; + for (int j = w; j >= weight; --j) { + dp[j] = max(dp[j], dp[j - weight] + value); + } + } + return dp[w]; +} +``` + + + + +```py +def knapsack(weights: List[int], values: List[int], n: int, w: int) -> int: + dp = [0] * (w + 1) + for i in range(1, n + 1): + weight, value = weights[i - 1], values[i - 1] + for j in range(w, weight - 1, -1): + dp[j] = max(dp[j], [j - weight] + value) + return dp[w] +``` + + + + + +在完全背包问题中,一个物品可以拿多次。如图上半部分所示,假设我们遍历到物品 i = 2,且其重量为 weight = 2,价值为 value = 3;对于背包载重 j = 5,最多只能装下 2 个该物品。那么我们的状态转移方程就变成了 dp[2][5] = max(dp[1][5], dp[1][3] + 3, dp[1][1] + 6)。如果采用这种方法,假设背包载重无穷大而物体的重量无穷小,我们这里的比较次数也会趋近于无穷大,远超$O(nw)$ 的时间复杂度。 + +
        + + ![](6.4.png) + +
        图 6.4: 完全背包问题 - 状态转移矩阵样例
        +
        + +怎么解决这个问题呢?我们发现在 dp[2][3] 的时候我们其实已经考虑了 dp[1][3] 和 dp[2][1] 的情况,而在时 dp[2][1] 也已经考虑了 dp[1][1] 的情况。因此,如图下半部分所示,对于拿多个物品的情况,我们只需考虑 dp[2][3] 即可,即 dp[2][5] = max(dp[1][5], dp[2][3] + 3)。这样,我们就得到了完全背包问题的状态转移方程:dp[i][j] = max(dp[i-1][j], dp[i][j-w] + v),其与 0-1 背包问题的差别仅仅是把状态转移方程中的第二个 i-1 变成了 i。 + + + + +```cpp +int knapsack(vector weights, vector values, int n, int w) { + vector> dp(n + 1, vector(w + 1, 0)); + for (int i = 1; i <= n; ++i) { + int weight = weights[i - 1], value = values[i - 1]; + for (int j = 1; j <= w; ++j) { + if (j >= weight) { + dp[i][j] = max(dp[i - 1][j], dp[i][j - weight] + value); + } else { + dp[i][j] = dp[i - 1][j]; + } + } + } + return dp[n][w]; +} +``` + + + + +```py +def knapsack(weights: List[int], values: List[int], n: int, w: int) -> int: + dp = [[0 for _ in range(w + 1)] for _ in range(n + 1)] + for i in range(1, n + 1): + weight, value = weights[i - 1], values[i - 1] + for j in range(1, w + 1): + if j >= weight: + dp[i][j] = max(dp[i - 1][j], dp[i][j - weight] + value) + else: + dp[i][j] = dp[i - 1][j] + return dp[n][w] +``` + + + + + +同样的,我们也可以利用空间压缩将时间复杂度降低为 $O(w)$。这里要注意我们在遍历每一行的时候必须`正向遍历`,因为我们需要利用当前物品在第 j-weight 列的信息。 + + + + +```cpp +int knapsack(vector weights, vector values, int n, int w) { + vector dp(w + 1, 0); + for (int i = 1; i <= n; ++i) { + int weight = weights[i - 1], value = values[i - 1]; + for (int j = weight; j <= w; ++j) { + dp[j] = max(dp[j], dp[j - weight] + value); + } + } + return dp[w]; +} +``` + + + + +```py +def knapsack(weights: List[int], values: List[int], n: int, w: int) -> int: + dp = [0] * (w + 1) + for i in range(1, n + 1): + weight, value = weights[i - 1], values[i - 1] + for j in range(weight, w + 1): + dp[j] = max(dp[j], [j - weight] + value) + return dp[w] +``` + + + + + +:::warning + +压缩空间时到底需要正向还是逆向遍历呢?物品和重量哪个放在外层,哪个放在内层呢?这取决于状态转移方程的依赖关系。在思考空间压缩前,不妨将状态转移矩阵画出来,方便思考如何进行空间压缩,以及压缩哪个维度更省空间。 + +::: + +## [416. Partition Equal Subset Sum](https://leetcode.com/problems/partition-equal-subset-sum/) + +### 題目描述 + +给定一个正整数数组,求是否可以把这个数组分成和相等的两部分。 + +### 輸入輸出範例 + +输入是一个一维正整数数组,输出时一个布尔值,表示是否可以满足题目要求。 + +``` +Input: [1,5,11,5] +Output: true +``` + +在这个样例中,满足条件的分割方法是 [1,5,5] 和 [11]。 + +### 題解 + +本题等价于 0-1 背包问题,设所有数字和为 sum,我们的目标是选取一部分物品,使得它们的总和为 sum/2。这道题不需要考虑价值,因此我们只需要通过一个布尔值矩阵来表示状态转移矩阵。注意边界条件的处理。 + + + + +```cpp +bool canPartition(vector &nums) { + int nums_sum = accumulate(nums.begin(), nums.end(), 0); + if (nums_sum % 2 != 0) { + return false; + } + int target = nums_sum / 2, n = nums.size(); + vector> dp(n + 1, vector(target + 1, false)); + dp[0][0] = true; + for (int i = 1; i <= n; ++i) { + for (int j = 0; j <= target; ++j) { + if (j < nums[i - 1]) { + dp[i][j] = dp[i - 1][j]; + } else { + dp[i][j] = dp[i - 1][j] || dp[i - 1][j - nums[i - 1]]; + } + } + } + return dp[n][target]; +} +``` + + + + +```py +def canPartition(nums: List[int]) -> bool: + nums_sum = sum(nums) + if nums_sum % 2 != 0: + return False + target, n = nums_sum // 2, len(nums) + dp = [[False for _ in range(target + 1)] for _ in range(n + 1)] + dp[0][0] = True + for i in range(1, n + 1): + for j in range(target + 1): + if j < nums[i - 1]: + dp[i][j] = dp[i - 1][j] + else: + dp[i][j] = dp[i - 1][j] or dp[i - 1][j - nums[i - 1]] + return dp[n][target] +``` + + + + + +同样的,我们也可以对本题进行空间压缩。注意对数字和的遍历需要逆向。 + + + + +```cpp +bool canPartition(vector &nums) { + int nums_sum = accumulate(nums.begin(), nums.end(), 0); + if (nums_sum % 2 != 0) { + return false; + } + int target = nums_sum / 2, n = nums.size(); + vector dp(target + 1, false); + dp[0] = true; + for (int i = 1; i <= n; ++i) { + for (int j = target; j >= nums[i - 1]; --j) { + dp[j] = dp[j] || dp[j - nums[i - 1]]; + } + } + return dp[target]; +} +``` + + + + +```py +def canPartition(nums: List[int]) -> bool: + nums_sum = sum(nums) + if nums_sum % 2 != 0: + return False + target, n = nums_sum // 2, len(nums) + dp = [True] + [False] * target + for i in range(1, n + 1): + for j in range(target, nums[i - 1] - 1, -1): + dp[j] = dp[j] or dp[j - nums[i - 1]] + return dp[target] +``` + + + + + +## [474. Ones and Zeroes](https://leetcode.com/problems/ones-and-zeroes/) + +### 題目描述 + +给定 $m$ 个数字 0 和 $n$ 个数字 1,以及一些由 0-1 构成的字符串,求利用这些数字最多可以构成多少个给定的字符串,字符串只可以构成一次。 + +### 輸入輸出範例 + +输入两个整数 $m$ 和 $n$,表示 0 和 1 的数量,以及一个一维字符串数组,表示待构成的字符串; +输出是一个整数,表示最多可以生成的字符串个数。 + +``` +Input: Array = {"10", "0001", "111001", "1", "0"}, m = 5, n = 3 +Output: 4 +``` + +在这个样例中,我们可以用 5 个 0 和 3 个 1 构成 [“10”, “0001”, “1”, “0”]。 + +### 題解 + +这是一个多维费用的 0-1 背包问题,有两个背包大小,0 的数量和 1 的数量。我们在这里直接展示三维空间压缩到二维后的写法。 + + + + +```cpp +int findMaxForm(vector& strs, int m, int n) { + vector> dp(m + 1, vector(n + 1, 0)); + for (const string& s : strs) { + int zeros = 0, ones = 0; + for (char c : s) { + if (c == ’0’) { + ++zeros; + } else { + ++ones; + } + } + for (int i = m; i >= zeros; --i) { + for (int j = n; j >= ones; --j) { + dp[i][j] = max(dp[i][j], dp[i - zeros][j - ones] + 1); + } + } + } + return dp[m][n]; +} +``` + + + + +```py +def findMaxForm(strs: List[str], m: int, n: int) -> int: + dp = [[0 for _ in range(n + 1)] for _ in range(m + 1)] + for s in strs: + zeros = len(list(filter(lambda c: c == "0", s))) + ones = len(s) - zeros + for i in range(m, zeros - 1, -1): + for j in range(n, ones - 1, -1): + dp[i][j] = max(dp[i][j], dp[i - zeros][j - ones] + 1) + return dp[m][n] +``` + + + + + +## [322. Coin Change](https://leetcode.com/problems/coin-change/) + +### 題目描述 + +给定一些硬币的面额,求最少可以用多少颗硬币组成给定的金额。 + +### 輸入輸出範例 + +输入一个一维整数数组,表示硬币的面额;以及一个整数,表示给定的金额。输出一个整数,表示满足条件的最少的硬币数量。若不存在解,则返回-1。 + +``` +Input: coins = [1, 2, 5], amount = 11 +Output: 3 +``` + +在这个样例中,最少的组合方法是 11 = 5 + 5 + 1。 + +### 題解 + +因为每个硬币可以用无限多次,这道题本质上是完全背包。我们直接展示二维空间压缩为一维的写法。 + +这里注意,我们把 dp 数组初始化为 amount + 1 而不是-1 的原因是,在动态规划过程中有求最小值的操作,如果初始化成-1 则会导致结果始终为-1。至于为什么取这个值,是因为 i 最大可以取 amount,而最多的组成方式是只用 1 元硬币,因此 amount + 1 一定大于所有可能的组合方式,取最小值时一定不会是它。在动态规划完成后,若结果仍然是此值,则说明不存在满足条件的组合方法,返回-1。 + + + + +```cpp +int coinChange(vector& coins, int amount) { + vector dp(amount + 1, amount + 1); + dp[0] = 0; + for (int i = 1; i <= amount; ++i) { + for (int coin : coins) { + if (i >= coin) { + dp[i] = min(dp[i], dp[i - coin] + 1); + } + } + } + return dp[amount] != amount + 1 ? dp[amount] : -1; +} +``` + + + + +```py +def coinChange(coins: List[int], amount: int) -> int: + dp = [0] + [amount + 1] * amount + for i in range(1, amount + 1): + for coin in coins: + if i >= coin: + dp[i] = min(dp[i], dp[i - coin] + 1) + return dp[amount] if dp[amount] != amount + 1 else -1 +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-7-string-editing.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-7-string-editing.mdx new file mode 100644 index 00000000..bbc7ffc7 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-7-string-editing.mdx @@ -0,0 +1,132 @@ +--- +sidebar_position: 32 +--- + +# 6.7 字符串编辑 + +## [72. Edit Distance](https://leetcode.com/problems/edit-distance/) + +### 題目描述 + +给定两个字符串,已知你可以删除、替换和插入任意字符串的任意字符,求最少编辑几步可以将两个字符串变成相同。 + +### 輸入輸出範例 + +输入是两个字符串,输出是一个整数,表示最少的步骤。 + +``` +Input: word1 = "horse", word2 = "ros" +Output: 3 +``` + +在这个样例中,一种最优编辑方法是 horse -> rorse -> rose -> ros。 + +### 題解 + +类似于题目 1143,我们使用一个二维数组 dp[i][j],表示将第一个字符串到位置 i 为止,和第二个字符串到位置 j 为止,最多需要几步编辑。当第 i 位和第 j 位对应的字符相同时,dp[i][j] 等于 dp[i-1][j-1];当二者对应的字符不同时,修改的消耗是 dp[i-1][j-1]+1,插入 i 位置/删除 j 位置的消耗是 dp[i][j-1] + 1,插入 j 位置/删除 i 位置的消耗是 dp[i-1][j] + 1。 + + + + +```cpp +int minDistance(string word1, string word2) { + int m = word1.length(), n = word2.length(); + vector> dp(m + 1, vector(n + 1, 0)); + for (int i = 0; i <= m; ++i) { + for (int j = 0; j <= n; ++j) { + if (i == 0 || j == 0) { + dp[i][j] = i + j; + } else { + dp[i][j] = dp[i - 1][j - 1] + (word1[i - 1] != word2[j - 1]); + dp[i][j] = min(dp[i][j], dp[i - 1][j] + 1); + dp[i][j] = min(dp[i][j], dp[i][j - 1] + 1); + } + } + } + return dp[m][n]; +} +``` + + + + +```py +def minDistance(word1: str, word2: str) -> int: + m, n = len(word1), len(word2) + dp = [[0 for _ in range(n + 1)] for _ in range(m + 1)] + for i in range(m + 1): + for j in range(n + 1): + if i == 0 or j == 0: + dp[i][j] = i + j + else: + dp[i][j] = min( + dp[i - 1][j - 1] + int(word1[i - 1] != word2[j - 1]), + dp[i][j - 1] + 1, + dp[i - 1][j] + 1, + ) + return dp[m][n] +``` + + + + + +## [650. 2 Keys Keyboard](https://leetcode.com/problems/2-keys-keyboard/) + +### 題目描述 + +给定一个字母 A,已知你可以每次选择复制全部字符,或者粘贴之前复制的字符,求最少需要几次操作可以把字符串延展到指定长度。 + +### 輸入輸出範例 + +输入是一个正整数,代表指定长度;输出是一个整数,表示最少操作次数。 + +``` +Input: 3 +Output: 3 +``` + +在这个样例中,一种最优的操作方法是先复制一次,再粘贴两次。 + +### 題解 + +不同于以往通过加减实现的动态规划,这里需要乘除法来计算位置,因为粘贴操作是倍数增加的。我们使用一个一维数组 dp,其中位置 i 表示延展到长度 i 的最少操作次数。对于每个位置 j,如果 j 可以被 i 整除,那么长度 i 就可以由长度 j 操作得到,其操作次数等价于把一个长度为 j 的 A 延展到长度为 i/j。因此我们可以得到递推公式 dp[i] = dp[j] + dp[i/j]。 + + + + +```cpp +int minSteps(int n) { + vector dp(n + 1, 0); + for (int i = 2; i <= n; ++i) { + dp[i] = i; + for (int j = 2; j * j <= i; ++j) { + if (i % j == 0) { + dp[i] = dp[j] + dp[i / j]; + // 提前剪枝,因为j从小到大,因此操作数量一定最小。 + break; + } + } + } + return dp[n]; +} +``` + + + + +```py +def minSteps(n: int) -> int: + dp = [0] * 2 + list(range(2, n + 1)) + for i in range(2, n + 1): + for j in range(2, floor(sqrt(i)) + 1): + if i % j == 0: + dp[i] = dp[j] + dp[i // j] + # 提前剪枝,因为j从小到大,因此操作数量一定最小。 + break + return dp[n] +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-8-stock-trading.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-8-stock-trading.mdx new file mode 100644 index 00000000..691fd7e3 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-8-stock-trading.mdx @@ -0,0 +1,183 @@ +--- +sidebar_position: 33 +--- + +# 6.8 股票交易 + +`股票交易`类问题通常可以用动态规划来解决。对于稍微复杂一些的股票交易类问题,比如需要冷却时间或者交易费用,则可以用通过动态规划实现的`状态机`来解决。 + +## [121. Best Time to Buy and Sell Stock](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/) + +### 題目描述 + +给定一段时间内每天某只股票的固定价格,已知你只可以买卖各一次,求最大的收益。 + +### 輸入輸出範例 + +输入一个一维整数数组,表示每天的股票价格;输出一个整数,表示最大的收益。 + +``` +Input: [7,1,5,3,6,4] +Output: 5 +``` + +在这个样例中,最大的利润为在第二天价格为 1 时买入,在第五天价格为 6 时卖出。 + +### 題解 + +我们可以遍历一遍数组,在每一个位置 i 时,记录 i 位置之前所有价格中的最低价格,然后将当前的价格作为售出价格,查看当前收益是不是最大收益即可。注意本题中以及之后题目中的buy 和 sell 表示买卖操作时,用户账户的收益。因此买时为负,卖时为正。 + + + + +```cpp +int maxProfit(vector& prices) { + int buy = numeric_limits::lowest(), sell = 0; + for (int price : prices) { + buy = max(buy, -price); + sell = max(sell, buy + price); + } + return sell; +} +``` + + + + +```py +def maxProfit(prices: List[int]) -> int: + buy, sell = -sys.maxsize, 0 + for price in prices: + buy = max(buy, -price) + sell = max(sell, buy + price) + return sell +``` + + + + + +## [188. Best Time to Buy and Sell Stock IV](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/) + +### 題目描述 + +给定一段时间内每天某只股票的固定价格,已知你只可以买卖各 $k$ 次,且每次只能拥有一支股票,求最大的收益。 + +### 輸入輸出範例 + +输入一个一维整数数组,表示每天的股票价格;以及一个整数,表示可以买卖的次数 $k$。输出一个整数,表示最大的收益。 + +``` +Input: [3,2,6,5,0,3], k = 2 +Output: 7 +``` + +在这个样例中,最大的利润为在第二天价格为 2 时买入,在第三天价格为 6 时卖出;再在第五天价格为 0 时买入,在第六天价格为 3 时卖出。 + +### 題解 + +类似地,我们可以建立两个动态规划数组 buy 和 sell,对于每天的股票价格,buy[j] 表示在第 j 次买入时的最大收益,sell[j] 表示在第 j 次卖出时的最大收益。 + + + + + +```cpp +int maxProfit(int k, vector& prices) { + int days = prices.size(); + vector buy(k + 1, numeric_limits::lowest()), sell(k + 1, 0); + for (int i = 0; i < days; ++i) { + for (int j = 1; j <= k; ++j) { + buy[j] = max(buy[j], sell[j - 1] - prices[i]); + sell[j] = max(sell[j], buy[j] + prices[i]); + } + } + return sell[k]; +} +``` + + + + +```py +def maxProfit(k: int, prices: List[int]) -> int: + days = len(prices) + buy, sell = [-sys.maxsize] * (k + 1), [0] * (k + 1) + for i in range(days): + for j in range(1, k + 1): + buy[j] = max(buy[j], sell[j - 1] - prices[i]) + sell[j] = max(sell[j], buy[j] + prices[i]) + return sell[k] +``` + + + + + +## [309. Best Time to Buy and Sell Stock with Cooldown](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/) + +### 題目描述 + +给定一段时间内每天某只股票的固定价格,已知每次卖出之后必须冷却一天,且每次只能拥有一支股票,求最大的收益。 + +### 輸入輸出範例 + +输入一个一维整数数组,表示每天的股票价格;输出一个整数,表示最大的收益。 + +``` +Input: [1,2,3,0,2] +Output: 3 +``` + +在这个样例中,最大的利润获取操作是买入、卖出、冷却、买入、卖出。 + +### 題解 + +我们可以使用状态机来解决这类复杂的状态转移问题,通过建立多个状态以及它们的转移方式,我们可以很容易地推导出各个状态的转移方程。如图所示,我们可以建立四个状态来表示带有冷却的股票交易,以及它们的之间的转移方式。 + +
        + + ![](6.5.png) + +
        图 6.5: 题目 309 - 状态机状态转移
        +
        + + + + +```cpp +int maxProfit(vector& prices) { + int n = prices.size(); + vector buy(n), sell(n), s1(n), s2(n); + s1[0] = buy[0] = -prices[0]; + sell[0] = s2[0] = 0; + for (int i = 1; i < n; ++i) { + buy[i] = s2[i - 1] - prices[i]; + s1[i] = max(buy[i - 1], s1[i - 1]); + sell[i] = max(buy[i - 1], s1[i - 1]) + prices[i]; + s2[i] = max(s2[i - 1], sell[i - 1]); + } + return max(sell[n - 1], s2[n - 1]); +} +``` + + + + +```py +def maxProfit(prices: List[int]) -> int: + n = len(prices) + buy, sell, s1, s2 = [0] * n, [0] * n, [0] * n, [0] * n + s1[0] = buy[0] = -prices[0] + sell[0] = s2[0] = 0 + for i in range(1, n): + buy[i] = s2[i - 1] - prices[i] + s1[i] = max(buy[i - 1], s1[i - 1]) + sell[i] = max(buy[i - 1], s1[i - 1]) + prices[i] + s2[i] = max(s2[i - 1], sell[i - 1]) + return max(sell[n - 1], s2[n - 1]) +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-9-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-9-exercises.md new file mode 100644 index 00000000..97958de4 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-9-exercises.md @@ -0,0 +1,45 @@ +--- +sidebar_position: 34 +--- + +# 6.9 練習 + +## 基礎難度 + +### [213. House Robber II](https://leetcode.com/problems/house-robber-ii/) + +强盗抢劫题目的 follow-up,如何处理环形数组呢? + +### [53. Maximum Subarray](https://leetcode.com/problems/maximum-subarray/) + +经典的一维动态规划题目,试着把一维空间优化为常量吧。 + +### [343. Integer Break](https://leetcode.com/problems/integer-break/) + +分割类型题,先尝试用动态规划求解,再思考是否有更简单的解法。 + +### [583. Delete Operation for Two Strings](https://leetcode.com/problems/delete-operation-for-two-strings/) + +最长公共子序列的变种题。 + +## 進階難度 + +### [646. Maximum Length of Pair Chain](https://leetcode.com/problems/maximum-length-of-pair-chain/) + +最长递增子序列的变种题,同样的,尝试用二分进行加速。 + +### [10. Regular Expression Matching](https://leetcode.com/problems/regular-expression-matching/) + +正则表达式匹配,非常考验耐心。需要根据正则表达式的不同情况,即字符、星号,点号等,分情况讨论。 + +### [376. Wiggle Subsequence](https://leetcode.com/problems/wiggle-subsequence/) + +最长摆动子序列,通项公式比较特殊,需要仔细思考。 + +### [494. Target Sum](https://leetcode.com/problems/target-sum/) + +如果告诉你这道题是 0-1 背包,你是否会有一些思路? + +### [714. Best Time to Buy and Sell Stock with Transaction Fee](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/) + +建立状态机,股票交易类问题就会迎刃而解。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6.1.png b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6.1.png new file mode 100644 index 0000000000000000000000000000000000000000..6b075633b568d5d942aa5c48465c6d9405570cd8 GIT binary patch literal 34632 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 b`8TOCn|H(_jP^6`fPb*(ROPc}jlBK?n+e1I literal 0 HcmV?d00001 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6.3.png b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6.3.png new file mode 100644 index 0000000000000000000000000000000000000000..4ff0572c706140bae1f5106077d11faa558e1657 GIT binary patch literal 24349 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 IqZWSu1}%@5q5uE@ literal 0 HcmV?d00001 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6.4.png b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6.4.png new file mode 100644 index 0000000000000000000000000000000000000000..4acc447e937b7a5c5a0b1776104bb02828a9db0e GIT binary patch literal 38325 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 literal 0 HcmV?d00001 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6.5.png b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6.5.png new file mode 100644 index 0000000000000000000000000000000000000000..97774d350a26134d09ee8c80275c1678f4c363b8 GIT binary patch literal 49000 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 k$,那么 $T(n) =O( f (n))$ + +::: + +通过主定理我们可以知道,归并排序属于第二种情况,且时间复杂度为 $O(n \log n)$。其他的分治问题也可以通过主定理求得时间复杂度。 + +另外,自上而下的分治可以和 memoization 结合,避免重复遍历相同的子问题。如果方便推导,也可以换用自下而上的动态规划方法求解。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-2-expression-problems.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-2-expression-problems.mdx new file mode 100644 index 00000000..b4cbcabf --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-2-expression-problems.mdx @@ -0,0 +1,154 @@ +--- +sidebar_position: 36 +--- + +# 7.2 表达式问题 + +## [241. Different Ways to Add Parentheses](https://leetcode.com/problems/different-ways-to-add-parentheses/) + +### 題目描述 + +给定一个只包含加、减和乘法的数学表达式,求通过加括号可以得到多少种不同的结果。 + +### 輸入輸出範例 + +输入是一个字符串,表示数学表达式;输出是一个数组,存储所有不同的加括号结果。 + +``` +Input: "2-1-1" +Output: [0, 2] +``` + +在这个样例中,有两种加括号结果:((2-1)-1) = 0 和 (2-(1-1)) = 2。 + +### 題解 + +利用分治思想,我们可以把加括号转化为,对于每个运算符号,先执行处理两侧的数学表达式,再处理此运算符号。注意边界情况,即字符串内无运算符号,只有数字。 + + + + +```cpp +vector diffWaysToCompute(string expression) { + vector ways; + unordered_map> op_funcs; + op_funcs[’+’] = [](int x, int y) { return x + y; }; + op_funcs[’-’] = [](int x, int y) { return x - y; }; + op_funcs[’*’] = [](int x, int y) { return x * y; }; + for (int i = 0; i < expression.length(); ++i) { + char c = expression[i]; + if (!op_funcs.contains(c)) { + continue; + } + auto left = diffWaysToCompute(expression.substr(0, i)); + auto right = diffWaysToCompute(expression.substr(i + 1)); + for (int l : left) { + for (int r : right) { + ways.push_back(op_funcs[c](l, r)); + } + } + } + return ways.empty() ? vector{stoi(expression)} : ways; +} +``` + + + + +```py +def diffWaysToCompute(expression: str) -> List[int]: + ways = [] + op_funcs = { + "+": (lambda x, y: x + y), + "-": (lambda x, y: x - y), + "*": (lambda x, y: x * y), + } + for i, c in enumerate(expression): + if c not in op_funcs: + continue + left = diffWaysToCompute(expression[:i]) + right = diffWaysToCompute(expression[i + 1 :]) + ways += [op_funcs[c](l, r) for l in left for r in right] + return [int(expression)] if len(ways) == 0 else ways +``` + + + + + +我们发现,某些被 divide 的子字符串可能重复出现多次,因此我们可以用 memoization 来去重。比如建立一个哈希表,key 是 (l, r),value 是 ways。每次遇到相同的 (l, r),我们可以直接返回已经计算过的 ways。或者与其我们从上到下用分治处理 +memoization,不如直接从下到上用动态规划处理。 + + + + +```cpp +vector diffWaysToCompute(string expression) { + // 利用istringstream, 将数字和操作符进行分词。 + vector nums; + vector ops; + int num = 0; + char op = ’ ’; + istringstream ss(expression); + while (ss >> num) { + nums.push_back(num); + if (ss >> op) { + ops.push_back(op); + } + } + int n = nums.size(); + vector>> dp(n, vector>(n, vector())); + unordered_map> op_funcs; + op_funcs[’+’] = [](int a, int b) { return a + b; }; + op_funcs[’-’] = [](int a, int b) { return a - b; }; + op_funcs[’*’] = [](int a, int b) { return a * b; }; + for (int i = 0; i < n; ++i) { + for (int j = i; j >= 0; --j) { + if (i == j) { + dp[j][i].push_back(nums[i]); + continue; + } + for (int k = j; k < i; ++k) { + for (auto l : dp[j][k]) { + for (auto r : dp[k + 1][i]) { + dp[j][i].push_back(op_funcs[ops[k]](l, r)); + } + } + } + } + } + return dp[0][n - 1]; +} +``` + + + + +```py +def diffWaysToCompute(expression: str) -> List[int]: + # re.split可以将操作符(\D)和数字直接分开。 + sections = re.split(r"(\D)", expression) + nums = [int(num) for num in sections if num.isdigit()] + ops = [op for op in sections if not op.isdigit()] + n = len(nums) + dp = [[[] for _ in range(n)] for _ in range(n)] + op_funcs = { + "+": (lambda x, y: x + y), + "-": (lambda x, y: x - y), + "*": (lambda x, y: x * y), + } + for i in range(n): + for j in range(i, -1, -1): + if i == j: + dp[j][i].append(nums[i]) + continue + for k in range(j, i): + dp[j][i] += [op_funcs[ops[k]](l, r) + for l in dp[j][k] for r in dp[k + 1][i]] + + return dp[0][n - 1] + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-3-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-3-exercises.md new file mode 100644 index 00000000..2ea02c9f --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-3-exercises.md @@ -0,0 +1,17 @@ +--- +sidebar_position: 37 +--- + +# 7.3 練習 + +## 基礎難度 + +### [932. Beautiful Array](https://leetcode.com/problems/beautiful-array/) + +试着用从上到下的分治(递归)写法求解,最好加上 memoization;再用从下到上的动态规划写法求解。 + +## 進階難度 + +### [312. Burst Balloons](https://leetcode.com/problems/burst-balloons/) + +试着用从上到下的分治(递归)写法求解,最好加上 memoization;再用从下到上的动态规划写法求解。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/_category_.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/_category_.json new file mode 100644 index 00000000..2535d2d4 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "7. 化繁为简的分治法", + "position": 7, + "link": { + "type": "generated-index", + "description": "第 7 章 化繁为简的分治法" + } +} diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-1-introduction.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-1-introduction.md new file mode 100644 index 00000000..d753971e --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-1-introduction.md @@ -0,0 +1,7 @@ +--- +sidebar_position: 38 +--- + +# 8.1 引言 + +对于 LeetCode 上数量不少的数学题,我们尽量将其按照类型划分讲解。然而很多数学题的解法并不通用,我们也很难一口气把所有的套路讲清楚,因此我们只选择了几道经典或是典型的题目,供大家参考。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-2-lcm-gcd.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-2-lcm-gcd.mdx new file mode 100644 index 00000000..58dda1b8 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-2-lcm-gcd.mdx @@ -0,0 +1,72 @@ +--- +sidebar_position: 39 +--- + +# 8.2 公倍数与公因数 + +利用`辗转相除法`,我们可以很方便地求得两个数的最大公因数(greatest common divisor,GCD);将两个数相乘再除以最大公因数即可得到最小公倍数(least common multiple, LCM)。 + + + + + +```cpp +int gcd(int a, int b) { + return b == 0 ? a : gcd(b, a % b); +} + +int lcm(int a, int b) { + return a * b / gcd(a, b); +} +``` + + + + +```py +def gcd(a: int, b: int) -> int: + return a if b == 0 else gcd(b, a % b) + +def lcm(a: int, b: int) -> int: + return (a * b) // gcd(a, b) +``` + + + + + +进一步地,我们也可以通过扩展欧几里得算法(extended gcd)在求得 a 和 b 最大公因数的同时,也得到它们的系数 x 和 y,从而使 ax + by = gcd(a, b)。因为 Python 中 int 只能按值传递,我们可以用一个长度固定为 1 的 list() 来进行传递引用的操作。 + + + + +```cpp +int xGCD(int a, int b, int &x, int &y) { + if (b == 0) { + x = 1, y = 0; + return a; + } + int x_inner, y_inner; + int gcd = xGCD(b, a % b, x_inner, y_inner); + x = y_inner, y = x_inner - (a / b) * y_inner; + return gcd; +} +``` + + + + +```py +def xGCD(a: int, b: int, x: List[int], y: List[int]) -> int: + if b == 0: + x[0], y[0] = 1, 0 + return a + x_inner, y_inner = [0], [0] + gcd = xGCD(b, a % b, x_inner, y_inner) + x[0], y[0] = y_inner, x_inner - (a / b) * y_inner + return gcd +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-3-prime-numbers.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-3-prime-numbers.mdx new file mode 100644 index 00000000..9bee3e63 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-3-prime-numbers.mdx @@ -0,0 +1,138 @@ +--- +sidebar_position: 40 +--- + +# 8.3 质数 + +质数又称素数,指的是指在大于 1 的自然数中,除了 1 和它本身以外不再有其他因数的自然数。值得注意的是,每一个数都可以分解成质数的乘积。 + + +## [204. Count Primes](https://leetcode.com/problems/count-primes/) + +### 題目描述 + +给定一个数字 n,求小于 n 的质数的个数。 + +### 輸入輸出範例 + +输入一个整数,输出也是一个整数,表示小于输入数的质数的个数。 + +``` +Input: 10 +Output: 4 +``` + +在这个样例中,小于 10 的质数只有 [2,3,5,7]。 + +### 題解 + +`埃拉托斯特尼筛法`(Sieve of Eratosthenes,简称埃氏筛法)是非常常用的,判断一个整数是否是质数的方法。并且它可以在判断一个整数 n 时,同时判断所小于 n 的整数,因此非常适合这道题。其原理也十分易懂:从 1 到 n 遍历,假设当前遍历到 m,则把所有小于 n 的、且是 m 的倍数的整数标为和数;遍历完成后,没有被标为和数的数字即为质数。 + + + + +```cpp +int countPrimes(int n) { + if (n <= 2) { + return 0; + } + vector primes(n, true); + int count = n - 2; // 去掉不是质数的1 + for (int i = 2; i < n; ++i) { + if (primes[i]) { + for (int j = 2 * i; j < n; j += i) { + if (primes[j]) { + primes[j] = false; + --count; + } + } + } + } + return count; +} +``` + + + + +```py +def countPrimes(n: int) -> int: + if n <= 2: + return 0 + primes = [True for _ in range(n)] + count = n - 2 # 去掉不是质数的1 + for i in range(2, n): + if primes[i]: + for j in range(2 * i, n, i): + if primes[j]: + primes[j] = False + count -= 1 + return count +``` + + + + + +利用质数的一些性质,我们可以进一步优化该算法。 + + + + + +```cpp +int countPrimes(int n) { + if (n <= 2) { + return 0; + } + vector primes(n, true); + int sqrtn = sqrt(n); + int count = n / 2; // 偶数一定不是质数 + int i = 3; + // 最小质因子一定小于等于开方数。 + while (i <= sqrtn) { + // 向右找倍数,注意避免偶数和重复遍历。 + for (int j = i * i; j < n; j += 2 * i) { + if (primes[j]) { + --count; + primes[j] = false; + } + } + i += 2; + // 向右前进查找位置,注意避免偶数和重复遍历。 + while (i <= sqrtn && !primes[i]) { + i += 2; + } + } + return count; +} +``` + + + + +```py +def countPrimes(n: int) -> int: + if n <= 2: + return 0 + primes = [True for _ in range(n)] + sqrtn = sqrt(n) + count = n // 2 # 偶数一定不是质数 + i = 3 + # 最小质因子一定小于等于开方数。 + while i <= sqrtn: + # 向右找倍数,注意避免偶数和重复遍历。 + for j in range(i * i, n, 2 * i): + if primes[j]: + count -= 1 + primes[j] = False + i += 2 + # 向右前进查找位置,注意避免偶数和重复遍历。 + while i <= sqrtn and not primes[i]: + i += 2 + return count +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-4-number-processing.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-4-number-processing.mdx new file mode 100644 index 00000000..4537f107 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-4-number-processing.mdx @@ -0,0 +1,318 @@ +--- +sidebar_position: 41 +--- + +# 8.4 数字处理 + +## [504. Base 7](https://leetcode.com/problems/base-7/) + +### 題目描述 + +给定一个十进制整数,求它在七进制下的表示。 + +### 輸入輸出範例 + +输入一个整数,输出一个字符串,表示其七进制。 + +``` +Input: 100 +Output: "202" +``` + +在这个样例中,100 的七进制表示法来源于 101 = 2 * 49 + 0 * 7 + 2 * 1。 + +### 題解 + +`进制转换`类型的题,通常是利用除法和取模(mod)来进行计算,同时也要注意一些细节,如负数和零。如果输出是数字类型而非字符串,则也需要考虑是否会超出整数上下界。 + + + + +```cpp +string convertToBase7(int num) { + if (num == 0) { + return "0"; + } + string base7; + bool is_negative = num < 0; + num = abs(num); + while (num) { + int quotient = num / 7, remainder = num % 7; + base7 = to_string(remainder) + base7; + num = quotient; + } + return is_negative ? "-" + base7 : base7; +} +``` + + + + +```py +def convertToBase7(num: int) -> str: + if num == 0: + return "0" + base7 = "" + is_negative = num < 0 + num = abs(num) + while num: + quotient, remainder = num // 7, num % 7 + base7 = str(remainder) + base7 + num = quotient + return "-" + base7 if is_negative else base7 +``` + + + + + +## [172. Factorial Trailing Zeroes](https://leetcode.com/problems/factorial-trailing-zeroes/) + +### 題目描述 + +给定一个非负整数,判断它的阶乘结果的结尾有几个 0。 + +### 輸入輸出範例 + +输入一个非负整数,输出一个非负整数,表示输入的阶乘结果的结尾有几个 0。 + +``` +Input: 12 +Output: 2 +``` + +在这个样例中,12 != 479001600 的结尾有两个 0。 + +### 題解 + +每个尾部的 0 由 2 × 5 =10 而来,因此我们可以把阶乘的每一个元素拆成质数相乘,统计有多少个 2 和 5。明显的,质因子 2 的数量远多于质因子 5 的数量,因此我们可以只统计阶乘结果里有多少个质因子 5。 + + + + +```cpp +int trailingZeroes(int n) { + return n == 0 ? 0 : n / 5 + trailingZeroes(n / 5); +} +``` + + + + +```py +def trailingZeroes(n: int) -> int: + return 0 if n == 0 else n // 5 + trailingZeroes(n // 5) +``` + + + + + +## [415. Add Strings](https://leetcode.com/problems/add-strings/) + +### 題目描述 + +给定两个由数字组成的字符串,求它们相加的结果。 + +### 輸入輸出範例 + +输入是两个字符串,输出是一个整数,表示输入的数字和。 + +``` +Input: num1 = "99", num2 = "1" +Output: 100 +``` + +因为相加运算是从后往前进行的,所以可以先翻转字符串,再逐位计算。这种类型的题考察的是细节,如进位、位数差等等。 + +### 題解 + + + + + + +```cpp +string addStrings(string num1, string num2) { + string added_str; + reverse(num1.begin(), num1.end()); + reverse(num2.begin(), num2.end()); + int len1 = num1.length(), len2 = num2.length(); + if (len1 <= len2) { + swap(num1, num2); + swap(len1, len2); + } + int add_bit = 0; + for (int i = 0; i < len1; ++i) { + int cur_sum = + (num1[i] - ’0’) + (i < len2 ? num2[i] - ’0’ : 0) + add_bit; + added_str += to_string(cur_sum % 10); + add_bit = cur_sum >= 10; + } + if (add_bit) { + added_str += "1"; + } + reverse(added_str.begin(), added_str.end()); + return added_str; +} +``` + + + + +```py +def addStrings(num1: str, num2: str) -> str: + added_str = "" + num1 = num1[::-1] + num2 = num2[::-1] + len1, len2 = len(num1), len(num2) + if len1 <= len2: + num1, num2 = num2, num1 + len1, len2 = len2, len1 + add_bit = 0 + for i in range(len1): + cur_sum = int(num1[i]) + (int(num2[i]) if i < len2 else 0) + add_bit + added_str += str(cur_sum % 10) + add_bit = int(cur_sum >= 10) + if add_bit: + added_str += "1" + return added_str[::-1] +``` + + + + + + +## [326. Power of Three](https://leetcode.com/problems/power-of-three/) + +### 題目描述 + +判断一个数字是否是 3 的次方。 + +### 輸入輸出範例 + +输入一个整数,输出一个布尔值。 + +``` +Input: n = 27 +Output: true +``` + +### 題解 + +有两种方法,一种是利用对数。设 log3 n =m,如果 n 是 3 的整数次方,那么 m 一定是整数。 + + + + +```cpp +bool isPowerOfThree(int n) { + return fmod(log10(n) / log10(3), 1) == 0; +} +``` + + + + +```py +def isPowerOfThree(n: int) -> bool: + return n > 0 and math.fmod(math.log10(n) / math.log10(3), 1) == 0 +``` + + + + + +另一种方法是,因为在 C++ int 范围内 3 的最大次方是 $3^{19} = 1162261467$,如果 n 是 3 的整数次方,那么 1162261467 除以 n 的余数一定是零;反之亦然。然而对于 Python 来说,因为 int 理论上可以取无穷大,我们只能循环判断。 + + + + +```cpp +bool isPowerOfThree(int n) { + return n > 0 && 1162261467 % n == 0; +} +``` + + + + +```py +def isPowerOfThree(n: int) -> bool: + if n <= 0: + return False + while n % 3 == 0: + n //= 3 + return n == 1 +``` + + + + + +## [50. Pow(x, n)](https://leetcode.com/problems/powx-n/) + +### 題目描述 + +计算 x 的 n 次方。 + +### 輸入輸出範例 + +输入一个浮点数表示 x 和一个整数表示 n,输出一个浮点数表示次方结果。 + +``` +Input: x = 2.00000, n = 10 +Output: 1024.00000 +``` + +### 題解 + + +利用递归,我们可以较为轻松地解决本题。注意边界条件的处理。 + + + + +```cpp +double myPow(double x, int n) { + if (n == 0) { + return 1; + } + if (x == 0) { + return 0; + } + if (n == numeric_limits::min()) { + return 1 / (x * myPow(x, numeric_limits::max())); + } + if (n < 0) { + return 1 / myPow(x, -n); + } + if (n % 2 != 0) { + return x * myPow(x, n - 1); + } + double myPowSqrt = myPow(x, n >> 1); + return myPowSqrt * myPowSqrt; +} +``` + + + + +```py +def myPow(x: float, n: int) -> float: + if n == 0: + return 1 + if x == 0: + return 0 + if n < 0: + return 1 / myPow(x, -n) + if n % 2 != 0: + return x * myPow(x, n - 1) + myPowSqrt = myPow(x, n >> 1) + return myPowSqrt * myPowSqrt +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-5-random-sampling.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-5-random-sampling.mdx new file mode 100644 index 00000000..59b76881 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-5-random-sampling.mdx @@ -0,0 +1,228 @@ +--- +sidebar_position: 42 +--- + +# 8.5 随机与取样 + +## [384. Shuffle an Array](https://leetcode.com/problems/shuffle-an-array/) + +### 題目描述 + +给定一个数组,要求实现两个指令函数。第一个函数“shuffle”可以随机打乱这个数组,第二个函数“reset”可以恢复原来的顺序。 + +### 輸入輸出範例 + +输入是一个存有整数数字的数组,和一个包含指令函数名称的数组。输出是一个二维数组,表示每个指令生成的数组。 + +``` +Input: nums = [1,2,3], actions: ["shuffle","shuffle","reset"] +Output: [[2,1,3],[3,2,1],[1,2,3]] +``` + +在这个样例中,前两次打乱的结果只要是随机生成即可。 + +### 題解 + +我们采用经典的 `Fisher-Yates 洗牌算法`,原理是通过随机交换位置来实现随机打乱,有正向和反向两种写法,且实现非常方便。注意这里“reset”函数以及 Solution 类的构造函数的实现细节。 + + + + +```cpp +class Solution { + public: + Solution(vector nums) : nums_(nums) {} + + vector reset() { return nums_; } + + vector shuffle() { + vector shuffled(nums_); + int n = nums_.size(); + // 可以使用反向或者正向洗牌,效果相同。 + // 反向洗牌: + for (int i = n - 1; i >= 0; --i) { + swap(shuffled[i], shuffled[rand() % (i + 1)]); + } + // 正向洗牌: + // for (int i = 0; i < n; ++i) { + // int pos = rand() % (n - i); + // swap(shuffled[i], shuffled[i+pos]); + // } + return shuffled; + } + + private: + vector nums_; +}; +``` + + + + +```py +class Solution: + def __init__(self, nums: List[int]): + self.base = nums[:] + + def reset(self) -> List[int]: + return self.base[:] + + def shuffle(self) -> List[int]: + shuffled = self.base[:] + n = len(self.base) + # 可以使用反向或者正向洗牌,效果相同。 + # 反向洗牌: + for i in range(n - 1, -1, -1): + j = random.randint(0, i) + shuffled[i], shuffled[j] = shuffled[j], shuffled[i] + # 正向洗牌: + # for i in range(n): + # j = i + random.randint(0, n - i - 1) + # shuffled[i], shuffled[j] = shuffled[j], shuffled[i] + return shuffled +``` + + + + + +## [528. Random Pick with Weight](https://leetcode.com/problems/random-pick-with-weight/) + +### 題目描述 + +给定一个数组,数组每个位置的值表示该位置的权重,要求按照权重的概率去随机采样。 + +### 輸入輸出範例 + +输入是一维正整数数组,表示权重;和一个包含指令字符串的一维数组,表示运行几次随机采样。输出是一维整数数组,表示随机采样的整数在数组中的位置。 + +``` +Input: weights = [1,3], actions: ["pickIndex","pickIndex","pickIndex"] +Output: [0,1,1] +``` + +在这个样例中,每次选择的位置都是不确定的,但选择第 0 个位置的期望为 1/4,选择第 1 个位置的期望为 3/4。 + +### 題解 + +我们可以先使用 partial_sum求前缀和(即到每个位置为止之前所有数字的和),这个结果对于正整数数组是单调递增的。每当需要采样时,我们可以先随机产生一个数字,然后使用二分法查找其在前缀和中的位置,以模拟加权采样的过程。这里的二分法可以用 lower_bound 实现。 + +以样例为例,权重数组 [1,3] 的前缀和为 [1,4]。如果我们随机生成的数字为 1,那么 lower_bound 返回的位置为 0;如果我们随机生成的数字是 2、3、4,那么 lower_bound 返回的位置为 1。 + +关于前缀和的更多技巧,我们将在接下来的章节中继续深入讲解。 + + + + +```cpp +class Solution { + public: + Solution(vector weights) : cumsum_(weights) { + partial_sum(cumsum_.begin(), cumsum_.end(), cumsum_.begin()); + } + + int pickIndex() { + int val = (rand() % cumsum_.back()) + 1; + return lower_bound(cumsum_.begin(), cumsum_.end(), val) - + cumsum_.begin(); + } + + private: + vector cumsum_; +}; +``` + + + + +```py +class Solution: + def __init__(self, weights: List[int]): + self.cumsum = weights[:] + for i in range(1, len(weights)): + self.cumsum[i] += self.cumsum[i - 1] + + def pickIndex(self) -> int: + val = random.randint(1, self.cumsum[-1]) + return bisect.bisect_left(self.cumsum, val, 0, len(self.cumsum)) +``` + + + + + +## [382. Linked List Random Node](https://leetcode.com/problems/linked-list-random-node/) + +### 題目描述 + +给定一个单向链表,要求设计一个算法,可以随机取得其中的一个数字。 + +### 輸入輸出範例 + +输入是一个单向链表,输出是一个数字,表示链表里其中一个节点的值。 + +``` +Input: 1->2->3->4->5 +Output: 3 +``` + +在这个样例中,我们有均等的概率得到任意一个节点,比如 3。 + +### 題解 + +不同于数组,在未遍历完链表前,我们无法知道链表的总长度。这里我们就可以使用水库采样:遍历一次链表,在遍历到第 m 个节点时,有 $\frac{1}{m}$ 的概率选择这个节点覆盖掉之前的节点选择。 + +我们提供一个简单的,对于水库算法随机性的证明。对于长度为 n 的链表的第 m 个节点,最后被采样的充要条件是它被选择,且之后的节点都没有被选择。这种情况发生的概率为 $\frac{1}{m} × \frac{m}{m+1} × \frac{m}{m+2} × · · · × \frac{n−1}{n} = \frac{1}{n}$。因此每个点都有均等的概率被选择。 + +当然,这道题我们也可以预处理链表,遍历一遍之后把它转化成数组。 + + + + +```cpp +class Solution { + public: + Solution(ListNode* node) : head_(node) {} + + int getRandom() { + int pick = head_->val; + ListNode* node = head_->next; + int i = 2; + while (node) { + if (rand() % i == 0) { + pick = node->val; + } + ++i; + node = node->next; + } + return pick; + } + + private: + ListNode* head_; +}; +``` + + + + +```py +class Solution: + def __init__(self, head: Optional[ListNode]): + self.head = head + + def getRandom(self) -> int: + pick = self.head.val + node = self.head.next + i = 2 + while node is not None: + if random.randint(0, i - 1) == 0: + pick = node.val + i += 1 + node = node.next + return pick +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-6-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-6-exercises.md new file mode 100644 index 00000000..0d8bef0e --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-6-exercises.md @@ -0,0 +1,37 @@ +--- +sidebar_position: 43 +--- + +# 8.6 練習 + +## 基礎難度 + +### [168. Excel Sheet Column Title](https://leetcode.com/problems/excel-sheet-column-title/) + +7 进制转换的变种题,需要注意的一点是从 1 开始而不是 0。 + +### [67. Add Binary](https://leetcode.com/problems/add-binary/) + +字符串加法的变种题。 + +### [238. Product of Array Except Self](https://leetcode.com/problems/product-of-array-except-self/) + +你可以不使用除法做这道题吗?我们很早之前讲过的题目 135 或许能给你一些思路。 + +## 進階難度 + +### [462. Minimum Moves to Equal Array Elements II](https://leetcode.com/problems/minimum-moves-to-equal-array-elements-ii/) + +这道题是笔者最喜欢的 LeetCode 题目之一,需要先推理出怎么样移动是最优的,再考虑如何进行移动。你或许需要一些前些章节讲过的算法。 + +### [169. Majority Element](https://leetcode.com/problems/majority-element/) + +如果想不出简单的解决方法,搜索一下 Boyer-Moore Majority Vote 算法吧。 + +### [470. Implement Rand10() Using Rand7()](https://leetcode.com/problems/implement-rand10-using-rand7/) + +如何用一个随机数生成器生成另一个随机数生成器?你可能需要利用原来的生成器多次。 + +### [202. Happy Number](https://leetcode.com/problems/happy-number/) + +你可以简单的用一个 while 循环解决这道题,但是有没有更好的解决办法?如果我们把每个数字想象成一个节点,是否可以转化为环路检测? \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/_category_.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/_category_.json new file mode 100644 index 00000000..5fb8df9e --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "8. 巧解数学问题 ", + "position": 8, + "link": { + "type": "generated-index", + "description": "第 8 章 巧解数学问题" + } +} diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-1-common-techniques.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-1-common-techniques.md new file mode 100644 index 00000000..30f955ca --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-1-common-techniques.md @@ -0,0 +1,24 @@ +--- +sidebar_position: 44 +--- + +# 9.1 常用技巧 + +`位运算`是算法题里比较特殊的一种类型,它们利用二进制位运算的特性进行一些奇妙的优化和计算。常用的位运算符号包括: + +- `∧`:按位异或 +- `&`:按位与 +- `|`:按位或 +- `~`:取反 +- `<<`:算术左移 +- `>>`:算术右移 + +以下是一些常见的位运算特性,其中 `0s` 和 `1s` 分别表示只由 `0` 或 `1` 构成的二进制数字。 + +``` +x ^ 0s = x x & 0s = 0 x | 0s = x +x ^ 1s = ~x x & 1s = x x | 1s = 1s +x ^ x = 0 x & x = x x | x = x +``` + +除此之外,n & (n - 1) 可以去除 n 的位级表示中最低的那一位,例如对于二进制表示 11110100,减去 1 得到 11110011,这两个数按位与得到 11110000。n & (-n) 可以得到 n 的位级表示中最低的那一位,例如对于二进制表示 11110100,取负得到 00001100,这两个数按位与得到 00000100。还有更多的并不常用的技巧,若读者感兴趣可以自行研究,这里不再赘述。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-2-basic-bitwise-problems.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-2-basic-bitwise-problems.mdx new file mode 100644 index 00000000..f17e521c --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-2-basic-bitwise-problems.mdx @@ -0,0 +1,181 @@ +--- +sidebar_position: 45 +--- + +# 9.2 位运算基础问题 + +## [461. Hamming Distance](https://leetcode.com/problems/hamming-distance/) + +### 題目描述 + +给定两个十进制数字,求它们二进制表示的汉明距离(Hamming distance,即不同位的个数)。 + +### 輸入輸出範例 + +输入是两个十进制整数,输出是一个十进制整数,表示两个输入数字的汉明距离。 + +``` +Input: x = 1, y = 4 +Output: 2 +``` + +在这个样例中,1 的二进制是 0001,4 的二进制是 0100,一共有两位不同。 + +### 題解 + +对两个数进行按位异或操作,统计有多少个 1 即可。 + + + + +```cpp +int hammingDistance(int x, int y) { + int diff = x ^ y, dist = 0; + while (diff != 0) { + dist += diff & 1; + diff >>= 1; + } + return dist; +} +``` + + + + +```py +def hammingDistance(x: int, y: int) -> int: + diff = x ^ y + dist = 0 + while diff != 0: + dist += diff & 1 + diff = diff >> 1 + return dist +``` + + + + + +## [190. Reverse Bits](https://leetcode.com/problems/reverse-bits/) + +### 題目描述 + +给定一个十进制正整数,输出它在二进制下的翻转结果。 + +### 輸入輸出範例 + +输入和输出都是十进制正整数。 + +``` +Input: 43261596 (00000010100101000001111010011100) +Output: 964176192 (00111001011110000010100101000000) +``` + +使用算术左移和右移,可以很轻易地实现二进制的翻转。 + +### 題解 + + + + + + +```cpp +uint32_t reverseBits(uint32_t n) { + uint32_t m = 0; + for (int i = 0; i < 32; ++i) { + m <<= 1; + m += n & 1; + n >>= 1; + } + return m; +} +``` + + + + +```py +def reverseBits(n: int) -> int: + m = 0 + for _ in range(32): + m = m << 1 + m += n & 1 + n = n >> 1 + return m +``` + + + + + +## [136. Single Number](https://leetcode.com/problems/single-number/) + +### 題目描述 + +给定一个整数数组,这个数组里只有一个数次出现了一次,其余数字出现了两次,求这个只出现一次的数字。 + +### 輸入輸出範例 + +输入是一个一维整数数组,输出是该数组内的一个整数。 + +``` +Input: [4,1,2,1,2] +Output: 4 +``` + +### 題解 + +我们可以利用 x ∧ x = 0 和 x ∧ 0 = x 的特点,将数组内所有的数字进行按位异或。出现两次的所有数字按位异或的结果是 0,0 与出现一次的数字异或可以得到这个数字本身。 + + + + +```cpp +int singleNumber(vector& nums) { + int single = 0; + for (int num : nums) { + single ^= num; + } + return single; +} +``` + + + + +```py +def singleNumber(nums: List[int]) -> int: + single = 0 + for num in nums: + single = single ^ num + return single +``` + + + + + +这里我们也可以直接使用 reduce 函数: + + + + +```cpp +int singleNumber(vector& nums) { + return reduce(nums.begin(), nums.end(), 0, + [](int x, int y) { return x ^ y; }); +} +``` + + + + +```py +def singleNumber(nums: List[int]) -> int: + return functools.reduce(lambda x, y: x ^ y, nums) +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-3-binary-properties.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-3-binary-properties.mdx new file mode 100644 index 00000000..d5b383a8 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-3-binary-properties.mdx @@ -0,0 +1,123 @@ +--- +sidebar_position: 46 +--- + +# 9.3 二进制特性 + +利用二进制的一些特性,我们可以把位运算使用到更多问题上。 + +例如,我们可以利用二进制和位运算输出一个数组的所有子集。假设我们有一个长度为 $n$ 的数组,我们可以生成长度为 $n$ 的所有二进制,1 表示选取该数字,0 表示不选取。这样我们就获得了 $2^n$ 个子集。 + +## [318. Maximum Product of Word Lengths](https://leetcode.com/problems/maximum-product-of-word-lengths/) + +### 題目描述 + +给定多个字母串,求其中任意两个字母串的长度乘积的最大值,且这两个字母串不能含有相同字母。 + +### 輸入輸出範例 + +输入一个包含多个字母串的一维数组,输出一个整数,表示长度乘积的最大值。 + +``` +Input: ["a","ab","abc","d","cd","bcd","abcd"] +Output: 4 +``` + +在这个样例中,一种最优的选择是“ab”和“cd”。 + +### 題解 + +怎样快速判断两个字母串是否含有重复数字呢?可以为每个字母串建立一个长度为 26 的二进制数字,每个位置表示是否存在该字母。如果两个字母串含有重复数字,那它们的二进制表示的按位与不为 0。同时,我们可以建立一个哈希表来存储二进制数字到最长子母串长度的映射关系,比如 ab 和 aab 的二进制数字相同,但是 aab 更长。 + + + + +```cpp +int maxProduct(vector& words) { + unordered_map cache; + int max_prod = 0; + for (const string& word : words) { + int mask = 0, w_len = word.length(); + for (char c : word) { + mask |= 1 << (c - ’a’); + } + cache[mask] = max(cache[mask], w_len); + for (auto [h_mask, h_len] : cache) { + if ((mask & h_mask) == 0) { + max_prod = max(max_prod, w_len * h_len); + } + } + } + return max_prod; +} +``` + + + + +```py +def maxProduct(words: List[str]) -> int: + cache = dict() + max_prod = 0 + for word in words: + mask, w_len = 0, len(word) + for c in word: + mask = mask | (1 << (ord(c) - ord("a"))) + cache[mask] = max(cache.get(mask, 0), w_len) + for h_mask, h_len in cache.items(): + if (mask & h_mask) == 0: + max_prod = max(max_prod, w_len * h_len) + return max_prod +``` + + + + + +## [338. Counting Bits](https://leetcode.com/problems/counting-bits/) + +### 題目描述 + +给定一个非负整数 n,求从 0 到 n 的所有数字的二进制表达中,分别有多少个 1。 + +### 輸入輸出範例 + +输入是一个非负整数 n,输出是长度为 n +1 的非负整数数组,每个位置 m 表示 m 的二进制里有多少个 1。 + +``` +Input: 5 +Output: [0,1,1,2,1,2] +``` + +### 題解 + +本题可以利用动态规划和位运算进行快速的求解。定义一个数组 dp,其中 dp[i] 表示数字 i 的二进制含有 1 的个数。对于第 i 个数字,如果它二进制的最后一位为 1,那么它含有 1 的个数则为 dp[i-1] + 1;如果它二进制的最后一位为 0,那么它含有 1 的个数和其算术右移结果相同,即 dp[i>>1]。 + + + + +```cpp +vector countBits(int n) { + vector dp(n + 1, 0); + for (int i = 1; i <= n; ++i) + // 等价于:dp[i] = dp[i & (i - 1)] + 1; + dp[i] = i & 1 ? dp[i - 1] + 1 : dp[i >> 1]; + return dp; +} +``` + + + + +```py +def countBits(n: int) -> List[int]: + dp = [0] * (n + 1) + for i in range(1, n + 1): + # 等价于:dp[i] = dp[i & (i - 1)] + 1 + dp[i] = dp[i - 1] + 1 if i & 1 else dp[i >> 1] + return dp +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-4-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-4-exercises.md new file mode 100644 index 00000000..87db5ee0 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-4-exercises.md @@ -0,0 +1,25 @@ +--- +sidebar_position: 47 +--- + +# 9.4 練習 + +## 基礎難度 + +### [268. Missing Number](https://leetcode.com/problems/missing-number/) + +Single Number 的变种题。除了利用二进制,也可以使用高斯求和公式。 + +### [693. Binary Number with Alternating Bits](https://leetcode.com/problems/binary-number-with-alternating-bits/) + +利用位运算判断一个数的二进制是否会出现连续的 0 和 1。 + +### [476. Number Complement](https://leetcode.com/problems/number-complement/) + +二进制翻转的变种题。 + +## 進階難度 + +### [260. Single Number III](https://leetcode.com/problems/single-number-iii/) + +Single Number 的 follow-up,需要认真思考如何运用位运算求解。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/_category_.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/_category_.json new file mode 100644 index 00000000..dc298905 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "9. 神奇的位运算 ", + "position": 9, + "link": { + "type": "generated-index", + "description": "第 9 章 神奇的位运算" + } +} diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/index.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/index.md deleted file mode 100644 index b23b8581..00000000 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/index.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 0 ---- - -# 繁體序 - -繁體序 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-theme-classic/footer.json b/leetcode_101/i18n/zh-TW/docusaurus-theme-classic/footer.json index b753f2a6..7a748fc1 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-theme-classic/footer.json +++ b/leetcode_101/i18n/zh-TW/docusaurus-theme-classic/footer.json @@ -1,40 +1,4 @@ { - "link.title.Docs": { - "message": "Docs", - "description": "The title of the footer links column with title=Docs in the footer" - }, - "link.title.Community": { - "message": "Community", - "description": "The title of the footer links column with title=Community in the footer" - }, - "link.title.More": { - "message": "More", - "description": "The title of the footer links column with title=More in the footer" - }, - "link.item.label.Tutorial": { - "message": "Tutorial", - "description": "The label of footer link with label=Tutorial linking to /docs/intro" - }, - "link.item.label.Stack Overflow": { - "message": "Stack Overflow", - "description": "The label of footer link with label=Stack Overflow linking to https://stackoverflow.com/questions/tagged/docusaurus" - }, - "link.item.label.Discord": { - "message": "Discord", - "description": "The label of footer link with label=Discord linking to https://discordapp.com/invite/docusaurus" - }, - "link.item.label.X": { - "message": "X", - "description": "The label of footer link with label=X linking to https://x.com/docusaurus" - }, - "link.item.label.Blog": { - "message": "Blog", - "description": "The label of footer link with label=Blog linking to /blog" - }, - "link.item.label.GitHub": { - "message": "GitHub", - "description": "The label of footer link with label=GitHub linking to https://github.com/facebook/docusaurus" - }, "copyright": { "message": "Copyright © 2024 My Project, Inc. Built with Docusaurus.", "description": "The footer copyright" From b6decadb5ca549338571d42139a202ca714bad13 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Fri, 22 Nov 2024 12:06:42 +0100 Subject: [PATCH 21/49] i18n chapter 6 --- .../docs/10-data-structures/_category_.json | 2 +- .../11-string-manipulation/_category_.json | 2 +- .../_category_.json | 2 +- .../8-mathematical-solutions/_category_.json | 2 +- .../docs/9-bitwise-operations/_category_.json | 2 +- .../1-greedy-algorithms/_category_.json | 4 +- .../10-data-structures/_category_.json | 4 +- .../11-string-manipulation/_category_.json | 4 +- .../current/12-linked-lists/_category_.json | 4 +- .../current/13-trees/_category_.json | 4 +- .../current/14-graphs/_category_.json | 4 +- .../_category_.json | 4 +- .../2-1-algorithm-explanation.md | 2 +- .../2-two-pointer-techniques/_category_.json | 4 +- .../_category_.json | 4 +- .../4-sorting-algorithms/_category_.json | 4 +- .../5-1-algorithm-explanation.md | 2 +- .../5-searching-algorithms/_category_.json | 4 +- .../6-1-algorithm-explanation.md | 10 +-- .../6-dynamic-programming/6-2-basic-dp-1d.mdx | 48 ++++++++----- .../6-dynamic-programming/6-3-basic-dp-2d.mdx | 36 +++++----- .../6-4-partition-problems.mdx | 67 +++++++++--------- .../6-5-subsequence-problems.mdx | 33 ++++----- .../6-6-knapsack-problem.mdx | 51 +++++++------- .../6-7-string-editing.mdx | 29 +++++--- .../6-8-stock-trading.mdx | 32 ++++----- .../6-dynamic-programming/6-9-exercises.md | 18 ++--- .../6-dynamic-programming/_category_.json | 4 +- .../7-divide-and-conquer/_category_.json | 4 +- .../8-mathematical-solutions/_category_.json | 4 +- .../9-bitwise-operations/_category_.json | 4 +- .../1-2-assignment-problems.mdx | 22 +++++- .../1-3-interval-problems.mdx | 14 +++- .../1-greedy-algorithms/_category_.json | 4 +- .../10-data-structures/_category_.json | 4 +- .../11-string-manipulation/_category_.json | 4 +- .../current/12-linked-lists/_category_.json | 4 +- .../current/13-trees/_category_.json | 4 +- .../current/14-graphs/_category_.json | 4 +- .../_category_.json | 4 +- .../_category_.json | 4 +- .../5-2-depth-first-search.mdx | 2 +- .../5-searching-algorithms/_category_.json | 4 +- .../6-1-algorithm-explanation.md | 8 +-- .../6-dynamic-programming/6-2-basic-dp-1d.mdx | 45 +++++++----- .../6-dynamic-programming/6-3-basic-dp-2d.mdx | 35 +++++----- .../6-4-partition-problems.mdx | 70 +++++++++---------- .../6-5-subsequence-problems.mdx | 32 ++++----- .../6-6-knapsack-problem.mdx | 52 +++++++------- .../6-7-string-editing.mdx | 28 +++++--- .../6-8-stock-trading.mdx | 28 ++++---- .../6-dynamic-programming/6-9-exercises.md | 18 ++--- .../6-dynamic-programming/_category_.json | 4 +- .../7-divide-and-conquer/_category_.json | 4 +- .../8-mathematical-solutions/_category_.json | 4 +- .../9-bitwise-operations/_category_.json | 4 +- 56 files changed, 442 insertions(+), 362 deletions(-) diff --git a/leetcode_101/docs/10-data-structures/_category_.json b/leetcode_101/docs/10-data-structures/_category_.json index 4a0b8ebd..1e241891 100644 --- a/leetcode_101/docs/10-data-structures/_category_.json +++ b/leetcode_101/docs/10-data-structures/_category_.json @@ -1,5 +1,5 @@ { - "label": "10. 妙用数据结构 ", + "label": "10. 妙用数据结构", "position": 10, "link": { "type": "generated-index", diff --git a/leetcode_101/docs/11-string-manipulation/_category_.json b/leetcode_101/docs/11-string-manipulation/_category_.json index 688feb04..084ef32f 100644 --- a/leetcode_101/docs/11-string-manipulation/_category_.json +++ b/leetcode_101/docs/11-string-manipulation/_category_.json @@ -1,5 +1,5 @@ { - "label": "11. 令人头大的字符串 ", + "label": "11. 令人头大的字符串", "position": 11, "link": { "type": "generated-index", diff --git a/leetcode_101/docs/15-advanced-data-structures/_category_.json b/leetcode_101/docs/15-advanced-data-structures/_category_.json index cbe6af2e..dc11e088 100644 --- a/leetcode_101/docs/15-advanced-data-structures/_category_.json +++ b/leetcode_101/docs/15-advanced-data-structures/_category_.json @@ -1,5 +1,5 @@ { - "label": "15. 更加复杂的数据结构 ", + "label": "15. 更加复杂的数据结构", "position": 15, "link": { "type": "generated-index", diff --git a/leetcode_101/docs/8-mathematical-solutions/_category_.json b/leetcode_101/docs/8-mathematical-solutions/_category_.json index 5fb8df9e..2d1586cc 100644 --- a/leetcode_101/docs/8-mathematical-solutions/_category_.json +++ b/leetcode_101/docs/8-mathematical-solutions/_category_.json @@ -1,5 +1,5 @@ { - "label": "8. 巧解数学问题 ", + "label": "8. 巧解数学问题", "position": 8, "link": { "type": "generated-index", diff --git a/leetcode_101/docs/9-bitwise-operations/_category_.json b/leetcode_101/docs/9-bitwise-operations/_category_.json index dc298905..0f6be05e 100644 --- a/leetcode_101/docs/9-bitwise-operations/_category_.json +++ b/leetcode_101/docs/9-bitwise-operations/_category_.json @@ -1,5 +1,5 @@ { - "label": "9. 神奇的位运算 ", + "label": "9. 神奇的位运算", "position": 9, "link": { "type": "generated-index", diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/_category_.json index 4119cb25..85a7b37f 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/_category_.json +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/_category_.json @@ -1,8 +1,8 @@ { - "label": "1. 最易懂的贪心算法", + "label": "1. The Easiest Greedy Algorithm", "position": 1, "link": { "type": "generated-index", - "description": "第 1 章 最易懂的贪心算法" + "description": "Chapter 1: The Easiest Greedy Algorithm" } } diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/_category_.json index 4a0b8ebd..5fd3d33c 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/_category_.json +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/_category_.json @@ -1,8 +1,8 @@ { - "label": "10. 妙用数据结构 ", + "label": "10. Ingenious Use of Data Structures", "position": 10, "link": { "type": "generated-index", - "description": "第 10 章 妙用数据结构" + "description": "Chapter 10: Ingenious Use of Data Structures" } } diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/_category_.json index 688feb04..f81fb7bd 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/_category_.json +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/_category_.json @@ -1,8 +1,8 @@ { - "label": "11. 令人头大的字符串 ", + "label": "11. Tricky String Problems", "position": 11, "link": { "type": "generated-index", - "description": "第 11 章 令人头大的字符串" + "description": "Chapter 11: Tricky String Problems" } } diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/_category_.json index 184a7911..921d0a45 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/_category_.json +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/_category_.json @@ -1,8 +1,8 @@ { - "label": "12. 指针三剑客之一:链表", + "label": "12. The Three Musketeers of Pointers: Linked Lists", "position": 12, "link": { "type": "generated-index", - "description": "第 12 章 指针三剑客之一:链表" + "description": "Chapter 12: The Three Musketeers of Pointers: Linked Lists" } } diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/_category_.json index db81316e..a3026f20 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/_category_.json +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/_category_.json @@ -1,8 +1,8 @@ { - "label": "13. 指针三剑客之二:树", + "label": "13. The Three Musketeers of Pointers: Trees", "position": 13, "link": { "type": "generated-index", - "description": "第 13 章 指针三剑客之二:树" + "description": "Chapter 13: The Three Musketeers of Pointers: Trees" } } diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/_category_.json index 7a36d4cd..0d316bd1 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/_category_.json +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/_category_.json @@ -1,8 +1,8 @@ { - "label": "14. 指针三剑客之三:图", + "label": "14. The Three Musketeers of Pointers: Graphs", "position": 14, "link": { "type": "generated-index", - "description": "第 14 章 指针三剑客之三:图" + "description": "Chapter 14: The Three Musketeers of Pointers: Graphs" } } diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/_category_.json index cbe6af2e..b4f85a5a 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/_category_.json +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/_category_.json @@ -1,8 +1,8 @@ { - "label": "15. 更加复杂的数据结构 ", + "label": "15. More Complex Data Structures", "position": 15, "link": { "type": "generated-index", - "description": "第 15 章 更加复杂的数据结构" + "description": "Chapter 15: More Complex Data Structures" } } diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-1-algorithm-explanation.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-1-algorithm-explanation.md index 9746f6c7..49f37f03 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-1-algorithm-explanation.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-1-algorithm-explanation.md @@ -2,7 +2,7 @@ sidebar_position: 5 --- -# 2.1 算法解释 +# 2.1 Algorithm Explanation The two-pointer technique is primarily used for traversing arrays, where two pointers point to different elements to collaborate on a task. It can also be extended to multiple pointers across multiple arrays. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/_category_.json index 23d4e78a..175a1be9 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/_category_.json +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/_category_.json @@ -1,8 +1,8 @@ { - "label": "2. 玩转双指针", + "label": "2. Mastering Two Pointers", "position": 2, "link": { "type": "generated-index", - "description": "第 2 章 玩转双指针" + "description": "Chapter 2: Mastering Two Pointers" } } diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/_category_.json index 89e9fd2f..546acc0d 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/_category_.json +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/_category_.json @@ -1,8 +1,8 @@ { - "label": "3. 居合斩!二分查找", + "label": "3. Iaido! Binary Search", "position": 3, "link": { "type": "generated-index", - "description": "第 3 章 居合斩!二分查找" + "description": "Chapter 3: Iaido! Binary Search" } } diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/4-sorting-algorithms/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/4-sorting-algorithms/_category_.json index 4aad536a..5c12d644 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/4-sorting-algorithms/_category_.json +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/4-sorting-algorithms/_category_.json @@ -1,8 +1,8 @@ { - "label": "4. 千奇百怪的排序算法", + "label": "4. Peculiar Sorting Algorithms", "position": 4, "link": { "type": "generated-index", - "description": "第 4 章 千奇百怪的排序算法" + "description": "Chapter 4: Peculiar Sorting Algorithms" } } diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-1-algorithm-explanation.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-1-algorithm-explanation.md index 19af5419..3466ab7e 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-1-algorithm-explanation.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-1-algorithm-explanation.md @@ -2,6 +2,6 @@ sidebar_position: 21 --- -# 5.1 算法解释 +# 5.1 Algorithm Explanation `Depth First Search (DFS)` and `Breadth First Search (BFS)` are two of the most common priority search methods. They are widely used for searching in structures such as graphs and trees. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/_category_.json index 0943e8c5..8811fa48 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/_category_.json +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/_category_.json @@ -1,8 +1,8 @@ { - "label": "5. 一切皆可搜索", + "label": "5. Everything is Searchable", "position": 5, "link": { "type": "generated-index", - "description": "第 5 章 一切皆可搜索" + "description": "Chapter 5: Everything is Searchable" } } diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-1-algorithm-explanation.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-1-algorithm-explanation.md index 48055183..594591cd 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-1-algorithm-explanation.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-1-algorithm-explanation.md @@ -2,12 +2,12 @@ sidebar_position: 26 --- -# 6.1 算法解释 +# 6.1 Algorithm Explanation -这里我们引用一下维基百科的描述:“`动态规划`(Dynamic Programming, DP)在查找有很多`重叠子问题`的情况的最优解时有效。它将问题重新组合成子问题。为了避免多次解决这些子问题,它们的结果都逐渐被计算并被保存,从简单的问题直到整个问题都被解决。因此,动态规划保存递归时的结果,因而不会在解决同样的问题时花费时间 · · · · · · 动态规划只能应用于有`最优子结构`的问题。最优子结构的意思是局部最优解能决定全局最优解(对有些问题这个要求并不能完全满足,故有时需要引入一定的近似)。简单地说,问题能够分解成子问题来解决。” +Here, we quote Wikipedia’s description: "`Dynamic Programming` (DP) is effective in finding the optimal solution for problems with many `overlapping subproblems`. It redefines the problem into subproblems. To avoid repeatedly solving these subproblems, their results are progressively computed and stored, starting from simpler problems until the entire problem is resolved. Therefore, dynamic programming saves the results of recursion and avoids spending time solving the same problems repeatedly. Dynamic programming can only be applied to problems with an `optimal substructure`. The optimal substructure means that the local optimal solution can determine the global optimal solution (this requirement is not always completely met for some problems, so certain approximations may be introduced). Simply put, the problem can be broken down into subproblems to solve." -通俗一点来讲,动态规划和其它遍历算法(如深/广度优先搜索)都是将原问题拆成多个子问题然后求解,他们之间最本质的区别是,动态规划`保存子问题的解,避免重复计算`。解决动态规划问题的关键是找到`状态转移方程`,这样我们可以通过计算和储存子问题的解来求解最终问题。 +In simple terms, dynamic programming differs from other traversal algorithms (e.g., depth-first search or breadth-first search) in that it `stores the solutions of subproblems to avoid redundant calculations`. The key to solving dynamic programming problems lies in finding the `state transition equation`, which allows us to solve the final problem by computing and storing the solutions to subproblems. -同时,我们也可以对动态规划进行`空间压缩`,起到节省空间消耗的效果。这一技巧笔者将在之后的题目中介绍。 +Additionally, we can apply `space optimization` techniques to dynamic programming to reduce space usage. This technique will be introduced in subsequent problems. -在一些情况下,动态规划可以看成是带有`状态记录`(memoization)的优先搜索。状态记录的意思为,如果一个子问题在优先搜索时已经计算过一次,我们可以把它的结果储存下来,之后遍历到该子问题的时候可以直接返回储存的结果。动态规划是自下而上的,即先解决子问题,再解决父问题;而用带有状态记录的优先搜索是自上而下的,即从父问题搜索到子问题,若重复搜索到同一个子问题则进行状态记录,防止重复计算。如果题目需求的是最终状态,那么使用动态搜索比较方便;如果题目需要输出所有的路径,那么使用带有状态记录的优先搜索会比较方便。 \ No newline at end of file +In some cases, dynamic programming can be considered a form of `memoized` traversal. Memoization means that if a subproblem has been solved during traversal, its result can be stored and reused later when the same subproblem is encountered again. Dynamic programming is bottom-up, solving subproblems first and then the parent problem. Memoized traversal is top-down, starting from the parent problem and solving subproblems as they are encountered. If the problem requires only the final state, dynamic programming is more convenient; if the problem requires all possible paths, memoized traversal is more suitable. \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-2-basic-dp-1d.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-2-basic-dp-1d.mdx index 30d4d627..cec2501d 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-2-basic-dp-1d.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-2-basic-dp-1d.mdx @@ -2,32 +2,37 @@ sidebar_position: 27 --- -# 6.2 基本动态规划:一维 +# 6.2 Basic Dynamic Programming: One-Dimensional ## [70. Climbing Stairs](https://leetcode.com/problems/climbing-stairs/) ### Problem Description -给定 $n$ 节台阶,每次可以走一步或走两步,求一共有多少种方式可以走完这些台阶。 +Given $n$ steps of stairs, you can either take one step or two steps at a time. Determine how many ways there are to climb to the top. + ### Input and Output Example -输入是一个数字,表示台阶数量;输出是爬台阶的总方式。 +Input is a single number representing the number of steps; output is the total number of ways to climb the stairs. ``` Input: 3 Output: 3 ``` -在这个样例中,一共有三种方法走完这三节台阶:每次走一步;先走一步,再走两步;先走两步,再走一步。 +In this example, there are three ways to climb the three steps: +1. Take one step three times. +2. Take one step, then two steps. +3. Take two steps, then one step. ### Solution Explanation -这是十分经典的斐波那契数列题。定义一个数组 dp,dp[i] 表示走到第 i 阶的方法数。因为我们每次可以走一步或者两步,所以第 i 阶可以从第 i-1 或 i-2 阶到达。换句话说,走到第 i 阶的方法数即为走到第 i-1 阶的方法数加上走到第 i-2 阶的方法数。这样我们就得到了状态转移方程 dp[i] = dp[i-1] + dp[i-2]。注意边界条件的处理。 +This is a classic Fibonacci sequence problem. Define an array `dp` where `dp[i]` represents the number of ways to reach the $i^{th}$ step. Since you can either take one step or two steps, the $i^{th}$ step can be reached from the $(i-1)^{th}$ or the $(i-2)^{th}$ step. In other words, the number of ways to reach the $i^{th}$ step is the sum of the ways to reach the $(i-1)^{th}$ and $(i-2)^{th}$ steps. This gives us the state transition equation: `dp[i] = dp[i-1] + dp[i-2]`. Pay attention to the initial conditions. + :::warning -有的时候为了方便处理边界情况,我们可以在构造 dp 数组时多留一个位置,用来处理初始状态。本题即多留了一个第 0 阶的初始位置。 +To handle boundary cases conveniently, we can reserve an extra position in the `dp` array to represent the initial state. In this problem, an extra initial position for step 0 is added. ::: @@ -59,7 +64,8 @@ def climbStairs(n: int) -> int: -进一步的,我们可以对动态规划进行空间压缩。因为 dp[i] 只与 dp[i-1] 和 dp[i-2] 有关,因此可以只用两个变量来存储 dp[i-1] 和 dp[i-2],使得原来的 $O(n)$ 空间复杂度优化为 $O(1)$ 复杂度。 +Furthermore, we can apply space optimization to dynamic programming. Since dp[i] only depends on dp[i-1] and dp[i-2], we can use just two variables to store dp[i-1] and dp[i-2], reducing the original $O(n)$ space complexity to $O(1)$. + @@ -98,22 +104,31 @@ def climbStairs(n: int) -> int: ### Problem Description -假如你是一个劫匪,并且决定抢劫一条街上的房子,每个房子内的钱财数量各不相同。如果你抢了两栋相邻的房子,则会触发警报机关。求在不触发机关的情况下最多可以抢劫多少钱。 +Suppose you are a robber deciding to rob houses along a street, where each house has a different amount of money. If you rob two adjacent houses, an alarm will be triggered. Determine the maximum amount of money you can rob without triggering the alarm. ### Input and Output Example -输入是一个一维数组,表示每个房子的钱财数量;输出是劫匪可以最多抢劫的钱财数量。 +The input is a one-dimensional array `nums` representing the amount of money in each house; the output is the maximum amount of money the robber can steal. ``` Input: [2,7,9,3,1] Output: 12 ``` -在这个样例中,最多的抢劫方式为抢劫第 1、3、5 个房子。 +In this example, the optimal way to rob is to rob houses 1, 3, and 5. ### Solution Explanation -定义一个数组 dp,dp[i] 表示抢劫到第 i 个房子时,可以抢劫的最大数量。我们考虑 dp[i],此时可以抢劫的最大数量有两种可能,一种是我们选择不抢劫这个房子,此时累计的金额即为 dp[i-1];另一种是我们选择抢劫这个房子,那么此前累计的最大金额只能是 dp[i-2],因为我们不能够抢劫第 i-1 个房子,否则会触发警报机关。因此本题的状态转移方程为 dp[i] = max(dp[i-1], nums[i-1] + dp[i-2])。 +Define an array `dp`, where `dp[i]` represents the maximum amount of money that can be robbed up to the `i`-th house. To determine the value of `dp[i]`, there are two possible scenarios: + +1. **Do not rob this house**: In this case, the accumulated amount is `dp[i-1]`. +2. **Rob this house**: The previously accumulated maximum amount can only be `dp[i-2]`, because robbing the `i-1`-th house would trigger the alarm. + +Thus, the state transition equation for this problem is: + +$$ +dp[i] = \max(dp[i-1], dp[i-2] + \text{nums}[i-1]) +$$ @@ -147,7 +162,7 @@ def rob(nums: List[int]) -> int: -同样的,我们可以像题目 70 那样,对空间进行压缩。 +Similarly, we can optimize space complexity just like in Problem 70. Since `dp[i]` only depends on `dp[i-1]` and `dp[i-2]`, we can use only two variables to store these two values, reducing the original $O(n)$ space complexity to $O(1)$ space complexity. @@ -185,22 +200,23 @@ def rob(nums: List[int]) -> int: ### Problem Description -给定一个数组,求这个数组中连续且等差的子数组一共有多少个。 +Given an array, calculate the total number of continuous arithmetic subarrays. ### Input and Output Example -输入是一个一维数组,输出是满足等差条件的连续子数组个数。 +Input is a one-dimensional array, and output is the number of continuous subarrays that meet the arithmetic condition. ``` Input: nums = [1,2,3,4] Output: 3 ``` -在这个样例中,等差数列有 [1,2,3]、[2,3,4] 和 [1,2,3,4]。 +In this example, the arithmetic subarrays are [1,2,3], [2,3,4], and [1,2,3,4]. ### Solution Explanation -因为要求是等差数列,可以很自然地想到子数组必定满足 num[i] - num[i-1] = num[i-1] - num[i-2]。这里我们对于 dp 数组的定义是以 i 结尾的,满足该条件的子数组数量。因为等差子数组可以在任意一个位置终结,所以我们需要对 dp 数组求和进行子数组统计。 +Since the requirement is for arithmetic subarrays, it naturally follows that the subarray must satisfy the condition `num[i] - num[i-1] = num[i-1] - num[i-2]`. Here, we define the `dp` array such that `dp[i]` represents the number of subarrays ending at index `i` that satisfy this condition. Because arithmetic subarrays can end at any position, we need to sum up the `dp` array to calculate the total number of subarrays. + diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-3-basic-dp-2d.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-3-basic-dp-2d.mdx index 989c9333..b0024076 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-3-basic-dp-2d.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-3-basic-dp-2d.mdx @@ -2,18 +2,17 @@ sidebar_position: 28 --- -# 6.3 基本动态规划:二维 +# 6.3 Basic Dynamic Programming: Two-Dimensional ## [64. Minimum Path Sum](https://leetcode.com/problems/minimum-path-sum/) ### Problem Description -给定一个 $m × n$ 大小的非负整数矩阵,求从左上角开始到右下角结束的、经过的数字的和最 -小的路径。每次只能向右或者向下移动。 +Given an $m × n$ non-negative integer matrix, find the path from the top-left to the bottom-right corner with the smallest sum of numbers. You can only move right or down. ### Input and Output Example -输入是一个二维数组,输出是最优路径的数字和。 +Input is a two-dimensional array, and output is the sum of the numbers along the optimal path. ``` Input: @@ -23,15 +22,16 @@ Input: Output: 7 ``` -在这个样例中,最短路径为 1->3->1->1->1。 +In this example, the shortest path is 1->3->1->1->1. ### Solution Explanation -我们可以定义一个同样是二维的 dp 数组,其中 dp[i][j] 表示从左上角开始到 (i, j) 位置的最优路径的数字和。因为每次只能向下或者向右移动,我们可以很直观地得到状态转移方程 dp[i][j] = grid[i][j] + min(dp[i-1][j], dp[i][j-1]),其中 grid 表示原数组。 +We can define a `dp` array of the same dimensions, where `dp[i][j]` represents the sum of numbers along the optimal path from the top-left corner to position `(i, j)`. Since you can only move down or right, the state transition equation is `dp[i][j] = grid[i][j] + min(dp[i-1][j], dp[i][j-1])`, where `grid` represents the original matrix. + :::warning -Python 语言中,多维数组多初始化比较特殊,直接初始化为 [[val] * n] * m 会导致只是创造了 m 个 [[val] * n] 的引用。正确的初始化方法为 [[val for _ in range(n)] for _ in range(m)]。 +In Python, initializing multi-dimensional arrays requires caution. Direct initialization using `[[val] * n] * m` creates `m` references to the same `[[val] * n]` object. The correct initialization method is `[[val for _ in range(n)] for _ in range(m)]`. ::: @@ -83,16 +83,14 @@ def minPathSum(grid: List[List[int]]) -> int: -因为 dp 矩阵的每一个值只和左边和上面的值相关,我们可以使用空间压缩将 dp 数组压缩为一维。对于第 i 行,在遍历到第 j 列的时候,因为第 j-1 列已经更新过了,所以 dp[j-1] 代表 dp[i][j-1]的值;而 dp[j] 待更新,当前存储的值是在第 i-1 行的时候计算的,所以代表 dp[i-1][j] 的值。 +Since each value in the `dp` matrix depends only on the values to its left and above, we can apply space optimization to reduce the `dp` array to one dimension. For the `i-th` row, when iterating to the `j-th` column, since the `j-1-th` column has already been updated, `dp[j-1]` represents the value of `dp[i][j-1]`. Meanwhile, `dp[j]` is yet to be updated, and the current stored value represents the value of `dp[i-1][j]` from the previous row. :::warning -如果不是很熟悉空间压缩技巧,笔者推荐您优先尝试写出非空间压缩的解法,如果时间充裕且力所能及再进行空间压缩。 +If you are not very familiar with space optimization techniques, it is recommended to first write a solution without space optimization. Apply space optimization only if time permits and you are comfortable with the approach. ::: - - @@ -146,11 +144,11 @@ def minPathSum(grid: List[List[int]]) -> int: ### Problem Description -给定一个由 0 和 1 组成的二维矩阵,求每个位置到最近的 0 的距离。 +Given a 2D matrix consisting of 0s and 1s, find the distance of each position to the nearest 0. ### Input and Output Example -输入是一个二维 0-1 数组,输出是一个同样大小的非负整数数组,表示每个位置到最近的 0 的距离。 +The input is a 2D 0-1 array, and the output is a 2D non-negative integer array of the same size, representing the distance of each position to the nearest 0. ``` Input: @@ -166,7 +164,9 @@ Output: ### Solution Explanation -一般来说,因为这道题涉及到四个方向上的最近搜索,所以很多人的第一反应可能会是广度优先搜索。但是对于一个大小 $O(mn)$ 的二维数组,对每个位置进行四向搜索,最坏情况的时间复杂度(即全是 1)会达到恐怖的 $O(m^2n^2)$。一种办法是使用一个二维布尔值数组做 memoization,使得广度优先搜索不会重复遍历相同位置;另一种更简单的方法是,我们从左上到右下进行一次动态搜索,再从右下到左上进行一次动态搜索。两次动态搜索即可完成四个方向上的查找。 +Typically, as this problem involves finding the nearest position in four directions, many people might initially consider breadth-first search (BFS). However, for a 2D array of size $O(mn)$, performing four-directional BFS for each position results in a worst-case time complexity of $O(m^2n^2)$ (when all entries are 1). + +One approach is to use a 2D boolean array for memoization, ensuring that BFS does not revisit the same position. A simpler approach, however, is to perform a dynamic search from the top-left to the bottom-right, followed by another dynamic search from the bottom-right to the top-left. These two searches efficiently account for all four directions. @@ -240,11 +240,11 @@ def updateMatrix(matrix: List[List[int]]) -> List[List[int]]: ### Problem Description -给定一个二维的 0-1 矩阵,求全由 1 构成的最大正方形面积。 +Given a 2D binary matrix filled with 0s and 1s, find the largest square containing only 1s and return its area. ### Input and Output Example -输入是一个二维 0-1 数组,输出是最大正方形面积。 +The input is a 2D binary matrix, and the output is the area of the largest square. ``` Input: @@ -257,14 +257,14 @@ Output: 4 ### Solution Explanation -对于在矩阵内搜索正方形或长方形的题型,一种常见的做法是定义一个二维 dp 数组,其中 dp[i][j] 表示满足题目条件的、以 (i, j) 为右下角的正方形或者长方形的属性。对于本题,则表示以 (i, j) 为右下角的全由 1 构成的最大正方形边长。如果当前位置是 0,那么 dp[i][j] 即为 0;如果当前位置是 1,我们假设 dp[i][j] = k,其充分条件为 dp[i-1][j-1]、dp[i][j-1] 和 dp[i-1][j] 的值必须都不小于 k − 1,否则 (i, j) 位置不可以构成一个面积为 $k^2$ 的正方形。同理,如果这三个值中的的最小值为 k − 1,则 (i, j) 位置一定且最大可以构成一个面积为 $k^2$ 的正方形。 +For problems involving finding squares or rectangles in a matrix, a common approach is to define a 2D dp array, where dp[i][j] represents the attribute of the square or rectangle that meets the problem's requirements with (i, j) as the bottom-right corner. In this problem, dp[i][j] represents the side length of the largest square containing only 1s with (i, j) as the bottom-right corner. If the current position is 0, then dp[i][j] = 0. If the current position is 1, assuming dp[i][j] = k, the necessary condition is that dp[i-1][j-1], dp[i][j-1], and dp[i-1][j] must all be at least k − 1; otherwise, (i, j) cannot form a square of area $k^2$. Conversely, if the minimum of these three values is k − 1, then (i, j) can and will form a square of area $k^2$.
        ![](6.1.png) -
        图 6.1: 题目 542 - 左边为一个 0-1 矩阵,右边为其对应的 dp 矩阵,我们可以发现最大的正方形边长为 3
        +
        Figure 6.1: Problem 221 - The left shows a 0-1 matrix, and the right shows its corresponding dp matrix. The largest square has a side length of 3
        diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-4-partition-problems.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-4-partition-problems.mdx index 8942200f..934c6ba1 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-4-partition-problems.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-4-partition-problems.mdx @@ -2,28 +2,29 @@ sidebar_position: 29 --- -# 6.4 分割类型题 +# 6.4 Partition Type Problems ## [279. Perfect Squares](https://leetcode.com/problems/perfect-squares/) ### Problem Description -给定一个正整数,求其最少可以由几个完全平方数相加构成。 +Given a positive integer, find the minimum number of perfect square numbers that sum up to the given number. ### Input and Output Example -输入是给定的正整数,输出也是一个正整数,表示输入的数字最少可以由几个完全平方数相加构成。 +The input is a given positive integer, and the output is also a positive integer, representing the minimum number of perfect square numbers that sum up to the input number. ``` Input: n = 13 Output: 2 ``` -在这个样例中,13 的最少构成方法为 4+9。 +In this example, the minimal representation of 13 is 4 + 9. ### Solution Explanation -对于分割类型题,动态规划的状态转移方程通常并不依赖相邻的位置,而是依赖于满足分割条件的位置。我们定义一个一维矩阵 dp,其中 dp[i] 表示数字 i 最少可以由几个完全平方数相加构成。在本题中,位置 i 只依赖 $i - j^2$ 的位置,如 i - 1、i - 4、i - 9 等等,才能满足完全平方分割的条件。因此 dp[i] 可以取的最小值即为 1+ min(dp[i-1], dp[i-4], dp[i-9] · · · )。注意边界条件的处理。 +For partition-type problems, the dynamic programming state transition equation usually does not depend on adjacent positions but on positions that satisfy the partition condition. We define a 1D array `dp`, where `dp[i]` represents the minimum number of perfect square numbers that sum up to `i`. In this problem, position `i` only depends on positions like $i - j^2$, such as `i - 1`, `i - 4`, `i - 9`, and so on, to meet the perfect square partition condition. Therefore, `dp[i]` can take the minimum value as $1 + \min(dp[i-1], dp[i-4], dp[i-9] · · · )$. Note the handling of boundary conditions. + @@ -61,22 +62,22 @@ def numSquares(n: int) -> int: ### Problem Description -已知字母 A-Z 可以表示成数字 1-26。给定一个数字串,求有多少种不同的字符串等价于这个数字串。 +Given that letters A-Z can be represented as numbers 1-26, find the number of ways a given numeric string can be decoded into valid strings. ### Input and Output Example -输入是一个由数字组成的字符串,输出是满足条件的解码方式总数。 +The input is a numeric string, and the output is the total number of decoding ways that satisfy the conditions. ``` Input: "226" Output: 3 ``` -在这个样例中,有三种解码方式:BZ(2 26)、VF(22 6) 或 BBF(2 2 6)。 +In this example, there are three decoding ways: BZ(2 26), VF(22 6), or BBF(2 2 6). ### Solution Explanation -这是一道很经典的动态规划题,难度不大但是十分考验耐心。这是因为只有 1-26 可以表示字母,因此对于一些特殊情况,比如数字 0 或者当相邻两数字大于 26 时,需要有不同的状态转移方程,详见如下代码。 +This is a classic dynamic programming problem. While not difficult, it requires careful handling of edge cases. Only numbers 1-26 can represent letters, so special conditions such as `0` or adjacent numbers greater than 26 require different state transition formulas, as shown in the code below. @@ -84,7 +85,7 @@ Output: 3 ```cpp int numDecodings(string s) { int n = s.length(); - int prev = s[0] - ’0’; + int prev = s[0] - '0'; if (prev == 0) { return 0; } @@ -93,22 +94,22 @@ int numDecodings(string s) { } vector dp(n + 1, 1); for (int i = 2; i <= n; ++i) { - int cur = s[i - 1] - ’0’; + int cur = s[i - 1] - '0'; if ((prev == 0 || prev > 2) && cur == 0) { - // 00, 30, 40, ..., 90, 非法。 + // 00, 30, 40, ..., 90 are invalid combinations. return 0; } if ((prev < 2 && prev > 0) || (prev == 2 && cur <= 6)) { // 10, 11, ..., 25, 26. if (cur == 0) { - // 10, 20,只能连续解码两位。 + // 10, 20 can only be decoded as two-digit numbers. dp[i] = dp[i - 2]; } else { - // 可以解码当前位,也可以连续解码两位。 + // Can be decoded as a single-digit or two-digit number. dp[i] = dp[i - 2] + dp[i - 1]; } } else { - // 合法,但只能解码当前位。 + // Valid, but can only be decoded as a single-digit number. dp[i] = dp[i - 1]; } prev = cur; @@ -132,18 +133,18 @@ def numDecodings(s: str) -> int: for i in range(2, n + 1): cur = ord(s[i - 1]) - ord("0") if (prev == 0 or prev > 2) and cur == 0: - # 00, 30, 40, ..., 90, 非法。 + # 00, 30, 40, ..., 90 are invalid combinations. return 0 if 0 < prev < 2 or (prev == 2 and cur <= 6): # 10, 11, ..., 25, 26. if cur == 0: - # 10, 20,只能连续解码两位。 + # 10, 20 can only be decoded as two-digit numbers. dp[i] = dp[i - 2] else: - # 可以解码当前位,也可以连续解码两位。 + # Can be decoded as a single-digit or two-digit number. dp[i] = dp[i - 2] + dp[i - 1] else: - # 合法,但只能解码当前位。 + # Valid, but can only be decoded as a single-digit number. dp[i] = dp[i - 1] prev = cur return dp[n] @@ -157,7 +158,7 @@ def numDecodings(s: str) -> int: ### Problem Description -给定一个字符串和一个字符串集合,求是否存在一种分割方式,使得原字符串分割后的子字符串都可以在集合内找到。 +Given a string and a set of strings, determine if there is a way to split the string such that every substring after splitting can be found in the set. ### Input and Output Example @@ -166,11 +167,11 @@ Input: s = "applepenapple", wordDict = ["apple", "pen"] Output: true ``` -在这个样例中,字符串可以被分割为 [“apple”,“pen”,“apple”]。 +In this example, the string can be split into [“apple”,“pen”,“apple”]. ### Solution Explanation -类似于完全平方数分割问题,这道题的分割条件由集合内的字符串决定,因此在考虑每个分割位置时,需要遍历字符串集合,以确定当前位置是否可以成功分割。注意对于位置 0,需要初始化值为真。 +Similar to the problem of splitting into perfect squares, the splitting condition in this problem is determined by the strings in the set. When considering each splitting position, we need to iterate through the set of strings to check if the current position can be successfully split. Note that for position 0, the value needs to be initialized to true. @@ -186,8 +187,8 @@ bool wordBreak(string s, vector& wordDict) { if (i >= m && s.substr(i - m, m) == word) { dp[i] = dp[i - m]; } - // 提前剪枝,略微加速运算。 - // 如果不剪枝,上一行代码需要变更为 dp[i] = dp[i] || dp[i - m]; + // Early pruning to slightly speed up. + // Without pruning, the above line should be dp[i] = dp[i] || dp[i - m]; if (dp[i]) { break; } @@ -209,8 +210,8 @@ def wordBreak(s: str, wordDict: List[str]) -> bool: m = len(word) if i >= m and s[i - m : i] == word: dp[i] = dp[i - m] - # 提前剪枝,略微加速运算。 - # 如果不剪枝,上一行代码需要变更为 dp[i] = dp[i] or dp[i-m] + # Early pruning to slightly speed up. + # Without pruning, the above line should be dp[i] = dp[i] or dp[i-m] if dp[i]: break return dp[n] @@ -224,7 +225,7 @@ def wordBreak(s: str, wordDict: List[str]) -> bool: ### Problem Description -给定一个数组,每个元素代表一本书的厚度和高度。问对于一个固定宽度的书架,如果按照数组中书的顺序从左到右、从上到下摆放,最小总高度是多少。 +Given an array, where each element represents the width and height of a book, determine the minimum total height of a bookshelf with fixed width, where books are placed in the given order from left to right and top to bottom. ### Input and Output Example @@ -239,12 +240,12 @@ Output: 6 ![](https://assets.leetcode.com/uploads/2019/06/24/shelves.png) -
        图 6.2: 书架摆放问题 - 样例图解
        +
        Figure 6.2: Bookcase Arrangement Problem - Example Illustration
        ### Solution Explanation -令 dp[i] 表示放置第 i 本书时的最小总高度,则 dp[i] 可以是在第 i-1 本书下面重新放一排,也可以是在满足不超过前一排宽度的情况下放在前一排。 +Let dp[i] represent the minimum total height when placing the i-th book. dp[i] can either represent placing the i-th book on a new row or on the previous row, provided the row width constraint is satisfied. @@ -297,7 +298,8 @@ def minHeightShelves(books: List[List[int]], shelfWidth: int) -> int: ### Problem Description -给定一个不重复数字的数组和一个目标数,求加起来是目标数的所有排列的总数量。(虽然这道题叫做 Combination Sum,但是不同顺序的组合会被当作不同答案,因此本质上是排列。) +Given an array of unique numbers and a target number, find the total number of permutations that sum up to the target. (Although the problem is named "Combination Sum," different orderings of the same combination are considered distinct, so this is essentially a permutation problem.) + ### Input and Output Example @@ -306,12 +308,13 @@ Input: nums = [1,2,3], target = 4 Output: 7 ``` -七种不同的排列为 (1, 1, 1, 1)、(1, 1, 2)、(1, 2, 1)、(1, 3)、(2, 1, 1)、(2, 2) 和 (3, 1)。 +The seven different permutations are (1, 1, 1, 1), (1, 1, 2), (1, 2, 1), (1, 3), (2, 1, 1), (2, 2), and (3, 1). ### Solution Explanation -令 dp[i] 表示加起来和为 i 时,满足条件的排列数量。在内循环中我们可以直接对所有合法数字进行拿取。这里注意,在 C++ 题解中,因为求和时很容易超过 int 上界,我们这里用 double 存储 dp 数组。 +Let dp[i] represent the number of permutations that sum up to i. In the inner loop, we directly consider all valid numbers from the array. Note that in the C++ solution, since summing can easily exceed the `int` limit, we use `double` to store the dp array. + diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-5-subsequence-problems.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-5-subsequence-problems.mdx index 9e83bdcb..d12f1592 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-5-subsequence-problems.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-5-subsequence-problems.mdx @@ -2,36 +2,36 @@ sidebar_position: 30 --- -# 6.5 子序列问题 +# 6.5 Subsequence Problem ## [300. Longest Increasing Subsequence](https://leetcode.com/problems/longest-increasing-subsequence/) ### Problem Description -给定一个未排序的整数数组,求最长的递增子序列。 +Given an unsorted array of integers, find the length of the longest increasing subsequence. :::warning -按照 LeetCode 的习惯,子序列(subsequence)不必连续,子数组(subarray)或子字符串(substring)必须连续。 +According to LeetCode conventions, a subsequence does not need to be contiguous, while a subarray or substring must be contiguous. ::: ### Input and Output Example -输入是一个一维数组,输出是一个正整数,表示最长递增子序列的长度。 +Input is a 1D array, and output is a positive integer representing the length of the longest increasing subsequence. ``` Input: [10,9,2,5,3,7,101,4] Output: 4 ``` -在这个样例中,最长递增子序列之一是 [2,3,7,101]。 +In this example, one of the longest increasing subsequences is [2,3,7,101]. ### Solution Explanation -对于子序列问题,第一种动态规划方法是,定义一个 dp 数组,其中 dp[i] 表示以 i 结尾的子序列的性质。在处理好每个位置后,统计一遍各个位置的结果即可得到题目要求的结果。 +For subsequence problems, a common dynamic programming approach is to define a dp array where dp[i] represents the property of a subsequence ending at index i. After processing each position, summing up the results of all positions will yield the required result. -在本题中,dp[i] 可以表示以 i 结尾的、最长子序列长度。对于每一个位置 i,如果其之前的某个位置 j 所对应的数字小于位置 i 所对应的数字,则我们可以获得一个以 i 结尾的、长度为 dp[j] + 1 的子序列。为了遍历所有情况,我们需要 i 和 j 进行两层循环,其时间复杂度为 $O(n^2)$。 +In this problem, dp[i] represents the length of the longest subsequence ending at index i. For each position i, if a previous position j has a smaller value than nums[i], we can form a subsequence of length dp[j] + 1 ending at i. To check all possibilities, we use a nested loop with i and j, resulting in a time complexity of $O(n^2)$. @@ -70,9 +70,10 @@ def lengthOfLIS(nums: List[int]) -> int: -本题还可以使用二分查找将时间复杂度降低为 $O(n \log n)$。我们定义一个 dp 数组,其中 dp[k] 存储长度为 k+1 的最长递增子序列的最后一个数字。我们遍历每一个位置 i,如果其对应的数字大于 dp 数组中所有数字的值,那么我们把它放在 dp 数组尾部,表示最长递增子序列长度加 1;如果我们发现这个数字在 dp 数组中比数字 a 大、比数字 b 小,则我们将 b 更新为此数字,使得之后构成递增序列的可能性增大。以这种方式维护的 dp 数组永远是递增的,因此可以用二分查找加速搜索。 +This problem can also be solved using binary search to reduce the time complexity to $O(n \log n)$. We define a `dp` array where `dp[k]` stores the last number of the longest increasing subsequence of length `k+1`. As we iterate through each position `i`, if the number is larger than all numbers in the `dp` array, we append it to the end of `dp`, indicating that the length of the longest increasing subsequence has increased by 1. If the number lies between two numbers `a` and `b` in the `dp` array, we replace `b` with this number to increase the possibility of forming a longer increasing subsequence. Using this method, the `dp` array is always maintained in increasing order, allowing us to use binary search to speed up the process. -以样例为例,对于数组 [10,9,2,5,3,7,101,4],我们每轮的更新查找情况为: + +For example, for the array [10,9,2,5,3,7,101,4], the updates in each round are as follows: ``` num dp @@ -86,9 +87,9 @@ num dp 4 [2,3,4,101] ``` -最终我们知道最长递增子序列的长度是 4。注意 dp 数组最终的形式并不一定是合法的排列形式,如 [2,3,4,101] 并不是子序列;但之前覆盖掉的 [2,3,7,101] 是最优解之一。 +Finally, we determine that the length of the longest increasing subsequence is 4. Note that the final form of the `dp` array does not necessarily represent a valid subsequence, e.g., [2,3,4,101] is not a subsequence, but the previously updated [2,3,7,101] is one of the optimal solutions. -类似的,对于其他题目,如果状态转移方程的结果递增或递减,且需要进行插入或查找操作,我们也可以使用二分法进行加速。 +Similarly, for other problems, if the results of the state transition equation are increasing or decreasing and require insertion or search operations, we can also use binary search to speed up the solution. @@ -129,24 +130,24 @@ def lengthOfLIS(nums: List[int]) -> int: ### Problem Description -给定两个字符串,求它们最长的公共子序列长度。 +Given two strings, find the length of their longest common subsequence. ### Input and Output Example -输入是两个字符串,输出是一个整数,表示它们满足题目条件的长度。 +Input consists of two strings, and the output is an integer representing the length of their longest common subsequence. ``` Input: text1 = "abcde", text2 = "ace" Output: 3 ``` -在这个样例中,最长公共子序列是“ace”。 +In this example, the longest common subsequence is "ace." ### Solution Explanation -对于子序列问题,第二种动态规划方法是,定义一个 dp 数组,其中 dp[i] 表示到位置 i 为止的子序列的性质,并不必须以 i 结尾。这样 dp 数组的最后一位结果即为题目所求,不需要再对每个位置进行统计。 +For subsequence problems, the second dynamic programming approach defines a dp array where dp[i] represents the property of the subsequence up to position i, without requiring it to end at i. The final result is the last value of the dp array, eliminating the need to compute each position. -在本题中,我们可以建立一个二维数组 dp,其中 dp[i][j] 表示到第一个字符串位置 i 为止、到第二个字符串位置 j 为止、最长的公共子序列长度。这样一来我们就可以很方便地分情况讨论这两个位置对应的字母相同与不同的情况了。 +In this problem, we use a 2D array dp, where dp[i][j] represents the length of the longest common subsequence up to position i in the first string and position j in the second string. This makes it straightforward to handle the cases where the letters at these positions are the same or different. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-6-knapsack-problem.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-6-knapsack-problem.mdx index 72f98236..0a12b00b 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-6-knapsack-problem.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-6-knapsack-problem.mdx @@ -2,11 +2,11 @@ sidebar_position: 31 --- -# 6.6 背包问题 +# 6.6 Knapsack Problem -`背包问题(knapsack problem)`是一种组合优化的 NP 完全问题:有 n 个物品和载重为 w 的背包,每个物品都有自己的重量 weight 和价值 value,求拿哪些物品可以使得背包所装下物品的总价值最大。如果限定每种物品只能选择 0 个或 1 个,则问题称为 `0-1 背包问题(0-1 knapsack)`;如果不限定每种物品的数量,则问题称为`无界背包问题或完全背包问题(unbounded knapsack)`。 +The `knapsack problem` is a combinatorial optimization NP-complete problem: given n items and a knapsack with weight capacity w, where each item has a weight and a value, determine which items to include in the knapsack to maximize the total value. If each item can only be chosen 0 or 1 time, the problem is called the `0-1 knapsack problem`; if there is no limit to the number of items chosen, it is called the `unbounded knapsack problem`. -我们可以用动态规划来解决背包问题。以 0-1 背包问题为例。我们可以定义一个二维数组 dp存储最大价值,其中 dp[i][j] 表示前 i 件物品重量不超过 j 的情况下能达到的最大价值。在我们遍历到第 i 件物品时,在当前背包总载重为 j 的情况下,如果我们不将物品 i 放入背包,那么 dp[i][j] = dp[i-1][j],即前 i 个物品的最大价值等于只取前 i-1 个物品时的最大价值;如果我们将物品 i 放入背包,假设第 i 件物品重量为 weight,价值为 value,那么我们得到 dp[i][j] = dp[i-1][j-weight] + value。我们只需在遍历过程中对这两种情况取最大值即可,总时间复杂度和空间复杂度都为 $O(nw)$。 +We can solve the knapsack problem using dynamic programming. Taking the 0-1 knapsack problem as an example, we define a 2D array `dp` to store the maximum value, where `dp[i][j]` represents the maximum value achievable with the first i items and a knapsack weight limit of j. When processing the i-th item, if we do not include item i in the knapsack, then `dp[i][j] = dp[i-1][j]`, which means the maximum value equals that of the first i-1 items. If we include item i, with weight `weight` and value `value`, then `dp[i][j] = dp[i-1][j-weight] + value`. We take the maximum of these two options during iteration, resulting in a time complexity and space complexity of $O(nw)$. @@ -53,10 +53,10 @@ def knapsack(weights: List[int], values: List[int], n: int, w: int) -> int: ![](6.3.png) -
        图 6.3: 0-1 背包问题 - 状态转移矩阵样例
        +
        Figure 6.3: 0-1 Knapsack Problem - State Transition Matrix Example
        -我们可以进一步对 0-1 背包进行空间优化,将空间复杂度降低为 O(w)。如图所示,假设我们目前考虑物品 i = 2,且其重量为 weight = 2,价值为 value = 3;对于背包载重 j,我们可以得到 dp[2][j] = max(dp[1][j], dp[1][j-2] + 3)。这里可以发现我们永远只依赖于上一排 i = 1 的信息,之前算过的其他物品都不需要再使用。因此我们可以去掉 dp 矩阵的第一个维度,在考虑物品 i 时变成 dp[j] = max(dp[j], dp[j-weight] + value)。这里要注意我们在遍历每一行的时候必须`逆向遍历`,这样才能够调用上一行物品 i-1 时 dp[j-weight] 的值;若按照从左往右的顺序进行正向遍历,则dp[j-weight] 的值在遍历到 j 之前就已经被更新成物品 i 的值了。 +We can further optimize the space complexity of the 0-1 knapsack problem to $O(w)$. As shown in the figure, assume we are currently considering item $i = 2$, with a weight of $weight = 2$ and a value of $value = 3$. For a knapsack capacity of $j$, we have $dp[2][j] = max(dp[1][j], dp[1][j-2] + 3)$. Here, we observe that we always depend only on the information from the previous row $i = 1$, and the results of other items computed earlier are no longer needed. Therefore, we can remove the first dimension of the $dp$ matrix, reducing it to $dp[j] = max(dp[j], dp[j-weight] + value)$ when considering item $i$. It's important to note that we must **traverse in reverse order** for each row. This ensures that the value of $dp[j-weight]$ from the previous row (item $i-1$) is correctly accessed. If traversed in the forward direction (left to right), $dp[j-weight]$ would already be updated to the value of item $i$ before reaching $j$. @@ -91,16 +91,17 @@ def knapsack(weights: List[int], values: List[int], n: int, w: int) -> int: -在完全背包问题中,一个物品可以拿多次。如图上半部分所示,假设我们遍历到物品 i = 2,且其重量为 weight = 2,价值为 value = 3;对于背包载重 j = 5,最多只能装下 2 个该物品。那么我们的状态转移方程就变成了 dp[2][5] = max(dp[1][5], dp[1][3] + 3, dp[1][1] + 6)。如果采用这种方法,假设背包载重无穷大而物体的重量无穷小,我们这里的比较次数也会趋近于无穷大,远超$O(nw)$ 的时间复杂度。 +In the unbounded knapsack problem, an item can be chosen multiple times. As shown in the top part of the figure, assume we are processing item $i = 2$, with a weight of $weight = 2$ and a value of $value = 3$. For a knapsack capacity of $j = 5$, we can fit at most 2 of this item. Thus, our state transition equation becomes $dp[2][5] = max(dp[1][5], dp[1][3] + 3, dp[1][1] + 6)$. If we use this approach and assume infinite knapsack capacity with infinitely small item weight, the number of comparisons would approach infinity, far exceeding the time complexity of $O(nw)$.
        ![](6.4.png) -
        图 6.4: 完全背包问题 - 状态转移矩阵样例
        +
        Figure 6.4: Unbounded Knapsack Problem - State Transition Matrix Example
        -怎么解决这个问题呢?我们发现在 dp[2][3] 的时候我们其实已经考虑了 dp[1][3] 和 dp[2][1] 的情况,而在时 dp[2][1] 也已经考虑了 dp[1][1] 的情况。因此,如图下半部分所示,对于拿多个物品的情况,我们只需考虑 dp[2][3] 即可,即 dp[2][5] = max(dp[1][5], dp[2][3] + 3)。这样,我们就得到了完全背包问题的状态转移方程:dp[i][j] = max(dp[i-1][j], dp[i][j-w] + v),其与 0-1 背包问题的差别仅仅是把状态转移方程中的第二个 i-1 变成了 i。 +How do we solve this issue? We observe that at $dp[2][3]$, we have already accounted for $dp[1][3]$ and $dp[2][1]$, and at $dp[2][1]$, we have already considered $dp[1][1]$. Therefore, as shown in the bottom part of the figure, for cases involving multiple items, we only need to consider $dp[2][3]$, i.e., $dp[2][5] = max(dp[1][5], dp[2][3] + 3)$. This gives us the state transition equation for the unbounded knapsack problem: $dp[i][j] = max(dp[i-1][j], dp[i][j-w] + v)$, which differs from the 0-1 knapsack problem only in that the second $i-1$ in the state transition equation is replaced by $i$. + @@ -142,7 +143,7 @@ def knapsack(weights: List[int], values: List[int], n: int, w: int) -> int: -同样的,我们也可以利用空间压缩将时间复杂度降低为 $O(w)$。这里要注意我们在遍历每一行的时候必须`正向遍历`,因为我们需要利用当前物品在第 j-weight 列的信息。 +Similarly, we can use space optimization to reduce the time complexity to $O(w)$. It is important to note that during each row traversal, we must perform a `forward traversal`, as we need to use the information of the current item at column $j-weight$. @@ -179,7 +180,7 @@ def knapsack(weights: List[int], values: List[int], n: int, w: int) -> int: :::warning -压缩空间时到底需要正向还是逆向遍历呢?物品和重量哪个放在外层,哪个放在内层呢?这取决于状态转移方程的依赖关系。在思考空间压缩前,不妨将状态转移矩阵画出来,方便思考如何进行空间压缩,以及压缩哪个维度更省空间。 +When compressing space, should we use `forward` or `backward` traversal? Should items or weights be placed in the outer loop? This depends on the dependency relationships in the state transition equation. Before considering space compression, it is helpful to draw the state transition matrix to better understand how to compress space and which dimension to compress for optimal efficiency. ::: @@ -187,22 +188,22 @@ def knapsack(weights: List[int], values: List[int], n: int, w: int) -> int: ### Problem Description -给定一个正整数数组,求是否可以把这个数组分成和相等的两部分。 +Given a positive integer array, determine whether it can be partitioned into two subsets with equal sums. ### Input and Output Example -输入是一个一维正整数数组,输出时一个布尔值,表示是否可以满足题目要求。 +The input is a one-dimensional positive integer array, and the output is a boolean value indicating whether the array can be partitioned as required. ``` Input: [1,5,11,5] Output: true ``` -在这个样例中,满足条件的分割方法是 [1,5,5] 和 [11]。 +In this example, the array can be partitioned into [1,5,5] and [11]. ### Solution Explanation -本题等价于 0-1 背包问题,设所有数字和为 sum,我们的目标是选取一部分物品,使得它们的总和为 sum/2。这道题不需要考虑价值,因此我们只需要通过一个布尔值矩阵来表示状态转移矩阵。注意边界条件的处理。 +This problem is equivalent to the 0-1 knapsack problem. Given the total sum of all numbers, `sum`, the goal is to find a subset of numbers whose total equals `sum / 2`. Since there is no need to consider values, a boolean matrix can be used to represent the state transition matrix. Pay attention to the handling of boundary conditions. @@ -253,7 +254,7 @@ def canPartition(nums: List[int]) -> bool: -同样的,我们也可以对本题进行空间压缩。注意对数字和的遍历需要逆向。 +Similarly, we can perform space compression for this problem. Note that the traversal of the sum of numbers needs to be in reverse order. @@ -300,23 +301,23 @@ def canPartition(nums: List[int]) -> bool: ### Problem Description -给定 $m$ 个数字 0 和 $n$ 个数字 1,以及一些由 0-1 构成的字符串,求利用这些数字最多可以构成多少个给定的字符串,字符串只可以构成一次。 +Given $m$ zeros and $n$ ones, and an array of binary strings, determine the maximum number of given strings that can be formed using these zeros and ones, with each string being used at most once. ### Input and Output Example -输入两个整数 $m$ 和 $n$,表示 0 和 1 的数量,以及一个一维字符串数组,表示待构成的字符串; -输出是一个整数,表示最多可以生成的字符串个数。 +Input consists of two integers $m$ and $n$, representing the count of zeros and ones respectively, along with a one-dimensional array of strings representing the strings to form; +Output is an integer representing the maximum number of strings that can be formed. ``` Input: Array = {"10", "0001", "111001", "1", "0"}, m = 5, n = 3 Output: 4 ``` -在这个样例中,我们可以用 5 个 0 和 3 个 1 构成 [“10”, “0001”, “1”, “0”]。 +In this example, we can use 5 zeros and 3 ones to form [“10”, “0001”, “1”, “0”]. ### Solution Explanation -这是一个多维费用的 0-1 背包问题,有两个背包大小,0 的数量和 1 的数量。我们在这里直接展示三维空间压缩到二维后的写法。 +This is a multidimensional 0-1 knapsack problem, where there are two constraints: the number of zeros and the number of ones. Below is the implementation of compressing the three-dimensional solution into a two-dimensional space. @@ -366,24 +367,24 @@ def findMaxForm(strs: List[str], m: int, n: int) -> int: ### Problem Description -给定一些硬币的面额,求最少可以用多少颗硬币组成给定的金额。 +Given a list of coin denominations, find the minimum number of coins required to make up a given amount. ### Input and Output Example -输入一个一维整数数组,表示硬币的面额;以及一个整数,表示给定的金额。输出一个整数,表示满足条件的最少的硬币数量。若不存在解,则返回-1。 +Input is a one-dimensional integer array representing coin denominations and an integer representing the target amount. Output is an integer indicating the minimum number of coins required. If no solution exists, return -1. ``` Input: coins = [1, 2, 5], amount = 11 Output: 3 ``` -在这个样例中,最少的组合方法是 11 = 5 + 5 + 1。 +In this example, the minimum combination is 11 = 5 + 5 + 1. ### Solution Explanation -因为每个硬币可以用无限多次,这道题本质上是完全背包。我们直接展示二维空间压缩为一维的写法。 +Since each coin can be used an unlimited number of times, this problem is essentially an unbounded knapsack problem. Below is the implementation using one-dimensional space compression. -这里注意,我们把 dp 数组初始化为 amount + 1 而不是-1 的原因是,在动态规划过程中有求最小值的操作,如果初始化成-1 则会导致结果始终为-1。至于为什么取这个值,是因为 i 最大可以取 amount,而最多的组成方式是只用 1 元硬币,因此 amount + 1 一定大于所有可能的组合方式,取最小值时一定不会是它。在动态规划完成后,若结果仍然是此值,则说明不存在满足条件的组合方法,返回-1。 +Note: The `dp` array is initialized to `amount + 1` instead of `-1` because the dynamic programming process involves taking the minimum. If initialized to `-1`, the result would always be `-1`. The choice of `amount + 1` is because the maximum possible number of coins is `amount` (using only 1-value coins), so this value is guaranteed to be greater than any valid combination. If the result remains `amount + 1` after the DP process, it means no valid combination exists, and we return `-1`. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-7-string-editing.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-7-string-editing.mdx index 328bc9eb..f5331c5d 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-7-string-editing.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-7-string-editing.mdx @@ -2,28 +2,34 @@ sidebar_position: 32 --- -# 6.7 字符串编辑 +# 6.7 String Editing ## [72. Edit Distance](https://leetcode.com/problems/edit-distance/) ### Problem Description -给定两个字符串,已知你可以删除、替换和插入任意字符串的任意字符,求最少编辑几步可以将两个字符串变成相同。 +Given two strings, you can delete, replace, or insert any character from either string. Find the minimum number of steps required to make the two strings identical. ### Input and Output Example -输入是两个字符串,输出是一个整数,表示最少的步骤。 +Input consists of two strings, and the output is an integer representing the minimum number of steps. ``` Input: word1 = "horse", word2 = "ros" Output: 3 ``` -在这个样例中,一种最优编辑方法是 horse -> rorse -> rose -> ros。 +In this example, one optimal sequence of edits is horse -> rorse -> rose -> ros. ### Solution Explanation -类似于题目 1143,我们使用一个二维数组 dp[i][j],表示将第一个字符串到位置 i 为止,和第二个字符串到位置 j 为止,最多需要几步编辑。当第 i 位和第 j 位对应的字符相同时,dp[i][j] 等于 dp[i-1][j-1];当二者对应的字符不同时,修改的消耗是 dp[i-1][j-1]+1,插入 i 位置/删除 j 位置的消耗是 dp[i][j-1] + 1,插入 j 位置/删除 i 位置的消耗是 dp[i-1][j] + 1。 +Similar to problem 1143, we use a two-dimensional array `dp[i][j]`, where `dp[i][j]` represents the minimum number of edits required to transform the first string up to position `i` and the second string up to position `j`. + +- If the characters at position `i` and `j` are the same, then `dp[i][j] = dp[i-1][j-1]`. +- If the characters differ: + - The cost of modification is `dp[i-1][j-1] + 1`. + - The cost of inserting at position `i`/deleting at position `j` is `dp[i][j-1] + 1`. + - The cost of inserting at position `j`/deleting at position `i` is `dp[i-1][j] + 1`. @@ -75,22 +81,23 @@ def minDistance(word1: str, word2: str) -> int: ### Problem Description -给定一个字母 A,已知你可以每次选择复制全部字符,或者粘贴之前复制的字符,求最少需要几次操作可以把字符串延展到指定长度。 +Given the letter `A`, you can either copy all characters or paste the previously copied characters. Find the minimum number of operations needed to extend the string to the specified length. ### Input and Output Example -输入是一个正整数,代表指定长度;输出是一个整数,表示最少操作次数。 +The input is a positive integer representing the target length, and the output is an integer representing the minimum number of operations required. ``` Input: 3 Output: 3 ``` -在这个样例中,一种最优的操作方法是先复制一次,再粘贴两次。 +In this example, one optimal sequence of operations is to copy once and paste twice. ### Solution Explanation -不同于以往通过加减实现的动态规划,这里需要乘除法来计算位置,因为粘贴操作是倍数增加的。我们使用一个一维数组 dp,其中位置 i 表示延展到长度 i 的最少操作次数。对于每个位置 j,如果 j 可以被 i 整除,那么长度 i 就可以由长度 j 操作得到,其操作次数等价于把一个长度为 j 的 A 延展到长度为 i/j。因此我们可以得到递推公式 dp[i] = dp[j] + dp[i/j]。 +Unlike typical dynamic programming problems that use addition or subtraction, this problem requires multiplication and division for state transitions because the paste operation doubles the length. We use a one-dimensional array `dp`, where `dp[i]` represents the minimum number of operations needed to extend the string to length `i`. For each position `j`, if `j` divides `i`, then length `i` can be achieved by operating on length `j`. The number of operations needed is equivalent to extending length `j` to length `i / j`. Thus, the recursive formula is `dp[i] = dp[j] + dp[i / j]`. + @@ -103,7 +110,7 @@ int minSteps(int n) { for (int j = 2; j * j <= i; ++j) { if (i % j == 0) { dp[i] = dp[j] + dp[i / j]; - // 提前剪枝,因为j从小到大,因此操作数量一定最小。 + // Early pruning since smaller j guarantees the minimal operations. break; } } @@ -122,7 +129,7 @@ def minSteps(n: int) -> int: for j in range(2, floor(sqrt(i)) + 1): if i % j == 0: dp[i] = dp[j] + dp[i // j] - # 提前剪枝,因为j从小到大,因此操作数量一定最小。 + # Early pruning since smaller j guarantees the minimal operations. break return dp[n] ``` diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-8-stock-trading.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-8-stock-trading.mdx index 0c27000b..d4d8baca 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-8-stock-trading.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-8-stock-trading.mdx @@ -2,30 +2,31 @@ sidebar_position: 33 --- -# 6.8 股票交易 +# 6.8 Stock Trading -`股票交易`类问题通常可以用动态规划来解决。对于稍微复杂一些的股票交易类问题,比如需要冷却时间或者交易费用,则可以用通过动态规划实现的`状态机`来解决。 +`Stock trading` problems can often be solved using dynamic programming. For more complex stock trading scenarios, such as requiring cooldown periods or transaction fees, a `state machine` implemented with dynamic programming is a common approach. ## [121. Best Time to Buy and Sell Stock](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/) ### Problem Description -给定一段时间内每天某只股票的固定价格,已知你只可以买卖各一次,求最大的收益。 +Given the fixed prices of a stock over a period of days, where you can only buy and sell once, find the maximum profit. ### Input and Output Example -输入一个一维整数数组,表示每天的股票价格;输出一个整数,表示最大的收益。 +The input is a one-dimensional array of integers representing daily stock prices, and the output is an integer representing the maximum profit. ``` Input: [7,1,5,3,6,4] Output: 5 ``` -在这个样例中,最大的利润为在第二天价格为 1 时买入,在第五天价格为 6 时卖出。 +In this example, the maximum profit is achieved by buying on day 2 (price = 1) and selling on day 5 (price = 6). ### Solution Explanation -我们可以遍历一遍数组,在每一个位置 i 时,记录 i 位置之前所有价格中的最低价格,然后将当前的价格作为售出价格,查看当前收益是不是最大收益即可。注意本题中以及之后题目中的buy 和 sell 表示买卖操作时,用户账户的收益。因此买时为负,卖时为正。 +We can traverse the array once, maintaining a record of the lowest price encountered before each day `i`. For each price, calculate the profit as the difference between the current price and the minimum price seen so far. Update the maximum profit accordingly. Note that in this problem, as well as others, `buy` and `sell` represent account operations: buying decreases account value (negative), and selling increases it (positive). + @@ -61,23 +62,22 @@ def maxProfit(prices: List[int]) -> int: ### Problem Description -给定一段时间内每天某只股票的固定价格,已知你只可以买卖各 $k$ 次,且每次只能拥有一支股票,求最大的收益。 +Given the fixed prices of a stock over a period of days, you can buy and sell at most $k$ times, holding at most one stock at a time. Find the maximum profit. ### Input and Output Example -输入一个一维整数数组,表示每天的股票价格;以及一个整数,表示可以买卖的次数 $k$。输出一个整数,表示最大的收益。 +The input is a one-dimensional array of integers representing daily stock prices, and an integer $k$ representing the number of allowed transactions. The output is an integer representing the maximum profit. ``` Input: [3,2,6,5,0,3], k = 2 Output: 7 ``` -在这个样例中,最大的利润为在第二天价格为 2 时买入,在第三天价格为 6 时卖出;再在第五天价格为 0 时买入,在第六天价格为 3 时卖出。 +In this example, the maximum profit is achieved by buying on day 2 (price = 2) and selling on day 3 (price = 6); then buying again on day 5 (price = 0) and selling on day 6 (price = 3). ### Solution Explanation -类似地,我们可以建立两个动态规划数组 buy 和 sell,对于每天的股票价格,buy[j] 表示在第 j 次买入时的最大收益,sell[j] 表示在第 j 次卖出时的最大收益。 - +Similarly, we can define two dynamic programming arrays, `buy` and `sell`. For each day, `buy[j]` represents the maximum profit after the $j$-th buy, and `sell[j]` represents the maximum profit after the $j$-th sell. @@ -118,28 +118,28 @@ def maxProfit(k: int, prices: List[int]) -> int: ### Problem Description -给定一段时间内每天某只股票的固定价格,已知每次卖出之后必须冷却一天,且每次只能拥有一支股票,求最大的收益。 +Given the fixed prices of a stock over a period of days, you can only own one stock at a time, and after selling a stock, you must wait one day (cooldown) before buying again. Find the maximum profit. ### Input and Output Example -输入一个一维整数数组,表示每天的股票价格;输出一个整数,表示最大的收益。 +The input is a one-dimensional array of integers representing daily stock prices. The output is an integer representing the maximum profit. ``` Input: [1,2,3,0,2] Output: 3 ``` -在这个样例中,最大的利润获取操作是买入、卖出、冷却、买入、卖出。 +In this example, the optimal sequence of operations is buy, sell, cooldown, buy, sell. ### Solution Explanation -我们可以使用状态机来解决这类复杂的状态转移问题,通过建立多个状态以及它们的转移方式,我们可以很容易地推导出各个状态的转移方程。如图所示,我们可以建立四个状态来表示带有冷却的股票交易,以及它们的之间的转移方式。 +We can solve such complex state transition problems using a **state machine**. By defining multiple states and their transitions, we can derive the transition equations for each state. As illustrated, we can define four states to represent stock transactions with cooldowns, along with their transitions.
        ![](6.5.png) -
        图 6.5: 题目 309 - 状态机状态转移
        +
        Figure 6.5: Problem 309 - State Machine Transitions
        diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-9-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-9-exercises.md index a4fe5a77..ce5b107f 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-9-exercises.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-9-exercises.md @@ -8,38 +8,38 @@ sidebar_position: 34 ### [213. House Robber II](https://leetcode.com/problems/house-robber-ii/) -强盗抢劫题目的 follow-up,如何处理环形数组呢? +Follow-up of the robber problem: how to handle circular arrays? ### [53. Maximum Subarray](https://leetcode.com/problems/maximum-subarray/) -经典的一维动态规划题目,试着把一维空间优化为常量吧。 +A classic one-dimensional dynamic programming problem. Try optimizing the space complexity to a constant. ### [343. Integer Break](https://leetcode.com/problems/integer-break/) -分割类型题,先尝试用动态规划求解,再思考是否有更简单的解法。 +A partition problem. First, solve it using dynamic programming, then think about whether there's a simpler approach. ### [583. Delete Operation for Two Strings](https://leetcode.com/problems/delete-operation-for-two-strings/) -最长公共子序列的变种题。 +A variation of the longest common subsequence problem. ## Advanced Difficulty ### [646. Maximum Length of Pair Chain](https://leetcode.com/problems/maximum-length-of-pair-chain/) -最长递增子序列的变种题,同样的,尝试用二分进行加速。 +A variation of the longest increasing subsequence problem. Similarly, try speeding it up using binary search. ### [10. Regular Expression Matching](https://leetcode.com/problems/regular-expression-matching/) -正则表达式匹配,非常考验耐心。需要根据正则表达式的不同情况,即字符、星号,点号等,分情况讨论。 +Regex matching is a test of patience. You need to handle different cases, such as characters, asterisks, dots, etc., with careful condition discussions. ### [376. Wiggle Subsequence](https://leetcode.com/problems/wiggle-subsequence/) -最长摆动子序列,通项公式比较特殊,需要仔细思考。 +The longest wiggle subsequence has a special formula. Think it through carefully. ### [494. Target Sum](https://leetcode.com/problems/target-sum/) -如果告诉你这道题是 0-1 背包,你是否会有一些思路? +If told this is a 0-1 knapsack problem, does that give you any ideas? ### [714. Best Time to Buy and Sell Stock with Transaction Fee](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/) -建立状态机,股票交易类问题就会迎刃而解。 \ No newline at end of file +Build a state machine, and stock trading problems will become much easier to solve. \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/_category_.json index 1a2cb467..4c1135db 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/_category_.json +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/_category_.json @@ -1,8 +1,8 @@ { - "label": "6. 深入浅出动态规划", + "label": "6. Dynamic Programming Made Simple", "position": 6, "link": { "type": "generated-index", - "description": "第 6 章 深入浅出动态规划" + "description": "Chapter 6: Dynamic Programming Made Simple" } } diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/_category_.json index 2535d2d4..4c5832a8 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/_category_.json +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/_category_.json @@ -1,8 +1,8 @@ { - "label": "7. 化繁为简的分治法", + "label": "7. Simplifying with Divide and Conquer", "position": 7, "link": { "type": "generated-index", - "description": "第 7 章 化繁为简的分治法" + "description": "Chapter 7: Simplifying with Divide and Conquer" } } diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/_category_.json index 5fb8df9e..8ded4db1 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/_category_.json +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/_category_.json @@ -1,8 +1,8 @@ { - "label": "8. 巧解数学问题 ", + "label": "8. Clever Math Problem Solving", "position": 8, "link": { "type": "generated-index", - "description": "第 8 章 巧解数学问题" + "description": "Chapter 8: Clever Math Problem Solving" } } diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/_category_.json index dc298905..cb4d422b 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/_category_.json +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/_category_.json @@ -1,8 +1,8 @@ { - "label": "9. 神奇的位运算 ", + "label": "9. Magical Bit Manipulation", "position": 9, "link": { "type": "generated-index", - "description": "第 9 章 神奇的位运算" + "description": "Chapter 9: Magical Bit Manipulation" } } diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-2-assignment-problems.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-2-assignment-problems.mdx index 23722515..0568cbdc 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-2-assignment-problems.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-2-assignment-problems.mdx @@ -78,6 +78,17 @@ def findContentChildren(children: List[int], cookies: List[int]) -> int: +### 複雜度分析 + +- **時間複雜度**:排序的時間為 $O(n \log n)$,雙指針遍歷的時間為 $O(n)$,因此總時間複雜度為: + $$ + O(n_{\text{children}} \log n_{\text{children}} + n_{\text{cookies}} \log n_{\text{cookies}}) + $$ +- **空間複雜度**:排序需要額外的 $O(n)$ 空間,總空間複雜度為: + $$ + O(n_{\text{children}} + n_{\text{cookies}}) + $$ + ## [135. Candy](https://leetcode.com/problems/candy/) ### 題目描述 @@ -140,4 +151,13 @@ def candy(ratings_list: List[int]) -> int:
        -
        \ No newline at end of file +
        + +### 複雜度分析 + +- 時間複雜度 + - 從左到右遍歷和從右到左遍歷各需花費 $O(n)$ 的時間。 + - 總時間複雜度為 $O(n)$。 + +- 空間複雜度 + - 使用一個額外的陣列 `candies` 來儲存每個小孩的糖果數量,因此空間複雜度為 $O(n)$。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-3-interval-problems.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-3-interval-problems.mdx index 6c0587f2..adaf8c1d 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-3-interval-problems.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-3-interval-problems.mdx @@ -72,4 +72,16 @@ def eraseOverlapIntervals(intervals: List[List[int]]) -> int:
        -
        \ No newline at end of file +
        + +### 複雜度分析 + +- **時間複雜度** + - 將區間依照結束時間進行排序需花費 $O(n \log n)$ 的時間。 + - 遍歷排序後的區間需花費 $O(n)$ 的時間。 + - 總時間複雜度為 $O(n \log n)$。 + +- **空間複雜度** + - 排序操作可能需要 $O(n)$ 的額外空間(基於 Timsort 實現)。 + - 其他變數(如 `removed` 和 `prev_end`)僅需 $O(1)$ 空間。 + - 總空間複雜度為 $O(n)$。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/_category_.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/_category_.json index 4119cb25..ef63db0a 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/_category_.json +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/_category_.json @@ -1,8 +1,8 @@ { - "label": "1. 最易懂的贪心算法", + "label": "1. 最易懂的貪心演算法", "position": 1, "link": { "type": "generated-index", - "description": "第 1 章 最易懂的贪心算法" + "description": "第 1 章 最易懂的貪心演算法" } } diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/_category_.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/_category_.json index 4a0b8ebd..bc804e26 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/_category_.json +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/_category_.json @@ -1,8 +1,8 @@ { - "label": "10. 妙用数据结构 ", + "label": "10. 妙用資料結構", "position": 10, "link": { "type": "generated-index", - "description": "第 10 章 妙用数据结构" + "description": "第 10 章 妙用資料結構" } } diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/_category_.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/_category_.json index 688feb04..bf71f88e 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/_category_.json +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/_category_.json @@ -1,8 +1,8 @@ { - "label": "11. 令人头大的字符串 ", + "label": "11. 頭痛的字串處理", "position": 11, "link": { "type": "generated-index", - "description": "第 11 章 令人头大的字符串" + "description": "第 11 章 頭痛的字串處理" } } diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/_category_.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/_category_.json index 184a7911..cec51af2 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/_category_.json +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/_category_.json @@ -1,8 +1,8 @@ { - "label": "12. 指针三剑客之一:链表", + "label": "12. 指標三劍客之一:鏈結串列", "position": 12, "link": { "type": "generated-index", - "description": "第 12 章 指针三剑客之一:链表" + "description": "第 12 章 指標三劍客之一:鏈結串列" } } diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/_category_.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/_category_.json index db81316e..4a692469 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/_category_.json +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/_category_.json @@ -1,8 +1,8 @@ { - "label": "13. 指针三剑客之二:树", + "label": "13. 指標三劍客之二:樹", "position": 13, "link": { "type": "generated-index", - "description": "第 13 章 指针三剑客之二:树" + "description": "第 13 章 指標三劍客之二:樹" } } diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/_category_.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/_category_.json index 7a36d4cd..5ee5393f 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/_category_.json +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/_category_.json @@ -1,8 +1,8 @@ { - "label": "14. 指针三剑客之三:图", + "label": "14. 指標三劍客之三:圖", "position": 14, "link": { "type": "generated-index", - "description": "第 14 章 指针三剑客之三:图" + "description": "第 14 章 指標三劍客之三:圖" } } diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/_category_.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/_category_.json index cbe6af2e..a38a7773 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/_category_.json +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/_category_.json @@ -1,8 +1,8 @@ { - "label": "15. 更加复杂的数据结构 ", + "label": "15. 更加複雜的資料結構", "position": 15, "link": { "type": "generated-index", - "description": "第 15 章 更加复杂的数据结构" + "description": "第 15 章 更加複雜的資料結構" } } diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/_category_.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/_category_.json index 89e9fd2f..36d8f9aa 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/_category_.json +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/_category_.json @@ -1,8 +1,8 @@ { - "label": "3. 居合斩!二分查找", + "label": "3. 居合斬!二分搜尋", "position": 3, "link": { "type": "generated-index", - "description": "第 3 章 居合斩!二分查找" + "description": "第 3 章 居合斬!二分搜尋" } } diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-2-depth-first-search.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-2-depth-first-search.mdx index 1c320d88..73ef96a8 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-2-depth-first-search.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-2-depth-first-search.mdx @@ -2,7 +2,7 @@ sidebar_position: 22 --- -# 5.2 深度优先搜索 +# 5.2 深度優先搜尋 `深度優先搜尋 (DFS)` 是一種搜尋方法,在搜尋到一個新節點時,會立即對該節點進行遍歷。因此,遍歷需要使用 `先入後出 (LIFO) 的堆疊`,也可以透過與堆疊等價的 `遞迴` 來實現。對於樹結構而言,由於每次總是對新節點進行遍歷,因此看起來像是往“深”的方向前進。在 Python 中,我們可以使用 collections.deque 來實現 C++ 中的堆疊。然而,在大多數情況下,我們會選擇使用 C++ 的 vector 或 Python 的 list 來實現堆疊,因為它們不僅是先入後出的數據結構,還支持隨機存取。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/_category_.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/_category_.json index 0943e8c5..5d112130 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/_category_.json +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/_category_.json @@ -1,8 +1,8 @@ { - "label": "5. 一切皆可搜索", + "label": "5. 一切皆可搜尋", "position": 5, "link": { "type": "generated-index", - "description": "第 5 章 一切皆可搜索" + "description": "第 5 章 一切皆可搜尋" } } diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-1-algorithm-explanation.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-1-algorithm-explanation.md index 48055183..12462a45 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-1-algorithm-explanation.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-1-algorithm-explanation.md @@ -4,10 +4,10 @@ sidebar_position: 26 # 6.1 算法解释 -这里我们引用一下维基百科的描述:“`动态规划`(Dynamic Programming, DP)在查找有很多`重叠子问题`的情况的最优解时有效。它将问题重新组合成子问题。为了避免多次解决这些子问题,它们的结果都逐渐被计算并被保存,从简单的问题直到整个问题都被解决。因此,动态规划保存递归时的结果,因而不会在解决同样的问题时花费时间 · · · · · · 动态规划只能应用于有`最优子结构`的问题。最优子结构的意思是局部最优解能决定全局最优解(对有些问题这个要求并不能完全满足,故有时需要引入一定的近似)。简单地说,问题能够分解成子问题来解决。” +這裡我們引用一下維基百科的描述:「`動態規劃`(Dynamic Programming, DP)在尋找有許多`重疊子問題`情況的最優解時非常有效。它將問題重新分解成子問題。為了避免多次解決這些子問題,它們的結果會逐步被計算並保存,從簡單的問題開始,直到整個問題被解決。因此,動態規劃保存遞迴中的結果,從而避免在解決相同問題時浪費時間⋯⋯ 動態規劃只能應用於有`最優子結構`的問題。最優子結構的意思是,局部最優解能夠決定全局最優解(對某些問題來說這個要求不完全滿足,因此有時需要引入一定的近似)。簡單來說,問題能夠分解成子問題來解決。」 -通俗一点来讲,动态规划和其它遍历算法(如深/广度优先搜索)都是将原问题拆成多个子问题然后求解,他们之间最本质的区别是,动态规划`保存子问题的解,避免重复计算`。解决动态规划问题的关键是找到`状态转移方程`,这样我们可以通过计算和储存子问题的解来求解最终问题。 +通俗來說,動態規劃與其他遍歷算法(如深度優先搜索或廣度優先搜索)的最大區別在於,動態規劃`保存子問題的解,避免重複計算`。解決動態規劃問題的關鍵是找到`狀態轉移方程`,通過計算與保存子問題的解來求解最終問題。 -同时,我们也可以对动态规划进行`空间压缩`,起到节省空间消耗的效果。这一技巧笔者将在之后的题目中介绍。 +同時,我們也可以對動態規劃進行`空間壓縮`,以節省空間消耗。這一技巧筆者會在後續題目中介紹。 -在一些情况下,动态规划可以看成是带有`状态记录`(memoization)的优先搜索。状态记录的意思为,如果一个子问题在优先搜索时已经计算过一次,我们可以把它的结果储存下来,之后遍历到该子问题的时候可以直接返回储存的结果。动态规划是自下而上的,即先解决子问题,再解决父问题;而用带有状态记录的优先搜索是自上而下的,即从父问题搜索到子问题,若重复搜索到同一个子问题则进行状态记录,防止重复计算。如果题目需求的是最终状态,那么使用动态搜索比较方便;如果题目需要输出所有的路径,那么使用带有状态记录的优先搜索会比较方便。 \ No newline at end of file +在某些情況下,動態規劃可以視為帶有`狀態記錄`(memoization)的優先搜索。狀態記錄的意思是,如果一個子問題在優先搜索時已經計算過一次,可以將結果保存下來,之後再次遍歷到該子問題時可以直接返回保存的結果。動態規劃是自下而上的,先解決子問題再解決父問題;而帶有狀態記錄的優先搜索是自上而下的,從父問題搜索到子問題,如果重複搜索到同一個子問題則記錄其狀態以防重複計算。如果題目需求的是最終狀態,使用動態規劃會比較方便;如果需要輸出所有的路徑,則使用帶有狀態記錄的優先搜索會更適合。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-2-basic-dp-1d.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-2-basic-dp-1d.mdx index 3fd95068..010aaa5c 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-2-basic-dp-1d.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-2-basic-dp-1d.mdx @@ -2,32 +2,36 @@ sidebar_position: 27 --- -# 6.2 基本动态规划:一维 +# 6.2 基本動態規劃:一維 ## [70. Climbing Stairs](https://leetcode.com/problems/climbing-stairs/) ### 題目描述 -给定 $n$ 节台阶,每次可以走一步或走两步,求一共有多少种方式可以走完这些台阶。 +給定 $n$ 階台階,每次可以走一步或兩步,求有多少種方法可以走完這些台階。 ### 輸入輸出範例 -输入是一个数字,表示台阶数量;输出是爬台阶的总方式。 +輸入是一個數字,表示台階的數量;輸出是爬完台階的總方法數。 ``` Input: 3 Output: 3 ``` -在这个样例中,一共有三种方法走完这三节台阶:每次走一步;先走一步,再走两步;先走两步,再走一步。 +在這個例子中,一共有三種方法可以爬完這三階台階: +1. 每次走一步。 +2. 先走一步,再走兩步。 +3. 先走兩步,再走一步。 ### 題解 -这是十分经典的斐波那契数列题。定义一个数组 dp,dp[i] 表示走到第 i 阶的方法数。因为我们每次可以走一步或者两步,所以第 i 阶可以从第 i-1 或 i-2 阶到达。换句话说,走到第 i 阶的方法数即为走到第 i-1 阶的方法数加上走到第 i-2 阶的方法数。这样我们就得到了状态转移方程 dp[i] = dp[i-1] + dp[i-2]。注意边界条件的处理。 +這是一道經典的費波那契數列題目。定義一個數組 `dp`,其中 `dp[i]` 表示到達第 $i$ 階的方法數。由於每次可以走一步或兩步,所以第 $i$ 階可以從第 $(i-1)$ 階或第 $(i-2)$ 階到達。換句話說,到達第 $i$ 階的方法數是到達第 $(i-1)$ 階的方法數加上到達第 $(i-2)$ 階的方法數。因此我們得到了狀態轉移方程:`dp[i] = dp[i-1] + dp[i-2]`。注意初始條件的處理。 :::warning -有的时候为了方便处理边界情况,我们可以在构造 dp 数组时多留一个位置,用来处理初始状态。本题即多留了一个第 0 阶的初始位置。 +為了方便處理邊界情況,我們可以在構造 `dp` 數組時多留一個位置,用於表示初始狀態。本題即額外留了一個第 0 階的初始位置。 + ::: @@ -59,7 +63,7 @@ def climbStairs(n: int) -> int:
        -进一步的,我们可以对动态规划进行空间压缩。因为 dp[i] 只与 dp[i-1] 和 dp[i-2] 有关,因此可以只用两个变量来存储 dp[i-1] 和 dp[i-2],使得原来的 $O(n)$ 空间复杂度优化为 $O(1)$ 复杂度。 +進一步的,我們可以對動態規劃進行空間壓縮。因為 dp[i] 只與 dp[i-1] 和 dp[i-2] 有關,因此可以只用兩個變數來存儲 dp[i-1] 和 dp[i-2],使得原來的 $O(n)$ 空間複雜度優化為 $O(1)$ 複雜度。 @@ -98,22 +102,31 @@ def climbStairs(n: int) -> int: ### 題目描述 -假如你是一个劫匪,并且决定抢劫一条街上的房子,每个房子内的钱财数量各不相同。如果你抢了两栋相邻的房子,则会触发警报机关。求在不触发机关的情况下最多可以抢劫多少钱。 +假如你是一个劫匪,并且決定搶劫一條街上的房子,每個房子內的財物數量各不相同。如果你搶了兩棟相鄰的房子,則會觸發警報機關。求在不觸發機關的情況下最多可以搶劫多少錢。 ### 輸入輸出範例 -输入是一个一维数组,表示每个房子的钱财数量;输出是劫匪可以最多抢劫的钱财数量。 +輸入是一個一維數組,表示每個房子的財物數量;輸出是劫匪可以最多搶劫的財物數量。 ``` Input: [2,7,9,3,1] Output: 12 ``` -在这个样例中,最多的抢劫方式为抢劫第 1、3、5 个房子。 +在這個範例中,最多的搶劫方式為搶劫第 1、3、5 個房子。 ### 題解 -定义一个数组 dp,dp[i] 表示抢劫到第 i 个房子时,可以抢劫的最大数量。我们考虑 dp[i],此时可以抢劫的最大数量有两种可能,一种是我们选择不抢劫这个房子,此时累计的金额即为 dp[i-1];另一种是我们选择抢劫这个房子,那么此前累计的最大金额只能是 dp[i-2],因为我们不能够抢劫第 i-1 个房子,否则会触发警报机关。因此本题的状态转移方程为 dp[i] = max(dp[i-1], nums[i-1] + dp[i-2])。 +定義一個數組 `dp`,其中 `dp[i]` 表示搶劫到第 `i` 個房子時,可以搶劫的最大金額。我們考慮 `dp[i]` 的值,此時可以搶劫的最大金額有兩種可能: + +1. **選擇不搶劫這個房子**:此時累計的金額為 `dp[i-1]`; +2. **選擇搶劫這個房子**:那麼此前累計的最大金額只能是 `dp[i-2]`,因為我們無法搶劫第 `i-1` 個房子,否則會觸發警報。 + +因此,這道題的狀態轉移方程為: + +$$ +dp[i] = \max(dp[i-1], dp[i-2] + \text{nums}[i-1]) +$$ @@ -147,7 +160,7 @@ def rob(nums: List[int]) -> int: -同样的,我们可以像题目 70 那样,对空间进行压缩。 +同樣的,我們可以像題目 70 那樣,對空間進行壓縮。由於 `dp[i]` 只與 `dp[i-1]` 和 `dp[i-2]` 有關,因此我們可以僅使用兩個變數來儲存這兩個值,將原來的 $O(n)$ 空間複雜度優化為 $O(1)$ 空間複雜度。 @@ -185,22 +198,22 @@ def rob(nums: List[int]) -> int: ### 題目描述 -给定一个数组,求这个数组中连续且等差的子数组一共有多少个。 +給定一個數組,求這個數組中連續且等差的子數組一共有多少個。 ### 輸入輸出範例 -输入是一个一维数组,输出是满足等差条件的连续子数组个数。 +輸入是一維數組,輸出是滿足等差條件的連續子數組個數。 ``` Input: nums = [1,2,3,4] Output: 3 ``` -在这个样例中,等差数列有 [1,2,3]、[2,3,4] 和 [1,2,3,4]。 +在這個範例中,等差數列有 [1,2,3]、[2,3,4] 和 [1,2,3,4]。 ### 題解 -因为要求是等差数列,可以很自然地想到子数组必定满足 num[i] - num[i-1] = num[i-1] - num[i-2]。这里我们对于 dp 数组的定义是以 i 结尾的,满足该条件的子数组数量。因为等差子数组可以在任意一个位置终结,所以我们需要对 dp 数组求和进行子数组统计。 +因為要求是等差數列,可以很自然地想到子數組必定滿足 `num[i] - num[i-1] = num[i-1] - num[i-2]`。這裡我們對於 `dp` 陣列的定義是以 `i` 結尾,且滿足該條件的子數組數量。因為等差子數組可以在任意一個位置終結,所以我們需要對 `dp` 陣列求和以進行子數組統計。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-3-basic-dp-2d.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-3-basic-dp-2d.mdx index 7a889374..e65a13c7 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-3-basic-dp-2d.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-3-basic-dp-2d.mdx @@ -2,18 +2,17 @@ sidebar_position: 28 --- -# 6.3 基本动态规划:二维 +# 6.3 基本動態規劃:二維 ## [64. Minimum Path Sum](https://leetcode.com/problems/minimum-path-sum/) ### 題目描述 -给定一个 $m × n$ 大小的非负整数矩阵,求从左上角开始到右下角结束的、经过的数字的和最 -小的路径。每次只能向右或者向下移动。 +給定一個 $m × n$ 大小的非負整數矩陣,求從左上角開始到右下角結束的、經過的數字的和最小的路徑。每次只能向右或者向下移動。 ### 輸入輸出範例 -输入是一个二维数组,输出是最优路径的数字和。 +輸入是二維數組,輸出是最優路徑的數字和。 ``` Input: @@ -23,15 +22,15 @@ Input: Output: 7 ``` -在这个样例中,最短路径为 1->3->1->1->1。 +在這個範例中,最短路徑為 1->3->1->1->1。 ### 題解 -我们可以定义一个同样是二维的 dp 数组,其中 dp[i][j] 表示从左上角开始到 (i, j) 位置的最优路径的数字和。因为每次只能向下或者向右移动,我们可以很直观地得到状态转移方程 dp[i][j] = grid[i][j] + min(dp[i-1][j], dp[i][j-1]),其中 grid 表示原数组。 +我們可以定義一個同樣是二維的 `dp` 陣列,其中 `dp[i][j]` 表示從左上角開始到 `(i, j)` 位置的最優路徑的數字和。因為每次只能向下或者向右移動,我們可以很直觀地得到狀態轉移方程 `dp[i][j] = grid[i][j] + min(dp[i-1][j], dp[i][j-1])`,其中 `grid` 表示原數組。 :::warning -Python 语言中,多维数组多初始化比较特殊,直接初始化为 [[val] * n] * m 会导致只是创造了 m 个 [[val] * n] 的引用。正确的初始化方法为 [[val for _ in range(n)] for _ in range(m)]。 +在 Python 中,多維數組的初始化比較特殊,直接初始化為 `[[val] * n] * m` 會導致只是創造了 `m` 個 `[[val] * n]` 的引用。正確的初始化方法為 `[[val for _ in range(n)] for _ in range(m)]`。 ::: @@ -83,16 +82,14 @@ def minPathSum(grid: List[List[int]]) -> int: -因为 dp 矩阵的每一个值只和左边和上面的值相关,我们可以使用空间压缩将 dp 数组压缩为一维。对于第 i 行,在遍历到第 j 列的时候,因为第 j-1 列已经更新过了,所以 dp[j-1] 代表 dp[i][j-1]的值;而 dp[j] 待更新,当前存储的值是在第 i-1 行的时候计算的,所以代表 dp[i-1][j] 的值。 +因為 dp 矩陣的每一個值只和左邊和上面的值相關,我們可以使用空間壓縮將 dp 陣列壓縮為一維。對於第 i 行,在遍歷到第 j 列的時候,因為第 j-1 列已經更新過了,所以 dp[j-1] 代表 dp[i][j-1] 的值;而 dp[j] 待更新,當前儲存的值是在第 i-1 行的時候計算的,所以代表 dp[i-1][j] 的值。 :::warning -如果不是很熟悉空间压缩技巧,笔者推荐您优先尝试写出非空间压缩的解法,如果时间充裕且力所能及再进行空间压缩。 +如果不是很熟悉空間壓縮技巧,建議您優先嘗試寫出非空間壓縮的解法,若時間充裕且能力允許再進行空間壓縮。 ::: - - @@ -146,11 +143,11 @@ def minPathSum(grid: List[List[int]]) -> int: ### 題目描述 -给定一个由 0 和 1 组成的二维矩阵,求每个位置到最近的 0 的距离。 +給定一個由 0 和 1 組成的二維矩陣,求每個位置到最近的 0 的距離。 ### 輸入輸出範例 -输入是一个二维 0-1 数组,输出是一个同样大小的非负整数数组,表示每个位置到最近的 0 的距离。 +輸入是一個二維 0-1 陣列,輸出是一個同樣大小的非負整數陣列,表示每個位置到最近的 0 的距離。 ``` Input: @@ -166,7 +163,9 @@ Output: ### 題解 -一般来说,因为这道题涉及到四个方向上的最近搜索,所以很多人的第一反应可能会是广度优先搜索。但是对于一个大小 $O(mn)$ 的二维数组,对每个位置进行四向搜索,最坏情况的时间复杂度(即全是 1)会达到恐怖的 $O(m^2n^2)$。一种办法是使用一个二维布尔值数组做 memoization,使得广度优先搜索不会重复遍历相同位置;另一种更简单的方法是,我们从左上到右下进行一次动态搜索,再从右下到左上进行一次动态搜索。两次动态搜索即可完成四个方向上的查找。 +一般來說,因為這道題涉及到四個方向上的最近搜尋,所以很多人的第一反應可能會是廣度優先搜尋。但是對於一個大小 $O(mn)$ 的二維陣列,對每個位置進行四向搜尋,最壞情況的時間複雜度(即全是 1)會達到驚人的 $O(m^2n^2)$。 + +一種方法是使用一個二維布林值陣列進行記憶化,使得廣度優先搜尋不會重複遍歷相同位置;另一種更簡單的方法是,我們從左上到右下進行一次動態搜尋,再從右下到左上進行一次動態搜尋。兩次動態搜尋即可完成四個方向上的查找。 @@ -240,11 +239,11 @@ def updateMatrix(matrix: List[List[int]]) -> List[List[int]]: ### 題目描述 -给定一个二维的 0-1 矩阵,求全由 1 构成的最大正方形面积。 +給定一個二維的 0-1 矩陣,求全由 1 構成的最大正方形面積。 ### 輸入輸出範例 -输入是一个二维 0-1 数组,输出是最大正方形面积。 +輸入是一個二維 0-1 陣列,輸出是最大正方形面積。 ``` Input: @@ -257,14 +256,14 @@ Output: 4 ### 題解 -对于在矩阵内搜索正方形或长方形的题型,一种常见的做法是定义一个二维 dp 数组,其中 dp[i][j] 表示满足题目条件的、以 (i, j) 为右下角的正方形或者长方形的属性。对于本题,则表示以 (i, j) 为右下角的全由 1 构成的最大正方形边长。如果当前位置是 0,那么 dp[i][j] 即为 0;如果当前位置是 1,我们假设 dp[i][j] = k,其充分条件为 dp[i-1][j-1]、dp[i][j-1] 和 dp[i-1][j] 的值必须都不小于 k − 1,否则 (i, j) 位置不可以构成一个面积为 $k^2$ 的正方形。同理,如果这三个值中的的最小值为 k − 1,则 (i, j) 位置一定且最大可以构成一个面积为 $k^2$ 的正方形。 +對於在矩陣內搜尋正方形或長方形的題型,一種常見的做法是定義一個二維 dp 陣列,其中 dp[i][j] 表示滿足題目條件的、以 (i, j) 為右下角的正方形或者長方形的屬性。對於本題,則表示以 (i, j) 為右下角的全由 1 構成的最大正方形邊長。如果當前位置是 0,那麼 dp[i][j] 即為 0;如果當前位置是 1,我們假設 dp[i][j] = k,其充分條件為 dp[i-1][j-1]、dp[i][j-1] 和 dp[i-1][j] 的值必須都不小於 k − 1,否則 (i, j) 位置不可以構成一個面積為 $k^2$ 的正方形。同理,如果這三個值中的最小值為 k − 1,則 (i, j) 位置一定且最大可以構成一個面積為 $k^2$ 的正方形。
        ![](6.1.png) -
        图 6.1: 题目 542 - 左边为一个 0-1 矩阵,右边为其对应的 dp 矩阵,我们可以发现最大的正方形边长为 3
        +
        圖 6.1: 題目 221 - 左邊為一個 0-1 矩陣,右邊為其對應的 dp 矩陣,我們可以發現最大的正方形邊長為 3
        diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-4-partition-problems.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-4-partition-problems.mdx index a1a38cdf..8f95ccaf 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-4-partition-problems.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-4-partition-problems.mdx @@ -2,28 +2,29 @@ sidebar_position: 29 --- -# 6.4 分割类型题 +# 6.4 分割類型題 ## [279. Perfect Squares](https://leetcode.com/problems/perfect-squares/) ### 題目描述 -给定一个正整数,求其最少可以由几个完全平方数相加构成。 +給定一個正整數,求其最少可以由幾個完全平方數相加構成。 ### 輸入輸出範例 -输入是给定的正整数,输出也是一个正整数,表示输入的数字最少可以由几个完全平方数相加构成。 +輸入是給定的正整數,輸出也是一個正整數,表示輸入的數字最少可以由幾個完全平方數相加構成。 ``` Input: n = 13 Output: 2 ``` -在这个样例中,13 的最少构成方法为 4+9。 +在這個樣例中,13 的最少構成方法為 4 + 9。 ### 題解 -对于分割类型题,动态规划的状态转移方程通常并不依赖相邻的位置,而是依赖于满足分割条件的位置。我们定义一个一维矩阵 dp,其中 dp[i] 表示数字 i 最少可以由几个完全平方数相加构成。在本题中,位置 i 只依赖 $i - j^2$ 的位置,如 i - 1、i - 4、i - 9 等等,才能满足完全平方分割的条件。因此 dp[i] 可以取的最小值即为 1+ min(dp[i-1], dp[i-4], dp[i-9] · · · )。注意边界条件的处理。 +對於分割類型題,動態規劃的狀態轉移方程通常並不依賴相鄰的位置,而是依賴於滿足分割條件的位置。我們定義一個一維矩陣 dp,其中 dp[i] 表示數字 i 最少可以由幾個完全平方數相加構成。在本題中,位置 i 只依賴 $i - j^2$ 的位置,如 i - 1、i - 4、i - 9 等等,才能滿足完全平方分割的條件。因此 dp[i] 可以取的最小值即為 1 + min(dp[i-1], dp[i-4], dp[i-9] · · · )。注意邊界條件的處理。 + @@ -61,22 +62,22 @@ def numSquares(n: int) -> int: ### 題目描述 -已知字母 A-Z 可以表示成数字 1-26。给定一个数字串,求有多少种不同的字符串等价于这个数字串。 +已知字母 A-Z 可以表示成數字 1-26。給定一個數字串,求有多少種不同的字符串等價於這個數字串。 ### 輸入輸出範例 -输入是一个由数字组成的字符串,输出是满足条件的解码方式总数。 +輸入是一個由數字組成的字符串,輸出是滿足條件的解碼方式總數。 ``` Input: "226" Output: 3 ``` -在这个样例中,有三种解码方式:BZ(2 26)、VF(22 6) 或 BBF(2 2 6)。 +在這個範例中,有三種解碼方式:BZ(2 26)、VF(22 6) 或 BBF(2 2 6)。 ### 題解 -这是一道很经典的动态规划题,难度不大但是十分考验耐心。这是因为只有 1-26 可以表示字母,因此对于一些特殊情况,比如数字 0 或者当相邻两数字大于 26 时,需要有不同的状态转移方程,详见如下代码。 +這是一道很經典的動態規劃題,難度不大但十分考驗耐心。這是因為只有 1-26 可以表示字母,因此對於一些特殊情況,例如數字 0 或相鄰兩數字大於 26 時,需要有不同的狀態轉移方程,詳見如下程式碼。 @@ -84,7 +85,7 @@ Output: 3 ```cpp int numDecodings(string s) { int n = s.length(); - int prev = s[0] - ’0’; + int prev = s[0] - '0'; if (prev == 0) { return 0; } @@ -93,22 +94,22 @@ int numDecodings(string s) { } vector dp(n + 1, 1); for (int i = 2; i <= n; ++i) { - int cur = s[i - 1] - ’0’; + int cur = s[i - 1] - '0'; if ((prev == 0 || prev > 2) && cur == 0) { - // 00, 30, 40, ..., 90, 非法。 + // 00, 30, 40, ..., 90 為非法組合。 return 0; } if ((prev < 2 && prev > 0) || (prev == 2 && cur <= 6)) { - // 10, 11, ..., 25, 26. + // 10, 11, ..., 25, 26。 if (cur == 0) { - // 10, 20,只能连续解码两位。 + // 10, 20,只能解碼為兩位數。 dp[i] = dp[i - 2]; } else { - // 可以解码当前位,也可以连续解码两位。 + // 可解碼為單位數,也可解碼為兩位數。 dp[i] = dp[i - 2] + dp[i - 1]; } } else { - // 合法,但只能解码当前位。 + // 合法但只能解碼為單位數。 dp[i] = dp[i - 1]; } prev = cur; @@ -132,18 +133,18 @@ def numDecodings(s: str) -> int: for i in range(2, n + 1): cur = ord(s[i - 1]) - ord("0") if (prev == 0 or prev > 2) and cur == 0: - # 00, 30, 40, ..., 90, 非法。 + # 00, 30, 40, ..., 90 為非法組合。 return 0 if 0 < prev < 2 or (prev == 2 and cur <= 6): - # 10, 11, ..., 25, 26. + # 10, 11, ..., 25, 26。 if cur == 0: - # 10, 20,只能连续解码两位。 + # 10, 20,只能解碼為兩位數。 dp[i] = dp[i - 2] else: - # 可以解码当前位,也可以连续解码两位。 + # 可解碼為單位數,也可解碼為兩位數。 dp[i] = dp[i - 2] + dp[i - 1] else: - # 合法,但只能解码当前位。 + # 合法但只能解碼為單位數。 dp[i] = dp[i - 1] prev = cur return dp[n] @@ -157,7 +158,7 @@ def numDecodings(s: str) -> int: ### 題目描述 -给定一个字符串和一个字符串集合,求是否存在一种分割方式,使得原字符串分割后的子字符串都可以在集合内找到。 +給定一個字串和一個字串集合,求是否存在一種分割方式,使得原字串分割後的子字串都可以在集合內找到。 ### 輸入輸出範例 @@ -166,11 +167,11 @@ Input: s = "applepenapple", wordDict = ["apple", "pen"] Output: true ``` -在这个样例中,字符串可以被分割为 [“apple”,“pen”,“apple”]。 +在這個範例中,字串可以被分割為 [“apple”,“pen”,“apple”]。 ### 題解 -类似于完全平方数分割问题,这道题的分割条件由集合内的字符串决定,因此在考虑每个分割位置时,需要遍历字符串集合,以确定当前位置是否可以成功分割。注意对于位置 0,需要初始化值为真。 +類似於完全平方數分割問題,這道題的分割條件由集合內的字串決定,因此在考慮每個分割位置時,需要遍歷字串集合,以確定當前位置是否可以成功分割。注意對於位置 0,需要初始化值為真。 @@ -186,8 +187,8 @@ bool wordBreak(string s, vector& wordDict) { if (i >= m && s.substr(i - m, m) == word) { dp[i] = dp[i - m]; } - // 提前剪枝,略微加速运算。 - // 如果不剪枝,上一行代码需要变更为 dp[i] = dp[i] || dp[i - m]; + // 提前剪枝,略微加速運算。 + // 如果不剪枝,上一行代碼需要變更為 dp[i] = dp[i] || dp[i - m]; if (dp[i]) { break; } @@ -209,8 +210,8 @@ def wordBreak(s: str, wordDict: List[str]) -> bool: m = len(word) if i >= m and s[i - m : i] == word: dp[i] = dp[i - m] - # 提前剪枝,略微加速运算。 - # 如果不剪枝,上一行代码需要变更为 dp[i] = dp[i] or dp[i-m] + # 提前剪枝,略微加速運算。 + # 如果不剪枝,上一行代碼需要變更為 dp[i] = dp[i] or dp[i-m] if dp[i]: break return dp[n] @@ -224,11 +225,10 @@ def wordBreak(s: str, wordDict: List[str]) -> bool: ### 題目描述 -给定一个数组,每个元素代表一本书的厚度和高度。问对于一个固定宽度的书架,如果按照数组中书的顺序从左到右、从上到下摆放,最小总高度是多少。 +給定一個陣列,每個元素代表一本書的厚度和高度。問對於一個固定寬度的書架,如果按照陣列中書的順序從左到右、從上到下擺放,最小總高度是多少。 ### 輸入輸出範例 - ``` Input: books = [[1,1],[2,3],[2,3],[1,1],[1,1],[1,1],[1,2]], shelfWidth = 4 Output: 6 @@ -239,12 +239,12 @@ Output: 6 ![](https://assets.leetcode.com/uploads/2019/06/24/shelves.png) -
        图 6.2: 书架摆放问题 - 样例图解
        +
        圖 6.2: 書架擺放問題 - 範例圖解
        ### 題解 -令 dp[i] 表示放置第 i 本书时的最小总高度,则 dp[i] 可以是在第 i-1 本书下面重新放一排,也可以是在满足不超过前一排宽度的情况下放在前一排。 +令 dp[i] 表示放置第 i 本書時的最小總高度,則 dp[i] 可以是在第 i-1 本書下面重新放一排,也可以是在滿足不超過前一排寬度的情況下放在前一排。 @@ -297,7 +297,7 @@ def minHeightShelves(books: List[List[int]], shelfWidth: int) -> int: ### 題目描述 -给定一个不重复数字的数组和一个目标数,求加起来是目标数的所有排列的总数量。(虽然这道题叫做 Combination Sum,但是不同顺序的组合会被当作不同答案,因此本质上是排列。) +給定一個不重複數字的陣列和一個目標數,求加起來等於目標數的所有排列的總數量。(雖然這道題叫做 Combination Sum,但不同順序的組合會被當作不同答案,因此本質上是排列。) ### 輸入輸出範例 @@ -306,12 +306,12 @@ Input: nums = [1,2,3], target = 4 Output: 7 ``` -七种不同的排列为 (1, 1, 1, 1)、(1, 1, 2)、(1, 2, 1)、(1, 3)、(2, 1, 1)、(2, 2) 和 (3, 1)。 +七種不同的排列為 (1, 1, 1, 1)、(1, 1, 2)、(1, 2, 1)、(1, 3)、(2, 1, 1)、(2, 2) 和 (3, 1)。 ### 題解 -令 dp[i] 表示加起来和为 i 时,满足条件的排列数量。在内循环中我们可以直接对所有合法数字进行拿取。这里注意,在 C++ 题解中,因为求和时很容易超过 int 上界,我们这里用 double 存储 dp 数组。 +令 dp[i] 表示加起來等於 i 時,滿足條件的排列數量。在內循環中我們可以直接對所有合法數字進行取用。這裡注意,在 C++ 解法中,因為求和時很容易超過 `int` 的上界,我們用 `double` 儲存 dp 陣列。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-5-subsequence-problems.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-5-subsequence-problems.mdx index 873d6ea2..6acdb1c0 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-5-subsequence-problems.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-5-subsequence-problems.mdx @@ -2,36 +2,36 @@ sidebar_position: 30 --- -# 6.5 子序列问题 +# 6.5 子序列問題 ## [300. Longest Increasing Subsequence](https://leetcode.com/problems/longest-increasing-subsequence/) ### 題目描述 -给定一个未排序的整数数组,求最长的递增子序列。 +給定一個未排序的整數陣列,求最長的遞增子序列。 :::warning -按照 LeetCode 的习惯,子序列(subsequence)不必连续,子数组(subarray)或子字符串(substring)必须连续。 +按照 LeetCode 的慣例,子序列(subsequence)不必連續,而子陣列(subarray)或子字串(substring)必須連續。 ::: ### 輸入輸出範例 -输入是一个一维数组,输出是一个正整数,表示最长递增子序列的长度。 +輸入是一個一維陣列,輸出是一個正整數,表示最長遞增子序列的長度。 ``` Input: [10,9,2,5,3,7,101,4] Output: 4 ``` -在这个样例中,最长递增子序列之一是 [2,3,7,101]。 +在這個範例中,最長遞增子序列之一是 [2,3,7,101]。 ### 題解 -对于子序列问题,第一种动态规划方法是,定义一个 dp 数组,其中 dp[i] 表示以 i 结尾的子序列的性质。在处理好每个位置后,统计一遍各个位置的结果即可得到题目要求的结果。 +對於子序列問題,第一種動態規劃方法是,定義一個 dp 陣列,其中 dp[i] 表示以 i 結尾的子序列的屬性。在處理好每個位置後,統計一遍各個位置的結果即可得到題目要求的結果。 -在本题中,dp[i] 可以表示以 i 结尾的、最长子序列长度。对于每一个位置 i,如果其之前的某个位置 j 所对应的数字小于位置 i 所对应的数字,则我们可以获得一个以 i 结尾的、长度为 dp[j] + 1 的子序列。为了遍历所有情况,我们需要 i 和 j 进行两层循环,其时间复杂度为 $O(n^2)$。 +在本題中,dp[i] 可以表示以 i 結尾的、最長子序列長度。對於每一個位置 i,如果其之前的某個位置 j 所對應的數字小於位置 i 所對應的數字,則我們可以獲得一個以 i 結尾的、長度為 dp[j] + 1 的子序列。為了遍歷所有情況,我們需要 i 和 j 進行兩層循環,其時間複雜度為 $O(n^2)$。 @@ -70,9 +70,9 @@ def lengthOfLIS(nums: List[int]) -> int: -本题还可以使用二分查找将时间复杂度降低为 $O(n \log n)$。我们定义一个 dp 数组,其中 dp[k] 存储长度为 k+1 的最长递增子序列的最后一个数字。我们遍历每一个位置 i,如果其对应的数字大于 dp 数组中所有数字的值,那么我们把它放在 dp 数组尾部,表示最长递增子序列长度加 1;如果我们发现这个数字在 dp 数组中比数字 a 大、比数字 b 小,则我们将 b 更新为此数字,使得之后构成递增序列的可能性增大。以这种方式维护的 dp 数组永远是递增的,因此可以用二分查找加速搜索。 +本題還可以使用二分搜尋將時間複雜度降低為 $O(n \log n)$。我們定義一個 dp 陣列,其中 dp[k] 儲存長度為 k+1 的最長遞增子序列的最後一個數字。我們遍歷每一個位置 i,如果其對應的數字大於 dp 陣列中所有數字的值,那麼我們把它放在 dp 陣列尾部,表示最長遞增子序列長度加 1;如果我們發現這個數字在 dp 陣列中比數字 a 大、比數字 b 小,則我們將 b 更新為此數字,使得之後構成遞增序列的可能性增大。以這種方式維護的 dp 陣列永遠是遞增的,因此可以用二分搜尋加速搜尋。 -以样例为例,对于数组 [10,9,2,5,3,7,101,4],我们每轮的更新查找情况为: +以範例為例,對於陣列 [10,9,2,5,3,7,101,4],我們每輪的更新搜尋情況為: ``` num dp @@ -86,9 +86,9 @@ num dp 4 [2,3,4,101] ``` -最终我们知道最长递增子序列的长度是 4。注意 dp 数组最终的形式并不一定是合法的排列形式,如 [2,3,4,101] 并不是子序列;但之前覆盖掉的 [2,3,7,101] 是最优解之一。 +最終我們知道最長遞增子序列的長度是 4。注意 dp 陣列最終的形式並不一定是合法的排列形式,如 [2,3,4,101] 並不是子序列;但之前覆蓋掉的 [2,3,7,101] 是最優解之一。 -类似的,对于其他题目,如果状态转移方程的结果递增或递减,且需要进行插入或查找操作,我们也可以使用二分法进行加速。 +類似的,對於其他題目,如果狀態轉移方程的結果遞增或遞減,且需要進行插入或搜尋操作,我們也可以使用二分法進行加速。 @@ -129,24 +129,24 @@ def lengthOfLIS(nums: List[int]) -> int: ### 題目描述 -给定两个字符串,求它们最长的公共子序列长度。 +給定兩個字串,求它們最長的公共子序列長度。 ### 輸入輸出範例 -输入是两个字符串,输出是一个整数,表示它们满足题目条件的长度。 +輸入是兩個字串,輸出是一個整數,表示它們滿足題目條件的長度。 ``` Input: text1 = "abcde", text2 = "ace" Output: 3 ``` -在这个样例中,最长公共子序列是“ace”。 +在這個範例中,最長公共子序列是「ace」。 ### 題解 -对于子序列问题,第二种动态规划方法是,定义一个 dp 数组,其中 dp[i] 表示到位置 i 为止的子序列的性质,并不必须以 i 结尾。这样 dp 数组的最后一位结果即为题目所求,不需要再对每个位置进行统计。 +對於子序列問題,第二種動態規劃方法是,定義一個 dp 陣列,其中 dp[i] 表示到位置 i 為止的子序列的性質,並不必須以 i 結尾。這樣 dp 陣列的最後一位結果即為題目所求,不需要再對每個位置進行統計。 -在本题中,我们可以建立一个二维数组 dp,其中 dp[i][j] 表示到第一个字符串位置 i 为止、到第二个字符串位置 j 为止、最长的公共子序列长度。这样一来我们就可以很方便地分情况讨论这两个位置对应的字母相同与不同的情况了。 +在本題中,我們可以建立一個二維陣列 dp,其中 dp[i][j] 表示到第一個字串位置 i 為止、到第二個字串位置 j 為止、最長的公共子序列長度。這樣一來我們就可以很方便地分情況討論這兩個位置對應的字母相同與不同的情況了。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-6-knapsack-problem.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-6-knapsack-problem.mdx index 3bf0fd5a..5197c4e5 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-6-knapsack-problem.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-6-knapsack-problem.mdx @@ -2,11 +2,11 @@ sidebar_position: 31 --- -# 6.6 背包问题 +# 6.6 背包問題 -`背包问题(knapsack problem)`是一种组合优化的 NP 完全问题:有 n 个物品和载重为 w 的背包,每个物品都有自己的重量 weight 和价值 value,求拿哪些物品可以使得背包所装下物品的总价值最大。如果限定每种物品只能选择 0 个或 1 个,则问题称为 `0-1 背包问题(0-1 knapsack)`;如果不限定每种物品的数量,则问题称为`无界背包问题或完全背包问题(unbounded knapsack)`。 +`背包問題(knapsack problem)` 是一種組合優化的 NP 完全問題:有 n 個物品和載重為 w 的背包,每個物品都有自己的重量 weight 和價值 value,求拿哪些物品可以使得背包所裝下物品的總價值最大。如果限定每種物品只能選擇 0 個或 1 個,則問題稱為 `0-1 背包問題(0-1 knapsack)`;如果不限定每種物品的數量,則問題稱為 `無界背包問題或完全背包問題(unbounded knapsack)`。 -我们可以用动态规划来解决背包问题。以 0-1 背包问题为例。我们可以定义一个二维数组 dp存储最大价值,其中 dp[i][j] 表示前 i 件物品重量不超过 j 的情况下能达到的最大价值。在我们遍历到第 i 件物品时,在当前背包总载重为 j 的情况下,如果我们不将物品 i 放入背包,那么 dp[i][j] = dp[i-1][j],即前 i 个物品的最大价值等于只取前 i-1 个物品时的最大价值;如果我们将物品 i 放入背包,假设第 i 件物品重量为 weight,价值为 value,那么我们得到 dp[i][j] = dp[i-1][j-weight] + value。我们只需在遍历过程中对这两种情况取最大值即可,总时间复杂度和空间复杂度都为 $O(nw)$。 +我們可以用動態規劃來解決背包問題。以 0-1 背包問題為例。我們可以定義一個二維陣列 dp 儲存最大價值,其中 dp[i][j] 表示前 i 件物品重量不超過 j 的情況下能達到的最大價值。在我們遍歷到第 i 件物品時,在當前背包總載重為 j 的情況下,如果我們不將物品 i 放入背包,那麼 dp[i][j] = dp[i-1][j],即前 i 個物品的最大價值等於只取前 i-1 個物品時的最大價值;如果我們將物品 i 放入背包,假設第 i 件物品重量為 weight,價值為 value,那麼我們得到 dp[i][j] = dp[i-1][j-weight] + value。我們只需在遍歷過程中對這兩種情況取最大值即可,總時間複雜度和空間複雜度都為 $O(nw)$。 @@ -53,10 +53,11 @@ def knapsack(weights: List[int], values: List[int], n: int, w: int) -> int: ![](6.3.png) -
        图 6.3: 0-1 背包问题 - 状态转移矩阵样例
        +
        圖 6.3: 0-1 背包問題 - 狀態轉移矩陣範例
        -我们可以进一步对 0-1 背包进行空间优化,将空间复杂度降低为 O(w)。如图所示,假设我们目前考虑物品 i = 2,且其重量为 weight = 2,价值为 value = 3;对于背包载重 j,我们可以得到 dp[2][j] = max(dp[1][j], dp[1][j-2] + 3)。这里可以发现我们永远只依赖于上一排 i = 1 的信息,之前算过的其他物品都不需要再使用。因此我们可以去掉 dp 矩阵的第一个维度,在考虑物品 i 时变成 dp[j] = max(dp[j], dp[j-weight] + value)。这里要注意我们在遍历每一行的时候必须`逆向遍历`,这样才能够调用上一行物品 i-1 时 dp[j-weight] 的值;若按照从左往右的顺序进行正向遍历,则dp[j-weight] 的值在遍历到 j 之前就已经被更新成物品 i 的值了。 +我們可以進一步對 0-1 背包進行空間優化,將空間複雜度降低為 $O(w)$。如圖所示,假設我們目前考慮物品 $i = 2$,且其重量為 $weight = 2$,價值為 $value = 3$;對於背包載重 $j$,我們可以得到 $dp[2][j] = max(dp[1][j], dp[1][j-2] + 3)$。這裡可以發現我們永遠只依賴於上一排 $i = 1$ 的資訊,之前算過的其他物品都不需要再使用。因此我們可以去掉 $dp$ 矩陣的第一個維度,在考慮物品 $i$ 時變成 $dp[j] = max(dp[j], dp[j-weight] + value)$。這裡要注意我們在遍歷每一行的時候必須 **逆向遍歷**,這樣才能夠調用上一行物品 $i-1$ 時 $dp[j-weight]$ 的值;若按照從左往右的順序進行正向遍歷,則 $dp[j-weight]$ 的值在遍歷到 $j$ 之前就已經被更新成物品 $i$ 的值了。 + @@ -91,16 +92,17 @@ def knapsack(weights: List[int], values: List[int], n: int, w: int) -> int: -在完全背包问题中,一个物品可以拿多次。如图上半部分所示,假设我们遍历到物品 i = 2,且其重量为 weight = 2,价值为 value = 3;对于背包载重 j = 5,最多只能装下 2 个该物品。那么我们的状态转移方程就变成了 dp[2][5] = max(dp[1][5], dp[1][3] + 3, dp[1][1] + 6)。如果采用这种方法,假设背包载重无穷大而物体的重量无穷小,我们这里的比较次数也会趋近于无穷大,远超$O(nw)$ 的时间复杂度。 +在完全背包問題中,一個物品可以拿多次。如圖上半部分所示,假設我們遍歷到物品 $i = 2$,且其重量為 $weight = 2$,價值為 $value = 3$;對於背包載重 $j = 5$,最多只能裝下 2 個該物品。那麼我們的狀態轉移方程就變成了 $dp[2][5] = max(dp[1][5], dp[1][3] + 3, dp[1][1] + 6)$。如果採用這種方法,假設背包載重無窮大而物品的重量無窮小,我們這裡的比較次數也會趨近於無窮大,遠超 $O(nw)$ 的時間複雜度。
        ![](6.4.png) -
        图 6.4: 完全背包问题 - 状态转移矩阵样例
        +
        圖 6.4: 完全背包問題 - 狀態轉移矩陣範例
        -怎么解决这个问题呢?我们发现在 dp[2][3] 的时候我们其实已经考虑了 dp[1][3] 和 dp[2][1] 的情况,而在时 dp[2][1] 也已经考虑了 dp[1][1] 的情况。因此,如图下半部分所示,对于拿多个物品的情况,我们只需考虑 dp[2][3] 即可,即 dp[2][5] = max(dp[1][5], dp[2][3] + 3)。这样,我们就得到了完全背包问题的状态转移方程:dp[i][j] = max(dp[i-1][j], dp[i][j-w] + v),其与 0-1 背包问题的差别仅仅是把状态转移方程中的第二个 i-1 变成了 i。 +怎麼解決這個問題呢?我們發現在 $dp[2][3]$ 的時候我們其實已經考慮了 $dp[1][3]$ 和 $dp[2][1]$ 的情況,而在 $dp[2][1]$ 時也已經考慮了 $dp[1][1]$ 的情況。因此,如圖下半部分所示,對於拿多個物品的情況,我們只需考慮 $dp[2][3]$ 即可,即 $dp[2][5] = max(dp[1][5], dp[2][3] + 3)$。這樣,我們就得到了完全背包問題的狀態轉移方程:$dp[i][j] = max(dp[i-1][j], dp[i][j-w] + v)$,其與 0-1 背包問題的差別僅僅是把狀態轉移方程中的第二個 $i-1$ 變成了 $i$。 + @@ -142,7 +144,7 @@ def knapsack(weights: List[int], values: List[int], n: int, w: int) -> int: -同样的,我们也可以利用空间压缩将时间复杂度降低为 $O(w)$。这里要注意我们在遍历每一行的时候必须`正向遍历`,因为我们需要利用当前物品在第 j-weight 列的信息。 +同樣的,我們也可以利用空間壓縮將時間複雜度降低為 $O(w)$。這裡要注意我們在遍歷每一行的時候必須`正向遍歷`,因為我們需要利用當前物品在第 $j-weight$ 列的信息。 @@ -179,7 +181,7 @@ def knapsack(weights: List[int], values: List[int], n: int, w: int) -> int: :::warning -压缩空间时到底需要正向还是逆向遍历呢?物品和重量哪个放在外层,哪个放在内层呢?这取决于状态转移方程的依赖关系。在思考空间压缩前,不妨将状态转移矩阵画出来,方便思考如何进行空间压缩,以及压缩哪个维度更省空间。 +壓縮空間時到底需要`正向`還是`逆向`遍歷呢?物品和重量哪個放在外層,哪個放在內層呢?這取決於狀態轉移方程的依賴關係。在思考空間壓縮前,不妨將狀態轉移矩陣畫出來,方便思考如何進行空間壓縮,以及壓縮哪個維度更省空間。 ::: @@ -187,22 +189,22 @@ def knapsack(weights: List[int], values: List[int], n: int, w: int) -> int: ### 題目描述 -给定一个正整数数组,求是否可以把这个数组分成和相等的两部分。 +給定一個正整數數組,求是否可以把這個數組分成和相等的兩部分。 ### 輸入輸出範例 -输入是一个一维正整数数组,输出时一个布尔值,表示是否可以满足题目要求。 +輸入是一個一維正整數數組,輸出是一個布林值,表示是否可以滿足題目要求。 ``` Input: [1,5,11,5] Output: true ``` -在这个样例中,满足条件的分割方法是 [1,5,5] 和 [11]。 +在這個範例中,滿足條件的分割方法是 [1,5,5] 和 [11]。 ### 題解 -本题等价于 0-1 背包问题,设所有数字和为 sum,我们的目标是选取一部分物品,使得它们的总和为 sum/2。这道题不需要考虑价值,因此我们只需要通过一个布尔值矩阵来表示状态转移矩阵。注意边界条件的处理。 +本題等價於 0-1 背包問題,設所有數字和為 sum,我們的目標是選取一部分物品,使得它們的總和為 sum/2。這道題不需要考慮價值,因此我們只需要通過一個布林值矩陣來表示狀態轉移矩陣。注意邊界條件的處理。 @@ -253,7 +255,7 @@ def canPartition(nums: List[int]) -> bool: -同样的,我们也可以对本题进行空间压缩。注意对数字和的遍历需要逆向。 +同樣的,我們也可以對本題進行空間壓縮。注意對數字和的遍歷需要逆向。 @@ -300,23 +302,23 @@ def canPartition(nums: List[int]) -> bool: ### 題目描述 -给定 $m$ 个数字 0 和 $n$ 个数字 1,以及一些由 0-1 构成的字符串,求利用这些数字最多可以构成多少个给定的字符串,字符串只可以构成一次。 +給定 $m$ 個數字 0 和 $n$ 個數字 1,以及一些由 0-1 構成的字串,求利用這些數字最多可以構成多少個給定的字串,字串只可以構成一次。 ### 輸入輸出範例 -输入两个整数 $m$ 和 $n$,表示 0 和 1 的数量,以及一个一维字符串数组,表示待构成的字符串; -输出是一个整数,表示最多可以生成的字符串个数。 +輸入兩個整數 $m$ 和 $n$,表示 0 和 1 的數量,以及一維字串陣列,表示待構成的字串; +輸出是一個整數,表示最多可以生成的字串個數。 ``` Input: Array = {"10", "0001", "111001", "1", "0"}, m = 5, n = 3 Output: 4 ``` -在这个样例中,我们可以用 5 个 0 和 3 个 1 构成 [“10”, “0001”, “1”, “0”]。 +在這個範例中,我們可以用 5 個 0 和 3 個 1 構成 [“10”, “0001”, “1”, “0”]。 ### 題解 -这是一个多维费用的 0-1 背包问题,有两个背包大小,0 的数量和 1 的数量。我们在这里直接展示三维空间压缩到二维后的写法。 +這是一個多維費用的 0-1 背包問題,有兩個背包大小,分別是 0 的數量和 1 的數量。以下直接展示將三維空間壓縮到二維後的寫法。 @@ -366,24 +368,24 @@ def findMaxForm(strs: List[str], m: int, n: int) -> int: ### 題目描述 -给定一些硬币的面额,求最少可以用多少颗硬币组成给定的金额。 +給定一些硬幣的面額,求最少可以用多少顆硬幣組成給定的金額。 ### 輸入輸出範例 -输入一个一维整数数组,表示硬币的面额;以及一个整数,表示给定的金额。输出一个整数,表示满足条件的最少的硬币数量。若不存在解,则返回-1。 +輸入一個一維整數陣列,表示硬幣的面額;以及一個整數,表示給定的金額。輸出一個整數,表示滿足條件的最少的硬幣數量。若不存在解,則返回 -1。 ``` Input: coins = [1, 2, 5], amount = 11 Output: 3 ``` -在这个样例中,最少的组合方法是 11 = 5 + 5 + 1。 +在這個範例中,最少的組合方法是 11 = 5 + 5 + 1。 ### 題解 -因为每个硬币可以用无限多次,这道题本质上是完全背包。我们直接展示二维空间压缩为一维的写法。 +因為每個硬幣可以用無限多次,這道題本質上是完全背包。我們直接展示二維空間壓縮為一維的寫法。 -这里注意,我们把 dp 数组初始化为 amount + 1 而不是-1 的原因是,在动态规划过程中有求最小值的操作,如果初始化成-1 则会导致结果始终为-1。至于为什么取这个值,是因为 i 最大可以取 amount,而最多的组成方式是只用 1 元硬币,因此 amount + 1 一定大于所有可能的组合方式,取最小值时一定不会是它。在动态规划完成后,若结果仍然是此值,则说明不存在满足条件的组合方法,返回-1。 +這裡注意,我們把 `dp` 陣列初始化為 `amount + 1` 而不是 `-1` 的原因是,在動態規劃過程中有求最小值的操作,如果初始化成 `-1` 則會導致結果始終為 `-1`。至於為什麼取這個值,是因為 `i` 最大可以取 `amount`,而最多的組成方式是只用 1 元硬幣,因此 `amount + 1` 一定大於所有可能的組合方式,取最小值時一定不會是它。在動態規劃完成後,若結果仍然是此值,則說明不存在滿足條件的組合方法,返回 `-1`。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-7-string-editing.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-7-string-editing.mdx index bbc7ffc7..d23f2bcd 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-7-string-editing.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-7-string-editing.mdx @@ -2,28 +2,34 @@ sidebar_position: 32 --- -# 6.7 字符串编辑 +# 6.7 字符串編輯 ## [72. Edit Distance](https://leetcode.com/problems/edit-distance/) ### 題目描述 -给定两个字符串,已知你可以删除、替换和插入任意字符串的任意字符,求最少编辑几步可以将两个字符串变成相同。 +給定兩個字符串,已知你可以刪除、替換和插入任意字符串的任意字符,求最少編輯幾步可以將兩個字符串變成相同。 ### 輸入輸出範例 -输入是两个字符串,输出是一个整数,表示最少的步骤。 +輸入是兩個字符串,輸出是一個整數,表示最少的步驟。 ``` Input: word1 = "horse", word2 = "ros" Output: 3 ``` -在这个样例中,一种最优编辑方法是 horse -> rorse -> rose -> ros。 +在這個範例中,一種最優編輯方法是 horse -> rorse -> rose -> ros。 ### 題解 -类似于题目 1143,我们使用一个二维数组 dp[i][j],表示将第一个字符串到位置 i 为止,和第二个字符串到位置 j 为止,最多需要几步编辑。当第 i 位和第 j 位对应的字符相同时,dp[i][j] 等于 dp[i-1][j-1];当二者对应的字符不同时,修改的消耗是 dp[i-1][j-1]+1,插入 i 位置/删除 j 位置的消耗是 dp[i][j-1] + 1,插入 j 位置/删除 i 位置的消耗是 dp[i-1][j] + 1。 +類似於題目 1143,我們使用一個二維數組 `dp[i][j]`,表示將第一個字符串到位置 `i` 為止,和第二個字符串到位置 `j` 為止,最多需要幾步編輯。 + +- 當第 `i` 位和第 `j` 位對應的字符相同時,`dp[i][j] = dp[i-1][j-1]`; +- 當兩者對應的字符不相同時: + - 修改的消耗為 `dp[i-1][j-1] + 1`; + - 插入 `i` 位置/刪除 `j` 位置的消耗為 `dp[i][j-1] + 1`; + - 插入 `j` 位置/刪除 `i` 位置的消耗為 `dp[i-1][j] + 1`。 @@ -75,22 +81,22 @@ def minDistance(word1: str, word2: str) -> int: ### 題目描述 -给定一个字母 A,已知你可以每次选择复制全部字符,或者粘贴之前复制的字符,求最少需要几次操作可以把字符串延展到指定长度。 +給定一個字母 A,已知你可以每次選擇複製全部字符,或者粘貼之前複製的字符,求最少需要幾次操作可以把字符串延展到指定長度。 ### 輸入輸出範例 -输入是一个正整数,代表指定长度;输出是一个整数,表示最少操作次数。 +輸入是一個正整數,代表指定長度;輸出是一個整數,表示最少操作次數。 ``` Input: 3 Output: 3 ``` -在这个样例中,一种最优的操作方法是先复制一次,再粘贴两次。 +在這個範例中,一種最優的操作方法是先複製一次,再貼上兩次。 ### 題解 -不同于以往通过加减实现的动态规划,这里需要乘除法来计算位置,因为粘贴操作是倍数增加的。我们使用一个一维数组 dp,其中位置 i 表示延展到长度 i 的最少操作次数。对于每个位置 j,如果 j 可以被 i 整除,那么长度 i 就可以由长度 j 操作得到,其操作次数等价于把一个长度为 j 的 A 延展到长度为 i/j。因此我们可以得到递推公式 dp[i] = dp[j] + dp[i/j]。 +不同於以往通過加減實現的動態規劃,這裡需要乘除法來計算位置,因為粘貼操作是倍數增加的。我們使用一個一維數組 dp,其中位置 i 表示延展到長度 i 的最少操作次數。對於每個位置 j,如果 j 可以被 i 整除,那麼長度 i 就可以由長度 j 操作得到,其操作次數等價於把一個長度為 j 的 A 延展到長度為 i/j。因此我們可以得到遞推公式 dp[i] = dp[j] + dp[i/j]。 @@ -103,7 +109,7 @@ int minSteps(int n) { for (int j = 2; j * j <= i; ++j) { if (i % j == 0) { dp[i] = dp[j] + dp[i / j]; - // 提前剪枝,因为j从小到大,因此操作数量一定最小。 + // 提前剪枝,因為j從小到大,因此操作數量一定最小。 break; } } @@ -122,7 +128,7 @@ def minSteps(n: int) -> int: for j in range(2, floor(sqrt(i)) + 1): if i % j == 0: dp[i] = dp[j] + dp[i // j] - # 提前剪枝,因为j从小到大,因此操作数量一定最小。 + # 提前剪枝,因為j從小到大,因此操作數量一定最小。 break return dp[n] ``` diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-8-stock-trading.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-8-stock-trading.mdx index 691fd7e3..4ea4a8e7 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-8-stock-trading.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-8-stock-trading.mdx @@ -4,28 +4,28 @@ sidebar_position: 33 # 6.8 股票交易 -`股票交易`类问题通常可以用动态规划来解决。对于稍微复杂一些的股票交易类问题,比如需要冷却时间或者交易费用,则可以用通过动态规划实现的`状态机`来解决。 +`股票交易`類問題通常可以用動態規劃來解決。對於稍微複雜一些的股票交易類問題,比如需要冷卻時間或者交易費用,則可以通過動態規劃實現的`狀態機`來解決。 ## [121. Best Time to Buy and Sell Stock](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/) ### 題目描述 -给定一段时间内每天某只股票的固定价格,已知你只可以买卖各一次,求最大的收益。 +給定一段時間內每天某只股票的固定價格,已知你只可以買賣各一次,求最大的收益。 ### 輸入輸出範例 -输入一个一维整数数组,表示每天的股票价格;输出一个整数,表示最大的收益。 +輸入一個一維整數數組,表示每天的股票價格;輸出一個整數,表示最大的收益。 ``` Input: [7,1,5,3,6,4] Output: 5 ``` -在这个样例中,最大的利润为在第二天价格为 1 时买入,在第五天价格为 6 时卖出。 +在這個範例中,最大的利潤為在第二天價格為 1 時買入,在第五天價格為 6 時賣出。 ### 題解 -我们可以遍历一遍数组,在每一个位置 i 时,记录 i 位置之前所有价格中的最低价格,然后将当前的价格作为售出价格,查看当前收益是不是最大收益即可。注意本题中以及之后题目中的buy 和 sell 表示买卖操作时,用户账户的收益。因此买时为负,卖时为正。 +我們可以遍歷一遍數組,在每一個位置 i 時,記錄 i 位置之前所有價格中的最低價格,然後將當前的價格作為賣出價格,查看當前收益是否為最大收益即可。注意本題中以及之後題目中的 buy 和 sell 表示買賣操作時,用戶賬戶的收益。因此買時為負,賣時為正。 @@ -61,22 +61,22 @@ def maxProfit(prices: List[int]) -> int: ### 題目描述 -给定一段时间内每天某只股票的固定价格,已知你只可以买卖各 $k$ 次,且每次只能拥有一支股票,求最大的收益。 +給定一段時間內每天某只股票的固定價格,已知你只可以買賣各 $k$ 次,且每次只能擁有一支股票,求最大的收益。 ### 輸入輸出範例 -输入一个一维整数数组,表示每天的股票价格;以及一个整数,表示可以买卖的次数 $k$。输出一个整数,表示最大的收益。 +輸入一個一維整數數組,表示每天的股票價格;以及一個整數,表示可以買賣的次數 $k$。輸出一個整數,表示最大的收益。 ``` Input: [3,2,6,5,0,3], k = 2 Output: 7 ``` -在这个样例中,最大的利润为在第二天价格为 2 时买入,在第三天价格为 6 时卖出;再在第五天价格为 0 时买入,在第六天价格为 3 时卖出。 +在這個範例中,最大的利潤為在第二天價格為 2 時買入,在第三天價格為 6 時賣出;再在第五天價格為 0 時買入,在第六天價格為 3 時賣出。 ### 題解 -类似地,我们可以建立两个动态规划数组 buy 和 sell,对于每天的股票价格,buy[j] 表示在第 j 次买入时的最大收益,sell[j] 表示在第 j 次卖出时的最大收益。 +類似地,我們可以建立兩個動態規劃數組 `buy` 和 `sell`,對於每天的股票價格,`buy[j]` 表示在第 $j$ 次買入時的最大收益,`sell[j]` 表示在第 $j$ 次賣出時的最大收益。 @@ -118,28 +118,28 @@ def maxProfit(k: int, prices: List[int]) -> int: ### 題目描述 -给定一段时间内每天某只股票的固定价格,已知每次卖出之后必须冷却一天,且每次只能拥有一支股票,求最大的收益。 +給定一段時間內每天某只股票的固定價格,已知每次賣出之後必須冷卻一天,且每次只能擁有一支股票,求最大的收益。 ### 輸入輸出範例 -输入一个一维整数数组,表示每天的股票价格;输出一个整数,表示最大的收益。 +輸入一個一維整數數組,表示每天的股票價格;輸出一個整數,表示最大的收益。 ``` Input: [1,2,3,0,2] Output: 3 ``` -在这个样例中,最大的利润获取操作是买入、卖出、冷却、买入、卖出。 +在這個範例中,最大的利潤獲取操作是買入、賣出、冷卻、買入、賣出。 ### 題解 -我们可以使用状态机来解决这类复杂的状态转移问题,通过建立多个状态以及它们的转移方式,我们可以很容易地推导出各个状态的转移方程。如图所示,我们可以建立四个状态来表示带有冷却的股票交易,以及它们的之间的转移方式。 +我們可以使用狀態機來解決這類複雜的狀態轉移問題。通過建立多個狀態以及它們的轉移方式,我們可以很容易地推導出各個狀態的轉移方程。如圖所示,我們可以建立四個狀態來表示帶有冷卻的股票交易,以及它們之間的轉移方式。
        ![](6.5.png) -
        图 6.5: 题目 309 - 状态机状态转移
        +
        圖 6.5: 題目 309 - 狀態機狀態轉移
        diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-9-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-9-exercises.md index 97958de4..6372250f 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-9-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-9-exercises.md @@ -8,38 +8,38 @@ sidebar_position: 34 ### [213. House Robber II](https://leetcode.com/problems/house-robber-ii/) -强盗抢劫题目的 follow-up,如何处理环形数组呢? +強盜搶劫問題的 follow-up,如何處理環形數組呢? ### [53. Maximum Subarray](https://leetcode.com/problems/maximum-subarray/) -经典的一维动态规划题目,试着把一维空间优化为常量吧。 +經典的一維動態規劃題目,試著把一維空間優化為常量吧。 ### [343. Integer Break](https://leetcode.com/problems/integer-break/) -分割类型题,先尝试用动态规划求解,再思考是否有更简单的解法。 +分割類型題,先嘗試用動態規劃求解,再思考是否有更簡單的解法。 ### [583. Delete Operation for Two Strings](https://leetcode.com/problems/delete-operation-for-two-strings/) -最长公共子序列的变种题。 +最長公共子序列的變種題。 ## 進階難度 ### [646. Maximum Length of Pair Chain](https://leetcode.com/problems/maximum-length-of-pair-chain/) -最长递增子序列的变种题,同样的,尝试用二分进行加速。 +最長遞增子序列的變種題,同樣的,嘗試用二分進行加速。 ### [10. Regular Expression Matching](https://leetcode.com/problems/regular-expression-matching/) -正则表达式匹配,非常考验耐心。需要根据正则表达式的不同情况,即字符、星号,点号等,分情况讨论。 +正則表達式匹配,非常考驗耐心。需要根據正則表達式的不同情況,即字符、星號,點號等,分情況討論。 ### [376. Wiggle Subsequence](https://leetcode.com/problems/wiggle-subsequence/) -最长摆动子序列,通项公式比较特殊,需要仔细思考。 +最長擺動子序列,通項公式比較特殊,需要仔細思考。 ### [494. Target Sum](https://leetcode.com/problems/target-sum/) -如果告诉你这道题是 0-1 背包,你是否会有一些思路? +如果告訴你這道題是 0-1 背包,你是否會有一些思路? ### [714. Best Time to Buy and Sell Stock with Transaction Fee](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/) -建立状态机,股票交易类问题就会迎刃而解。 \ No newline at end of file +建立狀態機,股票交易類問題就會迎刃而解。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/_category_.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/_category_.json index 1a2cb467..bf74ea61 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/_category_.json +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/_category_.json @@ -1,8 +1,8 @@ { - "label": "6. 深入浅出动态规划", + "label": "6. 深入淺出動態規劃", "position": 6, "link": { "type": "generated-index", - "description": "第 6 章 深入浅出动态规划" + "description": "第 6 章 深入淺出動態規劃" } } diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/_category_.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/_category_.json index 2535d2d4..2a461e56 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/_category_.json +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/_category_.json @@ -1,8 +1,8 @@ { - "label": "7. 化繁为简的分治法", + "label": "7. 化繁為簡的分治法", "position": 7, "link": { "type": "generated-index", - "description": "第 7 章 化繁为简的分治法" + "description": "第 7 章 化繁為簡的分治法" } } diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/_category_.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/_category_.json index 5fb8df9e..007997b1 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/_category_.json +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/_category_.json @@ -1,8 +1,8 @@ { - "label": "8. 巧解数学问题 ", + "label": "8. 巧解數學問題", "position": 8, "link": { "type": "generated-index", - "description": "第 8 章 巧解数学问题" + "description": "第 8 章 巧解數學問題" } } diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/_category_.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/_category_.json index dc298905..c58b167a 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/_category_.json +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/_category_.json @@ -1,8 +1,8 @@ { - "label": "9. 神奇的位运算 ", + "label": "9. 神奇的位元運算", "position": 9, "link": { "type": "generated-index", - "description": "第 9 章 神奇的位运算" + "description": "第 9 章 神奇的位元運算" } } From 01074a0d78bd2a63151e287f16d127fbfaa87a83 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Sun, 24 Nov 2024 21:14:18 +0100 Subject: [PATCH 22/49] i18n chapter 7 --- .../7-1-algorithm-explanation.md | 20 +++++++++---------- .../7-2-expression-problems.mdx | 17 ++++++++-------- .../7-divide-and-conquer/7-3-exercises.md | 4 ++-- .../7-1-algorithm-explanation.md | 16 +++++++-------- .../7-2-expression-problems.mdx | 16 +++++++-------- .../7-divide-and-conquer/7-3-exercises.md | 4 ++-- 6 files changed, 39 insertions(+), 38 deletions(-) diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-1-algorithm-explanation.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-1-algorithm-explanation.md index 8c1f25c4..392dceaf 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-1-algorithm-explanation.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-1-algorithm-explanation.md @@ -2,21 +2,21 @@ sidebar_position: 35 --- -# 7.1 算法解释 +# 7.1 Algorithm Explanation -顾名思义,`分治问题`由“分”(divide)和“治”(conquer)两部分组成,通过把原问题分为子问题,再将子问题进行处理合并,从而实现对原问题的求解。我们在排序章节展示的归并排序就是典型的分治问题,其中“分”即为把大数组平均分成两个小数组,通过递归实现,最终我们会得到多个长度为 1 的子数组;“治”即为把已经排好序的两个小数组合成为一个排好序的大数组从长度为 1 的子数组开始,最终合成一个大数组。 +As the name suggests, `divide and conquer` problems consist of two parts: "divide" and "conquer." By breaking the original problem into subproblems and then solving and merging these subproblems, we can solve the original problem. Merge sort, introduced in the sorting chapter, is a classic example of divide and conquer. In merge sort, the "divide" step splits the array into two smaller arrays using recursion until we get multiple arrays of length 1. The "conquer" step merges two sorted arrays into a single sorted array, starting from arrays of length 1 and eventually forming the final array. -我们也使用数学表达式来表示这个过程。定义 $T(n)$ 表示处理一个长度为 $n$ 的数组的时间复杂度,则归并排序的时间复杂度递推公式为 $T(n) =2T(n/2) +O(n)$。其中 $2T(n/2)$ 表示我们分成了两个长度减半的子问题,$O(n)$ 则为合并两个长度为 $n/2$ 数组的时间复杂度。 +We can also use a mathematical expression to describe this process. Let $T(n)$ represent the time complexity of processing an array of length $n$. The recurrence relation for merge sort is $T(n) = 2T(n/2) + O(n)$. Here, $2T(n/2)$ represents splitting the array into two halves, and $O(n)$ represents the time complexity of merging two arrays of length $n/2$. -:::info 定理 7.1. 主定理 +:::info Theorem 7.1. Master Theorem -考虑 $T(n) =aT(n/b) + f (n)$,定义 $k =\log_{b} a$ -1. 如果 $f (n) =O(n^p)$ 且 $p < k$,那么 $T(n) =O(n^K)$ -2. 如果存在 $c ≥ 0$ 满足 $f (n) =O(n^k \log^c n)$,那么 $T(n) = O(n^k \log^{c+1} n)$ -3. 如果 $f (n) =O(n^p)$ 且 $p > k$,那么 $T(n) =O( f (n))$ +For $T(n) = aT(n/b) + f(n)$, define $k = \log_{b} a$: +1. If $f(n) = O(n^p)$ and $p < k$, then $T(n) = O(n^k)$ +2. If there exists $c \geq 0$ such that $f(n) = O(n^k \log^c n)$, then $T(n) = O(n^k \log^{c+1} n)$ +3. If $f(n) = O(n^p)$ and $p > k$, then $T(n) = O(f(n))$ ::: -通过主定理我们可以知道,归并排序属于第二种情况,且时间复杂度为 $O(n \log n)$。其他的分治问题也可以通过主定理求得时间复杂度。 +Using the master theorem, we can deduce that merge sort falls into the second category with a time complexity of $O(n \log n)$. Other divide-and-conquer problems can also use the master theorem to determine their time complexities. -另外,自上而下的分治可以和 memoization 结合,避免重复遍历相同的子问题。如果方便推导,也可以换用自下而上的动态规划方法求解。 \ No newline at end of file +Additionally, top-down divide-and-conquer can be combined with memoization to avoid redundant traversal of identical subproblems. Alternatively, if it's convenient for derivation, a bottom-up dynamic programming approach can be used instead. \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-2-expression-problems.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-2-expression-problems.mdx index 1a13bec4..8a5eeb02 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-2-expression-problems.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-2-expression-problems.mdx @@ -2,28 +2,28 @@ sidebar_position: 36 --- -# 7.2 表达式问题 +# 7.2 Expression Problems ## [241. Different Ways to Add Parentheses](https://leetcode.com/problems/different-ways-to-add-parentheses/) ### Problem Description -给定一个只包含加、减和乘法的数学表达式,求通过加括号可以得到多少种不同的结果。 +Given a mathematical expression containing addition, subtraction, and multiplication, find all possible results by adding parentheses in different ways. ### Input and Output Example -输入是一个字符串,表示数学表达式;输出是一个数组,存储所有不同的加括号结果。 +The input is a string representing a mathematical expression, and the output is an array containing all unique results. ``` Input: "2-1-1" Output: [0, 2] ``` -在这个样例中,有两种加括号结果:((2-1)-1) = 0 和 (2-(1-1)) = 2。 +In this example, there are two ways to add parentheses: ((2-1)-1) = 0 and (2-(1-1)) = 2. ### Solution Explanation -利用分治思想,我们可以把加括号转化为,对于每个运算符号,先执行处理两侧的数学表达式,再处理此运算符号。注意边界情况,即字符串内无运算符号,只有数字。 +Using the divide-and-conquer approach, we can break down the problem by considering each operator, first solving the sub-expressions on both sides of the operator, and then combining the results using the operator. Special attention is needed for the base case where the input string contains no operators, only a single number. @@ -76,14 +76,15 @@ def diffWaysToCompute(expression: str) -> List[int]: -我们发现,某些被 divide 的子字符串可能重复出现多次,因此我们可以用 memoization 来去重。比如建立一个哈希表,key 是 (l, r),value 是 ways。每次遇到相同的 (l, r),我们可以直接返回已经计算过的 ways。或者与其我们从上到下用分治处理 +memoization,不如直接从下到上用动态规划处理。 +We observe that some substrings produced by the `divide` step may appear multiple times. To avoid redundant calculations, we can use `memoization`. For instance, we can create a hash table where the `key` is `(l, r)` and the `value` is `ways`. Whenever the same `(l, r)` appears again, we can directly return the previously computed `ways`. Alternatively, instead of using a top-down divide-and-conquer approach with `memoization`, we could adopt a bottom-up dynamic programming approach. + ```cpp vector diffWaysToCompute(string expression) { - // 利用istringstream, 将数字和操作符进行分词。 + // Use istringstream to split numbers and operators. vector nums; vector ops; int num = 0; @@ -125,7 +126,7 @@ vector diffWaysToCompute(string expression) { ```py def diffWaysToCompute(expression: str) -> List[int]: - # re.split可以将操作符(\D)和数字直接分开。 + # re.split can directly separate operators (\D) and numbers. sections = re.split(r"(\D)", expression) nums = [int(num) for num in sections if num.isdigit()] ops = [op for op in sections if not op.isdigit()] diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-3-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-3-exercises.md index 348cff97..29634892 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-3-exercises.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-3-exercises.md @@ -8,10 +8,10 @@ sidebar_position: 37 ### [932. Beautiful Array](https://leetcode.com/problems/beautiful-array/) -试着用从上到下的分治(递归)写法求解,最好加上 memoization;再用从下到上的动态规划写法求解。 +Try solving this using a top-down divide-and-conquer (recursive) approach with `memoization` for optimization; then attempt a bottom-up dynamic programming approach. ## Advanced Difficulty ### [312. Burst Balloons](https://leetcode.com/problems/burst-balloons/) -试着用从上到下的分治(递归)写法求解,最好加上 memoization;再用从下到上的动态规划写法求解。 \ No newline at end of file +Try solving this using a top-down divide-and-conquer (recursive) approach with `memoization` for optimization; then attempt a bottom-up dynamic programming approach. \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-1-algorithm-explanation.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-1-algorithm-explanation.md index 8c1f25c4..222b79a9 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-1-algorithm-explanation.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-1-algorithm-explanation.md @@ -4,19 +4,19 @@ sidebar_position: 35 # 7.1 算法解释 -顾名思义,`分治问题`由“分”(divide)和“治”(conquer)两部分组成,通过把原问题分为子问题,再将子问题进行处理合并,从而实现对原问题的求解。我们在排序章节展示的归并排序就是典型的分治问题,其中“分”即为把大数组平均分成两个小数组,通过递归实现,最终我们会得到多个长度为 1 的子数组;“治”即为把已经排好序的两个小数组合成为一个排好序的大数组从长度为 1 的子数组开始,最终合成一个大数组。 +顧名思義,`分治問題`由“分”(divide)和“治”(conquer)兩部分組成,通過把原問題分為子問題,再將子問題進行處理合併,從而實現對原問題的求解。我們在排序章節展示的合併排序就是典型的分治問題,其中“分”即為把大數組平均分成兩個小數組,通過遞迴實現,最終我們會得到多個長度為 1 的子數組;“治”即為把已經排好序的兩個小數組合併為一個排好序的大數組,從長度為 1 的子數組開始,最終合成一個大數組。 -我们也使用数学表达式来表示这个过程。定义 $T(n)$ 表示处理一个长度为 $n$ 的数组的时间复杂度,则归并排序的时间复杂度递推公式为 $T(n) =2T(n/2) +O(n)$。其中 $2T(n/2)$ 表示我们分成了两个长度减半的子问题,$O(n)$ 则为合并两个长度为 $n/2$ 数组的时间复杂度。 +我們也使用數學表達式來表示這個過程。定義 $T(n)$ 表示處理一個長度為 $n$ 的數組的時間複雜度,則合併排序的時間複雜度遞推公式為 $T(n) = 2T(n/2) + O(n)$。其中 $2T(n/2)$ 表示我們分成了兩個長度減半的子問題,$O(n)$ 則為合併兩個長度為 $n/2$ 數組的時間複雜度。 :::info 定理 7.1. 主定理 -考虑 $T(n) =aT(n/b) + f (n)$,定义 $k =\log_{b} a$ -1. 如果 $f (n) =O(n^p)$ 且 $p < k$,那么 $T(n) =O(n^K)$ -2. 如果存在 $c ≥ 0$ 满足 $f (n) =O(n^k \log^c n)$,那么 $T(n) = O(n^k \log^{c+1} n)$ -3. 如果 $f (n) =O(n^p)$ 且 $p > k$,那么 $T(n) =O( f (n))$ +考慮 $T(n) = aT(n/b) + f(n)$,定義 $k = \log_{b} a$ +1. 如果 $f(n) = O(n^p)$ 且 $p < k$,那麼 $T(n) = O(n^k)$ +2. 如果存在 $c \geq 0$ 滿足 $f(n) = O(n^k \log^c n)$,那麼 $T(n) = O(n^k \log^{c+1} n)$ +3. 如果 $f(n) = O(n^p)$ 且 $p > k$,那麼 $T(n) = O(f(n))$ ::: -通过主定理我们可以知道,归并排序属于第二种情况,且时间复杂度为 $O(n \log n)$。其他的分治问题也可以通过主定理求得时间复杂度。 +通過主定理我們可以知道,合併排序屬於第二種情況,且時間複雜度為 $O(n \log n)$。其他的分治問題也可以通過主定理求得時間複雜度。 -另外,自上而下的分治可以和 memoization 结合,避免重复遍历相同的子问题。如果方便推导,也可以换用自下而上的动态规划方法求解。 \ No newline at end of file +另外,自上而下的分治可以和 memoization 結合,避免重複遍歷相同的子問題。如果方便推導,也可以換用自下而上的動態規劃方法求解。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-2-expression-problems.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-2-expression-problems.mdx index b4cbcabf..6b67e6cf 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-2-expression-problems.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-2-expression-problems.mdx @@ -2,28 +2,28 @@ sidebar_position: 36 --- -# 7.2 表达式问题 +# 7.2 表達式問題 ## [241. Different Ways to Add Parentheses](https://leetcode.com/problems/different-ways-to-add-parentheses/) ### 題目描述 -给定一个只包含加、减和乘法的数学表达式,求通过加括号可以得到多少种不同的结果。 +給定一個只包含加、減和乘法的數學表達式,求通過加括號可以得到多少種不同的結果。 ### 輸入輸出範例 -输入是一个字符串,表示数学表达式;输出是一个数组,存储所有不同的加括号结果。 +輸入是一個字符串,表示數學表達式;輸出是一個數組,儲存所有不同的加括號結果。 ``` Input: "2-1-1" Output: [0, 2] ``` -在这个样例中,有两种加括号结果:((2-1)-1) = 0 和 (2-(1-1)) = 2。 +在這個範例中,有兩種加括號結果:((2-1)-1) = 0 和 (2-(1-1)) = 2。 ### 題解 -利用分治思想,我们可以把加括号转化为,对于每个运算符号,先执行处理两侧的数学表达式,再处理此运算符号。注意边界情况,即字符串内无运算符号,只有数字。 +利用分治思想,我們可以把加括號轉化為,對於每個運算符號,先執行處理兩側的數學表達式,再處理此運算符號。注意邊界情況,即字符串內無運算符號,只有數字。 @@ -76,14 +76,14 @@ def diffWaysToCompute(expression: str) -> List[int]: -我们发现,某些被 divide 的子字符串可能重复出现多次,因此我们可以用 memoization 来去重。比如建立一个哈希表,key 是 (l, r),value 是 ways。每次遇到相同的 (l, r),我们可以直接返回已经计算过的 ways。或者与其我们从上到下用分治处理 +memoization,不如直接从下到上用动态规划处理。 +我們發現,某些被 `divide` 的子字串可能重複出現多次,因此我們可以利用 `memoization` 來避免重複計算。例如,我們可以建立一個哈希表,`key` 是 `(l, r)`,`value` 是 `ways`。當再次遇到相同的 `(l, r)` 時,我們可以直接返回已經計算過的 `ways`。或者,與其我們從上到下用分治法結合 `memoization`,不如直接從下到上使用動態規劃處理。 ```cpp vector diffWaysToCompute(string expression) { - // 利用istringstream, 将数字和操作符进行分词。 + // 利用 istringstream,將數字和運算符進行分詞。 vector nums; vector ops; int num = 0; @@ -125,7 +125,7 @@ vector diffWaysToCompute(string expression) { ```py def diffWaysToCompute(expression: str) -> List[int]: - # re.split可以将操作符(\D)和数字直接分开。 + # re.split 可以直接將運算符(\D)和數字分開。 sections = re.split(r"(\D)", expression) nums = [int(num) for num in sections if num.isdigit()] ops = [op for op in sections if not op.isdigit()] diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-3-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-3-exercises.md index 2ea02c9f..ed0c659c 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-3-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-3-exercises.md @@ -8,10 +8,10 @@ sidebar_position: 37 ### [932. Beautiful Array](https://leetcode.com/problems/beautiful-array/) -试着用从上到下的分治(递归)写法求解,最好加上 memoization;再用从下到上的动态规划写法求解。 +嘗試使用從上到下的分治(遞迴)寫法進行求解,並最好加入 `memoization` 優化;之後再嘗試使用從下到上的動態規劃寫法求解。 ## 進階難度 ### [312. Burst Balloons](https://leetcode.com/problems/burst-balloons/) -试着用从上到下的分治(递归)写法求解,最好加上 memoization;再用从下到上的动态规划写法求解。 \ No newline at end of file +嘗試使用從上到下的分治(遞迴)寫法進行求解,並最好加入 `memoization` 優化;之後再嘗試使用從下到上的動態規劃寫法求解。 From 43940ac413e754123beff612b716185eaf633cf8 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Sun, 24 Nov 2024 21:55:40 +0100 Subject: [PATCH 23/49] i18n chapter 8 --- .../8-1-introduction.md | 2 +- .../8-mathematical-solutions/8-2-lcm-gcd.mdx | 6 +-- .../8-3-prime-numbers.mdx | 36 ++++++------- .../8-4-number-processing.mdx | 40 +++++++-------- .../8-5-random-sampling.mdx | 50 ++++++++++--------- .../8-mathematical-solutions/8-6-exercises.md | 14 +++--- .../8-1-introduction.md | 2 +- .../8-mathematical-solutions/8-2-lcm-gcd.mdx | 7 ++- .../8-3-prime-numbers.mdx | 36 +++++++------ .../8-4-number-processing.mdx | 41 +++++++-------- .../8-5-random-sampling.mdx | 40 ++++++++------- .../8-mathematical-solutions/8-6-exercises.md | 14 +++--- 12 files changed, 145 insertions(+), 143 deletions(-) diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-1-introduction.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-1-introduction.md index d753971e..e05b8c10 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-1-introduction.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-1-introduction.md @@ -4,4 +4,4 @@ sidebar_position: 38 # 8.1 引言 -对于 LeetCode 上数量不少的数学题,我们尽量将其按照类型划分讲解。然而很多数学题的解法并不通用,我们也很难一口气把所有的套路讲清楚,因此我们只选择了几道经典或是典型的题目,供大家参考。 \ No newline at end of file +For the numerous math problems on LeetCode, we strive to categorize and explain them by type. However, many math problems have solutions that are not universally applicable, making it challenging to summarize all problem-solving techniques in one go. Therefore, we have selected a few classic or representative problems for your reference. \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-2-lcm-gcd.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-2-lcm-gcd.mdx index 58dda1b8..a4aac979 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-2-lcm-gcd.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-2-lcm-gcd.mdx @@ -2,9 +2,9 @@ sidebar_position: 39 --- -# 8.2 公倍数与公因数 +# 8.2 Least Common Multiple and Greatest Common Divisor -利用`辗转相除法`,我们可以很方便地求得两个数的最大公因数(greatest common divisor,GCD);将两个数相乘再除以最大公因数即可得到最小公倍数(least common multiple, LCM)。 +Using the `Euclidean algorithm`, we can efficiently calculate the greatest common divisor (GCD) of two numbers. Multiplying the two numbers and dividing the product by their GCD gives the least common multiple (LCM). @@ -35,7 +35,7 @@ def lcm(a: int, b: int) -> int: -进一步地,我们也可以通过扩展欧几里得算法(extended gcd)在求得 a 和 b 最大公因数的同时,也得到它们的系数 x 和 y,从而使 ax + by = gcd(a, b)。因为 Python 中 int 只能按值传递,我们可以用一个长度固定为 1 的 list() 来进行传递引用的操作。 +Furthermore, using the extended Euclidean algorithm (extended GCD), we can calculate not only the GCD of a and b but also their coefficients x and y such that ax + by = gcd(a, b). In Python, since int is passed by value, we can use a fixed-length list() to achieve reference passing. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-3-prime-numbers.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-3-prime-numbers.mdx index 5712ce64..b0c8134f 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-3-prime-numbers.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-3-prime-numbers.mdx @@ -2,31 +2,32 @@ sidebar_position: 40 --- -# 8.3 质数 +# 8.3 Prime Numbers -质数又称素数,指的是指在大于 1 的自然数中,除了 1 和它本身以外不再有其他因数的自然数。值得注意的是,每一个数都可以分解成质数的乘积。 +Prime numbers are integers greater than 1 that have no divisors other than 1 and themselves. It is important to note that every number can be expressed as a product of prime numbers. ## [204. Count Primes](https://leetcode.com/problems/count-primes/) ### Problem Description -给定一个数字 n,求小于 n 的质数的个数。 +Given a number \( n \), find the count of prime numbers less than \( n \). ### Input and Output Example -输入一个整数,输出也是一个整数,表示小于输入数的质数的个数。 +Input an integer and output another integer representing the count of prime numbers less than the input number. ``` Input: 10 Output: 4 ``` -在这个样例中,小于 10 的质数只有 [2,3,5,7]。 +In this example, the prime numbers less than 10 are [2, 3, 5, 7]. ### Solution Explanation -`埃拉托斯特尼筛法`(Sieve of Eratosthenes,简称埃氏筛法)是非常常用的,判断一个整数是否是质数的方法。并且它可以在判断一个整数 n 时,同时判断所小于 n 的整数,因此非常适合这道题。其原理也十分易懂:从 1 到 n 遍历,假设当前遍历到 m,则把所有小于 n 的、且是 m 的倍数的整数标为和数;遍历完成后,没有被标为和数的数字即为质数。 +The `Sieve of Eratosthenes` is a widely used algorithm for determining whether an integer is a prime number. It is particularly efficient for determining all prime numbers less than a given integer $n$. The principle is simple: iterate through numbers from $1$ to $n$, and for the current number $m$, mark all multiples of $m$ (less than $n$) as composite numbers. After processing, the numbers not marked as composite are prime. + @@ -37,7 +38,7 @@ int countPrimes(int n) { return 0; } vector primes(n, true); - int count = n - 2; // 去掉不是质数的1 + int count = n - 2; // Remove the non-prime number 1 for (int i = 2; i < n; ++i) { if (primes[i]) { for (int j = 2 * i; j < n; j += i) { @@ -60,7 +61,7 @@ def countPrimes(n: int) -> int: if n <= 2: return 0 primes = [True for _ in range(n)] - count = n - 2 # 去掉不是质数的1 + count = n - 2 # Remove the non-prime number 1 for i in range(2, n): if primes[i]: for j in range(2 * i, n, i): @@ -74,8 +75,7 @@ def countPrimes(n: int) -> int: -利用质数的一些性质,我们可以进一步优化该算法。 - +By leveraging certain properties of prime numbers, we can further optimize this algorithm. @@ -87,11 +87,11 @@ int countPrimes(int n) { } vector primes(n, true); int sqrtn = sqrt(n); - int count = n / 2; // 偶数一定不是质数 + int count = n / 2; // Even numbers are not prime int i = 3; - // 最小质因子一定小于等于开方数。 + // The smallest prime factor is always less than or equal to the square root. while (i <= sqrtn) { - // 向右找倍数,注意避免偶数和重复遍历。 + // Find multiples to the right, avoiding even numbers and redundant checks. for (int j = i * i; j < n; j += 2 * i) { if (primes[j]) { --count; @@ -99,7 +99,7 @@ int countPrimes(int n) { } } i += 2; - // 向右前进查找位置,注意避免偶数和重复遍历。 + // Move to the next position to the right, avoiding even numbers and redundant checks. while (i <= sqrtn && !primes[i]) { i += 2; } @@ -117,17 +117,17 @@ def countPrimes(n: int) -> int: return 0 primes = [True for _ in range(n)] sqrtn = sqrt(n) - count = n // 2 # 偶数一定不是质数 + count = n // 2 # Even numbers are not prime i = 3 - # 最小质因子一定小于等于开方数。 + # The smallest prime factor is always less than or equal to the square root. while i <= sqrtn: - # 向右找倍数,注意避免偶数和重复遍历。 + # Find multiples to the right, avoiding even numbers and redundant checks. for j in range(i * i, n, 2 * i): if primes[j]: count -= 1 primes[j] = False i += 2 - # 向右前进查找位置,注意避免偶数和重复遍历。 + # Move to the next position to the right, avoiding even numbers and redundant checks. while i <= sqrtn and not primes[i]: i += 2 return count diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-4-number-processing.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-4-number-processing.mdx index 765acb36..db72a64a 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-4-number-processing.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-4-number-processing.mdx @@ -2,28 +2,28 @@ sidebar_position: 41 --- -# 8.4 数字处理 +# 8.4 Numerical Processing ## [504. Base 7](https://leetcode.com/problems/base-7/) ### Problem Description -给定一个十进制整数,求它在七进制下的表示。 +Given a decimal integer, convert it to its base-7 representation. ### Input and Output Example -输入一个整数,输出一个字符串,表示其七进制。 +Input a decimal integer and output a string representing its base-7 format. ``` Input: 100 Output: "202" ``` -在这个样例中,100 的七进制表示法来源于 101 = 2 * 49 + 0 * 7 + 2 * 1。 +In this example, 100 in base-7 comes from 100 = 2 * 49 + 0 * 7 + 2 * 1. ### Solution Explanation -`进制转换`类型的题,通常是利用除法和取模(mod)来进行计算,同时也要注意一些细节,如负数和零。如果输出是数字类型而非字符串,则也需要考虑是否会超出整数上下界。 +For `base conversion` problems, division and modulus (mod) are typically used for calculations. Special attention is needed for edge cases such as negative numbers and zero. If the output is expected as a numeric type rather than a string, consider whether it might exceed integer bounds. @@ -70,22 +70,22 @@ def convertToBase7(num: int) -> str: ### Problem Description -给定一个非负整数,判断它的阶乘结果的结尾有几个 0。 +Given a non-negative integer, determine how many trailing zeroes are in its factorial result. ### Input and Output Example -输入一个非负整数,输出一个非负整数,表示输入的阶乘结果的结尾有几个 0。 +Input a non-negative integer and output a non-negative integer representing the number of trailing zeroes in the factorial result. ``` Input: 12 Output: 2 ``` -在这个样例中,12 != 479001600 的结尾有两个 0。 +In this example, 12! = 479001600 has two trailing zeroes. ### Solution Explanation -每个尾部的 0 由 2 × 5 =10 而来,因此我们可以把阶乘的每一个元素拆成质数相乘,统计有多少个 2 和 5。明显的,质因子 2 的数量远多于质因子 5 的数量,因此我们可以只统计阶乘结果里有多少个质因子 5。 +Each trailing 0 is produced by a factor of 2 × 5 = 10. Therefore, we can decompose each element in the factorial into its prime factors and count how many 2s and 5s there are. It is evident that the number of factor 2s is far greater than the number of factor 5s, so we only need to count the number of factor 5s in the factorial result. @@ -112,23 +112,21 @@ def trailingZeroes(n: int) -> int: ### Problem Description -给定两个由数字组成的字符串,求它们相加的结果。 +Given two strings composed of digits, find their sum as a result. ### Input and Output Example -输入是两个字符串,输出是一个整数,表示输入的数字和。 +Input consists of two strings, and output is an integer representing the sum of the input numbers. ``` Input: num1 = "99", num2 = "1" Output: 100 ``` -因为相加运算是从后往前进行的,所以可以先翻转字符串,再逐位计算。这种类型的题考察的是细节,如进位、位数差等等。 +Since addition proceeds from right to left, the strings can be reversed first, then calculated digit by digit. This type of problem tests attention to details, such as carrying and handling different string lengths. ### Solution Explanation - - @@ -188,11 +186,11 @@ def addStrings(num1: str, num2: str) -> str: ### Problem Description -判断一个数字是否是 3 的次方。 +Determine whether a number is a power of 3. ### Input and Output Example -输入一个整数,输出一个布尔值。 +Input an integer, output a boolean value. ``` Input: n = 27 @@ -201,7 +199,7 @@ Output: true ### Solution Explanation -有两种方法,一种是利用对数。设 log3 n =m,如果 n 是 3 的整数次方,那么 m 一定是整数。 +There are two methods. One is using logarithms. Let log3 n = m, if n is an integer power of 3, then m must be an integer. @@ -224,7 +222,7 @@ def isPowerOfThree(n: int) -> bool: -另一种方法是,因为在 C++ int 范围内 3 的最大次方是 $3^{19} = 1162261467$,如果 n 是 3 的整数次方,那么 1162261467 除以 n 的余数一定是零;反之亦然。然而对于 Python 来说,因为 int 理论上可以取无穷大,我们只能循环判断。 +Another method is that, within the range of a C++ `int`, the maximum power of 3 is $3^{19} = 1162261467$. If `n` is an integer power of 3, then `1162261467 % n` must equal zero; otherwise, it is not. However, in Python, since `int` can theoretically represent arbitrarily large numbers, we can only use a loop to verify. @@ -255,11 +253,11 @@ def isPowerOfThree(n: int) -> bool: ### Problem Description -计算 x 的 n 次方。 +Compute `x` raised to the power `n`. ### Input and Output Example -输入一个浮点数表示 x 和一个整数表示 n,输出一个浮点数表示次方结果。 +Input a floating-point number `x` and an integer `n`, output a floating-point number representing the result of the power computation. ``` Input: x = 2.00000, n = 10 @@ -269,7 +267,7 @@ Output: 1024.00000 ### Solution Explanation -利用递归,我们可以较为轻松地解决本题。注意边界条件的处理。 +Using recursion, we can solve this problem relatively easily. Pay attention to handling edge cases. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-5-random-sampling.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-5-random-sampling.mdx index 0d9386c8..8b494b7d 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-5-random-sampling.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-5-random-sampling.mdx @@ -2,28 +2,28 @@ sidebar_position: 42 --- -# 8.5 随机与取样 +# 8.5 Random and Sampling ## [384. Shuffle an Array](https://leetcode.com/problems/shuffle-an-array/) ### Problem Description -给定一个数组,要求实现两个指令函数。第一个函数“shuffle”可以随机打乱这个数组,第二个函数“reset”可以恢复原来的顺序。 +Given an array, implement two functions. The first function `shuffle` randomly shuffles the array, and the second function `reset` restores the array to its original order. ### Input and Output Example -输入是一个存有整数数字的数组,和一个包含指令函数名称的数组。输出是一个二维数组,表示每个指令生成的数组。 +Input is an array of integers and a list of function names. Output is a two-dimensional array representing the result of each function call. ``` Input: nums = [1,2,3], actions: ["shuffle","shuffle","reset"] Output: [[2,1,3],[3,2,1],[1,2,3]] ``` -在这个样例中,前两次打乱的结果只要是随机生成即可。 +In this example, the first two shuffle results can be any random permutations. ### Solution Explanation -我们采用经典的 `Fisher-Yates 洗牌算法`,原理是通过随机交换位置来实现随机打乱,有正向和反向两种写法,且实现非常方便。注意这里“reset”函数以及 Solution 类的构造函数的实现细节。 +We use the classical `Fisher-Yates Shuffle Algorithm`, which works by swapping elements randomly to shuffle the array. Both forward and backward implementations are equally valid. Pay attention to the implementation details of the `reset` function and the constructor of the `Solution` class. @@ -38,12 +38,11 @@ class Solution { vector shuffle() { vector shuffled(nums_); int n = nums_.size(); - // 可以使用反向或者正向洗牌,效果相同。 - // 反向洗牌: + // Reverse shuffle: effective and equivalent. for (int i = n - 1; i >= 0; --i) { swap(shuffled[i], shuffled[rand() % (i + 1)]); } - // 正向洗牌: + // Forward shuffle: another valid approach. // for (int i = 0; i < n; ++i) { // int pos = rand() % (n - i); // swap(shuffled[i], shuffled[i+pos]); @@ -70,12 +69,11 @@ class Solution: def shuffle(self) -> List[int]: shuffled = self.base[:] n = len(self.base) - # 可以使用反向或者正向洗牌,效果相同。 - # 反向洗牌: + # Reverse shuffle: effective and equivalent. for i in range(n - 1, -1, -1): j = random.randint(0, i) shuffled[i], shuffled[j] = shuffled[j], shuffled[i] - # 正向洗牌: + # Forward shuffle: another valid approach. # for i in range(n): # j = i + random.randint(0, n - i - 1) # shuffled[i], shuffled[j] = shuffled[j], shuffled[i] @@ -90,26 +88,26 @@ class Solution: ### Problem Description -给定一个数组,数组每个位置的值表示该位置的权重,要求按照权重的概率去随机采样。 +Given an array where each position's value represents its weight, implement a method to randomly sample indices based on these weights. ### Input and Output Example -输入是一维正整数数组,表示权重;和一个包含指令字符串的一维数组,表示运行几次随机采样。输出是一维整数数组,表示随机采样的整数在数组中的位置。 +Input consists of a one-dimensional positive integer array representing weights, and another one-dimensional string array of commands specifying the number of random samples. Output is a one-dimensional integer array indicating the sampled indices. ``` Input: weights = [1,3], actions: ["pickIndex","pickIndex","pickIndex"] Output: [0,1,1] ``` -在这个样例中,每次选择的位置都是不确定的,但选择第 0 个位置的期望为 1/4,选择第 1 个位置的期望为 3/4。 +In this example, the chosen index is uncertain each time, but the expected probability for index 0 is 1/4, and for index 1 is 3/4. ### Solution Explanation -我们可以先使用 partial_sum求前缀和(即到每个位置为止之前所有数字的和),这个结果对于正整数数组是单调递增的。每当需要采样时,我们可以先随机产生一个数字,然后使用二分法查找其在前缀和中的位置,以模拟加权采样的过程。这里的二分法可以用 lower_bound 实现。 +We can first calculate the prefix sum using `partial_sum`, which gives the cumulative sum of weights up to each position. The resulting array for positive integers is monotonically increasing. When sampling, we generate a random number and use binary search to locate its position within the prefix sum, simulating the weighted sampling process. This binary search can be implemented using `lower_bound`. -以样例为例,权重数组 [1,3] 的前缀和为 [1,4]。如果我们随机生成的数字为 1,那么 lower_bound 返回的位置为 0;如果我们随机生成的数字是 2、3、4,那么 lower_bound 返回的位置为 1。 +For the example, the prefix sum of weights [1,3] is [1,4]. If the random number is 1, `lower_bound` returns 0; if the random number is 2, 3, or 4, `lower_bound` returns 1. -关于前缀和的更多技巧,我们将在接下来的章节中继续深入讲解。 +We'll delve deeper into prefix sum techniques in the following sections. @@ -155,26 +153,32 @@ class Solution: ### Problem Description -给定一个单向链表,要求设计一个算法,可以随机取得其中的一个数字。 +Given a singly linked list, design an algorithm to randomly return one of its values. ### Input and Output Example -输入是一个单向链表,输出是一个数字,表示链表里其中一个节点的值。 +Input is a singly linked list, output is a number representing the value of one of its nodes. ``` Input: 1->2->3->4->5 Output: 3 ``` -在这个样例中,我们有均等的概率得到任意一个节点,比如 3。 +In this example, each node has an equal chance of being selected, such as node 3. ### Solution Explanation -不同于数组,在未遍历完链表前,我们无法知道链表的总长度。这里我们就可以使用水库采样:遍历一次链表,在遍历到第 m 个节点时,有 $\frac{1}{m}$ 的概率选择这个节点覆盖掉之前的节点选择。 +Unlike arrays, where the total size is known, we cannot determine the total length of a linked list before traversal. In this scenario, we can use **reservoir sampling**: traverse the linked list, and at the $m$-th node, choose it with a probability of $\frac{1}{m}$ to replace the previously chosen node. -我们提供一个简单的,对于水库算法随机性的证明。对于长度为 n 的链表的第 m 个节点,最后被采样的充要条件是它被选择,且之后的节点都没有被选择。这种情况发生的概率为 $\frac{1}{m} × \frac{m}{m+1} × \frac{m}{m+2} × · · · × \frac{n−1}{n} = \frac{1}{n}$。因此每个点都有均等的概率被选择。 +A simple proof of the randomness of reservoir sampling is as follows: for the $m$-th node in a linked list of length $n$, the sufficient and necessary condition for it to be sampled is that it is chosen, and none of the subsequent nodes are chosen. The probability is calculated as: -当然,这道题我们也可以预处理链表,遍历一遍之后把它转化成数组。 +$$ +\frac{1}{m} × \frac{m}{m+1} × \frac{m+1}{m+2} × · · · × \frac{n−1}{n} = \frac{1}{n} +$$ + +Thus, each node has an equal probability of being selected. + +Alternatively, we can preprocess the linked list by traversing it once and converting it into an array for easier random access. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-6-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-6-exercises.md index 1d7ac01a..cb0b2654 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-6-exercises.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-6-exercises.md @@ -8,30 +8,30 @@ sidebar_position: 43 ### [168. Excel Sheet Column Title](https://leetcode.com/problems/excel-sheet-column-title/) -7 进制转换的变种题,需要注意的一点是从 1 开始而不是 0。 +A variation of base-7 conversion, where the sequence starts from 1 instead of 0. ### [67. Add Binary](https://leetcode.com/problems/add-binary/) -字符串加法的变种题。 +A variation of string addition. ### [238. Product of Array Except Self](https://leetcode.com/problems/product-of-array-except-self/) -你可以不使用除法做这道题吗?我们很早之前讲过的题目 135 或许能给你一些思路。 +Can you solve this problem without using division? A previously discussed problem like 135 might give you some ideas. ## Advanced Difficulty ### [462. Minimum Moves to Equal Array Elements II](https://leetcode.com/problems/minimum-moves-to-equal-array-elements-ii/) -这道题是笔者最喜欢的 LeetCode 题目之一,需要先推理出怎么样移动是最优的,再考虑如何进行移动。你或许需要一些前些章节讲过的算法。 +One of my favorite LeetCode problems. It requires reasoning about the optimal way to make moves and then considering how to implement the moves. You might need some algorithms we discussed earlier. ### [169. Majority Element](https://leetcode.com/problems/majority-element/) -如果想不出简单的解决方法,搜索一下 Boyer-Moore Majority Vote 算法吧。 +If you can't come up with a simple solution, search for the Boyer-Moore Majority Vote algorithm. ### [470. Implement Rand10() Using Rand7()](https://leetcode.com/problems/implement-rand10-using-rand7/) -如何用一个随机数生成器生成另一个随机数生成器?你可能需要利用原来的生成器多次。 +How can you generate one random number generator using another? You may need to utilize the original generator multiple times. ### [202. Happy Number](https://leetcode.com/problems/happy-number/) -你可以简单的用一个 while 循环解决这道题,但是有没有更好的解决办法?如果我们把每个数字想象成一个节点,是否可以转化为环路检测? \ No newline at end of file +You can solve this problem using a simple `while` loop, but is there a better way? If we think of each number as a node, can we transform this into a cycle detection problem? \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-1-introduction.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-1-introduction.md index d753971e..5b73d0be 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-1-introduction.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-1-introduction.md @@ -4,4 +4,4 @@ sidebar_position: 38 # 8.1 引言 -对于 LeetCode 上数量不少的数学题,我们尽量将其按照类型划分讲解。然而很多数学题的解法并不通用,我们也很难一口气把所有的套路讲清楚,因此我们只选择了几道经典或是典型的题目,供大家参考。 \ No newline at end of file +對於 LeetCode 上數量不少的數學題,我們盡量將其按照類型劃分講解。然而許多數學題的解法並不具通用性,因此我們很難一次性將所有解題套路完整講解清楚。因此,我們挑選了一些經典或典型的題目,供大家參考。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-2-lcm-gcd.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-2-lcm-gcd.mdx index 58dda1b8..f9679ed6 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-2-lcm-gcd.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-2-lcm-gcd.mdx @@ -2,10 +2,9 @@ sidebar_position: 39 --- -# 8.2 公倍数与公因数 - -利用`辗转相除法`,我们可以很方便地求得两个数的最大公因数(greatest common divisor,GCD);将两个数相乘再除以最大公因数即可得到最小公倍数(least common multiple, LCM)。 +# 8.2 公倍數與公因數 +利用`輾轉相除法`,我們可以很方便地求得兩個數的最大公因數(greatest common divisor,GCD);將兩個數相乘再除以最大公因數即可得到最小公倍數(least common multiple, LCM)。 @@ -35,7 +34,7 @@ def lcm(a: int, b: int) -> int: -进一步地,我们也可以通过扩展欧几里得算法(extended gcd)在求得 a 和 b 最大公因数的同时,也得到它们的系数 x 和 y,从而使 ax + by = gcd(a, b)。因为 Python 中 int 只能按值传递,我们可以用一个长度固定为 1 的 list() 来进行传递引用的操作。 +進一步地,我們也可以通過擴展歐幾里得算法(extended gcd)在求得 a 和 b 最大公因數的同時,也得到它們的係數 x 和 y,從而使 ax + by = gcd(a, b)。因為 Python 中 int 只能按值傳遞,我們可以用一個長度固定為 1 的 list() 來進行傳遞引用的操作。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-3-prime-numbers.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-3-prime-numbers.mdx index 9bee3e63..ec93336c 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-3-prime-numbers.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-3-prime-numbers.mdx @@ -2,31 +2,30 @@ sidebar_position: 40 --- -# 8.3 质数 - -质数又称素数,指的是指在大于 1 的自然数中,除了 1 和它本身以外不再有其他因数的自然数。值得注意的是,每一个数都可以分解成质数的乘积。 +# 8.3 質數 +質數又稱素數,指的是在大於 1 的自然數中,除了 1 和它本身以外不再有其他因數的自然數。值得注意的是,每一個數都可以分解成質數的乘積。 ## [204. Count Primes](https://leetcode.com/problems/count-primes/) ### 題目描述 -给定一个数字 n,求小于 n 的质数的个数。 +給定一個數字 n,求小於 n 的質數的個數。 ### 輸入輸出範例 -输入一个整数,输出也是一个整数,表示小于输入数的质数的个数。 +輸入一個整數,輸出也是一個整數,表示小於輸入數的質數的個數。 ``` Input: 10 Output: 4 ``` -在这个样例中,小于 10 的质数只有 [2,3,5,7]。 +在這個範例中,小於 10 的質數只有 [2, 3, 5, 7]。 ### 題解 -`埃拉托斯特尼筛法`(Sieve of Eratosthenes,简称埃氏筛法)是非常常用的,判断一个整数是否是质数的方法。并且它可以在判断一个整数 n 时,同时判断所小于 n 的整数,因此非常适合这道题。其原理也十分易懂:从 1 到 n 遍历,假设当前遍历到 m,则把所有小于 n 的、且是 m 的倍数的整数标为和数;遍历完成后,没有被标为和数的数字即为质数。 +`埃拉托斯特尼篩法`(Sieve of Eratosthenes,簡稱埃氏篩法)是非常常用的,用於判斷一個整數是否為質數的方法。它也可以在判斷一個整數 $n$ 時,同時判斷所有小於 $n$ 的整數,因此非常適合這道題目。其原理也十分簡單:從 $1$ 到 $n$ 遍歷,假設當前遍歷到 $m$,則把所有小於 $n$ 且是 $m$ 的倍數的整數標記為和數;遍歷完成後,沒有被標記為和數的數字即為質數。 @@ -37,7 +36,7 @@ int countPrimes(int n) { return 0; } vector primes(n, true); - int count = n - 2; // 去掉不是质数的1 + int count = n - 2; // 移除不是質數的 1 for (int i = 2; i < n; ++i) { if (primes[i]) { for (int j = 2 * i; j < n; j += i) { @@ -60,7 +59,7 @@ def countPrimes(n: int) -> int: if n <= 2: return 0 primes = [True for _ in range(n)] - count = n - 2 # 去掉不是质数的1 + count = n - 2 # 移除不是質數的 1 for i in range(2, n): if primes[i]: for j in range(2 * i, n, i): @@ -74,8 +73,7 @@ def countPrimes(n: int) -> int: -利用质数的一些性质,我们可以进一步优化该算法。 - +利用質數的一些性質,我們可以進一步優化該演算法。 @@ -87,11 +85,11 @@ int countPrimes(int n) { } vector primes(n, true); int sqrtn = sqrt(n); - int count = n / 2; // 偶数一定不是质数 + int count = n / 2; // 偶數一定不是質數 int i = 3; - // 最小质因子一定小于等于开方数。 + // 最小質因子一定小於等於平方根。 while (i <= sqrtn) { - // 向右找倍数,注意避免偶数和重复遍历。 + // 向右找倍數,注意避免偶數和重複遍歷。 for (int j = i * i; j < n; j += 2 * i) { if (primes[j]) { --count; @@ -99,7 +97,7 @@ int countPrimes(int n) { } } i += 2; - // 向右前进查找位置,注意避免偶数和重复遍历。 + // 向右前進查找位置,注意避免偶數和重複遍歷。 while (i <= sqrtn && !primes[i]) { i += 2; } @@ -117,17 +115,17 @@ def countPrimes(n: int) -> int: return 0 primes = [True for _ in range(n)] sqrtn = sqrt(n) - count = n // 2 # 偶数一定不是质数 + count = n // 2 # 偶數一定不是質數 i = 3 - # 最小质因子一定小于等于开方数。 + # 最小質因子一定小於等於平方根。 while i <= sqrtn: - # 向右找倍数,注意避免偶数和重复遍历。 + # 向右找倍數,注意避免偶數和重複遍歷。 for j in range(i * i, n, 2 * i): if primes[j]: count -= 1 primes[j] = False i += 2 - # 向右前进查找位置,注意避免偶数和重复遍历。 + # 向右前進查找位置,注意避免偶數和重複遍歷。 while i <= sqrtn and not primes[i]: i += 2 return count diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-4-number-processing.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-4-number-processing.mdx index 4537f107..fc8a8085 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-4-number-processing.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-4-number-processing.mdx @@ -2,28 +2,28 @@ sidebar_position: 41 --- -# 8.4 数字处理 +# 8.4 數字處理 ## [504. Base 7](https://leetcode.com/problems/base-7/) ### 題目描述 -给定一个十进制整数,求它在七进制下的表示。 +給定一個十進制整數,求它在七進制下的表示。 ### 輸入輸出範例 -输入一个整数,输出一个字符串,表示其七进制。 +輸入一個整數,輸出一個字串,表示其七進制。 ``` Input: 100 Output: "202" ``` -在这个样例中,100 的七进制表示法来源于 101 = 2 * 49 + 0 * 7 + 2 * 1。 +在這個範例中,100 的七進制表示法來源於 100 = 2 * 49 + 0 * 7 + 2 * 1。 ### 題解 -`进制转换`类型的题,通常是利用除法和取模(mod)来进行计算,同时也要注意一些细节,如负数和零。如果输出是数字类型而非字符串,则也需要考虑是否会超出整数上下界。 +`進制轉換`類型的題目,通常是利用除法和取模(mod)來進行計算,同時也要注意一些細節,如負數和零。如果輸出是數字類型而非字串,也需要考慮是否會超出整數上下界。 @@ -70,22 +70,22 @@ def convertToBase7(num: int) -> str: ### 題目描述 -给定一个非负整数,判断它的阶乘结果的结尾有几个 0。 +給定一個非負整數,判斷它的階乘結果的結尾有幾個 0。 ### 輸入輸出範例 -输入一个非负整数,输出一个非负整数,表示输入的阶乘结果的结尾有几个 0。 +輸入一個非負整數,輸出一個非負整數,表示輸入的階乘結果的結尾有幾個 0。 ``` Input: 12 Output: 2 ``` -在这个样例中,12 != 479001600 的结尾有两个 0。 +在這個範例中,12! = 479001600 的結尾有兩個 0。 ### 題解 -每个尾部的 0 由 2 × 5 =10 而来,因此我们可以把阶乘的每一个元素拆成质数相乘,统计有多少个 2 和 5。明显的,质因子 2 的数量远多于质因子 5 的数量,因此我们可以只统计阶乘结果里有多少个质因子 5。 +每個尾部的 0 由 2 × 5 = 10 而來,因此我們可以把階乘的每一個元素拆成質數相乘,統計有多少個 2 和 5。明顯的,質因子 2 的數量遠多於質因子 5 的數量,因此我們可以只統計階乘結果裡有多少個質因子 5。 @@ -112,23 +112,21 @@ def trailingZeroes(n: int) -> int: ### 題目描述 -给定两个由数字组成的字符串,求它们相加的结果。 +給定兩個由數字組成的字符串,求它們相加的結果。 ### 輸入輸出範例 -输入是两个字符串,输出是一个整数,表示输入的数字和。 +輸入是兩個字符串,輸出是一個整數,表示輸入的數字和。 ``` Input: num1 = "99", num2 = "1" Output: 100 ``` -因为相加运算是从后往前进行的,所以可以先翻转字符串,再逐位计算。这种类型的题考察的是细节,如进位、位数差等等。 +因為相加運算是從後往前進行的,所以可以先翻轉字符串,再逐位計算。這種類型的題目考察的是細節,如進位、位數差等等。 ### 題解 - - @@ -188,11 +186,11 @@ def addStrings(num1: str, num2: str) -> str: ### 題目描述 -判断一个数字是否是 3 的次方。 +判斷一個數字是否是 3 的次方。 ### 輸入輸出範例 -输入一个整数,输出一个布尔值。 +輸入一個整數,輸出一個布林值。 ``` Input: n = 27 @@ -201,7 +199,7 @@ Output: true ### 題解 -有两种方法,一种是利用对数。设 log3 n =m,如果 n 是 3 的整数次方,那么 m 一定是整数。 +有兩種方法,一種是利用對數。設 log3 n = m,如果 n 是 3 的整數次方,那麼 m 一定是整數。 @@ -224,7 +222,7 @@ def isPowerOfThree(n: int) -> bool: -另一种方法是,因为在 C++ int 范围内 3 的最大次方是 $3^{19} = 1162261467$,如果 n 是 3 的整数次方,那么 1162261467 除以 n 的余数一定是零;反之亦然。然而对于 Python 来说,因为 int 理论上可以取无穷大,我们只能循环判断。 +另一種方法是,因為在 C++ `int` 範圍內 3 的最大次方是 $3^{19} = 1162261467$,如果 n 是 3 的整數次方,那麼 1162261467 除以 n 的餘數一定是零;反之亦然。然而對於 Python 來說,因為 `int` 理論上可以取無窮大,我們只能循環判斷。 @@ -255,11 +253,11 @@ def isPowerOfThree(n: int) -> bool: ### 題目描述 -计算 x 的 n 次方。 +計算 x 的 n 次方。 ### 輸入輸出範例 -输入一个浮点数表示 x 和一个整数表示 n,输出一个浮点数表示次方结果。 +輸入一個浮點數表示 x 和一個整數表示 n,輸出一個浮點數表示次方結果。 ``` Input: x = 2.00000, n = 10 @@ -268,8 +266,7 @@ Output: 1024.00000 ### 題解 - -利用递归,我们可以较为轻松地解决本题。注意边界条件的处理。 +利用遞迴,我們可以較為輕鬆地解決本題。注意邊界條件的處理。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-5-random-sampling.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-5-random-sampling.mdx index 59b76881..b5cb11af 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-5-random-sampling.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-5-random-sampling.mdx @@ -2,28 +2,28 @@ sidebar_position: 42 --- -# 8.5 随机与取样 +# 8.5 隨機與取樣 ## [384. Shuffle an Array](https://leetcode.com/problems/shuffle-an-array/) ### 題目描述 -给定一个数组,要求实现两个指令函数。第一个函数“shuffle”可以随机打乱这个数组,第二个函数“reset”可以恢复原来的顺序。 +給定一個數組,要求實現兩個指令函數。第一個函數「shuffle」可以隨機打亂這個數組,第二個函數「reset」可以恢復原來的順序。 ### 輸入輸出範例 -输入是一个存有整数数字的数组,和一个包含指令函数名称的数组。输出是一个二维数组,表示每个指令生成的数组。 +輸入是一個存有整數數字的數組,以及一個包含指令函數名稱的數組。輸出是一個二維數組,表示每個指令生成的數組。 ``` Input: nums = [1,2,3], actions: ["shuffle","shuffle","reset"] Output: [[2,1,3],[3,2,1],[1,2,3]] ``` -在这个样例中,前两次打乱的结果只要是随机生成即可。 +在這個範例中,前兩次打亂的結果只要是隨機生成即可。 ### 題解 -我们采用经典的 `Fisher-Yates 洗牌算法`,原理是通过随机交换位置来实现随机打乱,有正向和反向两种写法,且实现非常方便。注意这里“reset”函数以及 Solution 类的构造函数的实现细节。 +我們採用經典的 `Fisher-Yates 洗牌算法`,其原理是通過隨機交換位置來實現隨機打亂,有正向和反向兩種寫法,且實現非常方便。注意這裡「reset」函數以及 Solution 類的構造函數的實現細節。 @@ -90,26 +90,26 @@ class Solution: ### 題目描述 -给定一个数组,数组每个位置的值表示该位置的权重,要求按照权重的概率去随机采样。 +給定一個數組,數組每個位置的值表示該位置的權重,要求按照權重的概率去隨機抽樣。 ### 輸入輸出範例 -输入是一维正整数数组,表示权重;和一个包含指令字符串的一维数组,表示运行几次随机采样。输出是一维整数数组,表示随机采样的整数在数组中的位置。 +輸入是一維正整數數組,表示權重;以及一個包含指令字串的一維數組,表示運行幾次隨機抽樣。輸出是一維整數數組,表示隨機抽樣的整數在數組中的位置。 ``` Input: weights = [1,3], actions: ["pickIndex","pickIndex","pickIndex"] Output: [0,1,1] ``` -在这个样例中,每次选择的位置都是不确定的,但选择第 0 个位置的期望为 1/4,选择第 1 个位置的期望为 3/4。 +在這個範例中,每次選擇的位置都是不確定的,但選擇第 0 個位置的期望為 1/4,選擇第 1 個位置的期望為 3/4。 ### 題解 -我们可以先使用 partial_sum求前缀和(即到每个位置为止之前所有数字的和),这个结果对于正整数数组是单调递增的。每当需要采样时,我们可以先随机产生一个数字,然后使用二分法查找其在前缀和中的位置,以模拟加权采样的过程。这里的二分法可以用 lower_bound 实现。 +我們可以先使用前綴和(partial_sum)計算到每個位置為止之前所有數字的總和,這個結果對於正整數數組是單調遞增的。每當需要抽樣時,我們可以先隨機生成一個數字,然後使用二分法查找該數字在前綴和中的位置,以模擬加權抽樣的過程。這裡的二分法可以用 lower_bound 實現。 -以样例为例,权重数组 [1,3] 的前缀和为 [1,4]。如果我们随机生成的数字为 1,那么 lower_bound 返回的位置为 0;如果我们随机生成的数字是 2、3、4,那么 lower_bound 返回的位置为 1。 +以範例為例,權重數組 [1,3] 的前綴和為 [1,4]。如果我們隨機生成的數字為 1,那麼 lower_bound 返回的位置為 0;如果我們隨機生成的數字是 2、3、4,那麼 lower_bound 返回的位置為 1。 -关于前缀和的更多技巧,我们将在接下来的章节中继续深入讲解。 +關於前綴和的更多技巧,我們將在接下來的章節中繼續深入講解。 @@ -155,26 +155,32 @@ class Solution: ### 題目描述 -给定一个单向链表,要求设计一个算法,可以随机取得其中的一个数字。 +給定一個單向鏈表,要求設計一個演算法,可以隨機取得其中的一個數字。 ### 輸入輸出範例 -输入是一个单向链表,输出是一个数字,表示链表里其中一个节点的值。 +輸入是一個單向鏈表,輸出是一個數字,表示鏈表裡其中一個節點的值。 ``` Input: 1->2->3->4->5 Output: 3 ``` -在这个样例中,我们有均等的概率得到任意一个节点,比如 3。 +在這個範例中,我們有均等的概率得到任意一個節點,比如 3。 ### 題解 -不同于数组,在未遍历完链表前,我们无法知道链表的总长度。这里我们就可以使用水库采样:遍历一次链表,在遍历到第 m 个节点时,有 $\frac{1}{m}$ 的概率选择这个节点覆盖掉之前的节点选择。 +不同於數組,在未遍歷完鏈表前,我們無法知道鏈表的總長度。這裡我們可以使用水庫抽樣:遍歷一次鏈表,在遍歷到第 $m$ 個節點時,有 $\frac{1}{m}$ 的概率選擇這個節點覆蓋掉之前的選擇。 -我们提供一个简单的,对于水库算法随机性的证明。对于长度为 n 的链表的第 m 个节点,最后被采样的充要条件是它被选择,且之后的节点都没有被选择。这种情况发生的概率为 $\frac{1}{m} × \frac{m}{m+1} × \frac{m}{m+2} × · · · × \frac{n−1}{n} = \frac{1}{n}$。因此每个点都有均等的概率被选择。 +我們提供一個簡單的,對於水庫算法隨機性的證明。對於長度為 $n$ 的鏈表的第 $m$ 個節點,最後被抽樣的充要條件是它被選擇,且之後的節點都沒有被選擇。這種情況發生的概率為: -当然,这道题我们也可以预处理链表,遍历一遍之后把它转化成数组。 +$$ +\frac{1}{m} × \frac{m}{m+1} × \frac{m+1}{m+2} × · · · × \frac{n−1}{n} = \frac{1}{n} +$$ + +因此每個點都有均等的概率被選擇。 + +當然,這道題我們也可以預處理鏈表,遍歷一遍之後把它轉化成數組。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-6-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-6-exercises.md index 0d8bef0e..d84c4491 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-6-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-6-exercises.md @@ -8,30 +8,30 @@ sidebar_position: 43 ### [168. Excel Sheet Column Title](https://leetcode.com/problems/excel-sheet-column-title/) -7 进制转换的变种题,需要注意的一点是从 1 开始而不是 0。 +7 進制轉換的變種題,需要注意的一點是從 1 開始而不是 0。 ### [67. Add Binary](https://leetcode.com/problems/add-binary/) -字符串加法的变种题。 +字符串加法的變種題。 ### [238. Product of Array Except Self](https://leetcode.com/problems/product-of-array-except-self/) -你可以不使用除法做这道题吗?我们很早之前讲过的题目 135 或许能给你一些思路。 +你可以不使用除法做這道題嗎?我們很早之前講過的題目 135 或許能給你一些思路。 ## 進階難度 ### [462. Minimum Moves to Equal Array Elements II](https://leetcode.com/problems/minimum-moves-to-equal-array-elements-ii/) -这道题是笔者最喜欢的 LeetCode 题目之一,需要先推理出怎么样移动是最优的,再考虑如何进行移动。你或许需要一些前些章节讲过的算法。 +這道題是筆者最喜歡的 LeetCode 題目之一,需要先推理出怎麼樣移動是最優的,再考慮如何進行移動。你或許需要一些前些章節講過的算法。 ### [169. Majority Element](https://leetcode.com/problems/majority-element/) -如果想不出简单的解决方法,搜索一下 Boyer-Moore Majority Vote 算法吧。 +如果想不出簡單的解決方法,搜尋一下 Boyer-Moore Majority Vote 算法吧。 ### [470. Implement Rand10() Using Rand7()](https://leetcode.com/problems/implement-rand10-using-rand7/) -如何用一个随机数生成器生成另一个随机数生成器?你可能需要利用原来的生成器多次。 +如何用一個隨機數生成器生成另一個隨機數生成器?你可能需要利用原來的生成器多次。 ### [202. Happy Number](https://leetcode.com/problems/happy-number/) -你可以简单的用一个 while 循环解决这道题,但是有没有更好的解决办法?如果我们把每个数字想象成一个节点,是否可以转化为环路检测? \ No newline at end of file +你可以簡單的用一個 `while` 循環解決這道題,但是有沒有更好的解決辦法?如果我們把每個數字想像成一個節點,是否可以轉化為環路檢測? \ No newline at end of file From 847370d32a4bdf54cc9239699107faec8dcf624c Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Sun, 24 Nov 2024 22:48:22 +0100 Subject: [PATCH 24/49] fix i18n bug --- .../current.json | 4 ++-- .../8-1-introduction.md | 2 +- .../current.json | 20 +++++++++---------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current.json index e518f75d..9081fa19 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current.json +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current.json @@ -59,11 +59,11 @@ "message": "Chapter 7: Simplifying with Divide and Conquer", "description": "The generated-index page description for category 7. 化繁为简的分治法 in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.8. 巧解数学问题 ": { + "sidebar.tutorialSidebar.category.8. 巧解数学问题": { "message": "8. Clever Math Problem Solving", "description": "The label for category 8. 巧解数学问题 in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.8. 巧解数学问题 .link.generated-index.description": { + "sidebar.tutorialSidebar.category.8. 巧解数学问题.link.generated-index.description": { "message": "Chapter 8: Clever Math Problem Solving", "description": "The generated-index page description for category 8. 巧解数学问题 in sidebar tutorialSidebar" }, diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-1-introduction.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-1-introduction.md index e05b8c10..4603f312 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-1-introduction.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-1-introduction.md @@ -2,6 +2,6 @@ sidebar_position: 38 --- -# 8.1 引言 +# 8.1 Introduction For the numerous math problems on LeetCode, we strive to categorize and explain them by type. However, many math problems have solutions that are not universally applicable, making it challenging to summarize all problem-solving techniques in one go. Therefore, we have selected a few classic or representative problems for your reference. \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current.json index f086ff67..85ded7f0 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current.json +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current.json @@ -59,35 +59,35 @@ "message": "第 7 章 化繁為簡的分治法", "description": "The generated-index page description for category 7. 化繁為簡的分治法 in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.8. 巧解数学问题 ": { + "sidebar.tutorialSidebar.category.8. 巧解数学问题": { "message": "8. 巧解數學問題", "description": "The label for category 8. 巧解數學問題 in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.8. 巧解数学问题 .link.generated-index.description": { + "sidebar.tutorialSidebar.category.8. 巧解数学问题.link.generated-index.description": { "message": "第 8 章 巧解數學問題", "description": "The generated-index page description for category 8. 巧解數學問題 in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.9. 神奇的位运算 ": { + "sidebar.tutorialSidebar.category.9. 神奇的位运算": { "message": "9. 神奇的位元運算", "description": "The label for category 9. 神奇的位元運算 in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.9. 神奇的位运算 .link.generated-index.description": { + "sidebar.tutorialSidebar.category.9. 神奇的位运算.link.generated-index.description": { "message": "第 9 章 神奇的位元運算", "description": "The generated-index page description for category 9. 神奇的位元運算 in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.10. 妙用数据结构 ": { + "sidebar.tutorialSidebar.category.10. 妙用数据结构": { "message": "10. 巧用資料結構", "description": "The label for category 10. 巧用資料結構 in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.10. 妙用数据结构 .link.generated-index.description": { + "sidebar.tutorialSidebar.category.10. 妙用数据结构.link.generated-index.description": { "message": "第 10 章 巧用資料結構", "description": "The generated-index page description for category 10. 巧用資料結構 in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.11. 令人头大的字符串 ": { + "sidebar.tutorialSidebar.category.11. 令人头大的字符串": { "message": "11. 頭痛的字串處理", "description": "The label for category 11. 頭痛的字串處理 in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.11. 令人头大的字符串 .link.generated-index.description": { + "sidebar.tutorialSidebar.category.11. 令人头大的字符串.link.generated-index.description": { "message": "第 11 章 頭痛的字串處理", "description": "The generated-index page description for category 11. 頭痛的字串處理 in sidebar tutorialSidebar" }, @@ -115,11 +115,11 @@ "message": "第 14 章 指標三劍客之三:圖", "description": "The generated-index page description for category 14. 指標三劍客之三:圖 in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.15. 更加复杂的数据结构 ": { + "sidebar.tutorialSidebar.category.15. 更加复杂的数据结构": { "message": "15. 更加複雜的資料結構", "description": "The label for category 15. 更加複雜的資料結構 in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.15. 更加复杂的数据结构 .link.generated-index.description": { + "sidebar.tutorialSidebar.category.15. 更加复杂的数据结构.link.generated-index.description": { "message": "第 15 章 更加複雜的資料結構", "description": "The generated-index page description for category 15. 更加複雜的資料結構in sidebar tutorialSidebar" } From c3181fbdf78fe6239e8bb939230954780d591dd3 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Mon, 25 Nov 2024 21:20:35 +0100 Subject: [PATCH 25/49] i18n chapter 9 --- .../9-1-common-techniques.md | 40 ++++++++++++++----- .../9-2-basic-bitwise-problems.mdx | 26 ++++++------ .../9-3-binary-properties.mdx | 26 ++++++------ .../9-bitwise-operations/9-4-exercises.md | 8 ++-- .../9-1-common-techniques.md | 33 +++++++++++---- .../9-2-basic-bitwise-problems.mdx | 24 +++++------ .../9-3-binary-properties.mdx | 26 ++++++------ .../9-bitwise-operations/9-4-exercises.md | 8 ++-- 8 files changed, 115 insertions(+), 76 deletions(-) diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-1-common-techniques.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-1-common-techniques.md index 30f955ca..5d955fa6 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-1-common-techniques.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-1-common-techniques.md @@ -2,18 +2,19 @@ sidebar_position: 44 --- -# 9.1 常用技巧 +# 9.1 Common Techniques -`位运算`是算法题里比较特殊的一种类型,它们利用二进制位运算的特性进行一些奇妙的优化和计算。常用的位运算符号包括: +`Bit manipulation` is a unique category in algorithm problems. By leveraging the characteristics of binary bit operations, we can achieve fascinating optimizations and calculations. Here are some common bitwise operators and their functions: -- `∧`:按位异或 -- `&`:按位与 -- `|`:按位或 -- `~`:取反 -- `<<`:算术左移 -- `>>`:算术右移 -以下是一些常见的位运算特性,其中 `0s` 和 `1s` 分别表示只由 `0` 或 `1` 构成的二进制数字。 +- `∧`: Bitwise XOR +- `&`: Bitwise AND +- `|`: Bitwise OR +- `~`: Bitwise NOT +- `<<`: Arithmetic left shift +- `>>`: Arithmetic right shift + +Below are some commonly used bitwise properties, where `0s` and `1s` represent binary numbers composed entirely of `0` or `1`, respectively: ``` x ^ 0s = x x & 0s = 0 x | 0s = x @@ -21,4 +22,23 @@ x ^ 1s = ~x x & 1s = x x | 1s = 1s x ^ x = 0 x & x = x x | x = x ``` -除此之外,n & (n - 1) 可以去除 n 的位级表示中最低的那一位,例如对于二进制表示 11110100,减去 1 得到 11110011,这两个数按位与得到 11110000。n & (-n) 可以得到 n 的位级表示中最低的那一位,例如对于二进制表示 11110100,取负得到 00001100,这两个数按位与得到 00000100。还有更多的并不常用的技巧,若读者感兴趣可以自行研究,这里不再赘述。 \ No newline at end of file + +Additionally, here are some frequently used techniques: + +1. **Remove the lowest set bit**: `n & (n - 1)` + - This operation removes the lowest `1` in the binary representation of `n`. For example: + ``` + n = 11110100 + n - 1 = 11110011 + n & (n - 1) = 11110000 + ``` + +2. **Retrieve the lowest set bit**: `n & (-n)` + - This operation isolates the lowest `1` in the binary representation of `n`. For example: + ``` + n = 11110100 + -n = 00001100 + n & (-n) = 00000100 + ``` + +These are the commonly used bit manipulation tricks. For those interested, there are more advanced techniques worth exploring, but they will not be covered here. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-2-basic-bitwise-problems.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-2-basic-bitwise-problems.mdx index 3cf64a91..909507af 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-2-basic-bitwise-problems.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-2-basic-bitwise-problems.mdx @@ -2,28 +2,28 @@ sidebar_position: 45 --- -# 9.2 位运算基础问题 +# 9.2 Basic Problems in Bit Manipulation ## [461. Hamming Distance](https://leetcode.com/problems/hamming-distance/) ### Problem Description -给定两个十进制数字,求它们二进制表示的汉明距离(Hamming distance,即不同位的个数)。 +Given two decimal numbers, calculate the Hamming distance between their binary representations (i.e., the number of differing bits). ### Input and Output Example -输入是两个十进制整数,输出是一个十进制整数,表示两个输入数字的汉明距离。 +The input consists of two decimal integers, and the output is a decimal integer representing their Hamming distance. ``` Input: x = 1, y = 4 Output: 2 ``` -在这个样例中,1 的二进制是 0001,4 的二进制是 0100,一共有两位不同。 +In this example, the binary representation of 1 is `0001`, and that of 4 is `0100`, with two differing bits. ### Solution Explanation -对两个数进行按位异或操作,统计有多少个 1 即可。 +Perform a bitwise XOR operation on the two numbers and count the number of `1`s in the result. @@ -60,23 +60,21 @@ def hammingDistance(x: int, y: int) -> int: ### Problem Description -给定一个十进制正整数,输出它在二进制下的翻转结果。 +Given a decimal positive integer, output its reversed binary representation. ### Input and Output Example -输入和输出都是十进制正整数。 +Both input and output are decimal positive integers. ``` Input: 43261596 (00000010100101000001111010011100) Output: 964176192 (00111001011110000010100101000000) ``` -使用算术左移和右移,可以很轻易地实现二进制的翻转。 +Using arithmetic left shift and right shift, binary reversal can be easily implemented. ### Solution Explanation - - @@ -113,11 +111,11 @@ def reverseBits(n: int) -> int: ### Problem Description -给定一个整数数组,这个数组里只有一个数次出现了一次,其余数字出现了两次,求这个只出现一次的数字。 +Given an integer array, only one number in this array appears exactly once, while all other numbers appear twice. Find the number that appears only once. ### Input and Output Example -输入是一个一维整数数组,输出是该数组内的一个整数。 +The input is a one-dimensional integer array, and the output is an integer from the array. ``` Input: [4,1,2,1,2] @@ -126,7 +124,7 @@ Output: 4 ### Solution Explanation -我们可以利用 x ∧ x = 0 和 x ∧ 0 = x 的特点,将数组内所有的数字进行按位异或。出现两次的所有数字按位异或的结果是 0,0 与出现一次的数字异或可以得到这个数字本身。 +We can use the properties of x ∧ x = 0 and x ∧ 0 = x to solve this. By performing a bitwise XOR on all numbers in the array, the result of XORing all numbers that appear twice is 0. XORing 0 with the number that appears once gives the number itself. @@ -156,7 +154,7 @@ def singleNumber(nums: List[int]) -> int: -这里我们也可以直接使用 reduce 函数: +Here, we can also directly use the `reduce` function: diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-3-binary-properties.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-3-binary-properties.mdx index 773acd9d..08465c3d 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-3-binary-properties.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-3-binary-properties.mdx @@ -2,32 +2,32 @@ sidebar_position: 46 --- -# 9.3 二进制特性 +# 9.3 Binary Features -利用二进制的一些特性,我们可以把位运算使用到更多问题上。 +By leveraging some binary features, we can apply bitwise operations to solve a wider range of problems. -例如,我们可以利用二进制和位运算输出一个数组的所有子集。假设我们有一个长度为 $n$ 的数组,我们可以生成长度为 $n$ 的所有二进制,1 表示选取该数字,0 表示不选取。这样我们就获得了 $2^n$ 个子集。 +For example, we can use binary and bitwise operations to generate all subsets of an array. Suppose we have an array of length $n$, we can generate all binary numbers of length $n$, where 1 indicates selecting the number, and 0 indicates not selecting it. This way, we obtain $2^n$ subsets. ## [318. Maximum Product of Word Lengths](https://leetcode.com/problems/maximum-product-of-word-lengths/) ### Problem Description -给定多个字母串,求其中任意两个字母串的长度乘积的最大值,且这两个字母串不能含有相同字母。 +Given multiple strings, find the maximum product of lengths of any two strings such that the two strings do not share any common letters. ### Input and Output Example -输入一个包含多个字母串的一维数组,输出一个整数,表示长度乘积的最大值。 +Input is a one-dimensional array containing multiple strings, and output is an integer representing the maximum product of lengths. ``` Input: ["a","ab","abc","d","cd","bcd","abcd"] Output: 4 ``` -在这个样例中,一种最优的选择是“ab”和“cd”。 +In this example, one optimal pair is "ab" and "cd." ### Solution Explanation -怎样快速判断两个字母串是否含有重复数字呢?可以为每个字母串建立一个长度为 26 的二进制数字,每个位置表示是否存在该字母。如果两个字母串含有重复数字,那它们的二进制表示的按位与不为 0。同时,我们可以建立一个哈希表来存储二进制数字到最长子母串长度的映射关系,比如 ab 和 aab 的二进制数字相同,但是 aab 更长。 +How can we quickly determine if two strings share common letters? We can represent each string with a binary number of length 26, where each position indicates the presence of a specific letter. If two strings share common letters, their binary representations' bitwise AND will not be 0. Additionally, we can use a hash map to store the mapping from binary numbers to the longest string lengths. For example, "ab" and "aab" may have the same binary representation, but "aab" is longer. @@ -78,11 +78,11 @@ def maxProduct(words: List[str]) -> int: ### Problem Description -给定一个非负整数 n,求从 0 到 n 的所有数字的二进制表达中,分别有多少个 1。 +Given a non-negative integer `n`, find the number of `1`s in the binary representation of every number from `0` to `n`. ### Input and Output Example -输入是一个非负整数 n,输出是长度为 n +1 的非负整数数组,每个位置 m 表示 m 的二进制里有多少个 1。 +The input is a non-negative integer `n`, and the output is a list of non-negative integers of length `n + 1`, where each position `m` represents the number of `1`s in the binary representation of `m`. ``` Input: 5 @@ -91,7 +91,9 @@ Output: [0,1,1,2,1,2] ### Solution Explanation -本题可以利用动态规划和位运算进行快速的求解。定义一个数组 dp,其中 dp[i] 表示数字 i 的二进制含有 1 的个数。对于第 i 个数字,如果它二进制的最后一位为 1,那么它含有 1 的个数则为 dp[i-1] + 1;如果它二进制的最后一位为 0,那么它含有 1 的个数和其算术右移结果相同,即 dp[i>>1]。 +This problem can be solved efficiently using dynamic programming and bitwise operations. Define an array `dp`, where `dp[i]` represents the number of `1`s in the binary representation of the number `i`. For the number `i`: +- If the last bit of its binary representation is `1`, the count of `1`s is `dp[i-1] + 1`. +- If the last bit of its binary representation is `0`, the count of `1`s is the same as that of its arithmetic right-shift result, i.e., `dp[i>>1]`. @@ -100,7 +102,7 @@ Output: [0,1,1,2,1,2] vector countBits(int n) { vector dp(n + 1, 0); for (int i = 1; i <= n; ++i) - // 等价于:dp[i] = dp[i & (i - 1)] + 1; + // Equivalent to: dp[i] = dp[i & (i - 1)] + 1; dp[i] = i & 1 ? dp[i - 1] + 1 : dp[i >> 1]; return dp; } @@ -113,7 +115,7 @@ vector countBits(int n) { def countBits(n: int) -> List[int]: dp = [0] * (n + 1) for i in range(1, n + 1): - # 等价于:dp[i] = dp[i & (i - 1)] + 1 + # Equivalent to: dp[i] = dp[i & (i - 1)] + 1 dp[i] = dp[i - 1] + 1 if i & 1 else dp[i >> 1] return dp ``` diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-4-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-4-exercises.md index 9d4dd835..ad596dda 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-4-exercises.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-4-exercises.md @@ -8,18 +8,18 @@ sidebar_position: 47 ### [268. Missing Number](https://leetcode.com/problems/missing-number/) -Single Number 的变种题。除了利用二进制,也可以使用高斯求和公式。 +A variation of the Single Number problem. Besides using bitwise operations, the problem can also be solved using the Gaussian summation formula. ### [693. Binary Number with Alternating Bits](https://leetcode.com/problems/binary-number-with-alternating-bits/) -利用位运算判断一个数的二进制是否会出现连续的 0 和 1。 +Use bitwise operations to determine whether a number's binary representation alternates between `0` and `1`. ### [476. Number Complement](https://leetcode.com/problems/number-complement/) -二进制翻转的变种题。 +A variation of binary flipping problems. ## Advanced Difficulty ### [260. Single Number III](https://leetcode.com/problems/single-number-iii/) -Single Number 的 follow-up,需要认真思考如何运用位运算求解。 \ No newline at end of file +A follow-up to the Single Number problem. Requires careful thought on how to leverage bitwise operations to solve. \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-1-common-techniques.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-1-common-techniques.md index 30f955ca..93254a53 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-1-common-techniques.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-1-common-techniques.md @@ -4,16 +4,17 @@ sidebar_position: 44 # 9.1 常用技巧 -`位运算`是算法题里比较特殊的一种类型,它们利用二进制位运算的特性进行一些奇妙的优化和计算。常用的位运算符号包括: +`位運算`是演算法題目中較為特殊的一種類型,利用二進制位運算的特性可以實現一些奇妙的優化與計算。以下是一些常見的位運算符號及其功能: -- `∧`:按位异或 -- `&`:按位与 + +- `∧`:按位異或 +- `&`:按位與 - `|`:按位或 - `~`:取反 -- `<<`:算术左移 -- `>>`:算术右移 +- `<<`:算術左移 +- `>>`:算術右移 -以下是一些常见的位运算特性,其中 `0s` 和 `1s` 分别表示只由 `0` 或 `1` 构成的二进制数字。 +以下是一些常見的位運算特性,其中 `0s` 和 `1s` 分別表示只由 `0` 或 `1` 構成的二進制數字。 ``` x ^ 0s = x x & 0s = 0 x | 0s = x @@ -21,4 +22,22 @@ x ^ 1s = ~x x & 1s = x x | 1s = 1s x ^ x = 0 x & x = x x | x = x ``` -除此之外,n & (n - 1) 可以去除 n 的位级表示中最低的那一位,例如对于二进制表示 11110100,减去 1 得到 11110011,这两个数按位与得到 11110000。n & (-n) 可以得到 n 的位级表示中最低的那一位,例如对于二进制表示 11110100,取负得到 00001100,这两个数按位与得到 00000100。还有更多的并不常用的技巧,若读者感兴趣可以自行研究,这里不再赘述。 \ No newline at end of file +除此之外,以下是一些經常用到的特殊技巧: + +1. **消去最低位的 1**:`n & (n - 1)` + - 此操作可以去除 n 的位級表示中最低的那一位。例如: + ``` + n = 11110100 + n - 1 = 11110011 + n & (n - 1) = 11110000 + ``` + +2. **獲取最低位的 1**:`n & (-n)` + - 此操作可以得到 n 的位級表示中最低的那一位。例如: + ``` + n = 11110100 + -n = 00001100 + n & (-n) = 00000100 + ``` + +以上僅是常用的位運算技巧,如果讀者感興趣,可以進一步探索更多不常見但強大的位運算方法,這裡不再贅述。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-2-basic-bitwise-problems.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-2-basic-bitwise-problems.mdx index f17e521c..8d53957d 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-2-basic-bitwise-problems.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-2-basic-bitwise-problems.mdx @@ -2,13 +2,13 @@ sidebar_position: 45 --- -# 9.2 位运算基础问题 +# 9.2 位運算基礎問題 ## [461. Hamming Distance](https://leetcode.com/problems/hamming-distance/) ### 題目描述 -给定两个十进制数字,求它们二进制表示的汉明距离(Hamming distance,即不同位的个数)。 +給定兩個十進制數字,求它們二進制表示的漢明距離(Hamming distance,即不同位的個數)。 ### 輸入輸出範例 @@ -19,11 +19,11 @@ Input: x = 1, y = 4 Output: 2 ``` -在这个样例中,1 的二进制是 0001,4 的二进制是 0100,一共有两位不同。 +在這個範例中,1 的二進制是 0001,4 的二進制是 0100,一共有兩位不同。 ### 題解 -对两个数进行按位异或操作,统计有多少个 1 即可。 +對兩個數進行按位異或操作,統計結果中有多少個 1 即可。 @@ -60,23 +60,21 @@ def hammingDistance(x: int, y: int) -> int: ### 題目描述 -给定一个十进制正整数,输出它在二进制下的翻转结果。 +給定一個十進制正整數,輸出它在二進制下的翻轉結果。 ### 輸入輸出範例 -输入和输出都是十进制正整数。 +輸入和輸出都是十進制正整數。 ``` Input: 43261596 (00000010100101000001111010011100) Output: 964176192 (00111001011110000010100101000000) ``` -使用算术左移和右移,可以很轻易地实现二进制的翻转。 +使用算術左移和右移,可以很輕易地實現二進制的翻轉。 ### 題解 - - @@ -113,11 +111,11 @@ def reverseBits(n: int) -> int: ### 題目描述 -给定一个整数数组,这个数组里只有一个数次出现了一次,其余数字出现了两次,求这个只出现一次的数字。 +給定一個整數數組,這個數組裡只有一個數字只出現了一次,其餘數字出現了兩次,求這個只出現一次的數字。 ### 輸入輸出範例 -输入是一个一维整数数组,输出是该数组内的一个整数。 +輸入是一個一維整數數組,輸出是該數組內的一個整數。 ``` Input: [4,1,2,1,2] @@ -126,7 +124,7 @@ Output: 4 ### 題解 -我们可以利用 x ∧ x = 0 和 x ∧ 0 = x 的特点,将数组内所有的数字进行按位异或。出现两次的所有数字按位异或的结果是 0,0 与出现一次的数字异或可以得到这个数字本身。 +我們可以利用 x ∧ x = 0 和 x ∧ 0 = x 的特點,將數組內所有的數字進行按位異或。出現兩次的所有數字按位異或的結果是 0,0 與出現一次的數字異或可以得到這個數字本身。 @@ -156,7 +154,7 @@ def singleNumber(nums: List[int]) -> int: -这里我们也可以直接使用 reduce 函数: +這裡我們也可以直接使用 `reduce` 函數: diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-3-binary-properties.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-3-binary-properties.mdx index d5b383a8..043c754e 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-3-binary-properties.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-3-binary-properties.mdx @@ -2,32 +2,32 @@ sidebar_position: 46 --- -# 9.3 二进制特性 +# 9.3 二進制特性 -利用二进制的一些特性,我们可以把位运算使用到更多问题上。 +利用二進制的一些特性,我們可以把位運算使用到更多問題上。 -例如,我们可以利用二进制和位运算输出一个数组的所有子集。假设我们有一个长度为 $n$ 的数组,我们可以生成长度为 $n$ 的所有二进制,1 表示选取该数字,0 表示不选取。这样我们就获得了 $2^n$ 个子集。 +例如,我們可以利用二進制和位運算輸出一個數組的所有子集。假設我們有一個長度為 $n$ 的數組,我們可以生成長度為 $n$ 的所有二進制,1 表示選取該數字,0 表示不選取。這樣我們就獲得了 $2^n$ 個子集。 ## [318. Maximum Product of Word Lengths](https://leetcode.com/problems/maximum-product-of-word-lengths/) ### 題目描述 -给定多个字母串,求其中任意两个字母串的长度乘积的最大值,且这两个字母串不能含有相同字母。 +給定多個字母串,求其中任意兩個字母串的長度乘積的最大值,且這兩個字母串不能含有相同字母。 ### 輸入輸出範例 -输入一个包含多个字母串的一维数组,输出一个整数,表示长度乘积的最大值。 +輸入一個包含多個字母串的一維數組,輸出一個整數,表示長度乘積的最大值。 ``` Input: ["a","ab","abc","d","cd","bcd","abcd"] Output: 4 ``` -在这个样例中,一种最优的选择是“ab”和“cd”。 +在這個範例中,一種最優的選擇是“ab”和“cd”。 ### 題解 -怎样快速判断两个字母串是否含有重复数字呢?可以为每个字母串建立一个长度为 26 的二进制数字,每个位置表示是否存在该字母。如果两个字母串含有重复数字,那它们的二进制表示的按位与不为 0。同时,我们可以建立一个哈希表来存储二进制数字到最长子母串长度的映射关系,比如 ab 和 aab 的二进制数字相同,但是 aab 更长。 +怎樣快速判斷兩個字母串是否含有重複字母呢?可以為每個字母串建立一個長度為 26 的二進制數字,每個位置表示是否存在該字母。如果兩個字母串含有重複字母,那它們的二進制表示的按位與不為 0。同時,我們可以建立一個哈希表來存儲二進制數字到最長子母串長度的映射關係,比如 ab 和 aab 的二進制數字相同,但是 aab 更長。 @@ -78,11 +78,11 @@ def maxProduct(words: List[str]) -> int: ### 題目描述 -给定一个非负整数 n,求从 0 到 n 的所有数字的二进制表达中,分别有多少个 1。 +給定一個非負整數 n,求從 0 到 n 的所有數字的二進制表示中,各自有多少個 1。 ### 輸入輸出範例 -输入是一个非负整数 n,输出是长度为 n +1 的非负整数数组,每个位置 m 表示 m 的二进制里有多少个 1。 +輸入是一個非負整數 n,輸出是一個長度為 n + 1 的非負整數數組,每個位置 m 表示 m 的二進制中有多少個 1。 ``` Input: 5 @@ -91,7 +91,9 @@ Output: [0,1,1,2,1,2] ### 題解 -本题可以利用动态规划和位运算进行快速的求解。定义一个数组 dp,其中 dp[i] 表示数字 i 的二进制含有 1 的个数。对于第 i 个数字,如果它二进制的最后一位为 1,那么它含有 1 的个数则为 dp[i-1] + 1;如果它二进制的最后一位为 0,那么它含有 1 的个数和其算术右移结果相同,即 dp[i>>1]。 +本題可以利用動態規劃和位運算進行快速求解。定義一個數組 dp,其中 dp[i] 表示數字 i 的二進制中含有 1 的個數。對於第 i 個數字: +- 如果它二進制的最後一位為 1,那麼它含有 1 的個數為 dp[i-1] + 1; +- 如果它二進制的最後一位為 0,那麼它含有 1 的個數和其算術右移結果相同,即 dp[i>>1]。 @@ -100,7 +102,7 @@ Output: [0,1,1,2,1,2] vector countBits(int n) { vector dp(n + 1, 0); for (int i = 1; i <= n; ++i) - // 等价于:dp[i] = dp[i & (i - 1)] + 1; + // 等價於:dp[i] = dp[i & (i - 1)] + 1; dp[i] = i & 1 ? dp[i - 1] + 1 : dp[i >> 1]; return dp; } @@ -113,7 +115,7 @@ vector countBits(int n) { def countBits(n: int) -> List[int]: dp = [0] * (n + 1) for i in range(1, n + 1): - # 等价于:dp[i] = dp[i & (i - 1)] + 1 + # 等價於:dp[i] = dp[i & (i - 1)] + 1 dp[i] = dp[i - 1] + 1 if i & 1 else dp[i >> 1] return dp ``` diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-4-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-4-exercises.md index 87db5ee0..0befcaf0 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-4-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-4-exercises.md @@ -8,18 +8,18 @@ sidebar_position: 47 ### [268. Missing Number](https://leetcode.com/problems/missing-number/) -Single Number 的变种题。除了利用二进制,也可以使用高斯求和公式。 +Single Number 的變種題。除了利用二進位,也可以使用高斯求和公式解決。 ### [693. Binary Number with Alternating Bits](https://leetcode.com/problems/binary-number-with-alternating-bits/) -利用位运算判断一个数的二进制是否会出现连续的 0 和 1。 +利用位運算判斷一個數的二進位表示是否會出現連續的 `0` 和 `1`。 ### [476. Number Complement](https://leetcode.com/problems/number-complement/) -二进制翻转的变种题。 +二進位翻轉的變種題。 ## 進階難度 ### [260. Single Number III](https://leetcode.com/problems/single-number-iii/) -Single Number 的 follow-up,需要认真思考如何运用位运算求解。 \ No newline at end of file +Single Number 的進階版本。需要仔細思考如何利用位運算求解。 \ No newline at end of file From f2375cb5d9aeb1fe1771198a9ae1a9fca0dd12fb Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Tue, 26 Nov 2024 19:02:07 +0100 Subject: [PATCH 26/49] chapter 1 exercise solutions --- .../1-greedy-algorithms/1-4-exercises.md | 209 +++++++++++++++++- 1 file changed, 206 insertions(+), 3 deletions(-) diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-4-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-4-exercises.md index 569182af..a90f9d7f 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-4-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-4-exercises.md @@ -10,9 +10,77 @@ sidebar_position: 4 採取什麼樣的貪心策略,可以種植最多的花朵呢? +
        + 題解 + +#### 解題思路 + +1. **問題轉換**: + 為簡化邊界判斷,在花圃兩端添加虛擬位置 `0`。 + +2. **遍歷邏輯**: + - 對每個位置,檢查當前位置為 `0` 且左右兩側也為 `0` 時,可種植一朵花。 + - 種花後將位置設為 `1` 並將 `n` 減 1。 + +3. **最終判斷**: + 程式遍歷完後檢查 `n` 是否小於等於 `0`,返回結果。 + + + ```py + class Solution: + def canPlaceFlowers(self, flowerbed: List[int], n: int) -> bool: + flowerbed = [0] + flowerbed + [0] + for i, f in enumerate(flowerbed[1:-1],start=1): + if f == 0 and flowerbed[i-1] == 0 and flowerbed[i+1] == 0: + n -= 1 + flowerbed[i] = 1 + return n <= 0 + ``` + +#### 複雜度分析 + +- **時間複雜度**: 主迴圈遍歷了 `flowerbed` 的所有元素一次,因此時間複雜度為 $O(m)$,其中 $m$ 是 `flowerbed` 的長度。 + +- **空間複雜度**: 程式在 `flowerbed` 兩端添加了額外的元素,佔用固定的額外空間,因此空間複雜度為 $O(1)$。 + +
        + ### [452. Minimum Number of Arrows to Burst Balloons](https://leetcode.com/problems/minimum-number-of-arrows-to-burst-balloons/) -這道題和題目 435 十分類似,但是稍有不同,具體是哪里不同呢? +這道題和題目 435 十分類似,但是稍有不同,具體是哪裡不同呢? + +
        + 題解 + +#### 解題思路 + +- 將所有氣球根據右邊界進行升序排序。 +- 初始化箭數 `arrows` 為 1,並記錄第一支箭射出的右邊界 `end`。 +- 遍歷所有氣球: + - 如果當前氣球的左邊界大於 `end`,表示需要新增一支箭,更新 `end` 為當前氣球的右邊界。 +- 返回箭數 `arrows`。 + +```python +class Solution: + def findMinArrowShots(self, points: List[List[int]]) -> int: + points.sort(key=lambda x: x[1]) # 根據右邊界排序 + arrows = 1 + end = points[0][1] + + for x_start, x_end in points[1:]: + if x_start > end: # 氣球不重疊,需要新箭 + arrows += 1 + end = x_end + + return arrows +``` + +#### 複雜度分析 +- **時間複雜度**: $O(n \log n)$,其中 $n$ 是氣球數量,排序操作為主要開銷。 + +- **空間複雜度**: $O(1)$,除了排序使用的額外空間外,程式只使用了常數額外空間。 + +
        ### [763. Partition Labels](https://leetcode.com/problems/partition-labels/) @@ -20,21 +88,156 @@ sidebar_position: 4 :::warning -在處理數組前,統計一遍信息(如頻率、個數、第一次出現位置、最後一次出現位置等)可以使題目難度大幅降低。 +在處理陣列前,統計一遍訊息(如頻率、個數、第一次出現位置、最後一次出現位置等)可以使題目難度大幅降低。 ::: +
        + 題解 + +#### 解題思路 + +- 計算每個字符最後出現的位置,記錄為 `last` 字典。 +- 遍歷字符串,維護當前區間的右邊界 `end`,初始為 `0`,並記錄區間起點 `start`。 +- 當遍歷到的字符的最後出現位置超過當前的 `end` 時,更新 `end`。 +- 如果當前索引等於 `end`,表示找到了一個劃分區間,將區間長度加入結果列表,並將 `start` 更新為下一個字符的起點。 + +```python +class Solution: + def partitionLabels(self, s: str) -> List[int]: + last = {char: i for i, char in enumerate(s)} # 記錄每個字符的最後出現位置 + partitions = [] + start = end = 0 + + for i, char in enumerate(s): + end = max(end, last[char]) # 更新當前區間的右邊界,保證當前區間覆蓋所有字符的最後出現位置 + if i == end: # 當前索引等於區間右邊界,完成一個區間 + partitions.append(end - start + 1) + start = i + 1 # 更新下一區間的起點 + + return partitions +``` + +#### 複雜度分析 +- **時間複雜度**: $O(n)$,其中 $n$ 是字符串的長度,遍歷字符串兩次,一次建立字典,一次劃分區間。 + +- **空間複雜度**: $O(1)$,只使用了固定大小的字典和變數來儲存訊息。 + +
        + + ### [122. Best Time to Buy and Sell Stock II](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/) 股票交易題型裡比較簡單的題目,在不限制交易次數的情況下,怎樣可以獲得最大利潤呢? +
        + 題解 + +#### 解題思路 + +- 本題目允許多次交易(先買後賣),目標是最大化利潤。 +- **貪婪算法 (Greedy)**: + - 對於每一天,如果當天的價格高於前一天,就進行一次交易,將差值加入總利潤。 + - 本質上等價於抓住所有上升區間的收益。 +- 不需要記錄實際的交易,只需累加所有價格上升的差值。 + +```python +class Solution: + def maxProfit(self, prices: List[int]) -> int: + profit = 0 + for i in range(1, len(prices)): + if prices[i] > prices[i - 1]: + profit += prices[i] - prices[i - 1] + return profit +``` + +#### 複雜度分析 +- **時間複雜度**: $O(n)$,其中 $n$ 是 prices 的長度,需遍歷整個價格列表一次。 + +- **空間複雜度**: $O(1)$,只使用了常數額外空間。 + +
        + ## 進階難度 ### [406. Queue Reconstruction by Height](https://leetcode.com/problems/queue-reconstruction-by-height/) 溫馨提示,這道題可能同時需要排序和插入操作。 +
        + 題解 + +#### 解題思路 + +- **問題描述**: + 給定一組 `(h, k)` 人物對,其中 `h` 是身高,`k` 是在這個人前面身高至少與他相同的人數。根據這些條件,重建排列隊列。 + +- **貪婪算法**: + - 將所有人按照 **身高降序** 和 **k 值升序** 排序。 + - 初始化一個空隊列,依次將排序後的人插入隊列的第 `k` 個位置。 + - 由於身高越高的人已經插入,他們對後續的插入順序不產生影響。 + +```python +class Solution: + def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]: + # 按身高降序,k 值升序排序 + people.sort(key=lambda x: (-x[0], x[1])) + queue = [] + for person in people: + queue.insert(person[1], person) + return queue +``` + +#### 複雜度分析 +- **時間複雜度**: $O(n^2)$,其中 $n$ 是 people 的長度。 + - 排序需要 $O(n \log n)$。 + - 插入操作在最壞情況下需要 $O(n^2)$。 + +- **空間複雜度**: $O(n)$,用於儲存重建的隊列。 +
        ### [665. Non-decreasing Array](https://leetcode.com/problems/non-decreasing-array/) -需要仔細思考你的貪心策略在各種情況下,是否仍然是最優解。 \ No newline at end of file +需要仔細思考你的貪心策略在各種情況下,是否仍然是最優解。 + +
        + 題解 + +#### 解題思路 + +- **問題描述**: + 確認是否可以最多修改一個元素,讓整個陣列成為非遞減(每個元素小於或等於後一個元素)。 + +- **關鍵點**: + - 遍歷陣列時檢查是否有不符合非遞減的地方(即 `nums[i] > nums[i+1]`)。 + - 每次遇到不符合的情況: + - 嘗試修改 `nums[i]` 或 `nums[i+1]`,使整體保持非遞減。 + - 如果已經修改過一次,再次出現問題時直接返回 `False`。 + +- **修改策略**: + - 如果 `nums[i-1] <= nums[i+1]`,將 `nums[i]` 修改為 `nums[i+1]`。 + - 否則,將 `nums[i+1]` 修改為 `nums[i]`。 + +```python +class Solution: + def checkPossibility(self, nums: List[int]) -> bool: + modified = False # 是否已經修改過一次 + for i in range(len(nums) - 1): + if nums[i] > nums[i + 1]: # 發現不符合非遞減的情況 + if modified: # 已經修改過一次 + return False + # 嘗試修改 + if i == 0 or nums[i - 1] <= nums[i + 1]: + nums[i] = nums[i + 1] # 修改 nums[i] + else: + nums[i + 1] = nums[i] # 修改 nums[i+1] + modified = True # 標記已修改 + return True +``` + +#### 複雜度分析 +- **時間複雜度**: $O(n)$,其中 $n$ 是陣列的長度,只需遍歷陣列一次。 + +- **空間複雜度**: $O(1)$,只使用了常數額外空間。 + +
        \ No newline at end of file From f5001dbc8bfe9b472f2392c96456c1ba207c4b5f Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Tue, 26 Nov 2024 19:02:52 +0100 Subject: [PATCH 27/49] i18n chapter 10 --- .../10-data-structures/10-1-cpp-stl.md | 52 +++++++++-------- .../10-10-prefix-sum-integral-image.mdx | 33 ++++++----- .../10-data-structures/10-11-exercises.md | 42 ++++++++++---- .../10-2-python-data-structures.md | 35 ++++++----- .../10-data-structures/10-3-arrays.mdx | 34 +++++------ .../10-4-stack-and-queue.mdx | 22 +++---- .../10-5-monotonic-stack.mdx | 10 ++-- .../10-6-priority-queue.mdx | 58 +++++++++---------- .../current/10-data-structures/10-7-deque.mdx | 17 ++++-- .../10-data-structures/10-8-hash-table.mdx | 40 ++++++------- .../10-9-multisets-and-maps.mdx | 10 ++-- .../1-2-assignment-problems.mdx | 8 +-- .../1-3-interval-problems.mdx | 4 +- .../10-data-structures/10-1-cpp-stl.md | 47 ++++++++------- .../10-10-prefix-sum-integral-image.mdx | 32 +++++----- .../10-data-structures/10-11-exercises.md | 42 ++++++++++---- .../10-2-python-data-structures.md | 34 ++++++----- .../10-data-structures/10-3-arrays.mdx | 34 +++++------ .../10-4-stack-and-queue.mdx | 22 +++---- .../10-5-monotonic-stack.mdx | 10 ++-- .../10-6-priority-queue.mdx | 49 ++++++++-------- .../current/10-data-structures/10-7-deque.mdx | 12 ++-- .../10-data-structures/10-8-hash-table.mdx | 36 ++++++------ .../10-9-multisets-and-maps.mdx | 8 +-- .../2-1-algorithm-explanation.md | 14 ++--- .../2-two-pointer-techniques/2-2-two-sum.mdx | 8 +-- .../2-3-merge-sorted-arrays.mdx | 10 ++-- .../2-4-sliding-window.mdx | 2 +- .../2-two-pointer-techniques/2-6-exercises.md | 2 +- .../3-1-algorithm-explanation.md | 6 +- .../3-3-interval-search.mdx | 4 +- .../3-4-peak-finding.mdx | 6 +- .../3-5-rotated-array-search.mdx | 8 +-- .../3-6-exercises.md | 4 +- .../4-1-common-sorting-algorithms.mdx | 4 +- .../4-sorting-algorithms/4-2-quick-select.mdx | 6 +- .../4-sorting-algorithms/4-3-bucket-sort.mdx | 4 +- .../5-2-depth-first-search.mdx | 6 +- .../5-3-backtracking.mdx | 4 +- .../6-dynamic-programming/6-2-basic-dp-1d.mdx | 14 ++--- .../6-dynamic-programming/6-3-basic-dp-2d.mdx | 6 +- .../6-6-knapsack-problem.mdx | 4 +- .../6-7-string-editing.mdx | 4 +- .../6-8-stock-trading.mdx | 10 ++-- .../6-dynamic-programming/6-9-exercises.md | 2 +- .../7-1-algorithm-explanation.md | 4 +- .../7-2-expression-problems.mdx | 2 +- .../8-5-random-sampling.mdx | 16 ++--- .../9-2-basic-bitwise-problems.mdx | 6 +- .../9-3-binary-properties.mdx | 8 +-- 50 files changed, 457 insertions(+), 398 deletions(-) diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-1-cpp-stl.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-1-cpp-stl.md index 2ec42832..55bec1f2 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-1-cpp-stl.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-1-cpp-stl.md @@ -4,27 +4,31 @@ sidebar_position: 48 # 10.1 C++ STL -在刷题时,我们几乎一定会用到各种数据结构来辅助我们解决问题,因此我们必须熟悉各种数据结构的特点。C++ STL 提供的数据结构包括(实际底层细节可能因编译器而异): - -1. Sequence Containers:维持顺序的容器。 - 1. vector:`动态数组`,是我们最常使用的数据结构之一,用于 $O(1)$ 的随机读取。因为大部分算法的时间复杂度都会大于 $O(n)$,因此我们经常新建 vector 来存储各种数据或中间变量。因为在尾部增删的复杂度是 $O(1)$,我们也可以把它当作 stack 来用。 - 2. list:`双向链表`,也可以当作 stack 和 queue 来使用。由于 LeetCode 的题目多用 Node 来表示链表,且链表不支持快速随机读取,因此我们很少用到这个数据结构。一个例外是经典的 LRU 问题,我们需要利用链表的特性来解决,我们在后文会遇到这个问题。 - 3. deque:双端队列,这是一个非常强大的数据结构,既支持 $O(1)$ 随机读取,又支持 $O(1)$ 时间的头部增删和尾部增删(因此可以当作 stack 和 queue 来使用),不过有一定的额外开销。也可以用来近似一个双向链表来使用。 - 4. array:固定大小的数组,一般在刷题时我们不使用。 - 5. forward_list:单向链表,一般在刷题时我们不使用。 -2. Container Adaptors:基于其它容器实现的容器。 - 1. stack:`后入先出(LIFO)的数据结构`,默认基于 deque 实现。stack 常用于深度优先搜索、一些字符串匹配问题以及单调栈问题。 - 2. `先入先出(FIFO)的数据结构`,默认基于 deque 实现。queue 常用于广度优先搜索。 - 3. priority_queue:`优先队列(最大值先出的数据结构)`,默认基于 vector 实现堆结构。它可以在 $O(n \log n)$ 的时间排序数组,$O(\log n)$ 的时间插入任意值,$O(1)$ 的时间获得最大值,$O(\log n)$ 的时间删除最大值。priority_queue 常用于维护数据结构并快速获取最大值,并且可以自定义比较函数;比如通过存储负值或者更改比小函数为比大函数,即可实现最小值先出。 -3. Ordered Associative Containers:有序关联容器。 - 1. set:有序集合,元素不可重复,底层实现默认为红黑树,即一种特殊的二叉查找树(BST)。它可以在 $O(n \log n)$ 的时间排序数组,$O(\log n)$ 的时间插入、删除、查找任意值,$O(\log n)$ 的时间获得最小或最大值。这里注意,set 和 priority_queue 都可以用于维护数据结构并快速获取最大最小值,但是它们的时间复杂度和功能略有区别,如 priority_queue 默认不支持删除任意值,而 set 获得最大或最小值的时间复杂度略高,具体使用哪个根据需求而定。 - 2. multiset:支持重复元素的 set。 - 3. map:`有序映射或有序表`,在 set 的基础上加上映射关系,可以对每个元素 key 存一个值 value。 - 4. multimap:支持重复元素的 map。 -4. Unordered Associative Containers:无序关联容器。 - 1. unordered_set:`哈希集合`,可以在 $O(1)$ 的时间快速插入、查找、删除元素,常用于快速的查询一个元素是否在这个容器内。 - 2. unordered_multiset:支持重复元素的 unordered_set。 - 3. unordered_map:`哈希映射或哈希表`,在 unordered_set 的基础上加上映射关系,可以对每一个元素 key 存一个值 value。在某些情况下,如果 key 的范围已知且较小,我们也可以用 vector 代替 unordered_map,用位置表示 key,用每个位置的值表示 value。 - 4. unordered_multimap:支持重复元素的 unordered_map。 - -因为这并不是一本讲解 C++ 原理的书,更多的 STL 细节请读者自行搜索。只有理解了这些数据结构的原理和使用方法,才能够更加游刃有余地解决算法和数据结构问题。 +When solving problems, we almost always rely on various data structures to assist us. Therefore, we must familiarize ourselves with the characteristics of each data structure. C++ STL provides several data structures (the actual underlying implementation may vary depending on the compiler): + +1. **Sequence Containers**: Containers that maintain order. + 1. **vector**: A `dynamic array`, one of the most frequently used data structures, ideal for $O(1)$ random access. Since most algorithms have a time complexity greater than $O(n)$, we often use vectors to store various data or intermediate results. As insertion and deletion at the tail have $O(1)$ complexity, it can also be used as a stack. + 2. **list**: A `doubly linked list`, which can also be used as a stack or queue. However, since LeetCode problems often use Nodes to represent linked lists, and linked lists do not support fast random access, this data structure is rarely used. An exception is the classic LRU problem, where the characteristics of linked lists are utilized, as discussed later. + 3. **deque**: A double-ended queue, a powerful data structure that supports $O(1)$ random access and $O(1)$ insertion and deletion at both ends. It can be used as a stack or queue but comes with some overhead. It can also approximate a doubly linked list. + 4. **array**: A fixed-size array, generally not used in competitive programming. + 5. **forward_list**: A singly linked list, which is also generally not used in competitive programming. + +2. **Container Adaptors**: Containers implemented on top of other containers. + 1. **stack**: A `Last In First Out (LIFO)` data structure, implemented using deque by default. It is commonly used for depth-first search, certain string matching problems, and monotonic stack problems. + 2. **queue**: A `First In First Out (FIFO)` data structure, implemented using deque by default. It is commonly used for breadth-first search. + 3. **priority_queue**: A `priority queue (max-heap by default)` data structure, implemented using a vector as a heap. It supports sorting arrays in $O(n \log n)$ time, inserting any value in $O(\log n)$ time, retrieving the maximum value in $O(1)$ time, and deleting the maximum value in $O(\log n)$ time. priority_queue is used to maintain data structures and retrieve maximum values efficiently, and it allows custom comparison functions. For example, by storing negative values or changing the comparison function, a min-heap can be implemented. + +3. **Ordered Associative Containers**: Ordered associative containers. + 1. **set**: An ordered set where elements are unique, implemented using a red-black tree, a specialized Binary Search Tree (BST). It supports sorting arrays in $O(n \log n)$ time, inserting, deleting, or finding any value in $O(\log n)$ time, and retrieving the minimum or maximum value in $O(\log n)$ time. Note that both set and priority_queue can be used to maintain data structures and retrieve maximum or minimum values efficiently, but their time complexities and functionalities differ slightly. For instance, priority_queue does not support arbitrary value deletion by default, whereas set's time complexity for retrieving maximum or minimum values is slightly higher. The choice depends on specific requirements. + 2. **multiset**: A set that allows duplicate elements. + 3. **map**: An `ordered map or ordered table`, which extends set by associating each key with a value. + 4. **multimap**: A map that allows duplicate keys. + +4. **Unordered Associative Containers**: Containers with unordered associations. + 1. **unordered_set**: A `hash set` that allows for $O(1)$ time complexity for insertion, lookup, and deletion of elements. It is commonly used to quickly check if an element exists in the container. + 2. **unordered_multiset**: A hash set that supports duplicate elements. + 3. **unordered_map**: A `hash map` or `hash table` that extends unordered_set by mapping each key to a value. In some cases, if the range of keys is known and small, a vector can be used as a replacement for unordered_map, using the index to represent the key and the value at that index to represent the value. + 4. **unordered_multimap**: A hash map that supports duplicate keys. + +Since this is not a book on C++ fundamentals, more details about STL can be found through further research. Understanding the principles and usage of these data structures is crucial for solving algorithm and data structure problems effectively. + diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-10-prefix-sum-integral-image.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-10-prefix-sum-integral-image.mdx index 70062d7a..deb8157d 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-10-prefix-sum-integral-image.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-10-prefix-sum-integral-image.mdx @@ -2,19 +2,19 @@ sidebar_position: 57 --- -# 10.10 前缀和与积分图 +# 10.10 Prefix Sum and Integral Image -一维的前缀和(cumulative sum, cumsum),二维的积分图(summed-area table, image integral)都是把每个位置之前的一维线段或二维矩形预先存储,方便加速计算。如果需要对前缀和或积分图的值做寻址,则要存入哈希表;如果要对每个位置记录前缀和或积分图的值,则可以储存到一维或二维数组里,也常常伴随着动态规划。 +A one-dimensional prefix sum (cumulative sum, cumsum) and a two-dimensional integral image (summed-area table, image integral) are techniques used to precompute the sums of one-dimensional segments or two-dimensional rectangles up to each position. This allows for faster calculations and queries. If you need to index values from the prefix sum or integral image, they can be stored in a hash table. If you need to record values for each position, they can be stored in one-dimensional or two-dimensional arrays, often in conjunction with dynamic programming. ## [303. Range Sum Query - Immutable](https://leetcode.com/problems/range-sum-query-immutable/) ### Problem Description -设计一个数据结构,使得其能够快速查询给定数组中,任意两个位置间所有数字的和。 +Design a data structure to quickly query the sum of all numbers between any two positions in a given array. ### Input and Output Example -以下是数据结构的调用样例。 +Here is a sample usage of the data structure. ``` vector nums{-2,0,3,-5,2,-1}; @@ -25,7 +25,7 @@ num_array.sunRange(1,5); // Result = 0+3-5+2-1 = -1. ### Solution Explanation -对于一维的数组,我们可以使用前缀和来解决此类问题。先建立一个与数组 nums 长度相同的新数组 cumsum,表示 nums 每个位置之前前所有数字的和。cumsum 数组可以通过 C++ 自带的 partial_sum 函数建立,也可以直接遍历一遍 nums 数组,并利用状态转移方程 cumsum[i] = cumsum[i-1] + nums[i] 完成统计。如果我们需要获得位置 i 和 j 之间的数字和,只需计算 cum - sum[j+1] - cumsum[i] 即可。 +For a one-dimensional array, we can use a prefix sum to solve this problem. First, create a new array `cumsum` of the same length as `nums`, where each position in `cumsum` stores the sum of all numbers in `nums` up to that position. The `cumsum` array can be built using the C++ `partial_sum` function or by iterating through the `nums` array and calculating it using the state transition formula `cumsum[i] = cumsum[i-1] + nums[i]`. To obtain the sum of numbers between positions `i` and `j`, calculate `cumsum[j+1] - cumsum[i]`. @@ -68,11 +68,11 @@ class NumArray: ### Problem Description -设计一个数据结构,使得其能够快速查询给定矩阵中,任意两个位置包围的长方形中所有数字的和。 +Design a data structure to quickly query the sum of all numbers within a rectangle defined by any two positions in a given matrix. ### Input and Output Example -以下是数据结构的调用样例。其中 sumRegion 函数的四个输入分别是第一个点的横、纵坐标,和第二个点的横、纵坐标。 +Here is a sample usage of the data structure. The `sumRegion` function takes four inputs: the row and column of the first point, and the row and column of the second point. ``` vector matrix{{3,0,1,4,2}, @@ -88,13 +88,13 @@ num_matrix.sumRegion(1,1,2,2); // Result = 11. ### Solution Explanation -类似于前缀和,我们可以把这种思想拓展到二维,即积分图(summed-area table, image integral)。我们可以先建立一个 sat 矩阵,sat[i][j] 表示以位置 (0, 0) 为左上角、位置 (i-1, j-1) 为右下角的长方形中所有数字的和。 +Similar to prefix sums, we can extend this concept to two dimensions, known as a summed-area table (SAT) or image integral. We can first build an `sat` matrix, where `sat[i][j]` represents the sum of all numbers in the rectangle defined by `(0, 0)` as the top-left corner and `(i-1, j-1)` as the bottom-right corner.
        ![](10.4.png) -
        图 10.4: 题目 304 - 图 1 - 左边为给定矩阵,右边为积分图结果,右下角位置的积分图值为 5+48+45− 40 =58
        +
        Figure 10.4: Problem 304 - Diagram 1 - The left shows the given matrix, and the right shows the summed-area table. The value at the bottom-right corner of the SAT is 5+48+45−40 = 58.
        @@ -102,12 +102,13 @@ num_matrix.sumRegion(1,1,2,2); // Result = 11. ![](10.5.png) -
        图 10.5: 题目 304 - 图 2 - 左边为给定矩阵,右边为积分图结果,长方形 E 的数字和等于 58 − 11 − 13 +3 =37
        +
        Figure 10.5: Problem 304 - Diagram 2 - The left shows the given matrix, and the right shows the SAT. The sum of rectangle E equals 58 − 11 − 13 + 3 = 37.
        -如图 1 所示,我们可以用动态规划来计算 sat 矩阵:sat[i][j] = matrix[i-1][j-1] + sat[i-1][j] + sat[i][j-1] - sat[i-1][j-1],即当前坐标的数字 + 上面长方形的数字和 + 左边长方形的数字和 - 上面长方形和左边长方形重合面积(即左上一格的长方形)中的数字和。 +As shown in Figure 1, we can compute the `sat` matrix using dynamic programming: `sat[i][j] = matrix[i-1][j-1] + sat[i-1][j] + sat[i][j-1] - sat[i-1][j-1]`, which is the value at the current coordinate plus the sum of the rectangle above it plus the sum of the rectangle to its left minus the overlap (i.e., the top-left rectangle). + +As shown in Figure 2, suppose we need to query the sum of rectangle E. Since `E = D − B − C + A`, we observe that E can be derived using addition and subtraction of SAT values at four positions. Thus, the preprocessing time complexity is $O(mn)$, while the query time complexity is only $O(1)$. -如图 2 所示,假设我们要查询长方形 E 的数字和,因为 E = D − B − C + A,我们发现 E 其实可以由四个位置的积分图结果进行加减运算得到。因此这个算法在预处理时的时间复杂度为 $O(mn)$,而在查询时的时间复杂度仅为 $O(1)$。 @@ -172,22 +173,22 @@ class NumMatrix: ### Problem Description -给定一个数组,寻找和为 k 的连续区间个数。 +Given an array, find the number of continuous subarrays whose sum equals $k$. ### Input and Output Example -输入一个一维整数数组和一个整数值 k;输出一个整数,表示满足条件的连续区间个数。 +Input is a one-dimensional integer array and an integer value $k$; output is an integer representing the number of subarrays that meet the condition. ``` Input: nums = [1,1,1], k = 2 Output: 2 ``` -在这个样例中,我们可以找到两个 [1,1] 连续区间满足条件。 +In this example, we can find two subarrays [1,1] that satisfy the condition. ### Solution Explanation -本题同样是利用前缀和,不同的是这里我们使用一个哈希表 cache,其键是前缀和,而值是该前缀和出现的次数。在我们遍历到位置 i 时,假设当前的前缀和是 cumsum,那么 cache[cumsum-k] 即为以当前位置结尾、满足条件的区间个数。 +This problem also uses prefix sums. The difference here is that we employ a hash table `cache` where the keys are prefix sums and the values are the number of times that prefix sum appears. When iterating to position $i$, if the current prefix sum is `cumsum`, then `cache[cumsum-k]` represents the number of subarrays ending at the current position that satisfy the condition. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-11-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-11-exercises.md index ed345083..319a0dc3 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-11-exercises.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-11-exercises.md @@ -8,46 +8,66 @@ sidebar_position: 58 ### [566. Reshape the Matrix](https://leetcode.com/problems/reshape-the-matrix/) -没有什么难度,只是需要一点耐心。 +This problem is not particularly challenging; it only requires some patience. + +--- ### [225. Implement Stack using Queues](https://leetcode.com/problems/implement-stack-using-queues/) -利用相似的方法,我们也可以用 queue 实现 stack。 +Using a similar approach, we can also implement a stack using queues. + +--- ### [503. Next Greater Element II](https://leetcode.com/problems/next-greater-element-ii/) -Daily Temperature 的变种题。 +A variant of the `Daily Temperatures` problem. + +--- ### [217. Contains Duplicate](https://leetcode.com/problems/contains-duplicate/) -使用什么数据结构可以快速判断重复呢? +Which data structure would allow us to quickly check for duplicates? + +--- ### [697. Degree of an Array](https://leetcode.com/problems/degree-of-an-array/) -如何对数组进行预处理才能正确并快速地计算子数组的长度? +How can we preprocess an array to correctly and efficiently compute the length of a subarray? + +--- ### [594. Longest Harmonious Subsequence](https://leetcode.com/problems/longest-harmonious-subsequence/) -最长连续序列的变种题。 +A variant of the `Longest Consecutive Sequence` problem. + +--- ### [15. 3Sum](https://leetcode.com/problems/3sum/) -因为排序的复杂度是 $O(n \log n) < O(n^2)$,因此我们既可以排序后再进行 $O(n^2)$ 的指针搜索,也可以直接利用哈希表进行 $O(n^2)$ 的搜索。 +Since the complexity of sorting is $O(n \log n) < O(n^2)$, we can either sort the array first and then perform an $O(n^2)$ pointer search, or directly use a hash table for an $O(n^2)$ search. ## Advanced Difficulty +--- + ### [287. Find the Duplicate Number](https://leetcode.com/problems/find-the-duplicate-number/) -寻找丢失数字的变种题。除了标负位置,你还有没有其它算法可以解决这个问题? +A variant of the `Find Missing Number` problem. Besides marking negative values, are there any other algorithms to solve this? + +--- ### [313. Super Ugly Number](https://leetcode.com/problems/super-ugly-number/) -尝试使用优先队列解决这一问题。 +Try solving this using a priority queue. + +--- ### [870. Advantage Shuffle](https://leetcode.com/problems/advantage-shuffle/) -如果我们需要比较大小关系,而且同一数字可能出现多次,那么应该用什么数据结构呢? +If we need to compare relative sizes and the same number can appear multiple times, which data structure should we use? + +--- ### [307. Range Sum Query - Mutable](https://leetcode.com/problems/range-sum-query-mutable/) -前缀和的变种题。好吧我承认,这道题可能有些超纲,你或许需要搜索一下什么是线段树。 \ No newline at end of file +A variant of the `Prefix Sum` problem. I admit this might be slightly advanced; you might want to look up what a `Segment Tree` is. \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-2-python-data-structures.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-2-python-data-structures.md index b4221a27..c1a2a6b7 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-2-python-data-structures.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-2-python-data-structures.md @@ -2,21 +2,24 @@ sidebar_position: 49 --- -# 10.2 Python 常用数据结构 +# 10.2 Python Common Data Structures -类似于 C++ STL,Python 也提供了类似的数据结构(实际底层细节可能因编译器而异): +Similar to C++ STL, Python also provides various data structures (the underlying details may vary depending on the implementation): -1. Sequence Containers:维持顺序的容器。 - 1. list:`动态数组`,是我们最常使用的数据结构之一,用于 $O(1)$ 的随机读取。因为大部分算法的时间复杂度都会大于 $O(n)$,因此我们经常新建 list 来存储各种数据或中间变量。因为在尾部增删的复杂度是 $O(1)$,我们也可以把它当作 stack 来用。 - 2. tuple: `元组`,immutable list,不可改变其中元素或总长度。 - 3. collections.deque:`双端队列`,这是一个非常强大的数据结构,既支持 $O(1)$ 随机读取,又支持 $O(1)$ 时间的头部增删和尾部增删(因此可以当作 stack 和 queue 来使用),不过有一定的额外开销。也可以用来近似一个双向链表来使用。 -2. Container Adaptors:基于其它容器实现的容器。 - 1. heapq:`最小堆(最小值先出的数据结构)`,默认基于 list 实现堆结构。它可以在 $O(n \log n)$ 的时间排序数组,$O(\log n)$ 的时间插入任意值,$O(1)$ 的时间获得最小值,$O(\log n)$ 的时间删除最小值。heapq 常用于维护数据结构并快速获取最小值,但不支持自定义比较函数。所以通常我们需要提前算好自定义值,再把 (自定义值,位置) 的 tuple 存进 heapq。这样进行比较时就会默认从左到右比较 tuple 中的元素,即先比较自定义值,再比较元素的插入次序。 -3. Ordered Associative Containers:有序关联容器。 - 1. collections.OrderedDict:`顺序映射或顺序表`,注意这里的 Ordered 不同于 C++ 中 map的按大小排序,而是按照插入的先后次序排序。OrderedDict 很适合用来做 LRU。 -4. Unordered Associative Containers:无序关联容器。 - 1. set:`哈希集合`,可以在 O(1) 的时间快速插入、查找、删除元素,常用于快速的查询一个元素是否在这个容器内。 - 2. dict:`哈希映射或哈希表`,在 set 的基础上加上映射关系,可以对每一个元素 key 存一个值 value。在某些情况下,如果 key 的范围已知且较小,我们也可以用 list 代替 dict,用位置表示 key,用每个位置的值表示 value。 - 3. collections.Counter:`计数器`,是 dict 的一个特殊版本,可以直接传入一个 list,并对其中的每一个元素进行计数统计,key 是元素值,value 是元素出现的频次。可以用来当作多重集合。 - -同样的,因为这并不是一本讲解 Python 原理的书,更多的数据结构细节请读者自行搜索。只有理解了这些数据结构的原理和使用方法,才能够更加游刃有余地解决算法和数据结构问题。 \ No newline at end of file +1. **Sequence Containers**: Containers that maintain order. + 1. **list**: A `dynamic array`, one of the most commonly used data structures for $O(1)$ random access. Since most algorithm complexities exceed $O(n)$, lists are frequently used to store data or intermediate results. As adding or removing elements at the end has $O(1)$ complexity, lists can also be used as stacks. + 2. **tuple**: An `immutable list`, where neither the elements nor the length can be modified. + 3. **collections.deque**: A `double-ended queue`, a powerful data structure supporting $O(1)$ random access as well as $O(1)$ insertion and deletion at both ends (making it useful as a stack or queue). It has some overhead but can approximate a doubly linked list. + +2. **Container Adaptors**: Containers built on top of other data structures. + 1. **heapq**: A `min-heap` (a data structure where the smallest element is accessed first), implemented using lists. It supports array sorting in $O(n \log n)$, value insertion in $O(\log n)$, access to the smallest value in $O(1)$, and deletion of the smallest value in $O(\log n)$. `heapq` is often used for maintaining data structures and quickly accessing the smallest value, but it doesn't support custom comparison functions. Typically, we precompute the custom values and store them as tuples, like `(custom_value, index)`, in the heap. This way, tuple comparisons are done from left to right, comparing the custom value first and then the insertion order. + +3. **Ordered Associative Containers**: + 1. **collections.OrderedDict**: `Ordered mapping or ordered table`. Note that "Ordered" here means maintaining the insertion order, unlike C++'s map, which sorts keys by size. `OrderedDict` is particularly useful for implementing LRU (Least Recently Used) caching. + +4. **Unordered Associative Containers**: + 1. **set**: `Hash set`. Allows for fast insertion, lookup, and deletion of elements in O(1) time. Commonly used to quickly check if an element exists in the container. + 2. **dict**: `Hash map or hash table`. Builds upon the set structure by adding key-value mapping. In some scenarios, if the key range is known and small, a list can replace a dict, using indices to represent keys and list values for their corresponding values. + 3. **collections.Counter**: `Counter`. A specialized version of dict that accepts a list and counts the frequency of each element. Keys are the element values, and values are their frequencies. This can serve as a multiset. + +Similarly, since this is not a book on Python internals, readers are encouraged to explore more details about these data structures. Understanding their principles and usage will enable more effective problem-solving in algorithms and data structures. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-3-arrays.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-3-arrays.mdx index 8aa59501..fa0c98df 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-3-arrays.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-3-arrays.mdx @@ -2,29 +2,27 @@ sidebar_position: 50 --- -# 10.3 数组 +# 10.3 Arrays ## [448. Find All Numbers Disappeared in an Array](https://leetcode.com/problems/find-all-numbers-disappeared-in-an-array/) ### Problem Description -给定一个长度为 n 的数组,其中包含范围为 1 到 n 的整数,有些整数重复了多次,有些整数没有出现,求 1 到 n 中没有出现过的整数。 +Given an array of length n containing integers in the range from 1 to n, some integers appear multiple times, while others do not appear at all. Find all integers from 1 to n that are missing in the array. ### Input and Output Example -输入是一个一维整数数组,输出也是一个一维整数数组,表示输入数组内没出现过的数字。 +Input is a one-dimensional integer array, and the output is also a one-dimensional integer array representing the numbers that do not appear in the input array. ``` Input: [4,3,2,7,8,2,3,1] Output: [5,6] ``` -利用数组这种数据结构建立 n 个桶,把所有重复出现的位置进行标记,然后再遍历一遍数组,即可找到没有出现过的数字。进一步地,我们可以直接对原数组进行标记:把重复出现的数字-1在原数组的位置设为负数(这里-1 的目的是把 1 到 n 的数字映射到 0 到 n-1 的位置),最后仍然为正数的位置 +1 即为没有出现过的数。 +By using the array as a data structure to create n buckets, mark all positions where numbers appear multiple times, and then traverse the array to find the missing numbers. Furthermore, we can directly modify the original array: mark the positions corresponding to the numbers that appear as negative (this maps numbers from 1 to n to indices 0 to n-1), and the indices that remain positive correspond to the missing numbers. ### Solution Explanation - - @@ -66,11 +64,11 @@ def findDisappearedNumbers(nums: List[int]) -> List[int]: ### Problem Description -给定一个 n × n 的矩阵,求它顺时针旋转 90 度的结果,且必须在原矩阵上修改(in-place)。怎样能够尽量不创建额外储存空间呢? +Given an n × n matrix, rotate it 90 degrees clockwise in place. How can this be done with minimal additional storage space? ### Input and Output Example -输入和输出都是一个二维整数矩阵。 +Both the input and output are two-dimensional integer matrices. ``` Input: @@ -85,13 +83,13 @@ Output: ### Solution Explanation -每次只考虑四个间隔 90 度的位置,可以进行 O(1) 额外空间的旋转。 +Consider four positions spaced 90 degrees apart each time, and perform an $O(1)$ space rotation.
        ![](10.1.png) -
        图 10.1: 题目 48 - $O(1)$ 空间旋转样例,相同颜色代表四个互相交换的位置
        +
        Figure 10.1: Problem 48 - Example of $O(1)$ space rotation, same colors indicate four positions to be swapped
        @@ -135,11 +133,11 @@ def rotate(matrix: List[List[int]]) -> None: ### Problem Description -给定一个二维矩阵,已知每行和每列都是增序的,尝试设计一个快速搜索一个数字是否在矩阵中存在的算法。 +Given a 2D matrix where each row and each column is sorted in ascending order, design a fast algorithm to search for a number in the matrix. ### Input and Output Example -输入是一个二维整数矩阵,和一个待搜索整数。输出是一个布尔值,表示这个整数是否存在于矩阵中。 +The input is a two-dimensional integer matrix and a target integer to search. The output is a boolean value indicating whether the integer exists in the matrix. ``` Input: matrix = @@ -153,7 +151,7 @@ Output: true ### Solution Explanation -这道题有一个简单的技巧:我们可以从右上角开始查找,若当前值大于待搜索值,我们向左移动一位;若当前值小于待搜索值,我们向下移动一位。如果最终移动到左下角时仍不等于待搜索值,则说明待搜索值不存在于矩阵中。 +There is a simple trick for this problem: Start searching from the top-right corner. If the current value is greater than the target, move left; if it is smaller than the target, move down. If you reach the bottom-left corner without finding the target, the value does not exist in the matrix. @@ -200,24 +198,24 @@ def searchMatrix(matrix: List[List[int]], target: int) -> bool: ### Problem Description -给定一个含有 0 到 n 整数的数组,每个整数只出现一次,求这个数组最多可以分割成多少个子数组,使得对每个子数组进行增序排序后,原数组也是增序的。 +Given an array of integers containing 0 to n, where each integer appears only once, find the maximum number of chunks you can split the array into such that sorting each chunk results in the entire array being sorted in ascending order. ### Input and Output Example -输入一个一维整数数组,输出一个整数,表示最多的分割数。 +The input is a one-dimensional integer array, and the output is an integer representing the maximum number of chunks. ``` Input: [1,0,2,3,4] Output: 4 ``` -在这个样例中,最多分割是 [1, 0], [2], [3], [4]。 +In this example, the maximum chunks are [1, 0], [2], [3], [4]. ### Solution Explanation -从左往右遍历,同时记录当前的最大值,每当当前最大值等于数组位置时,我们可以多一次分割。 +Iterate from left to right, keeping track of the current maximum value. Whenever the current maximum value equals the current array index, we can perform a split. -为什么可以通过这个算法解决问题呢?如果当前最大值大于数组位置,则说明右边一定有小于数组位置的数字,需要把它也加入待排序的子数组;又因为数组只包含不重复的 0 到 n,所以当前最大值一定不会小于数组位置。所以每当当前最大值等于数组位置时,假设为 p,我们可以成功完成一次分割,并且其与上一次分割位置 q 之间的值一定是 q +1 到 p 的所有数字。 +Why does this algorithm work? If the current maximum value is greater than the current array index, it means there are smaller values on the right that need to be included in the chunk. Since the array contains only unique integers from 0 to n, the current maximum value will never be less than the current index. Therefore, whenever the current maximum value equals the current index, say p, we can successfully make a split. The values between the previous split point q and p will always contain all integers from q+1 to p. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-4-stack-and-queue.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-4-stack-and-queue.mdx index 5e5ea5f2..07d6ceb0 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-4-stack-and-queue.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-4-stack-and-queue.mdx @@ -2,17 +2,17 @@ sidebar_position: 51 --- -# 10.4 栈和队列 +# 10.4 Stacks and Queues ## [232. Implement Queue using Stacks](https://leetcode.com/problems/implement-queue-using-stacks/) ### Problem Description -尝试使用栈(stack)来实现队列(queue)。 +Try to implement a queue using stacks. ### Input and Output Example -以下是数据结构的调用样例。 +Here is an example of how the data structure is used. ``` MyQueue queue = new MyQueue(); @@ -25,7 +25,7 @@ queue.empty(); // returns false ### Solution Explanation -我们可以用两个栈来实现一个队列:因为我们需要得到先入先出的结果,所以必定要通过一个额外栈翻转一次数组。这个翻转过程既可以在插入时完成,也可以在取值时完成。我们这里展示在取值时完成的写法。 +We can implement a queue using two stacks: since we need a first-in-first-out result, we must reverse the array once using an additional stack. This reversing process can be completed either during insertion or during retrieval. Below is an example of implementing the reversal during retrieval. @@ -105,11 +105,11 @@ class MyQueue: ### Problem Description -设计一个最小栈,除了需要支持常规栈的操作外,还需要支持在 $O(1)$ 时间内查询栈内最小值的功能。 +Design a minimum stack that supports not only regular stack operations but also retrieving the minimum value in the stack in $O(1)$ time. ### Input and Output Example -以下是数据结构的调用样例。 +Here is an example of how the data structure is used. ``` MinStack minStack = new MinStack(); @@ -124,9 +124,9 @@ minStack.getMin(); // Returns -2. ### Solution Explanation -我们可以额外建立一个新栈,栈顶表示原栈里所有值的最小值。每当在原栈里插入一个数字时,若该数字小于等于新栈栈顶,则表示这个数字在原栈里是最小值,我们将其同时插入新栈内。每当从原栈里取出一个数字时,若该数字等于新栈栈顶,则表示这个数是原栈里的最小值之一,我们同时取出新栈栈顶的值。 +We can maintain an additional stack where the top represents the minimum value of all elements in the main stack. Every time a number is pushed onto the main stack, if it is less than or equal to the top of the auxiliary stack, it is also pushed onto the auxiliary stack, indicating it is a minimum value in the main stack. Similarly, every time a number is popped from the main stack, if it equals the top of the auxiliary stack, the top value of the auxiliary stack is also popped. -一个写起来更简单但是时间复杂度略高的方法是,我们每次插入原栈时,都向新栈插入一次原栈里所有值的最小值(新栈栈顶和待插入值中小的那一个);每次从原栈里取出数字时,同样取出新栈的栈顶。这样可以避免判断,但是每次都要插入和取出。我们这里只展示第一种写法。 +An alternative method, which is simpler to write but has slightly higher time complexity, involves always pushing the minimum value of all elements in the main stack (the smaller of the top value of the auxiliary stack and the new value being pushed) onto the auxiliary stack. Similarly, every pop operation removes the top value from both stacks. This eliminates the need for conditionals but requires inserting and removing a value every time. Here, we only demonstrate the first approach. @@ -194,11 +194,11 @@ class MinStack: ### Problem Description -给定一个只由左右圆括号、花括号和方括号组成的字符串,求这个字符串是否合法。合法的定义是每一个类型的左括号都有一个右括号一一对应,且括号内的字符串也满足此要求。 +Given a string containing only the characters `(`, `)`, `{`, `}`, `[`, and `]`, determine if the input string is valid. A valid string requires that every opening bracket has a corresponding closing bracket of the same type, and the substring enclosed by the brackets is also valid. ### Input and Output Example -输入是一个字符串,输出是一个布尔值,表示字符串是否合法。 +The input is a string, and the output is a boolean value indicating whether the string is valid. ``` Input: "{[]}()" @@ -207,7 +207,7 @@ Output: true ### Solution Explanation -括号匹配是典型的使用栈来解决的问题。我们从左往右遍历,每当遇到左括号便放入栈内,遇到右括号则判断其和栈顶的括号是否是统一类型,是则从栈内取出左括号,否则说明字符串不合法。 +Parenthesis matching is a classic problem that can be solved using a stack. As we iterate through the string from left to right, we push every opening bracket onto the stack. When encountering a closing bracket, we check if it matches the top of the stack. If it matches, we pop the stack; otherwise, the string is invalid. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-5-monotonic-stack.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-5-monotonic-stack.mdx index 0ddb3ec8..18668306 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-5-monotonic-stack.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-5-monotonic-stack.mdx @@ -2,19 +2,19 @@ sidebar_position: 52 --- -# 10.5 单调栈 +# 10.5 Monotonic Stack -`单调栈`通过维持栈内值的单调递增(递减)性,在整体 $O(n)$ 的时间内处理需要大小比较的问题。 +`Monotonic Stack` is a technique that maintains the monotonic increasing (or decreasing) property of a stack to solve comparison problems in $O(n)$ time complexity. ## [739. Daily Temperatures](https://leetcode.com/problems/daily-temperatures/) ### Problem Description -给定每天的温度,求对于每一天需要等几天才可以等到更暖和的一天。如果该天之后不存在更暖和的天气,则记为 0。 +Given the daily temperatures, determine how many days you need to wait for a warmer day. If there is no such day, return 0 for that day. ### Input and Output Example -输入是一个一维整数数组,输出是同样长度的整数数组,表示对于每天需要等待多少天。 +The input is a one-dimensional integer array, and the output is an array of the same length, indicating how many days you need to wait for each day. ``` Input: [73, 74, 75, 71, 69, 72, 76, 73] @@ -23,7 +23,7 @@ Output: [1, 1, 4, 2, 1, 1, 0, 0] ### Solution Explanation -我们可以维持一个单调递减的栈,表示每天的温度;为了方便计算天数差,我们这里存放位置(即日期)而非温度本身。我们从左向右遍历温度数组,对于每个日期 p,如果 p 的温度比栈顶存储位置 q 的温度高,则我们取出 q,并记录 q 需要等待的天数为 p − q;我们重复这一过程,直到 p 的温度小于等于栈顶存储位置的温度(或空栈)时,我们将 p 插入栈顶,然后考虑下一天。在这个过程中,栈内数组永远保持单调递减,避免了使用排序进行比较。最后若栈内剩余一些日期,则说明它们之后都没有出现更暖和的日期。 +We can maintain a monotonic decreasing stack that stores the temperatures. To facilitate calculating the day differences, we store indices (dates) instead of the temperatures themselves. As we iterate through the temperature array from left to right, for each day $p$, if the temperature on day $p$ is higher than the temperature of the day stored at the stack top $q$, we pop $q$ and record the waiting days for $q$ as $p - q$. We repeat this process until the temperature of day $p$ is less than or equal to the temperature at the stack top (or the stack becomes empty), then push $p$ into the stack and move to the next day. During this process, the stack always maintains a monotonic decreasing order, avoiding the need for sorting. Finally, if there are remaining indices in the stack, it means those days do not have warmer days in the future. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-6-priority-queue.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-6-priority-queue.mdx index d4f19248..60f32572 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-6-priority-queue.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-6-priority-queue.mdx @@ -2,20 +2,20 @@ sidebar_position: 53 --- -# 10.6 优先队列 +# 10.6 Priority Queue -`优先队列`(priority queue)可以在 O(1) 时间内获得最大值,并且可以在 O(log n) 时间内取出最大值或插入任意值。 +`Priority queue` allows retrieving the maximum value in $O(1)$ time and inserting or removing the maximum value in $O(\log n)$ time.
        ![](10.2.png) -
        图 10.2: (最大)堆,维护的是数据结构中的大于关系
        +
        Figure 10.2: (Max) Heap, maintaining the "greater than" relationship in the data structure
        -优先队列常常用堆(heap)来实现。堆是一个完全二叉树,其每个节点的值总是大于等于子节点的值。实际实现堆时,我们通常用一个数组而不是用指针建立一个树。这是因为堆是完全二叉树,所以用数组表示时,位置 i 的节点的父节点位置一定为 (i-1)/2,而它的两个子节点的位置又一定分别为 2i+1 和 2i+2。 +Priority queues are often implemented using heaps. A heap is a complete binary tree in which each node's value is always greater than or equal to its child nodes. When implementing heaps, arrays are often used instead of pointers to build a tree. This is because heaps are complete binary trees, so in an array representation, the parent node of position $i$ is located at $(i-1)/2$, and its two child nodes are located at $2i+1$ and $2i+2$, respectively. -以下是堆的实现方法,其中最核心的两个操作是上浮和下沉:如果一个节点比父节点大,那么需要交换这个两个节点;交换后还可能比它新的父节点大,因此需要不断地进行比较和交换操作,我们称之为上浮;类似地,如果一个节点比父节小,也需要不断地向下进行比较和交换操作我们称之为下沉。如果一个节点有两个子节点,我们总是交换最大的子节点。 +Here is the implementation of heaps. The two core operations are "swim" and "sink": if a node is greater than its parent node, we swap them; after swapping, it may still be greater than its new parent node, so we continue comparing and swapping, known as "swim." Similarly, if a node is smaller than its parent, it needs to compare and swap downward continuously, known as "sink." If a node has two child nodes, we always swap with the largest child node. @@ -25,7 +25,7 @@ sidebar_position: 53 class Heap { public: Heap() {} - // 上浮。 + // Swim void swim(int pos) { int next_pos = (pos - 1) / 2; while (pos > 0 && heap_[next_pos] < heap_[pos]) { @@ -34,7 +34,7 @@ class Heap { next_pos = (pos - 1) / 2; } } - // 下沉。 + // Sink void sink(int pos) { int n = heap_.size(); int next_pos = 2 * pos + 1; @@ -50,18 +50,18 @@ class Heap { next_pos = 2 * pos + 1; } } - // 插入任意值:把新的数字放在最后一位,然后上浮。 + // Insert any value: place the new number at the last position, then swim. void push(int k) { heap_.push_back(k); swim(heap_.size() - 1); } - // 删除最大值:把最后一个数字挪到开头,然后下沉。 + // Delete the maximum value: move the last number to the front, then sink. void pop() { heap_[0] = heap_.back(); heap_.pop_back(); sink(0); } - // 获得最大值。 + // Retrieve the maximum value. int top() { return heap_[0]; } private: @@ -77,7 +77,7 @@ class Heap: def __init__(self): self.heap = [] - # 上浮。 + # Swim def swim(self, pos: int): next_pos = (pos - 1) // 2 while pos > 0 and self.heap[next_pos] < self.heap[pos]: @@ -85,7 +85,7 @@ class Heap: pos = next_pos next_pos = (pos - 1) // 2 - # 下沉。 + # Sink def sink(self, pos: int): n = len(self.heap) next_pos = 2 * pos + 1 @@ -98,17 +98,17 @@ class Heap: pos = next_pos next_pos = 2 * pos + 1 - # 插入任意值:把新的数字放在最后一位,然后上浮。 + # Insert any value: place the new number at the last position, then swim. def push(self, k: int): self.heap.append(k) self.swim(len(self.heap) - 1) - # 删除最大值:把最后一个数字挪到开头,然后下沉。 + # Delete the maximum value: move the last number to the front, then sink. def pop(self): self.heap[0] = self.heap.pop() self.sink(0) - # 获得最大值。 + # Retrieve the maximum value. def top(self) -> int: return self.heap[0] @@ -118,17 +118,17 @@ class Heap: -通过将算法中的大于号和小于号互换,我们也可以得到一个快速获得最小值的优先队列。 +By swapping the greater-than and less-than operators in the algorithm, we can also create a priority queue that retrieves the minimum value quickly. ## [23. Merge k Sorted Lists](https://leetcode.com/problems/merge-k-sorted-lists/) ### Problem Description -给定 k 个增序的链表,试将它们合并成一条增序链表。 +Given `k` sorted linked lists, try to merge them into one sorted linked list. ### Input and Output Example -输入是一个一维数组,每个位置存储链表的头节点;输出是一条链表。 +The input is a one-dimensional array, where each position stores the head node of a linked list; the output is a single linked list. ``` Input: @@ -140,9 +140,9 @@ Output: 1->1->2->3->4->4->5->6 ### Solution Explanation -本题可以有很多中解法,比如类似于归并排序进行两两合并。我们这里展示一个速度比较快的方法,即把所有的链表存储在一个优先队列中,每次提取所有链表头部节点值最小的那个节点,直到所有链表都被提取完为止。 +There are multiple ways to solve this problem, such as using a merge sort-like approach to merge the lists pair by pair. Here, we demonstrate a faster method: store all the linked lists in a priority queue and extract the node with the smallest value from the head of all lists at each step until all lists have been completely merged. -因为 C++ priority_queue 的比较函数默认是对最大堆进行比较并维持递增关系,如果我们想要获取最小的节点值,我们则需要实现一个最小堆。因此堆的比较函数应该维持递减关系,即 lambda 函数中返回时用大于号而不是递增关系时的小于号进行比较。 +Since the default comparison function of a C++ `priority_queue` is for a max-heap and maintains an increasing order, to get the smallest node values, we need to implement a min-heap. Thus, the comparison function for the heap should maintain a decreasing order, i.e., the lambda function should use the greater-than operator instead of the less-than operator used for increasing order. @@ -177,7 +177,7 @@ def mergeKLists(lists: List[Optional[ListNode]]) -> Optional[ListNode]: pq = [] for idx, l in enumerate(lists): if l is not None: - # ListNode不可被哈希,所以这里我们直接记录它在lists中的位置。 + # ListNode cannot be hashed, so we directly record its position in lists. pq.append((l.val, idx)) heapq.heapify(pq) @@ -204,17 +204,17 @@ def mergeKLists(lists: List[Optional[ListNode]]) -> Optional[ListNode]: ### Problem Description -给定建筑物的起止位置和高度,返回建筑物轮廓(天际线)的拐点。 +Given the start and end positions along with the height of buildings, return the critical points of the building's silhouette (skyline). ### Input and Output Example -输入是一个二维整数数组,表示每个建筑物的 [左端, 右端, 高度];输出是一个二维整数数组,表示每个拐点的横纵坐标。 +The input is a 2D integer array representing each building as `[left, right, height]`; the output is a 2D integer array representing the x and y coordinates of the critical points of the skyline.
        ![](10.3.png) -
        图 10.3: 题目 218 - 建筑物及其天际线样例
        +
        Figure 10.3: Problem 218 - Example of buildings and their skyline
        ``` @@ -224,11 +224,11 @@ Output: [[2 10], [3 15], [7 12], [12 0], [15 10], [20 8], [24, 0]] ### Solution Explanation -我们可以使用优先队列储存每个建筑物的高度和右端(这里使用 pair,其默认比较函数是先比较第一个值,如果相等则再比较第二个值),从而获取目前会拔高天际线、且妨碍到前一个建筑物(的右端端点)的下一个建筑物。 +We can use a priority queue to store the height and the right endpoint of each building (using a pair). This helps us identify the next building that raises the skyline and interferes with the previous building's endpoint. -因为 Python 中 heapq 是最小堆,所以我们在存值的时候可以存负值,这样就变成了最大堆。 +Since Python's `heapq` implements a min-heap, we store negative values for heights to simulate a max-heap. -这道题比较复杂,如果实在难以理解,建议读者暂时跳过此题,或者在纸上举例子画一画。 +This problem is relatively complex. If you find it challenging to grasp, consider skipping it for now or illustrating examples on paper for better understanding. @@ -236,7 +236,7 @@ Output: [[2 10], [3 15], [7 12], [12 0], [15 10], [20 8], [24, 0]] ```cpp vector> getSkyline(vector>& buildings) { vector> skyline; - priority_queue> pq; // <高度, 右端> + priority_queue> pq; // int i = 0, n = buildings.size(); int cur_x, cur_h; while (i < n || !pq.empty()) { @@ -267,7 +267,7 @@ vector> getSkyline(vector>& buildings) { ```py def getSkyline(buildings: List[List[int]]) -> List[List[int]]: skyline = [] - pq = [] # <负高度,右端> + pq = [] # heapq.heapify(pq) i, n = 0, len(buildings) diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-7-deque.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-7-deque.mdx index 72e2b2e5..facf24fe 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-7-deque.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-7-deque.mdx @@ -2,24 +2,24 @@ sidebar_position: 54 --- -# 10.7 双端队列 +# 10.7 Double-Ended Queue ## [239. Sliding Window Maximum](https://leetcode.com/problems/sliding-window-maximum/) ### Problem Description -给定一个整数数组和一个滑动窗口大小,求在这个窗口的滑动过程中,每个时刻其包含的最大值。 +Given an integer array and a sliding window size, find the maximum value in the sliding window at each step. ### Input and Output Example -输入是一个一维整数数组,和一个表示滑动窗口大小的整数;输出是一个一维整数数组,表示每个时刻时的窗口内最大值。 +The input consists of a one-dimensional integer array and an integer representing the sliding window size; the output is a one-dimensional integer array representing the maximum value within the window at each step. ``` Input: nums = [1,3,-1,-3,5,3,6,7], k = 3 Output: [3,3,5,5,6,7] ``` -在这个样例中,滑动窗口在每个位置的最大包含值取法如下: +For this example, the sliding window's maximum value at each position is as follows: ``` Window position Max @@ -34,7 +34,14 @@ Output: [3,3,5,5,6,7] ### Solution Explanation -我们可以利用双端队列进行操作:每当向右移动时,把窗口左端的值从双端队列左端剔除,把双端队列右边小于窗口右端的值全部剔除。这样双端队列的最左端永远是当前窗口内的最大值。另外,这道题也是单调栈的一种延申:该双端队列利用从左到右递减来维持大小关系。 +We can use a deque to manage the sliding window efficiently: + +- As the window slides to the right, remove values from the deque's left end if they exit the window. +- Also, remove all elements from the deque's right end that are smaller than the new rightmost value in the window. + +This ensures that the deque's leftmost element is always the maximum value of the current window. + +Additionally, this approach can be considered an extension of a monotonic stack: the deque maintains a decreasing order from left to right to preserve the size relationship. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-8-hash-table.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-8-hash-table.mdx index 13e29371..d0cb8b4b 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-8-hash-table.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-8-hash-table.mdx @@ -2,39 +2,39 @@ sidebar_position: 55 --- -# 10.8 哈希表 +# 10.8 Hash Table -`哈希表(hash table, hash map)`,又称散列表,使用 $O(n)$ 空间复杂度存储数据,通过哈希函数(hash function)映射位置,从而实现近似 O(1) 时间复杂度的插入、查找、删除等操作。哈希表可以用来统计频率,记录内容等等。 +A `hash table` (also known as a hash map) uses $O(n)$ space complexity to store data. By leveraging a hash function, it maps positions to achieve approximate $O(1)$ time complexity for insertion, lookup, and deletion operations. Hash tables can be utilized for tasks such as frequency counting and content recording. -如果元素有穷,并且范围不大,那么可以用一个固定大小的数组来存储或统计元素。例如我们需要统计一个字符串中所有字母的出现次数,则可以用一个长度为 26 的数组来进行统计,其哈希函数即为字母在字母表的位置,这样空间复杂度就可以降低为常数。 +If the elements are finite and their range is small, a fixed-size array can be used to store or count elements. For instance, to count the occurrences of all letters in a string, you can use an array of length 26, where the hash function maps each letter to its position in the alphabet. This approach reduces the space complexity to a constant. ## [1. Two Sum](https://leetcode.com/problems/two-sum/) ### Problem Description -给定一个(未排序的)整数数组,已知有且只有两个数的和等于给定值,求这两个数的位置。 +Given an (unsorted) array of integers, find the indices of two numbers that add up to a specific target. Assume that there is exactly one solution. ### Input and Output Example -输入一个一维整数数组和一个目标值,输出是一个大小为 2 的一维数组,表示满足条件的两个数字的位置。 +Input is a one-dimensional integer array and a target value. Output is a one-dimensional array of size 2, representing the indices of the two numbers. ``` Input: nums = [2, 7, 15, 11], target = 9 Output: [0, 1] ``` -在这个样例中,第 0 个位置的值 2 和第 1 个位置的值 7 的和为 9。 +In this example, the value at index 0 (2) and the value at index 1 (7) sum up to 9. ### Solution Explanation -我们可以利用哈希表存储遍历过的值以及它们的位置,每次遍历到位置 i 的时候,查找哈希表里是否存在 target - nums[i],若存在,则说明这两个值的和为 target。 +We can use a hash table to store values we have already seen along with their indices. For each index `i`, we check if `target - nums[i]` exists in the hash table. If it does, it means the two numbers sum up to the target. ```cpp vector twoSum(vector& nums, int target) { - unordered_map cache; // <值,位置> + unordered_map cache; // for (int i = 0; i < nums.size(); ++i) { int num1 = nums[i], num2 = target - num1; if (cache.contains(num2)) { @@ -51,7 +51,7 @@ vector twoSum(vector& nums, int target) { ```py def twoSum(nums: List[int], target: int) -> List[int]: - cache = dict() # <值,位置> + cache = dict() # for i, num1 in enumerate(nums): num2 = target - num1 if num2 in cache: @@ -68,22 +68,22 @@ def twoSum(nums: List[int], target: int) -> List[int]: ### Problem Description -给定一个整数数组,求这个数组中的数字可以组成的最长连续序列有多长。 +Given an array of integers, find the length of the longest consecutive sequence that can be formed using the numbers in the array. ### Input and Output Example -输入一个整数数组,输出一个整数,表示连续序列的长度。 +Input is an array of integers, and output is an integer representing the length of the consecutive sequence. ``` Input: [100, 4, 200, 1, 3, 2] Output: 4 ``` -在这个样例中,最长连续序列是 [1,2,3,4]。 +In this example, the longest consecutive sequence is [1,2,3,4]. ### Solution Explanation -我们可以把所有数字放到一个哈希表,然后不断地从哈希表中任意取一个值,并删除掉其之前之后的所有连续数字,然后更新目前的最长连续序列长度。重复这一过程,我们就可以找到所有的连续数字序列。 +We can put all the numbers into a hash table and repeatedly pick any value from the hash table. For each value, we remove all its consecutive numbers before and after it, and update the length of the longest consecutive sequence. Repeating this process allows us to find all consecutive number sequences. @@ -142,11 +142,11 @@ def longestConsecutive(nums: List[int]) -> int: ### Problem Description -给定一些二维坐标中的点,求同一条线上最多有多少点。 +Given some points in a 2D plane, find the maximum number of points that lie on the same straight line. ### Input and Output Example -输入是一个二维整数数组,表示每个点的横纵坐标;输出是一个整数,表示满足条件的最多点数。 +Input is a 2D integer array representing the x and y coordinates of each point. Output is an integer representing the maximum number of points on the same line. ``` Input: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]] @@ -161,13 +161,13 @@ Input: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]] Output: 4 ``` -这个样例中,$y =5 − x$ 上有四个点。 +In this example, the line $y = 5 - x$ contains four points. ### Solution Explanation -对于每个点,我们对其它点建立哈希表,统计同一斜率的点一共有多少个。这里利用的原理是,一条线可以由一个点和斜率而唯一确定。另外也要考虑斜率不存在和重复坐标的情况。 +For each point, we use a hash table to count the number of points with the same slope relative to that point. A line is uniquely determined by one point and its slope. Additionally, we must account for cases where the slope does not exist and for duplicate coordinates. -本题也利用了一个小技巧:在遍历每个点时,对于数组中位置 i 的点,我们只需要考虑 i 之后的点即可,因为 i 之前的点已经考虑过 i 了。 +This problem also uses a small optimization: when iterating through each point at position `i`, we only consider points after `i` since points before `i` have already been considered. @@ -176,7 +176,7 @@ Output: 4 int maxPoints(vector>& points) { int max_count = 0, n = points.size(); for (int i = 0; i < n; ++i) { - unordered_map cache; // <斜率, 点个数> + unordered_map cache; // int same_xy = 1, same_y = 1; for (int j = i + 1; j < n; ++j) { if (points[i][1] == points[j][1]) { @@ -207,7 +207,7 @@ def maxPoints(points: List[List[int]]) -> int: max_count, n = 0, len(points) for i, point1 in enumerate(points): - cache = dict() # <斜率, 点个数> + cache = dict() # same_xy, same_y = 1, 1 for point2 in points[i + 1:]: diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-9-multisets-and-maps.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-9-multisets-and-maps.mdx index a923c443..5eaeb542 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-9-multisets-and-maps.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-9-multisets-and-maps.mdx @@ -2,17 +2,17 @@ sidebar_position: 56 --- -# 10.9 多重集合和映射 +# 10.9 Multisets and Mappings ## [332. Reconstruct Itinerary](https://leetcode.com/problems/reconstruct-itinerary/) ### Problem Description -给定一个人坐过的一些飞机的起止机场,已知这个人从 JFK 起飞,那么这个人是按什么顺序飞的;如果存在多种可能性,返回字母序最小的那种。 +Given a person's flight records with departure and arrival airports, starting from JFK, determine the flight order. If there are multiple possibilities, return the lexicographically smallest sequence. ### Input and Output Example -输入是一个二维字符串数组,表示多个起止机场对子;输出是一个一维字符串数组,表示飞行顺序。 +Input is a 2D string array representing pairs of departure and arrival airports; output is a 1D string array representing the flight order. ``` Input: [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]] @@ -21,9 +21,9 @@ Output: ["JFK", "MUC", "LHR", "SFO", "SJC"] ### Solution Explanation -本题可以先用哈希表记录起止机场,其中键是起始机场,值是一个多重(有序)集合,表示对应的终止机场。因为一个人可能坐过重复的线路,所以我们需要使用多重集合储存重复值。储存完成之后,我们可以利用栈/DFS 来恢复从终点到起点飞行的顺序,再将结果逆序得到从起点到终点的顺序。 +We can first use a hash table to store the departure and arrival airports, where the key is the departure airport, and the value is a multiset (ordered set) representing the corresponding arrival airports. Since a person may take the same route multiple times, we need to use a multiset to store duplicate values. After storing, we can use a stack/DFS to reconstruct the flight order from the endpoint to the starting point, and then reverse the result to get the order from the start to the endpoint. -因为 Python 没有默认的多重(有序)集合实现,我们可以直接存储一个数组,然后进行排序。也可以使用 Counter 结构,每次查找下一个机场时,返回 key 值最小的那个。 +Since Python doesn't have a built-in multiset implementation, we can store an array and sort it. Alternatively, we can use the `Counter` structure, selecting the smallest key each time we search for the next airport. diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-2-assignment-problems.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-2-assignment-problems.mdx index 0568cbdc..f38b39ac 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-2-assignment-problems.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-2-assignment-problems.mdx @@ -12,7 +12,7 @@ sidebar_position: 2 ### 輸入輸出範例 -輸入兩個數組,分別代表孩子的飢餓度和餅乾的飽腹度。輸出可以吃飽的孩子的最大數量。 +輸入兩個陣列,分別代表孩子的飢餓度和餅乾的飽腹度。輸出可以吃飽的孩子的最大數量。 ``` Input: [1,2], [1,2,3] @@ -29,13 +29,13 @@ Output: 2 :::warning -對數組或字符串排序是常見的操作,方便之後的大小比較。排序順序默認是從小到大。 +對陣列或字符串排序是常見的操作,方便之後的大小比較。排序順序默認是從小到大。 ::: :::warning -在之後的講解中,若我們談論的是對連續空間的變量進行操作,我們並不會明確區分數組和字符串,因為它們本質上都是在連續空間上的有序變量集合。一個字符串 "abc" 可以被看作一個數組 ['a', 'b', 'c']。 +在之後的講解中,若我們談論的是對連續空間的變量進行操作,我們並不會明確區分陣列和字符串,因為它們本質上都是在連續空間上的有序變量集合。一個字符串 "abc" 可以被看作一個陣列 ['a', 'b', 'c']。 ::: @@ -97,7 +97,7 @@ def findContentChildren(children: List[int], cookies: List[int]) -> int: ### 輸入輸出範例 -輸入是一個數組,表示孩子的評分。輸出是最少糖果的數量。 +輸入是一個陣列,表示孩子的評分。輸出是最少糖果的數量。 ``` Input: [1,0,2] diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-3-interval-problems.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-3-interval-problems.mdx index adaf8c1d..afa70919 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-3-interval-problems.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-3-interval-problems.mdx @@ -12,7 +12,7 @@ sidebar_position: 3 ### 輸入輸出範例 -輸入是一個數組,包含多個長度固定為 2 的子數組,表示每個區間的開始和結束。輸出是一個整數,表示需要移除的區間數量。 +輸入是一個陣列,包含多個長度固定為 2 的子陣列,表示每個區間的開始和結束。輸出是一個整數,表示需要移除的區間數量。 ``` @@ -28,7 +28,7 @@ Output: 1 具體實現方法為,先把區間按照結尾的大小進行增序排序(利用 lambda 函數),每次選擇結尾最小且與前一個選擇的區間不重疊的區間。 -在範例中,排序後的數組為 [[1,2], [1,3], [2,4]]。按照我們的貪心策略,首先初始化為區間 [1,2];由於 [1,3] 與 [1,2] 相交,我們跳過該區間;由於 [2,4] 與 [1,2] 不相交,我們將其保留。因此,最終保留的區間為 [[1,2], [2,4]]。 +在範例中,排序後的陣列為 [[1,2], [1,3], [2,4]]。按照我們的貪心策略,首先初始化為區間 [1,2];由於 [1,3] 與 [1,2] 相交,我們跳過該區間;由於 [2,4] 與 [1,2] 不相交,我們將其保留。因此,最終保留的區間為 [[1,2], [2,4]]。 :::warning diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-1-cpp-stl.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-1-cpp-stl.md index 2ec42832..945ec9c4 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-1-cpp-stl.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-1-cpp-stl.md @@ -4,27 +4,30 @@ sidebar_position: 48 # 10.1 C++ STL -在刷题时,我们几乎一定会用到各种数据结构来辅助我们解决问题,因此我们必须熟悉各种数据结构的特点。C++ STL 提供的数据结构包括(实际底层细节可能因编译器而异): +在刷題時,我們幾乎一定會用到各種資料結構來輔助我們解決問題,因此我們必須熟悉各種資料結構的特點。C++ STL 提供的資料結構包括(實際底層細節可能因編譯器而異): -1. Sequence Containers:维持顺序的容器。 - 1. vector:`动态数组`,是我们最常使用的数据结构之一,用于 $O(1)$ 的随机读取。因为大部分算法的时间复杂度都会大于 $O(n)$,因此我们经常新建 vector 来存储各种数据或中间变量。因为在尾部增删的复杂度是 $O(1)$,我们也可以把它当作 stack 来用。 - 2. list:`双向链表`,也可以当作 stack 和 queue 来使用。由于 LeetCode 的题目多用 Node 来表示链表,且链表不支持快速随机读取,因此我们很少用到这个数据结构。一个例外是经典的 LRU 问题,我们需要利用链表的特性来解决,我们在后文会遇到这个问题。 - 3. deque:双端队列,这是一个非常强大的数据结构,既支持 $O(1)$ 随机读取,又支持 $O(1)$ 时间的头部增删和尾部增删(因此可以当作 stack 和 queue 来使用),不过有一定的额外开销。也可以用来近似一个双向链表来使用。 - 4. array:固定大小的数组,一般在刷题时我们不使用。 - 5. forward_list:单向链表,一般在刷题时我们不使用。 -2. Container Adaptors:基于其它容器实现的容器。 - 1. stack:`后入先出(LIFO)的数据结构`,默认基于 deque 实现。stack 常用于深度优先搜索、一些字符串匹配问题以及单调栈问题。 - 2. `先入先出(FIFO)的数据结构`,默认基于 deque 实现。queue 常用于广度优先搜索。 - 3. priority_queue:`优先队列(最大值先出的数据结构)`,默认基于 vector 实现堆结构。它可以在 $O(n \log n)$ 的时间排序数组,$O(\log n)$ 的时间插入任意值,$O(1)$ 的时间获得最大值,$O(\log n)$ 的时间删除最大值。priority_queue 常用于维护数据结构并快速获取最大值,并且可以自定义比较函数;比如通过存储负值或者更改比小函数为比大函数,即可实现最小值先出。 -3. Ordered Associative Containers:有序关联容器。 - 1. set:有序集合,元素不可重复,底层实现默认为红黑树,即一种特殊的二叉查找树(BST)。它可以在 $O(n \log n)$ 的时间排序数组,$O(\log n)$ 的时间插入、删除、查找任意值,$O(\log n)$ 的时间获得最小或最大值。这里注意,set 和 priority_queue 都可以用于维护数据结构并快速获取最大最小值,但是它们的时间复杂度和功能略有区别,如 priority_queue 默认不支持删除任意值,而 set 获得最大或最小值的时间复杂度略高,具体使用哪个根据需求而定。 - 2. multiset:支持重复元素的 set。 - 3. map:`有序映射或有序表`,在 set 的基础上加上映射关系,可以对每个元素 key 存一个值 value。 - 4. multimap:支持重复元素的 map。 -4. Unordered Associative Containers:无序关联容器。 - 1. unordered_set:`哈希集合`,可以在 $O(1)$ 的时间快速插入、查找、删除元素,常用于快速的查询一个元素是否在这个容器内。 - 2. unordered_multiset:支持重复元素的 unordered_set。 - 3. unordered_map:`哈希映射或哈希表`,在 unordered_set 的基础上加上映射关系,可以对每一个元素 key 存一个值 value。在某些情况下,如果 key 的范围已知且较小,我们也可以用 vector 代替 unordered_map,用位置表示 key,用每个位置的值表示 value。 - 4. unordered_multimap:支持重复元素的 unordered_map。 +1. **順序容器(Sequence Containers)**:維持順序的容器。 + 1. **vector**:`動態陣列`,是我們最常使用的資料結構之一,用於 $O(1)$ 的隨機讀取。因為大部分演算法的時間複雜度會大於 $O(n)$,因此我們經常新建 vector 來存儲各種資料或中間變數。由於在尾部增刪的複雜度是 $O(1)$,我們也可以把它當作 stack 來用。 + 2. **list**:`雙向鏈結串列`,也可以當作 stack 和 queue 來使用。由於 LeetCode 的題目多用 Node 來表示鏈結串列,且鏈結串列不支援快速隨機讀取,因此我們很少用到這個資料結構。一個例外是經典的 LRU 問題,我們需要利用鏈結串列的特性來解決,我們在後文會遇到這個問題。 + 3. **deque**:雙端佇列,這是一個非常強大的資料結構,既支援 $O(1)$ 隨機讀取,又支援 $O(1)$ 時間的頭部增刪和尾部增刪(因此可以當作 stack 和 queue 來使用),不過有一定的額外開銷。也可以用來近似一個雙向鏈結串列來使用。 + 4. **array**:固定大小的陣列,一般在刷題時我們不使用。 + 5. **forward_list**:單向鏈結串列,一般在刷題時我們不使用。 +2. **容器適配器(Container Adaptors)**:基於其他容器實現的容器。 + 1. **stack**:`後進先出(LIFO)的資料結構`,預設基於 deque 實現。stack 常用於深度優先搜尋、一些字串匹配問題以及單調堆疊問題。 + 2. **queue**:`先進先出(FIFO)的資料結構`,預設基於 deque 實現。queue 常用於廣度優先搜尋。 + 3. **priority_queue**:`優先佇列(最大值先出的資料結構)`,預設基於 vector 實現堆結構。它可以在 $O(n \log n)$ 的時間排序陣列,$O(\log n)$ 的時間插入任意值,$O(1)$ 的時間獲得最大值,$O(\log n)$ 的時間刪除最大值。priority_queue 常用於維護資料結構並快速獲取最大值,並且可以自定義比較函數;比如通過儲存負值或者更改比較函數,即可實現最小值先出。 + +3. **有序關聯容器(Ordered Associative Containers)**:有序的關聯容器。 + 1. **set**:有序集合,元素不可重複,底層實現預設為紅黑樹,即一種特殊的二元搜尋樹(BST)。它可以在 $O(n \log n)$ 的時間排序陣列,$O(\log n)$ 的時間插入、刪除、查找任意值,$O(\log n)$ 的時間獲得最小或最大值。需要注意的是,set 和 priority_queue 都可以用於維護資料結構並快速獲取最大最小值,但它們的時間複雜度和功能略有區別,如 priority_queue 預設不支援刪除任意值,而 set 獲得最大或最小值的時間複雜度略高,具體使用哪個取決於需求。 + 2. **multiset**:支援重複元素的 set。 + 3. **map**:`有序映射或有序表`,在 set 的基礎上增加映射關係,可以對每個元素 key 存一個值 value。 + 4. **multimap**:支援重複元素的 map。 + +4. **無序關聯容器(Unordered Associative Containers)**:無序的關聯容器。 + 1. **unordered_set**:`雜湊集合`,可以在 $O(1)$ 的時間快速插入、查找、刪除元素,常用於快速判斷某元素是否在容器內。 + 2. **unordered_multiset**:支援重複元素的 unordered_set。 + 3. **unordered_map**:`雜湊映射或雜湊表`,在 unordered_set 的基礎上增加映射關係,可以對每一個元素 key 存一個值 value。在某些情況下,如果 key 的範圍已知且較小,我們也可以用 vector 代替 unordered_map,用位置表示 key,用每個位置的值表示 value。 + 4. **unordered_multimap**:支援重複元素的 unordered_map。 + +由於這並不是一本講解 C++ 原理的書,更多的 STL 細節請讀者自行搜尋。只有理解了這些資料結構的原理和使用方法,才能更輕鬆地解決算法和資料結構問題。 -因为这并不是一本讲解 C++ 原理的书,更多的 STL 细节请读者自行搜索。只有理解了这些数据结构的原理和使用方法,才能够更加游刃有余地解决算法和数据结构问题。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-10-prefix-sum-integral-image.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-10-prefix-sum-integral-image.mdx index 8878d9c8..3d06fcfa 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-10-prefix-sum-integral-image.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-10-prefix-sum-integral-image.mdx @@ -2,19 +2,19 @@ sidebar_position: 57 --- -# 10.10 前缀和与积分图 +# 10.10 前綴和與積分圖 -一维的前缀和(cumulative sum, cumsum),二维的积分图(summed-area table, image integral)都是把每个位置之前的一维线段或二维矩形预先存储,方便加速计算。如果需要对前缀和或积分图的值做寻址,则要存入哈希表;如果要对每个位置记录前缀和或积分图的值,则可以储存到一维或二维数组里,也常常伴随着动态规划。 +一維的前綴和(cumulative sum, cumsum),二維的積分圖(summed-area table, image integral)是通過將每個位置之前的一維線段或二維矩形的數值預先計算並儲存,從而加速後續的查詢與計算。如果需要對前綴和或積分圖的值進行查找,可以將其存入雜湊表;如果需要對每個位置記錄前綴和或積分圖的值,則可以將其儲存到一維或二維數組中,通常還伴隨著動態規劃。 ## [303. Range Sum Query - Immutable](https://leetcode.com/problems/range-sum-query-immutable/) ### 題目描述 -设计一个数据结构,使得其能够快速查询给定数组中,任意两个位置间所有数字的和。 +設計一個資料結構,使得其能夠快速查詢給定陣列中任意兩個位置間所有數字的總和。 ### 輸入輸出範例 -以下是数据结构的调用样例。 +以下是資料結構的調用範例。 ``` vector nums{-2,0,3,-5,2,-1}; @@ -25,7 +25,7 @@ num_array.sunRange(1,5); // Result = 0+3-5+2-1 = -1. ### 題解 -对于一维的数组,我们可以使用前缀和来解决此类问题。先建立一个与数组 nums 长度相同的新数组 cumsum,表示 nums 每个位置之前前所有数字的和。cumsum 数组可以通过 C++ 自带的 partial_sum 函数建立,也可以直接遍历一遍 nums 数组,并利用状态转移方程 cumsum[i] = cumsum[i-1] + nums[i] 完成统计。如果我们需要获得位置 i 和 j 之间的数字和,只需计算 cum - sum[j+1] - cumsum[i] 即可。 +對於一維的陣列,我們可以使用前綴和來解決此類問題。先建立一個與陣列 `nums` 長度相同的新陣列 `cumsum`,表示 `nums` 每個位置之前所有數字的總和。`cumsum` 陣列可以通過 C++ 自帶的 `partial_sum` 函數建立,也可以直接遍歷一遍 `nums` 陣列,並利用狀態轉移方程 `cumsum[i] = cumsum[i-1] + nums[i]` 完成統計。如果我們需要獲得位置 `i` 和 `j` 之間的數字和,只需計算 `cumsum[j+1] - cumsum[i]` 即可。 @@ -68,11 +68,11 @@ class NumArray: ### 題目描述 -设计一个数据结构,使得其能够快速查询给定矩阵中,任意两个位置包围的长方形中所有数字的和。 +設計一個資料結構,使得其能夠快速查詢給定矩陣中,任意兩個位置包圍的長方形中所有數字的總和。 ### 輸入輸出範例 -以下是数据结构的调用样例。其中 sumRegion 函数的四个输入分别是第一个点的横、纵坐标,和第二个点的横、纵坐标。 +以下是資料結構的調用範例。其中 `sumRegion` 函數的四個輸入分別是第一個點的橫、縱坐標,和第二個點的橫、縱坐標。 ``` vector matrix{{3,0,1,4,2}, @@ -88,13 +88,13 @@ num_matrix.sumRegion(1,1,2,2); // Result = 11. ### 題解 -类似于前缀和,我们可以把这种思想拓展到二维,即积分图(summed-area table, image integral)。我们可以先建立一个 sat 矩阵,sat[i][j] 表示以位置 (0, 0) 为左上角、位置 (i-1, j-1) 为右下角的长方形中所有数字的和。 +類似於前綴和,我們可以把這種思想拓展到二維,即積分圖(summed-area table, image integral)。我們可以先建立一個 `sat` 矩陣,`sat[i][j]` 表示以位置 `(0, 0)` 為左上角、位置 `(i-1, j-1)` 為右下角的長方形中所有數字的總和。
        ![](10.4.png) -
        图 10.4: 题目 304 - 图 1 - 左边为给定矩阵,右边为积分图结果,右下角位置的积分图值为 5+48+45− 40 =58
        +
        圖 10.4: 題目 304 - 圖 1 - 左邊為給定矩陣,右邊為積分圖結果,右下角位置的積分圖值為 5+48+45−40 = 58
        @@ -102,12 +102,12 @@ num_matrix.sumRegion(1,1,2,2); // Result = 11. ![](10.5.png) -
        图 10.5: 题目 304 - 图 2 - 左边为给定矩阵,右边为积分图结果,长方形 E 的数字和等于 58 − 11 − 13 +3 =37
        +
        圖 10.5: 題目 304 - 圖 2 - 左邊為給定矩陣,右邊為積分圖結果,長方形 E 的數字總和等於 58 − 11 − 13 + 3 = 37
        -如图 1 所示,我们可以用动态规划来计算 sat 矩阵:sat[i][j] = matrix[i-1][j-1] + sat[i-1][j] + sat[i][j-1] - sat[i-1][j-1],即当前坐标的数字 + 上面长方形的数字和 + 左边长方形的数字和 - 上面长方形和左边长方形重合面积(即左上一格的长方形)中的数字和。 +如圖 1 所示,我們可以用動態規劃來計算 `sat` 矩陣:`sat[i][j] = matrix[i-1][j-1] + sat[i-1][j] + sat[i][j-1] - sat[i-1][j-1]`,即當前座標的數字 + 上面長方形的數字總和 + 左邊長方形的數字總和 - 上面長方形和左邊長方形重疊區域(即左上一格的長方形)中的數字總和。 -如图 2 所示,假设我们要查询长方形 E 的数字和,因为 E = D − B − C + A,我们发现 E 其实可以由四个位置的积分图结果进行加减运算得到。因此这个算法在预处理时的时间复杂度为 $O(mn)$,而在查询时的时间复杂度仅为 $O(1)$。 +如圖 2 所示,假設我們要查詢長方形 E 的數字總和,因為 `E = D − B − C + A`,我們發現 E 其實可以由四個位置的積分圖結果進行加減運算得到。因此這個演算法在預處理時的時間複雜度為 $O(mn)$,而在查詢時的時間複雜度僅為 $O(1)$。 @@ -172,22 +172,22 @@ class NumMatrix: ### 題目描述 -给定一个数组,寻找和为 k 的连续区间个数。 +給定一個陣列,尋找和為 $k$ 的連續子陣列個數。 ### 輸入輸出範例 -输入一个一维整数数组和一个整数值 k;输出一个整数,表示满足条件的连续区间个数。 +輸入是一維整數陣列和一個整數值 $k$;輸出是一個整數,表示滿足條件的連續子陣列個數。 ``` Input: nums = [1,1,1], k = 2 Output: 2 ``` -在这个样例中,我们可以找到两个 [1,1] 连续区间满足条件。 +在這個範例中,我們可以找到兩個 [1,1] 連續子陣列滿足條件。 ### 題解 -本题同样是利用前缀和,不同的是这里我们使用一个哈希表 cache,其键是前缀和,而值是该前缀和出现的次数。在我们遍历到位置 i 时,假设当前的前缀和是 cumsum,那么 cache[cumsum-k] 即为以当前位置结尾、满足条件的区间个数。 +本題同樣是利用前綴和,不同的是這裡我們使用一個雜湊表 `cache`,其鍵是前綴和,而值是該前綴和出現的次數。在我們遍歷到位置 $i$ 時,假設當前的前綴和是 `cumsum`,那麼 `cache[cumsum-k]` 即為以當前位置結尾、滿足條件的子陣列個數。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-11-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-11-exercises.md index ecdbafb5..66bbb482 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-11-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-11-exercises.md @@ -8,46 +8,66 @@ sidebar_position: 58 ### [566. Reshape the Matrix](https://leetcode.com/problems/reshape-the-matrix/) -没有什么难度,只是需要一点耐心。 +這題沒什麼難度,只是需要耐心操作。 + +--- ### [225. Implement Stack using Queues](https://leetcode.com/problems/implement-stack-using-queues/) -利用相似的方法,我们也可以用 queue 实现 stack。 +使用類似的方式,我們也可以用佇列(queue)實現堆疊(stack)。 + +--- ### [503. Next Greater Element II](https://leetcode.com/problems/next-greater-element-ii/) -Daily Temperature 的变种题。 +`Daily Temperatures` 的變種題。 + +--- ### [217. Contains Duplicate](https://leetcode.com/problems/contains-duplicate/) -使用什么数据结构可以快速判断重复呢? +使用什麼資料結構可以快速判斷是否有重複呢? + +--- ### [697. Degree of an Array](https://leetcode.com/problems/degree-of-an-array/) -如何对数组进行预处理才能正确并快速地计算子数组的长度? +如何對陣列進行預處理,才能正確且快速計算子陣列的長度? + +--- ### [594. Longest Harmonious Subsequence](https://leetcode.com/problems/longest-harmonious-subsequence/) -最长连续序列的变种题。 +`最長連續序列` 的變種題。 + +--- ### [15. 3Sum](https://leetcode.com/problems/3sum/) -因为排序的复杂度是 $O(n \log n) < O(n^2)$,因此我们既可以排序后再进行 $O(n^2)$ 的指针搜索,也可以直接利用哈希表进行 $O(n^2)$ 的搜索。 +因為排序的複雜度是 $O(n \log n) < O(n^2)$,我們既可以先排序後再進行 $O(n^2)$ 的指針搜尋,也可以直接利用雜湊表進行 $O(n^2)$ 的搜尋。 + +--- ## 進階難度 ### [287. Find the Duplicate Number](https://leetcode.com/problems/find-the-duplicate-number/) -寻找丢失数字的变种题。除了标负位置,你还有没有其它算法可以解决这个问题? +`尋找丟失的數字` 的變種題。除了標記負值的方法,你是否有其它算法來解決這個問題? + +--- ### [313. Super Ugly Number](https://leetcode.com/problems/super-ugly-number/) -尝试使用优先队列解决这一问题。 +嘗試使用優先佇列來解決這個問題。 + +--- ### [870. Advantage Shuffle](https://leetcode.com/problems/advantage-shuffle/) -如果我们需要比较大小关系,而且同一数字可能出现多次,那么应该用什么数据结构呢? +如果我們需要比較大小關係,而且同一數字可能出現多次,那麼應該使用什麼資料結構呢? + +--- ### [307. Range Sum Query - Mutable](https://leetcode.com/problems/range-sum-query-mutable/) -前缀和的变种题。好吧我承认,这道题可能有些超纲,你或许需要搜索一下什么是线段树。 \ No newline at end of file +`前綴和` 的變種題。好吧我承認,這題可能稍微超出範圍,你或許需要搜索一下什麼是`線段樹`。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-2-python-data-structures.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-2-python-data-structures.md index b4221a27..cc063234 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-2-python-data-structures.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-2-python-data-structures.md @@ -2,21 +2,23 @@ sidebar_position: 49 --- -# 10.2 Python 常用数据结构 +# 10.2 Python 常用資料結構 -类似于 C++ STL,Python 也提供了类似的数据结构(实际底层细节可能因编译器而异): +類似於 C++ STL,Python 也提供了許多資料結構(實際底層實作細節可能因編譯器而異): -1. Sequence Containers:维持顺序的容器。 - 1. list:`动态数组`,是我们最常使用的数据结构之一,用于 $O(1)$ 的随机读取。因为大部分算法的时间复杂度都会大于 $O(n)$,因此我们经常新建 list 来存储各种数据或中间变量。因为在尾部增删的复杂度是 $O(1)$,我们也可以把它当作 stack 来用。 - 2. tuple: `元组`,immutable list,不可改变其中元素或总长度。 - 3. collections.deque:`双端队列`,这是一个非常强大的数据结构,既支持 $O(1)$ 随机读取,又支持 $O(1)$ 时间的头部增删和尾部增删(因此可以当作 stack 和 queue 来使用),不过有一定的额外开销。也可以用来近似一个双向链表来使用。 -2. Container Adaptors:基于其它容器实现的容器。 - 1. heapq:`最小堆(最小值先出的数据结构)`,默认基于 list 实现堆结构。它可以在 $O(n \log n)$ 的时间排序数组,$O(\log n)$ 的时间插入任意值,$O(1)$ 的时间获得最小值,$O(\log n)$ 的时间删除最小值。heapq 常用于维护数据结构并快速获取最小值,但不支持自定义比较函数。所以通常我们需要提前算好自定义值,再把 (自定义值,位置) 的 tuple 存进 heapq。这样进行比较时就会默认从左到右比较 tuple 中的元素,即先比较自定义值,再比较元素的插入次序。 -3. Ordered Associative Containers:有序关联容器。 - 1. collections.OrderedDict:`顺序映射或顺序表`,注意这里的 Ordered 不同于 C++ 中 map的按大小排序,而是按照插入的先后次序排序。OrderedDict 很适合用来做 LRU。 -4. Unordered Associative Containers:无序关联容器。 - 1. set:`哈希集合`,可以在 O(1) 的时间快速插入、查找、删除元素,常用于快速的查询一个元素是否在这个容器内。 - 2. dict:`哈希映射或哈希表`,在 set 的基础上加上映射关系,可以对每一个元素 key 存一个值 value。在某些情况下,如果 key 的范围已知且较小,我们也可以用 list 代替 dict,用位置表示 key,用每个位置的值表示 value。 - 3. collections.Counter:`计数器`,是 dict 的一个特殊版本,可以直接传入一个 list,并对其中的每一个元素进行计数统计,key 是元素值,value 是元素出现的频次。可以用来当作多重集合。 - -同样的,因为这并不是一本讲解 Python 原理的书,更多的数据结构细节请读者自行搜索。只有理解了这些数据结构的原理和使用方法,才能够更加游刃有余地解决算法和数据结构问题。 \ No newline at end of file +1. **順序容器**:維持順序的容器。 + 1. **list**:`動態陣列`,是我們最常用的資料結構之一,適合用於 $O(1)$ 的隨機存取。由於大多數演算法的時間複雜度會大於 $O(n)$,我們經常建立 list 來儲存各種資料或中間結果。因為尾部的新增或移除操作有 $O(1)$ 的複雜度,我們也可以將其當作堆疊(stack)使用。 + 2. **tuple**:不可變的陣列,無法更改其中的元素或總長度。 + 3. **collections.deque**:`雙端佇列`,是一種功能強大的資料結構,支援 $O(1)$ 的隨機存取,也支援 $O(1)$ 時間的頭尾新增或移除操作(因此可作為堆疊或佇列使用)。但它有些額外開銷,也可用來模擬雙向鏈結串列。 + +2. **容器適配器**:基於其他容器實作的容器。 + 1. **heapq**:`最小堆`(最小值優先的資料結構),基於 list 實作的堆結構。它支援在 $O(n \log n)$ 時間內排序陣列,$O(\log n)$ 時間插入任意值,$O(1)$ 時間獲取最小值,$O(\log n)$ 時間移除最小值。`heapq` 常用於維持資料結構並快速獲取最小值,但不支援自定義比較函式。因此,通常需要預先計算自定義值,並將 (自定義值, 索引) 的 tuple 儲存於 heapq 中,進行比較時會優先比較自定義值,若相同則比較插入順序。 + +3. **有序關聯容器**: + 1. **collections.OrderedDict**:`順序映射或順序表`,注意這裡的 Ordered 與 C++ 中 map 的按大小排序不同,而是按照插入的先後順序排序。`OrderedDict` 非常適合用來實現 LRU(最近最少使用)。 +4. **無序關聯容器**: + 1. **set**:`雜湊集合`,可以在 O(1) 的時間內快速插入、查詢和刪除元素,常用於快速查詢某個元素是否存在於容器中。 + 2. **dict**:`雜湊映射或雜湊表`,在 set 的基礎上增加了鍵值對的映射關係,可以對每個鍵(key)存儲對應的值(value)。在某些情況下,如果鍵的範圍已知且較小,我們也可以用 list 代替 dict,用索引位置表示鍵,用每個位置的值表示對應的值。 + 3. **collections.Counter**:`計數器`,是 dict 的一種特殊版本,可以直接傳入一個 list,並對其中的每個元素進行計數統計,鍵為元素值,值為該元素出現的頻次。可以用來作為多重集合。 + +同樣地,因為這並不是一本講解 Python 原理的書,更多的資料結構細節請讀者自行搜索。只有理解這些資料結構的原理和使用方法,才能夠更加游刃有餘地解決算法和資料結構問題。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-3-arrays.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-3-arrays.mdx index 9be3c06a..d7628808 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-3-arrays.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-3-arrays.mdx @@ -2,29 +2,27 @@ sidebar_position: 50 --- -# 10.3 数组 +# 10.3 陣列 ## [448. Find All Numbers Disappeared in an Array](https://leetcode.com/problems/find-all-numbers-disappeared-in-an-array/) ### 題目描述 -给定一个长度为 n 的数组,其中包含范围为 1 到 n 的整数,有些整数重复了多次,有些整数没有出现,求 1 到 n 中没有出现过的整数。 +給定一個長度為 n 的陣列,其中包含範圍為 1 到 n 的整數,有些整數重複出現多次,有些整數沒有出現,求 1 到 n 中沒有出現過的整數。 ### 輸入輸出範例 -输入是一个一维整数数组,输出也是一个一维整数数组,表示输入数组内没出现过的数字。 +輸入是一個一維整數陣列,輸出也是一個一維整數陣列,表示輸入陣列中沒出現過的數字。 ``` Input: [4,3,2,7,8,2,3,1] Output: [5,6] ``` -利用数组这种数据结构建立 n 个桶,把所有重复出现的位置进行标记,然后再遍历一遍数组,即可找到没有出现过的数字。进一步地,我们可以直接对原数组进行标记:把重复出现的数字-1在原数组的位置设为负数(这里-1 的目的是把 1 到 n 的数字映射到 0 到 n-1 的位置),最后仍然为正数的位置 +1 即为没有出现过的数。 +利用陣列這種資料結構建立 n 個桶,把所有重複出現的位置進行標記,然後再遍歷一遍陣列,即可找到沒有出現過的數字。進一步地,我們可以直接對原陣列進行標記:把重複出現的數字在原陣列的位置設為負數(這裡負數的目的是把 1 到 n 的數字映射到 0 到 n-1 的位置),最後仍然為正數的位置即為沒有出現過的數。 ### 題解 - - @@ -66,11 +64,11 @@ def findDisappearedNumbers(nums: List[int]) -> List[int]: ### 題目描述 -给定一个 n × n 的矩阵,求它顺时针旋转 90 度的结果,且必须在原矩阵上修改(in-place)。怎样能够尽量不创建额外储存空间呢? +給定一個 n × n 的矩陣,求它順時針旋轉 90 度的結果,且必須在原矩陣上修改(in-place)。怎樣能夠盡量不創建額外儲存空間呢? ### 輸入輸出範例 -输入和输出都是一个二维整数矩阵。 +輸入和輸出都是一個二維整數矩陣。 ``` Input: @@ -85,13 +83,13 @@ Output: ### 題解 -每次只考虑四个间隔 90 度的位置,可以进行 O(1) 额外空间的旋转。 +每次只考慮四個間隔 90 度的位置,可以進行 $O(1)$ 額外空間的旋轉。
        ![](10.1.png) -
        图 10.1: 题目 48 - $O(1)$ 空间旋转样例,相同颜色代表四个互相交换的位置
        +
        圖 10.1: 題目 48 - $O(1)$ 空間旋轉範例,相同顏色代表四個互相交換的位置
        @@ -135,11 +133,11 @@ def rotate(matrix: List[List[int]]) -> None: ### 題目描述 -给定一个二维矩阵,已知每行和每列都是增序的,尝试设计一个快速搜索一个数字是否在矩阵中存在的算法。 +給定一個二維矩陣,已知每行和每列都是遞增排序,嘗試設計一個快速搜索某個數字是否存在於矩陣中的演算法。 ### 輸入輸出範例 -输入是一个二维整数矩阵,和一个待搜索整数。输出是一个布尔值,表示这个整数是否存在于矩阵中。 +輸入是一個二維整數矩陣,和一個待搜索整數。輸出是一個布林值,表示該整數是否存在於矩陣中。 ``` Input: matrix = @@ -153,7 +151,7 @@ Output: true ### 題解 -这道题有一个简单的技巧:我们可以从右上角开始查找,若当前值大于待搜索值,我们向左移动一位;若当前值小于待搜索值,我们向下移动一位。如果最终移动到左下角时仍不等于待搜索值,则说明待搜索值不存在于矩阵中。 +這道題有一個簡單的技巧:我們可以從右上角開始查找,若當前值大於待搜索值,我們向左移動一位;若當前值小於待搜索值,我們向下移動一位。如果最終移動到左下角時仍不等於待搜索值,則說明該值不存在於矩陣中。 @@ -200,24 +198,24 @@ def searchMatrix(matrix: List[List[int]], target: int) -> bool: ### 題目描述 -给定一个含有 0 到 n 整数的数组,每个整数只出现一次,求这个数组最多可以分割成多少个子数组,使得对每个子数组进行增序排序后,原数组也是增序的。 +給定一個包含 0 到 n 的整數陣列,每個整數只出現一次,求這個陣列最多可以分割成多少個子陣列,使得對每個子陣列進行遞增排序後,原陣列也是遞增的。 ### 輸入輸出範例 -输入一个一维整数数组,输出一个整数,表示最多的分割数。 +輸入是一個一維整數陣列,輸出是一個整數,表示最多的分割數。 ``` Input: [1,0,2,3,4] Output: 4 ``` -在这个样例中,最多分割是 [1, 0], [2], [3], [4]。 +在這個範例中,最多的分割是 [1, 0], [2], [3], [4]。 ### 題解 -从左往右遍历,同时记录当前的最大值,每当当前最大值等于数组位置时,我们可以多一次分割。 +從左到右遍歷,同時記錄目前的最大值,每當目前最大值等於目前陣列位置時,我們可以進行一次分割。 -为什么可以通过这个算法解决问题呢?如果当前最大值大于数组位置,则说明右边一定有小于数组位置的数字,需要把它也加入待排序的子数组;又因为数组只包含不重复的 0 到 n,所以当前最大值一定不会小于数组位置。所以每当当前最大值等于数组位置时,假设为 p,我们可以成功完成一次分割,并且其与上一次分割位置 q 之间的值一定是 q +1 到 p 的所有数字。 +為什麼這個演算法可以解決問題呢?如果目前最大值大於目前陣列位置,則說明右邊一定有小於目前位置的數字,需要把它也加入待排序的子陣列;又因為陣列只包含不重複的 0 到 n,所以目前最大值一定不會小於目前陣列位置。因此,每當目前最大值等於目前陣列位置時,假設為 p,我們可以成功完成一次分割,並且其與上一次分割位置 q 之間的值一定是 q+1 到 p 的所有數字。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-4-stack-and-queue.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-4-stack-and-queue.mdx index 93150382..11212c84 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-4-stack-and-queue.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-4-stack-and-queue.mdx @@ -2,17 +2,17 @@ sidebar_position: 51 --- -# 10.4 栈和队列 +# 10.4 堆疊與佇列 ## [232. Implement Queue using Stacks](https://leetcode.com/problems/implement-queue-using-stacks/) ### 題目描述 -尝试使用栈(stack)来实现队列(queue)。 +嘗試使用堆疊(stack)來實作佇列(queue)。 ### 輸入輸出範例 -以下是数据结构的调用样例。 +以下是資料結構的調用範例。 ``` MyQueue queue = new MyQueue(); @@ -25,7 +25,7 @@ queue.empty(); // returns false ### 題解 -我们可以用两个栈来实现一个队列:因为我们需要得到先入先出的结果,所以必定要通过一个额外栈翻转一次数组。这个翻转过程既可以在插入时完成,也可以在取值时完成。我们这里展示在取值时完成的写法。 +我們可以用兩個堆疊來實作一個佇列:因為需要得到先入先出的結果,所以必須透過一個額外的堆疊翻轉一次陣列。這個翻轉過程可以在插入時完成,也可以在取值時完成。以下展示在取值時完成的寫法。 @@ -105,11 +105,11 @@ class MyQueue: ### 題目描述 -设计一个最小栈,除了需要支持常规栈的操作外,还需要支持在 $O(1)$ 时间内查询栈内最小值的功能。 +設計一個最小堆疊,除了需要支援一般堆疊的操作外,還需要支援在 $O(1)$ 時間內查詢堆疊中最小值的功能。 ### 輸入輸出範例 -以下是数据结构的调用样例。 +以下是資料結構的使用範例: ``` MinStack minStack = new MinStack(); @@ -124,9 +124,9 @@ minStack.getMin(); // Returns -2. ### 題解 -我们可以额外建立一个新栈,栈顶表示原栈里所有值的最小值。每当在原栈里插入一个数字时,若该数字小于等于新栈栈顶,则表示这个数字在原栈里是最小值,我们将其同时插入新栈内。每当从原栈里取出一个数字时,若该数字等于新栈栈顶,则表示这个数是原栈里的最小值之一,我们同时取出新栈栈顶的值。 +我們可以額外建立一個輔助堆疊,該堆疊的頂部用來表示原堆疊中所有值的最小值。每當在原堆疊中插入一個數字時,若該數字小於或等於輔助堆疊的頂部,則表示該數字是原堆疊的最小值之一,我們同時將其插入輔助堆疊中。每當從原堆疊中取出一個數字時,若該數字等於輔助堆疊的頂部,則表示該數字是原堆疊中的最小值之一,我們同時取出輔助堆疊的頂部值。 -一个写起来更简单但是时间复杂度略高的方法是,我们每次插入原栈时,都向新栈插入一次原栈里所有值的最小值(新栈栈顶和待插入值中小的那一个);每次从原栈里取出数字时,同样取出新栈的栈顶。这样可以避免判断,但是每次都要插入和取出。我们这里只展示第一种写法。 +另一種實現較簡單但時間複雜度略高的方法是,每次插入原堆疊時,都向輔助堆疊插入一次原堆疊中所有值的最小值(輔助堆疊頂部和待插入值中的較小值);每次從原堆疊中取出數字時,同樣從輔助堆疊中取出頂部值。這樣可以避免條件判斷,但需要每次都插入和取出。這裡只展示第一種方法。 @@ -194,11 +194,11 @@ class MinStack: ### 題目描述 -给定一个只由左右圆括号、花括号和方括号组成的字符串,求这个字符串是否合法。合法的定义是每一个类型的左括号都有一个右括号一一对应,且括号内的字符串也满足此要求。 +給定一個只由左右圓括號、花括號和方括號組成的字串,判斷這個字串是否合法。合法的定義是每一種類型的左括號都有一個右括號一一對應,且括號內的字串也滿足此要求。 ### 輸入輸出範例 -输入是一个字符串,输出是一个布尔值,表示字符串是否合法。 +輸入是一個字串,輸出是一個布林值,表示字串是否合法。 ``` Input: "{[]}()" @@ -207,7 +207,7 @@ Output: true ### 題解 -括号匹配是典型的使用栈来解决的问题。我们从左往右遍历,每当遇到左括号便放入栈内,遇到右括号则判断其和栈顶的括号是否是统一类型,是则从栈内取出左括号,否则说明字符串不合法。 +括號匹配是典型使用堆疊來解決的問題。我們從左到右遍歷字串,每當遇到左括號時將其放入堆疊;當遇到右括號時,判斷其是否與堆疊頂部的括號類型相符,若相符則從堆疊中移除左括號,否則說明字串不合法。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-5-monotonic-stack.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-5-monotonic-stack.mdx index a4de08f5..b21fdb4b 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-5-monotonic-stack.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-5-monotonic-stack.mdx @@ -2,19 +2,19 @@ sidebar_position: 52 --- -# 10.5 单调栈 +# 10.5 單調堆疊 -`单调栈`通过维持栈内值的单调递增(递减)性,在整体 $O(n)$ 的时间内处理需要大小比较的问题。 +`單調堆疊`透過維持堆疊內值的單調遞增(遞減)性,可以在整體 $O(n)$ 的時間內解決需要大小比較的問題。 ## [739. Daily Temperatures](https://leetcode.com/problems/daily-temperatures/) ### 題目描述 -给定每天的温度,求对于每一天需要等几天才可以等到更暖和的一天。如果该天之后不存在更暖和的天气,则记为 0。 +給定每天的溫度,求對於每一天需要等幾天才可以等到更暖和的一天。如果該天之後不存在更暖和的天氣,則記為 0。 ### 輸入輸出範例 -输入是一个一维整数数组,输出是同样长度的整数数组,表示对于每天需要等待多少天。 +輸入是一個一維整數陣列,輸出是相同長度的整數陣列,表示對於每天需要等待多少天。 ``` Input: [73, 74, 75, 71, 69, 72, 76, 73] @@ -23,7 +23,7 @@ Output: [1, 1, 4, 2, 1, 1, 0, 0] ### 題解 -我们可以维持一个单调递减的栈,表示每天的温度;为了方便计算天数差,我们这里存放位置(即日期)而非温度本身。我们从左向右遍历温度数组,对于每个日期 p,如果 p 的温度比栈顶存储位置 q 的温度高,则我们取出 q,并记录 q 需要等待的天数为 p − q;我们重复这一过程,直到 p 的温度小于等于栈顶存储位置的温度(或空栈)时,我们将 p 插入栈顶,然后考虑下一天。在这个过程中,栈内数组永远保持单调递减,避免了使用排序进行比较。最后若栈内剩余一些日期,则说明它们之后都没有出现更暖和的日期。 +我們可以維持一個單調遞減的堆疊,表示每天的溫度;為了方便計算天數差,我們存放位置(即日期)而非溫度本身。我們從左到右遍歷溫度陣列,對於每個日期 $p$,如果 $p$ 的溫度比堆疊頂部存儲位置 $q$ 的溫度高,則我們取出 $q$,並記錄 $q$ 需要等待的天數為 $p - q$;我們重複這一過程,直到 $p$ 的溫度小於等於堆疊頂部存儲位置的溫度(或空堆疊)時,將 $p$ 插入堆疊頂部,然後考慮下一天。在此過程中,堆疊內陣列永遠保持單調遞減,避免了使用排序進行比較。最後若堆疊內剩餘一些日期,則說明它們之後都沒有出現更暖和的日期。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-6-priority-queue.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-6-priority-queue.mdx index 9a225ba9..8750681e 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-6-priority-queue.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-6-priority-queue.mdx @@ -2,20 +2,21 @@ sidebar_position: 53 --- -# 10.6 优先队列 +# 10.6 優先佇列 + +`優先佇列`(priority queue)可以在 $O(1)$ 時間內獲得最大值,並且可以在 $O(\log n)$ 時間內取出最大值或插入任意值。 -`优先队列`(priority queue)可以在 O(1) 时间内获得最大值,并且可以在 O(log n) 时间内取出最大值或插入任意值。
        ![](10.2.png) -
        图 10.2: (最大)堆,维护的是数据结构中的大于关系
        +
        圖 10.2: (最大)堆,維護的是資料結構中的大於關係
        -优先队列常常用堆(heap)来实现。堆是一个完全二叉树,其每个节点的值总是大于等于子节点的值。实际实现堆时,我们通常用一个数组而不是用指针建立一个树。这是因为堆是完全二叉树,所以用数组表示时,位置 i 的节点的父节点位置一定为 (i-1)/2,而它的两个子节点的位置又一定分别为 2i+1 和 2i+2。 +優先佇列常常用堆(heap)來實現。堆是一個完全二元樹,其每個節點的值總是大於等於子節點的值。實際實現堆時,我們通常用一個陣列而不是用指標建立一個樹。這是因為堆是完全二元樹,所以用陣列表示時,位置 $i$ 的節點的父節點位置一定為 $(i-1)/2$,而它的兩個子節點的位置又一定分別為 $2i+1$ 和 $2i+2$。 -以下是堆的实现方法,其中最核心的两个操作是上浮和下沉:如果一个节点比父节点大,那么需要交换这个两个节点;交换后还可能比它新的父节点大,因此需要不断地进行比较和交换操作,我们称之为上浮;类似地,如果一个节点比父节小,也需要不断地向下进行比较和交换操作我们称之为下沉。如果一个节点有两个子节点,我们总是交换最大的子节点。 +以下是堆的實現方法,其中最核心的兩個操作是上浮和下沉:如果一個節點比父節點大,那麼需要交換這兩個節點;交換後還可能比它新的父節點大,因此需要不斷地進行比較和交換操作,我們稱之為上浮;類似地,如果一個節點比父節點小,也需要不斷地向下進行比較和交換操作我們稱之為下沉。如果一個節點有兩個子節點,我們總是交換最大的子節點。 @@ -50,18 +51,18 @@ class Heap { next_pos = 2 * pos + 1; } } - // 插入任意值:把新的数字放在最后一位,然后上浮。 + // 插入任意值:把新的數字放在最後一位,然後上浮。 void push(int k) { heap_.push_back(k); swim(heap_.size() - 1); } - // 删除最大值:把最后一个数字挪到开头,然后下沉。 + // 刪除最大值:把最後一個數字挪到開頭,然後下沉。 void pop() { heap_[0] = heap_.back(); heap_.pop_back(); sink(0); } - // 获得最大值。 + // 獲得最大值。 int top() { return heap_[0]; } private: @@ -98,17 +99,17 @@ class Heap: pos = next_pos next_pos = 2 * pos + 1 - # 插入任意值:把新的数字放在最后一位,然后上浮。 + # 插入任意值:把新的數字放在最後一位,然後上浮。 def push(self, k: int): self.heap.append(k) self.swim(len(self.heap) - 1) - # 删除最大值:把最后一个数字挪到开头,然后下沉。 + # 刪除最大值:把最後一個數字挪到開頭,然後下沉。 def pop(self): self.heap[0] = self.heap.pop() self.sink(0) - # 获得最大值。 + # 獲得最大值。 def top(self) -> int: return self.heap[0] @@ -118,17 +119,17 @@ class Heap: -通过将算法中的大于号和小于号互换,我们也可以得到一个快速获得最小值的优先队列。 +通過將算法中的大於號和小於號互換,我們也可以得到一個快速獲得最小值的優先佇列。 ## [23. Merge k Sorted Lists](https://leetcode.com/problems/merge-k-sorted-lists/) ### 題目描述 -给定 k 个增序的链表,试将它们合并成一条增序链表。 +給定 k 個遞增的鏈結串列,嘗試將它們合併成一條遞增鏈結串列。 ### 輸入輸出範例 -输入是一个一维数组,每个位置存储链表的头节点;输出是一条链表。 +輸入是一維陣列,每個位置儲存鏈結串列的頭節點;輸出是一條鏈結串列。 ``` Input: @@ -140,9 +141,9 @@ Output: 1->1->2->3->4->4->5->6 ### 題解 -本题可以有很多中解法,比如类似于归并排序进行两两合并。我们这里展示一个速度比较快的方法,即把所有的链表存储在一个优先队列中,每次提取所有链表头部节点值最小的那个节点,直到所有链表都被提取完为止。 +本題可以有多種解法,例如類似於合併排序進行兩兩合併。我們這裡展示一個速度較快的方法,即把所有的鏈結串列存入一個優先佇列中,每次提取所有鏈結串列頭部節點值中最小的那個節點,直到所有鏈結串列都被提取完為止。 -因为 C++ priority_queue 的比较函数默认是对最大堆进行比较并维持递增关系,如果我们想要获取最小的节点值,我们则需要实现一个最小堆。因此堆的比较函数应该维持递减关系,即 lambda 函数中返回时用大于号而不是递增关系时的小于号进行比较。 +由於 C++ priority_queue 的比較函數預設是對最大堆進行比較並維持遞增關係,如果我們想要獲取最小的節點值,我們則需要實現一個最小堆。因此,堆的比較函數應該維持遞減關係,即 lambda 函數中返回時用大於號而不是遞增關係時的小於號進行比較。 @@ -177,7 +178,7 @@ def mergeKLists(lists: List[Optional[ListNode]]) -> Optional[ListNode]: pq = [] for idx, l in enumerate(lists): if l is not None: - # ListNode不可被哈希,所以这里我们直接记录它在lists中的位置。 + # ListNode 無法被雜湊,因此這裡我們直接記錄它在 lists 中的位置。 pq.append((l.val, idx)) heapq.heapify(pq) @@ -204,17 +205,17 @@ def mergeKLists(lists: List[Optional[ListNode]]) -> Optional[ListNode]: ### 題目描述 -给定建筑物的起止位置和高度,返回建筑物轮廓(天际线)的拐点。 +給定建築物的起始位置、結束位置和高度,返回建築物輪廓(天際線)的轉折點。 ### 輸入輸出範例 -输入是一个二维整数数组,表示每个建筑物的 [左端, 右端, 高度];输出是一个二维整数数组,表示每个拐点的横纵坐标。 +輸入是一個二維整數陣列,每個建築物用 [左端, 右端, 高度] 表示;輸出是一個二維整數陣列,表示天際線轉折點的橫縱座標。
        ![](10.3.png) -
        图 10.3: 题目 218 - 建筑物及其天际线样例
        +
        圖 10.3: 問題 218 - 建築物與其天際線範例
        ``` @@ -224,11 +225,11 @@ Output: [[2 10], [3 15], [7 12], [12 0], [15 10], [20 8], [24, 0]] ### 題解 -我们可以使用优先队列储存每个建筑物的高度和右端(这里使用 pair,其默认比较函数是先比较第一个值,如果相等则再比较第二个值),从而获取目前会拔高天际线、且妨碍到前一个建筑物(的右端端点)的下一个建筑物。 +我們可以使用優先隊列來儲存每棟建築的高度與右端(這裡使用 pair,其默認的比較函數是先比較第一個值,如果相等則再比較第二個值),從而找到目前會提高天際線的建築,並排除妨礙到前一棟建築(右端點)的建築。 -因为 Python 中 heapq 是最小堆,所以我们在存值的时候可以存负值,这样就变成了最大堆。 +因為 Python 的 `heapq` 是最小堆,所以我們在存值的時候可以存負值,這樣就模擬了最大堆。 -这道题比较复杂,如果实在难以理解,建议读者暂时跳过此题,或者在纸上举例子画一画。 +這題較為複雜,若難以理解,建議暫時跳過,或者在紙上畫圖舉例分析。 @@ -267,7 +268,7 @@ vector> getSkyline(vector>& buildings) { ```py def getSkyline(buildings: List[List[int]]) -> List[List[int]]: skyline = [] - pq = [] # <负高度,右端> + pq = [] # <負高度, 右端> heapq.heapify(pq) i, n = 0, len(buildings) diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-7-deque.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-7-deque.mdx index a5a97fab..943c8341 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-7-deque.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-7-deque.mdx @@ -2,24 +2,24 @@ sidebar_position: 54 --- -# 10.7 双端队列 +# 10.7 雙端佇列 ## [239. Sliding Window Maximum](https://leetcode.com/problems/sliding-window-maximum/) ### 題目描述 -给定一个整数数组和一个滑动窗口大小,求在这个窗口的滑动过程中,每个时刻其包含的最大值。 +給定一個整數陣列和一個滑動視窗大小,求在這個視窗滑動過程中的每個時刻,其包含的最大值。 ### 輸入輸出範例 -输入是一个一维整数数组,和一个表示滑动窗口大小的整数;输出是一个一维整数数组,表示每个时刻时的窗口内最大值。 +輸入是一個一維整數陣列,以及一個表示滑動視窗大小的整數;輸出是一個一維整數陣列,表示每個時刻視窗內的最大值。 ``` Input: nums = [1,3,-1,-3,5,3,6,7], k = 3 Output: [3,3,5,5,6,7] ``` -在这个样例中,滑动窗口在每个位置的最大包含值取法如下: +在此範例中,滑動視窗在每個位置的最大值如下: ``` Window position Max @@ -34,7 +34,9 @@ Output: [3,3,5,5,6,7] ### 題解 -我们可以利用双端队列进行操作:每当向右移动时,把窗口左端的值从双端队列左端剔除,把双端队列右边小于窗口右端的值全部剔除。这样双端队列的最左端永远是当前窗口内的最大值。另外,这道题也是单调栈的一种延申:该双端队列利用从左到右递减来维持大小关系。 +我們可以利用雙端佇列來實現:每次滑動視窗向右移動時,將視窗左端的值從雙端佇列左端移除,並將雙端佇列右邊小於當前視窗右端值的元素剔除。這樣,雙端佇列的最左端永遠是當前視窗內的最大值。 + +此外,這道題也可以視為單調堆疊的一種延伸:此雙端佇列利用從左到右遞減的順序來維持大小關係。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-8-hash-table.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-8-hash-table.mdx index d9a6e5a0..318e2faf 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-8-hash-table.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-8-hash-table.mdx @@ -2,32 +2,32 @@ sidebar_position: 55 --- -# 10.8 哈希表 +# 10.8 雜湊表 -`哈希表(hash table, hash map)`,又称散列表,使用 $O(n)$ 空间复杂度存储数据,通过哈希函数(hash function)映射位置,从而实现近似 O(1) 时间复杂度的插入、查找、删除等操作。哈希表可以用来统计频率,记录内容等等。 +`雜湊表(hash table, hash map)`,又稱散列表,使用 $O(n)$ 空間複雜度存儲資料,通過雜湊函數(hash function)映射位置,從而實現近似 O(1) 時間複雜度的插入、查詢、刪除等操作。雜湊表可以用來統計頻率、記錄內容等等。 -如果元素有穷,并且范围不大,那么可以用一个固定大小的数组来存储或统计元素。例如我们需要统计一个字符串中所有字母的出现次数,则可以用一个长度为 26 的数组来进行统计,其哈希函数即为字母在字母表的位置,这样空间复杂度就可以降低为常数。 +如果元素是有限的,且範圍不大,那麼可以用一個固定大小的陣列來存儲或統計元素。例如,我們需要統計一個字串中所有字母的出現次數,則可以用一個長度為 26 的陣列來進行統計,其雜湊函數即為字母在字母表中的位置,這樣空間複雜度就可以降低為常數。 ## [1. Two Sum](https://leetcode.com/problems/two-sum/) ### 題目描述 -给定一个(未排序的)整数数组,已知有且只有两个数的和等于给定值,求这两个数的位置。 +給定一個(未排序的)整數陣列,已知有且只有兩個數的和等於給定值,求這兩個數的位置。 ### 輸入輸出範例 -输入一个一维整数数组和一个目标值,输出是一个大小为 2 的一维数组,表示满足条件的两个数字的位置。 +輸入是一個一維整數陣列和一個目標值,輸出是一個大小為 2 的一維陣列,表示滿足條件的兩個數字的位置。 ``` Input: nums = [2, 7, 15, 11], target = 9 Output: [0, 1] ``` -在这个样例中,第 0 个位置的值 2 和第 1 个位置的值 7 的和为 9。 +在這個範例中,第 0 個位置的值 2 和第 1 個位置的值 7 的和為 9。 ### 題解 -我们可以利用哈希表存储遍历过的值以及它们的位置,每次遍历到位置 i 的时候,查找哈希表里是否存在 target - nums[i],若存在,则说明这两个值的和为 target。 +我們可以利用雜湊表儲存遍歷過的值以及它們的位置,每次遍歷到位置 i 的時候,查找雜湊表裡是否存在 `target - nums[i]`,若存在,則說明這兩個值的和為 `target`。 @@ -68,22 +68,22 @@ def twoSum(nums: List[int], target: int) -> List[int]: ### 題目描述 -给定一个整数数组,求这个数组中的数字可以组成的最长连续序列有多长。 +給定一個整數陣列,求這個陣列中的數字可以組成的最長連續序列有多長。 ### 輸入輸出範例 -输入一个整数数组,输出一个整数,表示连续序列的长度。 +輸入是一個整數陣列,輸出是一個整數,表示連續序列的長度。 ``` Input: [100, 4, 200, 1, 3, 2] Output: 4 ``` -在这个样例中,最长连续序列是 [1,2,3,4]。 +在這個範例中,最長連續序列是 [1,2,3,4]。 ### 題解 -我们可以把所有数字放到一个哈希表,然后不断地从哈希表中任意取一个值,并删除掉其之前之后的所有连续数字,然后更新目前的最长连续序列长度。重复这一过程,我们就可以找到所有的连续数字序列。 +我們可以把所有數字放到一個雜湊表,然後不斷地從雜湊表中任意取一個值,並刪除掉其之前之後的所有連續數字,然後更新目前的最長連續序列長度。重複這一過程,我們就可以找到所有的連續數字序列。 @@ -142,11 +142,11 @@ def longestConsecutive(nums: List[int]) -> int: ### 題目描述 -给定一些二维坐标中的点,求同一条线上最多有多少点。 +給定一些二維座標中的點,求同一條線上最多有多少點。 ### 輸入輸出範例 -输入是一个二维整数数组,表示每个点的横纵坐标;输出是一个整数,表示满足条件的最多点数。 +輸入是一個二維整數陣列,表示每個點的橫縱座標;輸出是一個整數,表示滿足條件的最多點數。 ``` Input: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]] @@ -161,13 +161,13 @@ Input: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]] Output: 4 ``` -这个样例中,$y =5 − x$ 上有四个点。 +在這個範例中,$y = 5 - x$ 上有四個點。 ### 題解 -对于每个点,我们对其它点建立哈希表,统计同一斜率的点一共有多少个。这里利用的原理是,一条线可以由一个点和斜率而唯一确定。另外也要考虑斜率不存在和重复坐标的情况。 +對於每個點,我們對其他點建立雜湊表,統計同一斜率的點一共有多少個。這裡利用的原理是,一條線可以由一個點和斜率唯一確定。此外,也需要考慮斜率不存在和重複座標的情況。 -本题也利用了一个小技巧:在遍历每个点时,对于数组中位置 i 的点,我们只需要考虑 i 之后的点即可,因为 i 之前的点已经考虑过 i 了。 +本題還利用了一個小技巧:在遍歷每個點時,對於陣列中位置 i 的點,我們只需要考慮 i 之後的點即可,因為 i 之前的點已經考慮過 i 了。 @@ -176,7 +176,7 @@ Output: 4 int maxPoints(vector>& points) { int max_count = 0, n = points.size(); for (int i = 0; i < n; ++i) { - unordered_map cache; // <斜率, 点个数> + unordered_map cache; // <斜率, 點的數量> int same_xy = 1, same_y = 1; for (int j = i + 1; j < n; ++j) { if (points[i][1] == points[j][1]) { @@ -207,7 +207,7 @@ def maxPoints(points: List[List[int]]) -> int: max_count, n = 0, len(points) for i, point1 in enumerate(points): - cache = dict() # <斜率, 点个数> + cache = dict() # <斜率, 點的數量> same_xy, same_y = 1, 1 for point2 in points[i + 1:]: diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-9-multisets-and-maps.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-9-multisets-and-maps.mdx index aa08778c..8bfe5fd1 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-9-multisets-and-maps.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-9-multisets-and-maps.mdx @@ -8,11 +8,11 @@ sidebar_position: 56 ### 題目描述 -给定一个人坐过的一些飞机的起止机场,已知这个人从 JFK 起飞,那么这个人是按什么顺序飞的;如果存在多种可能性,返回字母序最小的那种。 +給定一個人搭乘過的一些飛機的起止機場,已知這個人從 JFK 起飛,那麼這個人是按什麼順序飛的;如果存在多種可能性,返回字母序最小的那種。 ### 輸入輸出範例 -输入是一个二维字符串数组,表示多个起止机场对子;输出是一个一维字符串数组,表示飞行顺序。 +輸入是一個二維字串陣列,表示多個起止機場的組合;輸出是一個一維字串陣列,表示飛行順序。 ``` Input: [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]] @@ -21,9 +21,9 @@ Output: ["JFK", "MUC", "LHR", "SFO", "SJC"] ### 題解 -本题可以先用哈希表记录起止机场,其中键是起始机场,值是一个多重(有序)集合,表示对应的终止机场。因为一个人可能坐过重复的线路,所以我们需要使用多重集合储存重复值。储存完成之后,我们可以利用栈/DFS 来恢复从终点到起点飞行的顺序,再将结果逆序得到从起点到终点的顺序。 +本題可以先用雜湊表記錄起止機場,其中鍵是起始機場,值是一個多重(有序)集合,表示對應的終止機場。因為一個人可能搭過重複的航線,所以我們需要使用多重集合來儲存重複值。儲存完成之後,我們可以利用堆疊/DFS 來還原從終點到起點的飛行順序,再將結果逆序得到從起點到終點的順序。 -因为 Python 没有默认的多重(有序)集合实现,我们可以直接存储一个数组,然后进行排序。也可以使用 Counter 结构,每次查找下一个机场时,返回 key 值最小的那个。 +由於 Python 沒有內建的多重(有序)集合實作,我們可以直接儲存一個陣列,然後進行排序。也可以使用 Counter 結構,每次查找下一個機場時,返回鍵值最小的那個。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-1-algorithm-explanation.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-1-algorithm-explanation.md index 4435a283..d515b54d 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-1-algorithm-explanation.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-1-algorithm-explanation.md @@ -4,18 +4,18 @@ sidebar_position: 5 # 2.1 算法解释 -雙指針主要用於遍歷數組,兩個指針指向不同的元素,從而協同完成任務。也可以延伸到多個數組的多個指針。 +雙指針主要用於遍歷陣列,兩個指針指向不同的元素,從而協同完成任務。也可以延伸到多個陣列的多個指針。 -若兩個指針指向同一數組,遍歷方向相同且不會相交,則也稱為滑動窗口(兩個指針包圍的區域即為當前的窗口),經常用於區間搜索。 +若兩個指針指向同一陣列,遍歷方向相同且不會相交,則也稱為滑動窗口(兩個指針包圍的區域即為當前的窗口),經常用於區間搜索。 -若兩個指針指向同一數組,但是遍歷方向相反,則可以用來進行搜索,待搜索的數組往往是排好序的。 +若兩個指針指向同一陣列,但是遍歷方向相反,則可以用來進行搜索,待搜索的陣列往往是排好序的。 在 C++ 中,要注意 `const` 的位置對指針效果的影響: ```cpp int x; -int * p1 = &x; // 指针可以被修改,值也可以被修改 -const int * p2 = &x; // 指针可以被修改,值不可以被修改(const int) -int * const p3 = &x; // 指针不可以被修改(* const),值可以被修改 -const int * const p4 = &x; // 指针不可以被修改,值也不可以被修改 +int * p1 = &x; // 指針可以被修改,值也可以被修改 +const int * p2 = &x; // 指針可以被修改,值不可以被修改(const int) +int * const p3 = &x; // 指針不可以被修改(* const),值可以被修改 +const int * const p4 = &x; // 指針不可以被修改,值也不可以被修改 ``` diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-2-two-sum.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-2-two-sum.mdx index 7c51e67f..eb125af4 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-2-two-sum.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-2-two-sum.mdx @@ -8,11 +8,11 @@ sidebar_position: 6 ### 題目描述 -在一個增序的整數數組裡找到兩個數,使它們的和為給定值。已知有且只有一對解。 +在一個增序的整數陣列裡找到兩個數,使它們的和為給定值。已知有且只有一對解。 ### 輸入輸出範例 -輸入是一個數組(`numbers`)和一個給定值(`target`)。輸出是兩個數的位置,從 1 開始計數。 +輸入是一個陣列(`numbers`)和一個給定值(`target`)。輸出是兩個數的位置,從 1 開始計數。 ``` Input: numbers = [2,7,11,15], target = 9 @@ -23,11 +23,11 @@ Output: [1,2] ### 題解 -因為數組已經排好序,我們可以採用方向相反的雙指針來尋找這兩個數字。一個指針初始指向最小的元素,即數組最左邊,向右遍歷;另一個指針初始指向最大的元素,即數組最右邊,向左遍歷。 +因為陣列已經排好序,我們可以採用方向相反的雙指針來尋找這兩個數字。一個指針初始指向最小的元素,即陣列最左邊,向右遍歷;另一個指針初始指向最大的元素,即陣列最右邊,向左遍歷。 如果兩個指針指向元素的和等於給定值,那麼它們就是我們要的結果。如果兩個指針指向元素的和小於給定值,我們把左邊的指針右移一位,使得當前的和增加一點。如果兩個指針指向元素的和大於給定值,我們把右邊的指針左移一位,使得當前的和減少一點。 -可以證明,對於排好序且有解的數組,雙指針一定能遍歷到最優解。證明方法如下:假設最優解的兩個數的位置分別是 `l` 和 `r`。我們假設在左指針在 `l` 左邊的時候,右指針已經移動到了 `r`;此時兩個指針指向值的和小於給定值,因此左指針會一直右移直到到達 `l`。同理,如果我們假設在右指針在 `r` 右邊的時候,左指針已經移動到了 `l`;此時兩個指針指向值的和大於給定值,因此右指針會一直左移直到到達 `r`。所以雙指針在任何時候都不可能處於 `(l,r)` 之間,又因為不滿足條件時指針必須移動一個,所以最終一定會收斂在 `l` 和 `r`。 +可以證明,對於排好序且有解的陣列,雙指針一定能遍歷到最優解。證明方法如下:假設最優解的兩個數的位置分別是 `l` 和 `r`。我們假設在左指針在 `l` 左邊的時候,右指針已經移動到了 `r`;此時兩個指針指向值的和小於給定值,因此左指針會一直右移直到到達 `l`。同理,如果我們假設在右指針在 `r` 右邊的時候,左指針已經移動到了 `l`;此時兩個指針指向值的和大於給定值,因此右指針會一直左移直到到達 `r`。所以雙指針在任何時候都不可能處於 `(l,r)` 之間,又因為不滿足條件時指針必須移動一個,所以最終一定會收斂在 `l` 和 `r`。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-3-merge-sorted-arrays.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-3-merge-sorted-arrays.mdx index a320fb5a..d08967c5 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-3-merge-sorted-arrays.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-3-merge-sorted-arrays.mdx @@ -2,17 +2,17 @@ sidebar_position: 7 --- -# 2.3 合併兩個有序數組 +# 2.3 合併兩個有序陣列 ## [88. Merge Sorted Array](https://leetcode.com/problems/merge-sorted-array/) ### 題目描述 -給定兩個有序數組,將它們合併為一個數組。 +給定兩個有序陣列,將它們合併為一個陣列。 ### 輸入輸出範例 -輸入是兩個數組和它們分別的長度 `m` 和 `n`。其中第一個數組的長度被延長至 `m + n`,多出的 `n` 位被 `0` 填補。題目要求把第二個數組合併到第一個數組上,不需要開闢額外空間。 +輸入是兩個陣列和它們分別的長度 `m` 和 `n`。其中第一個陣列的長度被延長至 `m + n`,多出的 `n` 位被 `0` 填補。題目要求把第二個陣列合併到第一個陣列上,不需要開闢額外空間。 ``` Input: nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3 @@ -22,9 +22,9 @@ Output: nums1 = [1,2,2,3,5,6] ### 題解 -因為這兩個數組已經排好序,我們可以將兩個指針分別放在兩個數組的末尾,即 `nums1` 的 `(m - 1)` 位和 `nums2` 的 `(n - 1)` 位。每次將較大的那個數字複製到 `nums1` 的後邊,然後向前移動一位。 +因為這兩個陣列已經排好序,我們可以將兩個指針分別放在兩個陣列的末尾,即 `nums1` 的 `(m - 1)` 位和 `nums2` 的 `(n - 1)` 位。每次將較大的那個數字複製到 `nums1` 的後邊,然後向前移動一位。 -我們也需要第三個指針來定位 `nums1` 的末尾,以便進行複製。在以下的代碼裡,我們直接利用 `m` 和 `n` 當作兩個數組的指針,再額外創建一個 `pos` 指針,起始位置為 `m + n - 1`。每次向左移動 `m` 或 `n` 的時候,也要向左移動 `pos`。注意,如果 `nums1` 的數字已經複製完,不要忘記繼續複製 `nums2` 的數字;如果 `nums2` 的數字已經複製完,剩下的 `nums1` 的數字不需要改變,因為它們已經排好序。 +我們也需要第三個指針來定位 `nums1` 的末尾,以便進行複製。在以下的代碼裡,我們直接利用 `m` 和 `n` 當作兩個陣列的指針,再額外創建一個 `pos` 指針,起始位置為 `m + n - 1`。每次向左移動 `m` 或 `n` 的時候,也要向左移動 `pos`。注意,如果 `nums1` 的數字已經複製完,不要忘記繼續複製 `nums2` 的數字;如果 `nums2` 的數字已經複製完,剩下的 `nums1` 的數字不需要改變,因為它們已經排好序。 在 C++ 的題解中,我們使用了 `++` 和 `--` 的小技巧:`a++` 和 `++a` 都會將 `a` 加 1,但 `a++` 的返回值為 `a`,而 `++a` 的返回值為 `a + 1`。如果只希望增加 `a` 的值而不需要返回值,則兩種寫法都可以(`++a` 在未經編譯器優化的情況下運行速度會略快一些)。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-4-sliding-window.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-4-sliding-window.mdx index 351e91bc..500991bb 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-4-sliding-window.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-4-sliding-window.mdx @@ -24,7 +24,7 @@ Output: "BANC" ### 題解 -本題使用滑動窗口求解,即兩個指針 `l` 和 `r` 都是從最左端向最右端移動,且 `l` 的位置一定在 `r` 的左邊或重合。在 C++ 解法中,使用了兩個長度為 128 的數組,`valid` 和 `freq`,用來映射字符(ASCII 僅包含 128 個字符)。其中 `valid` 表示每個字符在 `t` 中是否存在,而 `freq` 表示目前 `t` 中每個字符在 `s` 的滑動窗口中缺少的數量:如果為正,則說明還缺少;如果為負,則說明有盈餘。在 Python 解法中,直接使用了 `Counter` 數據結構,同時統計 `t` 中存在的字符和其缺少的數量(也可以用 `dict` 替代)。 +本題使用滑動窗口求解,即兩個指針 `l` 和 `r` 都是從最左端向最右端移動,且 `l` 的位置一定在 `r` 的左邊或重合。在 C++ 解法中,使用了兩個長度為 128 的陣列,`valid` 和 `freq`,用來映射字符(ASCII 僅包含 128 個字符)。其中 `valid` 表示每個字符在 `t` 中是否存在,而 `freq` 表示目前 `t` 中每個字符在 `s` 的滑動窗口中缺少的數量:如果為正,則說明還缺少;如果為負,則說明有盈餘。在 Python 解法中,直接使用了 `Counter` 數據結構,同時統計 `t` 中存在的字符和其缺少的數量(也可以用 `dict` 替代)。 需要注意,本題雖然在 `for` 循環裡出現了一個 `while` 循環,但由於 `while` 循環負責移動 `l` 指針,且 `l` 只會從左到右移動一次,因此總時間複雜度仍然是 $O(n)$。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-6-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-6-exercises.md index a14f93c1..6a9f045e 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-6-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-6-exercises.md @@ -16,7 +16,7 @@ Two Sum 題目的變形題之二。 ### [524. Longest Word in Dictionary through Deleting](https://leetcode.com/problems/longest-word-in-dictionary-through-deleting/) -合併兩個有序數組的變形題。 +合併兩個有序陣列的變形題。 ## 進階難度 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-1-algorithm-explanation.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-1-algorithm-explanation.md index 79446fff..950c18cf 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-1-algorithm-explanation.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-1-algorithm-explanation.md @@ -4,11 +4,11 @@ sidebar_position: 11 # 3.1 算法解釋 -`二分搜尋` 也常被稱為 `二分法` 或 `折半搜尋` (binary search, bisect),每次搜尋時通過將待搜尋的單調區間分成兩部分並只取一部分繼續搜尋,將搜尋的複雜度大大減少。對於一個長度為 $O(n)$ 的數組,二分搜尋的時間複雜度為 $O(\log n)$。 +`二分搜尋` 也常被稱為 `二分法` 或 `折半搜尋` (binary search, bisect),每次搜尋時通過將待搜尋的單調區間分成兩部分並只取一部分繼續搜尋,將搜尋的複雜度大大減少。對於一個長度為 $O(n)$ 的陣列,二分搜尋的時間複雜度為 $O(\log n)$。 -舉例來說,給定一個排好序的數組 $\{3,4,5,6,7\}$,我們希望搜尋 4 是否在這個數組中。第一次折半時考慮中位數 5,因為 5 大於 4,所以如果 4 存在於這個數組,那麼它必定存在於 5 左邊這一半。於是我們的搜尋區間變成了 $\{3,4,5\}$。(注意,根據具體情況和您的解題習慣,這裡的 5 可以保留也可以不保留,這並不影響時間複雜度的等級。)第二次折半時考慮新的中位數 4,正好是我們需要搜尋的數字。於是我們發現,對於一個長度為 5 的數組,我們只進行了 2 次搜尋。如果是遍歷數組,最壞情況則需要搜尋 5 次。 +舉例來說,給定一個排好序的陣列 $\{3,4,5,6,7\}$,我們希望搜尋 4 是否在這個陣列中。第一次折半時考慮中位數 5,因為 5 大於 4,所以如果 4 存在於這個陣列,那麼它必定存在於 5 左邊這一半。於是我們的搜尋區間變成了 $\{3,4,5\}$。(注意,根據具體情況和您的解題習慣,這裡的 5 可以保留也可以不保留,這並不影響時間複雜度的等級。)第二次折半時考慮新的中位數 4,正好是我們需要搜尋的數字。於是我們發現,對於一個長度為 5 的陣列,我們只進行了 2 次搜尋。如果是遍歷陣列,最壞情況則需要搜尋 5 次。 -我們也可以用更數學化的方式定義二分搜尋。給定一個在 $[a, b]$ 區間內的單調函數 $f(t)$,若 $f(a)$ 和 $f(b)$ 正負性相反,那麼必定存在一個解 $c$,使得 $f(c) = 0$。在上述例子中,$f(t)$ 是離散函數 $f(t) = t + 2$,搜尋 4 是否存在等價於求 $f(t) - 4 = 0$ 是否有離散解。因為 $f(1) - 4 = 3 - 4 = -1 < 0$、$f(5) - 4 = 7 - 4 = 3 > 0$,且函數在區間內單調遞增,因此我們可以利用二分搜尋求解。如果最後二分到了不能再分的情況,如只剩一個數字,且剩餘區間裡不存在滿足條件的解,則說明不存在離散解,即 4 不在這個數組中。 +我們也可以用更數學化的方式定義二分搜尋。給定一個在 $[a, b]$ 區間內的單調函數 $f(t)$,若 $f(a)$ 和 $f(b)$ 正負性相反,那麼必定存在一個解 $c$,使得 $f(c) = 0$。在上述例子中,$f(t)$ 是離散函數 $f(t) = t + 2$,搜尋 4 是否存在等價於求 $f(t) - 4 = 0$ 是否有離散解。因為 $f(1) - 4 = 3 - 4 = -1 < 0$、$f(5) - 4 = 7 - 4 = 3 > 0$,且函數在區間內單調遞增,因此我們可以利用二分搜尋求解。如果最後二分到了不能再分的情況,如只剩一個數字,且剩餘區間裡不存在滿足條件的解,則說明不存在離散解,即 4 不在這個陣列中。 具體到代碼上,二分搜尋時區間的左右端取開區間還是閉區間在絕大多數情況下都可以,因此有些初學者會容易搞不清楚如何定義區間開閉性。這裡提供兩個小訣竅:第一是嘗試熟練使用一種寫法,比如左閉右開(滿足 C++、Python 等語言的習慣)或左閉右閉(便於處理邊界條件),盡量只保持這一種寫法;第二是在解題時思考如果最後區間只剩下一個數或者兩個數,自己的寫法是否會陷入死循環,如果某種寫法無法跳出死循環,則考慮嘗試另一種寫法。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-3-interval-search.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-3-interval-search.mdx index e15b91df..b3b777fc 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-3-interval-search.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-3-interval-search.mdx @@ -8,12 +8,12 @@ sidebar_position: 13 ### 題目描述 -給定一個遞增的整數數組和一個目標值,查找該值第一次和最後一次出現的位置。 +給定一個遞增的整數陣列和一個目標值,查找該值第一次和最後一次出現的位置。 ### 輸入輸出範例 -輸入是一個數組和一個值,輸出為該值第一次出現的位置和最後一次出現的位置(從 0 開始);如果該值不存在,則兩個返回值都設為 -1。 +輸入是一個陣列和一個值,輸出為該值第一次出現的位置和最後一次出現的位置(從 0 開始);如果該值不存在,則兩個返回值都設為 -1。 ``` Input: nums = [5,7,7,8,8,10], target = 8 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-4-peak-finding.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-4-peak-finding.mdx index 77ce6558..97d8151f 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-4-peak-finding.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-4-peak-finding.mdx @@ -8,11 +8,11 @@ sidebar_position: 14 ### 題目描述 -給定一個數組,定義最大值為比兩邊都大的數字,要求出任意一個最大值的位置。一個數組中可能存在多個最大值,返回任意一個即可。要求時間複雜度為 $O(\log n)$。 +給定一個陣列,定義最大值為比兩邊都大的數字,要求出任意一個最大值的位置。一個陣列中可能存在多個最大值,返回任意一個即可。要求時間複雜度為 $O(\log n)$。 ### 輸入輸出範例 -輸入是一個數組,輸出為最大值的位置。 +輸入是一個陣列,輸出為最大值的位置。 ``` Input: nums = [1,2,3,1] @@ -24,7 +24,7 @@ Output: 2 ### 題解 -為了實現 $O(\log n)$ 的時間複雜度,我們可以對數組進行二分搜尋。在確保數組兩端不是最大值後,若當前中點不是最大值,那麼其左右一側必定存在一個最大值。 +為了實現 $O(\log n)$ 的時間複雜度,我們可以對陣列進行二分搜尋。在確保陣列兩端不是最大值後,若當前中點不是最大值,那麼其左右一側必定存在一個最大值。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-5-rotated-array-search.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-5-rotated-array-search.mdx index 7304132b..c300716f 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-5-rotated-array-search.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-5-rotated-array-search.mdx @@ -2,24 +2,24 @@ sidebar_position: 15 --- -# 3.5 搜尋旋轉數組中的數字 +# 3.5 搜尋旋轉陣列中的數字 ## [81. Search in Rotated Sorted Array II](https://leetcode.com/problems/search-in-rotated-sorted-array-ii/) ### 題目描述 -一個原本遞增的數組被首尾相連後按某個位置斷開(如 [1,2,2,3,4,5] → [2,3,4,5,1,2],在第一位和第二位斷開),我們稱其為旋轉數組。給定一個值,判斷這個值是否存在於這個旋轉數組中。 +一個原本遞增的陣列被首尾相連後按某個位置斷開(如 [1,2,2,3,4,5] → [2,3,4,5,1,2],在第一位和第二位斷開),我們稱其為旋轉陣列。給定一個值,判斷這個值是否存在於這個旋轉陣列中。 ### 輸入輸出範例 -輸入是一個數組和一個值,輸出是一個布林值,表示數組中是否存在該值。 +輸入是一個陣列和一個值,輸出是一個布林值,表示陣列中是否存在該值。 ``` Input: nums = [2,5,6,0,0,1,2], target = 0 Output: true ``` -即使數組被旋轉過,我們仍然可以利用這個數組的遞增性,使用二分搜尋。對於當前的中點,如果它指向的值小於等於右端,那麼說明右區間是排好序的;反之,那麼說明左區間是排好序的。如果目標值位於排好序的區間內,我們可以對這個區間繼續二分搜尋;反之,我們對於另一半區間繼續二分搜尋。本題我們採用左閉右閉的寫法。 +即使陣列被旋轉過,我們仍然可以利用這個陣列的遞增性,使用二分搜尋。對於當前的中點,如果它指向的值小於等於右端,那麼說明右區間是排好序的;反之,那麼說明左區間是排好序的。如果目標值位於排好序的區間內,我們可以對這個區間繼續二分搜尋;反之,我們對於另一半區間繼續二分搜尋。本題我們採用左閉右閉的寫法。 ### 題解 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-6-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-6-exercises.md index dfce9bf4..27fa8dfc 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-6-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-6-exercises.md @@ -8,7 +8,7 @@ sidebar_position: 16 ### [154. Find Minimum in Rotated Sorted Array II](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array-ii/) -旋轉數組的變形題之一。 +旋轉陣列的變形題之一。 ### [540. Single Element in a Sorted Array](https://leetcode.com/problems/single-element-in-a-sorted-array/) @@ -18,4 +18,4 @@ sidebar_position: 16 ### [4. Median of Two Sorted Arrays](https://leetcode.com/problems/median-of-two-sorted-arrays/) -需要對兩個數組同時進行二分搜尋。 +需要對兩個陣列同時進行二分搜尋。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-1-common-sorting-algorithms.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-1-common-sorting-algorithms.mdx index 8c1596c0..281e2a71 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-1-common-sorting-algorithms.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-1-common-sorting-algorithms.mdx @@ -4,7 +4,7 @@ sidebar_position: 17 # 4.1 常用排序算法 -雖然在 C++ 和 Python 裡都可以通過 sort 函數排序,而且在刷題時很少需要自己手寫排序算法,但熟悉各種排序算法可以加深對算法的基本理解,並有助於解決由這些排序算法引申出的題目。這裡展示兩種時間複雜度為 $O(n \log n)$ 的排序算法:`快速排序` 和 `合併排序`。其中前者速度較快,後者能保證相同值的元素在數組中的相對位置不變(即“穩定排序”)。 +雖然在 C++ 和 Python 裡都可以通過 sort 函數排序,而且在刷題時很少需要自己手寫排序算法,但熟悉各種排序算法可以加深對算法的基本理解,並有助於解決由這些排序算法引申出的題目。這裡展示兩種時間複雜度為 $O(n \log n)$ 的排序算法:`快速排序` 和 `合併排序`。其中前者速度較快,後者能保證相同值的元素在陣列中的相對位置不變(即“穩定排序”)。 ## 快速排序(Quicksort) @@ -89,7 +89,7 @@ def quickSort(nums: List[int], l: int, r: int) -> None: 合併排序是典型的分治法,會在後續章節展開講解。簡單來說,對於一個未排序片段,我們可以先分別排序其左半側和右半側,然後將兩側重新合併(“治”);排序每個半側時可以通過遞歸再次將其切分為兩側(“分”)。 -我們採用左閉右閉的二分寫法,初始化條件為 $l = 0, r = n - 1$,並提前建立一個與 nums 大小相同的數組 cache,用來存儲臨時結果。 +我們採用左閉右閉的二分寫法,初始化條件為 $l = 0, r = n - 1$,並提前建立一個與 nums 大小相同的陣列 cache,用來存儲臨時結果。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-2-quick-select.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-2-quick-select.mdx index fa401029..f3e18bbe 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-2-quick-select.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-2-quick-select.mdx @@ -8,11 +8,11 @@ sidebar_position: 18 ### 題目描述 -在一個未排序的數組中,找到第 $k$ 大的數字。 +在一個未排序的陣列中,找到第 $k$ 大的數字。 ### 輸入輸出範例 -輸入一個數組和一個目標值 $k$,輸出第 $k$ 大的數字。題目保證一定有解。 +輸入一個陣列和一個目標值 $k$,輸出第 $k$ 大的數字。題目保證一定有解。 ``` Input: [3,2,1,5,6,4] and k = 2 @@ -21,7 +21,7 @@ Output: 5 ### 題解 -`快速選擇` 通常用於解決 k-th Element 問題,可以在平均 $O(n)$ 時間複雜度和 $O(1)$ 空間複雜度下完成求解。快速選擇的實現與快速排序相似,但只需要找到第 $k$ 大的中樞(pivot),不需要對中樞左右再進行排序。與快速排序一樣,快速選擇一般需要先將數組打亂,否則最壞情況下的時間複雜度為 $O(n^2)$。 +`快速選擇` 通常用於解決 k-th Element 問題,可以在平均 $O(n)$ 時間複雜度和 $O(1)$ 空間複雜度下完成求解。快速選擇的實現與快速排序相似,但只需要找到第 $k$ 大的中樞(pivot),不需要對中樞左右再進行排序。與快速排序一樣,快速選擇一般需要先將陣列打亂,否則最壞情況下的時間複雜度為 $O(n^2)$。 如果直接使用上述快速排序的代碼運行,可能會在 LeetCode 平台上接近超時。我們可以使用空間換取時間,直接儲存比中樞值小和大的元素,盡量避免進行交換操作。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-3-bucket-sort.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-3-bucket-sort.mdx index a8e42c52..154eebd8 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-3-bucket-sort.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-3-bucket-sort.mdx @@ -8,11 +8,11 @@ sidebar_position: 19 ### 題目描述 -給定一個數組,求前 $k$ 個最常出現的數字。 +給定一個陣列,求前 $k$ 個最常出現的數字。 ### 輸入輸出範例 -輸入是一個數組和一個目標值 $k$。輸出是一個長度為 $k$ 的數組。 +輸入是一個陣列和一個目標值 $k$。輸出是一個長度為 $k$ 的陣列。 ``` Input: nums = [1,1,1,1,2,2,3,4], k = 2 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-2-depth-first-search.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-2-depth-first-search.mdx index 73ef96a8..b42ac1fd 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-2-depth-first-search.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-2-depth-first-search.mdx @@ -46,7 +46,7 @@ Output: 6 當然,我們也可以使用堆疊(stack)來實現深度優先搜索,但由於堆疊與遞歸的運作原理相同,而遞歸相對來說實現起來更為方便,因此在刷題時建議使用遞歸的寫法,這樣也有利於進行回溯(見下節)。不過在實際工程中,直接使用堆疊可能才是更好的選擇,原因有二:一是更容易理解,二是不容易出現遞歸堆疊溢出的情況。 -我們先展示使用堆疊的寫法。這裡我們使用了一個小技巧,對於四個方向的遍歷,可以創建一個數組 `[-1, 0, 1, 0, -1]`,每相鄰兩位即對應上下左右四個方向之一。當然,您也可以顯式地寫成 `[-1, 0]`、`[1, 0]`、`[0, 1]` 和 `[0, -1]`,以便於理解。 +我們先展示使用堆疊的寫法。這裡我們使用了一個小技巧,對於四個方向的遍歷,可以創建一個陣列 `[-1, 0, 1, 0, -1]`,每相鄰兩位即對應上下左右四個方向之一。當然,您也可以顯式地寫成 `[-1, 0]`、`[1, 0]`、`[0, 1]` 和 `[0, -1]`,以便於理解。 @@ -182,7 +182,7 @@ def maxAreaOfIsland(grid: List[List[int]]) -> int: ### 輸入輸出範例 -輸入是一個二維數組,輸出是一個整數,表示城市圈數量。因為城市相鄰關係具有對稱性,該二維數組為對稱矩陣。同時,因為自己也處於自己的城市圈,對角線上的值全部為 1。 +輸入是一個二維陣列,輸出是一個整數,表示城市圈數量。因為城市相鄰關係具有對稱性,該二維陣列為對稱矩陣。同時,因為自己也處於自己的城市圈,對角線上的值全部為 1。 ``` Input: @@ -269,7 +269,7 @@ def findCircleNum(isConnected: List[List[int]]) -> int: ### 輸入輸出範例 -輸入是一個二維的非負整數矩陣,表示海拔高度。輸出是一個二維的數組,其中第二維大小固定為 2,表示滿足條件的位置坐標。 +輸入是一個二維的非負整數矩陣,表示海拔高度。輸出是一個二維的陣列,其中第二維大小固定為 2,表示滿足條件的位置坐標。 ``` Input: diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-3-backtracking.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-3-backtracking.mdx index 112e331e..29314786 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-3-backtracking.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-3-backtracking.mdx @@ -17,7 +17,7 @@ sidebar_position: 23 ### 題目描述 -給定一個無重複數字的整數數組,求其所有排列方式。 +給定一個無重複數字的整數陣列,求其所有排列方式。 ### 輸入輸出範例 @@ -32,7 +32,7 @@ Output: [[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,2,1], [3,1,2]] ### 題解 -如何生成所有排列方式呢?對於每個位置 \(i\),我們可以將其與之後的任意位置交換,然後處理位置 \(i+1\),直到處理到最後一位。為了避免每次遍歷時新建一個數組存儲前 \(i\) 個已交換好的數字,我們可以利用回溯法,僅修改原數組,並在遞迴完成後復原。 +如何生成所有排列方式呢?對於每個位置 \(i\),我們可以將其與之後的任意位置交換,然後處理位置 \(i+1\),直到處理到最後一位。為了避免每次遍歷時新建一個陣列存儲前 \(i\) 個已交換好的數字,我們可以利用回溯法,僅修改原陣列,並在遞迴完成後復原。 以樣例 `[1,2,3]` 為例,按照此方法,我們的輸出順序為:`[[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,2,1], [3,1,2]]`,確保涵蓋所有排列。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-2-basic-dp-1d.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-2-basic-dp-1d.mdx index 010aaa5c..e72e030f 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-2-basic-dp-1d.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-2-basic-dp-1d.mdx @@ -26,11 +26,11 @@ Output: 3 ### 題解 -這是一道經典的費波那契數列題目。定義一個數組 `dp`,其中 `dp[i]` 表示到達第 $i$ 階的方法數。由於每次可以走一步或兩步,所以第 $i$ 階可以從第 $(i-1)$ 階或第 $(i-2)$ 階到達。換句話說,到達第 $i$ 階的方法數是到達第 $(i-1)$ 階的方法數加上到達第 $(i-2)$ 階的方法數。因此我們得到了狀態轉移方程:`dp[i] = dp[i-1] + dp[i-2]`。注意初始條件的處理。 +這是一道經典的費波那契數列題目。定義一個陣列 `dp`,其中 `dp[i]` 表示到達第 $i$ 階的方法數。由於每次可以走一步或兩步,所以第 $i$ 階可以從第 $(i-1)$ 階或第 $(i-2)$ 階到達。換句話說,到達第 $i$ 階的方法數是到達第 $(i-1)$ 階的方法數加上到達第 $(i-2)$ 階的方法數。因此我們得到了狀態轉移方程:`dp[i] = dp[i-1] + dp[i-2]`。注意初始條件的處理。 :::warning -為了方便處理邊界情況,我們可以在構造 `dp` 數組時多留一個位置,用於表示初始狀態。本題即額外留了一個第 0 階的初始位置。 +為了方便處理邊界情況,我們可以在構造 `dp` 陣列時多留一個位置,用於表示初始狀態。本題即額外留了一個第 0 階的初始位置。 ::: @@ -106,7 +106,7 @@ def climbStairs(n: int) -> int: ### 輸入輸出範例 -輸入是一個一維數組,表示每個房子的財物數量;輸出是劫匪可以最多搶劫的財物數量。 +輸入是一個一維陣列,表示每個房子的財物數量;輸出是劫匪可以最多搶劫的財物數量。 ``` Input: [2,7,9,3,1] @@ -117,7 +117,7 @@ Output: 12 ### 題解 -定義一個數組 `dp`,其中 `dp[i]` 表示搶劫到第 `i` 個房子時,可以搶劫的最大金額。我們考慮 `dp[i]` 的值,此時可以搶劫的最大金額有兩種可能: +定義一個陣列 `dp`,其中 `dp[i]` 表示搶劫到第 `i` 個房子時,可以搶劫的最大金額。我們考慮 `dp[i]` 的值,此時可以搶劫的最大金額有兩種可能: 1. **選擇不搶劫這個房子**:此時累計的金額為 `dp[i-1]`; 2. **選擇搶劫這個房子**:那麼此前累計的最大金額只能是 `dp[i-2]`,因為我們無法搶劫第 `i-1` 個房子,否則會觸發警報。 @@ -198,11 +198,11 @@ def rob(nums: List[int]) -> int: ### 題目描述 -給定一個數組,求這個數組中連續且等差的子數組一共有多少個。 +給定一個陣列,求這個陣列中連續且等差的子陣列一共有多少個。 ### 輸入輸出範例 -輸入是一維數組,輸出是滿足等差條件的連續子數組個數。 +輸入是一維陣列,輸出是滿足等差條件的連續子陣列個數。 ``` Input: nums = [1,2,3,4] @@ -213,7 +213,7 @@ Output: 3 ### 題解 -因為要求是等差數列,可以很自然地想到子數組必定滿足 `num[i] - num[i-1] = num[i-1] - num[i-2]`。這裡我們對於 `dp` 陣列的定義是以 `i` 結尾,且滿足該條件的子數組數量。因為等差子數組可以在任意一個位置終結,所以我們需要對 `dp` 陣列求和以進行子數組統計。 +因為要求是等差數列,可以很自然地想到子陣列必定滿足 `num[i] - num[i-1] = num[i-1] - num[i-2]`。這裡我們對於 `dp` 陣列的定義是以 `i` 結尾,且滿足該條件的子陣列數量。因為等差子陣列可以在任意一個位置終結,所以我們需要對 `dp` 陣列求和以進行子陣列統計。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-3-basic-dp-2d.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-3-basic-dp-2d.mdx index e65a13c7..beefab02 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-3-basic-dp-2d.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-3-basic-dp-2d.mdx @@ -12,7 +12,7 @@ sidebar_position: 28 ### 輸入輸出範例 -輸入是二維數組,輸出是最優路徑的數字和。 +輸入是二維陣列,輸出是最優路徑的數字和。 ``` Input: @@ -26,11 +26,11 @@ Output: 7 ### 題解 -我們可以定義一個同樣是二維的 `dp` 陣列,其中 `dp[i][j]` 表示從左上角開始到 `(i, j)` 位置的最優路徑的數字和。因為每次只能向下或者向右移動,我們可以很直觀地得到狀態轉移方程 `dp[i][j] = grid[i][j] + min(dp[i-1][j], dp[i][j-1])`,其中 `grid` 表示原數組。 +我們可以定義一個同樣是二維的 `dp` 陣列,其中 `dp[i][j]` 表示從左上角開始到 `(i, j)` 位置的最優路徑的數字和。因為每次只能向下或者向右移動,我們可以很直觀地得到狀態轉移方程 `dp[i][j] = grid[i][j] + min(dp[i-1][j], dp[i][j-1])`,其中 `grid` 表示原陣列。 :::warning -在 Python 中,多維數組的初始化比較特殊,直接初始化為 `[[val] * n] * m` 會導致只是創造了 `m` 個 `[[val] * n]` 的引用。正確的初始化方法為 `[[val for _ in range(n)] for _ in range(m)]`。 +在 Python 中,多維陣列的初始化比較特殊,直接初始化為 `[[val] * n] * m` 會導致只是創造了 `m` 個 `[[val] * n]` 的引用。正確的初始化方法為 `[[val for _ in range(n)] for _ in range(m)]`。 ::: diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-6-knapsack-problem.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-6-knapsack-problem.mdx index 5197c4e5..ec02f125 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-6-knapsack-problem.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-6-knapsack-problem.mdx @@ -189,11 +189,11 @@ def knapsack(weights: List[int], values: List[int], n: int, w: int) -> int: ### 題目描述 -給定一個正整數數組,求是否可以把這個數組分成和相等的兩部分。 +給定一個正整數陣列,求是否可以把這個陣列分成和相等的兩部分。 ### 輸入輸出範例 -輸入是一個一維正整數數組,輸出是一個布林值,表示是否可以滿足題目要求。 +輸入是一個一維正整數陣列,輸出是一個布林值,表示是否可以滿足題目要求。 ``` Input: [1,5,11,5] diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-7-string-editing.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-7-string-editing.mdx index d23f2bcd..2889a682 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-7-string-editing.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-7-string-editing.mdx @@ -23,7 +23,7 @@ Output: 3 ### 題解 -類似於題目 1143,我們使用一個二維數組 `dp[i][j]`,表示將第一個字符串到位置 `i` 為止,和第二個字符串到位置 `j` 為止,最多需要幾步編輯。 +類似於題目 1143,我們使用一個二維陣列 `dp[i][j]`,表示將第一個字符串到位置 `i` 為止,和第二個字符串到位置 `j` 為止,最多需要幾步編輯。 - 當第 `i` 位和第 `j` 位對應的字符相同時,`dp[i][j] = dp[i-1][j-1]`; - 當兩者對應的字符不相同時: @@ -96,7 +96,7 @@ Output: 3 ### 題解 -不同於以往通過加減實現的動態規劃,這裡需要乘除法來計算位置,因為粘貼操作是倍數增加的。我們使用一個一維數組 dp,其中位置 i 表示延展到長度 i 的最少操作次數。對於每個位置 j,如果 j 可以被 i 整除,那麼長度 i 就可以由長度 j 操作得到,其操作次數等價於把一個長度為 j 的 A 延展到長度為 i/j。因此我們可以得到遞推公式 dp[i] = dp[j] + dp[i/j]。 +不同於以往通過加減實現的動態規劃,這裡需要乘除法來計算位置,因為粘貼操作是倍數增加的。我們使用一個一維陣列 dp,其中位置 i 表示延展到長度 i 的最少操作次數。對於每個位置 j,如果 j 可以被 i 整除,那麼長度 i 就可以由長度 j 操作得到,其操作次數等價於把一個長度為 j 的 A 延展到長度為 i/j。因此我們可以得到遞推公式 dp[i] = dp[j] + dp[i/j]。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-8-stock-trading.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-8-stock-trading.mdx index 4ea4a8e7..d02e1f32 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-8-stock-trading.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-8-stock-trading.mdx @@ -14,7 +14,7 @@ sidebar_position: 33 ### 輸入輸出範例 -輸入一個一維整數數組,表示每天的股票價格;輸出一個整數,表示最大的收益。 +輸入一個一維整數陣列,表示每天的股票價格;輸出一個整數,表示最大的收益。 ``` Input: [7,1,5,3,6,4] @@ -25,7 +25,7 @@ Output: 5 ### 題解 -我們可以遍歷一遍數組,在每一個位置 i 時,記錄 i 位置之前所有價格中的最低價格,然後將當前的價格作為賣出價格,查看當前收益是否為最大收益即可。注意本題中以及之後題目中的 buy 和 sell 表示買賣操作時,用戶賬戶的收益。因此買時為負,賣時為正。 +我們可以遍歷一遍陣列,在每一個位置 i 時,記錄 i 位置之前所有價格中的最低價格,然後將當前的價格作為賣出價格,查看當前收益是否為最大收益即可。注意本題中以及之後題目中的 buy 和 sell 表示買賣操作時,用戶賬戶的收益。因此買時為負,賣時為正。 @@ -65,7 +65,7 @@ def maxProfit(prices: List[int]) -> int: ### 輸入輸出範例 -輸入一個一維整數數組,表示每天的股票價格;以及一個整數,表示可以買賣的次數 $k$。輸出一個整數,表示最大的收益。 +輸入一個一維整數陣列,表示每天的股票價格;以及一個整數,表示可以買賣的次數 $k$。輸出一個整數,表示最大的收益。 ``` Input: [3,2,6,5,0,3], k = 2 @@ -76,7 +76,7 @@ Output: 7 ### 題解 -類似地,我們可以建立兩個動態規劃數組 `buy` 和 `sell`,對於每天的股票價格,`buy[j]` 表示在第 $j$ 次買入時的最大收益,`sell[j]` 表示在第 $j$ 次賣出時的最大收益。 +類似地,我們可以建立兩個動態規劃陣列 `buy` 和 `sell`,對於每天的股票價格,`buy[j]` 表示在第 $j$ 次買入時的最大收益,`sell[j]` 表示在第 $j$ 次賣出時的最大收益。 @@ -122,7 +122,7 @@ def maxProfit(k: int, prices: List[int]) -> int: ### 輸入輸出範例 -輸入一個一維整數數組,表示每天的股票價格;輸出一個整數,表示最大的收益。 +輸入一個一維整數陣列,表示每天的股票價格;輸出一個整數,表示最大的收益。 ``` Input: [1,2,3,0,2] diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-9-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-9-exercises.md index 6372250f..f4336fd1 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-9-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-9-exercises.md @@ -8,7 +8,7 @@ sidebar_position: 34 ### [213. House Robber II](https://leetcode.com/problems/house-robber-ii/) -強盜搶劫問題的 follow-up,如何處理環形數組呢? +強盜搶劫問題的 follow-up,如何處理環形陣列呢? ### [53. Maximum Subarray](https://leetcode.com/problems/maximum-subarray/) diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-1-algorithm-explanation.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-1-algorithm-explanation.md index 222b79a9..da404df1 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-1-algorithm-explanation.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-1-algorithm-explanation.md @@ -4,9 +4,9 @@ sidebar_position: 35 # 7.1 算法解释 -顧名思義,`分治問題`由“分”(divide)和“治”(conquer)兩部分組成,通過把原問題分為子問題,再將子問題進行處理合併,從而實現對原問題的求解。我們在排序章節展示的合併排序就是典型的分治問題,其中“分”即為把大數組平均分成兩個小數組,通過遞迴實現,最終我們會得到多個長度為 1 的子數組;“治”即為把已經排好序的兩個小數組合併為一個排好序的大數組,從長度為 1 的子數組開始,最終合成一個大數組。 +顧名思義,`分治問題`由“分”(divide)和“治”(conquer)兩部分組成,通過把原問題分為子問題,再將子問題進行處理合併,從而實現對原問題的求解。我們在排序章節展示的合併排序就是典型的分治問題,其中“分”即為把大陣列平均分成兩個小陣列,通過遞迴實現,最終我們會得到多個長度為 1 的子陣列;“治”即為把已經排好序的兩個小陣列合併為一個排好序的大陣列,從長度為 1 的子陣列開始,最終合成一個大陣列。 -我們也使用數學表達式來表示這個過程。定義 $T(n)$ 表示處理一個長度為 $n$ 的數組的時間複雜度,則合併排序的時間複雜度遞推公式為 $T(n) = 2T(n/2) + O(n)$。其中 $2T(n/2)$ 表示我們分成了兩個長度減半的子問題,$O(n)$ 則為合併兩個長度為 $n/2$ 數組的時間複雜度。 +我們也使用數學表達式來表示這個過程。定義 $T(n)$ 表示處理一個長度為 $n$ 的陣列的時間複雜度,則合併排序的時間複雜度遞推公式為 $T(n) = 2T(n/2) + O(n)$。其中 $2T(n/2)$ 表示我們分成了兩個長度減半的子問題,$O(n)$ 則為合併兩個長度為 $n/2$ 陣列的時間複雜度。 :::info 定理 7.1. 主定理 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-2-expression-problems.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-2-expression-problems.mdx index 6b67e6cf..2888cc56 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-2-expression-problems.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-2-expression-problems.mdx @@ -12,7 +12,7 @@ sidebar_position: 36 ### 輸入輸出範例 -輸入是一個字符串,表示數學表達式;輸出是一個數組,儲存所有不同的加括號結果。 +輸入是一個字符串,表示數學表達式;輸出是一個陣列,儲存所有不同的加括號結果。 ``` Input: "2-1-1" diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-5-random-sampling.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-5-random-sampling.mdx index b5cb11af..7521bd45 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-5-random-sampling.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-5-random-sampling.mdx @@ -8,11 +8,11 @@ sidebar_position: 42 ### 題目描述 -給定一個數組,要求實現兩個指令函數。第一個函數「shuffle」可以隨機打亂這個數組,第二個函數「reset」可以恢復原來的順序。 +給定一個陣列,要求實現兩個指令函數。第一個函數「shuffle」可以隨機打亂這個陣列,第二個函數「reset」可以恢復原來的順序。 ### 輸入輸出範例 -輸入是一個存有整數數字的數組,以及一個包含指令函數名稱的數組。輸出是一個二維數組,表示每個指令生成的數組。 +輸入是一個存有整數數字的陣列,以及一個包含指令函數名稱的陣列。輸出是一個二維陣列,表示每個指令生成的陣列。 ``` Input: nums = [1,2,3], actions: ["shuffle","shuffle","reset"] @@ -90,11 +90,11 @@ class Solution: ### 題目描述 -給定一個數組,數組每個位置的值表示該位置的權重,要求按照權重的概率去隨機抽樣。 +給定一個陣列,陣列每個位置的值表示該位置的權重,要求按照權重的概率去隨機抽樣。 ### 輸入輸出範例 -輸入是一維正整數數組,表示權重;以及一個包含指令字串的一維數組,表示運行幾次隨機抽樣。輸出是一維整數數組,表示隨機抽樣的整數在數組中的位置。 +輸入是一維正整數陣列,表示權重;以及一個包含指令字串的一維陣列,表示運行幾次隨機抽樣。輸出是一維整數陣列,表示隨機抽樣的整數在陣列中的位置。 ``` Input: weights = [1,3], actions: ["pickIndex","pickIndex","pickIndex"] @@ -105,9 +105,9 @@ Output: [0,1,1] ### 題解 -我們可以先使用前綴和(partial_sum)計算到每個位置為止之前所有數字的總和,這個結果對於正整數數組是單調遞增的。每當需要抽樣時,我們可以先隨機生成一個數字,然後使用二分法查找該數字在前綴和中的位置,以模擬加權抽樣的過程。這裡的二分法可以用 lower_bound 實現。 +我們可以先使用前綴和(partial_sum)計算到每個位置為止之前所有數字的總和,這個結果對於正整數陣列是單調遞增的。每當需要抽樣時,我們可以先隨機生成一個數字,然後使用二分法查找該數字在前綴和中的位置,以模擬加權抽樣的過程。這裡的二分法可以用 lower_bound 實現。 -以範例為例,權重數組 [1,3] 的前綴和為 [1,4]。如果我們隨機生成的數字為 1,那麼 lower_bound 返回的位置為 0;如果我們隨機生成的數字是 2、3、4,那麼 lower_bound 返回的位置為 1。 +以範例為例,權重陣列 [1,3] 的前綴和為 [1,4]。如果我們隨機生成的數字為 1,那麼 lower_bound 返回的位置為 0;如果我們隨機生成的數字是 2、3、4,那麼 lower_bound 返回的位置為 1。 關於前綴和的更多技巧,我們將在接下來的章節中繼續深入講解。 @@ -170,7 +170,7 @@ Output: 3 ### 題解 -不同於數組,在未遍歷完鏈表前,我們無法知道鏈表的總長度。這裡我們可以使用水庫抽樣:遍歷一次鏈表,在遍歷到第 $m$ 個節點時,有 $\frac{1}{m}$ 的概率選擇這個節點覆蓋掉之前的選擇。 +不同於陣列,在未遍歷完鏈表前,我們無法知道鏈表的總長度。這裡我們可以使用水庫抽樣:遍歷一次鏈表,在遍歷到第 $m$ 個節點時,有 $\frac{1}{m}$ 的概率選擇這個節點覆蓋掉之前的選擇。 我們提供一個簡單的,對於水庫算法隨機性的證明。對於長度為 $n$ 的鏈表的第 $m$ 個節點,最後被抽樣的充要條件是它被選擇,且之後的節點都沒有被選擇。這種情況發生的概率為: @@ -180,7 +180,7 @@ $$ 因此每個點都有均等的概率被選擇。 -當然,這道題我們也可以預處理鏈表,遍歷一遍之後把它轉化成數組。 +當然,這道題我們也可以預處理鏈表,遍歷一遍之後把它轉化成陣列。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-2-basic-bitwise-problems.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-2-basic-bitwise-problems.mdx index 8d53957d..00c82e9d 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-2-basic-bitwise-problems.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-2-basic-bitwise-problems.mdx @@ -111,11 +111,11 @@ def reverseBits(n: int) -> int: ### 題目描述 -給定一個整數數組,這個數組裡只有一個數字只出現了一次,其餘數字出現了兩次,求這個只出現一次的數字。 +給定一個整數陣列,這個陣列裡只有一個數字只出現了一次,其餘數字出現了兩次,求這個只出現一次的數字。 ### 輸入輸出範例 -輸入是一個一維整數數組,輸出是該數組內的一個整數。 +輸入是一個一維整數陣列,輸出是該陣列內的一個整數。 ``` Input: [4,1,2,1,2] @@ -124,7 +124,7 @@ Output: 4 ### 題解 -我們可以利用 x ∧ x = 0 和 x ∧ 0 = x 的特點,將數組內所有的數字進行按位異或。出現兩次的所有數字按位異或的結果是 0,0 與出現一次的數字異或可以得到這個數字本身。 +我們可以利用 x ∧ x = 0 和 x ∧ 0 = x 的特點,將陣列內所有的數字進行按位異或。出現兩次的所有數字按位異或的結果是 0,0 與出現一次的數字異或可以得到這個數字本身。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-3-binary-properties.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-3-binary-properties.mdx index 043c754e..8f5e697a 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-3-binary-properties.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-3-binary-properties.mdx @@ -6,7 +6,7 @@ sidebar_position: 46 利用二進制的一些特性,我們可以把位運算使用到更多問題上。 -例如,我們可以利用二進制和位運算輸出一個數組的所有子集。假設我們有一個長度為 $n$ 的數組,我們可以生成長度為 $n$ 的所有二進制,1 表示選取該數字,0 表示不選取。這樣我們就獲得了 $2^n$ 個子集。 +例如,我們可以利用二進制和位運算輸出一個陣列的所有子集。假設我們有一個長度為 $n$ 的陣列,我們可以生成長度為 $n$ 的所有二進制,1 表示選取該數字,0 表示不選取。這樣我們就獲得了 $2^n$ 個子集。 ## [318. Maximum Product of Word Lengths](https://leetcode.com/problems/maximum-product-of-word-lengths/) @@ -16,7 +16,7 @@ sidebar_position: 46 ### 輸入輸出範例 -輸入一個包含多個字母串的一維數組,輸出一個整數,表示長度乘積的最大值。 +輸入一個包含多個字母串的一維陣列,輸出一個整數,表示長度乘積的最大值。 ``` Input: ["a","ab","abc","d","cd","bcd","abcd"] @@ -82,7 +82,7 @@ def maxProduct(words: List[str]) -> int: ### 輸入輸出範例 -輸入是一個非負整數 n,輸出是一個長度為 n + 1 的非負整數數組,每個位置 m 表示 m 的二進制中有多少個 1。 +輸入是一個非負整數 n,輸出是一個長度為 n + 1 的非負整數陣列,每個位置 m 表示 m 的二進制中有多少個 1。 ``` Input: 5 @@ -91,7 +91,7 @@ Output: [0,1,1,2,1,2] ### 題解 -本題可以利用動態規劃和位運算進行快速求解。定義一個數組 dp,其中 dp[i] 表示數字 i 的二進制中含有 1 的個數。對於第 i 個數字: +本題可以利用動態規劃和位運算進行快速求解。定義一個陣列 dp,其中 dp[i] 表示數字 i 的二進制中含有 1 的個數。對於第 i 個數字: - 如果它二進制的最後一位為 1,那麼它含有 1 的個數為 dp[i-1] + 1; - 如果它二進制的最後一位為 0,那麼它含有 1 的個數和其算術右移結果相同,即 dp[i>>1]。 From d7e04373349e42d2facdc86ab1efa7debee57702 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Tue, 26 Nov 2024 21:14:34 +0100 Subject: [PATCH 28/49] add separators --- .../docs/1-greedy-algorithms/1-4-exercises.md | 11 ++++++ .../10-data-structures/10-11-exercises.md | 20 +++++++++++ .../11-string-manipulation/11-5-exercises.md | 5 +++ .../docs/12-linked-lists/12-4-exercises.md | 6 ++++ leetcode_101/docs/13-trees/13-7-exercises.md | 34 +++++++++++++++++++ leetcode_101/docs/14-graphs/14-4-exercises.md | 4 +++ .../15-4-exercises.md | 4 +++ .../2-two-pointer-techniques/2-6-exercises.md | 6 ++++ .../3-6-exercises.md | 4 +++ .../4-sorting-algorithms/4-4-exercises.md | 2 ++ .../5-searching-algorithms/5-5-exercises.md | 10 ++++++ .../6-dynamic-programming/6-9-exercises.md | 17 ++++++++++ .../7-divide-and-conquer/7-3-exercises.md | 2 ++ .../8-mathematical-solutions/8-6-exercises.md | 12 +++++++ .../9-bitwise-operations/9-4-exercises.md | 6 ++++ .../1-greedy-algorithms/1-4-exercises.md | 9 ++++- .../10-data-structures/10-11-exercises.md | 4 +-- .../11-string-manipulation/11-5-exercises.md | 5 +++ .../current/12-linked-lists/12-4-exercises.md | 6 ++++ .../current/13-trees/13-7-exercises.md | 34 +++++++++++++++++++ .../current/14-graphs/14-4-exercises.md | 6 ++++ .../15-4-exercises.md | 6 ++++ .../2-two-pointer-techniques/2-6-exercises.md | 6 ++++ .../3-6-exercises.md | 4 +++ .../4-sorting-algorithms/4-4-exercises.md | 2 ++ .../5-searching-algorithms/5-5-exercises.md | 10 ++++++ .../6-dynamic-programming/6-9-exercises.md | 16 +++++++++ .../7-divide-and-conquer/7-3-exercises.md | 2 ++ .../8-mathematical-solutions/8-6-exercises.md | 12 +++++++ .../9-bitwise-operations/9-4-exercises.md | 6 ++++ .../current.json | 8 ++--- .../1-greedy-algorithms/1-4-exercises.md | 9 +++++ .../11-string-manipulation/11-5-exercises.md | 5 +++ .../current/12-linked-lists/12-4-exercises.md | 6 ++++ .../current/13-trees/13-7-exercises.md | 34 +++++++++++++++++++ .../current/14-graphs/14-4-exercises.md | 4 +++ .../15-4-exercises.md | 4 +++ .../2-two-pointer-techniques/2-6-exercises.md | 6 ++++ .../2-two-pointer-techniques/_category_.json | 4 +-- .../3-6-exercises.md | 4 +++ .../4-sorting-algorithms/4-4-exercises.md | 2 ++ .../5-searching-algorithms/5-5-exercises.md | 10 ++++++ .../6-dynamic-programming/6-9-exercises.md | 16 +++++++++ .../7-divide-and-conquer/7-3-exercises.md | 2 ++ .../8-mathematical-solutions/8-6-exercises.md | 12 +++++++ .../9-bitwise-operations/9-4-exercises.md | 6 ++++ 46 files changed, 394 insertions(+), 9 deletions(-) diff --git a/leetcode_101/docs/1-greedy-algorithms/1-4-exercises.md b/leetcode_101/docs/1-greedy-algorithms/1-4-exercises.md index 5432be4e..3db0069d 100644 --- a/leetcode_101/docs/1-greedy-algorithms/1-4-exercises.md +++ b/leetcode_101/docs/1-greedy-algorithms/1-4-exercises.md @@ -10,10 +10,14 @@ sidebar_position: 4 采取什么样的贪心策略,可以种植最多的花朵呢? +--- + ### [452. Minimum Number of Arrows to Burst Balloons](https://leetcode.com/problems/minimum-number-of-arrows-to-burst-balloons/) 这道题和题目 435 十分类似,但是稍有不同,具体是哪里不同呢? +--- + ### [763. Partition Labels](https://leetcode.com/problems/partition-labels/) 为了满足你的贪心策略,是否需要一些预处理? @@ -24,17 +28,24 @@ sidebar_position: 4 ::: +--- + ### [122. Best Time to Buy and Sell Stock II](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/) 股票交易题型里比较简单的题目,在不限制交易次数的情况下,怎样可以获得最大利润呢? + + ## 进阶难度 + ### [406. Queue Reconstruction by Height](https://leetcode.com/problems/queue-reconstruction-by-height/) 温馨提示,这道题可能同时需要排序和插入操作。 +--- + ### [665. Non-decreasing Array](https://leetcode.com/problems/non-decreasing-array/) 需要仔细思考你的贪心策略在各种情况下,是否仍然是最优解。 \ No newline at end of file diff --git a/leetcode_101/docs/10-data-structures/10-11-exercises.md b/leetcode_101/docs/10-data-structures/10-11-exercises.md index 778cbf90..8ca0e841 100644 --- a/leetcode_101/docs/10-data-structures/10-11-exercises.md +++ b/leetcode_101/docs/10-data-structures/10-11-exercises.md @@ -10,44 +10,64 @@ sidebar_position: 58 没有什么难度,只是需要一点耐心。 +--- + ### [225. Implement Stack using Queues](https://leetcode.com/problems/implement-stack-using-queues/) 利用相似的方法,我们也可以用 queue 实现 stack。 +--- + ### [503. Next Greater Element II](https://leetcode.com/problems/next-greater-element-ii/) Daily Temperature 的变种题。 +--- + ### [217. Contains Duplicate](https://leetcode.com/problems/contains-duplicate/) 使用什么数据结构可以快速判断重复呢? +--- + ### [697. Degree of an Array](https://leetcode.com/problems/degree-of-an-array/) 如何对数组进行预处理才能正确并快速地计算子数组的长度? +--- + ### [594. Longest Harmonious Subsequence](https://leetcode.com/problems/longest-harmonious-subsequence/) 最长连续序列的变种题。 +--- + ### [15. 3Sum](https://leetcode.com/problems/3sum/) 因为排序的复杂度是 $O(n \log n) < O(n^2)$,因此我们既可以排序后再进行 $O(n^2)$ 的指针搜索,也可以直接利用哈希表进行 $O(n^2)$ 的搜索。 +--- + ## 进阶难度 ### [287. Find the Duplicate Number](https://leetcode.com/problems/find-the-duplicate-number/) 寻找丢失数字的变种题。除了标负位置,你还有没有其它算法可以解决这个问题? +--- + ### [313. Super Ugly Number](https://leetcode.com/problems/super-ugly-number/) 尝试使用优先队列解决这一问题。 +--- + ### [870. Advantage Shuffle](https://leetcode.com/problems/advantage-shuffle/) 如果我们需要比较大小关系,而且同一数字可能出现多次,那么应该用什么数据结构呢? +--- + ### [307. Range Sum Query - Mutable](https://leetcode.com/problems/range-sum-query-mutable/) 前缀和的变种题。好吧我承认,这道题可能有些超纲,你或许需要搜索一下什么是线段树。 \ No newline at end of file diff --git a/leetcode_101/docs/11-string-manipulation/11-5-exercises.md b/leetcode_101/docs/11-string-manipulation/11-5-exercises.md index 11abb1d5..92025cb3 100644 --- a/leetcode_101/docs/11-string-manipulation/11-5-exercises.md +++ b/leetcode_101/docs/11-string-manipulation/11-5-exercises.md @@ -10,10 +10,13 @@ sidebar_position: 63 计算一组字符可以构成的回文字符串的最大长度,可以利用其它数据结构进行辅助统计。 +--- + ### [3. Longest Substring Without Repeating Characters](https://leetcode.com/problems/longest-substring-without-repeating-characters/) 计算最长无重复子字符串,同样的,可以利用其它数据结构进行辅助统计。 +--- ## 进阶难度 @@ -21,6 +24,8 @@ sidebar_position: 63 题目 227 的 follow-up,十分推荐练习。 +--- + ### [5. Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/) 类似于我们讲过的子序列问题,子数组或子字符串问题常常也可以用动态规划来解决。先使用动态规划写出一个 $O(n^2)$ 时间复杂度的算法,再搜索一下 Manacher’s Algorithm,它可以在 $O(n)$ 时间解决这一问题。 \ No newline at end of file diff --git a/leetcode_101/docs/12-linked-lists/12-4-exercises.md b/leetcode_101/docs/12-linked-lists/12-4-exercises.md index f015e8e4..c5f3b2db 100644 --- a/leetcode_101/docs/12-linked-lists/12-4-exercises.md +++ b/leetcode_101/docs/12-linked-lists/12-4-exercises.md @@ -10,14 +10,20 @@ sidebar_position: 67 虽然 LeetCode 没有强制要求,但是我们仍然建议你回收内存,尤其当题目要求你删除的时候。 +--- + ### [328. Odd Even Linked List](https://leetcode.com/problems/odd-even-linked-list/) 这道题其实很简单,千万不要把题目复杂化。 +--- + ### [19. Remove Nth Node From End of List](https://leetcode.com/problems/remove-nth-node-from-end-of-list/) 既然我们可以使用快慢指针找到中点,也可以利用类似的方法找到倒数第 n 个节点,无需遍历第二遍。 +--- + ## 进阶难度 ### [148. Sort List](https://leetcode.com/problems/sort-list/) diff --git a/leetcode_101/docs/13-trees/13-7-exercises.md b/leetcode_101/docs/13-trees/13-7-exercises.md index 1b672f7b..d002c2c0 100644 --- a/leetcode_101/docs/13-trees/13-7-exercises.md +++ b/leetcode_101/docs/13-trees/13-7-exercises.md @@ -10,72 +10,106 @@ sidebar_position: 74 巧用递归,你可以在五行内完成这道题。 +--- + ### [617. Merge Two Binary Trees](https://leetcode.com/problems/merge-two-binary-trees/) 同样的,利用递归可以轻松搞定。 +--- + ### [572. Subtree of Another Tree](https://leetcode.com/problems/subtree-of-another-tree/) 子树是对称树的姊妹题,写法也十分类似。 +--- + ### [404. Sum of Left Leaves](https://leetcode.com/problems/sum-of-left-leaves/) 怎么判断一个节点是不是左节点呢?一种可行的方法是,在辅函数里多传一个参数,表示当前节点是不是父节点的左节点。 +--- + ### [513. Find Bottom Left Tree Value](https://leetcode.com/problems/find-bottom-left-tree-value/) 最左下角的节点满足什么条件?针对这种条件,我们该如何找到它? +--- + ### [538. Convert BST to Greater Tree](https://leetcode.com/problems/convert-bst-to-greater-tree/) 尝试利用某种遍历方式来解决此题,每个节点只需遍历一次。 +--- + ### [235. Lowest Common Ancestor of a Binary Search Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/) 利用 BST 的独特性质,这道题可以很轻松完成。 +--- + ### [530. Minimum Absolute Difference in BST](https://leetcode.com/problems/minimum-absolute-difference-in-bst/) 还记得我们所说的,对于 BST 应该利用哪种遍历吗? +--- + ## 进阶难度 ### [1530. Number of Good Leaf Nodes Pairs](https://leetcode.com/problems/number-of-good-leaf-nodes-pairs/) 题目 543 的变种题,注意在辅函数中,每次更新的全局变量是左右两边距离之和满足条件的数量,而返回的是左右两边所有(长度不溢出的)子节点的高度 +1。 +--- + ### [889. Construct Binary Tree from Preorder and Postorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-postorder-traversal/) 给定任意两种遍历结果,我们都可以重建树的结构。 +--- + ### [106. Construct Binary Tree from Inorder and Postorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/) 给定任意两种遍历结果,我们都可以重建树的结构。 +--- + ### [94. Binary Tree Inorder Traversal](https://leetcode.com/problems/binary-tree-inorder-traversal/) 因为前中序后遍历是用递归实现的,而递归的底层实现是栈操作,因此我们总能用栈实现。 +--- + ### [145. Binary Tree Postorder Traversal](https://leetcode.com/problems/binary-tree-postorder-traversal/) 因为前中序后遍历是用递归实现的,而递归的底层实现是栈操作,因此我们总能用栈实现。 +--- + ### [236. Lowest Common Ancestor of a Binary Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/) 现在不是 BST,而是普通的二叉树了,该怎么办? +--- + ### [109. Convert Sorted List to Binary Search Tree](https://leetcode.com/problems/convert-sorted-list-to-binary-search-tree/) 把排好序的链表变成 BST。为了使得 BST 尽量平衡,我们需要寻找链表的中点。 +--- + ### [897. Increasing Order Search Tree](https://leetcode.com/problems/increasing-order-search-tree/) 把 BST 压成一个链表,务必考虑清楚指针操作的顺序,否则可能会出现环路。 +--- + ### [653. Two Sum IV - Input is a BST](https://leetcode.com/problems/two-sum-iv-input-is-a-bst/) 啊哈,这道题可能会把你骗到。 +--- + ### [450. Delete Node in a BST](https://leetcode.com/problems/delete-node-in-a-bst/) 当寻找到待删节点时,你可以分情况考虑——当前节点是叶节点、只有一个子节点和有两个子节点。建议同时回收内存。 \ No newline at end of file diff --git a/leetcode_101/docs/14-graphs/14-4-exercises.md b/leetcode_101/docs/14-graphs/14-4-exercises.md index 83809992..88b9166e 100644 --- a/leetcode_101/docs/14-graphs/14-4-exercises.md +++ b/leetcode_101/docs/14-graphs/14-4-exercises.md @@ -10,12 +10,16 @@ sidebar_position: 78 虽然使用深度优先搜索可以解决大部分的图遍历问题,但是注意判断是否陷入了环路。 +--- + ## 进阶难度 ### [1135. Connecting Cities With Minimum Cost](https://leetcode.com/problems/connecting-cities-with-minimum-cost/) 笔者其实已经把这道题的题解写好了,才发现这道题是需要解锁才可以看的题目。为了避免版权纠纷,故将其移至练习题内。本题考察最小生成树(minimum spanning tree, MST)的求法,通常可以用两种方式求得:Prim’s Algorithm,利用优先队列选择最小的消耗;以及 Kruskal’s Algorithm,排序后使用并查集。 +--- + ### [882. Reachable Nodes In Subdivided Graph](https://leetcode.com/problems/reachable-nodes-in-subdivided-graph/) 这道题笔者考虑了很久,最终决定把它放在练习题而非详细讲解。本题是经典的节点最短距离问题,常用的算法有 Bellman-Ford 单源最短路算法,以及 Dijkstra 无负边单源最短路算法。虽然经典,但是 LeetCode 很少有相关的题型,因此这里仅供读者自行深入学习。 \ No newline at end of file diff --git a/leetcode_101/docs/15-advanced-data-structures/15-4-exercises.md b/leetcode_101/docs/15-advanced-data-structures/15-4-exercises.md index 71084880..9f48dbb4 100644 --- a/leetcode_101/docs/15-advanced-data-structures/15-4-exercises.md +++ b/leetcode_101/docs/15-advanced-data-structures/15-4-exercises.md @@ -10,12 +10,16 @@ sidebar_position: 78 使用并查集,按照 Kruskal’s Algorithm 把这道题再解决一次吧。 +--- + ## 进阶难度 ### [432. All O`one Data Structure](https://leetcode.com/problems/all-oone-data-structure/) 设计一个 increaseKey,decreaseKey,getMaxKey,getMinKey 均为 O(1) 时间复杂度的数据结构。 +--- + ### [716. Max Stack](https://leetcode.com/problems/max-stack/) 设计一个支持 push,pop,top,getMax 和 popMax 的 stack。可以用类似 LRU 的方法降低时间复杂度,但是因为想要获得的是最大值,我们应该把 unordered_map 换成哪一种数据结构呢? \ No newline at end of file diff --git a/leetcode_101/docs/2-two-pointer-techniques/2-6-exercises.md b/leetcode_101/docs/2-two-pointer-techniques/2-6-exercises.md index 00003ee8..e97b5cf4 100644 --- a/leetcode_101/docs/2-two-pointer-techniques/2-6-exercises.md +++ b/leetcode_101/docs/2-two-pointer-techniques/2-6-exercises.md @@ -10,14 +10,20 @@ sidebar_position: 10 Two Sum 题目的变形题之一。 +--- + ### [680. Valid Palindrome II](https://leetcode.com/problems/valid-palindrome-ii/) Two Sum 题目的变形题之二。 +--- + ### [524. Longest Word in Dictionary through Deleting](https://leetcode.com/problems/longest-word-in-dictionary-through-deleting/) 归并两个有序数组的变形题。 +--- + ## 进阶难度 ### [340. Longest Substring with At Most K Distinct Characters](https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/) diff --git a/leetcode_101/docs/3-binary-search-techniques/3-6-exercises.md b/leetcode_101/docs/3-binary-search-techniques/3-6-exercises.md index c44e816e..bba38092 100644 --- a/leetcode_101/docs/3-binary-search-techniques/3-6-exercises.md +++ b/leetcode_101/docs/3-binary-search-techniques/3-6-exercises.md @@ -10,10 +10,14 @@ sidebar_position: 16 旋转数组的变形题之一。 +--- + ### [540. Single Element in a Sorted Array](https://leetcode.com/problems/single-element-in-a-sorted-array/) 在出现独立数之前和之后,奇偶位数的值发生了什么变化? +--- + ## 进阶难度 ### [4. Median of Two Sorted Arrays](https://leetcode.com/problems/median-of-two-sorted-arrays/) diff --git a/leetcode_101/docs/4-sorting-algorithms/4-4-exercises.md b/leetcode_101/docs/4-sorting-algorithms/4-4-exercises.md index 5688eb44..321e6463 100644 --- a/leetcode_101/docs/4-sorting-algorithms/4-4-exercises.md +++ b/leetcode_101/docs/4-sorting-algorithms/4-4-exercises.md @@ -10,6 +10,8 @@ sidebar_position: 20 桶排序的变形题。 +--- + ## 进阶难度 ### [75. Sort Colors](https://leetcode.com/problems/sort-colors/) diff --git a/leetcode_101/docs/5-searching-algorithms/5-5-exercises.md b/leetcode_101/docs/5-searching-algorithms/5-5-exercises.md index 1922b36d..cfd5d3d7 100644 --- a/leetcode_101/docs/5-searching-algorithms/5-5-exercises.md +++ b/leetcode_101/docs/5-searching-algorithms/5-5-exercises.md @@ -10,24 +10,34 @@ sidebar_position: 25 先从最外侧填充,然后再考虑里侧。 +--- + ### [257. Binary Tree Paths](https://leetcode.com/problems/binary-tree-paths/) 输出二叉树中所有从根到叶子的路径,回溯法使用与否有什么区别? +--- + ## 进阶难度 ### [47. Permutations II](https://leetcode.com/problems/permutations-ii/) 排列题的 follow-up,如何处理重复元素? +--- + ### [40. Combination Sum II](https://leetcode.com/problems/combination-sum-ii/) 组合题的 follow-up,如何处理重复元素? +--- + ### [37. Sudoku Solver](https://leetcode.com/problems/sudoku-solver/) 十分经典的数独题,可以利用回溯法求解。事实上对于数独类型的题,有很多进阶的搜索方法和剪枝策略可以提高速度,如启发式搜索。 +--- + ### [310. Minimum Height Trees](https://leetcode.com/problems/minimum-height-trees/) 如何将这道题转为搜索类型题?是使用深度优先还是广度优先呢? \ No newline at end of file diff --git a/leetcode_101/docs/6-dynamic-programming/6-9-exercises.md b/leetcode_101/docs/6-dynamic-programming/6-9-exercises.md index edb73762..f02150aa 100644 --- a/leetcode_101/docs/6-dynamic-programming/6-9-exercises.md +++ b/leetcode_101/docs/6-dynamic-programming/6-9-exercises.md @@ -10,36 +10,53 @@ sidebar_position: 34 强盗抢劫题目的 follow-up,如何处理环形数组呢? +--- + ### [53. Maximum Subarray](https://leetcode.com/problems/maximum-subarray/) 经典的一维动态规划题目,试着把一维空间优化为常量吧。 +--- + ### [343. Integer Break](https://leetcode.com/problems/integer-break/) 分割类型题,先尝试用动态规划求解,再思考是否有更简单的解法。 +--- + ### [583. Delete Operation for Two Strings](https://leetcode.com/problems/delete-operation-for-two-strings/) 最长公共子序列的变种题。 +--- + ## 进阶难度 + ### [646. Maximum Length of Pair Chain](https://leetcode.com/problems/maximum-length-of-pair-chain/) 最长递增子序列的变种题,同样的,尝试用二分进行加速。 +--- + ### [10. Regular Expression Matching](https://leetcode.com/problems/regular-expression-matching/) 正则表达式匹配,非常考验耐心。需要根据正则表达式的不同情况,即字符、星号,点号等,分情况讨论。 +--- + ### [376. Wiggle Subsequence](https://leetcode.com/problems/wiggle-subsequence/) 最长摆动子序列,通项公式比较特殊,需要仔细思考。 +--- + ### [494. Target Sum](https://leetcode.com/problems/target-sum/) 如果告诉你这道题是 0-1 背包,你是否会有一些思路? +--- + ### [714. Best Time to Buy and Sell Stock with Transaction Fee](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/) 建立状态机,股票交易类问题就会迎刃而解。 \ No newline at end of file diff --git a/leetcode_101/docs/7-divide-and-conquer/7-3-exercises.md b/leetcode_101/docs/7-divide-and-conquer/7-3-exercises.md index a52cf92b..bc1968dd 100644 --- a/leetcode_101/docs/7-divide-and-conquer/7-3-exercises.md +++ b/leetcode_101/docs/7-divide-and-conquer/7-3-exercises.md @@ -10,6 +10,8 @@ sidebar_position: 37 试着用从上到下的分治(递归)写法求解,最好加上 memoization;再用从下到上的动态规划写法求解。 +--- + ## 进阶难度 ### [312. Burst Balloons](https://leetcode.com/problems/burst-balloons/) diff --git a/leetcode_101/docs/8-mathematical-solutions/8-6-exercises.md b/leetcode_101/docs/8-mathematical-solutions/8-6-exercises.md index 5d4495c3..f68091ae 100644 --- a/leetcode_101/docs/8-mathematical-solutions/8-6-exercises.md +++ b/leetcode_101/docs/8-mathematical-solutions/8-6-exercises.md @@ -10,28 +10,40 @@ sidebar_position: 43 7 进制转换的变种题,需要注意的一点是从 1 开始而不是 0。 +--- + ### [67. Add Binary](https://leetcode.com/problems/add-binary/) 字符串加法的变种题。 +--- + ### [238. Product of Array Except Self](https://leetcode.com/problems/product-of-array-except-self/) 你可以不使用除法做这道题吗?我们很早之前讲过的题目 135 或许能给你一些思路。 +--- + ## 进阶难度 ### [462. Minimum Moves to Equal Array Elements II](https://leetcode.com/problems/minimum-moves-to-equal-array-elements-ii/) 这道题是笔者最喜欢的 LeetCode 题目之一,需要先推理出怎么样移动是最优的,再考虑如何进行移动。你或许需要一些前些章节讲过的算法。 +--- + ### [169. Majority Element](https://leetcode.com/problems/majority-element/) 如果想不出简单的解决方法,搜索一下 Boyer-Moore Majority Vote 算法吧。 +--- + ### [470. Implement Rand10() Using Rand7()](https://leetcode.com/problems/implement-rand10-using-rand7/) 如何用一个随机数生成器生成另一个随机数生成器?你可能需要利用原来的生成器多次。 +--- + ### [202. Happy Number](https://leetcode.com/problems/happy-number/) 你可以简单的用一个 while 循环解决这道题,但是有没有更好的解决办法?如果我们把每个数字想象成一个节点,是否可以转化为环路检测? \ No newline at end of file diff --git a/leetcode_101/docs/9-bitwise-operations/9-4-exercises.md b/leetcode_101/docs/9-bitwise-operations/9-4-exercises.md index b813d8a1..244cacb2 100644 --- a/leetcode_101/docs/9-bitwise-operations/9-4-exercises.md +++ b/leetcode_101/docs/9-bitwise-operations/9-4-exercises.md @@ -10,14 +10,20 @@ sidebar_position: 47 Single Number 的变种题。除了利用二进制,也可以使用高斯求和公式。 +--- + ### [693. Binary Number with Alternating Bits](https://leetcode.com/problems/binary-number-with-alternating-bits/) 利用位运算判断一个数的二进制是否会出现连续的 0 和 1。 +--- + ### [476. Number Complement](https://leetcode.com/problems/number-complement/) 二进制翻转的变种题。 +--- + ## 进阶难度 ### [260. Single Number III](https://leetcode.com/problems/single-number-iii/) diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-4-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-4-exercises.md index 8b0c7be3..3959bef2 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-4-exercises.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-4-exercises.md @@ -10,10 +10,14 @@ sidebar_position: 4 What kind of greedy strategy can be used to plant the maximum number of flowers? +--- + ### [452. Minimum Number of Arrows to Burst Balloons](https://leetcode.com/problems/minimum-number-of-arrows-to-burst-balloons/) This problem is very similar to problem 435, but what is the subtle difference? +--- + ### [763. Partition Labels](https://leetcode.com/problems/partition-labels/) To satisfy your greedy strategy, do you need some preprocessing? @@ -22,13 +26,15 @@ To satisfy your greedy strategy, do you need some preprocessing? Counting information (such as frequency, count, first appearance position, last appearance position, etc.) before processing the array can significantly reduce the difficulty of the problem. - ::: +--- + ### [122. Best Time to Buy and Sell Stock II](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/) Among stock trading problems, this is a relatively simple one. Without restricting the number of transactions, how can you achieve the maximum profit? +--- ## Advanced Difficulty @@ -36,6 +42,7 @@ Among stock trading problems, this is a relatively simple one. Without restricti Friendly reminder, this problem may require both sorting and insertion operations. +--- ### [665. Non-decreasing Array](https://leetcode.com/problems/non-decreasing-array/) diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-11-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-11-exercises.md index 319a0dc3..40680f39 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-11-exercises.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/10-11-exercises.md @@ -46,10 +46,10 @@ A variant of the `Longest Consecutive Sequence` problem. Since the complexity of sorting is $O(n \log n) < O(n^2)$, we can either sort the array first and then perform an $O(n^2)$ pointer search, or directly use a hash table for an $O(n^2)$ search. -## Advanced Difficulty - --- +## Advanced Difficulty + ### [287. Find the Duplicate Number](https://leetcode.com/problems/find-the-duplicate-number/) A variant of the `Find Missing Number` problem. Besides marking negative values, are there any other algorithms to solve this? diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-5-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-5-exercises.md index 9744bd9f..c6bc8c46 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-5-exercises.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-5-exercises.md @@ -10,10 +10,13 @@ sidebar_position: 63 计算一组字符可以构成的回文字符串的最大长度,可以利用其它数据结构进行辅助统计。 +--- + ### [3. Longest Substring Without Repeating Characters](https://leetcode.com/problems/longest-substring-without-repeating-characters/) 计算最长无重复子字符串,同样的,可以利用其它数据结构进行辅助统计。 +--- ## Advanced Difficulty @@ -21,6 +24,8 @@ sidebar_position: 63 题目 227 的 follow-up,十分推荐练习。 +--- + ### [5. Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/) 类似于我们讲过的子序列问题,子数组或子字符串问题常常也可以用动态规划来解决。先使用动态规划写出一个 $O(n^2)$ 时间复杂度的算法,再搜索一下 Manacher’s Algorithm,它可以在 $O(n)$ 时间解决这一问题。 \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-4-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-4-exercises.md index 47601598..29920cf9 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-4-exercises.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-4-exercises.md @@ -10,14 +10,20 @@ sidebar_position: 67 虽然 LeetCode 没有强制要求,但是我们仍然建议你回收内存,尤其当题目要求你删除的时候。 +--- + ### [328. Odd Even Linked List](https://leetcode.com/problems/odd-even-linked-list/) 这道题其实很简单,千万不要把题目复杂化。 +--- + ### [19. Remove Nth Node From End of List](https://leetcode.com/problems/remove-nth-node-from-end-of-list/) 既然我们可以使用快慢指针找到中点,也可以利用类似的方法找到倒数第 n 个节点,无需遍历第二遍。 +--- + ## Advanced Difficulty ### [148. Sort List](https://leetcode.com/problems/sort-list/) diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-7-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-7-exercises.md index b8e9846c..974e6b5e 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-7-exercises.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-7-exercises.md @@ -10,72 +10,106 @@ sidebar_position: 74 巧用递归,你可以在五行内完成这道题。 +--- + ### [617. Merge Two Binary Trees](https://leetcode.com/problems/merge-two-binary-trees/) 同样的,利用递归可以轻松搞定。 +--- + ### [572. Subtree of Another Tree](https://leetcode.com/problems/subtree-of-another-tree/) 子树是对称树的姊妹题,写法也十分类似。 +--- + ### [404. Sum of Left Leaves](https://leetcode.com/problems/sum-of-left-leaves/) 怎么判断一个节点是不是左节点呢?一种可行的方法是,在辅函数里多传一个参数,表示当前节点是不是父节点的左节点。 +--- + ### [513. Find Bottom Left Tree Value](https://leetcode.com/problems/find-bottom-left-tree-value/) 最左下角的节点满足什么条件?针对这种条件,我们该如何找到它? +--- + ### [538. Convert BST to Greater Tree](https://leetcode.com/problems/convert-bst-to-greater-tree/) 尝试利用某种遍历方式来解决此题,每个节点只需遍历一次。 +--- + ### [235. Lowest Common Ancestor of a Binary Search Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/) 利用 BST 的独特性质,这道题可以很轻松完成。 +--- + ### [530. Minimum Absolute Difference in BST](https://leetcode.com/problems/minimum-absolute-difference-in-bst/) 还记得我们所说的,对于 BST 应该利用哪种遍历吗? +--- + ## Advanced Difficulty ### [1530. Number of Good Leaf Nodes Pairs](https://leetcode.com/problems/number-of-good-leaf-nodes-pairs/) 题目 543 的变种题,注意在辅函数中,每次更新的全局变量是左右两边距离之和满足条件的数量,而返回的是左右两边所有(长度不溢出的)子节点的高度 +1。 +--- + ### [889. Construct Binary Tree from Preorder and Postorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-postorder-traversal/) 给定任意两种遍历结果,我们都可以重建树的结构。 +--- + ### [106. Construct Binary Tree from Inorder and Postorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/) 给定任意两种遍历结果,我们都可以重建树的结构。 +--- + ### [94. Binary Tree Inorder Traversal](https://leetcode.com/problems/binary-tree-inorder-traversal/) 因为前中序后遍历是用递归实现的,而递归的底层实现是栈操作,因此我们总能用栈实现。 +--- + ### [145. Binary Tree Postorder Traversal](https://leetcode.com/problems/binary-tree-postorder-traversal/) 因为前中序后遍历是用递归实现的,而递归的底层实现是栈操作,因此我们总能用栈实现。 +--- + ### [236. Lowest Common Ancestor of a Binary Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/) 现在不是 BST,而是普通的二叉树了,该怎么办? +--- + ### [109. Convert Sorted List to Binary Search Tree](https://leetcode.com/problems/convert-sorted-list-to-binary-search-tree/) 把排好序的链表变成 BST。为了使得 BST 尽量平衡,我们需要寻找链表的中点。 +--- + ### [897. Increasing Order Search Tree](https://leetcode.com/problems/increasing-order-search-tree/) 把 BST 压成一个链表,务必考虑清楚指针操作的顺序,否则可能会出现环路。 +--- + ### [653. Two Sum IV - Input is a BST](https://leetcode.com/problems/two-sum-iv-input-is-a-bst/) 啊哈,这道题可能会把你骗到。 +--- + ### [450. Delete Node in a BST](https://leetcode.com/problems/delete-node-in-a-bst/) 当寻找到待删节点时,你可以分情况考虑——当前节点是叶节点、只有一个子节点和有两个子节点。建议同时回收内存。 \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-4-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-4-exercises.md index 7ea74b28..1c0d256d 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-4-exercises.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-4-exercises.md @@ -6,16 +6,22 @@ sidebar_position: 78 ## Basic Difficulty +--- + ### [1059. All Paths from Source Lead to Destination](https://leetcode.com/problems/all-paths-from-source-lead-to-destination/) 虽然使用深度优先搜索可以解决大部分的图遍历问题,但是注意判断是否陷入了环路。 +--- + ## Advanced Difficulty ### [1135. Connecting Cities With Minimum Cost](https://leetcode.com/problems/connecting-cities-with-minimum-cost/) 笔者其实已经把这道题的题解写好了,才发现这道题是需要解锁才可以看的题目。为了避免版权纠纷,故将其移至练习题内。本题考察最小生成树(minimum spanning tree, MST)的求法,通常可以用两种方式求得:Prim’s Algorithm,利用优先队列选择最小的消耗;以及 Kruskal’s Algorithm,排序后使用并查集。 +--- + ### [882. Reachable Nodes In Subdivided Graph](https://leetcode.com/problems/reachable-nodes-in-subdivided-graph/) 这道题笔者考虑了很久,最终决定把它放在练习题而非详细讲解。本题是经典的节点最短距离问题,常用的算法有 Bellman-Ford 单源最短路算法,以及 Dijkstra 无负边单源最短路算法。虽然经典,但是 LeetCode 很少有相关的题型,因此这里仅供读者自行深入学习。 \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-4-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-4-exercises.md index 4be6947c..78a90026 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-4-exercises.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-4-exercises.md @@ -6,16 +6,22 @@ sidebar_position: 78 ## Basic Difficulty +--- + ### [1135. Connecting Cities With Minimum Cost](https://leetcode.com/problems/connecting-cities-with-minimum-cost/) 使用并查集,按照 Kruskal’s Algorithm 把这道题再解决一次吧。 +--- + ## Advanced Difficulty ### [432. All O`one Data Structure](https://leetcode.com/problems/all-oone-data-structure/) 设计一个 increaseKey,decreaseKey,getMaxKey,getMinKey 均为 O(1) 时间复杂度的数据结构。 +--- + ### [716. Max Stack](https://leetcode.com/problems/max-stack/) 设计一个支持 push,pop,top,getMax 和 popMax 的 stack。可以用类似 LRU 的方法降低时间复杂度,但是因为想要获得的是最大值,我们应该把 unordered_map 换成哪一种数据结构呢? \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-6-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-6-exercises.md index fbd60062..540d2e45 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-6-exercises.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-6-exercises.md @@ -10,14 +10,20 @@ sidebar_position: 10 A variation of the Two Sum problem. +--- + ### [680. Valid Palindrome II](https://leetcode.com/problems/valid-palindrome-ii/) Another variation of the Two Sum problem. +--- + ### [524. Longest Word in Dictionary through Deleting](https://leetcode.com/problems/longest-word-in-dictionary-through-deleting/) A variation of the Merge Sorted Array problem. +--- + ## Advanced Difficulty ### [340. Longest Substring with At Most K Distinct Characters](https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/) diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-6-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-6-exercises.md index 1ebf4db6..19e8c1f6 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-6-exercises.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-6-exercises.md @@ -10,10 +10,14 @@ sidebar_position: 16 A variation of the rotated array problem. +--- + ### [540. Single Element in a Sorted Array](https://leetcode.com/problems/single-element-in-a-sorted-array/) What changes occur in the parity (odd/even positions) of values before and after the unique element? +--- + ## Advanced Difficulty ### [4. Median of Two Sorted Arrays](https://leetcode.com/problems/median-of-two-sorted-arrays/) diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-4-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-4-exercises.md index 85ea25bb..0f811934 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-4-exercises.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-4-exercises.md @@ -10,6 +10,8 @@ sidebar_position: 20 A variant of the bucket sort problem. +--- + ## Advanced Difficulty ### [75. Sort Colors](https://leetcode.com/problems/sort-colors/) diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-5-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-5-exercises.md index 8217d877..123840ec 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-5-exercises.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-5-exercises.md @@ -10,24 +10,34 @@ sidebar_position: 25 Start by filling from the outer edges, then consider the inner regions. +--- + ### [257. Binary Tree Paths](https://leetcode.com/problems/binary-tree-paths/) Output all paths from the root to the leaves in a binary tree. What is the difference if backtracking is used? +--- + ## Advanced Difficulty ### [47. Permutations II](https://leetcode.com/problems/permutations-ii/) A follow-up to the permutations problem. How to handle duplicate elements? +--- + ### [40. Combination Sum II](https://leetcode.com/problems/combination-sum-ii/) A follow-up to the combination problem. How to handle duplicate elements? +--- + ### [37. Sudoku Solver](https://leetcode.com/problems/sudoku-solver/) A very classic Sudoku problem that can be solved using backtracking. In fact, there are many advanced search methods and pruning strategies, such as heuristic search, to improve speed for Sudoku-related problems. +--- + ### [310. Minimum Height Trees](https://leetcode.com/problems/minimum-height-trees/) How can this problem be transformed into a search problem? Should depth-first search or breadth-first search be used? \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-9-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-9-exercises.md index ce5b107f..79eb3e3b 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-9-exercises.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-9-exercises.md @@ -10,36 +10,52 @@ sidebar_position: 34 Follow-up of the robber problem: how to handle circular arrays? +--- + ### [53. Maximum Subarray](https://leetcode.com/problems/maximum-subarray/) A classic one-dimensional dynamic programming problem. Try optimizing the space complexity to a constant. +--- + ### [343. Integer Break](https://leetcode.com/problems/integer-break/) A partition problem. First, solve it using dynamic programming, then think about whether there's a simpler approach. +--- + ### [583. Delete Operation for Two Strings](https://leetcode.com/problems/delete-operation-for-two-strings/) A variation of the longest common subsequence problem. +--- + ## Advanced Difficulty ### [646. Maximum Length of Pair Chain](https://leetcode.com/problems/maximum-length-of-pair-chain/) A variation of the longest increasing subsequence problem. Similarly, try speeding it up using binary search. +--- + ### [10. Regular Expression Matching](https://leetcode.com/problems/regular-expression-matching/) Regex matching is a test of patience. You need to handle different cases, such as characters, asterisks, dots, etc., with careful condition discussions. +--- + ### [376. Wiggle Subsequence](https://leetcode.com/problems/wiggle-subsequence/) The longest wiggle subsequence has a special formula. Think it through carefully. +--- + ### [494. Target Sum](https://leetcode.com/problems/target-sum/) If told this is a 0-1 knapsack problem, does that give you any ideas? +--- + ### [714. Best Time to Buy and Sell Stock with Transaction Fee](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/) Build a state machine, and stock trading problems will become much easier to solve. \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-3-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-3-exercises.md index 29634892..18032a1e 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-3-exercises.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-3-exercises.md @@ -10,6 +10,8 @@ sidebar_position: 37 Try solving this using a top-down divide-and-conquer (recursive) approach with `memoization` for optimization; then attempt a bottom-up dynamic programming approach. +--- + ## Advanced Difficulty ### [312. Burst Balloons](https://leetcode.com/problems/burst-balloons/) diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-6-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-6-exercises.md index cb0b2654..53d7a6e9 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-6-exercises.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-6-exercises.md @@ -10,28 +10,40 @@ sidebar_position: 43 A variation of base-7 conversion, where the sequence starts from 1 instead of 0. +--- + ### [67. Add Binary](https://leetcode.com/problems/add-binary/) A variation of string addition. +--- + ### [238. Product of Array Except Self](https://leetcode.com/problems/product-of-array-except-self/) Can you solve this problem without using division? A previously discussed problem like 135 might give you some ideas. +--- + ## Advanced Difficulty ### [462. Minimum Moves to Equal Array Elements II](https://leetcode.com/problems/minimum-moves-to-equal-array-elements-ii/) One of my favorite LeetCode problems. It requires reasoning about the optimal way to make moves and then considering how to implement the moves. You might need some algorithms we discussed earlier. +--- + ### [169. Majority Element](https://leetcode.com/problems/majority-element/) If you can't come up with a simple solution, search for the Boyer-Moore Majority Vote algorithm. +--- + ### [470. Implement Rand10() Using Rand7()](https://leetcode.com/problems/implement-rand10-using-rand7/) How can you generate one random number generator using another? You may need to utilize the original generator multiple times. +--- + ### [202. Happy Number](https://leetcode.com/problems/happy-number/) You can solve this problem using a simple `while` loop, but is there a better way? If we think of each number as a node, can we transform this into a cycle detection problem? \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-4-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-4-exercises.md index ad596dda..b975477b 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-4-exercises.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-4-exercises.md @@ -10,14 +10,20 @@ sidebar_position: 47 A variation of the Single Number problem. Besides using bitwise operations, the problem can also be solved using the Gaussian summation formula. +--- + ### [693. Binary Number with Alternating Bits](https://leetcode.com/problems/binary-number-with-alternating-bits/) Use bitwise operations to determine whether a number's binary representation alternates between `0` and `1`. +--- + ### [476. Number Complement](https://leetcode.com/problems/number-complement/) A variation of binary flipping problems. +--- + ## Advanced Difficulty ### [260. Single Number III](https://leetcode.com/problems/single-number-iii/) diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current.json index 85ded7f0..31dc7343 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current.json +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current.json @@ -12,12 +12,12 @@ "description": "The generated-index page description for category 1. 最易懂的貪心演算法 in sidebar tutorialSidebar" }, "sidebar.tutorialSidebar.category.2. 玩转双指针": { - "message": "2. 玩轉雙指標", - "description": "The label for category 2. 玩轉雙指標 in sidebar tutorialSidebar" + "message": "2. 玩轉雙指針", + "description": "The label for category 2. 玩轉雙指針 in sidebar tutorialSidebar" }, "sidebar.tutorialSidebar.category.2. 玩转双指针.link.generated-index.description": { - "message": "第 2 章 玩轉雙指標", - "description": "The generated-index page description for category 2. 玩轉雙指標 in sidebar tutorialSidebar" + "message": "第 2 章 玩轉雙指針", + "description": "The generated-index page description for category 2. 玩轉雙指針 in sidebar tutorialSidebar" }, "sidebar.tutorialSidebar.category.3. 居合斩!二分查找": { "message": "3. 居合斬!二分搜尋", diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-4-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-4-exercises.md index a90f9d7f..832a207a 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-4-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/1-greedy-algorithms/1-4-exercises.md @@ -45,6 +45,8 @@ sidebar_position: 4 +--- + ### [452. Minimum Number of Arrows to Burst Balloons](https://leetcode.com/problems/minimum-number-of-arrows-to-burst-balloons/) 這道題和題目 435 十分類似,但是稍有不同,具體是哪裡不同呢? @@ -82,6 +84,8 @@ class Solution: +--- + ### [763. Partition Labels](https://leetcode.com/problems/partition-labels/) 為了滿足你的貪心策略,是否需要一些預處理? @@ -125,6 +129,7 @@ class Solution: +--- ### [122. Best Time to Buy and Sell Stock II](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/) @@ -158,6 +163,8 @@ class Solution: +--- + ## 進階難度 ### [406. Queue Reconstruction by Height](https://leetcode.com/problems/queue-reconstruction-by-height/) @@ -196,6 +203,8 @@ class Solution: - **空間複雜度**: $O(n)$,用於儲存重建的隊列。 +--- + ### [665. Non-decreasing Array](https://leetcode.com/problems/non-decreasing-array/) 需要仔細思考你的貪心策略在各種情況下,是否仍然是最優解。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-5-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-5-exercises.md index 7bde275b..c8a923e0 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-5-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-5-exercises.md @@ -10,10 +10,13 @@ sidebar_position: 63 计算一组字符可以构成的回文字符串的最大长度,可以利用其它数据结构进行辅助统计。 +--- + ### [3. Longest Substring Without Repeating Characters](https://leetcode.com/problems/longest-substring-without-repeating-characters/) 计算最长无重复子字符串,同样的,可以利用其它数据结构进行辅助统计。 +--- ## 進階難度 @@ -21,6 +24,8 @@ sidebar_position: 63 题目 227 的 follow-up,十分推荐练习。 +--- + ### [5. Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/) 类似于我们讲过的子序列问题,子数组或子字符串问题常常也可以用动态规划来解决。先使用动态规划写出一个 $O(n^2)$ 时间复杂度的算法,再搜索一下 Manacher’s Algorithm,它可以在 $O(n)$ 时间解决这一问题。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-4-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-4-exercises.md index 04e945c0..2a972dbd 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-4-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-4-exercises.md @@ -10,14 +10,20 @@ sidebar_position: 67 虽然 LeetCode 没有强制要求,但是我们仍然建议你回收内存,尤其当题目要求你删除的时候。 +--- + ### [328. Odd Even Linked List](https://leetcode.com/problems/odd-even-linked-list/) 这道题其实很简单,千万不要把题目复杂化。 +--- + ### [19. Remove Nth Node From End of List](https://leetcode.com/problems/remove-nth-node-from-end-of-list/) 既然我们可以使用快慢指针找到中点,也可以利用类似的方法找到倒数第 n 个节点,无需遍历第二遍。 +--- + ## 進階難度 ### [148. Sort List](https://leetcode.com/problems/sort-list/) diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-7-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-7-exercises.md index 75690a1e..285dae73 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-7-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-7-exercises.md @@ -10,72 +10,106 @@ sidebar_position: 74 巧用递归,你可以在五行内完成这道题。 +--- + ### [617. Merge Two Binary Trees](https://leetcode.com/problems/merge-two-binary-trees/) 同样的,利用递归可以轻松搞定。 +--- + ### [572. Subtree of Another Tree](https://leetcode.com/problems/subtree-of-another-tree/) 子树是对称树的姊妹题,写法也十分类似。 +--- + ### [404. Sum of Left Leaves](https://leetcode.com/problems/sum-of-left-leaves/) 怎么判断一个节点是不是左节点呢?一种可行的方法是,在辅函数里多传一个参数,表示当前节点是不是父节点的左节点。 +--- + ### [513. Find Bottom Left Tree Value](https://leetcode.com/problems/find-bottom-left-tree-value/) 最左下角的节点满足什么条件?针对这种条件,我们该如何找到它? +--- + ### [538. Convert BST to Greater Tree](https://leetcode.com/problems/convert-bst-to-greater-tree/) 尝试利用某种遍历方式来解决此题,每个节点只需遍历一次。 +--- + ### [235. Lowest Common Ancestor of a Binary Search Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/) 利用 BST 的独特性质,这道题可以很轻松完成。 +--- + ### [530. Minimum Absolute Difference in BST](https://leetcode.com/problems/minimum-absolute-difference-in-bst/) 还记得我们所说的,对于 BST 应该利用哪种遍历吗? +--- + ## 進階難度 ### [1530. Number of Good Leaf Nodes Pairs](https://leetcode.com/problems/number-of-good-leaf-nodes-pairs/) 题目 543 的变种题,注意在辅函数中,每次更新的全局变量是左右两边距离之和满足条件的数量,而返回的是左右两边所有(长度不溢出的)子节点的高度 +1。 +--- + ### [889. Construct Binary Tree from Preorder and Postorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-postorder-traversal/) 给定任意两种遍历结果,我们都可以重建树的结构。 +--- + ### [106. Construct Binary Tree from Inorder and Postorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/) 给定任意两种遍历结果,我们都可以重建树的结构。 +--- + ### [94. Binary Tree Inorder Traversal](https://leetcode.com/problems/binary-tree-inorder-traversal/) 因为前中序后遍历是用递归实现的,而递归的底层实现是栈操作,因此我们总能用栈实现。 +--- + ### [145. Binary Tree Postorder Traversal](https://leetcode.com/problems/binary-tree-postorder-traversal/) 因为前中序后遍历是用递归实现的,而递归的底层实现是栈操作,因此我们总能用栈实现。 +--- + ### [236. Lowest Common Ancestor of a Binary Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/) 现在不是 BST,而是普通的二叉树了,该怎么办? +--- + ### [109. Convert Sorted List to Binary Search Tree](https://leetcode.com/problems/convert-sorted-list-to-binary-search-tree/) 把排好序的链表变成 BST。为了使得 BST 尽量平衡,我们需要寻找链表的中点。 +--- + ### [897. Increasing Order Search Tree](https://leetcode.com/problems/increasing-order-search-tree/) 把 BST 压成一个链表,务必考虑清楚指针操作的顺序,否则可能会出现环路。 +--- + ### [653. Two Sum IV - Input is a BST](https://leetcode.com/problems/two-sum-iv-input-is-a-bst/) 啊哈,这道题可能会把你骗到。 +--- + ### [450. Delete Node in a BST](https://leetcode.com/problems/delete-node-in-a-bst/) 当寻找到待删节点时,你可以分情况考虑——当前节点是叶节点、只有一个子节点和有两个子节点。建议同时回收内存。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-4-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-4-exercises.md index 858cde06..bbc7ae3c 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-4-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-4-exercises.md @@ -10,12 +10,16 @@ sidebar_position: 78 虽然使用深度优先搜索可以解决大部分的图遍历问题,但是注意判断是否陷入了环路。 +--- + ## 進階難度 ### [1135. Connecting Cities With Minimum Cost](https://leetcode.com/problems/connecting-cities-with-minimum-cost/) 笔者其实已经把这道题的题解写好了,才发现这道题是需要解锁才可以看的题目。为了避免版权纠纷,故将其移至练习题内。本题考察最小生成树(minimum spanning tree, MST)的求法,通常可以用两种方式求得:Prim’s Algorithm,利用优先队列选择最小的消耗;以及 Kruskal’s Algorithm,排序后使用并查集。 +--- + ### [882. Reachable Nodes In Subdivided Graph](https://leetcode.com/problems/reachable-nodes-in-subdivided-graph/) 这道题笔者考虑了很久,最终决定把它放在练习题而非详细讲解。本题是经典的节点最短距离问题,常用的算法有 Bellman-Ford 单源最短路算法,以及 Dijkstra 无负边单源最短路算法。虽然经典,但是 LeetCode 很少有相关的题型,因此这里仅供读者自行深入学习。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-4-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-4-exercises.md index b32a11f3..c7f6920c 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-4-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-4-exercises.md @@ -10,12 +10,16 @@ sidebar_position: 78 使用并查集,按照 Kruskal’s Algorithm 把这道题再解决一次吧。 +--- + ## 進階難度 ### [432. All O`one Data Structure](https://leetcode.com/problems/all-oone-data-structure/) 设计一个 increaseKey,decreaseKey,getMaxKey,getMinKey 均为 O(1) 时间复杂度的数据结构。 +--- + ### [716. Max Stack](https://leetcode.com/problems/max-stack/) 设计一个支持 push,pop,top,getMax 和 popMax 的 stack。可以用类似 LRU 的方法降低时间复杂度,但是因为想要获得的是最大值,我们应该把 unordered_map 换成哪一种数据结构呢? \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-6-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-6-exercises.md index 6a9f045e..4d414d7c 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-6-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-6-exercises.md @@ -10,14 +10,20 @@ sidebar_position: 10 Two Sum 題目的變形題之一。 +--- + ### [680. Valid Palindrome II](https://leetcode.com/problems/valid-palindrome-ii/) Two Sum 題目的變形題之二。 +--- + ### [524. Longest Word in Dictionary through Deleting](https://leetcode.com/problems/longest-word-in-dictionary-through-deleting/) 合併兩個有序陣列的變形題。 +--- + ## 進階難度 ### [340. Longest Substring with At Most K Distinct Characters](https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/) diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/_category_.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/_category_.json index 83ef1575..01ecb243 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/_category_.json +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/_category_.json @@ -1,8 +1,8 @@ { - "label": "2. 玩轉雙指標", + "label": "2. 玩轉雙指針", "position": 2, "link": { "type": "generated-index", - "description": "第 2 章 玩轉雙指標" + "description": "第 2 章 玩轉雙指針" } } diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-6-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-6-exercises.md index 27fa8dfc..19ea8ed1 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-6-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-6-exercises.md @@ -10,10 +10,14 @@ sidebar_position: 16 旋轉陣列的變形題之一。 +--- + ### [540. Single Element in a Sorted Array](https://leetcode.com/problems/single-element-in-a-sorted-array/) 在出現單獨數之前和之後,奇數位與偶數位的值發生了什麼變化? +--- + ## 進階難度 ### [4. Median of Two Sorted Arrays](https://leetcode.com/problems/median-of-two-sorted-arrays/) diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-4-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-4-exercises.md index 570ece94..7979d20f 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-4-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-4-exercises.md @@ -10,6 +10,8 @@ sidebar_position: 20 桶排序的變形題。 +--- + ## 進階難度 ### [75. Sort Colors](https://leetcode.com/problems/sort-colors/) diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-5-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-5-exercises.md index 62961584..1f09844b 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-5-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-5-exercises.md @@ -10,24 +10,34 @@ sidebar_position: 25 從最外側開始填充,然後再考慮內部區域。 +--- + ### [257. Binary Tree Paths](https://leetcode.com/problems/binary-tree-paths/) 輸出二元樹中所有從根節點到葉子節點的路徑。使用回溯法與否有什麼區別? +--- + ## 進階難度 ### [47. Permutations II](https://leetcode.com/problems/permutations-ii/) 排列問題的進階版本,如何處理重複的元素? +--- + ### [40. Combination Sum II](https://leetcode.com/problems/combination-sum-ii/) 組合問題的進階版本,如何處理重複的元素? +--- + ### [37. Sudoku Solver](https://leetcode.com/problems/sudoku-solver/) 非常經典的數獨問題,可以利用回溯法解決。事實上,針對數獨類型的問題,有許多進階的搜索方法和剪枝策略可以提升求解速度,例如啟發式搜索。 +--- + ### [310. Minimum Height Trees](https://leetcode.com/problems/minimum-height-trees/) 如何將這道題轉化為搜索類型的問題?應該使用深度優先搜索還是廣度優先搜索? \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-9-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-9-exercises.md index f4336fd1..02541d9a 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-9-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-9-exercises.md @@ -10,36 +10,52 @@ sidebar_position: 34 強盜搶劫問題的 follow-up,如何處理環形陣列呢? +--- + ### [53. Maximum Subarray](https://leetcode.com/problems/maximum-subarray/) 經典的一維動態規劃題目,試著把一維空間優化為常量吧。 +--- + ### [343. Integer Break](https://leetcode.com/problems/integer-break/) 分割類型題,先嘗試用動態規劃求解,再思考是否有更簡單的解法。 +--- + ### [583. Delete Operation for Two Strings](https://leetcode.com/problems/delete-operation-for-two-strings/) 最長公共子序列的變種題。 +--- + ## 進階難度 ### [646. Maximum Length of Pair Chain](https://leetcode.com/problems/maximum-length-of-pair-chain/) 最長遞增子序列的變種題,同樣的,嘗試用二分進行加速。 +--- + ### [10. Regular Expression Matching](https://leetcode.com/problems/regular-expression-matching/) 正則表達式匹配,非常考驗耐心。需要根據正則表達式的不同情況,即字符、星號,點號等,分情況討論。 +--- + ### [376. Wiggle Subsequence](https://leetcode.com/problems/wiggle-subsequence/) 最長擺動子序列,通項公式比較特殊,需要仔細思考。 +--- + ### [494. Target Sum](https://leetcode.com/problems/target-sum/) 如果告訴你這道題是 0-1 背包,你是否會有一些思路? +--- + ### [714. Best Time to Buy and Sell Stock with Transaction Fee](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/) 建立狀態機,股票交易類問題就會迎刃而解。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-3-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-3-exercises.md index ed0c659c..be141f55 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-3-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-3-exercises.md @@ -10,6 +10,8 @@ sidebar_position: 37 嘗試使用從上到下的分治(遞迴)寫法進行求解,並最好加入 `memoization` 優化;之後再嘗試使用從下到上的動態規劃寫法求解。 +--- + ## 進階難度 ### [312. Burst Balloons](https://leetcode.com/problems/burst-balloons/) diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-6-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-6-exercises.md index d84c4491..165a9a1c 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-6-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-6-exercises.md @@ -10,28 +10,40 @@ sidebar_position: 43 7 進制轉換的變種題,需要注意的一點是從 1 開始而不是 0。 +--- + ### [67. Add Binary](https://leetcode.com/problems/add-binary/) 字符串加法的變種題。 +--- + ### [238. Product of Array Except Self](https://leetcode.com/problems/product-of-array-except-self/) 你可以不使用除法做這道題嗎?我們很早之前講過的題目 135 或許能給你一些思路。 +--- + ## 進階難度 ### [462. Minimum Moves to Equal Array Elements II](https://leetcode.com/problems/minimum-moves-to-equal-array-elements-ii/) 這道題是筆者最喜歡的 LeetCode 題目之一,需要先推理出怎麼樣移動是最優的,再考慮如何進行移動。你或許需要一些前些章節講過的算法。 +--- + ### [169. Majority Element](https://leetcode.com/problems/majority-element/) 如果想不出簡單的解決方法,搜尋一下 Boyer-Moore Majority Vote 算法吧。 +--- + ### [470. Implement Rand10() Using Rand7()](https://leetcode.com/problems/implement-rand10-using-rand7/) 如何用一個隨機數生成器生成另一個隨機數生成器?你可能需要利用原來的生成器多次。 +--- + ### [202. Happy Number](https://leetcode.com/problems/happy-number/) 你可以簡單的用一個 `while` 循環解決這道題,但是有沒有更好的解決辦法?如果我們把每個數字想像成一個節點,是否可以轉化為環路檢測? \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-4-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-4-exercises.md index 0befcaf0..2d2923b4 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-4-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-4-exercises.md @@ -10,14 +10,20 @@ sidebar_position: 47 Single Number 的變種題。除了利用二進位,也可以使用高斯求和公式解決。 +--- + ### [693. Binary Number with Alternating Bits](https://leetcode.com/problems/binary-number-with-alternating-bits/) 利用位運算判斷一個數的二進位表示是否會出現連續的 `0` 和 `1`。 +--- + ### [476. Number Complement](https://leetcode.com/problems/number-complement/) 二進位翻轉的變種題。 +--- + ## 進階難度 ### [260. Single Number III](https://leetcode.com/problems/single-number-iii/) From 8557774ecc242569b7e05f733b3da7ca8e7fb4d9 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Wed, 27 Nov 2024 01:20:37 +0100 Subject: [PATCH 29/49] i18n preface --- .../docs/1-greedy-algorithms/1-4-exercises.md | 2 +- leetcode_101/docs/index.md | 2 +- .../current/acknowledgments.md | 16 ++++++ .../current/index.md | 51 +++++++++++++++++++ .../current/acknowledgments.md | 16 ++++++ .../current/index.md | 51 +++++++++++++++++++ 6 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/acknowledgments.md create mode 100644 leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/index.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/acknowledgments.md create mode 100644 leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/index.md diff --git a/leetcode_101/docs/1-greedy-algorithms/1-4-exercises.md b/leetcode_101/docs/1-greedy-algorithms/1-4-exercises.md index 3db0069d..1d7b4a23 100644 --- a/leetcode_101/docs/1-greedy-algorithms/1-4-exercises.md +++ b/leetcode_101/docs/1-greedy-algorithms/1-4-exercises.md @@ -34,7 +34,7 @@ sidebar_position: 4 股票交易题型里比较简单的题目,在不限制交易次数的情况下,怎样可以获得最大利润呢? - +--- ## 进阶难度 diff --git a/leetcode_101/docs/index.md b/leetcode_101/docs/index.md index 676d12f9..b8b869c5 100644 --- a/leetcode_101/docs/index.md +++ b/leetcode_101/docs/index.md @@ -2,7 +2,7 @@ sidebar_position: 0 --- -# 0. LeetCode 101: 力扣刷题指南 (第二版) +# LeetCode 101: 力扣刷题指南 (第二版) ![](https://github.com/changgyhub/leetcode_101/blob/master/misc/cover.jpg?raw=true) diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/acknowledgments.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/acknowledgments.md new file mode 100644 index 00000000..8dca8d96 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/acknowledgments.md @@ -0,0 +1,16 @@ +--- +sidebar_position: 79 +--- + +# 鸣谢名单 + +## 官方唯一指定最强王者赞助 +Yudi Zhang + +## 友情赞助 +排名不分先后:Yujia Chen、Chaoyu Wang、Chunyan Bai、Haoshuo Huang、Wenting Ye、Yuting Wang、Bill Liu、Zhiyu Min、Xuyang Cheng、Keyi Xian、Yihan Zhang、Rui Yan、Mao Cheng、Michael +Wang 等。 + +## GitHub 用户 + +排名不分先后:quweikoala、szlghl1、mag1cianag、woodpenker、yangCoder96、cluckl、shaoshuai-luo、KivenGood、alicegong、hitYunhongXu、shengchen1998、jihchi、hapoyige、hitYunhongXu、h82258652、conan81412B、Mirrorigin、Light-young、XiangYG、xnervwang、sabaizzz、PhoenixChen98、zhang-wang997、corbg118、tracyqwerty、yorhaha、DeckardZ46、Ricardo-609、namu-guwal、hkulyc、jacklanda、View0、HelloYJohn、Corezcy、MoyuST、lutengda、fengshansi 等。 \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/index.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/index.md new file mode 100644 index 00000000..a6264fa7 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/index.md @@ -0,0 +1,51 @@ +--- +sidebar_position: 0 +--- + +# LeetCode 101: A Grinding Guide (2nd Edition) + +![](https://github.com/changgyhub/leetcode_101/blob/master/misc/cover.jpg?raw=true) + +Author: Chang Gao + +Languages: C++ & Python + +Version: Official Version 2.0c, latest version available on GitHub [changgyhub/leetcode_101](https://github.com/changgyhub/leetcode_101) + +:::info +A textbook and reference guide for readers with basic programming knowledge but limited problem-solving experience. +::: + +## Preface + +At the end of 2019, the first edition of this book was officially released on GitHub and received an enthusiastic response. Over the past five years, the author has gained extensive work experience and recognized numerous flaws and shortcomings in the first edition. Thus, at the end of 2024, the author reorganized the content and released this second edition. + +This book is divided into three main parts: algorithms, mathematics, and data structures, spanning fifteen chapters. It provides a comprehensive explanation of techniques frequently used when solving LeetCode problems. In the first edition, the number of problems was restricted to 101 to align with the term "101" (symbolizing an introduction in English). However, the scope of interview questions has expanded over time. Hence, the second edition includes additional key problems to help readers fill any gaps in their knowledge. The author carefully selected problems based on their likelihood of appearing in interviews, ease of understanding, and general applicability. Each chapter concludes with practice problems that readers are strongly encouraged to attempt after completing the chapter. + +Every regular problem in this book comes with solutions in both C++ and Python3. Since the book’s purpose is not to teach C++ or Python, the author avoids delving too deeply into syntax details and uses some modern C++ standards and Pythonic code. As of late 2024, all code in the book runs correctly on LeetCode and, while maintaining readability, is often the fastest or most space-efficient solution. + +Remember, solving problems is only a small part of improving your interview and work capabilities. There is a vast ocean of computer science to explore, and it is not recommended to spend excessive time on problem-solving. To become a proficient computer scientist, treat problem-solving as an entry point while also strengthening your professional foundation, improving your skills, and staying informed about the latest advancements in the field. + +This book was completed during the author’s spare time and may contain errors or areas for improvement. Some problem explanations may lack detail or clarity. Readers are welcome to submit issues on GitHub to help refine the book, and the author will acknowledge your contributions in the acknowledgments section. For suggestions or inquiries, visit the author’s personal website or send a message via email or LinkedIn, and the author will respond promptly. + +Special thanks to GitHub user CyC2018 for their LeetCode problem explanations, which greatly assisted the author in the early stages of this book. Gratitude also goes to ElegantBook for its elegant LATEX template, which made it easy to transform notes into a professional-looking eBook. The cover photo of the second edition was taken by the author in July 2024 at the seaside town of Sausalito, north of the Golden Gate Bridge in San Francisco. Incidentally, the author bought a large three-scoop ice cream cone there, but it was too sweet to finish and had to be discarded. + +If you find this book helpful, consider supporting the author! + + + +## Important Notice + +GitHub repository for this book: [github.com/changgyhub/leetcode_101](https://github.com/changgyhub/leetcode_101) + +This book is free of charge and prohibits any commercial use, as its purpose is solely for sharing and teaching. Academic sharing and circulation are welcome. All problem copyrights belong to LeetCode, and this book does not display content or code for LeetCode premium problems. + +## Introduction + +When visiting the LeetCode website, problems can often be categorized by type. The most common categories include arrays, dynamic programming, mathematics, strings, trees, hash maps, depth-first search, binary search, greedy algorithms, breadth-first search, and two pointers. This book covers the above categories and most other popular problem types, while categorizing them by type and difficulty level in a step-by-step manner. + +The first major category is algorithms. This book starts with the simplest greedy algorithms and gradually progresses to two pointers, binary search, sorting algorithms, search algorithms, and finally, more challenging topics such as dynamic programming and divide-and-conquer. + +The second category is mathematics, encompassing problems related to pure mathematics and computer-related topics like bit manipulation. These problems often test intellectual sharpness but are less commonly used in real-world work. The author recommends prioritizing other categories. + +The third category is data structures, including C++ STL, Python3 built-in data structures, string manipulation, linked lists, trees, and graphs. Linked lists are a subset of trees and graphs. The book concludes with an introduction to more advanced data structures like the classic Union-Find and LRU. diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/acknowledgments.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/acknowledgments.md new file mode 100644 index 00000000..8dca8d96 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/acknowledgments.md @@ -0,0 +1,16 @@ +--- +sidebar_position: 79 +--- + +# 鸣谢名单 + +## 官方唯一指定最强王者赞助 +Yudi Zhang + +## 友情赞助 +排名不分先后:Yujia Chen、Chaoyu Wang、Chunyan Bai、Haoshuo Huang、Wenting Ye、Yuting Wang、Bill Liu、Zhiyu Min、Xuyang Cheng、Keyi Xian、Yihan Zhang、Rui Yan、Mao Cheng、Michael +Wang 等。 + +## GitHub 用户 + +排名不分先后:quweikoala、szlghl1、mag1cianag、woodpenker、yangCoder96、cluckl、shaoshuai-luo、KivenGood、alicegong、hitYunhongXu、shengchen1998、jihchi、hapoyige、hitYunhongXu、h82258652、conan81412B、Mirrorigin、Light-young、XiangYG、xnervwang、sabaizzz、PhoenixChen98、zhang-wang997、corbg118、tracyqwerty、yorhaha、DeckardZ46、Ricardo-609、namu-guwal、hkulyc、jacklanda、View0、HelloYJohn、Corezcy、MoyuST、lutengda、fengshansi 等。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/index.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/index.md new file mode 100644 index 00000000..80e636a8 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/index.md @@ -0,0 +1,51 @@ +--- +sidebar_position: 0 +--- + +# LeetCode 101: LeetCode 刷題指南 (第二版) + +![](https://github.com/changgyhub/leetcode_101/blob/master/misc/cover.jpg?raw=true) + +作者:高畅 Chang Gao + +語言:C++ & Python + +版本:正式版 2.0c,最新版見 GitHub [changgyhub/leetcode_101](https://github.com/changgyhub/leetcode_101) + +:::info +一本面向有一定程式基礎,但缺乏刷題經驗的讀者的教科書和工具書。 +::: + +## 序 + +2019 年底,本書第一版在 GitHub 上正式發佈,反響非常熱烈。過去五年,作者累積了許多工作經驗,也愈發覺得本書存在許多錯誤與不完善之處。因此在 2024 年底,作者重新整理內容,發佈了第二版。 + +本書分為算法、數學和資料結構三大部分,共計十五個章節,詳細介紹了解 LeetCode 時常用的技巧。在第一版中,為了強行呼應 "101"(在英文中意為入門),作者將題目精簡至 101 道。但隨著面試題型愈加多樣化,第二版新增了一些重點題目,幫助讀者查漏補缺。在選題時,作者兼顧題目在面試中的出現頻率、學習難易度及泛用性。每章節後附有練習題,推薦讀者學習完後使用這些題目進行鞏固。 + +本書中的所有常規題目均附有 C++ 和 Python3 的解法。由於本書的目的並非教學 C++ 和 Python 語言,作者在行文時不會過多解釋語法細節,並會適當使用一些新 C++ 標準語法和 Pythonic 寫法。至 2024 年底,所有代碼均能在 LeetCode 正常運行,並且在易讀性的基礎上幾乎都是最快或最省空間的解法。 + +請謹記,解題只是提升面試和工作能力的一部分。在電腦科學的海洋中,值得探索的領域甚多,不建議將過多時間耗在解題上。成為優秀的電腦科學家,除了把解題作為入職的敲門磚,更應打好專業基礎、提升技能並了解最新技術動向。 + +本書由作者閒暇時間完成,可能存在錯誤或不完善之處。部分題目解釋可能不夠詳細或清楚,歡迎讀者至 GitHub 提 issue 修正,作者將加入您於鳴謝名單(見後記)。若有建議或疑問,請至作者個人網站聯繫,亦可通過郵件或 LinkedIn 傳訊,作者會儘快回復。 + +感謝 GitHub 用戶 CyC2018 的 LeetCode 題解,為作者早期整理內容提供了幫助。感謝 ElegantBook 提供的精美 LATEX 模板,使得作者能輕鬆將筆記變為專業的電子書。另外,第二版封面圖片為作者於 2024 年 7 月在舊金山金門大橋北方的 Sausalito 小鎮海邊拍攝,當時還買了一份超大杯冰淇淋,可惜太甜吃不下,只能作罷。 + +若本書對您有幫助,不妨支持作者! + + + +## 重要聲明 + +本書 GitHub 地址:[github.com/changgyhub/leetcode_101](https://github.com/changgyhub/leetcode_101) + +由於本書目的是分享與教學,本書永久免費,禁止任何營利性用途。歡迎以學術為目的的分享與傳閱。本書所有題目版權歸 LeetCode 官方所有,本書不展示任何付費會員專享題目內容或相關代碼。 + +## 簡介 + +打開 LeetCode 網站,若按題目類型分類,出現次數最多的包括數組、動態規劃、數學、字串、樹、雜湊表、深度優先搜索、二分搜尋、貪心算法、廣度優先搜索、雙指針等。本書涵蓋上述題型以及大多數流行題型,並依照類型分類與難易程度進行逐步講解。 + +第一大類為算法。本書從最簡單的貪心算法開始,逐漸進階至雙指針、二分搜尋、排序算法與搜索算法,最終講解難度較高的動態規劃與分治算法。 + +第二大類為數學,涵蓋純數學問題與計算機知識相關的位運算問題。這類問題多用於測試思維靈敏度,實際工作中較少使用,建議優先處理其他類型問題。 + +第三大類為資料結構,包括 C++ STL、Python3 自帶的資料結構、字串處理、鏈結串列、樹與圖。其中,鏈結串列為樹與圖的子集。最後亦介紹一些更複雜的資料結構,如經典的並查集與 LRU。 From b78413b52188d4914a0699d76ace85e67e0c6e4a Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Wed, 27 Nov 2024 01:23:42 +0100 Subject: [PATCH 30/49] i18n acknowledgments --- .../current/acknowledgments.md | 14 +++++++------- .../current/acknowledgments.md | 13 +++++++------ 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/acknowledgments.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/acknowledgments.md index 8dca8d96..6c1f5320 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/acknowledgments.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/acknowledgments.md @@ -2,15 +2,15 @@ sidebar_position: 79 --- -# 鸣谢名单 +# Acknowledgments -## 官方唯一指定最强王者赞助 +## Officially Recognized Supreme Supporter Yudi Zhang -## 友情赞助 -排名不分先后:Yujia Chen、Chaoyu Wang、Chunyan Bai、Haoshuo Huang、Wenting Ye、Yuting Wang、Bill Liu、Zhiyu Min、Xuyang Cheng、Keyi Xian、Yihan Zhang、Rui Yan、Mao Cheng、Michael -Wang 等。 +## Friendly Sponsors +In no particular order: Yujia Chen、Chaoyu Wang、Chunyan Bai、Haoshuo Huang、Wenting Ye、Yuting Wang、Bill Liu、Zhiyu Min、Xuyang Cheng、Keyi Xian、Yihan Zhang、Rui Yan、Mao Cheng、Michael +Wang, and others. -## GitHub 用户 +## GitHub Contributors -排名不分先后:quweikoala、szlghl1、mag1cianag、woodpenker、yangCoder96、cluckl、shaoshuai-luo、KivenGood、alicegong、hitYunhongXu、shengchen1998、jihchi、hapoyige、hitYunhongXu、h82258652、conan81412B、Mirrorigin、Light-young、XiangYG、xnervwang、sabaizzz、PhoenixChen98、zhang-wang997、corbg118、tracyqwerty、yorhaha、DeckardZ46、Ricardo-609、namu-guwal、hkulyc、jacklanda、View0、HelloYJohn、Corezcy、MoyuST、lutengda、fengshansi 等。 \ No newline at end of file +In no particular order: quweikoala、szlghl1、mag1cianag、woodpenker、yangCoder96、cluckl、shaoshuai-luo、KivenGood、alicegong、hitYunhongXu、shengchen1998、jihchi、hapoyige、hitYunhongXu、h82258652、conan81412B、Mirrorigin、Light-young、XiangYG、xnervwang、sabaizzz、PhoenixChen98、zhang-wang997、corbg118、tracyqwerty、yorhaha、DeckardZ46、Ricardo-609、namu-guwal、hkulyc、jacklanda、View0、HelloYJohn、Corezcy、MoyuST、lutengda、fengshansi, and others. \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/acknowledgments.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/acknowledgments.md index 8dca8d96..72f6ca66 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/acknowledgments.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/acknowledgments.md @@ -2,15 +2,16 @@ sidebar_position: 79 --- -# 鸣谢名单 +# 鳴謝名單 -## 官方唯一指定最强王者赞助 +## 官方唯一指定最強王者贊助 Yudi Zhang -## 友情赞助 -排名不分先后:Yujia Chen、Chaoyu Wang、Chunyan Bai、Haoshuo Huang、Wenting Ye、Yuting Wang、Bill Liu、Zhiyu Min、Xuyang Cheng、Keyi Xian、Yihan Zhang、Rui Yan、Mao Cheng、Michael +## 友情贊助 + +排名不分先後:Yujia Chen、Chaoyu Wang、Chunyan Bai、Haoshuo Huang、Wenting Ye、Yuting Wang、Bill Liu、Zhiyu Min、Xuyang Cheng、Keyi Xian、Yihan Zhang、Rui Yan、Mao Cheng、Michael Wang 等。 -## GitHub 用户 +## GitHub 用戶 -排名不分先后:quweikoala、szlghl1、mag1cianag、woodpenker、yangCoder96、cluckl、shaoshuai-luo、KivenGood、alicegong、hitYunhongXu、shengchen1998、jihchi、hapoyige、hitYunhongXu、h82258652、conan81412B、Mirrorigin、Light-young、XiangYG、xnervwang、sabaizzz、PhoenixChen98、zhang-wang997、corbg118、tracyqwerty、yorhaha、DeckardZ46、Ricardo-609、namu-guwal、hkulyc、jacklanda、View0、HelloYJohn、Corezcy、MoyuST、lutengda、fengshansi 等。 \ No newline at end of file +排名不分先後:quweikoala、szlghl1、mag1cianag、woodpenker、yangCoder96、cluckl、shaoshuai-luo、KivenGood、alicegong、hitYunhongXu、shengchen1998、jihchi、hapoyige、hitYunhongXu、h82258652、conan81412B、Mirrorigin、Light-young、XiangYG、xnervwang、sabaizzz、PhoenixChen98、zhang-wang997、corbg118、tracyqwerty、yorhaha、DeckardZ46、Ricardo-609、namu-guwal、hkulyc、jacklanda、View0、HelloYJohn、Corezcy、MoyuST、lutengda、fengshansi 等。 \ No newline at end of file From 702ea47f9722cb3ab857d7bd49fa2622a2b2c3f8 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Wed, 27 Nov 2024 18:08:26 +0100 Subject: [PATCH 31/49] i18n chapter 11 --- .../11-1-introduction.md | 4 +- .../11-2-string-comparison.mdx | 58 +++++++++++-------- .../11-3-string-interpretation.mdx | 20 +++---- .../11-4-string-matching.mdx | 34 +++++------ .../11-string-manipulation/11-5-exercises.md | 8 +-- .../11-1-introduction.md | 2 +- .../11-2-string-comparison.mdx | 57 ++++++++++-------- .../11-3-string-interpretation.mdx | 20 +++---- .../11-4-string-matching.mdx | 34 +++++------ .../11-string-manipulation/11-5-exercises.md | 8 +-- 10 files changed, 134 insertions(+), 111 deletions(-) diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-1-introduction.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-1-introduction.md index 9cd88891..76271dfe 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-1-introduction.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-1-introduction.md @@ -2,6 +2,6 @@ sidebar_position: 59 --- -# 11.1 引言 +# 11.1 Introduction -字符串可以看成是字符组成的数组。由于字符串是程序里经常需要处理的数据类型,因此有很多针对字符串处理的题目,以下是一些常见的类型。 \ No newline at end of file +Strings can be considered as arrays of characters. Since strings are a frequently used data type in programming, there are many problems related to string manipulation. Below are some common types of such problems. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-2-string-comparison.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-2-string-comparison.mdx index bec7f3c5..d7d7bfb6 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-2-string-comparison.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-2-string-comparison.mdx @@ -2,17 +2,17 @@ sidebar_position: 60 --- -# 11.2 字符串比较 +# 11.2 String Comparison ## [242. Valid Anagram](https://leetcode.com/problems/valid-anagram/) ### Problem Description -判断两个字符串包含的字符是否完全相同。 +Determine if two strings contain exactly the same characters. ### Input and Output Example -输入两个字符串,输出一个布尔值,表示两个字符串是否满足条件。 +Input two strings and output a boolean indicating whether the two strings meet the condition. ``` Input: s = "anagram", t = "nagaram" @@ -21,7 +21,8 @@ Output: true ### Solution Explanation -我们可以利用哈希表或者数组统计两个数组中每个数字出现的频次,若频次相同,则说明它们包含的字符完全相同。 +We can use a hash table or an array to count the frequency of each character in both strings. If the frequencies match, it means the strings contain the exact same characters. + @@ -60,22 +61,24 @@ def isAnagram(s: str, t: str) -> bool: ### Problem Description -判断两个字符串是否同构。同构的定义是,可以通过把一个字符串的某些相同的字符转换成另一些相同的字符,使得两个字符串相同,且两种不同的字符不能够被转换成同一种字符。 +Determine if two strings are isomorphic. Two strings are isomorphic if characters in one string can be replaced to get the other string, while ensuring that no two different characters map to the same character. ### Input and Output Example -输入两个字符串,输出一个布尔值,表示两个字符串是否满足条件。 +Input two strings and output a boolean indicating whether they meet the condition. ``` Input: s = "paper", t = "title" Output: true ``` -在这个样例中,通过把 s 中的 p、a、e、r 字符转换成 t、i、l、e 字符,可以使得两个字符串相同。 +In this example, by replacing `p`, `a`, `e`, `r` in `s` with `t`, `i`, `l`, `e` respectively, the two strings can become identical. ### Solution Explanation -我们可以将问题转化一下:记录两个字符串每个位置的字符第一次出现的位置,如果两个字符串中相同位置的字符与它们第一次出现的位置一样,那么这两个字符串同构。举例来说,对于“paper”和“title”,假设我们现在遍历到第三个字符“p”和“t”,发现它们第一次出现的位置都在第一个字符,则说明目前位置满足同构。同样的,我们可以用哈希表存储,也可以用一个长度为 128 的数组(ASCII 定义下字符的总数量)。 +We can reformulate the problem: track the first appearance position of each character in both strings. If the characters at the same position in both strings have the same first appearance position, the strings are isomorphic. + +For example, for "paper" and "title," if we reach the third characters `p` and `t`, we find their first appearances are at the first character, which satisfies the isomorphic condition. We can use a hash table for storage or a fixed-length array of size 128 (for the total number of ASCII characters). @@ -117,22 +120,22 @@ def isIsomorphic(s: str, t: str) -> bool: ### Problem Description -给定一个字符,求其有多少个回文子字符串。回文的定义是左右对称。 +Given a string, find how many of its substrings are palindromic. A palindrome is defined as being symmetric from left to right. ### Input and Output Example -输入是一个字符串,输出一个整数,表示回文子字符串的数量。 +Input is a string, and output is an integer representing the count of palindromic substrings. ``` Input: "aaa" Output: 6 ``` -六个回文子字符串分别是 ["a","a","a","aa","aa","aaa"]。 +The six palindromic substrings are ["a", "a", "a", "aa", "aa", "aaa"]. ### Solution Explanation -我们可以从字符串的每个位置开始,向左向右延长,判断存在多少以当前位置为中轴的回文子字符串。 +We can start from every position in the string and extend to the left and right, counting how many palindromic substrings have the current position as their center. @@ -152,8 +155,8 @@ int extendSubstrings(string s, int l, int r) { int countSubstrings(string s) { int count = 0; for (int i = 0; i < s.length(); ++i) { - count += extendSubstrings(s, i, i); // 奇数长度 - count += extendSubstrings(s, i, i + 1); // 偶数长度 + count += extendSubstrings(s, i, i); // Odd length + count += extendSubstrings(s, i, i + 1); // Even length } return count; } @@ -175,7 +178,7 @@ def extendSubstrings(s: str, l: int, r: int) -> int: # Main function def countSubstrings(s: str) -> int: return sum( - # 奇数长度 + 偶数长度。 + # Odd length + Even length extendSubstrings(s, i, i) + extendSubstrings(s, i, i + 1) for i in range(len(s)) ) @@ -190,22 +193,26 @@ def countSubstrings(s: str) -> int: ### Problem Description -给定一个 0-1 字符串,求有多少非空子字符串的 0 和 1 数量相同,且 0 和 1 必须连续出现(比如 0011、1100;0101 不算)。 +Given a binary string (composed of '0's and '1's), count the number of non-empty substrings where the number of '0's and '1's are equal, and all '0's and '1's must appear consecutively (e.g., "0011", "1100"; but "0101" is not valid). ### Input and Output Example -输入是一个字符串,输出一个整数,表示满足条件的子字符串的数量。 +Input is a string, and output is an integer representing the count of valid substrings. ``` Input: "00110011" Output: 6 ``` -在这个样例中,六个 0 和 1 数量相同的子字符串是 ["0011","01","1100","10","0011","01"]。 +In this example, the six substrings where '0's and '1's are equal are ["0011", "01", "1100", "10", "0011", "01"]. ### Solution Explanation -从左往右遍历数组,记录和当前位置数字相同且连续的长度,以及其之前连续的不同数字的长度。举例来说,对于 00110 的最后一位,我们记录的相同数字长度是 1,因为只有一个连续 0;我们记录的不同数字长度是 2,因为在 0 之前有两个连续的 1。若不同数字的连续长度大于等于当前数字的连续长度,则说明存在一个且只存在一个以当前数字结尾的满足条件的子字符串。 +Traverse the string from left to right, keeping track of the length of consecutive characters that are the same as the current character, as well as the length of the consecutive different characters before it. For example, in "00110", the last '0' has: +- A consecutive length of 1 for '0', because there's only one '0' at the end. +- A consecutive length of 2 for '1', because there are two '1's right before it. + +If the length of the consecutive different characters is greater than or equal to the current consecutive length, then there exists exactly one valid substring ending at the current character. @@ -256,22 +263,27 @@ def countBinarySubstrings(s: str) -> int: ### Problem Description -给定一个包括字母和左右括号的字符串,求最少要移除多少个括号才能使其合法。 +Given a string containing letters and parentheses, determine the minimum number of parentheses to remove to make the string valid. ### Input and Output Example -输入是一个字符串,输出是合法且长度最长的移除结果。 +Input is a string, and output is a valid string with the longest possible length after removal. ``` Input: s = "lee(t(c)o)de)" Output: "lee(t(c)o)de" ``` -返回 lee(t(co)de) 或 lee(t(c)ode) 也算正确。 +Returning "lee(t(co)de)" or "lee(t(c)ode)" is also considered correct. ### Solution Explanation -因为只有一种括号,所以我们并不一定利用栈来统计,可以直接用一个临时变量统计在当前位置时,左括号比右括号多出现多少次。如果在遍历过程中出现负数,则需要移除多余的右括号。如果遍历结束时临时变量为正数,则需要从右到左移除多余的左括号。这里我们使用了一个小技巧,先标记待删除位置,最后一起移除。 +Since only one type of parenthesis is involved, we don't necessarily need a stack to track them. Instead, we can use a temporary variable to count how many more left parentheses are present than right parentheses at any position. + +- If this count becomes negative during traversal, it means there are extra right parentheses that need to be removed. +- At the end of the traversal, if the count is positive, it means there are extra left parentheses that need to be removed by traversing from right to left. + +A small optimization here is to first mark all positions that need to be removed and then remove them in one go. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-3-string-interpretation.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-3-string-interpretation.mdx index 14b7b505..2571954d 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-3-string-interpretation.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-3-string-interpretation.mdx @@ -2,36 +2,36 @@ sidebar_position: 61 --- -# 11.3 字符串理解 +# 11.3 String Parsing ## [227. Basic Calculator II](https://leetcode.com/problems/basic-calculator-ii/) ### Problem Description -给定一个包含加减乘除整数运算的字符串,求其运算的整数值结果。如果除不尽则向 0 取整。 +Given a string containing addition, subtraction, multiplication, and division of integers, calculate the result. Division truncates towards zero. ### Input and Output Example -输入是一个合法的运算字符串,输出是一个整数,表示其运算结果。 +Input is a valid arithmetic string, and output is an integer representing the result. ``` Input: " 3+5 / 2 " Output: 5 ``` -在这个样例中,因为除法的优先度高于加法,所以结果是 5 而非 4。 +In this example, since division has a higher priority than addition, the result is 5 rather than 4. ### Solution Explanation -如果我们在字符串左边加上一个加号,可以证明其并不改变运算结果,且字符串可以分割成多个 < 一个运算符,一个数字 > 对子的形式;这样一来我们就可以从左往右处理了。由于乘除的优先级高于加减,因此我们需要使用一个中间变量来存储高优先度的运算结果。 +If we prepend a `+` sign to the left of the string, it doesn't change the result, and the string can be divided into multiple pairs of ``. This allows us to process the string from left to right. Since multiplication and division have higher precedence than addition and subtraction, we need an intermediate variable to store results of high-priority operations. -此类型题也考察很多细节处理,如无运算符的情况,和多个空格的情况等等。 +This type of problem also tests edge cases, such as strings without operators or with multiple spaces. ```cpp -// 辅函数 - parse从位置i开始的一个数字。 +// Helper function to parse a number starting from position i. int parseNum(const string& s, int& i) { int num = 0, n = s.length(); while (i < n && isdigit(s[i])) { @@ -81,8 +81,8 @@ int calculate(string s) { ```py from typing import Tuple -# 辅函数 - parse从位置i开始的一个数字。 -# 返回(数字, 下一个i位置) +# Helper function to parse a number starting from position i. +# Returns (number, next position i) def parseNum(s: str, i: int) -> Tuple[int, int]: num, n = 0, len(s) while i < n and s[i].isdigit(): @@ -113,7 +113,7 @@ def calculate(s: str) -> int: case "*": local_num *= num case "/": - # int()会实现向0取整,而//对负数会远离0取整。 + # int() performs truncation towards zero, unlike // for negatives. local_num = int(local_num / num) if i < n: diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-4-string-matching.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-4-string-matching.mdx index 270efe60..f52314bc 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-4-string-matching.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-4-string-matching.mdx @@ -2,17 +2,17 @@ sidebar_position: 62 --- -# 11.4 字符串匹配 +# 11.4 String Matching ## [28. Implement strStr()](https://leetcode.com/problems/find-the-index-of-the-first-occurrence-in-a-string/) ### Problem Description -判断一个字符串是不是另一个字符串的子字符串,并返回其位置。 +Determine whether a string is a substring of another string, and return its starting index. ### Input and Output Example -输入一个母字符串和一个子字符串,输出一个整数,表示子字符串在母字符串的位置,若不存在则返回-1。 +Input a parent string and a substring, and output an integer representing the position of the substring in the parent string. Return -1 if it doesn't exist. ``` Input: haystack = "hello", needle = "ll" @@ -21,9 +21,9 @@ Output: 2 ### Solution Explanation -使用著名的Knuth-Morris-Pratt(KMP)算法,可以在 $O(m +n)$ 时间利用动态规划完成匹配。这里我们定义 dp 数组为,dp[i] 表示 needle 中以 i 位置截止的片段(即后缀),最长可以匹配到needle 从头开始的哪个位置(即前缀)。例如,ababaca 的 dp 数组是 [-1,-1,0,1,2,-1,0],表示每个位置最长可以匹配 [无, 无, a, ab, aba, 无, a]。 +We can use the famous Knuth-Morris-Pratt (KMP) algorithm to achieve matching in $O(m + n)$ time using dynamic programming. Here we define the `dp` array where `dp[i]` represents the longest prefix of `needle` that is also a suffix ending at position `i`. For example, for `needle = "ababaca"`, the `dp` array is `[-1, -1, 0, 1, 2, -1, 0]`, indicating the longest matches: [None, None, "a", "ab", "aba", None, "a"]. -这道题比较复杂,初学者可以暂时跳过。 +This problem is complex, and beginners may skip it temporarily. @@ -35,12 +35,12 @@ vector computeDp(const string &needle) { vector dp(n, -1); for (int j = 1, k = -1; j < n; ++j) { while (k > -1 && needle[k + 1] != needle[j]) { - k = dp[k]; // 如果下一位不同,回溯到前一个前缀片段 + k = dp[k]; // If mismatch, backtrack to the previous prefix } if (needle[k + 1] == needle[j]) { - ++k; // 前缀和后缀片段相同,匹配长度加1 + ++k; // Match found, increase the match length } - dp[j] = k; // 更新前缀匹配位置 + dp[j] = k; // Update the prefix match position } return dp; } @@ -50,13 +50,13 @@ int strStr(const string &haystack, const string &needle) { vector dp = computeDp(needle); for (int i = 0, k = -1; i < m; ++i) { while (k > -1 && needle[k + 1] != haystack[i]) { - k = dp[k]; // 如果下一位不同,回溯到前一个相同片段 + k = dp[k]; // If mismatch, backtrack to the previous match } if (needle[k + 1] == haystack[i]) { - ++k; // 片段相同,匹配长度加1 + ++k; / Match found, increase the match length } if (k == n - 1) { - return i - n + 1; // 匹配结束 + return i - n + 1; // Match complete } } return -1; @@ -76,10 +76,10 @@ def computeDp(needle: str) -> List[int]: k = -1 for j in range(1, n): while k > -1 and needle[k + 1] != needle[j]: - k = dp[k] # 如果下一位不同,回溯到前一个前缀片段 + k = dp[k] # If mismatch, backtrack to the previous prefix if needle[k + 1] == needle[j]: - k += 1 # 前缀和后缀片段相同,匹配长度加1 - dp[j] = k # 更新前缀匹配位置 + k += 1 # Match found, increase the match length + dp[j] = k # Update the prefix match position return dp # Main function @@ -92,11 +92,11 @@ def strStr(haystack: str, needle: str) -> int: k = -1 for i in range(m): while k > -1 and needle[k + 1] != haystack[i]: - k = dp[k] # 如果下一位不同,回溯到前一个相同片段 + k = dp[k] # If mismatch, backtrack to the previous match if needle[k + 1] == haystack[i]: - k += 1 # 片段相同,匹配长度加1 + k += 1 # Match found, increase the match length if k == n - 1: - return i - n + 1 # 匹配结束 + return i - n + 1 # Match complete return -1 ``` diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-5-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-5-exercises.md index c6bc8c46..c0d8083e 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-5-exercises.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-5-exercises.md @@ -8,13 +8,13 @@ sidebar_position: 63 ### [409. Longest Palindrome](https://leetcode.com/problems/longest-palindrome/) -计算一组字符可以构成的回文字符串的最大长度,可以利用其它数据结构进行辅助统计。 +Calculate the maximum length of a palindrome string that can be constructed from a set of characters. Auxiliary data structures can be used for counting. --- ### [3. Longest Substring Without Repeating Characters](https://leetcode.com/problems/longest-substring-without-repeating-characters/) -计算最长无重复子字符串,同样的,可以利用其它数据结构进行辅助统计。 +Compute the length of the longest substring without repeating characters. Similarly, auxiliary data structures can be used for tracking character occurrences. --- @@ -22,10 +22,10 @@ sidebar_position: 63 ### [772. Basic Calculator III](https://leetcode.com/problems/basic-calculator-iii/) -题目 227 的 follow-up,十分推荐练习。 +A follow-up to Problem 227. Highly recommended for practice. --- ### [5. Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/) -类似于我们讲过的子序列问题,子数组或子字符串问题常常也可以用动态规划来解决。先使用动态规划写出一个 $O(n^2)$ 时间复杂度的算法,再搜索一下 Manacher’s Algorithm,它可以在 $O(n)$ 时间解决这一问题。 \ No newline at end of file +Similar to the subsequence problems discussed earlier, subarray or substring problems can often be solved using dynamic programming. Start by implementing a $O(n^2)$ solution with dynamic programming, then explore Manacher's Algorithm, which can solve the problem in $O(n)$ time. \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-1-introduction.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-1-introduction.md index 9cd88891..6f273266 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-1-introduction.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-1-introduction.md @@ -4,4 +4,4 @@ sidebar_position: 59 # 11.1 引言 -字符串可以看成是字符组成的数组。由于字符串是程序里经常需要处理的数据类型,因此有很多针对字符串处理的题目,以下是一些常见的类型。 \ No newline at end of file +字串可以視為由字元組成的陣列。由於字串是程式中經常需要處理的資料型別,因此有許多針對字串處理的題目,以下是一些常見的類型。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-2-string-comparison.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-2-string-comparison.mdx index 4d4606b1..2c82c6c2 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-2-string-comparison.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-2-string-comparison.mdx @@ -2,17 +2,17 @@ sidebar_position: 60 --- -# 11.2 字符串比较 +# 11.2 字串比較 ## [242. Valid Anagram](https://leetcode.com/problems/valid-anagram/) ### 題目描述 -判断两个字符串包含的字符是否完全相同。 +判斷兩個字串包含的字元是否完全相同。 ### 輸入輸出範例 -输入两个字符串,输出一个布尔值,表示两个字符串是否满足条件。 +輸入兩個字串,輸出一個布林值,表示兩個字串是否滿足條件。 ``` Input: s = "anagram", t = "nagaram" @@ -21,7 +21,7 @@ Output: true ### 題解 -我们可以利用哈希表或者数组统计两个数组中每个数字出现的频次,若频次相同,则说明它们包含的字符完全相同。 +我們可以利用雜湊表或陣列來統計兩個字串中每個字元出現的頻率。如果頻率相同,則說明它們包含的字元完全相同。 @@ -60,22 +60,24 @@ def isAnagram(s: str, t: str) -> bool: ### 題目描述 -判断两个字符串是否同构。同构的定义是,可以通过把一个字符串的某些相同的字符转换成另一些相同的字符,使得两个字符串相同,且两种不同的字符不能够被转换成同一种字符。 +判斷兩個字串是否同構。兩個字串同構的定義為,透過將一個字串中的某些相同字元轉換為另一組相同字元,能使得兩個字串相同,且不同的字元不能被轉換為相同的字元。 ### 輸入輸出範例 -输入两个字符串,输出一个布尔值,表示两个字符串是否满足条件。 +輸入兩個字串,輸出一個布林值,表示兩個字串是否滿足條件。 ``` Input: s = "paper", t = "title" Output: true ``` -在这个样例中,通过把 s 中的 p、a、e、r 字符转换成 t、i、l、e 字符,可以使得两个字符串相同。 +在這個例子中,將 `s` 中的 `p`、`a`、`e`、`r` 轉換為 `t`、`i`、`l`、`e`,兩個字串就可以變得相同。 ### 題解 -我们可以将问题转化一下:记录两个字符串每个位置的字符第一次出现的位置,如果两个字符串中相同位置的字符与它们第一次出现的位置一样,那么这两个字符串同构。举例来说,对于“paper”和“title”,假设我们现在遍历到第三个字符“p”和“t”,发现它们第一次出现的位置都在第一个字符,则说明目前位置满足同构。同样的,我们可以用哈希表存储,也可以用一个长度为 128 的数组(ASCII 定义下字符的总数量)。 +我們可以將問題重新表述:記錄兩個字串中每個位置的字元首次出現的位置。如果兩個字串中相同位置的字元與它們的首次出現位置相同,則這兩個字串同構。 + +舉例來說,對於 "paper" 和 "title",假設我們現在處理第三個字元 `p` 和 `t`,發現它們首次出現的位置都在第一個字元,這表示目前位置滿足同構條件。我們可以使用雜湊表進行存儲,或者用一個長度為 128 的陣列(ASCII 定義下的字元總數)。 @@ -117,22 +119,22 @@ def isIsomorphic(s: str, t: str) -> bool: ### 題目描述 -给定一个字符,求其有多少个回文子字符串。回文的定义是左右对称。 +給定一個字串,求其有多少個回文子字串。回文的定義是左右對稱。 ### 輸入輸出範例 -输入是一个字符串,输出一个整数,表示回文子字符串的数量。 +輸入是一個字串,輸出是一個整數,表示回文子字串的數量。 ``` Input: "aaa" Output: 6 ``` -六个回文子字符串分别是 ["a","a","a","aa","aa","aaa"]。 +六個回文子字串分別是 ["a", "a", "a", "aa", "aa", "aaa"]。 ### 題解 -我们可以从字符串的每个位置开始,向左向右延长,判断存在多少以当前位置为中轴的回文子字符串。 +我們可以從字串的每個位置開始,向左向右延長,判斷存在多少以當前位置為中心的回文子字串。 @@ -152,8 +154,8 @@ int extendSubstrings(string s, int l, int r) { int countSubstrings(string s) { int count = 0; for (int i = 0; i < s.length(); ++i) { - count += extendSubstrings(s, i, i); // 奇数长度 - count += extendSubstrings(s, i, i + 1); // 偶数长度 + count += extendSubstrings(s, i, i); // 奇數長度 + count += extendSubstrings(s, i, i + 1); // 偶數長度 } return count; } @@ -175,7 +177,7 @@ def extendSubstrings(s: str, l: int, r: int) -> int: # 主函式。 def countSubstrings(s: str) -> int: return sum( - # 奇数长度 + 偶数长度。 + # 奇數長度 + 偶數長度 extendSubstrings(s, i, i) + extendSubstrings(s, i, i + 1) for i in range(len(s)) ) @@ -190,22 +192,26 @@ def countSubstrings(s: str) -> int: ### 題目描述 -给定一个 0-1 字符串,求有多少非空子字符串的 0 和 1 数量相同,且 0 和 1 必须连续出现(比如 0011、1100;0101 不算)。 +給定一個 0 和 1 組成的字串,求有多少非空子字串,其 '0' 和 '1' 的數量相同,且 '0' 和 '1' 必須連續出現(例如 "0011", "1100";但 "0101" 不算有效)。 ### 輸入輸出範例 -输入是一个字符串,输出一个整数,表示满足条件的子字符串的数量。 +輸入是一個字串,輸出是一個整數,表示符合條件的子字串的數量。 ``` Input: "00110011" Output: 6 ``` -在这个样例中,六个 0 和 1 数量相同的子字符串是 ["0011","01","1100","10","0011","01"]。 +在這個範例中,六個 '0' 和 '1' 數量相同的子字串為 ["0011", "01", "1100", "10", "0011", "01"]。 ### 題解 -从左往右遍历数组,记录和当前位置数字相同且连续的长度,以及其之前连续的不同数字的长度。举例来说,对于 00110 的最后一位,我们记录的相同数字长度是 1,因为只有一个连续 0;我们记录的不同数字长度是 2,因为在 0 之前有两个连续的 1。若不同数字的连续长度大于等于当前数字的连续长度,则说明存在一个且只存在一个以当前数字结尾的满足条件的子字符串。 +從左往右遍歷字串,記錄當前字元連續出現的長度,以及其前一段不同字元的連續長度。例如對於字串 "00110" 的最後一位 '0',我們記錄的值為: +- 相同字元長度為 1,因為最後只有一個連續的 '0'; +- 不同字元長度為 2,因為在最後的 '0' 之前,有兩個連續的 '1'。 + +若不同字元的連續長度大於等於當前字元的連續長度,則說明存在一個且僅一個以當前字元結尾、符合條件的子字串。 @@ -256,22 +262,27 @@ def countBinarySubstrings(s: str) -> int: ### 題目描述 -给定一个包括字母和左右括号的字符串,求最少要移除多少个括号才能使其合法。 +給定一個包含字母與括號的字串,求最少移除多少括號才能使其合法。 ### 輸入輸出範例 -输入是一个字符串,输出是合法且长度最长的移除结果。 +輸入是一個字串,輸出是一個合法且長度最長的結果字串。 ``` Input: s = "lee(t(c)o)de)" Output: "lee(t(c)o)de" ``` -返回 lee(t(co)de) 或 lee(t(c)ode) 也算正确。 +返回 "lee(t(co)de)" 或 "lee(t(c)ode)" 也算正確。 ### 題解 -因为只有一种括号,所以我们并不一定利用栈来统计,可以直接用一个临时变量统计在当前位置时,左括号比右括号多出现多少次。如果在遍历过程中出现负数,则需要移除多余的右括号。如果遍历结束时临时变量为正数,则需要从右到左移除多余的左括号。这里我们使用了一个小技巧,先标记待删除位置,最后一起移除。 +因為只有一種括號類型,因此我們不一定需要用堆疊來統計括號對應情況。相反,我們可以使用一個臨時變數來記錄當前位置時左括號比右括號多出多少個: + +- 如果在遍歷過程中,這個數值變為負數,說明有多餘的右括號需要移除。 +- 若遍歷結束時這個值為正數,則說明有多餘的左括號需要移除,這可以透過從右到左的遍歷完成。 + +一個小技巧是先標記待刪除的位置,最後一次性移除這些位置的括號。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-3-string-interpretation.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-3-string-interpretation.mdx index 7c9ef3ee..45cf997e 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-3-string-interpretation.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-3-string-interpretation.mdx @@ -2,36 +2,36 @@ sidebar_position: 61 --- -# 11.3 字符串理解 +# 11.3 字串解析 ## [227. Basic Calculator II](https://leetcode.com/problems/basic-calculator-ii/) ### 題目描述 -给定一个包含加减乘除整数运算的字符串,求其运算的整数值结果。如果除不尽则向 0 取整。 +給定一個包含加減乘除整數運算的字串,計算其運算結果。如果除不盡則向 0 取整。 ### 輸入輸出範例 -输入是一个合法的运算字符串,输出是一个整数,表示其运算结果。 +輸入是一個合法的運算字串,輸出是一個整數,表示其運算結果。 ``` Input: " 3+5 / 2 " Output: 5 ``` -在这个样例中,因为除法的优先度高于加法,所以结果是 5 而非 4。 +在這個例子中,因為除法的優先級高於加法,所以結果是 5 而不是 4。 ### 題解 -如果我们在字符串左边加上一个加号,可以证明其并不改变运算结果,且字符串可以分割成多个 < 一个运算符,一个数字 > 对子的形式;这样一来我们就可以从左往右处理了。由于乘除的优先级高于加减,因此我们需要使用一个中间变量来存储高优先度的运算结果。 +如果我們在字串左邊加上一個 `+` 號,可以證明其並不改變運算結果,且字串可以分割成多個 `<運算符, 數字>` 的配對形式;這樣一來我們就可以從左到右處理。由於乘除的優先級高於加減,因此我們需要使用一個中間變數來存儲高優先度的運算結果。 -此类型题也考察很多细节处理,如无运算符的情况,和多个空格的情况等等。 +此類型題目也考驗很多細節處理,例如沒有運算符的情況,以及多個空格的情況等等。 ```cpp -// 辅函数 - parse从位置i开始的一个数字。 +// 輔助函數 - parse 從位置 i 開始的一個數字。 int parseNum(const string& s, int& i) { int num = 0, n = s.length(); while (i < n && isdigit(s[i])) { @@ -81,8 +81,8 @@ int calculate(string s) { ```py from typing import Tuple -# 辅函数 - parse从位置i开始的一个数字。 -# 返回(数字, 下一个i位置) +# 輔助函數 - parse 從位置 i 開始的一個數字。 +# 返回 (數字, 下一個 i 位置) def parseNum(s: str, i: int) -> Tuple[int, int]: num, n = 0, len(s) while i < n and s[i].isdigit(): @@ -113,7 +113,7 @@ def calculate(s: str) -> int: case "*": local_num *= num case "/": - # int()会实现向0取整,而//对负数会远离0取整。 + # int() 會實現向 0 取整,而 // 對負數會遠離 0 取整。 local_num = int(local_num / num) if i < n: diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-4-string-matching.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-4-string-matching.mdx index 22d6a833..d85c8b22 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-4-string-matching.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-4-string-matching.mdx @@ -2,17 +2,17 @@ sidebar_position: 62 --- -# 11.4 字符串匹配 +# 11.4 字串匹配 ## [28. Implement strStr()](https://leetcode.com/problems/find-the-index-of-the-first-occurrence-in-a-string/) ### 題目描述 -判断一个字符串是不是另一个字符串的子字符串,并返回其位置。 +判斷一個字串是否為另一個字串的子字串,並返回其位置。 ### 輸入輸出範例 -输入一个母字符串和一个子字符串,输出一个整数,表示子字符串在母字符串的位置,若不存在则返回-1。 +輸入一個母字串和一個子字串,輸出一個整數,表示子字串在母字串中的位置,若不存在則返回 -1。 ``` Input: haystack = "hello", needle = "ll" @@ -21,9 +21,9 @@ Output: 2 ### 題解 -使用著名的Knuth-Morris-Pratt(KMP)算法,可以在 $O(m +n)$ 时间利用动态规划完成匹配。这里我们定义 dp 数组为,dp[i] 表示 needle 中以 i 位置截止的片段(即后缀),最长可以匹配到needle 从头开始的哪个位置(即前缀)。例如,ababaca 的 dp 数组是 [-1,-1,0,1,2,-1,0],表示每个位置最长可以匹配 [无, 无, a, ab, aba, 无, a]。 +使用著名的 Knuth-Morris-Pratt(KMP)演算法,可以在 $O(m + n)$ 時間內利用動態規劃完成匹配。這裡我們定義 `dp` 陣列為,`dp[i]` 表示 `needle` 中以位置 `i` 結尾的片段(即後綴),最長可以匹配到 `needle` 的起始位置(即前綴)。例如,對於 `needle = "ababaca"`,`dp` 陣列為 `[-1, -1, 0, 1, 2, -1, 0]`,表示每個位置的最大匹配 [無, 無, a, ab, aba, 無, a]。 -这道题比较复杂,初学者可以暂时跳过。 +這道題比較複雜,初學者可以暫時跳過。 @@ -35,12 +35,12 @@ vector computeDp(const string &needle) { vector dp(n, -1); for (int j = 1, k = -1; j < n; ++j) { while (k > -1 && needle[k + 1] != needle[j]) { - k = dp[k]; // 如果下一位不同,回溯到前一个前缀片段 + k = dp[k]; // 如果下一位不同,回溯到前一個前綴片段 } if (needle[k + 1] == needle[j]) { - ++k; // 前缀和后缀片段相同,匹配长度加1 + ++k; // 前綴和後綴片段相同,匹配長度加 1 } - dp[j] = k; // 更新前缀匹配位置 + dp[j] = k; // 更新前綴匹配位置 } return dp; } @@ -50,13 +50,13 @@ int strStr(const string &haystack, const string &needle) { vector dp = computeDp(needle); for (int i = 0, k = -1; i < m; ++i) { while (k > -1 && needle[k + 1] != haystack[i]) { - k = dp[k]; // 如果下一位不同,回溯到前一个相同片段 + k = dp[k]; // 如果下一位不同,回溯到前一個相同片段 } if (needle[k + 1] == haystack[i]) { - ++k; // 片段相同,匹配长度加1 + ++k; // 片段相同,匹配長度加 1 } if (k == n - 1) { - return i - n + 1; // 匹配结束 + return i - n + 1; // 匹配完成 } } return -1; @@ -76,10 +76,10 @@ def computeDp(needle: str) -> List[int]: k = -1 for j in range(1, n): while k > -1 and needle[k + 1] != needle[j]: - k = dp[k] # 如果下一位不同,回溯到前一个前缀片段 + k = dp[k] # 如果下一位不同,回溯到前一個前綴片段 if needle[k + 1] == needle[j]: - k += 1 # 前缀和后缀片段相同,匹配长度加1 - dp[j] = k # 更新前缀匹配位置 + k += 1 # 前綴和後綴片段相同,匹配長度加 1 + dp[j] = k # 更新前綴匹配位置 return dp # 主函式。 @@ -92,11 +92,11 @@ def strStr(haystack: str, needle: str) -> int: k = -1 for i in range(m): while k > -1 and needle[k + 1] != haystack[i]: - k = dp[k] # 如果下一位不同,回溯到前一个相同片段 + k = dp[k] # 如果下一位不同,回溯到前一個相同片段 if needle[k + 1] == haystack[i]: - k += 1 # 片段相同,匹配长度加1 + k += 1 # 片段相同,匹配長度加 1 if k == n - 1: - return i - n + 1 # 匹配结束 + return i - n + 1 # 匹配完成 return -1 ``` diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-5-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-5-exercises.md index c8a923e0..6576e517 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-5-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-5-exercises.md @@ -8,13 +8,13 @@ sidebar_position: 63 ### [409. Longest Palindrome](https://leetcode.com/problems/longest-palindrome/) -计算一组字符可以构成的回文字符串的最大长度,可以利用其它数据结构进行辅助统计。 +計算一組字符可以構成的回文字符串的最大長度,可以使用其他資料結構進行輔助統計。 --- ### [3. Longest Substring Without Repeating Characters](https://leetcode.com/problems/longest-substring-without-repeating-characters/) -计算最长无重复子字符串,同样的,可以利用其它数据结构进行辅助统计。 +計算最長無重複子字符串的長度,同樣可以使用其他資料結構進行輔助統計。 --- @@ -22,10 +22,10 @@ sidebar_position: 63 ### [772. Basic Calculator III](https://leetcode.com/problems/basic-calculator-iii/) -题目 227 的 follow-up,十分推荐练习。 +題目 227 的 follow-up,非常推薦練習。 --- ### [5. Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/) -类似于我们讲过的子序列问题,子数组或子字符串问题常常也可以用动态规划来解决。先使用动态规划写出一个 $O(n^2)$ 时间复杂度的算法,再搜索一下 Manacher’s Algorithm,它可以在 $O(n)$ 时间解决这一问题。 \ No newline at end of file +類似於我們之前講過的子序列問題,子陣列或子字符串問題常常也可以用動態規劃來解決。先用動態規劃寫出一個 $O(n^2)$ 時間複雜度的解法,然後搜索一下 Manacher’s Algorithm,它可以在 $O(n)$ 時間內解決這個問題。 \ No newline at end of file From a8443e40e1675943bed1b37aecfc0fdcba79680d Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Wed, 27 Nov 2024 18:35:06 +0100 Subject: [PATCH 32/49] i18n chapter 12 --- .../12-1-data-structure-introduction.md | 11 +++++--- .../12-2-basic-linked-list-operations.mdx | 28 ++++++++++--------- .../12-3-other-linked-list-techniques.mdx | 21 ++++++++------ .../current/12-linked-lists/12-4-exercises.md | 8 +++--- .../12-1-data-structure-introduction.md | 11 +++++--- .../12-2-basic-linked-list-operations.mdx | 26 +++++++++-------- .../12-3-other-linked-list-techniques.mdx | 21 ++++++++------ .../current/12-linked-lists/12-4-exercises.md | 8 +++--- 8 files changed, 75 insertions(+), 59 deletions(-) diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-1-data-structure-introduction.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-1-data-structure-introduction.md index b298b78e..466b6169 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-1-data-structure-introduction.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-1-data-structure-introduction.md @@ -2,9 +2,9 @@ sidebar_position: 64 --- -# 12.1 数据结构介绍 +# 12.1 Introduction to Data Structures -(单向)`链表`是由节点和指针构成的数据结构,每个节点存有一个值,和一个指向下一个节点的指针,因此很多链表问题可以用递归来处理。不同于数组,链表并不能直接获取任意节点的值,必须要通过指针找到该节点后才能获取其值。同理,在未遍历到链表结尾时,我们也无法知道链表的长度,除非依赖其他数据结构储存长度。LeetCode 默认的链表表示方法如下。 +A (singly) `linked list` is a data structure composed of nodes and pointers. Each node contains a value and a pointer to the next node. As a result, many linked list problems can be solved using recursion. Unlike arrays, a linked list cannot directly access the value of any node; it must traverse through pointers to reach the desired node. Similarly, the length of a linked list cannot be determined unless it is fully traversed or tracked using another data structure. LeetCode’s default representation of a linked list is as follows. @@ -31,10 +31,13 @@ class ListNode: -由于在进行链表操作时,尤其是删除节点时,经常会因为对当前节点进行操作而导致内存或指针出现问题。有两个小技巧可以解决这个问题:一是尽量处理当前节点的下一个节点而非当前节点本身,二是建立一个虚拟节点 (dummy node),使其指向当前链表的头节点,这样即使原链表所有节点全被删除,也会有一个 dummy 存在,返回 dummy->next 即可。 +When performing operations on a linked list, especially when deleting nodes, issues with memory or pointers often arise due to directly modifying the current node. Two techniques can help mitigate these problems: + +1. Try to operate on the next node rather than the current node itself. +2. Create a dummy node that points to the head of the current linked list. This ensures that even if all nodes in the original list are deleted, the dummy node persists, and you can safely return `dummy->next`. :::warning - 一般来说,算法题不需要删除内存。在刷 LeetCode 的时候,如果想要删除一个节点,可以直接进行指针操作而无需回收内存。实际做软件工程时,对于无用的内存,笔者建议尽量显式回收,或利用智能指针。 +In most algorithm problems, explicit memory deletion is unnecessary. When solving LeetCode problems, you can simply adjust pointers without deallocating memory. However, in real-world software engineering, it is recommended to explicitly free unused memory or use smart pointers to manage it efficiently. ::: \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-2-basic-linked-list-operations.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-2-basic-linked-list-operations.mdx index 42dd9ad3..80920253 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-2-basic-linked-list-operations.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-2-basic-linked-list-operations.mdx @@ -2,17 +2,17 @@ sidebar_position: 65 --- -# 12.2 链表的基本操作 +# 12.2 Basic Operations on Linked Lists ## [206. Reverse Linked List](https://leetcode.com/problems/reverse-linked-list/) ### Problem Description -翻转一个链表。 +Reverse a linked list. ### Input and Output Example -输入一个链表,输出该链表翻转后的结果。 +Input a linked list, output the reversed linked list. ``` Input: 1->2->3->4->5->nullptr @@ -21,9 +21,9 @@ Output: 5->4->3->2->1->nullptr ### Solution Explanation -链表翻转是非常基础也一定要掌握的技能。我们提供了两种写法——递归和非递归。建议你同时掌握这两种写法。 +Reversing a linked list is a fundamental skill that must be mastered. We provide two approaches—recursive and iterative. It's recommended to learn both. -递归的写法为: +Recursive Approach: @@ -57,7 +57,7 @@ def reverseList( -非递归的写法为: +The non-recursive implementation is as follows: @@ -97,11 +97,12 @@ def reverseList(head: Optional[ListNode]) -> Optional[ListNode]: ### Problem Description -给定两个增序的链表,试将其合并成一个增序的链表。 +Given two sorted linked lists, merge them into one sorted linked list. ### Input and Output Example -输入两个链表,输出一个链表,表示两个链表合并的结果。 +Input: Two linked lists. +Output: A linked list representing the merged result. ``` Input: 1->2->4, 1->3->4 @@ -110,7 +111,8 @@ Output: 1->1->2->3->4->4 ### Solution Explanation -我们提供了递归和非递归,共两种写法。递归的写法为: +We provide both recursive and non-recursive implementations. +The recursive implementation is as follows: @@ -152,7 +154,7 @@ def mergeTwoLists( -非递归的写法为: +The non-recursive implementation is as follows: @@ -207,11 +209,11 @@ def mergeTwoLists( ### Problem Description -给定一个矩阵,交换每个相邻的一对节点。 +Given a linked list, swap every two adjacent nodes. ### Input and Output Example -输入一个链表,输出该链表交换后的结果。 +Input a linked list, output the linked list after swapping nodes in pairs. ``` Input: 1->2->3->4 @@ -220,7 +222,7 @@ Output: 2->1->4->3 ### Solution Explanation -利用指针进行交换操作,没有太大难度,但一定要细心。 +Use pointers to perform the swap operation. The problem is not very difficult, but requires careful attention. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-3-other-linked-list-techniques.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-3-other-linked-list-techniques.mdx index c0e4717d..3c2843b8 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-3-other-linked-list-techniques.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-3-other-linked-list-techniques.mdx @@ -2,17 +2,17 @@ sidebar_position: 66 --- -# 12.3 其它链表技巧 +# 12.3 Other Linked List Techniques ## [160. Intersection of Two Linked Lists](https://leetcode.com/problems/intersection-of-two-linked-lists/) ### Problem Description -给定两个链表,判断它们是否相交于一点,并求这个相交节点。 +Given two linked lists, determine if they intersect at a point and find the intersecting node. ### Input and Output Example -输入是两条链表,输出是一个节点。如无相交节点,则返回一个空节点。 +Input consists of two linked lists, output is a node. If there is no intersection, return `nullptr`. ``` Input: @@ -28,7 +28,9 @@ Output: c1 ### Solution Explanation -假设链表 A 的头节点到相交点的距离是 a,链表 B 的头节点到相交点的距离是 b,相交点到链表终点的距离为 c。我们使用两个指针,分别指向两个链表的头节点,并以相同的速度前进,若到达链表结尾,则移动到另一条链表的头节点继续前进。按照这种前进方法,两个指针会在 a + b + c 次前进后同时到达相交节点。 +Assume the distance from the head of linked list A to the intersection is `a`, the distance from the head of linked list B to the intersection is `b`, and the distance from the intersection to the end of the lists is `c`. + +We use two pointers starting at the heads of the two linked lists and move them forward at the same speed. When a pointer reaches the end of a list, it continues from the head of the other list. With this approach, both pointers will meet at the intersection node after `a + b + c` steps. @@ -67,11 +69,12 @@ def getIntersectionNode( ### Problem Description -以 $O(1)$ 的空间复杂度,判断链表是否回文。 +Determine if a linked list is a palindrome using $O(1)$ space complexity. ### Input and Output Example -输入是一个链表,输出是一个布尔值,表示链表是否回文。 +Input: A linked list. +Output: A boolean indicating whether the linked list is a palindrome. ``` Input: 1->2->3->2->1 @@ -80,7 +83,7 @@ Output: true ### Solution Explanation -先使用快慢指针找到链表中点,再把链表切成两半;然后把后半段翻转;最后比较两半是否相等。 +First, use a slow and fast pointer to find the middle of the linked list. Then split the list into two halves. Reverse the second half and compare the two halves for equality. @@ -95,7 +98,7 @@ bool isPalindrome(ListNode* head) { slow = slow->next; fast = fast->next->next; } - slow->next = reverseList(slow->next); // 见题目206 + slow->next = reverseList(slow->next); // Refer to problem 206. slow = slow->next; while (slow != nullptr) { if (head->val != slow->val) { @@ -122,7 +125,7 @@ def isPalindrome(head: Optional[ListNode]) -> bool: slow = slow.next fast = fast.next.next - slow.next = reverseList(slow.next) # 见题目206 + slow.next = reverseList(slow.next) # Refer to problem 206. slow = slow.next while slow is not None: diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-4-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-4-exercises.md index 29920cf9..c73fb065 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-4-exercises.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-4-exercises.md @@ -8,19 +8,19 @@ sidebar_position: 67 ### [83. Remove Duplicates from Sorted List](https://leetcode.com/problems/remove-duplicates-from-sorted-list/) -虽然 LeetCode 没有强制要求,但是我们仍然建议你回收内存,尤其当题目要求你删除的时候。 +Although LeetCode doesn't enforce it, we still recommend freeing memory, especially when the problem requires deletion. --- ### [328. Odd Even Linked List](https://leetcode.com/problems/odd-even-linked-list/) -这道题其实很简单,千万不要把题目复杂化。 +This problem is actually quite simple; don’t overcomplicate it. --- ### [19. Remove Nth Node From End of List](https://leetcode.com/problems/remove-nth-node-from-end-of-list/) -既然我们可以使用快慢指针找到中点,也可以利用类似的方法找到倒数第 n 个节点,无需遍历第二遍。 +Since we can use the fast and slow pointer technique to find the midpoint, we can also use a similar approach to locate the nth node from the end, without a second traversal. --- @@ -28,4 +28,4 @@ sidebar_position: 67 ### [148. Sort List](https://leetcode.com/problems/sort-list/) -利用快慢指针找到链表中点后,可以对链表进行归并排序。 \ No newline at end of file +After using fast and slow pointers to find the midpoint of the linked list, you can perform merge sort on it. diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-1-data-structure-introduction.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-1-data-structure-introduction.md index b298b78e..d62d5040 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-1-data-structure-introduction.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-1-data-structure-introduction.md @@ -2,9 +2,9 @@ sidebar_position: 64 --- -# 12.1 数据结构介绍 +# 12.1 資料結構介紹 -(单向)`链表`是由节点和指针构成的数据结构,每个节点存有一个值,和一个指向下一个节点的指针,因此很多链表问题可以用递归来处理。不同于数组,链表并不能直接获取任意节点的值,必须要通过指针找到该节点后才能获取其值。同理,在未遍历到链表结尾时,我们也无法知道链表的长度,除非依赖其他数据结构储存长度。LeetCode 默认的链表表示方法如下。 +(單向)`鏈結串列`是由節點與指標構成的資料結構,每個節點存有一個值,以及一個指向下一個節點的指標。因此,許多鏈結串列問題可以使用遞迴來處理。不同於陣列,鏈結串列無法直接獲取任意節點的值,必須透過指標找到該節點後才能取得其值。同樣地,在未遍歷至鏈結串列結尾前,我們無法得知其長度,除非依賴其他資料結構來儲存長度。LeetCode 預設的鏈結串列表示方法如下。 @@ -31,10 +31,13 @@ class ListNode: -由于在进行链表操作时,尤其是删除节点时,经常会因为对当前节点进行操作而导致内存或指针出现问题。有两个小技巧可以解决这个问题:一是尽量处理当前节点的下一个节点而非当前节点本身,二是建立一个虚拟节点 (dummy node),使其指向当前链表的头节点,这样即使原链表所有节点全被删除,也会有一个 dummy 存在,返回 dummy->next 即可。 +由於在進行鏈結串列操作時,特別是刪除節點時,經常因為直接操作當前節點而導致記憶體或指標出現問題。有兩個小技巧可以解決這個問題: + +1. 儘量操作當前節點的下一個節點,而非當前節點本身。 +2. 建立一個虛擬節點 (dummy node),使其指向當前鏈結串列的頭節點。這樣即使原鏈結串列中的所有節點全被刪除,虛擬節點依然存在,最終返回 `dummy->next` 即可。 :::warning - 一般来说,算法题不需要删除内存。在刷 LeetCode 的时候,如果想要删除一个节点,可以直接进行指针操作而无需回收内存。实际做软件工程时,对于无用的内存,笔者建议尽量显式回收,或利用智能指针。 +一般來說,演算法題不需要釋放記憶體。在刷 LeetCode 的時候,若需要刪除一個節點,可以直接進行指標操作而無需回收記憶體。但在實際軟體工程中,對於無用的記憶體,建議盡量顯式釋放,或者使用智能指標進行管理。 ::: \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-2-basic-linked-list-operations.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-2-basic-linked-list-operations.mdx index 242e7e95..1c85be5d 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-2-basic-linked-list-operations.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-2-basic-linked-list-operations.mdx @@ -8,11 +8,11 @@ sidebar_position: 65 ### 題目描述 -翻转一个链表。 +翻轉一個鏈結串列。 ### 輸入輸出範例 -输入一个链表,输出该链表翻转后的结果。 +輸入一個鏈結串列,輸出該鏈結串列翻轉後的結果。 ``` Input: 1->2->3->4->5->nullptr @@ -21,9 +21,9 @@ Output: 5->4->3->2->1->nullptr ### 題解 -链表翻转是非常基础也一定要掌握的技能。我们提供了两种写法——递归和非递归。建议你同时掌握这两种写法。 +鏈結串列翻轉是非常基礎也必須掌握的技能。我們提供了兩種寫法——遞迴和非遞迴。建議同時掌握這兩種寫法。 -递归的写法为: +遞迴的寫法為: @@ -57,7 +57,7 @@ def reverseList( -非递归的写法为: +非遞迴的寫法為: @@ -97,11 +97,12 @@ def reverseList(head: Optional[ListNode]) -> Optional[ListNode]: ### 題目描述 -给定两个增序的链表,试将其合并成一个增序的链表。 +給定兩個遞增排序的鏈表,將它們合併成一個遞增排序的鏈表。 ### 輸入輸出範例 -输入两个链表,输出一个链表,表示两个链表合并的结果。 +輸入:兩個鏈表。 +輸出:一個鏈表,表示合併的結果。 ``` Input: 1->2->4, 1->3->4 @@ -110,7 +111,8 @@ Output: 1->1->2->3->4->4 ### 題解 -我们提供了递归和非递归,共两种写法。递归的写法为: +我們提供遞迴與非遞迴兩種寫法。 +遞迴的寫法如下: @@ -152,7 +154,7 @@ def mergeTwoLists( -非递归的写法为: +非遞迴的寫法為: @@ -207,11 +209,11 @@ def mergeTwoLists( ### 題目描述 -给定一个矩阵,交换每个相邻的一对节点。 +給定一個鏈表,交換每一對相鄰的節點。 ### 輸入輸出範例 -输入一个链表,输出该链表交换后的结果。 +輸入一個鏈表,輸出交換後的鏈表。 ``` Input: 1->2->3->4 @@ -220,7 +222,7 @@ Output: 2->1->4->3 ### 題解 -利用指针进行交换操作,没有太大难度,但一定要细心。 +使用指標進行交換操作,題目難度不高,但需要細心。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-3-other-linked-list-techniques.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-3-other-linked-list-techniques.mdx index a5c8ed72..9a253ec6 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-3-other-linked-list-techniques.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-3-other-linked-list-techniques.mdx @@ -2,17 +2,17 @@ sidebar_position: 66 --- -# 12.3 其它链表技巧 +# 12.3 其他鏈結串列技巧 ## [160. Intersection of Two Linked Lists](https://leetcode.com/problems/intersection-of-two-linked-lists/) ### 題目描述 -给定两个链表,判断它们是否相交于一点,并求这个相交节点。 +給定兩個鏈結串列,判斷它們是否在某一個節點相交,並找出相交的節點。 ### 輸入輸出範例 -输入是两条链表,输出是一个节点。如无相交节点,则返回一个空节点。 +輸入為兩條鏈結串列,輸出為相交的節點。如果沒有相交節點,則回傳 `nullptr`。 ``` Input: @@ -28,7 +28,9 @@ Output: c1 ### 題解 -假设链表 A 的头节点到相交点的距离是 a,链表 B 的头节点到相交点的距离是 b,相交点到链表终点的距离为 c。我们使用两个指针,分别指向两个链表的头节点,并以相同的速度前进,若到达链表结尾,则移动到另一条链表的头节点继续前进。按照这种前进方法,两个指针会在 a + b + c 次前进后同时到达相交节点。 +假設鏈結串列 A 的起點到相交點的距離是 `a`,鏈結串列 B 的起點到相交點的距離是 `b`,而相交點到串列尾端的距離為 `c`。 + +我們可以用兩個指標,分別從兩個鏈結串列的起點開始,並以相同的速度向前移動。如果指標到達串列的尾端,就切換到另一個鏈結串列的起點繼續移動。透過這種方式,兩個指標在經過 `a + b + c` 次移動後,會同時抵達相交的節點。 @@ -67,11 +69,11 @@ def getIntersectionNode( ### 題目描述 -以 $O(1)$ 的空间复杂度,判断链表是否回文。 +以 $O(1)$ 的空間複雜度,判斷鏈結串列是否為回文。 ### 輸入輸出範例 -输入是一个链表,输出是一个布尔值,表示链表是否回文。 +輸入是一個鏈結串列,輸出是一個布林值,表示鏈結串列是否為回文。 ``` Input: 1->2->3->2->1 @@ -80,7 +82,8 @@ Output: true ### 題解 -先使用快慢指针找到链表中点,再把链表切成两半;然后把后半段翻转;最后比较两半是否相等。 +先使用快慢指標找到鏈結串列的中點,再把鏈結串列切成兩半;然後把後半段翻轉;最後比較兩半是否相等。 + @@ -95,7 +98,7 @@ bool isPalindrome(ListNode* head) { slow = slow->next; fast = fast->next->next; } - slow->next = reverseList(slow->next); // 见题目206 + slow->next = reverseList(slow->next); // 見題目206 slow = slow->next; while (slow != nullptr) { if (head->val != slow->val) { @@ -122,7 +125,7 @@ def isPalindrome(head: Optional[ListNode]) -> bool: slow = slow.next fast = fast.next.next - slow.next = reverseList(slow.next) # 见题目206 + slow.next = reverseList(slow.next) # 見題目206 slow = slow.next while slow is not None: diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-4-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-4-exercises.md index 2a972dbd..c3550fca 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-4-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-4-exercises.md @@ -8,19 +8,19 @@ sidebar_position: 67 ### [83. Remove Duplicates from Sorted List](https://leetcode.com/problems/remove-duplicates-from-sorted-list/) -虽然 LeetCode 没有强制要求,但是我们仍然建议你回收内存,尤其当题目要求你删除的时候。 +雖然 LeetCode 並未強制要求,但我們仍然建議回收記憶體,特別是在題目要求刪除節點時。 --- ### [328. Odd Even Linked List](https://leetcode.com/problems/odd-even-linked-list/) -这道题其实很简单,千万不要把题目复杂化。 +這道題其實很簡單,千萬不要把題目複雜化。 --- ### [19. Remove Nth Node From End of List](https://leetcode.com/problems/remove-nth-node-from-end-of-list/) -既然我们可以使用快慢指针找到中点,也可以利用类似的方法找到倒数第 n 个节点,无需遍历第二遍。 +既然可以使用快慢指針找到鏈表的中點,也可以利用類似的方法找到倒數第 N 個節點,無需再次遍歷。 --- @@ -28,4 +28,4 @@ sidebar_position: 67 ### [148. Sort List](https://leetcode.com/problems/sort-list/) -利用快慢指针找到链表中点后,可以对链表进行归并排序。 \ No newline at end of file +利用快慢指針找到鏈表的中點後,可以對鏈表進行合併排序。 \ No newline at end of file From 0aea05688ca0f6f04187361dc1dc796b0812fa62 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Wed, 27 Nov 2024 21:36:32 +0100 Subject: [PATCH 33/49] i18n chapter 13 --- .../12-1-data-structure-introduction.md | 2 +- .../13-1-data-structure-introduction.mdx | 7 +-- .../current/13-trees/13-2-tree-recursion.mdx | 62 +++++++++++-------- .../13-trees/13-3-level-order-traversal.mdx | 10 +-- ...4-preorder-inorder-postorder-traversal.mdx | 31 ++++++---- .../13-trees/13-5-binary-search-tree.mdx | 25 ++++---- .../current/13-trees/13-6-trie.mdx | 14 ++--- .../current/13-trees/13-7-exercises.md | 36 +++++------ .../13-1-data-structure-introduction.mdx | 7 +-- .../current/13-trees/13-2-tree-recursion.mdx | 62 +++++++++++-------- .../13-trees/13-3-level-order-traversal.mdx | 10 +-- ...4-preorder-inorder-postorder-traversal.mdx | 32 ++++++---- .../13-trees/13-5-binary-search-tree.mdx | 26 ++++---- .../current/13-trees/13-6-trie.mdx | 14 ++--- .../current/13-trees/13-7-exercises.md | 36 +++++------ 15 files changed, 207 insertions(+), 167 deletions(-) diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-1-data-structure-introduction.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-1-data-structure-introduction.md index 466b6169..a0c1c3ef 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-1-data-structure-introduction.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-1-data-structure-introduction.md @@ -2,7 +2,7 @@ sidebar_position: 64 --- -# 12.1 Introduction to Data Structures +# 12.1 Data Structure Introduction A (singly) `linked list` is a data structure composed of nodes and pointers. Each node contains a value and a pointer to the next node. As a result, many linked list problems can be solved using recursion. Unlike arrays, a linked list cannot directly access the value of any node; it must traverse through pointers to reach the desired node. Similarly, the length of a linked list cannot be determined unless it is fully traversed or tracked using another data structure. LeetCode’s default representation of a linked list is as follows. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-1-data-structure-introduction.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-1-data-structure-introduction.mdx index 3d50814f..f7af25dc 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-1-data-structure-introduction.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-1-data-structure-introduction.mdx @@ -2,10 +2,9 @@ sidebar_position: 68 --- -# 13.1 数据结构介绍 - -作为(单)链表的升级版,我们通常接触的树都是`二叉树`(binary tree),即每个节点最多有两个子节点;且除非题目说明,默认树中不存在循环结构。LeetCode 默认的树表示方法如下。 +# 13.1 Data Structure Introduction +As an upgraded version of the (single) linked list, the trees we commonly encounter are typically `binary trees`, where each node has at most two child nodes. Unless otherwise specified, trees are assumed to have no circular structures. LeetCode's default representation of trees is as follows: @@ -34,4 +33,4 @@ class TreeNode: -可以看出,其与链表的主要差别就是多了一个子节点的指针。 \ No newline at end of file +It can be seen that the primary difference compared to a linked list is the addition of a pointer for a second child node. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-2-tree-recursion.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-2-tree-recursion.mdx index 8351caa5..f7fa7117 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-2-tree-recursion.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-2-tree-recursion.mdx @@ -2,21 +2,21 @@ sidebar_position: 69 --- -# 13.2 树的递归 +# 13.2 Tree Recursion -对于一些简单的递归题,某些 LeetCode 达人喜欢写 one-line code,即用一行代码解决问题。我们也会展示一些这样的代码,但是对于新手,笔者仍然建议您使用多行的 if-else 判断语句。 +For simple recursion problems, some LeetCode experts prefer to write one-line code, solving problems with a single line. While we will showcase such solutions, beginners are still advised to use multi-line if-else statements. -在很多时候,树递归的写法与深度优先搜索的递归写法相同,因此本书不会区分二者。 +In many cases, the recursive implementation for trees is similar to the recursive implementation for depth-first search. Hence, this book does not differentiate between the two. ## [104. Maximum Depth of Binary Tree](https://leetcode.com/problems/maximum-depth-of-binary-tree/) ### Problem Description -求一个二叉树的最大深度。 +Find the maximum depth of a binary tree. ### Input and Output Example -输入是一个二叉树,输出是一个整数,表示该树的最大深度。 +The input is a binary tree, and the output is an integer representing the maximum depth of the tree. ``` Input: @@ -30,7 +30,7 @@ Output: 3 ### Solution Explanation -利用递归,我们可以很方便地求得最大深度。 +Using recursion, we can easily determine the maximum depth. @@ -62,11 +62,11 @@ def maxDepth(root: Optional[TreeNode]) -> int: ### Problem Description -判断一个二叉树是否平衡。树平衡的定义是,对于树上的任意节点,其两侧节点的最大深度的差值不得大于 1。 +Determine whether a binary tree is balanced. A balanced tree is defined as a tree in which the maximum depth difference between any two child nodes of a node is no greater than 1. ### Input and Output Example -输入是一个二叉树,输出一个布尔值,表示树是否平衡。 +The input is a binary tree, and the output is a boolean indicating whether the tree is balanced. ``` Input: @@ -82,7 +82,10 @@ Output: false ### Solution Explanation -解法类似于求树的最大深度,但有两个不同的地方:一是我们需要先处理子树的深度再进行比较,二是如果我们在处理子树时发现其已经不平衡了,则可以返回一个-1,使得所有其长辈节点可以避免多余的判断(本题的判断比较简单,做差后取绝对值即可;但如果此处是一个开销较大的比较过程,则避免重复判断可以节省大量的计算时间)。 +The solution is similar to calculating the maximum depth of a tree but with two key differences: + +1. The depth of the subtrees must be calculated first before performing the comparison. +2. If an imbalance is detected while processing a subtree, return -1 immediately to signal imbalance. This allows ancestor nodes to avoid redundant checks. (In this problem, determining imbalance is straightforward by taking the absolute difference, but avoiding redundant computations is crucial in scenarios involving more costly comparisons.) @@ -132,11 +135,11 @@ def isBalanced(root: Optional[TreeNode]) -> bool: ### Problem Description -求一个二叉树的最长直径。直径的定义是二叉树上任意两节点之间的无向距离。 +Find the longest diameter of a binary tree. The diameter is defined as the undirected distance between any two nodes in the binary tree. ### Input and Output Example -输入是一个二叉树,输出一个整数,表示最长直径。 +Input is a binary tree, and output is an integer representing the longest diameter. ``` Input: @@ -148,11 +151,13 @@ Input: Output: 3 ``` -在这个样例中,最长直径是 [4,2,1,3] 和 [5,2,1,3]。 +In this example, the longest diameter is [4,2,1,3] and [5,2,1,3]. ### Solution Explanation -同样的,我们可以利用递归来处理树。解题时要注意,在我们处理某个子树时,我们更新的最长直径值和递归返回的值是不同的。这是因为待更新的最长直径值是经过该子树根节点的最长直径(即两侧长度);而函数返回值是以该子树根节点为端点的最长直径值(即一侧长度),使用这样的返回值才可以通过递归更新父节点的最长直径值)。 +We can use recursion to solve this problem. It's important to note that when processing a subtree, the updated longest diameter and the returned value from the recursion are different. + +The updated longest diameter refers to the diameter passing through the root of the subtree (i.e., the sum of the lengths of the left and right subtrees). The function's return value, however, is the longest diameter with the root of the subtree as an endpoint (i.e., the length of one side of the subtree). This return value design allows the parent node's longest diameter to be updated recursively. @@ -205,11 +210,11 @@ def diameterOfBinaryTree(root: Optional[TreeNode]) -> int: ### Problem Description -给定一个整数二叉树,求有多少条路径节点值的和等于给定值。 +Given a binary tree of integers, find the number of paths where the sum of the node values equals a given target. ### Input and Output Example -输入一个二叉树和一个给定整数,输出一个整数,表示有多少条满足条件的路径。 +Input is a binary tree and a target integer. Output is an integer representing the number of paths that satisfy the condition. ``` Input: sum = 8, tree = @@ -223,18 +228,22 @@ Input: sum = 8, tree = Output: 3 ``` -在这个样例中,和为 8 的路径一共有三个:[[5,3],[5,2,1],[-3,11]]。 +In this example, there are three paths where the sum equals 8: `[[5,3],[5,2,1],[-3,11]]`. ### Solution Explanation -递归每个节点时,需要分情况考虑:(1)如果选取该节点加入路径,则之后必须继续加入连续节点,或停止加入节点(2)如果不选取该节点加入路径,则对其左右节点进行重新进行考虑。因此一个方便的方法是我们创建一个辅函数,专门用来计算连续加入节点的路径。 +When recursively processing each node, consider two scenarios: +1. If the current node is included in the path, subsequent nodes must be added continuously, or the path stops. +2. If the current node is not included, restart the path calculation from its left and right children. + +A convenient way to handle this is to create an auxiliary function specifically for calculating paths that start from the current node. ```cpp // Auxiliary function -// long long防止test case中大数溢出,一般情况下用int即可。 +// Use long long to prevent overflow with large test cases; int is usually sufficient. long long pathSumStartWithRoot(TreeNode* root, long long targetSum) { if (root == nullptr) { return 0; @@ -287,11 +296,11 @@ def pathSum(root: Optional[TreeNode], targetSum: int) -> int: ### Problem Description -判断一个二叉树是否对称。 +Determine whether a binary tree is symmetric. ### Input and Output Example -输入一个二叉树,输出一个布尔值,表示该树是否对称。 +Input a binary tree, output a boolean indicating whether the tree is symmetric. ``` Input: @@ -305,8 +314,11 @@ Output: true ### Solution Explanation -判断一个树是否对称等价于判断左右子树是否对称。笔者一般习惯将判断两个子树是否相等或对称类型的题的解法叫做“四步法”:(1)如果两个子树都为空指针,则它们相等或对称(2)如果两个子树只有一个为空指针,则它们不相等或不对称(3)如果两个子树根节点的值不相等,则它们不相等或不对称(4)根据相等或对称要求,进行递归处理。 - +Determining whether a tree is symmetric is equivalent to checking if its left and right subtrees are symmetric. A common approach for such problems is the "four-step method": +1. If both subtrees are null, they are symmetric. +2. If one subtree is null and the other is not, they are not symmetric. +3. If the root values of the two subtrees are not equal, they are not symmetric. +4. Based on symmetry requirements, recursively process the subtrees. @@ -370,11 +382,11 @@ def isSymmetric(root: Optional[TreeNode]) -> bool: ### Problem Description -给定一个整数二叉树和一些整数,求删掉这些整数对应的节点后,剩余的子树。 +Given an integer binary tree and some integers, delete the nodes corresponding to these integers and return the remaining subtrees. ### Input and Output Example -输入是一个整数二叉树和一个一维整数数组,输出一个数组,每个位置存储一个子树(的根节点)。 +Input is an integer binary tree and a one-dimensional integer array. Output is an array where each position contains a subtree (its root node). ``` Input: to_delete = [3,5], tree = @@ -393,7 +405,7 @@ Output: [ ### Solution Explanation -这道题最主要需要注意的细节是如果通过递归处理原树,以及需要在什么时候断开指针。同时,为了便于寻找待删除节点,可以建立一个哈希表方便查找。笔者强烈建议读者在看完题解后,自己写一遍本题,加深对于递归的理解和运用能力。 +The key details in this problem include how to recursively handle the original tree and when to disconnect pointers. Additionally, to efficiently find nodes to delete, you can create a hash table for quick lookup. It is highly recommended that readers attempt to implement this problem after reviewing the solution to deepen their understanding and application of recursion. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-3-level-order-traversal.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-3-level-order-traversal.mdx index a434b418..ca3c5b3e 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-3-level-order-traversal.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-3-level-order-traversal.mdx @@ -2,19 +2,19 @@ sidebar_position: 70 --- -# 13.3 层次遍历 +# 13.3 Level Order Traversal -我们可以使用广度优先搜索进行层次遍历。注意,不需要使用两个队列来分别存储当前层的节点和下一层的节点,因为在开始遍历一层的节点时,当前队列中的节点数就是当前层的节点数,只要控制遍历这么多节点数,就能保证这次遍历的都是当前层的节点。 +We can use Breadth-First Search (BFS) for level order traversal. Note that it is unnecessary to use two queues to separately store the current layer's nodes and the next layer's nodes. At the beginning of each layer's traversal, the number of nodes in the current queue equals the number of nodes in the current layer. By controlling the traversal to only process that many nodes, we ensure that the traversal covers only the current layer. ## [637. Average of Levels in Binary Tree](https://leetcode.com/problems/average-of-levels-in-binary-tree/) ### Problem Description -给定一个二叉树,求每一层的节点值的平均数。 +Given a binary tree, compute the average value of nodes at each level. ### Input and Output Example -输入是一个二叉树,输出是一个一维数组,表示每层节点值的平均数。 +Input is a binary tree, and the output is a one-dimensional array representing the average value of nodes at each level. ``` Input: @@ -28,7 +28,7 @@ Output: [3, 14.5, 11] ### Solution Explanation -利用广度优先搜索,我们可以很方便地求取每层的平均值。 +Using Breadth-First Search, we can conveniently calculate the average value for each level. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-4-preorder-inorder-postorder-traversal.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-4-preorder-inorder-postorder-traversal.mdx index e0761a67..3ac5f766 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-4-preorder-inorder-postorder-traversal.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-4-preorder-inorder-postorder-traversal.mdx @@ -2,9 +2,9 @@ sidebar_position: 71 --- -# 13.4 前中后序遍历 +# 13.4 Preorder, Inorder, and Postorder Traversals -前序遍历、中序遍历和后序遍历是三种利用深度优先搜索遍历二叉树的方式。它们是在对节点访问的顺序有一点不同,其它完全相同。考虑如下一棵树, +Preorder traversal, inorder traversal, and postorder traversal are three ways to traverse a binary tree using Depth-First Search (DFS). They differ only in the order of node visits, while the rest remains the same. Consider the following binary tree: ``` 1 @@ -14,7 +14,7 @@ sidebar_position: 71 4 5 6 ``` -前序遍历先遍历父结点,再遍历左结点,最后遍历右节点,我们得到的遍历顺序是 [1 2 4 5 3 6]。 +In **preorder traversal**, the parent node is visited first, followed by the left node and then the right node. The traversal order is [1 2 4 5 3 6]. @@ -41,7 +41,7 @@ def preorder(root: TreeNode): -中序遍历先遍历左节点,再遍历父结点,最后遍历右节点,我们得到的遍历顺序是 [4 2 5 1 3 6]。 +In **inorder traversal**, the left node is visited first, followed by the parent node and then the right node. The traversal order is [4 2 5 1 3 6]. @@ -68,7 +68,7 @@ def inorder(root: TreeNode): -后序遍历先遍历左节点,再遍历右结点,最后遍历父节点,我们得到的遍历顺序是 [4 5 2 6 3 1]。 +In **postorder traversal**, the left node is visited first, followed by the right node and then the parent node. The traversal order is [4 5 2 6 3 1]. @@ -99,11 +99,11 @@ def postorder(root: TreeNode): ### Problem Description -给定一个二叉树的前序遍历和中序遍历结果,尝试复原这个树。已知树里不存在重复值的节点。 +Given the preorder and inorder traversal results of a binary tree, reconstruct the tree. It is guaranteed that there are no duplicate values in the tree nodes. ### Input and Output Example -输入是两个一维数组,分别表示树的前序遍历和中序遍历结果;输出是一个二叉树。 +Input consists of two 1D arrays representing the preorder and inorder traversal results of the tree. Output is the reconstructed binary tree. ``` Input: preorder = [4,9,20,15,7], inorder = [9,4,15,20,7] @@ -117,7 +117,12 @@ Output: ### Solution Explanation -我们通过本题的样例讲解一下本题的思路。前序遍历的第一个节点是 4,意味着 4 是根节点。我们在中序遍历结果里找到 4 这个节点,根据中序遍历的性质可以得出,4 在中序遍历数组位置的左子数组为左子树,节点数为 1,对应的是前序排列数组里 4 之后的 1 个数字(9);4 在中序遍历数组位置的右子数组为右子树,节点数为 3,对应的是前序排列数组里最后的 3 个数字。有了这些信息,我们就可以对左子树和右子树进行递归复原了。为了方便查找数字的位置,我们可以用哈希表预处理中序遍历的结果。 +Using the provided example, the first node in the preorder traversal is `4`, indicating that `4` is the root node. In the inorder traversal, locating `4` provides the following insights: + +- The left subarray in the inorder traversal corresponds to the left subtree. It contains `1` node (`9`), which maps to the next `1` element in the preorder traversal after `4`. +- The right subarray in the inorder traversal corresponds to the right subtree. It contains `3` nodes (`15`, `20`, `7`), which map to the last `3` elements in the preorder traversal. + +With this information, the left and right subtrees can be recursively reconstructed. To simplify locating values, a hash map can be used to preprocess the inorder traversal results. @@ -180,11 +185,11 @@ def buildTree(preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: ### Problem Description -不使用递归,实现二叉树的前序遍历。 +Implement a binary tree preorder traversal without using recursion. ### Input and Output Example -输入一个二叉树,输出一个数组,为二叉树前序遍历的结果, +Input is a binary tree, and the output is an array representing the preorder traversal of the binary tree. ``` Input: @@ -198,7 +203,7 @@ Output: [1,2,3] ### Solution Explanation -因为递归的本质是栈调用,因此我们可以通过栈来实现前序遍历。注意入栈的顺序。 +Since recursion inherently uses a stack, we can simulate the preorder traversal using an explicit stack. Note the order of stack operations. @@ -216,7 +221,7 @@ vector preorderTraversal(TreeNode* root) { s.pop(); po.push_back(node->val); if (node->right) { - s.push(node->right); // 先右后左,保证左子树先遍历 + s.push(node->right); // Push the right child first, then the left child, to ensure the left subtree is traversed first. } if (node->left) { s.push(node->left); @@ -239,7 +244,7 @@ def preorderTraversal(root: Optional[TreeNode]) -> List[int]: node = s.pop() po.append(node.val) if node.right is not None: - s.append(node.right) # 先右后左,保证左子树先遍历 + s.append(node.right) # Push the right child first, then the left child, to ensure the left subtree is traversed first. if node.left is not None: s.append(node.left) return po diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-5-binary-search-tree.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-5-binary-search-tree.mdx index 81d81f1c..b34b772d 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-5-binary-search-tree.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-5-binary-search-tree.mdx @@ -2,11 +2,11 @@ sidebar_position: 72 --- -# 13.5 二叉查找树 +# 13.5 Binary Search Tree -`二叉查找树`(Binary Search Tree, BST)是一种特殊的二叉树:对于每个父节点,其左子树中所有节点的值小于等于父结点的值,其右子树中所有节点的值大于等于父结点的值。因此对于一个二叉查找树,我们可以在 O(log n) 的时间内查找一个值是否存在:从根节点开始,若当前节点的值大于查找值则向左下走,若当前节点的值小于查找值则向右下走。同时因为二叉查找树是有序的,对其中序遍历的结果即为排好序的数组。 +A `Binary Search Tree` (BST) is a special type of binary tree: for every parent node, all nodes in its left subtree have values less than or equal to the parent's value, and all nodes in its right subtree have values greater than or equal to the parent's value. Therefore, for a BST, we can determine whether a value exists in $O(\log n)$ time: starting from the root, move to the left if the current node's value is greater than the target value, or move to the right if it's smaller. Additionally, since a BST is ordered, an in-order traversal of the tree results in a sorted array. -例如下面这棵树即为二叉查找树,其中序遍历结果为 [1 2 3 4 5 6]。 +For example, the tree below is a BST, and its in-order traversal yields [1, 2, 3, 4, 5, 6]. ``` 4 @@ -20,11 +20,11 @@ sidebar_position: 72 ### Problem Description -给定一个二叉查找树,已知有两个节点被不小心交换了,试复原此树。 +Given a binary search tree, where two nodes have been swapped by mistake, restore the tree to its correct structure. ### Input and Output Example -输入是一个被误交换两个节点的二叉查找树,输出是改正后的二叉查找树。 +The input is a binary search tree where two nodes have been swapped, and the output is the corrected tree. ``` Input: @@ -41,11 +41,14 @@ Output: 3 ``` -在这个样例中,2 和 3 被不小心交换了。 +In this example, 2 and 3 were swapped by mistake. ### Solution Explanation -我们可以使用中序遍历这个二叉查找树,同时设置一个 prev 指针,记录当前节点中序遍历时的前节点。如果当前节点大于 prev 节点的值,说明需要调整次序。有一个技巧是如果遍历整个序列过程中只出现了一次次序错误,说明就是这两个相邻节点需要被交换;如果出现了两次次序错误,那就需要交换这两个节点。 +We can perform an in-order traversal of the BST and use a `prev` pointer to keep track of the previous node during traversal. If the current node's value is less than the `prev` node's value, it indicates an order mismatch that needs correction. + +- If there's only one mismatch in the entire traversal, it means the two swapped nodes are adjacent. +- If there are two mismatches, the two non-adjacent nodes are swapped and need correction. @@ -82,7 +85,7 @@ void recoverTree(TreeNode* root) { ```py # Auxiliary function -# 注意,Python中并不方便在辅函数中直接传指针,因此我们建造长度为1的list进行传引用。 +# In Python, it is not straightforward to pass pointers directly in auxiliary functions. Therefore, we use a list of length 1 to simulate passing by reference. def inorder( root: Optional[TreeNode], mistake1=List[Optional[TreeNode]], @@ -115,11 +118,11 @@ def recoverTree(root: Optional[TreeNode]) -> None: ### Problem Description -给定一个二叉查找树和两个整数 L 和 R,且 L < R,试修剪此二叉查找树,使得修剪后所有节点的值都在 [L, R] 的范围内。 +Given a binary search tree and two integers L and R, where L < R, trim the tree so that all nodes in the tree have values within the range [L, R]. ### Input and Output Example -输入是一个二叉查找树和两个整数 L 和 R,输出一个被修剪好的二叉查找树。 +Input is a binary search tree and two integers L and R. Output is the trimmed binary search tree. ``` Input: L = 1, R = 3, tree = @@ -140,7 +143,7 @@ Output: ### Solution Explanation -利用二叉查找树的大小关系,我们可以很容易地利用递归进行树的处理。 +By leveraging the properties of a binary search tree, we can efficiently solve this problem using recursion. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-6-trie.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-6-trie.mdx index 3e544261..8b68bfdb 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-6-trie.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-6-trie.mdx @@ -2,28 +2,28 @@ sidebar_position: 73 --- -# 13.6 字典树 +# 13.6 Trie -字典树(Trie)用于判断字符串是否存在或者是否具有某种字符串前缀。 +A Trie is a tree-like data structure used to determine whether a string exists or whether it has a specific prefix.
        ![](13.1.png) -
        图 13.1: 字典树,存储了单词 A、to、tea、ted、ten、i、in 和 inn,以及它们的频率
        +
        Fig. 13.1: Trie storing words A, to, tea, ted, ten, i, in, and inn, along with their frequencies
        -为什么需要用字典树解决这类问题呢?假如我们有一个储存了近万个单词的字典,即使我们使用哈希,在其中搜索一个单词的实际开销也是非常大的,且无法轻易支持搜索单词前缀。然而由于一个英文单词的长度 n 通常在 10 以内,如果我们使用字典树,则可以在 $O(n)$——近似 $O(1)$ 的时间内完成搜索,且额外开销非常小。 +Why use a Trie for such problems? Suppose we have a dictionary storing nearly 10,000 words. Even with a hash table, searching for a word can be computationally expensive, and supporting prefix-based searches becomes difficult. However, since the length of an English word, `n`, is usually less than 10, using a Trie allows searches to be completed in $O(n)$—approximately $O(1)$ time—with minimal additional overhead. ## [208. Implement Trie (Prefix Tree)](https://leetcode.com/problems/implement-trie-prefix-tree/) ### Problem Description -尝试建立一个字典树,支持快速插入单词、查找单词、查找单词前缀的功能。 +Create a Trie that supports fast insertion of words, word lookup, and prefix lookup. ### Input and Output Example -以下是数据结构的调用样例。 +Below is an example of how to use the data structure. ``` Trie trie = new Trie(); @@ -37,7 +37,7 @@ trie.search("app"); // true ### Solution Explanation -以下是字典树的典型实现方法。 +Here is the typical implementation of a Trie. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-7-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-7-exercises.md index 974e6b5e..b4123e0a 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-7-exercises.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-7-exercises.md @@ -8,49 +8,49 @@ sidebar_position: 74 ### [226. Invert Binary Tree](https://leetcode.com/problems/invert-binary-tree/) -巧用递归,你可以在五行内完成这道题。 +With a clever use of recursion, you can complete this task in just five lines. --- ### [617. Merge Two Binary Trees](https://leetcode.com/problems/merge-two-binary-trees/) -同样的,利用递归可以轻松搞定。 +Similarly, recursion can easily handle this task. --- ### [572. Subtree of Another Tree](https://leetcode.com/problems/subtree-of-another-tree/) -子树是对称树的姊妹题,写法也十分类似。 +This is the sister problem of Symmetric Tree, and the implementation is very similar. --- ### [404. Sum of Left Leaves](https://leetcode.com/problems/sum-of-left-leaves/) -怎么判断一个节点是不是左节点呢?一种可行的方法是,在辅函数里多传一个参数,表示当前节点是不是父节点的左节点。 +How can you determine if a node is a left leaf? One feasible approach is to pass an additional parameter to the helper function indicating whether the current node is a left child of its parent. --- ### [513. Find Bottom Left Tree Value](https://leetcode.com/problems/find-bottom-left-tree-value/) -最左下角的节点满足什么条件?针对这种条件,我们该如何找到它? +What condition must the bottom-left node satisfy? How can we locate it based on this condition? --- ### [538. Convert BST to Greater Tree](https://leetcode.com/problems/convert-bst-to-greater-tree/) -尝试利用某种遍历方式来解决此题,每个节点只需遍历一次。 +Try to solve this problem using a specific traversal method, visiting each node exactly once. --- ### [235. Lowest Common Ancestor of a Binary Search Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/) -利用 BST 的独特性质,这道题可以很轻松完成。 +Using the unique properties of a BST, this problem can be solved quite easily. --- ### [530. Minimum Absolute Difference in BST](https://leetcode.com/problems/minimum-absolute-difference-in-bst/) -还记得我们所说的,对于 BST 应该利用哪种遍历吗? +Remember the traversal method we discussed for BSTs? --- @@ -58,58 +58,58 @@ sidebar_position: 74 ### [1530. Number of Good Leaf Nodes Pairs](https://leetcode.com/problems/number-of-good-leaf-nodes-pairs/) -题目 543 的变种题,注意在辅函数中,每次更新的全局变量是左右两边距离之和满足条件的数量,而返回的是左右两边所有(长度不溢出的)子节点的高度 +1。 +A variation of problem 543. Pay attention in the helper function: the global variable should be updated based on the number of valid pairs of distances between left and right subtrees, while the return value is the height of all valid leaf nodes (+1) from both subtrees. --- ### [889. Construct Binary Tree from Preorder and Postorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-postorder-traversal/) -给定任意两种遍历结果,我们都可以重建树的结构。 +Given any two traversal results, we can reconstruct the tree structure. --- ### [106. Construct Binary Tree from Inorder and Postorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/) -给定任意两种遍历结果,我们都可以重建树的结构。 +Given any two traversal results, we can reconstruct the tree structure. --- ### [94. Binary Tree Inorder Traversal](https://leetcode.com/problems/binary-tree-inorder-traversal/) -因为前中序后遍历是用递归实现的,而递归的底层实现是栈操作,因此我们总能用栈实现。 +Since preorder, inorder, and postorder traversals are implemented using recursion, and recursion inherently uses a stack, we can always use a stack to implement them. --- ### [145. Binary Tree Postorder Traversal](https://leetcode.com/problems/binary-tree-postorder-traversal/) -因为前中序后遍历是用递归实现的,而递归的底层实现是栈操作,因此我们总能用栈实现。 +Since preorder, inorder, and postorder traversals are implemented using recursion, and recursion inherently uses a stack, we can always use a stack to implement them. --- ### [236. Lowest Common Ancestor of a Binary Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/) -现在不是 BST,而是普通的二叉树了,该怎么办? +Now it’s not a BST but a general binary tree. What should we do? --- ### [109. Convert Sorted List to Binary Search Tree](https://leetcode.com/problems/convert-sorted-list-to-binary-search-tree/) -把排好序的链表变成 BST。为了使得 BST 尽量平衡,我们需要寻找链表的中点。 +Convert a sorted linked list into a BST. To ensure the BST remains balanced, we need to find the middle point of the list. --- ### [897. Increasing Order Search Tree](https://leetcode.com/problems/increasing-order-search-tree/) -把 BST 压成一个链表,务必考虑清楚指针操作的顺序,否则可能会出现环路。 +Flatten a BST into a linked list. Be cautious about the order of pointer manipulations to avoid creating loops. --- ### [653. Two Sum IV - Input is a BST](https://leetcode.com/problems/two-sum-iv-input-is-a-bst/) -啊哈,这道题可能会把你骗到。 +Ah, this problem might trick you. --- ### [450. Delete Node in a BST](https://leetcode.com/problems/delete-node-in-a-bst/) -当寻找到待删节点时,你可以分情况考虑——当前节点是叶节点、只有一个子节点和有两个子节点。建议同时回收内存。 \ No newline at end of file +When you locate the node to delete, consider different cases: whether the node is a leaf, has only one child, or has two children. It’s recommended to reclaim memory at the same time. \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-1-data-structure-introduction.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-1-data-structure-introduction.mdx index 3d50814f..b1d3f9b6 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-1-data-structure-introduction.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-1-data-structure-introduction.mdx @@ -2,10 +2,9 @@ sidebar_position: 68 --- -# 13.1 数据结构介绍 - -作为(单)链表的升级版,我们通常接触的树都是`二叉树`(binary tree),即每个节点最多有两个子节点;且除非题目说明,默认树中不存在循环结构。LeetCode 默认的树表示方法如下。 +# 13.1 資料結構介紹 +作為(單)鏈結串列的升級版,我們通常接觸的樹都是`二元樹`(binary tree),即每個節點最多有兩個子節點;且除非題目說明,預設樹中不存在循環結構。LeetCode 預設的樹表示方法如下。 @@ -34,4 +33,4 @@ class TreeNode: -可以看出,其与链表的主要差别就是多了一个子节点的指针。 \ No newline at end of file +可以看出,其與鏈結串列的主要差別就是多了一個子節點的指標。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-2-tree-recursion.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-2-tree-recursion.mdx index 290491c9..75f3f6da 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-2-tree-recursion.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-2-tree-recursion.mdx @@ -2,21 +2,21 @@ sidebar_position: 69 --- -# 13.2 树的递归 +# 13.2 樹的遞迴 -对于一些简单的递归题,某些 LeetCode 达人喜欢写 one-line code,即用一行代码解决问题。我们也会展示一些这样的代码,但是对于新手,笔者仍然建议您使用多行的 if-else 判断语句。 +對於一些簡單的遞迴題,某些 LeetCode 達人喜歡寫 one-line code,即用一行程式碼解決問題。我們也會展示一些這樣的程式碼,但對於新手,筆者仍然建議您使用多行的 if-else 判斷語句。 -在很多时候,树递归的写法与深度优先搜索的递归写法相同,因此本书不会区分二者。 +在許多情況下,樹遞迴的寫法與深度優先搜索的遞迴寫法相同,因此本書不會區分兩者。 ## [104. Maximum Depth of Binary Tree](https://leetcode.com/problems/maximum-depth-of-binary-tree/) ### 題目描述 -求一个二叉树的最大深度。 +求一個二元樹的最大深度。 ### 輸入輸出範例 -输入是一个二叉树,输出是一个整数,表示该树的最大深度。 +輸入是一個二元樹,輸出是一個整數,表示該樹的最大深度。 ``` Input: @@ -30,7 +30,7 @@ Output: 3 ### 題解 -利用递归,我们可以很方便地求得最大深度。 +利用遞迴,我們可以很方便地求得最大深度。 @@ -62,11 +62,11 @@ def maxDepth(root: Optional[TreeNode]) -> int: ### 題目描述 -判断一个二叉树是否平衡。树平衡的定义是,对于树上的任意节点,其两侧节点的最大深度的差值不得大于 1。 +判斷一個二元樹是否平衡。平衡樹的定義是:對於樹上的任意節點,其左右子節點的最大深度差不得超過 1。 ### 輸入輸出範例 -输入是一个二叉树,输出一个布尔值,表示树是否平衡。 +輸入是一個二元樹,輸出是一個布林值,表示該樹是否平衡。 ``` Input: @@ -82,7 +82,10 @@ Output: false ### 題解 -解法类似于求树的最大深度,但有两个不同的地方:一是我们需要先处理子树的深度再进行比较,二是如果我们在处理子树时发现其已经不平衡了,则可以返回一个-1,使得所有其长辈节点可以避免多余的判断(本题的判断比较简单,做差后取绝对值即可;但如果此处是一个开销较大的比较过程,则避免重复判断可以节省大量的计算时间)。 +解法類似於計算樹的最大深度,但有兩個不同點: + +1. 必須先計算子樹的深度,再進行比較。 +2. 如果在處理子樹時發現該子樹已經不平衡,則立即返回 -1,讓其祖先節點能避免不必要的判斷。(本題的判斷相對簡單,只需計算深度差的絕對值即可;但如果比較過程較為複雜,避免重複判斷可以節省大量計算時間。) @@ -132,11 +135,11 @@ def isBalanced(root: Optional[TreeNode]) -> bool: ### 題目描述 -求一个二叉树的最长直径。直径的定义是二叉树上任意两节点之间的无向距离。 +求一個二元樹的最長直徑。直徑的定義是二元樹上任意兩節點之間的無向距離。 ### 輸入輸出範例 -输入是一个二叉树,输出一个整数,表示最长直径。 +輸入是一個二元樹,輸出是一個整數,表示最長直徑。 ``` Input: @@ -148,11 +151,13 @@ Input: Output: 3 ``` -在这个样例中,最长直径是 [4,2,1,3] 和 [5,2,1,3]。 +在這個範例中,最長直徑是 [4,2,1,3] 和 [5,2,1,3]。 ### 題解 -同样的,我们可以利用递归来处理树。解题时要注意,在我们处理某个子树时,我们更新的最长直径值和递归返回的值是不同的。这是因为待更新的最长直径值是经过该子树根节点的最长直径(即两侧长度);而函数返回值是以该子树根节点为端点的最长直径值(即一侧长度),使用这样的返回值才可以通过递归更新父节点的最长直径值)。 +我們可以利用遞迴來處理二元樹。在解題時需要注意一點:當我們處理某個子樹時,我們更新的最長直徑值和遞迴返回的值是不相同的。 + +更新的最長直徑值是指經過該子樹根節點的最長直徑(也就是左右子樹的長度總和);而函數返回的值則是以該子樹根節點為端點的最長直徑(也就是單側子樹的長度)。這樣設計返回值,可以遞迴地更新父節點的最長直徑。 @@ -205,11 +210,11 @@ def diameterOfBinaryTree(root: Optional[TreeNode]) -> int: ### 題目描述 -给定一个整数二叉树,求有多少条路径节点值的和等于给定值。 +給定一個整數二元樹,求路徑節點值的總和等於給定目標值的路徑數量。 ### 輸入輸出範例 -输入一个二叉树和一个给定整数,输出一个整数,表示有多少条满足条件的路径。 +輸入是一個二元樹和一個目標整數。輸出是一個整數,表示滿足條件的路徑數量。 ``` Input: sum = 8, tree = @@ -223,18 +228,22 @@ Input: sum = 8, tree = Output: 3 ``` -在这个样例中,和为 8 的路径一共有三个:[[5,3],[5,2,1],[-3,11]]。 +在這個例子中,總和為 8 的路徑共有三條:`[[5,3],[5,2,1],[-3,11]]`。 ### 題解 -递归每个节点时,需要分情况考虑:(1)如果选取该节点加入路径,则之后必须继续加入连续节点,或停止加入节点(2)如果不选取该节点加入路径,则对其左右节点进行重新进行考虑。因此一个方便的方法是我们创建一个辅函数,专门用来计算连续加入节点的路径。 +在遞迴處理每個節點時,需要分為兩種情況考慮: +1. 若選取當前節點加入路徑,則之後的節點必須連續加入,或停止加入。 +2. 若不選取當前節點,則需對其左右子節點重新進行考慮。 + +為此,我們可以建立一個輔助函式,專門計算從當前節點開始的連續路徑數量。 ```cpp // 輔助函式。 -// long long防止test case中大数溢出,一般情况下用int即可。 +// 使用 long long 防止 test case 中出現大數溢位,通常情況下 int 即可。 long long pathSumStartWithRoot(TreeNode* root, long long targetSum) { if (root == nullptr) { return 0; @@ -287,11 +296,11 @@ def pathSum(root: Optional[TreeNode], targetSum: int) -> int: ### 題目描述 -判断一个二叉树是否对称。 +判斷一個二元樹是否對稱。 ### 輸入輸出範例 -输入一个二叉树,输出一个布尔值,表示该树是否对称。 +輸入一個二元樹,輸出一個布林值,表示該樹是否對稱。 ``` Input: @@ -305,8 +314,11 @@ Output: true ### 題解 -判断一个树是否对称等价于判断左右子树是否对称。笔者一般习惯将判断两个子树是否相等或对称类型的题的解法叫做“四步法”:(1)如果两个子树都为空指针,则它们相等或对称(2)如果两个子树只有一个为空指针,则它们不相等或不对称(3)如果两个子树根节点的值不相等,则它们不相等或不对称(4)根据相等或对称要求,进行递归处理。 - +判斷一棵樹是否對稱等價於判斷左右子樹是否對稱。筆者一般習慣將判斷兩個子樹是否相等或對稱類型的題解法稱為「四步法」: +1. 如果兩個子樹都為空指標,則它們相等或對稱。 +2. 如果兩個子樹只有一個為空指標,則它們不相等或不對稱。 +3. 如果兩個子樹根節點的值不相等,則它們不相等或不對稱。 +4. 根據相等或對稱的要求,進行遞迴處理。 @@ -370,11 +382,11 @@ def isSymmetric(root: Optional[TreeNode]) -> bool: ### 題目描述 -给定一个整数二叉树和一些整数,求删掉这些整数对应的节点后,剩余的子树。 +給定一個整數二元樹和一些整數,求刪掉這些整數對應的節點後,剩餘的子樹。 ### 輸入輸出範例 -输入是一个整数二叉树和一个一维整数数组,输出一个数组,每个位置存储一个子树(的根节点)。 +輸入是一個整數二元樹和一維整數陣列,輸出是一個陣列,每個位置存儲一個子樹(的根節點)。 ``` Input: to_delete = [3,5], tree = @@ -393,7 +405,7 @@ Output: [ ### 題解 -这道题最主要需要注意的细节是如果通过递归处理原树,以及需要在什么时候断开指针。同时,为了便于寻找待删除节点,可以建立一个哈希表方便查找。笔者强烈建议读者在看完题解后,自己写一遍本题,加深对于递归的理解和运用能力。 +本題主要需要注意的細節包括如何透過遞迴處理原樹,以及在何時斷開指標。同時,為了方便尋找待刪除的節點,可以建立一個雜湊表進行快速查找。筆者強烈建議讀者在看完題解後,自己實現一次本題,加深對於遞迴的理解與運用能力。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-3-level-order-traversal.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-3-level-order-traversal.mdx index 9c2e6426..b7f8cb81 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-3-level-order-traversal.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-3-level-order-traversal.mdx @@ -2,19 +2,19 @@ sidebar_position: 70 --- -# 13.3 层次遍历 +# 13.3 層次遍歷 -我们可以使用广度优先搜索进行层次遍历。注意,不需要使用两个队列来分别存储当前层的节点和下一层的节点,因为在开始遍历一层的节点时,当前队列中的节点数就是当前层的节点数,只要控制遍历这么多节点数,就能保证这次遍历的都是当前层的节点。 +我們可以使用廣度優先搜尋進行層次遍歷。注意,不需要使用兩個佇列來分別存儲當前層的節點和下一層的節點,因為在開始遍歷一層節點時,當前佇列中的節點數就是當前層的節點數,只要控制遍歷這麼多節點數,就能保證這次遍歷的都是當前層的節點。 ## [637. Average of Levels in Binary Tree](https://leetcode.com/problems/average-of-levels-in-binary-tree/) ### 題目描述 -给定一个二叉树,求每一层的节点值的平均数。 +給定一個二元樹,求每一層的節點值的平均數。 ### 輸入輸出範例 -输入是一个二叉树,输出是一个一维数组,表示每层节点值的平均数。 +輸入是一個二元樹,輸出是一個一維陣列,表示每層節點值的平均數。 ``` Input: @@ -28,7 +28,7 @@ Output: [3, 14.5, 11] ### 題解 -利用广度优先搜索,我们可以很方便地求取每层的平均值。 +利用廣度優先搜尋,我們可以很方便地求取每層的平均值。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-4-preorder-inorder-postorder-traversal.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-4-preorder-inorder-postorder-traversal.mdx index 1fe695bc..b4099c87 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-4-preorder-inorder-postorder-traversal.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-4-preorder-inorder-postorder-traversal.mdx @@ -2,9 +2,9 @@ sidebar_position: 71 --- -# 13.4 前中后序遍历 +# 13.4 前中後序遍歷 -前序遍历、中序遍历和后序遍历是三种利用深度优先搜索遍历二叉树的方式。它们是在对节点访问的顺序有一点不同,其它完全相同。考虑如下一棵树, +前序遍歷、中序遍歷和後序遍歷是三種利用深度優先搜尋(DFS)遍歷二元樹的方式。它們在節點訪問的順序上有所不同,其餘部分完全相同。考慮如下二元樹: ``` 1 @@ -14,7 +14,7 @@ sidebar_position: 71 4 5 6 ``` -前序遍历先遍历父结点,再遍历左结点,最后遍历右节点,我们得到的遍历顺序是 [1 2 4 5 3 6]。 +前序遍歷先訪問父節點,再訪問左節點,最後訪問右節點,得到的遍歷順序是 [1 2 4 5 3 6]。 @@ -41,7 +41,7 @@ def preorder(root: TreeNode): -中序遍历先遍历左节点,再遍历父结点,最后遍历右节点,我们得到的遍历顺序是 [4 2 5 1 3 6]。 +中序遍歷先訪問左節點,再訪問父節點,最後訪問右節點,得到的遍歷順序是 [4 2 5 1 3 6]。 @@ -68,7 +68,7 @@ def inorder(root: TreeNode): -后序遍历先遍历左节点,再遍历右结点,最后遍历父节点,我们得到的遍历顺序是 [4 5 2 6 3 1]。 +後序遍歷先訪問左節點,再訪問右節點,最後訪問父節點,得到的遍歷順序是 [4 5 2 6 3 1]。 @@ -99,11 +99,11 @@ def postorder(root: TreeNode): ### 題目描述 -给定一个二叉树的前序遍历和中序遍历结果,尝试复原这个树。已知树里不存在重复值的节点。 +給定一棵二元樹的前序遍歷和中序遍歷結果,嘗試復原這棵樹。已知樹裡不存在重複值的節點。 ### 輸入輸出範例 -输入是两个一维数组,分别表示树的前序遍历和中序遍历结果;输出是一个二叉树。 +輸入是兩個一維陣列,分別表示樹的前序遍歷和中序遍歷結果;輸出是一棵二元樹。 ``` Input: preorder = [4,9,20,15,7], inorder = [9,4,15,20,7] @@ -117,7 +117,12 @@ Output: ### 題解 -我们通过本题的样例讲解一下本题的思路。前序遍历的第一个节点是 4,意味着 4 是根节点。我们在中序遍历结果里找到 4 这个节点,根据中序遍历的性质可以得出,4 在中序遍历数组位置的左子数组为左子树,节点数为 1,对应的是前序排列数组里 4 之后的 1 个数字(9);4 在中序遍历数组位置的右子数组为右子树,节点数为 3,对应的是前序排列数组里最后的 3 个数字。有了这些信息,我们就可以对左子树和右子树进行递归复原了。为了方便查找数字的位置,我们可以用哈希表预处理中序遍历的结果。 +我們通過本題的範例講解一下本題的思路。前序遍歷的第一個節點是 `4`,意味著 `4` 是根節點。我們在中序遍歷結果中找到 `4` 這個節點,根據中序遍歷的性質可以得出: + +- `4` 在中序遍歷陣列中的位置左側子陣列為左子樹,節點數為 `1`,對應的是前序遍歷陣列中 `4` 之後的 `1` 個數字(`9`)。 +- `4` 在中序遍歷陣列中的位置右側子陣列為右子樹,節點數為 `3`,對應的是前序遍歷陣列最後的 `3` 個數字。 + +有了這些訊息,我們可以對左子樹和右子樹進行遞迴復原。為了方便查找數字的位置,我們可以用雜湊表預處理中序遍歷的結果。 @@ -180,11 +185,11 @@ def buildTree(preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: ### 題目描述 -不使用递归,实现二叉树的前序遍历。 +不使用遞迴,實現二元樹的前序遍歷。 ### 輸入輸出範例 -输入一个二叉树,输出一个数组,为二叉树前序遍历的结果, +輸入是一棵二元樹,輸出是一個陣列,表示二元樹前序遍歷的結果。 ``` Input: @@ -198,7 +203,8 @@ Output: [1,2,3] ### 題解 -因为递归的本质是栈调用,因此我们可以通过栈来实现前序遍历。注意入栈的顺序。 +由於遞迴的本質是透過堆疊進行函數調用,因此我們可以使用堆疊來實現前序遍歷。注意進堆疊的順序。 + @@ -216,7 +222,7 @@ vector preorderTraversal(TreeNode* root) { s.pop(); po.push_back(node->val); if (node->right) { - s.push(node->right); // 先右后左,保证左子树先遍历 + s.push(node->right); // 先右後左,保證左子樹先遍歷 } if (node->left) { s.push(node->left); @@ -239,7 +245,7 @@ def preorderTraversal(root: Optional[TreeNode]) -> List[int]: node = s.pop() po.append(node.val) if node.right is not None: - s.append(node.right) # 先右后左,保证左子树先遍历 + s.append(node.right) # 先右後左,保證左子樹先遍歷 if node.left is not None: s.append(node.left) return po diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-5-binary-search-tree.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-5-binary-search-tree.mdx index 24ffd664..b0641f4c 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-5-binary-search-tree.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-5-binary-search-tree.mdx @@ -2,11 +2,11 @@ sidebar_position: 72 --- -# 13.5 二叉查找树 +# 13.5 二元搜尋樹 -`二叉查找树`(Binary Search Tree, BST)是一种特殊的二叉树:对于每个父节点,其左子树中所有节点的值小于等于父结点的值,其右子树中所有节点的值大于等于父结点的值。因此对于一个二叉查找树,我们可以在 O(log n) 的时间内查找一个值是否存在:从根节点开始,若当前节点的值大于查找值则向左下走,若当前节点的值小于查找值则向右下走。同时因为二叉查找树是有序的,对其中序遍历的结果即为排好序的数组。 +`二元搜尋樹`(Binary Search Tree, BST)是一種特殊的二元樹:對於每個父節點,其左子樹中所有節點的值小於等於父節點的值,其右子樹中所有節點的值大於等於父節點的值。因此對於一個二元搜尋樹,我們可以在 $O(\log n)$ 的時間內查找某值是否存在:從根節點開始,若當前節點的值大於查找值則向左下走,若當前節點的值小於查找值則向右下走。同時因為二元搜尋樹是有序的,對其中序遍歷的結果即為排好序的陣列。 -例如下面这棵树即为二叉查找树,其中序遍历结果为 [1 2 3 4 5 6]。 +例如下面這棵樹即為二元搜尋樹,其中序遍歷結果為 [1, 2, 3, 4, 5, 6]。 ``` 4 @@ -20,11 +20,11 @@ sidebar_position: 72 ### 題目描述 -给定一个二叉查找树,已知有两个节点被不小心交换了,试复原此树。 +給定一個二元搜尋樹,已知有兩個節點被不小心交換了,試復原此樹。 ### 輸入輸出範例 -输入是一个被误交换两个节点的二叉查找树,输出是改正后的二叉查找树。 +輸入是一個被誤交換兩個節點的二元搜尋樹,輸出是改正後的二元搜尋樹。 ``` Input: @@ -41,11 +41,15 @@ Output: 3 ``` -在这个样例中,2 和 3 被不小心交换了。 +在這個範例中,2 和 3 被不小心交換了。 ### 題解 -我们可以使用中序遍历这个二叉查找树,同时设置一个 prev 指针,记录当前节点中序遍历时的前节点。如果当前节点大于 prev 节点的值,说明需要调整次序。有一个技巧是如果遍历整个序列过程中只出现了一次次序错误,说明就是这两个相邻节点需要被交换;如果出现了两次次序错误,那就需要交换这两个节点。 +我們可以使用中序遍歷這個二元搜尋樹,同時設置一個 `prev` 指標,記錄當前節點中序遍歷時的前一節點。如果當前節點的值小於 `prev` 節點的值,說明次序需要調整。有一個技巧是: + +- 如果遍歷整個序列的過程中只出現一次次序錯誤,說明這兩個相鄰節點需要被交換。 +- 如果出現了兩次次序錯誤,則需要交換這兩個節點。 + @@ -82,7 +86,7 @@ void recoverTree(TreeNode* root) { ```py # 輔助函式。 -# 注意,Python中并不方便在辅函数中直接传指针,因此我们建造长度为1的list进行传引用。 +# 注意,Python 中並不方便在輔函式中直接傳指標,因此我們建造長度為 1 的 list 進行傳引用。 def inorder( root: Optional[TreeNode], mistake1=List[Optional[TreeNode]], @@ -115,11 +119,11 @@ def recoverTree(root: Optional[TreeNode]) -> None: ### 題目描述 -给定一个二叉查找树和两个整数 L 和 R,且 L < R,试修剪此二叉查找树,使得修剪后所有节点的值都在 [L, R] 的范围内。 +給定一個二元搜尋樹和兩個整數 L 和 R,且 L < R,試修剪此二元搜尋樹,使得修剪後所有節點的值都在 [L, R] 的範圍內。 ### 輸入輸出範例 -输入是一个二叉查找树和两个整数 L 和 R,输出一个被修剪好的二叉查找树。 +輸入是一個二元搜尋樹和兩個整數 L 和 R,輸出一個被修剪好的二元搜尋樹。 ``` Input: L = 1, R = 3, tree = @@ -140,7 +144,7 @@ Output: ### 題解 -利用二叉查找树的大小关系,我们可以很容易地利用递归进行树的处理。 +利用二元搜尋樹的大小關係,我們可以很容易地利用遞迴進行樹的處理。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-6-trie.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-6-trie.mdx index 80546986..412a4b6c 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-6-trie.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-6-trie.mdx @@ -2,28 +2,28 @@ sidebar_position: 73 --- -# 13.6 字典树 +# 13.6 字典樹 -字典树(Trie)用于判断字符串是否存在或者是否具有某种字符串前缀。 +字典樹(Trie)用於判斷字串是否存在或者是否具有某種字串前綴。
        ![](13.1.png) -
        图 13.1: 字典树,存储了单词 A、to、tea、ted、ten、i、in 和 inn,以及它们的频率
        +
        圖 13.1: 字典樹,儲存了單字 A、to、tea、ted、ten、i、in 和 inn,以及它們的頻率
        -为什么需要用字典树解决这类问题呢?假如我们有一个储存了近万个单词的字典,即使我们使用哈希,在其中搜索一个单词的实际开销也是非常大的,且无法轻易支持搜索单词前缀。然而由于一个英文单词的长度 n 通常在 10 以内,如果我们使用字典树,则可以在 $O(n)$——近似 $O(1)$ 的时间内完成搜索,且额外开销非常小。 +為什麼需要用字典樹解決這類問題呢?假如我們有一個儲存了近萬個單字的字典,即使我們使用雜湊表,在其中搜尋一個單字的實際開銷也是非常大的,且無法輕易支援搜尋單字前綴。然而由於一個英文單字的長度 n 通常在 10 以內,如果我們使用字典樹,則可以在 $O(n)$——近似 $O(1)$ 的時間內完成搜尋,且額外開銷非常小。 ## [208. Implement Trie (Prefix Tree)](https://leetcode.com/problems/implement-trie-prefix-tree/) ### 題目描述 -尝试建立一个字典树,支持快速插入单词、查找单词、查找单词前缀的功能。 +嘗試建立一個字典樹,支援快速插入單字、查找單字、查找單字前綴的功能。 ### 輸入輸出範例 -以下是数据结构的调用样例。 +以下是資料結構的調用範例。 ``` Trie trie = new Trie(); @@ -37,7 +37,7 @@ trie.search("app"); // true ### 題解 -以下是字典树的典型实现方法。 +以下是字典樹的典型實現方法。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-7-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-7-exercises.md index 285dae73..ac9e968e 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-7-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-7-exercises.md @@ -8,49 +8,49 @@ sidebar_position: 74 ### [226. Invert Binary Tree](https://leetcode.com/problems/invert-binary-tree/) -巧用递归,你可以在五行内完成这道题。 +巧用遞迴,你可以在五行內完成這道題。 --- ### [617. Merge Two Binary Trees](https://leetcode.com/problems/merge-two-binary-trees/) -同样的,利用递归可以轻松搞定。 +同樣的,利用遞迴可以輕鬆搞定。 --- ### [572. Subtree of Another Tree](https://leetcode.com/problems/subtree-of-another-tree/) -子树是对称树的姊妹题,写法也十分类似。 +子樹是對稱樹的姊妹題,寫法也十分類似。 --- ### [404. Sum of Left Leaves](https://leetcode.com/problems/sum-of-left-leaves/) -怎么判断一个节点是不是左节点呢?一种可行的方法是,在辅函数里多传一个参数,表示当前节点是不是父节点的左节点。 +怎麼判斷一個節點是不是左節點呢?一種可行的方法是,在輔函式裡多傳一個參數,表示當前節點是不是父節點的左節點。 --- ### [513. Find Bottom Left Tree Value](https://leetcode.com/problems/find-bottom-left-tree-value/) -最左下角的节点满足什么条件?针对这种条件,我们该如何找到它? +最左下角的節點滿足什麼條件?針對這種條件,我們該如何找到它? --- ### [538. Convert BST to Greater Tree](https://leetcode.com/problems/convert-bst-to-greater-tree/) -尝试利用某种遍历方式来解决此题,每个节点只需遍历一次。 +嘗試利用某種遍歷方式來解決此題,每個節點只需遍歷一次。 --- ### [235. Lowest Common Ancestor of a Binary Search Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/) -利用 BST 的独特性质,这道题可以很轻松完成。 +利用 BST 的獨特性質,這道題可以很輕鬆完成。 --- ### [530. Minimum Absolute Difference in BST](https://leetcode.com/problems/minimum-absolute-difference-in-bst/) -还记得我们所说的,对于 BST 应该利用哪种遍历吗? +還記得我們所說的,對於 BST 應該利用哪種遍歷嗎? --- @@ -58,58 +58,58 @@ sidebar_position: 74 ### [1530. Number of Good Leaf Nodes Pairs](https://leetcode.com/problems/number-of-good-leaf-nodes-pairs/) -题目 543 的变种题,注意在辅函数中,每次更新的全局变量是左右两边距离之和满足条件的数量,而返回的是左右两边所有(长度不溢出的)子节点的高度 +1。 +題目 543 的變種題,注意在輔函式中,每次更新的全域變數是左右兩邊距離之和滿足條件的數量,而返回的是左右兩邊所有(長度不溢出的)子節點的高度 +1。 --- ### [889. Construct Binary Tree from Preorder and Postorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-postorder-traversal/) -给定任意两种遍历结果,我们都可以重建树的结构。 +給定任意兩種遍歷結果,我們都可以重建樹的結構。 --- ### [106. Construct Binary Tree from Inorder and Postorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/) -给定任意两种遍历结果,我们都可以重建树的结构。 +給定任意兩種遍歷結果,我們都可以重建樹的結構。 --- ### [94. Binary Tree Inorder Traversal](https://leetcode.com/problems/binary-tree-inorder-traversal/) -因为前中序后遍历是用递归实现的,而递归的底层实现是栈操作,因此我们总能用栈实现。 +因為前中序後遍歷是用遞迴實現的,而遞迴的底層實現是堆疊操作,因此我們總能用堆疊實現。 --- ### [145. Binary Tree Postorder Traversal](https://leetcode.com/problems/binary-tree-postorder-traversal/) -因为前中序后遍历是用递归实现的,而递归的底层实现是栈操作,因此我们总能用栈实现。 +因為前中序後遍歷是用遞迴實現的,而遞迴的底層實現是堆疊操作,因此我們總能用堆疊實現。 --- ### [236. Lowest Common Ancestor of a Binary Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/) -现在不是 BST,而是普通的二叉树了,该怎么办? +現在不是 BST,而是普通的二元樹了,該怎麼辦? --- ### [109. Convert Sorted List to Binary Search Tree](https://leetcode.com/problems/convert-sorted-list-to-binary-search-tree/) -把排好序的链表变成 BST。为了使得 BST 尽量平衡,我们需要寻找链表的中点。 +把排好序的鏈結串列變成 BST。為了使得 BST 盡量平衡,我們需要尋找鏈結串列的中點。 --- ### [897. Increasing Order Search Tree](https://leetcode.com/problems/increasing-order-search-tree/) -把 BST 压成一个链表,务必考虑清楚指针操作的顺序,否则可能会出现环路。 +把 BST 壓成一個鏈結串列,務必考慮清楚指標操作的順序,否則可能會出現環路。 --- ### [653. Two Sum IV - Input is a BST](https://leetcode.com/problems/two-sum-iv-input-is-a-bst/) -啊哈,这道题可能会把你骗到。 +啊哈,這道題可能會把你騙到。 --- ### [450. Delete Node in a BST](https://leetcode.com/problems/delete-node-in-a-bst/) -当寻找到待删节点时,你可以分情况考虑——当前节点是叶节点、只有一个子节点和有两个子节点。建议同时回收内存。 \ No newline at end of file +當尋找到待刪節點時,你可以分情況考慮——當前節點是葉節點、只有一個子節點和有兩個子節點。建議同時回收記憶體。 From e36ad5535a4442aa75e9056ddbd0ffb4a693c201 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Wed, 27 Nov 2024 21:57:27 +0100 Subject: [PATCH 34/49] i18n chapter 14 --- .../14-1-data-structure-introduction.mdx | 8 +++---- .../14-graphs/14-2-bipartite-graph.mdx | 12 +++++------ .../14-graphs/14-3-topological-sorting.mdx | 21 ++++++++++++------- .../14-1-data-structure-introduction.mdx | 8 +++---- .../14-graphs/14-2-bipartite-graph.mdx | 12 +++++------ .../14-graphs/14-3-topological-sorting.mdx | 21 ++++++++++++------- .../current/14-graphs/14-4-exercises.md | 14 ++++++++++--- 7 files changed, 59 insertions(+), 37 deletions(-) diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-1-data-structure-introduction.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-1-data-structure-introduction.mdx index 8e592d82..ac08203f 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-1-data-structure-introduction.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-1-data-structure-introduction.mdx @@ -2,15 +2,15 @@ sidebar_position: 75 --- -# 14.1 数据结构介绍 +# 14.1 Data Structure Introduction -作为指针三剑客之三,图是树的升级版。`图`通常分为有向(directed)或无向(undirected),有循环(cyclic)或无循环(acyclic),所有节点相连(connected)或不相连(disconnected)。树即是一个相连的无向无环图,而另一种很常见的图是`有向无环图`(Directed Acyclic Graph,DAG)。 +As the third member of the pointer triumvirate, graphs are an advanced version of trees. A `graph` can be classified as directed or undirected, cyclic or acyclic, and connected or disconnected. A tree is essentially a connected, undirected, acyclic graph. Another common type of graph is the `Directed Acyclic Graph (DAG)`.
        ![](14.1.png) -
        图 14.1: 有向无环图样例
        +
        Figure 14.1: Example of a Directed Acyclic Graph
        -图通常有两种表示方法。假设图中一共有 n 个节点、m 条边。第一种表示方法是`邻接矩阵`(adjacency matrix):我们可以建立一个 n × n 的矩阵 G,如果第 i 个节点连向第 j 个节点,则 G[i][j] = 1,反之为 0;如果图是无向的,则这个矩阵一定是对称矩阵,即 G[i][j] = G[j][i]。第二种表示方法是`邻接链表`(adjacency list):我们可以建立一个大小为 n 的数组,每个位置 i 储存一个数组或者链表,表示第 i 个节点连向的其它节点。邻接矩阵空间开销比邻接链表大,但是邻接链表不支持快速查找 i 和 j 是否相连,因此两种表示方法可以根据题目需要适当选择。除此之外,我们也可以直接用一个 m × 2 的矩阵储存所有的边。 \ No newline at end of file +There are two common ways to represent a graph. Suppose there are `n` nodes and `m` edges in the graph. The first method is the `adjacency matrix`: we can create an `n × n` matrix `G`, where `G[i][j] = 1` if node `i` is connected to node `j`, and `0` otherwise. For an undirected graph, the matrix is symmetric, i.e., `G[i][j] = G[j][i]`. The second method is the `adjacency list`: we can create an array of size `n`, where each index `i` stores an array or linked list representing the nodes connected to node `i`. The adjacency matrix requires more memory but allows for faster edge lookup, whereas the adjacency list is more space-efficient but does not support quick edge existence checks. Additionally, we can use an `m × 2` matrix to store all the edges directly. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-2-bipartite-graph.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-2-bipartite-graph.mdx index ce5ee08d..12fa3fb6 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-2-bipartite-graph.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-2-bipartite-graph.mdx @@ -2,19 +2,19 @@ sidebar_position: 76 --- -# 14.2 二分图 +# 14.2 Bipartite Graph -`二分图`算法也称为`染色法`,是一种广度优先搜索。如果可以用两种颜色对图中的节点进行着色,并且保证相邻的节点颜色不同,那么图为二分。 +The `bipartite graph` algorithm, also known as the `coloring method`, uses a breadth-first search (BFS). A graph is bipartite if its nodes can be colored using two colors such that no two adjacent nodes have the same color. ## [785. Is Graph Bipartite?](https://leetcode.com/problems/is-graph-bipartite/) ### Problem Description -给定一个图,判断其是否可以二分。 +Given a graph, determine if it is bipartite. ### Input and Output Example -输入是邻接链表表示的图(如位置 0 的邻接链表为 [1,3],表示 0 与 1、0 与 3 相连);输出是一个布尔值,表示图是否二分。 +The input is a graph represented as an adjacency list (e.g., position `0` in the adjacency list is `[1,3]`, indicating node `0` is connected to nodes `1` and `3`). The output is a boolean value indicating whether the graph is bipartite. ``` Input: [[1,3], [0,2], [1,3], [0,2]] @@ -25,11 +25,11 @@ Input: [[1,3], [0,2], [1,3], [0,2]] Output: true ``` -在这个样例中,我们可以把 {0,2} 分为一组,把 {1,3} 分为另一组。 +In this example, we can partition the nodes into two groups: `{0,2}` and `{1,3}`. ### Solution Explanation -利用队列和广度优先搜索,我们可以对未染色的节点进行染色,并且检查是否有颜色相同的相邻节点存在。注意在代码中,我们用 0 表示未检查的节点,用 1 和 2 表示两种不同的颜色。 +Using a queue and breadth-first search (BFS), we can color unvisited nodes and check whether adjacent nodes share the same color. In the code, `0` represents unvisited nodes, and `1` and `2` represent the two different colors. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-3-topological-sorting.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-3-topological-sorting.mdx index d49ee4ad..1fa8fa8e 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-3-topological-sorting.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/14-graphs/14-3-topological-sorting.mdx @@ -2,32 +2,39 @@ sidebar_position: 77 --- -# 14.3 拓扑排序 +# 14.3 Topological Sort -`拓扑排序`(topological sort)是一种常见的,对有向无环图排序的算法。给定有向无环图中的 $N$ 个节点,我们把它们排序成一个线性序列;若原图中节点 i 指向节点 j,则排序结果中 i 一定在 j 之前。拓扑排序的结果不是唯一的,只要满足以上条件即可。 +`Topological Sort` is a common algorithm used to order nodes in a directed acyclic graph (DAG). Given $N$ nodes in a DAG, the goal is to arrange them in a linear sequence such that if node $i$ points to node $j$, then $i$ appears before $j$ in the sequence. The result of a topological sort is not unique as long as the above condition is satisfied. ## [210. Course Schedule II](https://leetcode.com/problems/course-schedule-ii/) ### Problem Description -给定 N 个课程和这些课程的前置必修课,求可以一次性上完所有课的顺序。 +Given $N$ courses and their prerequisites, determine an order in which all the courses can be completed. ### Input and Output Example -输入是一个正整数,表示课程数量,和一个二维矩阵,表示所有的有向边(如 [1,0] 表示上课程 1 之前必须先上课程 0)。输出是一个一维数组,表示拓扑排序结果。 +The input consists of a positive integer representing the number of courses and a 2D array representing directed edges (e.g., `[1,0]` indicates course 1 must be taken after course 0). The output is a 1D array representing a topological order. ``` Input: numCourses = 4, prerequisites = [[1,0],[2,0],[3,1],[3,2]] Output: [0,1,2,3] ``` -在这个样例中,另一种可行的顺序是 [0,2,1,3]。 +In this example, another valid order could be `[0,2,1,3]`. ### Solution Explanation -我们可以先建立一个邻接矩阵表示图,方便进行直接查找。这里注意我们将所有的边反向,使得如果课程 i 指向课程 j,那么课程 i 需要在课程 j 前面先修完。这样更符合我们的直观理解。 +e can first build an adjacency matrix to represent the graph, facilitating direct lookups. Note that we reverse all edges, so if course $i$ points to course $j$, it means course $i$ must be completed before course $j$. This aligns with our intuitive understanding of prerequisites. -拓扑排序也可以被看成是广度优先搜索的一种情况:我们先遍历一遍所有节点,把入度为 0 的节点(即没有前置课程要求)放在队列中。在每次从队列中获得节点时,我们将该节点放在目前排序的末尾,并且把它指向的课程的入度各减 1;如果在这个过程中有课程的所有前置必修课都已修完(即入度为 0),我们把这个节点加入队列中。当队列的节点都被处理完时,说明所有的节点都已排好序,或因图中存在循环而无法上完所有课程。 +Topological sorting can be viewed as a special case of breadth-first search (BFS): + +1. Traverse all nodes and enqueue nodes with an in-degree of $0$ (i.e., nodes without prerequisites). +2. While processing the queue: + - Add the current node to the sorted order. + - Decrease the in-degree of all nodes it points to by $1$. + - If a node’s in-degree becomes $0$, enqueue it. +3. When the queue is empty, the nodes are either fully sorted, or a cycle exists in the graph, preventing all courses from being completed. diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-1-data-structure-introduction.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-1-data-structure-introduction.mdx index 8e592d82..b5c858b8 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-1-data-structure-introduction.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-1-data-structure-introduction.mdx @@ -2,15 +2,15 @@ sidebar_position: 75 --- -# 14.1 数据结构介绍 +# 14.1 資料結構介紹 -作为指针三剑客之三,图是树的升级版。`图`通常分为有向(directed)或无向(undirected),有循环(cyclic)或无循环(acyclic),所有节点相连(connected)或不相连(disconnected)。树即是一个相连的无向无环图,而另一种很常见的图是`有向无环图`(Directed Acyclic Graph,DAG)。 +作為指標三劍客之一,圖是樹的升級版。`圖`通常可以分為有向(directed)或無向(undirected)、有循環(cyclic)或無循環(acyclic)、所有節點相連(connected)或不相連(disconnected)。樹其實就是一種相連的無向無環圖,而另一種很常見的圖則是`有向無環圖`(Directed Acyclic Graph,DAG)。
        ![](14.1.png) -
        图 14.1: 有向无环图样例
        +
        圖 14.1: 有向無環圖範例
        -图通常有两种表示方法。假设图中一共有 n 个节点、m 条边。第一种表示方法是`邻接矩阵`(adjacency matrix):我们可以建立一个 n × n 的矩阵 G,如果第 i 个节点连向第 j 个节点,则 G[i][j] = 1,反之为 0;如果图是无向的,则这个矩阵一定是对称矩阵,即 G[i][j] = G[j][i]。第二种表示方法是`邻接链表`(adjacency list):我们可以建立一个大小为 n 的数组,每个位置 i 储存一个数组或者链表,表示第 i 个节点连向的其它节点。邻接矩阵空间开销比邻接链表大,但是邻接链表不支持快速查找 i 和 j 是否相连,因此两种表示方法可以根据题目需要适当选择。除此之外,我们也可以直接用一个 m × 2 的矩阵储存所有的边。 \ No newline at end of file +圖通常有兩種表示方法。假設圖中有 `n` 個節點和 `m` 條邊。第一種表示方法是`鄰接矩陣`(adjacency matrix):我們可以建立一個 `n × n` 的矩陣 `G`,如果第 `i` 個節點連向第 `j` 個節點,則 `G[i][j] = 1`,反之為 `0`;如果圖是無向的,則此矩陣必定是對稱矩陣,即 `G[i][j] = G[j][i]`。第二種表示方法是`鄰接鏈結串列`(adjacency list):我們可以建立一個大小為 `n` 的陣列,每個位置 `i` 儲存一個陣列或鏈結串列,表示第 `i` 個節點連向的其他節點。鄰接矩陣的空間開銷比鄰接鏈結串列大,但鄰接鏈結串列不支援快速查找節點 `i` 和節點 `j` 是否相連。因此,可以根據題目的需要選擇適合的表示方法。此外,我們也可以直接用一個 `m × 2` 的矩陣來儲存所有的邊。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-2-bipartite-graph.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-2-bipartite-graph.mdx index 883bbc4e..95cc7555 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-2-bipartite-graph.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-2-bipartite-graph.mdx @@ -2,19 +2,19 @@ sidebar_position: 76 --- -# 14.2 二分图 +# 14.2 二分圖 -`二分图`算法也称为`染色法`,是一种广度优先搜索。如果可以用两种颜色对图中的节点进行着色,并且保证相邻的节点颜色不同,那么图为二分。 +`二分圖`演算法也稱為`染色法`,是一種廣度優先搜索。如果能用兩種顏色對圖中的節點進行著色,且保證相鄰的節點顏色不同,那麼這個圖就是二分圖。 ## [785. Is Graph Bipartite?](https://leetcode.com/problems/is-graph-bipartite/) ### 題目描述 -给定一个图,判断其是否可以二分。 +給定一個圖,判斷它是否可以二分。 ### 輸入輸出範例 -输入是邻接链表表示的图(如位置 0 的邻接链表为 [1,3],表示 0 与 1、0 与 3 相连);输出是一个布尔值,表示图是否二分。 +輸入是一個鄰接鏈結串列表示的圖(例如位置 0 的鄰接鏈結串列為 `[1,3]`,表示節點 0 與節點 1 相連,節點 0 與節點 3 相連);輸出是一個布林值,表示圖是否二分。 ``` Input: [[1,3], [0,2], [1,3], [0,2]] @@ -25,11 +25,11 @@ Input: [[1,3], [0,2], [1,3], [0,2]] Output: true ``` -在这个样例中,我们可以把 {0,2} 分为一组,把 {1,3} 分为另一组。 +在這個範例中,我們可以把 `{0,2}` 分為一組,把 `{1,3}` 分為另一組。 ### 題解 -利用队列和广度优先搜索,我们可以对未染色的节点进行染色,并且检查是否有颜色相同的相邻节点存在。注意在代码中,我们用 0 表示未检查的节点,用 1 和 2 表示两种不同的颜色。 +利用佇列和廣度優先搜索,我們可以對未著色的節點進行著色,並檢查是否存在顏色相同的相鄰節點。注意在程式碼中,我們使用 `0` 表示未檢查的節點,使用 `1` 和 `2` 表示兩種不同的顏色。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-3-topological-sorting.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-3-topological-sorting.mdx index 8a9dcb1d..0e48f56a 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-3-topological-sorting.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-3-topological-sorting.mdx @@ -2,32 +2,39 @@ sidebar_position: 77 --- -# 14.3 拓扑排序 +# 14.3 拓撲排序 -`拓扑排序`(topological sort)是一种常见的,对有向无环图排序的算法。给定有向无环图中的 $N$ 个节点,我们把它们排序成一个线性序列;若原图中节点 i 指向节点 j,则排序结果中 i 一定在 j 之前。拓扑排序的结果不是唯一的,只要满足以上条件即可。 +`拓撲排序`(topological sort)是一種常見的算法,用於對有向無環圖(DAG)進行排序。給定 DAG 中的 $N$ 個節點,我們需要將它們排序成一個線性序列;如果節點 $i$ 指向節點 $j$,則排序結果中 $i$ 必須在 $j$ 之前。拓撲排序的結果並不唯一,只要滿足以上條件即可。 ## [210. Course Schedule II](https://leetcode.com/problems/course-schedule-ii/) ### 題目描述 -给定 N 个课程和这些课程的前置必修课,求可以一次性上完所有课的顺序。 +給定 $N$ 門課程以及它們的前置必修課,找出可以一次性完成所有課程的修課順序。 ### 輸入輸出範例 -输入是一个正整数,表示课程数量,和一个二维矩阵,表示所有的有向边(如 [1,0] 表示上课程 1 之前必须先上课程 0)。输出是一个一维数组,表示拓扑排序结果。 +輸入是一個正整數,表示課程數量,以及一個二維陣列,表示所有的有向邊(例如 `[1,0]` 表示課程 1 必須在課程 0 之後修完)。輸出是一個一維陣列,表示拓撲排序的結果。 ``` Input: numCourses = 4, prerequisites = [[1,0],[2,0],[3,1],[3,2]] Output: [0,1,2,3] ``` -在这个样例中,另一种可行的顺序是 [0,2,1,3]。 +在這個例子中,另一種可行的順序是 `[0,2,1,3]`。 ### 題解 -我们可以先建立一个邻接矩阵表示图,方便进行直接查找。这里注意我们将所有的边反向,使得如果课程 i 指向课程 j,那么课程 i 需要在课程 j 前面先修完。这样更符合我们的直观理解。 +我們可以先建立一個鄰接矩陣來表示圖,方便進行直接查找。這裡注意,我們將所有的邊進行反向處理,使得如果課程 $i$ 指向課程 $j$,表示課程 $i$ 必須在課程 $j$ 之前完成。這樣處理更符合我們對前置課程的直觀理解。 -拓扑排序也可以被看成是广度优先搜索的一种情况:我们先遍历一遍所有节点,把入度为 0 的节点(即没有前置课程要求)放在队列中。在每次从队列中获得节点时,我们将该节点放在目前排序的末尾,并且把它指向的课程的入度各减 1;如果在这个过程中有课程的所有前置必修课都已修完(即入度为 0),我们把这个节点加入队列中。当队列的节点都被处理完时,说明所有的节点都已排好序,或因图中存在循环而无法上完所有课程。 +拓撲排序可以看作是廣度優先搜索(BFS)的一種特殊情況: + +1. 遍歷所有節點,將入度為 $0$ 的節點(即無前置課程要求的節點)加入隊列。 +2. 處理隊列中的節點: + - 將當前節點加入排序結果中。 + - 將當前節點指向的所有節點的入度減少 $1$。 + - 如果某個節點的入度變為 $0$,將該節點加入隊列。 +3. 當隊列處理完畢後,若所有節點均已排序,則完成拓撲排序;否則,若圖中存在環,則無法完成所有課程。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-4-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-4-exercises.md index bbc7ae3c..9000cc1c 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-4-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/14-graphs/14-4-exercises.md @@ -8,7 +8,7 @@ sidebar_position: 78 ### [1059. All Paths from Source Lead to Destination](https://leetcode.com/problems/all-paths-from-source-lead-to-destination/) -虽然使用深度优先搜索可以解决大部分的图遍历问题,但是注意判断是否陷入了环路。 +雖然使用深度優先搜尋(DFS)可以解決大部分圖的遍歷問題,但需要特別注意檢查是否陷入了環路。 --- @@ -16,10 +16,18 @@ sidebar_position: 78 ### [1135. Connecting Cities With Minimum Cost](https://leetcode.com/problems/connecting-cities-with-minimum-cost/) -笔者其实已经把这道题的题解写好了,才发现这道题是需要解锁才可以看的题目。为了避免版权纠纷,故将其移至练习题内。本题考察最小生成树(minimum spanning tree, MST)的求法,通常可以用两种方式求得:Prim’s Algorithm,利用优先队列选择最小的消耗;以及 Kruskal’s Algorithm,排序后使用并查集。 +筆者其實已經撰寫了這道題的詳細解答,但後來發現該題需要付費解鎖才能查看。為了避免版權糾紛,將此題移至練習題中。本題考察最小生成樹(minimum spanning tree, MST)的求法,通常可以用兩種演算法實現: + +- **Prim’s Algorithm**:利用優先佇列選擇最小的消耗。 +- **Kruskal’s Algorithm**:對邊排序後使用並查集(Union-Find)。 --- ### [882. Reachable Nodes In Subdivided Graph](https://leetcode.com/problems/reachable-nodes-in-subdivided-graph/) -这道题笔者考虑了很久,最终决定把它放在练习题而非详细讲解。本题是经典的节点最短距离问题,常用的算法有 Bellman-Ford 单源最短路算法,以及 Dijkstra 无负边单源最短路算法。虽然经典,但是 LeetCode 很少有相关的题型,因此这里仅供读者自行深入学习。 \ No newline at end of file +筆者考慮了很久,最終決定將這道題放在練習題中,而非詳細講解。本題屬於經典的節點最短距離問題,常用的解法包括: + +- **Bellman-Ford** 單源最短路演算法(允許負邊權重)。 +- **Dijkstra** 無負邊單源最短路演算法。 + +雖然這些都是經典演算法,但 LeetCode 中相關題型較少,因此這裡僅供讀者自行深入學習。 \ No newline at end of file From faa23b1d92c0dc20dff1ca53ecb4122085404e62 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Wed, 27 Nov 2024 22:24:47 +0100 Subject: [PATCH 35/49] i18n chapter 15 --- .../10-2-python-data-structures.md | 2 +- .../10-6-priority-queue.mdx | 2 +- .../10-data-structures/10-8-hash-table.mdx | 2 +- .../15-4-exercises.md | 2 +- .../15-1-introduction.md | 4 +-- .../15-2-union-find.mdx | 20 ++++++------ .../15-3-composite-data-structures.mdx | 32 +++++++++---------- .../15-4-exercises.md | 8 ++--- .../10-2-python-data-structures.md | 2 +- .../10-data-structures/10-8-hash-table.mdx | 2 +- .../15-1-introduction.md | 2 +- .../15-2-union-find.mdx | 20 ++++++------ .../15-3-composite-data-structures.mdx | 29 ++++++++--------- .../15-4-exercises.md | 6 ++-- 14 files changed, 65 insertions(+), 68 deletions(-) diff --git a/leetcode_101/docs/10-data-structures/10-2-python-data-structures.md b/leetcode_101/docs/10-data-structures/10-2-python-data-structures.md index b4221a27..906ce872 100644 --- a/leetcode_101/docs/10-data-structures/10-2-python-data-structures.md +++ b/leetcode_101/docs/10-data-structures/10-2-python-data-structures.md @@ -15,7 +15,7 @@ sidebar_position: 49 3. Ordered Associative Containers:有序关联容器。 1. collections.OrderedDict:`顺序映射或顺序表`,注意这里的 Ordered 不同于 C++ 中 map的按大小排序,而是按照插入的先后次序排序。OrderedDict 很适合用来做 LRU。 4. Unordered Associative Containers:无序关联容器。 - 1. set:`哈希集合`,可以在 O(1) 的时间快速插入、查找、删除元素,常用于快速的查询一个元素是否在这个容器内。 + 1. set:`哈希集合`,可以在 $O(1)$ 的时间快速插入、查找、删除元素,常用于快速的查询一个元素是否在这个容器内。 2. dict:`哈希映射或哈希表`,在 set 的基础上加上映射关系,可以对每一个元素 key 存一个值 value。在某些情况下,如果 key 的范围已知且较小,我们也可以用 list 代替 dict,用位置表示 key,用每个位置的值表示 value。 3. collections.Counter:`计数器`,是 dict 的一个特殊版本,可以直接传入一个 list,并对其中的每一个元素进行计数统计,key 是元素值,value 是元素出现的频次。可以用来当作多重集合。 diff --git a/leetcode_101/docs/10-data-structures/10-6-priority-queue.mdx b/leetcode_101/docs/10-data-structures/10-6-priority-queue.mdx index 85ded21f..8abab8ef 100644 --- a/leetcode_101/docs/10-data-structures/10-6-priority-queue.mdx +++ b/leetcode_101/docs/10-data-structures/10-6-priority-queue.mdx @@ -4,7 +4,7 @@ sidebar_position: 53 # 10.6 优先队列 -`优先队列`(priority queue)可以在 O(1) 时间内获得最大值,并且可以在 O(log n) 时间内取出最大值或插入任意值。 +`优先队列`(priority queue)可以在 $O(1)$ 时间内获得最大值,并且可以在 O(log n) 时间内取出最大值或插入任意值。
        diff --git a/leetcode_101/docs/10-data-structures/10-8-hash-table.mdx b/leetcode_101/docs/10-data-structures/10-8-hash-table.mdx index 36531124..7053facd 100644 --- a/leetcode_101/docs/10-data-structures/10-8-hash-table.mdx +++ b/leetcode_101/docs/10-data-structures/10-8-hash-table.mdx @@ -4,7 +4,7 @@ sidebar_position: 55 # 10.8 哈希表 -`哈希表(hash table, hash map)`,又称散列表,使用 $O(n)$ 空间复杂度存储数据,通过哈希函数(hash function)映射位置,从而实现近似 O(1) 时间复杂度的插入、查找、删除等操作。哈希表可以用来统计频率,记录内容等等。 +`哈希表(hash table, hash map)`,又称散列表,使用 $O(n)$ 空间复杂度存储数据,通过哈希函数(hash function)映射位置,从而实现近似 $O(1)$ 时间复杂度的插入、查找、删除等操作。哈希表可以用来统计频率,记录内容等等。 如果元素有穷,并且范围不大,那么可以用一个固定大小的数组来存储或统计元素。例如我们需要统计一个字符串中所有字母的出现次数,则可以用一个长度为 26 的数组来进行统计,其哈希函数即为字母在字母表的位置,这样空间复杂度就可以降低为常数。 diff --git a/leetcode_101/docs/15-advanced-data-structures/15-4-exercises.md b/leetcode_101/docs/15-advanced-data-structures/15-4-exercises.md index 9f48dbb4..53d544da 100644 --- a/leetcode_101/docs/15-advanced-data-structures/15-4-exercises.md +++ b/leetcode_101/docs/15-advanced-data-structures/15-4-exercises.md @@ -16,7 +16,7 @@ sidebar_position: 78 ### [432. All O`one Data Structure](https://leetcode.com/problems/all-oone-data-structure/) -设计一个 increaseKey,decreaseKey,getMaxKey,getMinKey 均为 O(1) 时间复杂度的数据结构。 +设计一个 increaseKey,decreaseKey,getMaxKey,getMinKey 均为 $O(1)$ 时间复杂度的数据结构。 --- diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-1-introduction.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-1-introduction.md index 26e5cdac..1237fceb 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-1-introduction.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-1-introduction.md @@ -2,6 +2,6 @@ sidebar_position: 75 --- -# 15.1 引言 +# 15.1 Introduction -目前为止,我们接触了大量的数据结构,包括利用指针实现的三剑客和 C++ 自带的 STL 等。对于一些题目,我们不仅需要利用多个数据结果解决问题,还需要把这些数据结构进行嵌套和联动,进行更为复杂、更为快速的操作。 \ No newline at end of file +So far, we have explored a wide range of data structures, including the "pointer trio" (linked list, tree, and graph) and C++'s built-in STL library. For certain problems, it is necessary not only to utilize multiple data structures but also to nest and integrate them, enabling more complex and efficient operations. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-2-union-find.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-2-union-find.mdx index de94cf53..5e786f67 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-2-union-find.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-2-union-find.mdx @@ -2,26 +2,26 @@ sidebar_position: 76 --- -# 15.2 并查集 +# 15.2 Union-Find -`并查集`(union-find, disjoint set)可以动态地连通两个点,并且可以非常快速地判断两个点是否连通。假设存在 n 个节点,我们先将所有节点的父节点标为自己;每次要连接节点 i 和 j 时,我们可以将秩较小一方的父节点标为另一方(按秩合并);每次要查询两个节点是否相连时,我们可以查找 i 和 j 的祖先是否最终为同一个人,并减少祖先层级(路径压缩)。 +`Union-Find` (disjoint set) is a data structure used for dynamic connectivity problems. It efficiently connects two points and determines whether two points are connected. Given `n` nodes, we initialize the parent of each node to itself. To connect nodes `i` and `j`, we attach the smaller rank's parent to the larger rank's parent (union by rank). To check if two nodes are connected, we find their ancestors and determine if they are the same, applying path compression to speed up subsequent queries.
        ![](15.1.png) -
        图 15.1: 并查集样例,其中 union 操作可以将两个集合按秩合并,find 操作可以查找节点的祖先并压缩路径。
        +
        Figure 15.1: Union-Find Example. `union` merges two sets by rank, and `find` retrieves a node's ancestor while compressing paths.
        ## [684. Redundant Connection](https://leetcode.com/problems/redundant-connection/) ### Problem Description -在无向图找出一条边,移除它之后该图能够成为一棵树(即无向无环图)。如果有多个解,返回在原数组中位置最靠后的那条边。 +In an undirected graph, find an edge that, when removed, leaves the graph as a tree (i.e., acyclic and connected). If there are multiple solutions, return the edge appearing last in the input. ### Input and Output Example -输入是一个二维数组,表示所有的边(对应的两个节点);输出是一个一维数组,表示需要移除的边(对应的两个节点)。 +The input is a 2D array representing all edges (pairs of nodes), and the output is a 1D array representing the edge to remove. ``` Input: [[1,2], [1,3], [2,3]] @@ -33,7 +33,7 @@ Output: [2,3] ### Solution Explanation -因为需要判断是否两个节点被重复连通,所以我们可以使用并查集来解决此类问题。具体实现算法如下所示。 +Since we need to determine whether two nodes are repeatedly connected, we can solve this problem using the Union-Find data structure. The detailed implementation is as follows: @@ -60,7 +60,7 @@ class Solution { private: int find(int i) { - // 路径压缩。 + // Path Compression while (i != id_[i]) { id_[i] = id_[id_[i]]; i = id_[i]; @@ -73,7 +73,7 @@ class Solution { if (i == j) { return; } - // 按秩合并。 + // Union by Rank if (depth_[i] <= depth_[j]) { id_[i] = j; depth_[j] = max(depth_[j], depth_[i] + 1); @@ -102,7 +102,7 @@ class Solution: self.depth = None def find(self, i: int) -> int: - # 路径压缩。 + # Path Compression while i != self.id[i]: self.id[i] = self.id[self.id[i]] i = self.id[i] @@ -113,7 +113,7 @@ class Solution: j = self.find(j) if i == j: return - # 按秩合并。 + # Union by Rank if self.depth[i] <= self.depth[j]: self.id[i] = j self.depth[j] = max(self.depth[j], self.depth[i] + 1) diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-3-composite-data-structures.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-3-composite-data-structures.mdx index b9b28338..e4642b88 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-3-composite-data-structures.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-3-composite-data-structures.mdx @@ -2,36 +2,36 @@ sidebar_position: 77 --- -# 15.3 复合数据结构 +# 15.3 Composite Data Structures -这一类题通常采用哈希表或有序表辅助记录,从而加速寻址;再配上数组或者链表进行连续的数据储存,从而加速连续选址或删除值。 +This type of problem often uses a hash table or ordered map for auxiliary record-keeping to speed up lookups; paired with arrays or linked lists for continuous data storage to expedite sequential selection or value deletion. ## [146. LRU Cache](https://leetcode.com/problems/lru-cache/) ### Problem Description -设计一个固定大小的,最近最少使用缓存 (least recently used cache, LRU)。每次将信息插入未满的缓存的时候,以及更新或查找一个缓存内存在的信息的时候,将该信息标为最近使用。在缓存满的情况下将一个新信息插入的时候,需要移除最旧的信息,插入新信息,并将该新信息标为最近使用。 +Design a fixed-size Least Recently Used Cache (LRU). When inserting data into a non-full cache or updating/retrieving existing data in the cache, mark the data as recently used. When the cache is full, evict the least recently used data, insert the new data, and mark it as recently used. ### Input and Output Example -以下是数据结构的调用样例。给定一个大小为 n 的缓存,利用最近最少使用策略储存数据。 +Here is an example of calling this data structure. Given a cache with size `n`, store data using the least recently used strategy. ``` LRUCache cache = new LRUCache( 2 /* capacity */ ); cache.put(1, 1); cache.put(2, 2); -cache.get(1); // 输出 value 1 -cache.put(3, 3); // 移除 key 2 -cache.get(2); // 输出 value -1 (未找到) -cache.put(4, 4); // 移除 key 1 -cache.get(1); // 输出 value -1 (未找到) -cache.get(3); // 输出 value 3 -cache.get(4); // 输出 value 4 +cache.get(1); // Output value 1 +cache.put(3, 3); // Evict key 2 +cache.get(2); // Output value -1 (not found) +cache.put(4, 4); // Evict key 1 +cache.get(1); // Output value -1 (not found) +cache.get(3); // Output value 3 +cache.get(4); // Output value 4 ``` ### Solution Explanation -我们采用一个链表来储存信息的 key 和 value,链表的链接顺序即为最近使用的新旧顺序,最新的信息在链表头节点。同时我们需要一个哈希表进行查找,键是信息的 key,值是其在链表中的对应指针/迭代器。每次查找成功(cache hit)时,需要把指针/迭代器对应的节点移动到链表的头节点。 +We use a linked list to store the keys and values, with the order of the linked list representing the least-to-most recently used sequence. The most recently used data resides at the head of the list. Additionally, a hash table is used for lookups, where the key corresponds to the data key and the value points to the corresponding pointer/iterator in the linked list. On every cache hit (successful lookup), the corresponding node is moved to the head of the linked list. @@ -141,7 +141,7 @@ class LRUCache: -对于 Python 而言,我们还可以直接利用 OrderedDict 函数实现 LRU,这将大大简化题目难度。这里笔者希望读者还是仔细研读一下以上题解,了解 LRU 实现的核心原理。 +In Python, we can directly use the `OrderedDict` function to implement LRU, which significantly simplifies the problem. However, the author encourages readers to carefully study the explanation above to understand the core principles behind LRU implementation. ```py @@ -168,11 +168,11 @@ class LRUCache: ### Problem Description -设计一个插入、删除和随机取值均为 $O(1)$ 时间复杂度的数据结构。 +Design a data structure that supports insertion, deletion, and random access, all in $O(1)$ time complexity. ### Input and Output Example -以下是数据结构的调用样例。 +Here is an example of how the data structure is used: ``` RandomizedSet randomizedSet = new RandomizedSet(); @@ -187,7 +187,7 @@ randomizedSet.getRandom(); // 100% 2 ### Solution Explanation -我们采用一个数组存储插入的数字,同时利用一个哈希表查找位置。每次插入数字时,直接加入数组,且将位置记录在哈希表中。每次删除数字时,将当前数组最后一位与删除位互换,并更新哈希表。随机取值时,则可以在数组内任意选取位置。 +We use an array to store the inserted numbers and a hash table to track their positions. When inserting a number, we add it directly to the array and record its position in the hash table. When deleting a number, we swap the current last element of the array with the element to be removed and update the hash table. For random access, we can simply select any position in the array. diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-4-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-4-exercises.md index 78a90026..74a99c00 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-4-exercises.md +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-4-exercises.md @@ -6,11 +6,9 @@ sidebar_position: 78 ## Basic Difficulty ---- - ### [1135. Connecting Cities With Minimum Cost](https://leetcode.com/problems/connecting-cities-with-minimum-cost/) -使用并查集,按照 Kruskal’s Algorithm 把这道题再解决一次吧。 +Solve this problem again using union-find and Kruskal’s Algorithm. --- @@ -18,10 +16,10 @@ sidebar_position: 78 ### [432. All O`one Data Structure](https://leetcode.com/problems/all-oone-data-structure/) -设计一个 increaseKey,decreaseKey,getMaxKey,getMinKey 均为 O(1) 时间复杂度的数据结构。 +Design a data structure that supports increaseKey, decreaseKey, getMaxKey, and getMinKey, all in $O(1)$ time complexity. --- ### [716. Max Stack](https://leetcode.com/problems/max-stack/) -设计一个支持 push,pop,top,getMax 和 popMax 的 stack。可以用类似 LRU 的方法降低时间复杂度,但是因为想要获得的是最大值,我们应该把 unordered_map 换成哪一种数据结构呢? \ No newline at end of file +Design a stack that supports push, pop, top, getMax, and popMax. You can use a method similar to LRU to reduce time complexity, but since we need to get the maximum value, which data structure should replace the unordered_map? diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-2-python-data-structures.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-2-python-data-structures.md index cc063234..48aec81d 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-2-python-data-structures.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-2-python-data-structures.md @@ -17,7 +17,7 @@ sidebar_position: 49 3. **有序關聯容器**: 1. **collections.OrderedDict**:`順序映射或順序表`,注意這裡的 Ordered 與 C++ 中 map 的按大小排序不同,而是按照插入的先後順序排序。`OrderedDict` 非常適合用來實現 LRU(最近最少使用)。 4. **無序關聯容器**: - 1. **set**:`雜湊集合`,可以在 O(1) 的時間內快速插入、查詢和刪除元素,常用於快速查詢某個元素是否存在於容器中。 + 1. **set**:`雜湊集合`,可以在 $O(1)$ 的時間內快速插入、查詢和刪除元素,常用於快速查詢某個元素是否存在於容器中。 2. **dict**:`雜湊映射或雜湊表`,在 set 的基礎上增加了鍵值對的映射關係,可以對每個鍵(key)存儲對應的值(value)。在某些情況下,如果鍵的範圍已知且較小,我們也可以用 list 代替 dict,用索引位置表示鍵,用每個位置的值表示對應的值。 3. **collections.Counter**:`計數器`,是 dict 的一種特殊版本,可以直接傳入一個 list,並對其中的每個元素進行計數統計,鍵為元素值,值為該元素出現的頻次。可以用來作為多重集合。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-8-hash-table.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-8-hash-table.mdx index 318e2faf..e8cca020 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-8-hash-table.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-8-hash-table.mdx @@ -4,7 +4,7 @@ sidebar_position: 55 # 10.8 雜湊表 -`雜湊表(hash table, hash map)`,又稱散列表,使用 $O(n)$ 空間複雜度存儲資料,通過雜湊函數(hash function)映射位置,從而實現近似 O(1) 時間複雜度的插入、查詢、刪除等操作。雜湊表可以用來統計頻率、記錄內容等等。 +`雜湊表(hash table, hash map)`,又稱散列表,使用 $O(n)$ 空間複雜度存儲資料,通過雜湊函數(hash function)映射位置,從而實現近似 $O(1)$ 時間複雜度的插入、查詢、刪除等操作。雜湊表可以用來統計頻率、記錄內容等等。 如果元素是有限的,且範圍不大,那麼可以用一個固定大小的陣列來存儲或統計元素。例如,我們需要統計一個字串中所有字母的出現次數,則可以用一個長度為 26 的陣列來進行統計,其雜湊函數即為字母在字母表中的位置,這樣空間複雜度就可以降低為常數。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-1-introduction.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-1-introduction.md index 26e5cdac..1ecf728e 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-1-introduction.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-1-introduction.md @@ -4,4 +4,4 @@ sidebar_position: 75 # 15.1 引言 -目前为止,我们接触了大量的数据结构,包括利用指针实现的三剑客和 C++ 自带的 STL 等。对于一些题目,我们不仅需要利用多个数据结果解决问题,还需要把这些数据结构进行嵌套和联动,进行更为复杂、更为快速的操作。 \ No newline at end of file +到目前為止,我們已經接觸了大量的資料結構,包括利用指標實現的三劍客(鏈結串列、樹和圖)以及 C++ 自帶的 STL 函式庫。對於某些題目,我們不僅需要使用多種資料結構來解決問題,還需要將這些資料結構進行嵌套與聯動,以實現更複雜且更快速的操作。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-2-union-find.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-2-union-find.mdx index c96d00c8..21855e9b 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-2-union-find.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-2-union-find.mdx @@ -2,26 +2,26 @@ sidebar_position: 76 --- -# 15.2 并查集 +# 15.2 並查集 -`并查集`(union-find, disjoint set)可以动态地连通两个点,并且可以非常快速地判断两个点是否连通。假设存在 n 个节点,我们先将所有节点的父节点标为自己;每次要连接节点 i 和 j 时,我们可以将秩较小一方的父节点标为另一方(按秩合并);每次要查询两个节点是否相连时,我们可以查找 i 和 j 的祖先是否最终为同一个人,并减少祖先层级(路径压缩)。 +`並查集`(union-find, disjoint set)是一種用於動態連通性問題的數據結構,可以高效地實現動態連接兩個點,並快速判斷兩個點是否連通。假設有 n 個節點,我們初始化時將所有節點的父節點設為自身;每次需要連接節點 i 和 j 時,可以將秩較小一方的父節點標記為另一方(按秩合併);每次需要查詢兩個節點是否相連時,可以查找 i 和 j 的祖先是否相同,並通過路徑壓縮減少祖先層級,從而加速後續的查詢操作。
        ![](15.1.png) -
        图 15.1: 并查集样例,其中 union 操作可以将两个集合按秩合并,find 操作可以查找节点的祖先并压缩路径。
        +
        圖 15.1: 並查集範例,其中 union 操作可以將兩個集合按秩合併,find 操作可以查找節點的祖先並壓縮路徑。
        ## [684. Redundant Connection](https://leetcode.com/problems/redundant-connection/) ### 題目描述 -在无向图找出一条边,移除它之后该图能够成为一棵树(即无向无环图)。如果有多个解,返回在原数组中位置最靠后的那条边。 +在無向圖中找出一條邊,移除後該圖可以成為一棵樹(即無向無環圖)。如果有多個解,返回原陣列中位置最靠後的那條邊。 ### 輸入輸出範例 -输入是一个二维数组,表示所有的边(对应的两个节点);输出是一个一维数组,表示需要移除的边(对应的两个节点)。 +輸入是一個二維陣列,表示所有的邊(對應的兩個節點);輸出是一個一維陣列,表示需要移除的邊(對應的兩個節點)。 ``` Input: [[1,2], [1,3], [2,3]] @@ -33,7 +33,7 @@ Output: [2,3] ### 題解 -因为需要判断是否两个节点被重复连通,所以我们可以使用并查集来解决此类问题。具体实现算法如下所示。 +由於需要判斷是否兩個節點被重複連通,我們可以使用並查集來解決此類問題。以下為實現細節: @@ -60,7 +60,7 @@ class Solution { private: int find(int i) { - // 路径压缩。 + // 路徑壓縮。 while (i != id_[i]) { id_[i] = id_[id_[i]]; i = id_[i]; @@ -73,7 +73,7 @@ class Solution { if (i == j) { return; } - // 按秩合并。 + // 按秩合併。 if (depth_[i] <= depth_[j]) { id_[i] = j; depth_[j] = max(depth_[j], depth_[i] + 1); @@ -102,7 +102,7 @@ class Solution: self.depth = None def find(self, i: int) -> int: - # 路径压缩。 + # 路徑壓縮。 while i != self.id[i]: self.id[i] = self.id[self.id[i]] i = self.id[i] @@ -113,7 +113,7 @@ class Solution: j = self.find(j) if i == j: return - # 按秩合并。 + # 按秩合併。 if self.depth[i] <= self.depth[j]: self.id[i] = j self.depth[j] = max(self.depth[j], self.depth[i] + 1) diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-3-composite-data-structures.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-3-composite-data-structures.mdx index b981e52d..d6d81c75 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-3-composite-data-structures.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-3-composite-data-structures.mdx @@ -2,36 +2,36 @@ sidebar_position: 77 --- -# 15.3 复合数据结构 +# 15.3 複合資料結構 -这一类题通常采用哈希表或有序表辅助记录,从而加速寻址;再配上数组或者链表进行连续的数据储存,从而加速连续选址或删除值。 +這一類題目通常採用雜湊表或有序表輔助記錄,以加速尋址;再搭配陣列或鏈結串列進行連續的資料儲存,以加速連續選址或刪除值。 ## [146. LRU Cache](https://leetcode.com/problems/lru-cache/) ### 題目描述 -设计一个固定大小的,最近最少使用缓存 (least recently used cache, LRU)。每次将信息插入未满的缓存的时候,以及更新或查找一个缓存内存在的信息的时候,将该信息标为最近使用。在缓存满的情况下将一个新信息插入的时候,需要移除最旧的信息,插入新信息,并将该新信息标为最近使用。 +設計一個固定大小的最近最少使用快取(Least Recently Used Cache, LRU)。當快取未滿時插入資料,或者查找或更新快取內已存在的資料時,將該資料標記為最近使用。在快取滿的情況下,插入新資料時需要移除最久未使用的資料,插入新資料,並將該新資料標記為最近使用。 ### 輸入輸出範例 -以下是数据结构的调用样例。给定一个大小为 n 的缓存,利用最近最少使用策略储存数据。 +以下是資料結構的調用範例。給定一個大小為 n 的快取,利用最近最少使用策略儲存資料。 ``` LRUCache cache = new LRUCache( 2 /* capacity */ ); cache.put(1, 1); cache.put(2, 2); -cache.get(1); // 输出 value 1 +cache.get(1); // 輸出 value 1 cache.put(3, 3); // 移除 key 2 -cache.get(2); // 输出 value -1 (未找到) +cache.get(2); // 輸出 value -1 (未找到) cache.put(4, 4); // 移除 key 1 -cache.get(1); // 输出 value -1 (未找到) -cache.get(3); // 输出 value 3 -cache.get(4); // 输出 value 4 +cache.get(1); // 輸出 value -1 (未找到) +cache.get(3); // 輸出 value 3 +cache.get(4); // 輸出 value 4 ``` ### 題解 -我们采用一个链表来储存信息的 key 和 value,链表的链接顺序即为最近使用的新旧顺序,最新的信息在链表头节点。同时我们需要一个哈希表进行查找,键是信息的 key,值是其在链表中的对应指针/迭代器。每次查找成功(cache hit)时,需要把指针/迭代器对应的节点移动到链表的头节点。 +我們採用一個鏈結串列來儲存資料的 key 和 value,鏈結串列的連結順序即為最近使用的新舊順序,最新的資料在鏈結串列的頭節點。同時我們需要一個雜湊表進行查找,其鍵是資料的 key,值是其在鏈結串列中的對應指標/迭代器。每次查找成功(cache hit)時,需要將指標/迭代器對應的節點移動到鏈結串列的頭節點。 @@ -141,8 +141,7 @@ class LRUCache: -对于 Python 而言,我们还可以直接利用 OrderedDict 函数实现 LRU,这将大大简化题目难度。这里笔者希望读者还是仔细研读一下以上题解,了解 LRU 实现的核心原理。 - +對於 Python 而言,我們還可以直接利用 `OrderedDict` 函數實現 LRU,這將大大簡化題目的難度。不過,筆者希望讀者還是能仔細研讀以上的解題說明,深入了解 LRU 實現的核心原理。 ```py class LRUCache: @@ -168,11 +167,11 @@ class LRUCache: ### 題目描述 -设计一个插入、删除和随机取值均为 $O(1)$ 时间复杂度的数据结构。 +設計一個插入、刪除和隨機取值均為 $O(1)$ 時間複雜度的資料結構。 ### 輸入輸出範例 -以下是数据结构的调用样例。 +以下是資料結構的調用範例。 ``` RandomizedSet randomizedSet = new RandomizedSet(); @@ -187,7 +186,7 @@ randomizedSet.getRandom(); // 100% 2 ### 題解 -我们采用一个数组存储插入的数字,同时利用一个哈希表查找位置。每次插入数字时,直接加入数组,且将位置记录在哈希表中。每次删除数字时,将当前数组最后一位与删除位互换,并更新哈希表。随机取值时,则可以在数组内任意选取位置。 +我們採用一個陣列儲存插入的數字,同時利用一個雜湊表查找位置。每次插入數字時,直接加入陣列,且將位置記錄在雜湊表中。每次刪除數字時,將當前陣列最後一位與刪除位互換,並更新雜湊表。隨機取值時,則可以在陣列內任意選取位置。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-4-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-4-exercises.md index c7f6920c..80a2f240 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-4-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/15-advanced-data-structures/15-4-exercises.md @@ -8,7 +8,7 @@ sidebar_position: 78 ### [1135. Connecting Cities With Minimum Cost](https://leetcode.com/problems/connecting-cities-with-minimum-cost/) -使用并查集,按照 Kruskal’s Algorithm 把这道题再解决一次吧。 +使用並查集,按照 Kruskal’s Algorithm 再解一次這道題吧。 --- @@ -16,10 +16,10 @@ sidebar_position: 78 ### [432. All O`one Data Structure](https://leetcode.com/problems/all-oone-data-structure/) -设计一个 increaseKey,decreaseKey,getMaxKey,getMinKey 均为 O(1) 时间复杂度的数据结构。 +設計一個包含 increaseKey,decreaseKey,getMaxKey,getMinKey 均為 $O(1)$ 時間複雜度的資料結構。 --- ### [716. Max Stack](https://leetcode.com/problems/max-stack/) -设计一个支持 push,pop,top,getMax 和 popMax 的 stack。可以用类似 LRU 的方法降低时间复杂度,但是因为想要获得的是最大值,我们应该把 unordered_map 换成哪一种数据结构呢? \ No newline at end of file +設計一個支持 push,pop,top,getMax 和 popMax 的堆疊。可以用類似 LRU 的方法降低時間複雜度,但因為要獲取的是最大值,我們應該把 unordered_map 換成哪一種資料結構呢? From f423731791c3e640ec92426caddaffc5b38c4203 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Wed, 27 Nov 2024 22:49:50 +0100 Subject: [PATCH 36/49] add logo --- leetcode_101/docusaurus.config.ts | 16 +++++----------- leetcode_101/static/img/logo.png | Bin 0 -> 134091 bytes 2 files changed, 5 insertions(+), 11 deletions(-) create mode 100644 leetcode_101/static/img/logo.png diff --git a/leetcode_101/docusaurus.config.ts b/leetcode_101/docusaurus.config.ts index 788a0bbc..67644ea9 100644 --- a/leetcode_101/docusaurus.config.ts +++ b/leetcode_101/docusaurus.config.ts @@ -9,7 +9,7 @@ import type * as Preset from "@docusaurus/preset-classic"; const config: Config = { title: "LeetCode 101 - A Grinding Guide", tagline: "LeetCode", - favicon: "img/favicon.ico", + favicon: "img/logo.png", // Set the production url of your site here url: "https://noworneverev.github.io/", @@ -51,8 +51,8 @@ const config: Config = { docs: { routeBasePath: "/", sidebarPath: "./sidebars.ts", - editUrl: - "https://github.com/noworneverev/leetcode_101/tree/master/leetcode_101", + // editUrl: + // "https://github.com/noworneverev/leetcode_101/tree/master/leetcode_101", remarkPlugins: [remarkMath], rehypePlugins: [rehypeKatex], }, @@ -84,15 +84,9 @@ const config: Config = { title: "LeetCode 101 - A Grinding Guide", logo: { alt: "My Site Logo", - src: "img/logo.svg", + src: "img/logo.png", }, items: [ - // { - // type: "docSidebar", - // sidebarId: "tutorialSidebar", - // position: "left", - // label: "Tutorial", - // }, { type: "localeDropdown", position: "right", @@ -147,7 +141,7 @@ const config: Config = { // ], // }, // ], - copyright: `Copyright © ${new Date().getFullYear()} My Project, Inc. Built with Docusaurus.`, + copyright: `Copyright © ${new Date().getFullYear()} Chang Gao. Built with Docusaurus.`, }, prism: { theme: prismThemes.github, diff --git a/leetcode_101/static/img/logo.png b/leetcode_101/static/img/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..4743e5fbdd9ddc3f491ff8d561ffedcbfe40eeaf GIT binary patch literal 134091 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

        o`IOl#s4}E*)O@mp`u1Oe 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

        jr8wFc;uSqF7FS4E#jOKC*Au~sDB+IvS#~e zq>`P1fy|lo8|QSgi&d6OW`RCK#H;NdPVdN^8r+PIVunb4loj~h(IBa9Lnh2&R+c?e`gngi9AYQPV1Zv9JVgb6y`3(*47m*Q9>UAkq{VH~ zTGlmcvO#_mf9QqXj6XRE-7+%^6A9#?riAg;#C2W{QdapI>RUq3wGpgo&O7{DNvEWd zepV(CkA<-WSF()8H1P83<^1v8Jg7+2Yx7{1ymIWQU<=c%%kN?`H`nLEFzCD`7L!8F zdibly0)?SW7QGf`OmM!9@a5m1Rpwh}xQU+`$rCh9$&6Bo>b$7w1>x=Y>qukdLWTZV zJktsBDynekp;N^V&EM_hBp;h|^bTMNF>|fBG6mTEf>{iYOOqJ^KK%t=_NZ>Hnf|LwaRoAWSDZdiia*>mdhD^`2WO;);e z=oadjPIn2V)tT3~AHfIvDLYDczk=LNJtU#a-4V(*XA_l*L=umgJD*K@XL5U(Rv zZz3CXuPKaRg?ge@NhaLjm^YWDdQ(EQ6nAY7Cx)i+IR6l{Dt|bT^GZ{qUY*&0$-GCE zM#P-$E|3qVI6#4udIjY56$XT~5Gf-&(3cm9PC=&rY zO{!ER77{pbyVVh$By!_EZQK3+@0IuDE!qCzOi;(zct-3FWz-h~SOi~&B|(-dv^nvJ zkCIVaX`Hs0_P!nM#68w9bXr~GB&da0IZ-XSsMUq&?Xz>X@>5uy84|^uHq$KKvApy} zzx>mIO_cw4#*M!l-{51XA3AR1mB**U9yk05&fjoy!(x*p#H8GYdo-TcC<^e=5sTDm zt=S|x7}f2)4%Kiocm_K93i;mXSC*NHi|f{E7_~GQO;7D6%bB$8=CTvAh$Q4;FxC8a z-M<)-&`y;45H&BSAR**de3m9xdYK3DYDt+>a{E1b-lK4tvHq|eYPB4szmWLlxF~05 zv!IBD-@6?nxwj7Wg?mr&EpbAuY{Tu-()~UUD$>p0K?RnxQJ7*1s08f$0|f3DDBR#G zSR6z$KUydrNVHI)uU@!d1+}G5g1p?0p%AcxFlN;Gl0|6Tvw)v%nF;UdlQma;o-B7p;`p+%TzGCj5t6!0 z$m<W#X($LaW#<=&0nh>#^@CGrCgAJ@}| zgZC8RBF3K1qnR?S5AUnT)c+XUW1i-W_BjkRV4{&t8ZFv*E$S%pX_8ct&A7ER3iD!+ zg%J)Zr!t3LY5e&B8VDDtcA?52Ftrsl1(z?Ut|}WEqb66if~wYHzBsNv7t2SR7%Q8z z8%aSwB&tb*KILwN4G7lfLH`=R%UQi4`s*fi3-huy7DCFt=SG^KA_@WOV(JqIO>=fo6q6^z-~jOJP6k|NidaI9KE6 zCuDim$m@SaIc*zW(l6LzuPLd!h@2-HMBa1#@(o%z(X@HODd@~S-PYB|BfaD@h*g$N-L3yG}IcnNE`^w&wxB16&=x1ZhoI7o+g>K zlC=DyM#>#ME%b_Zvf3dEm8)xijH)!byGGMt?Z?e6CBv#N5;CJfr+~pllBw)0PonXL zK=~=k-3=OvnVre&fL0WwS^lK1VyfxBc8@oFhFzbMKPpPYL-GraA<9Cp`8)=T+FC{u zEiHV*{0z!F8dP}r8I6JVa|}gu-`sjti_{CwM^z&Nb9}k7NIUG(ME-n9qjG|Ki(Jg> zIY!Z7po9;g{lpatP?tFd37%CNrf(2C&=`)T+k6}1>&-m^Kf)K>U}CsjV1wjHin7F$)@O3r8|pt z7Rb*+70)Gmhfc)sZ-@lDWSgo{u&;dxhpRl@sEw)Y=d?g30=XAl!zWHnDnS$@6+Jb; zDNKBHLe5Q&mC}`-tvPmT z{=O1THL8}-X)*dK|2*VzWNwbGCg{#a~U%L!sIA&Ct?kn4f75pb%=Mo%z!(#kz z?c4iC4OSG}dHS^mW5a530?e2|1MJzKe>qY?Y6ZePQ=Y316`DuWWVs02_Uo5gZ2l0e z%-!1$n(^Lqu%BXol`tVt-*;VfPFx+kyWVLHcymUgl-t&D3mxp^EI$sV$7H%irlBP* z$5k7u{H{kYnMyOK@rJ+4TSXv#Sq$_!*?ZOc%S1yT701A<`cs+ zp@vINDd&SqO+Xw18f1h;;#vvkq=rdidZm3PC~o$Y&9jr^SZym$69hnID$7lHdmGMQysEErtGT zk&5n`?5{H_Ak^cY)xAtfC)2O-t+mb|4KZHI*>Xb;F%LYy7Xc%K5~W3I$zk4@2OVvu zQQ-rg4*EynVB9YjyZB9^U^^7k%GRDKw8v$|%AKRg;XR9HEYYpAu^}p(RoQD#A&t2? zxL-0qDxW7M3;ex4etG*tSE8++4AOl&Q$jU@S>i4rv8cO7I{rm@$_u3}V{iix#Lr7h z0u&O%R8&+Y9)GIlPaxTY@OkQE8)}O*8&-e9V)`kfi9KzCbxH*lGJ%n!5NE;K>g9TM zM(#REaac=$?HaOpki-s`#j#@w4yfNETC6}MbCc{IIF&E>O_jF)AmI{u4p04UI2FN8{n+GN1W!zH1oz7+Uvj%hN| zX2DQbqFl|K2v1AY>vobhVrRB}0fY7s=C+}K5r_{U=r$&S7!wuEh}-EvCJTC9bBX;Z zGfaACaao$748*uuZ8#8P0mpPc5Rxw}VAhm{**4AKd7jA~Uy;M0(G~ z@A5u7f$zn~NVp0)Ds)vWQ=^L%1;D)MhsZg2bWIDI*$>hoktD^Zj`Z1{vqkrY?xBB5 z?f*=KlOw_DXJuvPU;i=we)MrKb@JEHR|#_PHxHJ-582|~l(;A&nM!oyD5xlXpKqkc zd&$4tfm|g#(G$sYl2TPEsO=P;n>YMFoDvg1^%n@cMZg}i3i2=JPB#(KEs=AyxS{eX z3o|pbc~P6k|198S!Dnb6-Wp!Y?9o#tabnIN#*kqpd| zFLM_^PxCjB`!iHt6`}C~kM^lOJ1a}u#|5^|q%q4Z&uu*B!+r-U)ng=XwPSq&qCB`2e$hQ#A0-qD5JRe2=znpVLIK z1d3^BW$1%G`9Lq$huT4Ast-u@%6c8aXex7U|FvaN`T?iv)3;Be>I~Y~ zH)&F|&82*Vv_4i3wE1n-$})7RR#jQvdHOYmm;s`e?4KpMFte6#57|M`Wi%SpRNGZL zNaUfet0Z??va;}x0W!sL8W<-9iJ0!`>Yk3+{Y;r!x~3DI4!8pgI*CbFM6bB~?X!QpiI^_c+hfy(Z`Y413FES(TCH-=lh zj1;28g()L-^+hmZTHu!VWW88aKldZ=g3v5AJ(8gC${bUA{%zp)x_qNdq!=kr60oP9 zeR@oq_6{7L>xIgi5FJxP97U8ZYdr+QVuR4g42U4tn>dW&NCrGJWvXD+nt-%O1+G2_ z-8XAj>Nmjp+xFAj+gCcP^yOT*r?t16o4i^hDg@vi*r8hd;!yEAoU&_~&zPy0{Zpqg z`lW`Bp0M0fOA*0T=2Ae<{tS!K9srE13Ef(#oBpbfulrk3O=oYlvNSb0Tjf;PfG;Su zp$Y^W=zB!o++H#7>_GWQQ3Si}wMMbAe)=Lvy6wJ)YiLXP9FIJ7iCN3e#v*t-#VT#D~c!E7*LlSKfDe&lFi9fN`QEdVn;KES@<0*EeZ|p43;TGQV+}SZ!%dN zo^KZA$Y8(IF&P0B+?CrkQq)AQWnQM-LZzX5fV_K*Su-O=ZF)B{rca~l9Z_`6DCc5i z`$90+m9@o+#z(%({`dm&upStJ3w-367Rg*~byP%eG%C+5fwxp*h)KuzL2n-K;J-Ie z0vN(^AinJ%L4$6g^H&G9IIra437Iti)=~Z3R6d7WcmHIN=&Y&7V}>9P5ESszV9QHS zK>?%f{Jn04&b=u;4j9700QIzcA3kbvUN!^|xsQq83$nKZ=9d5IQ-|GU!2gg(RdyK9 zaNxE4OPeR+fTDX%%i4@IO+i+2HinHuLGK~sou?0xD{S$RR<#6j|B)k&Mo%*EIIO&6n^mUtHQ$#&m2#-`{qUOKE{R?7Bk)yPS6iG|QUyC<==N~$6cI^wMncraT3|%N z$%^0$vExQ{<)*CUT>t=)(Wk)OF@{-m{`J0i{5t>NPGq^Z(?8BJz(lzIG1NGDb)Efi zw`W^L#n5#Ok%yE2N;J8%OdXnJ*o-p3Wm_Fzl0;t^9Tz(zp@BAxAK(;9bABPHhtIg9 z*e;vlo3S$yzwV6OB_ElWo}55^Y-}BrvG=zCA?diCj0~?o9*7`o5v&$!hp!Dvy7ogZ z)Vb89GHY#aibq9Z>|}w<0A>!hvXi`X(t_LH&H&SXQmoGKn&vraN=mG5Kw)(m$bP^{ zDwR6v&r+?KI*ojy$4XVBEm;chz$rvO;DZ*gd#e2 zAK%9&fALTh^Y4*A9n82snK2TQ?p*sTeQ1=(KBblL0+=4-0feeCpej>pcr?nZe>q%E z?5YLa1^p%qOpMAS(n|R@GD{QyjRbsK6JWfOv>HktB9dwrUOpa}u7hq&6@Zf#P@`X0 z20h9jBXR9)D4CQvUubQy&@sENW6=%;I7osY@xgd-?aL#8PR~vNnyyQ&VOyS={|-Fy z_2~Cz*A1b=qku?mQN>1`%f%Yu0*_S;SMV4_&5IIvUNM4DXj5%z$v6 z&l*fGXIt-zy1Mrm2h`z7e|$N8+bUsNa4f`qaCa117~<pY;|b17l4pPnRsSqBgup5y7%o~LECX1 zqh9A06XE2u*#7xi$bupcjyK>B+A3P~DYnX3&z{XObL?+liGP-nM|$Cv)PEKe9tz4> zGqWfjkA-IIK-ycFmO400p4+c4t@g9rX5i@rlF(G2m7P{9eFsk;C1WgCPA<(Jg0s#UGJS%!_xjOhGA;b#`J#XQda;?;uAZxFFz{caLGUBki`^H22c_-Bl)BW5^y=xK{1u z{&G-pE<&D+>JPvqG1qy46t;-114f)5E?2;kTlDSB>x_^nNhU{HUm}}%VL0?k#S(51 z?a4qi+^WA?u7>Q|Q$T+hM@l<03m@zOn_N1tCLSZ?15vm~Z_zRBDQG~g(fE2P@+iiq z*ZGpmscRknv&4&t1uteo2Hk<0Lc20tDPGxOvm2h*bsg@-e;sbR%SIbuZ>Xw3llm1m zu!?z<4!28*}de{GpZj;j#dsVH->9@HI( z@DJMF%cgW_jxK>rp1g1Dnu8aa>oHnXanH-Azf4-18kw1WicbdJer7k^cOB2{N{`TB zt)?;WbuRNJsjjl))Gv!-CjKi)K^A<~Z!#AK#a@Ik>B;>?!0SlM&fTj&hEbE9U8TJ3 z!s{{HMAtv+0*qj9M)|jb)BACiL&){#D+LJe!2NF+B{dD*k)6J$ldUZvzU?+w`S#UO zAXyQ8$PJM^#JE*QTL8O6ua5SS60051N$-NUZDM$&=gT0&tz&$aOKqSQJ^=HyY@Jk6 z%z#-8{pz$M(HlM_mXm&iF)XNhSaXq$qYdHz2^VHSs*xuAql1rNL-``(mwl7V>`w(u# zU|FZ2J6_#gnj_?MF-m@!GfIp-&_Cg?BmoNUGzlu+x?5!dy#^OA4$;Be9SGii0;Jt% zL2JGBUsqz^1KVPYE3Bd!C~d&H2=!o=lM!u=4kLUxL0w;u_@LA*Z8H4JeTN!qyhC6! zL?e)0Ux$Hc^lc+&$I?yo64{?3xOpX^?Rji+D2=qhk>)uauzQd`p#_tdT7Xq(kd4eK z>^Mh`wp-Rq62Av?_?&OXxON`Xv!A-nccQbc1aVkwZBuwG%eS26#`=bKyQ6r+6+P4c>7*3%Y!HG8sHkf08S6E?00Zidl`xj-? zt3^9s)2((_#Y^pQwm^ej8CZ*HWoGI!bBvJVy%2|*GSA&>p8opW>??t7vQSVWy}^=* zvqW|nWnw*@UQrn5Vz_7#(^#ug8+7mzbYmyZ^oo^i%*|BM-`DunKS_t=qoAOyw4>L2 zlsScmmu(K+K!CzW9?a2tKD@NsL&+O)fhK1&buE zpL)7idiDKjvL(`ImadpC$W)*Q7W~HRi}B>D5wm8aT(HK2s?BxFY-Q~ZblIl>r6Qoq zHP8m{*~x9B! z0(%$`nWC?|1O^W@_l4*c-#z7#%Pnu*U8Y`>04ifUs?Ky0$juJ_wB8iHsH85lx%~cv z#0`YX-X6~80lYCf7z^LWJmUfFk-D&(J$v=QyzsMW1@0yCLp4P2qEkiU**K~8O|=)H z0uKWNACzG=ucGP4ffUo~`51;#GjGtBN}k7ZK;}Vu3+_OJaR3^@q5?E6QCPCVxBe0g ziz}eJ*7^;_z(f7F-D&k9s8`e;43azp5n=>5oVKcVr#Xm(da8IP#w;!AhL6(e`W}z7 z@m1SW@|pxPGWPQKQs#NmGGViCJL%~CiOga*l(ZJhk+2>Koh)~BG-VBEN#*oTOBD33 zgVO_LXGW=ZFk0|@vEz!1<7=v4bq`iMs7|$w#E|L7il1#KU}H^Aj3Z!BT>NKnOO{WQ zGByNw8IK&WqLnS9atU?%gS1a`_X%xn3R*jw_zT{;W{#W)*x>va6~$z1unS5BOFWx5 zRN7?h`~S-FI?UNQYodZvX|rNQHGV)tFD>!0s*t>~2t^g%~s|5DWFQISW%&%WFjAjwl(`up}|4$1*;rJ%Vue4t}NIs3uRKT#Jjbq&#^5ZOCJja+R(uvaYV% z&b7vrfV$EqWeBgYNYBlN%TqgoFY)aUJYR)HFtSAJ zSU--c2>YG=R$|pvqY9Y1oEX(7bJ7*r$>+4hdd?!im75MdDtNq&k)7(JJ$hb`eGGNl zdfB5e4~piO6a!iwX**; zE>@NP=KzJ}?vgGHUhrAwfY}=7#Z6f3 zuArAtm{jRh)>U3d7-+v+_bi6@%9x7OD~^iZ3F?fy;-oD3 zr3feq%m{Jvmj!v^k#@MM3Ps`kTiAfvS zj64=e7;C!ioE0vBb;YDS^5*S4-Jxhv_l~g2a1q>3K?j=OXE&3GA5*SakzB49U?qd0O2+c zu$6@0xqPfBWVn~q{&U~NVzWV7$((wi3k+BUZQr1^RxOxDz0_ySo$IEy3O0-CcqQcY?cHVD39><`49T+v}XFQ?>WA zv-Pp@IbB`zDHK{4b1FR_r7>fe^*WreY5AuB6%B)|Mb*t7m76iwfMjQlqht%q@_TzA zt3J1#ZB4Vy3j532*1M#l&_9kUy^cS5$!d;4;SFN1%`We4<})%hIl?63%a(aC+z^W9 z#|_iPGeSB35dfgnA(;;Me4>oMg<7O95OUJms+@9q`~FwGFGxt)a6zmDNgzT&z?JsV z>TkJhqtUI|7~)Dfrgq04#Bn|bXrnm7>ing0B3Ei9YaygT#-=ojEMFZYR2B{tKxKi2 zAPKA@{&E}y*WGP;7g)TyQ92E=BHhSm#jik3d5l`HdxVXx&anKh(;?2fbAJdK;>?ju zrH@d}PpulqUr^@COHTKCJ~|XjXQGL4{A|uFpCOo(u_J08+w)2G5FW(z zXWMm`O2eR+Q`tj*hm$HYWTXWP4IDsKN2kK6L{Fei&Msw)q^s6Z^i%xMvDksR^N8Gz zbg9eRUHcQBf@Iq4S%U@Dr4weBo6B#5+PDE*nzdR6Xr0X4$zPvW#E7fTSYt&eEKDg& z%Ndc6mckTxcer`)qvv_*|BMpueYTt{xjSK?uw1GCiv=gi;|MFfRMexwyzL+{t8z}8 zdUi`sdpD0Bc3*p(~7gAFG`6Q37e=3E|!K$R6Ip(59B4RMPCYuXSzi(rVF<^+*Ll>ZCt) znl{Z?=o`(t>QTJB7)_RIi771Ge^$!LsN3BX(#;x@rAPOpUI{`a^z9A&8gps4g6v3h zN&u$WD_ssJWPrOZ>K4xpFs0^wwfza%fuKs}i!+pR%4HjoBwHqvk@3be8 zjUlH|DpWvxLTX5GgQ5H&XG$^GU(5+jj5SnX`V&kgwx?f&y!LCu2C!wMZ63%3E;lWWFeE_SzF=~_v=!^EdAi(5Ya`aFD=0x_Tvfmk0Jx@)1so#o~IZ<_K_b(W_Mcf`@{>_XZ6@#50ve?%A7A%JIHNJqp= zF5b9NVa_=-9HUdj@K*mbJ%aHq1T(f6Q-SC!EXi_`5%SR;#S-`#gb^VQ{M^lPc4SpxpwZ*YrJBXc#>z*(LkrbmSD@VQ(u&X@{N~3Y9%ApgiF&W#<_rBL=f8l(noF%$*EihPT(-E2?k zl3hRyofw)O<@)R98z#0%m8LIip5=<;o+Z+UQm&*NzWW(D2HRwLfXJzZXxlNrUx1Nv zb>47MJscwXC6Nq5BdJVL@OkiBd1Rm_3CH>OF$XrbM5$uVrpq-I?py#Ek~<-~6qSUQ zrRRnK7$-;iY@*dD&HRP!h18}5nVql3@GIxPU=cdu_dVw~D+!dIta6|KmzT|v7leWLX3gx<;uU@ST@3J9;1tFbv2QUU=Q}XbJK(U5-?S#$HXMOui&V}CneYc{55OM4fggb)T=CgN|K`Ma;vLLYCjv(xV#8}HMXbb!*Nb8w)# z>*bH|jJr4486u=dp=x|iE}?$6545}}_R&oW5#3t5IX{{%e0m?o;slo`Et<)d%FOU5 zc*R&+q>t@yZjvyMa>)2AD|Cn$82#&Tw?)j^|J{HkB zkbj`@R4ZLzQ25gofQTcFJVu?y@b`b?41grn2&REVz{@Elc5!O8sRBr`u*weSTs2#v ztN32;Vo<~E(hnbe{3J3Gzm#Fh#LvG1>6cfhv_6FOQ}4v`f=a#OsA>qk*)@kQmx6Bm zF&N)Gq8qvtdnSvrhM=}?d@SF&b95{`OrS6juLtLE)v`V=wLVMF3%xJzvvZJBcwF$M zP#N_wf`kR?QiXrm$S0}4Mjylhza?}v6!ltCwJxM|H3Pgx9l zQ=bo=&|ZvuUWoA<3j~P_6Oh3D(T1Iwc^A#e{SF?Y zqH1wG*JN%uo2R@lIuO{xpMW>wx{r0G^Jm;7E#|;;aRQkqW_f=m`V{8 z*F6Vkz1g1VL?NZpVg#PseLGoiWB7(wA=G}&JD!@H{FV~#_rC5tEi&+PE1d@dxXKTD z|Gm+0AzwfFuz2})|8Y=(Duti~9fTuUTc7ZVl&^CMN|KDM$b} zIV+7YOo9;2_N0gnxxu)FA?BqGwsf|7Z2|u!DM(eSZ>7Fy!t(7&=I(;8z~X#Wp4|~o zkFVA9I(IgR!nT`yVXYdx;li~#l(M)_^8gu&POYx=eODzNSWfHd>2=z!HTP__yWR=_ z%C7plqP3E>zu#UDfcees+{aDoHxyub#p2zy03C?~8jQyOe3TTCq|Nh5kc6DAv5T?S zSr&>4D@to6U2-hG=$C1onuHnND0+gkW=>;3WEXh!n(wDrpYqi(p}k3r=g0fMq3Lxc z8n@YadhJ{n_@7jMssmR!5C@e+2ymPM^I>MB3GSw*R3gxj2nb0O^C;SVkhUW~wjuyP z5FHj)QKsb5NfdL0fJY7Pe1a5_BrvG|(qyBo@XIFX#2TH|j2qp`o_D8QlHdL9j+d?| z&wtDCYex9~Bi3@t&CKu~yI^%nt;bGSYtG4^s>T20wnqhV!}F1UE0)<384Op%6*TCV z8@c5IJx1Wx?=2FXSI1NaGHX@%PpIOEU^q@_?Sj#SlO>y)Y*!oq4H?G?ym)*j9eG=u z{I96}YUx+>_cET&@2^i2&Fclx>VO!P8gs*?r<%DjAVw_K|6b+p!obv8D93A@9Xk=! zEK);yz=00haz9B>sR$34E|H*06~wdoTOE8fe( zqAe|QI^??yhNG_+U}2K}#!qQkrnKLI@qU<2f8DPcR)ke!mwizbvIQO(64so{JNXI$ zeQVpPzD%z7DTrPV(_f^ryeqEvtL)n3rE!U^hRPRgU2L}}>})*FSHXOb+t*N|mx!#; zkR5tj2yytIQ*r#;l8Y)V+N&;y1}zoU=Gto=dn+-Ey_xx7U0$_pdFY`)wb{MCk%xJ? zxdz@cGRJWw9^0FT>CfB;Td9C@t^?N3X~WgFfNA_aajfunMvnuSt1LjC3FBvLLJH1o zhECe4Q2|3FHrOM9f_{5<7&hKIq&i*i^;1)ykd9VwCYz6Tb=v_!F*a5$_~8rfcJ#R< z_GHR|67z?pLA544X2!`SxI8yoxS{i5mCy#A)oEY4pv^r4-P)y8Mj9I1P9!Y4K4Bvz zIb=l?@1NZ3y+HVhb*R}6^{7$!b~}{SzU45oK0g8en!B1Ry4S@rf-N~m=GS*Vt2uYc zm7~k~Vu#UYv}R36efxMLWV{LpJHam32{$`eZnH_ebT;EJpAIA1pr&{RjYRWZIF;ww zoN3B*rQV9c8-jMk{+`T(kI zt7=q|!e6V)?7r!<`Lsa~+S6B(F@;mfL69>F zJg&5_^_dR+@M>C0qv#y~3!39i5K`E}^B@4(?}IcIYO0H&u{+LDpNoFl$?S0}!iqNve5pn6HZCKQI{2?>f+!22P8v&-9_{6_Z?pon+Q zPL8mBH2Z{f+duXKrEl|-#&<5G%{R|Oo8{JD?!^l3Px^9|whatm-1+l$hrbACUIlBY z%{-2fun8MG}I# z+6_(u$0DV5#+q!GBAHvS7zw;iWRhhmEl>YUVR39kZwmwwfU(ezhZ*RYcdc{{>HOWn z8!)`sq<#}f?KWT_@#N*k@?as~3 z+*Z%yruQ6}uZPnb>Ly^b(vZSxseF<6^o!kF)AT8#b&1<+-`2Ao^o;xc>N@O7tV6t# zsC(XNO;0w8z@5?`bgrR>RrEw(#x^WD)iDlVUptNzZ-tlK$d#XJZYL^wnzRpsYCM5U z78EgNC_Rwm2nXCaAPmsISiXyG2*%g-!E!C$GXra7Wzm5j8^U3vn`wxht>_#@bl8g0 zb@DLV=P#M3Pzlz8M+(E_*Q${cnz~l2)JdJv(oNdjaS6oAhs#)d+?>z0-!TcFc;X!x z-LG-y=f9NTR(`pOe!;hnnpHaQYVy7t2{&+@`gWHm)Ju}E zFLiwL9H(Lx^-`d|Phmu&=GmUq-t~7E8*3a34vNB4jRcNYJYF5^h}j)#n;AQ!zBO}V z9tIf@w!U2|)CABMR-*Mh>%|suL^YJR;{GUN)vzQU0ndh`_!7?$WN9fV7IoPI-g5~+ zdlL+cnxB{mM}={}fL4)oln{su&3l0`k?rG5;gUyH%j-;WzCMQKD>8(yOz=a@I|ji( zyv^YRix(2JOUdb_A)rA`E$E|}!IF*VYO9aXaZba}uG12_dPbZbJi(x)cnPnhY={^+ zg4yUc<@M*j2N2;ZC6qOoc{v zQ#9Y$Q#igrP6~6qjQVzgmHXhymd3?EK30BB`ZNrdQ?N<Vv-#c%R8!P%6(M1J=m6Ni)=&w^Yq%K7J(=m^FJy89!p?8KGAvvIs-!WV^R<>PkLR1eDytb=4_;6Y_nxb# zsBiZE10ox!Cv^s6LH-`$Fp*HKr+5DA4bIk#xAmm)>u^{?kh)5gke1}*Ps(#B&h$XW zC#HJ&3&2OCdo6h#WYI%TINPNf(dlipo!`?ykWeRnDnB9U94=P8YpN5^Oo}&hX$l4M zA_sCJ)S-?(Jq^+38k1VBMP0V3c5zzB%l~LY*R$*HtMYjyK+Paqf_ghE>B)868|Lw4 z0^8xyaG(SZ-cB|slz0%0&Erw2BJ&TQ*#;r#fI5zg$`;Tx3=xjFO+f7eh6heZPU}Cr zeJa7QwSWFBut`l}50VH$2Zbwq+OsYvSA~%r(e~YS)?}2Kf1lE4f_?Z ziqo3ZF-@yGhyuz1YwsP+7Oa$EV5K@8T{I;`RJ47&xHqZLGsl+5=x{sd2TV++p3g>~ zVYyL{ym=hDyzU6xiw}Igsl%Cx7X!k|&^NPJ^dreS~!mEC+3a+unb}IP10Z2`6F8b0ei*VUqxJ%6*$p4JSBzhJ-z2L06cXPYkhiDHf)3-kx*gQ)~k1f*oer-SH zDRqU?<)ynCMBzAq|kgQlgcbEec+Q3wlyFp!TDBi_f4ZXlu zV0y89jwm46{V#L}#)US)>;6J!N#7gW^=vtDH-fjks@yC9;yz$cjnn~}aw-Y-zLM7~qviLXJ$q*7BI4CWUnldflf z8T?oj(heTaj)O)8`!NYMFukhIj&z>heYXaES+sddeeD)YcOV!Bs*p2vV30l~3 z35V6>Lp5C?-DGmBr$LQjy?2-8BXiQQCp@!WELXn+ys@*utL--y7}Vz9BlaI@zbNPZ zuH^2|8pZJ#O-`Yr;ICdB@Ul)beSxYXUqYhn zSbpU)WN$4~(|rm&lfd~L)*VbQ|GTh8tD>jG3C=GI8ATpeCyp!lU3p8E?wQTL0vUyk z(b1}XdWY_sP93Lk0%@XS02GrX9-DTIkuvWrqV(5GlEm#bG?0`ZS-!yjx*D?BrLE%$D6$>VvGTuPoq=@u2cHmx zm&POu3^PRQyTtL7R&F%j!45mcaMf=>g4^FQQJS8de`n?#Hp{Fht3?cpe-`IpNuv*7 z@By#U&U-mpSfiz?NJ)+#MwZ9!_5N5mdsu6OduSwYN!GTkbmUtL7 z#BX#3$ayTnNrKPOf-e?CQ@8K|T%5MF6Xq-GP8-0Be$*=i~7hP{`B2eD*%9wsCuE&c3XCfE5B=f0Rh zjJ^1Dmp9vfL)Gu{x<5M*)Z99F{0sJFsrI|v>{`>Xt#}@5N48eXtE`botvB4q{`?CI z(e0mK&xrI5KS9+C|GN!u((flHsgDX%`+ z8fQI5?N?BcBC>^vNNDAksj{lvC=kEe4v9S*cfeu(fHEC~MxwO%-8saBcfWMb)LqUG zDQ-@%JYv`nJD%9!Gl31XK~YHWeZdZt%dHfVBUBF&f5!uKQxz)K45yKK)|b4_?>2!$ z@@x}Hp-wGVF95JF&GO~$nEzL=BZfi}P&&ERKAEWGJM@VM!Qca8JyNb5vsYafY%xr=>`8(ioIC=qHQqMG2!F-+d+zilk|+gS1n`)_Kw7WxsZa(y@Mi zM!#(t4q#6F#^sb6QbLlZJHWwZ+jrmpJ~T%zPemnBrp4IYe~E0XIIOyvpAXTqba_ij zKu}MT6EHF+`u|!0uD$ER&(|L8d$->6Byn8w`+N9g86td0H8e?6+je(F4ca+Nd)Gzt zmiGMUQcH>Wz$t0>1u7ch!|v>4&%%Eq`o|j$S{D1I*+aR9sule$_5_7w6ZWyvrBh@x zcKk|tU;Ub;VE;0#V4pv7`XRZF`NF>3M3o3HzH9wE{Z;yk#pSJ~+}Lp=UH4@#IO=QV zFe8`|6#~h&(=oBe$h+Eh`Rpw;g`=AbTmlKnCZwwYbOsFSxd8_L_ujs{Ge_igx3+d1 z)31LYY>Xf?PdmeUtg#v1s|`MFWKe#p2o(adF}}3)2TSqwf~V-zNbM96m{Z7RJ;*4# z$%+2a6v<~wy2h^v{JU!a)~lDZ54LMR;b81hSUg%4nky~Fn)^Mn5{71b-tSqmLAh4S8G6;HGI*hhS#C$e^bNL-QZivf7Pdzm<3)S18HP8C4nkl)zlh zKfk!*#NgkebHPa!VCsd37NAFRa$M2f%2FR>WBQe#7G^QbinA-ukg!0uL9|0~kE~Hg znjeysJU_0YZhKGihrJc|&IsfAIx2VA~;rbI@J43s~M{z*)Iz73)60O4& z-`mxIHsJ>lOYe9W1xJL=Pi_f~)95#F3Tg&q+WQIM8K*U_g00jerP!!84^XQjHB1(f z15r3p6XERb^ant3Xw0)-DaWQURHj?4w&iSIR5*oC70cvH4N82_0B#fQxNC#9@rfQm`B}H;+ z^RERXbHHj-3x{^SmeQ%qkCaq3ty)jJF62nFjM7Kq8?S)W*VOQF5e7gRph0cd;H4@h z-{iUN+=Q{t&eO}w$kb)PWRIQEE<%=z-I@EqdcCt6miv^I28`*WZ z+1h1)vHc_EeJ8&E{jTZ1 zuo{aerRWF16PX3*EfZuh=k*iJdz5F_BgB_iQ*~bWG||uxQO3QF`7s-W_MMW*_iP9A zVtt^sLlXD(|A;&a_sE=#<{^hslC>(6kSLJGH1yaUNyAI|`5480IKFMkn_joX=|cYK zRJ%Ws)73*82!sZb(&XOkx{ueYxha*v^8CKLXmO{V}D2MHBu$1cc}W1tJe2lW6x% zZJF2-YSKy&Nw^_F7A+Fl`e9;^B8?khf!A!91`wK5^I~o<3|E6RFj?0G7(J!E!2W zbX=yi);9bD`_oNRGh!lQZFm7)gQsKf`_SKcQ`$*1cFhUcjQf^}gA0soUi; z=Hw=`U|Rnr_s0n+;T+fz_oM5R1&j;QB7{(=|Ai$n;eWE$tl25z?c~|EX7_*h5mc4` zLGPLmKU(|){Cd9H#PIKBsizqDJ7WqQY&imt6ppcq5s;QpsNg%tG^=&#yzEp};+8<- zWQ0%_WFnE`|FxW>0bsPgEe@gF*M&sydw(#9S-ofhAk`hlB&J4C z5+WLV{e-_yNo1IxFuY3lPE;hU@Bh!$3kcce&KuWg6C`y#Uk&Z{UKv^_Q-zIPx3+3w z%ROynOX%Bm;Q5eljiHazKr)%DPa%cK4T>6NFehL56P@29d@J?XL@|hcZYfoP# zpdroYLG$a;RyVW(B8W)ZfoDlpA#K1f#9r>>V|QwnHgn2nt9knHQ4ub-c-%1rL$BC7NEls%8NZ2(djnqds~(_t z05dwjd9+@~?-?#3_hh^d5xLEJ0}9U8!!r4SWqO27P0TN)Ah6cG5qaR<%qE9+c{wJC zGnq1u{|2rL*pE4ph$HQxPOz#CqtRSQ+tTqK`i#4zv4!DSloRxriAvG9k-G&%YHJ#XYaFv}V` zI?^M={z$4UOy5$RlNCsoT$KUJHkj;XB?zZ`_lT;)Xh^oa+O{^ji}J>ub3?!VJa+5m zUhD$c@qhD#(5BO`VM1V|6Z-`j8J#7HQ%uwW6xyha{drmF{dbo0+>Jo1_gAzAv#I=^x4$f% zH@%+O{_oHK@l>u6$TbrNCjQk`alahP-_w}}y8>4rA~2hR|RgVlLD=3@_u zkZaYVcojv)F!he$uXEz(Bs%Rb_*Gin!)<2i9l|aoQ8cs!_p|OS9m#+>S}LzLhk)RO z+AMK}!LF^y>GFw^HJB1h+7+98T4IyLxT^SSb zJy5K6dh*r52>c?eQN%D_2CaviC3x^}2VAHu{*+CeCN&TUE8RPS*-9 z7H&k*Yc7{bc2hoq%n9wGQ`)|g) zIAV&BCVt~848AgREcB9;LKcQ_y#bD1T?RQVaVJg^AvKS~EB)U+6RO_K`t?=_52xr4qe+3koE*hl0E`6GNTq# zuFxgM48}}f`hR*P?9Iq5jiq_4!;76FT(x*Q%lQ&X>_N}~)2wmKhv zxeI3KRs=3#v$YU$at+d0ER>RkAAJ6I1ybv=WLq;0_qOlL{JH*On*M{~udt@<$L16X z(x@{8>gt@CM`8tmixphbNr5ImI{hMo>UJ2oZ7GRiQ3Ydl8Y|=JYOHby@-Nl}Z zWqk?>i2tjJG!`V9x_rJ`7-dF5$l|QP<68t6>z_DSmx*5XxOM;~513R$jDJhMS~et- zjhxVe0WhUV=^V$ZI^8CmR2Xx4kt3@WZt(R^bLk)uHT53AW46;^I5r70?&B`^E^as3 z)va^t-H&1$ay9k83HinrEt6qdp6Uuw%1v1%Qgh@w-}8B!FiLMqeY^aq+p$ust1q*n zy?m2{HBC1lQ!X;9>gC~F{xH)UCnYUSiIG{h+=Z7)XF%LIT?_JwBE9P%y`uE{ z$9v_EYf(P)F98U*qtvpdN}n6UgI?2{tS#=m3w}ny3)peq9t_hW#zi5ZSk4EP-h)oj4sf*g@G@glnC++E|ra088@Q7$X8k+l?URhq6t| zdUMfBokQv0s%NNUE?8Sn;SZSM_xIP!&Ycgb?G(YBnx=AzT*`pXi>(j8& zA`{soRHieqFuCaaxxK&GVYWXBY1dsgS93KG4v~kr8p!Y#%^9F!3lUIWQLe=V5sRZt zmbx;&VYN_6^%zdVDGRCf_B0}NAOlUr0n+9Qz~J@*T?)NlqfS&C90o`KvnoW5?NBXI z$Yhk*_niYiw~EKwgKejf!{JdeWGIq{^H*l7Au6N;UUWLCSVgESk(QVU39z20Srf^O z`dG32x1SY$*F*k1DW%Y%pH5~A7_$8P+K`4@1#^d}zy92=%%79_+NMGjS~skYMo+P{ z%s3$I{fsSSz==XF9!>lke;b8tSny!#mz@90e2&(y!h|*zfk|INQqSy0#|;7PKjQv6<+#K2^0_(@p<&3b8xQ@YJ?RMo)JbIz5=q z8d2s=EZ!T5bH^xd*M+@09;g}PP$GYV4VcR(eM4@9>BWpt{)*$B=%SuO(1p=%6evbf zE(lBPPoyZV7eEBmzf!L@NXfKC{FymwK3_hT0=uc{B3zb zE<=%~WOxAxYi%dkRm6RykG!R~%%NLX#hCE$P=6;RXZO@L( ziTHZ+xk0uT&kVu-BtleS z6`lnF8wnwij0-A0cN|mBj=!+nO!;2=LdkL#O_;bw{Z~Fc|DCft*I>IpXKw##onoc< zZ^1_*1?p~qE_SyQM#@eFc|oMyi5Xg=+DTA1v3TmqS9OLnt?+kFLtA?rzfRjhzc!7e|!LH3m?&ijd@F9cNESZv}#=fQX1WJAdho{ zQFbkGbAn6XsuJvFgE&VH^kboy)V{oRwYG+vX5{MRn(SDoroM{R#2_DGb z3yz|bvBi~toAF;&BS?iIhn@o119bPNTWLHlqi;Kg!4YtnJc2@KAZXPlULvFoU2RYM z?jRR;u6NC=N1$v%2e&uq2|jI;vP2A7k=ksun|iw>OF<|I6EH{6B3wJNjqJlR668pKnqj`t;g#9i`1~T2xTW5S3?puw0Q73V z6X;vj^zs>Kx3$y_Rr9I$Ebqj{=RGQ%=Kq1!PbMOrhCan@+F;^ zHiu|HV)7rVpy*E(18tJLl88vMY-AK2Ml5dygiCDX&~8DJ%*Q=2ynT$UxxOCvSIc&K zez^z~+VZ{xze7xaS1B7D>qFxn@nWkjw>R+CU>3gK?n7}{%2K}c73So0O_mL&z;>qL zUkBmwSB8fR%kXo*eWItQ%OgvDR}ygevRHABNtyncr~@K9o3ny4x>}n;V-zJXAW#t@ zx>?PwM8}EmMy)KXDnH&h`9vK$b_3jg0EdQ6fuWHeMuYJgmw3H~bmCv{RvJ(`5#cb>MzT6vU9e&0+S%$YJ5VAeZ%S>;xr1XW!Sd*5aSa6Hk#b6Xz@(Epg9mP zz+dd;BC=|exH+dP@698Q&{;<}dbM%m_Dvl~@DQa%9nYIqnm4>qUWX~2j`AQ&RS!|H z;K*9$g(W0H)s*%7R$mQ-`7LLTEe3wbtLI7Y$AQ21bpg$G2WRo?OLqUqYYxD{>G@&J zZ!}08>Z;!T!NiF0F>_dAq=EFa$dMeUr2IrD_N9LZPNE;0!~b2BfXfhrN%x6LDu}4) z69I=}69lG-10WN|<=vkVThSfouh>nn^U!FCsL!;hJ`oqu#4PqeCg)T$>bJsK1l;?j z?JhCG&fr046tFWi`Mhnb#+sK89Uov#du~R*y80YUqx_#KW$12?OzPP63?bz{2A>r(1WHy>Ig91XBN?) zHj={$lZDw4+f649rgXh3q4j06cDR)|qul&LXK5cThI~V1s^!1oHKtsflvv>}vr#4; z(}};60)kga#O@zbj34M`fZXMsa~&a$-|6GnFYYkGfqPj%F3|vDW^fPLMin6xREphP zh>YtLyh%52HglMxnAhIkI^Uv3st_yLpnZ_)|2*;C*$_F>MmIO5`f@jUsa0b3H;DLE zEq=f;z{vvu0&4NX`sr0b+rH~18MZ5CIL#V16*(bo7cc0FNNzwbiX%MKKOsT8bdt26 zMmeKNM=FRmOG_GeTGcfZbkPj=a`3a;n8QC?teVtgv3Tn=9Ru^PfC^3US2>Z zI+bXq1<}cTZRtpQSve%3s74qW$EU-p$1H0`MbrO%3V~FJMgEn}NaR6C95L zZ6K}`b$HFaA-@zFV2Fk2$36I%4GmYI6+@~*HKAVA0Q^l=+VF9ur?$OI;GN2l2e=dX zFf^heH-X0O&*Gmy0@^z1|F*`*X>J5rzC->#V`P0w7kpW}W&=hc(n|orkzZdIjW{wN ziQ{W;@bn>+4%yMED9A<^ffbqulK zy|gg7pjC@r!F_TW#mqb6G23QCI#{M@JZz@?{HV(z3Y+Vk7oDf;!N@egy3drXu-l)d z7TNa!6go3+@P=A<2}hEG0?5QO9!klUH8sb*YlQ*p^&demY|!pd(24R_Zl#p%h7B1B zLaj5RnH0n&_z`CAa_ew5Ds|P+Vv>BGrKPe7^2B~v(uFhtpitY>uGS{{sE8HuV?~T) zgqkBYr>`qdP$c7vZ8m-c*1u`rN93I6bC1=Y=Y~n(O})b@?CJ05XrV>B-y?v5kZgvG z=ctJn7iI}!bfqez@?-1+EkJ-*_4TH))2MIqjJT~9=T`vIVZZMi3- z6J#CEG0A6@LnO(!Nk6(?LxPt-sf1;s)=N_2Vxw_hn@JtGsfGJ4FDB}U7YI^3dE2_i zxR}@fR>UlS;``dcnn%R-mHwguyG;l5Q7`x9} z9aqU-Xq;5deI)=%Q4=!LCS8Wv@-1G4xubK)sUwJD>MC zPgaJiWe&@-U@1rwX`NRw7W=i&6BN**uKs!G2L$5=jed!W+zh>5yIVf^-^=yu&UkoF zgp|(@A3qk?)%yZ=q%G`V|Gg?ug@ z!S-h2B8EGCAm`Xhm78ry4s@^>b#V;LQ-$W&6!!fRz>}DK@Ht}5lbU4<_ zC=(I_<6dLp*Dxvgqxf|h2>*enZGj`ZkZIecZeNNno&Y_|;NstPWpH}fya+Z3R=gsh zZG(1bVX44{ikj|m6;T0L0ZH!_p2)vK&bvYXTa*R=ldwYZ>4xK^k)5F3tWNS_IoY! z?ggDfSqlGnFc9=rl+dmbXz=$HL_kpDhgW!kg($rto4@@01CrFwEct~*=-6MF_*XLKC)6v*cr~|d0(f1vEt)~o_)2*B0ywpj zAuzqeVlg$PI%;T3HMuAtH4mnz<1iAhaB79j(S;;ga@(sQNpE1Hq?>|Z&|vzjazfLJFImUHW2+$d_n(0~PwOc^C_f5&EK_+*rQsay@EBtM z7#5r9jL`|%D^e5id}d8AEOvVJVS(Bw*=A!?ZmJH7pK(!R=NCIm7jvfu0=+Bp;g)a~ z=Gt8e37Qa+$7B*$mtRQMqoT^k<>bnm6_Q2S6P$PmrH-`V-7ft=uYdP0zm}O6Y2P1A zeKTwmtj{I$y1n#sueqC@u>ZaSNZS7~;OTJm`abP+^jsEAcJ;;g#PF_wD+RP8v@|nd zurj#pcVQ{4_HY_Tz`T)eW4Zg;fOYo@#B|&p^)(}t z_f0v3#Mb0nPgid=x4opr2|Z5=^#qMD^~n9FLw(0yM*)ts=A#Sy^H*9TZW68@@oyrt z5awN2C=&mBixO~N%u_&k$uh3v> zgA|xdkEZlZGcS!q@>MqW)8IB<3}b+XEQjlXblAhoh)lLcQ?1tP!{k6zqpV$Cw3rcK zDKh}#bOh3#w(bfth!G)^mmA)Gg5$WC~LCdyK)45NN$jO4OgzOjpnbmRJOzODO?&F}QAcOsBL z8u5=0Vp>Dv$Gk0K80Vn%1sv2HRi1FXr(|-J*jy<2C-D>KgGp1@Kx(Q_OPC63Buf6Q zlVi0fCpzgo#$SBfOyC!n@L$ZBB@p>4@FyB6xK?c@UeS_5=<#Gqtlu9Vv`@z5iE4-+MnaI=;2C5NdO z64)6-T4pqskHb*|CmN}}n7`SXU^5Yy1g3Ppez2!ErHkmWKnXnw5uyd{SEt+qG#lZj zpz9g>#rioT-lN>juW@~*=wnK4TPBxUv{%!DmRcy#Na+zRwrlCPq;)3adHV56n~jze zsX;-B9sl01jDc!9cTL%I{`lWC{MA$X<7MeJR+efv&YVslx3e=jF``vm1z&tgx;2z% zF8i~&ASADc7K~sHbsJQG9jSrWtE)JI?rD8k04kzkD;MF5}l&gz1 zlOps-W(LLutV#Eyp29P_0EggHzPgtvh1b2V2o=>4jrd8qq%uLpY&Y^dd41~ErH9=E z_XWv}CkuI|jnUj6X9*QGbvdhi>TI@r59KIG=rfe_wa5#8EDYK4uS#A$^tr+Fu%;R+ zDw8_*zq9ym2GQj56T+crnmAo`LpuOzp$s%MQ;qL-And{U;RtgN-)F!}wiVaXpEPi3 zm-XOz8HWYMB3Fc=-%3Z1dcM>D3GWj$@NxLu!I14bBR3TA+pvh1tr(rSMGH!Z(f=%n zs&tyt6X8LDqXTMnpl#5W=Qv%7!{xL{aI7P_kh@H`_4YF9KyH8yWR&EFP8poT5L?i& zlCY_2wMTRs)~YoY)0r2^%zOf*8Iw-G;GZmsBZQ-CEr8z`KI04~eyyWQlXqOl)3mtW z^0w!QArV+rZrRsRHTwS3Cl^6PZ6X&Z%2AzKQCfj=vo)w0e$l8vuC4~~UqFaJ4dXI8YGLW zUeIzbjLfjtF=rIf^c!AYGBDh-5C6NK{Ch!xdh}|k1}ss!s^~?R#6@@bDy*BEnQ6n7 zxXEXczdSW=51T<&Ppw(>1+lC^qXqQ!7Au!pq7T98wX=tN&(%^S3)Skg1GVG)E)c5^eq@_8vPq~PZ8YhVEB<3z0{A*#ork+iM|l%m0^;{Er>upc|l zL1{9L=9P;F$fFD%%{lNr7vLDq+Xi$yV&7elnLPn?*P~^}%b;`?O8#*lVPZodAuai^ z8WAsd$S+~3fa}n$TPFr{fF)UG_%l?+!8Q<}MU&@@O6V-mn*fV&UX&w>?imXgLs z7m6MLIufP$tQeQc^IE_eA6W_P=vmb`Utu0iZ_Xo{!=cOdR3m|=0UgJe&B%VBPSV^B z(>+d>LRW5>%hlkpO=?;izpmTG2_6p4fx(9x^|{64HLFmd4i zjhod#Dw$5LU%%mvNTl%R4?Hj;@5Z>FAHF=G?}q_>`cHoT0TfRa8_^z=bGb zQ9CG)3K<+C^jJfJZEDx8ThEd%s9GFA_o)gY12r3OKCd(n4n?9gd)7SeWf_kl>UX;s z2?r_w0jVFl`J8szPz!Y2lhg;YDSBi-48;z+&}bIpfMh6a3Q(EI=Z1ff_!E5n zu*tY^@x&7>XHz-@lma4j zc)6hE+;!JoM;BgjA%i(jQf7&5325k1i~}wmCTs$Vk{f9Z>im}`hu`7WcN3w@o12c%b(O(m zm-Vtt5$8}>SMLD2-)lJZY?>QDgSP9|tqTJ|Th<{tQZ22VMFTDPthepi(D(=5;>pt^V_ z;fMd!A?!_$2m}J>;Ks*;&GIl)P=aI>e&-KKXPBz(HSD=vQ-kjE9tVv1ku)IA(VN$m zB!Yi0DXoCdG%a1Sf~HT0Pr1-2PNZpE{=mtjs}Fc;M3%XJF1diRD=l|(hsFjj1yHD3 z{`}`ZGwq_s%&Qk4CcO-|mb>-VTe%Zcm(E?d%wN<$u9_$JcM=-|-Nba_{R zZm(KwK-clbb;I|dE+$O)ggZOI8i0@A>*wQl?Eqw@gajdcXi!NiPM*KH5n;tzU$83_1F)$|B_Df5cyw6TFj@kt5uiJLZVp&2t~ zT8#^Aod$QgXe65h)quwiYL|E{NgFq9rE%jXaGNq&0if-i0K1q$`B;m7|NZw9{L)dh zWUJYd=>#XguptWedF1=%ZW^uW`;}tRNDg1Y+unZr?d-{7S6mABER$f@ZrxZOcwZ)4*+zgCa@YY=3+|6?Q9jrzt4@(b1oF; zPYg}O;{=~Kt2RI@a5rz-%0^>2W<5`E+d3AIEkdDl*r5X`91fAs1399sq`-%(E2JZr zHPjE@k30zL*t5{Gr>W0DJvmaB#H;AhWnx$NO+P;ywbc!a67kIS!ykR>i;HQC}q6|I&buV|QN0lXf(m6pT@GV71*_6EA zPz_!ZAMfUFHbCh~(Kk8Ierwc|dn_KgjQO!c%a!C#j}@eFv3G?uD{|mG2uPlhpeUV~lIDVLi(HxBfr& z-UH0Cs>&WeFTYCN)m^DWRp&(KZgNI&Kt+NeLX(pu!4b1KDyZZJ6huUkAR=HBL_kJI zL{tU|EfOR&(235ma@EVfS$m&#?|HXgbyYR~=l_ko%g6Vs-@EbLbJp2s?Y-Cb64S{2 zYZOsIG=N&hjWrAA%{QTN-eh`Hx~ecb5wX1q=;1=xs<~)5Blpc@(q_uk2}0fAoJdNd zdZ+Y4nWVMyQ+HP?-MX#wp2|qoCD;D&hZ}ab50;PfTcB*A?__Vd`Q~dzC1a86vzhGi z@kBICzM2Ud1Z4mo232)+tvI7rtz0A8B8dNW0i6jOUIw9kGk|PpOk*Gos~KT>QyH^# z=~Ag`BwV!B;wCVF(uGs*@WT%mZI_udXLvO!v(G;Jn99ne2k4*%SXVO`Z$1=2XX?LDUpC5x z6RiudE})ZVhpaFD=6hs))2E(#NwZhRqSo4!B09UoroebSB zIS`=3I(H2KPSorV=wkr#_3Ji@6P|eyK4qs;0uA*eCH5SeEZJPjba!-`cswf6E4JI% z+foCAQUZPf4{(5pz3(xj$26FU6DJDo0ze1V;)|h?Dl{gY%9^gu-j%(*nX_-a`KOvT zT;ASS3zPwUC!25a;%}Z*RZ+P(5s!{is)d3{lr!~D%nVV4i@mpcod7#X1WnXXtDc+6 zs>1HJRz5<>qA0wOH^YaG5GUb^<*Urnr7!7u@(R$P9@GNY%*z=wW|-@*zup{j$cMah zi$!md5zAu~07k;o``u{e26avVf)MgTWD8=!-C`F6Ph=3niTj=JepjS*@%*sNVWI2h zQ!eg(4h7KNIP{p~7$v{Y_dqJb1y{tzQ#_2ZOfc6LZ&5+rx0PMs{j_4IUm?;f>G@obpL!M|s- zg=}Yg&oAO8@zpE7_r3M+w=aIsk1qrIPV|7AulsIGq#}A-p^!hcBB|<#q*^dQXo0Eq zr?Jnl$id~pLImV)K0qO9Se{7fc8e>(qQ?eH z@|tU|k!nA%lxSr}El_e2c)x&74i?wMb1SG}2_F+`3Hs?*UU{Wg6(0K$R4~{NJ@g|I z*>cRWpYZ4aIj8s%{=Wxwe^OOo;^ZXsmleceVidl^$^&hS|B>zb@WYRa&I`a#5^1Q# z6V-6jWFjUigiMm+3a&q357I9Em9X;+01K@C{VH`we-2i00CXg?0YqK@0QSQg4fnZV z;XDC!d4@s;l`Mpc@e`wpCw}UygX7nUS^>SQOD+3RqZ`eFKUc;Y+pM7%y8Qx4h>?eZ1v z)M8bx9G`E#`KDR^?n<>l!%^w@!qdwCw&IOVumPa!;0~#tMgag9kuXPqJb2t!UU|(b z1nO;yoUFBg@NZ;WqPX(D`|d5jyB7LC6VS;a(=kX3@&5bomuf>uou>nmfW@%E%P+su zELyb4jBOs{IY`AymvU%Kno*}{&_Wjw3x03^?Q-a@g$~MvphhrvDG(RXaVp5yQUe9= z6My5nu)r}fKlISA%Z;Sze``UE2yx_ z4@)#vC@&Kp-rulc)n@*Jxnl8SY>;lkJz;;Ygf3BV3yafGtwO&> zBtsYT1%Kd$!wTe5v?3le70D_|Zh86TSIp+k+x!r;5FAx1>xz9BE?j8NIO7a+!3F1g zkuLaMb;NCKF$d-l+ab8S%Rd9GK}jIe2H}%P%E3mfks9pNr%yLG-uMG^zySw%g&eeP zjNBdYoZ*N;Kxfp&K!D!a+3x9~1H>XW!UXqA$zD!25-H?liOPGkegV8ETI%>7Gz{X* zpL^~FbI(2Zh{Koi!knbVYBd12VdB?NN=X5YPVoM~+_TgN5#_>3z~$0;-jyp>%e!FK zFl(c7^2LOM_W;ftijf^1?P8U~ZO+vO&o6DmDpelk;0- zEkIpp!CcN-^-+^aWi{!kyZh}>A$-P_*Z$y{_t_Oc(1(`+eTc9B#v3kM6pMv#h{YmJ zT4hJMYx1!^H>%6`>gr))wRCs)iiN&*&3Y>VptJ-!e-UkA4WFE?b*WYzmhP1@SdgFu zfIu}P=%FlI_O36fD={xVpd$_)7CK~gk+~<ZcLe;+0j)tFAUQ-Ai!jn2@~i!~raH0y@jwG0Fvp z;a+fGZo*M1KnHCBOB45pNF}^C@ZnHaLIMRuR4OoxN(cs>){AQ)2WT;e9hj z-F~n$fX?>gd2laS5o&>KOsE=NLf{9mRwUzQ@4fdFd4pIiYI;-MI^pEhnNPn0&lv=C z#Ghl6Rhon?>S_~x0SF)0C?pxE@y*LM z-Q8okWWteaTYSnw@`4^X(R7wYxSW@!g~GgcfTtMIB*2xd+M?f74r+*8JXajNKKXi1eoEyr91+K= z^A%x>(CKe(86*8wd2|{a0RMtX_hJFX2e?>}#(1zG^F!w;{Jc8PJE& zWH;XM-9^S^Z>X+LHYJjA2^)+?v>FiyqMuwuwM5Nnro5;7 zKjO);fo>72FHEjpCkYJL&6~HH|NiT9QUpT=skP8`AZpabv}w~sALXQz7Kuff&Ss>l zJY{;{Z(ALFDch5{-e`Qx}x%cN3bpgF-!nA;nb_aKkNGK!|!2r=PP*~|&v>KDlxR$YI_G}eG z1L(%BTm+oAd{;8DIJp(x#OfqzFiz{0S!-z-D_p#&Pv%vs0-!I3KuC+e2+!Zu zvndpce!Z%u>Gn%6y|k}-*$~F+2X)snpbzrRUw!qr##F>ZKZ?a7M}WSF#Z?z1ErUe| zD1d$V{|G=Gy6FIKgb2En3pi}V*uzT4JMlv#i&Yqd;2DfVr&a8}58l66z$T&+ z6H)+ry-fCup~tZRRORst5-&b=@?#n;b>4x9&IT_u7%1Y;*cb=>s7{B5Ix~-io zla0%vyJ`M|wa}qQ0yx=TzVxGiH=Ty$~JanQ{s?YV2@SfcMO3T~>f8;j6pOQ_9!GgZm($Z{p z*=4%v?&&mGG2#7+0wg2_av`A~t3(&VD5>PP&7aceX zysj0gfE<+&MO1=$e(8&5)hab;06=#mcUl>~4A4mR8uYHlLo2}L;6`m^Fy_C4r?rra?$FKH_9o(2o(16k;3SH2Hg z?2JT_?;U9YwQzkWHh~S_ABM0u!xm3?lG?08$i2 z0H8xy3!R*`HDSFF=!z^trgB=|5|+6)co;GU&@-wfj@13XzpB-Y;QVp{oiqoobI?Ht znF}tsz#Mh-k)rtm3mstjegU0UI6fi%1P3fa6*Y8Howd{x$LGgB_A&F7uYASqy6diX zQnc1*0MNmqyPdO79J<|qps>Xtpt}~jgfUt`m(`a2HvwHNb32(9ednyGX!XL;jpt{? zOMAN(!9diZA7P@-NMw#8oDcnjDvU0rqZ5FoJUFrSTdPhf5%A*TtB5AVX9FiZ_;V(4 zak5ayq>-Y|Gj^F~CXE|s+S;}kMZUNZTUz;wiEn;{j7)3{eRU`qX0GxXa4+=@Bh9Q? zGfjPiQcb49f>|z`<%HB z2K~1e5}DVGK1RXFX9QWKm1gzYHR5zdNxQ5>FkldBwjl2fa;~5`KL5pwO(L$b@z~z) zjLv(4e*op>ps0w7LMQpodt9^%01!kOdr!u+XV6Nh@7HRhnYj^eJY-gz=_vw&Ig!Lc=2OHi=}+G&MDv=`$wF*ht&5c8H7t<$^6&(1;;u6}7f^ zwPv%0%d4tJUSD>O4j!xi8RL0qSNlJ>_pLWwKgUF~_r#;IIVjJCa4uLaNTHWZI$M(w z))uJ_P%RkDu*@OEg#m_SAhqN*J)S_#CgFJX=@#wiRQVH-vD)fhghM23DynKkTOEK7 zFiD9sPAlnfAoChhpcGc^c&j=#uK2N>H-SGI}J zc#xuyl^Lm*j8HF#aR==(vaVL17Y!qM0I8Ho#!#XT{T9D-I%EIU-j9EyZYZksz&YiDg%_?Cv8BtbmbE{abzs5z#wQbUX#L16Y~!La0HSf#lG(g@ zi+S?NC&j{H@Idp`OTK3CDXRfhUdXtEwwXIx!*tBlnF8ncg z`epCDZSPOHaVGEVw%cyzlv7SI=bm?-M1d$k=B2We8=uw}xQn~!U^^_^v!kP}sK5oD zLo8W_;z4!N12aE7k8SMn=2kR~5iUFrqLvs1gGmefLk$zM2PlTY_eJ0*zl?nm0fNdt z*m`=qyaXq%-e|S!z524ue6P|^Z02b^jy@O?1;e-AdfT+NYK0~dZ6LWRC)v%V3n+ zi}>5to-C;Kg8~$YTmjXA&^@I1uUfTAmc8ugK?}zPX@8JfXQl-Z#%>dUz)_Ox6`r~f zu^e@`fa<#S8%=MoI-{_W<^f0`#rw>&&yws>2zH6}A65FrUBEoEtO)qFo?NhHz5XdCK>QHUW>0s252-OY43FeEJ~#RaUWc zlJASF3;;U%3N%~bkcL#QSkNM}rPPU7=@FGz-hKC7O;uH;>FMh5czk!F;C+_r7hJ`# zZ*aBePWtXXI9EE;D|E~F@#CcUg*<0IV`32$>h`0EB%2}>F+HhFzN5YS{(L_Fxw5{? z;PJ8y=sReud+xY-emog}FrDe0L={BPn%!Ah(c6#7$R6o1Zo86jtH2*)Hsd{NDSW;$4pFBPRoQBExx5bQ*0lW5#q-U0to= zli9TL`Y1(c9l_wzdr}#*bxZ48m6g?}eCIpYy)bx4`(W=`2K0X3|1W>}%SdnM#?K~` ziSJ~xsVWQz)k0B;RL==&GxIRG02-+K2@Ace6Z$RPUgh)PWtflw&av1EDh6~~Kcoe~ zqjR7r@W*5#!5o3r003m|+I5Iu^kRrPz;F%>W`q_Ve8?dZ?E;vRd@W4#$WcC4waQoS3tIX{bO7djyQyTm=>okXKC>36GFtrH&KD~%@> zueLE{mQiMI_UxJBl*TGEB_WG`rn39)xngivmhSIr30Nw~8YaQx+13~@2oeC*G;Vye zl|iUBU7f9R{a8X(EH!E>1`ge{wRZMKqlq7d!&Tq9?6S+s`Ywa$`(;4yr;$*RXn0lC z?a^rDqoO_+(WN>79UUBh%l{#*j|k2Zsr?vKVuj@tVBsud!~{W5fWg>uWVWWKZ;cfL zx(ftyoV5sf+tGNX_XN0~zy0kc0h4sbW>{LsAD8f;g`l%?+;PW=bJPX%;PTo9bcQDi zFj$Kd&-K`2j|rf|8Oljc+ed*8w8FQ(^)2)9BaV>b!`LzzP5&0kCsAB6>HPwE5O5%C zi^L*oxwwEXfNcSt-v_$`DG*VqbU15jwjfLpf5R!xwqf7EL;_9vHEY)R6q9vOlCFSs zE#lHK3E(?c2%^!@7tlGOlY&tn4%!_4nib36lRk$P5;j!u)9_1`8JIkIvY9hymZf&G zrjSE__O*cA=XWQU;A)NkreVUBCMP{mk8c0L-(0O?Wri||&`gg;L*g{$5b}LN8ug>kat@F8unUq+AH{0x$@h%&GN1bA|(IpTP-{{k3RS=+?}&K>{wI z>;3D*<57b)D;j+U5&)p#np;Lm=wv3_) zDF=NK=!Zy2G?osv6_p@}#eVNnXuIf=>y6j4wLmQy3} z66hhxz_tRtg-IQmvj`~#m|?}lV|aet&*aGyg#yESrVcqN7`~HI?}lNat5&`zfR5-P zPTtb53@DAPv_JI8$BY?mYKB!Qpl32BR-%9g+rw=aPJ*6c!8UUNT@s5J5^DRgH3WDr zv?2b+`;ZmG)Cm&KsG9jI+$D}@s6kd%i%%-mlY2W7i=KGRH8;HYe;Qc+7jAxM$IJi1 zt^NOZi68&)`U8gztGc_Urltio5|L1ZO@PztR3NPy$uylE2>ViP6#_FlWp8gPK)Lw9 zAz*ARbR6e$?9jC!pfjSv1$MM+Kn`lkj0!PXyJXpnx(IVxd(K5CoAGoima!7*dfYxAb`7J zvur1KAJ)?K43)4tH?fk`$-l2!C9a9d4QhQh=dc} zon4(bR8@`m_GOn{rkqrHE7<~NKo2wvqFcHRGW(+D==vd}6a>3I+x7Wk@WY7dSbc%Di7P<>C_l7!_IGw}pISJ}`uLShhUVBYeGYDhULe0Lu3;vA_lFWD~ zEiEl_9Twg|KOyM4lL*cYOCIkRbRP&)hh;h;v3{%Xhx>9Xn{lA{0hI2N!(y zS?8G3Pd{B`Q(=&!=(7%R-|dMcK~zB{n6MI2DNEaHpZ?Ui94p%eDgruI5r};bQU=gk z;R=Y?2m+nlp9OTTT&U|ppklib(Dhk;u`H|-ph5{BhqkF+jfp{cjnF$`RU?;{aqk%b z&y|+sJ+yYnqzb1iG98l_#3qK~+9 zttV=vwkRqXfi?lx4gQwVF!^aonIAXhn#Up`&^3mX_=Hg$)tVQ>h-ITo6tQ=cAh_BS7wiEe3(D2&8S; zB9CV*dMV&_zk@UYCKC7=Ale17w$4r%1FDfuz(e0a0Ss8^STTWaAwa_t_k1Z4%?S`= zA{sT@wzkT|4eOlO^(!VJ@hNBO>qkhKVAH62c|a%4MqpQ>7izP||W~NCcY zu*^ZZ;8S^5TXHPGF$6hra?EbnBF`%pk&}@}E?yj-8P!0CMI%uTp|DU5t5>hFs(-%j zx5U%uvZf+gVLo-j@#fQ?{ugpe7g@@(&t}u+)mLAY&{EtZ zpMxtOH*C?R7&uXR7ABIg9N7T8Q#$x~-}0O`M3vx(z5@+-0PpXA|9c7XT)A?!WXbCB zR#L*o_N%2jS+aW7iHb>DX+KemWL^Q{x3gIQodKo80vg<(MMW^djvF^dYI{~zX*3Be zbe(9m&$#Wz)d>N;Kg{&sm1e zNa~3tk`j;p?z=0rnvpG>0lEcNIzJ~*onpTJ^{<RQgVMV{%Z=k2cotawP*uca zArlFBP-9FYnKY^1UUSHYKPdmseP z#BQYk9dgGAuLPhIJm@&YGe(hlV}ZC7pcA0rgJ8lC_SX_?84q9?o*J}v@jbF-!F9ul z4yp?B!gPkJR=Uy@xE8E*gcma6g_A6XlHVD#j`mEZoy~l5fDUV^B3UV#9&cLbD0YoT6o93;g>{@o<1zF3&wpM(7&;s7=32~n zb^s&v&LIyAX;=xygmDP12u*4vtyN!YKd~(6K)Oy-z#a1S1wCA%{-zWnxihXNR5meKkbh2j8;*p;0F$ z>W)7C_~Wv2azWUgWB_L1ynW4hUq%_{1^@!kp&9hf+snmi=+Z;(xf&blBwP`bL`P?< zttnbCnQU5}y!m1dJxHn0XV4#~&nOpK`ZQ?VICOUfqwUP9Pq5(8U-3>*VIZRp(NIC2 z9U3={4WrdC$Va3<7xL!bhNdwWU3uk|TL&D_AHW^T7P|A&Z@KA)ePi*^eFc+i27qkc zxx> zM3;YtmGTnVh8(m}GL}+0k|7>F!E|$8mpr63|Hzx#v_sw_%MTHAKP@M*n0@HkXm4BD6zo?MP`i&@RwN zGKJ9Fp-AZDn{N8i^B+LG9`KRNfNq=U(n~Lm*40#et!7yD*9#_-z;breri~)|NefG@ zAm5239astgTZgA3z=S9m@XcJh1}z*eZ3_~{X038tuhO;PffMdh*QHrReKO6@T zn=xaCBw}G>XecHCv<+woI9QSDFB7F#@=xC#UST2`F~~QN^!f}YpB|ZvUFGLn+xAToq0-(C8Cq>3HxtwC&=FfP z-M5Ogvj+j)wRYWo5w%CqD@7TI4I3=yWA7RJXT_PMnk~9Y&_pGOMq%J@+_*{j?oFGv zh=YmzITK%?O@pWk#EU~j3xfv(hgqMzx1as&XXf_XZ#Pdr{j^6d$>7AQIiEM<#*a7O z|Ni%-ct-8;TA_AuACyU8f{SZO;&>@j*3)TTeBp2AKmOxCqy{UJY;awGPGz#n0(rs$ zX3R@e0>H+TF|QbiOoY~HtOmA97GRPXwI6vA3 zV2TyQx#xb`?6=RpLVKwomQn|dNbx3Z0Y7zaCKHwBg%@5hH{X1Vh^XP6sFkkyGQ2J( zF<9s*2;pXq>g1LXp8%p;wr*9r1<&AzP>R^588KqGIq<*(MEDDlE%K}()uBOBkwi7w zm0b|9@ozo{?VDK0hB0^R_f&oh2u%UmI|eDj-n-;&6;>3 zVQ#qLIs&2X#Y5ZzqPx5%neDe&W%Xd~!12>d^g; zD@0N&e6M=Heq@iXG?+l4?O6_wTBudS`S za`EED(ElxOwgt)-x-sU)8*dyI%B5~Jq5NqWU~TQnn?ti3^$%TOq9x3Da|~dCn?MRU z0i8u2*wJ0eL=Ntcr!q8=$>%r~(7~yLn!tS`v-R0$pEFyx zZubBk7P<^j3y5%0ks<{r7+Ww-k4N_St8(x=t$P4Ki5b^A{`-Fh2Fv zQ#}qI69*R8-bB+6pz}EZPDn)h%U}ND#Z%*X0XP!&iLgNy|8OBjR_{CmN=P8 zlY8mz_Wqc)>m_M1#8RU-7zfTceY{hwBCfjX3bSzj0-+GlPB<^q`h!#x-UE2+`npE3 z=AU`yS(!lLXeOYOPiJ4kXG_aiSwVq*!oMXuv`1s>5k{N0PED*dfxD z?=H?zVWi;sq5WP}RrOjfA3pKUJMVn8jOKm|lmY#JWJSNX_^QKlp~8>5yF15W zV1~oGEJY-M8@H?`hoxXxJ>DkFxI8yHA1E6-RD(d{c5oiYut!=!w8Z`E`>#sQ$GC3G zMbg3oN35G#HpyhASYQCk<;z!k4pC@jz(I&wxaNr$)u!|Lq8o3 zQAD=5B409*6!PYbGtU&EFC51~%!!Mu2c{DREpz|^zzCstC{YKiRjs(3Sf+`%>ZZGX z3dVpl^R)6*@q6G9dlSI^eU+Nx469pYNmL5rGwmn%`1;^H}7OWr@; zA2*y#Xwjq1`n(%EzPJ*^zNpHi#au%8Ox4%bUAt!8hAWmVS)u|$<*lD}{RgOFF1qNV zVH3uWy&;uKo!QaRE|Cj}0zk?*tWg(8e5-=IcHYFH#Alb{w8}6zF@ON*)B<6Lb(l>ke9Gnz>!ak$Nj*+lOP%=7=ge1mYEh@Fr<$KF!1OXk? z3AWYmt&s?sM;>`Z=mP)`KxxAG@m>*QCTQVV(XNsg-DZc6~;afKv{e?M9&H@7kCAkj&t|LFo#&-Q7uo6e5r3bvQ0`>=ZlW-8PIw zbVZ417kpy1Gi=zf*9#_m_L3z_p8c^&$SnW>AOJ~3K~w-i)(#)_18t!ncieID#>U3O zjmclz+S)o9vZ5MZSWtcIY^sljwt|*&dH~aiE%D`A7}y6L4m>=aWu+_-;W2H20Zs}U z&kOx(%?iw-+DuW@39b#WwkiB+Ew;?%GM1wpg!rtitd@ys*<0@j2&{fj!Gq4xn6(PA z57NUgx#SXwRKW)B{pUabxmmn;u{;N_!+{1cIpM@bQgj;5P^P4Fa=|rRK==4nS9itQ z6zkS+Fc)2Pk$LE$2Q0WnMJpRl$5<>Xkq~OBYne83;~Kr=Xp~!(Khg+6fcK;otgZ-} z(F;d(B06aC<5~bjC|F{J(%pr;0>nuV7wO;w4%|=P6ZX+a6hBFa?VwIb)vHIiBig#E zsz$7HOkhxB41ze?mc|5t9ytQDXU{fUwrrBg6;5toAo>ZjNErzOKgh1TE|4f0MEKy| z)Q_P49lk&5S9ztKO8t*}3MNds?deVeaw-S-Igz>!Q+@w_m@Zc`L@4z8po10nrTs3X z3XzsdwD*;+sH%Llrl#i0k3atS@-nFR=Xv{pw9NeZ^N)M&wb#B{Q&Y20EuEA}B$cxT zu)`@uOGN7Z;4pkgsd~jvy!bYI65GK7M;?yMtF{BToaYJ>?i2)-x#&-cf1cS z<#RTJko&-rA)xEP4GFJ}0tm1K-+t$9`Q3{}w-f>H4^}#;6NE5gsgKB(AO7%%V%=k7 zl_omXu>Z}s{7@u#5!oWwwJGwn)VXSLYnKuTw3~tZH3Cqd`ONtex`?)qCn8c=XV2aD zFx54cvT8!Oove7Q<4;yMHV;4txNoJ>smB$NP69d+xT_vS`S^fR5WsaQ9JC=O=Z=m} zaYXj^AO&BmL!rFf-uvt+?*~*JEp$=|oK*0AGO6+Xu+VWVqBbx=fXad{4ptkySKN;q zpN{Y05ZrCI-OT#+YlQ|w*rZzJes(C+{So$wGIOY!v}yAO0d!i#+Sl|LX_JgbBe`Hq z%7i>R|IO@Jcd}$(Lma-_w(dK2&rLw*B;DUm>l3;c$^MJLG=HrCeG z{`7wwz?Uvvy3~J}9}o-+KIRA3LOlHg60tTAZBB%t)-8Zkgm4c#WL>gQJM#nhen08 zf%B~FpFtoGTHpZ9VoSW(n#V+4Osy0<@q-kbx7xJv=^mvikw$${nBVzoq1Ks?%3;WS z&S$cTMBC&ajhkbyz4=kYLoi{d)*>}^XO+PZm%*04iD=_Ui{&wtXlg?VI z7Y?CAN#ur%3jIXtjSL|BX50xzPmAAGR7v8e2XQUcuu=ymHw+M=bZiYgf+U=xM;>{k z0MuP~-6i!fxw;@o;S(SZOaAypCz!^DMs=`?Hj2s%;IpW_+ztR8gB-O#&p6`@^XOxb zm~0lIkRh{R;XH{Vfkhmaq#n>KFv8S=lS#OsVS=!}3Cb>@`(UjhrL-vJc*fB?lmo-? z2)tbCx3;zkp!am+IYDJrhBW~^71~KS-TAO@pl3CLGLiRG5#wkt37q=hznGf)pmpLnd!fj49 z@A7MrR|Ux9bCw!+ucJg4**U`lH%J|K5*^Sp0tI>>s;1yEQ7bDmv)p*)w|p@4PYO-QnFIK@RWsBm@^^2JFp zDkBxxd8_T2Dj`8Lh2)zmDaz)E7|F0ye)Xfu?}?_63!}4UEdDBf7}vUo@!%djbriGg zH1)Y6XPb63FYzqJv$zt}o&h^hT0^4mXTBtz_(>$a}Ml%*aDod^X%Cg;`(A{ii?|S0CI`C(9pRUfx*4&L6wl|DM)r zDRGF!M-xol{+1ckppk;nbclj&n6=K3(0K{s3hM>uch+y9r+zU#c1fnii35{C(hmj; zjFB!=Y6zHDnXqvG4j=s?C}`-T|4y^ey6wMFL<7uQ#7ReZN*%_)#b$fJzSm)vIl2F% zY2qk>g3ArVFeE55s*ou6phIq~kJRu>uh*L?%eBCOu&GKF*MEFLSgRF|tZ~Utnv(n2 zi5Vmqb9#1!50p;8_r)BRnDM=q&*2RtcTXkaZdDc2_-$FsZF*h-1m68aJ#!+r;!7F3rI`>uh7JA2m*|xy7Xp`6(W;COt$v!2IZ?4pm!)JQ1D>BP zf{S@09FeidU+Y9UVp$>x{=>>rh+oM1eZR`mgmG3(+L8`LqNLW)3+aql3;P~XTK4og z8BIVzts9~pksuZIopx?FiLT~VP$J82LSU~O$WX}wfapZ%V-~5zW*pYdz}11rjCOC# z@iinzwJI_3*2h9j#EL6I3D#{8yFFB4-eL{o8q!BpIMZ(lzlC34i+1K z8hM@0LT1gZ(~RG3Z3!Bh{sgp`{2L5WKy-?b^noMe6?BGY1Ru}jfX)R_f+Z8+44C## zfk?&JN3-V+(u)$|=Ve53 zfZHmFb)jWr1C!Ky-QYXbQQ2YP;O|ro#yYUyxs|XVm+S7NGvJF2(m&cGTIJ4>0HHVA zK*n~zUznx3+`N9+@P>Vkb4M%<#lT#I%_2|3jlYIieTy@wW1gGSc>LtBz~%ud12eYE zwm!75Zg>*uWG2y(QgJXq9V!s%go*ZW+*X;%5G>g+{j{{;GIQ($fUf6g(H< zM$`Y9oLN!EU5*|6q0kD(jO~&TXdcH(D&6WmT2Ohx7R47Al;xiIvl#N!o!74Cc z>k6Zg#o$*xqBYEA*o&#?ZV>0kPxYHV9A&l~zI$s~kQo%3&XK`>^B2sNf!vrF6i0?5 zkeV|hPN+M2-uH&+SE_}~klPK0-HP&ZaHG=ma88Xc@wj1N^V>HD70iObp!1Q3(HU1! zwg)=WFb*29xe?ER9V*eyuM^YWANCFo0agqT_o5q3cDWc=_ZjH}%4^Nn9m*jJM`Gq; zEJG|8#oLi|!4ZN#g5;+{^JFJcyyD{yj$$HgB^NQRhSX6;nfFu&i`M(O+g)3{sL{DEVR(8#{RGDbCoPbq?Ddbjn`1Ix1WBl5YjdHCQ>v@#+9(Me z(_o#HRZ}n~Q;V$_05`EVS17={@0i3$iZ}}RLj!$V2-4AKqq%l4hMREdxsJUop+PU* zut{5hPmhBb1Z+irqEHT4EL6Q`7AS{$NNg9Y2n@Zgvrc`skt?{svm74g z)9hGV+Ii?@oC{E{dQO-Lw4;GUkf0GSlf7xNT>VkiegR)k=E0BRm{Dm%;X;rxAcpRq&@;$)ViNDxu$9B zT65Etvta{{OL|Nf_RTMCTHjJf7%&3?t6cO{*F$47S=h)+uNHLLf+@mb1S&ad*9`BNkuILfp`DBNBe9C;&7@M>%PlKxG>*&Iy~I%V_?UYi(3_fQm*v?6rE z9l)131He>F}nh7r|`n)rH{|+!ZI*wG_tuVj{RFd`y`NMR@P8H@#)dY>UQaJMi~>{qQKtg^H&u;r;9E{+AJf@M z&or22bYe*V0$8#P!?YJhuJXdUkafn=1hwHyrkJs+#jHCkb)1PVQbAGl()yJ6B*fcO zKM)A(;(nqW1^XGYcwSg@5RE-K3ia|qt;7+$LmU-9?w8DYIqf_fA-mEE9#wkl#P+=s zUl!#&E`v9zg$-A_wBn$xVusPSe+9hmQiPT-K1_FpUMLej6J!v8A|Px{x~r3g`PRwM8-;p#ERk%pRJbTL<`b<0=ShZSW zG0LN}TfYrEG@%`IBt0Cj{_pWr^BwLbN{1!nBJ}3=Y=|L*P!+ZDGJ_`|&5sF{YjRRH zwPbcrEWJaiZ@ALLuy8SaY&O>f0j*6HE%cw^J}q=6sz&CdVumRHtCZ2S+Rt^fUC0ok zl9U4oz|%4k;5x^ZNfc+%CBhcMs~C7m>j#*Om=iX|1emKyIFBm_JgfgFZ1R4%aNZR6 zHLQDyxiI}CZ&;}^jtW=k{NI*bFS?+DFqT$0^kR4-ecUz~%-Py$>*Y#eToQWyG%p>M zfAGY_k6~gsxJF2+0p$v3<7VV?LpEp{j7St-C@WI`e1Iw*x*I=;usU6MgV=RJ|AO(? z92ZCU+IQ{&>ED?s@FC{c^Y{F^x?lYT$pGwAF!J)kw1t46K!7@D`$ZB&>jvScSP6LR zj#?a5x<4Nm$Cia3`p?fV|E2HQHoHdN{t6Y2&0^J`LRbVZPnMOP>jvvK^hYj4+@VaS zGA5H30l85oNUMyO&!U}*R2c=fh7ATmq*7`M4&e40JHksCSGl@6UO)M&Ss_aYh1Hd+ zN*p7m1+j?5e7)D1mdar>&3q*}Ui$r8FR-|iStc6xVfXG43G!voG<5366Z?wFMVZuk z5d&N)tdzUd77`UDMZU$3lw#7U0ctUV^#NCTF4U5JniF`3MGORYW5HYmP>Gj`Ns^FU zWnXjt{TJ+}xZh=5$LN%_8Hp=G!h7YYiChKrl#OAx7(y1*)Z^e6hq9`M@smFGF}mLc46hE0S4^P5 zqyQaFCYe`%Kvpu-MHpUQ&5Y-Y(o*5}c_M>YT3)ggLNWZ^w`_x-sa8R@1Z0jmO|#AtGMQxo zE^ZR=b?FvVwf*#tq>)ZSPkV{jiP1ZAQJ=cGWe99uAbf}ihfI{olZC@G2Q_ePpfKD! z$t!1eb=_x{{^VML_~%?TjD~roC2;L4s_b8JXyVFMlas$~6!aVM)F&1e&Zm_kSenwL z`H4Z$bsMq9S&`?oYaUCf5G$Ve$d0M;Mc7}&gf#@0O%q3YK99SwPD3C%wEGmaRnF;+ zf2CUKJ!PS_=MNQ4PmzCqGW1JskN(s}YA^dID8H`ny+uG0{ z`$`NgjXn&qqCDtU^zR^EcmUJwebtY|lTi0Rll+nDLjq}W9I=7;jbb`g^LwnZFAGDi z-NrFabz1UJ0{7bzLCR~?!nxYz6so6w+R;5sMi{7P_kuf2=dn*Oc!#LHDDcP< zw){r>Ob}QRYJ7~lEsO7lzRM)|eXmCAu7dceR}9?dH4h*`vo-)%AhF3H65tRV3xXpu zhy-_PS1vRNL~CxV{Q9P$S=vew0x{8TNap!KW0NxK2#3X}RDv*Z@k-wtw=Tm=b?sb-^LMxn4t&9rAY)~^Or7=VvjUz>w zwNU|o6d7IhB%eU{=-aI8(`1d{6c9j5b5)_&s5J*G;nJ^a=n91Znm`If7YQMt8nzyY zvXMN#HPBVz05M((Lc6{WyiFp=3Zui?F`_=p(UA~LnZePo)4bcwNu zW15=t|5m@ScGAT&LsohMhW-5)ikabml-oFo?FxzsS`(TW0Q@f6muLLLf29m>swxk#pF$s!h*By~C&GlVP3bl|z~9t+pvhOE0SDOY^d{ zK5Q5}kUkGFQBdwytf7kALIIxtjAu}kl!ON$#v@>^X@8k@-(p~@D$y}mU+*YtG(@3_ z^M-PCWu(j7>W=%?Cb8-Jxx0=Z?*TMo1^QX+|KHNy%z{q%+@P_0cDCisy zf8?NA{lfq*sVPcPb(%N3{6vGOqnWuLV7)HYQ3I;l6Jd;Vy_S>a83uwN!Y(NE=~*TI zc>_oujgEMc&te9u+2Q>wA-vE4la{_BKRRi?#@$5`Frb?5X*zYNa#bif6&X` zCg0z@JhklIfy)n|FTBojeEKw!JhK6`z-qsrvfh@E`FGneSy=R>&mG|e`rE^Bx9`u1 zs|X%kOz@ntqf~?Uwpm*ZLwwqNh#tR@MDqR?{E7LYb2J%6#QFS~^JX`^LWw^5?*fvI z015Y1IgT*qSg%10D(2jp*Xz@=ezsBIAPeQb5U>ehq#Pf9vx!D~pxf_~DK?RiawGs> zC`AxVG@$#^aHSv4Rr^h~>RhLv=?bvbb%*s8Dl5)@bw#sykx?|P6H1S-DaX57sO1ZE z=$r6+Z7*$u<3eWI41D-SZvL+>Awrg+RGarm>r~&w76cD)FosEqNLWh#P{fGE68uxZ`DL z3atm`wGC~vA;|}RjAOzq>r(Hu6djkOuGxsbSmB*W*vlVtB~p+TOw{SJ!M~8gSR+*q z6M^j9E?^^Zbug&&nrL15Vpljt=RmDQjBI`85{La*AFLnZ|G5N~13)$azcVE$(3(y1 z)qAJ-0zwO$7bi{LUmpeib@AKUON=GzaJv~8v@QFBFF}Q$6dEL@5rGaYxPgJhMhJSa zBDAH(nj{P*=48vj*}U;_&};}2n554n)^EB;!r(-o`9Nb`UD`!ySCq$_4f4760`aL> zZU;L%TzT@Y>d;uXnMg?u3zg)LmWnhUxAd!{9EgLw7I9rBW@b+D<4-WjI=1f@mZ{x$ zDCE&(=EM=HDWUG0E?uI`RK!-6bM=#GoT+WFezRll)6zBtmK@S03=X@NXcZ3%tq+tO zz_+i2Kow0(Y6;F|h9;Ac$S*kQVPhld5z*iCCU&gO;?nc_?7g5w%mNL~4civoibqRZ zpyiSHaIdGlT(#Aq>MVA1wlo_MM-Vp9D%BSQT(=ioG;ws(bEU{ygUsAXw7fV*t6pS=mp_-EmyOR0xH6tg#>;oGfZf{Viw#6F!=y@vTN`lf#)q8f%iJQIb}pKP1=C z>aK1*f-0>7^90bk3sJuj97gE5x8mYk{FUj0Y-g#Yi^lXo85CV$A2h3IWs>BfaJ4*te9$(m^l2hsAROzP>VL%-4+Pc|+cz6*MPIC_ z7rbx;Ttrv`p88Ek49d%iWD}iN&A>dP6M7>64?9Z4)wJ0}PcwnX0|mQ+%s#8t`~NQs zfV%$Wd})qLuIp*qScK(0@ElTN2kl=9T@J-l?{}EoU5$LHPVIcZ^SaEwCD%|6OFV%r z6!xiAmzQ%IW}QodSXxk+!tI&eAHKqgcFZ9UzD?-c=p7c3QjGlK#7&}!f>Drp?33eQ zjh8^h1=7`3y|3sAj@{qKEb8g$#r!?3df6n~sbRYO@xQA747oVdd99f_W1(9thj|*) zZU}UvEbx^S4Ci?l&y&rr&*Q*ZS$SUK;*d}NtmWn85C)@+5T~Bmt!{TqmX_<=4Q7DH zCg`m#329^3gWXQ#=I*8WO{&D(r!8&wn4!iYVACbH?iXt~zBim0I^lUfzc`-GeR>A? z_Lw;^6Fl1w{Cb(`G7dS7%nl}Vs%uY6CiigLKTQEJY0suUV|kzR0AJeh|JW)*x7V08 zAEftVlhxTRXWSEkDXX+N>4{Q;x|LY`V38IX)#)N03Cq|`SO5BD0KPEW)P|HAJ9JO& zhEZc~1vQq&^B0KeAcePHr{bC(_fkPXMK%?Cn8{DO6q|IE1zV$c*?!)z&3vX}^(BTu zko;xi;@Hh(r}d}$FO!67^rgyPdy3-X!D(DJK@uIVZXQclN+R7dt1y>wzkkoYoG5`Z zVYi!;I;T5nHa3l)hPfd+=I#*cm6Sp$APe=Rp6+kl02F#GB|baBGXk{10v6^0X?^L3 zx}u_K>DM!>2Ue2*ei2BZJnIyuILGleBzl!s1oAF87eTj{^DH$HLa7~UPWGoxOt92S zfNv6TMh#-!n8_FQ+*1CLgI6KuX4EkO(KkPPQIrfCn(OtvOKj}-r*#i)YcUlGw^eQ& zRWi3m>au=hQW5{mn zs8;~!g~Op6`&k(%exIjrN6C;kDfC}=Pt-J%$XWxq8W#4oAKvC@W}O^!A^YGeXu5?8 zael*LWB=X;nMDbM4;66V*!0;-6$TobJUUjVxDLW0)8UWkERwAK{Qt;^FI|j-Wb97z zFYYQVZC!a5jBH;O+3ed*%p#gm1sX$8)V}_$tn9tLT?*P?Xp#JqV5Zo=&_Zo0Hw+4b zqpy}KY%CZW)X%!r;i6oaxj(PWtM2gPESo+23S1N;m1|SToTHi(S69#Pvowd+xnB^p zgoxjWyUlkakdOhjIue}kkPIP(%LM;n>Kld-u)%Cd5Qaw7aO>%tbFEf8DDSmtcRV`C z32OH1_x+Li1IXYo0?`NRjPP#z0;ZVsBIg`k4mxp>K1O)vKd^_Gi;Uk)g#c-3vdqY@ z{$Ihj$bc-ZmOm)7EAzZT?$m{a?LLhv0s(&aUh#u)etGQYWw}*}G2_0`xMSg1jh64P zUX~YY%l|e^hRt@K&jW-RALJ_u;z!(W7c?`vsF#ZU*z(iCm4;KN0rLkw z4d}S&o?4PTMp@^;d@$-CDcG7`=jaDd5rXiKX?sDN5jpBIqVj^TfQt9MsJ5vGWEJTQ zs=R$=<&S;{$Q?&4;QDn6;bC`8a}QCXG#32%FnEJAWqRd$cbhtKzoFTCDiyE;Ih=h;QH2B-|JUMc%ktb|-(CIV@UE!n z)~_(l&YnJfG#K;(BPPI9_Plg*ty5*@g|0+`E{8hReq`D^T?AtcFc3IS=e+LGk3-~bKQOs_3;)v0>Y#YmB>fV6T>ryRl<&%F z4F>sBmgGmbKv_dwVJ?gLKAkPs?{7FSHyj^XvySY2vt$OQ>()JqIdP!`a+0b}kb_3{ zzNqPrxx-Brs@dH9+cf?yCs8x9J=A{yp_g4^$cbA}?nKm7_zpzdV(~*00jWEF(qNQr`y>3EU(WewJ&HJNL`N$MrR9yLtRgCRZ8h4OpPK* znUXH=H*^gn-#0r=)ibRz>xhculd{-K3pao;>*9!3E_BQEWTnjWOvkyKqOjyK2SL~> zmC>oo4L0>pFY?u?_N#j59gLk(R^M)ap(`{tI~ir}f?&|&Y6f61gj6ysnq#KuVGoq_ghtR(`aFh$BzYLI<5WEL>Y2K~42G)zG|MacC*5b7dUA}_8Y-&| z>o`ROaQ_Pf5a11J0c0PgQr;>-ki8ZC-xX$7Y41DN+wTrmIhKW9&Rnq1L!x7}|Gg{` z;38KZVo}?UK_Q$uoSaB`mUCwkn5Od`qD-=KpDx(fEH3Ub*kzu*YAzzq|2m$>lv*sK z1GkmsTzo4HWyRF4a*%r|A*KYlINqY6-Su3)sOpZ)-}uYG;dP3fiUfVoMe*ID&#wPA z(id#MZuUuGng+f8Ku!MzVT2U_Ji&ze#P!4v&GI z38DPPQdKQa8itGh{+&?6&Ei2S5KDfjVdDLgRX z`2EKZE#Y}3#{@_0?hwwa1D2bXrZ!(IU!i+ytJoouDdGeJ^C+UPt-}zaHst{)K{o3g zK%5L`XrU1p{`UDZcWeK+3a#I#%hehE1}>KvHo|;h4MwG<4D+YLkEV|&<2*N(Z)NKwSEfdTYKT(YJ#6A0fO&!H+72^(PpO zVzMs+M{%^d7CSy90_1(vkbUEoag_AXOSD{kH9Rl3q+`{#KZ>^|UgRzjO(fhdMJLgY zAnRRc^I?!S?DN2p%KbdjCI$8O=?7%mq^Rs+`F0hLHVDZbzyy#tYbQN0%tHqgDeot{ z=z;K`Yfg}Br?}&#^GRhojxI)QW_Da!G>{ZWZEm{`D)sxsV4GNQM2+fCQ>XH2d!GN& zrDV|T@31)JJK@EDceunG4^ItkK8Q-y=&L7b_XDJa z&2v1_vELGAvw^TkC^!zY0%AbSq`$xjm;{PbVlRa=UuQM|z>2&_l4^0is7u(%UA+Ua z1m}Q^><)1Xg0H-s};p)+)k2 zz=dB|l}U$hG3xvGxQCy@g@-EiO%gvr@&TvzkkM1X&3!HQ)nilmx6Jn&!LS>@AicCLYp zg-n)ytaEU#f6tf08!?owmO{zG-vI^YN#Dbudz73kHr$=&0_8AdT3S5C@&w~R&{mYR zW|AGOr19U-`%IOyxnvVmAYG+jZpduf6YBjXpFaQbe}lhS$hb_uk8$VMs*=SbCg^sG z4J7Z6``Q2nxEnQoi(C%)c!MMTl7N@4Y)x%iqACWW*eQ=+cVekvgKQp9LAgddB1K?t zLm^yPO$eMSd3eoVP;5k+`dSwNd?m(97oJ@ZGxX z;DaC`r{x%7@OSm2i~<7=A`%{y5~;%)Br#tWksV|tbyf3!y0f#hv~TX;3@aTE@bDNS zvp8FX@W{B)H_j7{;$6d>RRbbF1I5&!A(54aCi*rn3BNbS&d2`X&h<18W8osmc>Dr} zp3FtTMZ4-QLV}4yANJW^%5o}*8Yq#8s=O#humY!>r5dtPsF;HI3N!b+)8dGVfh>q0 zq10A%M{t~_z*<9wi4QX^oI1=cx?8EZP=O17%CzIW@i4onw$=#V-l1$&U~g_4$rc+2 z#q)jfqjt=0xmB`pwtu2t>l^@50(}b_E?`U?w-R~L-Cm&l6v{x9Qhl)5?Kt>uoU{?< zkVc#L%kHCid0QT!Xpk9!{FdzulhiO=>CCV5qw%Xz;mDiha$!lGBXb*+y zixJnmhma0u8k(x`MB3wr@_XP!?pY#LgKKt9yQ9x%*KUeykH_nDlFzW z^pDOmNUCp5g7fVNG)#)@S}y{;4`XgZM!Awka{j z{z1(^TcG%blWiB63$LuD9s5zGg+q95s*Ksfp{%JP>Vp;U{0K>npsKW&= zJ1|2RM{!}dm9a~>d@CDd~ID+TpyfYRc@XfNxelu^9a-p{EDXp_A zbfR;8K3HLjecnhEaqndQQg-36n!-zg!+Bj6n6EvjI`Nz2UGXGRx3?KR6I^dO5m!Rp zo?@VcQ~!-)*rqN9;4L}h>T#F8|3y182WF0JKW04w0Y`|TST>Pav37~*XVr1&WSq0J3&NJ$a3I*X?(|E)O8XS-xMW zL{6Z!OE>#o-fYR({c8^PAo%2j*h@S1^+fe%D;Oj49gU}njv)ssnVni~Prx+#5W@!> zdqf##s#r0H=~ALjnRaaMPumm$7EWZDi=U5vxz}}nq2>AtTDD7){lrWEO|bN!AOvJ~ zIRb0`hCmq~)`fD5v-XHy<6JIBHwGDki;Z`45QNH;+P>rn=y88Z8Z0$mpxapX^tfxA zg3`y7Lsj|~!d&F-Vn}^L(&>2Ffw3mgXR5o=0bwdGBFMDR>`pIlfsqne97BaZ8+hVNsSL`Q!*iqBs|Fb(CDP949@oS zNF}+o8wxq>^9rOQ-QQevl&IC9;(4NirtBoY_3RL7SLoO$vxb@D9v{fz4Ks?ZfiRh7cU=>w~QtS?0OLST3K-`Y>M+ z=Wmsen(m!L({JjUo=Ir|RX&8Xx++)n@$u#2tq>wge>dCkbxGq5Jm&ZPW&9E<-v;zp zMy|kf-2t`*&7=zY#H6v+_Pe^d4RMyJs}-vpyTJ7YiR>O;x6O2A%D;sfGP4tkkcHF9oTm^uYRNmKZ1M5PC`z9RM zoG2(V6dyi~Sj4EYL>(>^-6ju6^@HW01iDDKy{DuIfK7l{C^Qx_d8=^q+3kR5$6*Ne^RTv?zC#9vgTp%Xj%4b+Dw*d!>neX5~MXyo&|}E&x0NF>_**X<|k= zvI|w~pYR19U57EFOO#|)qG^wCX=Pk!VeCn+v6g7^pIi=QZ%6Yaf5Fb#9JeHH#TY?E z4bpP2x>i{h87-s$*|_2>j^V6fp>T_OUj^r@sh1yAF3e4qmudr?H|9^o9ct`~iSe(uN>26RSUAqbjEtkt61VUZZp6IFIHpY*VWelRZUpElaIl z`h4uUso|w5K(O!A55ug26B5Tj5bjTmo>ns~rDZx3$~pwn z=S%+wK_9zrkn@uLL+C*diU_sp*Ni5+2AtX)dN59L=S+f!W&dOx2u2?J5_%F!{vlr4 zpSk@B;`I5vz;{f0A7RGwHzx*OQ(;J0N1jaBRpAe035wh8j#{B;(RrRp#*ACTk!LIS zXt$s?VN|xN>lf=^CIVcy#*t2{nZutr3u19{cp>TUk( zb{+1B9w%~K1F4D7VN#OSEch^ak=DrzB+TP5-bVDzG(DwsAN2xgryvu=N{4 zTLysmn_b~swCK>oT8m4;5@(&Di_NHz&Y{HylxrqRAqJjMzGeSE&4ZT1YyuELOb5dY z4w6C5%wXE_Y;j2-z;PhSg6su(=KC}?2mHkHNxEEPd*v2>kw4uS*3|LrF~*dkBZiXm z4jBV34I%)PT~XFbo1^UOHJm_Owyg61-wX)l(A%3Lc5wHGc5jL<2lCx%tbL$1u)y&KTJC zW@AI~U~+fPd}3lWQlsoYzoM1mBgFPh@T^1W!xZd4(*tGCF`;l!U29n=H*#N`Nksli z_Oi9LhG6I2ohWmR70^~!SZsX4y4q(AP;D4l_7{>8k?ppA5_zpA8Lh$lM(YG&fXhQ6 zMc+@I$oZVLsO-$<8ZE7~DwfcxAvACh(U0TdWk)3QcLhMg@jIk{Ki*%)AwVaaKMtpH z{~+qpT1;)lya=7$azrk$9UE06tSndqMfJhw9@Q44jYY0#@V6=zl^VNpVF>a zoN6(v8ltkr;kRe&VDevszQ*=EH0suKuQWw9@}V3Izuo@Tx59%M*i% z5swDrxbtjWi(=Ya*S)g_Kq@d!m(6m^wj)5Jj{pV?MHO{yF_8PNpBV6I6FF|Qpx!L4 zvrX(2WR^9?XBCl+NTjYyL{J9Tk1e%;j`JO1fs;q)W$78_R)Lr(|8)G+p`CUiNk9sV zM;eQxafp355J3deeurboexJ=5%Xz=GY7{p2caA>wRd<{^!m$2L;k6fkkRbo}vjAIb zk7J9sRMrvucf+6*>gm&*x-vIJ`By<8hfw>)@h+$BvA(FVP#61G0oje5_;8X5 zSwTYup09>A%4YZX{*&F>L2^!y4XNFf@m&5I`-bJfQkMoYnVYEFunl+l2SO2)Z4VU}nm-S2kjXU8} z-N|&p2PR@c$PO%xjFAA8;e055w5fNG6qQB0x=xe(*H!e}hhop%#ui@(KV-2^x9?(P6!V?n+xdbH=7syB6#$3~aD!3O4(5IJKpb36T^{G9;?Iter zb~Uq34cI3xw&=yZsmA)s1=L}HeH|L__)P#PMzIzMSZ`VXV?(gL4uzf0<@{{Pz}Lk| z*3JZ6C(2z-3Qsx=79Z?gTbLe>Xu1FMBVLdglzeHyk2*iEIWu-V!vuw7n2T`6ZlV$d z>cI^K&~Ue)0Hwun>x44Z7hKuIl$A)PU_Bu$Q_+uG<&Qq402QOx9fD5q9mxipVhYT{ zwFLs@r`QyUYodk0P2ZdGvlztaI=E)^Nsl+B7UBBlv`vTAd%AMnY`=S5c)!}(JLkEN zN{4_%$fr&bB5BhSwHCPg#!F}16aznMm!;U+y$(`iT(ce|FQs@QVh4j zt`;*dcS^3mT<&GPM6dvFnJyESKxwr^`CBq0&hRPj=R>lnW0cQm9RCd1TiwqEPEJlZ zK^IH3>ARnXBP8?N^P)Ip_pJL|(U8=BsHv)&;`!K^(^OL@K{8b(- zzO|CGftq4J430k{li2Qbhw{5x3Q=yxdj2$s2Fi|lV2%7KK6?dPO$yki^iK>b<%gVi$e+XuyBBLM}f=C zmI~)UBm(KeBF!u*738BtS5mXe2bv>$1csu*HuZd?YKswg($|my5)fQhj6qdQERx9gcSp&?3!#FpHn#Q zNKvOq_dih@9b>P3Jo){goAj?fbZ=W>n}?y6liBO=Lm~gB;Uw|osc6yudBAMNO)mZQ z6I_2DUDYiLzpQWjRQl5Z|NHNBftKT@49kT)jZdF{!7g)njFn(1tRDOAgyGdmBYzq-BaU*@==-V!1o9Wf#UF+%b?QQ${Az5lb-*|fh9&mlI0giE%m zp4afSqmGn4SfeDwIBWbGeL#`)jozXuE2}3k5n&TVx$?h@eYL3FHr|PW+E0W6Zw#?4 z7{NN{&s|yc>J3(t!toPn$=^l>%Zb!0m=qG}mGg8ti;&`KBT~=vD=}*OX)_}KDk!z~ z!jPH>zyZT-DQg`g;chm{{IpK3L)X%ba;&Q2G?VbgRJS=>_qnybF+o7 zh32;})57Py6z^=jVEnItUAv*+-~b8VS77CZx;gU&Gy-CCI-XC67j9O)Ah=BPBYEu) ze)<>S=aU+Z~A}Gy+l;He+Ycy&r*%yJA^4 z@&RKaoTS)Pu2=8xDo0SU^v}QHQ1D$*|4qAYUPv7U=fH$d;rRKXP;YO!0$L~OK~clw z`W~Iv0)Z%GyxWaF3dr<~psEjk65?`KEDQ>|Cc4tAOAV-@gIM+a=PFat?+ii|=A_Fdb?I?dYizpWFO(EiqH4WS>{jV0| zqFf)D!+Fex;iUwrrGehd&89f^>#gJ8`NJnvjul$1p?*f;puElv?+#O3{d3zfz(#T^ z?(>3Ks{H0I8^R*%m0!r4piRG@=Q1ig%O`5MiQ?DF6s{|mD`Lm+TEn{4a=qb0VN3El zd+gs6J%zxJQ1v`lEYl zFf_Ux0#n>Wu&%IJ?=^l}pDvuQ4W$K6(_k$VYjLj`<+Zq2I%l*%jDPUR4MxGICUjOW zI)c>n8y1H*A&6Ot<=LNLo-Wp3n!`ga!oELh_VwZ@W(frPUjfd{avQpj+4_hw`9{B@l0jw3e z8;0<~+tUBCuh3BNnfP3BoBI9ahyVM)3^4{Gb~KgSs#-`!L6I>J$UzyRGs<%O_COjU zkUo0$c~j4KZzo7X;ay=4x6P9B|NN^LCiByq{9RDO4g_SQS zJ)M}LuSh|+3VknprXlK!zYdyo?4ETuwQ4=R3>g_&J4u&2`Qe~1Bd=9Wbp91sIh`vR zBE!9$z9mxkQUx)yZTx~OsOD8-ZGRMc+uoKw?kCX3_MqpqrEr~zTMj&IMC(Vd#$|>d z-YHr`#`k{X>zql!nTqv%K~syoy&Q@i25KQpn3JP{UGNyyc_kFl8eOL)2^_g?sg|t( z>wm^-^9`QxGwA}t_^~980jJCvP1Cm3mAUWl1q=yntWi=bP<}H7PFz+CuHS!@dJLKE z|1CSOxe)$W0#AlGrI^>4R98Q+dH<<~fy76f3KT=ICMsI~6r3xKl09_C0>;2j9a}X7 zQtUP7c1wClzvM;!t2@S4M6nj6c7@l%$+b08fXd3iA>^cPpG-q_`#&^YbyU;u+up#@ zAyU#vgOr3cjP7nJ5s*@Hbd8b*X$67NDcv2?0;9WYgmmY-@9&)VpPikvvwxm__T2Y< z-B+Lp=MV#$?*b9-;ucEJRlR6&k2_alwLY`{`+En(Q1^jdCpBP4SPMay?aTVAVi}3I z^*{AT22;`!^=5iXK*D{)J+*(%y@UViA1~CTy3O4P645ThR(xdZ=f4hIBeYvYP1WGgkQh|#?6$BT{_Aq~{ zSrs)1NLExV{>guWsYU7%BT!Uz45_X3dy#{ocBei}Mxu67JcWbJYy>}*pD1U}>HQp_ z^6t^RK*jxdx!*3%laiVq&914C4MDIMiUoe2X=s;CEL7Q2k~gu@7sZx-smidLXQNsV>OhYMxyq>DUEEKkOwu=?5;7Cd%}Kfgh7$# z=@==?%M19xdXLRYt1HHDAQ@cwJxftpQtE)_dT|_s0160bOmn_&lHvFF)^WZ%`R*2Fb&r!iR&Clv%^dr=mnVUroD0 z@Rnp*aCc?pZAAel#GE)+{v4+%=+zxuYXAN%UktrHc#U&;&u890sEv=T$*O$UheA^Z z`s#ZszXE&0j;ptlUxn@mV|2a*3;Z6(n$To<8SeCEVnyu!N5%18Lk4ACRQv=5A#-fD zqu+Ttlf60n$(KVU1W8*@-a< z1-#vi*+^^fX`@>1#vTHw!^dTwW;}Kn$@@IRy2X*>3Q>l~iZNT9ETiOJqk6T?ke3LM zN`zWwr*+Lb&sIh_d3R_|+y#H#D z_d;9W_>`HRXK;(|$bcw>uy0*alZ^ap4ATVIh>#Qi8yg#z;UsGYVOhN#Rj7y>2rZLY zl!$z=;W1A3FjEZO=JAdrX;^WWUbj=hs0Ib~&sGHCURhJk_;vWUt)%um#%&tY=cokz zKBFF`Z`<3A8tR>;eq%>%W#@X}*$EdkfkfB~Siq*^a|(8}Q+xQ|>~IY$3;-QDXRZc= z%Am}*Ov5L3u`7hsW&@sXw1yCdU>rsf8hkuQ$}Arih& zb@`=kWI6p&C+v&KN4l0rq@3v22y3`-e3?2uY^UK13lR9Fp>Rw({x>A zuB*jdACc-CWe(Lk$h;Me^=~l}w7>Djqk_I?vC0WMg6cwXpTM&@g%edCavP!okvATT zdBfIAoW$_QE;voAe{+{^6Xib~cK0s$AhN4c+I(?eW zLK66o2 zZ^0L1XL-f1dX0H@zy5T_gbho@2{GL!enG>gOZ$#4X#3QS%{38AB?8AC@NA(S;(Gb8 z1YFVG)(lb?-TGx?IleqO2<5EBAus#EvTQePot{TLLJ{*aBflRnD|Mo3+WC_FyhcaP z4)-AtE}i}Bxle?~-$3|#V})c46e%+%=L{NCQ0822Vk ze^Gt`0WC)l=3qPVx4pDh=FYewVNnhNzeDKKm<=RS|G5cLT7g&VTm`-^HO2!?7RD5( z`lx9>#y(J|iF%><{i}EiaQKS@2b@&e1-Xwf%X4Csyh9hk_q~7&|U5V&GEzoZQBa=huJRk|wSBPqeRZ{g`&|qryzU z5-GNODNp$BQ#%2N7OIL$597P}O()X3iguoAPa?$DRR%q{yix~UsT{Q?#2-GwyL}iW z?Nr(tuL}Ue@4fOA8x{!%qShfZDHa?s3X|S2KYox_#}U~eHmD>6wR%y zl0J|8=-!7_D};Qdx$q&v!DducaLcMqNZo19zVC0HZ}X7&x={PG-eI{b^kcOr1-{?h zuD95iKbL_~tMa^`)e2){^(K2+#`YO>n~GAS?s`k(e>Q`uotd>0Wa@&@=r^aWfgGgq z0$4ZF*TlZ@9gw%O=us+X{sL0Srp&}^-pVawa1;dWxK1!A`+N0oCQ<|Sof4THs5oP( z`f^XI=jL_esn2c09$F7kr~#moMq)^O~Cy8{KjNy!+ETL*cBEnL7t#&B63`jG-G>wHJKnfp~O}62dO3iT;PjmaI=p$ zF6`d(U6+(O>K#$@>9>QTs^ZvJer+ya@oKo$uqeRt`K;V5uObL?`eI`pK0FTDUtCP= z&ZVO@nE(iC_iPpbVafx0-=S7bd4}|{FAzw_by(5UKRmELeT_#NRzB2^VdW+xRvV&* z1~<>vFfnledh=0!_CXzqGWbCGi6s+@*SY;5OQ%RN(;;a;(>f}#>+Vcx z3 zj&x!NCRo9o_yrk=4XKx?2=eUnEb;X}(_9Oi*gUWvU%P4L3V2{JdU1uoAaoR}0yDu% z8X+wzVe8iFwVhBM-Ms!sT9n?Dp&5tF!k?dL00{6SF z;fDsKtNA?N;RoDE&(hMUUjK6l5x)^S8ISX??Us*N?8$~(GkP(b(=k;fx@dy+sl4C8 zuwPVVCjc#-#(vBVHK1DNNfAO1vOfxTYZ8;wav9yRyIo(ogn3**lJqkhhBUDG_;n|R zc1QCI3cO=~B`OXO%NE8W=iu5UesN@EjF`R{9*rt})hn=kNbGAH+yPQr^`{U(%SbllNL6V4jlr{Tu{vBZI?c37gw%<`5yYc-b6L*)617Ve= z+{sxiR`SYXh-hS#^WEcw24?=QJSVLdRM>P)d_tw?(ZUeMtX@~Ai-RzTmJS4o|2s}l=sY2Q~i1v>Ipo^}agiFl-Zi_Xf5sXBN zqWemMV&O9-mDSw)lnm^z;C`9u@IDlXHauH504rxr_+2qEoPP+|rzoYEbEjY!E%dpO zP5k;0OUWvF7?X`(%zs6g7qlK+x~3rf-0E7yPV(6sMKh)316YXLF=C9i+GB1P%SNHB z^mo_G?3yp{049(~)>OBH8KWfZ4_U-OZwByWfqH>``RyxI?->?;(E?hfz~xxMm?v>) zg4>>zp`qr8;@rxLxWk;&^CPy+!BqxY^dB>s)-_3)pIb0PI=r}g)B@6?~=GtW$-yvyiVGho!XmGc7Tin33hBs2^q#bU<>9wCn z$dwrWFeau$cU}Kx+e;c~Yjc>moc8KyYj^4XDI%|f&hyb$3Hs%JbGd88NxIOPPC9?* zdK5wgPu%0v=6uq)8HFs|>mwghg^xUr9zehEo9_djS``A+5j)ii7k4_%SwllPJAvFw zg0DjGz_W@Ds_tRsug!38U%xfS35y*Zjjyem-Y%Chr3t083URnPL4dVhi5ov~rzweC z?iH0pjOQs5+FX^9ZJp-amP2B$?Y-LLvp`8Dtf$hmM;9MDwYcL&0aVyn04mk^WNCDm zt6P$$G)%H*$~F`d>HLnT?nKb*cI=1;Dn2X&ekoMW=tEsuk+g<}x@24hG zLE+0^#7m4gXOs;G)3$QLhH9S{8?kR_E~i|?D1U_3!HinoOYM+U!-Fskqw z6#!xlrkyRsE+-2Q()gVJZ0r5^Agr(@>;r!N_)s#JrhRGSgwjh|TiX%Mq*QstVa<*c z{hpKHK&aflYlSz2ig}rgL_n^Al@$Bt_pgM#a4Q9W`+jpeB=VSTe8f&9W#&dPeG z!W^0(=Aa*;-SmU+K^Gd8(Qj`72&9_QVhH3Df}((58esRW`wb294vcqbJW`&5Yp6#E zMmK%ARs?tx2v-06@z8D~fa((jhSIIOpyefVwW~yta1_kW{w{Sd;ctr z(x0z0g_$$T%J#$%uX(bhYK?kU)(q`R-Z$XLBam7XK95lxG|1NLsi`uSX8wyzP#z=H zL4KQx3@oDjTL+#ncJzO%#BSI>J zYhxM8krE-iCuX0zf1QZpO-tECpM~E{6@?}ek37{r0{R^FhduOwt#j{=;4n6lC?a69 zca6=2f~Qh3(R3=|O`RlkGAf+|s3O8gG`D6@sqgJIZHJ~^-?=tmB0N)c`szu{dQ>Hi z#|AOp#alrv10(PYf& zKjwKfQDzUm13dN}R1|#s_CbkpeCzc`yXLhd&k9S`y#^Fv67&L{XbIu+^6cygVUat7 z$FmdZ0EXHhn`%lzizO%ONPl8&ZXh}ZL%;rac^JS$qG+8E%(h8(aOY6TUj_*+;)z5Hq z0mP9Y?2P2rP>44r4Zn+C z?0?=04j{w}dw%yb8l8hG|dz@=t4=7XAe1(^^B#)h@B*C!MCss7=8F*LGbCRAlw&?jRA^*=#Z&*D}> zj9-+^I59;?c5(P2%!M@;-YY`7Bv^kE2pG>B+(aPHGJj_WP02O!fZeMx?bJ!cTqj3~ z*80OQGO;$!=s;w9RK!xT8G3lioSEIL&S|bOW~up?Awuhr1fWtRIJNwp%_9=Lz@U5U zyUHZRrFufu!zWY{hv5di{TQ2;ez4c=wX5N(On*C{Xq=`hNJ_#W`;%EeE4h_n((AhS zN#y-wH~)(*e$m!2-0_(*LuC>7!zy7Rpp%#WUT_N?L$nN%)Bh11CSsj-xvr?^nhjHB z^S81NgF^X%Okj9ZjD%a^P*-?W0OvC9zR>2J!Wn%Q5k{Ef@!sIWNN$|?f{zX=qP^JW z1@iIzhIv{g@d!_Sq&`-!nTIgw#lDBUj|uGAv)qYPm%iH%ww>fIdVT4{B_FeK+qI_U zMB^1h%&9}OR<7SspQ2hNEc~(#6NdV?E*GZ=PlFPvUBDx~u(7fU6v0A<+Y)vvH<`!4 z>*zF**6m>^!h#SPM1lqqFDLU*s|LPgQX{tjdNXlQiq{{_NFSYCR+95O5yxwARR+`#=c(t+b`{7y!h+EHJmPeu?>bjlltO`-Q%m+W@@Cjrbd9 zzJPN>0D{OYad5=oAYxQ6DYH@G83e+p1rdMwrTTp}VM!rHkNlnz!W5E6ku21hE;bXI zHkNMDJbEYqNHoRH3}QUjW+-Wp&wa@zB?D!^+%>QhRWkhOFz+;CIc-$2&;UEW*aN=+Dkv+i9X4*j(S0h_2qSd#AzrTCf-s4KM5q!LuG%AI}8X_7O|x z#0ww{_3Zu=59x86g;$!ZCJpEC8}D#~8%nOJR!$~9k1(XFx^a-;IFyZ;GK$+3Ic}^J zC}(-aB58q|3vJg>3{pRvpDD}%;69LU0v2^}1Uv)Vc<+-3j`lW{#6}Va9?i;MsOhT4 zFsmsMiI7zk7NRv*^ET)G1~=Z%n~Yx#1DZgDacjzmYsD0mRV++F8wH z{$aw}UeFcfoKrB)mX!U40pe%oJ7~FRQ!$g^p|IOwnJ|`o4Qb1cWRAyS+1-Zo-$yCo z)E176E5Ao1)qzmL>YBfZzzOK5(ZlHYbb`+LWFVg2(z}_jc^Lyk!O7Z7E)lqt>qn(a z_W0mnvS6mOq5YMJgZSs0Pr`j%kL+)VWfFr5Q#o_X%f(9xLP|b1ei7A&eY>+mrXFAy zm!om)BpA;ZLOJo9viaB>#G6ujrl}HM)QCyHc%4JgcxuHl)QgE|^fzr)xz4HD{2(Yr z^DZZpm4+E+gq=2nR1lPz#C<}hl&HOVDP^uBK}y-Bs3A$E*RC#l${==m;o^Nh;`evg z!UJmg&Qyv3V;RB+6^HW)8bZt2QZ;kGy@Sop=<>qsT?u#nw5Xa8d1z$lDG1uE?^lN2V!6 zeu5Tc?l6zGii`ylID1bfOD)AgOAtYNzPL^sLoW2Ir8l?NIG{ECt(3Xp+gL`Fi3da1 zpnTr~T=IH66ZhAzn%byfHE1hN^Ma-0xfFZfC@ON}>B9(EXh0B3e368lR3_W5^a0}2 z=M4N-BJeHiYYgXF3@6gJE0i2wcC2EzeGy(-)TaHET*Unas<)deBWiOEYa{g(CW4aNNlWLhT?z088haa(^+u|H=>;s; zi0A{Lo0$r?Wz)IHo?EXznS1u#ZUkX1(pRb1h0}E71;H$R;A@PgLWi8N3`{9lv|+N#bDRXEy~|Tqs$S+G&HzPAPJNzzkg?_xCq%&u{UC{ ze3a(4pF#45+;P%9+}tAkO?GQ$2tRhYx8p6I{=D7KBj*tA^Tc3$72zwKZnArN^W0XP zzp-xQ;Cy>-5yCk8>%agVFRKM<(y@Qng6G#qgX7OgiKm7iDrMRTkTSvplfrAKxzsZF zJV{duiL|we*nIF?+1-gBL#{Ih9%nmuh>x6QS4oc@B)AfXA56GkH#SyRR|_L|@Dprb z?`(%;>TLmj2wKA_E#LY95V{fq)38tYyu6&+`*wS}*16}iVqo#g>(E%b-Nna3OEg-v(W3sb<1nq80y71c&_jQ^oex=Nl-xbHu53W=9H>X zYy*@Qw#p#QY#^t-q^^n1eC-;{YMJVwn@i~(n};x*$6Xz_cbA(m<6qENpC3y3i}!bT zB)T&*4+qO05_In0j}98;Izbnk=D>Y9;I zJ@HrkEb|VA&n7CurxnU9n1s8%olJxygJ{|{&BJy4vayn_m6>5pJ3HnhCPdDk6Uy0m zVqEh3cYghh^n+ja_nQoW=+DpZjEsQepN6FA1w^WOtRCdHyRitfvZe)KTzH3$`O~HP z+Ns&lMlGTU!;{NyZcS}zV${1orxrI|W0vDMJvXg2`hk17h8qvof#uRZztdcHQPy5? z#BNAS>UGgh7Z=j*uE^(Rz8AncSoPp_q)XS0OKf0xfm#Nb zwBy(~XiU7QB!_8*DRuqJZ69`A1hj5JcbdgpLU$R(uf3=^Byw+$AnTXk{mLgme^8m- zTh>Fi%H4-h(ou^A*~qwr4eYIR4K|Ji$o7$WLIF{3;@DVjovGm8PSB$o&8`g-C44=ICV0}wZ!%fYY4taWi;o~JkKJz8P zNSVBd8oPzwvSGDfY;hHuDY%*SG|eS0f*)#1@I!m#7;wM=2fy`@c=+_xJfj;;J`}Ij z!KN&)V#!HN^|e6S<;uKDkO!72l%>Io6uc|jNe|LN4HWV(fPh)o_B(*z8r{*NY@!qP za7ahl1KdGvwJ!Ys=4Xd2?D*Z*+G3lfQ!WmCNq4))X|OO=wrIbAukXcl26nwx3|g=` zvS%j(!Va>vbbTeFH->hm8Cgr9qkbR6s8_yz^|ru9qUOoRZ*f|Fxe*=;9G_O>0$Kz2 z_wDAj1d^4w;nuF-zvVdLMzRcQR~paOa!!F{fmD4)fUC?=hXEtAir?k;W3>$@{brB* zE5Y&-dPgFww#X48ppbxk>-fL4mCkk($Mz2J?Qtxn&_lNh)26iL3eB%0JBdi>85Y(yoczjNXO4y6w>V$fe3*~auW zG5#9&Bt1{7ziyIgu17O{`u*EKgkpSy@$mI`4OCc1>pt;5BI%qQ1AaikhTtks#h@DG z1qgrmmy9CZLP=s7Mz?BW%w&p%P}7+0urLQ`e8d6zS4AqF-AX|!>oPL^?Sz&)*4{*3 z7g~9szWszI1EkdrMR?$!>Cs#-hVHz4*@vN${yu)iV_fJ382u#*oEXZ%x!|-*Vto`2 zR|c9Kb3Mtp=p;-2kbnKwW@7gDV&_yQim=hE8Yv~VfG}M90wi-_VyalXab5tj2Y@)) zQ;IqTrZ31JaQZRVMLxYpajZ1X zPsB9o@d|}V7q7BI=_&(0B&gPFG~-E`W>;&Z>~cn!NQEDlqSu4niY%#mZPnja<{E$A z-A~F%ZkR7HCMvtS)V9(o<;utA;rp+lDD`bl^!95q+3Y3Z3PidlgfAoha>#}N8qWH# z5NmK^_^A*;81MK6B&AV^g|uMzT*mEk8wU{%Z+e-}ASHh?=A!oHaQ;9#!37oA%&C-* zX$3MrN+7~ZKfkVa6a}=k=A`Mh-(W32oSRJ;p)auf>=wL>1em;n@&MJ|Z|AHsuj1Ev z1{SEM|AFE;>%QGI(!+FFR4k=ZGjqIrk;`+w}L$VzoZ?uI-i1T zz0Th+wApi||LS61Ry+s5w}mygZ13_AVV4(QiV?pnn2u7DM-XOoGK)TTgJ}(2H7eR@fhL z%D)TuC2HXo-L0Gru`Sfv5^|W_QM!3tzSD($?a>KE@prvItRISqyI(jdT`2R@IJQy6 z3sI|W?Qq&Mh2GkU* zT#ed9eirjd?c{`qWxKe_Rt*%a7(ewUX|!Gf>B znTQ-y#_9o71j1~gWR+C7jAbv1QQ^P)NIygQ>}D)Q04BvGm$>^!NBM0&cuw>LM3v^g zL`fWErG=fKPesm9CaN{u1=$t5grnEGH`u4{(yz({9Up$G@p@$L|BH|y#gltFHn|qN z8N&448oiNjf%*p(cIxW;d4GA6{;a00-BXw_=xHVEB_uEO%Q6Uy>2)PI)vX(pqi<#+ zJ)BZrdna8T(4d*9kf+M$ar7k(b%()CfIYiQvQMv)sQTi-ahL_fZM%JRGLxTE~ z&Y#AH3ZGP%bz2Jy@hfCRG34mQg^IB0pKKcHY*KwV-k;P|xsyA`<#hy#?ukOb58$pO zRd2E);9Lax%S0uIeOy@)6vmpgm=t67WHSik0zuH^)B}N!-Pk*k`f=IDP8?VW-xxf+ z416010sz^iE4(&HDA#%y=>=GbcBPX`^e?Il&ae9VbwAOe6lRdG1wP+@t(qmC!KD7P zlfWln2@ch0*;0Xj1T34vBo{0FBt2MxDAZ7je4Kh71F8+N}MaCUGSG~?JL^kC=9uZ68WtRChxi7xI3 zFcI@oGkQ&6=T8ZK`2@{DnVDH~d*qV)_ceXkGLg;U6NUi2?x#;(AG2B z&X=0L8`E%`W6YoY*{)K4;>n=(^w@ILym~<(iiy8O_CU-D%gRfC?kI0>E*2ns9*(S@ zGrRH46jlo&sV2e+W%tnn-0==)Zp)E`eaJV$k>Ln0`bZpwC#x~6lE#<$SuIN`IeB|( ze8rB8-u33E6Ejj?~wi6zUfixuzZlD zw9(vJR@T)B&H60iRf8&INZITk_f!mx#b_gf8;;trxpzGe`w^T><*~d~ed(2cU$jX# zsOQDCYE3A4k6RcE!o|FiT9J2btqQGoT#e1kXEc`qyy@gjhS~U^W-D`LkLSuOZQ9_o z8BW@OZ8EU?NK=Szj%0Y|7irWvOMZX7dkT2IK7OB-*MAuOOil_{-ymvyx;vmqe9SPb z2=8?W@BO4(w)i<}4o6o<{~i7lA~zr}hN2-Y+*pUDRrMRbo4EWXe==k*OhU$n6m8x@ z_-7J{V{E;Lw<2ob6d3aD?Dv^a{F$v*5{*_|m{k;#7YAa+La<4`Xuyxhv5ZoPjHMC_ zO3b-6j(lrys(h2F%+EsqjW}DxF_=?jRHg_eaT+Ysg;kzZFcF{Y6#$Kjw6miS;_0|w z0Z|s`rZOe?+jg;Jp#=6Q@uAu$nIFDVd3r{z<$Lr^Vj-w@)S2R_;Po+qtb5I)q%iKG7+SOq2wK6eL z#aPqR*Oy-QYnvJ$?@g(6q_WAU6hM1<2i*e(k%qC_$-sGg*f2Jj>UMSop6C1< z7&wSN>N$Y-S3lIROO>HVW+&*#ElBCqY8DUFA$782`I84vK`5X=22mod50;nH+=70i z;~gBEP|~!w{>+cddZeJM)MT?Bukrqmi_QyN8@e{PgZD@ZWuaz^0yB$dJB(bhNT^m& zbazQeYk8lM4O@OLA|5FAb0s~xFhE~d-}Rs(z;CQP@!hv05283Ed+B&Q`eq|JD{~M3 zoBz8{f5M|+%JLykH#y9<%XhexLXyk0qd`)vTQy`yw7edpD)sM2b|(%i*1yEAZ&^nT zKT z|C2k^bQZ3VzA`6=|L{bR!gY1U6dh~EW|IL4p}x0N2QkBfU4HUd1tk;pQYG^E_k^ZT z1iO^;w5ikPh|##?fmhCg0Pj^If+( zk7wVNRxj(zi_3AOZIiUm71f#yOJYfxSPBMa{88CFFJh_2TC-C6mwt$23&|*#dI`KIg>E=vac)={3H!5)Ks05sQKr*{UhfWFzl#| zC^QwDX$%ZKiiTGSC!;j$@JAL#ZS$=uC?VJWzhI@1==>cPo8;p4?|$98@A>NCDI<;( z^l=!%I<88d@Uhw*L$^vMrYp3t1DMxwmz~!&sOkn$yB_G3w%FBu#UFTbe2*+ z>D^=C@v8qlRr*Sg{NSSk|A; z6xZG%r^$LOhfJGE(?gwtaZ{{JajY_S-rw+-{h*s+@;C3zX@UG&joxgRcos8JFcEwl z51&$aiDVTIuDgu_=GvP4o1JTHtjno}oGDqB6&Z!-J=igBgLLNYwlF0HM#-SC!+KHD8|&d3@3zVG&_Pm*NMzri!esv4CzS| zMNAN%#6SG;e52H#_1&Y~wC&p-Y3#%!cQT=wJDCJ#=kDL1E4&Vejq<*M0}aPWH&3zS zQ;RMCHf)5nHJ-8OdML;J)!|c|Nz1h_+NCs0f_a$irdMo$`cIsHw?yRp)uF<|c$#eE z!=~I3kRcrmlJqa@`$=Zo3Zn$sMw;cpadoANQ6o)xgrZ9%=G1aat2#g`TzDfUxupY$ z;pBviuE@9@XMW>H{1%7hk7s$dsk4w-jO8U1uGfnbD_MAsq`SwzFtuY(vM1kX=?XI? za%pH=@P3_d4kmeWe#hZ+1=>d-sH&mm$vNJe0-0nkury;vV2%fllwgMR!&;50qERr0M zKdM$WW~GECzPR?GDTA8LuypUgb@sbl`R}XP9VCEeK9YJ;vfCCW^Na>_S||O=nO{&| zyV)E%d^U=jiK*=7lGv+5zbF!krX&(B|HuWAd(ZXp89xK`#)KyZQj$Hl4?;kPvtQfG zB;>}lQelfZseT#>VZi1_SrXLx6?AI{nd7P*+Q`IC1NM-#NvsJd&2N0MU$p;hj&m*# z1mGzgLDL3*=f%N@w#;|A{i3=iizol4OU)p*DQ|*kW?IQV?Yhcksi~^=fT*a#+U2*J z{sfzFQyAqJi;`qZJPyd){QVK1G*(btSQzzKB>iS?Zy|pc3xPFtr*RG=2RC$Sb-O)CCx)#Lk2c^%NiDi{@bhj>TNf(X{4@9_e}lSFpQyp@^X>OFNq zsXO9P61toS&+ywCiG3mV_T{vm-t72_nB#b2)VRzYtKIQFRRT2DSp!MK!VB;LL4LR< zdp9BcTsWIuvi@Ox+&xwTwn3_7@X(GWL&~vHiMZ~ss9{KcfwZ3=rr}L^@$b=fdO6W? zgwOT$@4bqvs^)Ngbx_%%&D@eS?}dhI7zpt-V|mGl5Gd4O zNkK;-Y^lUjfsD6-;w59#LH6(%OgRUXc{J>~Gzs$$e#{d^i%yWorz-JfT&JwsG=B(m zj|VI%6BFxBO)krGwKpa#EQ&O>5X1{;>l=C8|8UNI{yJTvTR#qe>El0oG3gBS!x)7s zCNkC4(%3zF`p7S)w#m36O=DVTO?)_7R@&+UxFirPI~d>AMp<@DiUS(%7N1bW+6kYpo`d8YEI$tKFm=JD(KTTl1>Z8_jEQTbNKcz8V7cB4WpRM4 z=NTyFdN9M@HgNLDb$}32sqDE(rnpp?a5Ek{WNNq--63ieq?lLih4sSku-vg5 z4&4o+{|f#zW3}5|D)KJ5NXgPcVq(x zYo*;GvVT3%w96qYaTiA^S5)l zv~thKH#_4ZBF)9QxixN^6zQgTx6&PUbi^B>tZA(IStI~h}rU)h(H zQwumxG*W06Pg!rCwttXueSCauRShE*&NAxhhKRpE^Q=9RE>yEX9j%(zI*a0G2QwiJA@d&HUU1Wt#Bsg4<~> zudlPV&y{WCginNYIa798LbU62I2cW7*FHz(e?^o3i?S9CABUns{TYTp|J@$0>~VMk zp93|AKzEl~+%(}I#zBe!g*ORSD)w8BA%?7qe-98rN5|E4g__4Bi(u|R`u0D-89<6v{ ziIE=_ry)rRk3_$)W=-!y4MUBenM~ut;Tc2qd)avE~t&A&;!%NC7=JF3(y|)GtnjRizX|n6CzIHl+P9M zog?Rh=73_6AiYyRA%VF=vDTEZ4=D7~fMqOGEVw|GO8%!xf(S{3b<3em>_E1Kq&&c} zyvH;tW>hqF6K$)AvC~uepoi}nC!il&=fnH-e;A>;Q9*B3RVD7{9UHQO;zE6f%7tc& zMbO&?1D+~B%HF(gsdbtV@X2%4+_~)@Z!>p8J8`^=%cv z2}KyXrT{fP37=KYY&jV4M1d1zzlEV94YN!xX1&htzGmtl_kl&dY(vVAyWT<8*<#@M zhY~VT)B!^%kpHny9{i5q!OjJVs;A}*9D%}g5D=s^DFDEqP?Cz2{^+*A(i%%kqdrx+ zm|nbNh5-NUYJ?LULe*FO@J%Rw5GL%_oMt-vw-DD zcs!BSZ{AYIyt`Lyq#($DBr}-t%k0vQ7C9sYiI$hZvW&Tw4?d1wadtpul(pX{7h=8p zlQ>rSrRsN07?fEXc^wS}F&CkPY zt-URwY>k093^D5C)XcboNG+qmWS3$u)SG-o%^2t^Ci3`sx3y3ZN=-K`kFn6B7c3x` z-7GaQ`j6C!clnCrf&byCPEP=c-h69+sBAuTg{LecU0x-VFD+rve|R`wC#;;Z8MKBx z9x5>AB}&V;p&=!u{0W@3%0Io2L!WDY>af+&5k)`1X=25W7gjPiz#r9CK^K#o;uE_P z5&?E>E6;KM9oN!(Dm;36BpeZN4ud2IFtx;e*cQ)5rv3+3JNXf*7+O{=yf!{5u6*Rl z+M5%wkajTh(!%aVKe>v0--c>$Ykhc`3z9)@ee4wSjfvoO7Xhb<>aHQ9s&V7`m|7!m zULZaqzwUw3T=TLtNxC5+3#ox*`XcNwz)ail3J1$N_I_o2d|cneHzmK>}o7KK)m00^Ny&mp@aPRtFwl3}n1yZ4XH2(Mr+7(I3 zfhCiW3V;BDnPh!@UY+SB{zn|(`r&FD604+{Zw$~F`o{)K^{*iO>!!(?{4Paq4+~Ki zX8r75Oay`jOPf{SknJPB1>D15K$wv;l76x>D~vZ>WGi2mvN?NHDKYo8G-*OCR znZxc+tOYBKo-I^pHgg&MH9YG>b&{};28I=?aO1sbGfSJiLsb6%)S*{RcFiD|J4&;x zwoqSOz)lhG%LOG8%Oc~6pBG0qMTZV%fesy)vG?wo4z8Jx0+f{QaGB!73hH_(}Y{&qUWyfF1`G5I+D52Eq;D%7kJTUtP+?JWv&vZ@iZxeAl9uT zfk`}0@$BzMM3MLNd7sh1@ndi-n(XpKv2XniRrbCE-^C*x(xn}<9`d$>G&Gu8U zqoiaAJ4W~oTXNnH29-AI*v?Z|`PYIN@6XI5)oZmmbVW@X$pukJ=d+uB7LDb@M`Noe|ND!T<3Z@lX^>J_ zdeGFwFQFQnJ{2Mo#wN;Drw?c7`VUbX;U4b`vN2Xj@zCcPVi+S}6P1--eo1OpH{t}h zGj{{exi((Y+6}8mY=&sA&uVqo&5GmN|6*~^d?oIS)qf?Ae)czDArjZnB#0_VP>hu8 zF*fKa6FnDLH?e3jbyy^xY2DYgf?6Y9sEg?xU*4sVu*8X zVZu~U4>P9XGA4##cI$HHH?;P;_US{mpn3%M2^>$YUoWzEU`pl{y?Msv=x=Dy`$^X|I2Smj_zt|n?@b%UAxt~P^ zt}+{?rKbbdZt!K9sVlw=6P!A4m8LoAs{e=_1s6qkecC-*uHC7-oT5=Dx1~DCeGNZ2 zu)slV_Qe$d=z5V7=t(3E4U&d12CrOEkH6IumWP_8OGX_nm%k!*AR9Cjk3|o7C68Ea z_?IV7?H6R~YfkKT1?vh$g_{dOK`J6g$+ev#Pnr_V^hqdpe+?&<=^(C@^zvJ>@E=u! zpV;D@-qVBh3|^jQJ|UM1lamd#t*s9&NFkxHeu^jLdQ&GL6&q1_M1KBtgOrOh_b*=-$EA;+Seh(9SpZfDfS#J^&VBOt{EvCv&k^uH?KQMtjm ze{^7t>&}$QpUEYS3Xgwyv7JL83_uz+8C9$PKH<+42_HRe(P0|FChkKU{1`nSh>Gq_ zXGN?$JZ!OgKV5NT;*q5N$8XV=8;Mb6p$VMYaIG&4b8$(0KkN|IBe`2t;1kB44pLCr z00H`yH!ZjA#=*e>NBFKpjmMopZ?{YG|D<1LQA{IV(#0>mTx9t93H}q@*>wM@B0587 z`MF;MFtPnVp1wLLj_!$ead&sO;DO+-f#B|L!QEX01Pc~i65Qd#-QC?C776b9hTp6A zsG|0d-J03$+tatZ@9A@J-xR*geQv9k*qP|~W74Efn0Mj>-DieKhA{PhF|mo%ATERVAu!ASpsP{uENP zfHZgqvsmAG??2}L@ZC>p+zyN`)M6e|N1prw+xv?0QTfX?^3C+Q9=CT+0N0ALtIn@5 zIR-p^xlE{GnFTEQ{;!+dNK=-RX~Ul<<+x~eO+f3v7}B3Wu&!6XHp%{)VcsDUMBUSH z7hX4S{v;K=s(gQ$G$au?mf7yO{Eq;DJ}PGD@-`to&HydXOz!U zehfpwHkRqVAa5I8q6(e*C;&Y-ZULfq%))p2N7&Y4^;5M!CB#}9~BB1zq zZe$V%Rhcl&MWiK5rN9azhvDNRs~P$by{VVBPEy0?&|pek?Bs8DejH^$g19vW%ythl zYR<9y(}^6CVCXdweG5>ivrsH@B>x&|#tPLk$f$-oN1%gj2DQ+|E#~E3RNIe` zVl5PY4IP&~>N9+Jt!nNj_;0Ny!VS!rZ78$eu5=p7i^1@ z4CLEjz;y;p#KbAVsX;r=UX%ECY+!6xk+9$6a<=UmZPljBcRM>j_`BA;cutf9vA=S$ zJ0+YIddSaDO9ri_;k!xwd*ID? zlK_J{O4DK8!=ZD9?@y7Sp!i|~FyW&bqo-)3MLDha*wS4Vkki@iKGR^nLV|^aqeAF$ z%W}^)gcg1m%^bR(VcdG`Fka=NU#22ZbK^)jekJCs(#BY_Dc;>* zLgK^>6jxM)K<3fk-VU@rVO^RhDD9mG_)G@RpUt^R=ehz|GLOSPV=BjgheC@pS>RV| z+QjzKwl-f0KR?0#-I+iC38xtWj5$BlE^b(f$ZPEr&j0G zf|;W#ZZ56~F&xUk|F}0488ymtv-mw^lmJ5I3%m>G>A&=pu0yyOd6p_iy|V8#6rcE< zi*WU=l1<_@=c7rIk#cw2GBKs-a?h9Bb8rRUIGOzpw2#5Z?1$E4L*e)U>k&_^I?Jwf z+%J38BWgp{~&M)A0}|DEF%`<#*9&yjt^*H<4;v8t_TO?@|eAD`9D zIKnT-PzF_tX!S$0io)`68+;-LWK33eta$3pJc;>)K$VT;i4-wWXml>pY~@;}%(p1a zTPia>CKfO#AMa93dg}sAS_bS47u<}^j+V5SW$dS>v{ILc#H{WhkaR&{c0Bn#`0q~@ z$z^v13c2sWAD^5QsO6JMYQ1LZ3x4a_1`Gcr<~ALd=UzAS!Oj6Ey2k~`#sUYgMSFJq z&2)b2cpYqS0oVbXiUl00kC1sI=A$Xo*@8Yx!6}ApKRy%lL7p6su=yPwPtIm)*8$)x znR!x{q#(g6E#$8~su1fXtc`!%WOA)x=x3=0MkPf^o;A0@qSW|um`2Z!>^zz|YUP7-NVe zy>_9}$`n{UMHT~DE63^OSw*2Lv`qsuMECp%r7HQVZxiacVjIe4pZD$`m$^KENvOG* z83{NvVqYpu#8=L9q?c_#(IJgdMqrxzh?B1auz;x>8fVYC=e-X8s_Dj{5{Qv%C z^*TQiYx0V%@7#MaATje{%r7KO9}3@V10jT|w4$;wc4DCyq+cevoVb3e!U!tTw|Amu zA$MSg3>Bk6)Ki7g;g%dN8!br(_eOxX_n!i^mx}Aw@g`S0QzczF73UZ{3)I>xJ5x7FzlKPCy%C zp?M6@zQJ{6(v_(HlrBLeVt6&@Tvk+!HHEQ%vg1SvHzq@*-N7^P>vsvIY6+j$)t(=o zfoFHs&hTEqy4PXWv%(&4^PrI5M>aouzmZ+dm;sD93<d1a1 zT@FLklp(sy+0+$+d6Ua(VFqMjK&xZ|hMwjCVP|TlYzC~~S&h>>Ik4j6%2#bbr zEm^~M#Ja%ha)IP~tH5Z9IMr~y3NraPhywmQ9L_~`nye69!20d4#CbWkBAP2-soWGo zE$XBy!Too8ZwQIBewNn<4D*T>Z}tZ-{KU1 z{avY?KmdTP5a6jikJ|w>)#k5?vslmYJlCMo9#Ia&xWPmQR@Tmn!oq`1_p`Ml4gZc+ ztZQV!jmWHVOK@(sSE}G9ckN?=mqR^i6K(3KZ*gU%?*m=cLzBY>%%L+~_QV9L>7Xuo zRb&Ujlpv|S!arAyJ^GF9IQ!R1@~(=xXq@S18WT;C#lOWWz`1%r6hwO~>t!~m#l>kR ztVoI87Ad0F1K40T8i1pAD9a6Br>X~u4=d1Fn@x7@#*ztlP$tS5;3Il<`d&UCjAwJ7 zuPMuqyUlI*|LExs#KzpeD*qALZ;~WO%i!RhmJ-|o*;@B&uEcqId)|cVl_P8P*Cw9P zi1}e`JG4jyFCIOf`#~^n7S*-Kpan*Raq6I6>=n$VW@;E>jHnqz4`br^*5;!x#k;H* z=Tpe^{{HA9i2!_}`~7}wS1T8gf_B=7ACZ2Q-a^WGQo9C6{wa(h6Mkyl->>m{6yu9m z7-)u&WW&!j6A-=h%%n_!H+Sx-;BVKopS}cg_ zN{z1{6l>}n-Nd8z#XyPmpE?fCduwgsK_rlEq))8Sxel#|Pn+bfc6%PvD&$v5z z=%ky;_OF-G78cZDS5WI!)YWkccEqR{9T_c!luXqAJ9J+b7CH>6OYUv@20@aX4`7bR z17mSrL9P-2v>j(^Gv?&ps|^|n+S1HER`=rhrAlpa!MC-t(*6;UDi70jHUwv~QJQ=Ixit}ypaD6?VGkM9hVoR5)or3U3d{r#rh= z{HbYb9V(z>(>k07_X=S^9uJKo7N`hKDu~AzE%+|XFiqxm?;-qe0?GqgVc{bz)=I6s zl9C3s+CP7Hq1bthHtO;)?K-y^DNtP)f-gqO<##)JItP|BIe`%v%`(u|mIrDq1(|L3 z&FtWd0}~iz-1d0#{C)ZH@l9UGt-w{oG0mm>a zbZbMr1? zkm38&;{K8A>VEQmjl=UxHbajw{pqADF?gjP z3Xfd#l$N${pWaOOhK$ip*P5>@b_t2^d(YsBcR%d=6Y9|a^g(*-Aj1JQIjr_PE+s4g zjP@`|rD*Wq+7UI3uYVNX6T{YgIJ!#ppTM*0AJo-b>?j#!jD&7viQs3ldZ?FU~;qDjCcoJ-4UDciQf%K!| zGy5ex4HqE5^inD!0T0`Q;C?&}fUpvCnKJSd491hl@ZyY3ur~e%S@?zkjkgP^EiVia zMsd6TEA`zvkP9+tw|m#aPpzl&L!M6q7I-5?X?w2kr*a%+7S2}F*M1E7O6@8sFpXEq zRF!M?*}lH`x_2O9*H{+@3Y8c*c)$nqM$wj**lfYS=0%Ved@xl+N~}P-G8p~(s(acK z`_jX&W*J*d%nA}fMZb8=DKD*f0@TVDaL!&`rH$x6{7!tErRlKie|IF&)y8&p2Dh#t>o+wFh)}JcB5!B zx!C*b`Fj`flStC&G%}a;`y;Vr55~xWGiw-?xo~+gy>5%gxdC|mV=2U~fijRxrLk9# zfF#JrzO|x~ZuQpE?ba<||JsXIZ2HIBpPodlCtQSEG5oH$VuW36#y`9;tg|)<{ z_}Q3#F9%71#2PQ4YY;VJ>pun?9@lt^t!dF_GbA-tR*Wa8dtr$(jdnRdKbeJJ(Q(mM z)0bkdRb8kTs4!5r|C#@+zevfP-1TXyDL6X62Ojo?c3@LN-UnRTkA9QnehplhVSg1% ztnH@Ib@(3P$m6N3%}Fdv{R9-@pJ8^X$nGiBMBCQpdi0$q6Qs8)Tm4ruC%vo6%gY}Og>oG9*zl>z zv~a0e(wvRC@nhF)PBN^n4=P;G1(B@!qwtE0=nSC2I+@srlJp63N}QPH0q(>!Ti0aN zWPavXd&A!rDs&GUB3%wQ89pF}IiDLx1eJdRyX1!U!FB(pp|1LM9L&fh;^PaG4Rlgn z$C@jziU=Ugyyh~gs;QZyUK#f_bN(|Zpm4oFgu!s=kZOB~Bk$`4Tvk@rWGmHKY*)!g zUXo+&F(znuFfWZ##@lG_dENOC$#U`N+Yzk!E5Dcq251j#{`Vb;*>lTSr{hH%)-~xg z8n1;Ne1#b%&K^a#gFkQIIoVm=(r|33qpQ2VSHwT5F#HjzlG^OfWK93JXDF64vvx9I zBm4Cb-6Xr1%rcThS|1ZKix@W8^18X->5wwn;(&zle)Au+KX}CriZ?DSEN<-Fy|^AO zln8u$#SxE5L64UE4a3GHm{&uTu-?URu{>|BGmC4l(lWbTlnk!f*L&t%^U>@-6BB2> z5Lv6sj}2zmj{zh?ZI5~FKKJfT;>W=6{kYigl1l6UhXwe*7Y26C^NxZRNjv6nl^?*&N|7@4*<`x)U(|Qx&>4ZbNjVQ7v?12QUV|8Zc;Q^o;I9-rA zYigl#jQU^s4vukAZ1sdD^*L>@qELT}EInRv7~H)~>kUUK8rN-@%JO)N%?^0;IzBxz zM_N;(joD*R$weDD(pKll=`3CIhsUHS(ZB9IMBWF1F0>3>^+FMt?FRrY#L@!k8 zpZGj%O9Ny|(EzU-OG6{6VncrZ&V7)`7M-1)o&BVu$3~{c$7B56jekA58-C4c&~8_U zFx>CJ=sAz*to^XVDH@M89LhA0NvDA&V^UB{Q`6&oqupmcJLk-m_umJ;Y4$9o1uqoi z;qAWD5F_s1e=h(tpS%6#YE&M$&Ab-V-MP8B`KVrzghy;<<;T5_ye-#H@)@hz%I$l@ z^)=mGT|FU#x@JiD-OF7f`bmOjy@0qSoONF5W9K?dlN!p7JetCs7@m7J3cTm}@m`EW zrO)>>c;K0`_+Krv@akT*Kmq|+WB0=voE^<)1n80agu&?e|9rY3|0_`AU4O+IC{gxD1Hx{wFQZg zZ?3LpEH%3v#{ZHsa2}?4+t}DBm7v5JKZM#=`T>cbAeI+@>)l@BD@0aRQgXz*{A&XE zuv8@d)Z$_)Fh9Rm!JjPa<^KfwOr6?{QQdD1GuViSLGkSQv ze0O&@=VMlUkS6HkPBTGL6ypK}i7`4%1Vz5AJL*Ik2YGoE54mBBx`(vXsuF?2AUoko z>8jzATU<5|$8|o{OVZcIs!7dU+5E~%7RBVEQgnOddjP1*ckN!c0*qMQjpY!+Wpml- zpwKR*Fzc=;#Bc~bTJl;>WTq@E#3~QJJ@iTNec{R(<)%|Dkv)iK1+2$$@aw$C6bONhp6{h=K@HU&fIsRA0Pl z{(<;a3yPBE?6@V`3pgD*T6=xk_ucg2R`bhjxp(jU?%iS-L4f{rMP%U7NmQyZ|GHR$ z^(H;b@R^>*f<`o(azr`g>ePcCW7Mf_-aht_2g<297NZirP0iW!FXWEW#y@vFY{|5L zXJ-nSVuc!z?e%x(e-jms{a>a95Ank{&K;Yr>I|w};Gt?dw5L+gW63`$h31Z1T(ciw zhzjhZ_v)aUYULUcvqfNZYXv4F9oLdWzC)a4*VSHU(|aW&x-zZ zwzl^0koV-s1Cd2UN{X9PsGfA|;pkYs$hKq_zHD+KP!$pk3CV#h4*E>@lYJK5?C1AH zm3X*@_X#KBX9e<5eOvtSnhWlrSzi4)H+@Kr1&g{P^3W#a-ax#f)9XinVJ@x|YmY12 zEoKS&S-R7Wq%6$L({!*PcE_!Df8k1Ds0#BpFaTxmF)oMk|P<9 z<5vGK>Sng^=0d_?a`eAcpAg|KD9y}*l~8_41WQPW(#)|JLiS>k%!wl()+oyIGRZ)< z&_`WZx-<7{MX;OfLhGRUS`%iX^@pFHLo>ii?n_=824Ij$iipAwTwU(7gnB~ zON|cpRVz@5jLyd|p0`Go!B!TpsMCeS>=u^!b^MEZU!P@BtwO_Z>KyHDWB*F9#d4DB zS>yV&KGO$?elVlv`(T}lJHk+K*|DsPlCm`kb`9@1>TfpNvhl@X{=&e4)TEX&d^&@CCbyJKljS*$@A^6A$`~HQ}q-3!uj`8h&-_>T%!c z>27hbTFZ2cA-3Lag#LvHF{6&w-st!25F5Xlf>D{`oq%zdJSaRcnyfCseN%UEJq79o zWiOA24~OTn#!C7oYI%9skkmT1oM1|{?i-y;l}gM3XfO|RpbdhRI1Xcze86TWGqR)n&@W(b%@#7eM2 zd3z9OSdo9qe+q#3ej?>!Fo7<(p>QGO5(0Ud2>6nTV!{KxVp(yci3gT?o%F`pz}y%! z@5?QNQR_d#dL1VAoZl%gd`Tcch{SM#MMo_N{?HaN&0AVklx?|l+wt(WG6*zFAhsgx z|A?(v$%W(?VPo-)gD4wtyF9AlwOP5r$a)ipw+8B;a5`%A#CIA zVnaTUpBlqo3+(e2swBbf+!Lo7tUpb8NWNhRiSG_sb2X!Pm3k`=AG;G@qvu!{vAdPF$9@k zp7QDhr-h@{Te=nZZ+P2%Pkl{t%Y^^>_Y|E$e{uIt~~b9ZUdyg;JgTnRa>dm zA^?WT4=u_gl$OcguA!mg*cADXs8z10`2!xs}H8& zz1M3unZu_4-1&LiwSwyNTA-W$GT4^X& zLWKDEJWkdo2hy<9{L7~y8crI_x(h-H!!!QE#vK_|WIiyz*T%iRiImm)>sT%Cz~EW0 zLr!xLaW8dTyjXD(^9Oj_zr-g^+Q8m)oNXu8HqRXC83iGL3P_P6 zCKdKoBJ|X`#FnDZ*?;2;*ju;*a8&%k-aQ1};S@wVF5kqu}Q~s3N_9XMhcK+$?eC`EeO@aFp9!l6o%J`wfA=@B_V_@=hI$IBA^6!oIVgk-hyv#Ay8&!k7-u#NjTU z5v0SkbXd8W5aDr-rOawhjBB5X@>c{aw10&y2saDD&mHcY#ziBt1KK(n71Ldtk}}?& zW%V~>8LmcOQz3T}ejYFEZ{=!8{$;#H@Ikue@S$XF09Ngjap-y_^y^plm z36^BNDzL26j8l}?gXn}37MxatJq>@&W=E$gPazABo*zk$v&iBjp2*S88 zP)|zdQ^O^;cPZ&A1Y*eRV|Z@c;nyhh;z3iZF8w!gTqY|2`NVbiZ7B~or|~0)2yEuU z?u)Fh44EL9o`=Gv2|=CH3Julvi`snp(%J~~3k1HH=;P<3l@x6; zvbH`IPO-71$M%*H%7GK{xLSygsBW(Qosl|EtTEUHKj-}4NT>SUooDw63YH$W#NMSR z>AxuVoXdyLSZ!IjC^X^W9Q|Y3$=0{7*}IJ)?n6ixqTgFlK&ScixG=G-Kxy)cLIMU$ zt3o4LUH_ILY6d2R6&_P}$xU5XiI5)RqV!wsOPLbSOMgubMtokyR^x16QD)*-WYW}8 zOV)D6c~y3?ERcy~R}Um1i)|b{jW<1h`pu&+K~ZnopQI#X%}{zo^^y6nd0IaJx)fAp z^qRs9m<*8)wj2Tv0Ws4WtJ8>WtCt1+R#Gn$c@)71N`FtslV@65T6@?*vN6dC%#bdG z3q2I1HkJ!W2=Skr=iKP~UE6YIGQsUcJh;uiLagW}Ux^RQ4EEwnS$@Cfz232m{F3QE zynY?ociQ0m^5r(;_Qu%J(Q$Ol^~zm*F$e7`=sD!EZ}*a1IR#nvd&r?AS7nQ6Wbbxv z46N=FLVmSL8m{C+NZwH{JzFB>X?2B{#d#&~Ec7HN&!-DWAWq>wd0@6j#wjW&kj`+| zS%_@%HQhQm_wSH2`&yu5J8Q{|;lTS_Xh7ca4?68DvH9Bbar;O>_!$|IXJ^ZA2GRTR zBJw5F|XP7ht_l}u6#$3>-a7FRc6E31Bk6f!>~YBTRxs?B3O6N zuV`U^5@tV&tWFXFR<{YDXpH5rwtU~`%Rda_MdYL?bn4}xM(8qbFmU)eTKn*O@#MYk z+b<6!RL!)R!cS3@ZSk?*?b*d@pIE!_bF|9l8-t#uaB0{uYIv0$=9VcxMQtf>yIOye*JmtdL2AT zC|(0x>WD%ce|c5@bou%Slh1+dv2!Q4Kj@<(Tk_$nb9u8A)GE{ulkv3OUxd)F^f~zX zp95i%%CbNE`T0Q&r_GUs=XFjkq>JWVdHL<;DP6FH%)I7E|i zu&w=hisKW~{Isr5Zw6<4-CT{s^@XdjCIgfYG`bt{7@Ntebb?QsavK}De`kztD8PHg zl$ObfH_Ed#NVWfs?Dsw}G1B&}e8t4DQG_gWt=Ewh7^LjQR>tg@vzilHu*ahe8e(+r zf0<;3np-5b+!}FWvzL4_xZhA&nIMK zYq($bNOSBz1RZh+(}m!ei!B?xj8a^=uMJ0G5Kk1G&jqxF-$yw9&F7Ll`n`4bwel$h z>_pNn?7bYHp9%Y0TkMq5*{QPEWQFw*lp%!?$r7hg9Gge=@;~)OI!?H~3;&(1+Ae zoma%FHJ|=XrvmqH64}I|%ej*Ed@5CF{zX)v4BVJPL;E@fKdG~qK+eSef(0}9{QNv8 zE3GvP^NP}kuFo{e`x&m|6zM^z-Q{qiNKnOgJWyzj-&d|f@9AEQ-6N?aFN2k-Fy#P- zumvY(*S$rtYT=tl1!ptY)pK{ZXn?cHfyS8A`_x=Iyeo_gzY3U!N9#J8o2y%P4Q~9=3I8#8`6#k1L3Crp*Eau$QMOk5*Q;PpRZGiL zX`9IWBQW?}v8ZS=!TfPYs(l$Do!)A)FcC=&^fNO*6EkbZEhzrnaCLsp$Hym5ra&df znk&NrN0K1KZu5H(?&+0y_tYeD{!4S(4KmYM86i4oP_FPI*q7@*GF|0am#s{+6{Yuv z_j`**l%(nV@ug&k^H$d}Zr*|i`E(kO8!fL7oES0M73kbuQ**Hjn5)>2`=`B$YUJt3 zBMaXsUZSy?HvD%}jQ+B_XA&Dv-_$uZD>jQX?mQ$-&UyYIH7F>kBkgF9ge#W=Cgk|P z*4F11E9t>{0FPih+P1<1aK*OWf}ZY7>aYIj3Atg@m*8i(f5%lc_NvSi6`;dZPT5qh zN_Eiv2DRvo0(!bx+G~Un6~Hl2v*3k|Y3x6+g^Z{N)$C$A zHoBUhrE(r-o&Dk@_}*Aj<%I(=V0Cj4l)h;t>EPw*FAFrp)uTl3(%31K+>~6wNpnKUcmU>7pau2Sf8zW zpDhe&oNt_hm*Eo_F?ygdf8%u#AiI01&U+1=-1>bXL|b1`uyP0p2pAk28!P%E?^Cq; z&pi+eYbP-S#X`6e8uIP@81{W%mZsIC!Y=#-wiT{Xjc`P|uK6?rLrnD9V9V9EbljJo zxS0?C#053Qp|Cj8Wn3NRsgaG47C$s8QJW!|JrbIoI?BuO(^-KT?csqoWZ>AhXg}xEhs=-*74TATb-phiWRsVa za#o;~1sLZqlLqls1tpF25YgwerR4vGyI&H&J1TB&HJh6HtX4`ur-L`zpEuRZG=wLO z6+%7zw0@k7^WjKbYUVQ;>Q>-(m;Z+WcOEaG`DJb(3_o81$B$JsL1P&(WE^DbZY42g^uFaELSi)kpVRYnz*mXMfuAic(aMLb`IuMNyGfod?U(yuYJr(xtR~ zxSx@`^MMVpLJ)zdw0Jx^S@~?Dyo@iCkhX;vD})p;Z9FN9Q3)`U999R|Ym4aV(4w=! z^eXxs5? zGeoS~(~>wG)GSGzztV7-w())y3t9RUbLb`ii~1}7K(dNF5H9&)hMmUy`Zml-SPV3` zVr1LBi3-%he+tn;mFjMrkDW@f9sKKKy7P$L?TVf>b6_DaRP5rK4vJaMq?@wD4Un@N z{EPG5NlEOdT}SmEUx)dLa@A(5hr_B)$>NdUw|awC4eY*u)hKWx5r@YT?-i{0EwxHt zg_{ztIdO@89M;z5koPsg--X!69j4?iKHm=S?bRMsEN~&Cp`pe6{ONl#-1Ds}urtKM zUQ!XCW!UW-J#LFP@F#9k@$XPf#eg=evqYz&1A^)ll$b2m56*@ma_tWP=b|}}N!!c;w(KEybFOZP-uP@pu{w3e{C^|P&E4WXHMYVR>HEJHw zem;WEE)=-~@u5t?ep5m3lLE^c+T&bP;m+?vDX6cyoW|WuVlVts z0q6?^cLgsSi%zTK3JNB7~mtOrGLkzrT{ec_k6h(OS zkzXXo`ze`-5qkI3{uYPJ*xZX5xqmNhpj440{1cC4Npw zw7SZLzj7ZZy<1eokw&%@h#G(v(ffxb?z}uX^U9|GhZ4QJY=K^z_Tue7wu5S(`3w{- z`~ZSz$qiv%-sP0x%DTEb?$qIR1$e<>Sl6FCgmD8^*HZ28Z9t?y)>&;*UaTOPig=Fo z7tQL~-(OCoTMoDu|>Z-VtOp z8k~9Q-JXMO2F#K+Hv`I1t2C0zJfi62;n*V3VsZ3+(LIOTJ1y|AA*{?eBfUwIn?DFz%n)l>v<;cbpN zWIAfEuD|oI7|~yXC}oq-X!q^F@8x_3k8eMl_Nm%N*JzedyXS(p^euq4Lp` z8724;eCcUjmL;6akUCmVRJS~~y50PFS1XsiPO9zCZiS1Bi?HE0pOto6;velChGU!b zh$drPx7Fp6qAy;C(u?LknoIM{{t5z^!iI{ArBzbmoyj$2=8R^fMlP-t!C}H2hOwkjvOtlas zR4mIGV6Vx(n?66H+td0rx;>Qkze)^mwl%}%6kQ(BOem|yTD6n76`+h+8Ti&u0`az&ewkq?-$zY^FkmC!6H?uaXt>OQ(o)Q1|$GC zQEyARBvtQXWHdTTJ1Aw;aog=<_Qb`rvbg##IgVbLm9{+FV9HJ!ne+WS`1-PuCDljH zoo905a5e&EN)%UA@#3dRJ@hNOoHLV!q*DGgm?2H>DnRp>riX_IWyZ*c6un=G{B0K% zDd?4q1Y+ee#{mJVO zy$s&s@fXs3y)7+S@$;W7&ownI^}9-;y*lfA=d5DL-j@1*eN*i5TvVq zkB+Tf{r9C|9IhANOr?4BIOd=}^calj8S%zoE$BC^yoc(tvX8&0NO~~~V!80EhMNv@ZPs8RdD+#McxosX#G$@hA3=|> z{Ji`BMzQ`YjbL&5d}^;UTT*q@a_3&KY-A&^^ZzvhxU8leX|&&5G(Apx5)u+3R{X-h ziz~i%nGBkz@{&xjM~uG4`U<_Sx}VpjT*Jb`HYmg@`o*a{aa-VXsHXg&mpNCY-r3X| zCWZx64x7jB5h$vvAxQ88LV~u0`2@tdU({{Dy?(0-rE`oPg|i&%cAzJpWQ*G$)?nJ) zB71Zi2#`Jxc5W;2+27R@Zx7l;?fC^KW-RMw8zzy6zWfkQSH^UUY|qi%yZv>R#fa<@ z9djEptjN$hmD0|t!nw+Ml=U%|f~U6d2}=DR1TudKRuuX9`8P7;Xf?;|^(s!`6nVPi z5c?HlVq^6uOi}6m6Y{J}S@B<_0;=z^_@#5+9<~df<~BDw?VLY*5mD@UX2U$N)Arc% z5WZ@C`hud&Dt-F356g1idY%=hY@dxD&q(nQ+Ft?t5iMo(-{EhGKhv|dX=8RwL;Z;A zUm)~__;V)7G*C!z3sv%b^-I*e72Btw3zZsHfAsVF_Ze?Pjb8o?$=$uo)2d-}L87^- zZ$ZTn{`nXl4z;Z)L%RKRbad2dkT|-qQ9*~7G=ny~+|0tC8kVL^nfFtfsd?# zo}bvXR$PD)upDktF*A~5tVP`;(xF9SP7!u=ycu-sh7r$AXdcmFitMtvxC~aL1U)bs zLMsWbs0bvz0vID13My^556%7z7T)^Xa5W>N*aElm(S)9$#Vp(1D2 zc;Lv$5Up1xpWz`7Ot9c0a;r+1qH?HWk+i$5vaaP{2MY_n6{$OQmEV*ncL<*~?ZQgm z#k^&dav55vvi`P!a}EG{weGDh)905tI;sF^r%8d8Dej`sfs4aI2aNc$b#sNm&K)x;>O7iWub|g1gX}2EeR)4O3H4k%syOU#CHOIL#zH5IZ($QnVkDQ|zO{E_{ zUerwIBzk-WDpr9n?6=z4cq}%YgfqSktCS*#)k+>MdYg%ogAVXBi1^o}k|nZ~=UbfO z`$nlY?0L$47(G}9{Q?>&P|h1D3SZQ+4{3HTd9Lvjg>j<$zetiS5%QTutweHh<*pj1 zfWRU>M@~N3#q-CCp_Q+|gpU=Qtedr% zKC9jX&|)IMro_UG6a5aoyl4SADJCP~B4;Z?*Li$;%5(1cThF9s3BcVxGPdNQEyLjO z^u1EBv$;MkEuEnliY!oZJg+1w@C`pc>^@h1pF2slX*mvsq}&PtpOZb|u{x1DaVS$d z$rT$Y`qjiUwn5eAQ_NxS%w)u@rpZe3prv4 zx=|v3(N#{VO5}Z0PF6)B@Cga!T5Id#_v+(!75Bgtli(;oHR|2s%n~stq?^314A1AW zvDSBQU3V@~OQ673apobteAf4|Q6X`;2)NuJB1M>fS^`oXe8e7mbyDcR%}(ojdDC z?df0j0uv3UE;Dx1#h!|ws33O6^wS@>b;yCQq(y_bCEoR}JiTPRIdq;*1v)LLRHyYw zkV`Rj5bG}_?;eVZi`uHHs*K@r_55(B*S;NF{H6QHhYa}`L{naUulbf%tGsZiwsM!@ z^9|n%uDdt*1=HT7+Vk3ytBWxQI^}mS&*J*{#SOKJxSD2mbFKt`Gm?7k)s#ir`x4iN z;yt*5&tfYl8pkFk8j>qc+`Kl`RFiy)&7s2l1VAmLyZnNw88-YF4)Y|{EZ`#o-|f?} zF+o^%%tDkLX2x6%y`cEJu>CWn1eXGne^RJ`23$-F0vJ1QVnRVpGbw^z%oLw$c;9)D zeZZiXjXGAGl17bO345F~Lq)?F85E|{QBq3m*v6fKVz8K}#Tnry&W%o~nx#*IH!(3$ zIilR=E^@wl_sfJgz>+9XVU6V;2B*MNLiN41rA4n9GsNXZ@0>we;{ScA_#marlU;Wwm}4&U9Jnm>V2UsA8t6@jtn@n+J5_EsK<18Hg<3gWaWZeNNsJN?5F+q(i|2>)*|Z313-%FKSdwTh=hM+kF9hE0~Bw@_u#WeU3K zU$n+?cPLKL;_mKJg1fszad#>1?he7-T}pxCp}4zyaX@MZ4eNew=JI6ZUw5-F@}Kxzn${o?)Rt&>(1YYvXhGWdCj>)R>mwPr5A12^~T& zDY^ZMJ^`!1#hSpsgvh@MOLko87d4pUwk5h;<^+wzI6vC$ikYeA#KQQcy#_$$`QxkE zpTviSpzb{7@80oR(88Z*&BNza#aD|c;Jss8ZYE3G<@lki5CfzSh*XflC`1`Z=_y&F zq9m-snPUp^CU45jK@pBRfR${TL>Or$i(5>VhHCJND@Mo=)V)fH z6Wv>yI3rHXzgO4>Nz&qu{l|Wjbh^fe!-&hzS*qk`FbQ@1%#j2zSr+EVtwTqavwn$( zeB$3|^UA&n?A>=(7t6ZD2;$Hng?77%6*#xE#|Z4GI-Vb#c4UG>N65KqbXq1Vh--~A z6o*$t>-=C5i_nD?U!8~ilIzF7K;w-*^K-9d$qjv*MDwAMkp`yU|-O4^(Zh?84;wg0fue+}uOfr=(FmkvnWPp+|KEV&B|m; ze#g7n`5q@c)4M--`q9HEO4OI?nNyp$jNHw%oW&T4edV|_UU8*3%@>7@5QthKH^2=o zHx?G00o}7$)z(l*a3%FDcydPMsdsDBf{-`p4`|<}1)a7<^=1jGy*H(Ek^Mea+)iS+ zfIjhcXSou%S-8A{Zu9;Q^|wtCqyb)jl=*X)LIdlp92~x8C7T_Si_}b_n;R<|_lH?o zS#5whCOEfflxs1Cj^4UCm(KO@xg+LFqhbzc59*xv?5Yz(&HXG2s_0)|Wz%QqGBT`W zU_}eE8Pfp8j1$Q-N7Z!}cx{%V zq^BDm;!<=QDPxwtm}Wo1hPY2yDq3)Eejh#N>Cm^%2&`XH>0JssMdPxEow3arC_B!7 zYZh;}k$|sVi2n*{tRLAHq?@K}K+M}`?*s$ElNXJ`Xs_30Q0hJSwdA(viEF6Bs4x9N zk2<5EZ53qCDzY5)3(2}+6=flnUd<}oR%{+?#G*h(GLnWJAbs9@JO+O$8 z8^3j1s&+;yw=g8YOfnn41kQGXTRLqlf~Gw5fXHm^R>p;osbEGK>I@E8+bi6sY46vr zPEWF=%4jy@^f{3AI{MfS)Ty(OU-DHLAnGixQm8)8lL)T^Cqnz#zFO}Q~uM-(*RM76De$L?1@Eah?I%ockBWx$yak|`2s2cr_Qx_dA%7O(!!0O`uqe%IDGy%})Z;4Jk+ z*J9dWwL1*(L9R?r6mk0BtmD~bVqBi6AA@2TTmwC@i&nUIRty7)_s9sc7(WtVCU>wB zuF)3>9UX0sA&wcxfoZvRo9T{SPK6MbeU&GaXk$rK%b@Hj>WUME^0`@%du@@8t{Mi+ zhTAbk->fwRK@!zO^3Odgt=>8>@btKcmht+~**QkDNO_c2cMgcO6X&k zI_n2yn7p{Wy7JywUN(_sJZ0nbv*Ss6*B)@)*<#ZhI}{A5Z|=$~hng-5cY!ugOfEahp(yk&Y4EK=gk z8Rt^xNj%3$`m3zM`Sr7s)`!_4qS4s`vGyvq75W9#h7Ab&wXxz?=g22I`ke|gaNDM- z=*Thg+h{i==zn9Dr zE4CZKSzgljcZ3z}!z@v#|FLz-MXLF(-G&Lz`yht?( zyCbNdAZo;+egTj`6kg!kS-g68cLg!O=2Ho=ujPE%WvQ*zbEZ-0_QEYbCRn(}!^xnR z)r}m#_i%TI(i;G*lC`s$9HS{XSDC$08I8IlWc=V=f5t$?m>|H(=W`r>?ze9Cd6GVl=S`l7XbLCWUCe@n)>C* zM0^m`LW_(Co;O+*gf1RmjST2D0^*raH=;Mko&-1NVu-X}9LJbFJsx@(g)(~ZqGdP~ z;E_gMi%(qyHkIiQv?g)jA0}i-1K#Kr)aq4iHBdB$-9nVDw3eWoBw(6aP`3=~JkGgc zK!b~peYwblFCpK=SsBZZtEzKq+Bj;DBE*OKRGoLJWpQSp%a2V(;k!G_*a($}FCGF` z_HO)z(sTnRTJs-j-0WHL1v<6=Y$jmdw?K8F?t={HQl^2vU07FHxp{9VfJZ-Szb%rh zfCGJg_gB@RX%Aiua&yR+ZR1ZOX=zQZsqzhB4>z}h^ohej<70mG7^+FF4c0QBE}xm) zT%m>{i=$QhIl$5VJ;??iU+3p5eo4Q?WRK+~EeYBvX@n2ljIZD4Ubj})sI(vYVR}^5 ziK808u$nvP7KlNabX?E-wU;Ih&}tApef8L1re3uUA2fZ~Nnlj)*x6g2W()jWk9=Tu zPuP1+K#whz*{ZiWT?jYH)JWt*tL(a2i;w@kV()@*^EKmYFBE@?lgNGZBvGYyRuT;2 z>A#D-y!DK`d^v-?+u12GQvP!UF4?)hPeAfZ7vrLZ&5Z9KUGnSyY@PRig?d^sr7rJ-ucWOH9tYiJu!S z8$mmJa4UIfMH1aw+uC|X2a9!Ic}`bq9|?%pJ=UL=X&D*UvOFxq!@vN>>&B0rO_rgW<tc+qke0aS7w#h3j+;`;EVgshyZoa>c)<1S^;6XrQH6G(oDf;jdM;UVG7r^qg??xo`=+S#vG8HBJpBc&n6Cj5e+8M zI#J(;mf3alck^$u2?(rla4bcn`f-Ob_$@$VED!3VA|4wgqm1lb8#jpM!<{`t)1-iFsF=r{m<1d86VB z2QC3ssto=gHgI>?Orlm?QhIx!9nZ*DSR#6$bx(cyRbEL-AW0Bd$lcGLlHL82V%&5< z54&5}{uqBRDnCECzaW>G?}y?lxFRIWanh-W`AfobaF5@t<$+g7Br^OLDM1ziALGH5 z@!Jdd3HswA)BzS>T2RvA_Lug8lYdiX9%}q)e$82VHVyLP0OzR#7XwwsBQ!lY?o{X8 z+}!ubx-%^@Nh+Om%uIc+_$7+QV-4bnz9wBw(e|~^D&1PJ$3e8-TmO=S9$+z485_|R z?lWRJDm;1ni?6Hbm0S%Utz1rX9Pr+y)wAm;@_Gigu~$AnM`$U$*+y#vQw5z*VvKft5N)(+%)c-|)Zb@mI7f0yJcTR}lg>Xp(% zRA@rHL$Bfp=x5II*HEmT~~vU!Yh9IjIvL-SN*8AL$Zg?j99Dl)gIP#5t|l6S+A zJhpEXpUJv(Q>a~Ywy@%M+6IK^P0K|#6I=j4xZ#bBjWSC&9TqHM;!~aSH)pL~|2z`w zb&P-V<=!f0ywbPpy%xcYg{_f^XhYAC)8G1}8e_swtKf?Ba3Tx%eB_;!1`FaN+Dk56+-qOEH+&8{HqT0CkI$M` z&TCWuvd;Y>e_x>>Gu@Ypl_2Hx1?x-E-}iqf#((OTGjF?nbK>>WVb*#=8Fhw?b;dNib8OVUJG)@Vd3paB^f7qN zE+VRL94pxFjNOAR>F(+l5Ed2^>NV+$0K2PwrDaBy961S%Fr`%Bn90^W;xV$^x&;fW z>FugT;hc}7|8}590*cVDnUSEhyx8^bdH}$GDIWVP(|lm5ZJz5`CwfJdM`U3T&qrl4312#$uLyC44hQ&^513SGasGjY#5v|F{Qau6#8{vWw0i3Ae=~@S&kQAM z70v{YaHKHhzDxeGr4%Q$c9lHh{W*tfaKM?T#`p7xEAPnLKm~`A7>x+*9`or%L@UBd zd|;rYq(q@x<$Fu|g9!ZbafDEG3=RNVkPU-gEukPkX(FXRV(Bzl6D$D16I$Eq0Iz&3 zF|+<5TOg$+y`?akva%almNH+wmV4e@Vkt$&HWp{CG{VhvDjgs%s;s~C4qFC;nr@-X*6d2!V#7B~F|RyrpW2yqzG^i8PRDGxyf9MI-X6eT#se2N;WwredM0tk0ur@E|PE7Sksveo6D+Z@L}OG4 zVuFf*K7YY2u4`5yt5YDNHcKzAvp3s}ZY$-FRmRXe|Sv7FTDNeQFsQJ!*}PjBux3 zuo9#7(-q7F`mzkIbldpnVC2HS3`6A33xnFdgP zV$iDr`bZK+0wsByn&Zqv|f3lJp@v$ zNWZy=oO;HVoG`#fdaQDKq+0` z&HXL~KASW)6PR-3p1oo+)wC5}n@`jG5*Fv0KZf5Fi4j@#6VF%QBOjv)d*^GJ5v2N^vYaPaFjG3(VWPG}@r*+Ui^Q_+mTe<>m@f z%nCq5>*a&NRX!vU$8`8+C{dPGmePsW#7d~9f|!UAj*sx~kFv=vflGC5bV<)(;jMh5 zHh6N4`xFmVhJjfBDxlXKPHzVG;g^8{EOy;Cx3ktQlqq!jW3F!paBP`lzb@QZyR5#u zP^O;aNq)RYQrt{~FA&AW&{2>SrtlG?S;m9K-XITJh?}*dqLPoR zU})b(Dd#g6@2yf=F0#R0d0^N<1Fd2GW3fwTPxiUiCD#sxcK;V z8GNEAfINhgXqy=wGA6zqcTL9>(^k>5xaecAUj5}f{k81$t9ksO2_Gpens`)*ozMF? z?=Bm%x4$}2Pp5L-fcCJBWtiD+3%}*-t;Ouo+=@MfJ{U|umTHO&No5XY6@5R({+df& z&ojvszegG^-K}WAjEMm8E^9Y+pIIC;p2p76IWS@F!kbyE_XmH0ypKq1M@!bF!JdqY zB#J^EIb@S$@}~oJY<3VD3;jB3F?FF=oni$L^H>esjyOY6F~04f6JB(twCPb*(s#wY zgz4NY7MYtL^ulT=u}HDAmy!`_Ih50onGasO=RE#yr^TuOWYwW5lnD*$`UDD#k&;WX_{T5i` zq54R?=xLEP$O_oivQWVDUHuTb;hY0z%)!Xe9=H}?t0_8W5`-3wbgm2bnl-s?VM-2? z!QDhQ9W!OvIf(7%-RtIQe2|Co^2U3rO6C@>sfg#{tB6SP#$%o)N_BSEaji^)!A_MN zRW^xNdxOgRL&61T{oq-2CEc<%V(H>Dvh1Y5wn|~;>b69+Gbk60PY$tn>%v(`zn+J@ zcTj@O-8P%rBvxvO)vJP0B6BN<&nlQvxi}IqFUtPruqs*Pg_+KF2mu;Q9oHt}QW#36 zlC7$Why6Lof`=3)p_&91z`|oe3(y1Zr}c%KE%-#?2eYVzZ}t0c^~h8j#*5it^s;Bx z7OgXPf7ldf9({l|R-8{=)T@nM*iiQPC69;G0I+78Fvdini&By&qGbfgSbM9=clk^l zkF=M?TOHTItOx~WH#unI_gyc65^N=6E>^$6kH!s#GMu4za1B0Qzs!lH2yPApt}Xd) z0B(_Y%nJEB^_fevSGfex%79#WHP6Engf_39uPI07>A~Z-Z=W6>(lg7}FRS23?@*r^ zexWJ^T)Xh}oH^m(z&LNI~eaK zj;|~$yI^y(uUWBPq#7gdT#x^%F$Xq)N9!SyH%d1{ve4!{vcg$@KnOJLDDOl5PI5GF zUg2WVk8&y&Fc^O~(pcJz!$gE+L9{-B==ZQ-2vz1HjIuP3pd2<41Yjrx>!cicvy609 z&syKj+qQc3>c-{Ft&~byZ#>I}aPIx?WRbgp!AbTg5lY4YzAJRoy)&je{bWv3(!Tx~u}8QX7-$UgqBBG>G$OR{xs=wah Z8b|cG2B2(k5bxWi`_d*{fC|}OU;|6_g(I1OOZ0le}`={3;T%T6icz@L^?NsbrIIS#1MKo$S$ zA+RA5>nU{wrb~$W7{u9kE*~N1>o8~ZMX(*>dlLskNC)(tCMY=10u-&ZAZ_h`R#Kg& z56+hoMdaDFLIQU}qaE;liJNYHgO$%^h`=!{tYX*USnB~jfDQR)C;}bPnr{W5cYmM3D~q z4a9{ki?$azgL8TtUEXRI*Ml-UsFh0AJmn*n-Zf4jP^h2TB#j47Jr$v#(RX9Ew{^?f-j zF8a2?JMq?MKQ!JYi5M=o$WA+(HAzpSnJf-$?0&n)O(JhYuq{JWCA(goejM29bK%JL zD+G0tJ99|fp5>)xnudrn&t}(YdALXK5LN!ASi<8&Z{Vz(DNDh@4F>%Z!L6rQn5BGL8{!+wLoH^%K)hvzX})G|k;LkMZ@B}}>(e=sEws!xELh9^IY z10N;dfHt)cx{QN=-*5(vmT_dBY_ZlhWR~Ij4B7p^-b!}GckwlWoW)6agNLWF%#C{S~eU6e-Sj=|$3F}S(j zoy&wF8?ta7wQUV`bbUt6Oudxy&+QBbf5>V^GoahfGX%D~bkhA7amK z5OkFmECM3DsvvZ{gkZ0VY9jX$k~#p%K)eGI)QW_ zrVD+)sdy3r(=>4ly;{RSsY-o*LyZLl@%f*aG-{Fq@e^6*I+>yYu;QiDCVhVp{n+sl z-r0yz-|EQ_UeWManHNTDh4i{lZ4Y38vtBy2hFgou3lQS-VVKFhlY`tLS-Er+gi;;x z7<6z#eTaaYpBp3_{jM;?*cZQl*UR*Qd;T58CnRizV&J)TZ%9knEb_)OFv_o>03rfC zsGwd+T!awVPD6LYsSw;1x2u1H=DxOD{XI#Pp~~Q-kX3c4onNRvLw^*LO`Ha~aRp(j zvhI?1khJl&AwtayARvb0X{DG)EdJm&4q1}QkI>d2AqSI=ED@j_kGtTGf^}h$N_8|x zRWbPDf3jLb@$ptw`Cy1+7bzd-`w0jBq1OX1y=LuSUwOJ8E?=mn_PwbeNKi5(aQ+t4 zh{DB?&9aa1z_d80jhtErtM7I9+Gni|X0u(>-uUd>1e?2FG zoRhD$##8e^ez+>PMVLV4na2u~mxyEHjQyg55rmqcN#EKzxH;$`lHo`*Vw0BJc6+?8Ry!D>@b+SeG~z&;@=?(bsbO3m25pM)zfx_TIO3-uo0L zfQVimx-?}Jr?b>hfXoOX^qepx-Wa=ff|V|Um{L-nyu>eecP*&kCWf`okdqBPN%lW| z!G@xCsx~*R?A8gls$LZC*IZ+bRCb~%K;hu~pa7~#AMvOx@n|Pzf>bOS;)vTGeqyl% zAF8H6bS(Y1mT=4}6#!xp4!gTx2$?sGSR#z!Z)~*`cUhdk%?<2+XCNL8IQybu&$(rH z?4$4Yr>9kqOnE9o6-g&Qb?;mJNmQokS59U%i!hKm!VS9@ccZZgOmGl>Vz(k4WVs3| zR*{=RNeD!zBwExFuUL60WN!IX*+b|SY1ey_%*V2(=`0ww1_y52^1ANe2~Q#U#ay;l z6P*4b;0K1A;NxJ`5#pPrVO(3AKr>1+`XGmRV-};SlmePFr~Wui#x2sSmz=x-(Jp`RvVWWXRzb*KiE4_P0lm)nQ13R zIO!4Cc6k-s*&n>V=R|y0#*D&2Ol{4gOk8ELP7bZClL&Nc!+MX7WNf)w@z1sjb4kc}*yVzi}m90a0-7TLZIb zV40^wvwsfOa_T@COuih}GR)o4Uu(w)cQvRSEH6ztV{A~t!cg~0rvl;+z;-89u!3kH zbKHZa5zn^ih8ATuQxIWMAUm6B?irdHf7~gXM|;XTB34MEz972o(VvV<83{jv)^g zMn-A2qA)hd5t5CTir59+m7~9u&pn6v^!kj33p?Ff=3r_6_djjrVnrB0k&wK<51T&Z z#YykE#a`pm1|r=nPMIz!{BnM(o;_wGRRDgitp&1u_V?Na$Dh&8d`_;9_O&S4w4N;t zrCZQAe`Uf~M1)lgQYN#(BFp_NAqOoKLEVb2S{T}ah)6?6Oom9_CKu(+NfVr``WL<^ z6`IEWIJgXWL8ln~vypPGsb&=L3aayX?6WL;d%PTPqL8aj`w|N-@AznSb39J_-EKL4 zyncSZaj>#BFp22&Y#uJ^i6t|MM_w+%?IH6_XlCwOcLk`cwU7>D87RU1T%EJBHQQ0I zdK?!o@`5h8v(?bR-V8tN;4A5lqk6bu3EOUGUe#(!xqNZ=gHenLQabK)s$qcg_m|L% z9)5#Ay?^QER5)v7oap`PfX3XTPzM$!x-Bk4J z@a9%S;EjinD!S~hVsEe~%GSgDFj7*Q`8jL7|7y2_?+Z2ou7c45XXUp*flP73J>CwX zDhLDQ5F0MtOg!~1=$Bn+;er2Lzd{y(W}eAE4%{2cXRts1QHbmS~f4_7pGGPC6~rl%GABz-SKS6h^;PBjJsn&Ufwe;gnqpZp;Xf%C#w8h zXyI3=33gEx&h2$L$lu>Q7)#Fh@xy}!g7vxx-`qU;Z2i@-pT>R)iZ{S$_&78{_sTPQrpuqO(>yhL5%CX5rQ zTCl8#!Qd}~NcxU(NRO(Vxr>!Qq#^-NpnSj4Ie0FkwTC}t&Q4T*8|K^55Gb>xvB8-% z`K5u;@zVz9M^F4vPM{i6s;ZWN47<#~VMJ+2`w-PGN3xAaya*a}rS>(ko&YwZb-JjI zLCl`=dvj1#0yXKw6 zPFPVe#&w#Hk($MwVdAX#;kqOWhd7A-N>x10ui&5G6KBeI$C?b} z+LmvhH2e3s7PY)jE(oFI>n6o@m}ERv0*k_2sfA7fT#&&d|LA6+tY8>tQs%gpU_$9Bdoqgq;3Pg}W){WX9Q>M;`st_Ic5{3;--&-oC zsw+zDvgaBm`)BUaFZl!f4vsV2`2BUrjr_8M#EqqDJz53!=VrKsfmd zyx&edA-F|@pN~9>qa{78V10+ZYWn6h|5n`#RdI-phNHYB=FUzu6(n&e*6|?ZPI~dt z>)*4pjp%Y{k6j)_^akBtx2#+34aQIW3Wu+MGa13W8G21F?5{(FK!(6N^Mh4t~!&>C|-xbZ`6Dub4G8*D`pr46_JvWQ|i z2Pq*b>HDl|9N0wu(1dL^Dze0CTQ9*bQ@nrx&CJ(SqyFU}rSoGwpHe1Xo{6Vt%=|^6 zd3e_oCMaY{=7=WS3Ezylau4R`D&Ok)jSvPxVWkxhgdhIirT^>=rZx-sij7#zXXb7n z9t?5oX5u!qYc(9^a5S{zpEou)^REcPZ=|JEHq{t$+(O|<(vMS9MH4}!(KM8viV6y~ z_!0SI`*jYSr|24%)j2~&toUUsE`HJZ>ZfKW#*cUb{10=xC)?;1JCA%JB_0JOC_#uQ zxo!i8#D9BxmFTNnj=*<+^8~7q;O6aF^TFSK_&d=;lj04-YDo%%nX|6+7DhX}R$W+> z8A+B9N`wi(JOCy@qqTFAn>hW2QgFM#R+xXlAFW90=WjK_*|q~$w`z@ zzG;Hrx>07b-vi52n{c#N*K0pq<$XE@JD~D(_-3Bf$R{Bv1N&i4FrT0M24(%wOvr^=^kC zcS)m>^pfKv=$FFXo5eQ1&sskbthH@v*DeZcF=xOlbBsn3`aQO|{{zaGJuZ5@bYQ`K zTnR&!OAOGs8F3q8!F0`D>eKtdhOQqQD05CxA=ORwi!>J+>sdVSmzQTr8JEDi)*Wl-vVTP`oo;wRWY*M!tN5GvXc6dPzjpG#{>N8_ z;1J|!z&Fa0Dn&5ixh3>q?qvO7ZcZ(MRl2=xHEhc_Ue${#4Y0{BB(#yf=LtM}?SDmJ z3gOKx0THUsoPY8<3>RpzNG zW*zQUf5cJ{)!nE5j%In3_RIUh%I=Y~lrX;~rX@3PXh_klD6NZKQQ~KW;&E|1&trIH zWt1b9IM#CeVe~w8(VWcQ%^-Mf9!gW3?(I-y&X5C_8N|${kCRc3B*ziSbDeg_V%^?n zXi3Pvz|t_UT65yW*-kp4l&Ju?6wJa;lym1wOOfCe@uyuRcY+$66oIKIb2|`DspP5t zS|bL0l%dE(*#9u}+ryfo*kfJB=`hh~LieJf-*T{bl@*VAM{S^)h zzo1-Ul06mdZ7Lcjs4GXQU*Ew9Ojb(pS*;_&KsCdoed?)a!G7@~25SZ=XVbL`a( ze7u{yW5Blvp^LWF4X>gnlz4kW@qlEGX+{>e)% zhS+`7o~d0E6coQTUF+exp0YTb>gOBjV)_G$Ci`&%5>lRTFUI`W93mL{v-_(!NepmPyH@=%cwgcxaejC_ zx103B>s;3Ss201-kF7of|A!T5bcCJr-+F|I*!BxvxQK4-ITyW_rn^spEK32oEd{=p zRy?@K9NmcDiHSX3#Kh5$gV}`e`&#vx-wbH*L&aySPwzWv)HP5G&Fj7 z;q$M6ZJ{Pn&EA8yDc>Tx{-->FD5r@wc_|ahjg1vw8tV8WaTh~U;UegP!?>J4&-33= z-MmM5E-cX7bnv#pUom~IVzgj={9@Ukc0CiEls;c8ANCc^oefP+OPki(4x`5#6@E(a z#1Rucm!m1Q{AkUWd}uweJ&+4o(-UGJMR4fRsx(*kCd)hN>n0KZ98=2oXT?A`uUH~1 zwQ#vXAW<}LCaTNH#D6b1Aaq%=$OxmMiD_3jq7fOPrCdh)fiArX13kE>OXeom83!5$ z))m*Q_DG^v0fciAuj+ z(**L#E-P)1fgm7|hGiwi)blA^|2d8*cZ#Hegs^U?A>77WHF21QuVQH8@nRN#@yn$Z zC}}R_#^M%;Il=$z45mG|@`vtx1lMHWoP=O_vnCA;neqA%LX2XO$oj5#e$RnctT>2# zL>9wQ^PoVlklWC)v8dRpZ0Mk@l0mO8FD_KPhiQ(zl5>;%oW;h>KO5{*QO4w7kq>@IJ-c8xF!_5u>b~N%;Oy9Sq1||$ z(@B{KDCY9s+$xS-=vU1NXCJB7l1N$=9i~*K7OHS)ps=7hr4q z59v3lYgY$$Oe*M0oG>Ypj6-%N?}uac1!+2Zn7Cv05^77)4ED>|Ldmr@J715h<)LwF ziYrS^iaeT(+_2ea&Dl$}e6wPPPl$fSeVcH*Dk9H>FI+urw*Q1=i}JMYQ9e&&%hJ`D@gtX$%q2wuI-iE=D3a@e{z5F^LsY!MKCefhI9bU{<08;9UI+5|?Ojibwr8Hs_` zm58r3M@q(|HuAnpUHzbeqQZ*0wB{r%z|bG*)%Li|!YXZ0t(@0G4yz2*sWZru-_lc< zTQy+*64BUaCvvoI(3vey^+|~pcgYI|zsm%KDp#EG&vE99{lJx=3e1vA*_Ov$gZej_&C?Am_5u`KBp?jkzZaW>~%y?xaIKz0@E@DAnk z?8hDeV}*zZ28pET4M`M5cM5}kKS7M%-#Ud9h?(RYExL|y`-?}bNBSB-A}xm|hL=f| zTUnLIxBOgrRvw|bQVM=hGY|>iIb)Ex&H<%Gls*4Q{y#5 z%_!zQQja7oH$KZ`WVfz!;h%LQ-cHUqsPRc(zD*+;}~LTj6 z6rk&8diISTLf)9IgnwY>m4GeIV?k8&rN77|tE%?2(+{n)4?=CpN29@cm z#am#@(LJHZXAcV-c&FF@JE)*OBWAd1&2C|QNPl^4Hdm>_ZGnf%4RDh0M%`-nt(?|0 zL+&Ubj(%KgWK^jqSNZVps|+j_2jK@r=`lE!-RJ4&=VwWmJ9nbc`}{V`LL2?UP31f} zTE}`=MwSSn$d3EDw|kC4{m!42YVifS%x2ZSZK`14T6nQV$Tt8g*Xc zh6d*ti%&lJHuj4*_jZ5HWm$1=Kbrtg`wZry#S_NPN-v4A=r`CVo|T;Sh3UVa!NGFa zX)8DIr)iy!CTO@)8Uu%lYS?8WVDP1Y1Ox+5Yw zyRp_{o53^twU?YQLLUbCMAe6-&c5@hS`DDpaN$!N?-9l|;(IR9-{xkCjg8JFErtaa z-SkERtrAWWhq~~uDB&KSkJOHiX26QIPIdaUy|Q(+`h~h?paL6Cy=rYoDH=pN#y|X^ zCrF?h0BQ_C*DgoLjY+1mjsQKR!nO-dk`aHj{Q+LlB(6wFKcAD!vOO>@vL6&3_!3G` zNfemt?E5>-uz=?``bHiRO2-$)CmClj;1LoKo2qZNg)wcs%ZUwdoN1ei>sW4Wy(2{w zB1XATJo;O`8p4bT(ATKc>Sq>{o|TR>-yHw3jM6w%K{>e^wiCyRkI>cqrFD04qgRFr z8(K2|RJQDD94`ai^GEqmHm+ZUMHW8k^l^w3xW`S=Ik>CE@x{P#h7R<9i4{n}e%n_B z$r2&Q#>tVP_&t>EGCadc4*0Osj<#d5H8$t|sW#WJ$NPI&ni1+t%G3{XJi+Bv5ghy5 z%Q7s7I(J7Cl&`f?-|<&Mc0y50$lVo0N?|ETYt+k(%v~M(t!U&-Q)BG)tR=Mc6jl6? z24p3R&d)l7*W*iM64C|u+KonK3Q54bWk>jL{gc_4$EN^&v#bZh={(4mJl`ANr^#>ZNuV5~8L7Fof&#gM_} zZuycM3n~Fb8U<#Uipb$z^mMD3z*SiZP`<-_jYtJiYYuJEySPtGhwkr7sks)-6r@VJ zRhV!4QOc}$3*tbKv*d)T{lfiqj{QV{>i432{e@+eSL!>x_xG&F7w$Vn>6Q99X7HG| z$D|rLC?JFm&GIbS#VN^@G!kRb5F^26*{^9fYCFLEEK-`cO^e{~9SBDy5)Tu92JBqh z5nt+qm!2jt3V#G&&8b>R%H+!sYZ(Ih3`49CL40^1F9(O~$Xu;$(w}dO`tNqZ#;kRA zx||pY$`ehJmFiesU;Q|9E>;%m_S)4L-+YdEz}Hc*wfC8P-`DQx+NHwKSHyrD4Q|BK zQq*kQO30jMX~9nLxtT;M^HAT)hHvMv_8{82ijQPHE=^}653s?Mj<*XX`AhjS>mCoS z1y*I9(P}gc3CTKSqcJOKp_I%TRBJqHRWG>9`n74Uzr7rx{r80eX3q>u*pmwRGe;-E z(D3U*`)@-s12V?;2v4DX+;4BI!chOctx*3vnM-1a=QsH1|H<(;k=)*iCatbzN(k^v NR!UK_PTV-;e*j&FbXoua literal 0 HcmV?d00001 From 8a42520dc8803eb0fec05ee914546f7ecd38bf0b Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Wed, 27 Nov 2024 23:01:12 +0100 Subject: [PATCH 37/49] add local search --- leetcode_101/docusaurus.config.ts | 13 +- leetcode_101/package-lock.json | 535 ++++++++++++++++++++++++++++++ leetcode_101/package.json | 1 + 3 files changed, 546 insertions(+), 3 deletions(-) diff --git a/leetcode_101/docusaurus.config.ts b/leetcode_101/docusaurus.config.ts index 67644ea9..92d92175 100644 --- a/leetcode_101/docusaurus.config.ts +++ b/leetcode_101/docusaurus.config.ts @@ -50,9 +50,7 @@ const config: Config = { { docs: { routeBasePath: "/", - sidebarPath: "./sidebars.ts", - // editUrl: - // "https://github.com/noworneverev/leetcode_101/tree/master/leetcode_101", + sidebarPath: "./sidebars.ts", remarkPlugins: [remarkMath], rehypePlugins: [rehypeKatex], }, @@ -63,6 +61,15 @@ const config: Config = { } satisfies Preset.Options, ], ], + themes: [ + [ + require.resolve("@easyops-cn/docusaurus-search-local"), + ({ + hashed: true, // Ensures search indexes are hashed for cache busting + language: ['en', 'zh'], // Add languages as needed, e.g., ['en', 'zh'] + }), + ], + ], stylesheets: [ { href: 'https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css', diff --git a/leetcode_101/package-lock.json b/leetcode_101/package-lock.json index c6006127..a75c98bc 100644 --- a/leetcode_101/package-lock.json +++ b/leetcode_101/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@docusaurus/core": "3.6.1", "@docusaurus/preset-classic": "3.6.1", + "@easyops-cn/docusaurus-search-local": "^0.46.1", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", "prism-react-renderer": "^2.3.0", @@ -2914,6 +2915,147 @@ "node": ">=18.0" } }, + "node_modules/@easyops-cn/autocomplete.js": { + "version": "0.38.1", + "resolved": "https://registry.npmjs.org/@easyops-cn/autocomplete.js/-/autocomplete.js-0.38.1.tgz", + "integrity": "sha512-drg76jS6syilOUmVNkyo1c7ZEBPcPuK+aJA7AksM5ZIIbV57DMHCywiCr+uHyv8BE5jUTU98j/H7gVrkHrWW3Q==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "immediate": "^3.2.3" + } + }, + "node_modules/@easyops-cn/docusaurus-search-local": { + "version": "0.46.1", + "resolved": "https://registry.npmjs.org/@easyops-cn/docusaurus-search-local/-/docusaurus-search-local-0.46.1.tgz", + "integrity": "sha512-kgenn5+pctVlJg8s1FOAm9KuZLRZvkBTMMGJvTTcvNTmnFIHVVYzYfA2Eg+yVefzsC8/cSZGKKJ0kLf8I+mQyw==", + "license": "MIT", + "dependencies": { + "@docusaurus/plugin-content-docs": "^2 || ^3", + "@docusaurus/theme-translations": "^2 || ^3", + "@docusaurus/utils": "^2 || ^3", + "@docusaurus/utils-common": "^2 || ^3", + "@docusaurus/utils-validation": "^2 || ^3", + "@easyops-cn/autocomplete.js": "^0.38.1", + "@node-rs/jieba": "^1.6.0", + "cheerio": "^1.0.0", + "clsx": "^1.1.1", + "comlink": "^4.4.2", + "debug": "^4.2.0", + "fs-extra": "^10.0.0", + "klaw-sync": "^6.0.0", + "lunr": "^2.3.9", + "lunr-languages": "^1.4.0", + "mark.js": "^8.11.1", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "@docusaurus/theme-common": "^2 || ^3", + "react": "^16.14.0 || ^17 || ^18", + "react-dom": "^16.14.0 || 17 || ^18" + } + }, + "node_modules/@easyops-cn/docusaurus-search-local/node_modules/cheerio": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz", + "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==", + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "encoding-sniffer": "^0.2.0", + "htmlparser2": "^9.1.0", + "parse5": "^7.1.2", + "parse5-htmlparser2-tree-adapter": "^7.0.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^6.19.5", + "whatwg-mimetype": "^4.0.0" + }, + "engines": { + "node": ">=18.17" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/@easyops-cn/docusaurus-search-local/node_modules/clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@easyops-cn/docusaurus-search-local/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@easyops-cn/docusaurus-search-local/node_modules/htmlparser2": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.3.1.tgz", + "integrity": "sha512-pVGjBIt1Y6gg3EJN8jTcfpP/+uuRksIo055oE/OBkDNcjZqVbfkWCksG1Jp4yZnj3iKWyWX8fdG/j6UDYPbFog==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.0.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.1.tgz", + "integrity": "sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.1.tgz", + "integrity": "sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@hapi/hoek": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", @@ -3075,6 +3217,271 @@ "react": ">=16" } }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.5.tgz", + "integrity": "sha512-kwUxR7J9WLutBbulqg1dfOrMTwhMdXLdcGUhcbCcGwnPLt3gz19uHVdwH1syKVDbE022ZS2vZxOWflFLS0YTjw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.1.0", + "@emnapi/runtime": "^1.1.0", + "@tybys/wasm-util": "^0.9.0" + } + }, + "node_modules/@node-rs/jieba": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba/-/jieba-1.10.4.tgz", + "integrity": "sha512-GvDgi8MnBiyWd6tksojej8anIx18244NmIOc1ovEw8WKNUejcccLfyu8vj66LWSuoZuKILVtNsOy4jvg3aoxIw==", + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@node-rs/jieba-android-arm-eabi": "1.10.4", + "@node-rs/jieba-android-arm64": "1.10.4", + "@node-rs/jieba-darwin-arm64": "1.10.4", + "@node-rs/jieba-darwin-x64": "1.10.4", + "@node-rs/jieba-freebsd-x64": "1.10.4", + "@node-rs/jieba-linux-arm-gnueabihf": "1.10.4", + "@node-rs/jieba-linux-arm64-gnu": "1.10.4", + "@node-rs/jieba-linux-arm64-musl": "1.10.4", + "@node-rs/jieba-linux-x64-gnu": "1.10.4", + "@node-rs/jieba-linux-x64-musl": "1.10.4", + "@node-rs/jieba-wasm32-wasi": "1.10.4", + "@node-rs/jieba-win32-arm64-msvc": "1.10.4", + "@node-rs/jieba-win32-ia32-msvc": "1.10.4", + "@node-rs/jieba-win32-x64-msvc": "1.10.4" + } + }, + "node_modules/@node-rs/jieba-android-arm-eabi": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba-android-arm-eabi/-/jieba-android-arm-eabi-1.10.4.tgz", + "integrity": "sha512-MhyvW5N3Fwcp385d0rxbCWH42kqDBatQTyP8XbnYbju2+0BO/eTeCCLYj7Agws4pwxn2LtdldXRSKavT7WdzNA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/jieba-android-arm64": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba-android-arm64/-/jieba-android-arm64-1.10.4.tgz", + "integrity": "sha512-XyDwq5+rQ+Tk55A+FGi6PtJbzf974oqnpyCcCPzwU3QVXJCa2Rr4Lci+fx8oOpU4plT3GuD+chXMYLsXipMgJA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/jieba-darwin-arm64": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba-darwin-arm64/-/jieba-darwin-arm64-1.10.4.tgz", + "integrity": "sha512-G++RYEJ2jo0rxF9626KUy90wp06TRUjAsvY/BrIzEOX/ingQYV/HjwQzNPRR1P1o32a6/U8RGo7zEBhfdybL6w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/jieba-darwin-x64": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba-darwin-x64/-/jieba-darwin-x64-1.10.4.tgz", + "integrity": "sha512-MmDNeOb2TXIZCPyWCi2upQnZpPjAxw5ZGEj6R8kNsPXVFALHIKMa6ZZ15LCOkSTsKXVC17j2t4h+hSuyYb6qfQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/jieba-freebsd-x64": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba-freebsd-x64/-/jieba-freebsd-x64-1.10.4.tgz", + "integrity": "sha512-/x7aVQ8nqUWhpXU92RZqd333cq639i/olNpd9Z5hdlyyV5/B65LLy+Je2B2bfs62PVVm5QXRpeBcZqaHelp/bg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/jieba-linux-arm-gnueabihf": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba-linux-arm-gnueabihf/-/jieba-linux-arm-gnueabihf-1.10.4.tgz", + "integrity": "sha512-crd2M35oJBRLkoESs0O6QO3BBbhpv+tqXuKsqhIG94B1d02RVxtRIvSDwO33QurxqSdvN9IeSnVpHbDGkuXm3g==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/jieba-linux-arm64-gnu": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba-linux-arm64-gnu/-/jieba-linux-arm64-gnu-1.10.4.tgz", + "integrity": "sha512-omIzNX1psUzPcsdnUhGU6oHeOaTCuCjUgOA/v/DGkvWC1jLcnfXe4vdYbtXMh4XOCuIgS1UCcvZEc8vQLXFbXQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/jieba-linux-arm64-musl": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba-linux-arm64-musl/-/jieba-linux-arm64-musl-1.10.4.tgz", + "integrity": "sha512-Y/tiJ1+HeS5nnmLbZOE+66LbsPOHZ/PUckAYVeLlQfpygLEpLYdlh0aPpS5uiaWMjAXYZYdFkpZHhxDmSLpwpw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/jieba-linux-x64-gnu": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba-linux-x64-gnu/-/jieba-linux-x64-gnu-1.10.4.tgz", + "integrity": "sha512-WZO8ykRJpWGE9MHuZpy1lu3nJluPoeB+fIJJn5CWZ9YTVhNDWoCF4i/7nxz1ntulINYGQ8VVuCU9LD86Mek97g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/jieba-linux-x64-musl": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba-linux-x64-musl/-/jieba-linux-x64-musl-1.10.4.tgz", + "integrity": "sha512-uBBD4S1rGKcgCyAk6VCKatEVQb6EDD5I40v/DxODi5CuZVCANi9m5oee/MQbAoaX7RydA2f0OSCE9/tcwXEwUg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/jieba-wasm32-wasi": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba-wasm32-wasi/-/jieba-wasm32-wasi-1.10.4.tgz", + "integrity": "sha512-Y2umiKHjuIJy0uulNDz9SDYHdfq5Hmy7jY5nORO99B4pySKkcrMjpeVrmWXJLIsEKLJwcCXHxz8tjwU5/uhz0A==", + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.3" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@node-rs/jieba-win32-arm64-msvc": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba-win32-arm64-msvc/-/jieba-win32-arm64-msvc-1.10.4.tgz", + "integrity": "sha512-nwMtViFm4hjqhz1it/juQnxpXgqlGltCuWJ02bw70YUDMDlbyTy3grCJPpQQpueeETcALUnTxda8pZuVrLRcBA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/jieba-win32-ia32-msvc": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba-win32-ia32-msvc/-/jieba-win32-ia32-msvc-1.10.4.tgz", + "integrity": "sha512-DCAvLx7Z+W4z5oKS+7vUowAJr0uw9JBw8x1Y23Xs/xMA4Em+OOSiaF5/tCJqZUCJ8uC4QeImmgDFiBqGNwxlyA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/jieba-win32-x64-msvc": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@node-rs/jieba-win32-x64-msvc/-/jieba-win32-x64-msvc-1.10.4.tgz", + "integrity": "sha512-+sqemSfS1jjb+Tt7InNbNzrRh1Ua3vProVvC4BZRPg010/leCbGFFiQHpzcPRfpxAXZrzG5Y0YBTsPzN/I4yHQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -3485,6 +3892,16 @@ "node": ">=10.13.0" } }, + "node_modules/@tybys/wasm-util": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz", + "integrity": "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@types/acorn": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", @@ -5156,6 +5573,12 @@ "node": ">=10" } }, + "node_modules/comlink": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/comlink/-/comlink-4.4.2.tgz", + "integrity": "sha512-OxGdvBmJuNKSCMO4NTl1L47VRp6xn2wG4F/2hYzB6tiCb709otOxtEYCSvK80PtjODfXXZu8ds+Nw5kVCjqd2g==", + "license": "Apache-2.0" + }, "node_modules/comma-separated-tokens": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", @@ -6252,6 +6675,31 @@ "node": ">= 0.8" } }, + "node_modules/encoding-sniffer": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz", + "integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==", + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } + }, + "node_modules/encoding-sniffer/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/enhanced-resolve": { "version": "5.17.1", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", @@ -8246,6 +8694,12 @@ "node": ">=16.x" } }, + "node_modules/immediate": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", + "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==", + "license": "MIT" + }, "node_modules/immer": { "version": "9.0.21", "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", @@ -8857,6 +9311,15 @@ "node": ">=0.10.0" } }, + "node_modules/klaw-sync": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", + "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.11" + } + }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -9032,6 +9495,24 @@ "yallist": "^3.0.2" } }, + "node_modules/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "license": "MIT" + }, + "node_modules/lunr-languages": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/lunr-languages/-/lunr-languages-1.14.0.tgz", + "integrity": "sha512-hWUAb2KqM3L7J5bcrngszzISY4BxrXn/Xhbb9TTCJYEGqlR1nG67/M14sp09+PTIRklobrn57IAxcdcO/ZFyNA==", + "license": "MPL-1.1" + }, + "node_modules/mark.js": { + "version": "8.11.1", + "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", + "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==", + "license": "MIT" + }, "node_modules/markdown-extensions": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", @@ -12055,6 +12536,18 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -15190,6 +15683,15 @@ "node": ">=14.17" } }, + "node_modules/undici": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.0.tgz", + "integrity": "sha512-BUgJXc752Kou3oOIuU1i+yZZypyZRqNPW0vqoMPl8VaoalSfeR0D8/t4iAS3yirs79SSMTxTag+ZC86uswv+Cw==", + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, "node_modules/undici-types": { "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", @@ -16146,6 +16648,39 @@ "node": ">=0.8.0" } }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/leetcode_101/package.json b/leetcode_101/package.json index 427f10a7..4a2a001d 100644 --- a/leetcode_101/package.json +++ b/leetcode_101/package.json @@ -17,6 +17,7 @@ "dependencies": { "@docusaurus/core": "3.6.1", "@docusaurus/preset-classic": "3.6.1", + "@easyops-cn/docusaurus-search-local": "^0.46.1", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", "prism-react-renderer": "^2.3.0", From 4f00ac60495177b172e659d09dc54174eadf18e8 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Wed, 27 Nov 2024 23:24:40 +0100 Subject: [PATCH 38/49] fix local search --- leetcode_101/docusaurus.config.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/leetcode_101/docusaurus.config.ts b/leetcode_101/docusaurus.config.ts index 92d92175..f3241be9 100644 --- a/leetcode_101/docusaurus.config.ts +++ b/leetcode_101/docusaurus.config.ts @@ -1,6 +1,7 @@ import { themes as prismThemes } from "prism-react-renderer"; import remarkMath from 'remark-math'; import rehypeKatex from 'rehype-katex'; +import localSearchPlugin from '@easyops-cn/docusaurus-search-local'; import type { Config } from "@docusaurus/types"; import type * as Preset from "@docusaurus/preset-classic"; @@ -63,11 +64,14 @@ const config: Config = { ], themes: [ [ - require.resolve("@easyops-cn/docusaurus-search-local"), - ({ + localSearchPlugin, + { hashed: true, // Ensures search indexes are hashed for cache busting language: ['en', 'zh'], // Add languages as needed, e.g., ['en', 'zh'] - }), + docsRouteBasePath: '/', + indexDocs: true, + indexBlog: false, + }, ], ], stylesheets: [ From cab36d91c94938f3df68418ddd0821b83eae4046 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Wed, 27 Nov 2024 23:31:13 +0100 Subject: [PATCH 39/49] fix i18n and footer --- .../docusaurus-plugin-content-docs/current.json | 16 ++++++++-------- .../i18n/en/docusaurus-theme-classic/footer.json | 2 +- .../zh-TW/docusaurus-theme-classic/footer.json | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current.json index 9081fa19..98a9eb63 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current.json +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current.json @@ -67,27 +67,27 @@ "message": "Chapter 8: Clever Math Problem Solving", "description": "The generated-index page description for category 8. 巧解数学问题 in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.9. 神奇的位运算 ": { + "sidebar.tutorialSidebar.category.9. 神奇的位运算": { "message": "9. Magical Bit Manipulation", "description": "The label for category 9. 神奇的位运算 in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.9. 神奇的位运算 .link.generated-index.description": { + "sidebar.tutorialSidebar.category.9. 神奇的位运算.link.generated-index.description": { "message": "Chapter 9: Magical Bit Manipulation", "description": "The generated-index page description for category 9. 神奇的位运算 in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.10. 妙用数据结构 ": { + "sidebar.tutorialSidebar.category.10. 妙用数据结构": { "message": "10. Ingenious Use of Data Structures", "description": "The label for category 10. 妙用数据结构 in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.10. 妙用数据结构 .link.generated-index.description": { + "sidebar.tutorialSidebar.category.10. 妙用数据结构.link.generated-index.description": { "message": "Chapter 10: Ingenious Use of Data Structures", "description": "The generated-index page description for category 10. 妙用数据结构 in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.11. 令人头大的字符串 ": { + "sidebar.tutorialSidebar.category.11. 令人头大的字符串": { "message": "11. Tricky String Problems", "description": "The label for category 11. 令人头大的字符串 in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.11. 令人头大的字符串 .link.generated-index.description": { + "sidebar.tutorialSidebar.category.11. 令人头大的字符串.link.generated-index.description": { "message": "Chapter 11: Tricky String Problems", "description": "The generated-index page description for category 11. 令人头大的字符串 in sidebar tutorialSidebar" }, @@ -115,11 +115,11 @@ "message": "Chapter 14: The Three Musketeers of Pointers: Graphs", "description": "The generated-index page description for category 14. 指针三剑客之三:图 in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.15. 更加复杂的数据结构 ": { + "sidebar.tutorialSidebar.category.15. 更加复杂的数据结构": { "message": "15. More Complex Data Structures", "description": "The label for category 15. 更加复杂的数据结构 in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.15. 更加复杂的数据结构 .link.generated-index.description": { + "sidebar.tutorialSidebar.category.15. 更加复杂的数据结构.link.generated-index.description": { "message": "Chapter 15: More Complex Data Structures", "description": "The generated-index page description for category 15. 更加复杂的数据结构 in sidebar tutorialSidebar" } diff --git a/leetcode_101/i18n/en/docusaurus-theme-classic/footer.json b/leetcode_101/i18n/en/docusaurus-theme-classic/footer.json index 7a748fc1..a3c09ca8 100644 --- a/leetcode_101/i18n/en/docusaurus-theme-classic/footer.json +++ b/leetcode_101/i18n/en/docusaurus-theme-classic/footer.json @@ -1,6 +1,6 @@ { "copyright": { - "message": "Copyright © 2024 My Project, Inc. Built with Docusaurus.", + "message": "Copyright © 2024 Chang Gao. Built with Docusaurus.", "description": "The footer copyright" } } diff --git a/leetcode_101/i18n/zh-TW/docusaurus-theme-classic/footer.json b/leetcode_101/i18n/zh-TW/docusaurus-theme-classic/footer.json index 7a748fc1..a3c09ca8 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-theme-classic/footer.json +++ b/leetcode_101/i18n/zh-TW/docusaurus-theme-classic/footer.json @@ -1,6 +1,6 @@ { "copyright": { - "message": "Copyright © 2024 My Project, Inc. Built with Docusaurus.", + "message": "Copyright © 2024 Chang Gao. Built with Docusaurus.", "description": "The footer copyright" } } From 21a77bd04ff9d74898cc09ed1ed323c5358041f1 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Fri, 29 Nov 2024 23:18:38 +0100 Subject: [PATCH 40/49] chapter 2 complexity analysis --- .../12-2-basic-linked-list-operations.mdx | 10 +++++----- .../current/12-linked-lists/12-4-exercises.md | 4 ++-- .../2-1-algorithm-explanation.md | 2 +- .../2-two-pointer-techniques/2-2-two-sum.mdx | 8 +++++++- .../2-3-merge-sorted-arrays.mdx | 7 ++++++- .../2-4-sliding-window.mdx | 7 ++++++- .../2-5-fast-slow-pointers.mdx | 15 ++++++++++----- .../5-1-algorithm-explanation.md | 2 +- .../6-1-algorithm-explanation.md | 2 +- .../7-1-algorithm-explanation.md | 2 +- .../8-5-random-sampling.mdx | 10 +++++----- 11 files changed, 45 insertions(+), 24 deletions(-) diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-2-basic-linked-list-operations.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-2-basic-linked-list-operations.mdx index 1c85be5d..0ac10156 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-2-basic-linked-list-operations.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-2-basic-linked-list-operations.mdx @@ -97,12 +97,12 @@ def reverseList(head: Optional[ListNode]) -> Optional[ListNode]: ### 題目描述 -給定兩個遞增排序的鏈表,將它們合併成一個遞增排序的鏈表。 +給定兩個遞增排序的鏈結串列,將它們合併成一個遞增排序的鏈結串列。 ### 輸入輸出範例 -輸入:兩個鏈表。 -輸出:一個鏈表,表示合併的結果。 +輸入:兩個鏈結串列。 +輸出:一個鏈結串列,表示合併的結果。 ``` Input: 1->2->4, 1->3->4 @@ -209,11 +209,11 @@ def mergeTwoLists( ### 題目描述 -給定一個鏈表,交換每一對相鄰的節點。 +給定一個鏈結串列,交換每一對相鄰的節點。 ### 輸入輸出範例 -輸入一個鏈表,輸出交換後的鏈表。 +輸入一個鏈結串列,輸出交換後的鏈結串列。 ``` Input: 1->2->3->4 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-4-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-4-exercises.md index c3550fca..3310590f 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-4-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-4-exercises.md @@ -20,7 +20,7 @@ sidebar_position: 67 ### [19. Remove Nth Node From End of List](https://leetcode.com/problems/remove-nth-node-from-end-of-list/) -既然可以使用快慢指針找到鏈表的中點,也可以利用類似的方法找到倒數第 N 個節點,無需再次遍歷。 +既然可以使用快慢指針找到鏈結串列的中點,也可以利用類似的方法找到倒數第 N 個節點,無需再次遍歷。 --- @@ -28,4 +28,4 @@ sidebar_position: 67 ### [148. Sort List](https://leetcode.com/problems/sort-list/) -利用快慢指針找到鏈表的中點後,可以對鏈表進行合併排序。 \ No newline at end of file +利用快慢指針找到鏈結串列的中點後,可以對鏈結串列進行合併排序。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-1-algorithm-explanation.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-1-algorithm-explanation.md index d515b54d..bf3b6f8e 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-1-algorithm-explanation.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-1-algorithm-explanation.md @@ -2,7 +2,7 @@ sidebar_position: 5 --- -# 2.1 算法解释 +# 2.1 算法解釋 雙指針主要用於遍歷陣列,兩個指針指向不同的元素,從而協同完成任務。也可以延伸到多個陣列的多個指針。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-2-two-sum.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-2-two-sum.mdx index eb125af4..350f1226 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-2-two-sum.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-2-two-sum.mdx @@ -69,4 +69,10 @@ def twoSum(numbers: List[int], target: int) -> List[int]: - \ No newline at end of file + + +### 複雜度分析 + +- **時間複雜度**: $O(n)$,其中 $n$ 是陣列的長度。每次迭代中,指針會移動一次,最多執行 $n$ 次迭代。 + +- **空間複雜度**: $O(1)$,只使用了常數額外空間。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-3-merge-sorted-arrays.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-3-merge-sorted-arrays.mdx index d08967c5..e2f8d83f 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-3-merge-sorted-arrays.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-3-merge-sorted-arrays.mdx @@ -65,4 +65,9 @@ def merge(nums1: List[int], m: int, nums2: List[int], n: int) -> None: - \ No newline at end of file + + +### 複雜度分析 + +- **時間複雜度**: $O(m + n)$,遍歷 `nums1` 和 `nums2` 一次。 +- **空間複雜度**: $O(1)$,直接在 `nums1` 上進行操作,未使用額外空間。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-4-sliding-window.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-4-sliding-window.mdx index 500991bb..65cfddd8 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-4-sliding-window.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-4-sliding-window.mdx @@ -105,4 +105,9 @@ def minWindow(s: str, t: str) -> str: - \ No newline at end of file + + +### 複雜度分析 + +- **時間複雜度**: $O(|s| + |t|)$,對字符串 `s` 遍歷一次(窗口擴展和收縮共計 $O(|s|)$),初始化 `t` 的統計需要 $O(|t|)$。 +- **空間複雜度**: $O(|t|)$,字典 `freq` 的大小與 `t` 中的不同字符數量成正比。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-5-fast-slow-pointers.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-5-fast-slow-pointers.mdx index eef1ba6f..c3039691 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-5-fast-slow-pointers.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-5-fast-slow-pointers.mdx @@ -8,13 +8,13 @@ sidebar_position: 9 ### 題目描述 -給定一個鏈表,如果存在環路,找到環路的起始點。 +給定一個鏈結串列,如果存在環路,找到環路的起始點。 ### 輸入輸出範例 -輸入是一個鏈表,輸出是鏈表中的一個節點。如果沒有環路,返回一個空指針。 +輸入是一個鏈結串列,輸出是鏈結串列中的一個節點。如果沒有環路,返回一個空指針。 在這個範例中,值為 2 的節點即為環路的起始點。 -如果沒有特別說明,LeetCode 採用如下的數據結構表示鏈表。 +如果沒有特別說明,LeetCode 採用如下的數據結構表示鏈結串列。 ![alt](https://assets.leetcode.com/uploads/2018/12/07/circularlinkedlist.png) @@ -35,7 +35,7 @@ class ListNode: ### 題解 -針對鏈表找環路的問題,有一個通用解法——快慢指針(Floyd 判圈法)。給定兩個指針,分別命名為 slow 和 fast,起始位置在鏈表的開頭。每次 fast 前進兩步,slow 前進一步。如果 fast 可以走到盡頭,則說明沒有環路;如果 fast 可以無限走下去,則說明一定有環路,且必然存在一個時刻 slow 和 fast 相遇。當 slow 和 fast 第一次相遇時,將 fast 重新移動到鏈表開頭,並 讓 slow 和 fast 每次都前進一步。當 slow 和 fast 第二次相遇時,相遇的節點即為環路的起始點。 +針對鏈結串列找環路的問題,有一個通用解法——快慢指針(Floyd 判圈法)。給定兩個指針,分別命名為 slow 和 fast,起始位置在鏈結串列的開頭。每次 fast 前進兩步,slow 前進一步。如果 fast 可以走到盡頭,則說明沒有環路;如果 fast 可以無限走下去,則說明一定有環路,且必然存在一個時刻 slow 和 fast 相遇。當 slow 和 fast 第一次相遇時,將 fast 重新移動到鏈結串列開頭,並 讓 slow 和 fast 每次都前進一步。當 slow 和 fast 第二次相遇時,相遇的節點即為環路的起始點。 :::warning @@ -95,4 +95,9 @@ def detectCycle(head: Optional[ListNode]) -> Optional[ListNode]: - \ No newline at end of file + + +### 複雜度分析 + +- **時間複雜度**: $O(n)$,其中 $n$ 是鏈結串列的節點數量。`slow` 和 `fast` 分別最多遍歷一次鏈結串列。 +- **空間複雜度**: $O(1)$,只使用了兩個指針,不需要額外的空間。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-1-algorithm-explanation.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-1-algorithm-explanation.md index 98562e8d..b39abea7 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-1-algorithm-explanation.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-1-algorithm-explanation.md @@ -2,6 +2,6 @@ sidebar_position: 21 --- -# 5.1 算法解释 +# 5.1 算法解釋 `深度優先搜尋 (DFS)` 和 `廣度優先搜尋 (BFS)` 是兩種最常見的優先搜尋方法,廣泛應用於圖與樹等結構的搜尋中。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-1-algorithm-explanation.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-1-algorithm-explanation.md index 12462a45..2768d5e5 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-1-algorithm-explanation.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-1-algorithm-explanation.md @@ -2,7 +2,7 @@ sidebar_position: 26 --- -# 6.1 算法解释 +# 6.1 算法解釋 這裡我們引用一下維基百科的描述:「`動態規劃`(Dynamic Programming, DP)在尋找有許多`重疊子問題`情況的最優解時非常有效。它將問題重新分解成子問題。為了避免多次解決這些子問題,它們的結果會逐步被計算並保存,從簡單的問題開始,直到整個問題被解決。因此,動態規劃保存遞迴中的結果,從而避免在解決相同問題時浪費時間⋯⋯ 動態規劃只能應用於有`最優子結構`的問題。最優子結構的意思是,局部最優解能夠決定全局最優解(對某些問題來說這個要求不完全滿足,因此有時需要引入一定的近似)。簡單來說,問題能夠分解成子問題來解決。」 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-1-algorithm-explanation.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-1-algorithm-explanation.md index da404df1..abe36bc5 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-1-algorithm-explanation.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-1-algorithm-explanation.md @@ -2,7 +2,7 @@ sidebar_position: 35 --- -# 7.1 算法解释 +# 7.1 算法解釋 顧名思義,`分治問題`由“分”(divide)和“治”(conquer)兩部分組成,通過把原問題分為子問題,再將子問題進行處理合併,從而實現對原問題的求解。我們在排序章節展示的合併排序就是典型的分治問題,其中“分”即為把大陣列平均分成兩個小陣列,通過遞迴實現,最終我們會得到多個長度為 1 的子陣列;“治”即為把已經排好序的兩個小陣列合併為一個排好序的大陣列,從長度為 1 的子陣列開始,最終合成一個大陣列。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-5-random-sampling.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-5-random-sampling.mdx index 7521bd45..45d1d3f2 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-5-random-sampling.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/8-mathematical-solutions/8-5-random-sampling.mdx @@ -155,11 +155,11 @@ class Solution: ### 題目描述 -給定一個單向鏈表,要求設計一個演算法,可以隨機取得其中的一個數字。 +給定一個單向鏈結串列,要求設計一個演算法,可以隨機取得其中的一個數字。 ### 輸入輸出範例 -輸入是一個單向鏈表,輸出是一個數字,表示鏈表裡其中一個節點的值。 +輸入是一個單向鏈結串列,輸出是一個數字,表示鏈結串列裡其中一個節點的值。 ``` Input: 1->2->3->4->5 @@ -170,9 +170,9 @@ Output: 3 ### 題解 -不同於陣列,在未遍歷完鏈表前,我們無法知道鏈表的總長度。這裡我們可以使用水庫抽樣:遍歷一次鏈表,在遍歷到第 $m$ 個節點時,有 $\frac{1}{m}$ 的概率選擇這個節點覆蓋掉之前的選擇。 +不同於陣列,在未遍歷完鏈結串列前,我們無法知道鏈結串列的總長度。這裡我們可以使用水庫抽樣:遍歷一次鏈結串列,在遍歷到第 $m$ 個節點時,有 $\frac{1}{m}$ 的概率選擇這個節點覆蓋掉之前的選擇。 -我們提供一個簡單的,對於水庫算法隨機性的證明。對於長度為 $n$ 的鏈表的第 $m$ 個節點,最後被抽樣的充要條件是它被選擇,且之後的節點都沒有被選擇。這種情況發生的概率為: +我們提供一個簡單的,對於水庫算法隨機性的證明。對於長度為 $n$ 的鏈結串列的第 $m$ 個節點,最後被抽樣的充要條件是它被選擇,且之後的節點都沒有被選擇。這種情況發生的概率為: $$ \frac{1}{m} × \frac{m}{m+1} × \frac{m+1}{m+2} × · · · × \frac{n−1}{n} = \frac{1}{n} @@ -180,7 +180,7 @@ $$ 因此每個點都有均等的概率被選擇。 -當然,這道題我們也可以預處理鏈表,遍歷一遍之後把它轉化成陣列。 +當然,這道題我們也可以預處理鏈結串列,遍歷一遍之後把它轉化成陣列。 From 300777a00a1141b92ca4c1c8b3cd77cf29496df2 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Sat, 30 Nov 2024 00:43:42 +0100 Subject: [PATCH 41/49] Ch2 exercise solutions --- .../2-two-pointer-techniques/2-6-exercises.md | 169 +++++++++++++++++- 1 file changed, 168 insertions(+), 1 deletion(-) diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-6-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-6-exercises.md index 4d414d7c..0587ea75 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-6-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/2-two-pointer-techniques/2-6-exercises.md @@ -10,22 +10,189 @@ sidebar_position: 10 Two Sum 題目的變形題之一。 +

        + 題解 + +#### 解題思路 + +- 本題需要判斷是否存在兩個非負整數 $a$ 和 $b$,使得 $a^2 + b^2 = c$,其中 $c$ 是輸入的整數。 +- **雙指針法**: + 1. 設置兩個指針:左指針 $a = 0$,右指針 $b = \lfloor \sqrt{c} \rfloor$。 + 2. 計算當前平方和 $a^2 + b^2$: + - 如果 $a^2 + b^2 = c$,返回 `True`。 + - 如果 $a^2 + b^2 < c$,增加 $a$。 + - 如果 $a^2 + b^2 > c$,減少 $b$。 + 3. 如果指針相交且沒有找到結果,返回 `False`。 + +```python +class Solution: + def judgeSquareSum(self, c: int) -> bool: + a, b = 0, int(c**0.5) # 初始化指針 + while a <= b: + square_sum = a * a + b * b + if square_sum == c: + return True + elif square_sum < c: + a += 1 # 增加左指針 + else: + b -= 1 # 減少右指針 + return False +``` + +#### 複雜度分析 + +- **時間複雜度**: $O(\sqrt{c})$,指針從兩端向中間收攏,最多執行 $\sqrt{c}$ 次迭代。 +- **空間複雜度**: $O(1)$,僅使用了固定數量的變數。 + +
        + + --- ### [680. Valid Palindrome II](https://leetcode.com/problems/valid-palindrome-ii/) Two Sum 題目的變形題之二。 +
        + 題解 + +#### 解題思路 + +- 本題需要判斷一個字符串是否可以通過刪除最多一個字符後,成為回文字符串。 +- **雙指針法**: + 1. 設置左右指針 `l` 和 `r`,分別指向字符串的頭部和尾部。 + 2. 如果 `s[l] == s[r]`,則將指針向中間移動。 + 3. 如果 `s[l] != s[r]`: + - 刪除左邊字符(檢查子串 `s[l+1:r+1]`)或右邊字符(檢查子串 `s[l:r]`)。 + - 如果任意一個子串是回文,則返回 `True`。 + 4. 如果左右指針正常移動到中間,說明原字符串是回文,返回 `True`。 + +- **輔助函數**: + 使用一個函數檢查子串是否是回文。 + +```python +class Solution: + def validPalindrome(self, s: str) -> bool: + def is_palindrome(sub: str) -> bool: + return sub == sub[::-1] + + l, r = 0, len(s) - 1 + while l < r: + if s[l] == s[r]: + l += 1 + r -= 1 + else: + return is_palindrome(s[l+1:r+1]) or is_palindrome(s[l:r]) + return True +``` + +#### 複雜度分析 + +- **時間複雜度**: $O(n)$,其中 $n$ 是字符串的長度。主迴圈遍歷字符串一次,檢查回文子串的操作最多進行一次,總計為線性時間。 +- **空間複雜度**: $O(1)$,除了輔助函數外,未使用額外空間。 + +
        + --- ### [524. Longest Word in Dictionary through Deleting](https://leetcode.com/problems/longest-word-in-dictionary-through-deleting/) 合併兩個有序陣列的變形題。 +
        + 題解 + +#### 解題思路 + +- 本題要求找出可以通過刪除字符串中若干字符而得到的最長單詞。如果有多個單詞的長度相同,返回字典序最小的單詞。 +- **雙指針法**: + 1. 對字典中的單詞列表按長度降序、字典序升序排序,保證先處理最長且字典序最小的單詞。 + 2. 遍歷排序後的單詞列表,檢查每個單詞是否是給定字符串的子序列。 + 3. 使用雙指針檢查是否為子序列: + - 指針 `i` 遍歷字符串 `s`,指針 `j` 遍歷目標單詞。 + - 如果 `s[i] == word[j]`,則移動 `j`。 + - 如果 `j` 能到達目標單詞的末尾,說明該單詞是子序列。 + +- 返回第一個滿足條件的單詞。 + +```python +class Solution: + def findLongestWord(self, s: str, dictionary: List[str]) -> str: + def is_subsequence(word: str, s: str) -> bool: + i, j = 0, 0 + while i < len(s) and j < len(word): + if s[i] == word[j]: + j += 1 + i += 1 + return j == len(word) + + dictionary.sort(key=lambda x: (-len(x), x)) # 長度降序,字典序升序 + for word in dictionary: + if is_subsequence(word, s): + return word + return "" +``` + +#### 複雜度分析 + +- **時間複雜度**: $O(m \cdot n)$,其中 $m$ 是字典中單詞的數量,$n$ 是字符串 `s` 的長度。排序的複雜度為 $O(m \log m)$,每個單詞的子序列檢查需要 $O(n)$。 +- **空間複雜度**: $O(1)$,除了排序和雙指針檢查外,未使用額外空間。 + +
        + + --- ## 進階難度 ### [340. Longest Substring with At Most K Distinct Characters](https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/) -需要利用其他數據結構方便統計當前的字符狀態。 \ No newline at end of file +需要利用其他數據結構方便統計當前的字符狀態。 + +
        + 題解 + +#### 解題思路 + +- 本題要求找到字串中最多包含 $k$ 種不同字元的最長子字串,適合使用 **滑動窗口法**: + 1. 使用雙指針 `l` 和 `r` 表示當前窗口的左右邊界,並用 `defaultdict(int)` 記錄窗口中每個字元的出現次數。 + 2. 當窗口中的字元種類數量超過 $k$ 時,通過移動左指針 `l` 縮小窗口,直到字元種類數量不超過 $k$。 + 3. 在每一步中,更新最長子字串的長度。 + +- **步驟**: + 1. 初始化一個 `defaultdict(int)` 來記錄字元出現次數。 + 2. 右指針 `r` 向右移動,將字元加入窗口,更新次數。 + 3. 當窗口內字元種類數量超過 $k$,左指針 `l` 向右移動,直到種類數量不超過 $k$。 + 4. 在每一步中記錄當前窗口的長度,並更新最長子字串的長度。 + +```python +from collections import defaultdict + +class Solution: + def lengthOfLongestSubstringKDistinct(self, s: str, k: int) -> int: + if k == 0 or not s: + return 0 + + freq = defaultdict(int) + l, max_length = 0, 0 + + for r in range(len(s)): + freq[s[r]] += 1 # 更新右指針字元出現次數 + + while len(freq) > k: # 縮小窗口直到字元種類不超過 k + freq[s[l]] -= 1 + if freq[s[l]] == 0: + del freq[s[l]] + l += 1 + + max_length = max(max_length, r - l + 1) # 更新最長長度 + + return max_length +``` + +#### 複雜度分析 + +- **時間複雜度**: $O(n)$,其中 $n$ 是字串的長度。右指針遍歷字串一次,左指針最多遍歷字串一次。 +- **空間複雜度**: $O(k)$,雜湊表最多儲存 $k$ 種字元及其出現次數。 + +
        From 8daf2f87c07598ee00830ed9abdfd3f730404b72 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Sun, 1 Dec 2024 00:03:06 +0100 Subject: [PATCH 42/49] Ch3 complexity analysis --- .../3-binary-search-techniques/3-2-square-root.mdx | 8 +++++++- .../3-binary-search-techniques/3-3-interval-search.mdx | 7 ++++++- .../3-binary-search-techniques/3-4-peak-finding.mdx | 7 ++++++- .../3-5-rotated-array-search.mdx | 7 ++++++- 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-2-square-root.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-2-square-root.mdx index b072e9fe..65038daa 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-2-square-root.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-2-square-root.mdx @@ -72,6 +72,11 @@ def mySqrt(x: int) -> int:
        +### 複雜度分析 + +- **時間複雜度**: $O(\log x)$,因為每次迭代將搜索範圍縮小一半。 +- **空間複雜度**: $O(1)$,只使用了常數額外空間。 + 此外,這道題還有一種更快的算法——`牛頓迭代法`,其公式為 $t_{n+1} = t_n - \frac{f(t_n)}{f'(t_n)}$。給定 $f(t) = t^2 − x = 0$,其迭代公式為 $t_{n+1} = \frac{t_n + \frac{x}{t_n}}{2}$。 @@ -100,4 +105,5 @@ def mySqrt(x: int) -> int:
        -
        \ No newline at end of file +
        + diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-3-interval-search.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-3-interval-search.mdx index b3b777fc..327ac7e8 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-3-interval-search.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-3-interval-search.mdx @@ -106,4 +106,9 @@ def searchRange(nums: List[int], target: int) -> List[int]:
        -
        \ No newline at end of file + + +### 複雜度分析 + +- **時間複雜度**: $O(\log n)$,其中 $n$ 是陣列的長度。`lowerBound` 和 `upperBound` 各執行一次二分搜尋,每次操作將搜索範圍減半。 +- **空間複雜度**: $O(1)$,只使用了常數額外空間。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-4-peak-finding.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-4-peak-finding.mdx index 97d8151f..41e8222d 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-4-peak-finding.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-4-peak-finding.mdx @@ -83,4 +83,9 @@ def findPeakElement(self, nums: List[int]) -> int: - \ No newline at end of file + + +### 複雜度分析 + +- **時間複雜度**: $O(\log n)$,其中 $n$ 是陣列的長度。每次迭代將搜索範圍縮小一半。 +- **空間複雜度**: $O(1)$,只使用了常數額外空間。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-5-rotated-array-search.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-5-rotated-array-search.mdx index c300716f..608c4dfe 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-5-rotated-array-search.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-5-rotated-array-search.mdx @@ -95,4 +95,9 @@ def search(nums: List[int], target: int) -> bool: - \ No newline at end of file + + +### 複雜度分析 + +- **時間複雜度**: $O(n)$,在最壞情況下,陣列中所有元素都相同,導致每次只能排除一個元素。 +- **空間複雜度**: $O(1)$,只使用了常數額外空間。 \ No newline at end of file From 67b0833d6b0a4e058abce01c3aa3ceb8c8b2d310 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Sun, 1 Dec 2024 09:45:29 +0100 Subject: [PATCH 43/49] Upgrade Docusaurus packages --- leetcode_101/package-lock.json | 2812 +++++++++++++++++++++++++++----- leetcode_101/package.json | 10 +- 2 files changed, 2454 insertions(+), 368 deletions(-) diff --git a/leetcode_101/package-lock.json b/leetcode_101/package-lock.json index a75c98bc..c72e57fe 100644 --- a/leetcode_101/package-lock.json +++ b/leetcode_101/package-lock.json @@ -8,8 +8,8 @@ "name": "leetcode-101", "version": "0.0.0", "dependencies": { - "@docusaurus/core": "3.6.1", - "@docusaurus/preset-classic": "3.6.1", + "@docusaurus/core": "^3.6.3", + "@docusaurus/preset-classic": "^3.6.3", "@easyops-cn/docusaurus-search-local": "^0.46.1", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", @@ -20,9 +20,9 @@ "remark-math": "^6.0.0" }, "devDependencies": { - "@docusaurus/module-type-aliases": "3.6.1", - "@docusaurus/tsconfig": "3.6.1", - "@docusaurus/types": "3.6.1", + "@docusaurus/module-type-aliases": "^3.6.3", + "@docusaurus/tsconfig": "^3.6.3", + "@docusaurus/types": "^3.6.3", "typescript": "~5.6.2" }, "engines": { @@ -30,34 +30,34 @@ } }, "node_modules/@algolia/autocomplete-core": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.17.6.tgz", - "integrity": "sha512-lkDoW4I7h2kKlIgf3pUt1LqvxyYKkVyiypoGLlUnhPSnCpmeOwudM6rNq6YYsCmdQtnDQoW5lUNNuj6ASg3qeg==", + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.17.7.tgz", + "integrity": "sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q==", "license": "MIT", "dependencies": { - "@algolia/autocomplete-plugin-algolia-insights": "1.17.6", - "@algolia/autocomplete-shared": "1.17.6" + "@algolia/autocomplete-plugin-algolia-insights": "1.17.7", + "@algolia/autocomplete-shared": "1.17.7" } }, "node_modules/@algolia/autocomplete-plugin-algolia-insights": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.17.6.tgz", - "integrity": "sha512-17NnaacuFzSWVuZu4NKzVeaFIe9Abpw8w+/gjc7xhZFtqj+GadufzodIdchwiB2eM2cDdiR3icW7gbNTB3K2YA==", + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.17.7.tgz", + "integrity": "sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A==", "license": "MIT", "dependencies": { - "@algolia/autocomplete-shared": "1.17.6" + "@algolia/autocomplete-shared": "1.17.7" }, "peerDependencies": { "search-insights": ">= 1 < 3" } }, "node_modules/@algolia/autocomplete-preset-algolia": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.6.tgz", - "integrity": "sha512-Cvg5JENdSCMuClwhJ1ON1/jSuojaYMiUW2KePm18IkdCzPJj/NXojaOxw58RFtQFpJgfVW8h2E8mEoDtLlMdeA==", + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.7.tgz", + "integrity": "sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA==", "license": "MIT", "dependencies": { - "@algolia/autocomplete-shared": "1.17.6" + "@algolia/autocomplete-shared": "1.17.7" }, "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", @@ -65,9 +65,9 @@ } }, "node_modules/@algolia/autocomplete-shared": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.6.tgz", - "integrity": "sha512-aq/3V9E00Tw2GC/PqgyPGXtqJUlVc17v4cn1EUhSc+O/4zd04Uwb3UmPm8KDaYQQOrkt1lwvCj2vG2wRE5IKhw==", + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.7.tgz", + "integrity": "sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg==", "license": "MIT", "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", @@ -99,15 +99,15 @@ } }, "node_modules/@algolia/client-abtesting": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.13.0.tgz", - "integrity": "sha512-6CoQjlMi1pmQYMQO8tXfuGxSPf6iKX5FP9MuMe6IWmvC81wwTvOehnwchyBl2wuPVhcw2Ar53K53mQ60DAC64g==", + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.15.0.tgz", + "integrity": "sha512-FaEM40iuiv1mAipYyiptP4EyxkJ8qHfowCpEeusdHUC4C7spATJYArD2rX3AxkVeREkDIgYEOuXcwKUbDCr7Nw==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.13.0", - "@algolia/requester-browser-xhr": "5.13.0", - "@algolia/requester-fetch": "5.13.0", - "@algolia/requester-node-http": "5.13.0" + "@algolia/client-common": "5.15.0", + "@algolia/requester-browser-xhr": "5.15.0", + "@algolia/requester-fetch": "5.15.0", + "@algolia/requester-node-http": "5.15.0" }, "engines": { "node": ">= 14.0.0" @@ -179,24 +179,24 @@ } }, "node_modules/@algolia/client-common": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.13.0.tgz", - "integrity": "sha512-2SP6bGGWOTN920MLZv8s7yIR3OqY03vEe4U+vb2MGdL8a/8EQznF3L/nTC/rGf/hvEfZlX2tGFxPJaF2waravg==", + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.15.0.tgz", + "integrity": "sha512-IofrVh213VLsDkPoSKMeM9Dshrv28jhDlBDLRcVJQvlL8pzue7PEB1EZ4UoJFYS3NSn7JOcJ/V+olRQzXlJj1w==", "license": "MIT", "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-insights": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.13.0.tgz", - "integrity": "sha512-ldHTe+LVgC6L4Wr6doAQQ7Ku0jAdhaaPg1T+IHzmmiRZb2Uq5OsjW2yC65JifOmzPCiMkIZE2mGRpWgkn5ktlw==", + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.15.0.tgz", + "integrity": "sha512-bDDEQGfFidDi0UQUCbxXOCdphbVAgbVmxvaV75cypBTQkJ+ABx/Npw7LkFGw1FsoVrttlrrQbwjvUB6mLVKs/w==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.13.0", - "@algolia/requester-browser-xhr": "5.13.0", - "@algolia/requester-fetch": "5.13.0", - "@algolia/requester-node-http": "5.13.0" + "@algolia/client-common": "5.15.0", + "@algolia/requester-browser-xhr": "5.15.0", + "@algolia/requester-fetch": "5.15.0", + "@algolia/requester-node-http": "5.15.0" }, "engines": { "node": ">= 14.0.0" @@ -224,30 +224,30 @@ } }, "node_modules/@algolia/client-query-suggestions": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.13.0.tgz", - "integrity": "sha512-pYo0jbLUtPDN1r341UHTaF2fgN5rbaZfDZqjPRKPM+FRlRmxFxqFQm1UUfpkSUWYGn7lECwDpbKYiKUf81MTwA==", + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.15.0.tgz", + "integrity": "sha512-wu8GVluiZ5+il8WIRsGKu8VxMK9dAlr225h878GGtpTL6VBvwyJvAyLdZsfFIpY0iN++jiNb31q2C1PlPL+n/A==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.13.0", - "@algolia/requester-browser-xhr": "5.13.0", - "@algolia/requester-fetch": "5.13.0", - "@algolia/requester-node-http": "5.13.0" + "@algolia/client-common": "5.15.0", + "@algolia/requester-browser-xhr": "5.15.0", + "@algolia/requester-fetch": "5.15.0", + "@algolia/requester-node-http": "5.15.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-search": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.13.0.tgz", - "integrity": "sha512-s2ge3uZ6Zg2sPSFibqijgEYsuorxcc8KVHg3I95nOPHvFHdnBtSHymhZvq4sp/fu8ijt/Y8jLwkuqm5myn+2Sg==", + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.15.0.tgz", + "integrity": "sha512-Z32gEMrRRpEta5UqVQA612sLdoqY3AovvUPClDfMxYrbdDAebmGDVPtSogUba1FZ4pP5dx20D3OV3reogLKsRA==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.13.0", - "@algolia/requester-browser-xhr": "5.13.0", - "@algolia/requester-fetch": "5.13.0", - "@algolia/requester-node-http": "5.13.0" + "@algolia/client-common": "5.15.0", + "@algolia/requester-browser-xhr": "5.15.0", + "@algolia/requester-fetch": "5.15.0", + "@algolia/requester-node-http": "5.15.0" }, "engines": { "node": ">= 14.0.0" @@ -260,15 +260,15 @@ "license": "MIT" }, "node_modules/@algolia/ingestion": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.13.0.tgz", - "integrity": "sha512-fm5LEOe4FPDOc1D+M9stEs8hfcdmbdD+pt9og5shql6ueTZJANDbFoQhDOpiPJizR/ps1GwmjkWfUEywx3sV+Q==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.15.0.tgz", + "integrity": "sha512-MkqkAxBQxtQ5if/EX2IPqFA7LothghVyvPoRNA/meS2AW2qkHwcxjuiBxv4H6mnAVEPfJlhu9rkdVz9LgCBgJg==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.13.0", - "@algolia/requester-browser-xhr": "5.13.0", - "@algolia/requester-fetch": "5.13.0", - "@algolia/requester-node-http": "5.13.0" + "@algolia/client-common": "5.15.0", + "@algolia/requester-browser-xhr": "5.15.0", + "@algolia/requester-fetch": "5.15.0", + "@algolia/requester-node-http": "5.15.0" }, "engines": { "node": ">= 14.0.0" @@ -290,15 +290,15 @@ } }, "node_modules/@algolia/monitoring": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.13.0.tgz", - "integrity": "sha512-e8Hshlnm2G5fapyUgWTBwhJ22yXcnLtPC4LWZKx7KOvv35GcdoHtlUBX94I/sWCJLraUr65JvR8qOo3LXC43dg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.15.0.tgz", + "integrity": "sha512-QPrFnnGLMMdRa8t/4bs7XilPYnoUXDY8PMQJ1sf9ZFwhUysYYhQNX34/enoO0LBjpoOY6rLpha39YQEFbzgKyQ==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.13.0", - "@algolia/requester-browser-xhr": "5.13.0", - "@algolia/requester-fetch": "5.13.0", - "@algolia/requester-node-http": "5.13.0" + "@algolia/client-common": "5.15.0", + "@algolia/requester-browser-xhr": "5.15.0", + "@algolia/requester-fetch": "5.15.0", + "@algolia/requester-node-http": "5.15.0" }, "engines": { "node": ">= 14.0.0" @@ -363,12 +363,12 @@ } }, "node_modules/@algolia/requester-browser-xhr": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.13.0.tgz", - "integrity": "sha512-NV6oSCt5lFuzfsVQoSBpewEWf/h4ySr7pv2bfwu9yF/jc/g39pig8+YpuqsxlRWBm/lTGVA2V0Ai9ySwrNumIA==", + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.15.0.tgz", + "integrity": "sha512-Po/GNib6QKruC3XE+WKP1HwVSfCDaZcXu48kD+gwmtDlqHWKc7Bq9lrS0sNZ456rfCKhXksOmMfUs4wRM/Y96w==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.13.0" + "@algolia/client-common": "5.15.0" }, "engines": { "node": ">= 14.0.0" @@ -381,24 +381,24 @@ "license": "MIT" }, "node_modules/@algolia/requester-fetch": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.13.0.tgz", - "integrity": "sha512-094bK4rumf+rXJazxv3mq6eKRM0ep5AxIo8T0YmOdldswQt79apeufFiPLN19nHEWH22xR2FelimD+T/wRSP+Q==", + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.15.0.tgz", + "integrity": "sha512-rOZ+c0P7ajmccAvpeeNrUmEKoliYFL8aOR5qGW5pFq3oj3Iept7Y5mEtEsOBYsRt6qLnaXn4zUKf+N8nvJpcIw==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.13.0" + "@algolia/client-common": "5.15.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/requester-node-http": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.13.0.tgz", - "integrity": "sha512-JY5xhEYMgki53Wm+A6R2jUpOUdD0zZnBq+PC5R1TGMNOYL1s6JjDrJeMsvaI2YWxYMUSoCnRoltN/yf9RI8n3A==", + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.15.0.tgz", + "integrity": "sha512-b1jTpbFf9LnQHEJP5ddDJKE2sAlhYd7EVSOWgzo/27n/SfCoHfqD0VWntnWYD83PnOKvfe8auZ2+xCb0TXotrQ==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.13.0" + "@algolia/client-common": "5.15.0" }, "engines": { "node": ">= 14.0.0" @@ -2142,6 +2142,1107 @@ "node": ">=0.1.90" } }, + "node_modules/@csstools/cascade-layer-name-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-2.0.4.tgz", + "integrity": "sha512-7DFHlPuIxviKYZrOiwVU/PiHLm3lLUR23OMuEEtfEOQTOp9hzQ2JjdY6X5H18RVuUPJqSCI+qNnD5iOLMVE0bA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.1.tgz", + "integrity": "sha512-MKtmkA0BX87PKaO1NFRTFH+UnkgnmySQOvNxJubsadusqPEC2aJ9MOQiMceZJJ6oitUl/i0L6u0M1IrmAOmgBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.0.tgz", + "integrity": "sha512-X69PmFOrjTZfN5ijxtI8hZ9kRADFSLrmmQ6hgDJ272Il049WGKpDY64KhrFm/7rbWve0z81QepawzjkKlqkNGw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.6.tgz", + "integrity": "sha512-S/IjXqTHdpI4EtzGoNCHfqraXF37x12ZZHA1Lk7zoT5pm2lMjFuqhX/89L7dqX4CcMacKK+6ZCs5TmEGb/+wKw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^5.0.1", + "@csstools/css-calc": "^2.1.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.4.tgz", + "integrity": "sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.3" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.3.tgz", + "integrity": "sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/media-query-list-parser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.2.tgz", + "integrity": "sha512-EUos465uvVvMJehckATTlNqGj4UJWkTmdWuDMjqvSUkjGpmOyFZBVwb4knxCm/k2GMTXY+c/5RkdndzFYWeX5A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" + } + }, + "node_modules/@csstools/postcss-cascade-layers": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-5.0.1.tgz", + "integrity": "sha512-XOfhI7GShVcKiKwmPAnWSqd2tBR0uxt+runAxttbSp/LY2U16yAVPmAf7e9q4JJ0d+xMNmpwNDLBXnmRCl3HMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/selector-specificity": "^5.0.0", + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-cascade-layers/node_modules/@csstools/selector-specificity": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", + "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/@csstools/postcss-cascade-layers/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@csstools/postcss-color-function": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-4.0.6.tgz", + "integrity": "sha512-EcvXfC60cTIumzpsxWuvVjb7rsJEHPvqn3jeMEBUaE3JSc4FRuP7mEQ+1eicxWmIrs3FtzMH9gR3sgA5TH+ebQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.0.6", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/postcss-progressive-custom-properties": "^4.0.0", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-color-mix-function": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-mix-function/-/postcss-color-mix-function-3.0.6.tgz", + "integrity": "sha512-jVKdJn4+JkASYGhyPO+Wa5WXSx1+oUgaXb3JsjJn/BlrtFh5zjocCY7pwWi0nuP24V1fY7glQsxEYcYNy0dMFg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.0.6", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/postcss-progressive-custom-properties": "^4.0.0", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-content-alt-text": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@csstools/postcss-content-alt-text/-/postcss-content-alt-text-2.0.4.tgz", + "integrity": "sha512-YItlZUOuZJCBlRaCf8Aucc1lgN41qYGALMly0qQllrxYJhiyzlI6RxOTMUvtWk+KhS8GphMDsDhKQ7KTPfEMSw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/postcss-progressive-custom-properties": "^4.0.0", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-exponential-functions": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@csstools/postcss-exponential-functions/-/postcss-exponential-functions-2.0.5.tgz", + "integrity": "sha512-mi8R6dVfA2nDoKM3wcEi64I8vOYEgQVtVKCfmLHXupeLpACfGAided5ddMt5f+CnEodNu4DifuVwb0I6fQDGGQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-calc": "^2.1.0", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-font-format-keywords": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-4.0.0.tgz", + "integrity": "sha512-usBzw9aCRDvchpok6C+4TXC57btc4bJtmKQWOHQxOVKen1ZfVqBUuCZ/wuqdX5GHsD0NRSr9XTP+5ID1ZZQBXw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-gamut-mapping": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@csstools/postcss-gamut-mapping/-/postcss-gamut-mapping-2.0.6.tgz", + "integrity": "sha512-0ke7fmXfc8H+kysZz246yjirAH6JFhyX9GTlyRnM0exHO80XcA9zeJpy5pOp5zo/AZiC/q5Pf+Hw7Pd6/uAoYA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.0.6", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-gradients-interpolation-method": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@csstools/postcss-gradients-interpolation-method/-/postcss-gradients-interpolation-method-5.0.6.tgz", + "integrity": "sha512-Itrbx6SLUzsZ6Mz3VuOlxhbfuyLTogG5DwEF1V8dAi24iMuvQPIHd7Ti+pNDp7j6WixndJGZaoNR0f9VSzwuTg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.0.6", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/postcss-progressive-custom-properties": "^4.0.0", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-hwb-function": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-4.0.6.tgz", + "integrity": "sha512-927Pqy3a1uBP7U8sTfaNdZVB0mNXzIrJO/GZ8us9219q9n06gOqCdfZ0E6d1P66Fm0fYHvxfDbfcUuwAn5UwhQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.0.6", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/postcss-progressive-custom-properties": "^4.0.0", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-ic-unit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-4.0.0.tgz", + "integrity": "sha512-9QT5TDGgx7wD3EEMN3BSUG6ckb6Eh5gSPT5kZoVtUuAonfPmLDJyPhqR4ntPpMYhUKAMVKAg3I/AgzqHMSeLhA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^4.0.0", + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-initial": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-initial/-/postcss-initial-2.0.0.tgz", + "integrity": "sha512-dv2lNUKR+JV+OOhZm9paWzYBXOCi+rJPqJ2cJuhh9xd8USVrd0cBEPczla81HNOyThMQWeCcdln3gZkQV2kYxA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-is-pseudo-class": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-5.0.1.tgz", + "integrity": "sha512-JLp3POui4S1auhDR0n8wHd/zTOWmMsmK3nQd3hhL6FhWPaox5W7j1se6zXOG/aP07wV2ww0lxbKYGwbBszOtfQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/selector-specificity": "^5.0.0", + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-is-pseudo-class/node_modules/@csstools/selector-specificity": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", + "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/@csstools/postcss-is-pseudo-class/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@csstools/postcss-light-dark-function": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@csstools/postcss-light-dark-function/-/postcss-light-dark-function-2.0.7.tgz", + "integrity": "sha512-ZZ0rwlanYKOHekyIPaU+sVm3BEHCe+Ha0/px+bmHe62n0Uc1lL34vbwrLYn6ote8PHlsqzKeTQdIejQCJ05tfw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/postcss-progressive-custom-properties": "^4.0.0", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-float-and-clear": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-float-and-clear/-/postcss-logical-float-and-clear-3.0.0.tgz", + "integrity": "sha512-SEmaHMszwakI2rqKRJgE+8rpotFfne1ZS6bZqBoQIicFyV+xT1UF42eORPxJkVJVrH9C0ctUgwMSn3BLOIZldQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-overflow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-overflow/-/postcss-logical-overflow-2.0.0.tgz", + "integrity": "sha512-spzR1MInxPuXKEX2csMamshR4LRaSZ3UXVaRGjeQxl70ySxOhMpP2252RAFsg8QyyBXBzuVOOdx1+bVO5bPIzA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-overscroll-behavior": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-overscroll-behavior/-/postcss-logical-overscroll-behavior-2.0.0.tgz", + "integrity": "sha512-e/webMjoGOSYfqLunyzByZj5KKe5oyVg/YSbie99VEaSDE2kimFm0q1f6t/6Jo+VVCQ/jbe2Xy+uX+C4xzWs4w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-resize": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-resize/-/postcss-logical-resize-3.0.0.tgz", + "integrity": "sha512-DFbHQOFW/+I+MY4Ycd/QN6Dg4Hcbb50elIJCfnwkRTCX05G11SwViI5BbBlg9iHRl4ytB7pmY5ieAFk3ws7yyg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-viewport-units": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-viewport-units/-/postcss-logical-viewport-units-3.0.3.tgz", + "integrity": "sha512-OC1IlG/yoGJdi0Y+7duz/kU/beCwO+Gua01sD6GtOtLi7ByQUpcIqs7UE/xuRPay4cHgOMatWdnDdsIDjnWpPw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-media-minmax": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@csstools/postcss-media-minmax/-/postcss-media-minmax-2.0.5.tgz", + "integrity": "sha512-sdh5i5GToZOIAiwhdntRWv77QDtsxP2r2gXW/WbLSCoLr00KTq/yiF1qlQ5XX2+lmiFa8rATKMcbwl3oXDMNew==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^2.1.0", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/media-query-list-parser": "^4.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-media-queries-aspect-ratio-number-values": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/postcss-media-queries-aspect-ratio-number-values/-/postcss-media-queries-aspect-ratio-number-values-3.0.4.tgz", + "integrity": "sha512-AnGjVslHMm5xw9keusQYvjVWvuS7KWK+OJagaG0+m9QnIjZsrysD2kJP/tr/UJIyYtMCtu8OkUd+Rajb4DqtIQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/media-query-list-parser": "^4.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-nested-calc": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-4.0.0.tgz", + "integrity": "sha512-jMYDdqrQQxE7k9+KjstC3NbsmC063n1FTPLCgCRS2/qHUbHM0mNy9pIn4QIiQGs9I/Bg98vMqw7mJXBxa0N88A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-normalize-display-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.0.tgz", + "integrity": "sha512-HlEoG0IDRoHXzXnkV4in47dzsxdsjdz6+j7MLjaACABX2NfvjFS6XVAnpaDyGesz9gK2SC7MbNwdCHusObKJ9Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-oklab-function": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-4.0.6.tgz", + "integrity": "sha512-Hptoa0uX+XsNacFBCIQKTUBrFKDiplHan42X73EklG6XmQLG7/aIvxoNhvZ7PvOWMt67Pw3bIlUY2nD6p5vL8A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.0.6", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/postcss-progressive-custom-properties": "^4.0.0", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-progressive-custom-properties": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-4.0.0.tgz", + "integrity": "sha512-XQPtROaQjomnvLUSy/bALTR5VCtTVUFwYs1SblvYgLSeTo2a/bMNwUwo2piXw5rTv/FEYiy5yPSXBqg9OKUx7Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-random-function": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-random-function/-/postcss-random-function-1.0.1.tgz", + "integrity": "sha512-Ab/tF8/RXktQlFwVhiC70UNfpFQRhtE5fQQoP2pO+KCPGLsLdWFiOuHgSRtBOqEshCVAzR4H6o38nhvRZq8deA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-calc": "^2.1.0", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-relative-color-syntax": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@csstools/postcss-relative-color-syntax/-/postcss-relative-color-syntax-3.0.6.tgz", + "integrity": "sha512-yxP618Xb+ji1I624jILaYM62uEmZcmbdmFoZHoaThw896sq0vU39kqTTF+ZNic9XyPtPMvq0vyvbgmHaszq8xg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.0.6", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/postcss-progressive-custom-properties": "^4.0.0", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-scope-pseudo-class": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-scope-pseudo-class/-/postcss-scope-pseudo-class-4.0.1.tgz", + "integrity": "sha512-IMi9FwtH6LMNuLea1bjVMQAsUhFxJnyLSgOp/cpv5hrzWmrUYU5fm0EguNDIIOHUqzXode8F/1qkC/tEo/qN8Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-scope-pseudo-class/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@csstools/postcss-sign-functions": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-sign-functions/-/postcss-sign-functions-1.1.0.tgz", + "integrity": "sha512-SLcc20Nujx/kqbSwDmj6oaXgpy3UjFhBy1sfcqPgDkHfOIfUtUVH7OXO+j7BU4v/At5s61N5ZX6shvgPwluhsA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-calc": "^2.1.0", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-stepped-value-functions": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-4.0.5.tgz", + "integrity": "sha512-G6SJ6hZJkhxo6UZojVlLo14MohH4J5J7z8CRBrxxUYy9JuZiIqUo5TBYyDGcE0PLdzpg63a7mHSJz3VD+gMwqw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-calc": "^2.1.0", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-text-decoration-shorthand": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-4.0.1.tgz", + "integrity": "sha512-xPZIikbx6jyzWvhms27uugIc0I4ykH4keRvoa3rxX5K7lEhkbd54rjj/dv60qOCTisoS+3bmwJTeyV1VNBrXaw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/color-helpers": "^5.0.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-trigonometric-functions": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-4.0.5.tgz", + "integrity": "sha512-/YQThYkt5MLvAmVu7zxjhceCYlKrYddK6LEmK5I4ojlS6BmO9u2yO4+xjXzu2+NPYmHSTtP4NFSamBCMmJ1NJA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-calc": "^2.1.0", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-unset-value": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-4.0.0.tgz", + "integrity": "sha512-cBz3tOCI5Fw6NIFEwU3RiwK6mn3nKegjpJuzCndoGq3BZPkUjnsq7uQmIeMNeMbMk7YD2MfKcgCpZwX5jyXqCA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/utilities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@csstools/utilities/-/utilities-2.0.0.tgz", + "integrity": "sha512-5VdOr0Z71u+Yp3ozOx8T11N703wIFGVRgOWbOZMKgglPJsWA54MRIoMNVMa7shUToIhx5J8vX4sOZgD2XiihiQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", @@ -2152,20 +3253,20 @@ } }, "node_modules/@docsearch/css": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.7.0.tgz", - "integrity": "sha512-1OorbTwi1eeDmr0v5t+ckSRlt1zM5GHjm92iIl3kUu7im3GHuP+csf6E0WBg8pdXQczTWP9J9+o9n+Vg6DH5cQ==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.8.0.tgz", + "integrity": "sha512-pieeipSOW4sQ0+bE5UFC51AOZp9NGxg89wAlZ1BAQFaiRAGK1IKUaPQ0UGZeNctJXyqZ1UvBtOQh2HH+U5GtmA==", "license": "MIT" }, "node_modules/@docsearch/react": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.7.0.tgz", - "integrity": "sha512-8e6tdDfkYoxafEEPuX5eE1h9cTkLvhe4KgoFkO5JCddXSQONnN1FHcDZRI4r8894eMpbYq6rdJF0dVYh8ikwNQ==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.8.0.tgz", + "integrity": "sha512-WnFK720+iwTVt94CxY3u+FgX6exb3BfN5kE9xUY6uuAH/9W/UFboBZFLlrw/zxFRHoHZCOXRtOylsXF+6LHI+Q==", "license": "MIT", "dependencies": { - "@algolia/autocomplete-core": "1.17.6", - "@algolia/autocomplete-preset-algolia": "1.17.6", - "@docsearch/css": "3.7.0", + "@algolia/autocomplete-core": "1.17.7", + "@algolia/autocomplete-preset-algolia": "1.17.7", + "@docsearch/css": "3.8.0", "algoliasearch": "^5.12.0" }, "peerDependencies": { @@ -2190,78 +3291,78 @@ } }, "node_modules/@docsearch/react/node_modules/@algolia/client-analytics": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.13.0.tgz", - "integrity": "sha512-pS3qyXiWTwKnrt/jE79fqkNqZp7kjsFNlJDcBGkSWid74DNc6DmArlkvPqyLxnoaYGjUGACT6g56n7E3mVV2TA==", + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.15.0.tgz", + "integrity": "sha512-lho0gTFsQDIdCwyUKTtMuf9nCLwq9jOGlLGIeQGKDxXF7HbiAysFIu5QW/iQr1LzMgDyM9NH7K98KY+BiIFriQ==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.13.0", - "@algolia/requester-browser-xhr": "5.13.0", - "@algolia/requester-fetch": "5.13.0", - "@algolia/requester-node-http": "5.13.0" + "@algolia/client-common": "5.15.0", + "@algolia/requester-browser-xhr": "5.15.0", + "@algolia/requester-fetch": "5.15.0", + "@algolia/requester-node-http": "5.15.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@docsearch/react/node_modules/@algolia/client-personalization": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.13.0.tgz", - "integrity": "sha512-RnCfOSN4OUJDuMNHFca2M8lY64Tmw0kQOZikge4TknTqHmlbKJb8IbJE7Rol79Z80W2Y+B1ydcjV7DPje4GMRA==", + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.15.0.tgz", + "integrity": "sha512-LfaZqLUWxdYFq44QrasCDED5bSYOswpQjSiIL7Q5fYlefAAUO95PzBPKCfUhSwhb4rKxigHfDkd81AvEicIEoA==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.13.0", - "@algolia/requester-browser-xhr": "5.13.0", - "@algolia/requester-fetch": "5.13.0", - "@algolia/requester-node-http": "5.13.0" + "@algolia/client-common": "5.15.0", + "@algolia/requester-browser-xhr": "5.15.0", + "@algolia/requester-fetch": "5.15.0", + "@algolia/requester-node-http": "5.15.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@docsearch/react/node_modules/@algolia/recommend": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.13.0.tgz", - "integrity": "sha512-53/wW96oaj1FKMzGdFcZ/epygfTppLDUvgI1thLkd475EtVZCH3ZZVUNCEvf1AtnNyH1RnItkFzX8ayWCpx2PQ==", + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.15.0.tgz", + "integrity": "sha512-5eupMwSqMLDObgSMF0XG958zR6GJP3f7jHDQ3/WlzCM9/YIJiWIUoJFGsko9GYsA5xbLDHE/PhWtq4chcCdaGQ==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.13.0", - "@algolia/requester-browser-xhr": "5.13.0", - "@algolia/requester-fetch": "5.13.0", - "@algolia/requester-node-http": "5.13.0" + "@algolia/client-common": "5.15.0", + "@algolia/requester-browser-xhr": "5.15.0", + "@algolia/requester-fetch": "5.15.0", + "@algolia/requester-node-http": "5.15.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@docsearch/react/node_modules/algoliasearch": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.13.0.tgz", - "integrity": "sha512-04lyQX3Ev/oLYQx+aagamQDXvkUUfX1mwrLrus15+9fNaYj28GDxxEzbwaRfvmHFcZyoxvup7mMtDTTw8SrTEQ==", - "license": "MIT", - "dependencies": { - "@algolia/client-abtesting": "5.13.0", - "@algolia/client-analytics": "5.13.0", - "@algolia/client-common": "5.13.0", - "@algolia/client-insights": "5.13.0", - "@algolia/client-personalization": "5.13.0", - "@algolia/client-query-suggestions": "5.13.0", - "@algolia/client-search": "5.13.0", - "@algolia/ingestion": "1.13.0", - "@algolia/monitoring": "1.13.0", - "@algolia/recommend": "5.13.0", - "@algolia/requester-browser-xhr": "5.13.0", - "@algolia/requester-fetch": "5.13.0", - "@algolia/requester-node-http": "5.13.0" + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.15.0.tgz", + "integrity": "sha512-Yf3Swz1s63hjvBVZ/9f2P1Uu48GjmjCN+Esxb6MAONMGtZB1fRX8/S1AhUTtsuTlcGovbYLxpHgc7wEzstDZBw==", + "license": "MIT", + "dependencies": { + "@algolia/client-abtesting": "5.15.0", + "@algolia/client-analytics": "5.15.0", + "@algolia/client-common": "5.15.0", + "@algolia/client-insights": "5.15.0", + "@algolia/client-personalization": "5.15.0", + "@algolia/client-query-suggestions": "5.15.0", + "@algolia/client-search": "5.15.0", + "@algolia/ingestion": "1.15.0", + "@algolia/monitoring": "1.15.0", + "@algolia/recommend": "5.15.0", + "@algolia/requester-browser-xhr": "5.15.0", + "@algolia/requester-fetch": "5.15.0", + "@algolia/requester-node-http": "5.15.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@docusaurus/babel": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docusaurus/babel/-/babel-3.6.1.tgz", - "integrity": "sha512-JcKaunW8Ml2nTnfnvFc55T00Y+aCpNWnf1KY/gG+wWxHYDH0IdXOOz+k6NAlEAerW8+VYLfUqRIqHZ7N/DVXvQ==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/babel/-/babel-3.6.3.tgz", + "integrity": "sha512-7dW9Hat9EHYCVicFXYA4hjxBY38+hPuCURL8oRF9fySRm7vzNWuEOghA1TXcykuXZp0HLG2td4RhDxCvGG7tNw==", "license": "MIT", "dependencies": { "@babel/core": "^7.25.9", @@ -2274,8 +3375,8 @@ "@babel/runtime": "^7.25.9", "@babel/runtime-corejs3": "^7.25.9", "@babel/traverse": "^7.25.9", - "@docusaurus/logger": "3.6.1", - "@docusaurus/utils": "3.6.1", + "@docusaurus/logger": "3.6.3", + "@docusaurus/utils": "3.6.3", "babel-plugin-dynamic-import-node": "^2.3.3", "fs-extra": "^11.1.1", "tslib": "^2.6.0" @@ -2285,18 +3386,17 @@ } }, "node_modules/@docusaurus/bundler": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docusaurus/bundler/-/bundler-3.6.1.tgz", - "integrity": "sha512-vHSEx8Ku9x/gfIC6k4xb8J2nTxagLia0KvZkPZhxfkD1+n8i+Dj4BZPWTmv+kCA17RbgAvECG0XRZ0/ZEspQBQ==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/bundler/-/bundler-3.6.3.tgz", + "integrity": "sha512-47JLuc8D4wA+6VOvmMd5fUC9rFppBQpQOnxDYiVXffm/DeV/wmm3sbpNd5Y+O+G2+nevLTRnvCm/qyancv0Y3A==", "license": "MIT", "dependencies": { "@babel/core": "^7.25.9", - "@docusaurus/babel": "3.6.1", - "@docusaurus/cssnano-preset": "3.6.1", - "@docusaurus/logger": "3.6.1", - "@docusaurus/types": "3.6.1", - "@docusaurus/utils": "3.6.1", - "autoprefixer": "^10.4.14", + "@docusaurus/babel": "3.6.3", + "@docusaurus/cssnano-preset": "3.6.3", + "@docusaurus/logger": "3.6.3", + "@docusaurus/types": "3.6.3", + "@docusaurus/utils": "3.6.3", "babel-loader": "^9.2.1", "clean-css": "^5.3.2", "copy-webpack-plugin": "^11.0.0", @@ -2309,6 +3409,7 @@ "null-loader": "^4.0.1", "postcss": "^8.4.26", "postcss-loader": "^7.3.3", + "postcss-preset-env": "^10.1.0", "react-dev-utils": "^12.0.1", "terser-webpack-plugin": "^5.3.9", "tslib": "^2.6.0", @@ -2329,18 +3430,18 @@ } }, "node_modules/@docusaurus/core": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.6.1.tgz", - "integrity": "sha512-cDKxPihiM2z7G+4QtpTczS7uxNfNG6naSqM65OmAJET0CFRHbc9mDlLFtQF0lsVES91SHqfcGaaLZmi2FjdwWA==", - "license": "MIT", - "dependencies": { - "@docusaurus/babel": "3.6.1", - "@docusaurus/bundler": "3.6.1", - "@docusaurus/logger": "3.6.1", - "@docusaurus/mdx-loader": "3.6.1", - "@docusaurus/utils": "3.6.1", - "@docusaurus/utils-common": "3.6.1", - "@docusaurus/utils-validation": "3.6.1", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.6.3.tgz", + "integrity": "sha512-xL7FRY9Jr5DWqB6pEnqgKqcMPJOX5V0pgWXi5lCiih11sUBmcFKM7c3+GyxcVeeWFxyYSDP3grLTWqJoP4P9Vw==", + "license": "MIT", + "dependencies": { + "@docusaurus/babel": "3.6.3", + "@docusaurus/bundler": "3.6.3", + "@docusaurus/logger": "3.6.3", + "@docusaurus/mdx-loader": "3.6.3", + "@docusaurus/utils": "3.6.3", + "@docusaurus/utils-common": "3.6.3", + "@docusaurus/utils-validation": "3.6.3", "boxen": "^6.2.1", "chalk": "^4.1.2", "chokidar": "^3.5.3", @@ -2391,9 +3492,9 @@ } }, "node_modules/@docusaurus/cssnano-preset": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.6.1.tgz", - "integrity": "sha512-ZxYUmNeyQHW2w4/PJ7d07jQDuxzmKr9uPAQ6IVe5dTkeIeV0mDBB3jOLeJkNoI42Ru9JKEqQ9aVDtM9ct6QHnw==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.6.3.tgz", + "integrity": "sha512-qP7SXrwZ+23GFJdPN4aIHQrZW+oH/7tzwEuc/RNL0+BdZdmIjYQqUxdXsjE4lFxLNZjj0eUrSNYIS6xwfij+5Q==", "license": "MIT", "dependencies": { "cssnano-preset-advanced": "^6.1.2", @@ -2406,9 +3507,9 @@ } }, "node_modules/@docusaurus/logger": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.6.1.tgz", - "integrity": "sha512-OvetI/nnOMBSqCkUzKAQhnIjhxduECK4qTu3tq/8/h/qqvLsvKURojm04WPE54L+Uy+UXMas0hnbBJd8zDlEOw==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.6.3.tgz", + "integrity": "sha512-xSubJixcNyMV9wMV4q0s47CBz3Rlc5jbcCCuij8pfQP8qn/DIpt0ks8W6hQWzHAedg/J/EwxxUOUrnEoKzJo8g==", "license": "MIT", "dependencies": { "chalk": "^4.1.2", @@ -2419,14 +3520,14 @@ } }, "node_modules/@docusaurus/mdx-loader": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.6.1.tgz", - "integrity": "sha512-KPIsYi0S3X3/rNrW3V1fgOu5t6ahYWc31zTHHod8pacFxdmk9Uf6uuw+Jd6Cly1ilgal+41Ku+s0gmMuqKqiqg==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.6.3.tgz", + "integrity": "sha512-3iJdiDz9540ppBseeI93tWTDtUGVkxzh59nMq4ignylxMuXBLK8dFqVeaEor23v1vx6TrGKZ2FuLaTB+U7C0QQ==", "license": "MIT", "dependencies": { - "@docusaurus/logger": "3.6.1", - "@docusaurus/utils": "3.6.1", - "@docusaurus/utils-validation": "3.6.1", + "@docusaurus/logger": "3.6.3", + "@docusaurus/utils": "3.6.3", + "@docusaurus/utils-validation": "3.6.3", "@mdx-js/mdx": "^3.0.0", "@slorber/remark-comment": "^1.0.0", "escape-html": "^1.0.3", @@ -2458,12 +3559,12 @@ } }, "node_modules/@docusaurus/module-type-aliases": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.6.1.tgz", - "integrity": "sha512-J+q1jgm7TnEfVIUZImSFeLA1rghb6nwtoB9siHdcgKpDqFJ9/S7xhQL2aEKE7iZMZYzpu+2F390E9A7GkdEJNA==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.6.3.tgz", + "integrity": "sha512-MjaXX9PN/k5ugNvfRZdWyKWq4FsrhN4LEXaj0pEmMebJuBNlFeGyKQUa9DRhJHpadNaiMLrbo9m3U7Ig5YlsZg==", "license": "MIT", "dependencies": { - "@docusaurus/types": "3.6.1", + "@docusaurus/types": "3.6.3", "@types/history": "^4.7.11", "@types/react": "*", "@types/react-router-config": "*", @@ -2477,19 +3578,19 @@ } }, "node_modules/@docusaurus/plugin-content-blog": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.6.1.tgz", - "integrity": "sha512-FUmsn3xg/XD/K/4FQd8XHrs92aQdZO5LUtpHnRvO1/6DY87SMz6B6ERAN9IGQQld//M2/LVTHkZy8oVhQZQHIQ==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.6.1", - "@docusaurus/logger": "3.6.1", - "@docusaurus/mdx-loader": "3.6.1", - "@docusaurus/theme-common": "3.6.1", - "@docusaurus/types": "3.6.1", - "@docusaurus/utils": "3.6.1", - "@docusaurus/utils-common": "3.6.1", - "@docusaurus/utils-validation": "3.6.1", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.6.3.tgz", + "integrity": "sha512-k0ogWwwJU3pFRFfvW1kRVHxzf2DutLGaaLjAnHVEU6ju+aRP0Z5ap/13DHyPOfHeE4WKpn/M0TqjdwZAcY3kAw==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.6.3", + "@docusaurus/logger": "3.6.3", + "@docusaurus/mdx-loader": "3.6.3", + "@docusaurus/theme-common": "3.6.3", + "@docusaurus/types": "3.6.3", + "@docusaurus/utils": "3.6.3", + "@docusaurus/utils-common": "3.6.3", + "@docusaurus/utils-validation": "3.6.3", "cheerio": "1.0.0-rc.12", "feed": "^4.2.2", "fs-extra": "^11.1.1", @@ -2511,20 +3612,20 @@ } }, "node_modules/@docusaurus/plugin-content-docs": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.6.1.tgz", - "integrity": "sha512-Uq8kyn5DYCDmkUlB9sWChhWghS4lUFNiQU+RXcAXJ3qCVXsBpPsh6RF+npQG1N+j4wAbjydM1iLLJJzp+x3eMQ==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.6.1", - "@docusaurus/logger": "3.6.1", - "@docusaurus/mdx-loader": "3.6.1", - "@docusaurus/module-type-aliases": "3.6.1", - "@docusaurus/theme-common": "3.6.1", - "@docusaurus/types": "3.6.1", - "@docusaurus/utils": "3.6.1", - "@docusaurus/utils-common": "3.6.1", - "@docusaurus/utils-validation": "3.6.1", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.6.3.tgz", + "integrity": "sha512-r2wS8y/fsaDcxkm20W5bbYJFPzdWdEaTWVYjNxlHlcmX086eqQR1Fomlg9BHTJ0dLXPzAlbC8EN4XqMr3QzNCQ==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.6.3", + "@docusaurus/logger": "3.6.3", + "@docusaurus/mdx-loader": "3.6.3", + "@docusaurus/module-type-aliases": "3.6.3", + "@docusaurus/theme-common": "3.6.3", + "@docusaurus/types": "3.6.3", + "@docusaurus/utils": "3.6.3", + "@docusaurus/utils-common": "3.6.3", + "@docusaurus/utils-validation": "3.6.3", "@types/react-router-config": "^5.0.7", "combine-promises": "^1.1.0", "fs-extra": "^11.1.1", @@ -2543,16 +3644,16 @@ } }, "node_modules/@docusaurus/plugin-content-pages": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.6.1.tgz", - "integrity": "sha512-TZtL+2zq20gqGalzoIT2rEF1T4YCZ26jTvlCJXs78+incIajfdHtmdOq7rQW0oV7oqTjpGllbp788nY/vY9jgw==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.6.3.tgz", + "integrity": "sha512-eHrmTgjgLZsuqfsYr5X2xEwyIcck0wseSofWrjTwT9FLOWp+KDmMAuVK+wRo7sFImWXZk3oV/xX/g9aZrhD7OA==", "license": "MIT", "dependencies": { - "@docusaurus/core": "3.6.1", - "@docusaurus/mdx-loader": "3.6.1", - "@docusaurus/types": "3.6.1", - "@docusaurus/utils": "3.6.1", - "@docusaurus/utils-validation": "3.6.1", + "@docusaurus/core": "3.6.3", + "@docusaurus/mdx-loader": "3.6.3", + "@docusaurus/types": "3.6.3", + "@docusaurus/utils": "3.6.3", + "@docusaurus/utils-validation": "3.6.3", "fs-extra": "^11.1.1", "tslib": "^2.6.0", "webpack": "^5.88.1" @@ -2566,14 +3667,14 @@ } }, "node_modules/@docusaurus/plugin-debug": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.6.1.tgz", - "integrity": "sha512-DeKPZtoVExDSYCbzoz7y5Dhc6+YPqRWfVGwEEUyKopSyQYefp0OV8hvASmbJCn2WyThRgspOUhog3FSEhz+agw==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.6.3.tgz", + "integrity": "sha512-zB9GXfIZNPRfzKnNjU6xGVrqn9bPXuGhpjgsuc/YtcTDjnjhasg38NdYd5LEqXex5G/zIorQgWB3n6x/Ut62vQ==", "license": "MIT", "dependencies": { - "@docusaurus/core": "3.6.1", - "@docusaurus/types": "3.6.1", - "@docusaurus/utils": "3.6.1", + "@docusaurus/core": "3.6.3", + "@docusaurus/types": "3.6.3", + "@docusaurus/utils": "3.6.3", "fs-extra": "^11.1.1", "react-json-view-lite": "^1.2.0", "tslib": "^2.6.0" @@ -2587,14 +3688,14 @@ } }, "node_modules/@docusaurus/plugin-google-analytics": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.6.1.tgz", - "integrity": "sha512-ZEoERiDHxSfhaEeT35ukQ892NzGHWiUvfxUsnPiRuGEhMoQlxMSp60shBuSZ1sUKuZlndoEl5qAXJg09Wls/Sg==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.6.3.tgz", + "integrity": "sha512-rCDNy1QW8Dag7nZq67pcum0bpFLrwvxJhYuVprhFh8BMBDxV0bY+bAkGHbSf68P3Bk9C3hNOAXX1srGLIDvcTA==", "license": "MIT", "dependencies": { - "@docusaurus/core": "3.6.1", - "@docusaurus/types": "3.6.1", - "@docusaurus/utils-validation": "3.6.1", + "@docusaurus/core": "3.6.3", + "@docusaurus/types": "3.6.3", + "@docusaurus/utils-validation": "3.6.3", "tslib": "^2.6.0" }, "engines": { @@ -2606,14 +3707,14 @@ } }, "node_modules/@docusaurus/plugin-google-gtag": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.6.1.tgz", - "integrity": "sha512-u/E9vXUsZxYaV6Brvfee8NiH/iR0cMml9P/ifz4EpH/Jfxdbw8rbCT0Nm/h7EFgEY48Uqkl5huSbIvFB9n8aTQ==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.6.3.tgz", + "integrity": "sha512-+OyDvhM6rqVkQOmLVkQWVJAizEEfkPzVWtIHXlWPOCFGK9X4/AWeBSrU0WG4iMg9Z4zD4YDRrU+lvI4s6DSC+w==", "license": "MIT", "dependencies": { - "@docusaurus/core": "3.6.1", - "@docusaurus/types": "3.6.1", - "@docusaurus/utils-validation": "3.6.1", + "@docusaurus/core": "3.6.3", + "@docusaurus/types": "3.6.3", + "@docusaurus/utils-validation": "3.6.3", "@types/gtag.js": "^0.0.12", "tslib": "^2.6.0" }, @@ -2626,14 +3727,14 @@ } }, "node_modules/@docusaurus/plugin-google-tag-manager": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.6.1.tgz", - "integrity": "sha512-By+NKkGYV8tSo8/RyS1OXikOtqsko5jJZ/uioJfBjsBGgSbiMJ+Y/HogFBke0mgSvf7NPGKZTbYm5+FJ8YUtPQ==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.6.3.tgz", + "integrity": "sha512-1M6UPB13gWUtN2UHX083/beTn85PlRI9ABItTl/JL1FJ5dJTWWFXXsHf9WW/6hrVwthwTeV/AGbGKvLKV+IlCA==", "license": "MIT", "dependencies": { - "@docusaurus/core": "3.6.1", - "@docusaurus/types": "3.6.1", - "@docusaurus/utils-validation": "3.6.1", + "@docusaurus/core": "3.6.3", + "@docusaurus/types": "3.6.3", + "@docusaurus/utils-validation": "3.6.3", "tslib": "^2.6.0" }, "engines": { @@ -2645,17 +3746,17 @@ } }, "node_modules/@docusaurus/plugin-sitemap": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.6.1.tgz", - "integrity": "sha512-i8R/GTKew4Cufb+7YQTwfPcNOhKTJzZ1VZ5OqQwI9c3pZK2TltQyhqKDVN94KCTbSSKvOYYytYfRAB2uPnH1/A==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.6.3.tgz", + "integrity": "sha512-94qOO4M9Fwv9KfVQJsgbe91k+fPJ4byf1L3Ez8TUa6TAFPo/BrLwQ80zclHkENlL1824TuxkcMKv33u6eydQCg==", "license": "MIT", "dependencies": { - "@docusaurus/core": "3.6.1", - "@docusaurus/logger": "3.6.1", - "@docusaurus/types": "3.6.1", - "@docusaurus/utils": "3.6.1", - "@docusaurus/utils-common": "3.6.1", - "@docusaurus/utils-validation": "3.6.1", + "@docusaurus/core": "3.6.3", + "@docusaurus/logger": "3.6.3", + "@docusaurus/types": "3.6.3", + "@docusaurus/utils": "3.6.3", + "@docusaurus/utils-common": "3.6.3", + "@docusaurus/utils-validation": "3.6.3", "fs-extra": "^11.1.1", "sitemap": "^7.1.1", "tslib": "^2.6.0" @@ -2669,24 +3770,24 @@ } }, "node_modules/@docusaurus/preset-classic": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.6.1.tgz", - "integrity": "sha512-b90Y1XRH9e+oa/E3NmiFEFOwgYUd+knFcZUy81nM3FJs038WbEA0T55NQsuPW0s7nOsCShQ7dVFyKxV+Wp31Nw==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.6.1", - "@docusaurus/plugin-content-blog": "3.6.1", - "@docusaurus/plugin-content-docs": "3.6.1", - "@docusaurus/plugin-content-pages": "3.6.1", - "@docusaurus/plugin-debug": "3.6.1", - "@docusaurus/plugin-google-analytics": "3.6.1", - "@docusaurus/plugin-google-gtag": "3.6.1", - "@docusaurus/plugin-google-tag-manager": "3.6.1", - "@docusaurus/plugin-sitemap": "3.6.1", - "@docusaurus/theme-classic": "3.6.1", - "@docusaurus/theme-common": "3.6.1", - "@docusaurus/theme-search-algolia": "3.6.1", - "@docusaurus/types": "3.6.1" + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.6.3.tgz", + "integrity": "sha512-VHSYWROT3flvNNI1SrnMOtW1EsjeHNK9dhU6s9eY5hryZe79lUqnZJyze/ymDe2LXAqzyj6y5oYvyBoZZk6ErA==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.6.3", + "@docusaurus/plugin-content-blog": "3.6.3", + "@docusaurus/plugin-content-docs": "3.6.3", + "@docusaurus/plugin-content-pages": "3.6.3", + "@docusaurus/plugin-debug": "3.6.3", + "@docusaurus/plugin-google-analytics": "3.6.3", + "@docusaurus/plugin-google-gtag": "3.6.3", + "@docusaurus/plugin-google-tag-manager": "3.6.3", + "@docusaurus/plugin-sitemap": "3.6.3", + "@docusaurus/theme-classic": "3.6.3", + "@docusaurus/theme-common": "3.6.3", + "@docusaurus/theme-search-algolia": "3.6.3", + "@docusaurus/types": "3.6.3" }, "engines": { "node": ">=18.0" @@ -2697,24 +3798,24 @@ } }, "node_modules/@docusaurus/theme-classic": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.6.1.tgz", - "integrity": "sha512-5lVUmIXk7zp+n9Ki2lYWrmhbd6mssOlKCnnDJvY4QDi3EgjRisIu5g4yKXoWTIbiqE7m7q/dS9cbeShEtfkKng==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.6.1", - "@docusaurus/logger": "3.6.1", - "@docusaurus/mdx-loader": "3.6.1", - "@docusaurus/module-type-aliases": "3.6.1", - "@docusaurus/plugin-content-blog": "3.6.1", - "@docusaurus/plugin-content-docs": "3.6.1", - "@docusaurus/plugin-content-pages": "3.6.1", - "@docusaurus/theme-common": "3.6.1", - "@docusaurus/theme-translations": "3.6.1", - "@docusaurus/types": "3.6.1", - "@docusaurus/utils": "3.6.1", - "@docusaurus/utils-common": "3.6.1", - "@docusaurus/utils-validation": "3.6.1", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.6.3.tgz", + "integrity": "sha512-1RRLK1tSArI2c00qugWYO3jRocjOZwGF1mBzPPylDVRwWCS/rnWWR91ChdbbaxIupRJ+hX8ZBYrwr5bbU0oztQ==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.6.3", + "@docusaurus/logger": "3.6.3", + "@docusaurus/mdx-loader": "3.6.3", + "@docusaurus/module-type-aliases": "3.6.3", + "@docusaurus/plugin-content-blog": "3.6.3", + "@docusaurus/plugin-content-docs": "3.6.3", + "@docusaurus/plugin-content-pages": "3.6.3", + "@docusaurus/theme-common": "3.6.3", + "@docusaurus/theme-translations": "3.6.3", + "@docusaurus/types": "3.6.3", + "@docusaurus/utils": "3.6.3", + "@docusaurus/utils-common": "3.6.3", + "@docusaurus/utils-validation": "3.6.3", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", "copy-text-to-clipboard": "^3.2.0", @@ -2738,15 +3839,15 @@ } }, "node_modules/@docusaurus/theme-common": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.6.1.tgz", - "integrity": "sha512-18iEYNpMvarGfq9gVRpGowSZD24vZ39Iz4acqaj64180i54V9el8tVnhNr/wRvrUm1FY30A1NHLqnMnDz4rYEQ==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.6.3.tgz", + "integrity": "sha512-b8ZkhczXHDxWWyvz+YJy4t/PlPbEogTTbgnHoflYnH7rmRtyoodTsu8WVM12la5LmlMJBclBXFl29OH8kPE7gg==", "license": "MIT", "dependencies": { - "@docusaurus/mdx-loader": "3.6.1", - "@docusaurus/module-type-aliases": "3.6.1", - "@docusaurus/utils": "3.6.1", - "@docusaurus/utils-common": "3.6.1", + "@docusaurus/mdx-loader": "3.6.3", + "@docusaurus/module-type-aliases": "3.6.3", + "@docusaurus/utils": "3.6.3", + "@docusaurus/utils-common": "3.6.3", "@types/history": "^4.7.11", "@types/react": "*", "@types/react-router-config": "*", @@ -2766,19 +3867,19 @@ } }, "node_modules/@docusaurus/theme-search-algolia": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.6.1.tgz", - "integrity": "sha512-BjmuiFRpQP1WEm8Mzu1Bb0Wdas6G65VHXDDNr7XTKgbstxalE6vuxt0ioXTDFS2YVep5748aVhKvnxR9gm2Liw==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.6.3.tgz", + "integrity": "sha512-rt+MGCCpYgPyWCGXtbxlwFbTSobu15jWBTPI2LHsHNa5B0zSmOISX6FWYAPt5X1rNDOqMGM0FATnh7TBHRohVA==", "license": "MIT", "dependencies": { "@docsearch/react": "^3.5.2", - "@docusaurus/core": "3.6.1", - "@docusaurus/logger": "3.6.1", - "@docusaurus/plugin-content-docs": "3.6.1", - "@docusaurus/theme-common": "3.6.1", - "@docusaurus/theme-translations": "3.6.1", - "@docusaurus/utils": "3.6.1", - "@docusaurus/utils-validation": "3.6.1", + "@docusaurus/core": "3.6.3", + "@docusaurus/logger": "3.6.3", + "@docusaurus/plugin-content-docs": "3.6.3", + "@docusaurus/theme-common": "3.6.3", + "@docusaurus/theme-translations": "3.6.3", + "@docusaurus/utils": "3.6.3", + "@docusaurus/utils-validation": "3.6.3", "algoliasearch": "^4.18.0", "algoliasearch-helper": "^3.13.3", "clsx": "^2.0.0", @@ -2797,9 +3898,9 @@ } }, "node_modules/@docusaurus/theme-translations": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.6.1.tgz", - "integrity": "sha512-bNm5G6sueUezvyhsBegA1wwM38yW0BnqpZTE9KHO2yKnkERNMaV5x/yPJ/DNCOHjJtCcJ5Uz55g2AS75Go31xA==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.6.3.tgz", + "integrity": "sha512-Gb0regclToVlngSIIwUCtBMQBq48qVUaN1XQNKW4XwlsgUyk0vP01LULdqbem7czSwIeBAFXFoORJ0RPX7ht/w==", "license": "MIT", "dependencies": { "fs-extra": "^11.1.1", @@ -2810,16 +3911,16 @@ } }, "node_modules/@docusaurus/tsconfig": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docusaurus/tsconfig/-/tsconfig-3.6.1.tgz", - "integrity": "sha512-RvjMG9M9YK8N/I5oudqJed8jjfWGI7csr4XCkGXBToNkkoi2QgkTz2DxH+obKdfLejQaASdIMynYaE5Lv7Qw9Q==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/tsconfig/-/tsconfig-3.6.3.tgz", + "integrity": "sha512-1pT/rTrRpMV15E4tJH95W5PrjboMn5JkKF+Ys8cTjMegetiXjs0gPFOSDA5hdTlberKQLDO50xPjMJHondLuzA==", "dev": true, "license": "MIT" }, "node_modules/@docusaurus/types": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.6.1.tgz", - "integrity": "sha512-hCB1hj9DYutVYBisnPNobz9SzEmCcf1EetJv09O49Cov3BqOkm+vnnjB3d957YJMtpLGQoKBeN/FF1DZ830JwQ==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.6.3.tgz", + "integrity": "sha512-xD9oTGDrouWzefkhe9ogB2fDV96/82cRpNGx2HIvI5L87JHNhQVIWimQ/3JIiiX/TEd5S9s+VO6FFguwKNRVow==", "license": "MIT", "dependencies": { "@mdx-js/mdx": "^3.0.0", @@ -2852,14 +3953,14 @@ } }, "node_modules/@docusaurus/utils": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.6.1.tgz", - "integrity": "sha512-nS3WCvepwrnBEgSG5vQu40XG95lC9Jeh/odV5u5IhU1eQFEGDst9xBi6IK5yZdsGvbuaXBZLZtOqWYtuuFa/rQ==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.6.3.tgz", + "integrity": "sha512-0R/FR3bKVl4yl8QwbL4TYFfR+OXBRpVUaTJdENapBGR3YMwfM6/JnhGilWQO8AOwPJGtGoDK7ib8+8UF9f3OZQ==", "license": "MIT", "dependencies": { - "@docusaurus/logger": "3.6.1", - "@docusaurus/types": "3.6.1", - "@docusaurus/utils-common": "3.6.1", + "@docusaurus/logger": "3.6.3", + "@docusaurus/types": "3.6.3", + "@docusaurus/utils-common": "3.6.3", "@svgr/webpack": "^8.1.0", "escape-string-regexp": "^4.0.0", "file-loader": "^6.2.0", @@ -2884,12 +3985,12 @@ } }, "node_modules/@docusaurus/utils-common": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.6.1.tgz", - "integrity": "sha512-LX1qiTiC0aS8c92uZ+Wj2iNCNJyYZJIKY8/nZDKNMBfo759VYVS3RX3fKP3DznB+16sYp7++MyCz/T6fOGaRfw==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.6.3.tgz", + "integrity": "sha512-v4nKDaANLgT3pMBewHYEMAl/ufY0LkXao1QkFWzI5huWFOmNQ2UFzv2BiKeHX5Ownis0/w6cAyoxPhVdDonlSQ==", "license": "MIT", "dependencies": { - "@docusaurus/types": "3.6.1", + "@docusaurus/types": "3.6.3", "tslib": "^2.6.0" }, "engines": { @@ -2897,14 +3998,14 @@ } }, "node_modules/@docusaurus/utils-validation": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.6.1.tgz", - "integrity": "sha512-+iMd6zRl5cJQm7nUP+7pSO/oAXsN79eHO34ME7l2YJt4GEAr70l5kkD58u2jEPpp+wSXT70c7x2A2lzJI1E8jw==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.6.3.tgz", + "integrity": "sha512-bhEGGiN5BE38h21vjqD70Gxg++j+PfYVddDUE5UFvLDup68QOcpD33CLr+2knPorlxRbEaNfz6HQDUMQ3HuqKw==", "license": "MIT", "dependencies": { - "@docusaurus/logger": "3.6.1", - "@docusaurus/utils": "3.6.1", - "@docusaurus/utils-common": "3.6.1", + "@docusaurus/logger": "3.6.3", + "@docusaurus/utils": "3.6.3", + "@docusaurus/utils-common": "3.6.3", "fs-extra": "^11.2.0", "joi": "^17.9.2", "js-yaml": "^4.1.0", @@ -5946,6 +7047,44 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/css-blank-pseudo": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-7.0.1.tgz", + "integrity": "sha512-jf+twWGDf6LDoXDUode+nc7ZlrqfaNphrBIBrcmeP3D8yw1uPaix1gCC8LUQUGQ6CycuK2opkbFFWFuq/a94ag==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-blank-pseudo/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/css-declaration-sorter": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz", @@ -5958,6 +7097,68 @@ "postcss": "^8.0.9" } }, + "node_modules/css-has-pseudo": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-7.0.1.tgz", + "integrity": "sha512-EOcoyJt+OsuKfCADgLT7gADZI5jMzIe/AeI6MeAYKiFBDmNmM7kk46DtSfMj5AohUJisqVzopBpnQTlvbyaBWg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/selector-specificity": "^5.0.0", + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-has-pseudo/node_modules/@csstools/selector-specificity": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", + "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/css-has-pseudo/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/css-loader": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", @@ -6037,6 +7238,28 @@ } } }, + "node_modules/css-prefers-color-scheme": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-10.0.0.tgz", + "integrity": "sha512-VCtXZAWivRglTZditUfB4StnsWr6YVZ2PRtuxQLKTNRdtAf8tpzaVPE9zXIF3VaSc7O70iK/j1+NXxyQCqdPjQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, "node_modules/css-select": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", @@ -6078,6 +7301,22 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/cssdb": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-8.2.1.tgz", + "integrity": "sha512-KwEPys7lNsC8OjASI8RrmwOYYDcm0JOW9zQhcV83ejYcQkirTEyeAGui8aO2F5PiS6SLpxuTzl6qlMElIdsgIg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + } + ], + "license": "MIT-0" + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -12019,9 +13258,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "funding": [ { "type": "github", @@ -12727,51 +13966,185 @@ "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "license": "MIT", "engines": { - "node": ">=4" + "node": ">=4" + } + }, + "node_modules/postcss": { + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-attribute-case-insensitive": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-7.0.1.tgz", + "integrity": "sha512-Uai+SupNSqzlschRyNx3kbCTWgY/2hcwtHEI/ej2LJWc9JJ77qKgGptd8DHwY1mXtZ7Aoh4z4yxfwMBue9eNgw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-attribute-case-insensitive/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-calc": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", + "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.11", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.2" + } + }, + "node_modules/postcss-clamp": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz", + "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=7.6.0" + }, + "peerDependencies": { + "postcss": "^8.4.6" + } + }, + "node_modules/postcss-color-functional-notation": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-7.0.6.tgz", + "integrity": "sha512-wLXvm8RmLs14Z2nVpB4CWlnvaWPRcOZFltJSlcbYwSJ1EDZKsKDhPKIMecCnuU054KSmlmubkqczmm6qBPCBhA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.0.6", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/postcss-progressive-custom-properties": "^4.0.0", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" } }, - "node_modules/postcss": { - "version": "8.4.48", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.48.tgz", - "integrity": "sha512-GCRK8F6+Dl7xYniR5a4FYbpBzU8XnZVeowqsQFYdcXuSbChgiks7qybSkbvnaeqv0G0B+dd9/jJgH8kkLDQeEA==", + "node_modules/postcss-color-hex-alpha": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-10.0.0.tgz", + "integrity": "sha512-1kervM2cnlgPs2a8Vt/Qbe5cQ++N7rkYo/2rz2BkqJZIHQwaVuJgQH38REHrAi4uM0b1fqxMkWYmese94iMp3w==", "funding": [ { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" + "type": "github", + "url": "https://github.com/sponsors/csstools" }, { - "type": "github", - "url": "https://github.com/sponsors/ai" + "type": "opencollective", + "url": "https://opencollective.com/csstools" } ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14" + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" } }, - "node_modules/postcss-calc": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", - "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", - "license": "MIT", + "node_modules/postcss-color-rebeccapurple": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-10.0.0.tgz", + "integrity": "sha512-JFta737jSP+hdAIEhk1Vs0q0YF5P8fFcj+09pweS8ktuGuZ8pPlykHsk6mPxZ8awDl4TrcxUqJo9l1IhVr/OjQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", "dependencies": { - "postcss-selector-parser": "^6.0.11", + "@csstools/utilities": "^2.0.0", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": ">=18" }, "peerDependencies": { - "postcss": "^8.2.2" + "postcss": "^8.4" } }, "node_modules/postcss-colormin": { @@ -12808,6 +14181,142 @@ "postcss": "^8.4.31" } }, + "node_modules/postcss-custom-media": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-11.0.5.tgz", + "integrity": "sha512-SQHhayVNgDvSAdX9NQ/ygcDQGEY+aSF4b/96z7QUX6mqL5yl/JgG/DywcF6fW9XbnCRE+aVYk+9/nqGuzOPWeQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/cascade-layer-name-parser": "^2.0.4", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/media-query-list-parser": "^4.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-custom-properties": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-14.0.4.tgz", + "integrity": "sha512-QnW8FCCK6q+4ierwjnmXF9Y9KF8q0JkbgVfvQEMa93x1GT8FvOiUevWCN2YLaOWyByeDX8S6VFbZEeWoAoXs2A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/cascade-layer-name-parser": "^2.0.4", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-custom-selectors": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-8.0.4.tgz", + "integrity": "sha512-ASOXqNvDCE0dAJ/5qixxPeL1aOVGHGW2JwSy7HyjWNbnWTQCl+fDc968HY1jCmZI0+BaYT5CxsOiUhavpG/7eg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/cascade-layer-name-parser": "^2.0.4", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-custom-selectors/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-dir-pseudo-class": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-9.0.1.tgz", + "integrity": "sha512-tRBEK0MHYvcMUrAuYMEOa0zg9APqirBcgzi6P21OhxtJyJADo/SWBwY1CAwEohQ/6HDaa9jCjLRG7K3PVQYHEA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-dir-pseudo-class/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-discard-comments": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.2.tgz", @@ -12850,25 +14359,214 @@ "integrity": "sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==", "license": "MIT", "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-unused": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-6.0.5.tgz", + "integrity": "sha512-wHalBlRHkaNnNwfC8z+ppX57VhvS+HWgjW508esjdaEYr3Mx7Gnn2xA4R/CKf5+Z9S5qsqC+Uzh4ueENWwCVUA==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-double-position-gradients": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-6.0.0.tgz", + "integrity": "sha512-JkIGah3RVbdSEIrcobqj4Gzq0h53GG4uqDPsho88SgY84WnpkTpI0k50MFK/sX7XqVisZ6OqUfFnoUO6m1WWdg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^4.0.0", + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-focus-visible": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-10.0.1.tgz", + "integrity": "sha512-U58wyjS/I1GZgjRok33aE8juW9qQgQUNwTSdxQGuShHzwuYdcklnvK/+qOWX1Q9kr7ysbraQ6ht6r+udansalA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-focus-visible/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-focus-within": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-9.0.1.tgz", + "integrity": "sha512-fzNUyS1yOYa7mOjpci/bR+u+ESvdar6hk8XNK/TRR0fiGTp2QT5N+ducP0n3rfH/m9I7H/EQU6lsa2BrgxkEjw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-focus-within/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-font-variant": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", + "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", + "license": "MIT", + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-gap-properties": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-6.0.0.tgz", + "integrity": "sha512-Om0WPjEwiM9Ru+VhfEDPZJAKWUd0mV1HmNXqp2C29z80aQ2uP9UVhLc7e3aYMIor/S5cVhoPgYQ7RtfeZpYTRw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-image-set-function": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-7.0.0.tgz", + "integrity": "sha512-QL7W7QNlZuzOwBTeXEmbVckNt1FSmhQtbMRvGGqqU4Nf4xk6KUEQhAoWuMzwbSv5jxiRiSZ5Tv7eiDB9U87znA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" }, "peerDependencies": { - "postcss": "^8.4.31" + "postcss": "^8.4" } }, - "node_modules/postcss-discard-unused": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-6.0.5.tgz", - "integrity": "sha512-wHalBlRHkaNnNwfC8z+ppX57VhvS+HWgjW508esjdaEYr3Mx7Gnn2xA4R/CKf5+Z9S5qsqC+Uzh4ueENWwCVUA==", - "license": "MIT", + "node_modules/postcss-lab-function": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-7.0.6.tgz", + "integrity": "sha512-HPwvsoK7C949vBZ+eMyvH2cQeMr3UREoHvbtra76/UhDuiViZH6pir+z71UaJQohd7VDSVUdR6TkWYKExEc9aQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", "dependencies": { - "postcss-selector-parser": "^6.0.16" + "@csstools/css-color-parser": "^3.0.6", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/postcss-progressive-custom-properties": "^4.0.0", + "@csstools/utilities": "^2.0.0" }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": ">=18" }, "peerDependencies": { - "postcss": "^8.4.31" + "postcss": "^8.4" } }, "node_modules/postcss-loader": { @@ -12893,6 +14591,31 @@ "webpack": "^5.0.0" } }, + "node_modules/postcss-logical": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-8.0.0.tgz", + "integrity": "sha512-HpIdsdieClTjXLOyYdUPAX/XQASNIwdKt5hoZW08ZOAiI+tbV0ta1oclkpVkW5ANU+xJvk3KkA0FejkjGLXUkg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, "node_modules/postcss-merge-idents": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-6.0.3.tgz", @@ -13020,13 +14743,13 @@ } }, "node_modules/postcss-modules-local-by-default": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", - "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.1.0.tgz", + "integrity": "sha512-rm0bdSv4jC3BDma3s9H19ZddW0aHX6EoqwDYU2IfZhRN+53QrufTRo2IdkAbRqLx4R2IYbZnbjKKxg4VN5oU9Q==", "license": "MIT", "dependencies": { "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", + "postcss-selector-parser": "^7.0.0", "postcss-value-parser": "^4.1.0" }, "engines": { @@ -13036,13 +14759,26 @@ "postcss": "^8.1.0" } }, + "node_modules/postcss-modules-local-by-default/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-modules-scope": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", - "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", "license": "ISC", "dependencies": { - "postcss-selector-parser": "^6.0.4" + "postcss-selector-parser": "^7.0.0" }, "engines": { "node": "^10 || ^12 || >= 14" @@ -13051,6 +14787,19 @@ "postcss": "^8.1.0" } }, + "node_modules/postcss-modules-scope/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-modules-values": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", @@ -13066,6 +14815,90 @@ "postcss": "^8.1.0" } }, + "node_modules/postcss-nesting": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-13.0.1.tgz", + "integrity": "sha512-VbqqHkOBOt4Uu3G8Dm8n6lU5+9cJFxiuty9+4rcoyRPO9zZS1JIs6td49VIoix3qYqELHlJIn46Oih9SAKo+yQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/selector-resolve-nested": "^3.0.0", + "@csstools/selector-specificity": "^5.0.0", + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-nesting/node_modules/@csstools/selector-resolve-nested": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-3.0.0.tgz", + "integrity": "sha512-ZoK24Yku6VJU1gS79a5PFmC8yn3wIapiKmPgun0hZgEI5AOqgH2kiPRsPz1qkGv4HL+wuDLH83yQyk6inMYrJQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/postcss-nesting/node_modules/@csstools/selector-specificity": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", + "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/postcss-nesting/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-normalize-charset": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.2.tgz", @@ -13199,6 +15032,28 @@ "postcss": "^8.4.31" } }, + "node_modules/postcss-opacity-percentage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-3.0.0.tgz", + "integrity": "sha512-K6HGVzyxUxd/VgZdX04DCtdwWJ4NGLG212US4/LA1TLAbHgmAsTWVR86o+gGIbFtnTkfOpb9sCRBx8K7HO66qQ==", + "funding": [ + { + "type": "kofi", + "url": "https://ko-fi.com/mrcgrtz" + }, + { + "type": "liberapay", + "url": "https://liberapay.com/mrcgrtz" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, "node_modules/postcss-ordered-values": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.2.tgz", @@ -13215,6 +15070,190 @@ "postcss": "^8.4.31" } }, + "node_modules/postcss-overflow-shorthand": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-6.0.0.tgz", + "integrity": "sha512-BdDl/AbVkDjoTofzDQnwDdm/Ym6oS9KgmO7Gr+LHYjNWJ6ExORe4+3pcLQsLA9gIROMkiGVjjwZNoL/mpXHd5Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-page-break": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", + "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", + "license": "MIT", + "peerDependencies": { + "postcss": "^8" + } + }, + "node_modules/postcss-place": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-10.0.0.tgz", + "integrity": "sha512-5EBrMzat2pPAxQNWYavwAfoKfYcTADJ8AXGVPcUZ2UkNloUTWzJQExgrzrDkh3EKzmAx1evfTAzF9I8NGcc+qw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-preset-env": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-10.1.1.tgz", + "integrity": "sha512-wqqsnBFD6VIwcHHRbhjTOcOi4qRVlB26RwSr0ordPj7OubRRxdWebv/aLjKLRR8zkZrbxZyuus03nOIgC5elMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/postcss-cascade-layers": "^5.0.1", + "@csstools/postcss-color-function": "^4.0.6", + "@csstools/postcss-color-mix-function": "^3.0.6", + "@csstools/postcss-content-alt-text": "^2.0.4", + "@csstools/postcss-exponential-functions": "^2.0.5", + "@csstools/postcss-font-format-keywords": "^4.0.0", + "@csstools/postcss-gamut-mapping": "^2.0.6", + "@csstools/postcss-gradients-interpolation-method": "^5.0.6", + "@csstools/postcss-hwb-function": "^4.0.6", + "@csstools/postcss-ic-unit": "^4.0.0", + "@csstools/postcss-initial": "^2.0.0", + "@csstools/postcss-is-pseudo-class": "^5.0.1", + "@csstools/postcss-light-dark-function": "^2.0.7", + "@csstools/postcss-logical-float-and-clear": "^3.0.0", + "@csstools/postcss-logical-overflow": "^2.0.0", + "@csstools/postcss-logical-overscroll-behavior": "^2.0.0", + "@csstools/postcss-logical-resize": "^3.0.0", + "@csstools/postcss-logical-viewport-units": "^3.0.3", + "@csstools/postcss-media-minmax": "^2.0.5", + "@csstools/postcss-media-queries-aspect-ratio-number-values": "^3.0.4", + "@csstools/postcss-nested-calc": "^4.0.0", + "@csstools/postcss-normalize-display-values": "^4.0.0", + "@csstools/postcss-oklab-function": "^4.0.6", + "@csstools/postcss-progressive-custom-properties": "^4.0.0", + "@csstools/postcss-random-function": "^1.0.1", + "@csstools/postcss-relative-color-syntax": "^3.0.6", + "@csstools/postcss-scope-pseudo-class": "^4.0.1", + "@csstools/postcss-sign-functions": "^1.1.0", + "@csstools/postcss-stepped-value-functions": "^4.0.5", + "@csstools/postcss-text-decoration-shorthand": "^4.0.1", + "@csstools/postcss-trigonometric-functions": "^4.0.5", + "@csstools/postcss-unset-value": "^4.0.0", + "autoprefixer": "^10.4.19", + "browserslist": "^4.23.1", + "css-blank-pseudo": "^7.0.1", + "css-has-pseudo": "^7.0.1", + "css-prefers-color-scheme": "^10.0.0", + "cssdb": "^8.2.1", + "postcss-attribute-case-insensitive": "^7.0.1", + "postcss-clamp": "^4.1.0", + "postcss-color-functional-notation": "^7.0.6", + "postcss-color-hex-alpha": "^10.0.0", + "postcss-color-rebeccapurple": "^10.0.0", + "postcss-custom-media": "^11.0.5", + "postcss-custom-properties": "^14.0.4", + "postcss-custom-selectors": "^8.0.4", + "postcss-dir-pseudo-class": "^9.0.1", + "postcss-double-position-gradients": "^6.0.0", + "postcss-focus-visible": "^10.0.1", + "postcss-focus-within": "^9.0.1", + "postcss-font-variant": "^5.0.0", + "postcss-gap-properties": "^6.0.0", + "postcss-image-set-function": "^7.0.0", + "postcss-lab-function": "^7.0.6", + "postcss-logical": "^8.0.0", + "postcss-nesting": "^13.0.1", + "postcss-opacity-percentage": "^3.0.0", + "postcss-overflow-shorthand": "^6.0.0", + "postcss-page-break": "^3.0.4", + "postcss-place": "^10.0.0", + "postcss-pseudo-class-any-link": "^10.0.1", + "postcss-replace-overflow-wrap": "^4.0.0", + "postcss-selector-not": "^8.0.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-pseudo-class-any-link": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-10.0.1.tgz", + "integrity": "sha512-3el9rXlBOqTFaMFkWDOkHUTQekFIYnaQY55Rsp8As8QQkpiSgIYEcF/6Ond93oHiDsGb4kad8zjt+NPlOC1H0Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-pseudo-class-any-link/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-reduce-idents": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-6.0.3.tgz", @@ -13261,6 +15300,53 @@ "postcss": "^8.4.31" } }, + "node_modules/postcss-replace-overflow-wrap": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", + "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", + "license": "MIT", + "peerDependencies": { + "postcss": "^8.0.3" + } + }, + "node_modules/postcss-selector-not": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-8.0.1.tgz", + "integrity": "sha512-kmVy/5PYVb2UOhy0+LqUYAhKj7DUGDpSWa5LZqlkWJaaAV+dxxsOG3+St0yNLu6vsKD7Dmqx+nWQt0iil89+WA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-selector-not/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-selector-parser": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", @@ -14615,9 +16701,9 @@ } }, "node_modules/search-insights": { - "version": "2.17.2", - "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.2.tgz", - "integrity": "sha512-zFNpOpUO+tY2D85KrxJ+aqwnIfdEGi06UH2+xEb+Bp9Mwznmauqc9djbnBibJO5mpfUPPa8st6Sx65+vbeO45g==", + "version": "2.17.3", + "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz", + "integrity": "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==", "license": "MIT", "peer": true }, diff --git a/leetcode_101/package.json b/leetcode_101/package.json index 4a2a001d..669ca3ca 100644 --- a/leetcode_101/package.json +++ b/leetcode_101/package.json @@ -15,8 +15,8 @@ "typecheck": "tsc" }, "dependencies": { - "@docusaurus/core": "3.6.1", - "@docusaurus/preset-classic": "3.6.1", + "@docusaurus/core": "^3.6.3", + "@docusaurus/preset-classic": "^3.6.3", "@easyops-cn/docusaurus-search-local": "^0.46.1", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", @@ -27,9 +27,9 @@ "remark-math": "^6.0.0" }, "devDependencies": { - "@docusaurus/module-type-aliases": "3.6.1", - "@docusaurus/tsconfig": "3.6.1", - "@docusaurus/types": "3.6.1", + "@docusaurus/module-type-aliases": "^3.6.3", + "@docusaurus/tsconfig": "^3.6.3", + "@docusaurus/types": "^3.6.3", "typescript": "~5.6.2" }, "browserslist": { From 7fc5f430e6b9bcb75f51be4a5f2554de3670b4a9 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Sun, 1 Dec 2024 10:55:05 +0100 Subject: [PATCH 44/49] Ch3 exercise solutions --- .../3-6-exercises.md | 162 ++++++++++++++++++ 1 file changed, 162 insertions(+) diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-6-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-6-exercises.md index 19ea8ed1..ffc09961 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-6-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/3-binary-search-techniques/3-6-exercises.md @@ -10,12 +10,102 @@ sidebar_position: 16 旋轉陣列的變形題之一。 +
        + 題解 + +#### 解題思路 + +本題需要找到旋轉排序陣列中的最小值,且陣列中可能包含重複元素。利用 **二分搜尋法**,可以在 $O(\log n)$ 的平均時間複雜度下高效解決,儘管最壞情況可能退化到 $O(n)$。 + +- **重點問題**: + 1. 如果陣列中沒有重複元素,透過比較 `nums[mid]` 和 `nums[r]` 可以直接判斷哪個區間是遞增的。 + 2. 如果陣列中有重複元素,當 `nums[mid] == nums[r]` 時,無法直接確定哪一邊是遞增的,因此需要額外處理。 + +- **核心邏輯**: + 1. 計算中間值 `mid = (l + r) // 2`。 + 2. 如果 `nums[mid] < nums[r]`,說明右半部分是遞增的,最小值可能在左半部分或中間,更新右邊界 `r = mid`。 + 3. 如果 `nums[mid] > nums[r]`,說明左半部分是遞增的,最小值只能在右半部分,更新左邊界 `l = mid + 1`。 + 4. 如果 `nums[mid] == nums[r]`,無法確定遞增區間,縮小搜尋範圍,將右邊界減一 `r -= 1`。 + +#### 程式碼 + +```python +class Solution: + def findMin(self, nums: List[int]) -> int: + l, r = 0, len(nums) - 1 + while l < r: + mid = (l + r) // 2 + if nums[mid] < nums[r]: + r = mid # 最小值可能在左半部分或中間 + elif nums[mid] > nums[r]: + l = mid + 1 # 最小值一定在右半部分 + else: + r -= 1 # 無法確定區間遞增性,縮小範圍 + return nums[l] +``` + +#### 複雜度分析 + +- **時間複雜度**: + - 平均情況:$O(\log n)$,每次迭代將搜尋範圍減半。 + - 最壞情況:$O(n)$,當所有元素相同時,無法利用二分特性,只能線性縮小範圍。 +- **空間複雜度**: $O(1)$,只使用了常數額外空間。 + +
        + + --- ### [540. Single Element in a Sorted Array](https://leetcode.com/problems/single-element-in-a-sorted-array/) 在出現單獨數之前和之後,奇數位與偶數位的值發生了什麼變化? +
        + 題解 + +#### 解題思路 + +本題需要在排序陣列中找到唯一不重複的元素,每個其他數字都恰好出現兩次。利用 **二分搜尋法**,可以有效地解決此問題。 + +1. **特性分析**: + - 不重複的單一元素會打破「成對分佈」的規律: + - 如果索引是偶數,且 `nums[mid] == nums[mid + 1]`,單一元素一定在右半部分。 + - 否則,單一元素在左半部分。 + - 調整 `mid` 為偶數,以便直接判斷其是否與右側元素配對。 + +2. **二分邏輯**: + - 若 `nums[mid] == nums[mid + 1]`,則單一元素在右側,移動左指標。 + - 若 `nums[mid] != nums[mid + 1]`,則單一元素在左側,移動右指標。 + +3. **最終結果**: + - 當 `left == right` 時,該索引即為單一元素所在位置。 + +#### 程式碼 + +```python +class Solution: + def singleNonDuplicate(self, nums: List[int]) -> int: + l, r = 0, len(nums) - 1 + while l < r: + mid = (l + r) // 2 + if mid % 2 == 1: # 保證 mid 是偶數 + mid -= 1 + if nums[mid] == nums[mid + 1]: + l = mid + 2 # 單一元素在右側 + else: + r = mid # 單一元素在左側 + return nums[l] +``` + +#### 複雜度分析 + +- **時間複雜度**: $O(\log n)$,因為每次迭代將搜尋範圍減半。 +- **空間複雜度**: $O(1)$,只使用了常數額外空間。 + +
        + + + --- ## 進階難度 @@ -23,3 +113,75 @@ sidebar_position: 16 ### [4. Median of Two Sorted Arrays](https://leetcode.com/problems/median-of-two-sorted-arrays/) 需要對兩個陣列同時進行二分搜尋。 + +
        + 題解 + +#### 解題思路 + +本題需要在兩個排序陣列中找到中位數,要求時間複雜度為 $O(\log (m+n))$。我們可以利用 **二分搜尋法** 高效解決。 + +1. **特性分析**: + - 中位數將兩個陣列分為「左側」和「右側」兩部分,保證: + - 左側所有元素的數量等於或多於右側。 + - 左側所有元素小於等於右側。 + - 透過二分搜尋在其中一個陣列上劃分位置,從而確定整體的中位數。 + +2. **解法步驟**: + - 確保對短的陣列進行二分搜尋,以降低時間複雜度。 + - 設置兩個指標 `left` 和 `right`,表示短陣列的二分搜尋範圍。 + - 計算劃分位置: + - `i` 為短陣列的劃分位置。 + - `j` 為長陣列的劃分位置,根據總長度和 `i` 計算得出。 + - 比較劃分後的左右部分,判斷是否滿足條件: + - 左側最大值 $\leq$ 右側最小值。 + +3. **處理邊界條件**: + - 若劃分正確,根據總長度的奇偶性返回結果: + - 奇數時,返回左側最大值。 + - 偶數時,返回左側最大值與右側最小值的平均值。 + - 若劃分不正確,調整 `left` 或 `right`,繼續二分搜尋。 + +#### 程式碼 + +```python +class Solution: + def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float: + # 保證 nums1 是較短的陣列 + if len(nums1) > len(nums2): + nums1, nums2 = nums2, nums1 + + m, n = len(nums1), len(nums2) + total_left = (m + n + 1) // 2 + + left, right = 0, m + while left <= right: + i = (left + right) // 2 # nums1 的劃分點 + j = total_left - i # nums2 的劃分點 + + nums1_left_max = float('-inf') if i == 0 else nums1[i - 1] + nums1_right_min = float('inf') if i == m else nums1[i] + nums2_left_max = float('-inf') if j == 0 else nums2[j - 1] + nums2_right_min = float('inf') if j == n else nums2[j] + + # 確保劃分正確 + if nums1_left_max <= nums2_right_min and nums2_left_max <= nums1_right_min: + # 如果總數是奇數,取左邊最大值 + if (m + n) % 2 == 1: + return max(nums1_left_max, nums2_left_max) + # 如果總數是偶數,取左邊最大值和右邊最小值的平均 + return (max(nums1_left_max, nums2_left_max) + min(nums1_right_min, nums2_right_min)) / 2 + + # 調整劃分 + elif nums1_left_max > nums2_right_min: + right = i - 1 + else: + left = i + 1 +``` + +#### 複雜度分析 + +- **時間複雜度**: $O(\log \min(m, n))$,其中 $m$ 和 $n$ 分別為兩個陣列的長度。因為對較短的陣列進行二分搜尋。 +- **空間複雜度**: $O(1)$,只使用了常數額外空間。 + +
        From 30473b3ca42feb58d43fcfb6538e978243381c28 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Sun, 1 Dec 2024 13:55:12 +0100 Subject: [PATCH 45/49] Fix i18n zh-TW --- .../current/10-data-structures/10-1-cpp-stl.md | 2 +- .../10-data-structures/10-2-python-data-structures.md | 2 +- .../current/10-data-structures/10-5-monotonic-stack.mdx | 2 +- .../current/10-data-structures/10-8-hash-table.mdx | 4 ++-- .../11-string-manipulation/11-2-string-comparison.mdx | 2 +- .../11-string-manipulation/11-3-string-interpretation.mdx | 2 +- .../current/13-trees/13-2-tree-recursion.mdx | 2 +- .../current/13-trees/13-3-level-order-traversal.mdx | 2 +- .../4-1-common-sorting-algorithms.mdx | 4 ++-- .../5-searching-algorithms/5-2-depth-first-search.mdx | 4 ++-- .../current/5-searching-algorithms/5-3-backtracking.mdx | 2 +- .../5-searching-algorithms/5-4-breadth-first-search.mdx | 8 ++++---- .../current/6-dynamic-programming/6-2-basic-dp-1d.mdx | 2 +- .../7-divide-and-conquer/7-2-expression-problems.mdx | 2 +- .../9-bitwise-operations/9-3-binary-properties.mdx | 2 +- 15 files changed, 21 insertions(+), 21 deletions(-) diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-1-cpp-stl.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-1-cpp-stl.md index 945ec9c4..93d6c374 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-1-cpp-stl.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-1-cpp-stl.md @@ -7,7 +7,7 @@ sidebar_position: 48 在刷題時,我們幾乎一定會用到各種資料結構來輔助我們解決問題,因此我們必須熟悉各種資料結構的特點。C++ STL 提供的資料結構包括(實際底層細節可能因編譯器而異): 1. **順序容器(Sequence Containers)**:維持順序的容器。 - 1. **vector**:`動態陣列`,是我們最常使用的資料結構之一,用於 $O(1)$ 的隨機讀取。因為大部分演算法的時間複雜度會大於 $O(n)$,因此我們經常新建 vector 來存儲各種資料或中間變數。由於在尾部增刪的複雜度是 $O(1)$,我們也可以把它當作 stack 來用。 + 1. **vector**:`動態陣列`,是我們最常使用的資料結構之一,用於 $O(1)$ 的隨機讀取。因為大部分演算法的時間複雜度會大於 $O(n)$,因此我們經常新建 vector 來儲存各種資料或中間變數。由於在尾部增刪的複雜度是 $O(1)$,我們也可以把它當作 stack 來用。 2. **list**:`雙向鏈結串列`,也可以當作 stack 和 queue 來使用。由於 LeetCode 的題目多用 Node 來表示鏈結串列,且鏈結串列不支援快速隨機讀取,因此我們很少用到這個資料結構。一個例外是經典的 LRU 問題,我們需要利用鏈結串列的特性來解決,我們在後文會遇到這個問題。 3. **deque**:雙端佇列,這是一個非常強大的資料結構,既支援 $O(1)$ 隨機讀取,又支援 $O(1)$ 時間的頭部增刪和尾部增刪(因此可以當作 stack 和 queue 來使用),不過有一定的額外開銷。也可以用來近似一個雙向鏈結串列來使用。 4. **array**:固定大小的陣列,一般在刷題時我們不使用。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-2-python-data-structures.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-2-python-data-structures.md index 48aec81d..d64c1bee 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-2-python-data-structures.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-2-python-data-structures.md @@ -18,7 +18,7 @@ sidebar_position: 49 1. **collections.OrderedDict**:`順序映射或順序表`,注意這裡的 Ordered 與 C++ 中 map 的按大小排序不同,而是按照插入的先後順序排序。`OrderedDict` 非常適合用來實現 LRU(最近最少使用)。 4. **無序關聯容器**: 1. **set**:`雜湊集合`,可以在 $O(1)$ 的時間內快速插入、查詢和刪除元素,常用於快速查詢某個元素是否存在於容器中。 - 2. **dict**:`雜湊映射或雜湊表`,在 set 的基礎上增加了鍵值對的映射關係,可以對每個鍵(key)存儲對應的值(value)。在某些情況下,如果鍵的範圍已知且較小,我們也可以用 list 代替 dict,用索引位置表示鍵,用每個位置的值表示對應的值。 + 2. **dict**:`雜湊映射或雜湊表`,在 set 的基礎上增加了鍵值對的映射關係,可以對每個鍵(key)儲存對應的值(value)。在某些情況下,如果鍵的範圍已知且較小,我們也可以用 list 代替 dict,用索引位置表示鍵,用每個位置的值表示對應的值。 3. **collections.Counter**:`計數器`,是 dict 的一種特殊版本,可以直接傳入一個 list,並對其中的每個元素進行計數統計,鍵為元素值,值為該元素出現的頻次。可以用來作為多重集合。 同樣地,因為這並不是一本講解 Python 原理的書,更多的資料結構細節請讀者自行搜索。只有理解這些資料結構的原理和使用方法,才能夠更加游刃有餘地解決算法和資料結構問題。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-5-monotonic-stack.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-5-monotonic-stack.mdx index b21fdb4b..e73105b4 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-5-monotonic-stack.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-5-monotonic-stack.mdx @@ -23,7 +23,7 @@ Output: [1, 1, 4, 2, 1, 1, 0, 0] ### 題解 -我們可以維持一個單調遞減的堆疊,表示每天的溫度;為了方便計算天數差,我們存放位置(即日期)而非溫度本身。我們從左到右遍歷溫度陣列,對於每個日期 $p$,如果 $p$ 的溫度比堆疊頂部存儲位置 $q$ 的溫度高,則我們取出 $q$,並記錄 $q$ 需要等待的天數為 $p - q$;我們重複這一過程,直到 $p$ 的溫度小於等於堆疊頂部存儲位置的溫度(或空堆疊)時,將 $p$ 插入堆疊頂部,然後考慮下一天。在此過程中,堆疊內陣列永遠保持單調遞減,避免了使用排序進行比較。最後若堆疊內剩餘一些日期,則說明它們之後都沒有出現更暖和的日期。 +我們可以維持一個單調遞減的堆疊,表示每天的溫度;為了方便計算天數差,我們存放位置(即日期)而非溫度本身。我們從左到右遍歷溫度陣列,對於每個日期 $p$,如果 $p$ 的溫度比堆疊頂部儲存位置 $q$ 的溫度高,則我們取出 $q$,並記錄 $q$ 需要等待的天數為 $p - q$;我們重複這一過程,直到 $p$ 的溫度小於等於堆疊頂部儲存位置的溫度(或空堆疊)時,將 $p$ 插入堆疊頂部,然後考慮下一天。在此過程中,堆疊內陣列永遠保持單調遞減,避免了使用排序進行比較。最後若堆疊內剩餘一些日期,則說明它們之後都沒有出現更暖和的日期。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-8-hash-table.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-8-hash-table.mdx index e8cca020..a7be373a 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-8-hash-table.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/10-8-hash-table.mdx @@ -4,9 +4,9 @@ sidebar_position: 55 # 10.8 雜湊表 -`雜湊表(hash table, hash map)`,又稱散列表,使用 $O(n)$ 空間複雜度存儲資料,通過雜湊函數(hash function)映射位置,從而實現近似 $O(1)$ 時間複雜度的插入、查詢、刪除等操作。雜湊表可以用來統計頻率、記錄內容等等。 +`雜湊表(hash table, hash map)`,又稱散列表,使用 $O(n)$ 空間複雜度儲存資料,通過雜湊函數(hash function)映射位置,從而實現近似 $O(1)$ 時間複雜度的插入、查詢、刪除等操作。雜湊表可以用來統計頻率、記錄內容等等。 -如果元素是有限的,且範圍不大,那麼可以用一個固定大小的陣列來存儲或統計元素。例如,我們需要統計一個字串中所有字母的出現次數,則可以用一個長度為 26 的陣列來進行統計,其雜湊函數即為字母在字母表中的位置,這樣空間複雜度就可以降低為常數。 +如果元素是有限的,且範圍不大,那麼可以用一個固定大小的陣列來儲存或統計元素。例如,我們需要統計一個字串中所有字母的出現次數,則可以用一個長度為 26 的陣列來進行統計,其雜湊函數即為字母在字母表中的位置,這樣空間複雜度就可以降低為常數。 ## [1. Two Sum](https://leetcode.com/problems/two-sum/) diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-2-string-comparison.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-2-string-comparison.mdx index 2c82c6c2..f243663a 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-2-string-comparison.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-2-string-comparison.mdx @@ -77,7 +77,7 @@ Output: true 我們可以將問題重新表述:記錄兩個字串中每個位置的字元首次出現的位置。如果兩個字串中相同位置的字元與它們的首次出現位置相同,則這兩個字串同構。 -舉例來說,對於 "paper" 和 "title",假設我們現在處理第三個字元 `p` 和 `t`,發現它們首次出現的位置都在第一個字元,這表示目前位置滿足同構條件。我們可以使用雜湊表進行存儲,或者用一個長度為 128 的陣列(ASCII 定義下的字元總數)。 +舉例來說,對於 "paper" 和 "title",假設我們現在處理第三個字元 `p` 和 `t`,發現它們首次出現的位置都在第一個字元,這表示目前位置滿足同構條件。我們可以使用雜湊表進行儲存,或者用一個長度為 128 的陣列(ASCII 定義下的字元總數)。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-3-string-interpretation.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-3-string-interpretation.mdx index 45cf997e..b266d4bf 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-3-string-interpretation.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-3-string-interpretation.mdx @@ -23,7 +23,7 @@ Output: 5 ### 題解 -如果我們在字串左邊加上一個 `+` 號,可以證明其並不改變運算結果,且字串可以分割成多個 `<運算符, 數字>` 的配對形式;這樣一來我們就可以從左到右處理。由於乘除的優先級高於加減,因此我們需要使用一個中間變數來存儲高優先度的運算結果。 +如果我們在字串左邊加上一個 `+` 號,可以證明其並不改變運算結果,且字串可以分割成多個 `<運算符, 數字>` 的配對形式;這樣一來我們就可以從左到右處理。由於乘除的優先級高於加減,因此我們需要使用一個中間變數來儲存高優先度的運算結果。 此類型題目也考驗很多細節處理,例如沒有運算符的情況,以及多個空格的情況等等。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-2-tree-recursion.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-2-tree-recursion.mdx index 75f3f6da..3c0ad993 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-2-tree-recursion.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-2-tree-recursion.mdx @@ -386,7 +386,7 @@ def isSymmetric(root: Optional[TreeNode]) -> bool: ### 輸入輸出範例 -輸入是一個整數二元樹和一維整數陣列,輸出是一個陣列,每個位置存儲一個子樹(的根節點)。 +輸入是一個整數二元樹和一維整數陣列,輸出是一個陣列,每個位置儲存一個子樹(的根節點)。 ``` Input: to_delete = [3,5], tree = diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-3-level-order-traversal.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-3-level-order-traversal.mdx index b7f8cb81..e5192862 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-3-level-order-traversal.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-3-level-order-traversal.mdx @@ -4,7 +4,7 @@ sidebar_position: 70 # 13.3 層次遍歷 -我們可以使用廣度優先搜尋進行層次遍歷。注意,不需要使用兩個佇列來分別存儲當前層的節點和下一層的節點,因為在開始遍歷一層節點時,當前佇列中的節點數就是當前層的節點數,只要控制遍歷這麼多節點數,就能保證這次遍歷的都是當前層的節點。 +我們可以使用廣度優先搜尋進行層次遍歷。注意,不需要使用兩個佇列來分別儲存當前層的節點和下一層的節點,因為在開始遍歷一層節點時,當前佇列中的節點數就是當前層的節點數,只要控制遍歷這麼多節點數,就能保證這次遍歷的都是當前層的節點。 ## [637. Average of Levels in Binary Tree](https://leetcode.com/problems/average-of-levels-in-binary-tree/) diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-1-common-sorting-algorithms.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-1-common-sorting-algorithms.mdx index 281e2a71..1cfd2cfc 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-1-common-sorting-algorithms.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-1-common-sorting-algorithms.mdx @@ -87,9 +87,9 @@ def quickSort(nums: List[int], l: int, r: int) -> None: ## 合併排序(Merge Sort) -合併排序是典型的分治法,會在後續章節展開講解。簡單來說,對於一個未排序片段,我們可以先分別排序其左半側和右半側,然後將兩側重新合併(“治”);排序每個半側時可以通過遞歸再次將其切分為兩側(“分”)。 +合併排序是典型的分治法,會在後續章節展開講解。簡單來說,對於一個未排序片段,我們可以先分別排序其左半側和右半側,然後將兩側重新合併(“治”);排序每個半側時可以通過遞迴再次將其切分為兩側(“分”)。 -我們採用左閉右閉的二分寫法,初始化條件為 $l = 0, r = n - 1$,並提前建立一個與 nums 大小相同的陣列 cache,用來存儲臨時結果。 +我們採用左閉右閉的二分寫法,初始化條件為 $l = 0, r = n - 1$,並提前建立一個與 nums 大小相同的陣列 cache,用來儲存臨時結果。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-2-depth-first-search.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-2-depth-first-search.mdx index b42ac1fd..910c3a40 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-2-depth-first-search.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-2-depth-first-search.mdx @@ -42,9 +42,9 @@ Output: 6 ### 題解 -此題是一個非常標準的搜索問題,我們可以用來練習深度優先搜索(DFS)。一般來說,深度優先搜索類型的題目可以分為主函數和輔函數兩部分。主函數負責遍歷所有的搜索位置,判斷是否可以開始搜索,如果可以則調用輔函數進行搜索。輔函數則負責深度優先搜索的遞歸調用。 +此題是一個非常標準的搜索問題,我們可以用來練習深度優先搜索(DFS)。一般來說,深度優先搜索類型的題目可以分為主函數和輔函數兩部分。主函數負責遍歷所有的搜索位置,判斷是否可以開始搜索,如果可以則調用輔函數進行搜索。輔函數則負責深度優先搜索的遞迴調用。 -當然,我們也可以使用堆疊(stack)來實現深度優先搜索,但由於堆疊與遞歸的運作原理相同,而遞歸相對來說實現起來更為方便,因此在刷題時建議使用遞歸的寫法,這樣也有利於進行回溯(見下節)。不過在實際工程中,直接使用堆疊可能才是更好的選擇,原因有二:一是更容易理解,二是不容易出現遞歸堆疊溢出的情況。 +當然,我們也可以使用堆疊(stack)來實現深度優先搜索,但由於堆疊與遞迴的運作原理相同,而遞迴相對來說實現起來更為方便,因此在刷題時建議使用遞迴的寫法,這樣也有利於進行回溯(見下節)。不過在實際工程中,直接使用堆疊可能才是更好的選擇,原因有二:一是更容易理解,二是不容易出現遞迴堆疊溢出的情況。 我們先展示使用堆疊的寫法。這裡我們使用了一個小技巧,對於四個方向的遍歷,可以創建一個陣列 `[-1, 0, 1, 0, -1]`,每相鄰兩位即對應上下左右四個方向之一。當然,您也可以顯式地寫成 `[-1, 0]`、`[1, 0]`、`[0, 1]` 和 `[0, -1]`,以便於理解。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-3-backtracking.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-3-backtracking.mdx index 29314786..b96bae61 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-3-backtracking.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-3-backtracking.mdx @@ -32,7 +32,7 @@ Output: [[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,2,1], [3,1,2]] ### 題解 -如何生成所有排列方式呢?對於每個位置 \(i\),我們可以將其與之後的任意位置交換,然後處理位置 \(i+1\),直到處理到最後一位。為了避免每次遍歷時新建一個陣列存儲前 \(i\) 個已交換好的數字,我們可以利用回溯法,僅修改原陣列,並在遞迴完成後復原。 +如何生成所有排列方式呢?對於每個位置 \(i\),我們可以將其與之後的任意位置交換,然後處理位置 \(i+1\),直到處理到最後一位。為了避免每次遍歷時新建一個陣列儲存前 \(i\) 個已交換好的數字,我們可以利用回溯法,僅修改原陣列,並在遞迴完成後復原。 以樣例 `[1,2,3]` 為例,按照此方法,我們的輸出順序為:`[[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,2,1], [3,1,2]]`,確保涵蓋所有排列。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-4-breadth-first-search.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-4-breadth-first-search.mdx index 59038699..3297147b 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-4-breadth-first-search.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-4-breadth-first-search.mdx @@ -322,7 +322,7 @@ void backtracking(const string &src, const string &dst, vector> findLadders(string beginWord, string endWord, vector &wordList) { vector> ladder; - // 使用哈希集合儲存字典,方便查找。 + // 使用雜湊集合儲存字典,方便查找。 unordered_set word_dict; for (const auto &w : wordList) { word_dict.insert(w); @@ -333,7 +333,7 @@ vector> findLadders(string beginWord, string endWord, word_dict.erase(beginWord); word_dict.erase(endWord); // 建立兩個queue,從beginWord和endWord同時延展,每次延展最小的。 - // 因為之後的去重操作需要遍歷queue,我們這裡用哈希表實現它, + // 因為之後的去重操作需要遍歷queue,我們這裡用雜湊表實現它, // 只要保證是分層次遍歷即可。 unordered_set q_small{beginWord}, q_large{endWord}; unordered_map> next_words; @@ -404,13 +404,13 @@ def backtracking(src: str, dst: str, next_words: Dict[str, List[str]], def findLadders(beginWord: str, endWord: str, wordList: List[str]) -> List[List[str]]: ladder = [] - # 使用哈希集合儲存字典,方便查找。 + # 使用雜湊集合儲存字典,方便查找。 word_dict = set(wordList) if endWord not in word_dict: return ladder word_dict = word_dict.difference(set([beginWord, endWord])) # 建立兩個queue,從beginWord和endWord同時延展,每次延展最小的。 - # 因為之後的去重操作需要遍歷queue,我們這裡用哈希表實現它, + # 因為之後的去重操作需要遍歷queue,我們這裡用雜湊表實現它, # 只要保證是分層次遍歷即可。 q_small, q_large = set([beginWord]), set([endWord]) next_words = dict() diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-2-basic-dp-1d.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-2-basic-dp-1d.mdx index e72e030f..2d665b15 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-2-basic-dp-1d.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/6-dynamic-programming/6-2-basic-dp-1d.mdx @@ -63,7 +63,7 @@ def climbStairs(n: int) -> int: -進一步的,我們可以對動態規劃進行空間壓縮。因為 dp[i] 只與 dp[i-1] 和 dp[i-2] 有關,因此可以只用兩個變數來存儲 dp[i-1] 和 dp[i-2],使得原來的 $O(n)$ 空間複雜度優化為 $O(1)$ 複雜度。 +進一步的,我們可以對動態規劃進行空間壓縮。因為 dp[i] 只與 dp[i-1] 和 dp[i-2] 有關,因此可以只用兩個變數來儲存 dp[i-1] 和 dp[i-2],使得原來的 $O(n)$ 空間複雜度優化為 $O(1)$ 複雜度。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-2-expression-problems.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-2-expression-problems.mdx index 2888cc56..17bb29c3 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-2-expression-problems.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/7-divide-and-conquer/7-2-expression-problems.mdx @@ -76,7 +76,7 @@ def diffWaysToCompute(expression: str) -> List[int]: -我們發現,某些被 `divide` 的子字串可能重複出現多次,因此我們可以利用 `memoization` 來避免重複計算。例如,我們可以建立一個哈希表,`key` 是 `(l, r)`,`value` 是 `ways`。當再次遇到相同的 `(l, r)` 時,我們可以直接返回已經計算過的 `ways`。或者,與其我們從上到下用分治法結合 `memoization`,不如直接從下到上使用動態規劃處理。 +我們發現,某些被 `divide` 的子字串可能重複出現多次,因此我們可以利用 `memoization` 來避免重複計算。例如,我們可以建立一個雜湊表,`key` 是 `(l, r)`,`value` 是 `ways`。當再次遇到相同的 `(l, r)` 時,我們可以直接返回已經計算過的 `ways`。或者,與其我們從上到下用分治法結合 `memoization`,不如直接從下到上使用動態規劃處理。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-3-binary-properties.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-3-binary-properties.mdx index 8f5e697a..6afe5ac9 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-3-binary-properties.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/9-bitwise-operations/9-3-binary-properties.mdx @@ -27,7 +27,7 @@ Output: 4 ### 題解 -怎樣快速判斷兩個字母串是否含有重複字母呢?可以為每個字母串建立一個長度為 26 的二進制數字,每個位置表示是否存在該字母。如果兩個字母串含有重複字母,那它們的二進制表示的按位與不為 0。同時,我們可以建立一個哈希表來存儲二進制數字到最長子母串長度的映射關係,比如 ab 和 aab 的二進制數字相同,但是 aab 更長。 +怎樣快速判斷兩個字母串是否含有重複字母呢?可以為每個字母串建立一個長度為 26 的二進制數字,每個位置表示是否存在該字母。如果兩個字母串含有重複字母,那它們的二進制表示的按位與不為 0。同時,我們可以建立一個雜湊表來儲存二進制數字到最長子母串長度的映射關係,比如 ab 和 aab 的二進制數字相同,但是 aab 更長。 From 0e494f4414b5661e74859c38526ebf0c64e77a1d Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Mon, 9 Dec 2024 01:09:26 +0100 Subject: [PATCH 46/49] Ch4 complexity analysis --- .../current/4-sorting-algorithms/4-2-quick-select.mdx | 9 ++++++++- .../current/4-sorting-algorithms/4-3-bucket-sort.mdx | 7 ++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-2-quick-select.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-2-quick-select.mdx index f3e18bbe..32a24ab0 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-2-quick-select.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-2-quick-select.mdx @@ -75,4 +75,11 @@ def findKthLargest(nums: List[int], k: int) -> int: - \ No newline at end of file + + +### 複雜度分析 + +- **時間複雜度**: + - 平均情況:$O(n)$,因為每次劃分會縮小問題規模。 + - 最壞情況:$O(n^2)$,當每次選擇的樞軸總是最差值(例如極大值或極小值)。 +- **空間複雜度**: $O(n)$,需要額外的空間來存放三個分組的元素。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-3-bucket-sort.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-3-bucket-sort.mdx index 154eebd8..d9eb505b 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-3-bucket-sort.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-3-bucket-sort.mdx @@ -80,4 +80,9 @@ def topKFrequent(nums: List[int], k: int) -> List[int]: - \ No newline at end of file + + +### 複雜度分析 +- **時間複雜度**: $O(n)$,統計頻率需要 $O(n)$ 時間,桶排序收集元素的時間複雜度也是 $O(n)$,其中 $n$ 是 `nums` 的長度。 + +- **空間複雜度**: $O(n)$:`counts` 和 `buckets` 需要儲存所有元素及其頻率,最壞情況下需要 $O(n)$ 空間。 \ No newline at end of file From 3de5d5e952e506743c2c2170da8214e708d37fff Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Mon, 9 Dec 2024 10:18:15 +0100 Subject: [PATCH 47/49] Ch4 exercise solutions --- .../4-sorting-algorithms/4-4-exercises.md | 96 ++++++++++++++++++- 1 file changed, 95 insertions(+), 1 deletion(-) diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-4-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-4-exercises.md index 7979d20f..9f74424b 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-4-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/4-sorting-algorithms/4-4-exercises.md @@ -10,10 +10,104 @@ sidebar_position: 20 桶排序的變形題。 +
        + 題解 + +#### 解題思路 + +本題要求根據字元的出現頻率對字元進行排序,並返回排序後的字串。可以使用 **雜湊表** 和 **桶排序** 來高效解決這個問題。 + +1. **統計字元頻率**: + - 使用 `Counter` 統計每個字元的出現次數,將結果儲存到 `counts`。 + +2. **桶排序**: + - 建立一個桶 `buckets`,其中索引表示字元的出現頻率,值是具有該頻率的字元列表。 + - 根據字元的頻率將它們放入對應的桶中。 + +3. **生成結果**: + - 從高頻到低頻遍歷桶,根據頻率將字元重複相應次數,拼接成結果字串。 + +#### 程式碼 + +```python +class Solution: + def frequencySort(self, s: str) -> str: + counts = Counter(s) + buckets = dict() + result = [] + for char, count in counts.items(): + if count in buckets: + buckets[count].append(char) + else: + buckets[count] = [char] + for count in range(len(s), 0, -1): + if count in buckets: + for char in buckets[count]: + result.append(char*count) + return ''.join(result) +``` + +#### 複雜度分析 + +- **時間複雜度**: + - $O(n)$,其中 $n$ 是字串的長度。統計頻率需要 $O(n)$,桶排序和拼接結果也需要 $O(n)$。 + +- **空間複雜度**: + - $O(n)$,用於儲存字元頻率的雜湊表和桶。 + +
        + + --- ## 進階難度 ### [75. Sort Colors](https://leetcode.com/problems/sort-colors/) -非常經典的荷蘭國旗問題,考察如何對三個重複且混亂的值進行排序。 \ No newline at end of file +非常經典的荷蘭國旗問題,考察如何對三個重複且混亂的值進行排序。 + +
        + 題解 + +#### 解題思路 + +本題要求對包含 `0`、`1` 和 `2` 的陣列進行排序,使得相同數字的元素相鄰,並且按照 `0`、`1`、`2` 的順序排列。我們可以在 $O(n)$ 的時間複雜度內使用 **雙指標(雙指針)** 來完成排序,該方法被稱為 **荷蘭國旗問題**。 + +1. **初始化三個指標**: + - `left`:指向下一個要放置 `0` 的位置。 + - `right`:指向下一個要放置 `2` 的位置。 + - `i`:當前遍歷的索引。 + +2. **遍歷陣列**: + - 當 `nums[i] == 0` 時,將 `nums[i]` 與 `nums[left]` 交換,然後將 `left` 和 `i` 向右移動。 + - 當 `nums[i] == 2` 時,將 `nums[i]` 與 `nums[right]` 交換,並將 `right` 向左移動(此時不移動 `i`,因為交換過來的值可能還需要處理)。 + - 當 `nums[i] == 1` 時,僅將 `i` 向右移動。 + +3. **終止條件**: + - 當 `i` 超過 `right` 時,排序完成。 + +#### 程式碼 + +```python +class Solution: + def sortColors(self, nums: List[int]) -> None: + left, i, right = 0, 0, len(nums) - 1 + + while i <= right: + if nums[i] == 0: + nums[left], nums[i] = nums[i], nums[left] + left += 1 + i += 1 + elif nums[i] == 2: + nums[right], nums[i] = nums[i], nums[right] + right -= 1 + else: + i += 1 +``` + +#### 複雜度分析 + +- **時間複雜度**: $O(n)$,其中 $n$ 是陣列的長度。每個元素最多只被遍歷一次。 +- **空間複雜度**: $O(1)$,僅使用了常數額外空間。 + +
        From a73b25344d84321a1ea15243444e13543b663039 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Sun, 5 Jan 2025 12:16:03 +0100 Subject: [PATCH 48/49] Ch5 complexity analysis --- .../5-2-depth-first-search.mdx | 14 +++--- .../5-4-breadth-first-search.mdx | 16 +++---- .../5-2-depth-first-search.mdx | 14 +++--- .../5-4-breadth-first-search.mdx | 18 ++++---- .../5-2-depth-first-search.mdx | 45 ++++++++++++++----- .../5-3-backtracking.mdx | 25 ++++++++++- .../5-4-breadth-first-search.mdx | 37 +++++++++++---- 7 files changed, 116 insertions(+), 53 deletions(-) diff --git a/leetcode_101/docs/5-searching-algorithms/5-2-depth-first-search.mdx b/leetcode_101/docs/5-searching-algorithms/5-2-depth-first-search.mdx index 60ba3e14..2027b337 100644 --- a/leetcode_101/docs/5-searching-algorithms/5-2-depth-first-search.mdx +++ b/leetcode_101/docs/5-searching-algorithms/5-2-depth-first-search.mdx @@ -9,9 +9,9 @@ sidebar_position: 22 考虑如下一颗简单的树,我们从 1 号节点开始遍历。假如遍历顺序是从左子节点到右子节点,那么按照优先向着“深”的方向前进的策略,则遍历过程为 1(起始节点)->2(遍历更深一层的左子节点)->4(遍历更深一层的左子节点)->2(无子节点,返回父结点)->1(子节点均已完成遍历,返回父结点)->3(遍历更深一层的右子节点)->1(无子节点,返回父结点)-> 结束程序(子节点均已完成遍历)。如果我们使用栈实现,我们的栈顶元素的变化过程为 1->2->4->3。 ``` - 1 - / \ - 2 3 + 1 + / \ + 2 3 / 4 ``` @@ -33,8 +33,8 @@ sidebar_position: 22 ``` Input: [[1,0,1,1,0,1,0,1], -[1,0,1,1,0,1,1,1], -[0,0,0,0,0,0,0,1]] + [1,0,1,1,0,1,1,1], + [0,0,0,0,0,0,0,1]] Output: 6 ``` @@ -184,8 +184,8 @@ def maxAreaOfIsland(grid: List[List[int]]) -> int: ``` Input: [[1,1,0], -[1,1,0], -[0,0,1]] + [1,1,0], + [0,0,1]] Output: 2 ``` diff --git a/leetcode_101/docs/5-searching-algorithms/5-4-breadth-first-search.mdx b/leetcode_101/docs/5-searching-algorithms/5-4-breadth-first-search.mdx index bb14e881..f4afb9ec 100644 --- a/leetcode_101/docs/5-searching-algorithms/5-4-breadth-first-search.mdx +++ b/leetcode_101/docs/5-searching-algorithms/5-4-breadth-first-search.mdx @@ -7,9 +7,9 @@ sidebar_position: 24 `广度优先搜索`(breadth-first search,BFS)不同与深度优先搜索,它是一层层进行遍历的,因此`需要用先入先出的队列 (queue)` 而非先入后出的栈 (stack) 进行遍历。由于是按层次进行遍历,广度优先搜索时按照“广”的方向进行遍历的,也常常用来处理最短路径等问题。在 Python 中,我们可以用 collections.deque 来实现 C++ 中的 queue。 ``` - 1 - / \ - 2 3 + 1 + / \ + 2 3 / 4 ``` @@ -106,11 +106,11 @@ def shortestPathBinaryMatrix(grid: List[List[int]]) -> int: for dy in range(-1, 2): if dx == 0 and dy == 0: continue - x, y = r + dx, c + dy - if x < 0 or y < 0 or x >= m or y >= n or grid[x][y] != 0: - continue - grid[x][y] = -1 - q.append((x, y)) + x, y = r + dx, c + dy + if x < 0 or y < 0 or x >= m or y >= n or grid[x][y] != 0: + continue + grid[x][y] = -1 + q.append((x, y)) count = len(q) return -1 ``` diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-2-depth-first-search.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-2-depth-first-search.mdx index 8daa29db..034fc8dc 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-2-depth-first-search.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-2-depth-first-search.mdx @@ -10,9 +10,9 @@ Consider the following simple tree, starting traversal from node 1. If the trave ``` - 1 - / \ - 2 3 + 1 + / \ + 2 3 / 4 ``` @@ -36,8 +36,8 @@ Input: a 2D grid; Output: the maximum area of an island. ``` Input: [[1,0,1,1,0,1,0,1], -[1,0,1,1,0,1,1,1], -[0,0,0,0,0,0,0,1]] + [1,0,1,1,0,1,1,1], + [0,0,0,0,0,0,0,1]] Output: 6 ``` @@ -188,8 +188,8 @@ The input is a 2D matrix, and the output is an integer representing the number o ``` Input: [[1,1,0], -[1,1,0], -[0,0,1]] + [1,1,0], + [0,0,1]] Output: 2 ``` diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-4-breadth-first-search.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-4-breadth-first-search.mdx index 7952b382..4293700a 100644 --- a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-4-breadth-first-search.mdx +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-4-breadth-first-search.mdx @@ -8,9 +8,9 @@ sidebar_position: 24 ``` - 1 - / \ - 2 3 + 1 + / \ + 2 3 / 4 ``` @@ -96,7 +96,7 @@ def shortestPathBinaryMatrix(grid: List[List[int]]) -> int: dist = 0 q = collections.deque() q.append((0, 0)) - grid[0][0] = -1 # -1 indicates visited + grid[0][0] = -1 # -1表示visited count = len(q) while count > 0: dist += 1 @@ -109,11 +109,11 @@ def shortestPathBinaryMatrix(grid: List[List[int]]) -> int: for dy in range(-1, 2): if dx == 0 and dy == 0: continue - x, y = r + dx, c + dy - if x < 0 or y < 0 or x >= m or y >= n or grid[x][y] != 0: - continue - grid[x][y] = -1 - q.append((x, y)) + x, y = r + dx, c + dy + if x < 0 or y < 0 or x >= m or y >= n or grid[x][y] != 0: + continue + grid[x][y] = -1 + q.append((x, y)) count = len(q) return -1 ``` diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-2-depth-first-search.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-2-depth-first-search.mdx index 910c3a40..10e2dd30 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-2-depth-first-search.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-2-depth-first-search.mdx @@ -9,9 +9,9 @@ sidebar_position: 22 考慮以下簡單的樹結構,從節點 1 開始進行遍歷。如果遍歷順序是從左子節點到右子節點,那麼按照優先往“深”的方向前進的策略,遍歷過程將是:1(起始節點)→ 2(更深層的左子節點)→ 4(更深層的左子節點)→ 2(無子節點,返回父節點)→ 1(所有子節點已完成遍歷,返回父節點)→ 3(更深層的右子節點)→ 1(無子節點,返回父節點)→ 結束程序(所有子節點已完成遍歷)。如果我們使用堆疊實現,堆疊頂部元素的變化過程將是:1 → 2 → 4 → 3。 ``` - 1 - / \ - 2 3 + 1 + / \ + 2 3 / 4 ``` @@ -33,8 +33,8 @@ sidebar_position: 22 ``` Input: [[1,0,1,1,0,1,0,1], -[1,0,1,1,0,1,1,1], -[0,0,0,0,0,0,0,1]] + [1,0,1,1,0,1,1,1], + [0,0,0,0,0,0,0,1]] Output: 6 ``` @@ -120,6 +120,11 @@ def maxAreaOfIsland(grid: List[List[int]]) -> int: +### 複雜度分析(堆疊) + +- **時間複雜度**: $O(m \times n)$,其中 $m$ 和 $n$ 分別是網格的行數和列數。每個節點最多訪問一次。 +- **空間複雜度**: $O(m \times n)$,最壞情況下堆疊中可能包含整個網格的所有陸地節點。 + 下面我們展示遞迴寫法,注意進行遞迴搜尋時,一定要檢查邊界條件。可以在每次呼叫輔助函式之前檢查,也可以在輔助函式的一開始進行檢查。這裡我們沒有利用 [-1, 0, 1, 0, -1] 陣列進行上下左右四個方向的搜尋,而是直接顯式地寫出來四種不同的遞迴函式。兩種寫法都可以,讀者可以掌握任意一種。 @@ -174,6 +179,12 @@ def maxAreaOfIsland(grid: List[List[int]]) -> int: +### 複雜度分析(遞迴) + +- **時間複雜度**: $O(m \times n)$,其中 $m$ 是網格的行數,$n$ 是網格的列數。每個節點最多訪問一次。 + +- **空間複雜度**: $O(m \times n)$,最壞情況下遞迴堆疊的深度可能等於整個網格的大小(當所有節點都是 `1` 時)。 + ## [547. Number of Provinces](https://leetcode.com/problems/number-of-provinces/) ### 題目描述 @@ -187,8 +198,8 @@ def maxAreaOfIsland(grid: List[List[int]]) -> int: ``` Input: [[1,1,0], -[1,1,0], -[0,0,1]] + [1,1,0], + [0,0,1]] Output: 2 ``` @@ -260,6 +271,12 @@ def findCircleNum(isConnected: List[List[int]]) -> int: +### 複雜度分析 + +- **時間複雜度**: $O(n^2)$,其中 $n$ 是城市的數量。遍歷整個 `isConnected` 矩陣,並對每個城市進行 DFS。 + +- **空間複雜度**: $O(n)$,用於儲存 `visited` 集合和遞迴呼叫的堆疊空間。 + ## [417. Pacific Atlantic Water Flow](https://leetcode.com/problems/pacific-atlantic-water-flow/) @@ -276,9 +293,9 @@ Input: 太平洋 ~ ~ ~ ~ ~ ~ 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 * + ~ 2 4 (5) 3 1 * + ~ (6) (7) 1 4 5 * + ~ (5) 1 1 2 4 * * * * * * 大西洋 Output: [[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]] ``` @@ -372,4 +389,10 @@ def pacificAtlantic(heights: List[List[int]]) -> List[List[int]]: - \ No newline at end of file + + +### 複雜度分析 + +- **時間複雜度**: $O(m \times n)$,其中 $m$ 是網格的行數,$n$ 是網格的列數。每個節點最多訪問一次。 + +- **空間複雜度**: $O(m \times n)$,用於儲存兩個布林矩陣和遞迴堆疊空間。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-3-backtracking.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-3-backtracking.mdx index b96bae61..806e5059 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-3-backtracking.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-3-backtracking.mdx @@ -34,7 +34,7 @@ Output: [[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,2,1], [3,1,2]] 如何生成所有排列方式呢?對於每個位置 \(i\),我們可以將其與之後的任意位置交換,然後處理位置 \(i+1\),直到處理到最後一位。為了避免每次遍歷時新建一個陣列儲存前 \(i\) 個已交換好的數字,我們可以利用回溯法,僅修改原陣列,並在遞迴完成後復原。 -以樣例 `[1,2,3]` 為例,按照此方法,我們的輸出順序為:`[[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,2,1], [3,1,2]]`,確保涵蓋所有排列。 +以範例 `[1,2,3]` 為例,按照此方法,我們的輸出順序為:`[[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,2,1], [3,1,2]]`,確保涵蓋所有排列。 @@ -88,6 +88,11 @@ def permute(nums: List[int]) -> List[List[int]]: +### 複雜度分析 + +- **時間複雜度**: $O(n \times n!)$,其中 $n$ 是輸入數字的個數。總共有 $n!$ 個排列,每個排列的長度為 $n$。 +- **空間複雜度**: $O(n)$,遞迴堆疊的深度最多為 $n$。 + ## [77. Combinations](https://leetcode.com/problems/combinations/) ### 題目描述 @@ -164,6 +169,11 @@ def combine(n: int, k: int) -> List[List[int]]: +### 複雜度分析 +- **時間複雜度**: $O(C(n, k))$,其中 $C(n, k) = \frac{n!}{k!(n-k)!}$ 是 $n$ 中選擇 $k$ 個的組合數量,每次生成組合需要 $O(k)$ 的操作。 +- **空間複雜度**: $O(k)$,遞迴深度與暫存的組合長度相同,最多為 $k$。 + + ## [79. Word Search](https://leetcode.com/problems/word-search/) ### 題目描述 @@ -264,6 +274,12 @@ def exist(board: List[List[str]], word: str) -> bool: +### 複雜度分析 + +- **時間複雜度**: $O(m \times n \times 4^L)$,其中 $m$ 與 $n$ 是矩陣的行數與列數,$L$ 是字串的長度。矩陣中每個單元格最多需要進行 $4^L$ 次遞迴檢查。 +- **空間複雜度**: $O(m \times n)$,用於儲存訪問狀態的二維布林陣列 `visited`。 + + ## [51. N-Queens](https://leetcode.com/problems/n-queens/) ### 題目描述 @@ -375,4 +391,9 @@ def solveNQueens(n: int) -> List[List[str]]: - \ No newline at end of file + + +### 複雜度分析 + +- **時間複雜度**: $O(n!)$,每一行(row)最多嘗試 $n$ 個位置,且需要遞迴 $n$ 層。 +- **空間複雜度**: $O(n^2)$,主要來自棋盤狀態記錄的 $O(n^2)$ 和輔助陣列(`column`、`ldiag`、`rdiag`)的 $O(n)$,以及遞迴堆疊的 $O(n)$,但棋盤占用空間為主導因素。 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-4-breadth-first-search.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-4-breadth-first-search.mdx index 3297147b..d27c76e6 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-4-breadth-first-search.mdx +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-4-breadth-first-search.mdx @@ -8,9 +8,9 @@ sidebar_position: 24 ``` - 1 - / \ - 2 3 + 1 + / \ + 2 3 / 4 ``` @@ -108,11 +108,11 @@ def shortestPathBinaryMatrix(grid: List[List[int]]) -> int: for dy in range(-1, 2): if dx == 0 and dy == 0: continue - x, y = r + dx, c + dy - if x < 0 or y < 0 or x >= m or y >= n or grid[x][y] != 0: - continue - grid[x][y] = -1 - q.append((x, y)) + x, y = r + dx, c + dy + if x < 0 or y < 0 or x >= m or y >= n or grid[x][y] != 0: + continue + grid[x][y] = -1 + q.append((x, y)) count = len(q) return -1 ``` @@ -121,6 +121,12 @@ def shortestPathBinaryMatrix(grid: List[List[int]]) -> int: +### 複雜度分析 + +- **時間複雜度**: $O(n^2)$,最差情況下需遍歷整個棋盤,其中 $n$ 為棋盤的邊長。 +- **空間複雜度**: $O(n^2)$,主要來自佇列 `q` 和訪問標記。 + + ## [934. Shortest Bridge](https://leetcode.com/problems/shortest-bridge/) ### 題目描述 @@ -266,6 +272,11 @@ def shortestBridge(grid: List[List[int]]) -> int: +### 複雜度分析 + +- **時間複雜度**: $O(n^2)$,其中 $n$ 是棋盤的邊長。DFS 遍歷第一個島嶼需要 $O(n^2)$,BFS 最多遍歷剩餘的格子,也需要 $O(n^2)$。 +- **空間複雜度**: $O(n^2)$,主要來自 `deque` 儲存邊界點,以及遞迴調用的堆疊空間。 + ## [126. Word Ladder II](https://leetcode.com/problems/word-ladder-ii/) ### 題目描述 @@ -453,4 +464,12 @@ def findLadders(beginWord: str, endWord: str, - \ No newline at end of file + + +### 複雜度分析 + +- **時間複雜度**: $O(N \times M^2)$,其中 $N$ 是單詞數量,$M$ 是單詞的長度。 + - 每個單詞的鄰居生成需要 $O(M \times 26)$ 次檢查。 + - BFS 最多需要處理 $N$ 個單詞。 + +- **空間複雜度**: $O(N \times M)$,主要來自 `next_words` 字典和 BFS 佇列。 From ef4f1b482c5b35d8856e24d2e47499e169fcf123 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Mon, 13 Jan 2025 09:49:09 +0100 Subject: [PATCH 49/49] Ch5 exercise solutions --- .../5-searching-algorithms/5-5-exercises.md | 391 +++++++++++++++++- 1 file changed, 390 insertions(+), 1 deletion(-) diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-5-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-5-exercises.md index 1f09844b..0f42bbf8 100644 --- a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-5-exercises.md +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/5-searching-algorithms/5-5-exercises.md @@ -10,12 +10,132 @@ sidebar_position: 25 從最外側開始填充,然後再考慮內部區域。 +
        +題解 + +#### 問題描述 + +給定一個 `m x n` 的二維矩陣,包含 `'X'` 和 `'O'`,找出所有被 `'X'` 包圍的區域,並將這些區域內的 `'O'` 替換為 `'X'`。被包圍的區域指的是完全被 `'X'` 包圍的 `'O'` 區域(上下左右四個方向)。 + +#### 解題思路 + +1. **關鍵觀察**: + - 位於矩陣邊界上的 `'O'` 以及與邊界相連的 `'O'` 不會被包圍。 + - 需要先將這些邊界上的 `'O'` 以及與其相連的 `'O'` 標記出來。 + +2. **解法設計**: + - 遍歷矩陣的四條邊界,對每個邊界上的 `'O'` 執行深度優先搜尋(DFS)或廣度優先搜尋(BFS),將與邊界相連的 `'O'` 標記為特殊字符(例如 `'T'`)。 + - 遍歷矩陣: + - 將剩餘的 `'O'` 替換為 `'X'`。 + - 將之前標記為 `'T'` 的恢復為 `'O'`。 + +3. **演算法步驟**: + - 使用 DFS 或 BFS 標記所有邊界的 `'O'`。 + - 替換剩餘的內部 `'O'`,恢復被標記的字符。 + +#### Python 範例程式碼 + +```python +class Solution: + def solve(self, board: List[List[str]]) -> None: + if not board or not board[0]: + return + + rows, cols = len(board), len(board[0]) + + def dfs(r, c): + if r < 0 or c < 0 or r >= rows or c >= cols or board[r][c] != 'O': + return + board[r][c] = 'T' # 標記為暫存字符 + # 向四個方向遞迴 + dfs(r + 1, c) + dfs(r - 1, c) + dfs(r, c + 1) + dfs(r, c - 1) + + # 標記邊界上的 'O' + for r in range(rows): + dfs(r, 0) + dfs(r, cols - 1) + for c in range(cols): + dfs(0, c) + dfs(rows - 1, c) + + # 處理矩陣 + for r in range(rows): + for c in range(cols): + if board[r][c] == 'O': + board[r][c] = 'X' # 替換被包圍的 'O' + elif board[r][c] == 'T': + board[r][c] = 'O' # 恢復邊界連通的 'O' +``` + +#### 複雜度分析 + +- **時間複雜度**: $O(m \times n)$,其中 $m$ 和 $n$ 分別是矩陣的行數和列數。DFS 遍歷整個矩陣。 +- **空間複雜度**: $O(m \times n)$,最壞情況下遞迴堆疊深度等於矩陣大小。 + +
        + + --- ### [257. Binary Tree Paths](https://leetcode.com/problems/binary-tree-paths/) 輸出二元樹中所有從根節點到葉子節點的路徑。使用回溯法與否有什麼區別? +
        +題解 + +#### 問題描述 + +給定一個二元樹,返回所有從根節點到葉節點的路徑。每條路徑以字符串形式表示,節點之間用 `"->"` 連接。 + +#### 解題思路 + +1. **問題分解**: + - 路徑從根節點開始,延伸至每個葉節點。 + - 使用遞迴遍歷二元樹,逐步構造路徑。 + - 當到達葉節點時,將完整路徑加入結果列表。 + +2. **演算法設計**: + - 使用深度優先搜尋(DFS)從根節點開始遍歷。 + - 每次進入新節點時,將其值加入當前路徑。 + - 若節點為葉節點,將當前路徑轉為字符串並加入結果。 + - 若不是葉節點,繼續對其左右子節點遞迴。 + +3. **特別處理**: + - 如果樹為空,直接返回空列表。 + +#### Python 範例程式碼 + +```python +class Solution: + def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]: + def dfs(node, path, paths): + if not node: + return + path.append(str(node.val)) # 加入當前節點值 + if not node.left and not node.right: # 如果是葉節點 + paths.append("->".join(path)) # 將路徑轉為字符串 + else: + dfs(node.left, path, paths) # 遞迴左子樹 + dfs(node.right, path, paths) # 遞迴右子樹 + path.pop() # 回溯 + + paths = [] + dfs(root, [], paths) + return paths +``` + +#### 複雜度分析 + +- **時間複雜度**: $O(n)$,其中 $n$ 是樹中節點數量。每個節點訪問一次。 +- **空間複雜度**: $O(h)$,其中 $h$ 是樹的高度。遞迴堆疊的最大深度與樹的高度成正比。 + +
        + + --- ## 進階難度 @@ -24,20 +144,289 @@ sidebar_position: 25 排列問題的進階版本,如何處理重複的元素? +
        +題解 + +#### 問題描述 + +給定一個可能包含重複元素的數字序列 `nums`,返回所有不重複的全排列。 + +#### 解題思路 + +1. **關鍵觀察**: + - 因為輸入數列可能包含重複數字,我們需要確保結果中的排列是唯一的。 + - 使用 `Counter` 來記錄每個數字的剩餘次數,可以在迭代中避免重複。 + +2. **解法設計**: + - 透過回溯法 (Backtracking) 枚舉所有排列: + - 每次選取數字前,檢查其計數是否大於 0。 + - 選取後,將計數減 1,並繼續遞迴。 + - 回溯時恢復該數字的計數,並從當前路徑中移除該數字。 + - 當路徑長度等於輸入數列長度時,將路徑加入結果。 + +--- + +#### Python 範例程式碼 + +```python +from collections import Counter + +class Solution: + def permuteUnique(self, nums: List[int]) -> List[List[int]]: + def btrack(path, counter): + if len(path) == len(nums): # 當路徑長度等於數列長度時,加入結果 + ans.append(path[:]) + return + for x in counter: # 遍歷所有唯一的數字 + if counter[x] > 0: + path.append(x) # 將數字加入路徑 + counter[x] -= 1 # 減少該數字的剩餘次數 + btrack(path, counter) # 遞迴 + path.pop() # 回溯時移除數字 + counter[x] += 1 # 恢復計數 + + ans = [] + btrack([], Counter(nums)) # 初始化計數器並開始回溯 + return ans +``` + +--- + +#### 複雜度分析 + +- **時間複雜度**: $O(n \times n!)$,其中 $n$ 是輸入數字的個數。 + - 總共有 $n!$ 個排列,每個排列的生成過程需要 $O(n)$ 時間。 +- **空間複雜度**: $O(n)$,用於遞迴堆疊和路徑的暫存空間。 + +
        + + + --- ### [40. Combination Sum II](https://leetcode.com/problems/combination-sum-ii/) 組合問題的進階版本,如何處理重複的元素? +
        +題解 + +#### 問題描述 + +給定一個整數數組 `candidates` 和一個目標值 `target`,找出所有不重複的組合,使得組合中的數字總和等於 `target`。 +`candidates` 中的每個數字只能在每個組合中使用一次。 + +--- + +#### 解題思路 + +1. **關鍵觀察**: + - 每個數字只能使用一次,因此需要在遍歷過程中跳過重複的數字。 + - 使用排序來幫助識別相鄰的重複數字,並在回溯過程中跳過它們。 + +2. **解法設計**: + - 先對 `candidates` 排序,方便後續處理重複元素。 + - 使用回溯法 (Backtracking): + - 每次選擇一個數字,將其加入當前路徑,並減少剩餘的目標值。 + - 遞迴處理下一個數字,確保索引只向後移動以避免重複使用。 + - 回溯時將數字移出路徑。 + - 如果當前數字與前一個數字相同且前一個數字未被使用,則跳過當前數字。 + +3. **重複處理**: + - 透過 `if i > start and candidates[i] == candidates[i - 1]` 跳過重複數字。 + +--- + +#### Python 範例程式碼 + +```python +class Solution: + def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]: + def backtrack(start, path, remaining): + if remaining == 0: # 如果目標值達成,加入結果 + ans.append(path[:]) + return + for i in range(start, len(candidates)): + # 跳過重複數字 + if i > start and candidates[i] == candidates[i - 1]: + continue + # 如果當前數字大於剩餘目標值,提前終止 + if candidates[i] > remaining: + break + path.append(candidates[i]) # 選擇當前數字 + backtrack(i + 1, path, remaining - candidates[i]) # 遞迴處理 + path.pop() # 回溯,移除當前數字 + + candidates.sort() # 排序以便處理重複元素 + ans = [] + backtrack(0, [], target) + return ans +``` + +--- + +#### 複雜度分析 + +- **時間複雜度**: $O(2^n)$,其中 $n$ 是 `candidates` 的長度。 + - 雖然排序需要 $O(n \log n)$ 時間,但主要的時間花費在回溯過程中,最壞情況下可能有 $2^n$ 種組合需要檢查。 +- **空間複雜度**: $O(n)$,遞迴堆疊的深度最多為 $n$。 + +
        + + --- ### [37. Sudoku Solver](https://leetcode.com/problems/sudoku-solver/) 非常經典的數獨問題,可以利用回溯法解決。事實上,針對數獨類型的問題,有許多進階的搜索方法和剪枝策略可以提升求解速度,例如啟發式搜索。 +
        +題解 + +#### 問題描述 + +編寫一個函式來解決數獨問題。 +數獨的解法需要滿足以下條件: +1. 每行的數字 `1-9` 必須唯一。 +2. 每列的數字 `1-9` 必須唯一。 +3. 每個 $3 \times 3$ 的小方格內數字 `1-9` 必須唯一。 + +輸入是一個 $9 \times 9$ 的二維列表,其中 `'.'` 表示空格,需用數字填充。 + +--- + +#### 解題思路 + +1. **問題拆解**: + - 使用回溯法 (Backtracking) 試圖填入數字。 + - 對每個空格測試數字 `1-9`,檢查是否符合數獨規則。 + - 如果符合則遞迴嘗試填寫下一格,否則回溯。 + +2. **有效性檢查**: + - 在每次填入數字時,檢查是否滿足數獨的行、列和 $3 \times 3$ 區域規則。 + +3. **優化**: + - 使用遞迴優先填入空格數量最少的位置,以減少無效測試次數。 + +--- + +#### Python 範例程式碼 + +```python +class Solution: + def solveSudoku(self, board: List[List[str]]) -> None: + def is_valid(r, c, num): + # 檢查列是否有重複 + if num in board[r]: + return False + # 檢查行是否有重複 + if num in (board[i][c] for i in range(9)): + return False + # 檢查 3x3 小方格是否有重複 + box_r, box_c = r // 3 * 3, c // 3 * 3 + for i in range(box_r, box_r + 3): + for j in range(box_c, box_c + 3): + if board[i][j] == num: + return False + return True + + def backtrack(): + for r in range(9): + for c in range(9): + if board[r][c] == '.': # 找到一個空格 + for num in map(str, range(1, 10)): # 試圖填入 '1' 到 '9' + if is_valid(r, c, num): # 檢查是否合法 + board[r][c] = num + if backtrack(): # 遞迴嘗試下一步 + return True + board[r][c] = '.' # 回溯 + return False # 若無法填入任何數字則失敗 + return True # 若所有格子都已填滿,返回成功 + + backtrack() +``` + +--- + +#### 複雜度分析 + +- **時間複雜度**: 最壞情況為 $O(9^{81})$,即最多需要嘗試每個格子可能的數字排列。但實際情況下,由於剪枝和限制,平均會遠小於最壞情況。 +- **空間複雜度**: $O(81)$,遞迴堆疊的深度最多為 81 層。 + +
        + + --- ### [310. Minimum Height Trees](https://leetcode.com/problems/minimum-height-trees/) -如何將這道題轉化為搜索類型的問題?應該使用深度優先搜索還是廣度優先搜索? \ No newline at end of file +如何將這道題轉化為搜索類型的問題?應該使用深度優先搜索還是廣度優先搜索? + +
        +題解 + +#### 問題描述 + +給定一個無向圖,表示為 $n$ 個節點的樹,其中每個節點被編號為 `0` 到 `n-1`,樹的邊緣表示為一個列表 `edges`,其中 `edges[i] = [a, b]` 表示節點 `a` 和節點 `b` 之間的邊。 +目標是找到所有樹的**最小高度樹**(Minimum Height Trees, MHT)的根。返回所有可能的根節點。 + +--- + +#### 解題思路 + +1. **關鍵觀察**: + - 樹的「中心節點」可以是 1 或 2 個節點,這些節點構成最小高度樹的根。 + - 使用拓撲排序修剪樹中的葉子節點,直到剩下 1 或 2 個節點為止。 + +2. **解法**: + - 利用 BFS 和鄰接表來實現拓撲排序。 + - 每次移除葉子節點,並更新鄰接節點的度數,將新的葉子節點加入隊列。 + - 當剩餘節點數量小於等於 2 時,返回這些節點。 + +--- + +#### Python 範例程式碼 + +```python +from collections import deque, defaultdict + +class Solution: + def findMinHeightTrees(self, n: int, edges: List[List[int]]) -> List[int]: + if n == 1: + return [0] + + # 建立鄰接表和度數表 + graph = defaultdict(list) + degree = [0] * n + for a, b in edges: + graph[a].append(b) + graph[b].append(a) + degree[a] += 1 + degree[b] += 1 + + # 初始化葉子節點 + leaves = deque([i for i in range(n) if degree[i] == 1]) + + # 拓撲排序修剪葉子 + remaining_nodes = n + while remaining_nodes > 2: + remaining_nodes -= len(leaves) + for _ in range(len(leaves)): + leaf = leaves.popleft() + for neighbor in graph[leaf]: + degree[neighbor] -= 1 + if degree[neighbor] == 1: + leaves.append(neighbor) + + # 剩下的節點即為樹的中心 + return list(leaves) +``` + +--- + +#### 複雜度分析 + +- **時間複雜度**: $O(n)$,每條邊只被訪問一次。 +- **空間複雜度**: $O(n)$,用於鄰接表和隊列。 + +
        \ No newline at end of file

        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 L^>bP0l+XkKx059e literal 0 HcmV?d00001 diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/_category_.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/_category_.json new file mode 100644 index 00000000..4a0b8ebd --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/10-data-structures/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "10. 妙用数据结构 ", + "position": 10, + "link": { + "type": "generated-index", + "description": "第 10 章 妙用数据结构" + } +} diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-1-introduction.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-1-introduction.md new file mode 100644 index 00000000..9cd88891 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-1-introduction.md @@ -0,0 +1,7 @@ +--- +sidebar_position: 59 +--- + +# 11.1 引言 + +字符串可以看成是字符组成的数组。由于字符串是程序里经常需要处理的数据类型,因此有很多针对字符串处理的题目,以下是一些常见的类型。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-2-string-comparison.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-2-string-comparison.mdx new file mode 100644 index 00000000..4d4606b1 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-2-string-comparison.mdx @@ -0,0 +1,339 @@ +--- +sidebar_position: 60 +--- + +# 11.2 字符串比较 + +## [242. Valid Anagram](https://leetcode.com/problems/valid-anagram/) + +### 題目描述 + +判断两个字符串包含的字符是否完全相同。 + +### 輸入輸出範例 + +输入两个字符串,输出一个布尔值,表示两个字符串是否满足条件。 + +``` +Input: s = "anagram", t = "nagaram" +Output: true +``` + +### 題解 + +我们可以利用哈希表或者数组统计两个数组中每个数字出现的频次,若频次相同,则说明它们包含的字符完全相同。 + + + + +```cpp +bool isAnagram(string s, string t) { + if (s.length() != t.length()) { + return false; + } + vector counts(26, 0); + for (int i = 0; i < s.length(); ++i) { + ++counts[s[i] - ’a’]; + --counts[t[i] - ’a’]; + } + return all_of(counts.begin(), counts.end(), [](int c) { return c == 0; }); +} +``` + + + + +```py +def isAnagram(s: str, t: str) -> bool: + if len(s) != len(t): + return False + counter = Counter(s) + counter.subtract(t) + return all(v == 0 for v in counter.values()) +``` + + + + + +## [205. Isomorphic Strings](https://leetcode.com/problems/isomorphic-strings/) + +### 題目描述 + +判断两个字符串是否同构。同构的定义是,可以通过把一个字符串的某些相同的字符转换成另一些相同的字符,使得两个字符串相同,且两种不同的字符不能够被转换成同一种字符。 + +### 輸入輸出範例 + +输入两个字符串,输出一个布尔值,表示两个字符串是否满足条件。 + +``` +Input: s = "paper", t = "title" +Output: true +``` + +在这个样例中,通过把 s 中的 p、a、e、r 字符转换成 t、i、l、e 字符,可以使得两个字符串相同。 + +### 題解 + +我们可以将问题转化一下:记录两个字符串每个位置的字符第一次出现的位置,如果两个字符串中相同位置的字符与它们第一次出现的位置一样,那么这两个字符串同构。举例来说,对于“paper”和“title”,假设我们现在遍历到第三个字符“p”和“t”,发现它们第一次出现的位置都在第一个字符,则说明目前位置满足同构。同样的,我们可以用哈希表存储,也可以用一个长度为 128 的数组(ASCII 定义下字符的总数量)。 + + + + +```cpp +bool isIsomorphic(string s, string t) { + vector s_init(128, 0), t_init(128, 0); + for (int i = 0; i < s.length(); ++i) { + if (s_init[s[i]] != t_init[t[i]]) { + return false; + } + s_init[s[i]] = t_init[t[i]] = i + 1; + } + return true; +} +``` + + + + +```py +def isIsomorphic(s: str, t: str) -> bool: + s_init, t_init = [0] * 128, [0] * 128 + + for i in range(len(s)): + if s_init[ord(s[i])] != t_init[ord(t[i])]: + return False + s_init[ord(s[i])] = t_init[ord(t[i])] = i + 1 + + return True + +``` + + + + + +## [647. Palindromic Substrings](https://leetcode.com/problems/palindromic-substrings/) + +### 題目描述 + +给定一个字符,求其有多少个回文子字符串。回文的定义是左右对称。 + +### 輸入輸出範例 + +输入是一个字符串,输出一个整数,表示回文子字符串的数量。 + +``` +Input: "aaa" +Output: 6 +``` + +六个回文子字符串分别是 ["a","a","a","aa","aa","aaa"]。 + +### 題解 + +我们可以从字符串的每个位置开始,向左向右延长,判断存在多少以当前位置为中轴的回文子字符串。 + + + + +```cpp +// 輔助函式。 +int extendSubstrings(string s, int l, int r) { + int count = 0, n = s.length(); + while (l >= 0 && r < n && s[l] == s[r]) { + --l; + ++r; + ++count; + } + return count; +} +// 主函式。 +int countSubstrings(string s) { + int count = 0; + for (int i = 0; i < s.length(); ++i) { + count += extendSubstrings(s, i, i); // 奇数长度 + count += extendSubstrings(s, i, i + 1); // 偶数长度 + } + return count; +} +``` + + + + +```py +# 輔助函式。 +def extendSubstrings(s: str, l: int, r: int) -> int: + count, n = 0, len(s) + while l >= 0 and r < n and s[l] == s[r]: + count += 1 + l -= 1 + r += 1 + return count + +# 主函式。 +def countSubstrings(s: str) -> int: + return sum( + # 奇数长度 + 偶数长度。 + extendSubstrings(s, i, i) + extendSubstrings(s, i, i + 1) + for i in range(len(s)) + ) + +``` + + + + + +## [696. Count Binary Substrings](https://leetcode.com/problems/count-binary-substrings/) + +### 題目描述 + +给定一个 0-1 字符串,求有多少非空子字符串的 0 和 1 数量相同,且 0 和 1 必须连续出现(比如 0011、1100;0101 不算)。 + +### 輸入輸出範例 + +输入是一个字符串,输出一个整数,表示满足条件的子字符串的数量。 + +``` +Input: "00110011" +Output: 6 +``` + +在这个样例中,六个 0 和 1 数量相同的子字符串是 ["0011","01","1100","10","0011","01"]。 + +### 題解 + +从左往右遍历数组,记录和当前位置数字相同且连续的长度,以及其之前连续的不同数字的长度。举例来说,对于 00110 的最后一位,我们记录的相同数字长度是 1,因为只有一个连续 0;我们记录的不同数字长度是 2,因为在 0 之前有两个连续的 1。若不同数字的连续长度大于等于当前数字的连续长度,则说明存在一个且只存在一个以当前数字结尾的满足条件的子字符串。 + + + + +```cpp +int countBinarySubstrings(string s) { + int prev = 0, cur = 1, count = 0; + for (int i = 1; i < s.length(); ++i) { + if (s[i] == s[i - 1]) { + ++cur; + } else { + prev = cur; + cur = 1; + } + if (prev >= cur) { + ++count; + } + } + return count; +} +``` + + + + +```py +def countBinarySubstrings(s: str) -> int: + prev, cur, count = 0, 1, 0 + + for i in range(1, len(s)): + if s[i] == s[i - 1]: + cur += 1 + else: + prev = cur + cur = 1 + if prev >= cur: + count += 1 + + return count + +``` + + + + + +## [1249. Minimum Remove to Make Valid Parentheses](https://leetcode.com/problems/minimum-remove-to-make-valid-parentheses/) + +### 題目描述 + +给定一个包括字母和左右括号的字符串,求最少要移除多少个括号才能使其合法。 + +### 輸入輸出範例 + +输入是一个字符串,输出是合法且长度最长的移除结果。 + +``` +Input: s = "lee(t(c)o)de)" +Output: "lee(t(c)o)de" +``` + +返回 lee(t(co)de) 或 lee(t(c)ode) 也算正确。 + +### 題解 + +因为只有一种括号,所以我们并不一定利用栈来统计,可以直接用一个临时变量统计在当前位置时,左括号比右括号多出现多少次。如果在遍历过程中出现负数,则需要移除多余的右括号。如果遍历结束时临时变量为正数,则需要从右到左移除多余的左括号。这里我们使用了一个小技巧,先标记待删除位置,最后一起移除。 + + + + +```cpp +string minRemoveToMakeValid(string s) { + int count = 0, n = s.length(); + char to_delete = '#'; + for (char& c : s) { + if (c == '(') { + ++count; + } else if (c == ')') { + if (count > 0) { + --count; + } else { + c = to_delete; + } + } + } + for (int i = n - 1; i >= 0; --i) { + if (count == 0) break; + if (s[i] == '(') { + s[i] = to_delete; + --count; + } + } + s.erase(remove_if(s.begin(), s.end(), + [to_delete](char c) { return c == to_delete; }), + s.end()); + return s; +} + +``` + + + + +```py +def minRemoveToMakeValid(s: str) -> str: + count, n = 0, len(s) + to_delete = set() + + for i in range(n): + if s[i] == "(": + count += 1 + elif s[i] == ")": + if count > 0: + count -= 1 + else: + to_delete.add(i) + + for i in range(n - 1, -1, -1): + if count == 0: + break + if s[i] == "(": + to_delete.add(i) + count -= 1 + + return "".join(s[i] for i in range(n) if i not in to_delete) + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-3-string-interpretation.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-3-string-interpretation.mdx new file mode 100644 index 00000000..7c9ef3ee --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-3-string-interpretation.mdx @@ -0,0 +1,129 @@ +--- +sidebar_position: 61 +--- + +# 11.3 字符串理解 + +## [227. Basic Calculator II](https://leetcode.com/problems/basic-calculator-ii/) + +### 題目描述 + +给定一个包含加减乘除整数运算的字符串,求其运算的整数值结果。如果除不尽则向 0 取整。 + +### 輸入輸出範例 + +输入是一个合法的运算字符串,输出是一个整数,表示其运算结果。 + +``` +Input: " 3+5 / 2 " +Output: 5 +``` + +在这个样例中,因为除法的优先度高于加法,所以结果是 5 而非 4。 + +### 題解 + +如果我们在字符串左边加上一个加号,可以证明其并不改变运算结果,且字符串可以分割成多个 < 一个运算符,一个数字 > 对子的形式;这样一来我们就可以从左往右处理了。由于乘除的优先级高于加减,因此我们需要使用一个中间变量来存储高优先度的运算结果。 + +此类型题也考察很多细节处理,如无运算符的情况,和多个空格的情况等等。 + + + + +```cpp +// 辅函数 - parse从位置i开始的一个数字。 +int parseNum(const string& s, int& i) { + int num = 0, n = s.length(); + while (i < n && isdigit(s[i])) { + num = 10 * num + (s[i++] - '0'); + } + return num; +} + +// 主函式。 +int calculate(string s) { + char op = '+'; + long global_num = 0, local_num = 0; + int i = -1, n = s.length(); + while (++i < n) { + if (s[i] == ' ') { + continue; + } + long num = parseNum(s, i); + switch (op) { + case '+': + global_num += local_num; + local_num = num; + break; + case '-': + global_num += local_num; + local_num = -num; + break; + case '*': + local_num *= num; + break; + case '/': + local_num /= num; + break; + } + if (i < n) { + op = s[i]; + } + } + return global_num + local_num; +} + +``` + + + + +```py +from typing import Tuple + +# 辅函数 - parse从位置i开始的一个数字。 +# 返回(数字, 下一个i位置) +def parseNum(s: str, i: int) -> Tuple[int, int]: + num, n = 0, len(s) + while i < n and s[i].isdigit(): + num = 10 * num + int(s[i]) + i += 1 + return (num, i) + +# 主函式。 +def calculate(s: str) -> int: + op = "+" + global_num, local_num = 0, 0 + i, n = 0, len(s) + + while i < n: + if s[i] == " ": + i += 1 + continue + + num, i = parseNum(s, i) + + match op: + case "+": + global_num += local_num + local_num = num + case "-": + global_num += local_num + local_num = -num + case "*": + local_num *= num + case "/": + # int()会实现向0取整,而//对负数会远离0取整。 + local_num = int(local_num / num) + + if i < n: + op = s[i] + i += 1 + + return global_num + local_num + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-4-string-matching.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-4-string-matching.mdx new file mode 100644 index 00000000..22d6a833 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-4-string-matching.mdx @@ -0,0 +1,106 @@ +--- +sidebar_position: 62 +--- + +# 11.4 字符串匹配 + +## [28. Implement strStr()](https://leetcode.com/problems/find-the-index-of-the-first-occurrence-in-a-string/) + +### 題目描述 + +判断一个字符串是不是另一个字符串的子字符串,并返回其位置。 + +### 輸入輸出範例 + +输入一个母字符串和一个子字符串,输出一个整数,表示子字符串在母字符串的位置,若不存在则返回-1。 + +``` +Input: haystack = "hello", needle = "ll" +Output: 2 +``` + +### 題解 + +使用著名的Knuth-Morris-Pratt(KMP)算法,可以在 $O(m +n)$ 时间利用动态规划完成匹配。这里我们定义 dp 数组为,dp[i] 表示 needle 中以 i 位置截止的片段(即后缀),最长可以匹配到needle 从头开始的哪个位置(即前缀)。例如,ababaca 的 dp 数组是 [-1,-1,0,1,2,-1,0],表示每个位置最长可以匹配 [无, 无, a, ab, aba, 无, a]。 + +这道题比较复杂,初学者可以暂时跳过。 + + + + +```cpp +// 輔助函式。 +vector computeDp(const string &needle) { + int n = needle.length(); + vector dp(n, -1); + for (int j = 1, k = -1; j < n; ++j) { + while (k > -1 && needle[k + 1] != needle[j]) { + k = dp[k]; // 如果下一位不同,回溯到前一个前缀片段 + } + if (needle[k + 1] == needle[j]) { + ++k; // 前缀和后缀片段相同,匹配长度加1 + } + dp[j] = k; // 更新前缀匹配位置 + } + return dp; +} +// 主函式。 +int strStr(const string &haystack, const string &needle) { + int m = haystack.length(), n = needle.length(); + vector dp = computeDp(needle); + for (int i = 0, k = -1; i < m; ++i) { + while (k > -1 && needle[k + 1] != haystack[i]) { + k = dp[k]; // 如果下一位不同,回溯到前一个相同片段 + } + if (needle[k + 1] == haystack[i]) { + ++k; // 片段相同,匹配长度加1 + } + if (k == n - 1) { + return i - n + 1; // 匹配结束 + } + } + return -1; +} +``` + + + + +```py +from typing import List + +# 輔助函式。 +def computeDp(needle: str) -> List[int]: + n = len(needle) + dp = [-1] * n + k = -1 + for j in range(1, n): + while k > -1 and needle[k + 1] != needle[j]: + k = dp[k] # 如果下一位不同,回溯到前一个前缀片段 + if needle[k + 1] == needle[j]: + k += 1 # 前缀和后缀片段相同,匹配长度加1 + dp[j] = k # 更新前缀匹配位置 + return dp + +# 主函式。 +def strStr(haystack: str, needle: str) -> int: + m, n = len(haystack), len(needle) + if n == 0: + return 0 # Edge case for an empty needle + + dp = computeDp(needle) + k = -1 + for i in range(m): + while k > -1 and needle[k + 1] != haystack[i]: + k = dp[k] # 如果下一位不同,回溯到前一个相同片段 + if needle[k + 1] == haystack[i]: + k += 1 # 片段相同,匹配长度加1 + if k == n - 1: + return i - n + 1 # 匹配结束 + return -1 + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-5-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-5-exercises.md new file mode 100644 index 00000000..7bde275b --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/11-5-exercises.md @@ -0,0 +1,26 @@ +--- +sidebar_position: 63 +--- + +# 11.5 練習 + +## 基礎難度 + +### [409. Longest Palindrome](https://leetcode.com/problems/longest-palindrome/) + +计算一组字符可以构成的回文字符串的最大长度,可以利用其它数据结构进行辅助统计。 + +### [3. Longest Substring Without Repeating Characters](https://leetcode.com/problems/longest-substring-without-repeating-characters/) + +计算最长无重复子字符串,同样的,可以利用其它数据结构进行辅助统计。 + + +## 進階難度 + +### [772. Basic Calculator III](https://leetcode.com/problems/basic-calculator-iii/) + +题目 227 的 follow-up,十分推荐练习。 + +### [5. Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/) + +类似于我们讲过的子序列问题,子数组或子字符串问题常常也可以用动态规划来解决。先使用动态规划写出一个 $O(n^2)$ 时间复杂度的算法,再搜索一下 Manacher’s Algorithm,它可以在 $O(n)$ 时间解决这一问题。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/_category_.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/_category_.json new file mode 100644 index 00000000..688feb04 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/11-string-manipulation/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "11. 令人头大的字符串 ", + "position": 11, + "link": { + "type": "generated-index", + "description": "第 11 章 令人头大的字符串" + } +} diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-1-data-structure-introduction.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-1-data-structure-introduction.md new file mode 100644 index 00000000..b298b78e --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-1-data-structure-introduction.md @@ -0,0 +1,40 @@ +--- +sidebar_position: 64 +--- + +# 12.1 数据结构介绍 + +(单向)`链表`是由节点和指针构成的数据结构,每个节点存有一个值,和一个指向下一个节点的指针,因此很多链表问题可以用递归来处理。不同于数组,链表并不能直接获取任意节点的值,必须要通过指针找到该节点后才能获取其值。同理,在未遍历到链表结尾时,我们也无法知道链表的长度,除非依赖其他数据结构储存长度。LeetCode 默认的链表表示方法如下。 + + + + +```cpp +struct ListNode { + int val; + ListNode *next; + ListNode(int x) : val(x), next(nullptr) {} +}; +``` + + + + +```py +class ListNode: + def __init__(self, x): + self.val = x + self.next = None # or a ListNode +``` + + + + + +由于在进行链表操作时,尤其是删除节点时,经常会因为对当前节点进行操作而导致内存或指针出现问题。有两个小技巧可以解决这个问题:一是尽量处理当前节点的下一个节点而非当前节点本身,二是建立一个虚拟节点 (dummy node),使其指向当前链表的头节点,这样即使原链表所有节点全被删除,也会有一个 dummy 存在,返回 dummy->next 即可。 + +:::warning + + 一般来说,算法题不需要删除内存。在刷 LeetCode 的时候,如果想要删除一个节点,可以直接进行指针操作而无需回收内存。实际做软件工程时,对于无用的内存,笔者建议尽量显式回收,或利用智能指针。 + +::: \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-2-basic-linked-list-operations.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-2-basic-linked-list-operations.mdx new file mode 100644 index 00000000..242e7e95 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-2-basic-linked-list-operations.mdx @@ -0,0 +1,270 @@ +--- +sidebar_position: 65 +--- + +# 12.2 链表的基本操作 + +## [206. Reverse Linked List](https://leetcode.com/problems/reverse-linked-list/) + +### 題目描述 + +翻转一个链表。 + +### 輸入輸出範例 + +输入一个链表,输出该链表翻转后的结果。 + +``` +Input: 1->2->3->4->5->nullptr +Output: 5->4->3->2->1->nullptr +``` + +### 題解 + +链表翻转是非常基础也一定要掌握的技能。我们提供了两种写法——递归和非递归。建议你同时掌握这两种写法。 + +递归的写法为: + + + + +```cpp +ListNode* reverseList(ListNode* head, ListNode* head_prev = nullptr) { + if (head == nullptr) { + return head_prev; + } + ListNode* head_next = head->next; + head->next = head_prev; + return reverseList(head_next, head); +} +``` + + + + +```py +def reverseList( + head: Optional[ListNode], head_prev: Optional[ListNode] = None +) -> Optional[ListNode]: + if head is None: + return head_prev + head_next = head.next + head.next = head_prev + return reverseList(head_next, head) +``` + + + + + +非递归的写法为: + + + + +```cpp +ListNode* reverseList(ListNode* head) { + ListNode *head_prev = nullptr, *head_next; + while (head) { + head_next = head->next; + head->next = head_prev; + head_prev = head; + head = head_next; + } + return head_prev; +} +``` + + + + +```py +def reverseList(head: Optional[ListNode]) -> Optional[ListNode]: + head_prev = None + while head is not None: + head_next = head.next + head.next = head_prev + head_prev = head + head = head_next + return head_prev +``` + + + + + +## [21. Merge Two Sorted Lists](https://leetcode.com/problems/merge-two-sorted-lists/) + +### 題目描述 + +给定两个增序的链表,试将其合并成一个增序的链表。 + +### 輸入輸出範例 + +输入两个链表,输出一个链表,表示两个链表合并的结果。 + +``` +Input: 1->2->4, 1->3->4 +Output: 1->1->2->3->4->4 +``` + +### 題解 + +我们提供了递归和非递归,共两种写法。递归的写法为: + + + + +```cpp +ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { + if (l2 == nullptr) { + return l1; + } + if (l1 == nullptr) { + return l2; + } + if (l1->val < l2->val) { + l1->next = mergeTwoLists(l1->next, l2); + return l1; + } + l2->next = mergeTwoLists(l1, l2->next); + return l2; +} +``` + + + + +```py +def mergeTwoLists( + l1: Optional[ListNode], l2: Optional[ListNode] +) -> Optional[ListNode]: + if l1 is None or l2 is None: + return l1 or l2 + if l1.val < l2.val: + l1.next = mergeTwoLists(l1.next, l2) + return l1 + l2.next = mergeTwoLists(l1, l2.next) + return l2 +``` + + + + + +非递归的写法为: + + + + +```cpp +ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) { + ListNode *dummy = new ListNode(0), *node = dummy; + while (l1 && l2) { + if (l1->val < l2->val) { + node->next = l1; + l1 = l1->next; + } else { + node->next = l2; + l2 = l2->next; + } + node = node->next; + } + node->next = l1 == nullptr ? l2 : l1; + return dummy->next; +} +``` + + + + +```py +def mergeTwoLists( + l1: Optional[ListNode], l2: Optional[ListNode] +) -> Optional[ListNode]: + dummy = ListNode() + head = dummy + + while l1 and l2: + if l1.val < l2.val: + dummy.next = l1 + l1 = l1.next + else: + dummy.next = l2 + l2 = l2.next + dummy = dummy.next + + dummy.next = l1 or l2 + return head.next + +``` + + + + + +## [24. Swap Nodes in Pairs](https://leetcode.com/problems/swap-nodes-in-pairs/) + +### 題目描述 + +给定一个矩阵,交换每个相邻的一对节点。 + +### 輸入輸出範例 + +输入一个链表,输出该链表交换后的结果。 + +``` +Input: 1->2->3->4 +Output: 2->1->4->3 +``` + +### 題解 + +利用指针进行交换操作,没有太大难度,但一定要细心。 + + + + +```cpp +ListNode* swapPairs(ListNode* head) { + ListNode *node1 = head, *node2; + if (node1 && node1->next) { + node2 = node1->next; + node1->next = node2->next; + node2->next = node1; + head = node2; + while (node1->next && node1->next->next) { + node2 = node1->next->next; + node1->next->next = node2->next; + node2->next = node1->next; + node1->next = node2; + node1 = node2->next; + } + } + return head; +} +``` + + + + +```py +def swapPairs(head: Optional[ListNode]) -> Optional[ListNode]: + node1 = head + if node1 is not None and node1.next is not None: + node2 = node1.next + node1.next = node2.next + node2.next = node1 + head = node2 + while node1.next is not None and node1.next.next is not None: + node2 = node1.next.next + node1.next.next = node2.next + node2.next = node1.next + node1.next = node2 + node1 = node2.next + return head +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-3-other-linked-list-techniques.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-3-other-linked-list-techniques.mdx new file mode 100644 index 00000000..a5c8ed72 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-3-other-linked-list-techniques.mdx @@ -0,0 +1,140 @@ +--- +sidebar_position: 66 +--- + +# 12.3 其它链表技巧 + +## [160. Intersection of Two Linked Lists](https://leetcode.com/problems/intersection-of-two-linked-lists/) + +### 題目描述 + +给定两个链表,判断它们是否相交于一点,并求这个相交节点。 + +### 輸入輸出範例 + +输入是两条链表,输出是一个节点。如无相交节点,则返回一个空节点。 + +``` +Input: +A: a1 -> a2 + | + v + c1 -> c2 -> c3 + ^ + | +B: b1 -> b2 -> b3 +Output: c1 +``` + +### 題解 + +假设链表 A 的头节点到相交点的距离是 a,链表 B 的头节点到相交点的距离是 b,相交点到链表终点的距离为 c。我们使用两个指针,分别指向两个链表的头节点,并以相同的速度前进,若到达链表结尾,则移动到另一条链表的头节点继续前进。按照这种前进方法,两个指针会在 a + b + c 次前进后同时到达相交节点。 + + + + +```cpp +ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { + ListNode *l1 = headA, *l2 = headB; + while (l1 != l2) { + l1 = l1 != nullptr ? l1->next : headB; + l2 = l2 != nullptr ? l2->next : headA; + } + return l1; +} +``` + + + + +```py +def getIntersectionNode( + headA: ListNode, headB: ListNode +) -> Optional[ListNode]: + l1 = headA + l2 = headB + while l1 != l2: + l1 = l1.next if l1 is not None else headB + l2 = l2.next if l2 is not None else headA + return l1 +``` + + + + + +## [234. Palindrome Linked List](https://leetcode.com/problems/palindrome-linked-list/) + +### 題目描述 + +以 $O(1)$ 的空间复杂度,判断链表是否回文。 + +### 輸入輸出範例 + +输入是一个链表,输出是一个布尔值,表示链表是否回文。 + +``` +Input: 1->2->3->2->1 +Output: true +``` + +### 題解 + +先使用快慢指针找到链表中点,再把链表切成两半;然后把后半段翻转;最后比较两半是否相等。 + + + + +```cpp +bool isPalindrome(ListNode* head) { + if (head == nullptr || head->next == nullptr) { + return true; + } + ListNode *slow = head, *fast = head; + while (fast->next && fast->next->next) { + slow = slow->next; + fast = fast->next->next; + } + slow->next = reverseList(slow->next); // 见题目206 + slow = slow->next; + while (slow != nullptr) { + if (head->val != slow->val) { + return false; + } + head = head->next; + slow = slow->next; + } + return true; +} +``` + + + + +```py +def isPalindrome(head: Optional[ListNode]) -> bool: + if head is None or head.next is None: + return True + + slow, fast = head, head + + while fast.next is not None and fast.next.next is not None: + slow = slow.next + fast = fast.next.next + + slow.next = reverseList(slow.next) # 见题目206 + slow = slow.next + + while slow is not None: + if head.val != slow.val: + return False + head = head.next + slow = slow.next + + return True + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-4-exercises.md b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-4-exercises.md new file mode 100644 index 00000000..04e945c0 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/12-4-exercises.md @@ -0,0 +1,25 @@ +--- +sidebar_position: 67 +--- + +# 12.4 練習 + +## 基礎難度 + +### [83. Remove Duplicates from Sorted List](https://leetcode.com/problems/remove-duplicates-from-sorted-list/) + +虽然 LeetCode 没有强制要求,但是我们仍然建议你回收内存,尤其当题目要求你删除的时候。 + +### [328. Odd Even Linked List](https://leetcode.com/problems/odd-even-linked-list/) + +这道题其实很简单,千万不要把题目复杂化。 + +### [19. Remove Nth Node From End of List](https://leetcode.com/problems/remove-nth-node-from-end-of-list/) + +既然我们可以使用快慢指针找到中点,也可以利用类似的方法找到倒数第 n 个节点,无需遍历第二遍。 + +## 進階難度 + +### [148. Sort List](https://leetcode.com/problems/sort-list/) + +利用快慢指针找到链表中点后,可以对链表进行归并排序。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/_category_.json b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/_category_.json new file mode 100644 index 00000000..184a7911 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/12-linked-lists/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "12. 指针三剑客之一:链表", + "position": 12, + "link": { + "type": "generated-index", + "description": "第 12 章 指针三剑客之一:链表" + } +} diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-1-data-structure-introduction.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-1-data-structure-introduction.mdx new file mode 100644 index 00000000..3d50814f --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-1-data-structure-introduction.mdx @@ -0,0 +1,37 @@ +--- +sidebar_position: 68 +--- + +# 13.1 数据结构介绍 + +作为(单)链表的升级版,我们通常接触的树都是`二叉树`(binary tree),即每个节点最多有两个子节点;且除非题目说明,默认树中不存在循环结构。LeetCode 默认的树表示方法如下。 + + + + + +```cpp +struct TreeNode { + int val; + TreeNode *left; + TreeNode *right; + TreeNode(int x) : val(x), left(NULL), right(NULL) {} +}; +``` + + + + +```py +class TreeNode: + def __init__(self, val=0, left=None, right=None): + self.val = val + self.left = left + self.right = right +``` + + + + + +可以看出,其与链表的主要差别就是多了一个子节点的指针。 \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-2-tree-recursion.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-2-tree-recursion.mdx new file mode 100644 index 00000000..290491c9 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-2-tree-recursion.mdx @@ -0,0 +1,469 @@ +--- +sidebar_position: 69 +--- + +# 13.2 树的递归 + +对于一些简单的递归题,某些 LeetCode 达人喜欢写 one-line code,即用一行代码解决问题。我们也会展示一些这样的代码,但是对于新手,笔者仍然建议您使用多行的 if-else 判断语句。 + +在很多时候,树递归的写法与深度优先搜索的递归写法相同,因此本书不会区分二者。 + +## [104. Maximum Depth of Binary Tree](https://leetcode.com/problems/maximum-depth-of-binary-tree/) + +### 題目描述 + +求一个二叉树的最大深度。 + +### 輸入輸出範例 + +输入是一个二叉树,输出是一个整数,表示该树的最大深度。 + +``` +Input: + 3 + / \ + 9 20 + / \ + 15 7 +Output: 3 +``` + +### 題解 + +利用递归,我们可以很方便地求得最大深度。 + + + + +```cpp +int maxDepth(TreeNode* root) { + if (root == nullptr) { + return 0; + } + return max(maxDepth(root->left), maxDepth(root->right)) + 1; +} +``` + + + + +```py +def maxDepth(root: Optional[TreeNode]) -> int: + if root is None: + return 0 + return max(maxDepth(root.left), maxDepth(root.right)) + 1 +``` + + + + + +## [110. Balanced Binary Tree](https://leetcode.com/problems/balanced-binary-tree/) + +### 題目描述 + +判断一个二叉树是否平衡。树平衡的定义是,对于树上的任意节点,其两侧节点的最大深度的差值不得大于 1。 + +### 輸入輸出範例 + +输入是一个二叉树,输出一个布尔值,表示树是否平衡。 + +``` +Input: + 1 + / \ + 2 2 + / \ + 3 3 + / \ +4 4 +Output: false +``` + +### 題解 + +解法类似于求树的最大深度,但有两个不同的地方:一是我们需要先处理子树的深度再进行比较,二是如果我们在处理子树时发现其已经不平衡了,则可以返回一个-1,使得所有其长辈节点可以避免多余的判断(本题的判断比较简单,做差后取绝对值即可;但如果此处是一个开销较大的比较过程,则避免重复判断可以节省大量的计算时间)。 + + + + +```cpp +// 輔助函式。 +int balancedDepth(TreeNode* root) { + if (root == nullptr) { + return 0; + } + int left = balancedDepth(root->left); + int right = balancedDepth(root->right); + if (left == -1 || right == -1 || abs(left - right) > 1) { + return -1; + } + return max(left, right) + 1; +} +// 主函式。 +bool isBalanced(TreeNode* root) { return balancedDepth(root) != -1; } +``` + + + + +```py +# 輔助函式。 +def balancedDepth(root: Optional[TreeNode]) -> int: + if root is None: + return 0 + left = balancedDepth(root.left) + right = balancedDepth(root.right) + if left == -1 or right == -1 or abs(left - right) > 1: + return -1 + return max(left, right) + 1 + +# 主函式。 +def isBalanced(root: Optional[TreeNode]) -> bool: + return balancedDepth(root) != -1 + +``` + + + + + +## [543. Diameter of Binary Tree](https://leetcode.com/problems/diameter-of-binary-tree/) + +### 題目描述 + +求一个二叉树的最长直径。直径的定义是二叉树上任意两节点之间的无向距离。 + +### 輸入輸出範例 + +输入是一个二叉树,输出一个整数,表示最长直径。 + +``` +Input: + 1 + / \ + 2 3 + / \ + 4 5 +Output: 3 +``` + +在这个样例中,最长直径是 [4,2,1,3] 和 [5,2,1,3]。 + +### 題解 + +同样的,我们可以利用递归来处理树。解题时要注意,在我们处理某个子树时,我们更新的最长直径值和递归返回的值是不同的。这是因为待更新的最长直径值是经过该子树根节点的最长直径(即两侧长度);而函数返回值是以该子树根节点为端点的最长直径值(即一侧长度),使用这样的返回值才可以通过递归更新父节点的最长直径值)。 + + + + +```cpp +// 輔助函式。 +int updateDiameter(TreeNode* node, int& diameter) { + if (node == nullptr) { + return 0; + } + int left = updateDiameter(node->left, diameter); + int right = updateDiameter(node->right, diameter); + diameter = max(diameter, left + right); + return max(left, right) + 1; +} +// 主函式。 +int diameterOfBinaryTree(TreeNode* root) { + int diameter = 0; + updateDiameter(root, diameter); + return diameter; +} +``` + + + + +```py +# 輔助函式。 +def updateDiameter(node: Optional[TreeNode], diameter: List[int]) -> int: + if node is None: + return 0 + left = updateDiameter(node.left, diameter) + right = updateDiameter(node.right, diameter) + diameter[0] = max(diameter[0], left + right) + return max(left, right) + 1 + +# 主函式。 +def diameterOfBinaryTree(root: Optional[TreeNode]) -> int: + diameter = [0] + updateDiameter(root, diameter) + return diameter[0] + +``` + + + + + +## [437. Path Sum III](https://leetcode.com/problems/path-sum-iii/) + +### 題目描述 + +给定一个整数二叉树,求有多少条路径节点值的和等于给定值。 + +### 輸入輸出範例 + +输入一个二叉树和一个给定整数,输出一个整数,表示有多少条满足条件的路径。 + +``` +Input: sum = 8, tree = + 10 + / \ + 5 -3 + / \ \ + 3 2 11 + / \ \ + 3 -2 1 +Output: 3 +``` + +在这个样例中,和为 8 的路径一共有三个:[[5,3],[5,2,1],[-3,11]]。 + +### 題解 + +递归每个节点时,需要分情况考虑:(1)如果选取该节点加入路径,则之后必须继续加入连续节点,或停止加入节点(2)如果不选取该节点加入路径,则对其左右节点进行重新进行考虑。因此一个方便的方法是我们创建一个辅函数,专门用来计算连续加入节点的路径。 + + + + +```cpp +// 輔助函式。 +// long long防止test case中大数溢出,一般情况下用int即可。 +long long pathSumStartWithRoot(TreeNode* root, long long targetSum) { + if (root == nullptr) { + return 0; + } + return (root->val == targetSum) + + pathSumStartWithRoot(root->left, targetSum - root->val) + + pathSumStartWithRoot(root->right, targetSum - root->val); +} +// 主函式。 +int pathSum(TreeNode* root, int targetSum) { + if (root == nullptr) { + return 0; + } + return pathSumStartWithRoot(root, targetSum) + + pathSum(root->left, targetSum) + pathSum(root->right, targetSum); +} +``` + + + + +```py +# 輔助函式。 +def pathSumStartWithRoot(root: Optional[TreeNode], targetSum: int) -> int: + if root is None: + return 0 + return ( + int(root.val == targetSum) + + pathSumStartWithRoot(root.left, targetSum - root.val) + + pathSumStartWithRoot(root.right, targetSum - root.val) + ) + +# 主函式。 +def pathSum(root: Optional[TreeNode], targetSum: int) -> int: + if root is None: + return 0 + return ( + pathSumStartWithRoot(root, targetSum) + + pathSum(root.left, targetSum) + + pathSum(root.right, targetSum) + ) + +``` + + + + + +## [101. Symmetric Tree](https://leetcode.com/problems/symmetric-tree/) + +### 題目描述 + +判断一个二叉树是否对称。 + +### 輸入輸出範例 + +输入一个二叉树,输出一个布尔值,表示该树是否对称。 + +``` +Input: + 1 + / \ + 2 2 + / \ / \ +3 4 4 3 +Output: true +``` + +### 題解 + +判断一个树是否对称等价于判断左右子树是否对称。笔者一般习惯将判断两个子树是否相等或对称类型的题的解法叫做“四步法”:(1)如果两个子树都为空指针,则它们相等或对称(2)如果两个子树只有一个为空指针,则它们不相等或不对称(3)如果两个子树根节点的值不相等,则它们不相等或不对称(4)根据相等或对称要求,进行递归处理。 + + + + + +```cpp +// 輔助函式。 +bool isLeftRightSymmetric(TreeNode* left, TreeNode* right) { + if (left == nullptr && right == nullptr) { + return true; + } + if (left == nullptr or right == nullptr) { + return false; + } + if (left->val != right->val) { + return false; + } + return isLeftRightSymmetric(left->left, right->right) && + isLeftRightSymmetric(left->right, right->left); +} +// 主函式。 +bool isSymmetric(TreeNode* root) { + if (root == nullptr) { + return true; + } + return isLeftRightSymmetric(root->left, root->right); +} +``` + + + + +```py +# 輔助函式。 +def isLeftRightSymmetric( + left: Optional[TreeNode], right: Optional[TreeNode] +) -> bool: + if left is None and right is None: + return True + if left is None or right is None: + return False + if left.val != right.val: + return False + return ( + isLeftRightSymmetric(left.left, right.right) and + isLeftRightSymmetric(left.right, right.left) + ) + +# 主函式。 +def isSymmetric(root: Optional[TreeNode]) -> bool: + if root is None: + return True + return isLeftRightSymmetric(root.left, root.right) + +``` + + + + + +## [1110. Delete Nodes And Return Forest](https://leetcode.com/problems/delete-nodes-and-return-forest/) + +### 題目描述 + +给定一个整数二叉树和一些整数,求删掉这些整数对应的节点后,剩余的子树。 + +### 輸入輸出範例 + +输入是一个整数二叉树和一个一维整数数组,输出一个数组,每个位置存储一个子树(的根节点)。 + +``` +Input: to_delete = [3,5], tree = + 1 + / \ + 2 3 + / \ / \ + 4 5 6 7 +Output: [ + 1 + / + 2 + / +4 ,6 ,7] +``` + +### 題解 + +这道题最主要需要注意的细节是如果通过递归处理原树,以及需要在什么时候断开指针。同时,为了便于寻找待删除节点,可以建立一个哈希表方便查找。笔者强烈建议读者在看完题解后,自己写一遍本题,加深对于递归的理解和运用能力。 + + + + +```cpp +// 輔助函式。 +TreeNode* moveNodesToForest(TreeNode* root, unordered_set& undeleted, + vector& forest) { + if (root == nullptr) { + return nullptr; + } + root->left = moveNodesToForest(root->left, undeleted, forest); + root->right = moveNodesToForest(root->right, undeleted, forest); + if (undeleted.contains(root->val)) { + if (root->left != nullptr) { + forest.push_back(root->left); + } + if (root->right != nullptr) { + forest.push_back(root->right); + } + root = nullptr; + } + return root; +} +// 主函式。 +vector delNodes(TreeNode* root, vector& to_delete) { + vector forest; + unordered_set undeleted(to_delete.begin(), to_delete.end()); + root = moveNodesToForest(root, undeleted, forest); + if (root != nullptr) { + forest.push_back(root); + } + return forest; +} +``` + + + + +```py +# 輔助函式。 +def moveNodesToForest( + root: Optional[TreeNode], undeleted: Set[int], forest: List[TreeNode] +) -> Optional[TreeNode]: + if root is None: + return None + + root.left = moveNodesToForest(root.left, undeleted, forest) + root.right = moveNodesToForest(root.right, undeleted, forest) + + if root.val in undeleted: + if root.left is not None: + forest.append(root.left) + if root.right is not None: + forest.append(root.right) + root = None + + return root + +# 主函式。 +def delNodes(root: Optional[TreeNode], to_delete: List[int]) -> List[TreeNode]: + forest = [] + undeleted = set(to_delete) + root = moveNodesToForest(root, undeleted, forest) + if root is not None: + forest.append(root) + return forest + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-3-level-order-traversal.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-3-level-order-traversal.mdx new file mode 100644 index 00000000..9c2e6426 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-3-level-order-traversal.mdx @@ -0,0 +1,92 @@ +--- +sidebar_position: 70 +--- + +# 13.3 层次遍历 + +我们可以使用广度优先搜索进行层次遍历。注意,不需要使用两个队列来分别存储当前层的节点和下一层的节点,因为在开始遍历一层的节点时,当前队列中的节点数就是当前层的节点数,只要控制遍历这么多节点数,就能保证这次遍历的都是当前层的节点。 + +## [637. Average of Levels in Binary Tree](https://leetcode.com/problems/average-of-levels-in-binary-tree/) + +### 題目描述 + +给定一个二叉树,求每一层的节点值的平均数。 + +### 輸入輸出範例 + +输入是一个二叉树,输出是一个一维数组,表示每层节点值的平均数。 + +``` +Input: + 3 + / \ + 9 20 + / \ + 15 7 +Output: [3, 14.5, 11] +``` + +### 題解 + +利用广度优先搜索,我们可以很方便地求取每层的平均值。 + + + + +```cpp +vector averageOfLevels(TreeNode* root) { + vector level_avg; + if (root == nullptr) { + return level_avg; + } + queue q; + q.push(root); + int count = q.size(); + while (count > 0) { + double level_sum = 0; + for (int i = 0; i < count; ++i) { + TreeNode* node = q.front(); + q.pop(); + level_sum += node->val; + if (node->left != nullptr) { + q.push(node->left); + } + if (node->right != nullptr) { + q.push(node->right); + } + } + level_avg.push_back(level_sum / count); + count = q.size(); + } + return level_avg; +} +``` + + + + +```py +def averageOfLevels(root: Optional[TreeNode]) -> List[float]: + level_avg = [] + if root is None: + return level_avg + q = collections.deque() + q.append(root) + count = len(q) + while count > 0: + level_sum = 0 + for _ in range(count): + node = q.popleft() + level_sum += node.val + if node.left is not None: + q.append(node.left) + if node.right is not None: + q.append(node.right) + level_avg.append(level_sum / count) + count = len(q) + return level_avg +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-4-preorder-inorder-postorder-traversal.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-4-preorder-inorder-postorder-traversal.mdx new file mode 100644 index 00000000..1fe695bc --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-4-preorder-inorder-postorder-traversal.mdx @@ -0,0 +1,250 @@ +--- +sidebar_position: 71 +--- + +# 13.4 前中后序遍历 + +前序遍历、中序遍历和后序遍历是三种利用深度优先搜索遍历二叉树的方式。它们是在对节点访问的顺序有一点不同,其它完全相同。考虑如下一棵树, + +``` + 1 + / \ + 2 3 + / \ \ +4 5 6 +``` + +前序遍历先遍历父结点,再遍历左结点,最后遍历右节点,我们得到的遍历顺序是 [1 2 4 5 3 6]。 + + + + +```cpp +void preorder(TreeNode* root) { + visit(root); + preorder(root->left); + preorder(root->right); +} +``` + + + + +```py +def preorder(root: TreeNode): + visit(root) + preorder(root.left) + preorder(root.right) +``` + + + + + +中序遍历先遍历左节点,再遍历父结点,最后遍历右节点,我们得到的遍历顺序是 [4 2 5 1 3 6]。 + + + + +```cpp +void inorder(TreeNode* root) { + inorder(root->left); + visit(root); + inorder(root->right); +} +``` + + + + +```py +def inorder(root: TreeNode): + inorder(root.left) + visit(root) + inorder(root.right) +``` + + + + + +后序遍历先遍历左节点,再遍历右结点,最后遍历父节点,我们得到的遍历顺序是 [4 5 2 6 3 1]。 + + + + +```cpp +void postorder(TreeNode* root) { + postorder(root->left); + postorder(root->right); + visit(root); +} +``` + + + + +```py +def postorder(root: TreeNode): + postorder(root.left) + postorder(root.right) + visit(root) +``` + + + + + +## [105. Construct Binary Tree from Preorder and Inorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/) + +### 題目描述 + +给定一个二叉树的前序遍历和中序遍历结果,尝试复原这个树。已知树里不存在重复值的节点。 + +### 輸入輸出範例 + +输入是两个一维数组,分别表示树的前序遍历和中序遍历结果;输出是一个二叉树。 + +``` +Input: preorder = [4,9,20,15,7], inorder = [9,4,15,20,7] +Output: + 4 + / \ + 9 20 + / \ + 15 7 +``` + +### 題解 + +我们通过本题的样例讲解一下本题的思路。前序遍历的第一个节点是 4,意味着 4 是根节点。我们在中序遍历结果里找到 4 这个节点,根据中序遍历的性质可以得出,4 在中序遍历数组位置的左子数组为左子树,节点数为 1,对应的是前序排列数组里 4 之后的 1 个数字(9);4 在中序遍历数组位置的右子数组为右子树,节点数为 3,对应的是前序排列数组里最后的 3 个数字。有了这些信息,我们就可以对左子树和右子树进行递归复原了。为了方便查找数字的位置,我们可以用哈希表预处理中序遍历的结果。 + + + + +```cpp +// 輔助函式。 +TreeNode* reconstruct(unordered_map& io_map, vector& po, int l, + int r, int mid_po) { + if (l > r) { + return nullptr; + } + int mid_val = po[mid_po]; + int mid_io = io_map[mid_val]; + int left_len = mid_io - l + 1; + TreeNode* node = new TreeNode(mid_val); + node->left = reconstruct(io_map, po, l, mid_io - 1, mid_po + 1); + node->right = reconstruct(io_map, po, mid_io + 1, r, mid_po + left_len); + return node; +} +// 主函式。 +TreeNode* buildTree(vector& preorder, vector& inorder) { + unordered_map io_map; + for (int i = 0; i < inorder.size(); ++i) { + io_map[inorder[i]] = i; + } + return reconstruct(io_map, preorder, 0, preorder.size() - 1, 0); +} +``` + + + + +```py +# 輔助函式。 +def reconstruct( + io_map: Dict[int, int], po: List[int], l: int, r: int, mid_po: int +) -> Optional[TreeNode]: + if l > r: + return None + mid_val = po[mid_po] + mid_io = io_map[mid_val] + left_len = mid_io - l + 1 + node = TreeNode(mid_val) + node.left = reconstruct(io_map, po, l, mid_io - 1, mid_po + 1) + node.right = reconstruct(io_map, po, mid_io + 1, r, mid_po + left_len) + return node + +# 主函式。 +def buildTree(preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: + io_map = {val: i for i, val in enumerate(inorder)} + return reconstruct(io_map, preorder, 0, len(preorder) - 1, 0) + +``` + + + + + +## [144. Binary Tree Preorder Traversal](https://leetcode.com/problems/binary-tree-preorder-traversal/) + +### 題目描述 + +不使用递归,实现二叉树的前序遍历。 + +### 輸入輸出範例 + +输入一个二叉树,输出一个数组,为二叉树前序遍历的结果, + +``` +Input: + 1 + \ + 2 + / + 3 +Output: [1,2,3] +``` + +### 題解 + +因为递归的本质是栈调用,因此我们可以通过栈来实现前序遍历。注意入栈的顺序。 + + + + +```cpp +vector preorderTraversal(TreeNode* root) { + vector po; + if (root == nullptr) { + return po; + } + stack s; + s.push(root); + while (!s.empty()) { + TreeNode* node = s.top(); + s.pop(); + po.push_back(node->val); + if (node->right) { + s.push(node->right); // 先右后左,保证左子树先遍历 + } + if (node->left) { + s.push(node->left); + } + } + return po; +} +``` + + + + +```py +def preorderTraversal(root: Optional[TreeNode]) -> List[int]: + po = [] + if root is None: + return po + s = [root] + while len(s) > 0: + node = s.pop() + po.append(node.val) + if node.right is not None: + s.append(node.right) # 先右后左,保证左子树先遍历 + if node.left is not None: + s.append(node.left) + return po +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-5-binary-search-tree.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-5-binary-search-tree.mdx new file mode 100644 index 00000000..24ffd664 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-5-binary-search-tree.mdx @@ -0,0 +1,185 @@ +--- +sidebar_position: 72 +--- + +# 13.5 二叉查找树 + +`二叉查找树`(Binary Search Tree, BST)是一种特殊的二叉树:对于每个父节点,其左子树中所有节点的值小于等于父结点的值,其右子树中所有节点的值大于等于父结点的值。因此对于一个二叉查找树,我们可以在 O(log n) 的时间内查找一个值是否存在:从根节点开始,若当前节点的值大于查找值则向左下走,若当前节点的值小于查找值则向右下走。同时因为二叉查找树是有序的,对其中序遍历的结果即为排好序的数组。 + +例如下面这棵树即为二叉查找树,其中序遍历结果为 [1 2 3 4 5 6]。 + +``` + 4 + / \ + 2 5 + / \ \ +1 3 6 +``` + +## [99. Recover Binary Search Tree](https://leetcode.com/problems/recover-binary-search-tree/) + +### 題目描述 + +给定一个二叉查找树,已知有两个节点被不小心交换了,试复原此树。 + +### 輸入輸出範例 + +输入是一个被误交换两个节点的二叉查找树,输出是改正后的二叉查找树。 + +``` +Input: + 3 + / \ +1 4 + / + 2 +Output: + 2 + / \ +1 4 + / + 3 +``` + +在这个样例中,2 和 3 被不小心交换了。 + +### 題解 + +我们可以使用中序遍历这个二叉查找树,同时设置一个 prev 指针,记录当前节点中序遍历时的前节点。如果当前节点大于 prev 节点的值,说明需要调整次序。有一个技巧是如果遍历整个序列过程中只出现了一次次序错误,说明就是这两个相邻节点需要被交换;如果出现了两次次序错误,那就需要交换这两个节点。 + + + + +```cpp +// 輔助函式。 +void inorder(TreeNode* root, TreeNode*& mistake1, TreeNode*& mistake2, + TreeNode*& prev) { + if (root == nullptr) { + return; + } + inorder(root->left, mistake1, mistake2, prev); + if (prev != nullptr && root->val < prev->val) { + if (mistake1 == nullptr) { + mistake1 = prev; + } + mistake2 = root; + } + prev = root; + inorder(root->right, mistake1, mistake2, prev); +} +// 主函式。 +void recoverTree(TreeNode* root) { + TreeNode *mistake1 = nullptr, *mistake2 = nullptr, *prev = nullptr; + inorder(root, mistake1, mistake2, prev); + if (mistake1 != nullptr && mistake2 != nullptr) { + swap(mistake1->val, mistake2->val); + } +} +``` + + + + +```py +# 輔助函式。 +# 注意,Python中并不方便在辅函数中直接传指针,因此我们建造长度为1的list进行传引用。 +def inorder( + root: Optional[TreeNode], + mistake1=List[Optional[TreeNode]], + mistake2=List[Optional[TreeNode]], + prev=List[Optional[TreeNode]], +): + if root is None: + return + inorder(root.left, mistake1, mistake2, prev) + if prev[0] is not None and root.val < prev[0].val: + if mistake1[0] is None: + mistake1[0] = prev[0] + mistake2[0] = root + prev[0] = root + inorder(root.right, mistake1, mistake2, prev) + +# 主函式。 +def recoverTree(root: Optional[TreeNode]) -> None: + mistake1, mistake2, prev = [None], [None], [None] + inorder(root, mistake1, mistake2, prev) + if mistake1[0] is not None and mistake2[0] is not None: + mistake1[0].val, mistake2[0].val = mistake2[0].val, mistake1[0].val +``` + + + + + +## [669. Trim a Binary Search Tree](https://leetcode.com/problems/trim-a-binary-search-tree/) + +### 題目描述 + +给定一个二叉查找树和两个整数 L 和 R,且 L < R,试修剪此二叉查找树,使得修剪后所有节点的值都在 [L, R] 的范围内。 + +### 輸入輸出範例 + +输入是一个二叉查找树和两个整数 L 和 R,输出一个被修剪好的二叉查找树。 + +``` +Input: L = 1, R = 3, tree = + 3 + / \ + 0 4 + \ + 2 + / + 1 +Output: + 3 + / + 2 + / +1 +``` + +### 題解 + +利用二叉查找树的大小关系,我们可以很容易地利用递归进行树的处理。 + + + + +```cpp +TreeNode* trimBST(TreeNode* root, int low, int high) { + if (root == nullptr) { + return root; + } + if (root->val > high) { + return trimBST(root->left, low, high); + } + if (root->val < low) { + return trimBST(root->right, low, high); + } + root->left = trimBST(root->left, low, high); + root->right = trimBST(root->right, low, high); + return root; +} +``` + + + + +```py +def trimBST( + root: Optional[TreeNode], low: int, high: int +) -> Optional[TreeNode]: + if root is None: + return None + if root.val > high: + return trimBST(root.left, low, high) + if root.val < low: + return trimBST(root.right, low, high) + root.left = trimBST(root.left, low, high) + root.right = trimBST(root.right, low, high) + return root +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-6-trie.mdx b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-6-trie.mdx new file mode 100644 index 00000000..80546986 --- /dev/null +++ b/leetcode_101/i18n/zh-TW/docusaurus-plugin-content-docs/current/13-trees/13-6-trie.mdx @@ -0,0 +1,137 @@ +--- +sidebar_position: 73 +--- + +# 13.6 字典树 + +字典树(Trie)用于判断字符串是否存在或者是否具有某种字符串前缀。 + +

      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 L^>bP0l+XkKx059e literal 0 HcmV?d00001 diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/_category_.json new file mode 100644 index 00000000..4a0b8ebd --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/10-data-structures/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "10. 妙用数据结构 ", + "position": 10, + "link": { + "type": "generated-index", + "description": "第 10 章 妙用数据结构" + } +} diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-1-introduction.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-1-introduction.md new file mode 100644 index 00000000..9cd88891 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-1-introduction.md @@ -0,0 +1,7 @@ +--- +sidebar_position: 59 +--- + +# 11.1 引言 + +字符串可以看成是字符组成的数组。由于字符串是程序里经常需要处理的数据类型,因此有很多针对字符串处理的题目,以下是一些常见的类型。 \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-2-string-comparison.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-2-string-comparison.mdx new file mode 100644 index 00000000..bec7f3c5 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-2-string-comparison.mdx @@ -0,0 +1,339 @@ +--- +sidebar_position: 60 +--- + +# 11.2 字符串比较 + +## [242. Valid Anagram](https://leetcode.com/problems/valid-anagram/) + +### Problem Description + +判断两个字符串包含的字符是否完全相同。 + +### Input and Output Example + +输入两个字符串,输出一个布尔值,表示两个字符串是否满足条件。 + +``` +Input: s = "anagram", t = "nagaram" +Output: true +``` + +### Solution Explanation + +我们可以利用哈希表或者数组统计两个数组中每个数字出现的频次,若频次相同,则说明它们包含的字符完全相同。 + + + + +```cpp +bool isAnagram(string s, string t) { + if (s.length() != t.length()) { + return false; + } + vector counts(26, 0); + for (int i = 0; i < s.length(); ++i) { + ++counts[s[i] - ’a’]; + --counts[t[i] - ’a’]; + } + return all_of(counts.begin(), counts.end(), [](int c) { return c == 0; }); +} +``` + + + + +```py +def isAnagram(s: str, t: str) -> bool: + if len(s) != len(t): + return False + counter = Counter(s) + counter.subtract(t) + return all(v == 0 for v in counter.values()) +``` + + + + + +## [205. Isomorphic Strings](https://leetcode.com/problems/isomorphic-strings/) + +### Problem Description + +判断两个字符串是否同构。同构的定义是,可以通过把一个字符串的某些相同的字符转换成另一些相同的字符,使得两个字符串相同,且两种不同的字符不能够被转换成同一种字符。 + +### Input and Output Example + +输入两个字符串,输出一个布尔值,表示两个字符串是否满足条件。 + +``` +Input: s = "paper", t = "title" +Output: true +``` + +在这个样例中,通过把 s 中的 p、a、e、r 字符转换成 t、i、l、e 字符,可以使得两个字符串相同。 + +### Solution Explanation + +我们可以将问题转化一下:记录两个字符串每个位置的字符第一次出现的位置,如果两个字符串中相同位置的字符与它们第一次出现的位置一样,那么这两个字符串同构。举例来说,对于“paper”和“title”,假设我们现在遍历到第三个字符“p”和“t”,发现它们第一次出现的位置都在第一个字符,则说明目前位置满足同构。同样的,我们可以用哈希表存储,也可以用一个长度为 128 的数组(ASCII 定义下字符的总数量)。 + + + + +```cpp +bool isIsomorphic(string s, string t) { + vector s_init(128, 0), t_init(128, 0); + for (int i = 0; i < s.length(); ++i) { + if (s_init[s[i]] != t_init[t[i]]) { + return false; + } + s_init[s[i]] = t_init[t[i]] = i + 1; + } + return true; +} +``` + + + + +```py +def isIsomorphic(s: str, t: str) -> bool: + s_init, t_init = [0] * 128, [0] * 128 + + for i in range(len(s)): + if s_init[ord(s[i])] != t_init[ord(t[i])]: + return False + s_init[ord(s[i])] = t_init[ord(t[i])] = i + 1 + + return True + +``` + + + + + +## [647. Palindromic Substrings](https://leetcode.com/problems/palindromic-substrings/) + +### Problem Description + +给定一个字符,求其有多少个回文子字符串。回文的定义是左右对称。 + +### Input and Output Example + +输入是一个字符串,输出一个整数,表示回文子字符串的数量。 + +``` +Input: "aaa" +Output: 6 +``` + +六个回文子字符串分别是 ["a","a","a","aa","aa","aaa"]。 + +### Solution Explanation + +我们可以从字符串的每个位置开始,向左向右延长,判断存在多少以当前位置为中轴的回文子字符串。 + + + + +```cpp +// Auxiliary function +int extendSubstrings(string s, int l, int r) { + int count = 0, n = s.length(); + while (l >= 0 && r < n && s[l] == s[r]) { + --l; + ++r; + ++count; + } + return count; +} +// Main function +int countSubstrings(string s) { + int count = 0; + for (int i = 0; i < s.length(); ++i) { + count += extendSubstrings(s, i, i); // 奇数长度 + count += extendSubstrings(s, i, i + 1); // 偶数长度 + } + return count; +} +``` + + + + +```py +# Auxiliary function +def extendSubstrings(s: str, l: int, r: int) -> int: + count, n = 0, len(s) + while l >= 0 and r < n and s[l] == s[r]: + count += 1 + l -= 1 + r += 1 + return count + +# Main function +def countSubstrings(s: str) -> int: + return sum( + # 奇数长度 + 偶数长度。 + extendSubstrings(s, i, i) + extendSubstrings(s, i, i + 1) + for i in range(len(s)) + ) + +``` + + + + + +## [696. Count Binary Substrings](https://leetcode.com/problems/count-binary-substrings/) + +### Problem Description + +给定一个 0-1 字符串,求有多少非空子字符串的 0 和 1 数量相同,且 0 和 1 必须连续出现(比如 0011、1100;0101 不算)。 + +### Input and Output Example + +输入是一个字符串,输出一个整数,表示满足条件的子字符串的数量。 + +``` +Input: "00110011" +Output: 6 +``` + +在这个样例中,六个 0 和 1 数量相同的子字符串是 ["0011","01","1100","10","0011","01"]。 + +### Solution Explanation + +从左往右遍历数组,记录和当前位置数字相同且连续的长度,以及其之前连续的不同数字的长度。举例来说,对于 00110 的最后一位,我们记录的相同数字长度是 1,因为只有一个连续 0;我们记录的不同数字长度是 2,因为在 0 之前有两个连续的 1。若不同数字的连续长度大于等于当前数字的连续长度,则说明存在一个且只存在一个以当前数字结尾的满足条件的子字符串。 + + + + +```cpp +int countBinarySubstrings(string s) { + int prev = 0, cur = 1, count = 0; + for (int i = 1; i < s.length(); ++i) { + if (s[i] == s[i - 1]) { + ++cur; + } else { + prev = cur; + cur = 1; + } + if (prev >= cur) { + ++count; + } + } + return count; +} +``` + + + + +```py +def countBinarySubstrings(s: str) -> int: + prev, cur, count = 0, 1, 0 + + for i in range(1, len(s)): + if s[i] == s[i - 1]: + cur += 1 + else: + prev = cur + cur = 1 + if prev >= cur: + count += 1 + + return count + +``` + + + + + +## [1249. Minimum Remove to Make Valid Parentheses](https://leetcode.com/problems/minimum-remove-to-make-valid-parentheses/) + +### Problem Description + +给定一个包括字母和左右括号的字符串,求最少要移除多少个括号才能使其合法。 + +### Input and Output Example + +输入是一个字符串,输出是合法且长度最长的移除结果。 + +``` +Input: s = "lee(t(c)o)de)" +Output: "lee(t(c)o)de" +``` + +返回 lee(t(co)de) 或 lee(t(c)ode) 也算正确。 + +### Solution Explanation + +因为只有一种括号,所以我们并不一定利用栈来统计,可以直接用一个临时变量统计在当前位置时,左括号比右括号多出现多少次。如果在遍历过程中出现负数,则需要移除多余的右括号。如果遍历结束时临时变量为正数,则需要从右到左移除多余的左括号。这里我们使用了一个小技巧,先标记待删除位置,最后一起移除。 + + + + +```cpp +string minRemoveToMakeValid(string s) { + int count = 0, n = s.length(); + char to_delete = '#'; + for (char& c : s) { + if (c == '(') { + ++count; + } else if (c == ')') { + if (count > 0) { + --count; + } else { + c = to_delete; + } + } + } + for (int i = n - 1; i >= 0; --i) { + if (count == 0) break; + if (s[i] == '(') { + s[i] = to_delete; + --count; + } + } + s.erase(remove_if(s.begin(), s.end(), + [to_delete](char c) { return c == to_delete; }), + s.end()); + return s; +} + +``` + + + + +```py +def minRemoveToMakeValid(s: str) -> str: + count, n = 0, len(s) + to_delete = set() + + for i in range(n): + if s[i] == "(": + count += 1 + elif s[i] == ")": + if count > 0: + count -= 1 + else: + to_delete.add(i) + + for i in range(n - 1, -1, -1): + if count == 0: + break + if s[i] == "(": + to_delete.add(i) + count -= 1 + + return "".join(s[i] for i in range(n) if i not in to_delete) + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-3-string-interpretation.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-3-string-interpretation.mdx new file mode 100644 index 00000000..14b7b505 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-3-string-interpretation.mdx @@ -0,0 +1,129 @@ +--- +sidebar_position: 61 +--- + +# 11.3 字符串理解 + +## [227. Basic Calculator II](https://leetcode.com/problems/basic-calculator-ii/) + +### Problem Description + +给定一个包含加减乘除整数运算的字符串,求其运算的整数值结果。如果除不尽则向 0 取整。 + +### Input and Output Example + +输入是一个合法的运算字符串,输出是一个整数,表示其运算结果。 + +``` +Input: " 3+5 / 2 " +Output: 5 +``` + +在这个样例中,因为除法的优先度高于加法,所以结果是 5 而非 4。 + +### Solution Explanation + +如果我们在字符串左边加上一个加号,可以证明其并不改变运算结果,且字符串可以分割成多个 < 一个运算符,一个数字 > 对子的形式;这样一来我们就可以从左往右处理了。由于乘除的优先级高于加减,因此我们需要使用一个中间变量来存储高优先度的运算结果。 + +此类型题也考察很多细节处理,如无运算符的情况,和多个空格的情况等等。 + + + + +```cpp +// 辅函数 - parse从位置i开始的一个数字。 +int parseNum(const string& s, int& i) { + int num = 0, n = s.length(); + while (i < n && isdigit(s[i])) { + num = 10 * num + (s[i++] - '0'); + } + return num; +} + +// Main function +int calculate(string s) { + char op = '+'; + long global_num = 0, local_num = 0; + int i = -1, n = s.length(); + while (++i < n) { + if (s[i] == ' ') { + continue; + } + long num = parseNum(s, i); + switch (op) { + case '+': + global_num += local_num; + local_num = num; + break; + case '-': + global_num += local_num; + local_num = -num; + break; + case '*': + local_num *= num; + break; + case '/': + local_num /= num; + break; + } + if (i < n) { + op = s[i]; + } + } + return global_num + local_num; +} + +``` + + + + +```py +from typing import Tuple + +# 辅函数 - parse从位置i开始的一个数字。 +# 返回(数字, 下一个i位置) +def parseNum(s: str, i: int) -> Tuple[int, int]: + num, n = 0, len(s) + while i < n and s[i].isdigit(): + num = 10 * num + int(s[i]) + i += 1 + return (num, i) + +# Main function +def calculate(s: str) -> int: + op = "+" + global_num, local_num = 0, 0 + i, n = 0, len(s) + + while i < n: + if s[i] == " ": + i += 1 + continue + + num, i = parseNum(s, i) + + match op: + case "+": + global_num += local_num + local_num = num + case "-": + global_num += local_num + local_num = -num + case "*": + local_num *= num + case "/": + # int()会实现向0取整,而//对负数会远离0取整。 + local_num = int(local_num / num) + + if i < n: + op = s[i] + i += 1 + + return global_num + local_num + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-4-string-matching.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-4-string-matching.mdx new file mode 100644 index 00000000..270efe60 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-4-string-matching.mdx @@ -0,0 +1,106 @@ +--- +sidebar_position: 62 +--- + +# 11.4 字符串匹配 + +## [28. Implement strStr()](https://leetcode.com/problems/find-the-index-of-the-first-occurrence-in-a-string/) + +### Problem Description + +判断一个字符串是不是另一个字符串的子字符串,并返回其位置。 + +### Input and Output Example + +输入一个母字符串和一个子字符串,输出一个整数,表示子字符串在母字符串的位置,若不存在则返回-1。 + +``` +Input: haystack = "hello", needle = "ll" +Output: 2 +``` + +### Solution Explanation + +使用著名的Knuth-Morris-Pratt(KMP)算法,可以在 $O(m +n)$ 时间利用动态规划完成匹配。这里我们定义 dp 数组为,dp[i] 表示 needle 中以 i 位置截止的片段(即后缀),最长可以匹配到needle 从头开始的哪个位置(即前缀)。例如,ababaca 的 dp 数组是 [-1,-1,0,1,2,-1,0],表示每个位置最长可以匹配 [无, 无, a, ab, aba, 无, a]。 + +这道题比较复杂,初学者可以暂时跳过。 + + + + +```cpp +// Auxiliary function +vector computeDp(const string &needle) { + int n = needle.length(); + vector dp(n, -1); + for (int j = 1, k = -1; j < n; ++j) { + while (k > -1 && needle[k + 1] != needle[j]) { + k = dp[k]; // 如果下一位不同,回溯到前一个前缀片段 + } + if (needle[k + 1] == needle[j]) { + ++k; // 前缀和后缀片段相同,匹配长度加1 + } + dp[j] = k; // 更新前缀匹配位置 + } + return dp; +} +// Main function +int strStr(const string &haystack, const string &needle) { + int m = haystack.length(), n = needle.length(); + vector dp = computeDp(needle); + for (int i = 0, k = -1; i < m; ++i) { + while (k > -1 && needle[k + 1] != haystack[i]) { + k = dp[k]; // 如果下一位不同,回溯到前一个相同片段 + } + if (needle[k + 1] == haystack[i]) { + ++k; // 片段相同,匹配长度加1 + } + if (k == n - 1) { + return i - n + 1; // 匹配结束 + } + } + return -1; +} +``` + + + + +```py +from typing import List + +# Auxiliary function +def computeDp(needle: str) -> List[int]: + n = len(needle) + dp = [-1] * n + k = -1 + for j in range(1, n): + while k > -1 and needle[k + 1] != needle[j]: + k = dp[k] # 如果下一位不同,回溯到前一个前缀片段 + if needle[k + 1] == needle[j]: + k += 1 # 前缀和后缀片段相同,匹配长度加1 + dp[j] = k # 更新前缀匹配位置 + return dp + +# Main function +def strStr(haystack: str, needle: str) -> int: + m, n = len(haystack), len(needle) + if n == 0: + return 0 # Edge case for an empty needle + + dp = computeDp(needle) + k = -1 + for i in range(m): + while k > -1 and needle[k + 1] != haystack[i]: + k = dp[k] # 如果下一位不同,回溯到前一个相同片段 + if needle[k + 1] == haystack[i]: + k += 1 # 片段相同,匹配长度加1 + if k == n - 1: + return i - n + 1 # 匹配结束 + return -1 + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-5-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-5-exercises.md new file mode 100644 index 00000000..9744bd9f --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/11-5-exercises.md @@ -0,0 +1,26 @@ +--- +sidebar_position: 63 +--- + +# 11.5 Exercises + +## Basic Difficulty + +### [409. Longest Palindrome](https://leetcode.com/problems/longest-palindrome/) + +计算一组字符可以构成的回文字符串的最大长度,可以利用其它数据结构进行辅助统计。 + +### [3. Longest Substring Without Repeating Characters](https://leetcode.com/problems/longest-substring-without-repeating-characters/) + +计算最长无重复子字符串,同样的,可以利用其它数据结构进行辅助统计。 + + +## Advanced Difficulty + +### [772. Basic Calculator III](https://leetcode.com/problems/basic-calculator-iii/) + +题目 227 的 follow-up,十分推荐练习。 + +### [5. Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/) + +类似于我们讲过的子序列问题,子数组或子字符串问题常常也可以用动态规划来解决。先使用动态规划写出一个 $O(n^2)$ 时间复杂度的算法,再搜索一下 Manacher’s Algorithm,它可以在 $O(n)$ 时间解决这一问题。 \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/_category_.json new file mode 100644 index 00000000..688feb04 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/11-string-manipulation/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "11. 令人头大的字符串 ", + "position": 11, + "link": { + "type": "generated-index", + "description": "第 11 章 令人头大的字符串" + } +} diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-1-data-structure-introduction.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-1-data-structure-introduction.md new file mode 100644 index 00000000..b298b78e --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-1-data-structure-introduction.md @@ -0,0 +1,40 @@ +--- +sidebar_position: 64 +--- + +# 12.1 数据结构介绍 + +(单向)`链表`是由节点和指针构成的数据结构,每个节点存有一个值,和一个指向下一个节点的指针,因此很多链表问题可以用递归来处理。不同于数组,链表并不能直接获取任意节点的值,必须要通过指针找到该节点后才能获取其值。同理,在未遍历到链表结尾时,我们也无法知道链表的长度,除非依赖其他数据结构储存长度。LeetCode 默认的链表表示方法如下。 + + + + +```cpp +struct ListNode { + int val; + ListNode *next; + ListNode(int x) : val(x), next(nullptr) {} +}; +``` + + + + +```py +class ListNode: + def __init__(self, x): + self.val = x + self.next = None # or a ListNode +``` + + + + + +由于在进行链表操作时,尤其是删除节点时,经常会因为对当前节点进行操作而导致内存或指针出现问题。有两个小技巧可以解决这个问题:一是尽量处理当前节点的下一个节点而非当前节点本身,二是建立一个虚拟节点 (dummy node),使其指向当前链表的头节点,这样即使原链表所有节点全被删除,也会有一个 dummy 存在,返回 dummy->next 即可。 + +:::warning + + 一般来说,算法题不需要删除内存。在刷 LeetCode 的时候,如果想要删除一个节点,可以直接进行指针操作而无需回收内存。实际做软件工程时,对于无用的内存,笔者建议尽量显式回收,或利用智能指针。 + +::: \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-2-basic-linked-list-operations.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-2-basic-linked-list-operations.mdx new file mode 100644 index 00000000..42dd9ad3 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-2-basic-linked-list-operations.mdx @@ -0,0 +1,270 @@ +--- +sidebar_position: 65 +--- + +# 12.2 链表的基本操作 + +## [206. Reverse Linked List](https://leetcode.com/problems/reverse-linked-list/) + +### Problem Description + +翻转一个链表。 + +### Input and Output Example + +输入一个链表,输出该链表翻转后的结果。 + +``` +Input: 1->2->3->4->5->nullptr +Output: 5->4->3->2->1->nullptr +``` + +### Solution Explanation + +链表翻转是非常基础也一定要掌握的技能。我们提供了两种写法——递归和非递归。建议你同时掌握这两种写法。 + +递归的写法为: + + + + +```cpp +ListNode* reverseList(ListNode* head, ListNode* head_prev = nullptr) { + if (head == nullptr) { + return head_prev; + } + ListNode* head_next = head->next; + head->next = head_prev; + return reverseList(head_next, head); +} +``` + + + + +```py +def reverseList( + head: Optional[ListNode], head_prev: Optional[ListNode] = None +) -> Optional[ListNode]: + if head is None: + return head_prev + head_next = head.next + head.next = head_prev + return reverseList(head_next, head) +``` + + + + + +非递归的写法为: + + + + +```cpp +ListNode* reverseList(ListNode* head) { + ListNode *head_prev = nullptr, *head_next; + while (head) { + head_next = head->next; + head->next = head_prev; + head_prev = head; + head = head_next; + } + return head_prev; +} +``` + + + + +```py +def reverseList(head: Optional[ListNode]) -> Optional[ListNode]: + head_prev = None + while head is not None: + head_next = head.next + head.next = head_prev + head_prev = head + head = head_next + return head_prev +``` + + + + + +## [21. Merge Two Sorted Lists](https://leetcode.com/problems/merge-two-sorted-lists/) + +### Problem Description + +给定两个增序的链表,试将其合并成一个增序的链表。 + +### Input and Output Example + +输入两个链表,输出一个链表,表示两个链表合并的结果。 + +``` +Input: 1->2->4, 1->3->4 +Output: 1->1->2->3->4->4 +``` + +### Solution Explanation + +我们提供了递归和非递归,共两种写法。递归的写法为: + + + + +```cpp +ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { + if (l2 == nullptr) { + return l1; + } + if (l1 == nullptr) { + return l2; + } + if (l1->val < l2->val) { + l1->next = mergeTwoLists(l1->next, l2); + return l1; + } + l2->next = mergeTwoLists(l1, l2->next); + return l2; +} +``` + + + + +```py +def mergeTwoLists( + l1: Optional[ListNode], l2: Optional[ListNode] +) -> Optional[ListNode]: + if l1 is None or l2 is None: + return l1 or l2 + if l1.val < l2.val: + l1.next = mergeTwoLists(l1.next, l2) + return l1 + l2.next = mergeTwoLists(l1, l2.next) + return l2 +``` + + + + + +非递归的写法为: + + + + +```cpp +ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) { + ListNode *dummy = new ListNode(0), *node = dummy; + while (l1 && l2) { + if (l1->val < l2->val) { + node->next = l1; + l1 = l1->next; + } else { + node->next = l2; + l2 = l2->next; + } + node = node->next; + } + node->next = l1 == nullptr ? l2 : l1; + return dummy->next; +} +``` + + + + +```py +def mergeTwoLists( + l1: Optional[ListNode], l2: Optional[ListNode] +) -> Optional[ListNode]: + dummy = ListNode() + head = dummy + + while l1 and l2: + if l1.val < l2.val: + dummy.next = l1 + l1 = l1.next + else: + dummy.next = l2 + l2 = l2.next + dummy = dummy.next + + dummy.next = l1 or l2 + return head.next + +``` + + + + + +## [24. Swap Nodes in Pairs](https://leetcode.com/problems/swap-nodes-in-pairs/) + +### Problem Description + +给定一个矩阵,交换每个相邻的一对节点。 + +### Input and Output Example + +输入一个链表,输出该链表交换后的结果。 + +``` +Input: 1->2->3->4 +Output: 2->1->4->3 +``` + +### Solution Explanation + +利用指针进行交换操作,没有太大难度,但一定要细心。 + + + + +```cpp +ListNode* swapPairs(ListNode* head) { + ListNode *node1 = head, *node2; + if (node1 && node1->next) { + node2 = node1->next; + node1->next = node2->next; + node2->next = node1; + head = node2; + while (node1->next && node1->next->next) { + node2 = node1->next->next; + node1->next->next = node2->next; + node2->next = node1->next; + node1->next = node2; + node1 = node2->next; + } + } + return head; +} +``` + + + + +```py +def swapPairs(head: Optional[ListNode]) -> Optional[ListNode]: + node1 = head + if node1 is not None and node1.next is not None: + node2 = node1.next + node1.next = node2.next + node2.next = node1 + head = node2 + while node1.next is not None and node1.next.next is not None: + node2 = node1.next.next + node1.next.next = node2.next + node2.next = node1.next + node1.next = node2 + node1 = node2.next + return head +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-3-other-linked-list-techniques.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-3-other-linked-list-techniques.mdx new file mode 100644 index 00000000..c0e4717d --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-3-other-linked-list-techniques.mdx @@ -0,0 +1,140 @@ +--- +sidebar_position: 66 +--- + +# 12.3 其它链表技巧 + +## [160. Intersection of Two Linked Lists](https://leetcode.com/problems/intersection-of-two-linked-lists/) + +### Problem Description + +给定两个链表,判断它们是否相交于一点,并求这个相交节点。 + +### Input and Output Example + +输入是两条链表,输出是一个节点。如无相交节点,则返回一个空节点。 + +``` +Input: +A: a1 -> a2 + | + v + c1 -> c2 -> c3 + ^ + | +B: b1 -> b2 -> b3 +Output: c1 +``` + +### Solution Explanation + +假设链表 A 的头节点到相交点的距离是 a,链表 B 的头节点到相交点的距离是 b,相交点到链表终点的距离为 c。我们使用两个指针,分别指向两个链表的头节点,并以相同的速度前进,若到达链表结尾,则移动到另一条链表的头节点继续前进。按照这种前进方法,两个指针会在 a + b + c 次前进后同时到达相交节点。 + + + + +```cpp +ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { + ListNode *l1 = headA, *l2 = headB; + while (l1 != l2) { + l1 = l1 != nullptr ? l1->next : headB; + l2 = l2 != nullptr ? l2->next : headA; + } + return l1; +} +``` + + + + +```py +def getIntersectionNode( + headA: ListNode, headB: ListNode +) -> Optional[ListNode]: + l1 = headA + l2 = headB + while l1 != l2: + l1 = l1.next if l1 is not None else headB + l2 = l2.next if l2 is not None else headA + return l1 +``` + + + + + +## [234. Palindrome Linked List](https://leetcode.com/problems/palindrome-linked-list/) + +### Problem Description + +以 $O(1)$ 的空间复杂度,判断链表是否回文。 + +### Input and Output Example + +输入是一个链表,输出是一个布尔值,表示链表是否回文。 + +``` +Input: 1->2->3->2->1 +Output: true +``` + +### Solution Explanation + +先使用快慢指针找到链表中点,再把链表切成两半;然后把后半段翻转;最后比较两半是否相等。 + + + + +```cpp +bool isPalindrome(ListNode* head) { + if (head == nullptr || head->next == nullptr) { + return true; + } + ListNode *slow = head, *fast = head; + while (fast->next && fast->next->next) { + slow = slow->next; + fast = fast->next->next; + } + slow->next = reverseList(slow->next); // 见题目206 + slow = slow->next; + while (slow != nullptr) { + if (head->val != slow->val) { + return false; + } + head = head->next; + slow = slow->next; + } + return true; +} +``` + + + + +```py +def isPalindrome(head: Optional[ListNode]) -> bool: + if head is None or head.next is None: + return True + + slow, fast = head, head + + while fast.next is not None and fast.next.next is not None: + slow = slow.next + fast = fast.next.next + + slow.next = reverseList(slow.next) # 见题目206 + slow = slow.next + + while slow is not None: + if head.val != slow.val: + return False + head = head.next + slow = slow.next + + return True + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-4-exercises.md b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-4-exercises.md new file mode 100644 index 00000000..47601598 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/12-4-exercises.md @@ -0,0 +1,25 @@ +--- +sidebar_position: 67 +--- + +# 12.4 Exercises + +## Basic Difficulty + +### [83. Remove Duplicates from Sorted List](https://leetcode.com/problems/remove-duplicates-from-sorted-list/) + +虽然 LeetCode 没有强制要求,但是我们仍然建议你回收内存,尤其当题目要求你删除的时候。 + +### [328. Odd Even Linked List](https://leetcode.com/problems/odd-even-linked-list/) + +这道题其实很简单,千万不要把题目复杂化。 + +### [19. Remove Nth Node From End of List](https://leetcode.com/problems/remove-nth-node-from-end-of-list/) + +既然我们可以使用快慢指针找到中点,也可以利用类似的方法找到倒数第 n 个节点,无需遍历第二遍。 + +## Advanced Difficulty + +### [148. Sort List](https://leetcode.com/problems/sort-list/) + +利用快慢指针找到链表中点后,可以对链表进行归并排序。 \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/_category_.json b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/_category_.json new file mode 100644 index 00000000..184a7911 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/12-linked-lists/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "12. 指针三剑客之一:链表", + "position": 12, + "link": { + "type": "generated-index", + "description": "第 12 章 指针三剑客之一:链表" + } +} diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-1-data-structure-introduction.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-1-data-structure-introduction.mdx new file mode 100644 index 00000000..3d50814f --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-1-data-structure-introduction.mdx @@ -0,0 +1,37 @@ +--- +sidebar_position: 68 +--- + +# 13.1 数据结构介绍 + +作为(单)链表的升级版,我们通常接触的树都是`二叉树`(binary tree),即每个节点最多有两个子节点;且除非题目说明,默认树中不存在循环结构。LeetCode 默认的树表示方法如下。 + + + + + +```cpp +struct TreeNode { + int val; + TreeNode *left; + TreeNode *right; + TreeNode(int x) : val(x), left(NULL), right(NULL) {} +}; +``` + + + + +```py +class TreeNode: + def __init__(self, val=0, left=None, right=None): + self.val = val + self.left = left + self.right = right +``` + + + + + +可以看出,其与链表的主要差别就是多了一个子节点的指针。 \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-2-tree-recursion.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-2-tree-recursion.mdx new file mode 100644 index 00000000..8351caa5 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-2-tree-recursion.mdx @@ -0,0 +1,469 @@ +--- +sidebar_position: 69 +--- + +# 13.2 树的递归 + +对于一些简单的递归题,某些 LeetCode 达人喜欢写 one-line code,即用一行代码解决问题。我们也会展示一些这样的代码,但是对于新手,笔者仍然建议您使用多行的 if-else 判断语句。 + +在很多时候,树递归的写法与深度优先搜索的递归写法相同,因此本书不会区分二者。 + +## [104. Maximum Depth of Binary Tree](https://leetcode.com/problems/maximum-depth-of-binary-tree/) + +### Problem Description + +求一个二叉树的最大深度。 + +### Input and Output Example + +输入是一个二叉树,输出是一个整数,表示该树的最大深度。 + +``` +Input: + 3 + / \ + 9 20 + / \ + 15 7 +Output: 3 +``` + +### Solution Explanation + +利用递归,我们可以很方便地求得最大深度。 + + + + +```cpp +int maxDepth(TreeNode* root) { + if (root == nullptr) { + return 0; + } + return max(maxDepth(root->left), maxDepth(root->right)) + 1; +} +``` + + + + +```py +def maxDepth(root: Optional[TreeNode]) -> int: + if root is None: + return 0 + return max(maxDepth(root.left), maxDepth(root.right)) + 1 +``` + + + + + +## [110. Balanced Binary Tree](https://leetcode.com/problems/balanced-binary-tree/) + +### Problem Description + +判断一个二叉树是否平衡。树平衡的定义是,对于树上的任意节点,其两侧节点的最大深度的差值不得大于 1。 + +### Input and Output Example + +输入是一个二叉树,输出一个布尔值,表示树是否平衡。 + +``` +Input: + 1 + / \ + 2 2 + / \ + 3 3 + / \ +4 4 +Output: false +``` + +### Solution Explanation + +解法类似于求树的最大深度,但有两个不同的地方:一是我们需要先处理子树的深度再进行比较,二是如果我们在处理子树时发现其已经不平衡了,则可以返回一个-1,使得所有其长辈节点可以避免多余的判断(本题的判断比较简单,做差后取绝对值即可;但如果此处是一个开销较大的比较过程,则避免重复判断可以节省大量的计算时间)。 + + + + +```cpp +// Auxiliary function +int balancedDepth(TreeNode* root) { + if (root == nullptr) { + return 0; + } + int left = balancedDepth(root->left); + int right = balancedDepth(root->right); + if (left == -1 || right == -1 || abs(left - right) > 1) { + return -1; + } + return max(left, right) + 1; +} +// Main function +bool isBalanced(TreeNode* root) { return balancedDepth(root) != -1; } +``` + + + + +```py +# Auxiliary function +def balancedDepth(root: Optional[TreeNode]) -> int: + if root is None: + return 0 + left = balancedDepth(root.left) + right = balancedDepth(root.right) + if left == -1 or right == -1 or abs(left - right) > 1: + return -1 + return max(left, right) + 1 + +# Main function +def isBalanced(root: Optional[TreeNode]) -> bool: + return balancedDepth(root) != -1 + +``` + + + + + +## [543. Diameter of Binary Tree](https://leetcode.com/problems/diameter-of-binary-tree/) + +### Problem Description + +求一个二叉树的最长直径。直径的定义是二叉树上任意两节点之间的无向距离。 + +### Input and Output Example + +输入是一个二叉树,输出一个整数,表示最长直径。 + +``` +Input: + 1 + / \ + 2 3 + / \ + 4 5 +Output: 3 +``` + +在这个样例中,最长直径是 [4,2,1,3] 和 [5,2,1,3]。 + +### Solution Explanation + +同样的,我们可以利用递归来处理树。解题时要注意,在我们处理某个子树时,我们更新的最长直径值和递归返回的值是不同的。这是因为待更新的最长直径值是经过该子树根节点的最长直径(即两侧长度);而函数返回值是以该子树根节点为端点的最长直径值(即一侧长度),使用这样的返回值才可以通过递归更新父节点的最长直径值)。 + + + + +```cpp +// Auxiliary function +int updateDiameter(TreeNode* node, int& diameter) { + if (node == nullptr) { + return 0; + } + int left = updateDiameter(node->left, diameter); + int right = updateDiameter(node->right, diameter); + diameter = max(diameter, left + right); + return max(left, right) + 1; +} +// Main function +int diameterOfBinaryTree(TreeNode* root) { + int diameter = 0; + updateDiameter(root, diameter); + return diameter; +} +``` + + + + +```py +# Auxiliary function +def updateDiameter(node: Optional[TreeNode], diameter: List[int]) -> int: + if node is None: + return 0 + left = updateDiameter(node.left, diameter) + right = updateDiameter(node.right, diameter) + diameter[0] = max(diameter[0], left + right) + return max(left, right) + 1 + +# Main function +def diameterOfBinaryTree(root: Optional[TreeNode]) -> int: + diameter = [0] + updateDiameter(root, diameter) + return diameter[0] + +``` + + + + + +## [437. Path Sum III](https://leetcode.com/problems/path-sum-iii/) + +### Problem Description + +给定一个整数二叉树,求有多少条路径节点值的和等于给定值。 + +### Input and Output Example + +输入一个二叉树和一个给定整数,输出一个整数,表示有多少条满足条件的路径。 + +``` +Input: sum = 8, tree = + 10 + / \ + 5 -3 + / \ \ + 3 2 11 + / \ \ + 3 -2 1 +Output: 3 +``` + +在这个样例中,和为 8 的路径一共有三个:[[5,3],[5,2,1],[-3,11]]。 + +### Solution Explanation + +递归每个节点时,需要分情况考虑:(1)如果选取该节点加入路径,则之后必须继续加入连续节点,或停止加入节点(2)如果不选取该节点加入路径,则对其左右节点进行重新进行考虑。因此一个方便的方法是我们创建一个辅函数,专门用来计算连续加入节点的路径。 + + + + +```cpp +// Auxiliary function +// long long防止test case中大数溢出,一般情况下用int即可。 +long long pathSumStartWithRoot(TreeNode* root, long long targetSum) { + if (root == nullptr) { + return 0; + } + return (root->val == targetSum) + + pathSumStartWithRoot(root->left, targetSum - root->val) + + pathSumStartWithRoot(root->right, targetSum - root->val); +} +// Main function +int pathSum(TreeNode* root, int targetSum) { + if (root == nullptr) { + return 0; + } + return pathSumStartWithRoot(root, targetSum) + + pathSum(root->left, targetSum) + pathSum(root->right, targetSum); +} +``` + + + + +```py +# Auxiliary function +def pathSumStartWithRoot(root: Optional[TreeNode], targetSum: int) -> int: + if root is None: + return 0 + return ( + int(root.val == targetSum) + + pathSumStartWithRoot(root.left, targetSum - root.val) + + pathSumStartWithRoot(root.right, targetSum - root.val) + ) + +# Main function +def pathSum(root: Optional[TreeNode], targetSum: int) -> int: + if root is None: + return 0 + return ( + pathSumStartWithRoot(root, targetSum) + + pathSum(root.left, targetSum) + + pathSum(root.right, targetSum) + ) + +``` + + + + + +## [101. Symmetric Tree](https://leetcode.com/problems/symmetric-tree/) + +### Problem Description + +判断一个二叉树是否对称。 + +### Input and Output Example + +输入一个二叉树,输出一个布尔值,表示该树是否对称。 + +``` +Input: + 1 + / \ + 2 2 + / \ / \ +3 4 4 3 +Output: true +``` + +### Solution Explanation + +判断一个树是否对称等价于判断左右子树是否对称。笔者一般习惯将判断两个子树是否相等或对称类型的题的解法叫做“四步法”:(1)如果两个子树都为空指针,则它们相等或对称(2)如果两个子树只有一个为空指针,则它们不相等或不对称(3)如果两个子树根节点的值不相等,则它们不相等或不对称(4)根据相等或对称要求,进行递归处理。 + + + + + +```cpp +// Auxiliary function +bool isLeftRightSymmetric(TreeNode* left, TreeNode* right) { + if (left == nullptr && right == nullptr) { + return true; + } + if (left == nullptr or right == nullptr) { + return false; + } + if (left->val != right->val) { + return false; + } + return isLeftRightSymmetric(left->left, right->right) && + isLeftRightSymmetric(left->right, right->left); +} +// Main function +bool isSymmetric(TreeNode* root) { + if (root == nullptr) { + return true; + } + return isLeftRightSymmetric(root->left, root->right); +} +``` + + + + +```py +# Auxiliary function +def isLeftRightSymmetric( + left: Optional[TreeNode], right: Optional[TreeNode] +) -> bool: + if left is None and right is None: + return True + if left is None or right is None: + return False + if left.val != right.val: + return False + return ( + isLeftRightSymmetric(left.left, right.right) and + isLeftRightSymmetric(left.right, right.left) + ) + +# Main function +def isSymmetric(root: Optional[TreeNode]) -> bool: + if root is None: + return True + return isLeftRightSymmetric(root.left, root.right) + +``` + + + + + +## [1110. Delete Nodes And Return Forest](https://leetcode.com/problems/delete-nodes-and-return-forest/) + +### Problem Description + +给定一个整数二叉树和一些整数,求删掉这些整数对应的节点后,剩余的子树。 + +### Input and Output Example + +输入是一个整数二叉树和一个一维整数数组,输出一个数组,每个位置存储一个子树(的根节点)。 + +``` +Input: to_delete = [3,5], tree = + 1 + / \ + 2 3 + / \ / \ + 4 5 6 7 +Output: [ + 1 + / + 2 + / +4 ,6 ,7] +``` + +### Solution Explanation + +这道题最主要需要注意的细节是如果通过递归处理原树,以及需要在什么时候断开指针。同时,为了便于寻找待删除节点,可以建立一个哈希表方便查找。笔者强烈建议读者在看完题解后,自己写一遍本题,加深对于递归的理解和运用能力。 + + + + +```cpp +// Auxiliary function +TreeNode* moveNodesToForest(TreeNode* root, unordered_set& undeleted, + vector& forest) { + if (root == nullptr) { + return nullptr; + } + root->left = moveNodesToForest(root->left, undeleted, forest); + root->right = moveNodesToForest(root->right, undeleted, forest); + if (undeleted.contains(root->val)) { + if (root->left != nullptr) { + forest.push_back(root->left); + } + if (root->right != nullptr) { + forest.push_back(root->right); + } + root = nullptr; + } + return root; +} +// Main function +vector delNodes(TreeNode* root, vector& to_delete) { + vector forest; + unordered_set undeleted(to_delete.begin(), to_delete.end()); + root = moveNodesToForest(root, undeleted, forest); + if (root != nullptr) { + forest.push_back(root); + } + return forest; +} +``` + + + + +```py +# Auxiliary function +def moveNodesToForest( + root: Optional[TreeNode], undeleted: Set[int], forest: List[TreeNode] +) -> Optional[TreeNode]: + if root is None: + return None + + root.left = moveNodesToForest(root.left, undeleted, forest) + root.right = moveNodesToForest(root.right, undeleted, forest) + + if root.val in undeleted: + if root.left is not None: + forest.append(root.left) + if root.right is not None: + forest.append(root.right) + root = None + + return root + +# Main function +def delNodes(root: Optional[TreeNode], to_delete: List[int]) -> List[TreeNode]: + forest = [] + undeleted = set(to_delete) + root = moveNodesToForest(root, undeleted, forest) + if root is not None: + forest.append(root) + return forest + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-3-level-order-traversal.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-3-level-order-traversal.mdx new file mode 100644 index 00000000..a434b418 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-3-level-order-traversal.mdx @@ -0,0 +1,92 @@ +--- +sidebar_position: 70 +--- + +# 13.3 层次遍历 + +我们可以使用广度优先搜索进行层次遍历。注意,不需要使用两个队列来分别存储当前层的节点和下一层的节点,因为在开始遍历一层的节点时,当前队列中的节点数就是当前层的节点数,只要控制遍历这么多节点数,就能保证这次遍历的都是当前层的节点。 + +## [637. Average of Levels in Binary Tree](https://leetcode.com/problems/average-of-levels-in-binary-tree/) + +### Problem Description + +给定一个二叉树,求每一层的节点值的平均数。 + +### Input and Output Example + +输入是一个二叉树,输出是一个一维数组,表示每层节点值的平均数。 + +``` +Input: + 3 + / \ + 9 20 + / \ + 15 7 +Output: [3, 14.5, 11] +``` + +### Solution Explanation + +利用广度优先搜索,我们可以很方便地求取每层的平均值。 + + + + +```cpp +vector averageOfLevels(TreeNode* root) { + vector level_avg; + if (root == nullptr) { + return level_avg; + } + queue q; + q.push(root); + int count = q.size(); + while (count > 0) { + double level_sum = 0; + for (int i = 0; i < count; ++i) { + TreeNode* node = q.front(); + q.pop(); + level_sum += node->val; + if (node->left != nullptr) { + q.push(node->left); + } + if (node->right != nullptr) { + q.push(node->right); + } + } + level_avg.push_back(level_sum / count); + count = q.size(); + } + return level_avg; +} +``` + + + + +```py +def averageOfLevels(root: Optional[TreeNode]) -> List[float]: + level_avg = [] + if root is None: + return level_avg + q = collections.deque() + q.append(root) + count = len(q) + while count > 0: + level_sum = 0 + for _ in range(count): + node = q.popleft() + level_sum += node.val + if node.left is not None: + q.append(node.left) + if node.right is not None: + q.append(node.right) + level_avg.append(level_sum / count) + count = len(q) + return level_avg +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-4-preorder-inorder-postorder-traversal.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-4-preorder-inorder-postorder-traversal.mdx new file mode 100644 index 00000000..e0761a67 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-4-preorder-inorder-postorder-traversal.mdx @@ -0,0 +1,250 @@ +--- +sidebar_position: 71 +--- + +# 13.4 前中后序遍历 + +前序遍历、中序遍历和后序遍历是三种利用深度优先搜索遍历二叉树的方式。它们是在对节点访问的顺序有一点不同,其它完全相同。考虑如下一棵树, + +``` + 1 + / \ + 2 3 + / \ \ +4 5 6 +``` + +前序遍历先遍历父结点,再遍历左结点,最后遍历右节点,我们得到的遍历顺序是 [1 2 4 5 3 6]。 + + + + +```cpp +void preorder(TreeNode* root) { + visit(root); + preorder(root->left); + preorder(root->right); +} +``` + + + + +```py +def preorder(root: TreeNode): + visit(root) + preorder(root.left) + preorder(root.right) +``` + + + + + +中序遍历先遍历左节点,再遍历父结点,最后遍历右节点,我们得到的遍历顺序是 [4 2 5 1 3 6]。 + + + + +```cpp +void inorder(TreeNode* root) { + inorder(root->left); + visit(root); + inorder(root->right); +} +``` + + + + +```py +def inorder(root: TreeNode): + inorder(root.left) + visit(root) + inorder(root.right) +``` + + + + + +后序遍历先遍历左节点,再遍历右结点,最后遍历父节点,我们得到的遍历顺序是 [4 5 2 6 3 1]。 + + + + +```cpp +void postorder(TreeNode* root) { + postorder(root->left); + postorder(root->right); + visit(root); +} +``` + + + + +```py +def postorder(root: TreeNode): + postorder(root.left) + postorder(root.right) + visit(root) +``` + + + + + +## [105. Construct Binary Tree from Preorder and Inorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/) + +### Problem Description + +给定一个二叉树的前序遍历和中序遍历结果,尝试复原这个树。已知树里不存在重复值的节点。 + +### Input and Output Example + +输入是两个一维数组,分别表示树的前序遍历和中序遍历结果;输出是一个二叉树。 + +``` +Input: preorder = [4,9,20,15,7], inorder = [9,4,15,20,7] +Output: + 4 + / \ + 9 20 + / \ + 15 7 +``` + +### Solution Explanation + +我们通过本题的样例讲解一下本题的思路。前序遍历的第一个节点是 4,意味着 4 是根节点。我们在中序遍历结果里找到 4 这个节点,根据中序遍历的性质可以得出,4 在中序遍历数组位置的左子数组为左子树,节点数为 1,对应的是前序排列数组里 4 之后的 1 个数字(9);4 在中序遍历数组位置的右子数组为右子树,节点数为 3,对应的是前序排列数组里最后的 3 个数字。有了这些信息,我们就可以对左子树和右子树进行递归复原了。为了方便查找数字的位置,我们可以用哈希表预处理中序遍历的结果。 + + + + +```cpp +// Auxiliary function +TreeNode* reconstruct(unordered_map& io_map, vector& po, int l, + int r, int mid_po) { + if (l > r) { + return nullptr; + } + int mid_val = po[mid_po]; + int mid_io = io_map[mid_val]; + int left_len = mid_io - l + 1; + TreeNode* node = new TreeNode(mid_val); + node->left = reconstruct(io_map, po, l, mid_io - 1, mid_po + 1); + node->right = reconstruct(io_map, po, mid_io + 1, r, mid_po + left_len); + return node; +} +// Main function +TreeNode* buildTree(vector& preorder, vector& inorder) { + unordered_map io_map; + for (int i = 0; i < inorder.size(); ++i) { + io_map[inorder[i]] = i; + } + return reconstruct(io_map, preorder, 0, preorder.size() - 1, 0); +} +``` + + + + +```py +# Auxiliary function +def reconstruct( + io_map: Dict[int, int], po: List[int], l: int, r: int, mid_po: int +) -> Optional[TreeNode]: + if l > r: + return None + mid_val = po[mid_po] + mid_io = io_map[mid_val] + left_len = mid_io - l + 1 + node = TreeNode(mid_val) + node.left = reconstruct(io_map, po, l, mid_io - 1, mid_po + 1) + node.right = reconstruct(io_map, po, mid_io + 1, r, mid_po + left_len) + return node + +# Main function +def buildTree(preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: + io_map = {val: i for i, val in enumerate(inorder)} + return reconstruct(io_map, preorder, 0, len(preorder) - 1, 0) + +``` + + + + + +## [144. Binary Tree Preorder Traversal](https://leetcode.com/problems/binary-tree-preorder-traversal/) + +### Problem Description + +不使用递归,实现二叉树的前序遍历。 + +### Input and Output Example + +输入一个二叉树,输出一个数组,为二叉树前序遍历的结果, + +``` +Input: + 1 + \ + 2 + / + 3 +Output: [1,2,3] +``` + +### Solution Explanation + +因为递归的本质是栈调用,因此我们可以通过栈来实现前序遍历。注意入栈的顺序。 + + + + +```cpp +vector preorderTraversal(TreeNode* root) { + vector po; + if (root == nullptr) { + return po; + } + stack s; + s.push(root); + while (!s.empty()) { + TreeNode* node = s.top(); + s.pop(); + po.push_back(node->val); + if (node->right) { + s.push(node->right); // 先右后左,保证左子树先遍历 + } + if (node->left) { + s.push(node->left); + } + } + return po; +} +``` + + + + +```py +def preorderTraversal(root: Optional[TreeNode]) -> List[int]: + po = [] + if root is None: + return po + s = [root] + while len(s) > 0: + node = s.pop() + po.append(node.val) + if node.right is not None: + s.append(node.right) # 先右后左,保证左子树先遍历 + if node.left is not None: + s.append(node.left) + return po +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-5-binary-search-tree.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-5-binary-search-tree.mdx new file mode 100644 index 00000000..81d81f1c --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-5-binary-search-tree.mdx @@ -0,0 +1,185 @@ +--- +sidebar_position: 72 +--- + +# 13.5 二叉查找树 + +`二叉查找树`(Binary Search Tree, BST)是一种特殊的二叉树:对于每个父节点,其左子树中所有节点的值小于等于父结点的值,其右子树中所有节点的值大于等于父结点的值。因此对于一个二叉查找树,我们可以在 O(log n) 的时间内查找一个值是否存在:从根节点开始,若当前节点的值大于查找值则向左下走,若当前节点的值小于查找值则向右下走。同时因为二叉查找树是有序的,对其中序遍历的结果即为排好序的数组。 + +例如下面这棵树即为二叉查找树,其中序遍历结果为 [1 2 3 4 5 6]。 + +``` + 4 + / \ + 2 5 + / \ \ +1 3 6 +``` + +## [99. Recover Binary Search Tree](https://leetcode.com/problems/recover-binary-search-tree/) + +### Problem Description + +给定一个二叉查找树,已知有两个节点被不小心交换了,试复原此树。 + +### Input and Output Example + +输入是一个被误交换两个节点的二叉查找树,输出是改正后的二叉查找树。 + +``` +Input: + 3 + / \ +1 4 + / + 2 +Output: + 2 + / \ +1 4 + / + 3 +``` + +在这个样例中,2 和 3 被不小心交换了。 + +### Solution Explanation + +我们可以使用中序遍历这个二叉查找树,同时设置一个 prev 指针,记录当前节点中序遍历时的前节点。如果当前节点大于 prev 节点的值,说明需要调整次序。有一个技巧是如果遍历整个序列过程中只出现了一次次序错误,说明就是这两个相邻节点需要被交换;如果出现了两次次序错误,那就需要交换这两个节点。 + + + + +```cpp +// Auxiliary function +void inorder(TreeNode* root, TreeNode*& mistake1, TreeNode*& mistake2, + TreeNode*& prev) { + if (root == nullptr) { + return; + } + inorder(root->left, mistake1, mistake2, prev); + if (prev != nullptr && root->val < prev->val) { + if (mistake1 == nullptr) { + mistake1 = prev; + } + mistake2 = root; + } + prev = root; + inorder(root->right, mistake1, mistake2, prev); +} +// Main function +void recoverTree(TreeNode* root) { + TreeNode *mistake1 = nullptr, *mistake2 = nullptr, *prev = nullptr; + inorder(root, mistake1, mistake2, prev); + if (mistake1 != nullptr && mistake2 != nullptr) { + swap(mistake1->val, mistake2->val); + } +} +``` + + + + +```py +# Auxiliary function +# 注意,Python中并不方便在辅函数中直接传指针,因此我们建造长度为1的list进行传引用。 +def inorder( + root: Optional[TreeNode], + mistake1=List[Optional[TreeNode]], + mistake2=List[Optional[TreeNode]], + prev=List[Optional[TreeNode]], +): + if root is None: + return + inorder(root.left, mistake1, mistake2, prev) + if prev[0] is not None and root.val < prev[0].val: + if mistake1[0] is None: + mistake1[0] = prev[0] + mistake2[0] = root + prev[0] = root + inorder(root.right, mistake1, mistake2, prev) + +# Main function +def recoverTree(root: Optional[TreeNode]) -> None: + mistake1, mistake2, prev = [None], [None], [None] + inorder(root, mistake1, mistake2, prev) + if mistake1[0] is not None and mistake2[0] is not None: + mistake1[0].val, mistake2[0].val = mistake2[0].val, mistake1[0].val +``` + + + + + +## [669. Trim a Binary Search Tree](https://leetcode.com/problems/trim-a-binary-search-tree/) + +### Problem Description + +给定一个二叉查找树和两个整数 L 和 R,且 L < R,试修剪此二叉查找树,使得修剪后所有节点的值都在 [L, R] 的范围内。 + +### Input and Output Example + +输入是一个二叉查找树和两个整数 L 和 R,输出一个被修剪好的二叉查找树。 + +``` +Input: L = 1, R = 3, tree = + 3 + / \ + 0 4 + \ + 2 + / + 1 +Output: + 3 + / + 2 + / +1 +``` + +### Solution Explanation + +利用二叉查找树的大小关系,我们可以很容易地利用递归进行树的处理。 + + + + +```cpp +TreeNode* trimBST(TreeNode* root, int low, int high) { + if (root == nullptr) { + return root; + } + if (root->val > high) { + return trimBST(root->left, low, high); + } + if (root->val < low) { + return trimBST(root->right, low, high); + } + root->left = trimBST(root->left, low, high); + root->right = trimBST(root->right, low, high); + return root; +} +``` + + + + +```py +def trimBST( + root: Optional[TreeNode], low: int, high: int +) -> Optional[TreeNode]: + if root is None: + return None + if root.val > high: + return trimBST(root.left, low, high) + if root.val < low: + return trimBST(root.right, low, high) + root.left = trimBST(root.left, low, high) + root.right = trimBST(root.right, low, high) + return root +``` + + + + \ No newline at end of file diff --git a/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-6-trie.mdx b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-6-trie.mdx new file mode 100644 index 00000000..3e544261 --- /dev/null +++ b/leetcode_101/i18n/en/docusaurus-plugin-content-docs/current/13-trees/13-6-trie.mdx @@ -0,0 +1,137 @@ +--- +sidebar_position: 73 +--- + +# 13.6 字典树 + +字典树(Trie)用于判断字符串是否存在或者是否具有某种字符串前缀。 + +

    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 L^>bP0l+XkKx059e literal 0 HcmV?d00001 diff --git a/leetcode_101/docs/10-data-structures/_category_.json b/leetcode_101/docs/10-data-structures/_category_.json index 5a2165d0..4a0b8ebd 100644 --- a/leetcode_101/docs/10-data-structures/_category_.json +++ b/leetcode_101/docs/10-data-structures/_category_.json @@ -3,6 +3,6 @@ "position": 10, "link": { "type": "generated-index", - "description": "5 minutes to learn the most important Docusaurus concepts." + "description": "第 10 章 妙用数据结构" } } From fa80896fc99e2cf2aa59f80fad42d74eb88df346 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Thu, 14 Nov 2024 11:59:52 +0100 Subject: [PATCH 14/49] chapter 11 --- .../11-1-introduction.md | 2 + .../11-2-string-comparison.md | 5 - .../11-2-string-comparison.mdx | 339 ++++++++++++++++++ .../11-3-string-interpretation.md | 5 - .../11-3-string-interpretation.mdx | 129 +++++++ .../11-4-string-matching.md | 5 - .../11-4-string-matching.mdx | 106 ++++++ .../11-string-manipulation/11-5-exercises.md | 21 ++ .../11-string-manipulation/_category_.json | 2 +- 9 files changed, 598 insertions(+), 16 deletions(-) delete mode 100644 leetcode_101/docs/11-string-manipulation/11-2-string-comparison.md create mode 100644 leetcode_101/docs/11-string-manipulation/11-2-string-comparison.mdx delete mode 100644 leetcode_101/docs/11-string-manipulation/11-3-string-interpretation.md create mode 100644 leetcode_101/docs/11-string-manipulation/11-3-string-interpretation.mdx delete mode 100644 leetcode_101/docs/11-string-manipulation/11-4-string-matching.md create mode 100644 leetcode_101/docs/11-string-manipulation/11-4-string-matching.mdx diff --git a/leetcode_101/docs/11-string-manipulation/11-1-introduction.md b/leetcode_101/docs/11-string-manipulation/11-1-introduction.md index 3d296da7..9cd88891 100644 --- a/leetcode_101/docs/11-string-manipulation/11-1-introduction.md +++ b/leetcode_101/docs/11-string-manipulation/11-1-introduction.md @@ -3,3 +3,5 @@ sidebar_position: 59 --- # 11.1 引言 + +字符串可以看成是字符组成的数组。由于字符串是程序里经常需要处理的数据类型,因此有很多针对字符串处理的题目,以下是一些常见的类型。 \ No newline at end of file diff --git a/leetcode_101/docs/11-string-manipulation/11-2-string-comparison.md b/leetcode_101/docs/11-string-manipulation/11-2-string-comparison.md deleted file mode 100644 index f916db53..00000000 --- a/leetcode_101/docs/11-string-manipulation/11-2-string-comparison.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 60 ---- - -# 11.2 字符串比较 diff --git a/leetcode_101/docs/11-string-manipulation/11-2-string-comparison.mdx b/leetcode_101/docs/11-string-manipulation/11-2-string-comparison.mdx new file mode 100644 index 00000000..c9daac80 --- /dev/null +++ b/leetcode_101/docs/11-string-manipulation/11-2-string-comparison.mdx @@ -0,0 +1,339 @@ +--- +sidebar_position: 60 +--- + +# 11.2 字符串比较 + +## [242. Valid Anagram](https://leetcode.com/problems/valid-anagram/) + +### 题目描述 + +判断两个字符串包含的字符是否完全相同。 + +### 输入输出样例 + +输入两个字符串,输出一个布尔值,表示两个字符串是否满足条件。 + +``` +Input: s = "anagram", t = "nagaram" +Output: true +``` + +### 题解 + +我们可以利用哈希表或者数组统计两个数组中每个数字出现的频次,若频次相同,则说明它们包含的字符完全相同。 + + + + +```cpp +bool isAnagram(string s, string t) { + if (s.length() != t.length()) { + return false; + } + vector counts(26, 0); + for (int i = 0; i < s.length(); ++i) { + ++counts[s[i] - ’a’]; + --counts[t[i] - ’a’]; + } + return all_of(counts.begin(), counts.end(), [](int c) { return c == 0; }); +} +``` + + + + +```py +def isAnagram(s: str, t: str) -> bool: + if len(s) != len(t): + return False + counter = Counter(s) + counter.subtract(t) + return all(v == 0 for v in counter.values()) +``` + + + + + +## [205. Isomorphic Strings](https://leetcode.com/problems/isomorphic-strings/) + +### 题目描述 + +判断两个字符串是否同构。同构的定义是,可以通过把一个字符串的某些相同的字符转换成另一些相同的字符,使得两个字符串相同,且两种不同的字符不能够被转换成同一种字符。 + +### 输入输出样例 + +输入两个字符串,输出一个布尔值,表示两个字符串是否满足条件。 + +``` +Input: s = "paper", t = "title" +Output: true +``` + +在这个样例中,通过把 s 中的 p、a、e、r 字符转换成 t、i、l、e 字符,可以使得两个字符串相同。 + +### 题解 + +我们可以将问题转化一下:记录两个字符串每个位置的字符第一次出现的位置,如果两个字符串中相同位置的字符与它们第一次出现的位置一样,那么这两个字符串同构。举例来说,对于“paper”和“title”,假设我们现在遍历到第三个字符“p”和“t”,发现它们第一次出现的位置都在第一个字符,则说明目前位置满足同构。同样的,我们可以用哈希表存储,也可以用一个长度为 128 的数组(ASCII 定义下字符的总数量)。 + + + + +```cpp +bool isIsomorphic(string s, string t) { + vector s_init(128, 0), t_init(128, 0); + for (int i = 0; i < s.length(); ++i) { + if (s_init[s[i]] != t_init[t[i]]) { + return false; + } + s_init[s[i]] = t_init[t[i]] = i + 1; + } + return true; +} +``` + + + + +```py +def isIsomorphic(s: str, t: str) -> bool: + s_init, t_init = [0] * 128, [0] * 128 + + for i in range(len(s)): + if s_init[ord(s[i])] != t_init[ord(t[i])]: + return False + s_init[ord(s[i])] = t_init[ord(t[i])] = i + 1 + + return True + +``` + + + + + +## [647. Palindromic Substrings](https://leetcode.com/problems/palindromic-substrings/) + +### 题目描述 + +给定一个字符,求其有多少个回文子字符串。回文的定义是左右对称。 + +### 输入输出样例 + +输入是一个字符串,输出一个整数,表示回文子字符串的数量。 + +``` +Input: "aaa" +Output: 6 +``` + +六个回文子字符串分别是 ["a","a","a","aa","aa","aaa"]。 + +### 题解 + +我们可以从字符串的每个位置开始,向左向右延长,判断存在多少以当前位置为中轴的回文子字符串。 + + + + +```cpp +// 辅函数。 +int extendSubstrings(string s, int l, int r) { + int count = 0, n = s.length(); + while (l >= 0 && r < n && s[l] == s[r]) { + --l; + ++r; + ++count; + } + return count; +} +// 主函数。 +int countSubstrings(string s) { + int count = 0; + for (int i = 0; i < s.length(); ++i) { + count += extendSubstrings(s, i, i); // 奇数长度 + count += extendSubstrings(s, i, i + 1); // 偶数长度 + } + return count; +} +``` + + + + +```py +# 辅函数。 +def extendSubstrings(s: str, l: int, r: int) -> int: + count, n = 0, len(s) + while l >= 0 and r < n and s[l] == s[r]: + count += 1 + l -= 1 + r += 1 + return count + +# 主函数。 +def countSubstrings(s: str) -> int: + return sum( + # 奇数长度 + 偶数长度。 + extendSubstrings(s, i, i) + extendSubstrings(s, i, i + 1) + for i in range(len(s)) + ) + +``` + + + + + +## [696. Count Binary Substrings](https://leetcode.com/problems/count-binary-substrings/) + +### 题目描述 + +给定一个 0-1 字符串,求有多少非空子字符串的 0 和 1 数量相同,且 0 和 1 必须连续出现(比如 0011、1100;0101 不算)。 + +### 输入输出样例 + +输入是一个字符串,输出一个整数,表示满足条件的子字符串的数量。 + +``` +Input: "00110011" +Output: 6 +``` + +在这个样例中,六个 0 和 1 数量相同的子字符串是 ["0011","01","1100","10","0011","01"]。 + +### 题解 + +从左往右遍历数组,记录和当前位置数字相同且连续的长度,以及其之前连续的不同数字的长度。举例来说,对于 00110 的最后一位,我们记录的相同数字长度是 1,因为只有一个连续 0;我们记录的不同数字长度是 2,因为在 0 之前有两个连续的 1。若不同数字的连续长度大于等于当前数字的连续长度,则说明存在一个且只存在一个以当前数字结尾的满足条件的子字符串。 + + + + +```cpp +int countBinarySubstrings(string s) { + int prev = 0, cur = 1, count = 0; + for (int i = 1; i < s.length(); ++i) { + if (s[i] == s[i - 1]) { + ++cur; + } else { + prev = cur; + cur = 1; + } + if (prev >= cur) { + ++count; + } + } + return count; +} +``` + + + + +```py +def countBinarySubstrings(s: str) -> int: + prev, cur, count = 0, 1, 0 + + for i in range(1, len(s)): + if s[i] == s[i - 1]: + cur += 1 + else: + prev = cur + cur = 1 + if prev >= cur: + count += 1 + + return count + +``` + + + + + +## [1249. Minimum Remove to Make Valid Parentheses](https://leetcode.com/problems/minimum-remove-to-make-valid-parentheses/) + +### 题目描述 + +给定一个包括字母和左右括号的字符串,求最少要移除多少个括号才能使其合法。 + +### 输入输出样例 + +输入是一个字符串,输出是合法且长度最长的移除结果。 + +``` +Input: s = "lee(t(c)o)de)" +Output: "lee(t(c)o)de" +``` + +返回 lee(t(co)de) 或 lee(t(c)ode) 也算正确。 + +### 题解 + +因为只有一种括号,所以我们并不一定利用栈来统计,可以直接用一个临时变量统计在当前位置时,左括号比右括号多出现多少次。如果在遍历过程中出现负数,则需要移除多余的右括号。如果遍历结束时临时变量为正数,则需要从右到左移除多余的左括号。这里我们使用了一个小技巧,先标记待删除位置,最后一起移除。 + + + + +```cpp +string minRemoveToMakeValid(string s) { + int count = 0, n = s.length(); + char to_delete = '#'; + for (char& c : s) { + if (c == '(') { + ++count; + } else if (c == ')') { + if (count > 0) { + --count; + } else { + c = to_delete; + } + } + } + for (int i = n - 1; i >= 0; --i) { + if (count == 0) break; + if (s[i] == '(') { + s[i] = to_delete; + --count; + } + } + s.erase(remove_if(s.begin(), s.end(), + [to_delete](char c) { return c == to_delete; }), + s.end()); + return s; +} + +``` + + + + +```py +def minRemoveToMakeValid(s: str) -> str: + count, n = 0, len(s) + to_delete = set() + + for i in range(n): + if s[i] == "(": + count += 1 + elif s[i] == ")": + if count > 0: + count -= 1 + else: + to_delete.add(i) + + for i in range(n - 1, -1, -1): + if count == 0: + break + if s[i] == "(": + to_delete.add(i) + count -= 1 + + return "".join(s[i] for i in range(n) if i not in to_delete) + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/11-string-manipulation/11-3-string-interpretation.md b/leetcode_101/docs/11-string-manipulation/11-3-string-interpretation.md deleted file mode 100644 index 5db24b00..00000000 --- a/leetcode_101/docs/11-string-manipulation/11-3-string-interpretation.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 61 ---- - -# 11.3 字符串理解 diff --git a/leetcode_101/docs/11-string-manipulation/11-3-string-interpretation.mdx b/leetcode_101/docs/11-string-manipulation/11-3-string-interpretation.mdx new file mode 100644 index 00000000..30d8f2ab --- /dev/null +++ b/leetcode_101/docs/11-string-manipulation/11-3-string-interpretation.mdx @@ -0,0 +1,129 @@ +--- +sidebar_position: 61 +--- + +# 11.3 字符串理解 + +## [227. Basic Calculator II](https://leetcode.com/problems/basic-calculator-ii/) + +### 题目描述 + +给定一个包含加减乘除整数运算的字符串,求其运算的整数值结果。如果除不尽则向 0 取整。 + +### 输入输出样例 + +输入是一个合法的运算字符串,输出是一个整数,表示其运算结果。 + +``` +Input: " 3+5 / 2 " +Output: 5 +``` + +在这个样例中,因为除法的优先度高于加法,所以结果是 5 而非 4。 + +### 题解 + +如果我们在字符串左边加上一个加号,可以证明其并不改变运算结果,且字符串可以分割成多个 < 一个运算符,一个数字 > 对子的形式;这样一来我们就可以从左往右处理了。由于乘除的优先级高于加减,因此我们需要使用一个中间变量来存储高优先度的运算结果。 + +此类型题也考察很多细节处理,如无运算符的情况,和多个空格的情况等等。 + + + + +```cpp +// 辅函数 - parse从位置i开始的一个数字。 +int parseNum(const string& s, int& i) { + int num = 0, n = s.length(); + while (i < n && isdigit(s[i])) { + num = 10 * num + (s[i++] - '0'); + } + return num; +} + +// 主函数。 +int calculate(string s) { + char op = '+'; + long global_num = 0, local_num = 0; + int i = -1, n = s.length(); + while (++i < n) { + if (s[i] == ' ') { + continue; + } + long num = parseNum(s, i); + switch (op) { + case '+': + global_num += local_num; + local_num = num; + break; + case '-': + global_num += local_num; + local_num = -num; + break; + case '*': + local_num *= num; + break; + case '/': + local_num /= num; + break; + } + if (i < n) { + op = s[i]; + } + } + return global_num + local_num; +} + +``` + + + + +```py +from typing import Tuple + +# 辅函数 - parse从位置i开始的一个数字。 +# 返回(数字, 下一个i位置) +def parseNum(s: str, i: int) -> Tuple[int, int]: + num, n = 0, len(s) + while i < n and s[i].isdigit(): + num = 10 * num + int(s[i]) + i += 1 + return (num, i) + +# 主函数。 +def calculate(s: str) -> int: + op = "+" + global_num, local_num = 0, 0 + i, n = 0, len(s) + + while i < n: + if s[i] == " ": + i += 1 + continue + + num, i = parseNum(s, i) + + match op: + case "+": + global_num += local_num + local_num = num + case "-": + global_num += local_num + local_num = -num + case "*": + local_num *= num + case "/": + # int()会实现向0取整,而//对负数会远离0取整。 + local_num = int(local_num / num) + + if i < n: + op = s[i] + i += 1 + + return global_num + local_num + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/11-string-manipulation/11-4-string-matching.md b/leetcode_101/docs/11-string-manipulation/11-4-string-matching.md deleted file mode 100644 index 547c3da8..00000000 --- a/leetcode_101/docs/11-string-manipulation/11-4-string-matching.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 62 ---- - -# 11.4 字符串匹配 diff --git a/leetcode_101/docs/11-string-manipulation/11-4-string-matching.mdx b/leetcode_101/docs/11-string-manipulation/11-4-string-matching.mdx new file mode 100644 index 00000000..8797d9de --- /dev/null +++ b/leetcode_101/docs/11-string-manipulation/11-4-string-matching.mdx @@ -0,0 +1,106 @@ +--- +sidebar_position: 62 +--- + +# 11.4 字符串匹配 + +## [28. Implement strStr()](https://leetcode.com/problems/find-the-index-of-the-first-occurrence-in-a-string/) + +### 题目描述 + +判断一个字符串是不是另一个字符串的子字符串,并返回其位置。 + +### 输入输出样例 + +输入一个母字符串和一个子字符串,输出一个整数,表示子字符串在母字符串的位置,若不存在则返回-1。 + +``` +Input: haystack = "hello", needle = "ll" +Output: 2 +``` + +### 题解 + +使用著名的Knuth-Morris-Pratt(KMP)算法,可以在 $O(m +n)$ 时间利用动态规划完成匹配。这里我们定义 dp 数组为,dp[i] 表示 needle 中以 i 位置截止的片段(即后缀),最长可以匹配到needle 从头开始的哪个位置(即前缀)。例如,ababaca 的 dp 数组是 [-1,-1,0,1,2,-1,0],表示每个位置最长可以匹配 [无, 无, a, ab, aba, 无, a]。 + +这道题比较复杂,初学者可以暂时跳过。 + + + + +```cpp +// 辅函数。 +vector computeDp(const string &needle) { + int n = needle.length(); + vector dp(n, -1); + for (int j = 1, k = -1; j < n; ++j) { + while (k > -1 && needle[k + 1] != needle[j]) { + k = dp[k]; // 如果下一位不同,回溯到前一个前缀片段 + } + if (needle[k + 1] == needle[j]) { + ++k; // 前缀和后缀片段相同,匹配长度加1 + } + dp[j] = k; // 更新前缀匹配位置 + } + return dp; +} +// 主函数。 +int strStr(const string &haystack, const string &needle) { + int m = haystack.length(), n = needle.length(); + vector dp = computeDp(needle); + for (int i = 0, k = -1; i < m; ++i) { + while (k > -1 && needle[k + 1] != haystack[i]) { + k = dp[k]; // 如果下一位不同,回溯到前一个相同片段 + } + if (needle[k + 1] == haystack[i]) { + ++k; // 片段相同,匹配长度加1 + } + if (k == n - 1) { + return i - n + 1; // 匹配结束 + } + } + return -1; +} +``` + + + + +```py +from typing import List + +# 辅函数。 +def computeDp(needle: str) -> List[int]: + n = len(needle) + dp = [-1] * n + k = -1 + for j in range(1, n): + while k > -1 and needle[k + 1] != needle[j]: + k = dp[k] # 如果下一位不同,回溯到前一个前缀片段 + if needle[k + 1] == needle[j]: + k += 1 # 前缀和后缀片段相同,匹配长度加1 + dp[j] = k # 更新前缀匹配位置 + return dp + +# 主函数。 +def strStr(haystack: str, needle: str) -> int: + m, n = len(haystack), len(needle) + if n == 0: + return 0 # Edge case for an empty needle + + dp = computeDp(needle) + k = -1 + for i in range(m): + while k > -1 and needle[k + 1] != haystack[i]: + k = dp[k] # 如果下一位不同,回溯到前一个相同片段 + if needle[k + 1] == haystack[i]: + k += 1 # 片段相同,匹配长度加1 + if k == n - 1: + return i - n + 1 # 匹配结束 + return -1 + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/11-string-manipulation/11-5-exercises.md b/leetcode_101/docs/11-string-manipulation/11-5-exercises.md index 48cd7c6b..11abb1d5 100644 --- a/leetcode_101/docs/11-string-manipulation/11-5-exercises.md +++ b/leetcode_101/docs/11-string-manipulation/11-5-exercises.md @@ -3,3 +3,24 @@ sidebar_position: 63 --- # 11.5 练习 + +## 基础难度 + +### [409. Longest Palindrome](https://leetcode.com/problems/longest-palindrome/) + +计算一组字符可以构成的回文字符串的最大长度,可以利用其它数据结构进行辅助统计。 + +### [3. Longest Substring Without Repeating Characters](https://leetcode.com/problems/longest-substring-without-repeating-characters/) + +计算最长无重复子字符串,同样的,可以利用其它数据结构进行辅助统计。 + + +## 进阶难度 + +### [772. Basic Calculator III](https://leetcode.com/problems/basic-calculator-iii/) + +题目 227 的 follow-up,十分推荐练习。 + +### [5. Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/) + +类似于我们讲过的子序列问题,子数组或子字符串问题常常也可以用动态规划来解决。先使用动态规划写出一个 $O(n^2)$ 时间复杂度的算法,再搜索一下 Manacher’s Algorithm,它可以在 $O(n)$ 时间解决这一问题。 \ No newline at end of file diff --git a/leetcode_101/docs/11-string-manipulation/_category_.json b/leetcode_101/docs/11-string-manipulation/_category_.json index a2f250df..688feb04 100644 --- a/leetcode_101/docs/11-string-manipulation/_category_.json +++ b/leetcode_101/docs/11-string-manipulation/_category_.json @@ -3,6 +3,6 @@ "position": 11, "link": { "type": "generated-index", - "description": "5 minutes to learn the most important Docusaurus concepts." + "description": "第 11 章 令人头大的字符串" } } From a0b1e281feeca858357d18b1e62001db8e3b8f94 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Thu, 14 Nov 2024 12:12:19 +0100 Subject: [PATCH 15/49] chapter 12 --- .../12-1-data-structure-introduction.md | 35 +++ .../12-2-basic-linked-list-operations.md | 5 - .../12-2-basic-linked-list-operations.mdx | 270 ++++++++++++++++++ .../12-3-other-linked-list-techniques.md | 5 - .../12-3-other-linked-list-techniques.mdx | 140 +++++++++ .../docs/12-linked-lists/12-4-exercises.md | 20 ++ .../docs/12-linked-lists/_category_.json | 2 +- 7 files changed, 466 insertions(+), 11 deletions(-) delete mode 100644 leetcode_101/docs/12-linked-lists/12-2-basic-linked-list-operations.md create mode 100644 leetcode_101/docs/12-linked-lists/12-2-basic-linked-list-operations.mdx delete mode 100644 leetcode_101/docs/12-linked-lists/12-3-other-linked-list-techniques.md create mode 100644 leetcode_101/docs/12-linked-lists/12-3-other-linked-list-techniques.mdx diff --git a/leetcode_101/docs/12-linked-lists/12-1-data-structure-introduction.md b/leetcode_101/docs/12-linked-lists/12-1-data-structure-introduction.md index a056db25..b298b78e 100644 --- a/leetcode_101/docs/12-linked-lists/12-1-data-structure-introduction.md +++ b/leetcode_101/docs/12-linked-lists/12-1-data-structure-introduction.md @@ -3,3 +3,38 @@ sidebar_position: 64 --- # 12.1 数据结构介绍 + +(单向)`链表`是由节点和指针构成的数据结构,每个节点存有一个值,和一个指向下一个节点的指针,因此很多链表问题可以用递归来处理。不同于数组,链表并不能直接获取任意节点的值,必须要通过指针找到该节点后才能获取其值。同理,在未遍历到链表结尾时,我们也无法知道链表的长度,除非依赖其他数据结构储存长度。LeetCode 默认的链表表示方法如下。 + + + + +```cpp +struct ListNode { + int val; + ListNode *next; + ListNode(int x) : val(x), next(nullptr) {} +}; +``` + + + + +```py +class ListNode: + def __init__(self, x): + self.val = x + self.next = None # or a ListNode +``` + + + + + +由于在进行链表操作时,尤其是删除节点时,经常会因为对当前节点进行操作而导致内存或指针出现问题。有两个小技巧可以解决这个问题:一是尽量处理当前节点的下一个节点而非当前节点本身,二是建立一个虚拟节点 (dummy node),使其指向当前链表的头节点,这样即使原链表所有节点全被删除,也会有一个 dummy 存在,返回 dummy->next 即可。 + +:::warning + + 一般来说,算法题不需要删除内存。在刷 LeetCode 的时候,如果想要删除一个节点,可以直接进行指针操作而无需回收内存。实际做软件工程时,对于无用的内存,笔者建议尽量显式回收,或利用智能指针。 + +::: \ No newline at end of file diff --git a/leetcode_101/docs/12-linked-lists/12-2-basic-linked-list-operations.md b/leetcode_101/docs/12-linked-lists/12-2-basic-linked-list-operations.md deleted file mode 100644 index bf0cf9ad..00000000 --- a/leetcode_101/docs/12-linked-lists/12-2-basic-linked-list-operations.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 65 ---- - -# 12.2 链表的基本操作 diff --git a/leetcode_101/docs/12-linked-lists/12-2-basic-linked-list-operations.mdx b/leetcode_101/docs/12-linked-lists/12-2-basic-linked-list-operations.mdx new file mode 100644 index 00000000..b63e43bf --- /dev/null +++ b/leetcode_101/docs/12-linked-lists/12-2-basic-linked-list-operations.mdx @@ -0,0 +1,270 @@ +--- +sidebar_position: 65 +--- + +# 12.2 链表的基本操作 + +## [206. Reverse Linked List](https://leetcode.com/problems/reverse-linked-list/) + +### 题目描述 + +翻转一个链表。 + +### 输入输出样例 + +输入一个链表,输出该链表翻转后的结果。 + +``` +Input: 1->2->3->4->5->nullptr +Output: 5->4->3->2->1->nullptr +``` + +### 题解 + +链表翻转是非常基础也一定要掌握的技能。我们提供了两种写法——递归和非递归。建议你同时掌握这两种写法。 + +递归的写法为: + + + + +```cpp +ListNode* reverseList(ListNode* head, ListNode* head_prev = nullptr) { + if (head == nullptr) { + return head_prev; + } + ListNode* head_next = head->next; + head->next = head_prev; + return reverseList(head_next, head); +} +``` + + + + +```py +def reverseList( + head: Optional[ListNode], head_prev: Optional[ListNode] = None +) -> Optional[ListNode]: + if head is None: + return head_prev + head_next = head.next + head.next = head_prev + return reverseList(head_next, head) +``` + + + + + +非递归的写法为: + + + + +```cpp +ListNode* reverseList(ListNode* head) { + ListNode *head_prev = nullptr, *head_next; + while (head) { + head_next = head->next; + head->next = head_prev; + head_prev = head; + head = head_next; + } + return head_prev; +} +``` + + + + +```py +def reverseList(head: Optional[ListNode]) -> Optional[ListNode]: + head_prev = None + while head is not None: + head_next = head.next + head.next = head_prev + head_prev = head + head = head_next + return head_prev +``` + + + + + +## [21. Merge Two Sorted Lists](https://leetcode.com/problems/merge-two-sorted-lists/) + +### 题目描述 + +给定两个增序的链表,试将其合并成一个增序的链表。 + +### 输入输出样例 + +输入两个链表,输出一个链表,表示两个链表合并的结果。 + +``` +Input: 1->2->4, 1->3->4 +Output: 1->1->2->3->4->4 +``` + +### 题解 + +我们提供了递归和非递归,共两种写法。递归的写法为: + + + + +```cpp +ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { + if (l2 == nullptr) { + return l1; + } + if (l1 == nullptr) { + return l2; + } + if (l1->val < l2->val) { + l1->next = mergeTwoLists(l1->next, l2); + return l1; + } + l2->next = mergeTwoLists(l1, l2->next); + return l2; +} +``` + + + + +```py +def mergeTwoLists( + l1: Optional[ListNode], l2: Optional[ListNode] +) -> Optional[ListNode]: + if l1 is None or l2 is None: + return l1 or l2 + if l1.val < l2.val: + l1.next = mergeTwoLists(l1.next, l2) + return l1 + l2.next = mergeTwoLists(l1, l2.next) + return l2 +``` + + + + + +非递归的写法为: + + + + +```cpp +ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) { + ListNode *dummy = new ListNode(0), *node = dummy; + while (l1 && l2) { + if (l1->val < l2->val) { + node->next = l1; + l1 = l1->next; + } else { + node->next = l2; + l2 = l2->next; + } + node = node->next; + } + node->next = l1 == nullptr ? l2 : l1; + return dummy->next; +} +``` + + + + +```py +def mergeTwoLists( + l1: Optional[ListNode], l2: Optional[ListNode] +) -> Optional[ListNode]: + dummy = ListNode() + head = dummy + + while l1 and l2: + if l1.val < l2.val: + dummy.next = l1 + l1 = l1.next + else: + dummy.next = l2 + l2 = l2.next + dummy = dummy.next + + dummy.next = l1 or l2 + return head.next + +``` + + + + + +## [24. Swap Nodes in Pairs](https://leetcode.com/problems/swap-nodes-in-pairs/) + +### 题目描述 + +给定一个矩阵,交换每个相邻的一对节点。 + +### 输入输出样例 + +输入一个链表,输出该链表交换后的结果。 + +``` +Input: 1->2->3->4 +Output: 2->1->4->3 +``` + +### 题解 + +利用指针进行交换操作,没有太大难度,但一定要细心。 + + + + +```cpp +ListNode* swapPairs(ListNode* head) { + ListNode *node1 = head, *node2; + if (node1 && node1->next) { + node2 = node1->next; + node1->next = node2->next; + node2->next = node1; + head = node2; + while (node1->next && node1->next->next) { + node2 = node1->next->next; + node1->next->next = node2->next; + node2->next = node1->next; + node1->next = node2; + node1 = node2->next; + } + } + return head; +} +``` + + + + +```py +def swapPairs(head: Optional[ListNode]) -> Optional[ListNode]: + node1 = head + if node1 is not None and node1.next is not None: + node2 = node1.next + node1.next = node2.next + node2.next = node1 + head = node2 + while node1.next is not None and node1.next.next is not None: + node2 = node1.next.next + node1.next.next = node2.next + node2.next = node1.next + node1.next = node2 + node1 = node2.next + return head +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/12-linked-lists/12-3-other-linked-list-techniques.md b/leetcode_101/docs/12-linked-lists/12-3-other-linked-list-techniques.md deleted file mode 100644 index fb563c55..00000000 --- a/leetcode_101/docs/12-linked-lists/12-3-other-linked-list-techniques.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 66 ---- - -# 12.3 其它链表技巧 diff --git a/leetcode_101/docs/12-linked-lists/12-3-other-linked-list-techniques.mdx b/leetcode_101/docs/12-linked-lists/12-3-other-linked-list-techniques.mdx new file mode 100644 index 00000000..0b473281 --- /dev/null +++ b/leetcode_101/docs/12-linked-lists/12-3-other-linked-list-techniques.mdx @@ -0,0 +1,140 @@ +--- +sidebar_position: 66 +--- + +# 12.3 其它链表技巧 + +## [160. Intersection of Two Linked Lists](https://leetcode.com/problems/intersection-of-two-linked-lists/) + +### 题目描述 + +给定两个链表,判断它们是否相交于一点,并求这个相交节点。 + +### 输入输出样例 + +输入是两条链表,输出是一个节点。如无相交节点,则返回一个空节点。 + +``` +Input: +A: a1 -> a2 + | + v + c1 -> c2 -> c3 + ^ + | +B: b1 -> b2 -> b3 +Output: c1 +``` + +### 题解 + +假设链表 A 的头节点到相交点的距离是 a,链表 B 的头节点到相交点的距离是 b,相交点到链表终点的距离为 c。我们使用两个指针,分别指向两个链表的头节点,并以相同的速度前进,若到达链表结尾,则移动到另一条链表的头节点继续前进。按照这种前进方法,两个指针会在 a + b + c 次前进后同时到达相交节点。 + + + + +```cpp +ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { + ListNode *l1 = headA, *l2 = headB; + while (l1 != l2) { + l1 = l1 != nullptr ? l1->next : headB; + l2 = l2 != nullptr ? l2->next : headA; + } + return l1; +} +``` + + + + +```py +def getIntersectionNode( + headA: ListNode, headB: ListNode +) -> Optional[ListNode]: + l1 = headA + l2 = headB + while l1 != l2: + l1 = l1.next if l1 is not None else headB + l2 = l2.next if l2 is not None else headA + return l1 +``` + + + + + +## [234. Palindrome Linked List](https://leetcode.com/problems/palindrome-linked-list/) + +### 题目描述 + +以 $O(1)$ 的空间复杂度,判断链表是否回文。 + +### 输入输出样例 + +输入是一个链表,输出是一个布尔值,表示链表是否回文。 + +``` +Input: 1->2->3->2->1 +Output: true +``` + +### 题解 + +先使用快慢指针找到链表中点,再把链表切成两半;然后把后半段翻转;最后比较两半是否相等。 + + + + +```cpp +bool isPalindrome(ListNode* head) { + if (head == nullptr || head->next == nullptr) { + return true; + } + ListNode *slow = head, *fast = head; + while (fast->next && fast->next->next) { + slow = slow->next; + fast = fast->next->next; + } + slow->next = reverseList(slow->next); // 见题目206 + slow = slow->next; + while (slow != nullptr) { + if (head->val != slow->val) { + return false; + } + head = head->next; + slow = slow->next; + } + return true; +} +``` + + + + +```py +def isPalindrome(head: Optional[ListNode]) -> bool: + if head is None or head.next is None: + return True + + slow, fast = head, head + + while fast.next is not None and fast.next.next is not None: + slow = slow.next + fast = fast.next.next + + slow.next = reverseList(slow.next) # 见题目206 + slow = slow.next + + while slow is not None: + if head.val != slow.val: + return False + head = head.next + slow = slow.next + + return True + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/12-linked-lists/12-4-exercises.md b/leetcode_101/docs/12-linked-lists/12-4-exercises.md index 717c288a..f015e8e4 100644 --- a/leetcode_101/docs/12-linked-lists/12-4-exercises.md +++ b/leetcode_101/docs/12-linked-lists/12-4-exercises.md @@ -3,3 +3,23 @@ sidebar_position: 67 --- # 12.4 练习 + +## 基础难度 + +### [83. Remove Duplicates from Sorted List](https://leetcode.com/problems/remove-duplicates-from-sorted-list/) + +虽然 LeetCode 没有强制要求,但是我们仍然建议你回收内存,尤其当题目要求你删除的时候。 + +### [328. Odd Even Linked List](https://leetcode.com/problems/odd-even-linked-list/) + +这道题其实很简单,千万不要把题目复杂化。 + +### [19. Remove Nth Node From End of List](https://leetcode.com/problems/remove-nth-node-from-end-of-list/) + +既然我们可以使用快慢指针找到中点,也可以利用类似的方法找到倒数第 n 个节点,无需遍历第二遍。 + +## 进阶难度 + +### [148. Sort List](https://leetcode.com/problems/sort-list/) + +利用快慢指针找到链表中点后,可以对链表进行归并排序。 \ No newline at end of file diff --git a/leetcode_101/docs/12-linked-lists/_category_.json b/leetcode_101/docs/12-linked-lists/_category_.json index 0e2d1b87..184a7911 100644 --- a/leetcode_101/docs/12-linked-lists/_category_.json +++ b/leetcode_101/docs/12-linked-lists/_category_.json @@ -3,6 +3,6 @@ "position": 12, "link": { "type": "generated-index", - "description": "5 minutes to learn the most important Docusaurus concepts." + "description": "第 12 章 指针三剑客之一:链表" } } From 4d9b9667fc57a139cbc707c446702e491e76eb87 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Thu, 14 Nov 2024 12:44:33 +0100 Subject: [PATCH 16/49] chapter 13 --- .../13-1-data-structure-introduction.md | 5 - .../13-1-data-structure-introduction.mdx | 37 ++ .../docs/13-trees/13-2-tree-recursion.md | 5 - .../docs/13-trees/13-2-tree-recursion.mdx | 469 ++++++++++++++++++ .../13-trees/13-3-level-order-traversal.md | 5 - .../13-trees/13-3-level-order-traversal.mdx | 92 ++++ ...-4-preorder-inorder-postorder-traversal.md | 5 - ...4-preorder-inorder-postorder-traversal.mdx | 250 ++++++++++ .../docs/13-trees/13-5-binary-search-tree.md | 5 - .../docs/13-trees/13-5-binary-search-tree.mdx | 185 +++++++ leetcode_101/docs/13-trees/13-6-trie.md | 5 - leetcode_101/docs/13-trees/13-6-trie.mdx | 137 +++++ leetcode_101/docs/13-trees/13-7-exercises.md | 76 +++ leetcode_101/docs/13-trees/13.1.png | Bin 0 -> 49070 bytes leetcode_101/docs/13-trees/_category_.json | 2 +- 15 files changed, 1247 insertions(+), 31 deletions(-) delete mode 100644 leetcode_101/docs/13-trees/13-1-data-structure-introduction.md create mode 100644 leetcode_101/docs/13-trees/13-1-data-structure-introduction.mdx delete mode 100644 leetcode_101/docs/13-trees/13-2-tree-recursion.md create mode 100644 leetcode_101/docs/13-trees/13-2-tree-recursion.mdx delete mode 100644 leetcode_101/docs/13-trees/13-3-level-order-traversal.md create mode 100644 leetcode_101/docs/13-trees/13-3-level-order-traversal.mdx delete mode 100644 leetcode_101/docs/13-trees/13-4-preorder-inorder-postorder-traversal.md create mode 100644 leetcode_101/docs/13-trees/13-4-preorder-inorder-postorder-traversal.mdx delete mode 100644 leetcode_101/docs/13-trees/13-5-binary-search-tree.md create mode 100644 leetcode_101/docs/13-trees/13-5-binary-search-tree.mdx delete mode 100644 leetcode_101/docs/13-trees/13-6-trie.md create mode 100644 leetcode_101/docs/13-trees/13-6-trie.mdx create mode 100644 leetcode_101/docs/13-trees/13.1.png diff --git a/leetcode_101/docs/13-trees/13-1-data-structure-introduction.md b/leetcode_101/docs/13-trees/13-1-data-structure-introduction.md deleted file mode 100644 index fea5fa67..00000000 --- a/leetcode_101/docs/13-trees/13-1-data-structure-introduction.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 68 ---- - -# 13.1 数据结构介绍 diff --git a/leetcode_101/docs/13-trees/13-1-data-structure-introduction.mdx b/leetcode_101/docs/13-trees/13-1-data-structure-introduction.mdx new file mode 100644 index 00000000..3d50814f --- /dev/null +++ b/leetcode_101/docs/13-trees/13-1-data-structure-introduction.mdx @@ -0,0 +1,37 @@ +--- +sidebar_position: 68 +--- + +# 13.1 数据结构介绍 + +作为(单)链表的升级版,我们通常接触的树都是`二叉树`(binary tree),即每个节点最多有两个子节点;且除非题目说明,默认树中不存在循环结构。LeetCode 默认的树表示方法如下。 + + + + + +```cpp +struct TreeNode { + int val; + TreeNode *left; + TreeNode *right; + TreeNode(int x) : val(x), left(NULL), right(NULL) {} +}; +``` + + + + +```py +class TreeNode: + def __init__(self, val=0, left=None, right=None): + self.val = val + self.left = left + self.right = right +``` + + + + + +可以看出,其与链表的主要差别就是多了一个子节点的指针。 \ No newline at end of file diff --git a/leetcode_101/docs/13-trees/13-2-tree-recursion.md b/leetcode_101/docs/13-trees/13-2-tree-recursion.md deleted file mode 100644 index 0d58455a..00000000 --- a/leetcode_101/docs/13-trees/13-2-tree-recursion.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 69 ---- - -# 13.2 树的递归 diff --git a/leetcode_101/docs/13-trees/13-2-tree-recursion.mdx b/leetcode_101/docs/13-trees/13-2-tree-recursion.mdx new file mode 100644 index 00000000..d88f751c --- /dev/null +++ b/leetcode_101/docs/13-trees/13-2-tree-recursion.mdx @@ -0,0 +1,469 @@ +--- +sidebar_position: 69 +--- + +# 13.2 树的递归 + +对于一些简单的递归题,某些 LeetCode 达人喜欢写 one-line code,即用一行代码解决问题。我们也会展示一些这样的代码,但是对于新手,笔者仍然建议您使用多行的 if-else 判断语句。 + +在很多时候,树递归的写法与深度优先搜索的递归写法相同,因此本书不会区分二者。 + +## [104. Maximum Depth of Binary Tree](https://leetcode.com/problems/maximum-depth-of-binary-tree/) + +### 题目描述 + +求一个二叉树的最大深度。 + +### 输入输出样例 + +输入是一个二叉树,输出是一个整数,表示该树的最大深度。 + +``` +Input: + 3 + / \ + 9 20 + / \ + 15 7 +Output: 3 +``` + +### 题解 + +利用递归,我们可以很方便地求得最大深度。 + + + + +```cpp +int maxDepth(TreeNode* root) { + if (root == nullptr) { + return 0; + } + return max(maxDepth(root->left), maxDepth(root->right)) + 1; +} +``` + + + + +```py +def maxDepth(root: Optional[TreeNode]) -> int: + if root is None: + return 0 + return max(maxDepth(root.left), maxDepth(root.right)) + 1 +``` + + + + + +## [110. Balanced Binary Tree](https://leetcode.com/problems/balanced-binary-tree/) + +### 题目描述 + +判断一个二叉树是否平衡。树平衡的定义是,对于树上的任意节点,其两侧节点的最大深度的差值不得大于 1。 + +### 输入输出样例 + +输入是一个二叉树,输出一个布尔值,表示树是否平衡。 + +``` +Input: + 1 + / \ + 2 2 + / \ + 3 3 + / \ +4 4 +Output: false +``` + +### 题解 + +解法类似于求树的最大深度,但有两个不同的地方:一是我们需要先处理子树的深度再进行比较,二是如果我们在处理子树时发现其已经不平衡了,则可以返回一个-1,使得所有其长辈节点可以避免多余的判断(本题的判断比较简单,做差后取绝对值即可;但如果此处是一个开销较大的比较过程,则避免重复判断可以节省大量的计算时间)。 + + + + +```cpp +// 辅函数。 +int balancedDepth(TreeNode* root) { + if (root == nullptr) { + return 0; + } + int left = balancedDepth(root->left); + int right = balancedDepth(root->right); + if (left == -1 || right == -1 || abs(left - right) > 1) { + return -1; + } + return max(left, right) + 1; +} +// 主函数。 +bool isBalanced(TreeNode* root) { return balancedDepth(root) != -1; } +``` + + + + +```py +# 辅函数。 +def balancedDepth(root: Optional[TreeNode]) -> int: + if root is None: + return 0 + left = balancedDepth(root.left) + right = balancedDepth(root.right) + if left == -1 or right == -1 or abs(left - right) > 1: + return -1 + return max(left, right) + 1 + +# 主函数。 +def isBalanced(root: Optional[TreeNode]) -> bool: + return balancedDepth(root) != -1 + +``` + + + + + +## [543. Diameter of Binary Tree](https://leetcode.com/problems/diameter-of-binary-tree/) + +### 题目描述 + +求一个二叉树的最长直径。直径的定义是二叉树上任意两节点之间的无向距离。 + +### 输入输出样例 + +输入是一个二叉树,输出一个整数,表示最长直径。 + +``` +Input: + 1 + / \ + 2 3 + / \ + 4 5 +Output: 3 +``` + +在这个样例中,最长直径是 [4,2,1,3] 和 [5,2,1,3]。 + +### 题解 + +同样的,我们可以利用递归来处理树。解题时要注意,在我们处理某个子树时,我们更新的最长直径值和递归返回的值是不同的。这是因为待更新的最长直径值是经过该子树根节点的最长直径(即两侧长度);而函数返回值是以该子树根节点为端点的最长直径值(即一侧长度),使用这样的返回值才可以通过递归更新父节点的最长直径值)。 + + + + +```cpp +// 辅函数。 +int updateDiameter(TreeNode* node, int& diameter) { + if (node == nullptr) { + return 0; + } + int left = updateDiameter(node->left, diameter); + int right = updateDiameter(node->right, diameter); + diameter = max(diameter, left + right); + return max(left, right) + 1; +} +// 主函数。 +int diameterOfBinaryTree(TreeNode* root) { + int diameter = 0; + updateDiameter(root, diameter); + return diameter; +} +``` + + + + +```py +# 辅函数。 +def updateDiameter(node: Optional[TreeNode], diameter: List[int]) -> int: + if node is None: + return 0 + left = updateDiameter(node.left, diameter) + right = updateDiameter(node.right, diameter) + diameter[0] = max(diameter[0], left + right) + return max(left, right) + 1 + +# 主函数。 +def diameterOfBinaryTree(root: Optional[TreeNode]) -> int: + diameter = [0] + updateDiameter(root, diameter) + return diameter[0] + +``` + + + + + +## [437. Path Sum III](https://leetcode.com/problems/path-sum-iii/) + +### 题目描述 + +给定一个整数二叉树,求有多少条路径节点值的和等于给定值。 + +### 输入输出样例 + +输入一个二叉树和一个给定整数,输出一个整数,表示有多少条满足条件的路径。 + +``` +Input: sum = 8, tree = + 10 + / \ + 5 -3 + / \ \ + 3 2 11 + / \ \ + 3 -2 1 +Output: 3 +``` + +在这个样例中,和为 8 的路径一共有三个:[[5,3],[5,2,1],[-3,11]]。 + +### 题解 + +递归每个节点时,需要分情况考虑:(1)如果选取该节点加入路径,则之后必须继续加入连续节点,或停止加入节点(2)如果不选取该节点加入路径,则对其左右节点进行重新进行考虑。因此一个方便的方法是我们创建一个辅函数,专门用来计算连续加入节点的路径。 + + + + +```cpp +// 辅函数。 +// long long防止test case中大数溢出,一般情况下用int即可。 +long long pathSumStartWithRoot(TreeNode* root, long long targetSum) { + if (root == nullptr) { + return 0; + } + return (root->val == targetSum) + + pathSumStartWithRoot(root->left, targetSum - root->val) + + pathSumStartWithRoot(root->right, targetSum - root->val); +} +// 主函数。 +int pathSum(TreeNode* root, int targetSum) { + if (root == nullptr) { + return 0; + } + return pathSumStartWithRoot(root, targetSum) + + pathSum(root->left, targetSum) + pathSum(root->right, targetSum); +} +``` + + + + +```py +# 辅函数。 +def pathSumStartWithRoot(root: Optional[TreeNode], targetSum: int) -> int: + if root is None: + return 0 + return ( + int(root.val == targetSum) + + pathSumStartWithRoot(root.left, targetSum - root.val) + + pathSumStartWithRoot(root.right, targetSum - root.val) + ) + +# 主函数。 +def pathSum(root: Optional[TreeNode], targetSum: int) -> int: + if root is None: + return 0 + return ( + pathSumStartWithRoot(root, targetSum) + + pathSum(root.left, targetSum) + + pathSum(root.right, targetSum) + ) + +``` + + + + + +## [101. Symmetric Tree](https://leetcode.com/problems/symmetric-tree/) + +### 题目描述 + +判断一个二叉树是否对称。 + +### 输入输出样例 + +输入一个二叉树,输出一个布尔值,表示该树是否对称。 + +``` +Input: + 1 + / \ + 2 2 + / \ / \ +3 4 4 3 +Output: true +``` + +### 题解 + +判断一个树是否对称等价于判断左右子树是否对称。笔者一般习惯将判断两个子树是否相等或对称类型的题的解法叫做“四步法”:(1)如果两个子树都为空指针,则它们相等或对称(2)如果两个子树只有一个为空指针,则它们不相等或不对称(3)如果两个子树根节点的值不相等,则它们不相等或不对称(4)根据相等或对称要求,进行递归处理。 + + + + + +```cpp +// 辅函数。 +bool isLeftRightSymmetric(TreeNode* left, TreeNode* right) { + if (left == nullptr && right == nullptr) { + return true; + } + if (left == nullptr or right == nullptr) { + return false; + } + if (left->val != right->val) { + return false; + } + return isLeftRightSymmetric(left->left, right->right) && + isLeftRightSymmetric(left->right, right->left); +} +// 主函数。 +bool isSymmetric(TreeNode* root) { + if (root == nullptr) { + return true; + } + return isLeftRightSymmetric(root->left, root->right); +} +``` + + + + +```py +# 辅函数。 +def isLeftRightSymmetric( + left: Optional[TreeNode], right: Optional[TreeNode] +) -> bool: + if left is None and right is None: + return True + if left is None or right is None: + return False + if left.val != right.val: + return False + return ( + isLeftRightSymmetric(left.left, right.right) and + isLeftRightSymmetric(left.right, right.left) + ) + +# 主函数。 +def isSymmetric(root: Optional[TreeNode]) -> bool: + if root is None: + return True + return isLeftRightSymmetric(root.left, root.right) + +``` + + + + + +## [1110. Delete Nodes And Return Forest](https://leetcode.com/problems/delete-nodes-and-return-forest/) + +### 题目描述 + +给定一个整数二叉树和一些整数,求删掉这些整数对应的节点后,剩余的子树。 + +### 输入输出样例 + +输入是一个整数二叉树和一个一维整数数组,输出一个数组,每个位置存储一个子树(的根节点)。 + +``` +Input: to_delete = [3,5], tree = + 1 + / \ + 2 3 + / \ / \ + 4 5 6 7 +Output: [ + 1 + / + 2 + / +4 ,6 ,7] +``` + +### 题解 + +这道题最主要需要注意的细节是如果通过递归处理原树,以及需要在什么时候断开指针。同时,为了便于寻找待删除节点,可以建立一个哈希表方便查找。笔者强烈建议读者在看完题解后,自己写一遍本题,加深对于递归的理解和运用能力。 + + + + +```cpp +// 辅函数。 +TreeNode* moveNodesToForest(TreeNode* root, unordered_set& undeleted, + vector& forest) { + if (root == nullptr) { + return nullptr; + } + root->left = moveNodesToForest(root->left, undeleted, forest); + root->right = moveNodesToForest(root->right, undeleted, forest); + if (undeleted.contains(root->val)) { + if (root->left != nullptr) { + forest.push_back(root->left); + } + if (root->right != nullptr) { + forest.push_back(root->right); + } + root = nullptr; + } + return root; +} +// 主函数。 +vector delNodes(TreeNode* root, vector& to_delete) { + vector forest; + unordered_set undeleted(to_delete.begin(), to_delete.end()); + root = moveNodesToForest(root, undeleted, forest); + if (root != nullptr) { + forest.push_back(root); + } + return forest; +} +``` + + + + +```py +# 辅函数。 +def moveNodesToForest( + root: Optional[TreeNode], undeleted: Set[int], forest: List[TreeNode] +) -> Optional[TreeNode]: + if root is None: + return None + + root.left = moveNodesToForest(root.left, undeleted, forest) + root.right = moveNodesToForest(root.right, undeleted, forest) + + if root.val in undeleted: + if root.left is not None: + forest.append(root.left) + if root.right is not None: + forest.append(root.right) + root = None + + return root + +# 主函数。 +def delNodes(root: Optional[TreeNode], to_delete: List[int]) -> List[TreeNode]: + forest = [] + undeleted = set(to_delete) + root = moveNodesToForest(root, undeleted, forest) + if root is not None: + forest.append(root) + return forest + +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/13-trees/13-3-level-order-traversal.md b/leetcode_101/docs/13-trees/13-3-level-order-traversal.md deleted file mode 100644 index 8bde635f..00000000 --- a/leetcode_101/docs/13-trees/13-3-level-order-traversal.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 70 ---- - -# 13.3 层次遍历 diff --git a/leetcode_101/docs/13-trees/13-3-level-order-traversal.mdx b/leetcode_101/docs/13-trees/13-3-level-order-traversal.mdx new file mode 100644 index 00000000..3c2e80ea --- /dev/null +++ b/leetcode_101/docs/13-trees/13-3-level-order-traversal.mdx @@ -0,0 +1,92 @@ +--- +sidebar_position: 70 +--- + +# 13.3 层次遍历 + +我们可以使用广度优先搜索进行层次遍历。注意,不需要使用两个队列来分别存储当前层的节点和下一层的节点,因为在开始遍历一层的节点时,当前队列中的节点数就是当前层的节点数,只要控制遍历这么多节点数,就能保证这次遍历的都是当前层的节点。 + +## [637. Average of Levels in Binary Tree](https://leetcode.com/problems/average-of-levels-in-binary-tree/) + +### 题目描述 + +给定一个二叉树,求每一层的节点值的平均数。 + +### 输入输出样例 + +输入是一个二叉树,输出是一个一维数组,表示每层节点值的平均数。 + +``` +Input: + 3 + / \ + 9 20 + / \ + 15 7 +Output: [3, 14.5, 11] +``` + +### 题解 + +利用广度优先搜索,我们可以很方便地求取每层的平均值。 + + + + +```cpp +vector averageOfLevels(TreeNode* root) { + vector level_avg; + if (root == nullptr) { + return level_avg; + } + queue q; + q.push(root); + int count = q.size(); + while (count > 0) { + double level_sum = 0; + for (int i = 0; i < count; ++i) { + TreeNode* node = q.front(); + q.pop(); + level_sum += node->val; + if (node->left != nullptr) { + q.push(node->left); + } + if (node->right != nullptr) { + q.push(node->right); + } + } + level_avg.push_back(level_sum / count); + count = q.size(); + } + return level_avg; +} +``` + + + + +```py +def averageOfLevels(root: Optional[TreeNode]) -> List[float]: + level_avg = [] + if root is None: + return level_avg + q = collections.deque() + q.append(root) + count = len(q) + while count > 0: + level_sum = 0 + for _ in range(count): + node = q.popleft() + level_sum += node.val + if node.left is not None: + q.append(node.left) + if node.right is not None: + q.append(node.right) + level_avg.append(level_sum / count) + count = len(q) + return level_avg +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/13-trees/13-4-preorder-inorder-postorder-traversal.md b/leetcode_101/docs/13-trees/13-4-preorder-inorder-postorder-traversal.md deleted file mode 100644 index 59d912e8..00000000 --- a/leetcode_101/docs/13-trees/13-4-preorder-inorder-postorder-traversal.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 71 ---- - -# 13.4 前中后序遍历 diff --git a/leetcode_101/docs/13-trees/13-4-preorder-inorder-postorder-traversal.mdx b/leetcode_101/docs/13-trees/13-4-preorder-inorder-postorder-traversal.mdx new file mode 100644 index 00000000..a2ae00d2 --- /dev/null +++ b/leetcode_101/docs/13-trees/13-4-preorder-inorder-postorder-traversal.mdx @@ -0,0 +1,250 @@ +--- +sidebar_position: 71 +--- + +# 13.4 前中后序遍历 + +前序遍历、中序遍历和后序遍历是三种利用深度优先搜索遍历二叉树的方式。它们是在对节点访问的顺序有一点不同,其它完全相同。考虑如下一棵树, + +``` + 1 + / \ + 2 3 + / \ \ +4 5 6 +``` + +前序遍历先遍历父结点,再遍历左结点,最后遍历右节点,我们得到的遍历顺序是 [1 2 4 5 3 6]。 + + + + +```cpp +void preorder(TreeNode* root) { + visit(root); + preorder(root->left); + preorder(root->right); +} +``` + + + + +```py +def preorder(root: TreeNode): + visit(root) + preorder(root.left) + preorder(root.right) +``` + + + + + +中序遍历先遍历左节点,再遍历父结点,最后遍历右节点,我们得到的遍历顺序是 [4 2 5 1 3 6]。 + + + + +```cpp +void inorder(TreeNode* root) { + inorder(root->left); + visit(root); + inorder(root->right); +} +``` + + + + +```py +def inorder(root: TreeNode): + inorder(root.left) + visit(root) + inorder(root.right) +``` + + + + + +后序遍历先遍历左节点,再遍历右结点,最后遍历父节点,我们得到的遍历顺序是 [4 5 2 6 3 1]。 + + + + +```cpp +void postorder(TreeNode* root) { + postorder(root->left); + postorder(root->right); + visit(root); +} +``` + + + + +```py +def postorder(root: TreeNode): + postorder(root.left) + postorder(root.right) + visit(root) +``` + + + + + +## [105. Construct Binary Tree from Preorder and Inorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/) + +### 题目描述 + +给定一个二叉树的前序遍历和中序遍历结果,尝试复原这个树。已知树里不存在重复值的节点。 + +### 输入输出样例 + +输入是两个一维数组,分别表示树的前序遍历和中序遍历结果;输出是一个二叉树。 + +``` +Input: preorder = [4,9,20,15,7], inorder = [9,4,15,20,7] +Output: + 4 + / \ + 9 20 + / \ + 15 7 +``` + +### 题解 + +我们通过本题的样例讲解一下本题的思路。前序遍历的第一个节点是 4,意味着 4 是根节点。我们在中序遍历结果里找到 4 这个节点,根据中序遍历的性质可以得出,4 在中序遍历数组位置的左子数组为左子树,节点数为 1,对应的是前序排列数组里 4 之后的 1 个数字(9);4 在中序遍历数组位置的右子数组为右子树,节点数为 3,对应的是前序排列数组里最后的 3 个数字。有了这些信息,我们就可以对左子树和右子树进行递归复原了。为了方便查找数字的位置,我们可以用哈希表预处理中序遍历的结果。 + + + + +```cpp +// 辅函数。 +TreeNode* reconstruct(unordered_map& io_map, vector& po, int l, + int r, int mid_po) { + if (l > r) { + return nullptr; + } + int mid_val = po[mid_po]; + int mid_io = io_map[mid_val]; + int left_len = mid_io - l + 1; + TreeNode* node = new TreeNode(mid_val); + node->left = reconstruct(io_map, po, l, mid_io - 1, mid_po + 1); + node->right = reconstruct(io_map, po, mid_io + 1, r, mid_po + left_len); + return node; +} +// 主函数。 +TreeNode* buildTree(vector& preorder, vector& inorder) { + unordered_map io_map; + for (int i = 0; i < inorder.size(); ++i) { + io_map[inorder[i]] = i; + } + return reconstruct(io_map, preorder, 0, preorder.size() - 1, 0); +} +``` + + + + +```py +# 辅函数。 +def reconstruct( + io_map: Dict[int, int], po: List[int], l: int, r: int, mid_po: int +) -> Optional[TreeNode]: + if l > r: + return None + mid_val = po[mid_po] + mid_io = io_map[mid_val] + left_len = mid_io - l + 1 + node = TreeNode(mid_val) + node.left = reconstruct(io_map, po, l, mid_io - 1, mid_po + 1) + node.right = reconstruct(io_map, po, mid_io + 1, r, mid_po + left_len) + return node + +# 主函数。 +def buildTree(preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: + io_map = {val: i for i, val in enumerate(inorder)} + return reconstruct(io_map, preorder, 0, len(preorder) - 1, 0) + +``` + + + + + +## [144. Binary Tree Preorder Traversal](https://leetcode.com/problems/binary-tree-preorder-traversal/) + +### 题目描述 + +不使用递归,实现二叉树的前序遍历。 + +### 输入输出样例 + +输入一个二叉树,输出一个数组,为二叉树前序遍历的结果, + +``` +Input: + 1 + \ + 2 + / + 3 +Output: [1,2,3] +``` + +### 题解 + +因为递归的本质是栈调用,因此我们可以通过栈来实现前序遍历。注意入栈的顺序。 + + + + +```cpp +vector preorderTraversal(TreeNode* root) { + vector po; + if (root == nullptr) { + return po; + } + stack s; + s.push(root); + while (!s.empty()) { + TreeNode* node = s.top(); + s.pop(); + po.push_back(node->val); + if (node->right) { + s.push(node->right); // 先右后左,保证左子树先遍历 + } + if (node->left) { + s.push(node->left); + } + } + return po; +} +``` + + + + +```py +def preorderTraversal(root: Optional[TreeNode]) -> List[int]: + po = [] + if root is None: + return po + s = [root] + while len(s) > 0: + node = s.pop() + po.append(node.val) + if node.right is not None: + s.append(node.right) # 先右后左,保证左子树先遍历 + if node.left is not None: + s.append(node.left) + return po +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/13-trees/13-5-binary-search-tree.md b/leetcode_101/docs/13-trees/13-5-binary-search-tree.md deleted file mode 100644 index 84ebd512..00000000 --- a/leetcode_101/docs/13-trees/13-5-binary-search-tree.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 72 ---- - -# 13.5 二叉查找树 diff --git a/leetcode_101/docs/13-trees/13-5-binary-search-tree.mdx b/leetcode_101/docs/13-trees/13-5-binary-search-tree.mdx new file mode 100644 index 00000000..b3e9b709 --- /dev/null +++ b/leetcode_101/docs/13-trees/13-5-binary-search-tree.mdx @@ -0,0 +1,185 @@ +--- +sidebar_position: 72 +--- + +# 13.5 二叉查找树 + +`二叉查找树`(Binary Search Tree, BST)是一种特殊的二叉树:对于每个父节点,其左子树中所有节点的值小于等于父结点的值,其右子树中所有节点的值大于等于父结点的值。因此对于一个二叉查找树,我们可以在 O(log n) 的时间内查找一个值是否存在:从根节点开始,若当前节点的值大于查找值则向左下走,若当前节点的值小于查找值则向右下走。同时因为二叉查找树是有序的,对其中序遍历的结果即为排好序的数组。 + +例如下面这棵树即为二叉查找树,其中序遍历结果为 [1 2 3 4 5 6]。 + +``` + 4 + / \ + 2 5 + / \ \ +1 3 6 +``` + +## [99. Recover Binary Search Tree](https://leetcode.com/problems/recover-binary-search-tree/) + +### 题目描述 + +给定一个二叉查找树,已知有两个节点被不小心交换了,试复原此树。 + +### 输入输出样例 + +输入是一个被误交换两个节点的二叉查找树,输出是改正后的二叉查找树。 + +``` +Input: + 3 + / \ +1 4 + / + 2 +Output: + 2 + / \ +1 4 + / + 3 +``` + +在这个样例中,2 和 3 被不小心交换了。 + +### 题解 + +我们可以使用中序遍历这个二叉查找树,同时设置一个 prev 指针,记录当前节点中序遍历时的前节点。如果当前节点大于 prev 节点的值,说明需要调整次序。有一个技巧是如果遍历整个序列过程中只出现了一次次序错误,说明就是这两个相邻节点需要被交换;如果出现了两次次序错误,那就需要交换这两个节点。 + + + + +```cpp +// 辅函数。 +void inorder(TreeNode* root, TreeNode*& mistake1, TreeNode*& mistake2, + TreeNode*& prev) { + if (root == nullptr) { + return; + } + inorder(root->left, mistake1, mistake2, prev); + if (prev != nullptr && root->val < prev->val) { + if (mistake1 == nullptr) { + mistake1 = prev; + } + mistake2 = root; + } + prev = root; + inorder(root->right, mistake1, mistake2, prev); +} +// 主函数。 +void recoverTree(TreeNode* root) { + TreeNode *mistake1 = nullptr, *mistake2 = nullptr, *prev = nullptr; + inorder(root, mistake1, mistake2, prev); + if (mistake1 != nullptr && mistake2 != nullptr) { + swap(mistake1->val, mistake2->val); + } +} +``` + + + + +```py +# 辅函数。 +# 注意,Python中并不方便在辅函数中直接传指针,因此我们建造长度为1的list进行传引用。 +def inorder( + root: Optional[TreeNode], + mistake1=List[Optional[TreeNode]], + mistake2=List[Optional[TreeNode]], + prev=List[Optional[TreeNode]], +): + if root is None: + return + inorder(root.left, mistake1, mistake2, prev) + if prev[0] is not None and root.val < prev[0].val: + if mistake1[0] is None: + mistake1[0] = prev[0] + mistake2[0] = root + prev[0] = root + inorder(root.right, mistake1, mistake2, prev) + +# 主函数。 +def recoverTree(root: Optional[TreeNode]) -> None: + mistake1, mistake2, prev = [None], [None], [None] + inorder(root, mistake1, mistake2, prev) + if mistake1[0] is not None and mistake2[0] is not None: + mistake1[0].val, mistake2[0].val = mistake2[0].val, mistake1[0].val +``` + + + + + +## [669. Trim a Binary Search Tree](https://leetcode.com/problems/trim-a-binary-search-tree/) + +### 题目描述 + +给定一个二叉查找树和两个整数 L 和 R,且 L < R,试修剪此二叉查找树,使得修剪后所有节点的值都在 [L, R] 的范围内。 + +### 输入输出样例 + +输入是一个二叉查找树和两个整数 L 和 R,输出一个被修剪好的二叉查找树。 + +``` +Input: L = 1, R = 3, tree = + 3 + / \ + 0 4 + \ + 2 + / + 1 +Output: + 3 + / + 2 + / +1 +``` + +### 题解 + +利用二叉查找树的大小关系,我们可以很容易地利用递归进行树的处理。 + + + + +```cpp +TreeNode* trimBST(TreeNode* root, int low, int high) { + if (root == nullptr) { + return root; + } + if (root->val > high) { + return trimBST(root->left, low, high); + } + if (root->val < low) { + return trimBST(root->right, low, high); + } + root->left = trimBST(root->left, low, high); + root->right = trimBST(root->right, low, high); + return root; +} +``` + + + + +```py +def trimBST( + root: Optional[TreeNode], low: int, high: int +) -> Optional[TreeNode]: + if root is None: + return None + if root.val > high: + return trimBST(root.left, low, high) + if root.val < low: + return trimBST(root.right, low, high) + root.left = trimBST(root.left, low, high) + root.right = trimBST(root.right, low, high) + return root +``` + + + + \ No newline at end of file diff --git a/leetcode_101/docs/13-trees/13-6-trie.md b/leetcode_101/docs/13-trees/13-6-trie.md deleted file mode 100644 index 7eeb30e2..00000000 --- a/leetcode_101/docs/13-trees/13-6-trie.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 73 ---- - -# 13.6 字典树 diff --git a/leetcode_101/docs/13-trees/13-6-trie.mdx b/leetcode_101/docs/13-trees/13-6-trie.mdx new file mode 100644 index 00000000..2e1f7e9d --- /dev/null +++ b/leetcode_101/docs/13-trees/13-6-trie.mdx @@ -0,0 +1,137 @@ +--- +sidebar_position: 73 +--- + +# 13.6 字典树 + +字典树(Trie)用于判断字符串是否存在或者是否具有某种字符串前缀。 + +