寻找独一无二的糖葫芦
1.问题描述
小C有n串长度为m的糖葫芦,每串糖葫芦可以用一个字符串表示。每个糖葫芦的甜度是所有字符甜度的总和,其中每个字符的甜度为该字符与 'a' 的差值。例如,字符 'a' 的甜度为 0,字符 'b' 的甜度为 1,依次类推,字符 'z' 的甜度为 25。
你需要帮助小C找到甜度最大的独一无二的糖葫芦。糖葫芦独一无二当且仅当它与其他n−1根糖葫芦都不同,且翻转后的字符串也不能与其他糖葫芦相同。例如,糖葫芦 "abc" 与 "cba" 视为相同的糖葫芦。
如果没有独一无二的糖葫芦,则返回0。
2.解题思路
2.1问题分析
- 甜度计算:每个字符的甜度是其与
'a'的差值。例如,'a'的甜度为 0,'b'的甜度为 1,依此类推。 - 独一无二:一个糖葫芦是独一无二的,如果它与所有其他糖葫芦不同,并且其翻转后的字符串也与其他糖葫芦不同。
- 目标:找到甜度最大的独一无二的糖葫芦。如果没有这样的糖葫芦,返回 0。
2.2基本思路
- 字符串排序:将每个字符串按字符排序,这样可以方便地比较字符串是否相同。
- 翻转字符串:生成每个字符串的翻转字符串,并将其排序。
- 计数器:使用计数器统计每个排序后的字符串和其翻转字符串的出现次数。
- 甜度计算:计算每个字符串的甜度。
- 筛选独一无二的糖葫芦:筛选出出现次数为 1 的字符串,并找到其中甜度最大的。
2.3示例
以样例1为例:
- 输入:
n = 3, m = 3, strings = ["ccz", "cba", "zcc"] - 排序后的字符串:
["ccz", "abc", "ccz"] - 翻转后的字符串:
["zcc", "abc", "zcc"] - 计数器:
{"ccz": 2, "abc": 1, "zcc": 2} - 甜度计算:
"ccz" -> 5, "cba" -> 3, "zcc" -> 5 - 结果:
"cba"是独一无二的,甜度为 3。
2.4代码
3.代码详解
- 字符串排序:
sorted_strings = [''.join(sorted(s)) for s in strings]将每个字符串按字符排序,方便比较。 - 翻转字符串:
reversed_strings = [''.join(sorted(s[::-1])) for s in strings]生成每个字符串的翻转字符串并排序。 - 计数器:
counter = Counter(sorted_strings + reversed_strings)统计每个排序后的字符串和其翻转字符串的出现次数。 - 甜度计算:
sweetness = sum(ord(c) - ord('a') for c in s)计算每个字符串的甜度。 - 筛选独一无二的糖葫芦:
if counter[''.join(sorted(s))] == 1 and counter[''.join(sorted(s[::-1]))] == 1检查字符串及其翻转字符串是否独一无二,并更新最大甜度。
珠子颜色去重
1.问题描述
小S拥有一条由n颗珠子组成的手链,每颗珠子都有一个对应的颜色编号。她希望将手链上相同颜色的珠子进行去重,只保留每种颜色最后出现的那颗珠子,同时保持珠子原来的相对顺序。
例如,如果珠子的颜色编号是 [1, 2, 1, 3, 4, 2, 4, 4],去重后的珠子颜色应该是 [1, 3, 2, 4]。
2.解题思路
2.1问题分析
我们需要处理一个包含颜色编号的列表,目标是去除重复的颜色,但只保留每种颜色最后出现的那一个,并且保持原有的相对顺序。
2.2基本思路
- 逆序遍历:从列表的末尾开始遍历,这样可以确保我们遇到的颜色是该颜色的最后一次出现。
- 使用集合记录已见过的颜色:当我们遇到一个颜色时,检查它是否已经出现在集合中。如果没有,则将其添加到结果列表中,并将其标记为已见过。
- 逆序结果:由于我们是逆序遍历的,最后的结果列表需要再逆序一次以恢复原来的相对顺序。
2.3示例
以输入 [1, 2, 1, 3, 4, 2, 4, 4] 为例:
-
逆序遍历:
[4, 4, 2, 4, 3, 1, 2, 1] -
记录已见过的颜色:
- 遇到
4,未见过,添加到结果列表,标记为已见过。 - 遇到
4,已见过,跳过。 - 遇到
2,未见过,添加到结果列表,标记为已见过。 - 遇到
4,已见过,跳过。 - 遇到
3,未见过,添加到结果列表,标记为已见过。 - 遇到
1,未见过,添加到结果列表,标记为已见过。 - 遇到
2,已见过,跳过。 - 遇到
1,已见过,跳过。
- 遇到
-
结果列表:
[4, 2, 3, 1] -
逆序结果列表:
[1, 3, 2, 4]
2.4代码
def solution(n: int, a: list) -> list:
seen = set()
res = []
for t in reversed(a):
if t not in seen:
seen.add(t)
res.append(t)
return list(reversed(res))
if __name__ == '__main__':
print(solution(n = 8, a = [1, 2, 1, 3, 4, 2, 4, 4]) == [1, 3, 2, 4])
print(solution(n = 5, a = [5, 5, 5, 5, 5]) == [5])
print(solution(n = 6, a = [6, 1, 2, 6, 1, 2]) == [6, 1, 2])
3.代码详解
- 逆序遍历:
for t in reversed(a)从列表的末尾开始遍历。 - 记录已见过的颜色:
seen = set()使用集合来记录已经见过的颜色。 - 添加到结果列表:
if t not in seen: seen.add(t); res.append(t)如果颜色未见过,则添加到结果列表中,并标记为已见过。 - 逆序结果列表:
return list(reversed(res))最后将结果列表逆序一次以恢复原来的相对顺序。 至此,完结撒花!