Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
193 changes: 193 additions & 0 deletions solution/3700-3799/3707.Equal Score Substrings/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
---
comments: true
difficulty: 简单
edit_url: https://github.com/doocs/leetcode/edit/main/solution/3700-3799/3707.Equal%20Score%20Substrings/README.md
---

<!-- problem:start -->

# [3707. 相等子字符串分数](https://leetcode.cn/problems/equal-score-substrings)

[English Version](/solution/3700-3799/3707.Equal%20Score%20Substrings/README_EN.md)

## 题目描述

<!-- description:start -->

<p>给你一个由小写英文字母组成的字符串 <code>s</code>。</p>

<p>一个字符串的&nbsp;<strong>得分&nbsp;</strong>是其字符在字母表中的位置之和,其中 <code>'a' = 1</code>,<code>'b' = 2</code>,...,<code>'z' = 26</code>。</p>

<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>

<p>如果存在这样的拆分,则返回 <code>true</code>,否则返回 <code>false</code>。</p>

<p>一个&nbsp;<strong>子字符串&nbsp;</strong>是字符串中&nbsp;<strong>非空&nbsp;</strong>的连续字符序列。</p>

<p>&nbsp;</p>

<p><strong class="example">示例 1:</strong></p>

<div class="example-block">
<p><strong>输入:</strong> <span class="example-io">s = "adcb"</span></p>

<p><strong>输出:</strong> <span class="example-io">true</span></p>

<p><strong>解释:</strong></p>

<p>在下标&nbsp;<code>i = 1</code> 处拆分:</p>

<ul>
<li>左子字符串 = <code>s[0..1] = "ad"</code>,得分 =&nbsp;<code>1 + 4 = 5</code></li>
<li>右子字符串 = <code>s[2..3] = "cb"</code>,得分 = <code>3 + 2 = 5</code></li>
</ul>

<p>两个子字符串的得分相等,因此输出为 <code>true</code>。</p>
</div>

<p><strong class="example">示例 2:</strong></p>

<div class="example-block">
<p><strong>输入:</strong> <span class="example-io">s = "bace"</span></p>

<p><strong>输出:</strong> <span class="example-io">false</span></p>

<p><strong>解释:​​​​​​</strong></p>

<p>没有拆分能产生相等的得分,因此输出为 <code>false</code>。</p>
</div>

<p>&nbsp;</p>

<p><strong>提示:</strong></p>

<ul>
<li><code>2 &lt;= s.length &lt;= 100</code></li>
<li><code>s</code> 由小写英文字母组成。</li>
</ul>

<!-- description:end -->

## 解法

<!-- solution:start -->

### 方法一:前缀和

我们先计算字符串的总得分,记为 $r$。然后我们从左到右遍历前 $n-1$ 个字符,计算前缀得分 $l$,并更新后缀得分 $r$。如果在某个位置 $i$,前缀得分 $l$ 等于后缀得分 $r$,则说明存在一个下标 $i$ 可以将字符串拆分成两个得分相等的子字符串,返回 $\textit{true}$。如果遍历结束后仍未找到这样的下标,返回 $\textit{false}$。

时间复杂度 $O(n)$,其中 $n$ 是字符串的长度。空间复杂度 $O(1)$。

<!-- tabs:start -->

#### Python3

```python
class Solution:
def scoreBalance(self, s: str) -> bool:
l = 0
r = sum(ord(c) - ord("a") + 1 for c in s)
for c in s[:-1]:
x = ord(c) - ord("a") + 1
l += x
r -= x
if l == r:
return True
return False
```

#### Java

```java
class Solution {
public boolean scoreBalance(String s) {
int n = s.length();
int l = 0, r = 0;
for (int i = 0; i < n; ++i) {
int x = s.charAt(i) - 'a' + 1;
r += x;
}
for (int i = 0; i < n - 1; ++i) {
int x = s.charAt(i) - 'a' + 1;
l += x;
r -= x;
if (l == r) {
return true;
}
}
return false;
}
}
```

#### C++

```cpp
class Solution {
public:
bool scoreBalance(string s) {
int l = 0, r = 0;
for (char c : s) {
int x = c - 'a' + 1;
r += x;
}
for (int i = 0; i < s.size() - 1; ++i) {
int x = s[i] - 'a' + 1;
l += x;
r -= x;
if (l == r) {
return true;
}
}
return false;
}
};
```

#### Go

```go
func scoreBalance(s string) bool {
var l, r int
for _, c := range s {
x := int(c-'a') + 1
r += x
}
for _, c := range s[:len(s)-1] {
x := int(c-'a') + 1
l += x
r -= x
if l == r {
return true
}
}
return false
}
```

#### TypeScript

```ts
function scoreBalance(s: string): boolean {
let [l, r] = [0, 0];
for (const c of s) {
const x = c.charCodeAt(0) - 96;
r += x;
}
for (let i = 0; i < s.length - 1; ++i) {
const x = s[i].charCodeAt(0) - 96;
l += x;
r -= x;
if (l === r) {
return true;
}
}
return false;
}
```

<!-- tabs:end -->

<!-- solution:end -->

<!-- problem:end -->
189 changes: 189 additions & 0 deletions solution/3700-3799/3707.Equal Score Substrings/README_EN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
---
comments: true
difficulty: Easy
edit_url: https://github.com/doocs/leetcode/edit/main/solution/3700-3799/3707.Equal%20Score%20Substrings/README_EN.md
---

<!-- problem:start -->

# [3707. Equal Score Substrings](https://leetcode.com/problems/equal-score-substrings)

[中文文档](/solution/3700-3799/3707.Equal%20Score%20Substrings/README.md)

## Description

<!-- description:start -->

<p>You are given a string <code>s</code> consisting of lowercase English letters.</p>

<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>

<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>

<p>Return <code>true</code> if such a split exists, otherwise return <code>false</code>.</p>
A <strong>substring</strong> is a contiguous <b>non-empty</b> sequence of characters within a string.
<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">s = &quot;adcb&quot;</span></p>

<p><strong>Output:</strong> <span class="example-io">true</span></p>

<p><strong>Explanation:</strong></p>

<p>Split at index <code>i = 1</code>:</p>

<ul>
<li>Left substring = <code>s[0..1] = &quot;ad&quot;</code> with <code>score = 1 + 4 = 5</code></li>
<li>Right substring = <code>s[2..3] = &quot;cb&quot;</code> with <code>score = 3 + 2 = 5</code></li>
</ul>

<p>Both substrings have equal scores, so the output is <code>true</code>.</p>
</div>

<p><strong class="example">Example 2:</strong></p>

<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">s = &quot;bace&quot;</span></p>

<p><strong>Output:</strong> <span class="example-io">false</span></p>

<p><strong>Explanation:​​​​​​</strong></p>

<p><strong>​​​​​​​</strong>No split produces equal scores, so the output is <code>false</code>.</p>
</div>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
<li><code>2 &lt;= s.length &lt;= 100</code></li>
<li><code>s</code> consists of lowercase English letters.</li>
</ul>

<!-- description:end -->

## Solutions

<!-- solution:start -->

### Solution 1: Prefix Sum

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}$.

The time complexity is $O(n)$, where $n$ is the length of the string. The space complexity is $O(1)$.

<!-- tabs:start -->

#### Python3

```python
class Solution:
def scoreBalance(self, s: str) -> bool:
l = 0
r = sum(ord(c) - ord("a") + 1 for c in s)
for c in s[:-1]:
x = ord(c) - ord("a") + 1
l += x
r -= x
if l == r:
return True
return False
```

#### Java

```java
class Solution {
public boolean scoreBalance(String s) {
int n = s.length();
int l = 0, r = 0;
for (int i = 0; i < n; ++i) {
int x = s.charAt(i) - 'a' + 1;
r += x;
}
for (int i = 0; i < n - 1; ++i) {
int x = s.charAt(i) - 'a' + 1;
l += x;
r -= x;
if (l == r) {
return true;
}
}
return false;
}
}
```

#### C++

```cpp
class Solution {
public:
bool scoreBalance(string s) {
int l = 0, r = 0;
for (char c : s) {
int x = c - 'a' + 1;
r += x;
}
for (int i = 0; i < s.size() - 1; ++i) {
int x = s[i] - 'a' + 1;
l += x;
r -= x;
if (l == r) {
return true;
}
}
return false;
}
};
```

#### Go

```go
func scoreBalance(s string) bool {
var l, r int
for _, c := range s {
x := int(c-'a') + 1
r += x
}
for _, c := range s[:len(s)-1] {
x := int(c-'a') + 1
l += x
r -= x
if l == r {
return true
}
}
return false
}
```

#### TypeScript

```ts
function scoreBalance(s: string): boolean {
let [l, r] = [0, 0];
for (const c of s) {
const x = c.charCodeAt(0) - 96;
r += x;
}
for (let i = 0; i < s.length - 1; ++i) {
const x = s[i].charCodeAt(0) - 96;
l += x;
r -= x;
if (l === r) {
return true;
}
}
return false;
}
```

<!-- tabs:end -->

<!-- solution:end -->

<!-- problem:end -->
Loading
Loading