问题描述
小U同学每天在早餐店有多种主食和饮料可以选择。给定两个数组,staples
表示不同主食的价格,drinks
表示不同饮料的价格。每天早上,小U最多会花费不超过 xx 元,他可能选择一份主食、一杯饮料,或只选择主食或饮料中的一个。你的任务是计算小U每天早上有多少种不同的选择,满足其最大花费不超过 xx。
例如:对于输入的主食价格 5 20 5
和饮料价格 5 5 2
,如果小U的最大花费为 5
,则一共有 5 种不同的选择。
测试样例
样例1:
输入:
staples = [5, 20, 5] ,drinks = [5, 5, 2] ,x = 5
输出:5
样例2:
输入:
staples = [3, 10, 7] ,drinks = [2, 5] ,x = 7
输出:5
样例3:
输入:
staples = [10, 15] ,drinks = [5, 6] ,x = 20
输出:7
C++解题
问题理解
小U每天早上可以选择一份主食、一杯饮料,或者只选择主食或饮料中的一个。我们需要计算在不超过给定预算 x
的情况下,有多少种不同的选择。
数据结构选择
staples
和drinks
是两个数组,分别表示主食和饮料的价格。- 我们需要遍历这两个数组,计算所有可能的组合,并统计满足条件的组合数量。
算法步骤
- 遍历主食数组:对于每一个主食价格,检查它是否小于等于
x
,如果是,则计数加一。 - 遍历饮料数组:对于每一个饮料价格,检查它是否小于等于
x
,如果是,则计数加一。 - 组合选择:对于每一个主食价格,遍历饮料数组,计算主食和饮料的总价格,如果总价格小于等于
x
,则计数加一。
关键点
- 需要避免重复计数,即只计算有效的组合。
- 可以使用两个嵌套循环来实现主食和饮料的组合遍历。
代码实现
#include <iostream>
#include <vector>
int solution(const std::vector<int>& staples, const std::vector<int>& drinks, int x) {
// PLEASE DO NOT MODIFY THE FUNCTION SIGNATURE
// write code here
int count = 0;
// 遍历主食数组,统计单个主食价格小于等于 x 的情况
for (int staple : staples) {
if (staple <= x) {
count++;
}
}
// 遍历饮料数组,统计单个饮料价格小于等于 x 的情况
for (int drink : drinks) {
if (drink <= x) {
count++;
}
}
// 遍历主食和饮料数组,统计主食和饮料组合价格小于等于 x 的情况
for (int staple : staples) {
for (int drink : drinks) {
if (staple + drink <= x) {
count++;
}
}
}
return count;
}
int main() {
std::cout << (solution({5, 20, 5}, {5, 5, 2}, 5) == 5) << std::endl;
std::cout << (solution({3, 10, 7}, {2, 5}, 7) == 5) << std::endl;
std::cout << (solution({10, 15}, {5, 6}, 20) == 7) << std::endl;
return 0;
}
Python解题
思路说明
题目要求计算小U在早餐店有多少种不同的选择,使得其花费不超过给定的最大金额 x。我们可以通过以下步骤来解决这个问题:
- 首先,对主食和饮料的价格进行排序,这样可以利用二分查找快速找到满足条件的组合。
- 计算只选择主食或只选择饮料的情况,即价格不超过 x 的主食和饮料的数量。
- 计算选择一份主食和一杯饮料的组合情况,通过遍历主食价格,利用二分查找找到与之搭配的饮料价格,使得总价格不超过 x。
解题过程
- 排序:对主食和饮料的价格数组进行排序,以便后续使用二分查找。
- 计算单选情况:使用
bisect_right
函数分别计算主食和饮料中价格不超过 x 的数量,并将其相加。 - 计算组合情况:遍历每个主食价格 k,对于每个 k,使用
bisect_right
函数找到饮料中价格不超过 x−k 的数量,并将其累加到结果中。
复杂度分析
- 时间复杂度:排序的时间复杂度为 O(nlogn),其中 n 是主食或饮料的数量。二分查找的时间复杂度为 O(logn),遍历主食的时间复杂度为 O(n)。因此,总的时间复杂度为 O(nlogn)。
- 空间复杂度:排序需要额外的空间来存储排序后的数组,空间复杂度为 O(n)。
知识点扩展
- 排序算法:排序是解决许多问题的基本工具,常见的排序算法有快速排序、归并排序等。
- 二分查找:二分查找是一种高效的查找算法,适用于已排序的数组,可以在 O(logn) 的时间复杂度内找到目标值。
- 组合优化:这类问题通常涉及在给定约束下找到所有可能的组合,可以通过遍历和剪枝等方法来解决。
代码实现
def solution(staples: list, drinks: list, x: int) -> int:
from bisect import bisect_right
a = sorted(staples)
b = sorted(drinks)
ans = bisect_right(a, x) + bisect_right(b, x)
for k in a:
ans += bisect_right(b, x - k)
return ans
if __name__ == '__main__':
print(solution(staples = [5, 20, 5] ,drinks = [5, 5, 2] ,x = 5) == 5)
print(solution(staples = [3, 10, 7] ,drinks = [2, 5] ,x = 7) == 5)
print(solution(staples = [10, 15] ,drinks = [5, 6] ,x = 20) == 7)