From 2db7e4e6c0273dd08cb00b0a6f0be7bf0011666b Mon Sep 17 00:00:00 2001 From: yanglbme Date: Mon, 17 Jun 2024 20:14:26 +0800 Subject: [PATCH] feat: add solutions to lc problems: No.524,525 * No.0524.Longest Word in Dictionary through Deleting * No.0525.Contiguous Array --- .../README.md | 179 +++++++++--------- .../README_EN.md | 179 +++++++++--------- .../Solution.cpp | 29 +-- .../Solution.go | 24 +-- .../Solution.java | 24 ++- .../Solution.py | 20 +- .../Solution.rs | 39 ++-- .../Solution.ts | 33 ++-- .../0500-0599/0525.Contiguous Array/README.md | 101 ++++++---- .../0525.Contiguous Array/README_EN.md | 101 ++++++---- .../0525.Contiguous Array/Solution.cpp | 16 +- .../0525.Contiguous Array/Solution.go | 16 +- .../0525.Contiguous Array/Solution.java | 12 +- .../0525.Contiguous Array/Solution.js | 14 +- .../0525.Contiguous Array/Solution.py | 14 +- .../0525.Contiguous Array/Solution.ts | 14 ++ 16 files changed, 452 insertions(+), 363 deletions(-) create mode 100644 solution/0500-0599/0525.Contiguous Array/Solution.ts diff --git a/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/README.md b/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/README.md index 72961426f104f..3449433c0f568 100644 --- a/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/README.md +++ b/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/README.md @@ -56,7 +56,13 @@ tags: -### 方法一 +### 方法一:判断子序列 + +我们定义一个函数 $check(s, t)$,用于判断字符串 $s$ 是否是字符串 $t$ 的子序列。我们可以使用双指针的方法,初始化两个指针 $i$ 和 $j$ 分别指向字符串 $s$ 和字符串 $t$ 的开头,然后不断移动指针 $j$,如果 $s[i]$ 和 $t[j]$ 相等,则移动指针 $i$,最后判断 $i$ 是否等于 $s$ 的长度即可。若 $i$ 等于 $s$ 的长度,则说明 $s$ 是 $t$ 的子序列。 + +我们初始化答案字符串 $ans$ 为空字符串,然后遍历数组 $dictionary$ 中的每个字符串 $t$,如果 $t$ 是 $s$ 的子序列,并且 $t$ 的长度大于 $ans$ 的长度,或者 $t$ 的长度等于 $ans$ 的长度且 $t$ 字典序小于 $ans$,则更新 $ans$ 为 $t$。 + +时间复杂度 $O(d \times (m + n))$,其中 $d$ 是字符串列表的长度,而 $m$ 和 $n$ 分别是字符串 $s$ 的长度和字符串列表中字符串的平均长度。空间复杂度 $O(1)$。 @@ -65,19 +71,19 @@ tags: ```python class Solution: def findLongestWord(self, s: str, dictionary: List[str]) -> str: - def check(a, b): - m, n = len(a), len(b) + def check(s: str, t: str) -> bool: + m, n = len(s), len(t) i = j = 0 while i < m and j < n: - if a[i] == b[j]: - j += 1 - i += 1 - return j == n - - ans = '' - for a in dictionary: - if check(s, a) and (len(ans) < len(a) or (len(ans) == len(a) and ans > a)): - ans = a + if s[i] == t[j]: + i += 1 + j += 1 + return i == m + + ans = "" + for t in dictionary: + if check(t, s) and (len(ans) < len(t) or (len(ans) == len(t) and ans > t)): + ans = t return ans ``` @@ -87,26 +93,24 @@ class Solution: class Solution { public String findLongestWord(String s, List dictionary) { String ans = ""; - for (String a : dictionary) { - if (check(s, a) - && (ans.length() < a.length() - || (ans.length() == a.length() && a.compareTo(ans) < 0))) { - ans = a; + for (String t : dictionary) { + int a = ans.length(), b = t.length(); + if (check(t, s) && (a < b || (a == b && t.compareTo(ans) < 0))) { + ans = t; } } return ans; } - private boolean check(String a, String b) { - int m = a.length(), n = b.length(); - int i = 0, j = 0; - while (i < m && j < n) { - if (a.charAt(i) == b.charAt(j)) { - ++j; + private boolean check(String s, String t) { + int m = s.length(), n = t.length(); + int i = 0; + for (int j = 0; i < m && j < n; ++j) { + if (s.charAt(i) == t.charAt(j)) { + ++i; } - ++i; } - return j == n; + return i == m; } } ``` @@ -118,20 +122,23 @@ class Solution { public: string findLongestWord(string s, vector& dictionary) { string ans = ""; - for (string& a : dictionary) - if (check(s, a) && (ans.size() < a.size() || (ans.size() == a.size() && a < ans))) - ans = a; - return ans; - } - - bool check(string& a, string& b) { - int m = a.size(), n = b.size(); - int i = 0, j = 0; - while (i < m && j < n) { - if (a[i] == b[j]) ++j; - ++i; + auto check = [&](const string& s, const string& t) { + int m = s.size(), n = t.size(); + int i = 0; + for (int j = 0; i < m && j < n; ++j) { + if (s[i] == t[j]) { + ++i; + } + } + return i == m; + }; + for (auto& t : dictionary) { + int a = ans.size(), b = t.size(); + if (check(t, s) && (a < b || (a == b && ans > t))) { + ans = t; + } } - return j == n; + return ans; } }; ``` @@ -140,21 +147,21 @@ public: ```go func findLongestWord(s string, dictionary []string) string { - ans := "" - check := func(a, b string) bool { - m, n := len(a), len(b) - i, j := 0, 0 - for i < m && j < n { - if a[i] == b[j] { - j++ + ans := '' + check := func(s, t string) bool { + m, n := len(s), len(t) + i := 0 + for j := 0; i < m && j < n; j++ { + if s[i] == t[j] { + i++ } - i++ } - return j == n + return i == m } - for _, a := range dictionary { - if check(s, a) && (len(ans) < len(a) || (len(ans) == len(a) && a < ans)) { - ans = a + for _, t := range dictionary { + a, b := len(ans), len(t) + if check(t, s) && (a < b || (a == b && ans > t)) { + ans = t } } return ans @@ -165,31 +172,24 @@ func findLongestWord(s string, dictionary []string) string { ```ts function findLongestWord(s: string, dictionary: string[]): string { - dictionary.sort((a, b) => { - if (a.length === b.length) { - return b < a ? 1 : -1; - } - return b.length - a.length; - }); - const n = s.length; - for (const target of dictionary) { - const m = target.length; - if (m > n) { - continue; - } + const check = (s: string, t: string): boolean => { + const [m, n] = [s.length, t.length]; let i = 0; - let j = 0; - while (i < n && j < m) { - if (s[i] === target[j]) { - j++; + for (let j = 0; i < m && j < n; ++j) { + if (s[i] === t[j]) { + ++i; } - i++; } - if (j === m) { - return target; + return i === m; + }; + let ans: string = ''; + for (const t of dictionary) { + const [a, b] = [ans.length, t.length]; + if (check(t, s) && (a < b || (a === b && ans > t))) { + ans = t; } } - return ''; + return ans; } ``` @@ -197,25 +197,32 @@ function findLongestWord(s: string, dictionary: string[]): string { ```rust impl Solution { - pub fn find_longest_word(s: String, mut dictionary: Vec) -> String { - dictionary.sort_unstable_by(|a, b| (b.len(), a).cmp(&(a.len(), b))); - for target in dictionary { - let target: Vec = target.chars().collect(); - let n = target.len(); - let mut i = 0; - for c in s.chars() { - if i == n { - break; - } - if c == target[i] { - i += 1; - } + pub fn find_longest_word(s: String, dictionary: Vec) -> String { + let mut ans = String::new(); + for t in dictionary { + let a = ans.len(); + let b = t.len(); + if Self::check(&t, &s) && (a < b || (a == b && t < ans)) { + ans = t; } - if i == n { - return target.iter().collect(); + } + ans + } + + fn check(s: &str, t: &str) -> bool { + let (m, n) = (s.len(), t.len()); + let mut i = 0; + let mut j = 0; + let s: Vec = s.chars().collect(); + let t: Vec = t.chars().collect(); + + while i < m && j < n { + if s[i] == t[j] { + i += 1; } + j += 1; } - String::new() + i == m } } ``` diff --git a/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/README_EN.md b/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/README_EN.md index a898a3e11e628..34ac49c771aee 100644 --- a/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/README_EN.md +++ b/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/README_EN.md @@ -52,7 +52,13 @@ tags: -### Solution 1 +### Solution 1: Subsequence Judgment + +We define a function $check(s, t)$ to determine whether string $s$ is a subsequence of string $t$. We can use a two-pointer approach, initializing two pointers $i$ and $j$ to point to the beginning of strings $s$ and $t$ respectively, then continuously move pointer $j$. If $s[i]$ equals $t[j]$, then move pointer $i$. Finally, check if $i$ equals the length of $s$. If $i$ equals the length of $s$, it means $s$ is a subsequence of $t$. + +We initialize the answer string $ans$ as an empty string. Then, we iterate through each string $t$ in the array $dictionary$. If $t$ is a subsequence of $s$, and the length of $t$ is greater than the length of $ans$, or the length of $t$ is equal to the length of $ans$ but $t$ is lexicographically smaller than $ans$, then we update $ans$ to $t$. + +The time complexity is $O(d \times (m + n))$, where $d$ is the length of the string list, and $m$ and $n$ are the lengths of string $s$ and the average length of strings in the list, respectively. The space complexity is $O(1)$. @@ -61,19 +67,19 @@ tags: ```python class Solution: def findLongestWord(self, s: str, dictionary: List[str]) -> str: - def check(a, b): - m, n = len(a), len(b) + def check(s: str, t: str) -> bool: + m, n = len(s), len(t) i = j = 0 while i < m and j < n: - if a[i] == b[j]: - j += 1 - i += 1 - return j == n - - ans = '' - for a in dictionary: - if check(s, a) and (len(ans) < len(a) or (len(ans) == len(a) and ans > a)): - ans = a + if s[i] == t[j]: + i += 1 + j += 1 + return i == m + + ans = "" + for t in dictionary: + if check(t, s) and (len(ans) < len(t) or (len(ans) == len(t) and ans > t)): + ans = t return ans ``` @@ -83,26 +89,24 @@ class Solution: class Solution { public String findLongestWord(String s, List dictionary) { String ans = ""; - for (String a : dictionary) { - if (check(s, a) - && (ans.length() < a.length() - || (ans.length() == a.length() && a.compareTo(ans) < 0))) { - ans = a; + for (String t : dictionary) { + int a = ans.length(), b = t.length(); + if (check(t, s) && (a < b || (a == b && t.compareTo(ans) < 0))) { + ans = t; } } return ans; } - private boolean check(String a, String b) { - int m = a.length(), n = b.length(); - int i = 0, j = 0; - while (i < m && j < n) { - if (a.charAt(i) == b.charAt(j)) { - ++j; + private boolean check(String s, String t) { + int m = s.length(), n = t.length(); + int i = 0; + for (int j = 0; i < m && j < n; ++j) { + if (s.charAt(i) == t.charAt(j)) { + ++i; } - ++i; } - return j == n; + return i == m; } } ``` @@ -114,20 +118,23 @@ class Solution { public: string findLongestWord(string s, vector& dictionary) { string ans = ""; - for (string& a : dictionary) - if (check(s, a) && (ans.size() < a.size() || (ans.size() == a.size() && a < ans))) - ans = a; - return ans; - } - - bool check(string& a, string& b) { - int m = a.size(), n = b.size(); - int i = 0, j = 0; - while (i < m && j < n) { - if (a[i] == b[j]) ++j; - ++i; + auto check = [&](const string& s, const string& t) { + int m = s.size(), n = t.size(); + int i = 0; + for (int j = 0; i < m && j < n; ++j) { + if (s[i] == t[j]) { + ++i; + } + } + return i == m; + }; + for (auto& t : dictionary) { + int a = ans.size(), b = t.size(); + if (check(t, s) && (a < b || (a == b && ans > t))) { + ans = t; + } } - return j == n; + return ans; } }; ``` @@ -136,21 +143,21 @@ public: ```go func findLongestWord(s string, dictionary []string) string { - ans := "" - check := func(a, b string) bool { - m, n := len(a), len(b) - i, j := 0, 0 - for i < m && j < n { - if a[i] == b[j] { - j++ + ans := '' + check := func(s, t string) bool { + m, n := len(s), len(t) + i := 0 + for j := 0; i < m && j < n; j++ { + if s[i] == t[j] { + i++ } - i++ } - return j == n + return i == m } - for _, a := range dictionary { - if check(s, a) && (len(ans) < len(a) || (len(ans) == len(a) && a < ans)) { - ans = a + for _, t := range dictionary { + a, b := len(ans), len(t) + if check(t, s) && (a < b || (a == b && ans > t)) { + ans = t } } return ans @@ -161,31 +168,24 @@ func findLongestWord(s string, dictionary []string) string { ```ts function findLongestWord(s: string, dictionary: string[]): string { - dictionary.sort((a, b) => { - if (a.length === b.length) { - return b < a ? 1 : -1; - } - return b.length - a.length; - }); - const n = s.length; - for (const target of dictionary) { - const m = target.length; - if (m > n) { - continue; - } + const check = (s: string, t: string): boolean => { + const [m, n] = [s.length, t.length]; let i = 0; - let j = 0; - while (i < n && j < m) { - if (s[i] === target[j]) { - j++; + for (let j = 0; i < m && j < n; ++j) { + if (s[i] === t[j]) { + ++i; } - i++; } - if (j === m) { - return target; + return i === m; + }; + let ans: string = ''; + for (const t of dictionary) { + const [a, b] = [ans.length, t.length]; + if (check(t, s) && (a < b || (a === b && ans > t))) { + ans = t; } } - return ''; + return ans; } ``` @@ -193,25 +193,32 @@ function findLongestWord(s: string, dictionary: string[]): string { ```rust impl Solution { - pub fn find_longest_word(s: String, mut dictionary: Vec) -> String { - dictionary.sort_unstable_by(|a, b| (b.len(), a).cmp(&(a.len(), b))); - for target in dictionary { - let target: Vec = target.chars().collect(); - let n = target.len(); - let mut i = 0; - for c in s.chars() { - if i == n { - break; - } - if c == target[i] { - i += 1; - } + pub fn find_longest_word(s: String, dictionary: Vec) -> String { + let mut ans = String::new(); + for t in dictionary { + let a = ans.len(); + let b = t.len(); + if Self::check(&t, &s) && (a < b || (a == b && t < ans)) { + ans = t; } - if i == n { - return target.iter().collect(); + } + ans + } + + fn check(s: &str, t: &str) -> bool { + let (m, n) = (s.len(), t.len()); + let mut i = 0; + let mut j = 0; + let s: Vec = s.chars().collect(); + let t: Vec = t.chars().collect(); + + while i < m && j < n { + if s[i] == t[j] { + i += 1; } + j += 1; } - String::new() + i == m } } ``` diff --git a/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/Solution.cpp b/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/Solution.cpp index ceb48033eb694..1e79b81c865ca 100644 --- a/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/Solution.cpp +++ b/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/Solution.cpp @@ -2,19 +2,22 @@ class Solution { public: string findLongestWord(string s, vector& dictionary) { string ans = ""; - for (string& a : dictionary) - if (check(s, a) && (ans.size() < a.size() || (ans.size() == a.size() && a < ans))) - ans = a; - return ans; - } - - bool check(string& a, string& b) { - int m = a.size(), n = b.size(); - int i = 0, j = 0; - while (i < m && j < n) { - if (a[i] == b[j]) ++j; - ++i; + auto check = [&](const string& s, const string& t) { + int m = s.size(), n = t.size(); + int i = 0; + for (int j = 0; i < m && j < n; ++j) { + if (s[i] == t[j]) { + ++i; + } + } + return i == m; + }; + for (auto& t : dictionary) { + int a = ans.size(), b = t.size(); + if (check(t, s) && (a < b || (a == b && ans > t))) { + ans = t; + } } - return j == n; + return ans; } }; \ No newline at end of file diff --git a/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/Solution.go b/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/Solution.go index 9fcb70ac278c9..51eae68cbd18f 100644 --- a/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/Solution.go +++ b/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/Solution.go @@ -1,19 +1,19 @@ func findLongestWord(s string, dictionary []string) string { - ans := "" - check := func(a, b string) bool { - m, n := len(a), len(b) - i, j := 0, 0 - for i < m && j < n { - if a[i] == b[j] { - j++ + ans := '' + check := func(s, t string) bool { + m, n := len(s), len(t) + i := 0 + for j := 0; i < m && j < n; j++ { + if s[i] == t[j] { + i++ } - i++ } - return j == n + return i == m } - for _, a := range dictionary { - if check(s, a) && (len(ans) < len(a) || (len(ans) == len(a) && a < ans)) { - ans = a + for _, t := range dictionary { + a, b := len(ans), len(t) + if check(t, s) && (a < b || (a == b && ans > t)) { + ans = t } } return ans diff --git a/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/Solution.java b/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/Solution.java index 0a412257d7f32..b557f009a5d86 100644 --- a/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/Solution.java +++ b/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/Solution.java @@ -1,25 +1,23 @@ class Solution { public String findLongestWord(String s, List dictionary) { String ans = ""; - for (String a : dictionary) { - if (check(s, a) - && (ans.length() < a.length() - || (ans.length() == a.length() && a.compareTo(ans) < 0))) { - ans = a; + for (String t : dictionary) { + int a = ans.length(), b = t.length(); + if (check(t, s) && (a < b || (a == b && t.compareTo(ans) < 0))) { + ans = t; } } return ans; } - private boolean check(String a, String b) { - int m = a.length(), n = b.length(); - int i = 0, j = 0; - while (i < m && j < n) { - if (a.charAt(i) == b.charAt(j)) { - ++j; + private boolean check(String s, String t) { + int m = s.length(), n = t.length(); + int i = 0; + for (int j = 0; i < m && j < n; ++j) { + if (s.charAt(i) == t.charAt(j)) { + ++i; } - ++i; } - return j == n; + return i == m; } } \ No newline at end of file diff --git a/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/Solution.py b/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/Solution.py index 4842805e1fe1a..adc634c77d292 100644 --- a/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/Solution.py +++ b/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/Solution.py @@ -1,16 +1,16 @@ class Solution: def findLongestWord(self, s: str, dictionary: List[str]) -> str: - def check(a, b): - m, n = len(a), len(b) + def check(s: str, t: str) -> bool: + m, n = len(s), len(t) i = j = 0 while i < m and j < n: - if a[i] == b[j]: - j += 1 - i += 1 - return j == n + if s[i] == t[j]: + i += 1 + j += 1 + return i == m - ans = '' - for a in dictionary: - if check(s, a) and (len(ans) < len(a) or (len(ans) == len(a) and ans > a)): - ans = a + ans = "" + for t in dictionary: + if check(t, s) and (len(ans) < len(t) or (len(ans) == len(t) and ans > t)): + ans = t return ans diff --git a/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/Solution.rs b/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/Solution.rs index de7e7529798e8..eaef4383c65df 100644 --- a/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/Solution.rs +++ b/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/Solution.rs @@ -1,22 +1,29 @@ impl Solution { - pub fn find_longest_word(s: String, mut dictionary: Vec) -> String { - dictionary.sort_unstable_by(|a, b| (b.len(), a).cmp(&(a.len(), b))); - for target in dictionary { - let target: Vec = target.chars().collect(); - let n = target.len(); - let mut i = 0; - for c in s.chars() { - if i == n { - break; - } - if c == target[i] { - i += 1; - } + pub fn find_longest_word(s: String, dictionary: Vec) -> String { + let mut ans = String::new(); + for t in dictionary { + let a = ans.len(); + let b = t.len(); + if Self::check(&t, &s) && (a < b || (a == b && t < ans)) { + ans = t; } - if i == n { - return target.iter().collect(); + } + ans + } + + fn check(s: &str, t: &str) -> bool { + let (m, n) = (s.len(), t.len()); + let mut i = 0; + let mut j = 0; + let s: Vec = s.chars().collect(); + let t: Vec = t.chars().collect(); + + while i < m && j < n { + if s[i] == t[j] { + i += 1; } + j += 1; } - String::new() + i == m } } diff --git a/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/Solution.ts b/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/Solution.ts index 0096427a49d4e..54d5c0ff9c3e8 100644 --- a/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/Solution.ts +++ b/solution/0500-0599/0524.Longest Word in Dictionary through Deleting/Solution.ts @@ -1,27 +1,20 @@ function findLongestWord(s: string, dictionary: string[]): string { - dictionary.sort((a, b) => { - if (a.length === b.length) { - return b < a ? 1 : -1; - } - return b.length - a.length; - }); - const n = s.length; - for (const target of dictionary) { - const m = target.length; - if (m > n) { - continue; - } + const check = (s: string, t: string): boolean => { + const [m, n] = [s.length, t.length]; let i = 0; - let j = 0; - while (i < n && j < m) { - if (s[i] === target[j]) { - j++; + for (let j = 0; i < m && j < n; ++j) { + if (s[i] === t[j]) { + ++i; } - i++; } - if (j === m) { - return target; + return i === m; + }; + let ans: string = ''; + for (const t of dictionary) { + const [a, b] = [ans.length, t.length]; + if (check(t, s) && (a < b || (a === b && ans > t))) { + ans = t; } } - return ''; + return ans; } diff --git a/solution/0500-0599/0525.Contiguous Array/README.md b/solution/0500-0599/0525.Contiguous Array/README.md index fc82eb988e6f8..0e49c1a1f4c82 100644 --- a/solution/0500-0599/0525.Contiguous Array/README.md +++ b/solution/0500-0599/0525.Contiguous Array/README.md @@ -51,7 +51,15 @@ tags: -### 方法一 +### 方法一:前缀和 + 哈希表 + +根据题目描述,我们可以将数组中的 $0$ 视作 $-1$,这样当遇到 $0$ 时,前缀和 $s$ 就会减一,当遇到 $1$ 时,前缀和 $s$ 就会加一。因此,假设前缀和 $s$ 在下标 $j$ 和 $i$ 处的值相等,其中 $j < i$,那么从下标 $j + 1$ 到 $i$ 的子数组中 $0$ 和 $1$ 的数量就是相等的。 + +我们使用哈希表存储所有的前缀和以及它们第一次出现的下标,初始时,我们将 $0$ 的前缀和映射到 $-1$。 + +遍历数组,计算前缀和 $s$,如果 $s$ 已经在哈希表中,那么我们就找到了一个和为 $0$ 的子数组,其长度为 $i - d[s]$,其中 $d[s]$ 是哈希表中保存的 $s$ 第一次出现的下标。如果 $s$ 不在哈希表中,我们将 $s$ 与它的下标 $i$ 存入哈希表。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组的长度。 @@ -60,14 +68,14 @@ tags: ```python class Solution: def findMaxLength(self, nums: List[int]) -> int: - s = ans = 0 - mp = {0: -1} - for i, v in enumerate(nums): - s += 1 if v == 1 else -1 - if s in mp: - ans = max(ans, i - mp[s]) + d = {0: -1} + ans = s = 0 + for i, x in enumerate(nums): + s += 1 if x else -1 + if s in d: + ans = max(ans, i - d[s]) else: - mp[s] = i + d[s] = i return ans ``` @@ -76,15 +84,15 @@ class Solution: ```java class Solution { public int findMaxLength(int[] nums) { - Map mp = new HashMap<>(); - mp.put(0, -1); - int s = 0, ans = 0; + Map d = new HashMap<>(); + d.put(0, -1); + int ans = 0, s = 0; for (int i = 0; i < nums.length; ++i) { s += nums[i] == 1 ? 1 : -1; - if (mp.containsKey(s)) { - ans = Math.max(ans, i - mp.get(s)); + if (d.containsKey(s)) { + ans = Math.max(ans, i - d.get(s)); } else { - mp.put(s, i); + d.put(s, i); } } return ans; @@ -98,15 +106,15 @@ class Solution { class Solution { public: int findMaxLength(vector& nums) { - unordered_map mp; - int s = 0, ans = 0; - mp[0] = -1; + unordered_map d{{0, -1}}; + int ans = 0, s = 0; for (int i = 0; i < nums.size(); ++i) { - s += nums[i] == 1 ? 1 : -1; - if (mp.count(s)) - ans = max(ans, i - mp[s]); - else - mp[s] = i; + s += nums[i] ? 1 : -1; + if (d.contains(s)) { + ans = max(ans, i - d[s]); + } else { + d[s] = i; + } } return ans; } @@ -117,23 +125,42 @@ public: ```go func findMaxLength(nums []int) int { - mp := map[int]int{0: -1} - s, ans := 0, 0 - for i, v := range nums { - if v == 0 { - v = -1 + d := map[int]int{0: -1} + ans, s := 0, 0 + for i, x := range nums { + if x == 0 { + x = -1 } - s += v - if j, ok := mp[s]; ok { + s += x + if j, ok := d[s]; ok { ans = max(ans, i-j) } else { - mp[s] = i + d[s] = i } } return ans } ``` +#### TypeScript + +```ts +function findMaxLength(nums: number[]): number { + const d: Record = { 0: -1 }; + let ans = 0; + let s = 0; + for (let i = 0; i < nums.length; ++i) { + s += nums[i] ? 1 : -1; + if (d.hasOwnProperty(s)) { + ans = Math.max(ans, i - d[s]); + } else { + d[s] = i; + } + } + return ans; +} +``` + #### JavaScript ```js @@ -142,14 +169,16 @@ func findMaxLength(nums []int) int { * @return {number} */ var findMaxLength = function (nums) { - const mp = new Map(); - mp.set(0, -1); - let s = 0; + const d = { 0: -1 }; let ans = 0; + let s = 0; for (let i = 0; i < nums.length; ++i) { - s += nums[i] == 0 ? -1 : 1; - if (mp.has(s)) ans = Math.max(ans, i - mp.get(s)); - else mp.set(s, i); + s += nums[i] ? 1 : -1; + if (d.hasOwnProperty(s)) { + ans = Math.max(ans, i - d[s]); + } else { + d[s] = i; + } } return ans; }; diff --git a/solution/0500-0599/0525.Contiguous Array/README_EN.md b/solution/0500-0599/0525.Contiguous Array/README_EN.md index 88760dd852a7c..8dfeb6693c9ae 100644 --- a/solution/0500-0599/0525.Contiguous Array/README_EN.md +++ b/solution/0500-0599/0525.Contiguous Array/README_EN.md @@ -51,7 +51,15 @@ tags: -### Solution 1 +### Solution 1: Prefix Sum + Hash Table + +According to the problem description, we can treat $0$s in the array as $-1$. In this way, when encountering a $0$, the prefix sum $s$ will decrease by one, and when encountering a $1$, the prefix sum $s$ will increase by one. Therefore, suppose the prefix sum $s$ is equal at indices $j$ and $i$, where $j < i$, then the subarray from index $j + 1$ to $i$ has an equal number of $0$s and $1$s. + +We use a hash table to store all prefix sums and their first occurrence indices. Initially, we map the prefix sum of $0$ to $-1$. + +As we iterate through the array, we calculate the prefix sum $s$. If $s$ is already in the hash table, then we have found a subarray with a sum of $0$, and its length is $i - d[s]$, where $d[s]$ is the index where $s$ first appeared in the hash table. If $s$ is not in the hash table, we store $s$ and its index $i$ in the hash table. + +The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the array. @@ -60,14 +68,14 @@ tags: ```python class Solution: def findMaxLength(self, nums: List[int]) -> int: - s = ans = 0 - mp = {0: -1} - for i, v in enumerate(nums): - s += 1 if v == 1 else -1 - if s in mp: - ans = max(ans, i - mp[s]) + d = {0: -1} + ans = s = 0 + for i, x in enumerate(nums): + s += 1 if x else -1 + if s in d: + ans = max(ans, i - d[s]) else: - mp[s] = i + d[s] = i return ans ``` @@ -76,15 +84,15 @@ class Solution: ```java class Solution { public int findMaxLength(int[] nums) { - Map mp = new HashMap<>(); - mp.put(0, -1); - int s = 0, ans = 0; + Map d = new HashMap<>(); + d.put(0, -1); + int ans = 0, s = 0; for (int i = 0; i < nums.length; ++i) { s += nums[i] == 1 ? 1 : -1; - if (mp.containsKey(s)) { - ans = Math.max(ans, i - mp.get(s)); + if (d.containsKey(s)) { + ans = Math.max(ans, i - d.get(s)); } else { - mp.put(s, i); + d.put(s, i); } } return ans; @@ -98,15 +106,15 @@ class Solution { class Solution { public: int findMaxLength(vector& nums) { - unordered_map mp; - int s = 0, ans = 0; - mp[0] = -1; + unordered_map d{{0, -1}}; + int ans = 0, s = 0; for (int i = 0; i < nums.size(); ++i) { - s += nums[i] == 1 ? 1 : -1; - if (mp.count(s)) - ans = max(ans, i - mp[s]); - else - mp[s] = i; + s += nums[i] ? 1 : -1; + if (d.contains(s)) { + ans = max(ans, i - d[s]); + } else { + d[s] = i; + } } return ans; } @@ -117,23 +125,42 @@ public: ```go func findMaxLength(nums []int) int { - mp := map[int]int{0: -1} - s, ans := 0, 0 - for i, v := range nums { - if v == 0 { - v = -1 + d := map[int]int{0: -1} + ans, s := 0, 0 + for i, x := range nums { + if x == 0 { + x = -1 } - s += v - if j, ok := mp[s]; ok { + s += x + if j, ok := d[s]; ok { ans = max(ans, i-j) } else { - mp[s] = i + d[s] = i } } return ans } ``` +#### TypeScript + +```ts +function findMaxLength(nums: number[]): number { + const d: Record = { 0: -1 }; + let ans = 0; + let s = 0; + for (let i = 0; i < nums.length; ++i) { + s += nums[i] ? 1 : -1; + if (d.hasOwnProperty(s)) { + ans = Math.max(ans, i - d[s]); + } else { + d[s] = i; + } + } + return ans; +} +``` + #### JavaScript ```js @@ -142,14 +169,16 @@ func findMaxLength(nums []int) int { * @return {number} */ var findMaxLength = function (nums) { - const mp = new Map(); - mp.set(0, -1); - let s = 0; + const d = { 0: -1 }; let ans = 0; + let s = 0; for (let i = 0; i < nums.length; ++i) { - s += nums[i] == 0 ? -1 : 1; - if (mp.has(s)) ans = Math.max(ans, i - mp.get(s)); - else mp.set(s, i); + s += nums[i] ? 1 : -1; + if (d.hasOwnProperty(s)) { + ans = Math.max(ans, i - d[s]); + } else { + d[s] = i; + } } return ans; }; diff --git a/solution/0500-0599/0525.Contiguous Array/Solution.cpp b/solution/0500-0599/0525.Contiguous Array/Solution.cpp index 7dfd55997f6af..25847230d7f4d 100644 --- a/solution/0500-0599/0525.Contiguous Array/Solution.cpp +++ b/solution/0500-0599/0525.Contiguous Array/Solution.cpp @@ -1,15 +1,15 @@ class Solution { public: int findMaxLength(vector& nums) { - unordered_map mp; - int s = 0, ans = 0; - mp[0] = -1; + unordered_map d{{0, -1}}; + int ans = 0, s = 0; for (int i = 0; i < nums.size(); ++i) { - s += nums[i] == 1 ? 1 : -1; - if (mp.count(s)) - ans = max(ans, i - mp[s]); - else - mp[s] = i; + s += nums[i] ? 1 : -1; + if (d.contains(s)) { + ans = max(ans, i - d[s]); + } else { + d[s] = i; + } } return ans; } diff --git a/solution/0500-0599/0525.Contiguous Array/Solution.go b/solution/0500-0599/0525.Contiguous Array/Solution.go index bbcba91ba465d..b50307088e5ab 100644 --- a/solution/0500-0599/0525.Contiguous Array/Solution.go +++ b/solution/0500-0599/0525.Contiguous Array/Solution.go @@ -1,15 +1,15 @@ func findMaxLength(nums []int) int { - mp := map[int]int{0: -1} - s, ans := 0, 0 - for i, v := range nums { - if v == 0 { - v = -1 + d := map[int]int{0: -1} + ans, s := 0, 0 + for i, x := range nums { + if x == 0 { + x = -1 } - s += v - if j, ok := mp[s]; ok { + s += x + if j, ok := d[s]; ok { ans = max(ans, i-j) } else { - mp[s] = i + d[s] = i } } return ans diff --git a/solution/0500-0599/0525.Contiguous Array/Solution.java b/solution/0500-0599/0525.Contiguous Array/Solution.java index dc84c023d479b..ea7d4e2798a96 100644 --- a/solution/0500-0599/0525.Contiguous Array/Solution.java +++ b/solution/0500-0599/0525.Contiguous Array/Solution.java @@ -1,14 +1,14 @@ class Solution { public int findMaxLength(int[] nums) { - Map mp = new HashMap<>(); - mp.put(0, -1); - int s = 0, ans = 0; + Map d = new HashMap<>(); + d.put(0, -1); + int ans = 0, s = 0; for (int i = 0; i < nums.length; ++i) { s += nums[i] == 1 ? 1 : -1; - if (mp.containsKey(s)) { - ans = Math.max(ans, i - mp.get(s)); + if (d.containsKey(s)) { + ans = Math.max(ans, i - d.get(s)); } else { - mp.put(s, i); + d.put(s, i); } } return ans; diff --git a/solution/0500-0599/0525.Contiguous Array/Solution.js b/solution/0500-0599/0525.Contiguous Array/Solution.js index 058f15c14fe13..d27304348adb2 100644 --- a/solution/0500-0599/0525.Contiguous Array/Solution.js +++ b/solution/0500-0599/0525.Contiguous Array/Solution.js @@ -3,14 +3,16 @@ * @return {number} */ var findMaxLength = function (nums) { - const mp = new Map(); - mp.set(0, -1); - let s = 0; + const d = { 0: -1 }; let ans = 0; + let s = 0; for (let i = 0; i < nums.length; ++i) { - s += nums[i] == 0 ? -1 : 1; - if (mp.has(s)) ans = Math.max(ans, i - mp.get(s)); - else mp.set(s, i); + s += nums[i] ? 1 : -1; + if (d.hasOwnProperty(s)) { + ans = Math.max(ans, i - d[s]); + } else { + d[s] = i; + } } return ans; }; diff --git a/solution/0500-0599/0525.Contiguous Array/Solution.py b/solution/0500-0599/0525.Contiguous Array/Solution.py index 2d3e77a2cb697..0c5c9dda41e48 100644 --- a/solution/0500-0599/0525.Contiguous Array/Solution.py +++ b/solution/0500-0599/0525.Contiguous Array/Solution.py @@ -1,11 +1,11 @@ class Solution: def findMaxLength(self, nums: List[int]) -> int: - s = ans = 0 - mp = {0: -1} - for i, v in enumerate(nums): - s += 1 if v == 1 else -1 - if s in mp: - ans = max(ans, i - mp[s]) + d = {0: -1} + ans = s = 0 + for i, x in enumerate(nums): + s += 1 if x else -1 + if s in d: + ans = max(ans, i - d[s]) else: - mp[s] = i + d[s] = i return ans diff --git a/solution/0500-0599/0525.Contiguous Array/Solution.ts b/solution/0500-0599/0525.Contiguous Array/Solution.ts new file mode 100644 index 0000000000000..78a9e385ff0f5 --- /dev/null +++ b/solution/0500-0599/0525.Contiguous Array/Solution.ts @@ -0,0 +1,14 @@ +function findMaxLength(nums: number[]): number { + const d: Record = { 0: -1 }; + let ans = 0; + let s = 0; + for (let i = 0; i < nums.length; ++i) { + s += nums[i] ? 1 : -1; + if (d.hasOwnProperty(s)) { + ans = Math.max(ans, i - d[s]); + } else { + d[s] = i; + } + } + return ans; +}