diff --git a/solution/0100-0199/0169.Majority Element/README.md b/solution/0100-0199/0169.Majority Element/README.md index 42c351d382cd4..c94416491b77c 100644 --- a/solution/0100-0199/0169.Majority Element/README.md +++ b/solution/0100-0199/0169.Majority Element/README.md @@ -199,6 +199,27 @@ impl Solution { } ``` +### **PHP** + +```php +class Solution { + /** + * @param Integer[] $nums + * @return Integer + */ + function majorityElement($nums) { + $major = 0; + $count = 0; + for ($i = 0; $i < count($nums); $i++) { + if ($count == 0) $major = $nums[$i]; + if ($major == $nums[$i]) $count++; + else $count--; + } + return $major; + } +} +``` + ### **...** ``` diff --git a/solution/0100-0199/0169.Majority Element/README_EN.md b/solution/0100-0199/0169.Majority Element/README_EN.md index 488c975fb9653..9401b5aff3991 100644 --- a/solution/0100-0199/0169.Majority Element/README_EN.md +++ b/solution/0100-0199/0169.Majority Element/README_EN.md @@ -169,6 +169,27 @@ impl Solution { } ``` +### **PHP** + +```php +class Solution { + /** + * @param Integer[] $nums + * @return Integer + */ + function majorityElement($nums) { + $major = 0; + $count = 0; + for ($i = 0; $i < count($nums); $i++) { + if ($count == 0) $major = $nums[$i]; + if ($major == $nums[$i]) $count++; + else $count--; + } + return $major; + } +} +``` + ### **...** ``` diff --git a/solution/0100-0199/0169.Majority Element/Solution.php b/solution/0100-0199/0169.Majority Element/Solution.php new file mode 100644 index 0000000000000..a53c4b76d1db0 --- /dev/null +++ b/solution/0100-0199/0169.Majority Element/Solution.php @@ -0,0 +1,16 @@ +class Solution { + /** + * @param Integer[] $nums + * @return Integer + */ + function majorityElement($nums) { + $major = 0; + $count = 0; + for ($i = 0; $i < count($nums); $i++) { + if ($count == 0) $major = $nums[$i]; + if ($major == $nums[$i]) $count++; + else $count--; + } + return $major; + } +} \ No newline at end of file diff --git a/solution/0800-0899/0842.Split Array into Fibonacci Sequence/README.md b/solution/0800-0899/0842.Split Array into Fibonacci Sequence/README.md index deca910fc75f7..ac7c8be0cdf10 100644 --- a/solution/0800-0899/0842.Split Array into Fibonacci Sequence/README.md +++ b/solution/0800-0899/0842.Split Array into Fibonacci Sequence/README.md @@ -58,6 +58,18 @@ +**方法一:回溯 + 剪枝** + +我们设计一个函数 $dfs(i)$,表示从字符串 $num$ 的第 $i$ 个字符开始拆分,拆分出的斐波那契式序列是否满足题目要求。如果满足,我们就返回 $true$,否则返回 $false$。 + +函数 $dfs(i)$ 的具体实现如下: + +如果 $i$ 等于字符串 $num$ 的长度,说明我们已经拆分完整个字符串,此时我们只需要判断拆分出的序列的长度是否大于 $2$ 即可。如果大于 $2$,说明我们找到了一组满足题目要求的斐波那契式序列,返回 $true$;否则返回 $false$。 + +如果 $i$ 小于字符串 $num$ 的长度,我们需要枚举拆分出的第一个数 $x$,如果 $x$ 的长度大于 $1$,且以 $0$ 开头,说明 $x$ 不是一个合法的数,我们直接返回 $false$。否则我们将 $x$ 转换成十进制数,如果 $x$ 大于 $2^{31} - 1$,或者 $x$ 大于 $ans$ 的最后两个数之和,直接返回 $false$。如果 $ans$ 的长度小于 $2$,或者 $x$ 等于 $ans$ 的最后两个数之和,我们将 $x$ 加入到 $ans$ 中,然后继续拆分字符串 $num$ 的后面的部分,如果返回 $true$,说明我们找到了一组满足题目要求的斐波那契式序列,返回 $true$;否则我们将 $x$ 从 $ans$ 中移除,然后继续枚举拆分出的第一个数 $x$。 + +时间复杂度 $O(n \times \log^2 M)$,空间复杂度 $O(n)$。其中 $n$ 和 $M$ 分别是字符串 $num$ 的长度和整型数的最大值。 + ### **Python3** @@ -65,7 +77,29 @@ ```python - +class Solution: + def splitIntoFibonacci(self, num: str) -> List[int]: + def dfs(i): + if i == n: + return len(ans) > 2 + x = 0 + for j in range(i, n): + if j > i and num[i] == '0': + break + x = x * 10 + int(num[j]) + if x > 2**31 - 1 or (len(ans) > 2 and x > ans[-2] + ans[-1]): + break + if len(ans) < 2 or ans[-2] + ans[-1] == x: + ans.append(x) + if dfs(j + 1): + return True + ans.pop() + return False + + n = len(num) + ans = [] + dfs(0) + return ans ``` ### **Java** @@ -73,7 +107,112 @@ ```java +class Solution { + private List ans = new ArrayList<>(); + private String num; + + public List splitIntoFibonacci(String num) { + this.num = num; + dfs(0); + return ans; + } + + private boolean dfs(int i) { + if (i == num.length()) { + return ans.size() >= 3; + } + long x = 0; + for (int j = i; j < num.length(); ++j) { + if (j > i && num.charAt(i) == '0') { + break; + } + x = x * 10 + num.charAt(j) - '0'; + if (x > Integer.MAX_VALUE || (ans.size() >= 2 && x > ans.get(ans.size() - 1) + ans.get(ans.size() - 2))) { + break; + } + if (ans.size() < 2 || x == ans.get(ans.size() - 1) + ans.get(ans.size() - 2)) { + ans.add((int) x); + if (dfs(j + 1)) { + return true; + } + ans.remove(ans.size() - 1); + } + } + return false; + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + vector splitIntoFibonacci(string num) { + int n = num.size(); + vector ans; + function dfs = [&](int i) -> bool { + if (i == n) { + return ans.size() > 2; + } + long long x = 0; + for (int j = i; j < n; ++j) { + if (j > i && num[i] == '0') { + break; + } + x = x * 10 + num[j] - '0'; + if (x > INT_MAX || (ans.size() > 1 && x > (long long) ans[ans.size() - 1] + ans[ans.size() - 2])) { + break; + } + if (ans.size() < 2 || x == (long long) ans[ans.size() - 1] + ans[ans.size() - 2]) { + ans.push_back(x); + if (dfs(j + 1)) { + return true; + } + ans.pop_back(); + } + } + return false; + }; + dfs(0); + return ans; + } +}; +``` +### **Go** + +```go +func splitIntoFibonacci(num string) []int { + n := len(num) + ans := []int{} + var dfs func(int) bool + dfs = func(i int) bool { + if i == n { + return len(ans) > 2 + } + x := 0 + for j := i; j < n; j++ { + if j > i && num[i] == '0' { + break + } + x = x*10 + int(num[j]-'0') + if x > math.MaxInt32 || (len(ans) > 1 && x > ans[len(ans)-1]+ans[len(ans)-2]) { + break + } + if len(ans) < 2 || x == ans[len(ans)-1]+ans[len(ans)-2] { + ans = append(ans, x) + if dfs(j + 1) { + return true + } + ans = ans[:len(ans)-1] + } + } + return false + } + dfs(0) + return ans +} ``` ### **...** diff --git a/solution/0800-0899/0842.Split Array into Fibonacci Sequence/README_EN.md b/solution/0800-0899/0842.Split Array into Fibonacci Sequence/README_EN.md index ab2c921916ea3..c9ae427b91e11 100644 --- a/solution/0800-0899/0842.Split Array into Fibonacci Sequence/README_EN.md +++ b/solution/0800-0899/0842.Split Array into Fibonacci Sequence/README_EN.md @@ -58,13 +58,140 @@ ### **Python3** ```python - +class Solution: + def splitIntoFibonacci(self, num: str) -> List[int]: + def dfs(i): + if i == n: + return len(ans) > 2 + x = 0 + for j in range(i, n): + if j > i and num[i] == '0': + break + x = x * 10 + int(num[j]) + if x > 2**31 - 1 or (len(ans) > 2 and x > ans[-2] + ans[-1]): + break + if len(ans) < 2 or ans[-2] + ans[-1] == x: + ans.append(x) + if dfs(j + 1): + return True + ans.pop() + return False + + n = len(num) + ans = [] + dfs(0) + return ans ``` ### **Java** ```java +class Solution { + private List ans = new ArrayList<>(); + private String num; + + public List splitIntoFibonacci(String num) { + this.num = num; + dfs(0); + return ans; + } + + private boolean dfs(int i) { + if (i == num.length()) { + return ans.size() >= 3; + } + long x = 0; + for (int j = i; j < num.length(); ++j) { + if (j > i && num.charAt(i) == '0') { + break; + } + x = x * 10 + num.charAt(j) - '0'; + if (x > Integer.MAX_VALUE || (ans.size() >= 2 && x > ans.get(ans.size() - 1) + ans.get(ans.size() - 2))) { + break; + } + if (ans.size() < 2 || x == ans.get(ans.size() - 1) + ans.get(ans.size() - 2)) { + ans.add((int) x); + if (dfs(j + 1)) { + return true; + } + ans.remove(ans.size() - 1); + } + } + return false; + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + vector splitIntoFibonacci(string num) { + int n = num.size(); + vector ans; + function dfs = [&](int i) -> bool { + if (i == n) { + return ans.size() > 2; + } + long long x = 0; + for (int j = i; j < n; ++j) { + if (j > i && num[i] == '0') { + break; + } + x = x * 10 + num[j] - '0'; + if (x > INT_MAX || (ans.size() > 1 && x > (long long) ans[ans.size() - 1] + ans[ans.size() - 2])) { + break; + } + if (ans.size() < 2 || x == (long long) ans[ans.size() - 1] + ans[ans.size() - 2]) { + ans.push_back(x); + if (dfs(j + 1)) { + return true; + } + ans.pop_back(); + } + } + return false; + }; + dfs(0); + return ans; + } +}; +``` +### **Go** + +```go +func splitIntoFibonacci(num string) []int { + n := len(num) + ans := []int{} + var dfs func(int) bool + dfs = func(i int) bool { + if i == n { + return len(ans) > 2 + } + x := 0 + for j := i; j < n; j++ { + if j > i && num[i] == '0' { + break + } + x = x*10 + int(num[j]-'0') + if x > math.MaxInt32 || (len(ans) > 1 && x > ans[len(ans)-1]+ans[len(ans)-2]) { + break + } + if len(ans) < 2 || x == ans[len(ans)-1]+ans[len(ans)-2] { + ans = append(ans, x) + if dfs(j + 1) { + return true + } + ans = ans[:len(ans)-1] + } + } + return false + } + dfs(0) + return ans +} ``` ### **...** diff --git a/solution/0800-0899/0842.Split Array into Fibonacci Sequence/Solution.cpp b/solution/0800-0899/0842.Split Array into Fibonacci Sequence/Solution.cpp new file mode 100644 index 0000000000000..6b849b5c8ba0f --- /dev/null +++ b/solution/0800-0899/0842.Split Array into Fibonacci Sequence/Solution.cpp @@ -0,0 +1,32 @@ +class Solution { +public: + vector splitIntoFibonacci(string num) { + int n = num.size(); + vector ans; + function dfs = [&](int i) -> bool { + if (i == n) { + return ans.size() > 2; + } + long long x = 0; + for (int j = i; j < n; ++j) { + if (j > i && num[i] == '0') { + break; + } + x = x * 10 + num[j] - '0'; + if (x > INT_MAX || (ans.size() > 1 && x > (long long) ans[ans.size() - 1] + ans[ans.size() - 2])) { + break; + } + if (ans.size() < 2 || x == (long long) ans[ans.size() - 1] + ans[ans.size() - 2]) { + ans.push_back(x); + if (dfs(j + 1)) { + return true; + } + ans.pop_back(); + } + } + return false; + }; + dfs(0); + return ans; + } +}; \ No newline at end of file diff --git a/solution/0800-0899/0842.Split Array into Fibonacci Sequence/Solution.go b/solution/0800-0899/0842.Split Array into Fibonacci Sequence/Solution.go new file mode 100644 index 0000000000000..5fc8028af0ec8 --- /dev/null +++ b/solution/0800-0899/0842.Split Array into Fibonacci Sequence/Solution.go @@ -0,0 +1,30 @@ +func splitIntoFibonacci(num string) []int { + n := len(num) + ans := []int{} + var dfs func(int) bool + dfs = func(i int) bool { + if i == n { + return len(ans) > 2 + } + x := 0 + for j := i; j < n; j++ { + if j > i && num[i] == '0' { + break + } + x = x*10 + int(num[j]-'0') + if x > math.MaxInt32 || (len(ans) > 1 && x > ans[len(ans)-1]+ans[len(ans)-2]) { + break + } + if len(ans) < 2 || x == ans[len(ans)-1]+ans[len(ans)-2] { + ans = append(ans, x) + if dfs(j + 1) { + return true + } + ans = ans[:len(ans)-1] + } + } + return false + } + dfs(0) + return ans +} \ No newline at end of file diff --git a/solution/0800-0899/0842.Split Array into Fibonacci Sequence/Solution.java b/solution/0800-0899/0842.Split Array into Fibonacci Sequence/Solution.java new file mode 100644 index 0000000000000..cd9f12a84ec47 --- /dev/null +++ b/solution/0800-0899/0842.Split Array into Fibonacci Sequence/Solution.java @@ -0,0 +1,34 @@ +class Solution { + private List ans = new ArrayList<>(); + private String num; + + public List splitIntoFibonacci(String num) { + this.num = num; + dfs(0); + return ans; + } + + private boolean dfs(int i) { + if (i == num.length()) { + return ans.size() >= 3; + } + long x = 0; + for (int j = i; j < num.length(); ++j) { + if (j > i && num.charAt(i) == '0') { + break; + } + x = x * 10 + num.charAt(j) - '0'; + if (x > Integer.MAX_VALUE || (ans.size() >= 2 && x > ans.get(ans.size() - 1) + ans.get(ans.size() - 2))) { + break; + } + if (ans.size() < 2 || x == ans.get(ans.size() - 1) + ans.get(ans.size() - 2)) { + ans.add((int) x); + if (dfs(j + 1)) { + return true; + } + ans.remove(ans.size() - 1); + } + } + return false; + } +} \ No newline at end of file diff --git a/solution/0800-0899/0842.Split Array into Fibonacci Sequence/Solution.py b/solution/0800-0899/0842.Split Array into Fibonacci Sequence/Solution.py new file mode 100644 index 0000000000000..8a40fc4933c89 --- /dev/null +++ b/solution/0800-0899/0842.Split Array into Fibonacci Sequence/Solution.py @@ -0,0 +1,23 @@ +class Solution: + def splitIntoFibonacci(self, num: str) -> List[int]: + def dfs(i): + if i == n: + return len(ans) > 2 + x = 0 + for j in range(i, n): + if j > i and num[i] == '0': + break + x = x * 10 + int(num[j]) + if x > 2**31 - 1 or (len(ans) > 2 and x > ans[-2] + ans[-1]): + break + if len(ans) < 2 or ans[-2] + ans[-1] == x: + ans.append(x) + if dfs(j + 1): + return True + ans.pop() + return False + + n = len(num) + ans = [] + dfs(0) + return ans diff --git a/solution/1000-1099/1092.Shortest Common Supersequence/README.md b/solution/1000-1099/1092.Shortest Common Supersequence/README.md index 387caa9292ef2..e16a1970c1d90 100644 --- a/solution/1000-1099/1092.Shortest Common Supersequence/README.md +++ b/solution/1000-1099/1092.Shortest Common Supersequence/README.md @@ -52,7 +52,26 @@ $$ 接下来我们基于 $f[i][j]$ 构造出最短公共超序列。 -用双指针 $i$ 和 $j$ 分别指向字符串 $str1$ 和 $str2$ 的末尾,然后从后往前遍历,每次比较 $str1[i]$ 和 $str2[j]$ 的值,如果 $str1[i] = str2[j]$,则将 $str1[i]$ 或 $str2[j]$ 中的任意一个字符加入到最短公共超序列的末尾,然后 $i$ 和 $j$ 同时减 1;如果 $str1[i] \neq str2[j]$,则将 $f[i][j]$ 与 $f[i - 1][j]$ 和 $f[i][j - 1]$ 中的最大值进行比较,如果 $f[i][j] = f[i - 1][j]$,则将 $str1[i]$ 加入到最短公共超序列的末尾,然后 $i$ 减 1;如果 $f[i][j] = f[i][j - 1]$,则将 $str2[j]$ 加入到最短公共超序列的末尾,然后 $j$ 减 1。重复上述操作,直到 $i = 0$ 或 $j = 0$,然后将剩余的字符串加入到最短公共超序列的末尾即可。 +```bash +str1: a b a c + +str2: c a b + +ans: c a b a c +``` + +不妨对照着上面的示例字符串,来看看如何构造出最短公共超序列。 + +我们用双指针 $i$ 和 $j$ 分别指向字符串 $str1$ 和 $str2$ 的末尾,然后从后往前遍历,每次比较 $str1[i]$ 和 $str2[j]$ 的值: + +- 如果 $str1[i] = str2[j]$,则将 $str1[i]$ 或 $str2[j]$ 中的任意一个字符加入到最答案序列的末尾,然后 $i$ 和 $j$ 同时减 $1$; +- 如果 $str1[i] \neq str2[j]$,则将 $f[i][j]$ 与 $f[i - 1][j]$ 和 $f[i][j - 1]$ 中的最大值进行比较: + - 如果 $f[i][j] = f[i - 1][j]$,则将 $str1[i]$ 加入到答案序列的末尾,然后 $i$ 减 $1$; + - 如果 $f[i][j] = f[i][j - 1]$,则将 $str2[j]$ 加入到答案序列的末尾,然后 $j$ 减 $1$。 + +重复上述操作,直到 $i = 0$ 或 $j = 0$,然后将剩余的字符串加入到答案序列的末尾即可。 + +最后我们将答案序列反转,即可得到最终的答案。 时间复杂度 $O(m\times n)$,空间复杂度 $O(m\times n)$。其中 $m$ 和 $n$ 分别是字符串 $str1$ 和 $str2$ 的长度。 @@ -228,6 +247,45 @@ func max(a, b int) int { } ``` +### **TypeScript** + +```ts +function shortestCommonSupersequence(str1: string, str2: string): string { + const m = str1.length; + const n = str2.length; + const f = new Array(m + 1).fill(0).map(() => new Array(n + 1).fill(0)); + for (let i = 1; i <= m; ++i) { + for (let j = 1; j <= n; ++j) { + if (str1[i - 1] == str2[j - 1]) { + f[i][j] = f[i - 1][j - 1] + 1; + } else { + f[i][j] = Math.max(f[i - 1][j], f[i][j - 1]); + } + } + } + let ans: string[] = []; + let i = m; + let j = n; + while (i > 0 || j > 0) { + if (i === 0) { + ans.push(str2[--j]); + } else if (j === 0) { + ans.push(str1[--i]); + } else { + if (f[i][j] === f[i - 1][j]) { + ans.push(str1[--i]); + } else if (f[i][j] === f[i][j - 1]) { + ans.push(str2[--j]); + } else { + ans.push(str1[--i]); + --j; + } + } + } + return ans.reverse().join(''); +} +``` + ### **...** ``` diff --git a/solution/1000-1099/1092.Shortest Common Supersequence/README_EN.md b/solution/1000-1099/1092.Shortest Common Supersequence/README_EN.md index ea8b2b940354e..096401d5f28eb 100644 --- a/solution/1000-1099/1092.Shortest Common Supersequence/README_EN.md +++ b/solution/1000-1099/1092.Shortest Common Supersequence/README_EN.md @@ -205,6 +205,45 @@ func max(a, b int) int { } ``` +### **TypeScript** + +```ts +function shortestCommonSupersequence(str1: string, str2: string): string { + const m = str1.length; + const n = str2.length; + const f = new Array(m + 1).fill(0).map(() => new Array(n + 1).fill(0)); + for (let i = 1; i <= m; ++i) { + for (let j = 1; j <= n; ++j) { + if (str1[i - 1] == str2[j - 1]) { + f[i][j] = f[i - 1][j - 1] + 1; + } else { + f[i][j] = Math.max(f[i - 1][j], f[i][j - 1]); + } + } + } + let ans: string[] = []; + let i = m; + let j = n; + while (i > 0 || j > 0) { + if (i === 0) { + ans.push(str2[--j]); + } else if (j === 0) { + ans.push(str1[--i]); + } else { + if (f[i][j] === f[i - 1][j]) { + ans.push(str1[--i]); + } else if (f[i][j] === f[i][j - 1]) { + ans.push(str2[--j]); + } else { + ans.push(str1[--i]); + --j; + } + } + } + return ans.reverse().join(''); +} +``` + ### **...** ``` diff --git a/solution/1000-1099/1092.Shortest Common Supersequence/Solution.ts b/solution/1000-1099/1092.Shortest Common Supersequence/Solution.ts new file mode 100644 index 0000000000000..6336bf7070bd8 --- /dev/null +++ b/solution/1000-1099/1092.Shortest Common Supersequence/Solution.ts @@ -0,0 +1,34 @@ +function shortestCommonSupersequence(str1: string, str2: string): string { + const m = str1.length; + const n = str2.length; + const f = new Array(m + 1).fill(0).map(() => new Array(n + 1).fill(0)); + for (let i = 1; i <= m; ++i) { + for (let j = 1; j <= n; ++j) { + if (str1[i - 1] == str2[j - 1]) { + f[i][j] = f[i - 1][j - 1] + 1; + } else { + f[i][j] = Math.max(f[i - 1][j], f[i][j - 1]); + } + } + } + let ans: string[] = []; + let i = m; + let j = n; + while (i > 0 || j > 0) { + if (i === 0) { + ans.push(str2[--j]); + } else if (j === 0) { + ans.push(str1[--i]); + } else { + if (f[i][j] === f[i - 1][j]) { + ans.push(str1[--i]); + } else if (f[i][j] === f[i][j - 1]) { + ans.push(str2[--j]); + } else { + ans.push(str1[--i]); + --j; + } + } + } + return ans.reverse().join(''); +} diff --git a/solution/1000-1099/1094.Car Pooling/README.md b/solution/1000-1099/1094.Car Pooling/README.md index 560505100f3f4..1d8eee89ff025 100644 --- a/solution/1000-1099/1094.Car Pooling/README.md +++ b/solution/1000-1099/1094.Car Pooling/README.md @@ -44,7 +44,11 @@ -差分数组。 +**方法一:差分数组** + +我们可以利用差分数组的思想,将每个行程的乘客数加到起点,减去终点,最后遍历差分数组,若当前乘客数大于容量,则返回 `false`,否则返回 `true`。 + +时间复杂度 $O(n)$,空间复杂度 $O(m)$。其中 $n$ 和 $m$ 分别为行程数和行程中的最大终点。 @@ -55,11 +59,11 @@ ```python class Solution: def carPooling(self, trips: List[List[int]], capacity: int) -> bool: - delta = [0] * 1001 - for num, start, end in trips: - delta[start] += num - delta[end] -= num - return all(s <= capacity for s in accumulate(delta)) + d = [0] * 1001 + for x, f, t in trips: + d[f] += x + d[t] -= x + return all(s <= capacity for s in accumulate(d)) ``` ### **Java** @@ -69,16 +73,16 @@ class Solution: ```java class Solution { public boolean carPooling(int[][] trips, int capacity) { - int[] delta = new int[1001]; - for (int[] trip : trips) { - int num = trip[0], start = trip[1], end = trip[2]; - delta[start] += num; - delta[end] -= num; + int[] d = new int[1001]; + for (var trip : trips) { + int x = trip[0], f = trip[1], t = trip[2]; + d[f] += x; + d[t] -= x; } - int cur = 0; - for (int num : delta) { - cur += num; - if (cur > capacity) { + int s = 0; + for (int x : d) { + s += x; + if (s > capacity) { return false; } } @@ -87,47 +91,22 @@ class Solution { } ``` -### **JavaScript** - -```js -/** - * @param {number[][]} trips - * @param {number} capacity - * @return {boolean} - */ -var carPooling = function (trips, capacity) { - let delta = new Array(1001).fill(0); - for (let [num, start, end] of trips) { - delta[start] += num; - delta[end] -= num; - } - let s = 0; - for (let num of delta) { - s += num; - if (s > capacity) { - return false; - } - } - return true; -}; -``` - ### **C++** ```cpp class Solution { public: bool carPooling(vector>& trips, int capacity) { - vector delta(1001); + int d[1001]{}; for (auto& trip : trips) { - int num = trip[0], start = trip[1], end = trip[2]; - delta[start] += num; - delta[end] -= num; + int x = trip[0], f = trip[1], t = trip[2]; + d[f] += x; + d[t] -= x; } - int cur = 0; - for (auto& num : delta) { - cur += num; - if (cur > capacity) { + int s = 0; + for (int x : d) { + s += x; + if (s > capacity) { return false; } } @@ -140,16 +119,16 @@ public: ```go func carPooling(trips [][]int, capacity int) bool { - delta := make([]int, 1010) + d := [1001]int{} for _, trip := range trips { - num, start, end := trip[0], trip[1], trip[2] - delta[start] += num - delta[end] -= num + x, f, t := trip[0], trip[1], trip[2] + d[f] += x + d[t] -= x } - cur := 0 - for _, num := range delta { - cur += num - if cur > capacity { + s := 0 + for _, x := range d { + s += x + if s > capacity { return false } } @@ -157,6 +136,51 @@ func carPooling(trips [][]int, capacity int) bool { } ``` +### **JavaScript** + +```js +/** + * @param {number[][]} trips + * @param {number} capacity + * @return {boolean} + */ +var carPooling = function (trips, capacity) { + const d = new Array(1001).fill(0); + for (const [x, f, t] of trips) { + d[f] += x; + d[t] -= x; + } + let s = 0; + for (const x of d) { + s += x; + if (s > capacity) { + return false; + } + } + return true; +}; +``` + +### **TypeScript** + +```ts +function carPooling(trips: number[][], capacity: number): boolean { + const d = new Array(1001).fill(0); + for (const [x, f, t] of trips) { + d[f] += x; + d[t] -= x; + } + let s = 0; + for (const x of d) { + s += x; + if (s > capacity) { + return false; + } + } + return true; +} +``` + ### **...** ``` diff --git a/solution/1000-1099/1094.Car Pooling/README_EN.md b/solution/1000-1099/1094.Car Pooling/README_EN.md index 11503b10ddbba..1a12ee3415189 100644 --- a/solution/1000-1099/1094.Car Pooling/README_EN.md +++ b/solution/1000-1099/1094.Car Pooling/README_EN.md @@ -45,11 +45,11 @@ ```python class Solution: def carPooling(self, trips: List[List[int]], capacity: int) -> bool: - delta = [0] * 1001 - for num, start, end in trips: - delta[start] += num - delta[end] -= num - return all(s <= capacity for s in accumulate(delta)) + d = [0] * 1001 + for x, f, t in trips: + d[f] += x + d[t] -= x + return all(s <= capacity for s in accumulate(d)) ``` ### **Java** @@ -57,16 +57,16 @@ class Solution: ```java class Solution { public boolean carPooling(int[][] trips, int capacity) { - int[] delta = new int[1001]; - for (int[] trip : trips) { - int num = trip[0], start = trip[1], end = trip[2]; - delta[start] += num; - delta[end] -= num; + int[] d = new int[1001]; + for (var trip : trips) { + int x = trip[0], f = trip[1], t = trip[2]; + d[f] += x; + d[t] -= x; } - int cur = 0; - for (int num : delta) { - cur += num; - if (cur > capacity) { + int s = 0; + for (int x : d) { + s += x; + if (s > capacity) { return false; } } @@ -75,47 +75,22 @@ class Solution { } ``` -### **JavaScript** - -```js -/** - * @param {number[][]} trips - * @param {number} capacity - * @return {boolean} - */ -var carPooling = function (trips, capacity) { - let delta = new Array(1001).fill(0); - for (let [num, start, end] of trips) { - delta[start] += num; - delta[end] -= num; - } - let s = 0; - for (let num of delta) { - s += num; - if (s > capacity) { - return false; - } - } - return true; -}; -``` - ### **C++** ```cpp class Solution { public: bool carPooling(vector>& trips, int capacity) { - vector delta(1001); + int d[1001]{}; for (auto& trip : trips) { - int num = trip[0], start = trip[1], end = trip[2]; - delta[start] += num; - delta[end] -= num; + int x = trip[0], f = trip[1], t = trip[2]; + d[f] += x; + d[t] -= x; } - int cur = 0; - for (auto& num : delta) { - cur += num; - if (cur > capacity) { + int s = 0; + for (int x : d) { + s += x; + if (s > capacity) { return false; } } @@ -128,16 +103,16 @@ public: ```go func carPooling(trips [][]int, capacity int) bool { - delta := make([]int, 1010) + d := [1001]int{} for _, trip := range trips { - num, start, end := trip[0], trip[1], trip[2] - delta[start] += num - delta[end] -= num + x, f, t := trip[0], trip[1], trip[2] + d[f] += x + d[t] -= x } - cur := 0 - for _, num := range delta { - cur += num - if cur > capacity { + s := 0 + for _, x := range d { + s += x + if s > capacity { return false } } @@ -145,6 +120,51 @@ func carPooling(trips [][]int, capacity int) bool { } ``` +### **JavaScript** + +```js +/** + * @param {number[][]} trips + * @param {number} capacity + * @return {boolean} + */ +var carPooling = function (trips, capacity) { + const d = new Array(1001).fill(0); + for (const [x, f, t] of trips) { + d[f] += x; + d[t] -= x; + } + let s = 0; + for (const x of d) { + s += x; + if (s > capacity) { + return false; + } + } + return true; +}; +``` + +### **TypeScript** + +```ts +function carPooling(trips: number[][], capacity: number): boolean { + const d = new Array(1001).fill(0); + for (const [x, f, t] of trips) { + d[f] += x; + d[t] -= x; + } + let s = 0; + for (const x of d) { + s += x; + if (s > capacity) { + return false; + } + } + return true; +} +``` + ### **...** ``` diff --git a/solution/1000-1099/1094.Car Pooling/Solution.cpp b/solution/1000-1099/1094.Car Pooling/Solution.cpp index c60b22713b329..b224fef231ac1 100644 --- a/solution/1000-1099/1094.Car Pooling/Solution.cpp +++ b/solution/1000-1099/1094.Car Pooling/Solution.cpp @@ -1,16 +1,16 @@ class Solution { public: bool carPooling(vector>& trips, int capacity) { - vector delta(1001); + int d[1001]{}; for (auto& trip : trips) { - int num = trip[0], start = trip[1], end = trip[2]; - delta[start] += num; - delta[end] -= num; + int x = trip[0], f = trip[1], t = trip[2]; + d[f] += x; + d[t] -= x; } - int cur = 0; - for (auto& num : delta) { - cur += num; - if (cur > capacity) { + int s = 0; + for (int x : d) { + s += x; + if (s > capacity) { return false; } } diff --git a/solution/1000-1099/1094.Car Pooling/Solution.go b/solution/1000-1099/1094.Car Pooling/Solution.go index e9df75addfc15..95c9c3d009eab 100644 --- a/solution/1000-1099/1094.Car Pooling/Solution.go +++ b/solution/1000-1099/1094.Car Pooling/Solution.go @@ -1,14 +1,14 @@ func carPooling(trips [][]int, capacity int) bool { - delta := make([]int, 1010) + d := [1001]int{} for _, trip := range trips { - num, start, end := trip[0], trip[1], trip[2] - delta[start] += num - delta[end] -= num + x, f, t := trip[0], trip[1], trip[2] + d[f] += x + d[t] -= x } - cur := 0 - for _, num := range delta { - cur += num - if cur > capacity { + s := 0 + for _, x := range d { + s += x + if s > capacity { return false } } diff --git a/solution/1000-1099/1094.Car Pooling/Solution.java b/solution/1000-1099/1094.Car Pooling/Solution.java index cf5759cfc2786..67d03795dc114 100644 --- a/solution/1000-1099/1094.Car Pooling/Solution.java +++ b/solution/1000-1099/1094.Car Pooling/Solution.java @@ -1,15 +1,15 @@ class Solution { public boolean carPooling(int[][] trips, int capacity) { - int[] delta = new int[1001]; - for (int[] trip : trips) { - int num = trip[0], start = trip[1], end = trip[2]; - delta[start] += num; - delta[end] -= num; + int[] d = new int[1001]; + for (var trip : trips) { + int x = trip[0], f = trip[1], t = trip[2]; + d[f] += x; + d[t] -= x; } - int cur = 0; - for (int num : delta) { - cur += num; - if (cur > capacity) { + int s = 0; + for (int x : d) { + s += x; + if (s > capacity) { return false; } } diff --git a/solution/1000-1099/1094.Car Pooling/Solution.js b/solution/1000-1099/1094.Car Pooling/Solution.js index e7b0a99f43fb8..6f0cf9bd6b9ae 100644 --- a/solution/1000-1099/1094.Car Pooling/Solution.js +++ b/solution/1000-1099/1094.Car Pooling/Solution.js @@ -4,14 +4,14 @@ * @return {boolean} */ var carPooling = function (trips, capacity) { - let delta = new Array(1001).fill(0); - for (let [num, start, end] of trips) { - delta[start] += num; - delta[end] -= num; + const d = new Array(1001).fill(0); + for (const [x, f, t] of trips) { + d[f] += x; + d[t] -= x; } let s = 0; - for (let num of delta) { - s += num; + for (const x of d) { + s += x; if (s > capacity) { return false; } diff --git a/solution/1000-1099/1094.Car Pooling/Solution.py b/solution/1000-1099/1094.Car Pooling/Solution.py index 5e3c693675535..b2e9e19504b99 100644 --- a/solution/1000-1099/1094.Car Pooling/Solution.py +++ b/solution/1000-1099/1094.Car Pooling/Solution.py @@ -1,7 +1,7 @@ class Solution: def carPooling(self, trips: List[List[int]], capacity: int) -> bool: - delta = [0] * 1001 - for num, start, end in trips: - delta[start] += num - delta[end] -= num - return all(s <= capacity for s in accumulate(delta)) + d = [0] * 1001 + for x, f, t in trips: + d[f] += x + d[t] -= x + return all(s <= capacity for s in accumulate(d)) diff --git a/solution/1000-1099/1094.Car Pooling/Solution.ts b/solution/1000-1099/1094.Car Pooling/Solution.ts new file mode 100644 index 0000000000000..9c42db6c3d9ea --- /dev/null +++ b/solution/1000-1099/1094.Car Pooling/Solution.ts @@ -0,0 +1,15 @@ +function carPooling(trips: number[][], capacity: number): boolean { + const d = new Array(1001).fill(0); + for (const [x, f, t] of trips) { + d[f] += x; + d[t] -= x; + } + let s = 0; + for (const x of d) { + s += x; + if (s > capacity) { + return false; + } + } + return true; +} diff --git a/solution/1600-1699/1639.Number of Ways to Form a Target String Given a Dictionary/README.md b/solution/1600-1699/1639.Number of Ways to Form a Target String Given a Dictionary/README.md index e8cdd284e17c0..a5aa0441efab8 100644 --- a/solution/1600-1699/1639.Number of Ways to Form a Target String Given a Dictionary/README.md +++ b/solution/1600-1699/1639.Number of Ways to Form a Target String Given a Dictionary/README.md @@ -81,6 +81,22 @@ +**方法一:预处理 + 记忆化搜索** + +我们注意到,字符串数组 $words$ 中的每一个字符串长度都相同,不妨记为 $n$,那么我们可以预处理出一个二维数组 $cnt$,其中 $cnt[j][c]$ 表示字符串数组 $words$ 中第 $j$ 个位置的字符 $c$ 的数量。 + +接下来,我们设计一个函数 $dfs(i, j)$,表示构造 $target[i,..]$ 且当前从 $words$ 中选取的字符位置为 $j$ 的方案数。那么答案就是 $dfs(0, 0)$。 + +函数 $dfs(i, j)$ 的计算逻辑如下: + +- 如果 $i \geq m$,说明 $target$ 中的所有字符都已经被选取,那么方案数为 $1$。 +- 如果 $j \geq n$,说明 $words$ 中的所有字符都已经被选取,那么方案数为 $0$。 +- 否则,我们可以不选择 $words$ 中的第 $j$ 个位置的字符,那么方案数为 $dfs(i, j + 1)$;或者我们选择 $words$ 中的第 $j$ 个位置的字符,那么方案数为 $dfs(i + 1, j + 1) \times cnt[j][target[i] - 'a']$。 + +最后,我们返回 $dfs(0, 0)$ 即可。注意答案的取模操作。 + +时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 为字符串 $target$ 的长度,而 $n$ 为字符串数组 $words$ 中每个字符串的长度。 + ### **Python3** @@ -88,7 +104,26 @@ ```python - +class Solution: + def numWays(self, words: List[str], target: str) -> int: + @cache + def dfs(i, j): + if i >= m: + return 1 + if j >= n: + return 0 + ans = dfs(i, j + 1) + dfs(i + 1, j + 1) * cnt[j][ord(target[i]) - ord("a")] + ans %= mod + return ans + + m = len(target) + n = len(words[0]) + cnt = [[0] * 26 for _ in range(n)] + for w in words: + for j, c in enumerate(w): + cnt[j][ord(c) - ord("a")] += 1 + mod = 10**9 + 7 + return dfs(0, 0) ``` ### **Java** @@ -96,7 +131,118 @@ ```java +class Solution { + private int m; + private int n; + private String target; + private Integer[][] f; + private int[][] cnt; + private final int mod = (int) 1e9 + 7; + + public int numWays(String[] words, String target) { + m = target.length(); + n = words[0].length(); + f = new Integer[m][n]; + this.target = target; + cnt = new int[n][26]; + for (var w : words) { + for (int j = 0; j < n; ++j) { + cnt[j][w.charAt(j) - 'a']++; + } + } + return dfs(0, 0); + } + + private int dfs(int i, int j) { + if (i >= m) { + return 1; + } + if (j >= n) { + return 0; + } + if (f[i][j] != null) { + return f[i][j]; + } + long ans = dfs(i, j + 1); + ans += 1L * dfs(i + 1, j + 1) * cnt[j][target.charAt(i) - 'a']; + ans %= mod; + return f[i][j] = (int) ans; + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + int numWays(vector& words, string target) { + const int mod = 1e9 + 7; + int m = target.size(), n = words[0].size(); + vector> cnt(n, vector(26)); + for (auto& w : words) { + for (int j = 0; j < n; ++j) { + ++cnt[j][w[j] - 'a']; + } + } + int f[m][n]; + memset(f, -1, sizeof(f)); + function dfs = [&](int i, int j) -> int { + if (i >= m) { + return 1; + } + if (j >= n) { + return 0; + } + if (f[i][j] != -1) { + return f[i][j]; + } + int ans = dfs(i, j + 1); + ans = (ans + 1LL * dfs(i + 1, j + 1) * cnt[j][target[i] - 'a']) % mod; + return f[i][j] = ans; + }; + return dfs(0, 0); + } +}; +``` +### **Go** + +```go +func numWays(words []string, target string) int { + m, n := len(target), len(words[0]) + f := make([][]int, m) + cnt := make([][26]int, n) + for _, w := range words { + for j, c := range w { + cnt[j][c-'a']++ + } + } + for i := range f { + f[i] = make([]int, n) + for j := range f[i] { + f[i][j] = -1 + } + } + const mod = 1e9 + 7 + var dfs func(i, j int) int + dfs = func(i, j int) int { + if i >= m { + return 1 + } + if j >= n { + return 0 + } + if f[i][j] != -1 { + return f[i][j] + } + ans := dfs(i, j+1) + ans = (ans + dfs(i+1, j+1)*cnt[j][target[i]-'a']) % mod + f[i][j] = ans + return ans + } + return dfs(0, 0) +} ``` ### **...** diff --git a/solution/1600-1699/1639.Number of Ways to Form a Target String Given a Dictionary/README_EN.md b/solution/1600-1699/1639.Number of Ways to Form a Target String Given a Dictionary/README_EN.md index 19b59f6e0f0ad..79c2f577d7418 100644 --- a/solution/1600-1699/1639.Number of Ways to Form a Target String Given a Dictionary/README_EN.md +++ b/solution/1600-1699/1639.Number of Ways to Form a Target String Given a Dictionary/README_EN.md @@ -64,13 +64,143 @@ ### **Python3** ```python - +class Solution: + def numWays(self, words: List[str], target: str) -> int: + @cache + def dfs(i, j): + if i >= m: + return 1 + if j >= n: + return 0 + ans = dfs(i, j + 1) + dfs(i + 1, j + 1) * cnt[j][ord(target[i]) - ord("a")] + ans %= mod + return ans + + m = len(target) + n = len(words[0]) + cnt = [[0] * 26 for _ in range(n)] + for w in words: + for j, c in enumerate(w): + cnt[j][ord(c) - ord("a")] += 1 + mod = 10**9 + 7 + return dfs(0, 0) ``` ### **Java** ```java +class Solution { + private int m; + private int n; + private String target; + private Integer[][] f; + private int[][] cnt; + private final int mod = (int) 1e9 + 7; + + public int numWays(String[] words, String target) { + m = target.length(); + n = words[0].length(); + f = new Integer[m][n]; + this.target = target; + cnt = new int[n][26]; + for (var w : words) { + for (int j = 0; j < n; ++j) { + cnt[j][w.charAt(j) - 'a']++; + } + } + return dfs(0, 0); + } + + private int dfs(int i, int j) { + if (i >= m) { + return 1; + } + if (j >= n) { + return 0; + } + if (f[i][j] != null) { + return f[i][j]; + } + long ans = dfs(i, j + 1); + ans += 1L * dfs(i + 1, j + 1) * cnt[j][target.charAt(i) - 'a']; + ans %= mod; + return f[i][j] = (int) ans; + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + int numWays(vector& words, string target) { + const int mod = 1e9 + 7; + int m = target.size(), n = words[0].size(); + vector> cnt(n, vector(26)); + for (auto& w : words) { + for (int j = 0; j < n; ++j) { + ++cnt[j][w[j] - 'a']; + } + } + int f[m][n]; + memset(f, -1, sizeof(f)); + function dfs = [&](int i, int j) -> int { + if (i >= m) { + return 1; + } + if (j >= n) { + return 0; + } + if (f[i][j] != -1) { + return f[i][j]; + } + int ans = dfs(i, j + 1); + ans = (ans + 1LL * dfs(i + 1, j + 1) * cnt[j][target[i] - 'a']) % mod; + return f[i][j] = ans; + }; + return dfs(0, 0); + } +}; +``` +### **Go** + +```go +func numWays(words []string, target string) int { + m, n := len(target), len(words[0]) + f := make([][]int, m) + cnt := make([][26]int, n) + for _, w := range words { + for j, c := range w { + cnt[j][c-'a']++ + } + } + for i := range f { + f[i] = make([]int, n) + for j := range f[i] { + f[i][j] = -1 + } + } + const mod = 1e9 + 7 + var dfs func(i, j int) int + dfs = func(i, j int) int { + if i >= m { + return 1 + } + if j >= n { + return 0 + } + if f[i][j] != -1 { + return f[i][j] + } + ans := dfs(i, j+1) + ans = (ans + dfs(i+1, j+1)*cnt[j][target[i]-'a']) % mod + f[i][j] = ans + return ans + } + return dfs(0, 0) +} ``` ### **...** diff --git a/solution/1600-1699/1639.Number of Ways to Form a Target String Given a Dictionary/Solution.cpp b/solution/1600-1699/1639.Number of Ways to Form a Target String Given a Dictionary/Solution.cpp new file mode 100644 index 0000000000000..03384ce33ac09 --- /dev/null +++ b/solution/1600-1699/1639.Number of Ways to Form a Target String Given a Dictionary/Solution.cpp @@ -0,0 +1,30 @@ +class Solution { +public: + int numWays(vector& words, string target) { + const int mod = 1e9 + 7; + int m = target.size(), n = words[0].size(); + vector> cnt(n, vector(26)); + for (auto& w : words) { + for (int j = 0; j < n; ++j) { + ++cnt[j][w[j] - 'a']; + } + } + int f[m][n]; + memset(f, -1, sizeof(f)); + function dfs = [&](int i, int j) -> int { + if (i >= m) { + return 1; + } + if (j >= n) { + return 0; + } + if (f[i][j] != -1) { + return f[i][j]; + } + int ans = dfs(i, j + 1); + ans = (ans + 1LL * dfs(i + 1, j + 1) * cnt[j][target[i] - 'a']) % mod; + return f[i][j] = ans; + }; + return dfs(0, 0); + } +}; \ No newline at end of file diff --git a/solution/1600-1699/1639.Number of Ways to Form a Target String Given a Dictionary/Solution.go b/solution/1600-1699/1639.Number of Ways to Form a Target String Given a Dictionary/Solution.go new file mode 100644 index 0000000000000..0b1b33a356c46 --- /dev/null +++ b/solution/1600-1699/1639.Number of Ways to Form a Target String Given a Dictionary/Solution.go @@ -0,0 +1,34 @@ +func numWays(words []string, target string) int { + m, n := len(target), len(words[0]) + f := make([][]int, m) + cnt := make([][26]int, n) + for _, w := range words { + for j, c := range w { + cnt[j][c-'a']++ + } + } + for i := range f { + f[i] = make([]int, n) + for j := range f[i] { + f[i][j] = -1 + } + } + const mod = 1e9 + 7 + var dfs func(i, j int) int + dfs = func(i, j int) int { + if i >= m { + return 1 + } + if j >= n { + return 0 + } + if f[i][j] != -1 { + return f[i][j] + } + ans := dfs(i, j+1) + ans = (ans + dfs(i+1, j+1)*cnt[j][target[i]-'a']) % mod + f[i][j] = ans + return ans + } + return dfs(0, 0) +} \ No newline at end of file diff --git a/solution/1600-1699/1639.Number of Ways to Form a Target String Given a Dictionary/Solution.java b/solution/1600-1699/1639.Number of Ways to Form a Target String Given a Dictionary/Solution.java new file mode 100644 index 0000000000000..b3edd3ffd30d3 --- /dev/null +++ b/solution/1600-1699/1639.Number of Ways to Form a Target String Given a Dictionary/Solution.java @@ -0,0 +1,38 @@ +class Solution { + private int m; + private int n; + private String target; + private Integer[][] f; + private int[][] cnt; + private final int mod = (int) 1e9 + 7; + + public int numWays(String[] words, String target) { + m = target.length(); + n = words[0].length(); + f = new Integer[m][n]; + this.target = target; + cnt = new int[n][26]; + for (var w : words) { + for (int j = 0; j < n; ++j) { + cnt[j][w.charAt(j) - 'a']++; + } + } + return dfs(0, 0); + } + + private int dfs(int i, int j) { + if (i >= m) { + return 1; + } + if (j >= n) { + return 0; + } + if (f[i][j] != null) { + return f[i][j]; + } + long ans = dfs(i, j + 1); + ans += 1L * dfs(i + 1, j + 1) * cnt[j][target.charAt(i) - 'a']; + ans %= mod; + return f[i][j] = (int) ans; + } +} \ No newline at end of file diff --git a/solution/1600-1699/1639.Number of Ways to Form a Target String Given a Dictionary/Solution.py b/solution/1600-1699/1639.Number of Ways to Form a Target String Given a Dictionary/Solution.py new file mode 100644 index 0000000000000..ecaf51d770e92 --- /dev/null +++ b/solution/1600-1699/1639.Number of Ways to Form a Target String Given a Dictionary/Solution.py @@ -0,0 +1,20 @@ +class Solution: + def numWays(self, words: List[str], target: str) -> int: + @cache + def dfs(i, j): + if i >= m: + return 1 + if j >= n: + return 0 + ans = dfs(i, j + 1) + dfs(i + 1, j + 1) * cnt[j][ord(target[i]) - ord("a")] + ans %= mod + return ans + + m = len(target) + n = len(words[0]) + cnt = [[0] * 26 for _ in range(n)] + for w in words: + for j, c in enumerate(w): + cnt[j][ord(c) - ord("a")] += 1 + mod = 10**9 + 7 + return dfs(0, 0)