豆包青训营考核3 | “朝闻道”

辉常腻害 2024-10-31 09:14:33

这是我参加朝闻道知识分享大赛的第 3 篇文章

二进制之和

问题描述

小U和小R喜欢探索二进制数字的奥秘。他们想找到一个方法,将两个二进制字符串相加并以十进制的形式呈现。这个过程需要注意的是,他们的二进制串可能非常长,所以常规的方法可能无法处理大数。小U和小R希望你帮助他们设计一个算法,该算法能在保证时间复杂度不超过O(n^2)的前提下,返回两个二进制字符串的十进制求和结果。


测试样例

样例1:

输入:binary1 = "101" ,binary2 = "110" 输出:'11'

样例2:

输入:binary1 = "111111" ,binary2 = "10100" 输出:'83'

样例3:

输入:binary1 = "111010101001001011" ,binary2 = "100010101001" 输出:'242420'

样例4:

输入:binary1 = "111010101001011" ,binary2 = "10010101001" 输出:'31220'

样例5:

输入:binary1 = "11" ,binary2 = "1" 输出:'4'

思路:二进制相加,模拟手动进位计算,然后二进制转十进制。时间复杂度O(n)。这里的测试用例不是很大,所以二进制数组转十进制我直接用一个整数保存(也可能是python的整数没有限制大小,所以能过)

def solution(binary1, binary2):
    # Please write your code here
    binary_array = []
    size1 = len(binary1)
    size2 = len(binary2)
    index = -1
    # 二进制数组相加:时间复杂度O(n)
    while -index <= size1 or -index <= size2:
        # 低位相加
        add_num = 0
        if -index <= size1:
            add_num += int(binary1[index])
        if -index <= size2:
            add_num += int(binary2[index])
​
        if -index > len(binary_array): # 如果位置不够,就开辟位置
            binary_array.insert(0, 0)
        if add_num + binary_array[index] > 1: # 进位
            binary_array[index] = (add_num + binary_array[index]) % 2
            binary_array.insert(0, 1)
        else: # 不进位
            binary_array[index] += add_num
​
        index -= 1
    # 二进制转十进制:时间复杂度O(n)
    result = 0
    index = -1
    pow_num = 0
    size = len(binary_array)
    while -index <= size:
        result += binary_array[index] * pow(2, pow_num)
        pow_num += 1
        index -= 1
    return str(result)

 

上述代码思想是通用的,改写为其他语言也很简单,不过python的数据类型不限制大小,所以我向应该能用内置的语法特性来做:

def solution(binary1, binary2):
    # Please write your code here
    # 将二进制字符串转换为十进制整数并相加
    decimal_sum = int(binary1, 2) + int(binary2, 2)
    # 将十进制结果转换为字符串返回
    return str(decimal_sum)

时间复杂度:O(n),主要在于 int 函数的转换复杂度,适用于较长的二进制字符串。

超市里的货物架调整

问题描述

在一个超市里,有一个包含 n 个格子的货物架,每个格子中放有一种商品,商品用小写字母 az 表示。当顾客进入超市时,他们会依次从第一个格子查找到第 n 个格子,寻找自己想要购买的商品。如果在某个格子中找到该商品,顾客就会购买它并离开;如果中途遇到一个空格子,或查找完所有格子还没有找到想要的商品,顾客也会离开。

作为超市管理员,你可以在顾客到来之前重新调整商品的顺序,以便尽可能多地出售商品。当第一个顾客进入后,商品位置不能再调整。你需要计算在最优调整下,最多可以卖出多少件商品。输入变量说明:

  • n:货物架的格子数

  • m:顾客想要购买的商品种类数

  • s:货物架上商品的初始顺序

  • c:顾客想要购买的商品种类


测试样例

样例1:

输入:n = 3 ,m = 4 ,s = "abc" ,c = "abcd" 输出:3

样例2:

输入:n = 4 ,m = 2 ,s = "abbc" ,c = "bb" 输出:2

样例3:

输入:n = 5 ,m = 4 ,s = "bcdea" ,c = "abcd" 输出:4

思路:很简单,没有顺序,直接数数量即可,时间复杂度O(n)

def solution(n: int, m: int, s: str, c: str) -> int:
    # write code here
    goods = {}
    needs = {}
    for i in s:
        goods[i] = goods.get(i, 0) + 1
    for i in c:
        needs[i] = needs.get(i, 0) + 1
    num = 0
    for k in needs:
        num += min(goods.get(k, 0), needs.get(k, 0))
    return num

 

观光景点组合得分问题

问题描述

小R正在研究一组观光景点,每个景点都有一个评分,保存在数组 values 中,其中 values[i] 表示第 i 个观光景点的评分。同时,景点之间的距离由它们的下标差 j - i 表示。

一对景点 (i < j) 的观光组合得分为 values[i] + values[j] + i - j,也就是两者评分之和减去它们之间的距离。

小R想知道,在哪种情况下能够获得观光景点组合的最高得分。


测试样例

样例1:

输入:values = [8, 3, 5, 5, 6] 输出:11

样例2:

输入:values = [10, 4, 8, 7] 输出:16

样例3:

输入:values = [1, 2, 3, 4, 5] 输出:8

思路一:两次循环,两两组合找最大。时间复杂度O(n^2)

def solution(values: list) -> int:
    # write code here
    max_value = 0
    n = len(values)
    for x in range(n - 1):
        for y in range(x + 1, n):
            max_value = max(max_value, values[x] + values[y] + x - y)
    return max_value  # Placeholder return

思路二:

给定的组合得分为:

我们可以将其重写为:

 

设定:

 

于是得分可以转化为:

在这种情况下,我们只需要遍历 values 数组一次,计算出所有的 A[i]B[j],然后在遍历中更新最大得分。

时间复杂度O(n)

def solution(values: list) -> int:
    # write code here
    n = len(values)
    max_score = 0
    maxA = values[0] + 0  # A[0] = values[0] + 0
​
    for j in range(1, n):
        # 计算 B[j] = values[j] - j
        currentB = values[j] - j
        # 计算得分
        max_score = max(max_score, maxA + currentB)
        # 更新 maxA
        maxA = max(maxA, values[j] + j)
​
    return max_score

数组元素之和最小化

问题描述

小C希望构造一个包含n个元素的数组,且满足以下条件:

  1. 数组中的所有元素两两不同。

  2. 数组所有元素的最大公约数为 k

  3. 数组元素之和尽可能小。

任务是输出该数组元素之和的最小值。


测试样例

样例1:

输入:n = 3 ,k = 1 输出:6

样例2:

输入:n = 2 ,k = 2 输出:6

样例3:

输入:n = 4 ,k = 3 输出:30

思路:元素要尽量的小,那就从最小的开始即可

def solution(n: int, k: int) -> int:
    # write code here
    return (k + n * k) * n // 2

 

最少前缀操作问题

问题描述

小U和小R有两个字符串,分别是ST,现在小U需要通过对SS进行若干次操作,使其变成T的一个前缀。操作可以是修改S的某一个字符,或者删除S末尾的字符。现在你需要帮助小U计算出,最少需要多少次操作才能让S变成T的前缀。


测试样例

样例1:

输入:S = "aba", T = "abb" 输出:1

样例2:

输入:S = "abcd", T = "efg" 输出:4

样例3:

输入:S = "xyz", T = "xy" 输出:1

样例4:

输入:S = "hello", T = "helloworld" 输出:0

样例5:

输入:S = "same", T = "same" 输出:0

思路:很简单,从前往后比较,不同则换,比完后还剩的就要删除

def solution(S: str, T: str) -> int:
    # write code here
    n = min(len(S), len(T))
    result = 0
    for i in range(n):
        if S[i] != T[i]:
            result += 1
    if len(S) > len(T):
        result += len(S) - len(T)
    return result

徒步旅行中的补给问题

问题描述

小R正在计划一次从地点A到地点B的徒步旅行,总路程需要 N 天。为了在旅途中保持充足的能量,小R每天必须消耗1份食物。幸运的是,小R在路途中每天都会经过一个补给站,可以购买食物进行补充。然而,每个补给站的食物每份的价格可能不同,并且小R最多只能同时携带 K 份食物。

现在,小R希望在保证每天都有食物的前提下,以最小的花费完成这次徒步旅行。你能帮助小R计算出最低的花费是多少吗?


测试样例

样例1:

输入:n = 5 ,k = 2 ,data = [1, 2, 3, 3, 2] 输出:9

样例2:

输入:n = 6 ,k = 3 ,data = [4, 1, 5, 2, 1, 3] 输出:9

样例3:

输入:n = 4 ,k = 1 ,data = [3, 2, 4, 1] 输出:10

思想:贪心,尽量拿价格小的。

我的想法是:

遍历到后面时,前面的价格应该也要算进来,也就是说走到这个站点,购买的食物应该是从该站点开始往前k个站点最小价格的那一个,因为最多只能携带k份食物,所以遍历到该站点时,那前面的第k+1个站点就需要从所选价格表中删除。

每次插入时都要快速的选取最小值,这就很容易想到一个数据结构——小顶堆(最小堆)。这里使用堆有个问题,就是删除的结点不一定是堆顶,因为不知道前面第k+1个站点价格大小,所以删除结点只能对列表删除结点,然后构建堆,时间复杂度O(n^2*log(n)),不如用一个min_value来记录最小值,复杂度为O(n^2)

def solution(n, k, data):
    # Edit your code here
    min_money = 0
    ready = []
    min_value = 0
    for i in data:
        # 当前站点加入ready
        ready.append(i)
        # 如果ready大于k,就将最先进入的站点价格删除
        if len(ready) > k:
            ready.pop(0)
        # 找到最小值(这一步的时间复杂度应该为O(n))。如果在这里建堆就没必要了,时间复杂度可能提升至O(n*log()n)
        min_value = min(ready)
        min_money += min_value
​
    return min_money

 

...全文
168 回复 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

1,042

社区成员

发帖
与我相关
我的任务
社区描述
中南民族大学CSDN高校俱乐部聚焦校内IT技术爱好者,通过构建系统化的内容和运营体系,旨在将中南民族大学CSDN社区变成校内最大的技术交流沟通平台。
经验分享 高校 湖北省·武汉市
社区管理员
  • c_university_1575
  • WhiteGlint666
  • wzh_scuec
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

欢迎各位加入中南民族大学&&CSDN高校俱乐部社区(官方QQ群:908527260),成为CSDN高校俱乐部的成员具体步骤(必填),填写如下表单,表单链接如下:
人才储备数据库及线上礼品发放表单邀请人吴钟昊:https://ddz.red/CSDN
CSDN高校俱乐部是给大家提供技术分享交流的平台,会不定期的给大家分享CSDN方面的相关比赛以及活动或实习报名链接,希望大家一起努力加油!共同建设中南民族大学良好的技术知识分享社区。

注意:

1.社区成员不得在社区发布违反社会主义核心价值观的言论。

2.社区成员不得在社区内谈及政治敏感话题。

3.该社区为知识分享的平台,可以相互探讨、交流学习经验,尽量不在社区谈论其他无关话题。

试试用AI创作助手写篇文章吧