2020年4月26日

统计连续重复最多的字符

问题描述

给定一个字符串,找出其中连续重复出现次数最多的字符及其出现次数。

示例

输入: "aabbbcccc"
输出: ["c", 4]  // 'c'连续出现4次

解题思路

跳步循环

/**
 * 查找字符串中连续出现次数最多的字符及其出现次数
 * @param str 输入的字符串
 * @returns 数组,包含最多连续出现的字符和出现次数
 * 
 * 示例用例:
 * 1. strMost_cycle("aabbbcccc") => ["c", 4] 
 *    // 'c'连续出现4次
 * 2. strMost_cycle("abcde") => ["a", 1]
 *    // 所有字符都只连续出现1次,返回第一个字符
 * 3. strMost_cycle("aaabba") => ["a", 3]
 *    // 'a'有连续3次和2次,取最大值3
 */
export function strMost_cycle(str: string): [string, number] {
    // 处理单字符特殊情况
    if (str.length === 1) {
        return [str[0], 1];
    }
    
    // 初始化结果:["字符", 出现次数]
    let res: [string, number] = ["", 0];
    let temCount = 0; // 临时计数器
    
    // 外层循环:遍历字符串
    for (let i = 0; i < str.length;) {
        temCount = 0;
        
        // 内层循环:统计从i开始连续相同字符的数量
        for (let j = i; j < str.length; j++) {
            if(str[i] === str[j]) {
                temCount++; // 相同字符计数增加
            }
            
            // 终止条件:遇到不同字符或到达字符串末尾
            if (str[i] !== str[j] || j === str.length - 1) {
                // 更新最大连续记录
                if (temCount > res[1]) {
                    res = [str[i], temCount];
                }
                
                // 到达字符串末尾直接返回结果
                if (j === str.length - 1) {
                    return res;
                }
                
                // 跳过已统计的连续字符
                i = j;
                break;
            }
        }
    }
    return res;
}

使用跳步循环的方法,外层循环遍历字符串,内层循环统计从当前位置开始连续相同字符的数量。通过比较临时计数器和当前最大连续记录,更新结果。这种方法的时间复杂度为O(n),其中n是字符串的长度。

双指针法

/**
 * 使用双指针法查找字符串中连续出现次数最多的字符及其出现次数
 * @param str 输入的字符串
 * @returns 数组,包含最多连续出现的字符和出现次数
 * 
 * 示例用例:
 * 1. strMost("aabbbcccc") => ["c", 4] 
 *    // 'c'连续出现4次
 * 2. strMost("abcde") => ["a", 1]
 *    // 所有字符都只连续出现1次,返回第一个字符
 * 3. strMost("aaabba") => ["a", 3]
 *    // 'a'有连续3次和1次,取最大值3
 */
export function strMost(str: string): [string, number] {
    // 处理空字符串情况
    if (!str) {
        return ["", 0];
    }
    // 处理单字符特殊情况
    if (str.length === 1) {
        return [str[0], 1];
    }
    
    // 初始化结果:["字符", 出现次数]
    const res: [string, number] = ["", 0];
    let i = 0;      // 慢指针:记录当前统计的字符起始位置
    let temCount = 0; // 当前字符的连续出现次数
    
    // 快指针j遍历整个字符串
    for (let j = 0; j < str.length; j++) {
        if (str[i] === str[j]) {
            temCount++; // 相同字符计数增加
        } else {
            // 发现新字符时,检查是否需要更新最大记录
            if (temCount > res[1]) {
                res[0] = str[i];
                res[1] = temCount;
            }
            // 重置指针和计数器
            i = j;
            temCount = 1;
        }
        
        // 处理字符串末尾情况
        if (j === str.length - 1) {
            if (temCount > res[1]) {
                res[0] = str[i];
                res[1] = temCount;
            }
        }
    }
    return res;
}

快指针j遍历整个字符串,慢指针i记录当前统计的字符起始位置。当遇到不同字符时,检查是否需要更新最大记录,并重置指针和计数器。这种方法的时间复杂度为O(n),其中n是字符串的长度。

Share