Skip to content

Commit 566b1b1

Browse files
authored
feat: add biweekly contest 167 (#4779)
1 parent 45411c3 commit 566b1b1

File tree

35 files changed

+2318
-2
lines changed

35 files changed

+2318
-2
lines changed
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
---
2+
comments: true
3+
difficulty: 简单
4+
edit_url: https://github.com/doocs/leetcode/edit/main/solution/3700-3799/3707.Equal%20Score%20Substrings/README.md
5+
---
6+
7+
<!-- problem:start -->
8+
9+
# [3707. 相等子字符串分数](https://leetcode.cn/problems/equal-score-substrings)
10+
11+
[English Version](/solution/3700-3799/3707.Equal%20Score%20Substrings/README_EN.md)
12+
13+
## 题目描述
14+
15+
<!-- description:start -->
16+
17+
<p>给你一个由小写英文字母组成的字符串 <code>s</code>。</p>
18+
19+
<p>一个字符串的&nbsp;<strong>得分&nbsp;</strong>是其字符在字母表中的位置之和,其中 <code>'a' = 1</code>,<code>'b' = 2</code>,...,<code>'z' = 26</code>。</p>
20+
21+
<p>请你判断是否存在一个下标&nbsp;<code>i</code>,使得该字符串可以被拆分成两个&nbsp;<strong>非空子字符串</strong> <code>s[0..i]</code> 和 <code>s[(i + 1)..(n - 1)]</code>,且它们的得分&nbsp;<strong>相等&nbsp;</strong>。</p>
22+
23+
<p>如果存在这样的拆分,则返回 <code>true</code>,否则返回 <code>false</code>。</p>
24+
25+
<p>一个&nbsp;<strong>子字符串&nbsp;</strong>是字符串中&nbsp;<strong>非空&nbsp;</strong>的连续字符序列。</p>
26+
27+
<p>&nbsp;</p>
28+
29+
<p><strong class="example">示例 1:</strong></p>
30+
31+
<div class="example-block">
32+
<p><strong>输入:</strong> <span class="example-io">s = "adcb"</span></p>
33+
34+
<p><strong>输出:</strong> <span class="example-io">true</span></p>
35+
36+
<p><strong>解释:</strong></p>
37+
38+
<p>在下标&nbsp;<code>i = 1</code> 处拆分:</p>
39+
40+
<ul>
41+
<li>左子字符串 = <code>s[0..1] = "ad"</code>,得分 =&nbsp;<code>1 + 4 = 5</code></li>
42+
<li>右子字符串 = <code>s[2..3] = "cb"</code>,得分 = <code>3 + 2 = 5</code></li>
43+
</ul>
44+
45+
<p>两个子字符串的得分相等,因此输出为 <code>true</code>。</p>
46+
</div>
47+
48+
<p><strong class="example">示例 2:</strong></p>
49+
50+
<div class="example-block">
51+
<p><strong>输入:</strong> <span class="example-io">s = "bace"</span></p>
52+
53+
<p><strong>输出:</strong> <span class="example-io">false</span></p>
54+
55+
<p><strong>解释:​​​​​​</strong></p>
56+
57+
<p>没有拆分能产生相等的得分,因此输出为 <code>false</code>。</p>
58+
</div>
59+
60+
<p>&nbsp;</p>
61+
62+
<p><strong>提示:</strong></p>
63+
64+
<ul>
65+
<li><code>2 &lt;= s.length &lt;= 100</code></li>
66+
<li><code>s</code> 由小写英文字母组成。</li>
67+
</ul>
68+
69+
<!-- description:end -->
70+
71+
## 解法
72+
73+
<!-- solution:start -->
74+
75+
### 方法一:前缀和
76+
77+
我们先计算字符串的总得分,记为 $r$。然后我们从左到右遍历前 $n-1$ 个字符,计算前缀得分 $l$,并更新后缀得分 $r$。如果在某个位置 $i$,前缀得分 $l$ 等于后缀得分 $r$,则说明存在一个下标 $i$ 可以将字符串拆分成两个得分相等的子字符串,返回 $\textit{true}$。如果遍历结束后仍未找到这样的下标,返回 $\textit{false}$。
78+
79+
时间复杂度 $O(n)$,其中 $n$ 是字符串的长度。空间复杂度 $O(1)$。
80+
81+
<!-- tabs:start -->
82+
83+
#### Python3
84+
85+
```python
86+
class Solution:
87+
def scoreBalance(self, s: str) -> bool:
88+
l = 0
89+
r = sum(ord(c) - ord("a") + 1 for c in s)
90+
for c in s[:-1]:
91+
x = ord(c) - ord("a") + 1
92+
l += x
93+
r -= x
94+
if l == r:
95+
return True
96+
return False
97+
```
98+
99+
#### Java
100+
101+
```java
102+
class Solution {
103+
public boolean scoreBalance(String s) {
104+
int n = s.length();
105+
int l = 0, r = 0;
106+
for (int i = 0; i < n; ++i) {
107+
int x = s.charAt(i) - 'a' + 1;
108+
r += x;
109+
}
110+
for (int i = 0; i < n - 1; ++i) {
111+
int x = s.charAt(i) - 'a' + 1;
112+
l += x;
113+
r -= x;
114+
if (l == r) {
115+
return true;
116+
}
117+
}
118+
return false;
119+
}
120+
}
121+
```
122+
123+
#### C++
124+
125+
```cpp
126+
class Solution {
127+
public:
128+
bool scoreBalance(string s) {
129+
int l = 0, r = 0;
130+
for (char c : s) {
131+
int x = c - 'a' + 1;
132+
r += x;
133+
}
134+
for (int i = 0; i < s.size() - 1; ++i) {
135+
int x = s[i] - 'a' + 1;
136+
l += x;
137+
r -= x;
138+
if (l == r) {
139+
return true;
140+
}
141+
}
142+
return false;
143+
}
144+
};
145+
```
146+
147+
#### Go
148+
149+
```go
150+
func scoreBalance(s string) bool {
151+
var l, r int
152+
for _, c := range s {
153+
x := int(c-'a') + 1
154+
r += x
155+
}
156+
for _, c := range s[:len(s)-1] {
157+
x := int(c-'a') + 1
158+
l += x
159+
r -= x
160+
if l == r {
161+
return true
162+
}
163+
}
164+
return false
165+
}
166+
```
167+
168+
#### TypeScript
169+
170+
```ts
171+
function scoreBalance(s: string): boolean {
172+
let [l, r] = [0, 0];
173+
for (const c of s) {
174+
const x = c.charCodeAt(0) - 96;
175+
r += x;
176+
}
177+
for (let i = 0; i < s.length - 1; ++i) {
178+
const x = s[i].charCodeAt(0) - 96;
179+
l += x;
180+
r -= x;
181+
if (l === r) {
182+
return true;
183+
}
184+
}
185+
return false;
186+
}
187+
```
188+
189+
<!-- tabs:end -->
190+
191+
<!-- solution:end -->
192+
193+
<!-- problem:end -->
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
---
2+
comments: true
3+
difficulty: Easy
4+
edit_url: https://github.com/doocs/leetcode/edit/main/solution/3700-3799/3707.Equal%20Score%20Substrings/README_EN.md
5+
---
6+
7+
<!-- problem:start -->
8+
9+
# [3707. Equal Score Substrings](https://leetcode.com/problems/equal-score-substrings)
10+
11+
[中文文档](/solution/3700-3799/3707.Equal%20Score%20Substrings/README.md)
12+
13+
## Description
14+
15+
<!-- description:start -->
16+
17+
<p>You are given a string <code>s</code> consisting of lowercase English letters.</p>
18+
19+
<p>The <strong>score</strong> of a string is the sum of the positions of its characters in the alphabet, where <code>&#39;a&#39; = 1</code>, <code>&#39;b&#39; = 2</code>, ..., <code>&#39;z&#39; = 26</code>.</p>
20+
21+
<p>Determine whether there exists an index <code>i</code> such that the string can be split into two <strong>non-empty substrings</strong> <code>s[0..i]</code> and <code>s[(i + 1)..(n - 1)]</code> that have <strong>equal</strong> scores.</p>
22+
23+
<p>Return <code>true</code> if such a split exists, otherwise return <code>false</code>.</p>
24+
A <strong>substring</strong> is a contiguous <b>non-empty</b> sequence of characters within a string.
25+
<p>&nbsp;</p>
26+
<p><strong class="example">Example 1:</strong></p>
27+
28+
<div class="example-block">
29+
<p><strong>Input:</strong> <span class="example-io">s = &quot;adcb&quot;</span></p>
30+
31+
<p><strong>Output:</strong> <span class="example-io">true</span></p>
32+
33+
<p><strong>Explanation:</strong></p>
34+
35+
<p>Split at index <code>i = 1</code>:</p>
36+
37+
<ul>
38+
<li>Left substring = <code>s[0..1] = &quot;ad&quot;</code> with <code>score = 1 + 4 = 5</code></li>
39+
<li>Right substring = <code>s[2..3] = &quot;cb&quot;</code> with <code>score = 3 + 2 = 5</code></li>
40+
</ul>
41+
42+
<p>Both substrings have equal scores, so the output is <code>true</code>.</p>
43+
</div>
44+
45+
<p><strong class="example">Example 2:</strong></p>
46+
47+
<div class="example-block">
48+
<p><strong>Input:</strong> <span class="example-io">s = &quot;bace&quot;</span></p>
49+
50+
<p><strong>Output:</strong> <span class="example-io">false</span></p>
51+
52+
<p><strong>Explanation:​​​​​​</strong></p>
53+
54+
<p><strong>​​​​​​​</strong>No split produces equal scores, so the output is <code>false</code>.</p>
55+
</div>
56+
57+
<p>&nbsp;</p>
58+
<p><strong>Constraints:</strong></p>
59+
60+
<ul>
61+
<li><code>2 &lt;= s.length &lt;= 100</code></li>
62+
<li><code>s</code> consists of lowercase English letters.</li>
63+
</ul>
64+
65+
<!-- description:end -->
66+
67+
## Solutions
68+
69+
<!-- solution:start -->
70+
71+
### Solution 1: Prefix Sum
72+
73+
We first calculate the total score of the string, denoted as $r$. Then we traverse the first $n-1$ characters from left to right, calculating the prefix score $l$ and updating the suffix score $r$. If at some position $i$, the prefix score $l$ equals the suffix score $r$, it means there exists an index $i$ that can split the string into two substrings with equal scores, so we return $\textit{true}$. If we finish traversing without finding such an index, we return $\textit{false}$.
74+
75+
The time complexity is $O(n)$, where $n$ is the length of the string. The space complexity is $O(1)$.
76+
77+
<!-- tabs:start -->
78+
79+
#### Python3
80+
81+
```python
82+
class Solution:
83+
def scoreBalance(self, s: str) -> bool:
84+
l = 0
85+
r = sum(ord(c) - ord("a") + 1 for c in s)
86+
for c in s[:-1]:
87+
x = ord(c) - ord("a") + 1
88+
l += x
89+
r -= x
90+
if l == r:
91+
return True
92+
return False
93+
```
94+
95+
#### Java
96+
97+
```java
98+
class Solution {
99+
public boolean scoreBalance(String s) {
100+
int n = s.length();
101+
int l = 0, r = 0;
102+
for (int i = 0; i < n; ++i) {
103+
int x = s.charAt(i) - 'a' + 1;
104+
r += x;
105+
}
106+
for (int i = 0; i < n - 1; ++i) {
107+
int x = s.charAt(i) - 'a' + 1;
108+
l += x;
109+
r -= x;
110+
if (l == r) {
111+
return true;
112+
}
113+
}
114+
return false;
115+
}
116+
}
117+
```
118+
119+
#### C++
120+
121+
```cpp
122+
class Solution {
123+
public:
124+
bool scoreBalance(string s) {
125+
int l = 0, r = 0;
126+
for (char c : s) {
127+
int x = c - 'a' + 1;
128+
r += x;
129+
}
130+
for (int i = 0; i < s.size() - 1; ++i) {
131+
int x = s[i] - 'a' + 1;
132+
l += x;
133+
r -= x;
134+
if (l == r) {
135+
return true;
136+
}
137+
}
138+
return false;
139+
}
140+
};
141+
```
142+
143+
#### Go
144+
145+
```go
146+
func scoreBalance(s string) bool {
147+
var l, r int
148+
for _, c := range s {
149+
x := int(c-'a') + 1
150+
r += x
151+
}
152+
for _, c := range s[:len(s)-1] {
153+
x := int(c-'a') + 1
154+
l += x
155+
r -= x
156+
if l == r {
157+
return true
158+
}
159+
}
160+
return false
161+
}
162+
```
163+
164+
#### TypeScript
165+
166+
```ts
167+
function scoreBalance(s: string): boolean {
168+
let [l, r] = [0, 0];
169+
for (const c of s) {
170+
const x = c.charCodeAt(0) - 96;
171+
r += x;
172+
}
173+
for (let i = 0; i < s.length - 1; ++i) {
174+
const x = s[i].charCodeAt(0) - 96;
175+
l += x;
176+
r -= x;
177+
if (l === r) {
178+
return true;
179+
}
180+
}
181+
return false;
182+
}
183+
```
184+
185+
<!-- tabs:end -->
186+
187+
<!-- solution:end -->
188+
189+
<!-- problem:end -->

0 commit comments

Comments
 (0)