选取了选择豆包MarsCode AI 刷题题库中的两道困难题目进行解析:二进制之和、魔法甜点之和:小包的新挑战。
二进制之和
问题描述
小U和小R喜欢探索二进制数字的奥秘。他们想找到一个方法,将两个二进制字符串相加并以十进制的形式呈现。这个过程需要注意的是,他们的二进制串可能非常长,所以常规的方法可能无法处理大数。小U和小R希望你帮助他们设计一个算法,该算法能在保证时间复杂度不超过O(n^2)的前提下,返回两个二进制字符串的十进制求和结果。
思路分析
- 数据结构选择:由于我们处理的是字符串形式的二进制数,我们可以直接操作字符串,而不需要将其转换为整数类型。这样可以避免整数溢出的问题。
- 算法步骤:
- 补齐长度:确保两个二进制字符串的长度相同。如果长度不同,可以在较短的字符串前面补0。这里使用zfill()方法,在字符串的左端补0。
- 逐位相加:从最低位(字符串的最后一位)开始,逐位相加,并记录进位。
- 处理进位:在每一位相加时,如果结果大于1,则需要进位。
- 生成结果:将每一位的结果(包括进位)拼接起来,形成最终的二进制字符串。
- 转换为十进制:最后,将二进制字符串转换为十进制字符串。
代码实现
def solution(binary1, binary2):
# 补齐长度
max_len = max(len(binary1), len(binary2))
binary1 = binary1.zfill(max_len)
binary2 = binary2.zfill(max_len)
carry = 0
result = []
# 从最低位开始逐位相加
for i in range(max_len - 1, -1, -1):
bit1 = int(binary1[i])
bit2 = int(binary2[i])
sum_bit = bit1 + bit2 + carry
# 计算当前位的结果和进位
result.append(str(sum_bit % 2))
carry = sum_bit // 2
# 如果最高位有进位,需要额外添加一位
if carry:
result.append('1')
# 结果是反向的,需要反转
result.reverse()
# 将二进制结果转换为十进制
binary_result = ''.join(result)
decimal_result = str(int(binary_result, 2))
return decimal_result
学习总结
zfill(len)方法,在左边填充0直至填充字符串长度为len;
反向遍历数组的方式:for i in range(n, -1, -1);
//整除,python的整除是地板除法,向下取整;
int(string, base)可以将base进制的字符串转换成10进制整数。
魔法甜点之和:小包的新挑战
问题描述
小R不再追求甜点中最高的喜爱值,今天他想要的是甜点喜爱值之和正好匹配他的预期值 S。为了达到这个目标,他可以使用魔法棒来改变甜点的喜爱值,使其变为原来喜爱值的阶乘。每个甜点只能使用一次魔法棒,也可以完全不用。
下午茶小哥今天带来了 N 个甜点,每个甜点都有一个固定的喜爱值。小R有 M 个魔法棒,他可以选择任意甜点使用,但每个甜点只能使用一次魔法棒。他的目标是通过选择一些甜点,可能使用魔法棒,使得这些甜点的喜爱值之和恰好为 S。
请计算小R有多少种不同的方案满足他的要求。如果两种方案中,选择的甜点不同,或者使用魔法棒的甜点不同,则视为不同的方案。
思路分析
参考了csdn上的博文:blog.csdn.net/2301_788484…
对于数组like中任意一个元素,有四种选择:选择,不选,用魔法棒选,用魔法棒不选。结合题目情景,没有用了魔法棒但不选的情况,所以只有三种方式。使用深度优先搜索DFS算法,遍历得出所有方案。
退出DFS的条件:当满足条件返回;所有元素遍历完返回;所选value>s返回。
代码解释:
-
参数:
i:当前处理的甜点索引。n:甜点的总数。m:剩余可用的魔法棒数量。s:目标喜爱值之和。like:甜点的喜爱值列表。
-
递归终止条件:
- 当
s == 0且m >= 0且i <= n时,表示找到了一个满足条件的方案,sum加 1。 - 当
s < 0或m < 0或i == n时,表示当前路径不可行,直接返回。
- 当
-
递归调用:
dfs(i + 1, n, m, s - like[i], like):不使用魔法棒,但选择当前甜点。dfs(i + 1, n, m, s, like):不使用魔法棒,也不选择当前甜点。dfs(i + 1, n, m - 1, s - factorial(like[i]), like):使用魔法棒,选择当前甜点。
代码实现
def factorial(x):
i=0
sum=1
for i in range(1, x+1):
sum*=i
return sum
def dfs(i, n, m, s, like):
global sum
if s==0 and m>=0 and i<=n:
sum+=1
return
if s<0:
return
if m<0:
return
if i==n:
return
dfs(i+1, n, m, s-like[i], like) # 不用但选
dfs(i+1, n, m, s, like) # 不用不选
dfs(i+1, n, m-1, s-factorial(like[i]), like) #用选
def solution(n, m, s, like):
global sum
sum = 0
dfs(0, n, m, s, like)
return sum
学习总结
方案寻找类问题可采用回溯法,使用DFS等遍历算法;巧用全局变量。