题目
给你一个由若干 0 和 1 组成的字符串 s
,请你计算并返回将该字符串分割成两个 非空 子字符串(即 左 子字符串和 右 子字符串)所能获得的最大得分。
「分割字符串的得分」为 左 子字符串中 0 的数量加上 右 子字符串中 1 的数量。
示例 1:
输入:s = "011101"
输出:5
解释:
将字符串 s 划分为两个非空子字符串的可行方案有:
左子字符串 = "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
示例 2:
输入:s = "00111"
输出:5
解释:当 左子字符串 = "00" 且 右子字符串 = "111" 时,我们得到最大得分 = 2 + 3 = 5
示例 3:
输入:s = "1111"
输出:3
提示:
2 <= s.length <= 500
- 字符串
s
仅由字符'0'
和'1'
组成。
解题
方法一:两次遍历
思路
总体思路是先进行一次遍历,维护左边一个字符,右边 n-1
个字符时分割字符串的得分(score
)。
然后再次遍历从 s[1]
开始到 s[n-2]
结束,每次计算 s[i]
从右子字符串移到左子字符串后得到的分数,在这个过程中维护分数的最大值最后返回即可。
以 s = "011101"
为例:
首先遍历一次字符串维护 0 | 11101
的分数为 ,然后从 s[1]
到 s[4]
:
i = 1
: (01 | 1101
)s[1] = '1'
- 左边'0'
的数量不变,右边少一个'1'
,所以总分数 - 1 = 。i = 2
: (011 | 101
)s[2] = '1'
- 同上,所以总分数 - 1 = 。i = 3
: (0111 | 01
)s[2] = '1'
- 同上,所以总分数 - 1 = 。i = 4
: (01110 | 1
)s[2] = '0'
- 左边多一个'0'
,右边'1'
的数量不变,所以总分数 + 1 = 。
最后得出最大分数为最开始的 5
。
代码
class Solution {
public int maxScore(String s) {
char[] chs = s.toCharArray();
int n = chs.length;
int score = chs[0] == '0' ? 1 : 0;
for (int i = 1; i < n; ++i) score += chs[i] - '0';
int max = score;
for (int i = 1; i < n - 1; ++i) {
if (chs[i] == '0') ++score;
else --score;
max = Math.max(max, score);
}
return max;
}
}
class Solution {
public:
int maxScore(string s) {
int score = !(s[0] - '0');
for (auto it = s.begin() + 1; it != s.end(); ++it) score += *it - '0';
int mx = score;
for (auto it = s.begin() + 1; it != s.end() - 1; ++it) {
if (*it - '0') --score;
else ++score;
mx = max(mx, score);
}
return mx;
}
};
评论区