AI刷题题目解析01 | 豆包MarsCode AI刷题

40 阅读4分钟

1.找单独的数

问题描述

在一个班级中,每位同学都拿到了一张卡片,上面有一个整数。有趣的是,除了一个数字之外,所有的数字都恰好出现了两次。现在需要你帮助班长小C快速找到那个拿了独特数字卡片的同学手上的数字是什么。

要求:

  1. 设计一个算法,使其时间复杂度为 O(n),其中 n 是班级的人数。
  2. 尽量减少额外空间的使用,以体现你的算法优化能力。

解题思路

可以利用异或运算(XOR)的特性。异或运算有一个非常有用的性质:对于任何整数 aa ^ a = 0,并且 a ^ 0 = a。这意味着如果我们对数组中的所有元素进行异或运算,所有出现两次的数字都会相互抵消,最终剩下的就是那个只出现一次的数字。

代码实现

def solution(cards):
    # 初始化结果变量为0
    result = 0
    
    # 遍历数组中的每个元素
    for card in cards:
        # 将结果与当前元素进行异或运算
        result ^= card
    
    # 返回结果
    return result

4.数字分组求偶数和

问题描述

小M面对一组从 1 到 9 的数字,这些数字被分成多个小组,并从每个小组中选择一个数字组成一个新的数。目标是使得这个新数的各位数字之和为偶数。任务是计算出有多少种不同的分组和选择方法可以达到这一目标。

  • numbers: 一个由多个整数字符串组成的列表,每个字符串可以视为一个数字组。小M需要从每个数字组中选择一个数字。

例如对于[123, 456, 789],14个符合条件的数为:147 149 158 167 169 248 257 259 268 347 349 358 367 369

解题思路

  1. 拆分数字组:将每个数字组拆分为单个数字。
  2. 生成所有可能的组合:使用递归或迭代的方式生成从每个数字组中选择一个数字的所有可能组合。
  3. 判断组合的和是否为偶数:对于每个生成的组合,计算其各位数字之和,并判断是否为偶数。
  4. 统计符合条件的组合数量:记录所有符合条件的组合数量。

代码实现

def solution(numbers):
    # 拆分数字组
    groups = [[int(digit) for digit in str(num)] for num in numbers]

    # 生成所有可能的组合并判断是否符合条件
    count = generate_combinations(groups, 0, [], 0)

    return count

def generate_combinations(groups: list[list[int]], index: int, current_combination: list[int], count: int) -> int:
    if index == len(groups):
        # 计算当前组合的各位数字之和
        sum_digits = sum(current_combination)
        # 判断是否为偶数
        if sum_digits % 2 == 0:
            count += 1
        return count

    # 递归生成组合
    current_group = groups[index]
    for num in current_group:
        current_combination.append(num)
        count = generate_combinations(groups, index + 1, current_combination, count)
        current_combination.pop()

    return count

84.数列差异的最小化

问题描述

小R在研究两个数列之间的关系。他给定了两个数列 a 和 b,长度分别为 n 和 m,并设计了一个有趣的公式:∣(a[i]−b[j])2−k2∣∣(a[i]−b[j])^2−k^2∣∣(a[i]−b[j])2−k2∣,其中 k 是给定的一个整数, 0≤i<n,0≤j<m 0≤i<n,0≤j<m 0≤i<n,0≤j<m。现在,小R想知道如何选择数列 a 和 b 中的元素 a[i] 和 b[j],使得这个公式的值达到最小。

给定两个整数数列 a(长度为 n) 和 b(长度为 m),以及一个整数 k,你需要找到这个公式的最小值。

解题思路

  1. 遍历数列 a 和 b

    • 对于每个 a[i],我们需要找到一个 b[j] 使得公式 ∣(a[i]−b[j])2−k2∣ 的值最小。
    • 由于 a 和 b 的长度可能非常大,直接遍历所有组合的时间复杂度是 O(n×m),这在大数据量下是不可接受的。
  2. 优化思路

    • 我们可以对数列 b 进行排序,然后使用二分查找来快速找到最接近的 b[j]
    • 对于每个 a[i],我们可以计算出 target = a[i]^2 - k^2,然后在排序后的 b 数列中找到最接近 target 的值。
  3. 二分查找

    • 使用二分查找可以在 log(m) 的时间内找到最接近 target 的值。

代码实现

def solution(n: int, m: int, k: int, a: list[int], b: list[int]) -> int:
    # 对数列 b 进行排序
    b.sort()
    
    min_diff = float('inf')
    
    for ai in a:
        target = ai**2 - k**2
        # 使用二分查找找到最接近 target 的 b[j]
        closest_b = binary_search_closest(b, target)
        # 计算当前的差值
        current_diff = abs((ai - closest_b)**2 - k**2)
        # 更新最小差值
        min_diff = min(min_diff, current_diff)
    
    return min_diff

def binary_search_closest(arr, target):
    # 实现二分查找,找到最接近 target 的值
    left, right = 0, len(arr) - 1
    closest = None
    
    while left <= right:
        mid = (left + right) // 2
        if arr[mid] == target:
            return arr[mid]
        elif arr[mid] < target:
            left = mid + 1
        else:
            right = mid - 1
        
        # 更新 closest
        if closest is None or abs(arr[mid] - target) < abs(closest - target):
            closest = arr[mid]
    
    return closest

备注:这道题的测试用例有问题