穷哈哈~

[题目链接](https://www.nowcoder.com/practice/5b3184b233f34fb39a7f259ae82eb42c)

思路

题目说小哈的笑声是字母 ha 交替出现的序列,比如 haahahahaahahahah 都是合法的笑声,但 hhaa 这种连续相同字符的就不算。我们要在给定字符串中找到最长的这样一段连续子串。

怎么做呢?用一个变量 cur 记录当前正在延伸的笑声长度,从左到右扫一遍字符串:

  • 如果当前字符既不是 h 也不是 a,那笑声断了,cur 归零。
  • 如果当前字符是 ha,并且前一个字符也是 ha 且和当前不同,说明交替还在继续,cur 加一。
  • 否则(前一个字符和当前相同,或者前一个字符不是 h/a),说明要从当前字符重新开始一段新的笑声,cur 置为 1。

扫描过程中维护 cur 的最大值就是答案。

拿样例验证一下:abacaba 里没有 h,所以每个 a 最多只能独立成段,长度为 1。而 ahahahahahahahahahah 整个串都是 ah 交替,长度 20 就是答案。

代码

#include <bits/stdc++.h>
using namespace std;
int main(){
    int n;
    cin >> n;
    string s;
    cin >> s;
    int ans = 0, cur = 0;
    for(int i = 0; i < n; i++){
        if(s[i] != 'h' && s[i] != 'a'){
            cur = 0;
        } else if(i == 0 || (s[i] != s[i-1] && (s[i-1] == 'h' || s[i-1] == 'a'))){
            cur++;
        } else {
            cur = 1;
        }
        ans = max(ans, cur);
    }
    cout << ans << endl;
    return 0;
}
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        String s = sc.next();
        int ans = 0, cur = 0;
        for (int i = 0; i < n; i++) {
            char c = s.charAt(i);
            if (c != 'h' && c != 'a') {
                cur = 0;
            } else if (i == 0 || (c != s.charAt(i - 1) && (s.charAt(i - 1) == 'h' || s.charAt(i - 1) == 'a'))) {
                cur++;
            } else {
                cur = 1;
            }
            ans = Math.max(ans, cur);
        }
        System.out.println(ans);
    }
}
n = int(input())
s = input()
ans = 0
cur = 0
for i in range(n):
    if s[i] not in ('h', 'a'):
        cur = 0
    elif i == 0 or (s[i] != s[i-1] and s[i-1] in ('h', 'a')):
        cur += 1
    else:
        cur = 1
    ans = max(ans, cur)
print(ans)
const readline = require('readline');
const rl = readline.createInterface({ input: process.stdin });
const lines = [];
rl.on('line', line => lines.push(line.trim()));
rl.on('close', () => {
    const n = parseInt(lines[0]);
    const s = lines[1];
    let ans = 0, cur = 0;
    for (let i = 0; i < n; i++) {
        if (s[i] !== 'h' && s[i] !== 'a') {
            cur = 0;
        } else if (i === 0 || (s[i] !== s[i-1] && (s[i-1] === 'h' || s[i-1] === 'a'))) {
            cur++;
        } else {
            cur = 1;
        }
        ans = Math.max(ans, cur);
    }
    console.log(ans);
});

复杂度分析

  • 时间复杂度:,只需遍历字符串一次。
  • 空间复杂度:,只用了常数个变量(不算存储输入字符串本身)。