代码实现:
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; }