豆包MarsCode 刷题(七) | 豆包MarsCode AI刷题

43 阅读4分钟

本博客含有两道题目:查找热点数据;字符串修改最少次数计算

查找热点数据

问题描述

给你一个整数数组 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 个高频元素的集合是唯一的

我的思路

  • 统计每个元素出现的频率
  • 由于时间复杂度的限制,使用堆去寻找频率最高的元素
  • 寻找完毕之后进行升序排序
  • 将元素进行拼接并返回

豆包思路

  1. 统计频率: 使用 Counter 统计数组中每个元素的频率。
  2. 找到频率最高的 k 个元素: 使用 heapq.nlargest 从频率统计中找到频率最高的 k 个元素。
  3. 排序: 对找到的 k 个元素按升序排序。
  4. 返回结果: 将排序后的元素转换为字符串并返回。

融合思路并编程

与豆包思路进行对比之后,发现思路几乎相近。

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) ,为了探索更高效的代码,对豆包进行了一些咨询,最终得到豆包的解释,代码无法继续优化以降低时间复杂度

  1. Counter(nums) :

    • 这一步已经是 O(n),无法进一步优化。
  2. heapq.nlargest(k, count.keys(), key=count.get) :

    • 这一步的时间复杂度是 O(n log k),已经是最优的,因为我们需要找到频率最高的 k 个元素。
  3. heap.sort() :

    • 这一步的时间复杂度是 O(k log k),已经是最优的,因为我们需要对 k 个元素进行排序。
  4. ",".join([str(item) for item in heap]) :

    • 这一步的时间复杂度是 O(k),已经是最优的。

字符串修改最少次数计算

问题描述

小C有一个由数字字符组成的字符串,她想对这个字符串进行修改,使修改后的字符串中没有连续相同的字符。她需要计算至少进行多少次修改,才能确保字符串中的每两个连续字符不同。

我的思路

  • 从第二个字符开始遍历字符串
  • 如果该字符与前一个字符相同,则改变次数加一,并且在下次遍历时跳动两个单位,即i=i+2
  • 如果该字符与前一个字符不相同,则在下次遍历时跳动一个单位,即i=i+1

豆包思路

  1. 遍历字符串:我们需要遍历字符串中的每一个字符。
  2. 检查连续字符:对于每一个字符,检查它是否与前一个字符相同。
  3. 计数修改次数:如果当前字符与前一个字符相同,则需要进行一次修改,并将计数器加一。
  4. 返回结果:遍历结束后,返回计数器的值。

融合思路并编程

对比思路,可以发现豆包的思路出现问题。然后用我的思路灌输给豆包,豆包随即也认同了我的思路,改进后的代码能够正确处理连续三个或四个相同字符的情况。每次遇到连续相同字符时,计数器都会增加,并且会跳过下一个字符,确保不会重复计数。最后让豆包进行编码,发现豆包的编码过程比我更为简洁。

我的代码:
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