刷题笔记:寻找独一无二的糖葫芦串
题目解析
题目给出了一个糖葫芦串列表,每个糖葫芦可以用一个字符串表示。需要找到独一无二且甜度最大的糖葫芦串。以下是题目的具体点:
-
甜度计算:
- 每个字符的甜度等于它与
'a'的 ASCII 值差值。例如:'a'的甜度是0,'b'的甜度是1,依次类推。 - 糖葫芦串的甜度是所有字符甜度的总和。
- 每个字符的甜度等于它与
-
独一无二条件:
-
一个糖葫芦串是独一无二的,当它与列表中其他任何糖葫芦串都不同,且其翻转后也与其他糖葫芦串不同。例如:
abc和cba视为相同。
-
为了处理翻转的情况,可以对字符串和其翻转字符串取字典序较小的作为统一表示。
-
-
输出:
- 找到甜度最大的独一无二糖葫芦串的甜度。
- 如果没有独一无二糖葫芦串,返回
0。
解决思路
1. 规范化字符串
-
每个字符串需要处理翻转等价性:
- 对字符串
s,将它和s[::-1](翻转字符串)进行字典序比较。 - 取较小值作为统一规范化表示。
- 对字符串
-
例如:
- 对于
abc和cba,它们的规范化结果都是abc。 - 对于
aa和aa(翻转结果相同),规范化结果是aa。
- 对于
2. 计算甜度
- 字符的甜度计算公式:
ord(c) - ord('a')。 - 字符串甜度是所有字符甜度的累加和。
3. 统计频次
- 使用字典
freq记录每个规范化字符串的出现次数。 - 使用字典
sweetness_map保存每个规范化字符串的甜度值。
4. 找独一无二字符串
-
遍历
freq中的字符串:- 如果出现次数为 1,则表示它是独一无二的糖葫芦串。
- 从这些独一无二的糖葫芦串中,找出甜度最大的一个。
5. 输出结果
- 如果存在独一无二的糖葫芦串,返回最大甜度。
- 如果没有独一无二的糖葫芦串,返回
0。
图解分析
假设输入:n = 5, m = 2, strings = ["aa", "bb", "ab", "ba", "cc"]
1. 输入字符串及其翻转等价性处理
原始串 s | 翻转串 s[::-1] | 规范化结果 normalized |
|---|---|---|
aa | aa | aa |
bb | bb | bb |
ab | ba | ab |
ba | ab | ab |
cc | cc | cc |
2. 甜度计算
串 normalized | 甜度计算 | 甜度 |
|---|---|---|
aa | 0 + 0 | 0 |
bb | 1 + 1 | 2 |
ab | 0 + 1 | 1 |
cc | 2 + 2 | 4 |
3. 频次统计
串 normalized | 出现次数 freq | 甜度 |
|---|---|---|
aa | 1 | 0 |
bb | 1 | 2 |
ab | 2 | 1 |
cc | 1 | 4 |
4. 找独一无二且甜度最大的糖葫芦
- 独一无二的串为:
aa、bb、cc。 - 最大甜度为
4(对应串cc)。
代码详解
def solution(n: int, m: int, strings: list) -> int:
# 用字典存储规范化后的糖葫芦及其出现次数
freq = {}
sweetness_map = {}
for s in strings:
# 规范化:取字符串和其翻转的字典序较小值
normalized = min(s, s[::-1])
# 计算甜度
sweetness = sum(ord(c) - ord('a') for c in s)
# 更新频次
freq[normalized] = freq.get(normalized, 0) + 1
# 保存甜度(只需要保存一次,因为规范化后的甜度是相同的)
sweetness_map[normalized] = sweetness
# 筛选独一无二的糖葫芦
max_sweetness = 0
for normalized, count in freq.items():
if count == 1: # 独一无二
max_sweetness = max(max_sweetness, sweetness_map[normalized])
return max_sweetness
代码运行过程
输入: n = 5, m = 2, strings = ["aa", "bb", "ab", "ba", "cc"]
Step 1: 规范化与频次统计
freq = {"aa": 1, "bb": 1, "ab": 2, "cc": 1}
sweetness_map = {"aa": 0, "bb": 2, "ab": 1, "cc": 4}
Step 2: 找独一无二的串
freq["aa"] = 1-> 独一无二,甜度0freq["bb"] = 1-> 独一无二,甜度2freq["cc"] = 1-> 独一无二,甜度4freq["ab"] = 2-> 非独一无二,跳过。
Step 3: 返回最大甜度
最大甜度 = 4。
复杂度分析
-
时间复杂度:
- 规范化每个字符串的时间为 O(m)O(m),总计 O(n⋅m)O(n \cdot m)。
- 甜度计算和字典操作的复杂度为 O(n)O(n)。
- 因此总时间复杂度为 O(n⋅m)O(n \cdot m)。
-
空间复杂度:
- 需要存储
freq和sweetness_map,共 O(n)。
- 需要存储
测试用例
if __name__ == '__main__':
# 测试样例
print(solution(3, 3, ["ccz", "cba", "zcc"])) # 输出: 3
print(solution(2, 3, ["abc", "cba"])) # 输出: 0
print(solution(5, 2, ["aa", "bb", "ab", "ba", "cc"])) # 输出: 4
print(solution(1, 1, ["z"])) # 输出: 25
print(solution(4, 3, ["abc", "def", "fed", "ghi"])) # 输出: 7
总结
- 规范化字符串解决了翻转等价性问题。
- 频次统计和甜度计算使得独一无二糖葫芦的筛选高效。
- 时间复杂度 O(n⋅m) 对较大输入也有良好性能表现。