超市里的货物架调整
问题背景
在一个超市里,有一个包含 n 个格子的货物架,每个格子中放有一种商品,商品用小写字母 a 到 z 表示。当顾客进入超市时,他们会依次从第一个格子查找到第 n 个格子,寻找自己想要购买的商品。如果在某个格子中找到该商品,顾客就会购买它并离开;如果中途遇到一个空格子,或查找完所有格子还没有找到想要的商品,顾客也会离开。
作为超市管理员,你可以在顾客到来之前重新调整商品的顺序,以便尽可能多地出售商品。当第一个顾客进入后,商品位置不能再调整。你需要计算在最优调整下,最多可以卖出多少件商品。
这是一道基于贪心思想的问题,核心在于如何通过最优排序尽可能满足顾客需求。
核心问题
- 如何有效统计并排列货架上的商品,以尽可能满足顾客的购买需求?
- 如何通过算法高效计算出在最优排序下,最多可以卖出的商品数?
问题建模
变量定义
- 货物架 (
s): 表示超市货架上的商品排列顺序,可以是任意小写字母。 - 顾客需求 (
c): 表示顾客想购买的商品清单。 - 商品数量限制:
- 每种商品的数量由其在货架上的初始分布决定,顾客只能购买货架上现存的商品。
- 目标: 调整货架上商品的顺序,以满足顾客尽可能多的购买需求。
解决思路
这道题的关键在于:
- 统计商品的初始数量。
- 对顾客的需求按照货架现有商品逐一满足。
- 在遍历顾客需求的过程中,优先满足存在的商品,并统计已售商品的数量。
算法设计
步骤分解
-
统计初始商品数量: 使用一个哈希表
shelf记录货架上每种商品的数量。示例: 若货架为
s = "abc",则shelf = {a: 1, b: 1, c: 1}。 -
统计顾客需求: 使用另一个哈希表
customers记录顾客需求的商品种类及其数量。示例: 若顾客需求为
c = "abcd",则customers = {a: 1, b: 1, c: 1, d: 1}。 -
贪心匹配: 遍历顾客需求列表,依次查看货架上是否存在该商品:
- 如果存在,将商品数量减少,同时增加售出计数。
- 如果不存在,跳过该商品。
-
返回结果: 最终售出的商品数即为最大值。
代码实现
以下是具体的代码实现和逐步解析:
package main
import "fmt"
func solution(n int, m int, s string, c string) int {
// 1. 创建一个哈希表存储货架上的商品数量
shelf := make(map[rune]int)
for _, item := range s {
shelf[item]++
}
// 2. 创建另一个哈希表存储顾客需求
customers := make(map[rune]int)
for _, item := range c {
customers[item]++
}
// 3. 贪心匹配:按照顾客需求顺序售卖商品
sold := 0
for _, item := range c {
if shelf[item] > 0 { // 如果货架上有该商品
sold++ // 售出商品
shelf[item]-- // 货架商品数量减少
}
}
return sold
}
func main() {
// 测试用例
fmt.Println(solution(3, 4, "abc", "abcd")) // 输出: 3
fmt.Println(solution(4, 2, "abbc", "bb")) // 输出: 2
fmt.Println(solution(5, 4, "bcdea", "abcd")) // 输出: 4
}
代码解析
核心逻辑
-
初始化哈希表: 使用
shelf和customers分别记录货架商品和顾客需求,时间复杂度为 (O(n + m)),其中 (n) 为货架长度,(m) 为顾客需求长度。 -
贪心遍历:
- 遍历顾客需求,优先售出货架上存在的商品。
- 每售出一个商品,减少货架对应商品数量。
时间复杂度为 (O(m))。
-
返回结果: 返回售出的商品数量
sold。
复杂度分析
-
时间复杂度:
- 初始化哈希表:(O(n + m))
- 贪心遍历顾客需求:(O(m))
- 总体复杂度为 (O(n + m))。
-
空间复杂度:
- 需要两个哈希表存储货架和顾客需求。
- 空间复杂度为 (O(k)),其中 (k) 是商品种类数。
测试样例与边界分析
测试样例
-
样例 1:
- 输入:
n = 3, m = 4, s = "abc", c = "abcd" - 解析:顾客需求为
a, b, c, d,但货架上没有d,所以最多能售出 3 件。 - 输出:
3
- 输入:
-
样例 2:
- 输入:
n = 4, m = 2, s = "abbc", c = "bb" - 解析:顾客需求为
b, b,货架上有两个b,因此能全部满足。 - 输出:
2
- 输入:
-
样例 3:
- 输入:
n = 5, m = 4, s = "bcdea", c = "abcd" - 解析:顾客需求为
a, b, c, d,货架上都有这些商品,因此最多能售出 4 件。 - 输出:
4
- 输入:
边界条件
-
空货架:
- 输入:
n = 0, m = 4, s = "", c = "abcd" - 输出:
0
- 输入:
-
无顾客需求:
- 输入:
n = 5, m = 0, s = "abcde", c = "" - 输出:
0
- 输入:
-
完全匹配:
- 输入:
n = 5, m = 5, s = "abcde", c = "abcde" - 输出:
5
- 输入:
总结与启发
-
贪心策略:
- 贪心算法在满足顾客需求的场景中非常高效,能够快速得出最优解。
-
扩展思考:
- 如果允许货架上商品数量不受限制,如何设计最优摆放?
- 如果商品可以以不同的权重计价,是否需要动态规划优化利润?
-
实际应用:
- 这种问题模型可以扩展到库存管理、资源分配等多个领域,通过调整策略以达到最优资源利用。