前言
今天是第五天打卡,依旧选择了一道高难度题目,现将自己的学习体会和心得记录如下:
题目解析:小E的倍数关系子集问题
问题描述:
小E想知道一个给定集合中,有多少个子集满足以下条件:
- 子集内的所有元素数量大于1。
- 子集内的所有元素两两之间互为倍数关系。 由于结果可能非常大,输出的结果需要对 109+710^9+7 取模。
样例:
plaintext
输入:n = 5, a = [1, 2, 3, 4, 5]
输出:6
思路解析:
解决这个问题,我可以使用动态规划(DP)的方法。具体步骤如下:
- 首先对数组进行排序,以便我们能逐步地从小到大考虑每个元素。
- 定义一个
dp数组,其中dp[i]记录以第i个元素为结尾的满足条件的子集数量。 - 遍历每个元素
a[i],对于每个a[i],再遍历之前的所有元素a[j],如果a[i]是a[j]的倍数,则更新dp[i]。 - 结果是
dp数组的所有元素和减去单个元素的子集数量,并对结果取模。
代码详解:
python
def solution(n: int, a: list) -> int:
MOD = 10**9 + 7
# 将数组按升序排序
a.sort()
# dp 数组记录以第 i 个元素为末尾的子集数量
dp = [0] * n
# 遍历每个元素
for i in range(n):
dp[i] = 1 # 自身作为一个单独的子集(初始值)
for j in range(i):
if a[i] % a[j] == 0: # 满足倍数关系
dp[i] += dp[j]
dp[i] %= MOD
# 计算结果,所有子集数量总和减去单个元素的子集
result = sum(dp) - n
return result % MOD
# 测试样例
if __name__ == '__main__':
print(solution(5, [1, 2, 3, 4, 5]) == 6) # 输出:6
print(solution(6, [2, 4, 8, 16, 32, 64]) == 57) # 输出:57
print(solution(4, [3, 6, 9, 12]) == 5) # 输出:5
知识总结
在使用豆包MarsCode AI刷题的过程中,我掌握了以下新知识点:
- 动态规划:通过分解问题,保存子问题的解决结果,避免重复计算,提高效率。
- 排序:通过排序可以使问题变得更简单,有助于结构化地解决问题。
- 模运算:处理大数时常用,可以防止溢出,保证结果的正确性。
理解与建议:
- 动态规划 是解决递归问题的重要工具,通过记忆化减少计算量。
- 排序 可以帮助简化逻辑,特别是在需要比较或排列元素时。
- 模运算 需要特别注意,其目的是保持数值在可控范围内。
对于初学者,建议在刷题时注意以下几点:
- 先尝试理解题意,分析问题的本质。
- 分步骤解决复杂问题,逐步提高代码的正确性和效率。
- 重视常用算法和数据结构的掌握,它们是解决问题的基础。
学习计划
结合豆包MarsCode AI刷题功能,我总结了以下高效学习方法:
-
制定刷题计划:
- 每周制定具体的刷题目标,例如每天完成一定数量的题目,涵盖不同难度和类型。
- 分析自己的弱点,集中时间和精力攻克难点。
-
利用错题进行针对性学习:
- 记录每次刷题的错题,分析错误原因,明确不足之处。
- 重复练习错题,通过变换题目条件进一步巩固知识点。
-
多种题型结合练习:
- 包括基础题、进阶题和综合题,全面提高解题能力。
- 定期进行总结和反思,调整学习策略。
工具运用
在学习过程中,如何将豆包MarsCode AI刷题功能与其他学习资源相结合:
-
与在线教程结合:
- 遇到不理解的题目时,可以查阅在线教程或相关书籍,深入理解题目背后的知识点。
- 结合视频教程,跟着老师一步步解析题目,巩固理解。
-
利用在线讨论社区:
- 加入编程学习社区,分享自己的解题经验,向其他同学请教疑惑。
- 参与社区的刷题竞赛,提高自己的解题速度和准确性。
-
系统化学习:
- 将刷题与系统化学习结合,系统掌握一门语言或一个算法专题。
- 通过完成实际项目,将所学知识应用于实践,提高实战能力。