Leetcode每日一题之最长平衡子字符串 算法

题目描述
给你一个仅由 0 和 1 组成的二进制字符串 s 。

如果子字符串中 所有的 0 都在 1 之前 且其中 0 的数量等于 1 的数量,则认为 s 的这个子字符串是平衡子字符串。请注意,空子字符串也视作平衡子字符串。

返回 s 中最长的平衡子字符串长度。

子字符串是字符串中的一个连续字符序列。

示例 1:

输入:s = “01000111”
输出:6
解释:最长的平衡子字符串是 “000111” ,长度为 6 。
示例 2:

输入:s = “00111”
输出:4
解释:最长的平衡子字符串是 “0011” ,长度为 4 。
示例 3:

输入:s = “111”
输出:0
解释:除了空子字符串之外不存在其他平衡子字符串,所以答案为 0 。

提示:

1 <= s.length <= 50
‘0’ <= s[i] <= ‘1’

package leetcode;

public class p2609 {
    public static void main(String[] args) {

    }

    /**
     *思路:遍历字符串,当值为字符0时让ct0++,为字符1时让ct1++,并用flag标识当前时连续的0还是1,
     * 同时处理下一个0开始的子串或是以1到达末尾的情况
     * 时间复杂度O(n) 空间复杂度O(1)
     */
    public static int findTheLongestBalancedSubstring(String s) {
        int maxLen=0;
        int ct0=0;
        int ct1=0;
        int flag=0;
        for (int i=0;i<s.length();i++){
            if (flag==0 && s.charAt(i)=='0'){
                ct0++;
            }else if (flag==0 && s.charAt(i)=='1'){
                flag=1;
                ct1++;
                if (i== s.length()-1){
                    int min=Math.min(ct0,ct1);
                    maxLen=Math.max(maxLen,min);
                }
            } else if (flag==1 && s.charAt(i)=='1') {
                ct1++;
                if (i== s.length()-1){
                    int min=Math.min(ct0,ct1);
                    maxLen=Math.max(maxLen,min);
                }
            } else if (flag==1 && s.charAt(i)=='0') {
                int min=Math.min(ct0,ct1);
                maxLen=Math.max(maxLen,min);
                ct0=ct1=0;
                flag=0;
                ct0++;
            }
        }
        return maxLen*2;
    }
    // 优化:发现当字符值为1的两个条件分支可以合并,使消耗内存减少了
    public static int findTheLongestBalancedSubstring2(String s) {
        int maxLen=0;
        int ct0=0;
        int ct1=0;
        int flag=0;
        for (int i=0;i<s.length();i++){
            if (flag==0 && s.charAt(i)=='0'){
                ct0++;
            }else if (s.charAt(i)=='1'){
                flag=1;
                ct1++;
                if (i== s.length()-1){
                    int min=Math.min(ct0,ct1);
                    maxLen=Math.max(maxLen,min);
                }
            } else if (flag==1 && s.charAt(i)=='0') {
                int min=Math.min(ct0,ct1);
                maxLen=Math.max(maxLen,min);
                ct0=ct1=0;
                flag=0;
                ct0++;
            }
        }
        return maxLen*2;
    }
    // 看了题解之后写的更优雅的代码
    // 但是这里消耗的内存却比上面优化的代码多,是因为while循环会占用更大的内存的原因吗?
    public static int findTheLongestBalancedSubstring3(String s) {
        int n=s.length(),index=0,maxLen=0;
        while (index<n){
            int ct0=0,ct1=0;
            while (index<n && s.charAt(index)=='0' && ++ct0>0) index++;
            while (index<n && s.charAt(index)=='1' && ++ct1>0) index++;
            maxLen=Math.max(maxLen,Math.min(ct0,ct1)*2);
        }
        return maxLen;
    }
}

总结:对于这种连续的1和0而且一定是0在前1在后,可以不使用flag标志位而直接用while循环统计其长度。

你可能感兴趣的:(LeetCode每日一题,leetcode,算法)