【字符串】C035_分割字符串的最大得分(暴力计数 / 线性扫描)

本文介绍了一种算法问题,即给定一个由0和1组成的字符串,如何通过将其分割成两个非空子串来获得最大得分,得分定义为左子串中的0的数量加上右子串中的1的数量。文章提供了两种解决方案,一种是暴力枚举所有可能的分割方式,时间复杂度为O(n^2),另一种是线性扫描法,时间复杂度为O(n)。

一、Problem

Given a string s of zeros and ones, return the maximum score after splitting the string into two non-empty substrings (i.e. left substring and right substring).

The score after splitting a string is the number of zeros in the left substring plus the number of ones in the right substring.

Input: s = "011101"
Output: 5 
Explanation: 
All possible ways of splitting s into two non-empty substrings are:
left = "0" and right = "11101", score = 1 + 4 = 5 
left = "01" and right = "1101", score = 1 + 3 = 4 
left = "011" and right = "101", score = 1 + 2 = 3 
left = "0111" and right = "01", score = 1 + 1 = 2 
left = "01110" and right = "1", score = 2 + 1 = 3

方法一:暴力

额…

public int maxScore(String s) {
    int sum = -1;
    for (int i = 1; i < s.length(); i++) {
        String l = s.substring(0, i);
        String r = s.substring(i, s.length());
        int l0 = 0, r1 = 0;
        for (char c : l.toCharArray()) {
            if (c == '0') l0++;
        }
        for (char c : r.toCharArray()) {
            if (c == '1') r1++;
        }
        sum = Math.max(sum, l0+r1);
    }
    return sum;
}
复杂度分析
  • 时间复杂度:O(n2)O(n^2)O(n2)
  • 空间复杂度:O(1)O(1)O(1)

方法二:线性扫描

优化了一下…

  • 先统计字符 1 的数量到 c1 中
  • 从左到右遍历字符串 s:
    • 如果当前分割点 i 是字符 1 表示右侧的字符 1 的数量少 1
    • 如果当前分割点 i 是字符 0 表示左侧的字符 0 的数量多 1
class Solution {
    public int maxScore(String S) {
        int max = 0, n = S.length(), c0 = 0, c1 = 0;
        char[] s = S.toCharArray();
        for (int i = 0; i < n; i++) if (s[i] == '1') c1++;

        for (int i = 0; i < n-1; i++) {
            if (s[i] == '1') c1--;
            else             c0++;
            max = Math.max(max, c1 + c0);
        }
        return max;
    }
}

复杂度分析

  • 时间复杂度:O(n)O(n)O(n)
  • 空间复杂度:O(1)O(1)O(1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值