今天我们将在豆包MarsCode AI刷题平台上,完成《超市里的货物架调整》这个算法问题,通过练习提升用户解决此类问题的能力。
《超市里的货物架调整》题目如下:
问题理解
你需要在顾客到来之前重新调整商品的顺序,以便尽可能多地出售商品。每个顾客只会购买他们想要的商品中的一种,并且一旦找到就会离开。因此,我们的目标是通过重新排列商品,使得尽可能多的顾客能够找到他们想要的商品。
数据结构选择
- 商品频率统计:我们可以使用
map来统计每种商品在货架上的数量。 - 顾客需求统计:同样使用
map来统计每种商品在顾客需求中的数量。
算法步骤
- 统计商品频率:遍历货架上的商品,统计每种商品的数量。
- 统计顾客需求:遍历顾客需求的商品,统计每种商品的需求数量。
- 计算最大可售商品数:对于每种商品,计算货架上该商品的数量与顾客需求数量的最小值,累加这些最小值即为最大可售商品数。
具体实现
#include <bits/stdc++.h>
using namespace std;
int solution(int n, int m, string s, string c) {
map<char, int> ps, pc;
// 统计货架上每种商品的数量
for(auto it : s)
ps[it]++;
// 统计顾客需求中每种商品的数量
for(auto it : c)
pc[it]++;
int cnt = 0;
// 计算最大销售量
for(auto [k, v] : pc) {
cnt += min(ps[k], v);
}
return cnt;
}
int main() {
cout << (solution(3, 4, "abc", "abcd") == 3) << endl;
cout << (solution(4, 2, "abbc", "bb") == 2) << endl;
cout << (solution(5, 4, "bcdea", "abcd") == 4) << endl;
return 0;
}
如何优化代码以减少时间复杂度?
要优化代码以减少时间复杂度,我们可以从以下几个方面入手:
1. 减少不必要的遍历
当前代码中,我们使用了两个 map 来分别统计货架上商品的数量和顾客需求的商品数量。这两个 map 的遍历是必要的,但我们可以考虑是否可以在一次遍历中完成统计。
2. 使用数组代替 map
由于商品种类是固定的(小写字母 a 到 z),我们可以使用数组来代替 map,这样可以减少 map 的查找和插入开销。
3. 减少重复计算
在计算最大可售商品数时,我们可以直接在一次遍历中完成,而不需要再次遍历 map。
具体实现
#include <bits/stdc++.h>
using namespace std;
int solution(int n, int m, string s, string c) {
// 使用数组来统计货架上商品的数量
int ps[26] = {0};
for(auto it : s)
ps[it - 'a']++;
int cnt = 0;
// 使用数组来统计顾客需求的商品数量,并计算最大可售商品数
int pc[26] = {0};
for(auto it : c)
pc[it - 'a']++;
for(int i = 0; i < 26; i++)
cnt += min(ps[i], pc[i]);
return cnt;
}
int main() {
cout << (solution(3, 4, "abc", "abcd") == 3) << endl;
cout << (solution(4, 2, "abbc", "bb") == 2) << endl;
cout << (solution(5, 4, "bcdea", "abcd") == 4) << endl;
return 0;
}
关键优化点
- 使用数组代替
map:由于商品种类是固定的(小写字母a到z),我们可以使用数组ps[26]和pc[26]来分别统计货架上商品的数量和顾客需求的商品数量。这样可以减少map的查找和插入开销。 - 一次遍历完成统计和计算:我们在一次遍历中完成对货架上商品数量的统计,并在另一次遍历中完成对顾客需求商品数量的统计和最大可售商品数的计算。
时间复杂度分析
- 原代码:使用
map进行统计和计算,时间复杂度为O(n + m),其中n是货架上商品的数量,m是顾客需求的商品种类数。 - 优化后代码:使用数组进行统计和计算,时间复杂度为
O(n + m),但由于数组的查找和插入操作是O(1)的,因此实际运行效率会更高。
通过这些优化,代码的时间复杂度保持不变,但实际运行效率会有所提升。