• LeetCode 1422. 分割字符串的最大得分


    【LetMeFly】1422.分割字符串的最大得分

    力扣题目链接:https://leetcode.cn/problems/maximum-score-after-splitting-a-string/

    给你一个由若干 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:暴力

    直接暴力枚举每一个可以分割的位置,在每次枚举时,暴力统计一下分割位置前面和后面分别有多少个’0’ / ‘1’

    • 时间复杂度 O ( n 2 ) O(n^2) O(n2),其中 n n n是字符串长度
    • 空间复杂度 O ( 1 ) O(1) O(1)

    方法一:前缀和

    frontZero[i]表示下标0~i'0'的个数

    backOne[i]表示下标i~n - 1'1'的个数

    我们预处理遍历一遍原始字符串,统计出上述两个数组。

    之和,只需要枚举分割的位置,并借助上述两个数组使用 O ( 1 ) O(1) O(1)的时间计算出这种分割方案的得分。

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

    AC代码

    C++

    class Solution {
    public:
        int maxScore(string& s) {
            int n = s.size();
    		// 预处理
            vector<int> frontZero(n);
            vector<int> backOne(n);
            frontZero[0] = s[0] == '0';
            for (int i = 1; i < n; i++) {
                frontZero[i] = frontZero[i - 1] + (s[i] == '0');
            }
            backOne[n - 1] = s[n - 1] == '1';
            for (int i = n - 2; i >= 0; i--) {
                backOne[i] = backOne[i + 1] + (s[i] == '1');
            }
    		// 模拟分割位置
            int ans = 0;
            for (int i = 1; i < n; i++) {
                ans = max(ans, frontZero[i - 1] + backOne[i]);
            }
            return ans;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    方法二:直接计算

    方法一中,我们通过预处理,先用两个数数组把第 i i i个位置前后的零/一存了下来,因此消耗了 O ( n ) O(n) O(n)的空间复杂度。

    那么,我们有没有什么办法使用 O ( 1 ) O(1) O(1)的额外空间来存储上述信息呢?

    注意,方法一中模拟分割位置时是从前往后依次模拟的。也就是说,我们可以在上次模拟结果的基础上,快速求出这次的“零、一信息”

    具体方法为:

    首先遍历一遍原始字符串,并求出从第一个元素分割的情况下的得分。

    之后从第二个元素开始往后模拟,如果这个元素是'0',那么把这个元素划分到“左字符串”的话,将会比上一种方案多一个“前字符串的0”,因此会在上一个方案的基础上多得一分;同理,如果这个元素是“1”,那么“后字符串”将少一个“1”,将会少得一分

    每次模拟分割位置并在上次分割的基础上计算出新的得分后,更新最大得分,就能得到答案。

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

    AC代码

    C++

    class Solution {
    public:
        int maxScore(string s) {
            int score = s[0] == '0';
            int n = s.size();
            for (int i = 1; i < n; i++) {
                score += s[i] == '1';
            }
            int ans = score;
            for (int i = 1; i < n - 1; i++) {
                if (s[i] == '0')
                    score++;
                else
                    score--;
                ans = max(ans, score);
            }
            return ans;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    同步发文于CSDN,原创不易,转载请附上原文链接哦~
    Tisfy:https://letmefly.blog.csdn.net/article/details/126329351

  • 相关阅读:
    青藏高原连续日光诱导叶绿素荧光数据集(2000-2018)
    【EI会议征稿】第二届可再生能源与电气科技国际学术会议(ICREET 2023)
    Kubernetes(31):kubeasz安装三主两从高可用集群
    Python爬虫详解(一看就懂)
    视频批量加水印:保护版权,提升效率
    举个栗子~Tableau 技巧(232):用工作表创建多行列图例
    C++程序设计-练手题集合【期末复习|考研复习】
    SS310L-ASEMI肖特基二极管SS310L
    Linux 入门:基本指令
    天佑药品销售管理系统
  • 原文地址:https://blog.csdn.net/Tisfy/article/details/126329351