设计停车系统 图解题解
这道题到底在问什么
- 输入
- new ParkingSystem(1, 1, 0); addCar(1)
- 输出
- true(大车位 1 个,停入后剩 0)
- 输入
- 接着 addCar(3)
- 输出
- false(小车位本就是 0,停不下)
最优解:一步一步想明白
- 3记住三个计数器:大车位余量、中车位余量、小车位余量。来车只动它自己那一种,大于 0 就减一停入,等于 0 就拒绝。
- 4停车场开张:大车位 2 个、中车位 2 个、小车位 2 个。三个计数器各记各的,等车来。
- 5来了一辆大车(carType=1)。只看大车位这一个计数器,现在余量是 2,看它还大不大于 0。
- 6大车位余量 2 大于 0,有空位:停进去,余量减一变成 1,返回 true。其它两种车位纹丝不动。
- 7来了一辆中车(carType=2)。只看中车位这一个计数器,现在余量是 2,看它还大不大于 0。
- 8中车位余量 2 大于 0,有空位:停进去,余量减一变成 1,返回 true。其它两种车位纹丝不动。
- 9来了一辆小车(carType=3)。只看小车位这一个计数器,现在余量是 2,看它还大不大于 0。
- 10小车位余量 2 大于 0,有空位:停进去,余量减一变成 1,返回 true。其它两种车位纹丝不动。
- 11来了一辆大车(carType=1)。只看大车位这一个计数器,现在余量是 1,看它还大不大于 0。
- 12大车位余量 1 大于 0,有空位:停进去,余量减一变成 0,返回 true。其它两种车位纹丝不动。
- 13来了一辆大车(carType=1)。只看大车位这一个计数器,现在余量是 0,看它还大不大于 0。
- 14大车位余量已经是 0,没空位了:这辆车停不下,余量保持 0,返回 false。
- 15来了一辆中车(carType=2)。只看中车位这一个计数器,现在余量是 1,看它还大不大于 0。
- 16中车位余量 1 大于 0,有空位:停进去,余量减一变成 0,返回 true。其它两种车位纹丝不动。
- 17来了一辆小车(carType=3)。只看小车位这一个计数器,现在余量是 1,看它还大不大于 0。
- 18小车位余量 1 大于 0,有空位:停进去,余量减一变成 0,返回 true。其它两种车位纹丝不动。
- 19来了一辆小车(carType=3)。只看小车位这一个计数器,现在余量是 0,看它还大不大于 0。
- 20小车位余量已经是 0,没空位了:这辆车停不下,余量保持 0,返回 false。
- 21来了一辆中车(carType=2)。只看中车位这一个计数器,现在余量是 0,看它还大不大于 0。
- 22中车位余量已经是 0,没空位了:这辆车停不下,余量保持 0,返回 false。
- 23来了一辆大车(carType=1)。只看大车位这一个计数器,现在余量是 0,看它还大不大于 0。
- 24大车位余量已经是 0,没空位了:这辆车停不下,余量保持 0,返回 false。
- 25来了一辆小车(carType=3)。只看小车位这一个计数器,现在余量是 0,看它还大不大于 0。
- 26小车位余量已经是 0,没空位了:这辆车停不下,余量保持 0,返回 false。
- 2711 辆车依次处理完毕:成功停入 6 辆、因满拒绝 5 辆。三个计数器最终余量就是各车位的剩余空位。
⚠️ 容易写错的地方
✗ 错:返回 true 时忘了把余量减一
✓ 对:停入成功就立刻 rem[carType] -= 1
不减一就成了无限车位,同一种车能一直停,结果全是 true
✗ 错:把三种车位混成一个总数来判断
✓ 对:每种车位各记各的,只看对应那一个
大车不能停小车位,合并计数会让大车占用本属于小车的空位,逻辑错误
✗ 错:carType 与数组下标对不齐
✓ 对:carType 是 1/2/3,数组留出下标 0 或做减一映射
carType 从 1 开始,若直接当下标又不留空位 0,会整体错位读错计数器
完整代码(Python / C++ / Java)
Python
class ParkingSystem:
def __init__(self, big, medium, small):
# 三个独立计数器,记各车位余量
self.rem = [0, big, medium, small] # 按 carType 索引
def addCar(self, carType: int) -> bool:
if self.rem[carType] > 0: # 还有空位
self.rem[carType] -= 1 # 停入,减一
return True
return False # 满了,拒绝C++
class ParkingSystem {
int rem[4]; // 按 carType 索引
public:
ParkingSystem(int big, int medium, int small) {
rem[1]=big; rem[2]=medium; rem[3]=small;
}
bool addCar(int carType) {
if (rem[carType] > 0) { rem[carType]--; return true; }
return false;
}
};Java
class ParkingSystem {
int[] rem = new int[4]; // 按 carType 索引
public ParkingSystem(int big, int medium, int small) {
rem[1]=big; rem[2]=medium; rem[3]=small;
}
public boolean addCar(int carType) {
if (rem[carType] > 0) { rem[carType]--; return true; }
return false;
}
}复杂度
时间
O(1)
每次 addCar 只读一次、改一次对应计数器,与车位数量无关
空间
O(1)
只存大/中/小三个计数器,固定三格
看不够?换成动画再走一遍
上面的推演每一步都对应一帧动画。点开交互动画版,能一步步看着 设计停车系统 的数据怎么变、指针怎么走,还能切 Python / Java / C++ 跟着练。
面试官可能追问
为什么这题用三个计数器就够了,不用真的建一个停车场矩阵?+
题目只问「能不能停下」,不关心停在哪个具体位置。所以只需记每种车位还剩几个空位,来一辆减一个,是否大于 0 就决定能否停入。
如果还要支持「车开走、释放车位」呢?+
加一个 removeCar(carType),对应计数器加一即可(可加上限保护,不超过初始容量)。计数器模型天然支持加减。
用数组按 carType 索引和写三个 if 有什么区别?+
效果一样,但数组索引省掉分支、更简洁,也更容易扩展到更多车型;前提是注意 carType 从 1 开始的下标对齐。
想听吴师兄把这道题讲给你听?
文字版和动画都随便看。开通图解算法年卡,可以听吴师兄把 设计停车系统 一步步讲透(全站已上线 905 份讲透,持续扩充), 卡住的地方还有 AI 私教小欧就着动画帮你拆到懂。
把这道题真正拿下
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。