diff --git a/solution/1400-1499/1422.Maximum Score After Splitting a String/README.md b/solution/1400-1499/1422.Maximum Score After Splitting a String/README.md index 3bbc25b38b792..c52c53c201fcb 100644 --- a/solution/1400-1499/1422.Maximum Score After Splitting a String/README.md +++ b/solution/1400-1499/1422.Maximum Score After Splitting a String/README.md @@ -28,13 +28,13 @@ tags:
示例 1:
输入:s = "011101" -输出:5 +输出:5 解释: 将字符串 s 划分为两个非空子字符串的可行方案有: -左子字符串 = "0" 且 右子字符串 = "11101",得分 = 1 + 4 = 5 -左子字符串 = "01" 且 右子字符串 = "1101",得分 = 1 + 3 = 4 -左子字符串 = "011" 且 右子字符串 = "101",得分 = 1 + 2 = 3 -左子字符串 = "0111" 且 右子字符串 = "01",得分 = 1 + 1 = 2 +左子字符串 = "0" 且 右子字符串 = "11101",得分 = 1 + 4 = 5 +左子字符串 = "01" 且 右子字符串 = "1101",得分 = 1 + 3 = 4 +左子字符串 = "011" 且 右子字符串 = "101",得分 = 1 + 2 = 3 +左子字符串 = "0111" 且 右子字符串 = "01",得分 = 1 + 1 = 2 左子字符串 = "01110" 且 右子字符串 = "1",得分 = 2 + 1 = 3@@ -66,7 +66,13 @@ tags: -### 方法一 +### 方法一:计数 + +我们用两个变量 $l$ 和 $r$ 分别记录左子字符串中 $0$ 的数量和右子字符串中 $1$ 的数量。初始时 $l = 0$,而 $r$ 则等于字符串 $s$ 中 $1$ 的数量。 + +遍历字符串 $s$ 的前 $n - 1$ 个字符,对于每一个位置 $i$,如果 $s[i] = 0$,则 $l$ 自增 $1$,否则 $r$ 自减 $1$。然后我们更新答案为 $l + r$ 的最大值。 + +时间复杂度 $O(n)$,其中 $n$ 为字符串 $s$ 的长度。空间复杂度 $O(1)$。 @@ -75,7 +81,13 @@ tags: ```python class Solution: def maxScore(self, s: str) -> int: - return max(s[:i].count('0') + s[i:].count('1') for i in range(1, len(s))) + l, r = 0, s.count("1") + ans = 0 + for x in s[:-1]: + l += int(x) ^ 1 + r -= int(x) + ans = max(ans, l + r) + return ans ``` #### Java @@ -83,20 +95,18 @@ class Solution: ```java class Solution { public int maxScore(String s) { - int ans = 0; - for (int i = 1; i < s.length(); ++i) { - int t = 0; - for (int j = 0; j < i; ++j) { - if (s.charAt(j) == '0') { - ++t; - } - } - for (int j = i; j < s.length(); ++j) { - if (s.charAt(j) == '1') { - ++t; - } + int l = 0, r = 0; + int n = s.length(); + for (int i = 0; i < n; ++i) { + if (s.charAt(i) == '1') { + ++r; } - ans = Math.max(ans, t); + } + int ans = 0; + for (int i = 0; i < n - 1; ++i) { + l += (s.charAt(i) - '0') ^ 1; + r -= s.charAt(i) - '0'; + ans = Math.max(ans, l + r); } return ans; } @@ -109,16 +119,12 @@ class Solution { class Solution { public: int maxScore(string s) { + int l = 0, r = count(s.begin(), s.end(), '1'); int ans = 0; - for (int i = 1, n = s.size(); i < n; ++i) { - int t = 0; - for (int j = 0; j < i; ++j) { - t += s[j] == '0'; - } - for (int j = i; j < n; ++j) { - t += s[j] == '1'; - } - ans = max(ans, t); + for (int i = 0; i < s.size() - 1; ++i) { + l += (s[i] - '0') ^ 1; + r -= s[i] - '0'; + ans = max(ans, l + r); } return ans; } @@ -128,23 +134,17 @@ public: #### Go ```go -func maxScore(s string) int { - ans := 0 - for i, n := 1, len(s); i < n; i++ { - t := 0 - for j := 0; j < i; j++ { - if s[j] == '0' { - t++ - } - } - for j := i; j < n; j++ { - if s[j] == '1' { - t++ - } +func maxScore(s string) (ans int) { + l, r := 0, strings.Count(s, "1") + for _, c := range s[:len(s)-1] { + if c == '0' { + l++ + } else { + r-- } - ans = max(ans, t) + ans = max(ans, l+r) } - return ans + return } ``` @@ -152,27 +152,20 @@ func maxScore(s string) int { ```ts function maxScore(s: string): number { - const n = s.length; - let res = 0; - let score = 0; - if (s[0] === '0') { - score++; + let [l, r] = [0, 0]; + for (const c of s) { + r += c === '1' ? 1 : 0; } - for (let i = 1; i < n; i++) { - if (s[i] === '1') { - score++; - } - } - res = Math.max(res, score); - for (let i = 1; i < n - 1; i++) { + let ans = 0; + for (let i = 0; i < s.length - 1; ++i) { if (s[i] === '0') { - score++; - } else if (s[i] === '1') { - score--; + ++l; + } else { + --r; } - res = Math.max(res, score); + ans = Math.max(ans, l + r); } - return res; + return ans; } ``` @@ -181,121 +174,17 @@ function maxScore(s: string): number { ```rust impl Solution { pub fn max_score(s: String) -> i32 { - let n = s.len(); - let mut res = 0; - let mut score = 0; - let bs = s.as_bytes(); - if bs[0] == b'0' { - score += 1; - } - for i in 1..n { - if bs[i] == b'1' { - score += 1; - } - } - res = res.max(score); - for i in 1..n - 1 { - if bs[i] == b'0' { - score += 1; - } else if bs[i] == b'1' { - score -= 1; - } - res = res.max(score); - } - res - } -} -``` - - - - - - - -### 方法二 - - - -#### Python3 - -```python -class Solution: - def maxScore(self, s: str) -> int: - ans = t = (s[0] == '0') + s[1:].count('1') - for i in range(1, len(s) - 1): - t += 1 if s[i] == '0' else -1 - ans = max(ans, t) - return ans -``` - -#### Java - -```java -class Solution { - public int maxScore(String s) { - int t = 0; - if (s.charAt(0) == '0') { - t++; - } - for (int i = 1; i < s.length(); ++i) { - if (s.charAt(i) == '1') { - t++; - } - } - int ans = t; - for (int i = 1; i < s.length() - 1; ++i) { - t += s.charAt(i) == '0' ? 1 : -1; - ans = Math.max(ans, t); - } - return ans; - } -} -``` - -#### C++ - -```cpp -class Solution { -public: - int maxScore(string s) { - int t = 0; - if (s[0] == '0') ++t; - for (int i = 1; i < s.size(); ++i) t += s[i] == '1'; - int ans = t; - for (int i = 1; i < s.size() - 1; ++i) { - t += s[i] == '0' ? 1 : -1; - ans = max(ans, t); + let mut l = 0; + let mut r = s.bytes().filter(|&b| b == b'1').count() as i32; + let mut ans = 0; + let cs = s.as_bytes(); + for i in 0..s.len() - 1 { + l += ((cs[i] - b'0') ^ 1) as i32; + r -= (cs[i] - b'0') as i32; + ans = ans.max(l + r); } - return ans; + ans } -}; -``` - -#### Go - -```go -func maxScore(s string) int { - t := 0 - if s[0] == '0' { - t++ - } - n := len(s) - for i := 1; i < n; i++ { - if s[i] == '1' { - t++ - } - } - ans := t - for i := 1; i < n-1; i++ { - if s[i] == '0' { - t++ - } else { - t-- - } - ans = max(ans, t) - } - return ans } ``` diff --git a/solution/1400-1499/1422.Maximum Score After Splitting a String/README_EN.md b/solution/1400-1499/1422.Maximum Score After Splitting a String/README_EN.md index 835d2d1d96eda..7baca8a654425 100644 --- a/solution/1400-1499/1422.Maximum Score After Splitting a String/README_EN.md +++ b/solution/1400-1499/1422.Maximum Score After Splitting a String/README_EN.md @@ -28,13 +28,13 @@ tags:
Input: s = "011101" -Output: 5 -Explanation: +Output: 5 +Explanation: All possible ways of splitting s into two non-empty substrings are: -left = "0" and right = "11101", score = 1 + 4 = 5 -left = "01" and right = "1101", score = 1 + 3 = 4 -left = "011" and right = "101", score = 1 + 2 = 3 -left = "0111" and right = "01", score = 1 + 1 = 2 +left = "0" and right = "11101", score = 1 + 4 = 5 +left = "01" and right = "1101", score = 1 + 3 = 4 +left = "011" and right = "101", score = 1 + 2 = 3 +left = "0111" and right = "01", score = 1 + 1 = 2 left = "01110" and right = "1", score = 2 + 1 = 3@@ -67,7 +67,13 @@ left = "01110" and right = "1", score = 2 + 1 = 3 -### Solution 1 +### Solution 1: Counting + +We use two variables $l$ and $r$ to record the number of 0s in the left substring and the number of 1s in the right substring, respectively. Initially, $l = 0$, and $r$ is equal to the number of 1s in the string $s$. + +We traverse the first $n - 1$ characters of the string $s$. For each position $i$, if $s[i] = 0$, then $l$ is incremented by 1; otherwise, $r$ is decremented by 1. Then we update the answer to be the maximum value of $l + r$. + +The time complexity is $O(n)$, where $n$ is the length of the string $s$. The space complexity is $O(1)$. @@ -76,7 +82,13 @@ left = "01110" and right = "1", score = 2 + 1 = 3 ```python class Solution: def maxScore(self, s: str) -> int: - return max(s[:i].count('0') + s[i:].count('1') for i in range(1, len(s))) + l, r = 0, s.count("1") + ans = 0 + for x in s[:-1]: + l += int(x) ^ 1 + r -= int(x) + ans = max(ans, l + r) + return ans ``` #### Java @@ -84,20 +96,18 @@ class Solution: ```java class Solution { public int maxScore(String s) { - int ans = 0; - for (int i = 1; i < s.length(); ++i) { - int t = 0; - for (int j = 0; j < i; ++j) { - if (s.charAt(j) == '0') { - ++t; - } - } - for (int j = i; j < s.length(); ++j) { - if (s.charAt(j) == '1') { - ++t; - } + int l = 0, r = 0; + int n = s.length(); + for (int i = 0; i < n; ++i) { + if (s.charAt(i) == '1') { + ++r; } - ans = Math.max(ans, t); + } + int ans = 0; + for (int i = 0; i < n - 1; ++i) { + l += (s.charAt(i) - '0') ^ 1; + r -= s.charAt(i) - '0'; + ans = Math.max(ans, l + r); } return ans; } @@ -110,16 +120,12 @@ class Solution { class Solution { public: int maxScore(string s) { + int l = 0, r = count(s.begin(), s.end(), '1'); int ans = 0; - for (int i = 1, n = s.size(); i < n; ++i) { - int t = 0; - for (int j = 0; j < i; ++j) { - t += s[j] == '0'; - } - for (int j = i; j < n; ++j) { - t += s[j] == '1'; - } - ans = max(ans, t); + for (int i = 0; i < s.size() - 1; ++i) { + l += (s[i] - '0') ^ 1; + r -= s[i] - '0'; + ans = max(ans, l + r); } return ans; } @@ -129,23 +135,17 @@ public: #### Go ```go -func maxScore(s string) int { - ans := 0 - for i, n := 1, len(s); i < n; i++ { - t := 0 - for j := 0; j < i; j++ { - if s[j] == '0' { - t++ - } - } - for j := i; j < n; j++ { - if s[j] == '1' { - t++ - } +func maxScore(s string) (ans int) { + l, r := 0, strings.Count(s, "1") + for _, c := range s[:len(s)-1] { + if c == '0' { + l++ + } else { + r-- } - ans = max(ans, t) + ans = max(ans, l+r) } - return ans + return } ``` @@ -153,27 +153,20 @@ func maxScore(s string) int { ```ts function maxScore(s: string): number { - const n = s.length; - let res = 0; - let score = 0; - if (s[0] === '0') { - score++; + let [l, r] = [0, 0]; + for (const c of s) { + r += c === '1' ? 1 : 0; } - for (let i = 1; i < n; i++) { - if (s[i] === '1') { - score++; - } - } - res = Math.max(res, score); - for (let i = 1; i < n - 1; i++) { + let ans = 0; + for (let i = 0; i < s.length - 1; ++i) { if (s[i] === '0') { - score++; - } else if (s[i] === '1') { - score--; + ++l; + } else { + --r; } - res = Math.max(res, score); + ans = Math.max(ans, l + r); } - return res; + return ans; } ``` @@ -182,121 +175,17 @@ function maxScore(s: string): number { ```rust impl Solution { pub fn max_score(s: String) -> i32 { - let n = s.len(); - let mut res = 0; - let mut score = 0; - let bs = s.as_bytes(); - if bs[0] == b'0' { - score += 1; - } - for i in 1..n { - if bs[i] == b'1' { - score += 1; - } - } - res = res.max(score); - for i in 1..n - 1 { - if bs[i] == b'0' { - score += 1; - } else if bs[i] == b'1' { - score -= 1; - } - res = res.max(score); - } - res - } -} -``` - - - - - - - -### Solution 2 - - - -#### Python3 - -```python -class Solution: - def maxScore(self, s: str) -> int: - ans = t = (s[0] == '0') + s[1:].count('1') - for i in range(1, len(s) - 1): - t += 1 if s[i] == '0' else -1 - ans = max(ans, t) - return ans -``` - -#### Java - -```java -class Solution { - public int maxScore(String s) { - int t = 0; - if (s.charAt(0) == '0') { - t++; - } - for (int i = 1; i < s.length(); ++i) { - if (s.charAt(i) == '1') { - t++; - } - } - int ans = t; - for (int i = 1; i < s.length() - 1; ++i) { - t += s.charAt(i) == '0' ? 1 : -1; - ans = Math.max(ans, t); - } - return ans; - } -} -``` - -#### C++ - -```cpp -class Solution { -public: - int maxScore(string s) { - int t = 0; - if (s[0] == '0') ++t; - for (int i = 1; i < s.size(); ++i) t += s[i] == '1'; - int ans = t; - for (int i = 1; i < s.size() - 1; ++i) { - t += s[i] == '0' ? 1 : -1; - ans = max(ans, t); + let mut l = 0; + let mut r = s.bytes().filter(|&b| b == b'1').count() as i32; + let mut ans = 0; + let cs = s.as_bytes(); + for i in 0..s.len() - 1 { + l += ((cs[i] - b'0') ^ 1) as i32; + r -= (cs[i] - b'0') as i32; + ans = ans.max(l + r); } - return ans; + ans } -}; -``` - -#### Go - -```go -func maxScore(s string) int { - t := 0 - if s[0] == '0' { - t++ - } - n := len(s) - for i := 1; i < n; i++ { - if s[i] == '1' { - t++ - } - } - ans := t - for i := 1; i < n-1; i++ { - if s[i] == '0' { - t++ - } else { - t-- - } - ans = max(ans, t) - } - return ans } ``` diff --git a/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution.cpp b/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution.cpp index f78ec22439dcc..bf8dbbfefbf61 100644 --- a/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution.cpp +++ b/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution.cpp @@ -1,17 +1,13 @@ class Solution { public: int maxScore(string s) { + int l = 0, r = count(s.begin(), s.end(), '1'); int ans = 0; - for (int i = 1, n = s.size(); i < n; ++i) { - int t = 0; - for (int j = 0; j < i; ++j) { - t += s[j] == '0'; - } - for (int j = i; j < n; ++j) { - t += s[j] == '1'; - } - ans = max(ans, t); + for (int i = 0; i < s.size() - 1; ++i) { + l += (s[i] - '0') ^ 1; + r -= s[i] - '0'; + ans = max(ans, l + r); } return ans; } -}; \ No newline at end of file +}; diff --git a/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution.go b/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution.go index 901ebc0bb8520..8c30ed90ece93 100644 --- a/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution.go +++ b/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution.go @@ -1,18 +1,12 @@ -func maxScore(s string) int { - ans := 0 - for i, n := 1, len(s); i < n; i++ { - t := 0 - for j := 0; j < i; j++ { - if s[j] == '0' { - t++ - } +func maxScore(s string) (ans int) { + l, r := 0, strings.Count(s, "1") + for _, c := range s[:len(s)-1] { + if c == '0' { + l++ + } else { + r-- } - for j := i; j < n; j++ { - if s[j] == '1' { - t++ - } - } - ans = max(ans, t) + ans = max(ans, l+r) } - return ans -} \ No newline at end of file + return +} diff --git a/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution.java b/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution.java index e3dad9d463fe2..62f0ab1478582 100644 --- a/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution.java +++ b/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution.java @@ -1,20 +1,18 @@ class Solution { public int maxScore(String s) { - int ans = 0; - for (int i = 1; i < s.length(); ++i) { - int t = 0; - for (int j = 0; j < i; ++j) { - if (s.charAt(j) == '0') { - ++t; - } - } - for (int j = i; j < s.length(); ++j) { - if (s.charAt(j) == '1') { - ++t; - } + int l = 0, r = 0; + int n = s.length(); + for (int i = 0; i < n; ++i) { + if (s.charAt(i) == '1') { + ++r; } - ans = Math.max(ans, t); + } + int ans = 0; + for (int i = 0; i < n - 1; ++i) { + l += (s.charAt(i) - '0') ^ 1; + r -= s.charAt(i) - '0'; + ans = Math.max(ans, l + r); } return ans; } -} \ No newline at end of file +} diff --git a/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution.py b/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution.py index ab07d81eec3ef..57827a3472cf4 100644 --- a/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution.py +++ b/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution.py @@ -1,3 +1,9 @@ class Solution: def maxScore(self, s: str) -> int: - return max(s[:i].count('0') + s[i:].count('1') for i in range(1, len(s))) + l, r = 0, s.count("1") + ans = 0 + for x in s[:-1]: + l += int(x) ^ 1 + r -= int(x) + ans = max(ans, l + r) + return ans diff --git a/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution.rs b/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution.rs index 4f7142e3d7597..a88411fb0c0fe 100644 --- a/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution.rs +++ b/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution.rs @@ -1,26 +1,14 @@ impl Solution { pub fn max_score(s: String) -> i32 { - let n = s.len(); - let mut res = 0; - let mut score = 0; - let bs = s.as_bytes(); - if bs[0] == b'0' { - score += 1; + let mut l = 0; + let mut r = s.bytes().filter(|&b| b == b'1').count() as i32; + let mut ans = 0; + let cs = s.as_bytes(); + for i in 0..s.len() - 1 { + l += ((cs[i] - b'0') ^ 1) as i32; + r -= (cs[i] - b'0') as i32; + ans = ans.max(l + r); } - for i in 1..n { - if bs[i] == b'1' { - score += 1; - } - } - res = res.max(score); - for i in 1..n - 1 { - if bs[i] == b'0' { - score += 1; - } else if bs[i] == b'1' { - score -= 1; - } - res = res.max(score); - } - res + ans } } diff --git a/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution.ts b/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution.ts index f8253a8503772..398485704c0c2 100644 --- a/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution.ts +++ b/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution.ts @@ -1,23 +1,16 @@ function maxScore(s: string): number { - const n = s.length; - let res = 0; - let score = 0; - if (s[0] === '0') { - score++; + let [l, r] = [0, 0]; + for (const c of s) { + r += c === '1' ? 1 : 0; } - for (let i = 1; i < n; i++) { - if (s[i] === '1') { - score++; - } - } - res = Math.max(res, score); - for (let i = 1; i < n - 1; i++) { + let ans = 0; + for (let i = 0; i < s.length - 1; ++i) { if (s[i] === '0') { - score++; - } else if (s[i] === '1') { - score--; + ++l; + } else { + --r; } - res = Math.max(res, score); + ans = Math.max(ans, l + r); } - return res; + return ans; } diff --git a/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution2.cpp b/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution2.cpp deleted file mode 100644 index 3109efd6356e9..0000000000000 --- a/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution2.cpp +++ /dev/null @@ -1,14 +0,0 @@ -class Solution { -public: - int maxScore(string s) { - int t = 0; - if (s[0] == '0') ++t; - for (int i = 1; i < s.size(); ++i) t += s[i] == '1'; - int ans = t; - for (int i = 1; i < s.size() - 1; ++i) { - t += s[i] == '0' ? 1 : -1; - ans = max(ans, t); - } - return ans; - } -}; \ No newline at end of file diff --git a/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution2.go b/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution2.go deleted file mode 100644 index 26aad8e48a855..0000000000000 --- a/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution2.go +++ /dev/null @@ -1,22 +0,0 @@ -func maxScore(s string) int { - t := 0 - if s[0] == '0' { - t++ - } - n := len(s) - for i := 1; i < n; i++ { - if s[i] == '1' { - t++ - } - } - ans := t - for i := 1; i < n-1; i++ { - if s[i] == '0' { - t++ - } else { - t-- - } - ans = max(ans, t) - } - return ans -} \ No newline at end of file diff --git a/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution2.java b/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution2.java deleted file mode 100644 index 2af2f65f0d499..0000000000000 --- a/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution2.java +++ /dev/null @@ -1,19 +0,0 @@ -class Solution { - public int maxScore(String s) { - int t = 0; - if (s.charAt(0) == '0') { - t++; - } - for (int i = 1; i < s.length(); ++i) { - if (s.charAt(i) == '1') { - t++; - } - } - int ans = t; - for (int i = 1; i < s.length() - 1; ++i) { - t += s.charAt(i) == '0' ? 1 : -1; - ans = Math.max(ans, t); - } - return ans; - } -} \ No newline at end of file diff --git a/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution2.py b/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution2.py deleted file mode 100644 index 04eb3724a077c..0000000000000 --- a/solution/1400-1499/1422.Maximum Score After Splitting a String/Solution2.py +++ /dev/null @@ -1,7 +0,0 @@ -class Solution: - def maxScore(self, s: str) -> int: - ans = t = (s[0] == '0') + s[1:].count('1') - for i in range(1, len(s) - 1): - t += 1 if s[i] == '0' else -1 - ans = max(ans, t) - return ans diff --git a/solution/1400-1499/1424.Diagonal Traverse II/README.md b/solution/1400-1499/1424.Diagonal Traverse II/README.md index 48385ce570025..f515c12354555 100644 --- a/solution/1400-1499/1424.Diagonal Traverse II/README.md +++ b/solution/1400-1499/1424.Diagonal Traverse II/README.md @@ -77,9 +77,9 @@ tags: - 下一条对角线的 $i + j$ 的值比前一条对角线的大; - 在同一条对角线中的 $i + j$ 是相同的,而 $j$ 值是从小到大递增。 -因此,我们将所有数字以 `(i + j, j, nums[i][j])` 的形式存进 `arr`,然后按照前两项排序。最后返回 `arr` 所有元素第二项组成的数组即可。 +因此,我们将所有数字以 $(i, j, \textit{nums}[i][j])$ 的形式存进 $\textit{arr}$,然后按照前两项排序。最后返回 $\textit{arr}$ 所有元素下标为 $2$ 的值组成的数组即可。 -时间复杂度 $O(n\log n)$,其中 $n$ 是 `nums` 数组元素的个数。 +时间复杂度 $O(n \times \log n)$,其中 $n$ 是数组 $\textit{nums}$ 中元素的个数。空间复杂度 $O(n)$。 @@ -163,6 +163,21 @@ func findDiagonalOrder(nums [][]int) []int { } ``` +#### TypeScript + +```ts +function findDiagonalOrder(nums: number[][]): number[] { + const arr: number[][] = []; + for (let i = 0; i < nums.length; ++i) { + for (let j = 0; j < nums[i].length; ++j) { + arr.push([i + j, j, nums[i][j]]); + } + } + arr.sort((a, b) => (a[0] === b[0] ? a[1] - b[1] : a[0] - b[0])); + return arr.map(x => x[2]); +} +``` + #### C# ```cs diff --git a/solution/1400-1499/1424.Diagonal Traverse II/README_EN.md b/solution/1400-1499/1424.Diagonal Traverse II/README_EN.md index d3001f93376b6..0e428edd54e24 100644 --- a/solution/1400-1499/1424.Diagonal Traverse II/README_EN.md +++ b/solution/1400-1499/1424.Diagonal Traverse II/README_EN.md @@ -53,7 +53,17 @@ tags: -### Solution 1 +### Solution 1: Sorting + +We observe that: + +- The value of $i + j$ is the same for each diagonal; +- The value of $i + j$ for the next diagonal is greater than that of the previous diagonal; +- Within the same diagonal, the value of $i + j$ is the same, and the value of $j$ increases from small to large. + +Therefore, we store all numbers in the form of $(i, j, \textit{nums}[i][j])$ into $\textit{arr}$, and then sort according to the first two items. Finally, return the array composed of the values at index 2 of all elements in $\textit{arr}$. + +The time complexity is $O(n \times \log n)$, where $n$ is the number of elements in the array $\textit{nums}$. The space complexity is $O(n)$. @@ -137,6 +147,21 @@ func findDiagonalOrder(nums [][]int) []int { } ``` +#### TypeScript + +```ts +function findDiagonalOrder(nums: number[][]): number[] { + const arr: number[][] = []; + for (let i = 0; i < nums.length; ++i) { + for (let j = 0; j < nums[i].length; ++j) { + arr.push([i + j, j, nums[i][j]]); + } + } + arr.sort((a, b) => (a[0] === b[0] ? a[1] - b[1] : a[0] - b[0])); + return arr.map(x => x[2]); +} +``` + #### C# ```cs diff --git a/solution/1400-1499/1424.Diagonal Traverse II/Solution.ts b/solution/1400-1499/1424.Diagonal Traverse II/Solution.ts new file mode 100644 index 0000000000000..bd3c93ca6fd96 --- /dev/null +++ b/solution/1400-1499/1424.Diagonal Traverse II/Solution.ts @@ -0,0 +1,10 @@ +function findDiagonalOrder(nums: number[][]): number[] { + const arr: number[][] = []; + for (let i = 0; i < nums.length; ++i) { + for (let j = 0; j < nums[i].length; ++j) { + arr.push([i + j, j, nums[i][j]]); + } + } + arr.sort((a, b) => (a[0] === b[0] ? a[1] - b[1] : a[0] - b[0])); + return arr.map(x => x[2]); +} diff --git a/solution/1400-1499/1425.Constrained Subsequence Sum/README.md b/solution/1400-1499/1425.Constrained Subsequence Sum/README.md index f96e8760a7d7c..3fd8621508fc5 100644 --- a/solution/1400-1499/1425.Constrained Subsequence Sum/README.md +++ b/solution/1400-1499/1425.Constrained Subsequence Sum/README.md @@ -67,6 +67,23 @@ tags: ### 方法一:动态规划 + 单调队列 +我们定义 $f[i]$ 表示以 $\textit{nums}[i]$ 结尾的满足条件的子序列的最大和。初始时 $f[i] = 0$,答案为 $\max_{0 \leq i \lt n} f(i)$。 + +我们注意到题目需要我们维护滑动窗口的最大值,这就是一个典型的单调队列应用场景。我们可以使用单调队列来优化动态规划的转移。 + +我们维护一个从队首到队尾单调递减的单调队列 $q$,队列中存储的是下标 $i$,初始时,我们将一个哨兵 $0$ 加入队列中。 + +我们遍历 $i$ 从 $0$ 到 $n - 1$,对于每个 $i$,我们执行以下操作: + +- 如果队首元素 $q[0]$ 满足 $i - q[0] > k$,说明队首元素已经不在滑动窗口内,我们需要从队首弹出队首元素; +- 然后,我们计算 $f[i] = \max(0, f[q[0]]) + \textit{nums}[i]$,表示我们将 $\textit{nums}[i]$ 加入滑动窗口后的最大子序列和; +- 接下来,我们更新答案 $\textit{ans} = \max(\textit{ans}, f[i])$; +- 最后,我们将 $i$ 加入队列尾部,并且保持队列的单调性,即如果 $f[q[\textit{back}]] \leq f[i]$,我们需要将队尾元素弹出,直到队列为空或者 $f[q[\textit{back}]] > f[i]$。 + +最终答案即为 $\textit{ans}$。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $\textit{nums}$ 的长度。 + #### Python3 @@ -74,18 +91,18 @@ tags: ```python class Solution: def constrainedSubsetSum(self, nums: List[int], k: int) -> int: + q = deque([0]) n = len(nums) - dp = [0] * n + f = [0] * n ans = -inf - q = deque() - for i, v in enumerate(nums): - if q and i - q[0] > k: + for i, x in enumerate(nums): + while i - q[0] > k: q.popleft() - dp[i] = max(0, 0 if not q else dp[q[0]]) + v - while q and dp[q[-1]] <= dp[i]: + f[i] = max(0, f[q[0]]) + x + ans = max(ans, f[i]) + while q and f[q[-1]] <= f[i]: q.pop() q.append(i) - ans = max(ans, dp[i]) return ans ``` @@ -94,20 +111,21 @@ class Solution: ```java class Solution { public int constrainedSubsetSum(int[] nums, int k) { - int n = nums.length; - int[] dp = new int[n]; - int ans = Integer.MIN_VALUE; Deque