分割字符串的最大得分

52 阅读2分钟

🎈 算法并不一定都是很难的题目,也有很多只是一些代码技巧,多进行一些算法题目的练习,可以帮助我们开阔解题思路,提升我们的逻辑思维能力,也可以将一些算法思维结合到业务代码的编写思考中。简而言之,平时进行的算法习题练习带给我们的好处一定是不少的,所以让我们一起来养成算法练习的习惯。今天练习的题目是一道比较简单的题目 ->分割字符串的最大得分

问题描述

给你一个由若干 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' 组成。

思路分析

首先我们要先理解一下题目的意思,题目会给我们一个由若干 0 和 1 组成的字符串 s ,请你计算并返回将该字符串分割成两个 非空 子字符串(即 左 子字符串和 右 子字符串)所能获得的最大得分。「分割字符串的得分」为 左 子字符串中 0 的数量加上 右 子字符串中 1 的数量。题目并不难理解,说的是我们可以将字符串分割成两个非空的子字符串,分割字符串的得分是左边字符串中 0 的数量加上右边字符串中 1 的数量,理解了题目的意思之后,我们便可以开始进行题目解答了。最简单的做法我们可以遍历字符串切割点,到达每个切割点时分别统计左边字符串中 0 的数量和右边字符串中 1 的数量,代码如下:

let left = 0,
  right = 0,
  res = 0;
for (let i = 1; i < s.length - 1; i++) {
  for (let j = 0; j < i; j++) left += 1 - Number(s[j]);
  for (let k = i; k < s.length; k++) right += Number(s[j]);
  res = Math.max(res, left + right);
}

上面这种方法我们需要进行两层的循环嵌套,数据量大的话性能并不好,那么我们可以想办法将嵌套循环给去掉吗?当然可以,以为字符串中 1 的数量是固定的,所以我们可以先统计出 s 字符串中所有 1 的数量:

for (let i = 0; i < s.length; i++) right += Number(s[i]);

然后再遍历字符串切割点,我们只需把字符串中 1 的总数减去遍历过的 1 的数量即可得到右边字符串中 1 的数量,这样便能快速的计算出左右字符串中 0 和 1 分别的数量。

for (let i = 0; i < s.length - 1; i++) {
  right -= Number(s[i]);
  left += 1 - Number(s[i]);
  res = Math.max(left + right, res);
}

AC 代码

完整 AC 代码如下:

/**
 * @param {string} s
 * @return {number}
 */
var maxScore = function (s) {
  let res = 0,
    left = 0,
    right = 0;
  for (let i = 0; i < s.length; i++) right += Number(s[i]);
  for (let i = 0; i < s.length - 1; i++) {
    right -= Number(s[i]);
    left += 1 - Number(s[i]);
    res = Math.max(left + right, res);
  }
  return res;
};

说在后面

🎉 这里是 JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打羽毛球 🏸 ,平时也喜欢写些东西,既为自己记录 📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解 🙇,写错的地方望指出,定会认真改进 😊,在此谢谢大家的支持,我们下文再见 🙌。