leetcode5392

题目描述

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

解题思路

方法一:暴力算法(超时)

双循环,外循环变量表示分割的位置,内层循环计算得分

// java
class Solution{
    public int maxScore(String s){
        int max = 0 ;
        for(int i = 1; i < s.length(); i++){
            int res = 0 ;
            for(int j = 0; j < i; j++)
                if(s.charAt(j) == '0')
                    res++ ;
            for(int j = i; j < s.length(); j++)
                if(s.charAt(j) == '1')
                    res++ ;
            max = (res > max) ? res : max ;
        }
        return max ;
    }
}

时间复杂度,N是字符串的长度
空间复杂度

方法二:线性搜索

两次遍历,第一次遍历搜索全部的字符'1',并将数量保存在变量right;第二次从左往右遍历,如果第1个字符是'0',那么如果从这分割字符串,右子串的得分就是'1'的数量,即right,结合左子串就得到一个分值。如果第1个字符是'1',那么左子串不得分,右子串分值减1...对每一个字符都做这样的判断,就可以得到一个最大值。

// java
class Solution{
    public int maxScore(String s) {
        int right = 0 ;
        int left  = 0 ;
        int max   = 0 ;
        for(char ch : s.toCharArray()) {
            if(ch == '1')
                right++ ;
        }
        // 注意边界值i = s.length()-1
        for(int i = 0; i < s.length()-1; i++) {
            char ch = s.charAt(i) ;
            if(ch == '0') {
                left++ ;
            }else {
                right-- ;
            }
            int temp = left + right ;
            max = (temp > max) ? temp : max ;
        }
        return max ;
    }
}

时间复杂度
空间复杂度