本博客含有两道题目:查找热点数据;字符串修改最少次数计算
查找热点数据
问题描述
给你一个整数数组 nums 和一个整数 k,请你用一个字符串返回其中出现频率前 k 高的元素。请按升序排列。
你所设计算法的时间复杂度必须优于 O(n log n),其中 n 是数组大小。
输入
- nums: 一个正整数数组
- k: 一个整数
返回
返回一个包含 k 个元素的字符串,数字元素之间用逗号分隔。数字元素按升序排列,表示出现频率最高的 k 个元素。
参数限制
- 1 <= nums[i] <= 10^4
- 1 <= nums.length <= 10^5
- k 的取值范围是 [1, 数组中不相同的元素的个数]
- 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的
我的思路
- 统计每个元素出现的频率
- 由于时间复杂度的限制,使用堆去寻找频率最高的元素
- 寻找完毕之后进行升序排序
- 将元素进行拼接并返回
豆包思路
- 统计频率: 使用
Counter统计数组中每个元素的频率。 - 找到频率最高的 k 个元素: 使用
heapq.nlargest从频率统计中找到频率最高的k个元素。 - 排序: 对找到的
k个元素按升序排序。 - 返回结果: 将排序后的元素转换为字符串并返回。
融合思路并编程
与豆包思路进行对比之后,发现思路几乎相近。
def solution(nums, k):
# Please write your code here
count = Counter(nums) # O(n)
count = Counter(nums)
heap=heapq.nlargest(k, count.keys(), key=count.get)
heap.sort()
return ",".join([str(item) for item in heap])
上述思路的时间复杂度是 O(n log k) ,为了探索更高效的代码,对豆包进行了一些咨询,最终得到豆包的解释,代码无法继续优化以降低时间复杂度
-
Counter(nums):- 这一步已经是 O(n),无法进一步优化。
-
heapq.nlargest(k, count.keys(), key=count.get):- 这一步的时间复杂度是 O(n log k),已经是最优的,因为我们需要找到频率最高的 k 个元素。
-
heap.sort():- 这一步的时间复杂度是 O(k log k),已经是最优的,因为我们需要对 k 个元素进行排序。
-
",".join([str(item) for item in heap]):- 这一步的时间复杂度是 O(k),已经是最优的。
字符串修改最少次数计算
问题描述
小C有一个由数字字符组成的字符串,她想对这个字符串进行修改,使修改后的字符串中没有连续相同的字符。她需要计算至少进行多少次修改,才能确保字符串中的每两个连续字符不同。
我的思路
- 从第二个字符开始遍历字符串
- 如果该字符与前一个字符相同,则改变次数加一,并且在下次遍历时跳动两个单位,即i=i+2
- 如果该字符与前一个字符不相同,则在下次遍历时跳动一个单位,即i=i+1
豆包思路
- 遍历字符串:我们需要遍历字符串中的每一个字符。
- 检查连续字符:对于每一个字符,检查它是否与前一个字符相同。
- 计数修改次数:如果当前字符与前一个字符相同,则需要进行一次修改,并将计数器加一。
- 返回结果:遍历结束后,返回计数器的值。
融合思路并编程
对比思路,可以发现豆包的思路出现问题。然后用我的思路灌输给豆包,豆包随即也认同了我的思路,改进后的代码能够正确处理连续三个或四个相同字符的情况。每次遇到连续相同字符时,计数器都会增加,并且会跳过下一个字符,确保不会重复计数。最后让豆包进行编码,发现豆包的编码过程比我更为简洁。
我的代码:
def solution(s: str) -> int:
changes = 0
flag=0
i=1
# 遍历字符串,从第二个字符开始
while (i <len(s)):
# 如果当前字符与前一个字符相同
i=i+flag
if i>=len(s):
return changes
if s[i] == s[i - 1]:
# 增加修改次数
flag=1
changes += 1
else:
flag=0
i+=1
# 返回修改次数
return changes
豆包代码:
def solution(s: str) -> int:
changes = 0
i = 1
# 遍历字符串,从第二个字符开始
while i < len(s):
# 如果当前字符与前一个字符相同
if s[i] == s[i - 1]:
# 增加修改次数
changes += 1
# 跳过下一个字符,因为我们已经修改了当前字符
i += 1
i += 1
# 返回修改次数
return changes