青训营试题算法解析十九

介绍

‌豆包青训营‌是由字节跳动和稀土掘金社区共同发起的技术培训和人才选拔项目。该项目的目标是培养具有职业竞争力的优秀开发工程师,并提供全程免费的课程,不收取任何费用‌。

课程内容和方向

豆包青训营的课程涵盖前端、后端和AI方向。在这个飞速发展的AI时代,学员将与豆包MarsCode团队一起深入探索技术领域,学习和运用AI,提高编程效率‌。此外,课程还包括大数据方向,适合对大数据感兴趣的学员学习‌,

本文提供训练营试题解析供参考

试题1:小X走字符串

问题描述:

python 复制代码
def solution(n: int, k: int, s: str) -> int:
    # 初始化体力值
    current_energy = k
    
    # 遍历字符串
    for i in range(n - 1):
        # 计算体力变化
        energy_change = ord(s[i + 1]) - ord(s[i])
        
        # 更新体力值
        current_energy -= energy_change
        
        # 检查体力值是否小于0
        if current_energy < 0:
            return -1
    
    # 返回剩余的体力值
    return current_energy

if __name__ == '__main__':
    print(solution(5, 2, "abcca") == 2)
    print(solution(6, 5, "abcdef") == 0)
    print(solution(4, 1, "acdb") == -1)

试题2:数字替换后的最大和计算

问题描述: 小C在白板上写了 n 个数字,分别为 a_1, a_2, ... , a_n。随后小R对这些数字进行了 m 次修改操作。在每次操作中,小R可以将白板上的某个数字替换为新数字 b_j。每次修改的数字不需要是相同的,但只能替换一次。小C想知道,经过这 m 次修改后,白板上所有数字之和的最大值是多少。

python 复制代码
def solution(n: int, m: int, a: list[int], b: list[int]) -> int:
    # 计算原始数组 a 的和
    original_sum = sum(a)
    
    # 对数组 a 进行升序排序
    a.sort()
    
    # 对数组 b 进行降序排序
    b.sort(reverse=True)
    
    # 初始化替换次数
    replacements = 0
    
    # 遍历数组 a 和 b,进行替换
    for i in range(min(n, m)):
        # 如果 b 中的最大值大于 a 中的最小值,进行替换
        if b[i] > a[i]:
            # 更新原始数组的和
            original_sum += b[i] - a[i]
            # 增加替换次数
            replacements += 1
        else:
            # 如果 b 中的值不再大于 a 中的值,停止替换
            break
    
    return original_sum

if __name__ == '__main__':
    print(solution(2, 3, [1, 2], [3, 4, 5]) == 9)
    print(solution(3, 2, [10, 1, 2], [100, 200]) == 310)
    print(solution(4, 4, [5, 3, 1, 2], [6, 7, 8, 9]) == 30)

试题3:数组操作和最大分数

问题描述: 小C和小U有一个从0开始的数组nums,以及一个非负整数k。每次操作中,小C可以选择一个尚未选择的下标i(范围在 [0, nums.length - 1]),然后将nums[i]替换为[nums[i] - k, nums[i] + k]之间的任意整数(包含边界)。在应用任意次数的操作后,返回数组nums可能达到的最大分数。数组的分数被定义为数组中最多重复的元素个数。注意,每个下标只能被操作一次。

python 复制代码
def solution(nums, k):
    # 初始化一个字典来记录每个可能的值及其出现的次数
    value_count = {}
    
    # 遍历数组中的每个元素
    for num in nums:
        # 计算当前元素可以被替换的所有可能值
        for possible_value in range(num - k, num + k + 1):
            # 更新字典中的计数
            if possible_value in value_count:
                value_count[possible_value] += 1
            else:
                value_count[possible_value] = 1
    
    # 查找字典中出现次数最多的值
    max_count = 0
    for count in value_count.values():
        if count > max_count:
            max_count = count
    
    return max_count

if __name__ == "__main__":
    print(solution([4, 6, 1, 2], 2) == 3)
    print(solution([1, 3, 5, 7], 1) == 2)
    print(solution([1, 3, 5, 7], 3) == 4)

试题4:数组极差最小化问题

问题描述: 小M有一个数组,她可以执行一次操作:选择两个相邻的元素并将它们合并,合并后的新元素值为原来两个元素的和。合并操作之后,数组的长度将减少1。小M想知道,执行一次操作后,数组的极差(最大值减去最小值)的最小可能值是多少。

python 复制代码
def solution(n: int, a: list) -> int:
    # 初始化最小极差为一个较大的值
    min_range = float('inf')
    
    # 遍历所有相邻元素对
    for i in range(n - 1):
        # 计算合并后的新数组
        new_array = a[:i] + [a[i] + a[i + 1]] + a[i + 2:]
        
        # 计算新数组的极差
        current_range = max(new_array) - min(new_array)
        
        # 更新最小极差
        if current_range < min_range:
            min_range = current_range
    
    # 返回最小极差
    return min_range

if __name__ == '__main__':
    print(solution(3, [1, 4, 5]) == 0)
    print(solution(5, [3, 6, 2, 8, 7]) == 5)
    print(solution(4, [10, 20, 30, 40]) == 10)

试题5:数组距离最小化

问题描述: 给定两个长度为n的整数数组a和b,你可以对第一个数组a中的每个元素执行以下操作至多一次: 将元素变为其相反数(即将x变为 -x) 你的目标是通过合理的操作,使得两个数组之间的"绝对值距离"最小。 两个数组的"绝对值距离"定义为:对于数组中每个对应位置的元素,计算它们绝对值之差的绝对值,然后将所有差值相加。 用数学公式表示为:distance=>abs(a;)- abs(b,),其中o≤i<n。 请返回可以得到的最小距离。 输入 n:数组的长度。 a:第一个数组。 b:第二个数组。 约束条件 1 ≤ n ≤ 10^5 -10^9 ≤ a[i], b[i] ≤ 10^9 返回 返回 a 和 b 两个数组之间的可能的最小距离值

python 复制代码
def solution(n: int, a: list[int], b: list[int]) -> int:
    # 初始化最小距离为0
    min_distance = 0
    
    # 遍历数组a和b的每个元素
    for i in range(n):
        # 计算不改变a[i]时的距离
        dist1 = abs(a[i] - b[i])
        # 计算改变a[i]时的距离
        dist2 = abs(-a[i] - b[i])
        
        # 选择较小的距离
        min_distance += min(dist1, dist2)
    
    return min_distance

def main():
    print(solution(3, [-1, 2, 3], [-3, 2, -1]) == 4)
    print(solution(4, [-1, 2, 3, 4], [1, -2, 5, -4]) == 2)
    print(solution(2, [100, -50], [-50, 100]) == 100)

if __name__ == "__main__":
    main()

试题6:数组跳跃的最小步数问题

问题描述: 小C面对一个由正整数构成的数组,从第一个成员开始跳跃,要求他用最少的步骤数到达数组的最后一个成员。初始步长范围受限,第一步的步长必须介于1和数组长度的一半之间(不包含),而从第二步起,每次跳跃的步长由当前所处成员的数字决定。若目标不可达,返回 -1。你的任务是输出所需的最少步数。

例如:在输入的数组 7 5 9 4 2 6 8 3 5 4 3 9 中,小C可以通过两次跳跃到达最后一个成员。

python 复制代码
def solution(arr: list) -> int:
    from collections import deque
    
    n = len(arr)
    if n == 1:
        return 0
    
    # 初始化队列和已访问集合
    queue = deque()
    visited = set()
    
    # 第一步的可能步长范围
    for step in range(1, n // 2):
        # 将初始位置和步数加入队列
        queue.append((step, 1))  # (当前位置, 步数)
        visited.add(step)
    
    # BFS遍历
    while queue:
        current_pos, steps = queue.popleft()
        
        # 如果当前位置已经是最后一个成员
        if current_pos == n - 1:
            return steps
        
        # 计算下一步的可能位置
        next_step = arr[current_pos]
        next_pos = current_pos + next_step
        
        # 如果下一步位置有效且未访问过
        if 0 <= next_pos < n and next_pos not in visited:
            queue.append((next_pos, steps + 1))
            visited.add(next_pos)
    
    # 如果队列为空且未找到目标
    return -1

if __name__ == '__main__':
    print(solution(arr=[7, 5, 9, 4, 2, 6, 8, 3, 5, 4, 3, 9]) == 2)
    print(solution(arr=[2, 3, 1, 1, 4]) == 2)
    print(solution(arr=[1, 2, 1, 1, 0]) == 3)
相关推荐
运维&陈同学18 分钟前
【Elasticsearch04】企业级日志分析系统ELK之Elasticsearch 插件
大数据·运维·后端·elk·elasticsearch·搜索引擎·全文检索·哈希算法
一只大侠39 分钟前
字符矩阵里面找单词:牛客字符框:JAVA
线性代数·算法·矩阵
福大大架构师每日一题1 小时前
36.2 内置的k8s采集任务分析
算法·贪心算法·kubernetes·prometheus
Clarify1 小时前
一种增量式的状态同步方案
后端·游戏开发
sweetheart7-71 小时前
LeetCode5. 最长回文子串(2024冬季每日一题 35)
c++·算法·leetcode·动态规划·力扣
涵涵子RUSH1 小时前
预处理内容
开发语言·c++·算法
lzz的编码时刻1 小时前
Spring Boot 声明式事务
java·spring boot·后端
FranYeCisco2 小时前
C++基础:操作符
数据结构·c++·算法
c++初学者ABC2 小时前
蓝桥杯算法训练 黑色星期五
c++·算法·蓝桥杯