竞赛算法求解:如何获取字符串中最多优势字符数量?
解法:最大化字符串中的优势字符数量
首先先明确问题定义:
给定一个字符串,若某个字符同时存在左右相邻字符,且自身在字母表中的位置严格大于这两个相邻字符,则称该字符为优势字符。我们需要设计高效算法,求解重新排列该字符串后最多可存在的优势字符数量(注:如果题目是要求原字符串中已有的优势字符数量,直接遍历一遍即可,但竞赛题通常聚焦排列后的最大值,这里按此场景解答)。
核心思路分析
优势字符的本质是字符串中的「峰」——左右两侧的字符都比它小。要最大化峰的数量,核心要处理字符频率的限制:
- 高频字符会限制排列灵活性:如果某个字符出现次数过多,必然会出现相邻情况,导致无法成为峰。
- 频率合理的场景下,我们可以通过「峰谷交替」的排列方式,让尽可能多的大字符占据峰的位置。
竞赛级算法步骤
- 统计字符频率:遍历字符串,统计每个字符的出现次数,同时计算字符串总长度
n。 - 定位高频字符:找出所有字符中出现次数最多的那个,记为
max_cnt。 - 计算非高频字符总数:
m = n - max_cnt(即除高频字符外,其他所有字符的总数量)。 - 分情况计算最大值:
- 情况1:高频字符数量过载(
max_cnt > m + 1):
此时高频字符无法被完全分隔,多余的高频字符会挤占峰的位置,最多能形成的优势字符数量为max(0, 2*m - max_cnt + 1)。 - 情况2:高频字符刚好可完全分隔(
max_cnt == m + 1):
此时高频字符会被非高频字符分隔成「首尾都是高频字符」的结构,只有中间的高频字符能成为优势字符,数量为max(0, max_cnt - 2)(等价于m - 1)。 - 情况3:高频字符数量合理(
max_cnt < m + 1):
此时我们可以通过峰谷交替排列,让尽可能多的大字符成为峰,最多数量为(n - 1) // 2。
- 情况1:高频字符数量过载(
代码示例(Python)
def max_dominant_chars(s): from collections import Counter char_counts = Counter(s) total_length = len(s) max_count = max(char_counts.values()) non_max_total = total_length - max_count if max_count > non_max_total + 1: return max(0, 2 * non_max_total - max_count + 1) elif max_count == non_max_total + 1: return max(0, max_count - 2) else: return (total_length - 1) // 2 # 测试用例验证 print(max_dominant_chars("zzzab")) # 输出1:对应排列zazbz,中间的z是优势字符 print(max_dominant_chars("zzzzabc")) # 输出2:对应排列zazbzcz,中间两个z是优势字符 print(max_dominant_chars("abac")) # 输出1:最多只能有1个优势字符(如排列acba中的c) print(max_dominant_chars("abcde")) # 输出2:对应排列a c b e d,c和e是优势字符
复杂度分析
- 时间复杂度:O(n),其中n是字符串长度,统计频率和遍历操作均为线性时间。
- 空间复杂度:O(1),因为字符集最多包含26个小写字母,计数器的空间为常数级。
内容的提问来源于stack exchange,提问作者Kefhee 11
相关产品推荐
相关产品推荐

