力扣 2609. 最长平衡子字符串

代码实现:

1. 遍历指针,使用状态机

/*
    使用状态机,设a=b=0
遍历字符串:
    遇到1后的0,a,b都清零,
    遇到0时 a++
    遇到1时 b++
*/
int findTheLongestBalancedSubstring(char *s)
{
	int ans = 0, a = 0, b = 0, st = 0, i = 0;
	while (1)
	{
		switch (s[i++])
		{
			case '0': 
                if (st == 1) 
                { 
                    a = 0; 
                    b = 0; 
                } 
                a++; 
                st = 0; 
                break;
			case '1':   
                b++; 
                st = 1; 
                break;
			case '\0': return ans<<1;
		}
		if (a - b >= 0 && b > ans) 
            ans = b;
	}
}

2. 计数

#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) > (b) ? (b) : (a))

int findTheLongestBalancedSubstring(char * s) 
{
    int res = 0;
    int count[2] = {0};
    for (int i = 0; s[i] != '\0'; i++)
    {
        if (s[i] == '1')
        {
            count[1]++;
            res = MAX(res, 2 * MIN(count[0], count[1]));
        }
        else if (i == 0 || s[i - 1] == '1')
        {
            count[0] = 1;
            count[1] = 0;
        }
        else
            count[0]++;
    }
    return res;    
}

3. 双指针法

#define MAX_VAL(x, y)   ((x) > (y) ? (x) : (y))
#define MIN_VAL(x, y)   ((x) < (y) ? (x) : (y))

int findTheLongestBalancedSubstring(char *s)
{
    int x = 0, y = 0, zero = 0, t = 0, result = 0;
    /* 循环条件用s[x]不等于结束符就行,不必事先获得s的长度。 */
    while (s[x])
    {
        //快指针探路。字符串最终会有一个结束符结尾,所以这里不必担心s[y]越界
        y = x + 1;
        while (s[y] == s[x])
            y++;
        
        //此时,左闭右开区间[x, y)是一段相同的字符,全0或全1,分情况考虑
        //全1的一整段。平衡字符串就是0、1长度较小值的两倍
        if (s[x] == '1')
        {
            t = MIN_VAL(y - x, zero) << 1;
            result = MAX_VAL(result, t);
            zero = 0;
        }
        //全0的一整段。先记录0的长度,待后面发现1时再更新结果
        else
            zero = y - x;
        
        /* 双指针前进。 */
        x = y;
    }
    return result;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值