diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index 12bf2f45aa2a5..9cbadf57631dc 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -1,6 +1,7 @@
name: deploy
on:
+ workflow_dispatch:
push:
branches:
- main
@@ -12,85 +13,118 @@ on:
- lcof/**
- lcci/**
- basic/**
- workflow_dispatch:
-
-env:
- MKDOCS_API_KEYS: ${{ secrets.MKDOCS_API_KEYS }}
-
-permissions:
- contents: write
concurrency:
- group: ${{github.workflow}} - ${{github.ref}}
+ group: ${{ github.workflow }} - ${{ github.ref }}
cancel-in-progress: true
jobs:
- deploy:
+ build:
runs-on: ubuntu-latest
- if: github.repository == 'doocs/leetcode'
steps:
- - uses: actions/checkout@v4
- - uses: actions/checkout@v4
+ - name: Checkout main branch
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Checkout docs branch
+ uses: actions/checkout@v4
with:
ref: docs
path: mkdocs
- - run: |
- mv -f mkdocs/* .
+ fetch-depth: 0
+
+ - name: Sync docs branch content
+ run: |
+ rsync -a --remove-source-files --exclude='.git' mkdocs/ ./
+ rm -rf mkdocs
mv solution/CONTEST_README.md docs/contest.md
mv solution/CONTEST_README_EN.md docs-en/contest.md
+
- name: Configure Git Credentials
run: |
- git config user.name github-actions[bot]
- git config user.email 41898282+github-actions[bot]@users.noreply.github.com
+ git config --global user.name github-actions[bot]
+ git config --global user.email 41898282+github-actions[bot]@users.noreply.github.com
- - uses: actions/setup-python@v5
+ - name: Setup Python
+ uses: actions/setup-python@v5
with:
python-version: 3.x
- - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
+ - name: Restore pip cache
+ uses: actions/cache@v4
+ with:
+ path: ~/.cache/pip
+ key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
+ restore-keys: |
+ ${{ runner.os }}-pip-
- - uses: actions/cache@v4
+ - name: Restore mkdocs-material cache
+ uses: actions/cache@v4
with:
- key: mkdocs-material-${{ env.cache_id }}
path: .cache
+ key: mkdocs-material-${{ env.cache_id }}
restore-keys: |
mkdocs-material-
-
+
- name: Install dependencies
run: |
python3 -m pip install --upgrade pip
python3 -m pip install -r requirements.txt
python3 -m pip install "mkdocs-material[imaging]"
- sudo apt-get install pngquant
+ sudo apt-get install -y pngquant
+
+ - name: Set MKDOCS_API_KEYS
+ run: echo "MKDOCS_API_KEYS=${{ secrets.MKDOCS_API_KEYS }}" >> $GITHUB_ENV
- - run: |
+ - name: Build site
+ run: |
python3 main.py
mkdocs build -f mkdocs.yml
mkdocs build -f mkdocs-en.yml
- - name: Deploy
- uses: peaceiris/actions-gh-pages@v4
+ - name: Generate CNAME
+ run: echo "leetcode.doocs.org" > ./site/CNAME
+
+ - name: Commit committer cache to docs branch
+ if: github.ref == 'refs/heads/main'
+ env:
+ GH_REPO: ${{ github.repository }}
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ CACHE_FILE=".git-committers-cache.json"
+ if [[ ! -f "$CACHE_FILE" ]]; then
+ echo "Cache file not found; skip commit."
+ exit 0
+ fi
+
+ echo "Cloning docs branch ..."
+ git clone --depth 1 --branch docs "https://x-access-token:${GH_TOKEN}@github.com/${GH_REPO}.git" docs-cache
+ cp "$CACHE_FILE" docs-cache/
+
+ cd docs-cache
+ git config user.name github-actions[bot]
+ git config user.email 41898282+github-actions[bot]@users.noreply.github.com
+
+ git add .git-committers-cache.json
+ git commit -m "chore: update committer cache [skip ci]" || echo "No changes to commit"
+ git push origin docs
+
+ - name: Upload artifact
+ uses: actions/upload-pages-artifact@v3
with:
- github_token: ${{ secrets.GITHUB_TOKEN }}
- publish_dir: ./site
-
- # sync:
- # runs-on: ubuntu-latest
- # needs: deploy
- # if: github.repository == 'doocs/leetcode'
- # steps:
- # - name: Sync to gitee.com
- # uses: wearerequired/git-mirror-action@master
- # env:
- # SSH_PRIVATE_KEY: ${{ secrets.RSA_PRIVATE_KEY }}
- # with:
- # source-repo: git@github.com:doocs/leetcode.git
- # destination-repo: git@gitee.com:Doocs/leetcode.git
-
- # - name: Build Gitee Pages
- # uses: yanglbme/gitee-pages-action@main
- # with:
- # gitee-username: yanglbme
- # gitee-password: ${{ secrets.GITEE_PASSWORD }}
- # gitee-repo: doocs/leetcode
- # branch: gh-pages
\ No newline at end of file
+ path: ./site
+
+ deploy:
+ needs: build
+ runs-on: ubuntu-latest
+ permissions:
+ pages: write
+ id-token: write
+ environment:
+ name: github_pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ steps:
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v4
diff --git a/.github/workflows/pr-add-label.yml b/.github/workflows/pr-add-label.yml
new file mode 100644
index 0000000000000..82661e9eb237e
--- /dev/null
+++ b/.github/workflows/pr-add-label.yml
@@ -0,0 +1,25 @@
+name: pr-add-label
+
+on:
+ pull_request_target:
+ types: [opened, edited, reopened, synchronize]
+
+jobs:
+ add-label:
+ permissions:
+ contents: read
+ pull-requests: write
+ runs-on: ubuntu-latest
+ if: github.repository == 'doocs/leetcode'
+ steps:
+ - name: Check PR number
+ id: pr_number
+ run: echo "PR_NUMBER=${{ github.event.pull_request.number }}" >> $GITHUB_ENV
+
+ - name: Run add-label Action
+ uses: actionv/pr-label-action@master
+ with:
+ github_token: ${{ secrets.DOOCS_BOT_ACTION_TOKEN }}
+ pr_number: ${{ env.PR_NUMBER }}
+ organize_name: "doocs"
+ team_name: "leetcode-algorithm"
diff --git a/.gitignore b/.gitignore
index e8ebbedd5ad1e..521323b59d92d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,10 +3,13 @@
.vscode
.temp
.vitepress
-.cache
*.iml
__pycache__
/node_modules
/solution/result.json
/solution/__pycache__
/solution/.env
+.cache
+!.cache/plugin/
+!.cache/plugin/git-committers/
+!.cache/plugin/git-committers/page-authors.json
\ No newline at end of file
diff --git a/.prettierignore b/.prettierignore
index 13715bc116db8..47b55e9bdf606 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -26,3 +26,4 @@ node_modules/
/solution/3100-3199/3150.Invalid Tweets II/Solution.sql
/solution/3100-3199/3198.Find Cities in Each State/Solution.sql
/solution/3300-3399/3328.Find Cities in Each State II/Solution.sql
+/solution/3400-3499/3451.Find Invalid IP Addresses/Solution.sql
diff --git a/README.md b/README.md
index fb03f8b48b1f5..aa8c9b92c5efa 100644
--- a/README.md
+++ b/README.md
@@ -1,15 +1,16 @@
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
## 介绍
@@ -20,7 +21,7 @@
## 站点
-https://doocs.github.io/leetcode
+
## 算法全解
@@ -189,11 +190,11 @@ https://doocs.github.io/leetcode
1. 进入 leetcode 目录,切换到一个新的分支;
1. 对项目做出一些变更,然后使用 git add、commit、push 等命令将你的本地变更提交到你的远程 GitHub 仓库;
1. 将你的变更以 PR 的形式提交过来,项目的维护人员会在第一时间对你的变更进行 review!
-1. 你也可以参考帮助文档 https://help.github.com/cn 了解更多细节。
+1. 你也可以参考帮助文档 了解更多细节。
-
-
-
+
+
+
[](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=149001365&machine=basicLinux32gb&location=SoutheastAsia)
@@ -214,32 +215,18 @@ https://doocs.github.io/leetcode
-## 赞助者
-
-感谢以下个人、组织对本项目的支持和赞助!
-
-
-
-
-
-> "_You help the developer community practice for interviews, and there is nothing better we could ask for._" -- [Alan Yessenbayev](https://opencollective.com/alan-yessenbayev)
-
-## 推荐者
-
-知名互联网科技博主 [@爱可可-爱生活](https://weibo.com/fly51fly) 微博推荐。
-
-
-
## 版权
本项目著作权归 [GitHub 开源社区 Doocs](https://github.com/doocs) 所有,商业转载请联系 @yanglbme 获得授权,非商业转载请注明出处。
-## 联系我们
+## 联系我们 & 支持项目
欢迎各位小伙伴们添加 @yanglbme 的个人微信(微信号:YLB0109),备注 「**leetcode**」。后续我们会创建算法、技术相关的交流群,大家一起交流学习,分享经验,共同进步。
-| |
-| ------------------------------------------------------------------------------------------------------------------------------ |
+如果你觉得这个项目对你有帮助,也欢迎通过微信扫码赞赏我们 ☕️~
+
+| | |
+| -------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
## 许可证
diff --git a/README_EN.md b/README_EN.md
index d81be5f48286a..3b461059720a9 100644
--- a/README_EN.md
+++ b/README_EN.md
@@ -1,15 +1,16 @@
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
## Introduction
@@ -18,9 +19,9 @@ This project contains solutions for problems from LeetCode, "Coding Interviews (
[中文文档](/README.md)
-## Sites
+## Site
-https://doocs.github.io/leetcode
+https://leetcode.doocs.org/en
## Solutions
@@ -31,8 +32,8 @@ https://doocs.github.io/leetcode
## JavaScript & Database Practice
-- [JavaScript Practice](/solution/JAVASCRIPT_README_EN.md)
-- [Database Practice](/solution/DATABASE_README_EN.md)
+- [JavaScript](/solution/JAVASCRIPT_README_EN.md)
+- [Database](/solution/DATABASE_README_EN.md)
## Topics
@@ -183,9 +184,9 @@ I'm looking for long-term contributors/partners to this repo! Send me [PRs](http
1. Create a pull request with your changes!
1. See [CONTRIBUTING](https://github.com/doocs/.github/blob/main/CONTRIBUTING.md) or [GitHub Help](https://help.github.com/en) for more details.
-
-
-
+
+
+
[](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=149001365&machine=basicLinux32gb&location=EastUs)
@@ -206,20 +207,15 @@ This project exists thanks to all the people who contribute.
-## Backers & Sponsors
-
-Thank you to all our backers and sponsors!
-
-
-
-
-
-> "_You help the developer community practice for interviews, and there is nothing better we could ask for._" -- [Alan Yessenbayev](https://opencollective.com/alan-yessenbayev)
-
## Copyright
The copyright of this project belongs to [Doocs](https://github.com/doocs) community. For commercial reprints, please contact [@yanglbme](mailto:contact@yanglibin.info) for authorization. For non-commercial reprints, please indicate the source.
+## Support Us
+
+If you find this project helpful, consider supporting us by buying us a coffee ☕️
+👉 [https://paypal.me/yanglbme](https://paypal.me/yanglbme)
+
## Contact Us
We welcome everyone to add @yanglbme's personal WeChat (WeChat ID: YLB0109), with the note "leetcode". In the future, we will create algorithm and technology related discussion groups, where we can learn and share experiences together, and make progress together.
diff --git a/images/doocs-leetcode.png b/images/doocs-leetcode.png
index 8a7f55f6253a6..a69e814914b16 100644
Binary files a/images/doocs-leetcode.png and b/images/doocs-leetcode.png differ
diff --git a/images/favicon-16x16.png b/images/favicon-16x16.png
deleted file mode 100644
index c846c93f0a389..0000000000000
Binary files a/images/favicon-16x16.png and /dev/null differ
diff --git a/images/favicon-32x32.png b/images/favicon-32x32.png
deleted file mode 100644
index 2d79130a1a393..0000000000000
Binary files a/images/favicon-32x32.png and /dev/null differ
diff --git a/images/leetcode-doocs.png b/images/leetcode-doocs.png
index 616eea1c01815..a69e814914b16 100644
Binary files a/images/leetcode-doocs.png and b/images/leetcode-doocs.png differ
diff --git a/images/pr-en.svg b/images/pr-en.svg
new file mode 100644
index 0000000000000..7465d268ffbf0
--- /dev/null
+++ b/images/pr-en.svg
@@ -0,0 +1 @@
+3.Create a New Branch & Make Changes
4.Commit & Push to Your Repo
LeetCode Repo doocs/leetcode.git
Your GitHub Repo yourusername/leetcode.git
\ No newline at end of file
diff --git a/images/pr.svg b/images/pr.svg
new file mode 100644
index 0000000000000..22e333230e98e
--- /dev/null
+++ b/images/pr.svg
@@ -0,0 +1 @@
+LeetCode 仓库 doocs/leetcode.git
你的 GitHub 仓库 yourusername/leetcode.git
\ No newline at end of file
diff --git a/images/starcharts.svg b/images/starcharts.svg
index ff5d6b61f6e17..44ce5b9c209b1 100644
--- a/images/starcharts.svg
+++ b/images/starcharts.svg
@@ -1,4 +1,4 @@
-
+
\n2018-09-25 2019-07-09 2020-04-21 2021-02-02 2021-11-16 2022-08-30 2023-06-13 2024-03-26 2025-01-07 Time 2018-09-25 2019-07-28 2020-05-29 2021-04-01 2022-02-01 2022-12-05 2023-10-07 2024-08-09 2025-06-11 Time 0 4200 8300 12400 16500 20700 24800 28900 33000 Stargazers 0 4400 8800 13200 17500 21900 26300 30700 35000 Stargazers
\ No newline at end of file
+L 941 21
+L 941 21
+L 941 21
+L 941 21
+L 941 21
+L 941 21
+L 941 21
+L 941 21
+L 941 21
+L 941 21
+L 941 21
+L 941 21
+L 941 21
+L 941 21
+L 941 21
+L 941 21
+L 941 21
+L 941 21
+L 941 21
+L 942 21
+L 942 21
+L 942 21
+L 942 21
+L 942 21
+L 942 21
+L 942 21
+L 942 21
+L 942 21
+L 942 21
+L 942 21
+L 942 21
+L 942 21
+L 942 21
+L 942 21
+L 942 21
+L 942 21
+L 942 21
+L 942 21
+L 942 21
+L 942 21
+L 943 21
+L 943 21
+L 943 21
+L 943 21
+L 943 21
+L 943 21
+L 943 21
+L 943 21
+L 943 21
+L 943 21
+L 943 21
+L 943 21
+L 943 21
+L 943 21
+L 943 21
+L 943 21
+L 943 21
+L 943 21
+L 943 21
+L 943 21
+L 943 21
+L 943 21
+L 943 21
+L 943 21
+L 943 21
+L 943 21
+L 943 21
+L 944 21
+L 944 21
+L 944 21
+L 944 21
+L 944 21
+L 944 21
+L 944 21
+L 944 21
+L 944 21
+L 944 21
+L 944 21
+L 944 21
+L 944 21
+L 944 21
+L 944 21
+L 944 21
+L 944 21
+L 944 21
+L 944 21
+L 944 21
+L 945 21
+L 945 21
+L 945 21
+L 945 21
+L 945 21
+L 945 21
+L 945 21
+L 945 21
+L 945 20
+L 945 20
+L 945 20
+L 945 20
+L 945 20
+L 945 20
+L 945 20
+L 945 20
+L 945 20
+L 945 20
+L 945 20
+L 945 20
+L 945 20
+L 945 20
+L 945 20
+L 946 20
+L 946 20
+L 946 20
+L 946 20
+L 946 20
+L 946 20
+L 946 20
+L 946 20
+L 946 20
+L 946 20
+L 946 20
+L 946 20
+L 946 20
+L 946 20
+L 946 20
+L 946 20
+L 946 20
+L 946 20
+L 946 20
+L 946 20
+L 946 20
+L 946 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 947 20
+L 948 20
+L 948 20
+L 948 20
+L 948 20
+L 948 20
+L 948 20
+L 948 20
+L 948 20
+L 948 20
+L 948 20
+L 948 20
+L 948 20
+L 948 20
+L 948 20
+L 948 20
+L 948 20
+L 948 20
+L 948 20
+L 948 20
+L 948 20
+L 948 20
+L 948 20
+L 948 20
+L 948 20
+L 948 20
+L 948 20
+L 949 20
+L 949 20
+L 949 20
+L 949 20
+L 949 20
+L 949 19
+L 949 19
+L 949 19
+L 949 19
+L 949 19
+L 949 19
+L 949 19
+L 949 19
+L 949 19
+L 950 19
+L 950 19
+L 950 19
+L 950 19
+L 950 19
+L 950 19
+L 950 19
+L 950 19
+L 950 19
+L 950 19
+L 950 19
+L 950 19
+L 950 19
+L 950 19
+L 950 19
+L 950 19
+L 950 19
+L 950 19
+L 950 19
+L 950 19
+L 950 19
+L 950 19
+L 950 19" style="stroke-width:2;stroke:rgba(129,199,239,1.0);fill:none"/>
\ No newline at end of file
diff --git a/images/support1.jpg b/images/support1.jpg
new file mode 100644
index 0000000000000..5d476dd5a74c4
Binary files /dev/null and b/images/support1.jpg differ
diff --git a/lcci/01.01.Is Unique/README.md b/lcci/01.01.Is Unique/README.md
index e8f0aafbf7165..013967f04e16f 100644
--- a/lcci/01.01.Is Unique/README.md
+++ b/lcci/01.01.Is Unique/README.md
@@ -19,7 +19,7 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcci/01.01.Is%20Unique/REA
示例 1:
输入: s = "leetcode"
-输出: false
+输出: false
示例 2:
@@ -56,8 +56,7 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcci/01.01.Is%20Unique/REA
class Solution:
def isUnique(self, astr: str) -> bool:
mask = 0
- for c in astr:
- i = ord(c) - ord('a')
+ for i in map(lambda c: ord(c) - ord("a"), astr):
if (mask >> i) & 1:
return False
mask |= 1 << i
diff --git a/lcci/01.01.Is Unique/README_EN.md b/lcci/01.01.Is Unique/README_EN.md
index 86501a1e6e8e5..a63cf58656329 100644
--- a/lcci/01.01.Is Unique/README_EN.md
+++ b/lcci/01.01.Is Unique/README_EN.md
@@ -64,8 +64,7 @@ The time complexity is $O(n)$, where $n$ is the length of the string. The space
class Solution:
def isUnique(self, astr: str) -> bool:
mask = 0
- for c in astr:
- i = ord(c) - ord('a')
+ for i in map(lambda c: ord(c) - ord("a"), astr):
if (mask >> i) & 1:
return False
mask |= 1 << i
diff --git a/lcci/01.01.Is Unique/Solution.py b/lcci/01.01.Is Unique/Solution.py
index 1d63247d2b3a0..06482062b2939 100644
--- a/lcci/01.01.Is Unique/Solution.py
+++ b/lcci/01.01.Is Unique/Solution.py
@@ -1,8 +1,7 @@
class Solution:
def isUnique(self, astr: str) -> bool:
mask = 0
- for c in astr:
- i = ord(c) - ord('a')
+ for i in map(lambda c: ord(c) - ord("a"), astr):
if (mask >> i) & 1:
return False
mask |= 1 << i
diff --git a/lcci/01.02.Check Permutation/README.md b/lcci/01.02.Check Permutation/README.md
index db958faa9953e..786b5c7538b57 100644
--- a/lcci/01.02.Check Permutation/README.md
+++ b/lcci/01.02.Check Permutation/README.md
@@ -93,11 +93,18 @@ class Solution {
class Solution {
public:
bool CheckPermutation(string s1, string s2) {
- if (s1.size() != s2.size()) return false;
- int cnt[26] = {0};
- for (char& c : s1) ++cnt[c - 'a'];
- for (char& c : s2)
- if (--cnt[c - 'a'] < 0) return false;
+ if (s1.size() != s2.size()) {
+ return false;
+ }
+ int cnt[26]{};
+ for (char c : s1) {
+ ++cnt[c - 'a'];
+ }
+ for (char c : s2) {
+ if (--cnt[c - 'a'] < 0) {
+ return false;
+ }
+ }
return true;
}
};
@@ -115,8 +122,7 @@ func CheckPermutation(s1 string, s2 string) bool {
cnt[c-'a']++
}
for _, c := range s2 {
- cnt[c-'a']--
- if cnt[c-'a'] < 0 {
+ if cnt[c-'a']--; cnt[c-'a'] < 0 {
return false
}
}
@@ -128,20 +134,18 @@ func CheckPermutation(s1 string, s2 string) bool {
```ts
function CheckPermutation(s1: string, s2: string): boolean {
- const n = s1.length;
- const m = s2.length;
- if (n !== m) {
+ if (s1.length !== s2.length) {
return false;
}
- const map = new Map();
- for (let i = 0; i < n; i++) {
- map.set(s1[i], (map.get(s1[i]) ?? 0) + 1);
- map.set(s2[i], (map.get(s2[i]) ?? 0) - 1);
+ const cnt: Record = {};
+ for (const c of s1) {
+ cnt[c] = (cnt[c] || 0) + 1;
}
- for (const v of map.values()) {
- if (v !== 0) {
+ for (const c of s2) {
+ if (!cnt[c]) {
return false;
}
+ cnt[c]--;
}
return true;
}
@@ -150,22 +154,26 @@ function CheckPermutation(s1: string, s2: string): boolean {
#### Rust
```rust
-use std::collections::HashMap;
impl Solution {
pub fn check_permutation(s1: String, s2: String) -> bool {
- let n = s1.len();
- let m = s2.len();
- if n != m {
+ if s1.len() != s2.len() {
return false;
}
- let s1 = s1.as_bytes();
- let s2 = s2.as_bytes();
- let mut map = HashMap::new();
- for i in 0..n {
- *map.entry(s1[i]).or_insert(0) += 1;
- *map.entry(s2[i]).or_insert(0) -= 1;
+
+ let mut cnt = vec![0; 26];
+ for c in s1.chars() {
+ cnt[(c as usize - 'a' as usize)] += 1;
+ }
+
+ for c in s2.chars() {
+ let index = c as usize - 'a' as usize;
+ if cnt[index] == 0 {
+ return false;
+ }
+ cnt[index] -= 1;
}
- map.values().all(|i| *i == 0)
+
+ true
}
}
```
@@ -179,19 +187,18 @@ impl Solution {
* @return {boolean}
*/
var CheckPermutation = function (s1, s2) {
- if (s1.length != s2.length) {
+ if (s1.length !== s2.length) {
return false;
}
- const cnt = new Array(26).fill(0);
- for (let i = 0; i < s1.length; ++i) {
- const j = s1.codePointAt(i) - 'a'.codePointAt(0);
- ++cnt[j];
+ const cnt = {};
+ for (const c of s1) {
+ cnt[c] = (cnt[c] || 0) + 1;
}
- for (let i = 0; i < s2.length; ++i) {
- const j = s2.codePointAt(i) - 'a'.codePointAt(0);
- if (--cnt[j] < 0) {
+ for (const c of s2) {
+ if (!cnt[c]) {
return false;
}
+ cnt[c]--;
}
return true;
};
@@ -206,19 +213,18 @@ class Solution {
return false
}
- var cnt = Array(repeating: 0, count: 26)
+ var cnt = [Int](repeating: 0, count: 26)
for char in s1 {
- let index = Int(char.asciiValue! - Character("a").asciiValue!)
- cnt[index] += 1
+ cnt[Int(char.asciiValue! - Character("a").asciiValue!)] += 1
}
for char in s2 {
let index = Int(char.asciiValue! - Character("a").asciiValue!)
- cnt[index] -= 1
- if cnt[index] < 0 {
+ if cnt[index] == 0 {
return false
}
+ cnt[index] -= 1
}
return true
@@ -268,8 +274,8 @@ class Solution {
class Solution {
public:
bool CheckPermutation(string s1, string s2) {
- sort(s1.begin(), s1.end());
- sort(s2.begin(), s2.end());
+ ranges::sort(s1);
+ ranges::sort(s2);
return s1 == s2;
}
};
@@ -308,6 +314,31 @@ impl Solution {
}
```
+#### JavaScript
+
+```js
+/**
+ * @param {string} s1
+ * @param {string} s2
+ * @return {boolean}
+ */
+var CheckPermutation = function (s1, s2) {
+ return [...s1].sort().join('') === [...s2].sort().join('');
+};
+```
+
+#### Swift
+
+```swift
+class Solution {
+ func CheckPermutation(_ s1: String, _ s2: String) -> Bool {
+ let s1 = s1.sorted()
+ let s2 = s2.sorted()
+ return s1 == s2
+ }
+}
+```
+
diff --git a/lcci/01.02.Check Permutation/README_EN.md b/lcci/01.02.Check Permutation/README_EN.md
index c18cd58477e8d..c582f9a548145 100644
--- a/lcci/01.02.Check Permutation/README_EN.md
+++ b/lcci/01.02.Check Permutation/README_EN.md
@@ -100,11 +100,18 @@ class Solution {
class Solution {
public:
bool CheckPermutation(string s1, string s2) {
- if (s1.size() != s2.size()) return false;
- int cnt[26] = {0};
- for (char& c : s1) ++cnt[c - 'a'];
- for (char& c : s2)
- if (--cnt[c - 'a'] < 0) return false;
+ if (s1.size() != s2.size()) {
+ return false;
+ }
+ int cnt[26]{};
+ for (char c : s1) {
+ ++cnt[c - 'a'];
+ }
+ for (char c : s2) {
+ if (--cnt[c - 'a'] < 0) {
+ return false;
+ }
+ }
return true;
}
};
@@ -122,8 +129,7 @@ func CheckPermutation(s1 string, s2 string) bool {
cnt[c-'a']++
}
for _, c := range s2 {
- cnt[c-'a']--
- if cnt[c-'a'] < 0 {
+ if cnt[c-'a']--; cnt[c-'a'] < 0 {
return false
}
}
@@ -135,20 +141,18 @@ func CheckPermutation(s1 string, s2 string) bool {
```ts
function CheckPermutation(s1: string, s2: string): boolean {
- const n = s1.length;
- const m = s2.length;
- if (n !== m) {
+ if (s1.length !== s2.length) {
return false;
}
- const map = new Map();
- for (let i = 0; i < n; i++) {
- map.set(s1[i], (map.get(s1[i]) ?? 0) + 1);
- map.set(s2[i], (map.get(s2[i]) ?? 0) - 1);
+ const cnt: Record = {};
+ for (const c of s1) {
+ cnt[c] = (cnt[c] || 0) + 1;
}
- for (const v of map.values()) {
- if (v !== 0) {
+ for (const c of s2) {
+ if (!cnt[c]) {
return false;
}
+ cnt[c]--;
}
return true;
}
@@ -157,22 +161,26 @@ function CheckPermutation(s1: string, s2: string): boolean {
#### Rust
```rust
-use std::collections::HashMap;
impl Solution {
pub fn check_permutation(s1: String, s2: String) -> bool {
- let n = s1.len();
- let m = s2.len();
- if n != m {
+ if s1.len() != s2.len() {
return false;
}
- let s1 = s1.as_bytes();
- let s2 = s2.as_bytes();
- let mut map = HashMap::new();
- for i in 0..n {
- *map.entry(s1[i]).or_insert(0) += 1;
- *map.entry(s2[i]).or_insert(0) -= 1;
+
+ let mut cnt = vec![0; 26];
+ for c in s1.chars() {
+ cnt[(c as usize - 'a' as usize)] += 1;
+ }
+
+ for c in s2.chars() {
+ let index = c as usize - 'a' as usize;
+ if cnt[index] == 0 {
+ return false;
+ }
+ cnt[index] -= 1;
}
- map.values().all(|i| *i == 0)
+
+ true
}
}
```
@@ -186,19 +194,18 @@ impl Solution {
* @return {boolean}
*/
var CheckPermutation = function (s1, s2) {
- if (s1.length != s2.length) {
+ if (s1.length !== s2.length) {
return false;
}
- const cnt = new Array(26).fill(0);
- for (let i = 0; i < s1.length; ++i) {
- const j = s1.codePointAt(i) - 'a'.codePointAt(0);
- ++cnt[j];
+ const cnt = {};
+ for (const c of s1) {
+ cnt[c] = (cnt[c] || 0) + 1;
}
- for (let i = 0; i < s2.length; ++i) {
- const j = s2.codePointAt(i) - 'a'.codePointAt(0);
- if (--cnt[j] < 0) {
+ for (const c of s2) {
+ if (!cnt[c]) {
return false;
}
+ cnt[c]--;
}
return true;
};
@@ -213,19 +220,18 @@ class Solution {
return false
}
- var cnt = Array(repeating: 0, count: 26)
+ var cnt = [Int](repeating: 0, count: 26)
for char in s1 {
- let index = Int(char.asciiValue! - Character("a").asciiValue!)
- cnt[index] += 1
+ cnt[Int(char.asciiValue! - Character("a").asciiValue!)] += 1
}
for char in s2 {
let index = Int(char.asciiValue! - Character("a").asciiValue!)
- cnt[index] -= 1
- if cnt[index] < 0 {
+ if cnt[index] == 0 {
return false
}
+ cnt[index] -= 1
}
return true
@@ -275,8 +281,8 @@ class Solution {
class Solution {
public:
bool CheckPermutation(string s1, string s2) {
- sort(s1.begin(), s1.end());
- sort(s2.begin(), s2.end());
+ ranges::sort(s1);
+ ranges::sort(s2);
return s1 == s2;
}
};
@@ -315,6 +321,31 @@ impl Solution {
}
```
+#### JavaScript
+
+```js
+/**
+ * @param {string} s1
+ * @param {string} s2
+ * @return {boolean}
+ */
+var CheckPermutation = function (s1, s2) {
+ return [...s1].sort().join('') === [...s2].sort().join('');
+};
+```
+
+#### Swift
+
+```swift
+class Solution {
+ func CheckPermutation(_ s1: String, _ s2: String) -> Bool {
+ let s1 = s1.sorted()
+ let s2 = s2.sorted()
+ return s1 == s2
+ }
+}
+```
+
diff --git a/lcci/01.02.Check Permutation/Solution.cpp b/lcci/01.02.Check Permutation/Solution.cpp
index 72808b7ee740c..ff8e6d531810c 100644
--- a/lcci/01.02.Check Permutation/Solution.cpp
+++ b/lcci/01.02.Check Permutation/Solution.cpp
@@ -1,11 +1,18 @@
class Solution {
public:
bool CheckPermutation(string s1, string s2) {
- if (s1.size() != s2.size()) return false;
- int cnt[26] = {0};
- for (char& c : s1) ++cnt[c - 'a'];
- for (char& c : s2)
- if (--cnt[c - 'a'] < 0) return false;
+ if (s1.size() != s2.size()) {
+ return false;
+ }
+ int cnt[26]{};
+ for (char c : s1) {
+ ++cnt[c - 'a'];
+ }
+ for (char c : s2) {
+ if (--cnt[c - 'a'] < 0) {
+ return false;
+ }
+ }
return true;
}
-};
\ No newline at end of file
+};
diff --git a/lcci/01.02.Check Permutation/Solution.go b/lcci/01.02.Check Permutation/Solution.go
index 7acd2c2c4bc00..e8fd1ace061de 100644
--- a/lcci/01.02.Check Permutation/Solution.go
+++ b/lcci/01.02.Check Permutation/Solution.go
@@ -7,10 +7,9 @@ func CheckPermutation(s1 string, s2 string) bool {
cnt[c-'a']++
}
for _, c := range s2 {
- cnt[c-'a']--
- if cnt[c-'a'] < 0 {
+ if cnt[c-'a']--; cnt[c-'a'] < 0 {
return false
}
}
return true
-}
\ No newline at end of file
+}
diff --git a/lcci/01.02.Check Permutation/Solution.js b/lcci/01.02.Check Permutation/Solution.js
index 4c0adedaf125b..7aa0ea9b1d428 100644
--- a/lcci/01.02.Check Permutation/Solution.js
+++ b/lcci/01.02.Check Permutation/Solution.js
@@ -4,19 +4,18 @@
* @return {boolean}
*/
var CheckPermutation = function (s1, s2) {
- if (s1.length != s2.length) {
+ if (s1.length !== s2.length) {
return false;
}
- const cnt = new Array(26).fill(0);
- for (let i = 0; i < s1.length; ++i) {
- const j = s1.codePointAt(i) - 'a'.codePointAt(0);
- ++cnt[j];
+ const cnt = {};
+ for (const c of s1) {
+ cnt[c] = (cnt[c] || 0) + 1;
}
- for (let i = 0; i < s2.length; ++i) {
- const j = s2.codePointAt(i) - 'a'.codePointAt(0);
- if (--cnt[j] < 0) {
+ for (const c of s2) {
+ if (!cnt[c]) {
return false;
}
+ cnt[c]--;
}
return true;
};
diff --git a/lcci/01.02.Check Permutation/Solution.rs b/lcci/01.02.Check Permutation/Solution.rs
index efe963a0130f2..45cda06875452 100644
--- a/lcci/01.02.Check Permutation/Solution.rs
+++ b/lcci/01.02.Check Permutation/Solution.rs
@@ -1,18 +1,22 @@
-use std::collections::HashMap;
impl Solution {
pub fn check_permutation(s1: String, s2: String) -> bool {
- let n = s1.len();
- let m = s2.len();
- if n != m {
+ if s1.len() != s2.len() {
return false;
}
- let s1 = s1.as_bytes();
- let s2 = s2.as_bytes();
- let mut map = HashMap::new();
- for i in 0..n {
- *map.entry(s1[i]).or_insert(0) += 1;
- *map.entry(s2[i]).or_insert(0) -= 1;
+
+ let mut cnt = vec![0; 26];
+ for c in s1.chars() {
+ cnt[(c as usize - 'a' as usize)] += 1;
}
- map.values().all(|i| *i == 0)
+
+ for c in s2.chars() {
+ let index = c as usize - 'a' as usize;
+ if cnt[index] == 0 {
+ return false;
+ }
+ cnt[index] -= 1;
+ }
+
+ true
}
}
diff --git a/lcci/01.02.Check Permutation/Solution.swift b/lcci/01.02.Check Permutation/Solution.swift
index 7161edfad155c..6bfd2af7416a5 100644
--- a/lcci/01.02.Check Permutation/Solution.swift
+++ b/lcci/01.02.Check Permutation/Solution.swift
@@ -3,22 +3,21 @@ class Solution {
if s1.count != s2.count {
return false
}
-
- var cnt = Array(repeating: 0, count: 26)
-
+
+ var cnt = [Int](repeating: 0, count: 26)
+
for char in s1 {
- let index = Int(char.asciiValue! - Character("a").asciiValue!)
- cnt[index] += 1
+ cnt[Int(char.asciiValue! - Character("a").asciiValue!)] += 1
}
-
+
for char in s2 {
let index = Int(char.asciiValue! - Character("a").asciiValue!)
- cnt[index] -= 1
- if cnt[index] < 0 {
+ if cnt[index] == 0 {
return false
}
+ cnt[index] -= 1
}
-
+
return true
}
-}
\ No newline at end of file
+}
diff --git a/lcci/01.02.Check Permutation/Solution.ts b/lcci/01.02.Check Permutation/Solution.ts
index 65f0c434d61b9..b6bb1f8822cec 100644
--- a/lcci/01.02.Check Permutation/Solution.ts
+++ b/lcci/01.02.Check Permutation/Solution.ts
@@ -1,18 +1,16 @@
function CheckPermutation(s1: string, s2: string): boolean {
- const n = s1.length;
- const m = s2.length;
- if (n !== m) {
+ if (s1.length !== s2.length) {
return false;
}
- const map = new Map();
- for (let i = 0; i < n; i++) {
- map.set(s1[i], (map.get(s1[i]) ?? 0) + 1);
- map.set(s2[i], (map.get(s2[i]) ?? 0) - 1);
+ const cnt: Record = {};
+ for (const c of s1) {
+ cnt[c] = (cnt[c] || 0) + 1;
}
- for (const v of map.values()) {
- if (v !== 0) {
+ for (const c of s2) {
+ if (!cnt[c]) {
return false;
}
+ cnt[c]--;
}
return true;
}
diff --git a/lcci/01.02.Check Permutation/Solution2.cpp b/lcci/01.02.Check Permutation/Solution2.cpp
index 70c67c68db593..142e3154d5a17 100644
--- a/lcci/01.02.Check Permutation/Solution2.cpp
+++ b/lcci/01.02.Check Permutation/Solution2.cpp
@@ -1,8 +1,8 @@
class Solution {
public:
bool CheckPermutation(string s1, string s2) {
- sort(s1.begin(), s1.end());
- sort(s2.begin(), s2.end());
+ ranges::sort(s1);
+ ranges::sort(s2);
return s1 == s2;
}
-};
\ No newline at end of file
+};
diff --git a/lcci/01.02.Check Permutation/Solution2.js b/lcci/01.02.Check Permutation/Solution2.js
new file mode 100644
index 0000000000000..a5d33c913da3a
--- /dev/null
+++ b/lcci/01.02.Check Permutation/Solution2.js
@@ -0,0 +1,8 @@
+/**
+ * @param {string} s1
+ * @param {string} s2
+ * @return {boolean}
+ */
+var CheckPermutation = function (s1, s2) {
+ return [...s1].sort().join('') === [...s2].sort().join('');
+};
diff --git a/lcci/01.02.Check Permutation/Solution2.swift b/lcci/01.02.Check Permutation/Solution2.swift
new file mode 100644
index 0000000000000..0aef38caddbb4
--- /dev/null
+++ b/lcci/01.02.Check Permutation/Solution2.swift
@@ -0,0 +1,7 @@
+class Solution {
+ func CheckPermutation(_ s1: String, _ s2: String) -> Bool {
+ let s1 = s1.sorted()
+ let s2 = s2.sorted()
+ return s1 == s2
+ }
+}
diff --git a/lcci/01.04.Palindrome Permutation/README.md b/lcci/01.04.Palindrome Permutation/README.md
index 689ccb5841266..b174846e8cd30 100644
--- a/lcci/01.04.Palindrome Permutation/README.md
+++ b/lcci/01.04.Palindrome Permutation/README.md
@@ -94,18 +94,15 @@ public:
```go
func canPermutePalindrome(s string) bool {
- vis := map[rune]bool{}
- cnt := 0
+ cnt := map[rune]int{}
for _, c := range s {
- if vis[c] {
- vis[c] = false
- cnt--
- } else {
- vis[c] = true
- cnt++
- }
+ cnt[c]++
}
- return cnt < 2
+ sum := 0
+ for _, v := range cnt {
+ sum += v & 1
+ }
+ return sum < 2
}
```
@@ -113,34 +110,26 @@ func canPermutePalindrome(s string) bool {
```ts
function canPermutePalindrome(s: string): boolean {
- const set = new Set();
+ const cnt: Record = {};
for (const c of s) {
- if (set.has(c)) {
- set.delete(c);
- } else {
- set.add(c);
- }
+ cnt[c] = (cnt[c] || 0) + 1;
}
- return set.size <= 1;
+ return Object.values(cnt).filter(v => v % 2 === 1).length < 2;
}
```
#### Rust
```rust
-use std::collections::HashSet;
+use std::collections::HashMap;
impl Solution {
pub fn can_permute_palindrome(s: String) -> bool {
- let mut set = HashSet::new();
+ let mut cnt = HashMap::new();
for c in s.chars() {
- if set.contains(&c) {
- set.remove(&c);
- } else {
- set.insert(c);
- }
+ *cnt.entry(c).or_insert(0) += 1;
}
- set.len() <= 1
+ cnt.values().filter(|&&v| v % 2 == 1).count() < 2
}
}
```
@@ -173,7 +162,7 @@ class Solution {
### 方法二:哈希表的另一种实现
-我们用哈希表 $vis$ 存储每个字符是否出现过。若出现过,则从哈希表中删除该字符;否则,将该字符加入哈希表。
+我们用一个哈希表 $\textit{vis}$ 存储每个字符是否出现过。若出现过,则从哈希表中删除该字符;否则,将该字符加入哈希表。
最后判断哈希表中字符的个数是否小于 $2$,若是,则是回文排列。
@@ -231,6 +220,76 @@ public:
};
```
+#### Go
+
+```go
+func canPermutePalindrome(s string) bool {
+ vis := map[rune]bool{}
+ for _, c := range s {
+ if vis[c] {
+ delete(vis, c)
+ } else {
+ vis[c] = true
+ }
+ }
+ return len(vis) < 2
+}
+```
+
+#### TypeScript
+
+```ts
+function canPermutePalindrome(s: string): boolean {
+ const vis = new Set();
+ for (const c of s) {
+ if (vis.has(c)) {
+ vis.delete(c);
+ } else {
+ vis.add(c);
+ }
+ }
+ return vis.size < 2;
+}
+```
+
+#### Rust
+
+```rust
+use std::collections::HashSet;
+
+impl Solution {
+ pub fn can_permute_palindrome(s: String) -> bool {
+ let mut vis = HashSet::new();
+ for c in s.chars() {
+ if vis.contains(&c) {
+ vis.remove(&c);
+ } else {
+ vis.insert(c);
+ }
+ }
+ vis.len() < 2
+ }
+}
+```
+
+#### Swift
+
+```swift
+class Solution {
+ func canPermutePalindrome(_ s: String) -> Bool {
+ var vis = Set()
+ for c in s {
+ if vis.contains(c) {
+ vis.remove(c)
+ } else {
+ vis.insert(c)
+ }
+ }
+ return vis.count < 2
+ }
+}
+```
+
diff --git a/lcci/01.04.Palindrome Permutation/README_EN.md b/lcci/01.04.Palindrome Permutation/README_EN.md
index e942aadc8b522..28d7e6c7c4c02 100644
--- a/lcci/01.04.Palindrome Permutation/README_EN.md
+++ b/lcci/01.04.Palindrome Permutation/README_EN.md
@@ -92,18 +92,15 @@ public:
```go
func canPermutePalindrome(s string) bool {
- vis := map[rune]bool{}
- cnt := 0
+ cnt := map[rune]int{}
for _, c := range s {
- if vis[c] {
- vis[c] = false
- cnt--
- } else {
- vis[c] = true
- cnt++
- }
+ cnt[c]++
}
- return cnt < 2
+ sum := 0
+ for _, v := range cnt {
+ sum += v & 1
+ }
+ return sum < 2
}
```
@@ -111,34 +108,26 @@ func canPermutePalindrome(s string) bool {
```ts
function canPermutePalindrome(s: string): boolean {
- const set = new Set();
+ const cnt: Record = {};
for (const c of s) {
- if (set.has(c)) {
- set.delete(c);
- } else {
- set.add(c);
- }
+ cnt[c] = (cnt[c] || 0) + 1;
}
- return set.size <= 1;
+ return Object.values(cnt).filter(v => v % 2 === 1).length < 2;
}
```
#### Rust
```rust
-use std::collections::HashSet;
+use std::collections::HashMap;
impl Solution {
pub fn can_permute_palindrome(s: String) -> bool {
- let mut set = HashSet::new();
+ let mut cnt = HashMap::new();
for c in s.chars() {
- if set.contains(&c) {
- set.remove(&c);
- } else {
- set.insert(c);
- }
+ *cnt.entry(c).or_insert(0) += 1;
}
- set.len() <= 1
+ cnt.values().filter(|&&v| v % 2 == 1).count() < 2
}
}
```
@@ -229,6 +218,76 @@ public:
};
```
+#### Go
+
+```go
+func canPermutePalindrome(s string) bool {
+ vis := map[rune]bool{}
+ for _, c := range s {
+ if vis[c] {
+ delete(vis, c)
+ } else {
+ vis[c] = true
+ }
+ }
+ return len(vis) < 2
+}
+```
+
+#### TypeScript
+
+```ts
+function canPermutePalindrome(s: string): boolean {
+ const vis = new Set();
+ for (const c of s) {
+ if (vis.has(c)) {
+ vis.delete(c);
+ } else {
+ vis.add(c);
+ }
+ }
+ return vis.size < 2;
+}
+```
+
+#### Rust
+
+```rust
+use std::collections::HashSet;
+
+impl Solution {
+ pub fn can_permute_palindrome(s: String) -> bool {
+ let mut vis = HashSet::new();
+ for c in s.chars() {
+ if vis.contains(&c) {
+ vis.remove(&c);
+ } else {
+ vis.insert(c);
+ }
+ }
+ vis.len() < 2
+ }
+}
+```
+
+#### Swift
+
+```swift
+class Solution {
+ func canPermutePalindrome(_ s: String) -> Bool {
+ var vis = Set()
+ for c in s {
+ if vis.contains(c) {
+ vis.remove(c)
+ } else {
+ vis.insert(c)
+ }
+ }
+ return vis.count < 2
+ }
+}
+```
+
diff --git a/lcci/01.04.Palindrome Permutation/Solution.go b/lcci/01.04.Palindrome Permutation/Solution.go
index 5d156fd33340e..76d5c69a60a52 100644
--- a/lcci/01.04.Palindrome Permutation/Solution.go
+++ b/lcci/01.04.Palindrome Permutation/Solution.go
@@ -1,14 +1,11 @@
-func canPermutePalindrome(s string) bool {
- vis := map[rune]bool{}
- cnt := 0
- for _, c := range s {
- if vis[c] {
- vis[c] = false
- cnt--
- } else {
- vis[c] = true
- cnt++
- }
- }
- return cnt < 2
-}
\ No newline at end of file
+func canPermutePalindrome(s string) bool {
+ cnt := map[rune]int{}
+ for _, c := range s {
+ cnt[c]++
+ }
+ sum := 0
+ for _, v := range cnt {
+ sum += v & 1
+ }
+ return sum < 2
+}
diff --git a/lcci/01.04.Palindrome Permutation/Solution.rs b/lcci/01.04.Palindrome Permutation/Solution.rs
index 0d0e1b07a5e70..895e119d6b604 100644
--- a/lcci/01.04.Palindrome Permutation/Solution.rs
+++ b/lcci/01.04.Palindrome Permutation/Solution.rs
@@ -1,15 +1,11 @@
-use std::collections::HashSet;
+use std::collections::HashMap;
impl Solution {
pub fn can_permute_palindrome(s: String) -> bool {
- let mut set = HashSet::new();
+ let mut cnt = HashMap::new();
for c in s.chars() {
- if set.contains(&c) {
- set.remove(&c);
- } else {
- set.insert(c);
- }
+ *cnt.entry(c).or_insert(0) += 1;
}
- set.len() <= 1
+ cnt.values().filter(|&&v| v % 2 == 1).count() < 2
}
}
diff --git a/lcci/01.04.Palindrome Permutation/Solution.ts b/lcci/01.04.Palindrome Permutation/Solution.ts
index 7bd7505057358..44ba2bc906e83 100644
--- a/lcci/01.04.Palindrome Permutation/Solution.ts
+++ b/lcci/01.04.Palindrome Permutation/Solution.ts
@@ -1,11 +1,7 @@
function canPermutePalindrome(s: string): boolean {
- const set = new Set();
+ const cnt: Record = {};
for (const c of s) {
- if (set.has(c)) {
- set.delete(c);
- } else {
- set.add(c);
- }
+ cnt[c] = (cnt[c] || 0) + 1;
}
- return set.size <= 1;
+ return Object.values(cnt).filter(v => v % 2 === 1).length < 2;
}
diff --git a/lcci/01.04.Palindrome Permutation/Solution2.go b/lcci/01.04.Palindrome Permutation/Solution2.go
new file mode 100644
index 0000000000000..425935647c9f4
--- /dev/null
+++ b/lcci/01.04.Palindrome Permutation/Solution2.go
@@ -0,0 +1,11 @@
+func canPermutePalindrome(s string) bool {
+ vis := map[rune]bool{}
+ for _, c := range s {
+ if vis[c] {
+ delete(vis, c)
+ } else {
+ vis[c] = true
+ }
+ }
+ return len(vis) < 2
+}
diff --git a/lcci/01.04.Palindrome Permutation/Solution2.rs b/lcci/01.04.Palindrome Permutation/Solution2.rs
new file mode 100644
index 0000000000000..5ef83e50f0c4d
--- /dev/null
+++ b/lcci/01.04.Palindrome Permutation/Solution2.rs
@@ -0,0 +1,15 @@
+use std::collections::HashSet;
+
+impl Solution {
+ pub fn can_permute_palindrome(s: String) -> bool {
+ let mut vis = HashSet::new();
+ for c in s.chars() {
+ if vis.contains(&c) {
+ vis.remove(&c);
+ } else {
+ vis.insert(c);
+ }
+ }
+ vis.len() < 2
+ }
+}
diff --git a/lcci/01.04.Palindrome Permutation/Solution2.swift b/lcci/01.04.Palindrome Permutation/Solution2.swift
new file mode 100644
index 0000000000000..993dc395a5b33
--- /dev/null
+++ b/lcci/01.04.Palindrome Permutation/Solution2.swift
@@ -0,0 +1,13 @@
+class Solution {
+ func canPermutePalindrome(_ s: String) -> Bool {
+ var vis = Set()
+ for c in s {
+ if vis.contains(c) {
+ vis.remove(c)
+ } else {
+ vis.insert(c)
+ }
+ }
+ return vis.count < 2
+ }
+}
diff --git a/lcci/01.04.Palindrome Permutation/Solution2.ts b/lcci/01.04.Palindrome Permutation/Solution2.ts
new file mode 100644
index 0000000000000..c72db04c15438
--- /dev/null
+++ b/lcci/01.04.Palindrome Permutation/Solution2.ts
@@ -0,0 +1,11 @@
+function canPermutePalindrome(s: string): boolean {
+ const vis = new Set();
+ for (const c of s) {
+ if (vis.has(c)) {
+ vis.delete(c);
+ } else {
+ vis.add(c);
+ }
+ }
+ return vis.size < 2;
+}
diff --git a/lcci/01.05.One Away/README.md b/lcci/01.05.One Away/README.md
index 471c6c5f9190c..762e58c78330d 100644
--- a/lcci/01.05.One Away/README.md
+++ b/lcci/01.05.One Away/README.md
@@ -43,13 +43,13 @@ second = "pal"
### 方法一:分情况讨论 + 双指针
-我们将字符串 $first$ 和 $second$ 的长度记为 $m$ 和 $n$,不妨设 $m \geq n$。
+我们将字符串 $\textit{first}$ 和 $\textit{second}$ 的长度记为 $m$ 和 $n$,不妨设 $m \geq n$。
接下来分情况讨论:
-- 当 $m - n \gt 1$ 时,$first$ 和 $second$ 无法通过一次编辑得到,返回 `false`;
-- 当 $m = n$ 时,$first$ 和 $second$ 只有在且仅在有且仅有一个字符不同的情况下才能通过一次编辑得到;
-- 当 $m - n = 1$ 时,$first$ 和 $second$ 只有在且仅在 $second$ 是 $first$ 删除一个字符后得到的情况下才能通过一次编辑得到,我们可以使用双指针来实现。
+- 当 $m - n \gt 1$ 时,$\textit{first}$ 和 $\textit{second}$ 无法通过一次编辑得到,返回 `false`;
+- 当 $m = n$ 时,$\textit{first}$ 和 $\textit{second}$ 只有在且仅在有且仅有一个字符不同的情况下才能通过一次编辑得到;
+- 当 $m - n = 1$ 时,$\textit{first}$ 和 $\textit{second}$ 只有在且仅在 $\textit{second}$ 是 $\textit{first}$ 删除一个字符后得到的情况下才能通过一次编辑得到,我们可以使用双指针来实现。
时间复杂度 $O(n)$,其中 $n$ 为字符串长度。空间复杂度 $O(1)$。
diff --git a/lcci/01.05.One Away/README_EN.md b/lcci/01.05.One Away/README_EN.md
index a0703be7fa38b..98a164c97d143 100644
--- a/lcci/01.05.One Away/README_EN.md
+++ b/lcci/01.05.One Away/README_EN.md
@@ -50,15 +50,15 @@ second = "pal"
-### Solution 1: Case Discussion + Two Pointers
+### Solution 1: Case Analysis + Two Pointers
-We denote the lengths of strings $first$ and $second$ as $m$ and $n$, respectively, where $m \geq n$.
+Let the lengths of the strings $\textit{first}$ and $\textit{second}$ be $m$ and $n$, respectively. Assume $m \geq n$.
-Next, we discuss different cases:
+Next, we discuss the following cases:
-- When $m - n > 1$, $first$ and $second$ cannot be obtained through a single edit, so we return `false`.
-- When $m = n$, $first$ and $second$ can only be obtained through a single edit if and only if exactly one character is different.
-- When $m - n = 1$, $first$ and $second$ can only be obtained through a single edit if and only if $second$ is obtained by deleting one character from $first$. We can use two pointers to implement this.
+- When $m - n \gt 1$, $\textit{first}$ and $\textit{second}$ cannot be made equal with one edit, so return `false`;
+- When $m = n$, $\textit{first}$ and $\textit{second}$ can be made equal with one edit only if there is exactly one different character;
+- When $m - n = 1$, $\textit{first}$ and $\textit{second}$ can be made equal with one edit only if $\textit{second}$ is obtained by deleting one character from $\textit{first}$. We can use two pointers to achieve this.
The time complexity is $O(n)$, where $n$ is the length of the string. The space complexity is $O(1)$.
diff --git a/lcci/01.06.Compress String/README.md b/lcci/01.06.Compress String/README.md
index 829eb7d532a86..2a08b263e8ae5 100644
--- a/lcci/01.06.Compress String/README.md
+++ b/lcci/01.06.Compress String/README.md
@@ -62,22 +62,6 @@ class Solution:
return min(S, t, key=len)
```
-#### Python3
-
-```python
-class Solution:
- def compressString(self, S: str) -> str:
- t = []
- i, n = 0, len(S)
- while i < n:
- j = i + 1
- while j < n and S[j] == S[i]:
- j += 1
- t.append(S[i] + str(j - i))
- i = j
- return min(S, "".join(t), key=len)
-```
-
#### Java
```java
diff --git a/lcci/01.06.Compress String/README_EN.md b/lcci/01.06.Compress String/README_EN.md
index 10346e225a81c..e1a9f55e5b8a0 100644
--- a/lcci/01.06.Compress String/README_EN.md
+++ b/lcci/01.06.Compress String/README_EN.md
@@ -69,22 +69,6 @@ class Solution:
return min(S, t, key=len)
```
-#### Python3
-
-```python
-class Solution:
- def compressString(self, S: str) -> str:
- t = []
- i, n = 0, len(S)
- while i < n:
- j = i + 1
- while j < n and S[j] == S[i]:
- j += 1
- t.append(S[i] + str(j - i))
- i = j
- return min(S, "".join(t), key=len)
-```
-
#### Java
```java
diff --git a/lcci/01.06.Compress String/Solution2.py b/lcci/01.06.Compress String/Solution2.py
deleted file mode 100644
index d3bc1c1aab18d..0000000000000
--- a/lcci/01.06.Compress String/Solution2.py
+++ /dev/null
@@ -1,11 +0,0 @@
-class Solution:
- def compressString(self, S: str) -> str:
- t = []
- i, n = 0, len(S)
- while i < n:
- j = i + 1
- while j < n and S[j] == S[i]:
- j += 1
- t.append(S[i] + str(j - i))
- i = j
- return min(S, "".join(t), key=len)
diff --git a/lcci/01.07.Rotate Matrix/README.md b/lcci/01.07.Rotate Matrix/README.md
index 2d6b196c90198..d9b2763c2a520 100644
--- a/lcci/01.07.Rotate Matrix/README.md
+++ b/lcci/01.07.Rotate Matrix/README.md
@@ -64,9 +64,9 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcci/01.07.Rotate%20Matrix
### 方法一:原地翻转
-根据题目要求,我们实际上需要将 $matrix[i][j]$ 旋转至 $matrix[j][n - i - 1]$。
+根据题目要求,我们实际上需要将 $\text{matrix}[i][j]$ 旋转至 $\text{matrix}[j][n - i - 1]$。
-我们可以先对矩阵进行上下翻转,即 $matrix[i][j]$ 和 $matrix[n - i - 1][j]$ 进行交换,然后再对矩阵进行主对角线翻转,即 $matrix[i][j]$ 和 $matrix[j][i]$ 进行交换。这样就能将 $matrix[i][j]$ 旋转至 $matrix[j][n - i - 1]$ 了。
+我们可以先对矩阵进行上下翻转,即 $\text{matrix}[i][j]$ 和 $\text{matrix}[n - i - 1][j]$ 进行交换,然后再对矩阵进行主对角线翻转,即 $\text{matrix}[i][j]$ 和 $\text{matrix}[j][i]$ 进行交换。这样就能将 $\text{matrix}[i][j]$ 旋转至 $\text{matrix}[j][n - i - 1]$ 了。
时间复杂度 $O(n^2)$,其中 $n$ 是矩阵的边长。空间复杂度 $O(1)$。
diff --git a/lcci/01.07.Rotate Matrix/README_EN.md b/lcci/01.07.Rotate Matrix/README_EN.md
index f093f2a013175..8a1f0badd0a68 100644
--- a/lcci/01.07.Rotate Matrix/README_EN.md
+++ b/lcci/01.07.Rotate Matrix/README_EN.md
@@ -92,11 +92,11 @@ Rotate the matrix in place. It becomes:
-### Solution 1: In-place Rotation
+### Solution 1: In-Place Rotation
-According to the problem requirements, we actually need to rotate $matrix[i][j]$ to $matrix[j][n - i - 1]$.
+According to the problem requirements, we need to rotate $\text{matrix}[i][j]$ to $\text{matrix}[j][n - i - 1]$.
-We can first flip the matrix upside down, that is, swap $matrix[i][j]$ and $matrix[n - i - 1][j]$, and then flip the matrix along the main diagonal, that is, swap $matrix[i][j]$ and $matrix[j][i]$. This way, we can rotate $matrix[i][j]$ to $matrix[j][n - i - 1]$.
+We can first flip the matrix upside down, i.e., swap $\text{matrix}[i][j]$ with $\text{matrix}[n - i - 1][j]$, and then flip the matrix along the main diagonal, i.e., swap $\text{matrix}[i][j]$ with $\text{matrix}[j][i]$. This will rotate $\text{matrix}[i][j]$ to $\text{matrix}[j][n - i - 1]$.
The time complexity is $O(n^2)$, where $n$ is the side length of the matrix. The space complexity is $O(1)$.
diff --git a/lcci/02.08.Linked List Cycle/README.md b/lcci/02.08.Linked List Cycle/README.md
index 37fbe9f8e76a7..facce4bf87406 100644
--- a/lcci/02.08.Linked List Cycle/README.md
+++ b/lcci/02.08.Linked List Cycle/README.md
@@ -44,6 +44,8 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcci/02.08.Linked%20List%2
+#### Python3
+
```python
# Definition for singly-linked list.
# class ListNode:
@@ -66,6 +68,8 @@ class Solution:
return ans
```
+#### Java
+
```java
/**
* Definition for singly-linked list.
@@ -98,6 +102,8 @@ public class Solution {
}
```
+#### C++
+
```cpp
/**
* Definition for singly-linked list.
@@ -129,6 +135,8 @@ public:
};
```
+#### Go
+
```go
/**
* Definition for singly-linked list.
@@ -155,6 +163,8 @@ func detectCycle(head *ListNode) *ListNode {
}
```
+#### TypeScript
+
```ts
/**
* Definition for singly-linked list.
@@ -186,6 +196,8 @@ function detectCycle(head: ListNode | null): ListNode | null {
}
```
+#### JavaScript
+
```js
/**
* Definition for singly-linked list.
@@ -217,6 +229,8 @@ var detectCycle = function (head) {
};
```
+#### Swift
+
```swift
/*
* public class ListNode {
@@ -251,4 +265,8 @@ class Solution {
}
```
+
+
+
+
diff --git a/lcci/04.08.First Common Ancestor/README.md b/lcci/04.08.First Common Ancestor/README.md
index d7a9fb878e8e4..c51706d069e79 100644
--- a/lcci/04.08.First Common Ancestor/README.md
+++ b/lcci/04.08.First Common Ancestor/README.md
@@ -22,7 +22,13 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcci/04.08.First%20Common%
-### 方法一
+### 方法一:递归
+
+我们首先判断根节点是否为空,或者根节点是否等于 $\textit{p}$ 或 $\textit{q}$,如果是的话,直接返回根节点。
+
+然后递归地对左右子树进行查找,分别得到 $\textit{left}$ 和 $\textit{right}$。如果 $\textit{left}$ 和 $\textit{right}$ 都不为空,说明 $\textit{p}$ 和 $\textit{q}$ 分别在左右子树中,那么根节点就是最近公共祖先。否则,如果 $\textit{left}$ 和 $\textit{right}$ 中有一个为空,说明 $\textit{p}$ 和 $\textit{q}$ 都在非空的子树中,那么非空的子树的根节点就是最近公共祖先。
+
+时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是二叉树中节点的数目。
@@ -41,11 +47,11 @@ class Solution:
def lowestCommonAncestor(
self, root: TreeNode, p: TreeNode, q: TreeNode
) -> TreeNode:
- if root is None or root == p or root == q:
+ if root is None or root in [p, q]:
return root
left = self.lowestCommonAncestor(root.left, p, q)
right = self.lowestCommonAncestor(root.right, p, q)
- return right if left is None else (left if right is None else root)
+ return root if left and right else left or right
```
#### Java
@@ -72,6 +78,84 @@ class Solution {
}
```
+#### C++
+
+```cpp
+/**
+ * Definition for a binary tree node.
+ * struct TreeNode {
+ * int val;
+ * TreeNode *left;
+ * TreeNode *right;
+ * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
+ * };
+ */
+class Solution {
+public:
+ TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
+ if (!root || root == p || root == q) {
+ return root;
+ }
+ TreeNode* left = lowestCommonAncestor(root->left, p, q);
+ TreeNode* right = lowestCommonAncestor(root->right, p, q);
+ return left && right ? root : (left ? left : right);
+ }
+};
+```
+
+#### Go
+
+```go
+/**
+ * Definition for a binary tree node.
+ * type TreeNode struct {
+ * Val int
+ * Left *TreeNode
+ * Right *TreeNode
+ * }
+ */
+func lowestCommonAncestor(root *TreeNode, p *TreeNode, q *TreeNode) *TreeNode {
+ if root == nil || root == p || root == q {
+ return root
+ }
+ left := lowestCommonAncestor(root.Left, p, q)
+ right := lowestCommonAncestor(root.Right, p, q)
+ if left == nil {
+ return right
+ }
+ if right == nil {
+ return left
+ }
+ return root
+}
+```
+
+#### JavaScript
+
+```js
+/**
+ * Definition for a binary tree node.
+ * function TreeNode(val) {
+ * this.val = val;
+ * this.left = this.right = null;
+ * }
+ */
+/**
+ * @param {TreeNode} root
+ * @param {TreeNode} p
+ * @param {TreeNode} q
+ * @return {TreeNode}
+ */
+var lowestCommonAncestor = function (root, p, q) {
+ if (!root || root === p || root === q) {
+ return root;
+ }
+ const left = lowestCommonAncestor(root.left, p, q);
+ const right = lowestCommonAncestor(root.right, p, q);
+ return left && right ? root : left || right;
+};
+```
+
#### Swift
```swift
diff --git a/lcci/04.08.First Common Ancestor/README_EN.md b/lcci/04.08.First Common Ancestor/README_EN.md
index 8df95cc286a11..e500060c3e04c 100644
--- a/lcci/04.08.First Common Ancestor/README_EN.md
+++ b/lcci/04.08.First Common Ancestor/README_EN.md
@@ -69,7 +69,13 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcci/04.08.First%20Common%
-### Solution 1
+### Solution 1: Recursion
+
+First, we check if the root node is null or if the root node is equal to $\textit{p}$ or $\textit{q}$. If so, we return the root node directly.
+
+Then, we recursively search the left and right subtrees to get $\textit{left}$ and $\textit{right}$, respectively. If both $\textit{left}$ and $\textit{right}$ are not null, it means $\textit{p}$ and $\textit{q}$ are in the left and right subtrees, respectively, so the root node is the lowest common ancestor. Otherwise, if either $\textit{left}$ or $\textit{right}$ is null, it means both $\textit{p}$ and $\textit{q}$ are in the non-null subtree, so the root node of the non-null subtree is the lowest common ancestor.
+
+The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the number of nodes in the binary tree.
@@ -88,11 +94,11 @@ class Solution:
def lowestCommonAncestor(
self, root: TreeNode, p: TreeNode, q: TreeNode
) -> TreeNode:
- if root is None or root == p or root == q:
+ if root is None or root in [p, q]:
return root
left = self.lowestCommonAncestor(root.left, p, q)
right = self.lowestCommonAncestor(root.right, p, q)
- return right if left is None else (left if right is None else root)
+ return root if left and right else left or right
```
#### Java
@@ -119,6 +125,84 @@ class Solution {
}
```
+#### C++
+
+```cpp
+/**
+ * Definition for a binary tree node.
+ * struct TreeNode {
+ * int val;
+ * TreeNode *left;
+ * TreeNode *right;
+ * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
+ * };
+ */
+class Solution {
+public:
+ TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
+ if (!root || root == p || root == q) {
+ return root;
+ }
+ TreeNode* left = lowestCommonAncestor(root->left, p, q);
+ TreeNode* right = lowestCommonAncestor(root->right, p, q);
+ return left && right ? root : (left ? left : right);
+ }
+};
+```
+
+#### Go
+
+```go
+/**
+ * Definition for a binary tree node.
+ * type TreeNode struct {
+ * Val int
+ * Left *TreeNode
+ * Right *TreeNode
+ * }
+ */
+func lowestCommonAncestor(root *TreeNode, p *TreeNode, q *TreeNode) *TreeNode {
+ if root == nil || root == p || root == q {
+ return root
+ }
+ left := lowestCommonAncestor(root.Left, p, q)
+ right := lowestCommonAncestor(root.Right, p, q)
+ if left == nil {
+ return right
+ }
+ if right == nil {
+ return left
+ }
+ return root
+}
+```
+
+#### JavaScript
+
+```js
+/**
+ * Definition for a binary tree node.
+ * function TreeNode(val) {
+ * this.val = val;
+ * this.left = this.right = null;
+ * }
+ */
+/**
+ * @param {TreeNode} root
+ * @param {TreeNode} p
+ * @param {TreeNode} q
+ * @return {TreeNode}
+ */
+var lowestCommonAncestor = function (root, p, q) {
+ if (!root || root === p || root === q) {
+ return root;
+ }
+ const left = lowestCommonAncestor(root.left, p, q);
+ const right = lowestCommonAncestor(root.right, p, q);
+ return left && right ? root : left || right;
+};
+```
+
#### Swift
```swift
diff --git a/lcci/04.08.First Common Ancestor/Solution.cpp b/lcci/04.08.First Common Ancestor/Solution.cpp
new file mode 100644
index 0000000000000..1cd5e13570f9b
--- /dev/null
+++ b/lcci/04.08.First Common Ancestor/Solution.cpp
@@ -0,0 +1,20 @@
+/**
+ * Definition for a binary tree node.
+ * struct TreeNode {
+ * int val;
+ * TreeNode *left;
+ * TreeNode *right;
+ * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
+ * };
+ */
+class Solution {
+public:
+ TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
+ if (!root || root == p || root == q) {
+ return root;
+ }
+ TreeNode* left = lowestCommonAncestor(root->left, p, q);
+ TreeNode* right = lowestCommonAncestor(root->right, p, q);
+ return left && right ? root : (left ? left : right);
+ }
+};
diff --git a/lcci/04.08.First Common Ancestor/Solution.go b/lcci/04.08.First Common Ancestor/Solution.go
new file mode 100644
index 0000000000000..b2668e2c48820
--- /dev/null
+++ b/lcci/04.08.First Common Ancestor/Solution.go
@@ -0,0 +1,22 @@
+/**
+ * Definition for a binary tree node.
+ * type TreeNode struct {
+ * Val int
+ * Left *TreeNode
+ * Right *TreeNode
+ * }
+ */
+func lowestCommonAncestor(root *TreeNode, p *TreeNode, q *TreeNode) *TreeNode {
+ if root == nil || root == p || root == q {
+ return root
+ }
+ left := lowestCommonAncestor(root.Left, p, q)
+ right := lowestCommonAncestor(root.Right, p, q)
+ if left == nil {
+ return right
+ }
+ if right == nil {
+ return left
+ }
+ return root
+}
diff --git a/lcci/04.08.First Common Ancestor/Solution.js b/lcci/04.08.First Common Ancestor/Solution.js
new file mode 100644
index 0000000000000..cba4ad1be11d1
--- /dev/null
+++ b/lcci/04.08.First Common Ancestor/Solution.js
@@ -0,0 +1,21 @@
+/**
+ * Definition for a binary tree node.
+ * function TreeNode(val) {
+ * this.val = val;
+ * this.left = this.right = null;
+ * }
+ */
+/**
+ * @param {TreeNode} root
+ * @param {TreeNode} p
+ * @param {TreeNode} q
+ * @return {TreeNode}
+ */
+var lowestCommonAncestor = function (root, p, q) {
+ if (!root || root === p || root === q) {
+ return root;
+ }
+ const left = lowestCommonAncestor(root.left, p, q);
+ const right = lowestCommonAncestor(root.right, p, q);
+ return left && right ? root : left || right;
+};
diff --git a/lcci/04.08.First Common Ancestor/Solution.py b/lcci/04.08.First Common Ancestor/Solution.py
index 1622fd413d1b0..ebd8bb7f1f46b 100644
--- a/lcci/04.08.First Common Ancestor/Solution.py
+++ b/lcci/04.08.First Common Ancestor/Solution.py
@@ -10,8 +10,8 @@ class Solution:
def lowestCommonAncestor(
self, root: TreeNode, p: TreeNode, q: TreeNode
) -> TreeNode:
- if root is None or root == p or root == q:
+ if root is None or root in [p, q]:
return root
left = self.lowestCommonAncestor(root.left, p, q)
right = self.lowestCommonAncestor(root.right, p, q)
- return right if left is None else (left if right is None else root)
+ return root if left and right else left or right
diff --git a/lcci/04.12.Paths with Sum/README.md b/lcci/04.12.Paths with Sum/README.md
index 5ff30a2c961e5..6f0a4bcdfbffc 100644
--- a/lcci/04.12.Paths with Sum/README.md
+++ b/lcci/04.12.Paths with Sum/README.md
@@ -70,15 +70,13 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcci/04.12.Paths%20with%20
```python
# Definition for a binary tree node.
# class TreeNode:
-# def __init__(self, x):
-# self.val = x
-# self.left = None
-# self.right = None
-
-
+# def __init__(self, val=0, left=None, right=None):
+# self.val = val
+# self.left = left
+# self.right = right
class Solution:
- def pathSum(self, root: TreeNode, sum: int) -> int:
- def dfs(root: TreeNode, s: int):
+ def pathSum(self, root: Optional[TreeNode], sum: int) -> int:
+ def dfs(root: Optional[TreeNode], s: int) -> int:
if root is None:
return 0
s += root.val
@@ -145,9 +143,8 @@ class Solution {
class Solution {
public:
int pathSum(TreeNode* root, int sum) {
- unordered_map cnt;
- cnt[0] = 1;
- function dfs = [&](TreeNode* root, long long s) {
+ unordered_map cnt{{0, 1}};
+ auto dfs = [&](this auto&& dfs, TreeNode* root, long long s) -> int {
if (!root) {
return 0;
}
@@ -285,43 +282,40 @@ impl Solution {
#### Swift
```swift
-/* class TreeNode {
-* var val: Int
-* var left: TreeNode?
-* var right: TreeNode?
-*
-* init(_ val: Int, _ left: TreeNode? = nil, _ right: TreeNode? = nil) {
-* self.val = val
-* self.left = left
-* self.right = right
-* }
-* }
-*/
-
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
class Solution {
- private var cnt: [Int: Int] = [:]
- private var target: Int = 0
-
func pathSum(_ root: TreeNode?, _ sum: Int) -> Int {
- cnt[0] = 1
- target = sum
- return dfs(root, 0)
+ var cnt: [Int: Int] = [0: 1]
- }
+ func dfs(_ root: TreeNode?, _ s: Int) -> Int {
+ guard let root = root else { return 0 }
- private func dfs(_ root: TreeNode?, _ s: Int) -> Int {
- guard let root = root else {
- return 0
- }
- let newSum = s + root.val
- let ans = cnt[newSum - target, default: 0]
+ var s = s + root.val
+ var ans = cnt[s - sum, default: 0]
- cnt[newSum, default: 0] += 1
- let leftPaths = dfs(root.left, newSum)
- let rightPaths = dfs(root.right, newSum)
- cnt[newSum, default: 0] -= 1
+ cnt[s, default: 0] += 1
+ ans += dfs(root.left, s)
+ ans += dfs(root.right, s)
+ cnt[s, default: 0] -= 1
- return ans + leftPaths + rightPaths
+ return ans
+ }
+
+ return dfs(root, 0)
}
}
```
diff --git a/lcci/04.12.Paths with Sum/README_EN.md b/lcci/04.12.Paths with Sum/README_EN.md
index e2b797b3c05f5..179134478b763 100644
--- a/lcci/04.12.Paths with Sum/README_EN.md
+++ b/lcci/04.12.Paths with Sum/README_EN.md
@@ -83,15 +83,13 @@ The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is
```python
# Definition for a binary tree node.
# class TreeNode:
-# def __init__(self, x):
-# self.val = x
-# self.left = None
-# self.right = None
-
-
+# def __init__(self, val=0, left=None, right=None):
+# self.val = val
+# self.left = left
+# self.right = right
class Solution:
- def pathSum(self, root: TreeNode, sum: int) -> int:
- def dfs(root: TreeNode, s: int):
+ def pathSum(self, root: Optional[TreeNode], sum: int) -> int:
+ def dfs(root: Optional[TreeNode], s: int) -> int:
if root is None:
return 0
s += root.val
@@ -158,9 +156,8 @@ class Solution {
class Solution {
public:
int pathSum(TreeNode* root, int sum) {
- unordered_map cnt;
- cnt[0] = 1;
- function dfs = [&](TreeNode* root, long long s) {
+ unordered_map cnt{{0, 1}};
+ auto dfs = [&](this auto&& dfs, TreeNode* root, long long s) -> int {
if (!root) {
return 0;
}
@@ -298,42 +295,40 @@ impl Solution {
#### Swift
```swift
-/* class TreeNode {
-* var val: Int
-* var left: TreeNode?
-* var right: TreeNode?
-*
-* init(_ val: Int, _ left: TreeNode? = nil, _ right: TreeNode? = nil) {
-* self.val = val
-* self.left = left
-* self.right = right
-* }
-* }
-*/
-
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
class Solution {
- private var cnt: [Int: Int] = [:]
- private var target: Int = 0
-
func pathSum(_ root: TreeNode?, _ sum: Int) -> Int {
- cnt[0] = 1
- target = sum
- return dfs(root, 0)
- }
+ var cnt: [Int: Int] = [0: 1]
- private func dfs(_ root: TreeNode?, _ s: Int) -> Int {
- guard let root = root else {
- return 0
- }
- let newSum = s + root.val
- let ans = cnt[newSum - target, default: 0]
+ func dfs(_ root: TreeNode?, _ s: Int) -> Int {
+ guard let root = root else { return 0 }
+
+ var s = s + root.val
+ var ans = cnt[s - sum, default: 0]
+
+ cnt[s, default: 0] += 1
+ ans += dfs(root.left, s)
+ ans += dfs(root.right, s)
+ cnt[s, default: 0] -= 1
- cnt[newSum, default: 0] += 1
- let leftPaths = dfs(root.left, newSum)
- let rightPaths = dfs(root.right, newSum)
- cnt[newSum, default: 0] -= 1
+ return ans
+ }
- return ans + leftPaths + rightPaths
+ return dfs(root, 0)
}
}
```
diff --git a/lcci/04.12.Paths with Sum/Solution.cpp b/lcci/04.12.Paths with Sum/Solution.cpp
index 72e43d0c492c0..9095a6ab905d9 100644
--- a/lcci/04.12.Paths with Sum/Solution.cpp
+++ b/lcci/04.12.Paths with Sum/Solution.cpp
@@ -10,9 +10,8 @@
class Solution {
public:
int pathSum(TreeNode* root, int sum) {
- unordered_map cnt;
- cnt[0] = 1;
- function dfs = [&](TreeNode* root, long long s) {
+ unordered_map cnt{{0, 1}};
+ auto dfs = [&](this auto&& dfs, TreeNode* root, long long s) -> int {
if (!root) {
return 0;
}
@@ -26,4 +25,4 @@ class Solution {
};
return dfs(root, 0);
}
-};
\ No newline at end of file
+};
diff --git a/lcci/04.12.Paths with Sum/Solution.py b/lcci/04.12.Paths with Sum/Solution.py
index 096e03e07552b..25e2179fe9ddc 100644
--- a/lcci/04.12.Paths with Sum/Solution.py
+++ b/lcci/04.12.Paths with Sum/Solution.py
@@ -1,14 +1,12 @@
# Definition for a binary tree node.
# class TreeNode:
-# def __init__(self, x):
-# self.val = x
-# self.left = None
-# self.right = None
-
-
+# def __init__(self, val=0, left=None, right=None):
+# self.val = val
+# self.left = left
+# self.right = right
class Solution:
- def pathSum(self, root: TreeNode, sum: int) -> int:
- def dfs(root: TreeNode, s: int):
+ def pathSum(self, root: Optional[TreeNode], sum: int) -> int:
+ def dfs(root: Optional[TreeNode], s: int) -> int:
if root is None:
return 0
s += root.val
diff --git a/lcci/04.12.Paths with Sum/Solution.swift b/lcci/04.12.Paths with Sum/Solution.swift
index cf1cbe9a5b95e..ad6fb0b161171 100644
--- a/lcci/04.12.Paths with Sum/Solution.swift
+++ b/lcci/04.12.Paths with Sum/Solution.swift
@@ -1,38 +1,36 @@
-/* class TreeNode {
-* var val: Int
-* var left: TreeNode?
-* var right: TreeNode?
-*
-* init(_ val: Int, _ left: TreeNode? = nil, _ right: TreeNode? = nil) {
-* self.val = val
-* self.left = left
-* self.right = right
-* }
-* }
-*/
-
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
class Solution {
- private var cnt: [Int: Int] = [:]
- private var target: Int = 0
-
func pathSum(_ root: TreeNode?, _ sum: Int) -> Int {
- cnt[0] = 1
- target = sum
- return dfs(root, 0)
- }
+ var cnt: [Int: Int] = [0: 1]
+
+ func dfs(_ root: TreeNode?, _ s: Int) -> Int {
+ guard let root = root else { return 0 }
- private func dfs(_ root: TreeNode?, _ s: Int) -> Int {
- guard let root = root else {
- return 0
+ var s = s + root.val
+ var ans = cnt[s - sum, default: 0]
+
+ cnt[s, default: 0] += 1
+ ans += dfs(root.left, s)
+ ans += dfs(root.right, s)
+ cnt[s, default: 0] -= 1
+
+ return ans
}
- let newSum = s + root.val
- let ans = cnt[newSum - target, default: 0]
-
- cnt[newSum, default: 0] += 1
- let leftPaths = dfs(root.left, newSum)
- let rightPaths = dfs(root.right, newSum)
- cnt[newSum, default: 0] -= 1
-
- return ans + leftPaths + rightPaths
+
+ return dfs(root, 0)
}
-}
\ No newline at end of file
+}
diff --git a/lcci/05.03.Reverse Bits/README.md b/lcci/05.03.Reverse Bits/README.md
index cbec7bc2a611d..fad13598cbc1b 100644
--- a/lcci/05.03.Reverse Bits/README.md
+++ b/lcci/05.03.Reverse Bits/README.md
@@ -134,13 +134,13 @@ function reverseBits(num: number): number {
class Solution {
func reverseBits(_ num: Int) -> Int {
var ans = 0
- var countZeros = 0
+ var cnt = 0
var j = 0
for i in 0..<32 {
- countZeros += (num >> i & 1 ^ 1)
- while countZeros > 1 {
- countZeros -= (num >> j & 1 ^ 1)
+ cnt += (num >> i & 1 ^ 1)
+ while cnt > 1 {
+ cnt -= (num >> j & 1 ^ 1)
j += 1
}
ans = max(ans, i - j + 1)
diff --git a/lcci/05.03.Reverse Bits/README_EN.md b/lcci/05.03.Reverse Bits/README_EN.md
index eb68a91114262..a9c88a668e959 100644
--- a/lcci/05.03.Reverse Bits/README_EN.md
+++ b/lcci/05.03.Reverse Bits/README_EN.md
@@ -142,13 +142,13 @@ function reverseBits(num: number): number {
class Solution {
func reverseBits(_ num: Int) -> Int {
var ans = 0
- var countZeros = 0
+ var cnt = 0
var j = 0
for i in 0..<32 {
- countZeros += (num >> i & 1 ^ 1)
- while countZeros > 1 {
- countZeros -= (num >> j & 1 ^ 1)
+ cnt += (num >> i & 1 ^ 1)
+ while cnt > 1 {
+ cnt -= (num >> j & 1 ^ 1)
j += 1
}
ans = max(ans, i - j + 1)
diff --git a/lcci/05.03.Reverse Bits/Solution.swift b/lcci/05.03.Reverse Bits/Solution.swift
index da1c7fe2acf4a..0bd69d4893f51 100644
--- a/lcci/05.03.Reverse Bits/Solution.swift
+++ b/lcci/05.03.Reverse Bits/Solution.swift
@@ -1,13 +1,13 @@
class Solution {
func reverseBits(_ num: Int) -> Int {
var ans = 0
- var countZeros = 0
+ var cnt = 0
var j = 0
for i in 0..<32 {
- countZeros += (num >> i & 1 ^ 1)
- while countZeros > 1 {
- countZeros -= (num >> j & 1 ^ 1)
+ cnt += (num >> i & 1 ^ 1)
+ while cnt > 1 {
+ cnt -= (num >> j & 1 ^ 1)
j += 1
}
ans = max(ans, i - j + 1)
diff --git a/lcci/08.02.Robot in a Grid/README.md b/lcci/08.02.Robot in a Grid/README.md
index cc1bf9f600664..8b60835e73b0c 100644
--- a/lcci/08.02.Robot in a Grid/README.md
+++ b/lcci/08.02.Robot in a Grid/README.md
@@ -15,7 +15,9 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcci/08.02.Robot%20in%20a%
设想有个机器人坐在一个网格的左上角,网格 r 行 c 列。机器人只能向下或向右移动,但不能走到一些被禁止的网格(有障碍物)。设计一种算法,寻找机器人从左上角移动到右下角的路径。
+

+
网格中的障碍物和空位置分别用 1
和 0
来表示。
返回一条可行的路径,路径由经过的网格的行号和列号组成。左上角为 0 行 0 列。
示例 1:
@@ -26,7 +28,7 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcci/08.02.Robot%20in%20a%
[0,0,0 ]
]
输出: [[0,0],[0,1],[0,2],[1,2],[2,2]]
-解释:
+解释:
输入中标粗的位置即为输出表示的路径,即
0行0列(左上角) -> 0行1列 -> 0行2列 -> 1行2列 -> 2行2列(右下角)
说明: r 和 c 的值均不超过 100。
@@ -107,7 +109,7 @@ public:
int m = obstacleGrid.size();
int n = obstacleGrid[0].size();
vector> ans;
- function dfs = [&](int i, int j) -> bool {
+ auto dfs = [&](this auto&& dfs, int i, int j) -> bool {
if (i >= m || j >= n || obstacleGrid[i][j] == 1) {
return false;
}
diff --git a/lcci/08.02.Robot in a Grid/README_EN.md b/lcci/08.02.Robot in a Grid/README_EN.md
index 3ba14cfdcd585..bb37b1b1bf1d9 100644
--- a/lcci/08.02.Robot in a Grid/README_EN.md
+++ b/lcci/08.02.Robot in a Grid/README_EN.md
@@ -15,7 +15,9 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcci/08.02.Robot%20in%20a%
Imagine a robot sitting on the upper left corner of grid with r rows and c columns. The robot can only move in two directions, right and down, but certain cells are "off limits" such that the robot cannot step on them. Design an algorithm to find a path for the robot from the top left to the bottom right.
+

+
"off limits" and empty grid are represented by 1
and 0
respectively.
Return a valid path, consisting of row number and column number of grids in the path.
Example 1:
@@ -116,7 +118,7 @@ public:
int m = obstacleGrid.size();
int n = obstacleGrid[0].size();
vector> ans;
- function dfs = [&](int i, int j) -> bool {
+ auto dfs = [&](this auto&& dfs, int i, int j) -> bool {
if (i >= m || j >= n || obstacleGrid[i][j] == 1) {
return false;
}
diff --git a/lcci/08.02.Robot in a Grid/Solution.cpp b/lcci/08.02.Robot in a Grid/Solution.cpp
index e9657e05ef757..f7daef341d833 100644
--- a/lcci/08.02.Robot in a Grid/Solution.cpp
+++ b/lcci/08.02.Robot in a Grid/Solution.cpp
@@ -4,7 +4,7 @@ class Solution {
int m = obstacleGrid.size();
int n = obstacleGrid[0].size();
vector> ans;
- function dfs = [&](int i, int j) -> bool {
+ auto dfs = [&](this auto&& dfs, int i, int j) -> bool {
if (i >= m || j >= n || obstacleGrid[i][j] == 1) {
return false;
}
@@ -18,4 +18,4 @@ class Solution {
};
return dfs(0, 0) ? ans : vector>();
}
-};
\ No newline at end of file
+};
diff --git a/lcci/08.06.Hanota/README.md b/lcci/08.06.Hanota/README.md
index 04efe8940d384..b5dc3d3966adc 100644
--- a/lcci/08.06.Hanota/README.md
+++ b/lcci/08.06.Hanota/README.md
@@ -91,7 +91,7 @@ class Solution {
class Solution {
public:
void hanota(vector& A, vector& B, vector& C) {
- function&, vector&, vector&)> dfs = [&](int n, vector& a, vector& b, vector& c) {
+ auto dfs = [&](this auto&& dfs, int n, vector& a, vector& b, vector& c) {
if (n == 1) {
c.push_back(a.back());
a.pop_back();
diff --git a/lcci/08.06.Hanota/README_EN.md b/lcci/08.06.Hanota/README_EN.md
index 6d4243950efb0..3f52664c584e4 100644
--- a/lcci/08.06.Hanota/README_EN.md
+++ b/lcci/08.06.Hanota/README_EN.md
@@ -98,7 +98,7 @@ class Solution {
class Solution {
public:
void hanota(vector& A, vector& B, vector& C) {
- function&, vector&, vector&)> dfs = [&](int n, vector& a, vector& b, vector& c) {
+ auto dfs = [&](this auto&& dfs, int n, vector& a, vector& b, vector& c) {
if (n == 1) {
c.push_back(a.back());
a.pop_back();
diff --git a/lcci/08.06.Hanota/Solution.cpp b/lcci/08.06.Hanota/Solution.cpp
index 7cf7ad9647324..3b5b8d483ce8b 100644
--- a/lcci/08.06.Hanota/Solution.cpp
+++ b/lcci/08.06.Hanota/Solution.cpp
@@ -1,7 +1,7 @@
class Solution {
public:
void hanota(vector& A, vector& B, vector& C) {
- function&, vector&, vector&)> dfs = [&](int n, vector& a, vector& b, vector& c) {
+ auto dfs = [&](this auto&& dfs, int n, vector& a, vector& b, vector& c) {
if (n == 1) {
c.push_back(a.back());
a.pop_back();
@@ -14,4 +14,4 @@ class Solution {
};
dfs(A.size(), A, B, C);
}
-};
\ No newline at end of file
+};
diff --git a/lcci/08.07.Permutation I/README.md b/lcci/08.07.Permutation I/README.md
index 34a783fde5bac..9d3e78c2da0d4 100644
--- a/lcci/08.07.Permutation I/README.md
+++ b/lcci/08.07.Permutation I/README.md
@@ -45,7 +45,7 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcci/08.07.Permutation%20I
### 方法一:DFS(回溯)
-我们设计一个函数 $dfs(i)$ 表示已经填完了前 $i$ 个位置,现在需要填第 $i+1$ 个位置。枚举所有可能的字符,如果这个字符没有被填过,就填入这个字符,然后继续填下一个位置,直到填完所有的位置。
+我们设计一个函数 $\textit{dfs}(i)$ 表示已经填完了前 $i$ 个位置,现在需要填第 $i+1$ 个位置。枚举所有可能的字符,如果这个字符没有被填过,就填入这个字符,然后继续填下一个位置,直到填完所有的位置。
时间复杂度 $O(n \times n!)$,其中 $n$ 是字符串的长度。一共有 $n!$ 个排列,每个排列需要 $O(n)$ 的时间来构造。
@@ -57,22 +57,20 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcci/08.07.Permutation%20I
class Solution:
def permutation(self, S: str) -> List[str]:
def dfs(i: int):
- if i == n:
+ if i >= n:
ans.append("".join(t))
return
for j, c in enumerate(S):
- if vis[j]:
- continue
- vis[j] = True
- t.append(c)
- dfs(i + 1)
- t.pop()
- vis[j] = False
+ if not vis[j]:
+ vis[j] = True
+ t[i] = c
+ dfs(i + 1)
+ vis[j] = False
+ ans = []
n = len(S)
vis = [False] * n
- ans = []
- t = []
+ t = list(S)
dfs(0)
return ans
```
@@ -82,30 +80,31 @@ class Solution:
```java
class Solution {
private char[] s;
- private boolean[] vis = new boolean['z' + 1];
+ private char[] t;
+ private boolean[] vis;
private List ans = new ArrayList<>();
- private StringBuilder t = new StringBuilder();
public String[] permutation(String S) {
s = S.toCharArray();
+ int n = s.length;
+ vis = new boolean[n];
+ t = new char[n];
dfs(0);
return ans.toArray(new String[0]);
}
private void dfs(int i) {
- if (i == s.length) {
- ans.add(t.toString());
+ if (i >= s.length) {
+ ans.add(new String(t));
return;
}
- for (char c : s) {
- if (vis[c]) {
- continue;
+ for (int j = 0; j < s.length; ++j) {
+ if (!vis[j]) {
+ vis[j] = true;
+ t[i] = s[j];
+ dfs(i + 1);
+ vis[j] = false;
}
- vis[c] = true;
- t.append(c);
- dfs(i + 1);
- t.deleteCharAt(t.length() - 1);
- vis[c] = false;
}
}
}
@@ -119,51 +118,49 @@ public:
vector permutation(string S) {
int n = S.size();
vector vis(n);
+ string t = S;
vector ans;
- string t;
- function dfs = [&](int i) {
+ auto dfs = [&](this auto&& dfs, int i) {
if (i >= n) {
- ans.push_back(t);
+ ans.emplace_back(t);
return;
}
for (int j = 0; j < n; ++j) {
- if (vis[j]) {
- continue;
+ if (!vis[j]) {
+ vis[j] = true;
+ t[i] = S[j];
+ dfs(i + 1);
+ vis[j] = false;
}
- vis[j] = true;
- t.push_back(S[j]);
- dfs(i + 1);
- t.pop_back();
- vis[j] = false;
}
};
dfs(0);
return ans;
}
};
+
```
#### Go
```go
func permutation(S string) (ans []string) {
- t := []byte{}
- vis := make([]bool, len(S))
+ t := []byte(S)
+ n := len(t)
+ vis := make([]bool, n)
var dfs func(int)
dfs = func(i int) {
- if i >= len(S) {
+ if i >= n {
ans = append(ans, string(t))
return
}
for j := range S {
- if vis[j] {
- continue
+ if !vis[j] {
+ vis[j] = true
+ t[i] = S[j]
+ dfs(i + 1)
+ vis[j] = false
}
- vis[j] = true
- t = append(t, S[j])
- dfs(i + 1)
- t = t[:len(t)-1]
- vis[j] = false
}
}
dfs(0)
@@ -178,7 +175,7 @@ function permutation(S: string): string[] {
const n = S.length;
const vis: boolean[] = Array(n).fill(false);
const ans: string[] = [];
- const t: string[] = [];
+ const t: string[] = Array(n).fill('');
const dfs = (i: number) => {
if (i >= n) {
ans.push(t.join(''));
@@ -189,9 +186,8 @@ function permutation(S: string): string[] {
continue;
}
vis[j] = true;
- t.push(S[j]);
+ t[i] = S[j];
dfs(i + 1);
- t.pop();
vis[j] = false;
}
};
@@ -211,7 +207,7 @@ var permutation = function (S) {
const n = S.length;
const vis = Array(n).fill(false);
const ans = [];
- const t = [];
+ const t = Array(n).fill('');
const dfs = i => {
if (i >= n) {
ans.push(t.join(''));
@@ -222,9 +218,8 @@ var permutation = function (S) {
continue;
}
vis[j] = true;
- t.push(S[j]);
+ t[i] = S[j];
dfs(i + 1);
- t.pop();
vis[j] = false;
}
};
@@ -237,33 +232,30 @@ var permutation = function (S) {
```swift
class Solution {
- private var s: [Character] = []
- private var vis: [Bool] = Array(repeating: false, count: 128)
- private var ans: [String] = []
- private var t: String = ""
-
func permutation(_ S: String) -> [String] {
- s = Array(S)
- dfs(0)
- return ans
- }
-
- private func dfs(_ i: Int) {
- if i == s.count {
- ans.append(t)
- return
- }
- for c in s {
- let index = Int(c.asciiValue!)
- if vis[index] {
- continue
+ var ans: [String] = []
+ let s = Array(S)
+ var t = s
+ var vis = Array(repeating: false, count: s.count)
+ let n = s.count
+
+ func dfs(_ i: Int) {
+ if i >= n {
+ ans.append(String(t))
+ return
+ }
+ for j in 0.. List[str]:
def dfs(i: int):
- if i == n:
+ if i >= n:
ans.append("".join(t))
return
for j, c in enumerate(S):
- if vis[j]:
- continue
- vis[j] = True
- t.append(c)
- dfs(i + 1)
- t.pop()
- vis[j] = False
+ if not vis[j]:
+ vis[j] = True
+ t[i] = c
+ dfs(i + 1)
+ vis[j] = False
+ ans = []
n = len(S)
vis = [False] * n
- ans = []
- t = []
+ t = list(S)
dfs(0)
return ans
```
@@ -88,30 +86,31 @@ class Solution:
```java
class Solution {
private char[] s;
- private boolean[] vis = new boolean['z' + 1];
+ private char[] t;
+ private boolean[] vis;
private List ans = new ArrayList<>();
- private StringBuilder t = new StringBuilder();
public String[] permutation(String S) {
s = S.toCharArray();
+ int n = s.length;
+ vis = new boolean[n];
+ t = new char[n];
dfs(0);
return ans.toArray(new String[0]);
}
private void dfs(int i) {
- if (i == s.length) {
- ans.add(t.toString());
+ if (i >= s.length) {
+ ans.add(new String(t));
return;
}
- for (char c : s) {
- if (vis[c]) {
- continue;
+ for (int j = 0; j < s.length; ++j) {
+ if (!vis[j]) {
+ vis[j] = true;
+ t[i] = s[j];
+ dfs(i + 1);
+ vis[j] = false;
}
- vis[c] = true;
- t.append(c);
- dfs(i + 1);
- t.deleteCharAt(t.length() - 1);
- vis[c] = false;
}
}
}
@@ -125,22 +124,20 @@ public:
vector permutation(string S) {
int n = S.size();
vector vis(n);
+ string t = S;
vector ans;
- string t;
- function dfs = [&](int i) {
+ auto dfs = [&](this auto&& dfs, int i) {
if (i >= n) {
- ans.push_back(t);
+ ans.emplace_back(t);
return;
}
for (int j = 0; j < n; ++j) {
- if (vis[j]) {
- continue;
+ if (!vis[j]) {
+ vis[j] = true;
+ t[i] = S[j];
+ dfs(i + 1);
+ vis[j] = false;
}
- vis[j] = true;
- t.push_back(S[j]);
- dfs(i + 1);
- t.pop_back();
- vis[j] = false;
}
};
dfs(0);
@@ -153,23 +150,22 @@ public:
```go
func permutation(S string) (ans []string) {
- t := []byte{}
- vis := make([]bool, len(S))
+ t := []byte(S)
+ n := len(t)
+ vis := make([]bool, n)
var dfs func(int)
dfs = func(i int) {
- if i >= len(S) {
+ if i >= n {
ans = append(ans, string(t))
return
}
for j := range S {
- if vis[j] {
- continue
+ if !vis[j] {
+ vis[j] = true
+ t[i] = S[j]
+ dfs(i + 1)
+ vis[j] = false
}
- vis[j] = true
- t = append(t, S[j])
- dfs(i + 1)
- t = t[:len(t)-1]
- vis[j] = false
}
}
dfs(0)
@@ -184,7 +180,7 @@ function permutation(S: string): string[] {
const n = S.length;
const vis: boolean[] = Array(n).fill(false);
const ans: string[] = [];
- const t: string[] = [];
+ const t: string[] = Array(n).fill('');
const dfs = (i: number) => {
if (i >= n) {
ans.push(t.join(''));
@@ -195,9 +191,8 @@ function permutation(S: string): string[] {
continue;
}
vis[j] = true;
- t.push(S[j]);
+ t[i] = S[j];
dfs(i + 1);
- t.pop();
vis[j] = false;
}
};
@@ -217,7 +212,7 @@ var permutation = function (S) {
const n = S.length;
const vis = Array(n).fill(false);
const ans = [];
- const t = [];
+ const t = Array(n).fill('');
const dfs = i => {
if (i >= n) {
ans.push(t.join(''));
@@ -228,9 +223,8 @@ var permutation = function (S) {
continue;
}
vis[j] = true;
- t.push(S[j]);
+ t[i] = S[j];
dfs(i + 1);
- t.pop();
vis[j] = false;
}
};
@@ -243,33 +237,30 @@ var permutation = function (S) {
```swift
class Solution {
- private var s: [Character] = []
- private var vis: [Bool] = Array(repeating: false, count: 128)
- private var ans: [String] = []
- private var t: String = ""
-
func permutation(_ S: String) -> [String] {
- s = Array(S)
- dfs(0)
- return ans
- }
-
- private func dfs(_ i: Int) {
- if i == s.count {
- ans.append(t)
- return
- }
- for c in s {
- let index = Int(c.asciiValue!)
- if vis[index] {
- continue
+ var ans: [String] = []
+ let s = Array(S)
+ var t = s
+ var vis = Array(repeating: false, count: s.count)
+ let n = s.count
+
+ func dfs(_ i: Int) {
+ if i >= n {
+ ans.append(String(t))
+ return
+ }
+ for j in 0.. permutation(string S) {
int n = S.size();
vector vis(n);
+ string t = S;
vector ans;
- string t;
- function dfs = [&](int i) {
+ auto dfs = [&](this auto&& dfs, int i) {
if (i >= n) {
- ans.push_back(t);
+ ans.emplace_back(t);
return;
}
for (int j = 0; j < n; ++j) {
- if (vis[j]) {
- continue;
+ if (!vis[j]) {
+ vis[j] = true;
+ t[i] = S[j];
+ dfs(i + 1);
+ vis[j] = false;
}
- vis[j] = true;
- t.push_back(S[j]);
- dfs(i + 1);
- t.pop_back();
- vis[j] = false;
}
};
dfs(0);
return ans;
}
-};
\ No newline at end of file
+};
diff --git a/lcci/08.07.Permutation I/Solution.go b/lcci/08.07.Permutation I/Solution.go
index 20d5c55fded5f..1f84fb692481e 100644
--- a/lcci/08.07.Permutation I/Solution.go
+++ b/lcci/08.07.Permutation I/Solution.go
@@ -1,23 +1,22 @@
func permutation(S string) (ans []string) {
- t := []byte{}
- vis := make([]bool, len(S))
+ t := []byte(S)
+ n := len(t)
+ vis := make([]bool, n)
var dfs func(int)
dfs = func(i int) {
- if i >= len(S) {
+ if i >= n {
ans = append(ans, string(t))
return
}
for j := range S {
- if vis[j] {
- continue
+ if !vis[j] {
+ vis[j] = true
+ t[i] = S[j]
+ dfs(i + 1)
+ vis[j] = false
}
- vis[j] = true
- t = append(t, S[j])
- dfs(i + 1)
- t = t[:len(t)-1]
- vis[j] = false
}
}
dfs(0)
return
-}
\ No newline at end of file
+}
diff --git a/lcci/08.07.Permutation I/Solution.java b/lcci/08.07.Permutation I/Solution.java
index 896ed99f9d1ea..f65456f945759 100644
--- a/lcci/08.07.Permutation I/Solution.java
+++ b/lcci/08.07.Permutation I/Solution.java
@@ -1,29 +1,30 @@
class Solution {
private char[] s;
- private boolean[] vis = new boolean['z' + 1];
+ private char[] t;
+ private boolean[] vis;
private List ans = new ArrayList<>();
- private StringBuilder t = new StringBuilder();
public String[] permutation(String S) {
s = S.toCharArray();
+ int n = s.length;
+ vis = new boolean[n];
+ t = new char[n];
dfs(0);
return ans.toArray(new String[0]);
}
private void dfs(int i) {
- if (i == s.length) {
- ans.add(t.toString());
+ if (i >= s.length) {
+ ans.add(new String(t));
return;
}
- for (char c : s) {
- if (vis[c]) {
- continue;
+ for (int j = 0; j < s.length; ++j) {
+ if (!vis[j]) {
+ vis[j] = true;
+ t[i] = s[j];
+ dfs(i + 1);
+ vis[j] = false;
}
- vis[c] = true;
- t.append(c);
- dfs(i + 1);
- t.deleteCharAt(t.length() - 1);
- vis[c] = false;
}
}
-}
\ No newline at end of file
+}
diff --git a/lcci/08.07.Permutation I/Solution.js b/lcci/08.07.Permutation I/Solution.js
index f1dcb5d98f69f..c18ebd79c017d 100644
--- a/lcci/08.07.Permutation I/Solution.js
+++ b/lcci/08.07.Permutation I/Solution.js
@@ -6,7 +6,7 @@ var permutation = function (S) {
const n = S.length;
const vis = Array(n).fill(false);
const ans = [];
- const t = [];
+ const t = Array(n).fill('');
const dfs = i => {
if (i >= n) {
ans.push(t.join(''));
@@ -17,9 +17,8 @@ var permutation = function (S) {
continue;
}
vis[j] = true;
- t.push(S[j]);
+ t[i] = S[j];
dfs(i + 1);
- t.pop();
vis[j] = false;
}
};
diff --git a/lcci/08.07.Permutation I/Solution.py b/lcci/08.07.Permutation I/Solution.py
index 537c2f0484bb7..7e64e799f8691 100644
--- a/lcci/08.07.Permutation I/Solution.py
+++ b/lcci/08.07.Permutation I/Solution.py
@@ -1,21 +1,19 @@
class Solution:
def permutation(self, S: str) -> List[str]:
def dfs(i: int):
- if i == n:
+ if i >= n:
ans.append("".join(t))
return
for j, c in enumerate(S):
- if vis[j]:
- continue
- vis[j] = True
- t.append(c)
- dfs(i + 1)
- t.pop()
- vis[j] = False
+ if not vis[j]:
+ vis[j] = True
+ t[i] = c
+ dfs(i + 1)
+ vis[j] = False
+ ans = []
n = len(S)
vis = [False] * n
- ans = []
- t = []
+ t = list(S)
dfs(0)
return ans
diff --git a/lcci/08.07.Permutation I/Solution.swift b/lcci/08.07.Permutation I/Solution.swift
index 48803e420ab09..33a987fc012d9 100644
--- a/lcci/08.07.Permutation I/Solution.swift
+++ b/lcci/08.07.Permutation I/Solution.swift
@@ -1,30 +1,27 @@
class Solution {
- private var s: [Character] = []
- private var vis: [Bool] = Array(repeating: false, count: 128)
- private var ans: [String] = []
- private var t: String = ""
-
func permutation(_ S: String) -> [String] {
- s = Array(S)
- dfs(0)
- return ans
- }
+ var ans: [String] = []
+ let s = Array(S)
+ var t = s
+ var vis = Array(repeating: false, count: s.count)
+ let n = s.count
- private func dfs(_ i: Int) {
- if i == s.count {
- ans.append(t)
- return
- }
- for c in s {
- let index = Int(c.asciiValue!)
- if vis[index] {
- continue
+ func dfs(_ i: Int) {
+ if i >= n {
+ ans.append(String(t))
+ return
+ }
+ for j in 0.. {
if (i >= n) {
ans.push(t.join(''));
@@ -13,9 +13,8 @@ function permutation(S: string): string[] {
continue;
}
vis[j] = true;
- t.push(S[j]);
+ t[i] = S[j];
dfs(i + 1);
- t.pop();
vis[j] = false;
}
};
diff --git a/lcci/08.08.Permutation II/README.md b/lcci/08.08.Permutation II/README.md
index 90b72d44fb2f1..936fb1b9d90cf 100644
--- a/lcci/08.08.Permutation II/README.md
+++ b/lcci/08.08.Permutation II/README.md
@@ -39,12 +39,12 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcci/08.08.Permutation%20I
我们可以先对字符串按照字符进行排序,这样就可以将重复的字符放在一起,方便我们进行去重。
-然后,我们设计一个函数 $dfs(i)$,表示当前需要填写第 $i$ 个位置的字符。函数的具体实现如下:
+然后,我们设计一个函数 $\textit{dfs}(i)$,表示当前需要填写第 $i$ 个位置的字符。函数的具体实现如下:
- 如果 $i = n$,说明我们已经填写完毕,将当前排列加入答案数组中,然后返回。
-- 否则,我们枚举第 $i$ 个位置的字符 $s[j]$,其中 $j$ 的范围是 $[0, n - 1]$。我们需要保证 $s[j]$ 没有被使用过,并且与前面枚举的字符不同,这样才能保证当前排列不重复。如果满足条件,我们就可以填写 $s[j]$,并继续递归地填写下一个位置,即调用 $dfs(i + 1)$。在递归调用结束后,我们需要将 $s[j]$ 标记为未使用,以便于进行后面的枚举。
+- 否则,我们枚举第 $i$ 个位置的字符 $\textit{s}[j]$,其中 $j$ 的范围是 $[0, n - 1]$。我们需要保证 $\textit{s}[j]$ 没有被使用过,并且与前面枚举的字符不同,这样才能保证当前排列不重复。如果满足条件,我们就可以填写 $\textit{s}[j]$,并继续递归地填写下一个位置,即调用 $\textit{dfs}(i + 1)$。在递归调用结束后,我们需要将 $\textit{s}[j]$ 标记为未使用,以便于进行后面的枚举。
-在主函数中,我们首先对字符串进行排序,然后调用 $dfs(0)$,即从第 $0$ 个位置开始填写,最终返回答案数组即可。
+在主函数中,我们首先对字符串进行排序,然后调用 $\textit{dfs}(0)$,即从第 $0$ 个位置开始填写,最终返回答案数组即可。
时间复杂度 $O(n \times n!)$,空间复杂度 $O(n)$。其中 $n$ 是字符串 $s$ 的长度。需要进行 $n!$ 次枚举,每次枚举需要 $O(n)$ 的时间来判断是否重复。另外,我们需要一个标记数组来标记每个位置是否被使用过,因此空间复杂度为 $O(n)$。
@@ -56,21 +56,20 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcci/08.08.Permutation%20I
class Solution:
def permutation(self, S: str) -> List[str]:
def dfs(i: int):
- if i == n:
+ if i >= n:
ans.append("".join(t))
return
- for j in range(n):
- if vis[j] or (j and cs[j] == cs[j - 1] and not vis[j - 1]):
- continue
- t[i] = cs[j]
- vis[j] = True
- dfs(i + 1)
- vis[j] = False
-
- cs = sorted(S)
- n = len(cs)
+ for j, c in enumerate(s):
+ if not vis[j] and (j == 0 or s[j] != s[j - 1] or vis[j - 1]):
+ vis[j] = True
+ t[i] = c
+ dfs(i + 1)
+ vis[j] = False
+
+ s = sorted(S)
ans = []
- t = [None] * n
+ t = s[:]
+ n = len(s)
vis = [False] * n
dfs(0)
return ans
@@ -80,35 +79,33 @@ class Solution:
```java
class Solution {
- private int n;
- private char[] cs;
- private List ans = new ArrayList<>();
+ private char[] s;
+ private char[] t;
private boolean[] vis;
- private StringBuilder t = new StringBuilder();
+ private List ans = new ArrayList<>();
public String[] permutation(String S) {
- cs = S.toCharArray();
- n = cs.length;
- Arrays.sort(cs);
+ int n = S.length();
+ s = S.toCharArray();
+ Arrays.sort(s);
+ t = new char[n];
vis = new boolean[n];
dfs(0);
return ans.toArray(new String[0]);
}
private void dfs(int i) {
- if (i == n) {
- ans.add(t.toString());
+ if (i >= s.length) {
+ ans.add(new String(t));
return;
}
- for (int j = 0; j < n; ++j) {
- if (vis[j] || (j > 0 && !vis[j - 1] && cs[j] == cs[j - 1])) {
- continue;
+ for (int j = 0; j < s.length; ++j) {
+ if (!vis[j] && (j == 0 || s[j] != s[j - 1] || vis[j - 1])) {
+ vis[j] = true;
+ t[i] = s[j];
+ dfs(i + 1);
+ vis[j] = false;
}
- vis[j] = true;
- t.append(cs[j]);
- dfs(i + 1);
- t.deleteCharAt(t.length() - 1);
- vis[j] = false;
}
}
}
@@ -120,26 +117,23 @@ class Solution {
class Solution {
public:
vector permutation(string S) {
- vector cs(S.begin(), S.end());
- sort(cs.begin(), cs.end());
- int n = cs.size();
- vector ans;
+ ranges::sort(S);
+ string t = S;
+ int n = t.size();
vector vis(n);
- string t;
- function dfs = [&](int i) {
- if (i == n) {
- ans.push_back(t);
+ vector ans;
+ auto dfs = [&](this auto&& dfs, int i) {
+ if (i >= n) {
+ ans.emplace_back(t);
return;
}
for (int j = 0; j < n; ++j) {
- if (vis[j] || (j && !vis[j - 1] && cs[j] == cs[j - 1])) {
- continue;
+ if (!vis[j] && (j == 0 || S[j] != S[j - 1] || vis[j - 1])) {
+ vis[j] = true;
+ t[i] = S[j];
+ dfs(i + 1);
+ vis[j] = false;
}
- vis[j] = true;
- t.push_back(cs[j]);
- dfs(i + 1);
- t.pop_back();
- vis[j] = false;
}
};
dfs(0);
@@ -152,26 +146,23 @@ public:
```go
func permutation(S string) (ans []string) {
- cs := []byte(S)
- sort.Slice(cs, func(i, j int) bool { return cs[i] < cs[j] })
- t := []byte{}
- n := len(cs)
- vis := make([]bool, n)
+ s := []byte(S)
+ sort.Slice(s, func(i, j int) bool { return s[i] < s[j] })
+ t := slices.Clone(s)
+ vis := make([]bool, len(s))
var dfs func(int)
dfs = func(i int) {
- if i == n {
+ if i >= len(s) {
ans = append(ans, string(t))
return
}
- for j := 0; j < n; j++ {
- if vis[j] || (j > 0 && !vis[j-1] && cs[j] == cs[j-1]) {
- continue
+ for j := range s {
+ if !vis[j] && (j == 0 || s[j] != s[j-1] || vis[j-1]) {
+ vis[j] = true
+ t[i] = s[j]
+ dfs(i + 1)
+ vis[j] = false
}
- vis[j] = true
- t = append(t, cs[j])
- dfs(i + 1)
- t = t[:len(t)-1]
- vis[j] = false
}
}
dfs(0)
@@ -183,25 +174,23 @@ func permutation(S string) (ans []string) {
```ts
function permutation(S: string): string[] {
- const cs: string[] = S.split('').sort();
- const ans: string[] = [];
- const n = cs.length;
+ const s: string[] = S.split('').sort();
+ const n = s.length;
+ const t = Array(n).fill('');
const vis: boolean[] = Array(n).fill(false);
- const t: string[] = [];
+ const ans: string[] = [];
const dfs = (i: number) => {
- if (i === n) {
+ if (i >= n) {
ans.push(t.join(''));
return;
}
for (let j = 0; j < n; ++j) {
- if (vis[j] || (j > 0 && !vis[j - 1] && cs[j] === cs[j - 1])) {
- continue;
+ if (!vis[j] && (j === 0 || s[j] !== s[j - 1] || vis[j - 1])) {
+ vis[j] = true;
+ t[i] = s[j];
+ dfs(i + 1);
+ vis[j] = false;
}
- vis[j] = true;
- t.push(cs[j]);
- dfs(i + 1);
- t.pop();
- vis[j] = false;
}
};
dfs(0);
@@ -217,25 +206,23 @@ function permutation(S: string): string[] {
* @return {string[]}
*/
var permutation = function (S) {
- const cs = S.split('').sort();
- const ans = [];
- const n = cs.length;
+ const s = S.split('').sort();
+ const n = s.length;
+ const t = Array(n).fill('');
const vis = Array(n).fill(false);
- const t = [];
+ const ans = [];
const dfs = i => {
- if (i === n) {
+ if (i >= n) {
ans.push(t.join(''));
return;
}
for (let j = 0; j < n; ++j) {
- if (vis[j] || (j > 0 && !vis[j - 1] && cs[j] === cs[j - 1])) {
- continue;
+ if (!vis[j] && (j === 0 || s[j] !== s[j - 1] || vis[j - 1])) {
+ vis[j] = true;
+ t[i] = s[j];
+ dfs(i + 1);
+ vis[j] = false;
}
- vis[j] = true;
- t.push(cs[j]);
- dfs(i + 1);
- t.pop();
- vis[j] = false;
}
};
dfs(0);
@@ -247,36 +234,30 @@ var permutation = function (S) {
```swift
class Solution {
- private var n: Int = 0
- private var cs: [Character] = []
- private var ans: [String] = []
- private var vis: [Bool] = []
- private var t: String = ""
-
func permutation(_ S: String) -> [String] {
- cs = Array(S)
- n = cs.count
- cs.sort()
- vis = Array(repeating: false, count: n)
- dfs(0)
- return ans
- }
-
- private func dfs(_ i: Int) {
- if i == n {
- ans.append(t)
- return
- }
- for j in 0.. 0 && !vis[j - 1] && cs[j] == cs[j - 1]) {
- continue
+ var ans: [String] = []
+ var s: [Character] = Array(S).sorted()
+ var t: [Character] = Array(repeating: " ", count: s.count)
+ var vis: [Bool] = Array(repeating: false, count: s.count)
+ let n = s.count
+
+ func dfs(_ i: Int) {
+ if i >= n {
+ ans.append(String(t))
+ return
+ }
+ for j in 0..
@@ -64,21 +64,20 @@ The time complexity is $O(n \times n!)$, and the space complexity is $O(n)$. Her
class Solution:
def permutation(self, S: str) -> List[str]:
def dfs(i: int):
- if i == n:
+ if i >= n:
ans.append("".join(t))
return
- for j in range(n):
- if vis[j] or (j and cs[j] == cs[j - 1] and not vis[j - 1]):
- continue
- t[i] = cs[j]
- vis[j] = True
- dfs(i + 1)
- vis[j] = False
-
- cs = sorted(S)
- n = len(cs)
+ for j, c in enumerate(s):
+ if not vis[j] and (j == 0 or s[j] != s[j - 1] or vis[j - 1]):
+ vis[j] = True
+ t[i] = c
+ dfs(i + 1)
+ vis[j] = False
+
+ s = sorted(S)
ans = []
- t = [None] * n
+ t = s[:]
+ n = len(s)
vis = [False] * n
dfs(0)
return ans
@@ -88,35 +87,33 @@ class Solution:
```java
class Solution {
- private int n;
- private char[] cs;
- private List ans = new ArrayList<>();
+ private char[] s;
+ private char[] t;
private boolean[] vis;
- private StringBuilder t = new StringBuilder();
+ private List ans = new ArrayList<>();
public String[] permutation(String S) {
- cs = S.toCharArray();
- n = cs.length;
- Arrays.sort(cs);
+ int n = S.length();
+ s = S.toCharArray();
+ Arrays.sort(s);
+ t = new char[n];
vis = new boolean[n];
dfs(0);
return ans.toArray(new String[0]);
}
private void dfs(int i) {
- if (i == n) {
- ans.add(t.toString());
+ if (i >= s.length) {
+ ans.add(new String(t));
return;
}
- for (int j = 0; j < n; ++j) {
- if (vis[j] || (j > 0 && !vis[j - 1] && cs[j] == cs[j - 1])) {
- continue;
+ for (int j = 0; j < s.length; ++j) {
+ if (!vis[j] && (j == 0 || s[j] != s[j - 1] || vis[j - 1])) {
+ vis[j] = true;
+ t[i] = s[j];
+ dfs(i + 1);
+ vis[j] = false;
}
- vis[j] = true;
- t.append(cs[j]);
- dfs(i + 1);
- t.deleteCharAt(t.length() - 1);
- vis[j] = false;
}
}
}
@@ -128,26 +125,23 @@ class Solution {
class Solution {
public:
vector permutation(string S) {
- vector cs(S.begin(), S.end());
- sort(cs.begin(), cs.end());
- int n = cs.size();
- vector ans;
+ ranges::sort(S);
+ string t = S;
+ int n = t.size();
vector vis(n);
- string t;
- function dfs = [&](int i) {
- if (i == n) {
- ans.push_back(t);
+ vector ans;
+ auto dfs = [&](this auto&& dfs, int i) {
+ if (i >= n) {
+ ans.emplace_back(t);
return;
}
for (int j = 0; j < n; ++j) {
- if (vis[j] || (j && !vis[j - 1] && cs[j] == cs[j - 1])) {
- continue;
+ if (!vis[j] && (j == 0 || S[j] != S[j - 1] || vis[j - 1])) {
+ vis[j] = true;
+ t[i] = S[j];
+ dfs(i + 1);
+ vis[j] = false;
}
- vis[j] = true;
- t.push_back(cs[j]);
- dfs(i + 1);
- t.pop_back();
- vis[j] = false;
}
};
dfs(0);
@@ -160,26 +154,23 @@ public:
```go
func permutation(S string) (ans []string) {
- cs := []byte(S)
- sort.Slice(cs, func(i, j int) bool { return cs[i] < cs[j] })
- t := []byte{}
- n := len(cs)
- vis := make([]bool, n)
+ s := []byte(S)
+ sort.Slice(s, func(i, j int) bool { return s[i] < s[j] })
+ t := slices.Clone(s)
+ vis := make([]bool, len(s))
var dfs func(int)
dfs = func(i int) {
- if i == n {
+ if i >= len(s) {
ans = append(ans, string(t))
return
}
- for j := 0; j < n; j++ {
- if vis[j] || (j > 0 && !vis[j-1] && cs[j] == cs[j-1]) {
- continue
+ for j := range s {
+ if !vis[j] && (j == 0 || s[j] != s[j-1] || vis[j-1]) {
+ vis[j] = true
+ t[i] = s[j]
+ dfs(i + 1)
+ vis[j] = false
}
- vis[j] = true
- t = append(t, cs[j])
- dfs(i + 1)
- t = t[:len(t)-1]
- vis[j] = false
}
}
dfs(0)
@@ -191,25 +182,23 @@ func permutation(S string) (ans []string) {
```ts
function permutation(S: string): string[] {
- const cs: string[] = S.split('').sort();
- const ans: string[] = [];
- const n = cs.length;
+ const s: string[] = S.split('').sort();
+ const n = s.length;
+ const t = Array(n).fill('');
const vis: boolean[] = Array(n).fill(false);
- const t: string[] = [];
+ const ans: string[] = [];
const dfs = (i: number) => {
- if (i === n) {
+ if (i >= n) {
ans.push(t.join(''));
return;
}
for (let j = 0; j < n; ++j) {
- if (vis[j] || (j > 0 && !vis[j - 1] && cs[j] === cs[j - 1])) {
- continue;
+ if (!vis[j] && (j === 0 || s[j] !== s[j - 1] || vis[j - 1])) {
+ vis[j] = true;
+ t[i] = s[j];
+ dfs(i + 1);
+ vis[j] = false;
}
- vis[j] = true;
- t.push(cs[j]);
- dfs(i + 1);
- t.pop();
- vis[j] = false;
}
};
dfs(0);
@@ -225,25 +214,23 @@ function permutation(S: string): string[] {
* @return {string[]}
*/
var permutation = function (S) {
- const cs = S.split('').sort();
- const ans = [];
- const n = cs.length;
+ const s = S.split('').sort();
+ const n = s.length;
+ const t = Array(n).fill('');
const vis = Array(n).fill(false);
- const t = [];
+ const ans = [];
const dfs = i => {
- if (i === n) {
+ if (i >= n) {
ans.push(t.join(''));
return;
}
for (let j = 0; j < n; ++j) {
- if (vis[j] || (j > 0 && !vis[j - 1] && cs[j] === cs[j - 1])) {
- continue;
+ if (!vis[j] && (j === 0 || s[j] !== s[j - 1] || vis[j - 1])) {
+ vis[j] = true;
+ t[i] = s[j];
+ dfs(i + 1);
+ vis[j] = false;
}
- vis[j] = true;
- t.push(cs[j]);
- dfs(i + 1);
- t.pop();
- vis[j] = false;
}
};
dfs(0);
@@ -255,36 +242,30 @@ var permutation = function (S) {
```swift
class Solution {
- private var n: Int = 0
- private var cs: [Character] = []
- private var ans: [String] = []
- private var vis: [Bool] = []
- private var t: String = ""
-
func permutation(_ S: String) -> [String] {
- cs = Array(S)
- n = cs.count
- cs.sort()
- vis = Array(repeating: false, count: n)
- dfs(0)
- return ans
- }
-
- private func dfs(_ i: Int) {
- if i == n {
- ans.append(t)
- return
- }
- for j in 0.. 0 && !vis[j - 1] && cs[j] == cs[j - 1]) {
- continue
+ var ans: [String] = []
+ var s: [Character] = Array(S).sorted()
+ var t: [Character] = Array(repeating: " ", count: s.count)
+ var vis: [Bool] = Array(repeating: false, count: s.count)
+ let n = s.count
+
+ func dfs(_ i: Int) {
+ if i >= n {
+ ans.append(String(t))
+ return
+ }
+ for j in 0.. permutation(string S) {
- vector cs(S.begin(), S.end());
- sort(cs.begin(), cs.end());
- int n = cs.size();
- vector ans;
+ ranges::sort(S);
+ string t = S;
+ int n = t.size();
vector vis(n);
- string t;
- function dfs = [&](int i) {
- if (i == n) {
- ans.push_back(t);
+ vector ans;
+ auto dfs = [&](this auto&& dfs, int i) {
+ if (i >= n) {
+ ans.emplace_back(t);
return;
}
for (int j = 0; j < n; ++j) {
- if (vis[j] || (j && !vis[j - 1] && cs[j] == cs[j - 1])) {
- continue;
+ if (!vis[j] && (j == 0 || S[j] != S[j - 1] || vis[j - 1])) {
+ vis[j] = true;
+ t[i] = S[j];
+ dfs(i + 1);
+ vis[j] = false;
}
- vis[j] = true;
- t.push_back(cs[j]);
- dfs(i + 1);
- t.pop_back();
- vis[j] = false;
}
};
dfs(0);
return ans;
}
-};
\ No newline at end of file
+};
diff --git a/lcci/08.08.Permutation II/Solution.go b/lcci/08.08.Permutation II/Solution.go
index bdb449b7c9389..ce2be679b7676 100644
--- a/lcci/08.08.Permutation II/Solution.go
+++ b/lcci/08.08.Permutation II/Solution.go
@@ -1,26 +1,23 @@
func permutation(S string) (ans []string) {
- cs := []byte(S)
- sort.Slice(cs, func(i, j int) bool { return cs[i] < cs[j] })
- t := []byte{}
- n := len(cs)
- vis := make([]bool, n)
+ s := []byte(S)
+ sort.Slice(s, func(i, j int) bool { return s[i] < s[j] })
+ t := slices.Clone(s)
+ vis := make([]bool, len(s))
var dfs func(int)
dfs = func(i int) {
- if i == n {
+ if i >= len(s) {
ans = append(ans, string(t))
return
}
- for j := 0; j < n; j++ {
- if vis[j] || (j > 0 && !vis[j-1] && cs[j] == cs[j-1]) {
- continue
+ for j := range s {
+ if !vis[j] && (j == 0 || s[j] != s[j-1] || vis[j-1]) {
+ vis[j] = true
+ t[i] = s[j]
+ dfs(i + 1)
+ vis[j] = false
}
- vis[j] = true
- t = append(t, cs[j])
- dfs(i + 1)
- t = t[:len(t)-1]
- vis[j] = false
}
}
dfs(0)
return
-}
\ No newline at end of file
+}
diff --git a/lcci/08.08.Permutation II/Solution.java b/lcci/08.08.Permutation II/Solution.java
index e0dffd2d0cfae..b03452a42cd0d 100644
--- a/lcci/08.08.Permutation II/Solution.java
+++ b/lcci/08.08.Permutation II/Solution.java
@@ -1,33 +1,31 @@
class Solution {
- private int n;
- private char[] cs;
- private List ans = new ArrayList<>();
+ private char[] s;
+ private char[] t;
private boolean[] vis;
- private StringBuilder t = new StringBuilder();
+ private List ans = new ArrayList<>();
public String[] permutation(String S) {
- cs = S.toCharArray();
- n = cs.length;
- Arrays.sort(cs);
+ int n = S.length();
+ s = S.toCharArray();
+ Arrays.sort(s);
+ t = new char[n];
vis = new boolean[n];
dfs(0);
return ans.toArray(new String[0]);
}
private void dfs(int i) {
- if (i == n) {
- ans.add(t.toString());
+ if (i >= s.length) {
+ ans.add(new String(t));
return;
}
- for (int j = 0; j < n; ++j) {
- if (vis[j] || (j > 0 && !vis[j - 1] && cs[j] == cs[j - 1])) {
- continue;
+ for (int j = 0; j < s.length; ++j) {
+ if (!vis[j] && (j == 0 || s[j] != s[j - 1] || vis[j - 1])) {
+ vis[j] = true;
+ t[i] = s[j];
+ dfs(i + 1);
+ vis[j] = false;
}
- vis[j] = true;
- t.append(cs[j]);
- dfs(i + 1);
- t.deleteCharAt(t.length() - 1);
- vis[j] = false;
}
}
-}
\ No newline at end of file
+}
diff --git a/lcci/08.08.Permutation II/Solution.js b/lcci/08.08.Permutation II/Solution.js
index 44aed97be109c..4bb6b59170d9f 100644
--- a/lcci/08.08.Permutation II/Solution.js
+++ b/lcci/08.08.Permutation II/Solution.js
@@ -3,25 +3,23 @@
* @return {string[]}
*/
var permutation = function (S) {
- const cs = S.split('').sort();
- const ans = [];
- const n = cs.length;
+ const s = S.split('').sort();
+ const n = s.length;
+ const t = Array(n).fill('');
const vis = Array(n).fill(false);
- const t = [];
+ const ans = [];
const dfs = i => {
- if (i === n) {
+ if (i >= n) {
ans.push(t.join(''));
return;
}
for (let j = 0; j < n; ++j) {
- if (vis[j] || (j > 0 && !vis[j - 1] && cs[j] === cs[j - 1])) {
- continue;
+ if (!vis[j] && (j === 0 || s[j] !== s[j - 1] || vis[j - 1])) {
+ vis[j] = true;
+ t[i] = s[j];
+ dfs(i + 1);
+ vis[j] = false;
}
- vis[j] = true;
- t.push(cs[j]);
- dfs(i + 1);
- t.pop();
- vis[j] = false;
}
};
dfs(0);
diff --git a/lcci/08.08.Permutation II/Solution.py b/lcci/08.08.Permutation II/Solution.py
index e6b19ccba395a..e39d27633f10d 100644
--- a/lcci/08.08.Permutation II/Solution.py
+++ b/lcci/08.08.Permutation II/Solution.py
@@ -1,21 +1,20 @@
class Solution:
def permutation(self, S: str) -> List[str]:
def dfs(i: int):
- if i == n:
+ if i >= n:
ans.append("".join(t))
return
- for j in range(n):
- if vis[j] or (j and cs[j] == cs[j - 1] and not vis[j - 1]):
- continue
- t[i] = cs[j]
- vis[j] = True
- dfs(i + 1)
- vis[j] = False
+ for j, c in enumerate(s):
+ if not vis[j] and (j == 0 or s[j] != s[j - 1] or vis[j - 1]):
+ vis[j] = True
+ t[i] = c
+ dfs(i + 1)
+ vis[j] = False
- cs = sorted(S)
- n = len(cs)
+ s = sorted(S)
ans = []
- t = [None] * n
+ t = s[:]
+ n = len(s)
vis = [False] * n
dfs(0)
return ans
diff --git a/lcci/08.08.Permutation II/Solution.swift b/lcci/08.08.Permutation II/Solution.swift
index a00ac743ff082..84151d360dc86 100644
--- a/lcci/08.08.Permutation II/Solution.swift
+++ b/lcci/08.08.Permutation II/Solution.swift
@@ -1,33 +1,27 @@
class Solution {
- private var n: Int = 0
- private var cs: [Character] = []
- private var ans: [String] = []
- private var vis: [Bool] = []
- private var t: String = ""
-
func permutation(_ S: String) -> [String] {
- cs = Array(S)
- n = cs.count
- cs.sort()
- vis = Array(repeating: false, count: n)
- dfs(0)
- return ans
- }
+ var ans: [String] = []
+ var s: [Character] = Array(S).sorted()
+ var t: [Character] = Array(repeating: " ", count: s.count)
+ var vis: [Bool] = Array(repeating: false, count: s.count)
+ let n = s.count
- private func dfs(_ i: Int) {
- if i == n {
- ans.append(t)
- return
- }
- for j in 0.. 0 && !vis[j - 1] && cs[j] == cs[j - 1]) {
- continue
+ func dfs(_ i: Int) {
+ if i >= n {
+ ans.append(String(t))
+ return
+ }
+ for j in 0.. {
- if (i === n) {
+ if (i >= n) {
ans.push(t.join(''));
return;
}
for (let j = 0; j < n; ++j) {
- if (vis[j] || (j > 0 && !vis[j - 1] && cs[j] === cs[j - 1])) {
- continue;
+ if (!vis[j] && (j === 0 || s[j] !== s[j - 1] || vis[j - 1])) {
+ vis[j] = true;
+ t[i] = s[j];
+ dfs(i + 1);
+ vis[j] = false;
}
- vis[j] = true;
- t.push(cs[j]);
- dfs(i + 1);
- t.pop();
- vis[j] = false;
}
};
dfs(0);
diff --git a/lcci/08.09.Bracket/README.md b/lcci/08.09.Bracket/README.md
index 6e4a46e5769b9..7272118acce4c 100644
--- a/lcci/08.09.Bracket/README.md
+++ b/lcci/08.09.Bracket/README.md
@@ -104,8 +104,7 @@ class Solution {
public:
vector generateParenthesis(int n) {
vector ans;
- function dfs;
- dfs = [&](int l, int r, string t) {
+ auto dfs = [&](this auto&& dfs, int l, int r, string t) {
if (l > n || r > n || l < r) return;
if (l == n && r == n) {
ans.push_back(t);
diff --git a/lcci/08.09.Bracket/README_EN.md b/lcci/08.09.Bracket/README_EN.md
index 295bd24efe68f..36ee966e887ab 100644
--- a/lcci/08.09.Bracket/README_EN.md
+++ b/lcci/08.09.Bracket/README_EN.md
@@ -112,8 +112,7 @@ class Solution {
public:
vector generateParenthesis(int n) {
vector ans;
- function dfs;
- dfs = [&](int l, int r, string t) {
+ auto dfs = [&](this auto&& dfs, int l, int r, string t) {
if (l > n || r > n || l < r) return;
if (l == n && r == n) {
ans.push_back(t);
diff --git a/lcci/08.09.Bracket/Solution.cpp b/lcci/08.09.Bracket/Solution.cpp
index 4c9a371b251c4..d386301341d2c 100644
--- a/lcci/08.09.Bracket/Solution.cpp
+++ b/lcci/08.09.Bracket/Solution.cpp
@@ -2,8 +2,7 @@ class Solution {
public:
vector generateParenthesis(int n) {
vector ans;
- function dfs;
- dfs = [&](int l, int r, string t) {
+ auto dfs = [&](this auto&& dfs, int l, int r, string t) {
if (l > n || r > n || l < r) return;
if (l == n && r == n) {
ans.push_back(t);
@@ -15,4 +14,4 @@ class Solution {
dfs(0, 0, "");
return ans;
}
-};
\ No newline at end of file
+};
diff --git a/lcci/17.15.Longest Word/README.md b/lcci/17.15.Longest Word/README.md
index a9840705c9c6a..0f6dffe5c3aa8 100644
--- a/lcci/17.15.Longest Word/README.md
+++ b/lcci/17.15.Longest Word/README.md
@@ -32,117 +32,79 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcci/17.15.Longest%20Word/
-### 方法一:前缀树 + DFS
+### 方法一:哈希表 + 排序 + DFS
+
+注意,题目中,每个单词实际上允许重复使用。
+
+我们可以用一个哈希表 $\textit{s}$ 存储所有单词,然后对单词按照长度降序排序,如果长度相同,按照字典序升序排序。
+
+接下来,我们遍历排序后的单词列表,对于每个单词 $\textit{w}$,我们先将其从哈希表 $\textit{s}$ 中移除,然后使用深度优先搜索 $\textit{dfs}$ 判断 $\textit{w}$ 是否可以由其他单词组成,如果可以,返回 $\textit{w}$。
+
+函数 $\textit{dfs}$ 的执行逻辑如下:
+
+- 如果 $\textit{w}$ 为空,返回 $\text{true}$;
+- 遍历 $\textit{w}$ 的所有前缀,如果前缀在哈希表 $\textit{s}$ 中且 $\textit{dfs}$ 返回 $\text{true}$,则返回 $\text{true}$;
+- 如果没有符合条件的前缀,返回 $\text{false}$。
+
+如果没有找到符合条件的单词,返回空字符串。
+
+时间复杂度 $O(m \times n \times \log n + n \times 2^M)$,空间复杂度 $O(m \times n)$。其中 $n$ 和 $m$ 分别为单词列表的长度和单词的平均长度,而 $M$ 为最长单词的长度。
#### Python3
```python
-class Trie:
- def __init__(self):
- self.children = [None] * 26
- self.is_end = False
-
- def insert(self, word):
- node = self
- for c in word:
- idx = ord(c) - ord('a')
- if node.children[idx] is None:
- node.children[idx] = Trie()
- node = node.children[idx]
- node.is_end = True
-
- def search(self, word):
- node = self
- for c in word:
- idx = ord(c) - ord('a')
- if node.children[idx] is None:
- return False
- node = node.children[idx]
- return node.is_end
-
-
class Solution:
def longestWord(self, words: List[str]) -> str:
- def cmp(a, b):
- if len(a) != len(b):
- return len(a) - len(b)
- return -1 if a > b else 1
-
- def dfs(w):
- return not w or any(
- trie.search(w[:i]) and dfs(w[i:]) for i in range(1, len(w) + 1)
- )
-
- words.sort(key=cmp_to_key(cmp))
- trie = Trie()
- ans = ""
+ def dfs(w: str) -> bool:
+ if not w:
+ return True
+ for k in range(1, len(w) + 1):
+ if w[:k] in s and dfs(w[k:]):
+ return True
+ return False
+
+ s = set(words)
+ words.sort(key=lambda x: (-len(x), x))
for w in words:
+ s.remove(w)
if dfs(w):
- ans = w
- trie.insert(w)
- return ans
+ return w
+ return ""
```
#### Java
```java
-class Trie {
- Trie[] children = new Trie[26];
- boolean isEnd;
-
- void insert(String word) {
- Trie node = this;
- for (char c : word.toCharArray()) {
- c -= 'a';
- if (node.children[c] == null) {
- node.children[c] = new Trie();
- }
- node = node.children[c];
- }
- node.isEnd = true;
- }
-
- boolean search(String word) {
- Trie node = this;
- for (char c : word.toCharArray()) {
- c -= 'a';
- if (node.children[c] == null) {
- return false;
- }
- node = node.children[c];
- }
- return node.isEnd;
- }
-}
-
class Solution {
- private Trie trie = new Trie();
+ private Set s = new HashSet<>();
public String longestWord(String[] words) {
+ for (String w : words) {
+ s.add(w);
+ }
Arrays.sort(words, (a, b) -> {
if (a.length() != b.length()) {
- return a.length() - b.length();
+ return b.length() - a.length();
}
- return b.compareTo(a);
+ return a.compareTo(b);
});
- String ans = "";
for (String w : words) {
+ s.remove(w);
if (dfs(w)) {
- ans = w;
+ return w;
}
- trie.insert(w);
}
- return ans;
+ return "";
}
private boolean dfs(String w) {
- if ("".equals(w)) {
+ if (w.length() == 0) {
return true;
}
- for (int i = 1; i <= w.length(); ++i) {
- if (trie.search(w.substring(0, i)) && dfs(w.substring(i))) {
+ for (int k = 1; k <= w.length(); ++k) {
+ if (s.contains(w.substring(0, k)) && dfs(w.substring(k))) {
return true;
}
}
@@ -151,131 +113,171 @@ class Solution {
}
```
-#### Go
-
-```go
-type Trie struct {
- children [26]*Trie
- isEnd bool
-}
+#### C++
-func newTrie() *Trie {
- return &Trie{}
-}
-func (this *Trie) insert(word string) {
- node := this
- for _, c := range word {
- c -= 'a'
- if node.children[c] == nil {
- node.children[c] = newTrie()
- }
- node = node.children[c]
- }
- node.isEnd = true
-}
+```cpp
+class Solution {
+public:
+ string longestWord(vector& words) {
+ unordered_set s(words.begin(), words.end());
+ ranges::sort(words, [&](const string& a, const string& b) {
+ return a.size() > b.size() || (a.size() == b.size() && a < b);
+ });
+ auto dfs = [&](this auto&& dfs, string w) -> bool {
+ if (w.empty()) {
+ return true;
+ }
+ for (int k = 1; k <= w.size(); ++k) {
+ if (s.contains(w.substr(0, k)) && dfs(w.substr(k))) {
+ return true;
+ }
+ }
+ return false;
+ };
+ for (const string& w : words) {
+ s.erase(w);
+ if (dfs(w)) {
+ return w;
+ }
+ }
+ return "";
+ }
+};
+```
-func (this *Trie) search(word string) bool {
- node := this
- for _, c := range word {
- c -= 'a'
- if node.children[c] == nil {
- return false
- }
- node = node.children[c]
- }
- return node.isEnd
-}
+#### Go
+```go
func longestWord(words []string) string {
+ s := map[string]bool{}
+ for _, w := range words {
+ s[w] = true
+ }
sort.Slice(words, func(i, j int) bool {
- a, b := words[i], words[j]
- if len(a) != len(b) {
- return len(a) < len(b)
- }
- return a > b
+ return len(words[i]) > len(words[j]) || (len(words[i]) == len(words[j]) && words[i] < words[j])
})
- trie := newTrie()
var dfs func(string) bool
dfs = func(w string) bool {
if len(w) == 0 {
return true
}
- for i := 1; i <= len(w); i++ {
- if trie.search(w[:i]) && dfs(w[i:]) {
+ for k := 1; k <= len(w); k++ {
+ if s[w[:k]] && dfs(w[k:]) {
return true
}
}
return false
}
- ans := ""
for _, w := range words {
+ s[w] = false
if dfs(w) {
- ans = w
+ return w
}
- trie.insert(w)
}
- return ans
+ return ""
}
```
-#### Swift
+#### TypeScript
-```swift
-class Trie {
- var children = [Trie?](repeating: nil, count: 26)
- var isEnd = false
-
- func insert(_ word: String) {
- var node = self
- for ch in word {
- let index = Int(ch.asciiValue! - Character("a").asciiValue!)
- if node.children[index] == nil {
- node.children[index] = Trie()
+```ts
+function longestWord(words: string[]): string {
+ const s = new Set(words);
+
+ words.sort((a, b) => (a.length === b.length ? a.localeCompare(b) : b.length - a.length));
+
+ const dfs = (w: string): boolean => {
+ if (w === '') {
+ return true;
+ }
+ for (let k = 1; k <= w.length; ++k) {
+ if (s.has(w.substring(0, k)) && dfs(w.substring(k))) {
+ return true;
}
- node = node.children[index]!
}
- node.isEnd = true
+ return false;
+ };
+
+ for (const w of words) {
+ s.delete(w);
+ if (dfs(w)) {
+ return w;
+ }
}
- func search(_ word: String) -> Bool {
- var node = self
- for ch in word {
- let index = Int(ch.asciiValue! - Character("a").asciiValue!)
- if node.children[index] == nil {
- return false
+ return '';
+}
+```
+
+#### Rust
+
+```rust
+use std::collections::HashSet;
+
+impl Solution {
+ pub fn longest_word(words: Vec) -> String {
+ let mut s: HashSet = words.iter().cloned().collect();
+ let mut words = words;
+ words.sort_by(|a, b| b.len().cmp(&a.len()).then(a.cmp(b)));
+
+ fn dfs(w: String, s: &mut HashSet) -> bool {
+ if w.is_empty() {
+ return true;
}
- node = node.children[index]!
+ for k in 1..=w.len() {
+ if s.contains(&w[0..k]) && dfs(w[k..].to_string(), s) {
+ return true;
+ }
+ }
+ false
}
- return node.isEnd
+ for w in words {
+ s.remove(&w);
+ if dfs(w.clone(), &mut s) {
+ return w;
+ }
+ }
+ String::new()
}
}
+```
+
+#### Swift
+```swift
class Solution {
func longestWord(_ words: [String]) -> String {
- var words = words.sorted(by: { $0.count < $1.count || ($0.count == $1.count && $0 > $1) })
- let trie = Trie()
+ var s: Set = Set(words)
+ var words = words
+ words.sort { (a, b) -> Bool in
+ if a.count == b.count {
+ return a < b
+ } else {
+ return a.count > b.count
+ }
+ }
- var dfs: ((String) -> Bool)!
- dfs = { w in
+ func dfs(_ w: String) -> Bool {
if w.isEmpty {
return true
}
- for i in 1...w.count {
- if trie.search(String(w.prefix(i))) && dfs(String(w.suffix(w.count - i))) {
+ for k in 1...w.count {
+ let prefix = String(w.prefix(k))
+ if s.contains(prefix) && dfs(String(w.dropFirst(k))) {
return true
}
}
return false
}
- var ans = ""
for w in words {
+ s.remove(w)
if dfs(w) {
- ans = w
+ return w
}
- trie.insert(w)
}
- return ans
+
+ return ""
}
}
```
diff --git a/lcci/17.15.Longest Word/README_EN.md b/lcci/17.15.Longest Word/README_EN.md
index 7d5dcf7f14dec..131326adf233f 100644
--- a/lcci/17.15.Longest Word/README_EN.md
+++ b/lcci/17.15.Longest Word/README_EN.md
@@ -41,117 +41,79 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcci/17.15.Longest%20Word/
-### Solution 1
+### Solution 1: Hash Table + Sorting + DFS
+
+Note that in the problem, each word can actually be reused.
+
+We can use a hash table $\textit{s}$ to store all the words, then sort the words in descending order of length, and if the lengths are the same, sort them in ascending lexicographical order.
+
+Next, we iterate through the sorted list of words. For each word $\textit{w}$, we first remove it from the hash table $\textit{s}$, then use depth-first search $\textit{dfs}$ to determine if $\textit{w}$ can be composed of other words. If it can, we return $\textit{w}$.
+
+The execution logic of the function $\textit{dfs}$ is as follows:
+
+- If $\textit{w}$ is empty, return $\text{true}$;
+- Iterate through all prefixes of $\textit{w}$. If a prefix is in the hash table $\textit{s}$ and $\textit{dfs}$ returns $\text{true}$, then return $\text{true}$;
+- If no prefix meets the condition, return $\text{false}$.
+
+If no word meets the condition, return an empty string.
+
+The time complexity is $O(m \times n \times \log n + n \times 2^M)$, and the space complexity is $O(m \times n)$. Here, $n$ and $m$ are the length of the word list and the average length of the words, respectively, and $M$ is the length of the longest word.
#### Python3
```python
-class Trie:
- def __init__(self):
- self.children = [None] * 26
- self.is_end = False
-
- def insert(self, word):
- node = self
- for c in word:
- idx = ord(c) - ord('a')
- if node.children[idx] is None:
- node.children[idx] = Trie()
- node = node.children[idx]
- node.is_end = True
-
- def search(self, word):
- node = self
- for c in word:
- idx = ord(c) - ord('a')
- if node.children[idx] is None:
- return False
- node = node.children[idx]
- return node.is_end
-
-
class Solution:
def longestWord(self, words: List[str]) -> str:
- def cmp(a, b):
- if len(a) != len(b):
- return len(a) - len(b)
- return -1 if a > b else 1
-
- def dfs(w):
- return not w or any(
- trie.search(w[:i]) and dfs(w[i:]) for i in range(1, len(w) + 1)
- )
-
- words.sort(key=cmp_to_key(cmp))
- trie = Trie()
- ans = ""
+ def dfs(w: str) -> bool:
+ if not w:
+ return True
+ for k in range(1, len(w) + 1):
+ if w[:k] in s and dfs(w[k:]):
+ return True
+ return False
+
+ s = set(words)
+ words.sort(key=lambda x: (-len(x), x))
for w in words:
+ s.remove(w)
if dfs(w):
- ans = w
- trie.insert(w)
- return ans
+ return w
+ return ""
```
#### Java
```java
-class Trie {
- Trie[] children = new Trie[26];
- boolean isEnd;
-
- void insert(String word) {
- Trie node = this;
- for (char c : word.toCharArray()) {
- c -= 'a';
- if (node.children[c] == null) {
- node.children[c] = new Trie();
- }
- node = node.children[c];
- }
- node.isEnd = true;
- }
-
- boolean search(String word) {
- Trie node = this;
- for (char c : word.toCharArray()) {
- c -= 'a';
- if (node.children[c] == null) {
- return false;
- }
- node = node.children[c];
- }
- return node.isEnd;
- }
-}
-
class Solution {
- private Trie trie = new Trie();
+ private Set s = new HashSet<>();
public String longestWord(String[] words) {
+ for (String w : words) {
+ s.add(w);
+ }
Arrays.sort(words, (a, b) -> {
if (a.length() != b.length()) {
- return a.length() - b.length();
+ return b.length() - a.length();
}
- return b.compareTo(a);
+ return a.compareTo(b);
});
- String ans = "";
for (String w : words) {
+ s.remove(w);
if (dfs(w)) {
- ans = w;
+ return w;
}
- trie.insert(w);
}
- return ans;
+ return "";
}
private boolean dfs(String w) {
- if ("".equals(w)) {
+ if (w.length() == 0) {
return true;
}
- for (int i = 1; i <= w.length(); ++i) {
- if (trie.search(w.substring(0, i)) && dfs(w.substring(i))) {
+ for (int k = 1; k <= w.length(); ++k) {
+ if (s.contains(w.substring(0, k)) && dfs(w.substring(k))) {
return true;
}
}
@@ -160,131 +122,171 @@ class Solution {
}
```
-#### Go
-
-```go
-type Trie struct {
- children [26]*Trie
- isEnd bool
-}
+#### C++
-func newTrie() *Trie {
- return &Trie{}
-}
-func (this *Trie) insert(word string) {
- node := this
- for _, c := range word {
- c -= 'a'
- if node.children[c] == nil {
- node.children[c] = newTrie()
- }
- node = node.children[c]
- }
- node.isEnd = true
-}
+```cpp
+class Solution {
+public:
+ string longestWord(vector& words) {
+ unordered_set s(words.begin(), words.end());
+ ranges::sort(words, [&](const string& a, const string& b) {
+ return a.size() > b.size() || (a.size() == b.size() && a < b);
+ });
+ auto dfs = [&](this auto&& dfs, string w) -> bool {
+ if (w.empty()) {
+ return true;
+ }
+ for (int k = 1; k <= w.size(); ++k) {
+ if (s.contains(w.substr(0, k)) && dfs(w.substr(k))) {
+ return true;
+ }
+ }
+ return false;
+ };
+ for (const string& w : words) {
+ s.erase(w);
+ if (dfs(w)) {
+ return w;
+ }
+ }
+ return "";
+ }
+};
+```
-func (this *Trie) search(word string) bool {
- node := this
- for _, c := range word {
- c -= 'a'
- if node.children[c] == nil {
- return false
- }
- node = node.children[c]
- }
- return node.isEnd
-}
+#### Go
+```go
func longestWord(words []string) string {
+ s := map[string]bool{}
+ for _, w := range words {
+ s[w] = true
+ }
sort.Slice(words, func(i, j int) bool {
- a, b := words[i], words[j]
- if len(a) != len(b) {
- return len(a) < len(b)
- }
- return a > b
+ return len(words[i]) > len(words[j]) || (len(words[i]) == len(words[j]) && words[i] < words[j])
})
- trie := newTrie()
var dfs func(string) bool
dfs = func(w string) bool {
if len(w) == 0 {
return true
}
- for i := 1; i <= len(w); i++ {
- if trie.search(w[:i]) && dfs(w[i:]) {
+ for k := 1; k <= len(w); k++ {
+ if s[w[:k]] && dfs(w[k:]) {
return true
}
}
return false
}
- ans := ""
for _, w := range words {
+ s[w] = false
if dfs(w) {
- ans = w
+ return w
}
- trie.insert(w)
}
- return ans
+ return ""
}
```
-#### Swift
+#### TypeScript
-```swift
-class Trie {
- var children = [Trie?](repeating: nil, count: 26)
- var isEnd = false
-
- func insert(_ word: String) {
- var node = self
- for ch in word {
- let index = Int(ch.asciiValue! - Character("a").asciiValue!)
- if node.children[index] == nil {
- node.children[index] = Trie()
+```ts
+function longestWord(words: string[]): string {
+ const s = new Set(words);
+
+ words.sort((a, b) => (a.length === b.length ? a.localeCompare(b) : b.length - a.length));
+
+ const dfs = (w: string): boolean => {
+ if (w === '') {
+ return true;
+ }
+ for (let k = 1; k <= w.length; ++k) {
+ if (s.has(w.substring(0, k)) && dfs(w.substring(k))) {
+ return true;
}
- node = node.children[index]!
}
- node.isEnd = true
+ return false;
+ };
+
+ for (const w of words) {
+ s.delete(w);
+ if (dfs(w)) {
+ return w;
+ }
}
- func search(_ word: String) -> Bool {
- var node = self
- for ch in word {
- let index = Int(ch.asciiValue! - Character("a").asciiValue!)
- if node.children[index] == nil {
- return false
+ return '';
+}
+```
+
+#### Rust
+
+```rust
+use std::collections::HashSet;
+
+impl Solution {
+ pub fn longest_word(words: Vec) -> String {
+ let mut s: HashSet = words.iter().cloned().collect();
+ let mut words = words;
+ words.sort_by(|a, b| b.len().cmp(&a.len()).then(a.cmp(b)));
+
+ fn dfs(w: String, s: &mut HashSet) -> bool {
+ if w.is_empty() {
+ return true;
}
- node = node.children[index]!
+ for k in 1..=w.len() {
+ if s.contains(&w[0..k]) && dfs(w[k..].to_string(), s) {
+ return true;
+ }
+ }
+ false
}
- return node.isEnd
+ for w in words {
+ s.remove(&w);
+ if dfs(w.clone(), &mut s) {
+ return w;
+ }
+ }
+ String::new()
}
}
+```
+
+#### Swift
+```swift
class Solution {
func longestWord(_ words: [String]) -> String {
- var words = words.sorted(by: { $0.count < $1.count || ($0.count == $1.count && $0 > $1) })
- let trie = Trie()
+ var s: Set = Set(words)
+ var words = words
+ words.sort { (a, b) -> Bool in
+ if a.count == b.count {
+ return a < b
+ } else {
+ return a.count > b.count
+ }
+ }
- var dfs: ((String) -> Bool)!
- dfs = { w in
+ func dfs(_ w: String) -> Bool {
if w.isEmpty {
return true
}
- for i in 1...w.count {
- if trie.search(String(w.prefix(i))) && dfs(String(w.suffix(w.count - i))) {
+ for k in 1...w.count {
+ let prefix = String(w.prefix(k))
+ if s.contains(prefix) && dfs(String(w.dropFirst(k))) {
return true
}
}
return false
}
- var ans = ""
for w in words {
+ s.remove(w)
if dfs(w) {
- ans = w
+ return w
}
- trie.insert(w)
}
- return ans
+
+ return ""
}
}
```
diff --git a/lcci/17.15.Longest Word/Solution.cpp b/lcci/17.15.Longest Word/Solution.cpp
new file mode 100644
index 0000000000000..19b158b023c7d
--- /dev/null
+++ b/lcci/17.15.Longest Word/Solution.cpp
@@ -0,0 +1,27 @@
+class Solution {
+public:
+ string longestWord(vector& words) {
+ unordered_set s(words.begin(), words.end());
+ ranges::sort(words, [&](const string& a, const string& b) {
+ return a.size() > b.size() || (a.size() == b.size() && a < b);
+ });
+ auto dfs = [&](this auto&& dfs, string w) -> bool {
+ if (w.empty()) {
+ return true;
+ }
+ for (int k = 1; k <= w.size(); ++k) {
+ if (s.contains(w.substr(0, k)) && dfs(w.substr(k))) {
+ return true;
+ }
+ }
+ return false;
+ };
+ for (const string& w : words) {
+ s.erase(w);
+ if (dfs(w)) {
+ return w;
+ }
+ }
+ return "";
+ }
+};
diff --git a/lcci/17.15.Longest Word/Solution.go b/lcci/17.15.Longest Word/Solution.go
index 2a6dbd07cf5a4..321fb05d318ae 100644
--- a/lcci/17.15.Longest Word/Solution.go
+++ b/lcci/17.15.Longest Word/Solution.go
@@ -1,62 +1,28 @@
-type Trie struct {
- children [26]*Trie
- isEnd bool
-}
-
-func newTrie() *Trie {
- return &Trie{}
-}
-func (this *Trie) insert(word string) {
- node := this
- for _, c := range word {
- c -= 'a'
- if node.children[c] == nil {
- node.children[c] = newTrie()
- }
- node = node.children[c]
- }
- node.isEnd = true
-}
-
-func (this *Trie) search(word string) bool {
- node := this
- for _, c := range word {
- c -= 'a'
- if node.children[c] == nil {
- return false
- }
- node = node.children[c]
- }
- return node.isEnd
-}
-
func longestWord(words []string) string {
+ s := map[string]bool{}
+ for _, w := range words {
+ s[w] = true
+ }
sort.Slice(words, func(i, j int) bool {
- a, b := words[i], words[j]
- if len(a) != len(b) {
- return len(a) < len(b)
- }
- return a > b
+ return len(words[i]) > len(words[j]) || (len(words[i]) == len(words[j]) && words[i] < words[j])
})
- trie := newTrie()
var dfs func(string) bool
dfs = func(w string) bool {
if len(w) == 0 {
return true
}
- for i := 1; i <= len(w); i++ {
- if trie.search(w[:i]) && dfs(w[i:]) {
+ for k := 1; k <= len(w); k++ {
+ if s[w[:k]] && dfs(w[k:]) {
return true
}
}
return false
}
- ans := ""
for _, w := range words {
+ s[w] = false
if dfs(w) {
- ans = w
+ return w
}
- trie.insert(w)
}
- return ans
-}
\ No newline at end of file
+ return ""
+}
diff --git a/lcci/17.15.Longest Word/Solution.java b/lcci/17.15.Longest Word/Solution.java
index 2d6e2d40bd4c3..e7bbcc380a592 100644
--- a/lcci/17.15.Longest Word/Solution.java
+++ b/lcci/17.15.Longest Word/Solution.java
@@ -1,61 +1,34 @@
-class Trie {
- Trie[] children = new Trie[26];
- boolean isEnd;
-
- void insert(String word) {
- Trie node = this;
- for (char c : word.toCharArray()) {
- c -= 'a';
- if (node.children[c] == null) {
- node.children[c] = new Trie();
- }
- node = node.children[c];
- }
- node.isEnd = true;
- }
-
- boolean search(String word) {
- Trie node = this;
- for (char c : word.toCharArray()) {
- c -= 'a';
- if (node.children[c] == null) {
- return false;
- }
- node = node.children[c];
- }
- return node.isEnd;
- }
-}
-
class Solution {
- private Trie trie = new Trie();
+ private Set s = new HashSet<>();
public String longestWord(String[] words) {
+ for (String w : words) {
+ s.add(w);
+ }
Arrays.sort(words, (a, b) -> {
if (a.length() != b.length()) {
- return a.length() - b.length();
+ return b.length() - a.length();
}
- return b.compareTo(a);
+ return a.compareTo(b);
});
- String ans = "";
for (String w : words) {
+ s.remove(w);
if (dfs(w)) {
- ans = w;
+ return w;
}
- trie.insert(w);
}
- return ans;
+ return "";
}
private boolean dfs(String w) {
- if ("".equals(w)) {
+ if (w.length() == 0) {
return true;
}
- for (int i = 1; i <= w.length(); ++i) {
- if (trie.search(w.substring(0, i)) && dfs(w.substring(i))) {
+ for (int k = 1; k <= w.length(); ++k) {
+ if (s.contains(w.substring(0, k)) && dfs(w.substring(k))) {
return true;
}
}
return false;
}
-}
\ No newline at end of file
+}
diff --git a/lcci/17.15.Longest Word/Solution.py b/lcci/17.15.Longest Word/Solution.py
index 5a5b69545a1a2..c2dd7b8387c09 100644
--- a/lcci/17.15.Longest Word/Solution.py
+++ b/lcci/17.15.Longest Word/Solution.py
@@ -1,44 +1,17 @@
-class Trie:
- def __init__(self):
- self.children = [None] * 26
- self.is_end = False
-
- def insert(self, word):
- node = self
- for c in word:
- idx = ord(c) - ord('a')
- if node.children[idx] is None:
- node.children[idx] = Trie()
- node = node.children[idx]
- node.is_end = True
-
- def search(self, word):
- node = self
- for c in word:
- idx = ord(c) - ord('a')
- if node.children[idx] is None:
- return False
- node = node.children[idx]
- return node.is_end
-
-
class Solution:
def longestWord(self, words: List[str]) -> str:
- def cmp(a, b):
- if len(a) != len(b):
- return len(a) - len(b)
- return -1 if a > b else 1
-
- def dfs(w):
- return not w or any(
- trie.search(w[:i]) and dfs(w[i:]) for i in range(1, len(w) + 1)
- )
+ def dfs(w: str) -> bool:
+ if not w:
+ return True
+ for k in range(1, len(w) + 1):
+ if w[:k] in s and dfs(w[k:]):
+ return True
+ return False
- words.sort(key=cmp_to_key(cmp))
- trie = Trie()
- ans = ""
+ s = set(words)
+ words.sort(key=lambda x: (-len(x), x))
for w in words:
+ s.remove(w)
if dfs(w):
- ans = w
- trie.insert(w)
- return ans
+ return w
+ return ""
diff --git a/lcci/17.15.Longest Word/Solution.rs b/lcci/17.15.Longest Word/Solution.rs
new file mode 100644
index 0000000000000..068124b25c26a
--- /dev/null
+++ b/lcci/17.15.Longest Word/Solution.rs
@@ -0,0 +1,28 @@
+use std::collections::HashSet;
+
+impl Solution {
+ pub fn longest_word(words: Vec) -> String {
+ let mut s: HashSet = words.iter().cloned().collect();
+ let mut words = words;
+ words.sort_by(|a, b| b.len().cmp(&a.len()).then(a.cmp(b)));
+
+ fn dfs(w: String, s: &mut HashSet) -> bool {
+ if w.is_empty() {
+ return true;
+ }
+ for k in 1..=w.len() {
+ if s.contains(&w[0..k]) && dfs(w[k..].to_string(), s) {
+ return true;
+ }
+ }
+ false
+ }
+ for w in words {
+ s.remove(&w);
+ if dfs(w.clone(), &mut s) {
+ return w;
+ }
+ }
+ String::new()
+ }
+}
diff --git a/lcci/17.15.Longest Word/Solution.swift b/lcci/17.15.Longest Word/Solution.swift
index f05b1fc22864c..008d82149d0be 100644
--- a/lcci/17.15.Longest Word/Solution.swift
+++ b/lcci/17.15.Longest Word/Solution.swift
@@ -1,57 +1,35 @@
-class Trie {
- var children = [Trie?](repeating: nil, count: 26)
- var isEnd = false
-
- func insert(_ word: String) {
- var node = self
- for ch in word {
- let index = Int(ch.asciiValue! - Character("a").asciiValue!)
- if node.children[index] == nil {
- node.children[index] = Trie()
+class Solution {
+ func longestWord(_ words: [String]) -> String {
+ var s: Set = Set(words)
+ var words = words
+ words.sort { (a, b) -> Bool in
+ if a.count == b.count {
+ return a < b
+ } else {
+ return a.count > b.count
}
- node = node.children[index]!
}
- node.isEnd = true
- }
- func search(_ word: String) -> Bool {
- var node = self
- for ch in word {
- let index = Int(ch.asciiValue! - Character("a").asciiValue!)
- if node.children[index] == nil {
- return false
- }
- node = node.children[index]!
- }
- return node.isEnd
- }
-}
-
-class Solution {
- func longestWord(_ words: [String]) -> String {
- var words = words.sorted(by: { $0.count < $1.count || ($0.count == $1.count && $0 > $1) })
- let trie = Trie()
-
- var dfs: ((String) -> Bool)!
- dfs = { w in
+ func dfs(_ w: String) -> Bool {
if w.isEmpty {
return true
}
- for i in 1...w.count {
- if trie.search(String(w.prefix(i))) && dfs(String(w.suffix(w.count - i))) {
+ for k in 1...w.count {
+ let prefix = String(w.prefix(k))
+ if s.contains(prefix) && dfs(String(w.dropFirst(k))) {
return true
}
}
return false
}
-
- var ans = ""
+
for w in words {
+ s.remove(w)
if dfs(w) {
- ans = w
+ return w
}
- trie.insert(w)
}
- return ans
+
+ return ""
}
}
diff --git a/lcci/17.15.Longest Word/Solution.ts b/lcci/17.15.Longest Word/Solution.ts
new file mode 100644
index 0000000000000..1dc4862412162
--- /dev/null
+++ b/lcci/17.15.Longest Word/Solution.ts
@@ -0,0 +1,26 @@
+function longestWord(words: string[]): string {
+ const s = new Set(words);
+
+ words.sort((a, b) => (a.length === b.length ? a.localeCompare(b) : b.length - a.length));
+
+ const dfs = (w: string): boolean => {
+ if (w === '') {
+ return true;
+ }
+ for (let k = 1; k <= w.length; ++k) {
+ if (s.has(w.substring(0, k)) && dfs(w.substring(k))) {
+ return true;
+ }
+ }
+ return false;
+ };
+
+ for (const w of words) {
+ s.delete(w);
+ if (dfs(w)) {
+ return w;
+ }
+ }
+
+ return '';
+}
diff --git "a/lcof2/\345\211\221\346\214\207 Offer II 057. \345\200\274\345\222\214\344\270\213\346\240\207\344\271\213\345\267\256\351\203\275\345\234\250\347\273\231\345\256\232\347\232\204\350\214\203\345\233\264\345\206\205/README.md" "b/lcof2/\345\211\221\346\214\207 Offer II 057. \345\200\274\345\222\214\344\270\213\346\240\207\344\271\213\345\267\256\351\203\275\345\234\250\347\273\231\345\256\232\347\232\204\350\214\203\345\233\264\345\206\205/README.md"
index 0a7445246a6a8..dd18ee74ba2eb 100644
--- "a/lcof2/\345\211\221\346\214\207 Offer II 057. \345\200\274\345\222\214\344\270\213\346\240\207\344\271\213\345\267\256\351\203\275\345\234\250\347\273\231\345\256\232\347\232\204\350\214\203\345\233\264\345\206\205/README.md"
+++ "b/lcof2/\345\211\221\346\214\207 Offer II 057. \345\200\274\345\222\214\344\270\213\346\240\207\344\271\213\345\267\256\351\203\275\345\234\250\347\273\231\345\256\232\347\232\204\350\214\203\345\233\264\345\206\205/README.md"
@@ -69,9 +69,6 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcof2/%E5%89%91%E6%8C%87%2
#### Python3
```python
-from sortedcontainers import SortedSet
-
-
class Solution:
def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:
s = SortedSet()
diff --git "a/lcof2/\345\211\221\346\214\207 Offer II 057. \345\200\274\345\222\214\344\270\213\346\240\207\344\271\213\345\267\256\351\203\275\345\234\250\347\273\231\345\256\232\347\232\204\350\214\203\345\233\264\345\206\205/Solution.py" "b/lcof2/\345\211\221\346\214\207 Offer II 057. \345\200\274\345\222\214\344\270\213\346\240\207\344\271\213\345\267\256\351\203\275\345\234\250\347\273\231\345\256\232\347\232\204\350\214\203\345\233\264\345\206\205/Solution.py"
index f7ec481ecdd5d..b0910923928e3 100644
--- "a/lcof2/\345\211\221\346\214\207 Offer II 057. \345\200\274\345\222\214\344\270\213\346\240\207\344\271\213\345\267\256\351\203\275\345\234\250\347\273\231\345\256\232\347\232\204\350\214\203\345\233\264\345\206\205/Solution.py"
+++ "b/lcof2/\345\211\221\346\214\207 Offer II 057. \345\200\274\345\222\214\344\270\213\346\240\207\344\271\213\345\267\256\351\203\275\345\234\250\347\273\231\345\256\232\347\232\204\350\214\203\345\233\264\345\206\205/Solution.py"
@@ -1,6 +1,3 @@
-from sortedcontainers import SortedSet
-
-
class Solution:
def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:
s = SortedSet()
diff --git "a/lcof2/\345\211\221\346\214\207 Offer II 058. \346\227\245\347\250\213\350\241\250/README.md" "b/lcof2/\345\211\221\346\214\207 Offer II 058. \346\227\245\347\250\213\350\241\250/README.md"
index a3933de14e03c..54acea6311fdc 100644
--- "a/lcof2/\345\211\221\346\214\207 Offer II 058. \346\227\245\347\250\213\350\241\250/README.md"
+++ "b/lcof2/\345\211\221\346\214\207 Offer II 058. \346\227\245\347\250\213\350\241\250/README.md"
@@ -65,9 +65,6 @@ MyCalendar.book(20, 30); // returns true ,第三个日程安排可以添加到
#### Python3
```python
-from sortedcontainers import SortedDict
-
-
class MyCalendar:
def __init__(self):
self.sd = SortedDict()
@@ -89,9 +86,6 @@ class MyCalendar:
#### Java
```java
-import java.util.Map;
-import java.util.TreeMap;
-
class MyCalendar {
private final TreeMap tm = new TreeMap<>();
diff --git "a/lcof2/\345\211\221\346\214\207 Offer II 058. \346\227\245\347\250\213\350\241\250/Solution.java" "b/lcof2/\345\211\221\346\214\207 Offer II 058. \346\227\245\347\250\213\350\241\250/Solution.java"
index 3d04816dc4b2e..1bb41cffcc07f 100644
--- "a/lcof2/\345\211\221\346\214\207 Offer II 058. \346\227\245\347\250\213\350\241\250/Solution.java"
+++ "b/lcof2/\345\211\221\346\214\207 Offer II 058. \346\227\245\347\250\213\350\241\250/Solution.java"
@@ -1,6 +1,3 @@
-import java.util.Map;
-import java.util.TreeMap;
-
class MyCalendar {
private final TreeMap tm = new TreeMap<>();
@@ -25,4 +22,4 @@ public boolean book(int start, int end) {
/**
* Your MyCalendar object will be instantiated and called as such: MyCalendar
* obj = new MyCalendar(); boolean param_1 = obj.book(start,end);
- */
\ No newline at end of file
+ */
diff --git "a/lcof2/\345\211\221\346\214\207 Offer II 058. \346\227\245\347\250\213\350\241\250/Solution.py" "b/lcof2/\345\211\221\346\214\207 Offer II 058. \346\227\245\347\250\213\350\241\250/Solution.py"
index a17617ab776e9..c04195aeb8688 100644
--- "a/lcof2/\345\211\221\346\214\207 Offer II 058. \346\227\245\347\250\213\350\241\250/Solution.py"
+++ "b/lcof2/\345\211\221\346\214\207 Offer II 058. \346\227\245\347\250\213\350\241\250/Solution.py"
@@ -1,6 +1,3 @@
-from sortedcontainers import SortedDict
-
-
class MyCalendar:
def __init__(self):
self.sd = SortedDict()
diff --git "a/lcp/LCP 24. \346\225\260\345\255\227\346\270\270\346\210\217/README.md" "b/lcp/LCP 24. \346\225\260\345\255\227\346\270\270\346\210\217/README.md"
index a53ff9a0a21f1..7ed8b092d36e0 100644
--- "a/lcp/LCP 24. \346\225\260\345\255\227\346\270\270\346\210\217/README.md"
+++ "b/lcp/LCP 24. \346\225\260\345\255\227\346\270\270\346\210\217/README.md"
@@ -403,9 +403,6 @@ class Solution {
#### Python3
```python
-from sortedcontainers import SortedList
-
-
class Solution:
def numsGame(self, nums: List[int]) -> List[int]:
l = SortedList()
diff --git "a/lcp/LCP 24. \346\225\260\345\255\227\346\270\270\346\210\217/Solution2.py" "b/lcp/LCP 24. \346\225\260\345\255\227\346\270\270\346\210\217/Solution2.py"
index aad34c9845934..16088eddc4e2d 100644
--- "a/lcp/LCP 24. \346\225\260\345\255\227\346\270\270\346\210\217/Solution2.py"
+++ "b/lcp/LCP 24. \346\225\260\345\255\227\346\270\270\346\210\217/Solution2.py"
@@ -1,6 +1,3 @@
-from sortedcontainers import SortedList
-
-
class Solution:
def numsGame(self, nums: List[int]) -> List[int]:
l = SortedList()
diff --git "a/lcp/LCP 52. \344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\346\237\223\350\211\262/README.md" "b/lcp/LCP 52. \344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\346\237\223\350\211\262/README.md"
index b9fe5e883c2c5..fd875e6061c85 100644
--- "a/lcp/LCP 52. \344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\346\237\223\350\211\262/README.md"
+++ "b/lcp/LCP 52. \344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\346\237\223\350\211\262/README.md"
@@ -89,9 +89,6 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcp/LCP%2052.%20%E4%BA%8C%
# self.left = None
# self.right = None
-from sortedcontainers import SortedList
-
-
class Solution:
def getNumber(self, root: Optional[TreeNode], ops: List[List[int]]) -> int:
def dfs(root):
diff --git "a/lcp/LCP 52. \344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\346\237\223\350\211\262/Solution.py" "b/lcp/LCP 52. \344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\346\237\223\350\211\262/Solution.py"
index 2e140bdb7fd66..fe7d41876e7c8 100644
--- "a/lcp/LCP 52. \344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\346\237\223\350\211\262/Solution.py"
+++ "b/lcp/LCP 52. \344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\346\237\223\350\211\262/Solution.py"
@@ -5,8 +5,6 @@
# self.left = None
# self.right = None
-from sortedcontainers import SortedList
-
class Solution:
def getNumber(self, root: Optional[TreeNode], ops: List[List[int]]) -> int:
diff --git "a/lcp/LCP 62. \344\272\244\351\200\232\346\236\242\347\272\275/README.md" "b/lcp/LCP 62. \344\272\244\351\200\232\346\236\242\347\272\275/README.md"
index 348f106b5e995..690d01b9e1c20 100644
--- "a/lcp/LCP 62. \344\272\244\351\200\232\346\236\242\347\272\275/README.md"
+++ "b/lcp/LCP 62. \344\272\244\351\200\232\346\236\242\347\272\275/README.md"
@@ -205,6 +205,41 @@ function transportationHub(path: number[][]): number {
}
```
+#### Swift
+
+```swift
+class Solution {
+ func transportationHub(_ path: [[Int]]) -> Int {
+ var inDegree = [Int: Int]()
+ var outDegree = [Int: Int]()
+ var nodeSet = Set()
+ var visitedEdges = Set()
+
+ for p in path {
+ let a = p[0]
+ let b = p[1]
+ let edgeKey = "\(a)-\(b)"
+
+ if !visitedEdges.contains(edgeKey) {
+ visitedEdges.insert(edgeKey)
+ nodeSet.insert(a)
+ nodeSet.insert(b)
+ inDegree[b, default: 0] += 1
+ outDegree[a, default: 0] += 1
+ }
+ }
+
+ for node in nodeSet {
+ if inDegree[node, default: 0] == nodeSet.count - 1 && outDegree[node, default: 0] == 0 {
+ return node
+ }
+ }
+
+ return -1
+ }
+}
+```
+
diff --git "a/lcp/LCP 62. \344\272\244\351\200\232\346\236\242\347\272\275/Solution.swift" "b/lcp/LCP 62. \344\272\244\351\200\232\346\236\242\347\272\275/Solution.swift"
new file mode 100644
index 0000000000000..dca4332f4a733
--- /dev/null
+++ "b/lcp/LCP 62. \344\272\244\351\200\232\346\236\242\347\272\275/Solution.swift"
@@ -0,0 +1,30 @@
+class Solution {
+ func transportationHub(_ path: [[Int]]) -> Int {
+ var inDegree = [Int: Int]()
+ var outDegree = [Int: Int]()
+ var nodeSet = Set()
+ var visitedEdges = Set()
+
+ for p in path {
+ let a = p[0]
+ let b = p[1]
+ let edgeKey = "\(a)-\(b)"
+
+ if !visitedEdges.contains(edgeKey) {
+ visitedEdges.insert(edgeKey)
+ nodeSet.insert(a)
+ nodeSet.insert(b)
+ inDegree[b, default: 0] += 1
+ outDegree[a, default: 0] += 1
+ }
+ }
+
+ for node in nodeSet {
+ if inDegree[node, default: 0] == nodeSet.count - 1 && outDegree[node, default: 0] == 0 {
+ return node
+ }
+ }
+
+ return -1
+ }
+}
\ No newline at end of file
diff --git "a/lcp/LCP 63. \345\274\271\347\217\240\346\270\270\346\210\217/README.md" "b/lcp/LCP 63. \345\274\271\347\217\240\346\270\270\346\210\217/README.md"
index 2d2823b8085a5..87edf23ce9852 100644
--- "a/lcp/LCP 63. \345\274\271\347\217\240\346\270\270\346\210\217/README.md"
+++ "b/lcp/LCP 63. \345\274\271\347\217\240\346\270\270\346\210\217/README.md"
@@ -274,6 +274,80 @@ func ballGame(num int, plate []string) (ans [][]int) {
}
```
+#### Swift
+
+```swift
+class Solution {
+ private var plate: [String] = []
+ private var num: Int = 0
+ private var m: Int = 0
+ private var n: Int = 0
+ private let dirs = [0, 1, 0, -1, 0]
+
+ func ballGame(_ num: Int, _ plate: [String]) -> [[Int]] {
+ self.num = num
+ self.plate = plate
+ self.m = plate.count
+ self.n = plate[0].count
+ var ans: [[Int]] = []
+
+ for i in 1.. Bool {
+ var k = num
+ var i = i, j = j, d = d
+
+ while plate[i][j] != "O" {
+ if k == 0 {
+ return false
+ }
+
+ if plate[i][j] == "W" {
+ d = (d + 3) % 4
+ } else if plate[i][j] == "E" {
+ d = (d + 1) % 4
+ }
+
+ i += dirs[d]
+ j += dirs[d + 1]
+
+ if i < 0 || i >= m || j < 0 || j >= n {
+ return false
+ }
+
+ k -= 1
+ }
+
+ return true
+ }
+}
+
+private extension String {
+ subscript(_ index: Int) -> Character {
+ return self[self.index(self.startIndex, offsetBy: index)]
+ }
+}
+```
+
diff --git "a/lcp/LCP 63. \345\274\271\347\217\240\346\270\270\346\210\217/Solution.swift" "b/lcp/LCP 63. \345\274\271\347\217\240\346\270\270\346\210\217/Solution.swift"
new file mode 100644
index 0000000000000..6a9b7c2f07875
--- /dev/null
+++ "b/lcp/LCP 63. \345\274\271\347\217\240\346\270\270\346\210\217/Solution.swift"
@@ -0,0 +1,69 @@
+class Solution {
+ private var plate: [String] = []
+ private var num: Int = 0
+ private var m: Int = 0
+ private var n: Int = 0
+ private let dirs = [0, 1, 0, -1, 0]
+
+ func ballGame(_ num: Int, _ plate: [String]) -> [[Int]] {
+ self.num = num
+ self.plate = plate
+ self.m = plate.count
+ self.n = plate[0].count
+ var ans: [[Int]] = []
+
+ for i in 1.. Bool {
+ var k = num
+ var i = i, j = j, d = d
+
+ while plate[i][j] != "O" {
+ if k == 0 {
+ return false
+ }
+
+ if plate[i][j] == "W" {
+ d = (d + 3) % 4
+ } else if plate[i][j] == "E" {
+ d = (d + 1) % 4
+ }
+
+ i += dirs[d]
+ j += dirs[d + 1]
+
+ if i < 0 || i >= m || j < 0 || j >= n {
+ return false
+ }
+
+ k -= 1
+ }
+
+ return true
+ }
+}
+
+private extension String {
+ subscript(_ index: Int) -> Character {
+ return self[self.index(self.startIndex, offsetBy: index)]
+ }
+}
\ No newline at end of file
diff --git "a/lcp/LCP 64. \344\272\214\345\217\211\346\240\221\347\201\257\351\245\260/README.md" "b/lcp/LCP 64. \344\272\214\345\217\211\346\240\221\347\201\257\351\245\260/README.md"
index 248022131b176..f1e53e794c997 100644
--- "a/lcp/LCP 64. \344\272\214\345\217\211\346\240\221\347\201\257\351\245\260/README.md"
+++ "b/lcp/LCP 64. \344\272\214\345\217\211\346\240\221\347\201\257\351\245\260/README.md"
@@ -258,6 +258,59 @@ func closeLampInTree(root *TreeNode) (ans int) {
}
```
+#### Swift
+
+```swift
+/* public class TreeNode {
+* public var val: Int
+* public var left: TreeNode?
+* public var right: TreeNode?
+* public init(_ val: Int) {
+* self.val = val
+* self.left = nil
+* self.right = nil
+* }
+* }
+*/
+
+class Solution {
+ func closeLampInTree(_ root: TreeNode?) -> Int {
+ return dfs(root)[0]
+ }
+
+ private func dfs(_ root: TreeNode?) -> [Int] {
+ var ans = [Int](repeating: 0, count: 4)
+ guard let root = root else {
+ return ans
+ }
+
+ let left = dfs(root.left)
+ let right = dfs(root.right)
+
+ let l1 = left[0], l2 = left[1], l3 = left[2], l4 = left[3]
+ let r1 = right[0], r2 = right[1], r3 = right[2], r4 = right[3]
+
+ if root.val != 0 {
+ ans[0] = min(l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 1, l4 + r4 + 3)
+ ans[1] = min(l1 + r1 + 2, l2 + r2, l3 + r3 + 2, l4 + r4 + 2)
+ ans[2] = min(l1 + r1, l2 + r2 + 2, l3 + r3 + 2, l4 + r4 + 2)
+ ans[3] = min(l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 3, l4 + r4 + 1)
+ } else {
+ ans[0] = min(l1 + r1, l2 + r2 + 2, l3 + r3 + 2, l4 + r4 + 2)
+ ans[1] = min(l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 3, l4 + r4 + 1)
+ ans[2] = min(l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 1, l4 + r4 + 3)
+ ans[3] = min(l1 + r1 + 2, l2 + r2, l3 + r3 + 2, l4 + r4 + 2)
+ }
+
+ return ans
+ }
+
+ private func min(_ nums: Int...) -> Int {
+ return nums.min() ?? Int.max
+ }
+}
+```
+
diff --git "a/lcp/LCP 64. \344\272\214\345\217\211\346\240\221\347\201\257\351\245\260/Solution.swift" "b/lcp/LCP 64. \344\272\214\345\217\211\346\240\221\347\201\257\351\245\260/Solution.swift"
new file mode 100644
index 0000000000000..af2daef730b5a
--- /dev/null
+++ "b/lcp/LCP 64. \344\272\214\345\217\211\346\240\221\347\201\257\351\245\260/Solution.swift"
@@ -0,0 +1,48 @@
+/* public class TreeNode {
+* public var val: Int
+* public var left: TreeNode?
+* public var right: TreeNode?
+* public init(_ val: Int) {
+* self.val = val
+* self.left = nil
+* self.right = nil
+* }
+* }
+*/
+
+class Solution {
+ func closeLampInTree(_ root: TreeNode?) -> Int {
+ return dfs(root)[0]
+ }
+
+ private func dfs(_ root: TreeNode?) -> [Int] {
+ var ans = [Int](repeating: 0, count: 4)
+ guard let root = root else {
+ return ans
+ }
+
+ let left = dfs(root.left)
+ let right = dfs(root.right)
+
+ let l1 = left[0], l2 = left[1], l3 = left[2], l4 = left[3]
+ let r1 = right[0], r2 = right[1], r3 = right[2], r4 = right[3]
+
+ if root.val != 0 {
+ ans[0] = min(l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 1, l4 + r4 + 3)
+ ans[1] = min(l1 + r1 + 2, l2 + r2, l3 + r3 + 2, l4 + r4 + 2)
+ ans[2] = min(l1 + r1, l2 + r2 + 2, l3 + r3 + 2, l4 + r4 + 2)
+ ans[3] = min(l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 3, l4 + r4 + 1)
+ } else {
+ ans[0] = min(l1 + r1, l2 + r2 + 2, l3 + r3 + 2, l4 + r4 + 2)
+ ans[1] = min(l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 3, l4 + r4 + 1)
+ ans[2] = min(l1 + r1 + 1, l2 + r2 + 1, l3 + r3 + 1, l4 + r4 + 3)
+ ans[3] = min(l1 + r1 + 2, l2 + r2, l3 + r3 + 2, l4 + r4 + 2)
+ }
+
+ return ans
+ }
+
+ private func min(_ nums: Int...) -> Int {
+ return nums.min() ?? Int.max
+ }
+}
\ No newline at end of file
diff --git "a/lcp/LCP 66. \346\234\200\345\260\217\345\261\225\345\217\260\346\225\260\351\207\217/README.md" "b/lcp/LCP 66. \346\234\200\345\260\217\345\261\225\345\217\260\346\225\260\351\207\217/README.md"
index b61565afd4889..734bad71eb452 100644
--- "a/lcp/LCP 66. \346\234\200\345\260\217\345\261\225\345\217\260\346\225\260\351\207\217/README.md"
+++ "b/lcp/LCP 66. \346\234\200\345\260\217\345\261\225\345\217\260\346\225\260\351\207\217/README.md"
@@ -151,6 +151,29 @@ func minNumBooths(demand []string) (ans int) {
}
```
+#### Swift
+
+```swift
+class Solution {
+ func minNumBooths(_ demand: [String]) -> Int {
+ var maxBooths = [Int](repeating: 0, count: 26)
+
+ for day in demand {
+ var dailyCount = [Int](repeating: 0, count: 26)
+ for char in day {
+ let index = Int(char.asciiValue! - Character("a").asciiValue!)
+ dailyCount[index] += 1
+ }
+ for i in 0..<26 {
+ maxBooths[i] = max(maxBooths[i], dailyCount[i])
+ }
+ }
+
+ return maxBooths.reduce(0, +)
+ }
+}
+```
+
diff --git "a/lcp/LCP 66. \346\234\200\345\260\217\345\261\225\345\217\260\346\225\260\351\207\217/Solution.swift" "b/lcp/LCP 66. \346\234\200\345\260\217\345\261\225\345\217\260\346\225\260\351\207\217/Solution.swift"
new file mode 100644
index 0000000000000..ba1b0d803592d
--- /dev/null
+++ "b/lcp/LCP 66. \346\234\200\345\260\217\345\261\225\345\217\260\346\225\260\351\207\217/Solution.swift"
@@ -0,0 +1,18 @@
+class Solution {
+ func minNumBooths(_ demand: [String]) -> Int {
+ var maxBooths = [Int](repeating: 0, count: 26)
+
+ for day in demand {
+ var dailyCount = [Int](repeating: 0, count: 26)
+ for char in day {
+ let index = Int(char.asciiValue! - Character("a").asciiValue!)
+ dailyCount[index] += 1
+ }
+ for i in 0..<26 {
+ maxBooths[i] = max(maxBooths[i], dailyCount[i])
+ }
+ }
+
+ return maxBooths.reduce(0, +)
+ }
+}
\ No newline at end of file
diff --git "a/lcp/LCP 67. \350\243\205\351\245\260\346\240\221/README.md" "b/lcp/LCP 67. \350\243\205\351\245\260\346\240\221/README.md"
index e4d4babb6c862..b2444818fc494 100644
--- "a/lcp/LCP 67. \350\243\205\351\245\260\346\240\221/README.md"
+++ "b/lcp/LCP 67. \350\243\205\351\245\260\346\240\221/README.md"
@@ -197,6 +197,46 @@ func expandBinaryTree(root *TreeNode) *TreeNode {
}
```
+#### Swift
+
+```swift
+/* class TreeNode {
+* var val: Int
+* var left: TreeNode?
+* var right: TreeNode?
+* init() { self.val = 0; self.left = nil; self.right = nil }
+* init(_ val: Int) { self.val = val; self.left = nil; self.right = nil }
+* init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+* self.val = val
+* self.left = left
+* self.right = right
+* }
+* }
+*/
+
+class Solution {
+ func expandBinaryTree(_ root: TreeNode?) -> TreeNode? {
+ return dfs(root)
+ }
+
+ private func dfs(_ root: TreeNode?) -> TreeNode? {
+ guard let root = root else { return nil }
+
+ let leftChild = dfs(root.left)
+ let rightChild = dfs(root.right)
+
+ if let leftChild = leftChild {
+ root.left = TreeNode(-1, leftChild, nil)
+ }
+ if let rightChild = rightChild {
+ root.right = TreeNode(-1, nil, rightChild)
+ }
+ return root
+ }
+}
+
+```
+
diff --git "a/lcp/LCP 67. \350\243\205\351\245\260\346\240\221/Solution.swift" "b/lcp/LCP 67. \350\243\205\351\245\260\346\240\221/Solution.swift"
new file mode 100644
index 0000000000000..56a1d82045ec9
--- /dev/null
+++ "b/lcp/LCP 67. \350\243\205\351\245\260\346\240\221/Solution.swift"
@@ -0,0 +1,36 @@
+/* class TreeNode {
+* var val: Int
+* var left: TreeNode?
+* var right: TreeNode?
+
+* init() { self.val = 0; self.left = nil; self.right = nil }
+* init(_ val: Int) { self.val = val; self.left = nil; self.right = nil }
+* init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+* self.val = val
+* self.left = left
+* self.right = right
+* }
+* }
+*/
+
+class Solution {
+ func expandBinaryTree(_ root: TreeNode?) -> TreeNode? {
+ return dfs(root)
+ }
+
+ private func dfs(_ root: TreeNode?) -> TreeNode? {
+ guard let root = root else { return nil }
+
+ let leftChild = dfs(root.left)
+ let rightChild = dfs(root.right)
+
+ if let leftChild = leftChild {
+ root.left = TreeNode(-1, leftChild, nil)
+ }
+ if let rightChild = rightChild {
+ root.right = TreeNode(-1, nil, rightChild)
+ }
+
+ return root
+ }
+}
diff --git "a/lcp/LCP 68. \347\276\216\350\247\202\347\232\204\350\212\261\346\235\237/README.md" "b/lcp/LCP 68. \347\276\216\350\247\202\347\232\204\350\212\261\346\235\237/README.md"
index dca809e537dc9..ce88be9f1561f 100644
--- "a/lcp/LCP 68. \347\276\216\350\247\202\347\232\204\350\212\261\346\235\237/README.md"
+++ "b/lcp/LCP 68. \347\276\216\350\247\202\347\232\204\350\212\261\346\235\237/README.md"
@@ -150,6 +150,37 @@ func beautifulBouquet(flowers []int, cnt int) (ans int) {
}
```
+#### Swift
+
+```swift
+class Solution {
+ func beautifulBouquet(_ flowers: [Int], _ cnt: Int) -> Int {
+ let mod = Int(1e9 + 7)
+ var maxFlower = 0
+ for flower in flowers {
+ maxFlower = max(maxFlower, flower)
+ }
+
+ var flowerCount = [Int](repeating: 0, count: maxFlower + 1)
+ var ans = 0
+ var j = 0
+
+ for i in 0.. cnt {
+ flowerCount[flowers[j]] -= 1
+ j += 1
+ }
+
+ ans = (ans + (i - j + 1)) % mod
+ }
+
+ return ans
+ }
+}
+```
+
diff --git "a/lcp/LCP 68. \347\276\216\350\247\202\347\232\204\350\212\261\346\235\237/Solution.swift" "b/lcp/LCP 68. \347\276\216\350\247\202\347\232\204\350\212\261\346\235\237/Solution.swift"
new file mode 100644
index 0000000000000..c94b4a21c3413
--- /dev/null
+++ "b/lcp/LCP 68. \347\276\216\350\247\202\347\232\204\350\212\261\346\235\237/Solution.swift"
@@ -0,0 +1,26 @@
+class Solution {
+ func beautifulBouquet(_ flowers: [Int], _ cnt: Int) -> Int {
+ let mod = Int(1e9 + 7)
+ var maxFlower = 0
+ for flower in flowers {
+ maxFlower = max(maxFlower, flower)
+ }
+
+ var flowerCount = [Int](repeating: 0, count: maxFlower + 1)
+ var ans = 0
+ var j = 0
+
+ for i in 0.. cnt {
+ flowerCount[flowers[j]] -= 1
+ j += 1
+ }
+
+ ans = (ans + (i - j + 1)) % mod
+ }
+
+ return ans
+ }
+}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 93e256af88f15..734a405a7a3b2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,7 +8,7 @@
"@commitlint/cli": "^19.3.0",
"@commitlint/config-conventional": "^19.2.2",
"@prettier/plugin-php": "^0.22.2",
- "clang-format": "1.8.0",
+ "clang-format": "^1.8.0",
"husky": "^9.0.1",
"lint-staged": "^15.2.7",
"prettier": "^3.3.2",
@@ -474,6 +474,7 @@
"resolved": "https://registry.npmjs.org/clang-format/-/clang-format-1.8.0.tgz",
"integrity": "sha512-pK8gzfu55/lHzIpQ1givIbWfn3eXnU7SfxqIwVgnn5jEM6j4ZJYjpFqFs4iSBPNedzRMmfjYjuQhu657WAXHXw==",
"dev": true,
+ "license": "Apache-2.0",
"dependencies": {
"async": "^3.2.3",
"glob": "^7.0.0",
diff --git a/package.json b/package.json
index 3040f2fc33aac..a4f2c373c3278 100644
--- a/package.json
+++ b/package.json
@@ -6,7 +6,7 @@
"@commitlint/cli": "^19.3.0",
"@commitlint/config-conventional": "^19.2.2",
"@prettier/plugin-php": "^0.22.2",
- "clang-format": "1.8.0",
+ "clang-format": "^1.8.0",
"husky": "^9.0.1",
"lint-staged": "^15.2.7",
"prettier": "^3.3.2",
diff --git a/requirements.txt b/requirements.txt
index a861898c020f6..b87c0a5b8c9e6 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,2 +1,2 @@
black==24.3.0
-Requests==2.32.0
\ No newline at end of file
+Requests==2.32.4
\ No newline at end of file
diff --git a/solution/0000-0099/0001.Two Sum/README.md b/solution/0000-0099/0001.Two Sum/README.md
index f9a38ce75e350..88c20df42f7fa 100644
--- a/solution/0000-0099/0001.Two Sum/README.md
+++ b/solution/0000-0099/0001.Two Sum/README.md
@@ -353,6 +353,55 @@ class Solution {
}
```
+#### C
+
+```c
+#include
+
+int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
+ int capacity = 1;
+ while (capacity < numsSize * 2) capacity <<= 1;
+ int* keys = malloc(capacity * sizeof(int));
+ int* vals = malloc(capacity * sizeof(int));
+ char* used = calloc(capacity, sizeof(char));
+ if (!keys || !vals || !used) {
+ free(keys);
+ free(vals);
+ free(used);
+ *returnSize = 0;
+ return NULL;
+ }
+ for (int i = 0; i < numsSize; ++i) {
+ int x = nums[i];
+ int y = target - x;
+ unsigned int h = (unsigned int) y & (capacity - 1);
+ while (used[h]) {
+ if (keys[h] == y) {
+ int* res = malloc(2 * sizeof(int));
+ res[0] = vals[h];
+ res[1] = i;
+ *returnSize = 2;
+ free(keys);
+ free(vals);
+ free(used);
+ return res;
+ }
+ h = (h + 1) & (capacity - 1);
+ }
+ unsigned int h2 = (unsigned int) x & (capacity - 1);
+ while (used[h2]) h2 = (h2 + 1) & (capacity - 1);
+ used[h2] = 1;
+ keys[h2] = x;
+ vals[h2] = i;
+ }
+ *returnSize = 0;
+ free(keys);
+ free(vals);
+ free(used);
+ return NULL;
+}
+```
+
diff --git a/solution/0000-0099/0001.Two Sum/README_EN.md b/solution/0000-0099/0001.Two Sum/README_EN.md
index 25b360b51dbb7..c536e027be740 100644
--- a/solution/0000-0099/0001.Two Sum/README_EN.md
+++ b/solution/0000-0099/0001.Two Sum/README_EN.md
@@ -350,6 +350,55 @@ class Solution {
}
```
+#### C
+
+```c
+#include
+
+int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
+ int capacity = 1;
+ while (capacity < numsSize * 2) capacity <<= 1;
+ int* keys = malloc(capacity * sizeof(int));
+ int* vals = malloc(capacity * sizeof(int));
+ char* used = calloc(capacity, sizeof(char));
+ if (!keys || !vals || !used) {
+ free(keys);
+ free(vals);
+ free(used);
+ *returnSize = 0;
+ return NULL;
+ }
+ for (int i = 0; i < numsSize; ++i) {
+ int x = nums[i];
+ int y = target - x;
+ unsigned int h = (unsigned int) y & (capacity - 1);
+ while (used[h]) {
+ if (keys[h] == y) {
+ int* res = malloc(2 * sizeof(int));
+ res[0] = vals[h];
+ res[1] = i;
+ *returnSize = 2;
+ free(keys);
+ free(vals);
+ free(used);
+ return res;
+ }
+ h = (h + 1) & (capacity - 1);
+ }
+ unsigned int h2 = (unsigned int) x & (capacity - 1);
+ while (used[h2]) h2 = (h2 + 1) & (capacity - 1);
+ used[h2] = 1;
+ keys[h2] = x;
+ vals[h2] = i;
+ }
+ *returnSize = 0;
+ free(keys);
+ free(vals);
+ free(used);
+ return NULL;
+}
+```
+
diff --git a/solution/0000-0099/0001.Two Sum/Solution.c b/solution/0000-0099/0001.Two Sum/Solution.c
new file mode 100644
index 0000000000000..5ed7119c426ee
--- /dev/null
+++ b/solution/0000-0099/0001.Two Sum/Solution.c
@@ -0,0 +1,44 @@
+#include
+
+int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
+ int capacity = 1;
+ while (capacity < numsSize * 2) capacity <<= 1;
+ int* keys = malloc(capacity * sizeof(int));
+ int* vals = malloc(capacity * sizeof(int));
+ char* used = calloc(capacity, sizeof(char));
+ if (!keys || !vals || !used) {
+ free(keys);
+ free(vals);
+ free(used);
+ *returnSize = 0;
+ return NULL;
+ }
+ for (int i = 0; i < numsSize; ++i) {
+ int x = nums[i];
+ int y = target - x;
+ unsigned int h = (unsigned int) y & (capacity - 1);
+ while (used[h]) {
+ if (keys[h] == y) {
+ int* res = malloc(2 * sizeof(int));
+ res[0] = vals[h];
+ res[1] = i;
+ *returnSize = 2;
+ free(keys);
+ free(vals);
+ free(used);
+ return res;
+ }
+ h = (h + 1) & (capacity - 1);
+ }
+ unsigned int h2 = (unsigned int) x & (capacity - 1);
+ while (used[h2]) h2 = (h2 + 1) & (capacity - 1);
+ used[h2] = 1;
+ keys[h2] = x;
+ vals[h2] = i;
+ }
+ *returnSize = 0;
+ free(keys);
+ free(vals);
+ free(used);
+ return NULL;
+}
diff --git a/solution/0000-0099/0002.Add Two Numbers/README.md b/solution/0000-0099/0002.Add Two Numbers/README.md
index 3806f64b53d17..6cda4e7ca4018 100644
--- a/solution/0000-0099/0002.Add Two Numbers/README.md
+++ b/solution/0000-0099/0002.Add Two Numbers/README.md
@@ -147,9 +147,9 @@ class Solution {
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
- ListNode* dummy = new ListNode();
+ ListNode dummy;
int carry = 0;
- ListNode* cur = dummy;
+ ListNode* cur = &dummy;
while (l1 || l2 || carry) {
int s = (l1 ? l1->val : 0) + (l2 ? l2->val : 0) + carry;
carry = s / 10;
@@ -158,7 +158,7 @@ public:
l1 = l1 ? l1->next : nullptr;
l2 = l2 ? l2->next : nullptr;
}
- return dummy->next;
+ return dummy.next;
}
};
```
@@ -494,6 +494,52 @@ proc addTwoNumbers(l1: var SinglyLinkedList, l2: var SinglyLinkedList): SinglyLi
result = aggregate
```
+#### C
+
+```c
+
+/**
+ * Definition for singly-linked list.
+ * struct ListNode {
+ * int val;
+ * struct ListNode *next;
+ * };
+ */
+
+struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
+ struct ListNode* dummy = (struct ListNode*) malloc(sizeof(struct ListNode));
+ dummy->val = 0;
+ dummy->next = NULL;
+ struct ListNode* curr = dummy;
+ int carry = 0;
+
+ while (l1 != NULL || l2 != NULL || carry != 0) {
+ int sum = carry;
+ if (l1 != NULL) {
+ sum += l1->val;
+ l1 = l1->next;
+ }
+ if (l2 != NULL) {
+ sum += l2->val;
+ l2 = l2->next;
+ }
+
+ carry = sum / 10;
+ int val = sum % 10;
+
+ struct ListNode* newNode = (struct ListNode*) malloc(sizeof(struct ListNode));
+ newNode->val = val;
+ newNode->next = NULL;
+ curr->next = newNode;
+ curr = curr->next;
+ }
+
+ struct ListNode* result = dummy->next;
+ free(dummy);
+ return result;
+}
+```
+
diff --git a/solution/0000-0099/0002.Add Two Numbers/README_EN.md b/solution/0000-0099/0002.Add Two Numbers/README_EN.md
index f6878f0937322..99c96e3961490 100644
--- a/solution/0000-0099/0002.Add Two Numbers/README_EN.md
+++ b/solution/0000-0099/0002.Add Two Numbers/README_EN.md
@@ -143,9 +143,9 @@ class Solution {
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
- ListNode* dummy = new ListNode();
+ ListNode dummy;
int carry = 0;
- ListNode* cur = dummy;
+ ListNode* cur = &dummy;
while (l1 || l2 || carry) {
int s = (l1 ? l1->val : 0) + (l2 ? l2->val : 0) + carry;
carry = s / 10;
@@ -154,7 +154,7 @@ public:
l1 = l1 ? l1->next : nullptr;
l2 = l2 ? l2->next : nullptr;
}
- return dummy->next;
+ return dummy.next;
}
};
```
@@ -490,6 +490,52 @@ proc addTwoNumbers(l1: var SinglyLinkedList, l2: var SinglyLinkedList): SinglyLi
result = aggregate
```
+#### C
+
+```c
+
+/**
+ * Definition for singly-linked list.
+ * struct ListNode {
+ * int val;
+ * struct ListNode *next;
+ * };
+ */
+
+struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
+ struct ListNode* dummy = (struct ListNode*) malloc(sizeof(struct ListNode));
+ dummy->val = 0;
+ dummy->next = NULL;
+ struct ListNode* curr = dummy;
+ int carry = 0;
+
+ while (l1 != NULL || l2 != NULL || carry != 0) {
+ int sum = carry;
+ if (l1 != NULL) {
+ sum += l1->val;
+ l1 = l1->next;
+ }
+ if (l2 != NULL) {
+ sum += l2->val;
+ l2 = l2->next;
+ }
+
+ carry = sum / 10;
+ int val = sum % 10;
+
+ struct ListNode* newNode = (struct ListNode*) malloc(sizeof(struct ListNode));
+ newNode->val = val;
+ newNode->next = NULL;
+ curr->next = newNode;
+ curr = curr->next;
+ }
+
+ struct ListNode* result = dummy->next;
+ free(dummy);
+ return result;
+}
+```
+
diff --git a/solution/0000-0099/0002.Add Two Numbers/Solution.c b/solution/0000-0099/0002.Add Two Numbers/Solution.c
new file mode 100644
index 0000000000000..0ca00b4bd6752
--- /dev/null
+++ b/solution/0000-0099/0002.Add Two Numbers/Solution.c
@@ -0,0 +1,41 @@
+
+/**
+ * Definition for singly-linked list.
+ * struct ListNode {
+ * int val;
+ * struct ListNode *next;
+ * };
+ */
+
+struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
+ struct ListNode* dummy = (struct ListNode*) malloc(sizeof(struct ListNode));
+ dummy->val = 0;
+ dummy->next = NULL;
+ struct ListNode* curr = dummy;
+ int carry = 0;
+
+ while (l1 != NULL || l2 != NULL || carry != 0) {
+ int sum = carry;
+ if (l1 != NULL) {
+ sum += l1->val;
+ l1 = l1->next;
+ }
+ if (l2 != NULL) {
+ sum += l2->val;
+ l2 = l2->next;
+ }
+
+ carry = sum / 10;
+ int val = sum % 10;
+
+ struct ListNode* newNode = (struct ListNode*) malloc(sizeof(struct ListNode));
+ newNode->val = val;
+ newNode->next = NULL;
+ curr->next = newNode;
+ curr = curr->next;
+ }
+
+ struct ListNode* result = dummy->next;
+ free(dummy);
+ return result;
+}
diff --git a/solution/0000-0099/0002.Add Two Numbers/Solution.cpp b/solution/0000-0099/0002.Add Two Numbers/Solution.cpp
index b06a8b66b90b4..0d1b36d111994 100644
--- a/solution/0000-0099/0002.Add Two Numbers/Solution.cpp
+++ b/solution/0000-0099/0002.Add Two Numbers/Solution.cpp
@@ -11,9 +11,9 @@
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
- ListNode* dummy = new ListNode();
+ ListNode dummy;
int carry = 0;
- ListNode* cur = dummy;
+ ListNode* cur = &dummy;
while (l1 || l2 || carry) {
int s = (l1 ? l1->val : 0) + (l2 ? l2->val : 0) + carry;
carry = s / 10;
@@ -22,6 +22,6 @@ class Solution {
l1 = l1 ? l1->next : nullptr;
l2 = l2 ? l2->next : nullptr;
}
- return dummy->next;
+ return dummy.next;
}
};
\ No newline at end of file
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/README.md b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/README.md
index f502d2ad9b027..d95ea8a5d77a9 100644
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/README.md
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/README.md
@@ -300,6 +300,33 @@ class Solution {
}
```
+#### C
+
+```c
+int lengthOfLongestSubstring(char* s) {
+ int freq[256] = {0};
+ int l = 0, r = 0;
+ int ans = 0;
+ int len = strlen(s);
+
+ for (r = 0; r < len; r++) {
+ char c = s[r];
+ freq[(unsigned char) c]++;
+
+ while (freq[(unsigned char) c] > 1) {
+ freq[(unsigned char) s[l]]--;
+ l++;
+ }
+
+ if (ans < r - l + 1) {
+ ans = r - l + 1;
+ }
+ }
+
+ return ans;
+}
+```
+
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/README_EN.md b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/README_EN.md
index c8302cd9b1aab..16624fcc16b80 100644
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/README_EN.md
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/README_EN.md
@@ -18,7 +18,7 @@ tags:
-Given a string s
, find the length of the longest substring without repeating characters.
+Given a string s
, find the length of the longest substring without duplicate characters.
Example 1:
@@ -298,6 +298,33 @@ class Solution {
}
```
+#### C
+
+```c
+int lengthOfLongestSubstring(char* s) {
+ int freq[256] = {0};
+ int l = 0, r = 0;
+ int ans = 0;
+ int len = strlen(s);
+
+ for (r = 0; r < len; r++) {
+ char c = s[r];
+ freq[(unsigned char) c]++;
+
+ while (freq[(unsigned char) c] > 1) {
+ freq[(unsigned char) s[l]]--;
+ l++;
+ }
+
+ if (ans < r - l + 1) {
+ ans = r - l + 1;
+ }
+ }
+
+ return ans;
+}
+```
+
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.c b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.c
new file mode 100644
index 0000000000000..673e098af92ac
--- /dev/null
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.c
@@ -0,0 +1,22 @@
+int lengthOfLongestSubstring(char* s) {
+ int freq[256] = {0};
+ int l = 0, r = 0;
+ int ans = 0;
+ int len = strlen(s);
+
+ for (r = 0; r < len; r++) {
+ char c = s[r];
+ freq[(unsigned char) c]++;
+
+ while (freq[(unsigned char) c] > 1) {
+ freq[(unsigned char) s[l]]--;
+ l++;
+ }
+
+ if (ans < r - l + 1) {
+ ans = r - l + 1;
+ }
+ }
+
+ return ans;
+}
diff --git a/solution/0000-0099/0004.Median of Two Sorted Arrays/README.md b/solution/0000-0099/0004.Median of Two Sorted Arrays/README.md
index a0c5af52f0caa..b6a21c5b7e751 100644
--- a/solution/0000-0099/0004.Median of Two Sorted Arrays/README.md
+++ b/solution/0000-0099/0004.Median of Two Sorted Arrays/README.md
@@ -350,6 +350,36 @@ proc medianOfTwoSortedArrays(nums1: seq[int], nums2: seq[int]): float =
# echo medianOfTwoSortedArrays(arrA, arrB)
```
+#### C
+
+```c
+int findKth(int* nums1, int m, int i, int* nums2, int n, int j, int k) {
+ if (i >= m)
+ return nums2[j + k - 1];
+ if (j >= n)
+ return nums1[i + k - 1];
+ if (k == 1)
+ return nums1[i] < nums2[j] ? nums1[i] : nums2[j];
+
+ int p = k / 2;
+
+ int x = (i + p - 1 < m) ? nums1[i + p - 1] : INT_MAX;
+ int y = (j + p - 1 < n) ? nums2[j + p - 1] : INT_MAX;
+
+ if (x < y)
+ return findKth(nums1, m, i + p, nums2, n, j, k - p);
+ else
+ return findKth(nums1, m, i, nums2, n, j + p, k - p);
+}
+
+double findMedianSortedArrays(int* nums1, int m, int* nums2, int n) {
+ int total = m + n;
+ int a = findKth(nums1, m, 0, nums2, n, 0, (total + 1) / 2);
+ int b = findKth(nums1, m, 0, nums2, n, 0, (total + 2) / 2);
+ return (a + b) / 2.0;
+}
+```
+
diff --git a/solution/0000-0099/0004.Median of Two Sorted Arrays/README_EN.md b/solution/0000-0099/0004.Median of Two Sorted Arrays/README_EN.md
index 15b73ee6ff6f0..2896e96ddc3af 100644
--- a/solution/0000-0099/0004.Median of Two Sorted Arrays/README_EN.md
+++ b/solution/0000-0099/0004.Median of Two Sorted Arrays/README_EN.md
@@ -346,6 +346,36 @@ proc medianOfTwoSortedArrays(nums1: seq[int], nums2: seq[int]): float =
# echo medianOfTwoSortedArrays(arrA, arrB)
```
+#### C
+
+```c
+int findKth(int* nums1, int m, int i, int* nums2, int n, int j, int k) {
+ if (i >= m)
+ return nums2[j + k - 1];
+ if (j >= n)
+ return nums1[i + k - 1];
+ if (k == 1)
+ return nums1[i] < nums2[j] ? nums1[i] : nums2[j];
+
+ int p = k / 2;
+
+ int x = (i + p - 1 < m) ? nums1[i + p - 1] : INT_MAX;
+ int y = (j + p - 1 < n) ? nums2[j + p - 1] : INT_MAX;
+
+ if (x < y)
+ return findKth(nums1, m, i + p, nums2, n, j, k - p);
+ else
+ return findKth(nums1, m, i, nums2, n, j + p, k - p);
+}
+
+double findMedianSortedArrays(int* nums1, int m, int* nums2, int n) {
+ int total = m + n;
+ int a = findKth(nums1, m, 0, nums2, n, 0, (total + 1) / 2);
+ int b = findKth(nums1, m, 0, nums2, n, 0, (total + 2) / 2);
+ return (a + b) / 2.0;
+}
+```
+
diff --git a/solution/0000-0099/0004.Median of Two Sorted Arrays/Solution.c b/solution/0000-0099/0004.Median of Two Sorted Arrays/Solution.c
new file mode 100644
index 0000000000000..2786c7ef9bfd8
--- /dev/null
+++ b/solution/0000-0099/0004.Median of Two Sorted Arrays/Solution.c
@@ -0,0 +1,25 @@
+int findKth(int* nums1, int m, int i, int* nums2, int n, int j, int k) {
+ if (i >= m)
+ return nums2[j + k - 1];
+ if (j >= n)
+ return nums1[i + k - 1];
+ if (k == 1)
+ return nums1[i] < nums2[j] ? nums1[i] : nums2[j];
+
+ int p = k / 2;
+
+ int x = (i + p - 1 < m) ? nums1[i + p - 1] : INT_MAX;
+ int y = (j + p - 1 < n) ? nums2[j + p - 1] : INT_MAX;
+
+ if (x < y)
+ return findKth(nums1, m, i + p, nums2, n, j, k - p);
+ else
+ return findKth(nums1, m, i, nums2, n, j + p, k - p);
+}
+
+double findMedianSortedArrays(int* nums1, int m, int* nums2, int n) {
+ int total = m + n;
+ int a = findKth(nums1, m, 0, nums2, n, 0, (total + 1) / 2);
+ int b = findKth(nums1, m, 0, nums2, n, 0, (total + 2) / 2);
+ return (a + b) / 2.0;
+}
diff --git a/solution/0000-0099/0005.Longest Palindromic Substring/README.md b/solution/0000-0099/0005.Longest Palindromic Substring/README.md
index 407fd7e12412c..c6c52ab64cd4f 100644
--- a/solution/0000-0099/0005.Longest Palindromic Substring/README.md
+++ b/solution/0000-0099/0005.Longest Palindromic Substring/README.md
@@ -277,6 +277,42 @@ public class Solution {
}
```
+#### C
+
+```c
+char* longestPalindrome(char* s) {
+ int n = strlen(s);
+ bool** f = (bool**) malloc(n * sizeof(bool*));
+ for (int i = 0; i < n; ++i) {
+ f[i] = (bool*) malloc(n * sizeof(bool));
+ for (int j = 0; j < n; ++j) {
+ f[i][j] = true;
+ }
+ }
+ int k = 0, mx = 1;
+ for (int i = n - 2; ~i; --i) {
+ for (int j = i + 1; j < n; ++j) {
+ f[i][j] = false;
+ if (s[i] == s[j]) {
+ f[i][j] = f[i + 1][j - 1];
+ if (f[i][j] && mx < j - i + 1) {
+ mx = j - i + 1;
+ k = i;
+ }
+ }
+ }
+ }
+ char* res = (char*) malloc((mx + 1) * sizeof(char));
+ strncpy(res, s + k, mx);
+ res[mx] = '\0';
+ for (int i = 0; i < n; ++i) {
+ free(f[i]);
+ }
+ free(f);
+ return res;
+}
+```
+
#### Nim
```nim
@@ -456,6 +492,39 @@ impl Solution {
}
```
+#### C#
+
+```cs
+public class Solution {
+ private string s;
+ private int n;
+
+ public String LongestPalindrome(string s) {
+ this.s = s;
+ n = s.Length;
+ int start = 0, mx = 1;
+ for (int i = 0; i < n; ++i) {
+ int a = F(i, i);
+ int b = F(i, i + 1);
+ int t = Math.Max(a, b);
+ if (mx < t) {
+ mx = t;
+ start = i - ((t - 1) >> 1);
+ }
+ }
+ return s.Substring(start, start + mx);
+ }
+
+ private int F(int l, int r) {
+ while (l >= 0 && r < n && s[l] == s[r]) {
+ --l;
+ ++r;
+ }
+ return r - l - 1;
+ }
+}
+```
+
#### PHP
```php
diff --git a/solution/0000-0099/0005.Longest Palindromic Substring/README_EN.md b/solution/0000-0099/0005.Longest Palindromic Substring/README_EN.md
index 895bbb34ed3ff..e317ceda58ac4 100644
--- a/solution/0000-0099/0005.Longest Palindromic Substring/README_EN.md
+++ b/solution/0000-0099/0005.Longest Palindromic Substring/README_EN.md
@@ -275,6 +275,42 @@ public class Solution {
}
```
+#### C
+
+```c
+char* longestPalindrome(char* s) {
+ int n = strlen(s);
+ bool** f = (bool**) malloc(n * sizeof(bool*));
+ for (int i = 0; i < n; ++i) {
+ f[i] = (bool*) malloc(n * sizeof(bool));
+ for (int j = 0; j < n; ++j) {
+ f[i][j] = true;
+ }
+ }
+ int k = 0, mx = 1;
+ for (int i = n - 2; ~i; --i) {
+ for (int j = i + 1; j < n; ++j) {
+ f[i][j] = false;
+ if (s[i] == s[j]) {
+ f[i][j] = f[i + 1][j - 1];
+ if (f[i][j] && mx < j - i + 1) {
+ mx = j - i + 1;
+ k = i;
+ }
+ }
+ }
+ }
+ char* res = (char*) malloc((mx + 1) * sizeof(char));
+ strncpy(res, s + k, mx);
+ res[mx] = '\0';
+ for (int i = 0; i < n; ++i) {
+ free(f[i]);
+ }
+ free(f);
+ return res;
+}
+```
+
#### Nim
```nim
@@ -454,6 +490,39 @@ impl Solution {
}
```
+#### C#
+
+```cs
+public class Solution {
+ private string s;
+ private int n;
+
+ public String LongestPalindrome(string s) {
+ this.s = s;
+ n = s.Length;
+ int start = 0, mx = 1;
+ for (int i = 0; i < n; ++i) {
+ int a = F(i, i);
+ int b = F(i, i + 1);
+ int t = Math.Max(a, b);
+ if (mx < t) {
+ mx = t;
+ start = i - ((t - 1) >> 1);
+ }
+ }
+ return s.Substring(start, start + mx);
+ }
+
+ private int F(int l, int r) {
+ while (l >= 0 && r < n && s[l] == s[r]) {
+ --l;
+ ++r;
+ }
+ return r - l - 1;
+ }
+}
+```
+
#### PHP
```php
diff --git a/solution/0000-0099/0005.Longest Palindromic Substring/Solution.c b/solution/0000-0099/0005.Longest Palindromic Substring/Solution.c
new file mode 100644
index 0000000000000..e5a88d6c8c467
--- /dev/null
+++ b/solution/0000-0099/0005.Longest Palindromic Substring/Solution.c
@@ -0,0 +1,31 @@
+char* longestPalindrome(char* s) {
+ int n = strlen(s);
+ bool** f = (bool**) malloc(n * sizeof(bool*));
+ for (int i = 0; i < n; ++i) {
+ f[i] = (bool*) malloc(n * sizeof(bool));
+ for (int j = 0; j < n; ++j) {
+ f[i][j] = true;
+ }
+ }
+ int k = 0, mx = 1;
+ for (int i = n - 2; ~i; --i) {
+ for (int j = i + 1; j < n; ++j) {
+ f[i][j] = false;
+ if (s[i] == s[j]) {
+ f[i][j] = f[i + 1][j - 1];
+ if (f[i][j] && mx < j - i + 1) {
+ mx = j - i + 1;
+ k = i;
+ }
+ }
+ }
+ }
+ char* res = (char*) malloc((mx + 1) * sizeof(char));
+ strncpy(res, s + k, mx);
+ res[mx] = '\0';
+ for (int i = 0; i < n; ++i) {
+ free(f[i]);
+ }
+ free(f);
+ return res;
+}
diff --git a/solution/0000-0099/0005.Longest Palindromic Substring/Solution2.cs b/solution/0000-0099/0005.Longest Palindromic Substring/Solution2.cs
new file mode 100644
index 0000000000000..48e1cf8b8e46c
--- /dev/null
+++ b/solution/0000-0099/0005.Longest Palindromic Substring/Solution2.cs
@@ -0,0 +1,28 @@
+public class Solution {
+ private string s;
+ private int n;
+
+ public String LongestPalindrome(string s) {
+ this.s = s;
+ n = s.Length;
+ int start = 0, mx = 1;
+ for (int i = 0; i < n; ++i) {
+ int a = F(i, i);
+ int b = F(i, i + 1);
+ int t = Math.Max(a, b);
+ if (mx < t) {
+ mx = t;
+ start = i - ((t - 1) >> 1);
+ }
+ }
+ return s.Substring(start, start + mx);
+ }
+
+ private int F(int l, int r) {
+ while (l >= 0 && r < n && s[l] == s[r]) {
+ --l;
+ ++r;
+ }
+ return r - l - 1;
+ }
+}
\ No newline at end of file
diff --git a/solution/0000-0099/0006.Zigzag Conversion/README.md b/solution/0000-0099/0006.Zigzag Conversion/README.md
index c12bad03a22aa..ee8279b690b66 100644
--- a/solution/0000-0099/0006.Zigzag Conversion/README.md
+++ b/solution/0000-0099/0006.Zigzag Conversion/README.md
@@ -78,9 +78,9 @@ P I
### 方法一:模拟
-我们用一个二维数组 $g$ 来模拟 $Z$ 字形排列的过程,其中 $g[i][j]$ 表示第 $i$ 行第 $j$ 列的字符。初始时 $i=0$,另外我们定义一个方向变量 $k$,初始时 $k=-1$,表示向上走。
+我们用一个二维数组 $g$ 来模拟 Z 字形排列的过程,其中 $g[i][j]$ 表示第 $i$ 行第 $j$ 列的字符。初始时 $i = 0$,另外我们定义一个方向变量 $k$,初始时 $k = -1$,表示向上走。
-我们从左到右遍历字符串 $s$,每次遍历到一个字符 $c$,将其追加到 $g[i]$ 中,如果此时 $i=0$ 或者 $i=numRows-1$,说明当前字符位于 $Z$ 字形排列的拐点,我们将 $k$ 的值反转,即 $k=-k$。接下来,我们将 $i$ 的值更新为 $i+k$,即向上或向下移动一行。继续遍历下一个字符,直到遍历完字符串 $s$,我们返回 $g$ 中所有行拼接后的字符串即可。
+我们从左到右遍历字符串 $s$,每次遍历到一个字符 $c$,将其追加到 $g[i]$ 中。如果此时 $i = 0$ 或者 $i = \textit{numRows} - 1$,说明当前字符位于 Z 字形排列的拐点,我们将 $k$ 的值反转,即 $k = -k$。接下来,我们将 $i$ 的值更新为 $i + k$,即向上或向下移动一行。继续遍历下一个字符,直到遍历完字符串 $s$,我们返回 $g$ 中所有行拼接后的字符串即可。
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串 $s$ 的长度。
@@ -199,29 +199,24 @@ function convert(s: string, numRows: number): string {
```rust
impl Solution {
pub fn convert(s: String, num_rows: i32) -> String {
- let num_rows = num_rows as usize;
if num_rows == 1 {
return s;
}
- let mut ss = vec![String::new(); num_rows];
+
+ let num_rows = num_rows as usize;
+ let mut g = vec![String::new(); num_rows];
let mut i = 0;
- let mut to_down = true;
+ let mut k = -1;
+
for c in s.chars() {
- ss[i].push(c);
- if to_down {
- i += 1;
- } else {
- i -= 1;
- }
+ g[i].push(c);
if i == 0 || i == num_rows - 1 {
- to_down = !to_down;
+ k = -k;
}
+ i = (i as isize + k) as usize;
}
- let mut res = String::new();
- for i in 0..num_rows {
- res += &ss[i];
- }
- res
+
+ g.concat()
}
}
```
@@ -282,213 +277,77 @@ public class Solution {
}
```
-
-
-
-
-
-
-### 方法二
-
-
-
-#### Python3
-
-```python
-class Solution:
- def convert(self, s: str, numRows: int) -> str:
- if numRows == 1:
- return s
- group = 2 * numRows - 2
- ans = []
- for i in range(1, numRows + 1):
- interval = group if i == numRows else 2 * numRows - 2 * i
- idx = i - 1
- while idx < len(s):
- ans.append(s[idx])
- idx += interval
- interval = group - interval
- if interval == 0:
- interval = group
- return ''.join(ans)
-```
-
-#### Java
+#### C
-```java
-class Solution {
- public String convert(String s, int numRows) {
- if (numRows == 1) {
- return s;
- }
- StringBuilder ans = new StringBuilder();
- int group = 2 * numRows - 2;
- for (int i = 1; i <= numRows; i++) {
- int interval = i == numRows ? group : 2 * numRows - 2 * i;
- int idx = i - 1;
- while (idx < s.length()) {
- ans.append(s.charAt(idx));
- idx += interval;
- interval = group - interval;
- if (interval == 0) {
- interval = group;
- }
- }
- }
- return ans.toString();
+```c
+char* convert(char* s, int numRows) {
+ if (numRows == 1) {
+ return strdup(s);
}
-}
-```
-#### C++
+ int len = strlen(s);
+ char** g = (char**) malloc(numRows * sizeof(char*));
+ int* idx = (int*) malloc(numRows * sizeof(int));
+ for (int i = 0; i < numRows; ++i) {
+ g[i] = (char*) malloc((len + 1) * sizeof(char));
+ idx[i] = 0;
+ }
-```cpp
-class Solution {
-public:
- string convert(string s, int numRows) {
- if (numRows == 1) return s;
- string ans;
- int group = 2 * numRows - 2;
- for (int i = 1; i <= numRows; ++i) {
- int interval = i == numRows ? group : 2 * numRows - 2 * i;
- int idx = i - 1;
- while (idx < s.length()) {
- ans.push_back(s[idx]);
- idx += interval;
- interval = group - interval;
- if (interval == 0) interval = group;
- }
+ int i = 0, k = -1;
+ for (int p = 0; p < len; ++p) {
+ g[i][idx[i]++] = s[p];
+ if (i == 0 || i == numRows - 1) {
+ k = -k;
}
- return ans;
+ i += k;
}
-};
-```
-#### Go
-
-```go
-func convert(s string, numRows int) string {
- if numRows == 1 {
- return s
- }
- n := len(s)
- ans := make([]byte, n)
- step := 2*numRows - 2
- count := 0
- for i := 0; i < numRows; i++ {
- for j := 0; j+i < n; j += step {
- ans[count] = s[i+j]
- count++
- if i != 0 && i != numRows-1 && j+step-i < n {
- ans[count] = s[j+step-i]
- count++
- }
- }
- }
- return string(ans)
-}
-```
-
-#### TypeScript
-
-```ts
-function convert(s: string, numRows: number): string {
- if (numRows === 1) {
- return s;
- }
- const ss = new Array(numRows).fill('');
- let i = 0;
- let toDown = true;
- for (const c of s) {
- ss[i] += c;
- if (toDown) {
- i++;
- } else {
- i--;
- }
- if (i === 0 || i === numRows - 1) {
- toDown = !toDown;
+ char* ans = (char*) malloc((len + 1) * sizeof(char));
+ int pos = 0;
+ for (int r = 0; r < numRows; ++r) {
+ for (int j = 0; j < idx[r]; ++j) {
+ ans[pos++] = g[r][j];
}
+ free(g[r]);
}
- return ss.reduce((r, s) => r + s);
-}
-```
-
-#### Rust
+ ans[pos] = '\0';
-```rust
-impl Solution {
- pub fn convert(s: String, num_rows: i32) -> String {
- let num_rows = num_rows as usize;
- let mut rows = vec![String::new(); num_rows];
- let iter = (0..num_rows).chain((1..num_rows - 1).rev()).cycle();
- iter.zip(s.chars()).for_each(|(i, c)| rows[i].push(c));
- rows.into_iter().collect()
- }
+ free(g);
+ free(idx);
+ return ans;
}
```
-#### JavaScript
-
-```js
-/**
- * @param {string} s
- * @param {number} numRows
- * @return {string}
- */
-var convert = function (s, numRows) {
- if (numRows == 1) return s;
- const arr = new Array(numRows);
- for (let i = 0; i < numRows; i++) arr[i] = [];
- let mi = 0,
- isDown = true;
- for (const c of s) {
- arr[mi].push(c);
-
- if (mi >= numRows - 1) isDown = false;
- else if (mi <= 0) isDown = true;
-
- if (isDown) mi++;
- else mi--;
- }
- let ans = [];
- for (const item of arr) {
- ans = ans.concat(item);
- }
- return ans.join('');
-};
-```
-
#### PHP
```php
class Solution {
/**
- * @param string $s
- * @param int $numRows
- * @return string
+ * @param String $s
+ * @param Integer $numRows
+ * @return String
*/
-
function convert($s, $numRows) {
- if ($numRows == 1 || strlen($s) <= $numRows) {
+ if ($numRows == 1) {
return $s;
}
- $result = '';
- $cycleLength = 2 * $numRows - 2;
- $n = strlen($s);
+ $g = array_fill(0, $numRows, '');
+ $i = 0;
+ $k = -1;
- for ($i = 0; $i < $numRows; $i++) {
- for ($j = 0; $j + $i < $n; $j += $cycleLength) {
- $result .= $s[$j + $i];
+ $length = strlen($s);
+ for ($j = 0; $j < $length; $j++) {
+ $c = $s[$j];
+ $g[$i] .= $c;
- if ($i != 0 && $i != $numRows - 1 && $j + $cycleLength - $i < $n) {
- $result .= $s[$j + $cycleLength - $i];
- }
+ if ($i == 0 || $i == $numRows - 1) {
+ $k = -$k;
}
- }
- return $result;
+ $i += $k;
+ }
+ return implode('', $g);
}
}
```
diff --git a/solution/0000-0099/0006.Zigzag Conversion/README_EN.md b/solution/0000-0099/0006.Zigzag Conversion/README_EN.md
index 04390da8f24e7..bf557fa6ee583 100644
--- a/solution/0000-0099/0006.Zigzag Conversion/README_EN.md
+++ b/solution/0000-0099/0006.Zigzag Conversion/README_EN.md
@@ -76,11 +76,11 @@ P I
### Solution 1: Simulation
-We use a two-dimensional array $g$ to simulate the process of the $Z$-shape arrangement, where $g[i][j]$ represents the character at the $i$-th row and the $j$-th column. Initially, $i=0$, and we define a direction variable $k$, initially $k=-1$, indicating moving upwards.
+We use a 2D array $g$ to simulate the process of arranging the string in a zigzag pattern, where $g[i][j]$ represents the character at row $i$ and column $j$. Initially, $i = 0$. We also define a direction variable $k$, initially $k = -1$, which means moving upwards.
-We traverse the string $s$ from left to right. Each time we traverse to a character $c$, we append it to $g[i]$. If $i=0$ or $i=numRows-1$ at this time, it means that the current character is at the turning point of the $Z$-shape arrangement, and we reverse the value of $k$, i.e., $k=-k$. Next, we update the value of $i$ to $i+k$, i.e., move up or down one row. Continue to traverse the next character until we have traversed the string $s$, and we return the string concatenated by all rows in $g$.
+We traverse the string $s$ from left to right. For each character $c$, we append it to $g[i]$. If $i = 0$ or $i = \textit{numRows} - 1$, it means the current character is at a turning point in the zigzag pattern, so we reverse the value of $k$, i.e., $k = -k$. Then, we update $i$ to $i + k$, which means moving up or down one row. Continue traversing the next character until the end of the string $s$. Finally, we return the concatenation of all rows in $g$ as the result.
-The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the string $s$.
+The time complexity is $O(n)$ and the space complexity is $O(n)$, where $n$ is the length of the string $s$.
@@ -197,29 +197,24 @@ function convert(s: string, numRows: number): string {
```rust
impl Solution {
pub fn convert(s: String, num_rows: i32) -> String {
- let num_rows = num_rows as usize;
if num_rows == 1 {
return s;
}
- let mut ss = vec![String::new(); num_rows];
+
+ let num_rows = num_rows as usize;
+ let mut g = vec![String::new(); num_rows];
let mut i = 0;
- let mut to_down = true;
+ let mut k = -1;
+
for c in s.chars() {
- ss[i].push(c);
- if to_down {
- i += 1;
- } else {
- i -= 1;
- }
+ g[i].push(c);
if i == 0 || i == num_rows - 1 {
- to_down = !to_down;
+ k = -k;
}
+ i = (i as isize + k) as usize;
}
- let mut res = String::new();
- for i in 0..num_rows {
- res += &ss[i];
- }
- res
+
+ g.concat()
}
}
```
@@ -280,213 +275,77 @@ public class Solution {
}
```
-
-
-
-
-
-
-### Solution 2
-
-
-
-#### Python3
-
-```python
-class Solution:
- def convert(self, s: str, numRows: int) -> str:
- if numRows == 1:
- return s
- group = 2 * numRows - 2
- ans = []
- for i in range(1, numRows + 1):
- interval = group if i == numRows else 2 * numRows - 2 * i
- idx = i - 1
- while idx < len(s):
- ans.append(s[idx])
- idx += interval
- interval = group - interval
- if interval == 0:
- interval = group
- return ''.join(ans)
-```
-
-#### Java
+#### C
-```java
-class Solution {
- public String convert(String s, int numRows) {
- if (numRows == 1) {
- return s;
- }
- StringBuilder ans = new StringBuilder();
- int group = 2 * numRows - 2;
- for (int i = 1; i <= numRows; i++) {
- int interval = i == numRows ? group : 2 * numRows - 2 * i;
- int idx = i - 1;
- while (idx < s.length()) {
- ans.append(s.charAt(idx));
- idx += interval;
- interval = group - interval;
- if (interval == 0) {
- interval = group;
- }
- }
- }
- return ans.toString();
+```c
+char* convert(char* s, int numRows) {
+ if (numRows == 1) {
+ return strdup(s);
}
-}
-```
-#### C++
+ int len = strlen(s);
+ char** g = (char**) malloc(numRows * sizeof(char*));
+ int* idx = (int*) malloc(numRows * sizeof(int));
+ for (int i = 0; i < numRows; ++i) {
+ g[i] = (char*) malloc((len + 1) * sizeof(char));
+ idx[i] = 0;
+ }
-```cpp
-class Solution {
-public:
- string convert(string s, int numRows) {
- if (numRows == 1) return s;
- string ans;
- int group = 2 * numRows - 2;
- for (int i = 1; i <= numRows; ++i) {
- int interval = i == numRows ? group : 2 * numRows - 2 * i;
- int idx = i - 1;
- while (idx < s.length()) {
- ans.push_back(s[idx]);
- idx += interval;
- interval = group - interval;
- if (interval == 0) interval = group;
- }
+ int i = 0, k = -1;
+ for (int p = 0; p < len; ++p) {
+ g[i][idx[i]++] = s[p];
+ if (i == 0 || i == numRows - 1) {
+ k = -k;
}
- return ans;
+ i += k;
}
-};
-```
-#### Go
-
-```go
-func convert(s string, numRows int) string {
- if numRows == 1 {
- return s
- }
- n := len(s)
- ans := make([]byte, n)
- step := 2*numRows - 2
- count := 0
- for i := 0; i < numRows; i++ {
- for j := 0; j+i < n; j += step {
- ans[count] = s[i+j]
- count++
- if i != 0 && i != numRows-1 && j+step-i < n {
- ans[count] = s[j+step-i]
- count++
- }
- }
- }
- return string(ans)
-}
-```
-
-#### TypeScript
-
-```ts
-function convert(s: string, numRows: number): string {
- if (numRows === 1) {
- return s;
- }
- const ss = new Array(numRows).fill('');
- let i = 0;
- let toDown = true;
- for (const c of s) {
- ss[i] += c;
- if (toDown) {
- i++;
- } else {
- i--;
- }
- if (i === 0 || i === numRows - 1) {
- toDown = !toDown;
+ char* ans = (char*) malloc((len + 1) * sizeof(char));
+ int pos = 0;
+ for (int r = 0; r < numRows; ++r) {
+ for (int j = 0; j < idx[r]; ++j) {
+ ans[pos++] = g[r][j];
}
+ free(g[r]);
}
- return ss.reduce((r, s) => r + s);
-}
-```
-
-#### Rust
+ ans[pos] = '\0';
-```rust
-impl Solution {
- pub fn convert(s: String, num_rows: i32) -> String {
- let num_rows = num_rows as usize;
- let mut rows = vec![String::new(); num_rows];
- let iter = (0..num_rows).chain((1..num_rows - 1).rev()).cycle();
- iter.zip(s.chars()).for_each(|(i, c)| rows[i].push(c));
- rows.into_iter().collect()
- }
+ free(g);
+ free(idx);
+ return ans;
}
```
-#### JavaScript
-
-```js
-/**
- * @param {string} s
- * @param {number} numRows
- * @return {string}
- */
-var convert = function (s, numRows) {
- if (numRows == 1) return s;
- const arr = new Array(numRows);
- for (let i = 0; i < numRows; i++) arr[i] = [];
- let mi = 0,
- isDown = true;
- for (const c of s) {
- arr[mi].push(c);
-
- if (mi >= numRows - 1) isDown = false;
- else if (mi <= 0) isDown = true;
-
- if (isDown) mi++;
- else mi--;
- }
- let ans = [];
- for (const item of arr) {
- ans = ans.concat(item);
- }
- return ans.join('');
-};
-```
-
#### PHP
```php
class Solution {
/**
- * @param string $s
- * @param int $numRows
- * @return string
+ * @param String $s
+ * @param Integer $numRows
+ * @return String
*/
-
function convert($s, $numRows) {
- if ($numRows == 1 || strlen($s) <= $numRows) {
+ if ($numRows == 1) {
return $s;
}
- $result = '';
- $cycleLength = 2 * $numRows - 2;
- $n = strlen($s);
+ $g = array_fill(0, $numRows, '');
+ $i = 0;
+ $k = -1;
- for ($i = 0; $i < $numRows; $i++) {
- for ($j = 0; $j + $i < $n; $j += $cycleLength) {
- $result .= $s[$j + $i];
+ $length = strlen($s);
+ for ($j = 0; $j < $length; $j++) {
+ $c = $s[$j];
+ $g[$i] .= $c;
- if ($i != 0 && $i != $numRows - 1 && $j + $cycleLength - $i < $n) {
- $result .= $s[$j + $cycleLength - $i];
- }
+ if ($i == 0 || $i == $numRows - 1) {
+ $k = -$k;
}
- }
- return $result;
+ $i += $k;
+ }
+ return implode('', $g);
}
}
```
diff --git a/solution/0000-0099/0006.Zigzag Conversion/Solution.c b/solution/0000-0099/0006.Zigzag Conversion/Solution.c
new file mode 100644
index 0000000000000..3111a73e7035c
--- /dev/null
+++ b/solution/0000-0099/0006.Zigzag Conversion/Solution.c
@@ -0,0 +1,36 @@
+char* convert(char* s, int numRows) {
+ if (numRows == 1) {
+ return strdup(s);
+ }
+
+ int len = strlen(s);
+ char** g = (char**) malloc(numRows * sizeof(char*));
+ int* idx = (int*) malloc(numRows * sizeof(int));
+ for (int i = 0; i < numRows; ++i) {
+ g[i] = (char*) malloc((len + 1) * sizeof(char));
+ idx[i] = 0;
+ }
+
+ int i = 0, k = -1;
+ for (int p = 0; p < len; ++p) {
+ g[i][idx[i]++] = s[p];
+ if (i == 0 || i == numRows - 1) {
+ k = -k;
+ }
+ i += k;
+ }
+
+ char* ans = (char*) malloc((len + 1) * sizeof(char));
+ int pos = 0;
+ for (int r = 0; r < numRows; ++r) {
+ for (int j = 0; j < idx[r]; ++j) {
+ ans[pos++] = g[r][j];
+ }
+ free(g[r]);
+ }
+ ans[pos] = '\0';
+
+ free(g);
+ free(idx);
+ return ans;
+}
diff --git a/solution/0000-0099/0006.Zigzag Conversion/Solution.php b/solution/0000-0099/0006.Zigzag Conversion/Solution.php
index 4eb4ee9795308..2d151b664b8f6 100644
--- a/solution/0000-0099/0006.Zigzag Conversion/Solution.php
+++ b/solution/0000-0099/0006.Zigzag Conversion/Solution.php
@@ -1,29 +1,29 @@
class Solution {
/**
- * @param string $s
- * @param int $numRows
- * @return string
+ * @param String $s
+ * @param Integer $numRows
+ * @return String
*/
-
function convert($s, $numRows) {
- if ($numRows == 1 || strlen($s) <= $numRows) {
+ if ($numRows == 1) {
return $s;
}
- $result = '';
- $cycleLength = 2 * $numRows - 2;
- $n = strlen($s);
+ $g = array_fill(0, $numRows, "");
+ $i = 0;
+ $k = -1;
- for ($i = 0; $i < $numRows; $i++) {
- for ($j = 0; $j + $i < $n; $j += $cycleLength) {
- $result .= $s[$j + $i];
+ $length = strlen($s);
+ for ($j = 0; $j < $length; $j++) {
+ $c = $s[$j];
+ $g[$i] .= $c;
- if ($i != 0 && $i != $numRows - 1 && $j + $cycleLength - $i < $n) {
- $result .= $s[$j + $cycleLength - $i];
- }
+ if ($i == 0 || $i == $numRows - 1) {
+ $k = -$k;
}
- }
- return $result;
+ $i += $k;
+ }
+ return implode("", $g);
}
}
diff --git a/solution/0000-0099/0006.Zigzag Conversion/Solution.rs b/solution/0000-0099/0006.Zigzag Conversion/Solution.rs
index bfbf876018144..2a4e99f2b0433 100644
--- a/solution/0000-0099/0006.Zigzag Conversion/Solution.rs
+++ b/solution/0000-0099/0006.Zigzag Conversion/Solution.rs
@@ -1,27 +1,22 @@
impl Solution {
pub fn convert(s: String, num_rows: i32) -> String {
- let num_rows = num_rows as usize;
if num_rows == 1 {
return s;
}
- let mut ss = vec![String::new(); num_rows];
+
+ let num_rows = num_rows as usize;
+ let mut g = vec![String::new(); num_rows];
let mut i = 0;
- let mut to_down = true;
+ let mut k = -1;
+
for c in s.chars() {
- ss[i].push(c);
- if to_down {
- i += 1;
- } else {
- i -= 1;
- }
+ g[i].push(c);
if i == 0 || i == num_rows - 1 {
- to_down = !to_down;
+ k = -k;
}
+ i = (i as isize + k) as usize;
}
- let mut res = String::new();
- for i in 0..num_rows {
- res += &ss[i];
- }
- res
+
+ g.concat()
}
}
diff --git a/solution/0000-0099/0006.Zigzag Conversion/Solution2.cpp b/solution/0000-0099/0006.Zigzag Conversion/Solution2.cpp
deleted file mode 100644
index f66b5d959b459..0000000000000
--- a/solution/0000-0099/0006.Zigzag Conversion/Solution2.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-class Solution {
-public:
- string convert(string s, int numRows) {
- if (numRows == 1) return s;
- string ans;
- int group = 2 * numRows - 2;
- for (int i = 1; i <= numRows; ++i) {
- int interval = i == numRows ? group : 2 * numRows - 2 * i;
- int idx = i - 1;
- while (idx < s.length()) {
- ans.push_back(s[idx]);
- idx += interval;
- interval = group - interval;
- if (interval == 0) interval = group;
- }
- }
- return ans;
- }
-};
\ No newline at end of file
diff --git a/solution/0000-0099/0006.Zigzag Conversion/Solution2.go b/solution/0000-0099/0006.Zigzag Conversion/Solution2.go
deleted file mode 100644
index acc9934f620c5..0000000000000
--- a/solution/0000-0099/0006.Zigzag Conversion/Solution2.go
+++ /dev/null
@@ -1,20 +0,0 @@
-func convert(s string, numRows int) string {
- if numRows == 1 {
- return s
- }
- n := len(s)
- ans := make([]byte, n)
- step := 2*numRows - 2
- count := 0
- for i := 0; i < numRows; i++ {
- for j := 0; j+i < n; j += step {
- ans[count] = s[i+j]
- count++
- if i != 0 && i != numRows-1 && j+step-i < n {
- ans[count] = s[j+step-i]
- count++
- }
- }
- }
- return string(ans)
-}
\ No newline at end of file
diff --git a/solution/0000-0099/0006.Zigzag Conversion/Solution2.java b/solution/0000-0099/0006.Zigzag Conversion/Solution2.java
deleted file mode 100644
index b2a9294d752f3..0000000000000
--- a/solution/0000-0099/0006.Zigzag Conversion/Solution2.java
+++ /dev/null
@@ -1,22 +0,0 @@
-class Solution {
- public String convert(String s, int numRows) {
- if (numRows == 1) {
- return s;
- }
- StringBuilder ans = new StringBuilder();
- int group = 2 * numRows - 2;
- for (int i = 1; i <= numRows; i++) {
- int interval = i == numRows ? group : 2 * numRows - 2 * i;
- int idx = i - 1;
- while (idx < s.length()) {
- ans.append(s.charAt(idx));
- idx += interval;
- interval = group - interval;
- if (interval == 0) {
- interval = group;
- }
- }
- }
- return ans.toString();
- }
-}
\ No newline at end of file
diff --git a/solution/0000-0099/0006.Zigzag Conversion/Solution2.js b/solution/0000-0099/0006.Zigzag Conversion/Solution2.js
deleted file mode 100644
index e291e38cb6b18..0000000000000
--- a/solution/0000-0099/0006.Zigzag Conversion/Solution2.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * @param {string} s
- * @param {number} numRows
- * @return {string}
- */
-var convert = function (s, numRows) {
- if (numRows == 1) return s;
- const arr = new Array(numRows);
- for (let i = 0; i < numRows; i++) arr[i] = [];
- let mi = 0,
- isDown = true;
- for (const c of s) {
- arr[mi].push(c);
-
- if (mi >= numRows - 1) isDown = false;
- else if (mi <= 0) isDown = true;
-
- if (isDown) mi++;
- else mi--;
- }
- let ans = [];
- for (const item of arr) {
- ans = ans.concat(item);
- }
- return ans.join('');
-};
diff --git a/solution/0000-0099/0006.Zigzag Conversion/Solution2.py b/solution/0000-0099/0006.Zigzag Conversion/Solution2.py
deleted file mode 100644
index 5fc2f82ff1e5a..0000000000000
--- a/solution/0000-0099/0006.Zigzag Conversion/Solution2.py
+++ /dev/null
@@ -1,16 +0,0 @@
-class Solution:
- def convert(self, s: str, numRows: int) -> str:
- if numRows == 1:
- return s
- group = 2 * numRows - 2
- ans = []
- for i in range(1, numRows + 1):
- interval = group if i == numRows else 2 * numRows - 2 * i
- idx = i - 1
- while idx < len(s):
- ans.append(s[idx])
- idx += interval
- interval = group - interval
- if interval == 0:
- interval = group
- return ''.join(ans)
diff --git a/solution/0000-0099/0006.Zigzag Conversion/Solution2.rs b/solution/0000-0099/0006.Zigzag Conversion/Solution2.rs
deleted file mode 100644
index f824b365dedec..0000000000000
--- a/solution/0000-0099/0006.Zigzag Conversion/Solution2.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-impl Solution {
- pub fn convert(s: String, num_rows: i32) -> String {
- let num_rows = num_rows as usize;
- let mut rows = vec![String::new(); num_rows];
- let iter = (0..num_rows).chain((1..num_rows - 1).rev()).cycle();
- iter.zip(s.chars()).for_each(|(i, c)| rows[i].push(c));
- rows.into_iter().collect()
- }
-}
diff --git a/solution/0000-0099/0006.Zigzag Conversion/Solution2.ts b/solution/0000-0099/0006.Zigzag Conversion/Solution2.ts
deleted file mode 100644
index 3085c8797be67..0000000000000
--- a/solution/0000-0099/0006.Zigzag Conversion/Solution2.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-function convert(s: string, numRows: number): string {
- if (numRows === 1) {
- return s;
- }
- const ss = new Array(numRows).fill('');
- let i = 0;
- let toDown = true;
- for (const c of s) {
- ss[i] += c;
- if (toDown) {
- i++;
- } else {
- i--;
- }
- if (i === 0 || i === numRows - 1) {
- toDown = !toDown;
- }
- }
- return ss.reduce((r, s) => r + s);
-}
diff --git a/solution/0000-0099/0008.String to Integer (atoi)/README.md b/solution/0000-0099/0008.String to Integer (atoi)/README.md
index a1c189c4a6ce7..87634a3e1f38a 100644
--- a/solution/0000-0099/0008.String to Integer (atoi)/README.md
+++ b/solution/0000-0099/0008.String to Integer (atoi)/README.md
@@ -214,6 +214,36 @@ class Solution {
}
```
+#### C++
+
+```cpp
+class Solution {
+public:
+ int myAtoi(string s) {
+ int i = 0, n = s.size();
+ while (i < n && s[i] == ' ')
+ ++i;
+
+ int sign = 1;
+ if (i < n && (s[i] == '-' || s[i] == '+')) {
+ sign = s[i] == '-' ? -1 : 1;
+ ++i;
+ }
+
+ int res = 0;
+ while (i < n && isdigit(s[i])) {
+ int digit = s[i] - '0';
+ if (res > INT_MAX / 10 || (res == INT_MAX / 10 && digit > INT_MAX % 10)) {
+ return sign == 1 ? INT_MAX : INT_MIN;
+ }
+ res = res * 10 + digit;
+ ++i;
+ }
+ return res * sign;
+ }
+};
+```
+
#### Go
```go
diff --git a/solution/0000-0099/0008.String to Integer (atoi)/README_EN.md b/solution/0000-0099/0008.String to Integer (atoi)/README_EN.md
index 7603001843b45..05ee6458e6711 100644
--- a/solution/0000-0099/0008.String to Integer (atoi)/README_EN.md
+++ b/solution/0000-0099/0008.String to Integer (atoi)/README_EN.md
@@ -160,7 +160,6 @@ class Solution:
i = 0
while s[i] == ' ':
i += 1
- # 仅包含空格
if i == n:
return 0
sign = -1 if s[i] == '-' else 1
@@ -168,11 +167,9 @@ class Solution:
i += 1
res, flag = 0, (2**31 - 1) // 10
while i < n:
- # 非数字,跳出循环体
if not s[i].isdigit():
break
c = int(s[i])
- # 溢出判断
if res > flag or (res == flag and c > 7):
return 2**31 - 1 if sign > 0 else -(2**31)
res = res * 10 + c
@@ -190,7 +187,6 @@ class Solution {
if (n == 0) return 0;
int i = 0;
while (s.charAt(i) == ' ') {
- // 仅包含空格
if (++i == n) return 0;
}
int sign = 1;
@@ -198,9 +194,7 @@ class Solution {
if (s.charAt(i) == '-' || s.charAt(i) == '+') ++i;
int res = 0, flag = Integer.MAX_VALUE / 10;
for (; i < n; ++i) {
- // 非数字,跳出循环体
if (s.charAt(i) < '0' || s.charAt(i) > '9') break;
- // 溢出判断
if (res > flag || (res == flag && s.charAt(i) > '7'))
return sign > 0 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
res = res * 10 + (s.charAt(i) - '0');
@@ -210,6 +204,36 @@ class Solution {
}
```
+#### C++
+
+```cpp
+class Solution {
+public:
+ int myAtoi(string s) {
+ int i = 0, n = s.size();
+ while (i < n && s[i] == ' ')
+ ++i;
+
+ int sign = 1;
+ if (i < n && (s[i] == '-' || s[i] == '+')) {
+ sign = s[i] == '-' ? -1 : 1;
+ ++i;
+ }
+
+ int res = 0;
+ while (i < n && isdigit(s[i])) {
+ int digit = s[i] - '0';
+ if (res > INT_MAX / 10 || (res == INT_MAX / 10 && digit > INT_MAX % 10)) {
+ return sign == 1 ? INT_MAX : INT_MIN;
+ }
+ res = res * 10 + digit;
+ ++i;
+ }
+ return res * sign;
+ }
+};
+```
+
#### Go
```go
@@ -282,8 +306,6 @@ const myAtoi = function (str) {
#### C#
```cs
-// https://leetcode.com/problems/string-to-integer-atoi/
-
public partial class Solution
{
public int MyAtoi(string str)
diff --git a/solution/0000-0099/0008.String to Integer (atoi)/Solution.cpp b/solution/0000-0099/0008.String to Integer (atoi)/Solution.cpp
new file mode 100644
index 0000000000000..72fc381920bf2
--- /dev/null
+++ b/solution/0000-0099/0008.String to Integer (atoi)/Solution.cpp
@@ -0,0 +1,25 @@
+class Solution {
+public:
+ int myAtoi(string s) {
+ int i = 0, n = s.size();
+ while (i < n && s[i] == ' ')
+ ++i;
+
+ int sign = 1;
+ if (i < n && (s[i] == '-' || s[i] == '+')) {
+ sign = s[i] == '-' ? -1 : 1;
+ ++i;
+ }
+
+ int res = 0;
+ while (i < n && isdigit(s[i])) {
+ int digit = s[i] - '0';
+ if (res > INT_MAX / 10 || (res == INT_MAX / 10 && digit > INT_MAX % 10)) {
+ return sign == 1 ? INT_MAX : INT_MIN;
+ }
+ res = res * 10 + digit;
+ ++i;
+ }
+ return res * sign;
+ }
+};
diff --git a/solution/0000-0099/0009.Palindrome Number/README.md b/solution/0000-0099/0009.Palindrome Number/README.md
index c0e23b1f63b38..5293dccce090b 100644
--- a/solution/0000-0099/0009.Palindrome Number/README.md
+++ b/solution/0000-0099/0009.Palindrome Number/README.md
@@ -177,13 +177,12 @@ function isPalindrome(x: number): boolean {
```rust
impl Solution {
pub fn is_palindrome(mut x: i32) -> bool {
- if x < 0 || (x % 10 == 0 && x != 0) {
+ if x < 0 || (x != 0 && x % 10 == 0) {
return false;
}
let mut y = 0;
while x > y {
- y *= 10;
- y += x % 10;
+ y = y * 10 + x % 10;
x /= 10;
}
x == y || x == y / 10
@@ -210,19 +209,41 @@ var isPalindrome = function (x) {
};
```
+#### C#
+
+```cs
+public class Solution {
+ public bool IsPalindrome(int x) {
+ if (x < 0 || (x > 0 && x % 10 == 0)) {
+ return false;
+ }
+ int y = 0;
+ for (; y < x; x /= 10) {
+ y = y * 10 + x % 10;
+ }
+ return x == y || x == y / 10;
+ }
+}
+```
+
#### PHP
```php
class Solution {
/**
- * @param int $x
- * @return boolean
+ * @param Integer $x
+ * @return Boolean
*/
-
function isPalindrome($x) {
- $str = (string) $x;
- $str_reverse = strrev($str);
- return $str === $str_reverse;
+ if ($x < 0 || ($x && $x % 10 == 0)) {
+ return false;
+ }
+ $y = 0;
+ while ($x > $y) {
+ $y = $y * 10 + ($x % 10);
+ $x = (int) ($x / 10);
+ }
+ return $x == $y || $x == (int) ($y / 10);
}
}
```
diff --git a/solution/0000-0099/0009.Palindrome Number/README_EN.md b/solution/0000-0099/0009.Palindrome Number/README_EN.md
index 0392466009818..8b0ac2e383ca0 100644
--- a/solution/0000-0099/0009.Palindrome Number/README_EN.md
+++ b/solution/0000-0099/0009.Palindrome Number/README_EN.md
@@ -169,13 +169,12 @@ function isPalindrome(x: number): boolean {
```rust
impl Solution {
pub fn is_palindrome(mut x: i32) -> bool {
- if x < 0 || (x % 10 == 0 && x != 0) {
+ if x < 0 || (x != 0 && x % 10 == 0) {
return false;
}
let mut y = 0;
while x > y {
- y *= 10;
- y += x % 10;
+ y = y * 10 + x % 10;
x /= 10;
}
x == y || x == y / 10
@@ -202,19 +201,41 @@ var isPalindrome = function (x) {
};
```
+#### C#
+
+```cs
+public class Solution {
+ public bool IsPalindrome(int x) {
+ if (x < 0 || (x > 0 && x % 10 == 0)) {
+ return false;
+ }
+ int y = 0;
+ for (; y < x; x /= 10) {
+ y = y * 10 + x % 10;
+ }
+ return x == y || x == y / 10;
+ }
+}
+```
+
#### PHP
```php
class Solution {
/**
- * @param int $x
- * @return boolean
+ * @param Integer $x
+ * @return Boolean
*/
-
function isPalindrome($x) {
- $str = (string) $x;
- $str_reverse = strrev($str);
- return $str === $str_reverse;
+ if ($x < 0 || ($x && $x % 10 == 0)) {
+ return false;
+ }
+ $y = 0;
+ while ($x > $y) {
+ $y = $y * 10 + ($x % 10);
+ $x = (int) ($x / 10);
+ }
+ return $x == $y || $x == (int) ($y / 10);
}
}
```
diff --git a/solution/0000-0099/0009.Palindrome Number/Solution.cs b/solution/0000-0099/0009.Palindrome Number/Solution.cs
new file mode 100644
index 0000000000000..f530d9156371b
--- /dev/null
+++ b/solution/0000-0099/0009.Palindrome Number/Solution.cs
@@ -0,0 +1,12 @@
+public class Solution {
+ public bool IsPalindrome(int x) {
+ if (x < 0 || (x > 0 && x % 10 == 0)) {
+ return false;
+ }
+ int y = 0;
+ for (; y < x; x /= 10) {
+ y = y * 10 + x % 10;
+ }
+ return x == y || x == y / 10;
+ }
+}
\ No newline at end of file
diff --git a/solution/0000-0099/0009.Palindrome Number/Solution.php b/solution/0000-0099/0009.Palindrome Number/Solution.php
index 9fd8c6654ec95..c4042d56fbed1 100644
--- a/solution/0000-0099/0009.Palindrome Number/Solution.php
+++ b/solution/0000-0099/0009.Palindrome Number/Solution.php
@@ -1,12 +1,17 @@
class Solution {
/**
- * @param int $x
- * @return boolean
+ * @param Integer $x
+ * @return Boolean
*/
-
function isPalindrome($x) {
- $str = (string) $x;
- $str_reverse = strrev($str);
- return $str === $str_reverse;
+ if ($x < 0 || ($x && $x % 10 == 0)) {
+ return false;
+ }
+ $y = 0;
+ while ($x > $y) {
+ $y = $y * 10 + ($x % 10);
+ $x = (int) ($x / 10);
+ }
+ return $x == $y || $x == (int) ($y / 10);
}
}
diff --git a/solution/0000-0099/0009.Palindrome Number/Solution.rs b/solution/0000-0099/0009.Palindrome Number/Solution.rs
index 7163690151d08..9275d20a011d7 100644
--- a/solution/0000-0099/0009.Palindrome Number/Solution.rs
+++ b/solution/0000-0099/0009.Palindrome Number/Solution.rs
@@ -1,20 +1,13 @@
impl Solution {
- pub fn is_palindrome(x: i32) -> bool {
- if x < 0 {
+ pub fn is_palindrome(mut x: i32) -> bool {
+ if x < 0 || (x != 0 && x % 10 == 0) {
return false;
}
- let s = x.to_string();
- let bs = s.as_bytes();
- let n = bs.len();
- let mut l = 0;
- let mut r = n - 1;
- while l < r {
- if bs[l] != bs[r] {
- return false;
- }
- l += 1;
- r -= 1;
+ let mut y = 0;
+ while x > y {
+ y = y * 10 + x % 10;
+ x /= 10;
}
- true
+ x == y || x == y / 10
}
}
diff --git a/solution/0000-0099/0016.3Sum Closest/README.md b/solution/0000-0099/0016.3Sum Closest/README.md
index 26a419cdec0e9..406e23f70dbb9 100644
--- a/solution/0000-0099/0016.3Sum Closest/README.md
+++ b/solution/0000-0099/0016.3Sum Closest/README.md
@@ -242,6 +242,36 @@ var threeSumClosest = function (nums, target) {
};
```
+#### C#
+
+```cs
+public class Solution {
+ public int ThreeSumClosest(int[] nums, int target) {
+ Array.Sort(nums);
+ int ans = 1 << 30;
+ int n = nums.Length;
+ for (int i = 0; i < n; ++i) {
+ int j = i + 1, k = n - 1;
+ while (j < k) {
+ int t = nums[i] + nums[j] + nums[k];
+ if (t == target) {
+ return t;
+ }
+ if (Math.Abs(t - target) < Math.Abs(ans - target)) {
+ ans = t;
+ }
+ if (t > target) {
+ --k;
+ } else {
+ ++j;
+ }
+ }
+ }
+ return ans;
+ }
+}
+```
+
#### PHP
```php
diff --git a/solution/0000-0099/0016.3Sum Closest/README_EN.md b/solution/0000-0099/0016.3Sum Closest/README_EN.md
index 92375933a0907..b5ccdf0198cd0 100644
--- a/solution/0000-0099/0016.3Sum Closest/README_EN.md
+++ b/solution/0000-0099/0016.3Sum Closest/README_EN.md
@@ -241,6 +241,36 @@ var threeSumClosest = function (nums, target) {
};
```
+#### C#
+
+```cs
+public class Solution {
+ public int ThreeSumClosest(int[] nums, int target) {
+ Array.Sort(nums);
+ int ans = 1 << 30;
+ int n = nums.Length;
+ for (int i = 0; i < n; ++i) {
+ int j = i + 1, k = n - 1;
+ while (j < k) {
+ int t = nums[i] + nums[j] + nums[k];
+ if (t == target) {
+ return t;
+ }
+ if (Math.Abs(t - target) < Math.Abs(ans - target)) {
+ ans = t;
+ }
+ if (t > target) {
+ --k;
+ } else {
+ ++j;
+ }
+ }
+ }
+ return ans;
+ }
+}
+```
+
#### PHP
```php
diff --git a/solution/0000-0099/0016.3Sum Closest/Solution.cs b/solution/0000-0099/0016.3Sum Closest/Solution.cs
new file mode 100644
index 0000000000000..d58947aab214b
--- /dev/null
+++ b/solution/0000-0099/0016.3Sum Closest/Solution.cs
@@ -0,0 +1,25 @@
+public class Solution {
+ public int ThreeSumClosest(int[] nums, int target) {
+ Array.Sort(nums);
+ int ans = 1 << 30;
+ int n = nums.Length;
+ for (int i = 0; i < n; ++i) {
+ int j = i + 1, k = n - 1;
+ while (j < k) {
+ int t = nums[i] + nums[j] + nums[k];
+ if (t == target) {
+ return t;
+ }
+ if (Math.Abs(t - target) < Math.Abs(ans - target)) {
+ ans = t;
+ }
+ if (t > target) {
+ --k;
+ } else {
+ ++j;
+ }
+ }
+ }
+ return ans;
+ }
+}
\ No newline at end of file
diff --git a/solution/0000-0099/0019.Remove Nth Node From End of List/README.md b/solution/0000-0099/0019.Remove Nth Node From End of List/README.md
index e9931cdde2d49..151c80eb0c329 100644
--- a/solution/0000-0099/0019.Remove Nth Node From End of List/README.md
+++ b/solution/0000-0099/0019.Remove Nth Node From End of List/README.md
@@ -280,7 +280,7 @@ var removeNthFromEnd = function (head, n) {
#### Swift
-````swift
+```swift
/**
* Definition for singly-linked list.
* public class ListNode {
@@ -340,6 +340,37 @@ def remove_nth_from_end(head, n)
end
```
+#### C#
+
+```cs
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public int val;
+ * public ListNode next;
+ * public ListNode(int val=0, ListNode next=null) {
+ * this.val = val;
+ * this.next = next;
+ * }
+ * }
+ */
+public class Solution {
+ public ListNode RemoveNthFromEnd(ListNode head, int n) {
+ ListNode dummy = new ListNode(0, head);
+ ListNode fast = dummy, slow = dummy;
+ while (n-- > 0) {
+ fast = fast.next;
+ }
+ while (fast.next != null) {
+ slow = slow.next;
+ fast = fast.next;
+ }
+ slow.next = slow.next.next;
+ return dummy.next;
+ }
+}
+```
+
#### PHP
```php
@@ -381,4 +412,3 @@ class Solution {
-````
diff --git a/solution/0000-0099/0019.Remove Nth Node From End of List/README_EN.md b/solution/0000-0099/0019.Remove Nth Node From End of List/README_EN.md
index 6c85e356c3109..3905ab6e2d5de 100644
--- a/solution/0000-0099/0019.Remove Nth Node From End of List/README_EN.md
+++ b/solution/0000-0099/0019.Remove Nth Node From End of List/README_EN.md
@@ -277,7 +277,7 @@ var removeNthFromEnd = function (head, n) {
#### Swift
-````swift
+```swift
/**
* Definition for singly-linked list.
* public class ListNode {
@@ -337,6 +337,37 @@ def remove_nth_from_end(head, n)
end
```
+#### C#
+
+```cs
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public int val;
+ * public ListNode next;
+ * public ListNode(int val=0, ListNode next=null) {
+ * this.val = val;
+ * this.next = next;
+ * }
+ * }
+ */
+public class Solution {
+ public ListNode RemoveNthFromEnd(ListNode head, int n) {
+ ListNode dummy = new ListNode(0, head);
+ ListNode fast = dummy, slow = dummy;
+ while (n-- > 0) {
+ fast = fast.next;
+ }
+ while (fast.next != null) {
+ slow = slow.next;
+ fast = fast.next;
+ }
+ slow.next = slow.next.next;
+ return dummy.next;
+ }
+}
+```
+
#### PHP
```php
@@ -378,4 +409,3 @@ class Solution {
-````
diff --git a/solution/0000-0099/0019.Remove Nth Node From End of List/Solution.cs b/solution/0000-0099/0019.Remove Nth Node From End of List/Solution.cs
new file mode 100644
index 0000000000000..fe8e8f8c798e3
--- /dev/null
+++ b/solution/0000-0099/0019.Remove Nth Node From End of List/Solution.cs
@@ -0,0 +1,26 @@
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public int val;
+ * public ListNode next;
+ * public ListNode(int val=0, ListNode next=null) {
+ * this.val = val;
+ * this.next = next;
+ * }
+ * }
+ */
+public class Solution {
+ public ListNode RemoveNthFromEnd(ListNode head, int n) {
+ ListNode dummy = new ListNode(0, head);
+ ListNode fast = dummy, slow = dummy;
+ while (n-- > 0) {
+ fast = fast.next;
+ }
+ while (fast.next != null) {
+ slow = slow.next;
+ fast = fast.next;
+ }
+ slow.next = slow.next.next;
+ return dummy.next;
+ }
+}
\ No newline at end of file
diff --git a/solution/0000-0099/0021.Merge Two Sorted Lists/README.md b/solution/0000-0099/0021.Merge Two Sorted Lists/README.md
index 264c42ada1421..e38399664ae75 100644
--- a/solution/0000-0099/0021.Merge Two Sorted Lists/README.md
+++ b/solution/0000-0099/0021.Merge Two Sorted Lists/README.md
@@ -295,24 +295,19 @@ var mergeTwoLists = function (list1, list2) {
*/
public class Solution {
public ListNode MergeTwoLists(ListNode list1, ListNode list2) {
- ListNode dummy = new ListNode();
- ListNode cur = dummy;
- while (list1 != null && list2 != null)
- {
- if (list1.val <= list2.val)
- {
- cur.next = list1;
- list1 = list1.next;
- }
- else
- {
- cur.next = list2;
- list2 = list2.next;
- }
- cur = cur.next;
+ if (list1 == null) {
+ return list2;
+ }
+ if (list2 == null) {
+ return list1;
+ }
+ if (list1.val <= list2.val) {
+ list1.next = MergeTwoLists(list1.next, list2);
+ return list1;
+ } else {
+ list2.next = MergeTwoLists(list1, list2.next);
+ return list2;
}
- cur.next = list1 == null ? list2 : list1;
- return dummy.next;
}
}
```
@@ -332,23 +327,60 @@ public class Solution {
# @param {ListNode} list2
# @return {ListNode}
def merge_two_lists(list1, list2)
- dummy = ListNode.new()
- cur = dummy
- while list1 && list2
- if list1.val <= list2.val
- cur.next = list1
- list1 = list1.next
- else
- cur.next = list2
- list2 = list2.next
- end
- cur = cur.next
+ if list1.nil?
+ return list2
+ end
+ if list2.nil?
+ return list1
+ end
+ if list1.val <= list2.val
+ list1.next = merge_two_lists(list1.next, list2)
+ return list1
+ else
+ list2.next = merge_two_lists(list1, list2.next)
+ return list2
end
- cur.next = list1 || list2
- dummy.next
end
```
+#### PHP
+
+```php
+/**
+ * Definition for a singly-linked list.
+ * class ListNode {
+ * public $val = 0;
+ * public $next = null;
+ * function __construct($val = 0, $next = null) {
+ * $this->val = $val;
+ * $this->next = $next;
+ * }
+ * }
+ */
+class Solution {
+ /**
+ * @param ListNode $list1
+ * @param ListNode $list2
+ * @return ListNode
+ */
+ function mergeTwoLists($list1, $list2) {
+ if (is_null($list1)) {
+ return $list2;
+ }
+ if (is_null($list2)) {
+ return $list1;
+ }
+ if ($list1->val <= $list2->val) {
+ $list1->next = $this->mergeTwoLists($list1->next, $list2);
+ return $list1;
+ } else {
+ $list2->next = $this->mergeTwoLists($list1, $list2->next);
+ return $list2;
+ }
+ }
+}
+```
+
@@ -603,6 +635,72 @@ var mergeTwoLists = function (list1, list2) {
};
```
+#### C#
+
+```cs
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public int val;
+ * public ListNode next;
+ * public ListNode(int val=0, ListNode next=null) {
+ * this.val = val;
+ * this.next = next;
+ * }
+ * }
+ */
+public class Solution {
+ public ListNode MergeTwoLists(ListNode list1, ListNode list2) {
+ ListNode dummy = new ListNode();
+ ListNode curr = dummy;
+ while (list1 != null && list2 != null) {
+ if (list1.val <= list2.val) {
+ curr.next = list1;
+ list1 = list1.next;
+ } else {
+ curr.next = list2;
+ list2 = list2.next;
+ }
+ curr = curr.next;
+ }
+ curr.next = list1 == null ? list2 : list1;
+ return dummy.next;
+ }
+}
+```
+
+#### Ruby
+
+```rb
+# Definition for singly-linked list.
+# class ListNode
+# attr_accessor :val, :next
+# def initialize(val = 0, _next = nil)
+# @val = val
+# @next = _next
+# end
+# end
+# @param {ListNode} list1
+# @param {ListNode} list2
+# @return {ListNode}
+def merge_two_lists(list1, list2)
+ dummy = ListNode.new()
+ cur = dummy
+ while list1 && list2
+ if list1.val <= list2.val
+ cur.next = list1
+ list1 = list1.next
+ else
+ cur.next = list2
+ list2 = list2.next
+ end
+ cur = cur.next
+ end
+ cur.next = list1 || list2
+ dummy.next
+end
+```
+
#### PHP
```php
@@ -616,18 +714,15 @@ var mergeTwoLists = function (list1, list2) {
# $this->next = $next;
# }
# }
-
class Solution {
/**
* @param ListNode $list1
* @param ListNode $list2
* @return ListNode
*/
-
function mergeTwoLists($list1, $list2) {
$dummy = new ListNode(0);
$current = $dummy;
-
while ($list1 != null && $list2 != null) {
if ($list1->val <= $list2->val) {
$current->next = $list1;
diff --git a/solution/0000-0099/0021.Merge Two Sorted Lists/README_EN.md b/solution/0000-0099/0021.Merge Two Sorted Lists/README_EN.md
index 1aaa040d75715..5813dda5912a8 100644
--- a/solution/0000-0099/0021.Merge Two Sorted Lists/README_EN.md
+++ b/solution/0000-0099/0021.Merge Two Sorted Lists/README_EN.md
@@ -297,24 +297,19 @@ var mergeTwoLists = function (list1, list2) {
*/
public class Solution {
public ListNode MergeTwoLists(ListNode list1, ListNode list2) {
- ListNode dummy = new ListNode();
- ListNode cur = dummy;
- while (list1 != null && list2 != null)
- {
- if (list1.val <= list2.val)
- {
- cur.next = list1;
- list1 = list1.next;
- }
- else
- {
- cur.next = list2;
- list2 = list2.next;
- }
- cur = cur.next;
+ if (list1 == null) {
+ return list2;
+ }
+ if (list2 == null) {
+ return list1;
+ }
+ if (list1.val <= list2.val) {
+ list1.next = MergeTwoLists(list1.next, list2);
+ return list1;
+ } else {
+ list2.next = MergeTwoLists(list1, list2.next);
+ return list2;
}
- cur.next = list1 == null ? list2 : list1;
- return dummy.next;
}
}
```
@@ -334,23 +329,60 @@ public class Solution {
# @param {ListNode} list2
# @return {ListNode}
def merge_two_lists(list1, list2)
- dummy = ListNode.new()
- cur = dummy
- while list1 && list2
- if list1.val <= list2.val
- cur.next = list1
- list1 = list1.next
- else
- cur.next = list2
- list2 = list2.next
- end
- cur = cur.next
+ if list1.nil?
+ return list2
+ end
+ if list2.nil?
+ return list1
+ end
+ if list1.val <= list2.val
+ list1.next = merge_two_lists(list1.next, list2)
+ return list1
+ else
+ list2.next = merge_two_lists(list1, list2.next)
+ return list2
end
- cur.next = list1 || list2
- dummy.next
end
```
+#### PHP
+
+```php
+/**
+ * Definition for a singly-linked list.
+ * class ListNode {
+ * public $val = 0;
+ * public $next = null;
+ * function __construct($val = 0, $next = null) {
+ * $this->val = $val;
+ * $this->next = $next;
+ * }
+ * }
+ */
+class Solution {
+ /**
+ * @param ListNode $list1
+ * @param ListNode $list2
+ * @return ListNode
+ */
+ function mergeTwoLists($list1, $list2) {
+ if (is_null($list1)) {
+ return $list2;
+ }
+ if (is_null($list2)) {
+ return $list1;
+ }
+ if ($list1->val <= $list2->val) {
+ $list1->next = $this->mergeTwoLists($list1->next, $list2);
+ return $list1;
+ } else {
+ $list2->next = $this->mergeTwoLists($list1, $list2->next);
+ return $list2;
+ }
+ }
+}
+```
+
@@ -605,6 +637,72 @@ var mergeTwoLists = function (list1, list2) {
};
```
+#### C#
+
+```cs
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public int val;
+ * public ListNode next;
+ * public ListNode(int val=0, ListNode next=null) {
+ * this.val = val;
+ * this.next = next;
+ * }
+ * }
+ */
+public class Solution {
+ public ListNode MergeTwoLists(ListNode list1, ListNode list2) {
+ ListNode dummy = new ListNode();
+ ListNode curr = dummy;
+ while (list1 != null && list2 != null) {
+ if (list1.val <= list2.val) {
+ curr.next = list1;
+ list1 = list1.next;
+ } else {
+ curr.next = list2;
+ list2 = list2.next;
+ }
+ curr = curr.next;
+ }
+ curr.next = list1 == null ? list2 : list1;
+ return dummy.next;
+ }
+}
+```
+
+#### Ruby
+
+```rb
+# Definition for singly-linked list.
+# class ListNode
+# attr_accessor :val, :next
+# def initialize(val = 0, _next = nil)
+# @val = val
+# @next = _next
+# end
+# end
+# @param {ListNode} list1
+# @param {ListNode} list2
+# @return {ListNode}
+def merge_two_lists(list1, list2)
+ dummy = ListNode.new()
+ cur = dummy
+ while list1 && list2
+ if list1.val <= list2.val
+ cur.next = list1
+ list1 = list1.next
+ else
+ cur.next = list2
+ list2 = list2.next
+ end
+ cur = cur.next
+ end
+ cur.next = list1 || list2
+ dummy.next
+end
+```
+
#### PHP
```php
@@ -618,18 +716,15 @@ var mergeTwoLists = function (list1, list2) {
# $this->next = $next;
# }
# }
-
class Solution {
/**
* @param ListNode $list1
* @param ListNode $list2
* @return ListNode
*/
-
function mergeTwoLists($list1, $list2) {
$dummy = new ListNode(0);
$current = $dummy;
-
while ($list1 != null && $list2 != null) {
if ($list1->val <= $list2->val) {
$current->next = $list1;
diff --git a/solution/0000-0099/0021.Merge Two Sorted Lists/Solution.cs b/solution/0000-0099/0021.Merge Two Sorted Lists/Solution.cs
index f51146a70d7d9..c5cf87486fe07 100644
--- a/solution/0000-0099/0021.Merge Two Sorted Lists/Solution.cs
+++ b/solution/0000-0099/0021.Merge Two Sorted Lists/Solution.cs
@@ -11,23 +11,18 @@
*/
public class Solution {
public ListNode MergeTwoLists(ListNode list1, ListNode list2) {
- ListNode dummy = new ListNode();
- ListNode cur = dummy;
- while (list1 != null && list2 != null)
- {
- if (list1.val <= list2.val)
- {
- cur.next = list1;
- list1 = list1.next;
- }
- else
- {
- cur.next = list2;
- list2 = list2.next;
- }
- cur = cur.next;
+ if (list1 == null) {
+ return list2;
+ }
+ if (list2 == null) {
+ return list1;
+ }
+ if (list1.val <= list2.val) {
+ list1.next = MergeTwoLists(list1.next, list2);
+ return list1;
+ } else {
+ list2.next = MergeTwoLists(list1, list2.next);
+ return list2;
}
- cur.next = list1 == null ? list2 : list1;
- return dummy.next;
}
-}
+}
\ No newline at end of file
diff --git a/solution/0000-0099/0021.Merge Two Sorted Lists/Solution.php b/solution/0000-0099/0021.Merge Two Sorted Lists/Solution.php
index 43c1e40cec909..5ba6c289539bf 100644
--- a/solution/0000-0099/0021.Merge Two Sorted Lists/Solution.php
+++ b/solution/0000-0099/0021.Merge Two Sorted Lists/Solution.php
@@ -1,40 +1,34 @@
-# Definition for singly-linked list.
-# class ListNode {
-# public $val;
-# public $next;
-# public function __construct($val = 0, $next = null)
-# {
-# $this->val = $val;
-# $this->next = $next;
-# }
-# }
-
+/**
+ * Definition for a singly-linked list.
+ * class ListNode {
+ * public $val = 0;
+ * public $next = null;
+ * function __construct($val = 0, $next = null) {
+ * $this->val = $val;
+ * $this->next = $next;
+ * }
+ * }
+ */
class Solution {
+
/**
* @param ListNode $list1
* @param ListNode $list2
* @return ListNode
*/
-
function mergeTwoLists($list1, $list2) {
- $dummy = new ListNode(0);
- $current = $dummy;
-
- while ($list1 != null && $list2 != null) {
- if ($list1->val <= $list2->val) {
- $current->next = $list1;
- $list1 = $list1->next;
- } else {
- $current->next = $list2;
- $list2 = $list2->next;
- }
- $current = $current->next;
+ if (is_null($list1)) {
+ return $list2;
+ }
+ if (is_null($list2)) {
+ return $list1;
}
- if ($list1 != null) {
- $current->next = $list1;
- } elseif ($list2 != null) {
- $current->next = $list2;
+ if ($list1->val <= $list2->val) {
+ $list1->next = $this->mergeTwoLists($list1->next, $list2);
+ return $list1;
+ } else {
+ $list2->next = $this->mergeTwoLists($list1, $list2->next);
+ return $list2;
}
- return $dummy->next;
}
-}
+}
\ No newline at end of file
diff --git a/solution/0000-0099/0021.Merge Two Sorted Lists/Solution.rb b/solution/0000-0099/0021.Merge Two Sorted Lists/Solution.rb
index f27273d9fd652..db48f5d196b65 100644
--- a/solution/0000-0099/0021.Merge Two Sorted Lists/Solution.rb
+++ b/solution/0000-0099/0021.Merge Two Sorted Lists/Solution.rb
@@ -10,18 +10,17 @@
# @param {ListNode} list2
# @return {ListNode}
def merge_two_lists(list1, list2)
- dummy = ListNode.new()
- cur = dummy
- while list1 && list2
- if list1.val <= list2.val
- cur.next = list1
- list1 = list1.next
- else
- cur.next = list2
- list2 = list2.next
- end
- cur = cur.next
+ if list1.nil?
+ return list2
end
- cur.next = list1 || list2
- dummy.next
-end
+ if list2.nil?
+ return list1
+ end
+ if list1.val <= list2.val
+ list1.next = merge_two_lists(list1.next, list2)
+ return list1
+ else
+ list2.next = merge_two_lists(list1, list2.next)
+ return list2
+ end
+end
\ No newline at end of file
diff --git a/solution/0000-0099/0021.Merge Two Sorted Lists/Solution2.cs b/solution/0000-0099/0021.Merge Two Sorted Lists/Solution2.cs
new file mode 100644
index 0000000000000..53d85f2d7f0fa
--- /dev/null
+++ b/solution/0000-0099/0021.Merge Two Sorted Lists/Solution2.cs
@@ -0,0 +1,29 @@
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public int val;
+ * public ListNode next;
+ * public ListNode(int val=0, ListNode next=null) {
+ * this.val = val;
+ * this.next = next;
+ * }
+ * }
+ */
+public class Solution {
+ public ListNode MergeTwoLists(ListNode list1, ListNode list2) {
+ ListNode dummy = new ListNode();
+ ListNode curr = dummy;
+ while (list1 != null && list2 != null) {
+ if (list1.val <= list2.val) {
+ curr.next = list1;
+ list1 = list1.next;
+ } else {
+ curr.next = list2;
+ list2 = list2.next;
+ }
+ curr = curr.next;
+ }
+ curr.next = list1 == null ? list2 : list1;
+ return dummy.next;
+ }
+}
\ No newline at end of file
diff --git a/solution/0000-0099/0021.Merge Two Sorted Lists/Solution2.php b/solution/0000-0099/0021.Merge Two Sorted Lists/Solution2.php
new file mode 100644
index 0000000000000..375be195d3815
--- /dev/null
+++ b/solution/0000-0099/0021.Merge Two Sorted Lists/Solution2.php
@@ -0,0 +1,37 @@
+# Definition for singly-linked list.
+# class ListNode {
+# public $val;
+# public $next;
+# public function __construct($val = 0, $next = null)
+# {
+# $this->val = $val;
+# $this->next = $next;
+# }
+# }
+class Solution {
+ /**
+ * @param ListNode $list1
+ * @param ListNode $list2
+ * @return ListNode
+ */
+ function mergeTwoLists($list1, $list2) {
+ $dummy = new ListNode(0);
+ $current = $dummy;
+ while ($list1 != null && $list2 != null) {
+ if ($list1->val <= $list2->val) {
+ $current->next = $list1;
+ $list1 = $list1->next;
+ } else {
+ $current->next = $list2;
+ $list2 = $list2->next;
+ }
+ $current = $current->next;
+ }
+ if ($list1 != null) {
+ $current->next = $list1;
+ } elseif ($list2 != null) {
+ $current->next = $list2;
+ }
+ return $dummy->next;
+ }
+}
diff --git a/solution/0000-0099/0021.Merge Two Sorted Lists/Solution2.rb b/solution/0000-0099/0021.Merge Two Sorted Lists/Solution2.rb
new file mode 100644
index 0000000000000..f27273d9fd652
--- /dev/null
+++ b/solution/0000-0099/0021.Merge Two Sorted Lists/Solution2.rb
@@ -0,0 +1,27 @@
+# Definition for singly-linked list.
+# class ListNode
+# attr_accessor :val, :next
+# def initialize(val = 0, _next = nil)
+# @val = val
+# @next = _next
+# end
+# end
+# @param {ListNode} list1
+# @param {ListNode} list2
+# @return {ListNode}
+def merge_two_lists(list1, list2)
+ dummy = ListNode.new()
+ cur = dummy
+ while list1 && list2
+ if list1.val <= list2.val
+ cur.next = list1
+ list1 = list1.next
+ else
+ cur.next = list2
+ list2 = list2.next
+ end
+ cur = cur.next
+ end
+ cur.next = list1 || list2
+ dummy.next
+end
diff --git a/solution/0000-0099/0022.Generate Parentheses/README.md b/solution/0000-0099/0022.Generate Parentheses/README.md
index 5dd9d47a628aa..b470955a10c8a 100644
--- a/solution/0000-0099/0022.Generate Parentheses/README.md
+++ b/solution/0000-0099/0022.Generate Parentheses/README.md
@@ -225,6 +225,33 @@ var generateParenthesis = function (n) {
};
```
+#### C#
+
+```cs
+public class Solution {
+ private List ans = new List();
+ private int n;
+
+ public List GenerateParenthesis(int n) {
+ this.n = n;
+ Dfs(0, 0, "");
+ return ans;
+ }
+
+ private void Dfs(int l, int r, string t) {
+ if (l > n || r > n || l < r) {
+ return;
+ }
+ if (l == n && r == n) {
+ ans.Add(t);
+ return;
+ }
+ Dfs(l + 1, r, t + "(");
+ Dfs(l, r + 1, t + ")");
+ }
+}
+```
+
#### PHP
```php
diff --git a/solution/0000-0099/0022.Generate Parentheses/README_EN.md b/solution/0000-0099/0022.Generate Parentheses/README_EN.md
index 6eeb019475ce1..867a20c5fb1d8 100644
--- a/solution/0000-0099/0022.Generate Parentheses/README_EN.md
+++ b/solution/0000-0099/0022.Generate Parentheses/README_EN.md
@@ -220,6 +220,33 @@ var generateParenthesis = function (n) {
};
```
+#### C#
+
+```cs
+public class Solution {
+ private List ans = new List();
+ private int n;
+
+ public List GenerateParenthesis(int n) {
+ this.n = n;
+ Dfs(0, 0, "");
+ return ans;
+ }
+
+ private void Dfs(int l, int r, string t) {
+ if (l > n || r > n || l < r) {
+ return;
+ }
+ if (l == n && r == n) {
+ ans.Add(t);
+ return;
+ }
+ Dfs(l + 1, r, t + "(");
+ Dfs(l, r + 1, t + ")");
+ }
+}
+```
+
#### PHP
```php
diff --git a/solution/0000-0099/0022.Generate Parentheses/Solution.cs b/solution/0000-0099/0022.Generate Parentheses/Solution.cs
new file mode 100644
index 0000000000000..6f6257e62a39e
--- /dev/null
+++ b/solution/0000-0099/0022.Generate Parentheses/Solution.cs
@@ -0,0 +1,22 @@
+public class Solution {
+ private List ans = new List();
+ private int n;
+
+ public List GenerateParenthesis(int n) {
+ this.n = n;
+ Dfs(0, 0, "");
+ return ans;
+ }
+
+ private void Dfs(int l, int r, string t) {
+ if (l > n || r > n || l < r) {
+ return;
+ }
+ if (l == n && r == n) {
+ ans.Add(t);
+ return;
+ }
+ Dfs(l + 1, r, t + "(");
+ Dfs(l, r + 1, t + ")");
+ }
+}
\ No newline at end of file
diff --git a/solution/0000-0099/0024.Swap Nodes in Pairs/README.md b/solution/0000-0099/0024.Swap Nodes in Pairs/README.md
index 38a1b4904219d..e2b5f98ec92b8 100644
--- a/solution/0000-0099/0024.Swap Nodes in Pairs/README.md
+++ b/solution/0000-0099/0024.Swap Nodes in Pairs/README.md
@@ -256,6 +256,34 @@ var swapPairs = function (head) {
};
```
+#### C#
+
+```cs
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public int val;
+ * public ListNode next;
+ * public ListNode(int val=0, ListNode next=null) {
+ * this.val = val;
+ * this.next = next;
+ * }
+ * }
+ */
+public class Solution {
+ public ListNode SwapPairs(ListNode head) {
+ if (head is null || head.next is null) {
+ return head;
+ }
+ ListNode t = SwapPairs(head.next.next);
+ ListNode p = head.next;
+ p.next = head;
+ head.next = t;
+ return p;
+ }
+}
+```
+
#### Ruby
```rb
@@ -466,6 +494,38 @@ var swapPairs = function (head) {
};
```
+#### C#
+
+```cs
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public int val;
+ * public ListNode next;
+ * public ListNode(int val=0, ListNode next=null) {
+ * this.val = val;
+ * this.next = next;
+ * }
+ * }
+ */
+public class Solution {
+ public ListNode SwapPairs(ListNode head) {
+ ListNode dummy = new ListNode(0, head);
+ ListNode pre = dummy;
+ ListNode cur = head;
+ while (cur is not null && cur.next is not null) {
+ ListNode t = cur.next;
+ cur.next = t.next;
+ t.next = cur;
+ pre.next = t;
+ pre = cur;
+ cur = cur.next;
+ }
+ return dummy.next;
+ }
+}
+```
+
#### PHP
```php
diff --git a/solution/0000-0099/0024.Swap Nodes in Pairs/README_EN.md b/solution/0000-0099/0024.Swap Nodes in Pairs/README_EN.md
index f2a3dc01f612a..e9340a634752c 100644
--- a/solution/0000-0099/0024.Swap Nodes in Pairs/README_EN.md
+++ b/solution/0000-0099/0024.Swap Nodes in Pairs/README_EN.md
@@ -269,6 +269,34 @@ var swapPairs = function (head) {
};
```
+#### C#
+
+```cs
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public int val;
+ * public ListNode next;
+ * public ListNode(int val=0, ListNode next=null) {
+ * this.val = val;
+ * this.next = next;
+ * }
+ * }
+ */
+public class Solution {
+ public ListNode SwapPairs(ListNode head) {
+ if (head is null || head.next is null) {
+ return head;
+ }
+ ListNode t = SwapPairs(head.next.next);
+ ListNode p = head.next;
+ p.next = head;
+ head.next = t;
+ return p;
+ }
+}
+```
+
#### Ruby
```rb
@@ -479,6 +507,38 @@ var swapPairs = function (head) {
};
```
+#### C#
+
+```cs
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public int val;
+ * public ListNode next;
+ * public ListNode(int val=0, ListNode next=null) {
+ * this.val = val;
+ * this.next = next;
+ * }
+ * }
+ */
+public class Solution {
+ public ListNode SwapPairs(ListNode head) {
+ ListNode dummy = new ListNode(0, head);
+ ListNode pre = dummy;
+ ListNode cur = head;
+ while (cur is not null && cur.next is not null) {
+ ListNode t = cur.next;
+ cur.next = t.next;
+ t.next = cur;
+ pre.next = t;
+ pre = cur;
+ cur = cur.next;
+ }
+ return dummy.next;
+ }
+}
+```
+
#### PHP
```php
diff --git a/solution/0000-0099/0024.Swap Nodes in Pairs/Solution.cs b/solution/0000-0099/0024.Swap Nodes in Pairs/Solution.cs
new file mode 100644
index 0000000000000..ddeda2166b005
--- /dev/null
+++ b/solution/0000-0099/0024.Swap Nodes in Pairs/Solution.cs
@@ -0,0 +1,23 @@
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public int val;
+ * public ListNode next;
+ * public ListNode(int val=0, ListNode next=null) {
+ * this.val = val;
+ * this.next = next;
+ * }
+ * }
+ */
+public class Solution {
+ public ListNode SwapPairs(ListNode head) {
+ if (head is null || head.next is null) {
+ return head;
+ }
+ ListNode t = SwapPairs(head.next.next);
+ ListNode p = head.next;
+ p.next = head;
+ head.next = t;
+ return p;
+ }
+}
\ No newline at end of file
diff --git a/solution/0000-0099/0024.Swap Nodes in Pairs/Solution2.cs b/solution/0000-0099/0024.Swap Nodes in Pairs/Solution2.cs
new file mode 100644
index 0000000000000..aee6f3c492711
--- /dev/null
+++ b/solution/0000-0099/0024.Swap Nodes in Pairs/Solution2.cs
@@ -0,0 +1,27 @@
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public int val;
+ * public ListNode next;
+ * public ListNode(int val=0, ListNode next=null) {
+ * this.val = val;
+ * this.next = next;
+ * }
+ * }
+ */
+public class Solution {
+ public ListNode SwapPairs(ListNode head) {
+ ListNode dummy = new ListNode(0, head);
+ ListNode pre = dummy;
+ ListNode cur = head;
+ while (cur is not null && cur.next is not null) {
+ ListNode t = cur.next;
+ cur.next = t.next;
+ t.next = cur;
+ pre.next = t;
+ pre = cur;
+ cur = cur.next;
+ }
+ return dummy.next;
+ }
+}
\ No newline at end of file
diff --git a/solution/0000-0099/0027.Remove Element/README.md b/solution/0000-0099/0027.Remove Element/README.md
index 66512c052c070..e0a104c1eb0d9 100644
--- a/solution/0000-0099/0027.Remove Element/README.md
+++ b/solution/0000-0099/0027.Remove Element/README.md
@@ -205,6 +205,22 @@ var removeElement = function (nums, val) {
};
```
+#### C#
+
+```cs
+public class Solution {
+ public int RemoveElement(int[] nums, int val) {
+ int k = 0;
+ foreach (int x in nums) {
+ if (x != val) {
+ nums[k++] = x;
+ }
+ }
+ return k;
+ }
+}
+```
+
#### PHP
```php
diff --git a/solution/0000-0099/0027.Remove Element/README_EN.md b/solution/0000-0099/0027.Remove Element/README_EN.md
index e033fd507fbbd..6bbc22e167933 100644
--- a/solution/0000-0099/0027.Remove Element/README_EN.md
+++ b/solution/0000-0099/0027.Remove Element/README_EN.md
@@ -205,6 +205,22 @@ var removeElement = function (nums, val) {
};
```
+#### C#
+
+```cs
+public class Solution {
+ public int RemoveElement(int[] nums, int val) {
+ int k = 0;
+ foreach (int x in nums) {
+ if (x != val) {
+ nums[k++] = x;
+ }
+ }
+ return k;
+ }
+}
+```
+
#### PHP
```php
diff --git a/solution/0000-0099/0027.Remove Element/Solution.cs b/solution/0000-0099/0027.Remove Element/Solution.cs
new file mode 100644
index 0000000000000..1ded258b8a3eb
--- /dev/null
+++ b/solution/0000-0099/0027.Remove Element/Solution.cs
@@ -0,0 +1,11 @@
+public class Solution {
+ public int RemoveElement(int[] nums, int val) {
+ int k = 0;
+ foreach (int x in nums) {
+ if (x != val) {
+ nums[k++] = x;
+ }
+ }
+ return k;
+ }
+}
\ No newline at end of file
diff --git a/solution/0000-0099/0030.Substring with Concatenation of All Words/README.md b/solution/0000-0099/0030.Substring with Concatenation of All Words/README.md
index 5d9bfce5f8868..66ddc9faa66c4 100644
--- a/solution/0000-0099/0030.Substring with Concatenation of All Words/README.md
+++ b/solution/0000-0099/0030.Substring with Concatenation of All Words/README.md
@@ -100,25 +100,21 @@ class Solution:
k = len(words[0])
ans = []
for i in range(k):
- cnt1 = Counter()
l = r = i
- t = 0
+ cnt1 = Counter()
while r + k <= m:
- w = s[r : r + k]
+ t = s[r : r + k]
r += k
- if w not in cnt:
+ if cnt[t] == 0:
l = r
cnt1.clear()
- t = 0
continue
- cnt1[w] += 1
- t += 1
- while cnt1[w] > cnt[w]:
- remove = s[l : l + k]
+ cnt1[t] += 1
+ while cnt1[t] > cnt[t]:
+ rem = s[l : l + k]
l += k
- cnt1[remove] -= 1
- t -= 1
- if t == n:
+ cnt1[rem] -= 1
+ if r - l == n * k:
ans.append(l)
return ans
```
@@ -129,34 +125,31 @@ class Solution:
class Solution {
public List findSubstring(String s, String[] words) {
Map cnt = new HashMap<>();
- for (String w : words) {
+ for (var w : words) {
cnt.merge(w, 1, Integer::sum);
}
- int m = s.length(), n = words.length;
- int k = words[0].length();
List ans = new ArrayList<>();
+ int m = s.length(), n = words.length, k = words[0].length();
for (int i = 0; i < k; ++i) {
- Map cnt1 = new HashMap<>();
int l = i, r = i;
- int t = 0;
+ Map cnt1 = new HashMap<>();
while (r + k <= m) {
- String w = s.substring(r, r + k);
+ var t = s.substring(r, r + k);
r += k;
- if (!cnt.containsKey(w)) {
+ if (!cnt.containsKey(t)) {
cnt1.clear();
l = r;
- t = 0;
continue;
}
- cnt1.merge(w, 1, Integer::sum);
- ++t;
- while (cnt1.get(w) > cnt.get(w)) {
- String remove = s.substring(l, l + k);
+ cnt1.merge(t, 1, Integer::sum);
+ while (cnt1.get(t) > cnt.get(t)) {
+ String w = s.substring(l, l + k);
+ if (cnt1.merge(w, -1, Integer::sum) == 0) {
+ cnt1.remove(w);
+ }
l += k;
- cnt1.merge(remove, -1, Integer::sum);
- --t;
}
- if (t == n) {
+ if (r - l == n * k) {
ans.add(l);
}
}
@@ -173,37 +166,42 @@ class Solution {
public:
vector findSubstring(string s, vector& words) {
unordered_map cnt;
- for (auto& w : words) {
- ++cnt[w];
+ for (const auto& w : words) {
+ cnt[w]++;
}
- int m = s.size(), n = words.size(), k = words[0].size();
+
vector ans;
+ int m = s.length(), n = words.size(), k = words[0].length();
+
for (int i = 0; i < k; ++i) {
- unordered_map cnt1;
int l = i, r = i;
- int t = 0;
+ unordered_map cnt1;
while (r + k <= m) {
- string w = s.substr(r, k);
+ string t = s.substr(r, k);
r += k;
- if (!cnt.count(w)) {
+
+ if (!cnt.contains(t)) {
cnt1.clear();
l = r;
- t = 0;
continue;
}
- ++cnt1[w];
- ++t;
- while (cnt1[w] > cnt[w]) {
- string remove = s.substr(l, k);
+
+ cnt1[t]++;
+
+ while (cnt1[t] > cnt[t]) {
+ string w = s.substr(l, k);
+ if (--cnt1[w] == 0) {
+ cnt1.erase(w);
+ }
l += k;
- --cnt1[remove];
- --t;
}
- if (t == n) {
+
+ if (r - l == n * k) {
ans.push_back(l);
}
}
}
+
return ans;
}
};
@@ -213,30 +211,33 @@ public:
```go
func findSubstring(s string, words []string) (ans []int) {
- cnt := map[string]int{}
+ cnt := make(map[string]int)
for _, w := range words {
cnt[w]++
}
m, n, k := len(s), len(words), len(words[0])
for i := 0; i < k; i++ {
- cnt1 := map[string]int{}
- l, r, t := i, i, 0
+ l, r := i, i
+ cnt1 := make(map[string]int)
for r+k <= m {
- w := s[r : r+k]
+ t := s[r : r+k]
r += k
- if _, ok := cnt[w]; !ok {
- l, t = r, 0
- cnt1 = map[string]int{}
+
+ if _, exists := cnt[t]; !exists {
+ cnt1 = make(map[string]int)
+ l = r
continue
}
- cnt1[w]++
- t++
- for cnt1[w] > cnt[w] {
- cnt1[s[l:l+k]]--
+ cnt1[t]++
+ for cnt1[t] > cnt[t] {
+ w := s[l : l+k]
+ cnt1[w]--
+ if cnt1[w] == 0 {
+ delete(cnt1, w)
+ }
l += k
- t--
}
- if t == n {
+ if r-l == n*k {
ans = append(ans, l)
}
}
@@ -253,33 +254,29 @@ function findSubstring(s: string, words: string[]): number[] {
for (const w of words) {
cnt.set(w, (cnt.get(w) || 0) + 1);
}
- const m = s.length;
- const n = words.length;
- const k = words[0].length;
const ans: number[] = [];
- for (let i = 0; i < k; ++i) {
+ const [m, n, k] = [s.length, words.length, words[0].length];
+ for (let i = 0; i < k; i++) {
+ let [l, r] = [i, i];
const cnt1: Map = new Map();
- let l = i;
- let r = i;
- let t = 0;
while (r + k <= m) {
- const w = s.slice(r, r + k);
+ const t = s.substring(r, r + k);
r += k;
- if (!cnt.has(w)) {
+ if (!cnt.has(t)) {
cnt1.clear();
l = r;
- t = 0;
continue;
}
- cnt1.set(w, (cnt1.get(w) || 0) + 1);
- ++t;
- while (cnt1.get(w)! - cnt.get(w)! > 0) {
- const remove = s.slice(l, l + k);
- cnt1.set(remove, cnt1.get(remove)! - 1);
+ cnt1.set(t, (cnt1.get(t) || 0) + 1);
+ while (cnt1.get(t)! > cnt.get(t)!) {
+ const w = s.substring(l, l + k);
+ cnt1.set(w, cnt1.get(w)! - 1);
+ if (cnt1.get(w) === 0) {
+ cnt1.delete(w);
+ }
l += k;
- --t;
}
- if (t === n) {
+ if (r - l === n * k) {
ans.push(l);
}
}
@@ -295,40 +292,50 @@ public class Solution {
public IList FindSubstring(string s, string[] words) {
var cnt = new Dictionary();
foreach (var w in words) {
- if (!cnt.ContainsKey(w)) {
- cnt[w] = 0;
+ if (cnt.ContainsKey(w)) {
+ cnt[w]++;
+ } else {
+ cnt[w] = 1;
}
- ++cnt[w];
}
- int m = s.Length, n = words.Length, k = words[0].Length;
+
var ans = new List();
+ int m = s.Length, n = words.Length, k = words[0].Length;
+
for (int i = 0; i < k; ++i) {
+ int l = i, r = i;
var cnt1 = new Dictionary();
- int l = i, r = i, t = 0;
while (r + k <= m) {
- var w = s.Substring(r, k);
+ var t = s.Substring(r, k);
r += k;
- if (!cnt.ContainsKey(w)) {
+
+ if (!cnt.ContainsKey(t)) {
cnt1.Clear();
- t = 0;
l = r;
continue;
}
- if (!cnt1.ContainsKey(w)) {
- cnt1[w] = 0;
+
+ if (cnt1.ContainsKey(t)) {
+ cnt1[t]++;
+ } else {
+ cnt1[t] = 1;
}
- ++cnt1[w];
- ++t;
- while (cnt1[w] > cnt[w]) {
- --cnt1[s.Substring(l, k)];
+
+ while (cnt1[t] > cnt[t]) {
+ var w = s.Substring(l, k);
+ cnt1[w]--;
+ if (cnt1[w] == 0) {
+ cnt1.Remove(w);
+ }
l += k;
- --t;
}
- if (t == n) {
+
+ if (r - l == n * k) {
ans.Add(l);
}
}
}
+
return ans;
}
}
@@ -346,47 +353,53 @@ class Solution {
function findSubstring($s, $words) {
$cnt = [];
foreach ($words as $w) {
- if (!isset($cnt[$w])) {
- $cnt[$w] = 1;
- } else {
+ if (isset($cnt[$w])) {
$cnt[$w]++;
+ } else {
+ $cnt[$w] = 1;
}
}
+
+ $ans = [];
$m = strlen($s);
$n = count($words);
$k = strlen($words[0]);
- $ans = [];
- for ($i = 0; $i < $k; ++$i) {
- $cnt1 = [];
+
+ for ($i = 0; $i < $k; $i++) {
$l = $i;
$r = $i;
- $t = 0;
+ $cnt1 = [];
while ($r + $k <= $m) {
- $w = substr($s, $r, $k);
+ $t = substr($s, $r, $k);
$r += $k;
- if (!array_key_exists($w, $cnt)) {
+
+ if (!isset($cnt[$t])) {
$cnt1 = [];
$l = $r;
- $t = 0;
continue;
}
- if (!isset($cnt1[$w])) {
- $cnt1[$w] = 1;
+
+ if (isset($cnt1[$t])) {
+ $cnt1[$t]++;
} else {
- $cnt1[$w]++;
+ $cnt1[$t] = 1;
}
- ++$t;
- while ($cnt1[$w] > $cnt[$w]) {
- $remove = substr($s, $l, $k);
+
+ while ($cnt1[$t] > $cnt[$t]) {
+ $w = substr($s, $l, $k);
+ $cnt1[$w]--;
+ if ($cnt1[$w] == 0) {
+ unset($cnt1[$w]);
+ }
$l += $k;
- $cnt1[$remove]--;
- $t--;
}
- if ($t == $n) {
+
+ if ($r - $l == $n * $k) {
$ans[] = $l;
}
}
}
+
return $ans;
}
}
@@ -396,44 +409,4 @@ class Solution {
-
-
-### 方法二
-
-
-
-#### C++
-
-```cpp
-class Solution {
-public:
- vector findSubstring(string s, vector& words) {
- unordered_map d;
- for (auto& w : words) ++d[w];
- vector ans;
- int n = s.size(), m = words.size(), k = words[0].size();
- for (int i = 0; i < k; ++i) {
- int cnt = 0;
- unordered_map t;
- for (int j = i; j <= n; j += k) {
- if (j - i >= m * k) {
- auto s1 = s.substr(j - m * k, k);
- --t[s1];
- cnt -= d[s1] > t[s1];
- }
- auto s2 = s.substr(j, k);
- ++t[s2];
- cnt += d[s2] >= t[s2];
- if (cnt == m) ans.emplace_back(j - (m - 1) * k);
- }
- }
- return ans;
- }
-};
-```
-
-
-
-
-
diff --git a/solution/0000-0099/0030.Substring with Concatenation of All Words/README_EN.md b/solution/0000-0099/0030.Substring with Concatenation of All Words/README_EN.md
index 02dffbb52991e..3f410f7e61eda 100644
--- a/solution/0000-0099/0030.Substring with Concatenation of All Words/README_EN.md
+++ b/solution/0000-0099/0030.Substring with Concatenation of All Words/README_EN.md
@@ -106,25 +106,21 @@ class Solution:
k = len(words[0])
ans = []
for i in range(k):
- cnt1 = Counter()
l = r = i
- t = 0
+ cnt1 = Counter()
while r + k <= m:
- w = s[r : r + k]
+ t = s[r : r + k]
r += k
- if w not in cnt:
+ if cnt[t] == 0:
l = r
cnt1.clear()
- t = 0
continue
- cnt1[w] += 1
- t += 1
- while cnt1[w] > cnt[w]:
- remove = s[l : l + k]
+ cnt1[t] += 1
+ while cnt1[t] > cnt[t]:
+ rem = s[l : l + k]
l += k
- cnt1[remove] -= 1
- t -= 1
- if t == n:
+ cnt1[rem] -= 1
+ if r - l == n * k:
ans.append(l)
return ans
```
@@ -135,34 +131,31 @@ class Solution:
class Solution {
public List findSubstring(String s, String[] words) {
Map cnt = new HashMap<>();
- for (String w : words) {
+ for (var w : words) {
cnt.merge(w, 1, Integer::sum);
}
- int m = s.length(), n = words.length;
- int k = words[0].length();
List ans = new ArrayList<>();
+ int m = s.length(), n = words.length, k = words[0].length();
for (int i = 0; i < k; ++i) {
- Map cnt1 = new HashMap<>();
int l = i, r = i;
- int t = 0;
+ Map cnt1 = new HashMap<>();
while (r + k <= m) {
- String w = s.substring(r, r + k);
+ var t = s.substring(r, r + k);
r += k;
- if (!cnt.containsKey(w)) {
+ if (!cnt.containsKey(t)) {
cnt1.clear();
l = r;
- t = 0;
continue;
}
- cnt1.merge(w, 1, Integer::sum);
- ++t;
- while (cnt1.get(w) > cnt.get(w)) {
- String remove = s.substring(l, l + k);
+ cnt1.merge(t, 1, Integer::sum);
+ while (cnt1.get(t) > cnt.get(t)) {
+ String w = s.substring(l, l + k);
+ if (cnt1.merge(w, -1, Integer::sum) == 0) {
+ cnt1.remove(w);
+ }
l += k;
- cnt1.merge(remove, -1, Integer::sum);
- --t;
}
- if (t == n) {
+ if (r - l == n * k) {
ans.add(l);
}
}
@@ -179,37 +172,42 @@ class Solution {
public:
vector findSubstring(string s, vector& words) {
unordered_map cnt;
- for (auto& w : words) {
- ++cnt[w];
+ for (const auto& w : words) {
+ cnt[w]++;
}
- int m = s.size(), n = words.size(), k = words[0].size();
+
vector ans;
+ int m = s.length(), n = words.size(), k = words[0].length();
+
for (int i = 0; i < k; ++i) {
- unordered_map cnt1;
int l = i, r = i;
- int t = 0;
+ unordered_map cnt1;
while (r + k <= m) {
- string w = s.substr(r, k);
+ string t = s.substr(r, k);
r += k;
- if (!cnt.count(w)) {
+
+ if (!cnt.contains(t)) {
cnt1.clear();
l = r;
- t = 0;
continue;
}
- ++cnt1[w];
- ++t;
- while (cnt1[w] > cnt[w]) {
- string remove = s.substr(l, k);
+
+ cnt1[t]++;
+
+ while (cnt1[t] > cnt[t]) {
+ string w = s.substr(l, k);
+ if (--cnt1[w] == 0) {
+ cnt1.erase(w);
+ }
l += k;
- --cnt1[remove];
- --t;
}
- if (t == n) {
+
+ if (r - l == n * k) {
ans.push_back(l);
}
}
}
+
return ans;
}
};
@@ -219,30 +217,33 @@ public:
```go
func findSubstring(s string, words []string) (ans []int) {
- cnt := map[string]int{}
+ cnt := make(map[string]int)
for _, w := range words {
cnt[w]++
}
m, n, k := len(s), len(words), len(words[0])
for i := 0; i < k; i++ {
- cnt1 := map[string]int{}
- l, r, t := i, i, 0
+ l, r := i, i
+ cnt1 := make(map[string]int)
for r+k <= m {
- w := s[r : r+k]
+ t := s[r : r+k]
r += k
- if _, ok := cnt[w]; !ok {
- l, t = r, 0
- cnt1 = map[string]int{}
+
+ if _, exists := cnt[t]; !exists {
+ cnt1 = make(map[string]int)
+ l = r
continue
}
- cnt1[w]++
- t++
- for cnt1[w] > cnt[w] {
- cnt1[s[l:l+k]]--
+ cnt1[t]++
+ for cnt1[t] > cnt[t] {
+ w := s[l : l+k]
+ cnt1[w]--
+ if cnt1[w] == 0 {
+ delete(cnt1, w)
+ }
l += k
- t--
}
- if t == n {
+ if r-l == n*k {
ans = append(ans, l)
}
}
@@ -259,33 +260,29 @@ function findSubstring(s: string, words: string[]): number[] {
for (const w of words) {
cnt.set(w, (cnt.get(w) || 0) + 1);
}
- const m = s.length;
- const n = words.length;
- const k = words[0].length;
const ans: number[] = [];
- for (let i = 0; i < k; ++i) {
+ const [m, n, k] = [s.length, words.length, words[0].length];
+ for (let i = 0; i < k; i++) {
+ let [l, r] = [i, i];
const cnt1: Map = new Map();
- let l = i;
- let r = i;
- let t = 0;
while (r + k <= m) {
- const w = s.slice(r, r + k);
+ const t = s.substring(r, r + k);
r += k;
- if (!cnt.has(w)) {
+ if (!cnt.has(t)) {
cnt1.clear();
l = r;
- t = 0;
continue;
}
- cnt1.set(w, (cnt1.get(w) || 0) + 1);
- ++t;
- while (cnt1.get(w)! - cnt.get(w)! > 0) {
- const remove = s.slice(l, l + k);
- cnt1.set(remove, cnt1.get(remove)! - 1);
+ cnt1.set(t, (cnt1.get(t) || 0) + 1);
+ while (cnt1.get(t)! > cnt.get(t)!) {
+ const w = s.substring(l, l + k);
+ cnt1.set(w, cnt1.get(w)! - 1);
+ if (cnt1.get(w) === 0) {
+ cnt1.delete(w);
+ }
l += k;
- --t;
}
- if (t === n) {
+ if (r - l === n * k) {
ans.push(l);
}
}
@@ -301,40 +298,50 @@ public class Solution {
public IList FindSubstring(string s, string[] words) {
var cnt = new Dictionary();
foreach (var w in words) {
- if (!cnt.ContainsKey(w)) {
- cnt[w] = 0;
+ if (cnt.ContainsKey(w)) {
+ cnt[w]++;
+ } else {
+ cnt[w] = 1;
}
- ++cnt[w];
}
- int m = s.Length, n = words.Length, k = words[0].Length;
+
var ans = new List();
+ int m = s.Length, n = words.Length, k = words[0].Length;
+
for (int i = 0; i < k; ++i) {
+ int l = i, r = i;
var cnt1 = new Dictionary();
- int l = i, r = i, t = 0;
while (r + k <= m) {
- var w = s.Substring(r, k);
+ var t = s.Substring(r, k);
r += k;
- if (!cnt.ContainsKey(w)) {
+
+ if (!cnt.ContainsKey(t)) {
cnt1.Clear();
- t = 0;
l = r;
continue;
}
- if (!cnt1.ContainsKey(w)) {
- cnt1[w] = 0;
+
+ if (cnt1.ContainsKey(t)) {
+ cnt1[t]++;
+ } else {
+ cnt1[t] = 1;
}
- ++cnt1[w];
- ++t;
- while (cnt1[w] > cnt[w]) {
- --cnt1[s.Substring(l, k)];
+
+ while (cnt1[t] > cnt[t]) {
+ var w = s.Substring(l, k);
+ cnt1[w]--;
+ if (cnt1[w] == 0) {
+ cnt1.Remove(w);
+ }
l += k;
- --t;
}
- if (t == n) {
+
+ if (r - l == n * k) {
ans.Add(l);
}
}
}
+
return ans;
}
}
@@ -352,47 +359,53 @@ class Solution {
function findSubstring($s, $words) {
$cnt = [];
foreach ($words as $w) {
- if (!isset($cnt[$w])) {
- $cnt[$w] = 1;
- } else {
+ if (isset($cnt[$w])) {
$cnt[$w]++;
+ } else {
+ $cnt[$w] = 1;
}
}
+
+ $ans = [];
$m = strlen($s);
$n = count($words);
$k = strlen($words[0]);
- $ans = [];
- for ($i = 0; $i < $k; ++$i) {
- $cnt1 = [];
+
+ for ($i = 0; $i < $k; $i++) {
$l = $i;
$r = $i;
- $t = 0;
+ $cnt1 = [];
while ($r + $k <= $m) {
- $w = substr($s, $r, $k);
+ $t = substr($s, $r, $k);
$r += $k;
- if (!array_key_exists($w, $cnt)) {
+
+ if (!isset($cnt[$t])) {
$cnt1 = [];
$l = $r;
- $t = 0;
continue;
}
- if (!isset($cnt1[$w])) {
- $cnt1[$w] = 1;
+
+ if (isset($cnt1[$t])) {
+ $cnt1[$t]++;
} else {
- $cnt1[$w]++;
+ $cnt1[$t] = 1;
}
- ++$t;
- while ($cnt1[$w] > $cnt[$w]) {
- $remove = substr($s, $l, $k);
+
+ while ($cnt1[$t] > $cnt[$t]) {
+ $w = substr($s, $l, $k);
+ $cnt1[$w]--;
+ if ($cnt1[$w] == 0) {
+ unset($cnt1[$w]);
+ }
$l += $k;
- $cnt1[$remove]--;
- $t--;
}
- if ($t == $n) {
+
+ if ($r - $l == $n * $k) {
$ans[] = $l;
}
}
}
+
return $ans;
}
}
@@ -402,44 +415,4 @@ class Solution {
-
-
-### Solution 2
-
-
-
-#### C++
-
-```cpp
-class Solution {
-public:
- vector findSubstring(string s, vector& words) {
- unordered_map d;
- for (auto& w : words) ++d[w];
- vector ans;
- int n = s.size(), m = words.size(), k = words[0].size();
- for (int i = 0; i < k; ++i) {
- int cnt = 0;
- unordered_map t;
- for (int j = i; j <= n; j += k) {
- if (j - i >= m * k) {
- auto s1 = s.substr(j - m * k, k);
- --t[s1];
- cnt -= d[s1] > t[s1];
- }
- auto s2 = s.substr(j, k);
- ++t[s2];
- cnt += d[s2] >= t[s2];
- if (cnt == m) ans.emplace_back(j - (m - 1) * k);
- }
- }
- return ans;
- }
-};
-```
-
-
-
-
-
diff --git a/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution.cpp b/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution.cpp
index abe7c53d28ef5..bcadd9565442d 100644
--- a/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution.cpp
+++ b/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution.cpp
@@ -2,37 +2,42 @@ class Solution {
public:
vector findSubstring(string s, vector& words) {
unordered_map cnt;
- for (auto& w : words) {
- ++cnt[w];
+ for (const auto& w : words) {
+ cnt[w]++;
}
- int m = s.size(), n = words.size(), k = words[0].size();
+
vector ans;
+ int m = s.length(), n = words.size(), k = words[0].length();
+
for (int i = 0; i < k; ++i) {
- unordered_map cnt1;
int l = i, r = i;
- int t = 0;
+ unordered_map cnt1;
while (r + k <= m) {
- string w = s.substr(r, k);
+ string t = s.substr(r, k);
r += k;
- if (!cnt.count(w)) {
+
+ if (!cnt.contains(t)) {
cnt1.clear();
l = r;
- t = 0;
continue;
}
- ++cnt1[w];
- ++t;
- while (cnt1[w] > cnt[w]) {
- string remove = s.substr(l, k);
+
+ cnt1[t]++;
+
+ while (cnt1[t] > cnt[t]) {
+ string w = s.substr(l, k);
+ if (--cnt1[w] == 0) {
+ cnt1.erase(w);
+ }
l += k;
- --cnt1[remove];
- --t;
}
- if (t == n) {
+
+ if (r - l == n * k) {
ans.push_back(l);
}
}
}
+
return ans;
}
-};
\ No newline at end of file
+};
diff --git a/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution.cs b/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution.cs
index e631e724cf196..ec0eb534b2344 100644
--- a/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution.cs
+++ b/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution.cs
@@ -2,40 +2,50 @@ public class Solution {
public IList FindSubstring(string s, string[] words) {
var cnt = new Dictionary();
foreach (var w in words) {
- if (!cnt.ContainsKey(w)) {
- cnt[w] = 0;
+ if (cnt.ContainsKey(w)) {
+ cnt[w]++;
+ } else {
+ cnt[w] = 1;
}
- ++cnt[w];
}
- int m = s.Length, n = words.Length, k = words[0].Length;
+
var ans = new List();
+ int m = s.Length, n = words.Length, k = words[0].Length;
+
for (int i = 0; i < k; ++i) {
+ int l = i, r = i;
var cnt1 = new Dictionary();
- int l = i, r = i, t = 0;
while (r + k <= m) {
- var w = s.Substring(r, k);
+ var t = s.Substring(r, k);
r += k;
- if (!cnt.ContainsKey(w)) {
+
+ if (!cnt.ContainsKey(t)) {
cnt1.Clear();
- t = 0;
l = r;
continue;
}
- if (!cnt1.ContainsKey(w)) {
- cnt1[w] = 0;
+
+ if (cnt1.ContainsKey(t)) {
+ cnt1[t]++;
+ } else {
+ cnt1[t] = 1;
}
- ++cnt1[w];
- ++t;
- while (cnt1[w] > cnt[w]) {
- --cnt1[s.Substring(l, k)];
+
+ while (cnt1[t] > cnt[t]) {
+ var w = s.Substring(l, k);
+ cnt1[w]--;
+ if (cnt1[w] == 0) {
+ cnt1.Remove(w);
+ }
l += k;
- --t;
}
- if (t == n) {
+
+ if (r - l == n * k) {
ans.Add(l);
}
}
}
+
return ans;
}
}
diff --git a/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution.go b/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution.go
index 21ff0def7e273..81cd58b695518 100644
--- a/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution.go
+++ b/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution.go
@@ -1,31 +1,34 @@
func findSubstring(s string, words []string) (ans []int) {
- cnt := map[string]int{}
+ cnt := make(map[string]int)
for _, w := range words {
cnt[w]++
}
m, n, k := len(s), len(words), len(words[0])
for i := 0; i < k; i++ {
- cnt1 := map[string]int{}
- l, r, t := i, i, 0
+ l, r := i, i
+ cnt1 := make(map[string]int)
for r+k <= m {
- w := s[r : r+k]
+ t := s[r : r+k]
r += k
- if _, ok := cnt[w]; !ok {
- l, t = r, 0
- cnt1 = map[string]int{}
+
+ if _, exists := cnt[t]; !exists {
+ cnt1 = make(map[string]int)
+ l = r
continue
}
- cnt1[w]++
- t++
- for cnt1[w] > cnt[w] {
- cnt1[s[l:l+k]]--
+ cnt1[t]++
+ for cnt1[t] > cnt[t] {
+ w := s[l : l+k]
+ cnt1[w]--
+ if cnt1[w] == 0 {
+ delete(cnt1, w)
+ }
l += k
- t--
}
- if t == n {
+ if r-l == n*k {
ans = append(ans, l)
}
}
}
return
-}
\ No newline at end of file
+}
diff --git a/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution.java b/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution.java
index b0c366a84d982..98f5b91328122 100644
--- a/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution.java
+++ b/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution.java
@@ -1,38 +1,35 @@
class Solution {
public List findSubstring(String s, String[] words) {
Map cnt = new HashMap<>();
- for (String w : words) {
+ for (var w : words) {
cnt.merge(w, 1, Integer::sum);
}
- int m = s.length(), n = words.length;
- int k = words[0].length();
List ans = new ArrayList<>();
+ int m = s.length(), n = words.length, k = words[0].length();
for (int i = 0; i < k; ++i) {
- Map cnt1 = new HashMap<>();
int l = i, r = i;
- int t = 0;
+ Map cnt1 = new HashMap<>();
while (r + k <= m) {
- String w = s.substring(r, r + k);
+ var t = s.substring(r, r + k);
r += k;
- if (!cnt.containsKey(w)) {
+ if (!cnt.containsKey(t)) {
cnt1.clear();
l = r;
- t = 0;
continue;
}
- cnt1.merge(w, 1, Integer::sum);
- ++t;
- while (cnt1.get(w) > cnt.get(w)) {
- String remove = s.substring(l, l + k);
+ cnt1.merge(t, 1, Integer::sum);
+ while (cnt1.get(t) > cnt.get(t)) {
+ String w = s.substring(l, l + k);
+ if (cnt1.merge(w, -1, Integer::sum) == 0) {
+ cnt1.remove(w);
+ }
l += k;
- cnt1.merge(remove, -1, Integer::sum);
- --t;
}
- if (t == n) {
+ if (r - l == n * k) {
ans.add(l);
}
}
}
return ans;
}
-}
\ No newline at end of file
+}
diff --git a/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution.php b/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution.php
index 666c296650ef1..db668e5e1e50a 100644
--- a/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution.php
+++ b/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution.php
@@ -1,4 +1,5 @@
class Solution {
+
/**
* @param String $s
* @param String[] $words
@@ -7,47 +8,53 @@ class Solution {
function findSubstring($s, $words) {
$cnt = [];
foreach ($words as $w) {
- if (!isset($cnt[$w])) {
- $cnt[$w] = 1;
- } else {
+ if (isset($cnt[$w])) {
$cnt[$w]++;
+ } else {
+ $cnt[$w] = 1;
}
}
+
+ $ans = [];
$m = strlen($s);
$n = count($words);
$k = strlen($words[0]);
- $ans = [];
- for ($i = 0; $i < $k; ++$i) {
- $cnt1 = [];
+
+ for ($i = 0; $i < $k; $i++) {
$l = $i;
$r = $i;
- $t = 0;
+ $cnt1 = [];
while ($r + $k <= $m) {
- $w = substr($s, $r, $k);
+ $t = substr($s, $r, $k);
$r += $k;
- if (!array_key_exists($w, $cnt)) {
+
+ if (!isset($cnt[$t])) {
$cnt1 = [];
$l = $r;
- $t = 0;
continue;
}
- if (!isset($cnt1[$w])) {
- $cnt1[$w] = 1;
+
+ if (isset($cnt1[$t])) {
+ $cnt1[$t]++;
} else {
- $cnt1[$w]++;
+ $cnt1[$t] = 1;
}
- ++$t;
- while ($cnt1[$w] > $cnt[$w]) {
- $remove = substr($s, $l, $k);
+
+ while ($cnt1[$t] > $cnt[$t]) {
+ $w = substr($s, $l, $k);
+ $cnt1[$w]--;
+ if ($cnt1[$w] == 0) {
+ unset($cnt1[$w]);
+ }
$l += $k;
- $cnt1[$remove]--;
- $t--;
}
- if ($t == $n) {
+
+ if ($r - $l == $n * $k) {
$ans[] = $l;
}
}
}
+
return $ans;
}
}
diff --git a/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution.py b/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution.py
index e40d0de4ced8e..1a8cdfd50d6fe 100644
--- a/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution.py
+++ b/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution.py
@@ -5,24 +5,20 @@ def findSubstring(self, s: str, words: List[str]) -> List[int]:
k = len(words[0])
ans = []
for i in range(k):
- cnt1 = Counter()
l = r = i
- t = 0
+ cnt1 = Counter()
while r + k <= m:
- w = s[r : r + k]
+ t = s[r : r + k]
r += k
- if w not in cnt:
+ if cnt[t] == 0:
l = r
cnt1.clear()
- t = 0
continue
- cnt1[w] += 1
- t += 1
- while cnt1[w] > cnt[w]:
- remove = s[l : l + k]
+ cnt1[t] += 1
+ while cnt1[t] > cnt[t]:
+ rem = s[l : l + k]
l += k
- cnt1[remove] -= 1
- t -= 1
- if t == n:
+ cnt1[rem] -= 1
+ if r - l == n * k:
ans.append(l)
return ans
diff --git a/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution.ts b/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution.ts
index 01ff17558a90c..8e7d3ccc0527a 100644
--- a/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution.ts
+++ b/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution.ts
@@ -3,33 +3,29 @@ function findSubstring(s: string, words: string[]): number[] {
for (const w of words) {
cnt.set(w, (cnt.get(w) || 0) + 1);
}
- const m = s.length;
- const n = words.length;
- const k = words[0].length;
const ans: number[] = [];
- for (let i = 0; i < k; ++i) {
+ const [m, n, k] = [s.length, words.length, words[0].length];
+ for (let i = 0; i < k; i++) {
+ let [l, r] = [i, i];
const cnt1: Map = new Map();
- let l = i;
- let r = i;
- let t = 0;
while (r + k <= m) {
- const w = s.slice(r, r + k);
+ const t = s.substring(r, r + k);
r += k;
- if (!cnt.has(w)) {
+ if (!cnt.has(t)) {
cnt1.clear();
l = r;
- t = 0;
continue;
}
- cnt1.set(w, (cnt1.get(w) || 0) + 1);
- ++t;
- while (cnt1.get(w)! - cnt.get(w)! > 0) {
- const remove = s.slice(l, l + k);
- cnt1.set(remove, cnt1.get(remove)! - 1);
+ cnt1.set(t, (cnt1.get(t) || 0) + 1);
+ while (cnt1.get(t)! > cnt.get(t)!) {
+ const w = s.substring(l, l + k);
+ cnt1.set(w, cnt1.get(w)! - 1);
+ if (cnt1.get(w) === 0) {
+ cnt1.delete(w);
+ }
l += k;
- --t;
}
- if (t === n) {
+ if (r - l === n * k) {
ans.push(l);
}
}
diff --git a/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution2.cpp b/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution2.cpp
deleted file mode 100644
index 2e88ae3ac098f..0000000000000
--- a/solution/0000-0099/0030.Substring with Concatenation of All Words/Solution2.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-class Solution {
-public:
- vector findSubstring(string s, vector& words) {
- unordered_map d;
- for (auto& w : words) ++d[w];
- vector ans;
- int n = s.size(), m = words.size(), k = words[0].size();
- for (int i = 0; i < k; ++i) {
- int cnt = 0;
- unordered_map t;
- for (int j = i; j <= n; j += k) {
- if (j - i >= m * k) {
- auto s1 = s.substr(j - m * k, k);
- --t[s1];
- cnt -= d[s1] > t[s1];
- }
- auto s2 = s.substr(j, k);
- ++t[s2];
- cnt += d[s2] >= t[s2];
- if (cnt == m) ans.emplace_back(j - (m - 1) * k);
- }
- }
- return ans;
- }
-};
\ No newline at end of file
diff --git a/solution/0000-0099/0033.Search in Rotated Sorted Array/README.md b/solution/0000-0099/0033.Search in Rotated Sorted Array/README.md
index 77320242b4963..d84ddc3e91a90 100644
--- a/solution/0000-0099/0033.Search in Rotated Sorted Array/README.md
+++ b/solution/0000-0099/0033.Search in Rotated Sorted Array/README.md
@@ -281,6 +281,34 @@ var search = function (nums, target) {
};
```
+#### C#
+
+```cs
+public class Solution {
+ public int Search(int[] nums, int target) {
+ int n = nums.Length;
+ int left = 0, right = n - 1;
+ while (left < right) {
+ int mid = (left + right) >> 1;
+ if (nums[0] <= nums[mid]) {
+ if (nums[0] <= target && target <= nums[mid]) {
+ right = mid;
+ } else {
+ left = mid + 1;
+ }
+ } else {
+ if (nums[mid] < target && target <= nums[n - 1]) {
+ left = mid + 1;
+ } else {
+ right = mid;
+ }
+ }
+ }
+ return nums[left] == target ? left : -1;
+ }
+}
+```
+
#### PHP
```php
diff --git a/solution/0000-0099/0033.Search in Rotated Sorted Array/README_EN.md b/solution/0000-0099/0033.Search in Rotated Sorted Array/README_EN.md
index 0826fedd5b185..871221d1251a8 100644
--- a/solution/0000-0099/0033.Search in Rotated Sorted Array/README_EN.md
+++ b/solution/0000-0099/0033.Search in Rotated Sorted Array/README_EN.md
@@ -269,6 +269,34 @@ var search = function (nums, target) {
};
```
+#### C#
+
+```cs
+public class Solution {
+ public int Search(int[] nums, int target) {
+ int n = nums.Length;
+ int left = 0, right = n - 1;
+ while (left < right) {
+ int mid = (left + right) >> 1;
+ if (nums[0] <= nums[mid]) {
+ if (nums[0] <= target && target <= nums[mid]) {
+ right = mid;
+ } else {
+ left = mid + 1;
+ }
+ } else {
+ if (nums[mid] < target && target <= nums[n - 1]) {
+ left = mid + 1;
+ } else {
+ right = mid;
+ }
+ }
+ }
+ return nums[left] == target ? left : -1;
+ }
+}
+```
+
#### PHP
```php
diff --git a/solution/0000-0099/0033.Search in Rotated Sorted Array/Solution.cs b/solution/0000-0099/0033.Search in Rotated Sorted Array/Solution.cs
new file mode 100644
index 0000000000000..94ec080d4a5a9
--- /dev/null
+++ b/solution/0000-0099/0033.Search in Rotated Sorted Array/Solution.cs
@@ -0,0 +1,23 @@
+public class Solution {
+ public int Search(int[] nums, int target) {
+ int n = nums.Length;
+ int left = 0, right = n - 1;
+ while (left < right) {
+ int mid = (left + right) >> 1;
+ if (nums[0] <= nums[mid]) {
+ if (nums[0] <= target && target <= nums[mid]) {
+ right = mid;
+ } else {
+ left = mid + 1;
+ }
+ } else {
+ if (nums[mid] < target && target <= nums[n - 1]) {
+ left = mid + 1;
+ } else {
+ right = mid;
+ }
+ }
+ }
+ return nums[left] == target ? left : -1;
+ }
+}
\ No newline at end of file
diff --git a/solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/README.md b/solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/README.md
index 361728caaea79..30c5a25b9f808 100644
--- a/solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/README.md
+++ b/solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/README.md
@@ -211,6 +211,31 @@ var searchRange = function (nums, target) {
};
```
+#### C#
+
+```cs
+public class Solution {
+ public int[] SearchRange(int[] nums, int target) {
+ int l = Search(nums, target);
+ int r = Search(nums, target + 1);
+ return l == r ? new int[] {-1, -1} : new int[] {l, r - 1};
+ }
+
+ private int Search(int[] nums, int x) {
+ int left = 0, right = nums.Length;
+ while (left < right) {
+ int mid = (left + right) >>> 1;
+ if (nums[mid] >= x) {
+ right = mid;
+ } else {
+ left = mid + 1;
+ }
+ }
+ return left;
+ }
+}
+```
+
#### PHP
```php
diff --git a/solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/README_EN.md b/solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/README_EN.md
index 491b8072d5031..2458ddc9bbc57 100644
--- a/solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/README_EN.md
+++ b/solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/README_EN.md
@@ -201,6 +201,31 @@ var searchRange = function (nums, target) {
};
```
+#### C#
+
+```cs
+public class Solution {
+ public int[] SearchRange(int[] nums, int target) {
+ int l = Search(nums, target);
+ int r = Search(nums, target + 1);
+ return l == r ? new int[] {-1, -1} : new int[] {l, r - 1};
+ }
+
+ private int Search(int[] nums, int x) {
+ int left = 0, right = nums.Length;
+ while (left < right) {
+ int mid = (left + right) >>> 1;
+ if (nums[mid] >= x) {
+ right = mid;
+ } else {
+ left = mid + 1;
+ }
+ }
+ return left;
+ }
+}
+```
+
#### PHP
```php
diff --git a/solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/Solution.cs b/solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/Solution.cs
new file mode 100644
index 0000000000000..b934d4277e689
--- /dev/null
+++ b/solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/Solution.cs
@@ -0,0 +1,20 @@
+public class Solution {
+ public int[] SearchRange(int[] nums, int target) {
+ int l = Search(nums, target);
+ int r = Search(nums, target + 1);
+ return l == r ? new int[] {-1, -1} : new int[] {l, r - 1};
+ }
+
+ private int Search(int[] nums, int x) {
+ int left = 0, right = nums.Length;
+ while (left < right) {
+ int mid = (left + right) >>> 1;
+ if (nums[mid] >= x) {
+ right = mid;
+ } else {
+ left = mid + 1;
+ }
+ }
+ return left;
+ }
+}
\ No newline at end of file
diff --git a/solution/0000-0099/0045.Jump Game II/README.md b/solution/0000-0099/0045.Jump Game II/README.md
index 4e2af261f818f..df5afce25a020 100644
--- a/solution/0000-0099/0045.Jump Game II/README.md
+++ b/solution/0000-0099/0045.Jump Game II/README.md
@@ -169,18 +169,17 @@ function jump(nums: number[]): number {
```rust
impl Solution {
pub fn jump(nums: Vec) -> i32 {
- let n = nums.len();
- let mut dp = vec![i32::MAX; n];
- dp[0] = 0;
- for i in 0..n - 1 {
- for j in 1..=nums[i] as usize {
- if i + j >= n {
- break;
- }
- dp[i + j] = dp[i + j].min(dp[i] + 1);
+ let mut ans = 0;
+ let mut mx = 0;
+ let mut last = 0;
+ for i in 0..(nums.len() - 1) {
+ mx = mx.max(i as i32 + nums[i]);
+ if last == i as i32 {
+ ans += 1;
+ last = mx;
}
}
- dp[n - 1]
+ ans
}
}
```
@@ -206,19 +205,18 @@ public class Solution {
#### C
```c
-#define min(a, b) a < b ? a : b
int jump(int* nums, int numsSize) {
- int dp[numsSize];
- for (int i = 0; i < numsSize; i++) {
- dp[i] = numsSize;
- }
- dp[0] = 0;
- for (int i = 0; i < numsSize - 1; i++) {
- for (int j = i + 1; j < (min(i + nums[i] + 1, numsSize)); j++) {
- dp[j] = min(dp[j], dp[i] + 1);
+ int ans = 0;
+ int mx = 0;
+ int last = 0;
+ for (int i = 0; i < numsSize - 1; ++i) {
+ mx = (mx > i + nums[i]) ? mx : (i + nums[i]);
+ if (last == i) {
+ ++ans;
+ last = mx;
}
}
- return dp[numsSize - 1];
+ return ans;
}
```
@@ -227,23 +225,23 @@ int jump(int* nums, int numsSize) {
```php
class Solution {
/**
- * @param integer[] $nums
- * @return integer
+ * @param Integer[] $nums
+ * @return Integer
*/
-
function jump($nums) {
- $maxReach = 0;
- $steps = 0;
- $lastJump = 0;
- for ($i = 0; $i <= count($nums) - 2; $i++) {
- $maxReach = max($maxReach, $i + $nums[$i]);
- if ($i == $lastJump) {
- $lastJump = $maxReach;
- $steps++;
+ $ans = 0;
+ $mx = 0;
+ $last = 0;
+
+ for ($i = 0; $i < count($nums) - 1; $i++) {
+ $mx = max($mx, $i + $nums[$i]);
+ if ($last == $i) {
+ $ans++;
+ $last = $mx;
}
}
- return $steps;
+ return $ans;
}
}
```
diff --git a/solution/0000-0099/0045.Jump Game II/README_EN.md b/solution/0000-0099/0045.Jump Game II/README_EN.md
index 4e1a30891520e..26a6b6242448f 100644
--- a/solution/0000-0099/0045.Jump Game II/README_EN.md
+++ b/solution/0000-0099/0045.Jump Game II/README_EN.md
@@ -166,18 +166,17 @@ function jump(nums: number[]): number {
```rust
impl Solution {
pub fn jump(nums: Vec) -> i32 {
- let n = nums.len();
- let mut dp = vec![i32::MAX; n];
- dp[0] = 0;
- for i in 0..n - 1 {
- for j in 1..=nums[i] as usize {
- if i + j >= n {
- break;
- }
- dp[i + j] = dp[i + j].min(dp[i] + 1);
+ let mut ans = 0;
+ let mut mx = 0;
+ let mut last = 0;
+ for i in 0..(nums.len() - 1) {
+ mx = mx.max(i as i32 + nums[i]);
+ if last == i as i32 {
+ ans += 1;
+ last = mx;
}
}
- dp[n - 1]
+ ans
}
}
```
@@ -203,19 +202,18 @@ public class Solution {
#### C
```c
-#define min(a, b) a < b ? a : b
int jump(int* nums, int numsSize) {
- int dp[numsSize];
- for (int i = 0; i < numsSize; i++) {
- dp[i] = numsSize;
- }
- dp[0] = 0;
- for (int i = 0; i < numsSize - 1; i++) {
- for (int j = i + 1; j < (min(i + nums[i] + 1, numsSize)); j++) {
- dp[j] = min(dp[j], dp[i] + 1);
+ int ans = 0;
+ int mx = 0;
+ int last = 0;
+ for (int i = 0; i < numsSize - 1; ++i) {
+ mx = (mx > i + nums[i]) ? mx : (i + nums[i]);
+ if (last == i) {
+ ++ans;
+ last = mx;
}
}
- return dp[numsSize - 1];
+ return ans;
}
```
@@ -224,23 +222,23 @@ int jump(int* nums, int numsSize) {
```php
class Solution {
/**
- * @param integer[] $nums
- * @return integer
+ * @param Integer[] $nums
+ * @return Integer
*/
-
function jump($nums) {
- $maxReach = 0;
- $steps = 0;
- $lastJump = 0;
- for ($i = 0; $i <= count($nums) - 2; $i++) {
- $maxReach = max($maxReach, $i + $nums[$i]);
- if ($i == $lastJump) {
- $lastJump = $maxReach;
- $steps++;
+ $ans = 0;
+ $mx = 0;
+ $last = 0;
+
+ for ($i = 0; $i < count($nums) - 1; $i++) {
+ $mx = max($mx, $i + $nums[$i]);
+ if ($last == $i) {
+ $ans++;
+ $last = $mx;
}
}
- return $steps;
+ return $ans;
}
}
```
diff --git a/solution/0000-0099/0045.Jump Game II/Solution.c b/solution/0000-0099/0045.Jump Game II/Solution.c
index 241e3ddcbf6dd..43ee05a49817d 100644
--- a/solution/0000-0099/0045.Jump Game II/Solution.c
+++ b/solution/0000-0099/0045.Jump Game II/Solution.c
@@ -1,14 +1,13 @@
-#define min(a, b) a < b ? a : b
int jump(int* nums, int numsSize) {
- int dp[numsSize];
- for (int i = 0; i < numsSize; i++) {
- dp[i] = numsSize;
- }
- dp[0] = 0;
- for (int i = 0; i < numsSize - 1; i++) {
- for (int j = i + 1; j < (min(i + nums[i] + 1, numsSize)); j++) {
- dp[j] = min(dp[j], dp[i] + 1);
+ int ans = 0;
+ int mx = 0;
+ int last = 0;
+ for (int i = 0; i < numsSize - 1; ++i) {
+ mx = (mx > i + nums[i]) ? mx : (i + nums[i]);
+ if (last == i) {
+ ++ans;
+ last = mx;
}
}
- return dp[numsSize - 1];
-}
\ No newline at end of file
+ return ans;
+}
diff --git a/solution/0000-0099/0045.Jump Game II/Solution.php b/solution/0000-0099/0045.Jump Game II/Solution.php
index 45c5fb59b475e..3d2184dbcaced 100644
--- a/solution/0000-0099/0045.Jump Game II/Solution.php
+++ b/solution/0000-0099/0045.Jump Game II/Solution.php
@@ -1,22 +1,21 @@
-) -> i32 {
- let n = nums.len();
- let mut dp = vec![i32::MAX; n];
- dp[0] = 0;
- for i in 0..n - 1 {
- for j in 1..=nums[i] as usize {
- if i + j >= n {
- break;
- }
- dp[i + j] = dp[i + j].min(dp[i] + 1);
+ let mut ans = 0;
+ let mut mx = 0;
+ let mut last = 0;
+ for i in 0..(nums.len() - 1) {
+ mx = mx.max(i as i32 + nums[i]);
+ if last == i as i32 {
+ ans += 1;
+ last = mx;
}
}
- dp[n - 1]
+ ans
}
}
diff --git a/solution/0000-0099/0047.Permutations II/README.md b/solution/0000-0099/0047.Permutations II/README.md
index 1f70f7bdbd925..8a3cb5cd85def 100644
--- a/solution/0000-0099/0047.Permutations II/README.md
+++ b/solution/0000-0099/0047.Permutations II/README.md
@@ -5,6 +5,7 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/0000-0099/0047.Pe
tags:
- 数组
- 回溯
+ - 排序
---
@@ -57,12 +58,12 @@ tags:
我们可以先对数组进行排序,这样就可以将重复的数字放在一起,方便我们进行去重。
-然后,我们设计一个函数 $dfs(i)$,表示当前需要填写第 $i$ 个位置的数。函数的具体实现如下:
+然后,我们设计一个函数 $\textit{dfs}(i)$,表示当前需要填写第 $i$ 个位置的数。函数的具体实现如下:
- 如果 $i = n$,说明我们已经填写完毕,将当前排列加入答案数组中,然后返回。
-- 否则,我们枚举第 $i$ 个位置的数 $nums[j]$,其中 $j$ 的范围是 $[0, n - 1]$。我们需要保证 $nums[j]$ 没有被使用过,并且与前面枚举的数不同,这样才能保证当前排列不重复。如果满足条件,我们就可以填写 $nums[j]$,并继续递归地填写下一个位置,即调用 $dfs(i + 1)$。在递归调用结束后,我们需要将 $nums[j]$ 标记为未使用,以便于进行后面的枚举。
+- 否则,我们枚举第 $i$ 个位置的数 $nums[j]$,其中 $j$ 的范围是 $[0, n - 1]$。我们需要保证 $nums[j]$ 没有被使用过,并且与前面枚举的数不同,这样才能保证当前排列不重复。如果满足条件,我们就可以填写 $nums[j]$,并继续递归地填写下一个位置,即调用 $\textit{dfs}(i + 1)$。在递归调用结束后,我们需要将 $nums[j]$ 标记为未使用,以便于进行后面的枚举。
-在主函数中,我们首先对数组进行排序,然后调用 $dfs(0)$,即从第 0 个位置开始填写,最终返回答案数组即可。
+在主函数中,我们首先对数组进行排序,然后调用 $\textit{dfs}(0)$,即从第 0 个位置开始填写,最终返回答案数组即可。
时间复杂度 $O(n \times n!)$,空间复杂度 $O(n)$。其中 $n$ 是数组的长度。需要进行 $n!$ 次枚举,每次枚举需要 $O(n)$ 的时间来判断是否重复。另外,我们需要一个标记数组来标记每个位置是否被使用过,因此空间复杂度为 $O(n)$。
@@ -140,12 +141,12 @@ class Solution {
class Solution {
public:
vector> permuteUnique(vector& nums) {
- sort(nums.begin(), nums.end());
+ ranges::sort(nums);
int n = nums.size();
vector> ans;
vector t(n);
vector vis(n);
- function dfs = [&](int i) {
+ auto dfs = [&](this auto&& dfs, int i) {
if (i == n) {
ans.emplace_back(t);
return;
@@ -170,7 +171,7 @@ public:
```go
func permuteUnique(nums []int) (ans [][]int) {
- sort.Ints(nums)
+ slices.Sort(nums)
n := len(nums)
t := make([]int, n)
vis := make([]bool, n)
@@ -202,8 +203,8 @@ function permuteUnique(nums: number[]): number[][] {
nums.sort((a, b) => a - b);
const n = nums.length;
const ans: number[][] = [];
- const t: number[] = new Array(n);
- const vis: boolean[] = new Array(n);
+ const t: number[] = Array(n);
+ const vis: boolean[] = Array(n).fill(false);
const dfs = (i: number) => {
if (i === n) {
ans.push(t.slice());
@@ -227,34 +228,75 @@ function permuteUnique(nums: number[]): number[][] {
#### Rust
```rust
-use std::collections::HashSet;
impl Solution {
- fn dfs(i: usize, nums: &mut Vec, res: &mut Vec>) {
+ pub fn permute_unique(mut nums: Vec) -> Vec> {
+ nums.sort();
let n = nums.len();
- if i == n {
- res.push(nums.clone());
- return;
- }
- let mut set = HashSet::new();
- for j in i..n {
- if set.contains(&nums[j]) {
- continue;
+ let mut ans = Vec::new();
+ let mut t = vec![0; n];
+ let mut vis = vec![false; n];
+
+ fn dfs(
+ nums: &Vec,
+ t: &mut Vec,
+ vis: &mut Vec,
+ ans: &mut Vec>,
+ i: usize,
+ ) {
+ if i == nums.len() {
+ ans.push(t.clone());
+ return;
+ }
+ for j in 0..nums.len() {
+ if vis[j] || (j > 0 && nums[j] == nums[j - 1] && !vis[j - 1]) {
+ continue;
+ }
+ t[i] = nums[j];
+ vis[j] = true;
+ dfs(nums, t, vis, ans, i + 1);
+ vis[j] = false;
}
- set.insert(nums[j]);
- nums.swap(i, j);
- Self::dfs(i + 1, nums, res);
- nums.swap(i, j);
}
- }
- pub fn permute_unique(mut nums: Vec) -> Vec> {
- let mut res = vec![];
- Self::dfs(0, &mut nums, &mut res);
- res
+ dfs(&nums, &mut t, &mut vis, &mut ans, 0);
+ ans
}
}
```
+#### JavaScript
+
+```js
+/**
+ * @param {number[]} nums
+ * @return {number[][]}
+ */
+var permuteUnique = function (nums) {
+ nums.sort((a, b) => a - b);
+ const n = nums.length;
+ const ans = [];
+ const t = Array(n);
+ const vis = Array(n).fill(false);
+ const dfs = i => {
+ if (i === n) {
+ ans.push(t.slice());
+ return;
+ }
+ for (let j = 0; j < n; ++j) {
+ if (vis[j] || (j > 0 && nums[j] === nums[j - 1] && !vis[j - 1])) {
+ continue;
+ }
+ t[i] = nums[j];
+ vis[j] = true;
+ dfs(i + 1);
+ vis[j] = false;
+ }
+ };
+ dfs(0);
+ return ans;
+};
+```
+
#### C#
```cs
diff --git a/solution/0000-0099/0047.Permutations II/README_EN.md b/solution/0000-0099/0047.Permutations II/README_EN.md
index f0beef94ee0a7..db501a859c053 100644
--- a/solution/0000-0099/0047.Permutations II/README_EN.md
+++ b/solution/0000-0099/0047.Permutations II/README_EN.md
@@ -5,6 +5,7 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/0000-0099/0047.Pe
tags:
- Array
- Backtracking
+ - Sorting
---
@@ -53,16 +54,16 @@ tags:
### Solution 1: Sorting + Backtracking
-We can first sort the array, which allows us to place duplicate numbers together, making it easier for us to remove duplicates.
+We can first sort the array so that duplicate numbers are placed together, making it easier to remove duplicates.
-Next, we design a function $dfs(i)$, indicating that we need to fill in the number at the $i$th position. The specific implementation of the function is as follows:
+Then, we design a function $\textit{dfs}(i)$, which represents the current number to be placed at the $i$-th position. The specific implementation of the function is as follows:
-- If $i = n$, it means we have finished filling in, add the current permutation to the answer array, and then return.
-- Otherwise, we enumerate the number $nums[j]$ at the $i$th position, where the range of $j$ is $[0, n - 1]$. We need to ensure that $nums[j]$ has not been used and is different from the number enumerated before, so as to ensure that the current permutation is not repeated. If the conditions are met, we can fill in $nums[j]$, and continue to recursively fill in the next position, that is, call $dfs(i + 1)$. After the recursive call ends, we need to mark $nums[j]$ as unused for later enumeration.
+- If $i = n$, it means we have filled all positions, add the current permutation to the answer array, and then return.
+- Otherwise, we enumerate the number $nums[j]$ for the $i$-th position, where the range of $j$ is $[0, n - 1]$. We need to ensure that $nums[j]$ has not been used and is different from the previously enumerated number to ensure that the current permutation is not duplicated. If the conditions are met, we can place $nums[j]$ and continue to recursively fill the next position by calling $\textit{dfs}(i + 1)$. After the recursive call ends, we need to mark $nums[j]$ as unused to facilitate subsequent enumeration.
-In the main function, we first sort the array, then call $dfs(0)$, that is, start filling from the 0th position, and finally return the answer array.
+In the main function, we first sort the array, then call $\textit{dfs}(0)$ to start filling from the 0th position, and finally return the answer array.
-The time complexity is $O(n \times n!)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array. We need to enumerate $n!$ times, and each enumeration takes $O(n)$ time to judge whether it is repeated. In addition, we need a marker array to mark whether each position has been used, so the space complexity is $O(n)$.
+The time complexity is $O(n \times n!)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array. We need to perform $n!$ enumerations, and each enumeration requires $O(n)$ time to check for duplicates. Additionally, we need a marker array to mark whether each position has been used, so the space complexity is $O(n)$.
Similar problems:
@@ -138,12 +139,12 @@ class Solution {
class Solution {
public:
vector> permuteUnique(vector