刷题记录|豆包MarsCode AI刷题

71 阅读4分钟

1.题号68.绿洲之旅:最少补给次数探索

题目描述不在重复,本题考虑使用贪心算法,找到当前能够到达的所用位置,再比较这些位置中哪些位置能够加的水最多,走到这个点,更新参数再走下一个点,直到剩余的水能走完所有路程

完整代码如下:

def find_can_arrive(current_water, position, supply, current_position):    # 找到能够到达的位置,且位置能加的水最多    now_water = 0    next_position = None    for i in range(current_position + 1, len(position)):        if position[i] <= current_water:            if supply[i] > now_water:                next_position = i                now_water = supply[i]        else:            break    return next_positiondef solution(d, w, position, supply):    current_position = -1    current_water = w    result = 0    go = 0    # 只要没办法让距离归0,就继续走    while d - current_water > 0:        next_position = find_can_arrive(current_water, position, supply, current_position)        if  next_position ==None:            return -1        go = position[next_position]        d -= go        current_water = current_water - go + supply[next_position]        current_position = next_position        result += 1        position = [elem - go for elem in position]    return result

现在逐行对代码进行解释,针对函数find_can_arrive,首先设立两个临时变量now_water = 0

next_position = None,一个用来记录当前位置的补给水量,一个用来返回下一个要到达的点

使用一个for循环遍历从当前位置之后的每一个位置,如果当前的水量足够到达下一个位置,并且下一个位置的水量比之前记录的最大水量还要多,我们就一直更新now_water和next_position知道我们找到的下一个位置是能都到达的地方可补给水最多的

针对solution函数,我使用一个while循环,只要剩余距离大于0,就继续寻找下一个能到达的位置。 调用find_can_arrive函数来确定下一个能到达的位置。 如果没有位置能到达(next_position为None),就返回-1。 同时更新剩余距离(d)、当前水量(current_water)、当前位置(current_position)和结果(result)即步数。最后当这个循环跳出,我们就可以得到结果

2.题号31不同整数计数问题

本题主要考察一个正则表达式的应用,判断非数字并将它替换成空格,以空格为标准划分字符串为列表,然后遍历这个列表去掉前导0,最后返回长度得到结果

完整代码如下

def solution(word: str) -> int:    # 使用正则表达式将非数字字符替换为空格    import re    replaced_word = re.sub(r'[^0-9]', ' ', word)    unique_numbers =[]        # 使用split方法将替换后的字符串拆分为整数列表    numbers = replaced_word.split()        # 去除前导零并存储为集合以获取唯一值    for i in numbers:        j = int(i)        if j not in unique_numbers:            unique_numbers.append(j)            # 返回不同整数的数量    return len(unique_numbers)

3.题号99.糖果传递游戏

针对该题的糖果分配规则

  1. 每个糖果都会先从第一个小朋友开始分配。如果当前小朋友的糖果数量(包括新分配的糖果)小于或等于他的右边的小朋友,则他会保留这个糖果。
  2. 如果当前小朋友的糖果数量大于他右边的小朋友,他会将这个糖果传递给下一个小朋友。
  3. 这个过程会持续,直到糖果传递到第 n 个小朋友。如果第 n 个小朋友也不能保留这个糖果,那么糖果会被传递给小U。

就是该题的编码思路,写一个for循环,遍历糖果数,有几个糖果遍历几次,按照上面的规则遍历糖果,并判断该糖果会被传递到哪里,同时记录位置与当前的分配状态,当遍历到最后一个,返回位置

def solution(n, m, a):    for candy in range(m):        # 存储当前糖果分配状态与位置,每次位置清0        current = a.copy()        pos = 0                while pos < n:            # 添加糖果            current[pos] += 1                      # 检查是否需要传递给下一个小朋友            if pos < n - 1:  # 不是最后一个小朋友                if current[pos] > current[pos + 1]:                    pos += 1  # 传递给下一个小朋友                else:                    # 当前小朋友可以保留糖果                    if candy == m - 1:  # 如果是最后一颗糖果                        return pos + 1  # 返回索引                    # 更新实际的糖果数组                    a[pos] = current[pos]                    break            else:  # 是最后一个小朋友                # 最后一个小朋友的糖果一定传给小U,因为小U的糖果数可以认为是无限大                if candy == m - 1:  # 如果是最后一颗糖果                    return n + 1  # 给小U                break                # 如果糖果传递完整个队列或传给了最后一个小朋友        if pos == n - 1:            if candy == m - 1:  # 如果是最后一颗糖果                return n + 1  # 返回小U的位置        elif pos < n - 1:#不是就更新状态            a[pos] = current[pos]

4.题号36,饭馆菜品选择问题

本体我的主要解决思路是使用while循环判断选了几道菜,每选到一道菜K就减一,同时记录选到的菜有没有蘑菇,还能不能选到有蘑菇的菜,能够正常吧k减到0就返回价格,反之就返回-1,时间复杂度为logn,详细代码如下

def solution(s: str, a: list[int], m: int, k: int) -> int:    b = a[:]  # 复制列表 a    s1 = list(s)  # 将字符串 s 转换为字符列表,以便进行修改    result = 0    if k > len(b):        return -1    while(k>0):        # 找到列表 b 中的最小值及其索引        min_val = min(b)        index = b.index(min_val)                # 根据字符和 m 的值进行条件判断        if s1[index] == '0':            result += min_val            b.pop(index)  # 从列表 b 中移除最小值            s1.pop(index)  # 从字符列表 s1 中移除对应位置的字符            k-=1            continue        elif s1[index] == '1' and m > 0:            result += min_val            m -= 1            b.pop(index)  # 从列表 b 中移除最小值            s1.pop(index)  # 从字符列表 s1 中移除对应位置的字符            k-=1            continue        elif s1[index] == '1' and m <= 0 and len(b) ==1:            return -1        elif s1[index] == '1' and m <= 0 and len(b) !=1:            b.pop(index)  # 从列表 b 中移除最小值            s1.pop(index)  # 从字符列表 s1 中移除对应位置的字符            continue        return result