分割字符串的最大得分

93 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第17天,点击查看活动详情

一、题目

LeetCode 分割字符串的最大得分

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

二、题解

给定有一个字符串,字符串中的字符只会出现01两种字符,需要将字符串从某个位置切割,这样获得有两个非空的字符串,计算前一个字符串的字符0的数量,计算后一个字符串中字符1的数量,返回数量较大的一个最大数量之和(字符0的数量与字符1的数量相加)。

方法一

根据题目的意思给定的字符串也不是很长,所有简单的可以直接遍历字符串,枚举可以分割的每个点i,然后分别计算分割得到的两个字符串中对应字符的数量之和。具体的遍历字符串s枚举分割点i,定义一个变量记录这次分割所得的数量之和,遍历分割点i之前的字符,如果字符是0的话,记录的数量之和就自增一,同样的遍历分割点i之后的字符,如果字符是1的话,记录的数量之和就自增一,最后保存记录最大的数量之和,枚举完成之后就返回最大的数量之和即可。

方法二 直接遍历字符串字符,初始的遍历一次数组,遇到字符1的时候分数就加一,然后再遍历一次字符串,如果字符是0的话就加一,否则分数就对应的减一,最后保留着最大的分数。

三、代码

方法一 Java代码

class Solution {
    public int maxScore(String s) {
        int maxScore = 0;
        int len = s.length();
        for (int i = 1; i < len; i++) {
            int score = 0;
            for (int j = 0; j < len; j++) {
                if (j < i && s.charAt(j) == '0') {
                    score++;
                }
                if (j >= i && s.charAt(j) == '1') {
                    score++;
                }
            }
            maxScore = Math.max(maxScore, score);
        }
        return maxScore;
    }
}

时间复杂度:O(n^2),首先需要枚举每一个分割点,其次需要遍历分割的字符串。

空间复杂度:O(1),只需使用常数的空间。


方法二 Java代码

class Solution {
    public int maxScore(String s) {
        int len = s.length();
        int score = s.charAt(0) == '0' ? 1 : 0;
        for (int i = 1; i < len; i++) {
            if (s.charAt(i) == '1') {
                score++;
            }
        }
        int maxScore = score;
        for (int i = 1; i < len - 1; i++) {
            if (s.charAt(i) == '0') {
                score++;
            } else {
                score--;
            }
            maxScore = Math.max(maxScore, score);
        }
        return maxScore;
    }
}

时间复杂度:O(n),需要遍历两次字符串的字符。

空间复杂度:O(1),只需使用常数的空间。