小C的宝塔探险 | 豆包MarsCode AI 刷题
问题描述
小C派遣了一名冒险家去探索一座神秘的宝塔。宝塔中有 n 个宝藏,每个宝藏的价值分别为 a_1, a_2, ..., a_n。每天,冒险家能够进入宝塔并选择一个价值不低于当天要求的最低价值 b_i 的宝藏。每个宝藏只能被选取一次,且冒险家每天只能选择一个宝藏。小C希望知道冒险家最多可以带出多少个宝藏。
测试样例
样例1:
输入:
n = 5,a = [1, 2, 3, 4, 1],b = [3, 1, 2, 3, 2]输出:4
样例2:
输入:
n = 4,a = [5, 6, 2, 3],b = [2, 5, 4, 3]输出:4
样例3:
输入:
n = 6,a = [7, 8, 1, 4, 3, 6],b = [4, 3, 5, 7, 2, 1]输出:6
解题思路
- 理解问题:我们需要在每一天选择一个价值不低于当天要求的最低价值的宝藏。每个宝藏只能被选取一次,且每天只能选择一个宝藏。目标是最大化选取的宝藏数量。
- 数据结构选择:
- 使用一个列表
a来存储宝藏的价值。 - 使用一个列表
b来存储每天的最低要求。
- 使用一个列表
- 算法步骤:
- 对宝藏价值列表
a进行排序。 - 对每天的要求列表
b进行排序。 - 使用双指针法,一个指针遍历
b,另一个指针遍历a,尝试匹配每一天的要求。
- 对宝藏价值列表
解题思路
-
理解问题:我们需要在每一天选择一个价值不低于当天要求的最低价值的宝藏。每个宝藏只能被选取一次,且每天只能选择一个宝藏。目标是最大化选取的宝藏数量。
-
数据结构选择:
-
使用一个列表
a来存储宝藏的价值。 -
使用一个列表
b来存储每天的最低要求。
-
-
算法步骤:
- 对宝藏价值列表
a进行排序。 - 对每天的要求列表
b进行排序。 - 使用双指针法,一个指针遍历
b,另一个指针遍历a,尝试匹配每一天的要求。
- 对宝藏价值列表
关键步骤解释
- 排序:对
a和b进行排序,这样可以更容易地进行匹配。 - 双指针法:使用两个指针
a_index和b_index分别遍历a和b,尝试匹配每一天的要求。 - 计数器:
count记录成功匹配的宝藏数量。
详细步骤
- 初始化:
count初始化为 0,用于记录成功匹配的宝藏数量。a_index和b_index初始化为 0,分别用于遍历a和b。
- 排序:
- 对
a进行排序,使得宝藏价值从小到大排列。 - 对
b进行排序,使得每天的要求从小到大排列。
- 对
- 双指针遍历:
- 使用
while循环,当a_index和b_index都小于n时继续循环。 - 如果当前宝藏价值
a[a_index]大于等于当天的要求b[b_index],则选择这个宝藏,并将count加 1,同时移动两个指针。 - 如果当前宝藏价值
a[a_index]小于当天的要求b[b_index],则移动a_index,尝试下一个宝藏。
- 使用
- 返回结果:
- 循环结束后,返回
count,即成功匹配的宝藏数量。
- 循环结束后,返回
知识总结:
知识点总结
-
排序算法:
-
概念:排序是将一组数据按照特定顺序(通常是升序或降序)进行排列的过程。
-
应用:在这个问题中,我们对宝藏价值列表
a和每天的要求列表b进行排序,以便更容易地进行匹配。 -
Python 实现:使用
list.sort()方法对列表进行原地排序。
-
-
双指针法:
-
概念:双指针法是一种常用的算法技巧,通过使用两个指针在数据结构中进行遍历和操作。
-
应用:在这个问题中,我们使用两个指针
a_index和b_index分别遍历排序后的宝藏价值列表a和每天的要求列表b,尝试匹配每一天的要求。 -
Python 实现:使用
while循环和条件判断来控制指针的移动。
-
-
贪心算法:
-
概念:贪心算法是一种在每一步选择中都采取在当前状态下最优的选择,以期望达到全局最优的算法。
-
应用:在这个问题中,我们每次选择价值不低于当天要求的最低价值的宝藏,以最大化选取的宝藏数量。
-
Python 实现:通过条件判断和指针移动来实现贪心选择。
-
-
时间复杂度分析:
-
概念:时间复杂度是衡量算法执行时间随输入规模增长的变化趋势。
-
应用:在这个问题中,排序的时间复杂度为
O(n log n),双指针遍历的时间复杂度为O(n),因此总的时间复杂度为O(n log n)。 -
Python 实现:通过分析代码中的排序和遍历操作来确定时间复杂度。
-
-
空间复杂度分析:
-
概念:空间复杂度是衡量算法在执行过程中所需的额外空间随输入规模增长的变化趋势。
-
应用:在这个问题中,我们只使用了常数级别的额外空间(指针和计数器),因此空间复杂度为
O(1)。 -
Python 实现:通过分析代码中使用的额外变量来确定空间复杂度。
-
通过排序、双指针法和贪心算法,我们可以有效地解决这个问题,确保每一天都能选择一个价值不低于当天要求的宝藏,并且最大化选取的宝藏数量。时间复杂度为 O(n log n),空间复杂度为 O(1)。
学习计划:
1.定期刷题:每天至少一道算法题,思考如何在第一步的基础上,如何优化算法,降低时间复杂度。
2.错题总结:总结一下这道题考察的知识点、切入的角度、同类型的题目等,还要思考有没有更优的办法,代码还能不能更加简洁一些。
工具运用:
豆包MarsCode AI提供了详细的解题思路和代码示例。
向豆包提出问题,可以获得思路启发,便于我们更好的理解和把握如何运用算法去解题。
针对代码中可能出现的语法错误,逻辑漏洞等问题,可以帮忙检查出并给出修改建议,提升代码的准确率和效率
在解完算法题后,可以帮你回顾题目中涉及到的算法知识,数据结构知识等,强化你对这些知识点的掌握程度。并且为你拓展相关的,更深入或者更广泛的算法知识内容,拓展知识面,更好的应对更多类型的算法题。
完整代码实现
def solution(n: int, a: list, b: list) -> int:
count = 0
a_index = 0
b_index = 0
a.sort() # 对宝藏价值数组进行排序
b.sort() # 对最低要求数组进行排序
while a_index < n and b_index < n:
if a[a_index] >= b[b_index]: # 修正条件
count += 1 # 可以选择当前宝藏
a_index += 1
b_index += 1
else:
a_index += 1 # 无法选择当前宝藏,尝试下一个宝藏
return count
if __name__ == '__main__':
print(solution(5, [1, 2, 3, 4, 1], [3, 1, 2, 3, 2]) == 4)
print(solution(4, [5, 6, 2, 3], [2, 5, 4, 3]) == 4) # 修正测试样例
print(solution(6, [7, 8, 1, 4, 3, 6], [4, 3, 5, 7, 2, 1]) == 6)