@@ -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 56. \344\277\241\347\211\251\344\274\240\351\200\201/README.md" "b/lcp/LCP 56. \344\277\241\347\211\251\344\274\240\351\200\201/README.md"
index b66d379ba9b7d..79d933a073abb 100644
--- "a/lcp/LCP 56. \344\277\241\347\211\251\344\274\240\351\200\201/README.md"
+++ "b/lcp/LCP 56. \344\277\241\347\211\251\344\274\240\351\200\201/README.md"
@@ -271,6 +271,57 @@ function conveyorBelt(matrix: string[], start: number[], end: number[]): number
}
```
+#### Swift
+
+```swift
+class Solution {
+ func conveyorBelt(_ matrix: [String], _ start: [Int], _ end: [Int]) -> Int {
+ let directions: [(Int, Int)] = [(-1, 0), (0, 1), (1, 0), (0, -1)]
+ let directionMap: [Character: Int] = ["^": 0, ">": 1, "v": 2, "<": 3]
+
+ let rows = matrix.count
+ let cols = matrix[0].count
+
+ var dist = Array(repeating: Array(repeating: Int.max, count: cols), count: rows)
+ var deque: [(Int, Int)] = []
+
+ dist[start[0]][start[1]] = 0
+ deque.append((start[0], start[1]))
+
+ while !deque.isEmpty {
+ let (i, j) = deque.removeFirst()
+
+ if i == end[0] && j == end[1] {
+ return dist[i][j]
+ }
+
+ for (k, (di, dj)) in directions.enumerated() {
+ let ni = i + di
+ let nj = j + dj
+
+ if ni >= 0 && ni < rows && nj >= 0 && nj < cols {
+ let currentChar = matrix[i][matrix[i].index(matrix[i].startIndex, offsetBy: j)]
+ let additionalCost = directionMap[currentChar] == k ? 0 : 1
+ let newDist = dist[i][j] + additionalCost
+
+ if newDist < dist[ni][nj] {
+ dist[ni][nj] = newDist
+
+ if additionalCost == 0 {
+ deque.insert((ni, nj), at: 0)
+ } else {
+ deque.append((ni, nj))
+ }
+ }
+ }
+ }
+ }
+
+ return -1
+ }
+}
+```
+
diff --git "a/lcp/LCP 56. \344\277\241\347\211\251\344\274\240\351\200\201/Solution.swift" "b/lcp/LCP 56. \344\277\241\347\211\251\344\274\240\351\200\201/Solution.swift"
new file mode 100644
index 0000000000000..49e38bff757e2
--- /dev/null
+++ "b/lcp/LCP 56. \344\277\241\347\211\251\344\274\240\351\200\201/Solution.swift"
@@ -0,0 +1,46 @@
+class Solution {
+ func conveyorBelt(_ matrix: [String], _ start: [Int], _ end: [Int]) -> Int {
+ let directions: [(Int, Int)] = [(-1, 0), (0, 1), (1, 0), (0, -1)]
+ let directionMap: [Character: Int] = ["^": 0, ">": 1, "v": 2, "<": 3]
+
+ let rows = matrix.count
+ let cols = matrix[0].count
+
+ var dist = Array(repeating: Array(repeating: Int.max, count: cols), count: rows)
+ var deque: [(Int, Int)] = []
+
+ dist[start[0]][start[1]] = 0
+ deque.append((start[0], start[1]))
+
+ while !deque.isEmpty {
+ let (i, j) = deque.removeFirst()
+
+ if i == end[0] && j == end[1] {
+ return dist[i][j]
+ }
+
+ for (k, (di, dj)) in directions.enumerated() {
+ let ni = i + di
+ let nj = j + dj
+
+ if ni >= 0 && ni < rows && nj >= 0 && nj < cols {
+ let currentChar = matrix[i][matrix[i].index(matrix[i].startIndex, offsetBy: j)]
+ let additionalCost = directionMap[currentChar] == k ? 0 : 1
+ let newDist = dist[i][j] + additionalCost
+
+ if newDist < dist[ni][nj] {
+ dist[ni][nj] = newDist
+
+ if additionalCost == 0 {
+ deque.insert((ni, nj), at: 0)
+ } else {
+ deque.append((ni, nj))
+ }
+ }
+ }
+ }
+ }
+
+ return -1
+ }
+}
\ No newline at end of file
diff --git "a/lcp/LCP 61. \346\260\224\346\270\251\345\217\230\345\214\226\350\266\213\345\212\277/README.md" "b/lcp/LCP 61. \346\260\224\346\270\251\345\217\230\345\214\226\350\266\213\345\212\277/README.md"
index 14bac274a24df..faf7cedef5e2f 100644
--- "a/lcp/LCP 61. \346\260\224\346\270\251\345\217\230\345\214\226\350\266\213\345\212\277/README.md"
+++ "b/lcp/LCP 61. \346\260\224\346\270\251\345\217\230\345\214\226\350\266\213\345\212\277/README.md"
@@ -183,6 +183,31 @@ impl Solution {
}
```
+#### Swift
+
+```swift
+class Solution {
+ func temperatureTrend(_ temperatureA: [Int], _ temperatureB: [Int]) -> Int {
+ var maxTrend = 0
+ var currentTrend = 0
+
+ for i in 0.. 0) {
+ currentTrend += 1
+ maxTrend = max(maxTrend, currentTrend)
+ } else {
+ currentTrend = 0
+ }
+ }
+
+ return maxTrend
+ }
+}
+```
+
diff --git "a/lcp/LCP 61. \346\260\224\346\270\251\345\217\230\345\214\226\350\266\213\345\212\277/Solution.swift" "b/lcp/LCP 61. \346\260\224\346\270\251\345\217\230\345\214\226\350\266\213\345\212\277/Solution.swift"
new file mode 100644
index 0000000000000..b0807755dc2a1
--- /dev/null
+++ "b/lcp/LCP 61. \346\260\224\346\270\251\345\217\230\345\214\226\350\266\213\345\212\277/Solution.swift"
@@ -0,0 +1,20 @@
+class Solution {
+ func temperatureTrend(_ temperatureA: [Int], _ temperatureB: [Int]) -> Int {
+ var maxTrend = 0
+ var currentTrend = 0
+
+ for i in 0.. 0) {
+ currentTrend += 1
+ maxTrend = max(maxTrend, currentTrend)
+ } else {
+ currentTrend = 0
+ }
+ }
+
+ return maxTrend
+ }
+}
\ No newline at end of file
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 74e45489db964..88c20df42f7fa 100644
--- a/solution/0000-0099/0001.Two Sum/README.md
+++ b/solution/0000-0099/0001.Two Sum/README.md
@@ -85,8 +85,7 @@ class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
d = {}
for i, x in enumerate(nums):
- y = target - x
- if y in d:
+ if (y := target - x) in d:
return [d[y], i]
d[x] = i
```
@@ -354,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 2e2b638512a97..c536e027be740 100644
--- a/solution/0000-0099/0001.Two Sum/README_EN.md
+++ b/solution/0000-0099/0001.Two Sum/README_EN.md
@@ -82,8 +82,7 @@ class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
d = {}
for i, x in enumerate(nums):
- y = target - x
- if y in d:
+ if (y := target - x) in d:
return [d[y], i]
d[x] = i
```
@@ -351,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/0001.Two Sum/Solution.py b/solution/0000-0099/0001.Two Sum/Solution.py
index 35a41d01ac455..5764f5daafd0e 100644
--- a/solution/0000-0099/0001.Two Sum/Solution.py
+++ b/solution/0000-0099/0001.Two Sum/Solution.py
@@ -2,7 +2,6 @@ class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
d = {}
for i, x in enumerate(nums):
- y = target - x
- if y in d:
+ if (y := target - x) in d:
return [d[y], i]
d[x] = i
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 0a34e8470465a..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
@@ -62,26 +62,15 @@ tags:
-### 方法一:双指针 + 哈希表
+### 方法一:滑动窗口
-定义一个哈希表记录当前窗口内出现的字符,记 $i$ 和 $j$ 分别表示不重复子串的开始位置和结束位置,无重复字符子串的最大长度记为 `ans`。
+我们可以用两个指针 $l$ 和 $r$ 维护一个滑动窗口,使其始终满足窗口内没有重复字符,初始时 $l$ 和 $r$ 都指向字符串的第一个字符。用一个哈希表或者长度为 $128$ 的数组 $\textit{cnt}$ 来记录每个字符出现的次数,其中 $\textit{cnt}[c]$ 表示字符 $c$ 出现的次数。
-遍历字符串 `s` 的每个字符 $s[j]$,我们记为 $c$。若 $s[i..j-1]$ 窗口内存在 $c$,则 $i$ 循环向右移动,更新哈希表,直至 $s[i..j-1]$ 窗口不存在 `c`,循环结束。将 `c` 加入哈希表中,此时 $s[i..j]$ 窗口内不含重复元素,更新 `ans` 的最大值。
+接下来,我们依次移动右指针 $r$,每次移动时,将 $\textit{cnt}[s[r]]$ 的值加 $1$,然后判断当前窗口 $[l, r]$ 内 $\textit{cnt}[s[r]]$ 是否大于 $1$,如果大于 $1$,说明当前窗口内有重复字符,我们需要移动左指针 $l$,直到窗口内没有重复字符为止。然后,我们更新答案 $\textit{ans} = \max(\textit{ans}, r - l + 1)$。
-最后返回 `ans` 即可。
+最终,我们返回答案 $\textit{ans}$ 即可。
-时间复杂度 $O(n)$,其中 $n$ 表示字符串 `s` 的长度。
-
-双指针算法模板:
-
-```java
-for (int i = 0, j = 0; i < n; ++i) {
- while (j < i && check(j, i)) {
- ++j;
- }
- // 具体问题的逻辑
-}
-```
+时间复杂度 $O(n)$,其中 $n$ 为字符串的长度。空间复杂度 $O(|\Sigma|)$,其中 $\Sigma$ 表示字符集,这里 $\Sigma$ 的大小为 $128$。
@@ -90,14 +79,14 @@ for (int i = 0, j = 0; i < n; ++i) {
```python
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
- ss = set()
- ans = i = 0
- for j, c in enumerate(s):
- while c in ss:
- ss.remove(s[i])
- i += 1
- ss.add(c)
- ans = max(ans, j - i + 1)
+ cnt = Counter()
+ ans = l = 0
+ for r, c in enumerate(s):
+ cnt[c] += 1
+ while cnt[c] > 1:
+ cnt[s[l]] -= 1
+ l += 1
+ ans = max(ans, r - l + 1)
return ans
```
@@ -106,15 +95,15 @@ class Solution:
```java
class Solution {
public int lengthOfLongestSubstring(String s) {
- boolean[] ss = new boolean[128];
- int ans = 0;
- for (int i = 0, j = 0; j < s.length(); ++j) {
- char c = s.charAt(j);
- while (ss[c]) {
- ss[s.charAt(i++)] = false;
+ int[] cnt = new int[128];
+ int ans = 0, n = s.length();
+ for (int l = 0, r = 0; r < n; ++r) {
+ char c = s.charAt(r);
+ ++cnt[c];
+ while (cnt[c] > 1) {
+ --cnt[s.charAt(l++)];
}
- ss[c] = true;
- ans = Math.max(ans, j - i + 1);
+ ans = Math.max(ans, r - l + 1);
}
return ans;
}
@@ -127,14 +116,14 @@ class Solution {
class Solution {
public:
int lengthOfLongestSubstring(string s) {
- bool ss[128]{};
- int ans = 0;
- for (int i = 0, j = 0; j < s.size(); ++j) {
- while (ss[s[j]]) {
- ss[s[i++]] = false;
+ int cnt[128]{};
+ int ans = 0, n = s.size();
+ for (int l = 0, r = 0; r < n; ++r) {
+ ++cnt[s[r]];
+ while (cnt[s[r]] > 1) {
+ --cnt[s[l++]];
}
- ss[s[j]] = true;
- ans = max(ans, j - i + 1);
+ ans = max(ans, r - l + 1);
}
return ans;
}
@@ -145,14 +134,15 @@ public:
```go
func lengthOfLongestSubstring(s string) (ans int) {
- ss := [128]bool{}
- for i, j := 0, 0; j < len(s); j++ {
- for ss[s[j]] {
- ss[s[i]] = false
- i++
+ cnt := [128]int{}
+ l := 0
+ for r, c := range s {
+ cnt[c]++
+ for cnt[c] > 1 {
+ cnt[s[l]]--
+ l++
}
- ss[s[j]] = true
- ans = max(ans, j-i+1)
+ ans = max(ans, r-l+1)
}
return
}
@@ -163,13 +153,15 @@ func lengthOfLongestSubstring(s string) (ans int) {
```ts
function lengthOfLongestSubstring(s: string): number {
let ans = 0;
- const ss: Set = new Set();
- for (let i = 0, j = 0; j < s.length; ++j) {
- while (ss.has(s[j])) {
- ss.delete(s[i++]);
+ const cnt = new Map();
+ const n = s.length;
+ for (let l = 0, r = 0; r < n; ++r) {
+ cnt.set(s[r], (cnt.get(s[r]) || 0) + 1);
+ while (cnt.get(s[r])! > 1) {
+ cnt.set(s[l], cnt.get(s[l])! - 1);
+ ++l;
}
- ss.add(s[j]);
- ans = Math.max(ans, j - i + 1);
+ ans = Math.max(ans, r - l + 1);
}
return ans;
}
@@ -178,24 +170,22 @@ function lengthOfLongestSubstring(s: string): number {
#### Rust
```rust
-use std::collections::HashSet;
-
impl Solution {
pub fn length_of_longest_substring(s: String) -> i32 {
- let s = s.as_bytes();
- let mut ss = HashSet::new();
- let mut i = 0;
- s.iter()
- .map(|c| {
- while ss.contains(&c) {
- ss.remove(&s[i]);
- i += 1;
- }
- ss.insert(c);
- ss.len()
- })
- .max()
- .unwrap_or(0) as i32
+ let mut cnt = [0; 128];
+ let mut ans = 0;
+ let mut l = 0;
+ let chars: Vec = s.chars().collect();
+ let n = chars.len();
+ for (r, &c) in chars.iter().enumerate() {
+ cnt[c as usize] += 1;
+ while cnt[c as usize] > 1 {
+ cnt[chars[l] as usize] -= 1;
+ l += 1;
+ }
+ ans = ans.max((r - l + 1) as i32);
+ }
+ ans
}
}
```
@@ -209,13 +199,15 @@ impl Solution {
*/
var lengthOfLongestSubstring = function (s) {
let ans = 0;
- const ss = new Set();
- for (let i = 0, j = 0; j < s.length; ++j) {
- while (ss.has(s[j])) {
- ss.delete(s[i++]);
+ const n = s.length;
+ const cnt = new Map();
+ for (let l = 0, r = 0; r < n; ++r) {
+ cnt.set(s[r], (cnt.get(s[r]) || 0) + 1);
+ while (cnt.get(s[r]) > 1) {
+ cnt.set(s[l], cnt.get(s[l]) - 1);
+ ++l;
}
- ss.add(s[j]);
- ans = Math.max(ans, j - i + 1);
+ ans = Math.max(ans, r - l + 1);
}
return ans;
};
@@ -226,14 +218,15 @@ var lengthOfLongestSubstring = function (s) {
```cs
public class Solution {
public int LengthOfLongestSubstring(string s) {
+ int n = s.Length;
int ans = 0;
- var ss = new HashSet();
- for (int i = 0, j = 0; j < s.Length; ++j) {
- while (ss.Contains(s[j])) {
- ss.Remove(s[i++]);
+ var cnt = new int[128];
+ for (int l = 0, r = 0; r < n; ++r) {
+ ++cnt[s[r]];
+ while (cnt[s[r]] > 1) {
+ --cnt[s[l++]];
}
- ss.Add(s[j]);
- ans = Math.Max(ans, j - i + 1);
+ ans = Math.Max(ans, r - l + 1);
}
return ans;
}
@@ -244,19 +237,18 @@ public class Solution {
```php
class Solution {
- /**
- * @param String $s
- * @return Integer
- */
function lengthOfLongestSubstring($s) {
+ $n = strlen($s);
$ans = 0;
- $ss = [];
- for ($i = 0, $j = 0; $j < strlen($s); ++$j) {
- while (in_array($s[$j], $ss)) {
- unset($ss[array_search($s[$i++], $ss)]);
+ $cnt = array_fill(0, 128, 0);
+ $l = 0;
+ for ($r = 0; $r < $n; ++$r) {
+ $cnt[ord($s[$r])]++;
+ while ($cnt[ord($s[$r])] > 1) {
+ $cnt[ord($s[$l])]--;
+ $l++;
}
- $ss[] = $s[$j];
- $ans = max($ans, $j - $i + 1);
+ $ans = max($ans, $r - $l + 1);
}
return $ans;
}
@@ -268,68 +260,73 @@ class Solution {
```swift
class Solution {
func lengthOfLongestSubstring(_ s: String) -> Int {
- var map = [Character: Int]()
- var currentStartingIndex = 0
- var i = 0
- var maxLength = 0
- for char in s {
- if map[char] != nil {
- if map[char]! >= currentStartingIndex {
- maxLength = max(maxLength, i - currentStartingIndex)
- currentStartingIndex = map[char]! + 1
- }
+ let n = s.count
+ var ans = 0
+ var cnt = [Int](repeating: 0, count: 128)
+ var l = 0
+ let sArray = Array(s)
+ for r in 0.. 1 {
+ cnt[Int(sArray[l].asciiValue!)] -= 1
+ l += 1
}
- map[char] = i
- i += 1
+ ans = max(ans, r - l + 1)
}
- return max(maxLength, i - currentStartingIndex)
+ return ans
}
}
```
-#### Nim
-
-```nim
-proc lengthOfLongestSubstring(s: string): int =
- var
- i = 0
- j = 0
- res = 0
- literals: set[char] = {}
-
- while i < s.len:
- while s[i] in literals:
- if s[j] in literals:
- excl(literals, s[j])
- j += 1
- literals.incl(s[i]) # Uniform Function Call Syntax f(x) = x.f
- res = max(res, i - j + 1)
- i += 1
-
- result = res # result has the default return value
-```
-
#### Kotlin
```kotlin
class Solution {
fun lengthOfLongestSubstring(s: String): Int {
- var char_set = BooleanArray(128)
- var left = 0
+ val n = s.length
var ans = 0
- s.forEachIndexed { right, c ->
- while (char_set[c.code]) {
- char_set[s[left].code] = false
- left++
+ val cnt = IntArray(128)
+ var l = 0
+ for (r in 0 until n) {
+ cnt[s[r].toInt()]++
+ while (cnt[s[r].toInt()] > 1) {
+ cnt[s[l].toInt()]--
+ l++
}
- char_set[c.code] = true
- ans = Math.max(ans, right - left + 1)
+ ans = Math.max(ans, r - l + 1)
}
return ans
}
}
```
+#### 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 7218d6526623c..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 longestsubstring without repeating characters.
+
Given a string s, find the length of the longestsubstring without duplicate characters.
Example 1:
@@ -60,26 +60,15 @@ Notice that the answer must be a substring, "pwke" is a subsequence an
-### Solution 1: Two pointers + Hash Table
+### Solution 1: Sliding Window
-Define a hash table to record the characters in the current window. Let $i$ and $j$ represent the start and end positions of the non-repeating substring, respectively. The length of the longest non-repeating substring is recorded by `ans`.
+We can use two pointers $l$ and $r$ to maintain a sliding window that always satisfies the condition of having no repeating characters within the window. Initially, both $l$ and $r$ point to the first character of the string. We use a hash table or an array of length $128$ called $\textit{cnt}$ to record the number of occurrences of each character, where $\textit{cnt}[c]$ represents the number of occurrences of character $c$.
-For each character $s[j]$ in the string `s`, we call it $c$. If $c$ exists in the window $s[i..j-1]$, we move $i$ to the right until $s[i..j-1]$ does not contain `c`. Then we add `c` to the hash table. At this time, the window $s[i..j]$ does not contain repeated elements, and we update the maximum value of `ans`.
+Next, we move the right pointer $r$ one step at a time. Each time we move it, we increment the value of $\textit{cnt}[s[r]]$ by $1$, and then check if the value of $\textit{cnt}[s[r]]$ is greater than $1$ within the current window $[l, r]$. If it is greater than $1$, it means there are repeating characters within the current window, and we need to move the left pointer $l$ until there are no repeating characters within the window. Then, we update the answer $\textit{ans} = \max(\textit{ans}, r - l + 1)$.
-Finally, return `ans`.
+Finally, we return the answer $\textit{ans}$.
-The time complexity is $O(n)$, where $n$ represents the length of the string `s`.
-
-Two pointers algorithm template:
-
-```java
-for (int i = 0, j = 0; i < n; ++i) {
- while (j < i && check(j, i)) {
- ++j;
- }
- // logic of specific problem
-}
-```
+The time complexity is $O(n)$, where $n$ is the length of the string. The space complexity is $O(|\Sigma|)$, where $\Sigma$ represents the character set, and the size of $\Sigma$ is $128$.
@@ -88,14 +77,14 @@ for (int i = 0, j = 0; i < n; ++i) {
```python
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
- ss = set()
- ans = i = 0
- for j, c in enumerate(s):
- while c in ss:
- ss.remove(s[i])
- i += 1
- ss.add(c)
- ans = max(ans, j - i + 1)
+ cnt = Counter()
+ ans = l = 0
+ for r, c in enumerate(s):
+ cnt[c] += 1
+ while cnt[c] > 1:
+ cnt[s[l]] -= 1
+ l += 1
+ ans = max(ans, r - l + 1)
return ans
```
@@ -104,15 +93,15 @@ class Solution:
```java
class Solution {
public int lengthOfLongestSubstring(String s) {
- boolean[] ss = new boolean[128];
- int ans = 0;
- for (int i = 0, j = 0; j < s.length(); ++j) {
- char c = s.charAt(j);
- while (ss[c]) {
- ss[s.charAt(i++)] = false;
+ int[] cnt = new int[128];
+ int ans = 0, n = s.length();
+ for (int l = 0, r = 0; r < n; ++r) {
+ char c = s.charAt(r);
+ ++cnt[c];
+ while (cnt[c] > 1) {
+ --cnt[s.charAt(l++)];
}
- ss[c] = true;
- ans = Math.max(ans, j - i + 1);
+ ans = Math.max(ans, r - l + 1);
}
return ans;
}
@@ -125,14 +114,14 @@ class Solution {
class Solution {
public:
int lengthOfLongestSubstring(string s) {
- bool ss[128]{};
- int ans = 0;
- for (int i = 0, j = 0; j < s.size(); ++j) {
- while (ss[s[j]]) {
- ss[s[i++]] = false;
+ int cnt[128]{};
+ int ans = 0, n = s.size();
+ for (int l = 0, r = 0; r < n; ++r) {
+ ++cnt[s[r]];
+ while (cnt[s[r]] > 1) {
+ --cnt[s[l++]];
}
- ss[s[j]] = true;
- ans = max(ans, j - i + 1);
+ ans = max(ans, r - l + 1);
}
return ans;
}
@@ -143,14 +132,15 @@ public:
```go
func lengthOfLongestSubstring(s string) (ans int) {
- ss := [128]bool{}
- for i, j := 0, 0; j < len(s); j++ {
- for ss[s[j]] {
- ss[s[i]] = false
- i++
+ cnt := [128]int{}
+ l := 0
+ for r, c := range s {
+ cnt[c]++
+ for cnt[c] > 1 {
+ cnt[s[l]]--
+ l++
}
- ss[s[j]] = true
- ans = max(ans, j-i+1)
+ ans = max(ans, r-l+1)
}
return
}
@@ -161,13 +151,15 @@ func lengthOfLongestSubstring(s string) (ans int) {
```ts
function lengthOfLongestSubstring(s: string): number {
let ans = 0;
- const ss: Set = new Set();
- for (let i = 0, j = 0; j < s.length; ++j) {
- while (ss.has(s[j])) {
- ss.delete(s[i++]);
+ const cnt = new Map();
+ const n = s.length;
+ for (let l = 0, r = 0; r < n; ++r) {
+ cnt.set(s[r], (cnt.get(s[r]) || 0) + 1);
+ while (cnt.get(s[r])! > 1) {
+ cnt.set(s[l], cnt.get(s[l])! - 1);
+ ++l;
}
- ss.add(s[j]);
- ans = Math.max(ans, j - i + 1);
+ ans = Math.max(ans, r - l + 1);
}
return ans;
}
@@ -176,24 +168,22 @@ function lengthOfLongestSubstring(s: string): number {
#### Rust
```rust
-use std::collections::HashSet;
-
impl Solution {
pub fn length_of_longest_substring(s: String) -> i32 {
- let s = s.as_bytes();
- let mut ss = HashSet::new();
- let mut i = 0;
- s.iter()
- .map(|c| {
- while ss.contains(&c) {
- ss.remove(&s[i]);
- i += 1;
- }
- ss.insert(c);
- ss.len()
- })
- .max()
- .unwrap_or(0) as i32
+ let mut cnt = [0; 128];
+ let mut ans = 0;
+ let mut l = 0;
+ let chars: Vec = s.chars().collect();
+ let n = chars.len();
+ for (r, &c) in chars.iter().enumerate() {
+ cnt[c as usize] += 1;
+ while cnt[c as usize] > 1 {
+ cnt[chars[l] as usize] -= 1;
+ l += 1;
+ }
+ ans = ans.max((r - l + 1) as i32);
+ }
+ ans
}
}
```
@@ -207,13 +197,15 @@ impl Solution {
*/
var lengthOfLongestSubstring = function (s) {
let ans = 0;
- const ss = new Set();
- for (let i = 0, j = 0; j < s.length; ++j) {
- while (ss.has(s[j])) {
- ss.delete(s[i++]);
+ const n = s.length;
+ const cnt = new Map();
+ for (let l = 0, r = 0; r < n; ++r) {
+ cnt.set(s[r], (cnt.get(s[r]) || 0) + 1);
+ while (cnt.get(s[r]) > 1) {
+ cnt.set(s[l], cnt.get(s[l]) - 1);
+ ++l;
}
- ss.add(s[j]);
- ans = Math.max(ans, j - i + 1);
+ ans = Math.max(ans, r - l + 1);
}
return ans;
};
@@ -224,14 +216,15 @@ var lengthOfLongestSubstring = function (s) {
```cs
public class Solution {
public int LengthOfLongestSubstring(string s) {
+ int n = s.Length;
int ans = 0;
- var ss = new HashSet();
- for (int i = 0, j = 0; j < s.Length; ++j) {
- while (ss.Contains(s[j])) {
- ss.Remove(s[i++]);
+ var cnt = new int[128];
+ for (int l = 0, r = 0; r < n; ++r) {
+ ++cnt[s[r]];
+ while (cnt[s[r]] > 1) {
+ --cnt[s[l++]];
}
- ss.Add(s[j]);
- ans = Math.Max(ans, j - i + 1);
+ ans = Math.Max(ans, r - l + 1);
}
return ans;
}
@@ -242,19 +235,18 @@ public class Solution {
```php
class Solution {
- /**
- * @param String $s
- * @return Integer
- */
function lengthOfLongestSubstring($s) {
+ $n = strlen($s);
$ans = 0;
- $ss = [];
- for ($i = 0, $j = 0; $j < strlen($s); ++$j) {
- while (in_array($s[$j], $ss)) {
- unset($ss[array_search($s[$i++], $ss)]);
+ $cnt = array_fill(0, 128, 0);
+ $l = 0;
+ for ($r = 0; $r < $n; ++$r) {
+ $cnt[ord($s[$r])]++;
+ while ($cnt[ord($s[$r])] > 1) {
+ $cnt[ord($s[$l])]--;
+ $l++;
}
- $ss[] = $s[$j];
- $ans = max($ans, $j - $i + 1);
+ $ans = max($ans, $r - $l + 1);
}
return $ans;
}
@@ -266,68 +258,73 @@ class Solution {
```swift
class Solution {
func lengthOfLongestSubstring(_ s: String) -> Int {
- var map = [Character: Int]()
- var currentStartingIndex = 0
- var i = 0
- var maxLength = 0
- for char in s {
- if map[char] != nil {
- if map[char]! >= currentStartingIndex {
- maxLength = max(maxLength, i - currentStartingIndex)
- currentStartingIndex = map[char]! + 1
- }
+ let n = s.count
+ var ans = 0
+ var cnt = [Int](repeating: 0, count: 128)
+ var l = 0
+ let sArray = Array(s)
+ for r in 0.. 1 {
+ cnt[Int(sArray[l].asciiValue!)] -= 1
+ l += 1
}
- map[char] = i
- i += 1
+ ans = max(ans, r - l + 1)
}
- return max(maxLength, i - currentStartingIndex)
+ return ans
}
}
```
-#### Nim
-
-```nim
-proc lengthOfLongestSubstring(s: string): int =
- var
- i = 0
- j = 0
- res = 0
- literals: set[char] = {}
-
- while i < s.len:
- while s[i] in literals:
- if s[j] in literals:
- excl(literals, s[j])
- j += 1
- literals.incl(s[i]) # Uniform Function Call Syntax f(x) = x.f
- res = max(res, i - j + 1)
- i += 1
-
- result = res # result has the default return value
-```
-
#### Kotlin
```kotlin
class Solution {
fun lengthOfLongestSubstring(s: String): Int {
- var char_set = BooleanArray(128)
- var left = 0
+ val n = s.length
var ans = 0
- s.forEachIndexed { right, c ->
- while (char_set[c.code]) {
- char_set[s[left].code] = false
- left++
+ val cnt = IntArray(128)
+ var l = 0
+ for (r in 0 until n) {
+ cnt[s[r].toInt()]++
+ while (cnt[s[r].toInt()] > 1) {
+ cnt[s[l].toInt()]--
+ l++
}
- char_set[c.code] = true
- ans = Math.max(ans, right - left + 1)
+ ans = Math.max(ans, r - l + 1)
}
return ans
}
}
```
+#### 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/0003.Longest Substring Without Repeating Characters/Solution.cpp b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.cpp
index 980f98df2cc44..549f59f0ae8b7 100644
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.cpp
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.cpp
@@ -1,15 +1,15 @@
class Solution {
public:
int lengthOfLongestSubstring(string s) {
- bool ss[128]{};
- int ans = 0;
- for (int i = 0, j = 0; j < s.size(); ++j) {
- while (ss[s[j]]) {
- ss[s[i++]] = false;
+ int cnt[128]{};
+ int ans = 0, n = s.size();
+ for (int l = 0, r = 0; r < n; ++r) {
+ ++cnt[s[r]];
+ while (cnt[s[r]] > 1) {
+ --cnt[s[l++]];
}
- ss[s[j]] = true;
- ans = max(ans, j - i + 1);
+ ans = max(ans, r - l + 1);
}
return ans;
}
-};
\ No newline at end of file
+};
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.cs b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.cs
index 2c29e34899025..044baded41e3a 100644
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.cs
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.cs
@@ -1,13 +1,14 @@
public class Solution {
public int LengthOfLongestSubstring(string s) {
+ int n = s.Length;
int ans = 0;
- var ss = new HashSet();
- for (int i = 0, j = 0; j < s.Length; ++j) {
- while (ss.Contains(s[j])) {
- ss.Remove(s[i++]);
+ var cnt = new int[128];
+ for (int l = 0, r = 0; r < n; ++r) {
+ ++cnt[s[r]];
+ while (cnt[s[r]] > 1) {
+ --cnt[s[l++]];
}
- ss.Add(s[j]);
- ans = Math.Max(ans, j - i + 1);
+ ans = Math.Max(ans, r - l + 1);
}
return ans;
}
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.go b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.go
index 68104afd448ff..365301a1ce97f 100644
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.go
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.go
@@ -1,12 +1,13 @@
func lengthOfLongestSubstring(s string) (ans int) {
- ss := [128]bool{}
- for i, j := 0, 0; j < len(s); j++ {
- for ss[s[j]] {
- ss[s[i]] = false
- i++
+ cnt := [128]int{}
+ l := 0
+ for r, c := range s {
+ cnt[c]++
+ for cnt[c] > 1 {
+ cnt[s[l]]--
+ l++
}
- ss[s[j]] = true
- ans = max(ans, j-i+1)
+ ans = max(ans, r-l+1)
}
return
-}
\ No newline at end of file
+}
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.java b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.java
index 28dda65b2442d..574f3c62a27e8 100644
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.java
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.java
@@ -1,15 +1,15 @@
class Solution {
public int lengthOfLongestSubstring(String s) {
- boolean[] ss = new boolean[128];
- int ans = 0;
- for (int i = 0, j = 0; j < s.length(); ++j) {
- char c = s.charAt(j);
- while (ss[c]) {
- ss[s.charAt(i++)] = false;
+ int[] cnt = new int[128];
+ int ans = 0, n = s.length();
+ for (int l = 0, r = 0; r < n; ++r) {
+ char c = s.charAt(r);
+ ++cnt[c];
+ while (cnt[c] > 1) {
+ --cnt[s.charAt(l++)];
}
- ss[c] = true;
- ans = Math.max(ans, j - i + 1);
+ ans = Math.max(ans, r - l + 1);
}
return ans;
}
-}
\ No newline at end of file
+}
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.js b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.js
index d87d290b2cfb3..16f64428d105f 100644
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.js
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.js
@@ -4,13 +4,15 @@
*/
var lengthOfLongestSubstring = function (s) {
let ans = 0;
- const ss = new Set();
- for (let i = 0, j = 0; j < s.length; ++j) {
- while (ss.has(s[j])) {
- ss.delete(s[i++]);
+ const n = s.length;
+ const cnt = new Map();
+ for (let l = 0, r = 0; r < n; ++r) {
+ cnt.set(s[r], (cnt.get(s[r]) || 0) + 1);
+ while (cnt.get(s[r]) > 1) {
+ cnt.set(s[l], cnt.get(s[l]) - 1);
+ ++l;
}
- ss.add(s[j]);
- ans = Math.max(ans, j - i + 1);
+ ans = Math.max(ans, r - l + 1);
}
return ans;
};
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.kt b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.kt
index f98e101a2f826..82cba82a59d3e 100644
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.kt
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.kt
@@ -1,15 +1,16 @@
class Solution {
fun lengthOfLongestSubstring(s: String): Int {
- var char_set = BooleanArray(128)
- var left = 0
+ val n = s.length
var ans = 0
- s.forEachIndexed { right, c ->
- while (char_set[c.code]) {
- char_set[s[left].code] = false
- left++
+ val cnt = IntArray(128)
+ var l = 0
+ for (r in 0 until n) {
+ cnt[s[r].toInt()]++
+ while (cnt[s[r].toInt()] > 1) {
+ cnt[s[l].toInt()]--
+ l++
}
- char_set[c.code] = true
- ans = Math.max(ans, right - left + 1)
+ ans = Math.max(ans, r - l + 1)
}
return ans
}
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.nim b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.nim
deleted file mode 100644
index 1275a35bfbee6..0000000000000
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.nim
+++ /dev/null
@@ -1,17 +0,0 @@
-proc lengthOfLongestSubstring(s: string): int =
- var
- i = 0
- j = 0
- res = 0
- literals: set[char] = {}
-
- while i < s.len:
- while s[i] in literals:
- if s[j] in literals:
- excl(literals, s[j])
- j += 1
- literals.incl(s[i]) # Uniform Function Call Syntax f(x) = x.f
- res = max(res, i - j + 1)
- i += 1
-
- result = res # result has the default return value
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.php b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.php
index d51d37abe0e51..af9ebc954a1d7 100644
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.php
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.php
@@ -1,18 +1,17 @@
class Solution {
- /**
- * @param String $s
- * @return Integer
- */
function lengthOfLongestSubstring($s) {
+ $n = strlen($s);
$ans = 0;
- $ss = [];
- for ($i = 0, $j = 0; $j < strlen($s); ++$j) {
- while (in_array($s[$j], $ss)) {
- unset($ss[array_search($s[$i++], $ss)]);
+ $cnt = array_fill(0, 128, 0);
+ $l = 0;
+ for ($r = 0; $r < $n; ++$r) {
+ $cnt[ord($s[$r])]++;
+ while ($cnt[ord($s[$r])] > 1) {
+ $cnt[ord($s[$l])]--;
+ $l++;
}
- $ss[] = $s[$j];
- $ans = max($ans, $j - $i + 1);
+ $ans = max($ans, $r - $l + 1);
}
return $ans;
}
-}
\ No newline at end of file
+}
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.py b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.py
index 752e44282faee..828f12c0e90c7 100644
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.py
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.py
@@ -1,11 +1,11 @@
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
- ss = set()
- ans = i = 0
- for j, c in enumerate(s):
- while c in ss:
- ss.remove(s[i])
- i += 1
- ss.add(c)
- ans = max(ans, j - i + 1)
+ cnt = Counter()
+ ans = l = 0
+ for r, c in enumerate(s):
+ cnt[c] += 1
+ while cnt[c] > 1:
+ cnt[s[l]] -= 1
+ l += 1
+ ans = max(ans, r - l + 1)
return ans
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.rs b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.rs
index 64e43f86096f5..ca4557f31fda6 100644
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.rs
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.rs
@@ -1,20 +1,18 @@
-use std::collections::HashSet;
-
impl Solution {
pub fn length_of_longest_substring(s: String) -> i32 {
- let s = s.as_bytes();
- let mut ss = HashSet::new();
- let mut i = 0;
- s.iter()
- .map(|c| {
- while ss.contains(&c) {
- ss.remove(&s[i]);
- i += 1;
- }
- ss.insert(c);
- ss.len()
- })
- .max()
- .unwrap_or(0) as i32
+ let mut cnt = [0; 128];
+ let mut ans = 0;
+ let mut l = 0;
+ let chars: Vec = s.chars().collect();
+ let n = chars.len();
+ for (r, &c) in chars.iter().enumerate() {
+ cnt[c as usize] += 1;
+ while cnt[c as usize] > 1 {
+ cnt[chars[l] as usize] -= 1;
+ l += 1;
+ }
+ ans = ans.max((r - l + 1) as i32);
+ }
+ ans
}
}
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.swift b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.swift
index 02462178bdfd5..672a8f0f20787 100644
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.swift
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.swift
@@ -1,19 +1,18 @@
class Solution {
func lengthOfLongestSubstring(_ s: String) -> Int {
- var map = [Character: Int]()
- var currentStartingIndex = 0
- var i = 0
- var maxLength = 0
- for char in s {
- if map[char] != nil {
- if map[char]! >= currentStartingIndex {
- maxLength = max(maxLength, i - currentStartingIndex)
- currentStartingIndex = map[char]! + 1
- }
+ let n = s.count
+ var ans = 0
+ var cnt = [Int](repeating: 0, count: 128)
+ var l = 0
+ let sArray = Array(s)
+ for r in 0.. 1 {
+ cnt[Int(sArray[l].asciiValue!)] -= 1
+ l += 1
}
- map[char] = i
- i += 1
+ ans = max(ans, r - l + 1)
}
- return max(maxLength, i - currentStartingIndex)
+ return ans
}
}
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.ts b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.ts
index 6f4d8610c0bb0..f37a5ffaa95b6 100644
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.ts
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.ts
@@ -1,12 +1,14 @@
function lengthOfLongestSubstring(s: string): number {
let ans = 0;
- const ss: Set = new Set();
- for (let i = 0, j = 0; j < s.length; ++j) {
- while (ss.has(s[j])) {
- ss.delete(s[i++]);
+ const cnt = new Map();
+ const n = s.length;
+ for (let l = 0, r = 0; r < n; ++r) {
+ cnt.set(s[r], (cnt.get(s[r]) || 0) + 1);
+ while (cnt.get(s[r])! > 1) {
+ cnt.set(s[l], cnt.get(s[l])! - 1);
+ ++l;
}
- ss.add(s[j]);
- ans = Math.max(ans, j - i + 1);
+ ans = Math.max(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/0011.Container With Most Water/README.md b/solution/0000-0099/0011.Container With Most Water/README.md
index 5a8a3969742f2..1a3de695501d6 100644
--- a/solution/0000-0099/0011.Container With Most Water/README.md
+++ b/solution/0000-0099/0011.Container With Most Water/README.md
@@ -62,13 +62,15 @@ tags:
### 方法一:双指针
-一开始,我们考虑相距最远的两个柱子所能容纳水的容量。水的宽度是两根柱子之间的距离,而水的高度取决于两根柱子之间较短的那个。
+我们使用两个指针 $l$ 和 $r$ 分别指向数组的左右两端,即 $l = 0$,而 $r = n - 1$,其中 $n$ 是数组的长度。
-当前柱子是最两侧的柱子,水的宽度最大,其他的组合,水的宽度都比这个小。不妨假设左侧柱子的高度小于等于右侧柱子的高度,那么水的高度就是左侧柱子的高度。如果我们移动右侧柱子,那么水的宽度就减小了,而水的高度却不会增加,因此水的容量一定减少。所以我们移动左侧柱子,更新最大容量。
+接下来,我们使用变量 $\textit{ans}$ 记录容器的最大容量,初始化为 $0$。
-循环此过程,直到两个柱子相遇。
+然后,我们开始进行循环,每次循环中,我们计算当前容器的容量,即 $\textit{min}(height[l], height[r]) \times (r - l)$,并将其与 $\textit{ans}$ 进行比较,将较大值赋给 $\textit{ans}$。然后,我们判断 $height[l]$ 和 $height[r]$ 的大小,如果 $\textit{height}[l] < \textit{height}[r]$,移动 $r$ 指针不会使得结果变得更好,因为容器的高度由较短的那根垂直线决定,所以我们移动 $l$ 指针。反之,我们移动 $r$ 指针。
-时间复杂度 $O(n)$,其中 $n$ 是数组 `height` 的长度。空间复杂度 $O(1)$。
+遍历结束后,返回 $\textit{ans}$ 即可。
+
+时间复杂度 $O(n)$,其中 $n$ 是数组 $\textit{height}$ 的长度。空间复杂度 $O(1)$。
@@ -77,15 +79,15 @@ tags:
```python
class Solution:
def maxArea(self, height: List[int]) -> int:
- i, j = 0, len(height) - 1
+ l, r = 0, len(height) - 1
ans = 0
- while i < j:
- t = (j - i) * min(height[i], height[j])
+ while l < r:
+ t = min(height[l], height[r]) * (r - l)
ans = max(ans, t)
- if height[i] < height[j]:
- i += 1
+ if height[l] < height[r]:
+ l += 1
else:
- j -= 1
+ r -= 1
return ans
```
@@ -94,15 +96,15 @@ class Solution:
```java
class Solution {
public int maxArea(int[] height) {
- int i = 0, j = height.length - 1;
+ int l = 0, r = height.length - 1;
int ans = 0;
- while (i < j) {
- int t = Math.min(height[i], height[j]) * (j - i);
+ while (l < r) {
+ int t = Math.min(height[l], height[r]) * (r - l);
ans = Math.max(ans, t);
- if (height[i] < height[j]) {
- ++i;
+ if (height[l] < height[r]) {
+ ++l;
} else {
- --j;
+ --r;
}
}
return ans;
@@ -116,15 +118,15 @@ class Solution {
class Solution {
public:
int maxArea(vector& height) {
- int i = 0, j = height.size() - 1;
+ int l = 0, r = height.size() - 1;
int ans = 0;
- while (i < j) {
- int t = min(height[i], height[j]) * (j - i);
+ while (l < r) {
+ int t = min(height[l], height[r]) * (r - l);
ans = max(ans, t);
- if (height[i] < height[j]) {
- ++i;
+ if (height[l] < height[r]) {
+ ++l;
} else {
- --j;
+ --r;
}
}
return ans;
@@ -136,14 +138,14 @@ public:
```go
func maxArea(height []int) (ans int) {
- i, j := 0, len(height)-1
- for i < j {
- t := min(height[i], height[j]) * (j - i)
+ l, r := 0, len(height)-1
+ for l < r {
+ t := min(height[l], height[r]) * (r - l)
ans = max(ans, t)
- if height[i] < height[j] {
- i++
+ if height[l] < height[r] {
+ l++
} else {
- j--
+ r--
}
}
return
@@ -154,16 +156,15 @@ func maxArea(height []int) (ans int) {
```ts
function maxArea(height: number[]): number {
- let i = 0;
- let j = height.length - 1;
+ let [l, r] = [0, height.length - 1];
let ans = 0;
- while (i < j) {
- const t = Math.min(height[i], height[j]) * (j - i);
+ while (l < r) {
+ const t = Math.min(height[l], height[r]) * (r - l);
ans = Math.max(ans, t);
- if (height[i] < height[j]) {
- ++i;
+ if (height[l] < height[r]) {
+ ++l;
} else {
- --j;
+ --r;
}
}
return ans;
@@ -175,15 +176,15 @@ function maxArea(height: number[]): number {
```rust
impl Solution {
pub fn max_area(height: Vec) -> i32 {
- let mut i = 0;
- let mut j = height.len() - 1;
+ let mut l = 0;
+ let mut r = height.len() - 1;
let mut ans = 0;
- while i < j {
- ans = ans.max(height[i].min(height[j]) * ((j - i) as i32));
- if height[i] <= height[j] {
- i += 1;
+ while l < r {
+ ans = ans.max(height[l].min(height[r]) * ((r - l) as i32));
+ if height[l] < height[r] {
+ l += 1;
} else {
- j -= 1;
+ r -= 1;
}
}
ans
@@ -199,16 +200,15 @@ impl Solution {
* @return {number}
*/
var maxArea = function (height) {
- let i = 0;
- let j = height.length - 1;
+ let [l, r] = [0, height.length - 1];
let ans = 0;
- while (i < j) {
- const t = Math.min(height[i], height[j]) * (j - i);
+ while (l < r) {
+ const t = Math.min(height[l], height[r]) * (r - l);
ans = Math.max(ans, t);
- if (height[i] < height[j]) {
- ++i;
+ if (height[l] < height[r]) {
+ ++l;
} else {
- --j;
+ --r;
}
}
return ans;
@@ -220,15 +220,15 @@ var maxArea = function (height) {
```cs
public class Solution {
public int MaxArea(int[] height) {
- int i = 0, j = height.Length - 1;
+ int l = 0, r = height.Length - 1;
int ans = 0;
- while (i < j) {
- int t = Math.Min(height[i], height[j]) * (j - i);
+ while (l < r) {
+ int t = Math.Min(height[l], height[r]) * (r - l);
ans = Math.Max(ans, t);
- if (height[i] < height[j]) {
- ++i;
+ if (height[l] < height[r]) {
+ ++l;
} else {
- --j;
+ --r;
}
}
return ans;
@@ -245,16 +245,16 @@ class Solution {
* @return Integer
*/
function maxArea($height) {
- $i = 0;
- $j = count($height) - 1;
+ $l = 0;
+ $r = count($height) - 1;
$ans = 0;
- while ($i < $j) {
- $t = min($height[$i], $height[$j]) * ($j - $i);
+ while ($l < $r) {
+ $t = min($height[$l], $height[$r]) * ($r - $l);
$ans = max($ans, $t);
- if ($height[$i] < $height[$j]) {
- ++$i;
+ if ($height[$l] < $height[$r]) {
+ ++$l;
} else {
- --$j;
+ --$r;
}
}
return $ans;
diff --git a/solution/0000-0099/0011.Container With Most Water/README_EN.md b/solution/0000-0099/0011.Container With Most Water/README_EN.md
index 459c81c5edec6..5d113a38fbc66 100644
--- a/solution/0000-0099/0011.Container With Most Water/README_EN.md
+++ b/solution/0000-0099/0011.Container With Most Water/README_EN.md
@@ -59,13 +59,15 @@ tags:
### Solution 1: Two Pointers
-Initially, we consider the capacity of the water that the two farthest pillars can hold. The width of the water is the distance between the two pillars, and the height of the water depends on the shorter one between the two pillars.
+We use two pointers $l$ and $r$ to point to the left and right ends of the array, respectively, i.e., $l = 0$ and $r = n - 1$, where $n$ is the length of the array.
-The current pillars are the pillars on the farthest sides, so the width of the water is the largest. For other combinations, the width of the water is smaller. Suppose the height of the left pillar is less than or equal to the height of the right pillar, then the height of the water is the height of the left pillar. If we move the right pillar, the width of the water will decrease, but the height of the water will not increase, so the capacity of the water will definitely decrease. Therefore, we move the left pillar and update the maximum capacity.
+Next, we use a variable $\textit{ans}$ to record the maximum capacity of the container, initially set to $0$.
-Repeat this process until the two pillars meet.
+Then, we start a loop. In each iteration, we calculate the current capacity of the container, i.e., $\textit{min}(height[l], height[r]) \times (r - l)$, and compare it with $\textit{ans}$, assigning the larger value to $\textit{ans}$. Then, we compare the values of $height[l]$ and $height[r]$. If $\textit{height}[l] < \textit{height}[r]$, moving the $r$ pointer will not improve the result because the height of the container is determined by the shorter vertical line, so we move the $l$ pointer. Otherwise, we move the $r$ pointer.
-The time complexity is $O(n)$, where $n$ is the length of the array `height`. The space complexity is $O(1)$.
+After the iteration, we return $\textit{ans}$.
+
+The time complexity is $O(n)$, where $n$ is the length of the array $\textit{height}$. The space complexity is $O(1)$.
@@ -74,15 +76,15 @@ The time complexity is $O(n)$, where $n$ is the length of the array `height`. Th
```python
class Solution:
def maxArea(self, height: List[int]) -> int:
- i, j = 0, len(height) - 1
+ l, r = 0, len(height) - 1
ans = 0
- while i < j:
- t = (j - i) * min(height[i], height[j])
+ while l < r:
+ t = min(height[l], height[r]) * (r - l)
ans = max(ans, t)
- if height[i] < height[j]:
- i += 1
+ if height[l] < height[r]:
+ l += 1
else:
- j -= 1
+ r -= 1
return ans
```
@@ -91,15 +93,15 @@ class Solution:
```java
class Solution {
public int maxArea(int[] height) {
- int i = 0, j = height.length - 1;
+ int l = 0, r = height.length - 1;
int ans = 0;
- while (i < j) {
- int t = Math.min(height[i], height[j]) * (j - i);
+ while (l < r) {
+ int t = Math.min(height[l], height[r]) * (r - l);
ans = Math.max(ans, t);
- if (height[i] < height[j]) {
- ++i;
+ if (height[l] < height[r]) {
+ ++l;
} else {
- --j;
+ --r;
}
}
return ans;
@@ -113,15 +115,15 @@ class Solution {
class Solution {
public:
int maxArea(vector& height) {
- int i = 0, j = height.size() - 1;
+ int l = 0, r = height.size() - 1;
int ans = 0;
- while (i < j) {
- int t = min(height[i], height[j]) * (j - i);
+ while (l < r) {
+ int t = min(height[l], height[r]) * (r - l);
ans = max(ans, t);
- if (height[i] < height[j]) {
- ++i;
+ if (height[l] < height[r]) {
+ ++l;
} else {
- --j;
+ --r;
}
}
return ans;
@@ -133,14 +135,14 @@ public:
```go
func maxArea(height []int) (ans int) {
- i, j := 0, len(height)-1
- for i < j {
- t := min(height[i], height[j]) * (j - i)
+ l, r := 0, len(height)-1
+ for l < r {
+ t := min(height[l], height[r]) * (r - l)
ans = max(ans, t)
- if height[i] < height[j] {
- i++
+ if height[l] < height[r] {
+ l++
} else {
- j--
+ r--
}
}
return
@@ -151,16 +153,15 @@ func maxArea(height []int) (ans int) {
```ts
function maxArea(height: number[]): number {
- let i = 0;
- let j = height.length - 1;
+ let [l, r] = [0, height.length - 1];
let ans = 0;
- while (i < j) {
- const t = Math.min(height[i], height[j]) * (j - i);
+ while (l < r) {
+ const t = Math.min(height[l], height[r]) * (r - l);
ans = Math.max(ans, t);
- if (height[i] < height[j]) {
- ++i;
+ if (height[l] < height[r]) {
+ ++l;
} else {
- --j;
+ --r;
}
}
return ans;
@@ -172,15 +173,15 @@ function maxArea(height: number[]): number {
```rust
impl Solution {
pub fn max_area(height: Vec) -> i32 {
- let mut i = 0;
- let mut j = height.len() - 1;
+ let mut l = 0;
+ let mut r = height.len() - 1;
let mut ans = 0;
- while i < j {
- ans = ans.max(height[i].min(height[j]) * ((j - i) as i32));
- if height[i] <= height[j] {
- i += 1;
+ while l < r {
+ ans = ans.max(height[l].min(height[r]) * ((r - l) as i32));
+ if height[l] < height[r] {
+ l += 1;
} else {
- j -= 1;
+ r -= 1;
}
}
ans
@@ -196,16 +197,15 @@ impl Solution {
* @return {number}
*/
var maxArea = function (height) {
- let i = 0;
- let j = height.length - 1;
+ let [l, r] = [0, height.length - 1];
let ans = 0;
- while (i < j) {
- const t = Math.min(height[i], height[j]) * (j - i);
+ while (l < r) {
+ const t = Math.min(height[l], height[r]) * (r - l);
ans = Math.max(ans, t);
- if (height[i] < height[j]) {
- ++i;
+ if (height[l] < height[r]) {
+ ++l;
} else {
- --j;
+ --r;
}
}
return ans;
@@ -217,15 +217,15 @@ var maxArea = function (height) {
```cs
public class Solution {
public int MaxArea(int[] height) {
- int i = 0, j = height.Length - 1;
+ int l = 0, r = height.Length - 1;
int ans = 0;
- while (i < j) {
- int t = Math.Min(height[i], height[j]) * (j - i);
+ while (l < r) {
+ int t = Math.Min(height[l], height[r]) * (r - l);
ans = Math.Max(ans, t);
- if (height[i] < height[j]) {
- ++i;
+ if (height[l] < height[r]) {
+ ++l;
} else {
- --j;
+ --r;
}
}
return ans;
@@ -242,16 +242,16 @@ class Solution {
* @return Integer
*/
function maxArea($height) {
- $i = 0;
- $j = count($height) - 1;
+ $l = 0;
+ $r = count($height) - 1;
$ans = 0;
- while ($i < $j) {
- $t = min($height[$i], $height[$j]) * ($j - $i);
+ while ($l < $r) {
+ $t = min($height[$l], $height[$r]) * ($r - $l);
$ans = max($ans, $t);
- if ($height[$i] < $height[$j]) {
- ++$i;
+ if ($height[$l] < $height[$r]) {
+ ++$l;
} else {
- --$j;
+ --$r;
}
}
return $ans;
diff --git a/solution/0000-0099/0011.Container With Most Water/Solution.cpp b/solution/0000-0099/0011.Container With Most Water/Solution.cpp
index 1a0ca2d84020b..02e6bd38cdaa7 100644
--- a/solution/0000-0099/0011.Container With Most Water/Solution.cpp
+++ b/solution/0000-0099/0011.Container With Most Water/Solution.cpp
@@ -1,17 +1,17 @@
class Solution {
public:
int maxArea(vector& height) {
- int i = 0, j = height.size() - 1;
+ int l = 0, r = height.size() - 1;
int ans = 0;
- while (i < j) {
- int t = min(height[i], height[j]) * (j - i);
+ while (l < r) {
+ int t = min(height[l], height[r]) * (r - l);
ans = max(ans, t);
- if (height[i] < height[j]) {
- ++i;
+ if (height[l] < height[r]) {
+ ++l;
} else {
- --j;
+ --r;
}
}
return ans;
}
-};
\ No newline at end of file
+};
diff --git a/solution/0000-0099/0011.Container With Most Water/Solution.cs b/solution/0000-0099/0011.Container With Most Water/Solution.cs
index 41f36b567786c..28251ddf2eb64 100644
--- a/solution/0000-0099/0011.Container With Most Water/Solution.cs
+++ b/solution/0000-0099/0011.Container With Most Water/Solution.cs
@@ -1,14 +1,14 @@
public class Solution {
public int MaxArea(int[] height) {
- int i = 0, j = height.Length - 1;
+ int l = 0, r = height.Length - 1;
int ans = 0;
- while (i < j) {
- int t = Math.Min(height[i], height[j]) * (j - i);
+ while (l < r) {
+ int t = Math.Min(height[l], height[r]) * (r - l);
ans = Math.Max(ans, t);
- if (height[i] < height[j]) {
- ++i;
+ if (height[l] < height[r]) {
+ ++l;
} else {
- --j;
+ --r;
}
}
return ans;
diff --git a/solution/0000-0099/0011.Container With Most Water/Solution.go b/solution/0000-0099/0011.Container With Most Water/Solution.go
index 11e6a37ffd337..c9a452ceb836a 100644
--- a/solution/0000-0099/0011.Container With Most Water/Solution.go
+++ b/solution/0000-0099/0011.Container With Most Water/Solution.go
@@ -1,13 +1,13 @@
func maxArea(height []int) (ans int) {
- i, j := 0, len(height)-1
- for i < j {
- t := min(height[i], height[j]) * (j - i)
+ l, r := 0, len(height)-1
+ for l < r {
+ t := min(height[l], height[r]) * (r - l)
ans = max(ans, t)
- if height[i] < height[j] {
- i++
+ if height[l] < height[r] {
+ l++
} else {
- j--
+ r--
}
}
return
-}
\ No newline at end of file
+}
diff --git a/solution/0000-0099/0011.Container With Most Water/Solution.java b/solution/0000-0099/0011.Container With Most Water/Solution.java
index 2684fefbfc466..215662673046f 100644
--- a/solution/0000-0099/0011.Container With Most Water/Solution.java
+++ b/solution/0000-0099/0011.Container With Most Water/Solution.java
@@ -1,16 +1,16 @@
class Solution {
public int maxArea(int[] height) {
- int i = 0, j = height.length - 1;
+ int l = 0, r = height.length - 1;
int ans = 0;
- while (i < j) {
- int t = Math.min(height[i], height[j]) * (j - i);
+ while (l < r) {
+ int t = Math.min(height[l], height[r]) * (r - l);
ans = Math.max(ans, t);
- if (height[i] < height[j]) {
- ++i;
+ if (height[l] < height[r]) {
+ ++l;
} else {
- --j;
+ --r;
}
}
return ans;
}
-}
\ No newline at end of file
+}
diff --git a/solution/0000-0099/0011.Container With Most Water/Solution.js b/solution/0000-0099/0011.Container With Most Water/Solution.js
index e250df9c33aee..afb2892f56d70 100644
--- a/solution/0000-0099/0011.Container With Most Water/Solution.js
+++ b/solution/0000-0099/0011.Container With Most Water/Solution.js
@@ -3,16 +3,15 @@
* @return {number}
*/
var maxArea = function (height) {
- let i = 0;
- let j = height.length - 1;
+ let [l, r] = [0, height.length - 1];
let ans = 0;
- while (i < j) {
- const t = Math.min(height[i], height[j]) * (j - i);
+ while (l < r) {
+ const t = Math.min(height[l], height[r]) * (r - l);
ans = Math.max(ans, t);
- if (height[i] < height[j]) {
- ++i;
+ if (height[l] < height[r]) {
+ ++l;
} else {
- --j;
+ --r;
}
}
return ans;
diff --git a/solution/0000-0099/0011.Container With Most Water/Solution.php b/solution/0000-0099/0011.Container With Most Water/Solution.php
index 604a65fff5213..857a27d7ebce8 100644
--- a/solution/0000-0099/0011.Container With Most Water/Solution.php
+++ b/solution/0000-0099/0011.Container With Most Water/Solution.php
@@ -4,18 +4,18 @@ class Solution {
* @return Integer
*/
function maxArea($height) {
- $i = 0;
- $j = count($height) - 1;
+ $l = 0;
+ $r = count($height) - 1;
$ans = 0;
- while ($i < $j) {
- $t = min($height[$i], $height[$j]) * ($j - $i);
+ while ($l < $r) {
+ $t = min($height[$l], $height[$r]) * ($r - $l);
$ans = max($ans, $t);
- if ($height[$i] < $height[$j]) {
- ++$i;
+ if ($height[$l] < $height[$r]) {
+ ++$l;
} else {
- --$j;
+ --$r;
}
}
return $ans;
}
-}
\ No newline at end of file
+}
diff --git a/solution/0000-0099/0011.Container With Most Water/Solution.py b/solution/0000-0099/0011.Container With Most Water/Solution.py
index becf251509aaf..eb43c7d241ae2 100644
--- a/solution/0000-0099/0011.Container With Most Water/Solution.py
+++ b/solution/0000-0099/0011.Container With Most Water/Solution.py
@@ -1,12 +1,12 @@
class Solution:
def maxArea(self, height: List[int]) -> int:
- i, j = 0, len(height) - 1
+ l, r = 0, len(height) - 1
ans = 0
- while i < j:
- t = (j - i) * min(height[i], height[j])
+ while l < r:
+ t = min(height[l], height[r]) * (r - l)
ans = max(ans, t)
- if height[i] < height[j]:
- i += 1
+ if height[l] < height[r]:
+ l += 1
else:
- j -= 1
+ r -= 1
return ans
diff --git a/solution/0000-0099/0011.Container With Most Water/Solution.rs b/solution/0000-0099/0011.Container With Most Water/Solution.rs
index b099e438e842e..1691c18a67b3f 100644
--- a/solution/0000-0099/0011.Container With Most Water/Solution.rs
+++ b/solution/0000-0099/0011.Container With Most Water/Solution.rs
@@ -1,14 +1,14 @@
impl Solution {
pub fn max_area(height: Vec) -> i32 {
- let mut i = 0;
- let mut j = height.len() - 1;
+ let mut l = 0;
+ let mut r = height.len() - 1;
let mut ans = 0;
- while i < j {
- ans = ans.max(height[i].min(height[j]) * ((j - i) as i32));
- if height[i] <= height[j] {
- i += 1;
+ while l < r {
+ ans = ans.max(height[l].min(height[r]) * ((r - l) as i32));
+ if height[l] < height[r] {
+ l += 1;
} else {
- j -= 1;
+ r -= 1;
}
}
ans
diff --git a/solution/0000-0099/0011.Container With Most Water/Solution.ts b/solution/0000-0099/0011.Container With Most Water/Solution.ts
index 69299730973b5..8c3b332b45b83 100644
--- a/solution/0000-0099/0011.Container With Most Water/Solution.ts
+++ b/solution/0000-0099/0011.Container With Most Water/Solution.ts
@@ -1,14 +1,13 @@
function maxArea(height: number[]): number {
- let i = 0;
- let j = height.length - 1;
+ let [l, r] = [0, height.length - 1];
let ans = 0;
- while (i < j) {
- const t = Math.min(height[i], height[j]) * (j - i);
+ while (l < r) {
+ const t = Math.min(height[l], height[r]) * (r - l);
ans = Math.max(ans, t);
- if (height[i] < height[j]) {
- ++i;
+ if (height[l] < height[r]) {
+ ++l;
} else {
- --j;
+ --r;
}
}
return ans;
diff --git a/solution/0000-0099/0014.Longest Common Prefix/README.md b/solution/0000-0099/0014.Longest Common Prefix/README.md
index 94c9bfbe90b0e..5f3529f01eb2c 100644
--- a/solution/0000-0099/0014.Longest Common Prefix/README.md
+++ b/solution/0000-0099/0014.Longest Common Prefix/README.md
@@ -44,7 +44,7 @@ tags:
1 <= strs.length <= 200
0 <= strs[i].length <= 200
-
strs[i] 仅由小写英文字母组成
+
strs[i] 如果非空,则仅由小写英文字母组成
diff --git a/solution/0000-0099/0014.Longest Common Prefix/README_EN.md b/solution/0000-0099/0014.Longest Common Prefix/README_EN.md
index 78d633afe5956..32b3183c65f1b 100644
--- a/solution/0000-0099/0014.Longest Common Prefix/README_EN.md
+++ b/solution/0000-0099/0014.Longest Common Prefix/README_EN.md
@@ -43,7 +43,7 @@ tags:
1 <= strs.length <= 200
0 <= strs[i].length <= 200
-
strs[i] consists of only lowercase English letters.
+
strs[i] consists of only lowercase English letters if it is non-empty.
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 310c885f7de9a..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
@@ -278,6 +278,38 @@ var removeNthFromEnd = function (head, n) {
};
```
+#### Swift
+
+```swift
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public var val: Int
+ * public var next: ListNode?
+ * public init() { self.val = 0; self.next = nil; }
+ * public init(_ val: Int) { self.val = val; self.next = nil; }
+ * public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
+ * }
+ */
+class Solution {
+ func removeNthFromEnd(_ head: ListNode?, _ n: Int) -> ListNode? {
+ let dummy = ListNode(0)
+ dummy.next = head
+ var fast: ListNode? = dummy
+ var slow: ListNode? = dummy
+ for _ in 0.. 0) {
+ fast = fast.next;
+ }
+ while (fast.next != null) {
+ slow = slow.next;
+ fast = fast.next;
+ }
+ slow.next = slow.next.next;
+ return dummy.next;
+ }
+}
+```
-# public function __construct($val = 0, $next = null)
-# {
-# $this->val = $val;
-# $this->next = $next;
-# }
-# }
+#### 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 $head
- * @param int $n
+ * @param Integer $n
* @return ListNode
*/
-
function removeNthFromEnd($head, $n) {
- $dummy = new ListNode(0);
- $dummy->next = $head;
-
- $first = $dummy;
- $second = $dummy;
-
- for ($i = 0; $i <= $n; $i++) {
- $second = $second->next;
+ $dummy = new ListNode(0, $head);
+ $fast = $slow = $dummy;
+ for ($i = 0; $i < $n; $i++) {
+ $fast = $fast->next;
}
-
- while ($second != null) {
- $first = $first->next;
- $second = $second->next;
+ while ($fast->next !== null) {
+ $fast = $fast->next;
+ $slow = $slow->next;
}
-
- $first->next = $first->next->next;
-
+ $slow->next = $slow->next->next;
return $dummy->next;
}
}
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 c2e89d64db00c..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
@@ -275,6 +275,38 @@ var removeNthFromEnd = function (head, n) {
};
```
+#### Swift
+
+```swift
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public var val: Int
+ * public var next: ListNode?
+ * public init() { self.val = 0; self.next = nil; }
+ * public init(_ val: Int) { self.val = val; self.next = nil; }
+ * public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
+ * }
+ */
+class Solution {
+ func removeNthFromEnd(_ head: ListNode?, _ n: Int) -> ListNode? {
+ let dummy = ListNode(0)
+ dummy.next = head
+ var fast: ListNode? = dummy
+ var slow: ListNode? = dummy
+ for _ in 0.. 0) {
+ fast = fast.next;
+ }
+ while (fast.next != null) {
+ slow = slow.next;
+ fast = fast.next;
+ }
+ slow.next = slow.next.next;
+ return dummy.next;
+ }
+}
+```
-# public function __construct($val = 0, $next = null)
-# {
-# $this->val = $val;
-# $this->next = $next;
-# }
-# }
+#### 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 $head
- * @param int $n
+ * @param Integer $n
* @return ListNode
*/
-
function removeNthFromEnd($head, $n) {
- $dummy = new ListNode(0);
- $dummy->next = $head;
-
- $first = $dummy;
- $second = $dummy;
-
- for ($i = 0; $i <= $n; $i++) {
- $second = $second->next;
+ $dummy = new ListNode(0, $head);
+ $fast = $slow = $dummy;
+ for ($i = 0; $i < $n; $i++) {
+ $fast = $fast->next;
}
-
- while ($second != null) {
- $first = $first->next;
- $second = $second->next;
+ while ($fast->next !== null) {
+ $fast = $fast->next;
+ $slow = $slow->next;
}
-
- $first->next = $first->next->next;
-
+ $slow->next = $slow->next->next;
return $dummy->next;
}
}
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/0019.Remove Nth Node From End of List/Solution.php b/solution/0000-0099/0019.Remove Nth Node From End of List/Solution.php
index a03530a2304f4..004a0f484e7ad 100644
--- a/solution/0000-0099/0019.Remove Nth Node From End of List/Solution.php
+++ b/solution/0000-0099/0019.Remove Nth Node From End of List/Solution.php
@@ -1,40 +1,31 @@
-# 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 $head
- * @param int $n
+ * @param Integer $n
* @return ListNode
*/
-
function removeNthFromEnd($head, $n) {
- $dummy = new ListNode(0);
- $dummy->next = $head;
-
- $first = $dummy;
- $second = $dummy;
-
- for ($i = 0; $i <= $n; $i++) {
- $second = $second->next;
+ $dummy = new ListNode(0, $head);
+ $fast = $slow = $dummy;
+ for ($i = 0; $i < $n; $i++) {
+ $fast = $fast->next;
}
-
- while ($second != null) {
- $first = $first->next;
- $second = $second->next;
+ while ($fast->next !== null) {
+ $fast = $fast->next;
+ $slow = $slow->next;
}
-
- $first->next = $first->next->next;
-
+ $slow->next = $slow->next->next;
return $dummy->next;
}
}
diff --git a/solution/0000-0099/0019.Remove Nth Node From End of List/Solution.swift b/solution/0000-0099/0019.Remove Nth Node From End of List/Solution.swift
new file mode 100644
index 0000000000000..310d4aa25aa78
--- /dev/null
+++ b/solution/0000-0099/0019.Remove Nth Node From End of List/Solution.swift
@@ -0,0 +1,27 @@
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public var val: Int
+ * public var next: ListNode?
+ * public init() { self.val = 0; self.next = nil; }
+ * public init(_ val: Int) { self.val = val; self.next = nil; }
+ * public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
+ * }
+ */
+class Solution {
+ func removeNthFromEnd(_ head: ListNode?, _ n: Int) -> ListNode? {
+ let dummy = ListNode(0)
+ dummy.next = head
+ var fast: ListNode? = dummy
+ var slow: ListNode? = dummy
+ for _ in 0..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/0023.Merge k Sorted Lists/README.md b/solution/0000-0099/0023.Merge k Sorted Lists/README.md
index c07f16ad90222..d06143c55db86 100644
--- a/solution/0000-0099/0023.Merge k Sorted Lists/README.md
+++ b/solution/0000-0099/0023.Merge k Sorted Lists/README.md
@@ -232,11 +232,7 @@ func (h *hp) Pop() any { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1];
function mergeKLists(lists: Array): ListNode | null {
const pq = new MinPriorityQueue({ priority: (node: ListNode) => node.val });
- for (const head of lists) {
- if (head) {
- pq.enqueue(head);
- }
- }
+ lists.filter(head => head).forEach(head => pq.enqueue(head));
const dummy: ListNode = new ListNode();
let cur: ListNode = dummy;
while (!pq.isEmpty()) {
@@ -318,11 +314,7 @@ impl Solution {
*/
var mergeKLists = function (lists) {
const pq = new MinPriorityQueue({ priority: node => node.val });
- for (const head of lists) {
- if (head) {
- pq.enqueue(head);
- }
- }
+ lists.filter(head => head).forEach(head => pq.enqueue(head));
const dummy = new ListNode();
let cur = dummy;
while (!pq.isEmpty()) {
diff --git a/solution/0000-0099/0023.Merge k Sorted Lists/README_EN.md b/solution/0000-0099/0023.Merge k Sorted Lists/README_EN.md
index c202848462f5a..e7e07e00330c5 100644
--- a/solution/0000-0099/0023.Merge k Sorted Lists/README_EN.md
+++ b/solution/0000-0099/0023.Merge k Sorted Lists/README_EN.md
@@ -233,11 +233,7 @@ func (h *hp) Pop() any { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1];
function mergeKLists(lists: Array): ListNode | null {
const pq = new MinPriorityQueue({ priority: (node: ListNode) => node.val });
- for (const head of lists) {
- if (head) {
- pq.enqueue(head);
- }
- }
+ lists.filter(head => head).forEach(head => pq.enqueue(head));
const dummy: ListNode = new ListNode();
let cur: ListNode = dummy;
while (!pq.isEmpty()) {
@@ -319,11 +315,7 @@ impl Solution {
*/
var mergeKLists = function (lists) {
const pq = new MinPriorityQueue({ priority: node => node.val });
- for (const head of lists) {
- if (head) {
- pq.enqueue(head);
- }
- }
+ lists.filter(head => head).forEach(head => pq.enqueue(head));
const dummy = new ListNode();
let cur = dummy;
while (!pq.isEmpty()) {
diff --git a/solution/0000-0099/0023.Merge k Sorted Lists/Solution.js b/solution/0000-0099/0023.Merge k Sorted Lists/Solution.js
index d6f1c7d4451db..d08377efe3a0b 100644
--- a/solution/0000-0099/0023.Merge k Sorted Lists/Solution.js
+++ b/solution/0000-0099/0023.Merge k Sorted Lists/Solution.js
@@ -11,11 +11,7 @@
*/
var mergeKLists = function (lists) {
const pq = new MinPriorityQueue({ priority: node => node.val });
- for (const head of lists) {
- if (head) {
- pq.enqueue(head);
- }
- }
+ lists.filter(head => head).forEach(head => pq.enqueue(head));
const dummy = new ListNode();
let cur = dummy;
while (!pq.isEmpty()) {
diff --git a/solution/0000-0099/0023.Merge k Sorted Lists/Solution.ts b/solution/0000-0099/0023.Merge k Sorted Lists/Solution.ts
index cf5c2a4ae41d8..cf00ff0f98869 100644
--- a/solution/0000-0099/0023.Merge k Sorted Lists/Solution.ts
+++ b/solution/0000-0099/0023.Merge k Sorted Lists/Solution.ts
@@ -12,11 +12,7 @@
function mergeKLists(lists: Array): ListNode | null {
const pq = new MinPriorityQueue({ priority: (node: ListNode) => node.val });
- for (const head of lists) {
- if (head) {
- pq.enqueue(head);
- }
- }
+ lists.filter(head => head).forEach(head => pq.enqueue(head));
const dummy: ListNode = new ListNode();
let cur: ListNode = dummy;
while (!pq.isEmpty()) {
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/0025.Reverse Nodes in k-Group/README.md b/solution/0000-0099/0025.Reverse Nodes in k-Group/README.md
index fcdc139163f01..e407ae48a1c8a 100644
--- a/solution/0000-0099/0025.Reverse Nodes in k-Group/README.md
+++ b/solution/0000-0099/0025.Reverse Nodes in k-Group/README.md
@@ -63,9 +63,15 @@ tags:
-### 方法一:迭代
+### 方法一:模拟
-时间复杂度为 $O(n)$,空间复杂度为 $O(1)$,其中 $n$ 是链表的长度。
+我们可以根据题意,模拟整个翻转的过程。
+
+首先,我们定义一个辅助函数 $\textit{reverse}$,用于翻转一个链表。然后,我们定义一个虚拟头结点 $\textit{dummy}$,并将其 $\textit{next}$ 指针指向 $\textit{head}$。
+
+接着,我们遍历链表,每次遍历 $k$ 个节点,若剩余节点不足 $k$ 个,则不进行翻转。否则,我们将 $k$ 个节点取出,然后调用 $\textit{reverse}$ 函数翻转这 $k$ 个节点。然后将翻转后的链表与原链表连接起来。继续遍历下一个 $k$ 个节点,直到遍历完整个链表。
+
+时间复杂度 $O(n)$,其中 $n$ 为链表的长度。空间复杂度 $O(1)$。
@@ -78,30 +84,30 @@ tags:
# self.val = val
# self.next = next
class Solution:
- def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
- def reverseList(head):
- pre, p = None, head
- while p:
- q = p.next
- p.next = pre
- pre = p
- p = q
- return pre
-
- dummy = ListNode(next=head)
- pre = cur = dummy
- while cur.next:
+ def reverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
+ def reverse(head: Optional[ListNode]) -> Optional[ListNode]:
+ dummy = ListNode()
+ cur = head
+ while cur:
+ nxt = cur.next
+ cur.next = dummy.next
+ dummy.next = cur
+ cur = nxt
+ return dummy.next
+
+ dummy = pre = ListNode(next=head)
+ while pre:
+ cur = pre
for _ in range(k):
cur = cur.next
if cur is None:
return dummy.next
- t = cur.next
+ node = pre.next
+ nxt = cur.next
cur.next = None
- start = pre.next
- pre.next = reverseList(start)
- start.next = t
- pre = start
- cur = pre
+ pre.next = reverse(node)
+ node.next = nxt
+ pre = node
return dummy.next
```
@@ -121,34 +127,36 @@ class Solution:
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
ListNode dummy = new ListNode(0, head);
- ListNode pre = dummy, cur = dummy;
- while (cur.next != null) {
- for (int i = 0; i < k && cur != null; ++i) {
+ dummy.next = head;
+ ListNode pre = dummy;
+ while (pre != null) {
+ ListNode cur = pre;
+ for (int i = 0; i < k; i++) {
cur = cur.next;
+ if (cur == null) {
+ return dummy.next;
+ }
}
- if (cur == null) {
- return dummy.next;
- }
- ListNode t = cur.next;
+ ListNode node = pre.next;
+ ListNode nxt = cur.next;
cur.next = null;
- ListNode start = pre.next;
- pre.next = reverseList(start);
- start.next = t;
- pre = start;
- cur = pre;
+ pre.next = reverse(node);
+ node.next = nxt;
+ pre = node;
}
return dummy.next;
}
- private ListNode reverseList(ListNode head) {
- ListNode pre = null, p = head;
- while (p != null) {
- ListNode q = p.next;
- p.next = pre;
- pre = p;
- p = q;
+ private ListNode reverse(ListNode head) {
+ ListNode dummy = new ListNode();
+ ListNode cur = head;
+ while (cur != null) {
+ ListNode nxt = cur.next;
+ cur.next = dummy.next;
+ dummy.next = cur;
+ cur = nxt;
}
- return pre;
+ return dummy.next;
}
}
```
@@ -164,30 +172,38 @@ class Solution {
* }
*/
func reverseKGroup(head *ListNode, k int) *ListNode {
- var dummy *ListNode = &ListNode{}
- p, cur := dummy, head
- for cur != nil {
- start := cur
+ dummy := &ListNode{Next: head}
+ pre := dummy
+
+ for pre != nil {
+ cur := pre
for i := 0; i < k; i++ {
+ cur = cur.Next
if cur == nil {
- p.Next = start
return dummy.Next
}
- cur = cur.Next
}
- p.Next, p = reverse(start, cur), start
+
+ node := pre.Next
+ nxt := cur.Next
+ cur.Next = nil
+ pre.Next = reverse(node)
+ node.Next = nxt
+ pre = node
}
return dummy.Next
}
-func reverse(start, end *ListNode) *ListNode {
- var pre *ListNode = nil
- for start != end {
- tmp := start.Next
- start.Next, pre = pre, start
- start = tmp
+func reverse(head *ListNode) *ListNode {
+ var dummy *ListNode
+ cur := head
+ for cur != nil {
+ nxt := cur.Next
+ cur.Next = dummy
+ dummy = cur
+ cur = nxt
}
- return pre
+ return dummy
}
```
@@ -207,40 +223,40 @@ func reverse(start, end *ListNode) *ListNode {
*/
function reverseKGroup(head: ListNode | null, k: number): ListNode | null {
- let dummy = new ListNode(0, head);
+ const dummy = new ListNode(0, head);
let pre = dummy;
- // pre->head-> ... ->tail-> next
- while (head != null) {
- let tail = pre;
- for (let i = 0; i < k; ++i) {
- tail = tail.next;
- if (tail == null) {
+ while (pre !== null) {
+ let cur: ListNode | null = pre;
+ for (let i = 0; i < k; i++) {
+ cur = cur?.next || null;
+ if (cur === null) {
return dummy.next;
}
}
- let t = tail.next;
- [head, tail] = reverse(head, tail);
- // set next
- pre.next = head;
- tail.next = t;
- // set new pre and new head
- pre = tail;
- head = t;
+
+ const node = pre.next;
+ const nxt = cur?.next || null;
+ cur!.next = null;
+ pre.next = reverse(node);
+ node!.next = nxt;
+ pre = node!;
}
+
return dummy.next;
}
-function reverse(head: ListNode, tail: ListNode) {
+function reverse(head: ListNode | null): ListNode | null {
+ let dummy: ListNode | null = null;
let cur = head;
- let pre = tail.next;
- // head -> next -> ... -> tail -> pre
- while (pre != tail) {
- let t = cur.next;
- cur.next = pre;
- pre = cur;
- cur = t;
+
+ while (cur !== null) {
+ const nxt = cur.next;
+ cur.next = dummy;
+ dummy = cur;
+ cur = nxt;
}
- return [tail, head];
+
+ return dummy;
}
```
@@ -312,7 +328,7 @@ impl Solution {
* public class ListNode {
* public int val;
* public ListNode next;
- * public ListNode(int val=0, ListNode next=null) {
+ * public ListNode(int val = 0, ListNode next = null) {
* this.val = val;
* this.next = next;
* }
@@ -320,39 +336,40 @@ impl Solution {
*/
public class Solution {
public ListNode ReverseKGroup(ListNode head, int k) {
- ListNode dummy = new ListNode(0, head);
- ListNode pre = dummy, cur = dummy;
- while (cur.next != null)
- {
- for (int i = 0; i < k && cur != null; ++i)
- {
+ var dummy = new ListNode(0);
+ dummy.next = head;
+ var pre = dummy;
+
+ while (pre != null) {
+ var cur = pre;
+ for (int i = 0; i < k; i++) {
+ if (cur.next == null) {
+ return dummy.next;
+ }
cur = cur.next;
}
- if (cur == null)
- {
- return dummy.next;
- }
- ListNode t = cur.next;
+
+ var node = pre.next;
+ var nxt = cur.next;
cur.next = null;
- ListNode start = pre.next;
- pre.next = ReverseList(start);
- start.next = t;
- pre = start;
- cur = pre;
+ pre.next = Reverse(node);
+ node.next = nxt;
+ pre = node;
}
+
return dummy.next;
}
- private ListNode ReverseList(ListNode head) {
- ListNode pre = null, p = head;
- while (p != null)
- {
- ListNode q = p.next;
- p.next = pre;
- pre = p;
- p = q;
+ private ListNode Reverse(ListNode head) {
+ ListNode prev = null;
+ var cur = head;
+ while (cur != null) {
+ var nxt = cur.next;
+ cur.next = prev;
+ prev = cur;
+ cur = nxt;
}
- return pre;
+ return prev;
}
}
```
@@ -360,153 +377,64 @@ public class Solution {
#### PHP
```php
-# 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 $head
- * @param int $k
+ * @param Integer $k
* @return ListNode
*/
-
function reverseKGroup($head, $k) {
$dummy = new ListNode(0);
$dummy->next = $head;
- $prevGroupTail = $dummy;
-
- while ($head !== null) {
- $count = 0;
- $groupHead = $head;
- $groupTail = $head;
-
- while ($count < $k && $head !== null) {
- $head = $head->next;
- $count++;
- }
- if ($count < $k) {
- $prevGroupTail->next = $groupHead;
- break;
- }
+ $pre = $dummy;
- $prev = null;
+ while ($pre !== null) {
+ $cur = $pre;
for ($i = 0; $i < $k; $i++) {
- $next = $groupHead->next;
- $groupHead->next = $prev;
- $prev = $groupHead;
- $groupHead = $next;
+ if ($cur->next === null) {
+ return $dummy->next;
+ }
+ $cur = $cur->next;
}
- $prevGroupTail->next = $prev;
- $prevGroupTail = $groupTail;
+
+ $node = $pre->next;
+ $nxt = $cur->next;
+ $cur->next = null;
+ $pre->next = $this->reverse($node);
+ $node->next = $nxt;
+ $pre = $node;
}
return $dummy->next;
}
-}
-```
-
-
-
-
-
-
-### 方法二:递归
-
-时间复杂度为 $O(n)$,空间复杂度为 $O(\log _k n)$,其中 $n$ 是链表的长度。
-
-
-
-#### Go
-
-```go
-/**
- * Definition for singly-linked list.
- * type ListNode struct {
- * Val int
- * Next *ListNode
- * }
- */
-func reverseKGroup(head *ListNode, k int) *ListNode {
- start, end := head, head
- for i := 0; i < k; i++ {
- if end == nil {
- return head
- }
- end = end.Next
- }
- res := reverse(start, end)
- start.Next = reverseKGroup(end, k)
- return res
-}
-
-func reverse(start, end *ListNode) *ListNode {
- var pre *ListNode = nil
- for start != end {
- tmp := start.Next
- start.Next, pre = pre, start
- start = tmp
- }
- return pre
-}
-```
-
-#### TypeScript
-
-```ts
-/**
- * Definition for singly-linked list.
- * class ListNode {
- * val: number
- * next: ListNode | null
- * constructor(val?: number, next?: ListNode | null) {
- * this.val = (val===undefined ? 0 : val)
- * this.next = (next===undefined ? null : next)
- * }
- * }
- */
-
-function reverseKGroup(head: ListNode | null, k: number): ListNode | null {
- if (k === 1) {
- return head;
- }
-
- const dummy = new ListNode(0, head);
- let root = dummy;
- while (root != null) {
- let pre = root;
- let cur = root;
-
- let count = 0;
- while (count !== k) {
- count++;
- cur = cur.next;
- if (cur == null) {
- return dummy.next;
- }
- }
-
- const nextRoot = pre.next;
- pre.next = cur;
-
- let node = nextRoot;
- let next = node.next;
- node.next = cur.next;
- while (node != cur) {
- [next.next, node, next] = [node, next, next.next];
+ /**
+ * Helper function to reverse a linked list.
+ * @param ListNode $head
+ * @return ListNode
+ */
+ function reverse($head) {
+ $prev = null;
+ $cur = $head;
+ while ($cur !== null) {
+ $nxt = $cur->next;
+ $cur->next = $prev;
+ $prev = $cur;
+ $cur = $nxt;
}
- root = nextRoot;
+ return $prev;
}
-
- return dummy.next;
}
```
diff --git a/solution/0000-0099/0025.Reverse Nodes in k-Group/README_EN.md b/solution/0000-0099/0025.Reverse Nodes in k-Group/README_EN.md
index 30abf3f03033f..33b5fafc1671d 100644
--- a/solution/0000-0099/0025.Reverse Nodes in k-Group/README_EN.md
+++ b/solution/0000-0099/0025.Reverse Nodes in k-Group/README_EN.md
@@ -56,9 +56,15 @@ tags:
-### Solution 1: Iteration
+### Solution 1: Simulation
-The time complexity is $O(n)$, and the space complexity is $O(1)$. Here, $n$ is the length of the linked list.
+We can simulate the entire reversal process according to the problem description.
+
+First, we define a helper function $\textit{reverse}$ to reverse a linked list. Then, we define a dummy head node $\textit{dummy}$ and set its $\textit{next}$ pointer to $\textit{head}$.
+
+Next, we traverse the linked list, processing $k$ nodes at a time. If the remaining nodes are fewer than $k$, we do not perform the reversal. Otherwise, we extract $k$ nodes and call the $\textit{reverse}$ function to reverse these $k$ nodes. Then, we connect the reversed linked list back to the original linked list. We continue to process the next $k$ nodes until the entire linked list is traversed.
+
+The time complexity is $O(n)$, where $n$ is the length of the linked list. The space complexity is $O(1)$.
@@ -71,30 +77,30 @@ The time complexity is $O(n)$, and the space complexity is $O(1)$. Here, $n$ is
# self.val = val
# self.next = next
class Solution:
- def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
- def reverseList(head):
- pre, p = None, head
- while p:
- q = p.next
- p.next = pre
- pre = p
- p = q
- return pre
-
- dummy = ListNode(next=head)
- pre = cur = dummy
- while cur.next:
+ def reverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
+ def reverse(head: Optional[ListNode]) -> Optional[ListNode]:
+ dummy = ListNode()
+ cur = head
+ while cur:
+ nxt = cur.next
+ cur.next = dummy.next
+ dummy.next = cur
+ cur = nxt
+ return dummy.next
+
+ dummy = pre = ListNode(next=head)
+ while pre:
+ cur = pre
for _ in range(k):
cur = cur.next
if cur is None:
return dummy.next
- t = cur.next
+ node = pre.next
+ nxt = cur.next
cur.next = None
- start = pre.next
- pre.next = reverseList(start)
- start.next = t
- pre = start
- cur = pre
+ pre.next = reverse(node)
+ node.next = nxt
+ pre = node
return dummy.next
```
@@ -114,34 +120,36 @@ class Solution:
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
ListNode dummy = new ListNode(0, head);
- ListNode pre = dummy, cur = dummy;
- while (cur.next != null) {
- for (int i = 0; i < k && cur != null; ++i) {
+ dummy.next = head;
+ ListNode pre = dummy;
+ while (pre != null) {
+ ListNode cur = pre;
+ for (int i = 0; i < k; i++) {
cur = cur.next;
+ if (cur == null) {
+ return dummy.next;
+ }
}
- if (cur == null) {
- return dummy.next;
- }
- ListNode t = cur.next;
+ ListNode node = pre.next;
+ ListNode nxt = cur.next;
cur.next = null;
- ListNode start = pre.next;
- pre.next = reverseList(start);
- start.next = t;
- pre = start;
- cur = pre;
+ pre.next = reverse(node);
+ node.next = nxt;
+ pre = node;
}
return dummy.next;
}
- private ListNode reverseList(ListNode head) {
- ListNode pre = null, p = head;
- while (p != null) {
- ListNode q = p.next;
- p.next = pre;
- pre = p;
- p = q;
+ private ListNode reverse(ListNode head) {
+ ListNode dummy = new ListNode();
+ ListNode cur = head;
+ while (cur != null) {
+ ListNode nxt = cur.next;
+ cur.next = dummy.next;
+ dummy.next = cur;
+ cur = nxt;
}
- return pre;
+ return dummy.next;
}
}
```
@@ -157,30 +165,38 @@ class Solution {
* }
*/
func reverseKGroup(head *ListNode, k int) *ListNode {
- var dummy *ListNode = &ListNode{}
- p, cur := dummy, head
- for cur != nil {
- start := cur
+ dummy := &ListNode{Next: head}
+ pre := dummy
+
+ for pre != nil {
+ cur := pre
for i := 0; i < k; i++ {
+ cur = cur.Next
if cur == nil {
- p.Next = start
return dummy.Next
}
- cur = cur.Next
}
- p.Next, p = reverse(start, cur), start
+
+ node := pre.Next
+ nxt := cur.Next
+ cur.Next = nil
+ pre.Next = reverse(node)
+ node.Next = nxt
+ pre = node
}
return dummy.Next
}
-func reverse(start, end *ListNode) *ListNode {
- var pre *ListNode = nil
- for start != end {
- tmp := start.Next
- start.Next, pre = pre, start
- start = tmp
+func reverse(head *ListNode) *ListNode {
+ var dummy *ListNode
+ cur := head
+ for cur != nil {
+ nxt := cur.Next
+ cur.Next = dummy
+ dummy = cur
+ cur = nxt
}
- return pre
+ return dummy
}
```
@@ -200,40 +216,40 @@ func reverse(start, end *ListNode) *ListNode {
*/
function reverseKGroup(head: ListNode | null, k: number): ListNode | null {
- let dummy = new ListNode(0, head);
+ const dummy = new ListNode(0, head);
let pre = dummy;
- // pre->head-> ... ->tail-> next
- while (head != null) {
- let tail = pre;
- for (let i = 0; i < k; ++i) {
- tail = tail.next;
- if (tail == null) {
+ while (pre !== null) {
+ let cur: ListNode | null = pre;
+ for (let i = 0; i < k; i++) {
+ cur = cur?.next || null;
+ if (cur === null) {
return dummy.next;
}
}
- let t = tail.next;
- [head, tail] = reverse(head, tail);
- // set next
- pre.next = head;
- tail.next = t;
- // set new pre and new head
- pre = tail;
- head = t;
+
+ const node = pre.next;
+ const nxt = cur?.next || null;
+ cur!.next = null;
+ pre.next = reverse(node);
+ node!.next = nxt;
+ pre = node!;
}
+
return dummy.next;
}
-function reverse(head: ListNode, tail: ListNode) {
+function reverse(head: ListNode | null): ListNode | null {
+ let dummy: ListNode | null = null;
let cur = head;
- let pre = tail.next;
- // head -> next -> ... -> tail -> pre
- while (pre != tail) {
- let t = cur.next;
- cur.next = pre;
- pre = cur;
- cur = t;
+
+ while (cur !== null) {
+ const nxt = cur.next;
+ cur.next = dummy;
+ dummy = cur;
+ cur = nxt;
}
- return [tail, head];
+
+ return dummy;
}
```
@@ -305,7 +321,7 @@ impl Solution {
* public class ListNode {
* public int val;
* public ListNode next;
- * public ListNode(int val=0, ListNode next=null) {
+ * public ListNode(int val = 0, ListNode next = null) {
* this.val = val;
* this.next = next;
* }
@@ -313,39 +329,40 @@ impl Solution {
*/
public class Solution {
public ListNode ReverseKGroup(ListNode head, int k) {
- ListNode dummy = new ListNode(0, head);
- ListNode pre = dummy, cur = dummy;
- while (cur.next != null)
- {
- for (int i = 0; i < k && cur != null; ++i)
- {
+ var dummy = new ListNode(0);
+ dummy.next = head;
+ var pre = dummy;
+
+ while (pre != null) {
+ var cur = pre;
+ for (int i = 0; i < k; i++) {
+ if (cur.next == null) {
+ return dummy.next;
+ }
cur = cur.next;
}
- if (cur == null)
- {
- return dummy.next;
- }
- ListNode t = cur.next;
+
+ var node = pre.next;
+ var nxt = cur.next;
cur.next = null;
- ListNode start = pre.next;
- pre.next = ReverseList(start);
- start.next = t;
- pre = start;
- cur = pre;
+ pre.next = Reverse(node);
+ node.next = nxt;
+ pre = node;
}
+
return dummy.next;
}
- private ListNode ReverseList(ListNode head) {
- ListNode pre = null, p = head;
- while (p != null)
- {
- ListNode q = p.next;
- p.next = pre;
- pre = p;
- p = q;
+ private ListNode Reverse(ListNode head) {
+ ListNode prev = null;
+ var cur = head;
+ while (cur != null) {
+ var nxt = cur.next;
+ cur.next = prev;
+ prev = cur;
+ cur = nxt;
}
- return pre;
+ return prev;
}
}
```
@@ -353,153 +370,64 @@ public class Solution {
#### PHP
```php
-# 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 $head
- * @param int $k
+ * @param Integer $k
* @return ListNode
*/
-
function reverseKGroup($head, $k) {
$dummy = new ListNode(0);
$dummy->next = $head;
- $prevGroupTail = $dummy;
-
- while ($head !== null) {
- $count = 0;
- $groupHead = $head;
- $groupTail = $head;
-
- while ($count < $k && $head !== null) {
- $head = $head->next;
- $count++;
- }
- if ($count < $k) {
- $prevGroupTail->next = $groupHead;
- break;
- }
+ $pre = $dummy;
- $prev = null;
+ while ($pre !== null) {
+ $cur = $pre;
for ($i = 0; $i < $k; $i++) {
- $next = $groupHead->next;
- $groupHead->next = $prev;
- $prev = $groupHead;
- $groupHead = $next;
+ if ($cur->next === null) {
+ return $dummy->next;
+ }
+ $cur = $cur->next;
}
- $prevGroupTail->next = $prev;
- $prevGroupTail = $groupTail;
+
+ $node = $pre->next;
+ $nxt = $cur->next;
+ $cur->next = null;
+ $pre->next = $this->reverse($node);
+ $node->next = $nxt;
+ $pre = $node;
}
return $dummy->next;
}
-}
-```
-
-
-
-
-
-
-### Solution 2: Recursion
-
-The time complexity is $O(n)$, and the space complexity is $O(\log_k n)$. Here, $n$ is the length of the linked list.
-
-
-
-#### Go
-
-```go
-/**
- * Definition for singly-linked list.
- * type ListNode struct {
- * Val int
- * Next *ListNode
- * }
- */
-func reverseKGroup(head *ListNode, k int) *ListNode {
- start, end := head, head
- for i := 0; i < k; i++ {
- if end == nil {
- return head
- }
- end = end.Next
- }
- res := reverse(start, end)
- start.Next = reverseKGroup(end, k)
- return res
-}
-
-func reverse(start, end *ListNode) *ListNode {
- var pre *ListNode = nil
- for start != end {
- tmp := start.Next
- start.Next, pre = pre, start
- start = tmp
- }
- return pre
-}
-```
-
-#### TypeScript
-
-```ts
-/**
- * Definition for singly-linked list.
- * class ListNode {
- * val: number
- * next: ListNode | null
- * constructor(val?: number, next?: ListNode | null) {
- * this.val = (val===undefined ? 0 : val)
- * this.next = (next===undefined ? null : next)
- * }
- * }
- */
-
-function reverseKGroup(head: ListNode | null, k: number): ListNode | null {
- if (k === 1) {
- return head;
- }
-
- const dummy = new ListNode(0, head);
- let root = dummy;
- while (root != null) {
- let pre = root;
- let cur = root;
-
- let count = 0;
- while (count !== k) {
- count++;
- cur = cur.next;
- if (cur == null) {
- return dummy.next;
- }
- }
-
- const nextRoot = pre.next;
- pre.next = cur;
-
- let node = nextRoot;
- let next = node.next;
- node.next = cur.next;
- while (node != cur) {
- [next.next, node, next] = [node, next, next.next];
+ /**
+ * Helper function to reverse a linked list.
+ * @param ListNode $head
+ * @return ListNode
+ */
+ function reverse($head) {
+ $prev = null;
+ $cur = $head;
+ while ($cur !== null) {
+ $nxt = $cur->next;
+ $cur->next = $prev;
+ $prev = $cur;
+ $cur = $nxt;
}
- root = nextRoot;
+ return $prev;
}
-
- return dummy.next;
}
```
diff --git a/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution.cpp b/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution.cpp
new file mode 100644
index 0000000000000..76be948c05bfc
--- /dev/null
+++ b/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution.cpp
@@ -0,0 +1,48 @@
+/**
+ * Definition for singly-linked list.
+ * struct ListNode {
+ * int val;
+ * ListNode *next;
+ * ListNode() : val(0), next(nullptr) {}
+ * ListNode(int x) : val(x), next(nullptr) {}
+ * ListNode(int x, ListNode *next) : val(x), next(next) {}
+ * };
+ */
+class Solution {
+public:
+ ListNode* reverseKGroup(ListNode* head, int k) {
+ ListNode* dummy = new ListNode(0, head);
+ ListNode* pre = dummy;
+
+ while (pre != nullptr) {
+ ListNode* cur = pre;
+ for (int i = 0; i < k; i++) {
+ cur = cur->next;
+ if (cur == nullptr) {
+ return dummy->next;
+ }
+ }
+
+ ListNode* node = pre->next;
+ ListNode* nxt = cur->next;
+ cur->next = nullptr;
+ pre->next = reverse(node);
+ node->next = nxt;
+ pre = node;
+ }
+ return dummy->next;
+ }
+
+private:
+ ListNode* reverse(ListNode* head) {
+ ListNode* dummy = new ListNode();
+ ListNode* cur = head;
+ while (cur != nullptr) {
+ ListNode* nxt = cur->next;
+ cur->next = dummy->next;
+ dummy->next = cur;
+ cur = nxt;
+ }
+ return dummy->next;
+ }
+};
diff --git a/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution.cs b/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution.cs
index f99c0cc7b8cb3..0ed6c2559514a 100644
--- a/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution.cs
+++ b/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution.cs
@@ -3,7 +3,7 @@
* public class ListNode {
* public int val;
* public ListNode next;
- * public ListNode(int val=0, ListNode next=null) {
+ * public ListNode(int val = 0, ListNode next = null) {
* this.val = val;
* this.next = next;
* }
@@ -11,38 +11,39 @@
*/
public class Solution {
public ListNode ReverseKGroup(ListNode head, int k) {
- ListNode dummy = new ListNode(0, head);
- ListNode pre = dummy, cur = dummy;
- while (cur.next != null)
- {
- for (int i = 0; i < k && cur != null; ++i)
- {
+ var dummy = new ListNode(0);
+ dummy.next = head;
+ var pre = dummy;
+
+ while (pre != null) {
+ var cur = pre;
+ for (int i = 0; i < k; i++) {
+ if (cur.next == null) {
+ return dummy.next;
+ }
cur = cur.next;
}
- if (cur == null)
- {
- return dummy.next;
- }
- ListNode t = cur.next;
+
+ var node = pre.next;
+ var nxt = cur.next;
cur.next = null;
- ListNode start = pre.next;
- pre.next = ReverseList(start);
- start.next = t;
- pre = start;
- cur = pre;
+ pre.next = Reverse(node);
+ node.next = nxt;
+ pre = node;
}
+
return dummy.next;
}
- private ListNode ReverseList(ListNode head) {
- ListNode pre = null, p = head;
- while (p != null)
- {
- ListNode q = p.next;
- p.next = pre;
- pre = p;
- p = q;
+ private ListNode Reverse(ListNode head) {
+ ListNode prev = null;
+ var cur = head;
+ while (cur != null) {
+ var nxt = cur.next;
+ cur.next = prev;
+ prev = cur;
+ cur = nxt;
}
- return pre;
+ return prev;
}
}
diff --git a/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution.go b/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution.go
index acde72a916dfb..30e1f8517c8b3 100644
--- a/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution.go
+++ b/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution.go
@@ -6,28 +6,36 @@
* }
*/
func reverseKGroup(head *ListNode, k int) *ListNode {
- var dummy *ListNode = &ListNode{}
- p, cur := dummy, head
- for cur != nil {
- start := cur
+ dummy := &ListNode{Next: head}
+ pre := dummy
+
+ for pre != nil {
+ cur := pre
for i := 0; i < k; i++ {
+ cur = cur.Next
if cur == nil {
- p.Next = start
return dummy.Next
}
- cur = cur.Next
}
- p.Next, p = reverse(start, cur), start
+
+ node := pre.Next
+ nxt := cur.Next
+ cur.Next = nil
+ pre.Next = reverse(node)
+ node.Next = nxt
+ pre = node
}
return dummy.Next
}
-func reverse(start, end *ListNode) *ListNode {
- var pre *ListNode = nil
- for start != end {
- tmp := start.Next
- start.Next, pre = pre, start
- start = tmp
+func reverse(head *ListNode) *ListNode {
+ var dummy *ListNode
+ cur := head
+ for cur != nil {
+ nxt := cur.Next
+ cur.Next = dummy
+ dummy = cur
+ cur = nxt
}
- return pre
-}
\ No newline at end of file
+ return dummy
+}
diff --git a/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution.java b/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution.java
index 056e76cd21a50..9d5cf82824617 100644
--- a/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution.java
+++ b/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution.java
@@ -11,33 +11,35 @@
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
ListNode dummy = new ListNode(0, head);
- ListNode pre = dummy, cur = dummy;
- while (cur.next != null) {
- for (int i = 0; i < k && cur != null; ++i) {
+ dummy.next = head;
+ ListNode pre = dummy;
+ while (pre != null) {
+ ListNode cur = pre;
+ for (int i = 0; i < k; i++) {
cur = cur.next;
+ if (cur == null) {
+ return dummy.next;
+ }
}
- if (cur == null) {
- return dummy.next;
- }
- ListNode t = cur.next;
+ ListNode node = pre.next;
+ ListNode nxt = cur.next;
cur.next = null;
- ListNode start = pre.next;
- pre.next = reverseList(start);
- start.next = t;
- pre = start;
- cur = pre;
+ pre.next = reverse(node);
+ node.next = nxt;
+ pre = node;
}
return dummy.next;
}
- private ListNode reverseList(ListNode head) {
- ListNode pre = null, p = head;
- while (p != null) {
- ListNode q = p.next;
- p.next = pre;
- pre = p;
- p = q;
+ private ListNode reverse(ListNode head) {
+ ListNode dummy = new ListNode();
+ ListNode cur = head;
+ while (cur != null) {
+ ListNode nxt = cur.next;
+ cur.next = dummy.next;
+ dummy.next = cur;
+ cur = nxt;
}
- return pre;
+ return dummy.next;
}
-}
\ No newline at end of file
+}
diff --git a/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution.php b/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution.php
index c1a93a0d2264f..2545456cb44eb 100644
--- a/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution.php
+++ b/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution.php
@@ -1,51 +1,59 @@
-# 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 $head
- * @param int $k
+ * @param Integer $k
* @return ListNode
*/
-
function reverseKGroup($head, $k) {
$dummy = new ListNode(0);
$dummy->next = $head;
- $prevGroupTail = $dummy;
+ $pre = $dummy;
- while ($head !== null) {
- $count = 0;
- $groupHead = $head;
- $groupTail = $head;
-
- while ($count < $k && $head !== null) {
- $head = $head->next;
- $count++;
- }
- if ($count < $k) {
- $prevGroupTail->next = $groupHead;
- break;
- }
-
- $prev = null;
+ while ($pre !== null) {
+ $cur = $pre;
for ($i = 0; $i < $k; $i++) {
- $next = $groupHead->next;
- $groupHead->next = $prev;
- $prev = $groupHead;
- $groupHead = $next;
+ if ($cur->next === null) {
+ return $dummy->next;
+ }
+ $cur = $cur->next;
}
- $prevGroupTail->next = $prev;
- $prevGroupTail = $groupTail;
+
+ $node = $pre->next;
+ $nxt = $cur->next;
+ $cur->next = null;
+ $pre->next = $this->reverse($node);
+ $node->next = $nxt;
+ $pre = $node;
}
return $dummy->next;
}
+
+ /**
+ * Helper function to reverse a linked list.
+ * @param ListNode $head
+ * @return ListNode
+ */
+ function reverse($head) {
+ $prev = null;
+ $cur = $head;
+ while ($cur !== null) {
+ $nxt = $cur->next;
+ $cur->next = $prev;
+ $prev = $cur;
+ $cur = $nxt;
+ }
+ return $prev;
+ }
}
diff --git a/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution.py b/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution.py
index 7326ecd429f47..8e7e5585f5597 100644
--- a/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution.py
+++ b/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution.py
@@ -4,28 +4,28 @@
# self.val = val
# self.next = next
class Solution:
- def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
- def reverseList(head):
- pre, p = None, head
- while p:
- q = p.next
- p.next = pre
- pre = p
- p = q
- return pre
+ def reverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
+ def reverse(head: Optional[ListNode]) -> Optional[ListNode]:
+ dummy = ListNode()
+ cur = head
+ while cur:
+ nxt = cur.next
+ cur.next = dummy.next
+ dummy.next = cur
+ cur = nxt
+ return dummy.next
- dummy = ListNode(next=head)
- pre = cur = dummy
- while cur.next:
+ dummy = pre = ListNode(next=head)
+ while pre:
+ cur = pre
for _ in range(k):
cur = cur.next
if cur is None:
return dummy.next
- t = cur.next
+ node = pre.next
+ nxt = cur.next
cur.next = None
- start = pre.next
- pre.next = reverseList(start)
- start.next = t
- pre = start
- cur = pre
+ pre.next = reverse(node)
+ node.next = nxt
+ pre = node
return dummy.next
diff --git a/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution.ts b/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution.ts
index 00c33bf2d9cec..ec3b5d0399090 100644
--- a/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution.ts
+++ b/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution.ts
@@ -11,38 +11,38 @@
*/
function reverseKGroup(head: ListNode | null, k: number): ListNode | null {
- let dummy = new ListNode(0, head);
+ const dummy = new ListNode(0, head);
let pre = dummy;
- // pre->head-> ... ->tail-> next
- while (head != null) {
- let tail = pre;
- for (let i = 0; i < k; ++i) {
- tail = tail.next;
- if (tail == null) {
+ while (pre !== null) {
+ let cur: ListNode | null = pre;
+ for (let i = 0; i < k; i++) {
+ cur = cur?.next || null;
+ if (cur === null) {
return dummy.next;
}
}
- let t = tail.next;
- [head, tail] = reverse(head, tail);
- // set next
- pre.next = head;
- tail.next = t;
- // set new pre and new head
- pre = tail;
- head = t;
+
+ const node = pre.next;
+ const nxt = cur?.next || null;
+ cur!.next = null;
+ pre.next = reverse(node);
+ node!.next = nxt;
+ pre = node!;
}
+
return dummy.next;
}
-function reverse(head: ListNode, tail: ListNode) {
+function reverse(head: ListNode | null): ListNode | null {
+ let dummy: ListNode | null = null;
let cur = head;
- let pre = tail.next;
- // head -> next -> ... -> tail -> pre
- while (pre != tail) {
- let t = cur.next;
- cur.next = pre;
- pre = cur;
- cur = t;
+
+ while (cur !== null) {
+ const nxt = cur.next;
+ cur.next = dummy;
+ dummy = cur;
+ cur = nxt;
}
- return [tail, head];
+
+ return dummy;
}
diff --git a/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution2.go b/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution2.go
deleted file mode 100644
index a542ee286c3b1..0000000000000
--- a/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution2.go
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * Definition for singly-linked list.
- * type ListNode struct {
- * Val int
- * Next *ListNode
- * }
- */
-func reverseKGroup(head *ListNode, k int) *ListNode {
- start, end := head, head
- for i := 0; i < k; i++ {
- if end == nil {
- return head
- }
- end = end.Next
- }
- res := reverse(start, end)
- start.Next = reverseKGroup(end, k)
- return res
-}
-
-func reverse(start, end *ListNode) *ListNode {
- var pre *ListNode = nil
- for start != end {
- tmp := start.Next
- start.Next, pre = pre, start
- start = tmp
- }
- return pre
-}
\ No newline at end of file
diff --git a/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution2.ts b/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution2.ts
deleted file mode 100644
index db9db71869596..0000000000000
--- a/solution/0000-0099/0025.Reverse Nodes in k-Group/Solution2.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * Definition for singly-linked list.
- * class ListNode {
- * val: number
- * next: ListNode | null
- * constructor(val?: number, next?: ListNode | null) {
- * this.val = (val===undefined ? 0 : val)
- * this.next = (next===undefined ? null : next)
- * }
- * }
- */
-
-function reverseKGroup(head: ListNode | null, k: number): ListNode | null {
- if (k === 1) {
- return head;
- }
-
- const dummy = new ListNode(0, head);
- let root = dummy;
- while (root != null) {
- let pre = root;
- let cur = root;
-
- let count = 0;
- while (count !== k) {
- count++;
- cur = cur.next;
- if (cur == null) {
- return dummy.next;
- }
- }
-
- const nextRoot = pre.next;
- pre.next = cur;
-
- let node = nextRoot;
- let next = node.next;
- node.next = cur.next;
- while (node != cur) {
- [next.next, node, next] = [node, next, next.next];
- }
- root = nextRoot;
- }
-
- return dummy.next;
-}
diff --git a/solution/0000-0099/0026.Remove Duplicates from Sorted Array/README.md b/solution/0000-0099/0026.Remove Duplicates from Sorted Array/README.md
index dda26e8bdaea5..fdb81fb61551c 100644
--- a/solution/0000-0099/0026.Remove Duplicates from Sorted Array/README.md
+++ b/solution/0000-0099/0026.Remove Duplicates from Sorted Array/README.md
@@ -250,26 +250,4 @@ class Solution {
-
-
-### 方法二
-
-
-
-#### C++
-
-```cpp
-class Solution {
-public:
- int removeDuplicates(vector& nums) {
- nums.erase(unique(nums.begin(), nums.end()), nums.end());
- return nums.size();
- }
-};
-```
-
-
-
-
-
diff --git a/solution/0000-0099/0026.Remove Duplicates from Sorted Array/README_EN.md b/solution/0000-0099/0026.Remove Duplicates from Sorted Array/README_EN.md
index 8ac890d1cd1c5..1cdc125638954 100644
--- a/solution/0000-0099/0026.Remove Duplicates from Sorted Array/README_EN.md
+++ b/solution/0000-0099/0026.Remove Duplicates from Sorted Array/README_EN.md
@@ -251,26 +251,4 @@ class Solution {
-
-
-### Solution 2
-
-
-
-#### C++
-
-```cpp
-class Solution {
-public:
- int removeDuplicates(vector& nums) {
- nums.erase(unique(nums.begin(), nums.end()), nums.end());
- return nums.size();
- }
-};
-```
-
-
-
-
-
diff --git a/solution/0000-0099/0026.Remove Duplicates from Sorted Array/Solution2.cpp b/solution/0000-0099/0026.Remove Duplicates from Sorted Array/Solution2.cpp
deleted file mode 100644
index c1cdf93285b2c..0000000000000
--- a/solution/0000-0099/0026.Remove Duplicates from Sorted Array/Solution2.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-class Solution {
-public:
- int removeDuplicates(vector& nums) {
- nums.erase(unique(nums.begin(), nums.end()), nums.end());
- return nums.size();
- }
-};
\ 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