一、面试问题
给定一个字符串s,任务是找出字符串中连续重复出现次数最多的字符。
注意:我们不需要考虑字符的总出现次数,只需要考虑在同一个位置连续出现的次数。
示例 1:
输入:s = "gooogle"
输出:o
解释:字符o连续出现 3 次,为最多。
示例 2:
输入:s = "aaaabbcbbb"
输出:a
解释:字符a连续出现 4 次,为最多。
二、【朴素解法】使用嵌套循环 —— 时间复杂度 O(n²),空间复杂度 O(1)
(一) 解法思路
核心思路是采用嵌套循环的方法:外层循环遍历字符串的每一个字符;针对每一个字符,内层循环会向后遍历并统计该字符的连续出现次数,直到遇到不同的字符为止。
(二) 使用 5 种语言实现
1. C++
// C++ 程序:找出给定字符串中**连续重复次数最多**的字符 #include<iostream> using namespace std; // 函数功能:找出字符串中连续重复出现次数最多的字符 char maxRepeating(string s) { int n = s.length(); // 获取字符串长度 int maxCnt = 0; // 记录最大连续重复次数 char res = s[0]; // 记录最终结果(出现最多的字符) // 外层循环:遍历字符串的每一个字符作为起点 for (int i = 0; i < n; i++) { int cnt = 0; // 统计当前字符 s[i] 的连续重复次数 // 内层循环:从 i 开始向后统计连续相同的字符 for (int j = i; j < n; j++) { // 如果遇到不同字符,停止统计 if (s[i] != s[j]) break; cnt++; // 相同则计数+1 } // 如果当前字符连续次数 > 历史最大值,更新结果 if (cnt > maxCnt) { maxCnt = cnt; res = s[i]; } } return res; // 返回连续重复最多的字符 } // 主函数:测试代码 int main() { string s = "aaaabbaaccde"; // 测试字符串 cout << maxRepeating(s); // 输出结果:a return 0; }2. Java
// Java 程序:找出给定字符串中连续重复出现次数最多的字符 class DSA { // 函数功能:找出字符串中连续重复次数最多的字符 static char maxRepeating(String s) { int n = s.length(); // 获取字符串长度 int maxCnt = 0; // 记录最大连续重复次数 char res = s.charAt(0); // 记录结果字符 // 遍历每个字符作为起点 for (int i = 0; i < n; i++) { int cnt = 0; // 统计从 i 开始连续相同的字符个数 for (int j = i; j < n; j++) { if (s.charAt(i) != s.charAt(j)) break; cnt++; } // 如果当前连续次数更大,则更新结果 if (cnt > maxCnt) { maxCnt = cnt; res = s.charAt(i); } } return res; } public static void main(String[] args) { String s = "aaaabbaaccde"; // 输出连续重复最多的字符:a System.out.println(maxRepeating(s)); } }3. Python
# Python 程序:找出字符串中**连续重复次数最多**的字符 # 函数功能:找出字符串中连续重复出现次数最多的字符 def maxRepeating(s): n = len(s) # 获取字符串长度 maxCnt = 0 # 记录最大连续重复次数 res = s[0] # 记录最终结果(出现最多的字符) # 外层循环:遍历每一个字符作为起点 for i in range(n): cnt = 0 # 统计当前字符 s[i] 的连续重复次数 # 内层循环:从 i 开始向后统计连续相同的字符 for j in range(i, n): if s[i] != s[j]: # 遇到不同字符,停止统计 break cnt += 1 # 字符相同,计数+1 # 如果当前连续次数 > 历史最大值,更新结果 if cnt > maxCnt: maxCnt = cnt res = s[i] return res # 返回连续重复最多的字符 # 主程序:测试代码 if __name__ == "__main__": s = "aaaabbaaccde" # 测试字符串 print(maxRepeating(s)) # 输出结果:a4. C#
// C# 程序:找出给定字符串中连续重复出现次数最多的字符 using System; class DSA { // 函数功能:找出字符串中连续重复次数最多的字符 static char maxRepeating(string s) { int n = s.Length; // 获取字符串长度 int maxCnt = 0; // 记录最大连续重复次数 char res = s[0]; // 存储最终结果(连续重复最多的字符) // 外层循环:遍历每个字符,作为统计起点 for (int i = 0; i < n; i++) { int cnt = 0; // 记录当前字符 s[i] 的连续重复次数 // 内层循环:从 i 开始向后统计连续相同字符 for (int j = i; j < n; j++) { // 遇到不同字符,停止统计 if (s[i] != s[j]) break; cnt++; // 字符相同,计数+1 } // 如果当前字符连续次数更大,更新最大值和结果 if (cnt > maxCnt) { maxCnt = cnt; res = s[i]; } } return res; } // 主函数:程序入口,测试代码 static void Main(string[] args) { string s = "aaaabbaaccde"; // 输出结果:a Console.WriteLine(maxRepeating(s)); } }5. JavaScript
// JavaScript 程序:找出字符串中连续重复出现次数最多的字符 // 函数功能:找出字符串中连续重复次数最多的字符 function maxRepeating(str) { let n = str.length; // 获取字符串长度 let maxCnt = 0; // 记录最大连续重复次数 let res = str[0]; // 记录结果字符 // 外层循环:遍历每个字符作为起点 for (let i = 0; i < n; i++) { let cnt = 0; // 统计当前字符的连续次数 // 内层循环:从 i 开始统计连续相同字符 for (let j = i; j < n; j++) { if (str[i] !== str[j]) { // 遇到不同字符,停止统计 break; } cnt++; // 字符相同,计数+1 } // 如果当前连续次数更大,更新结果 if (cnt > maxCnt) { maxCnt = cnt; res = str[i]; } } return res; } // 测试代码 let s = "aaaabbaaccde"; console.log(maxRepeating(s)); // 输出:a(三)代码输出和算法复杂度
输出:
a时间复杂度:O(n²)
空间复杂度:O(1)
三、【优化解法-1】连续重复最多字符 —— 时间复杂度 O(n),空间复杂度 O(1)
(一) 解法思路
在上述方法中,我们无需让外层循环从 0 到 n-1 逐个索引运行,而是可以直接从内层循环的结束位置继续更新外层循环。因为我们不需要多次统计相同的元素,下一次迭代可以直接从遇到的不同字符处开始。
(二) 使用 5 种语言实现
1. C++
// C++ 程序:查找字符串中连续重复次数最多的字符(优化版本) #include<iostream> using namespace std; // 函数:查找字符串中连续重复出现次数最多的字符 char maxRepeating(string s) { int n = s.length(); // 获取字符串的长度 int maxCnt = 0; // 存储最大的连续重复次数 char res = s[0]; // 存储最终结果:连续重复最多的字符 // 外层循环遍历字符串,核心优化:i 会直接跳过已统计的连续字符 for (int i=0; i<n; i++) { int cnt = 1; // 当前字符初始计数为1(自身) // 统计连续相同的字符:如果下一个字符和当前字符相同 while(i + 1 < n && s[i] == s[i + 1]) { i++; // i 自增,直接跳过重复字符,不再重复遍历 cnt++; // 连续次数加1 } // 如果当前连续次数大于历史最大值,更新结果 if (cnt > maxCnt) { maxCnt = cnt; res = s[i]; } } return res; } // 主函数:测试程序 int main() { string s = "aaaabbaaccde"; cout << maxRepeating(s); // 输出结果:a return 0; }2. Java
// Java 程序:优化版 —— 查找字符串中连续重复次数最多的字符 class DSA { // 函数:查找字符串中连续重复出现次数最多的字符 static char maxRepeating(String s) { int n = s.length(); // 获取字符串长度 int maxCnt = 0; // 记录最大连续重复次数 char res = s.charAt(0); // 记录结果字符 // 外层循环:核心优化,i 会直接跳过已统计的连续重复字符 for (int i = 0; i < n; i++) { int cnt = 1; // 当前字符初始计数为 1(自身) // 统计连续相同字符:如果下一个字符和当前字符相同 while (i + 1 < n && s.charAt(i) == s.charAt(i + 1)) { i++; // i 自增,直接跳过重复字符,不重复遍历 cnt++; // 连续次数 +1 } // 如果当前连续次数更大,更新最大值和结果 if (cnt > maxCnt) { maxCnt = cnt; res = s.charAt(i); } } return res; } // 主函数:测试代码 public static void main(String[] args) { String s = "aaaabbaaccde"; System.out.println(maxRepeating(s)); // 输出:a } }3. Python
# Python 程序:优化版 —— 查找字符串中连续重复次数最多的字符 # 核心优化:跳过已统计的连续字符,不重复遍历 # 函数:找出字符串中连续重复出现次数最多的字符 def maxRepeating(s): n = len(s) # 获取字符串长度 maxCnt = 0 # 记录最大连续重复次数 res = s[0] # 记录结果字符 i = 0 # 初始化索引,使用 while 循环手动控制 # 外层循环:遍历字符串(手动控制索引 i) while i < n: cnt = 1 # 当前字符初始计数为 1(自身) # 内层循环:统计连续相同的字符,同时跳过重复字符 while i + 1 < n and s[i] == s[i + 1]: i += 1 # 索引自增,直接跳过已统计的重复字符 cnt += 1 # 连续次数 +1 # 更新最大值和结果字符 if cnt > maxCnt: maxCnt = cnt res = s[i] i += 1 # 索引向后移动一位,处理下一组不同字符 return res # 返回连续重复最多的字符 # 主函数:测试代码 def main(): s = "aaaabbaaccde" print(maxRepeating(s)) # 输出:a if __name__ == "__main__": main()4. C#
// C# 程序:优化版 —— 查找字符串中连续重复次数最多的字符 using System; class GFG { // 函数:查找字符串中连续重复出现次数最多的字符 static char MaxRepeating(string s) { int n = s.Length; // 获取字符串长度 int maxCnt = 0; // 记录最大连续重复次数 char res = s[0]; // 记录结果字符 // 外层循环:核心优化,i 会直接跳过已统计的连续重复字符 for (int i = 0; i < n; i++) { int cnt = 1; // 当前字符初始计数为 1(自身) // 统计连续相同字符:如果下一个字符和当前字符相同 while (i + 1 < n && s[i] == s[i + 1]) { i++; // i 自增,直接跳过重复字符,不重复遍历 cnt++; // 连续次数 +1 } // 如果当前连续次数更大,更新最大值和结果 if (cnt > maxCnt) { maxCnt = cnt; res = s[i]; } } return res; } // 主函数:程序入口,测试代码 public static void Main() { string s = "aaaabbaaccde"; Console.WriteLine(MaxRepeating(s)); // 输出:a } }5. JavaScript
// JavaScript 程序:优化版 —— 查找字符串中连续重复次数最多的字符 // 核心优化:跳过已统计的连续字符,时间复杂度 O(n) // 函数:找出字符串中连续重复出现次数最多的字符 function maxRepeating(s) { let n = s.length; // 获取字符串长度 let maxCnt = 0; // 记录最大连续重复次数 let res = s[0]; // 记录结果字符 // 外层循环:核心优化,i 会直接跳过已统计的连续重复字符 for (let i = 0; i < n; i++) { let cnt = 1; // 当前字符初始计数为 1(自身) // 内层循环:统计连续相同的字符,同时跳过重复字符 while (i + 1 < n && s[i] === s[i + 1]) { i++; // 索引自增,直接跳过已统计的重复字符 cnt++; // 连续次数 +1 } // 如果当前连续次数更大,更新最大值和结果 if (cnt > maxCnt) { maxCnt = cnt; res = s[i]; } } return res; } // 主函数:测试代码 function main() { let s = "aaaabbaaccde"; console.log(maxRepeating(s)); // 输出:a } // 执行程序 main();(三)代码输出和算法复杂度
输出:
a时间复杂度:O(n)
空间复杂度:O(1)
四、【优化解法-2】使用计数变量法 —— 时间复杂度 O(n),空间复杂度 O(1)
(一) 解法思路
核心思路是:从字符串的第二个字符(索引 1)开始遍历,将每个字符与前一个字符进行比较,以此识别连续重复的字符序列。若当前字符与前一个字符相同,就将计数器加 1;若不同,则将计数器重置为 1。每次检查当前连续长度是否大于已记录的最大长度 —— 如果是,就同时更新最大计数值和结果字符。
(二) 使用 5 种语言实现
1. C++
// C++ 程序:最优单循环解法 —— 找连续重复最多的字符 #include <iostream> using namespace std; // 函数:找出字符串中连续重复出现次数最多的字符 char maxRepeating(string s) { int n = s.length(); // 字符串长度 int maxCnt = 0; // 记录最长连续次数 char res = s[0]; // 记录结果字符 int cnt = 1; // 当前连续计数,初始为1 // 从第二个字符(索引1)开始遍历 for (int i = 1; i < n; i++) { // 当前字符 == 前一个字符 → 连续次数+1 if (s[i] == s[i - 1]) { cnt++; } // 字符不同 → 重置连续计数为1(新的字符开始) else { cnt = 1; } // 如果当前连续次数 > 历史最大值 → 更新结果 if (cnt > maxCnt) { maxCnt = cnt; res = s[i]; // 记录当前最长连续字符 } } return res; } // 主函数测试 int main() { string s = "aaaabbaaccde"; cout << maxRepeating(s) << endl; // 输出:a return 0; }2. Java
// Java 程序:最优单循环解法 —— 查找字符串中连续重复次数最多的字符 class DSA { // 函数:找出字符串中连续重复出现次数最多的字符 static char maxRepeating(String s) { int n = s.length(); // 获取字符串长度 int maxCnt = 0; // 记录最长连续重复次数 char res = s.charAt(0); // 记录结果字符 int cnt = 1; // 当前连续计数,初始为 1 // 从第二个字符(索引 1)开始遍历 for (int i = 1; i < n; i++) { // 如果当前字符与前一个字符相同,连续计数 +1 if (s.charAt(i) == s.charAt(i - 1)) { cnt++; } // 如果字符不同,重置连续计数为 1 else { cnt = 1; } // 如果当前连续次数 > 历史最大值,更新结果 if (cnt > maxCnt) { maxCnt = cnt; res = s.charAt(i - 1); } } return res; } // 主函数:测试代码 public static void main(String args[]) { String s = "aaaabbaaccde"; System.out.println(maxRepeating(s)); // 输出:a } }3. Python
# Python 程序:最优单循环解法 —— 查找字符串中连续重复次数最多的字符 # 函数:找出字符串中连续重复出现次数最多的字符 def maxRepeating(s): n = len(s) # 获取字符串长度 maxCnt = 0 # 记录最长连续重复次数 res = s[0] # 记录结果字符 cnt = 1 # 当前连续计数,初始为 1 # 从第二个字符(索引 1)开始遍历 for i in range(1, n): # 如果当前字符与前一个字符相同 → 连续计数 +1 if s[i] == s[i - 1]: cnt += 1 # 如果字符不同 → 重置连续计数为 1 else: cnt = 1 # 如果当前连续次数 > 历史最大值 → 更新结果 if cnt > maxCnt: maxCnt = cnt res = s[i - 1] return res # 测试代码 s = "aaaabbaaccde" print(maxRepeating(s)) # 输出:a4. C#
// C# 程序:最优单循环解法 —— 查找字符串中连续重复次数最多的字符 using System; class DSA { // 函数:找出字符串中连续重复出现次数最多的字符 static char MaxRepeating(string s) { int n = s.Length; // 获取字符串长度 int maxCnt = 0; // 记录最长连续重复次数 char res = s[0]; // 记录结果字符 int cnt = 1; // 当前连续计数,初始为 1 // 从第二个字符(索引 1)开始遍历 for (int i = 1; i < n; i++) { // 当前字符 == 前一个字符 → 连续次数 +1 if (s[i] == s[i - 1]) { cnt++; } // 字符不同 → 重置计数为 1 else { cnt = 1; } // 如果当前连续次数更长 → 更新最大值和结果 if (cnt > maxCnt) { maxCnt = cnt; res = s[i - 1]; } } return res; } // 主函数:测试代码 public static void Main() { string s = "aaaabbaaccde"; Console.WriteLine(MaxRepeating(s)); // 输出:a } }5. JavaScript
// JavaScript 程序:最优单循环解法 —— 查找字符串中连续重复次数最多的字符 // 函数:找出字符串中连续重复出现次数最多的字符 function maxRepeating(s) { let n = s.length; // 获取字符串长度 let maxCnt = 0; // 记录最长连续重复次数 let res = s[0]; // 记录结果字符 let cnt = 1; // 当前连续计数,初始为 1 // 从第二个字符(索引 1)开始遍历 for (let i = 1; i < n; i++) { // 当前字符与前一个相同 → 连续计数 +1 if (s[i] === s[i - 1]) { cnt++; } // 字符不同 → 重置连续计数为 1 else { cnt = 1; } // 如果当前连续次数 > 历史最大值 → 更新结果 if (cnt > maxCnt) { maxCnt = cnt; res = s[i - 1]; } } return res; } // 测试代码 let s = "aaaabbaaccde"; console.log(maxRepeating(s)); // 输出:a(三)代码输出和算法复杂度
输出:
a时间复杂度:O(n)
空间复杂度:O(1)