# Snowflake 面试题:一维数组中"人"和"蛋糕"的最小距离(含题目解析)
题目描述
Given a 1-d space, represented as an int array. Each element in this array can have one of the three values {0, 1, 2} with meanings:
0— space is empty1— there is a person at this space2— there is a cake at this space
The distance between a cake and a person is defined as the number of spaces between them.
Please write a method to get the minimum distance between any person and any cake in the space.
Example:
1 0 2 0 0
Answer: 1
问题分析
给你一个一维数组,里面有**"人 (1)"和"蛋糕 (2)"。要求找到任意一个人和任意一个蛋糕之间的"最小距离"**。
做法就是找出所有 1 和 2 的索引,然后算它们之间的最小绝对差值即可。
解法一:暴力枚举
def min_distance_brute_force(space):
"""
暴力枚举所有人和蛋糕的距离
时间复杂度:O(P × C),P 是人数,C 是蛋糕数
空间复杂度:O(P + C)
"""
people = []
cakes = []
# 1. 收集所有人和蛋糕的位置
for i in range(len(space)):
if space[i] == 1:
people.append(i)
elif space[i] == 2:
cakes.append(i)
# 2. 计算最小距离
min_dist = float('inf')
for person in people:
for cake in cakes:
dist = abs(person - cake)
min_dist = min(min_dist, dist)
return min_dist if min_dist != float('inf') else -1
解法二:双指针(优化版)
def min_distance_two_pointers(space):
"""
使用双指针优化
时间复杂度:O(n)
空间复杂度:O(P + C)
"""
people = []
cakes = []
for i in range(len(space)):
if space[i] == 1:
people.append(i)
elif space[i] == 2:
cakes.append(i)
if not people or not cakes:
return -1
# 双指针遍历
min_dist = float('inf')
i, j = 0, 0
while i < len(people) and j < len(cakes):
dist = abs(people[i] - cakes[j])
min_dist = min(min_dist, dist)
# 移动较小的指针
if people[i] < cakes[j]:
i += 1
else:
j += 1
return min_dist
解法三:一次遍历(最优)
def min_distance_one_pass(space):
"""
一次遍历找最小距离
时间复杂度:O(n)
空间复杂度:O(1)
"""
min_dist = float('inf')
last_person = -1
last_cake = -1
for i in range(len(space)):
if space[i] == 1:
last_person = i
if last_cake != -1:
min_dist = min(min_dist, abs(last_person - last_cake))
elif space[i] == 2:
last_cake = i
if last_person != -1:
min_dist = min(min_dist, abs(last_person - last_cake))
return min_dist if min_dist != float('inf') else -1
解法四:动态规划
def min_distance_dp(space):
"""
使用动态规划
dp[i] = 从位置 i 到最近蛋糕的距离
"""
n = len(space)
# 从左到右扫描
left_dist = [float('inf')] * n
last_cake = -1
for i in range(n):
if space[i] == 2:
last_cake = i
if last_cake != -1:
left_dist[i] = i - last_cake
# 从右到左扫描
right_dist = [float('inf')] * n
last_cake = -1
for i in range(n - 1, -1, -1):
if space[i] == 2:
last_cake = i
if last_cake != -1:
right_dist[i] = last_cake - i
# 找最小距离
min_dist = float('inf')
for i in range(n):
if space[i] == 1:
dist = min(left_dist[i], right_dist[i])
min_dist = min(min_dist, dist)
return min_dist if min_dist != float('inf') else -1
测试用例
# Test 1: 基本情况
space1 = [1, 0, 2, 0, 0]
print(min_distance_one_pass(space1)) # 输出: 1
# Test 2: 多个人和蛋糕
space2 = [1, 0, 1, 2, 0, 2, 1]
print(min_distance_one_pass(space2)) # 输出: 1
# Test 3: 人和蛋糕相邻
space3 = [1, 2, 0, 0]
print(min_distance_one_pass(space3)) # 输出: 0
# Test 4: 只有人或只有蛋糕
space4 = [1, 0, 1, 0, 1]
print(min_distance_one_pass(space4)) # 输出: -1
# Test 5: 空数组
space5 = []
print(min_distance_one_pass(space5)) # 输出: -1
扩展问题
1. 找出所有人到最近蛋糕的距离
def all_person_distances(space):
"""
返回每个人到最近蛋糕的距离
"""
n = len(space)
people = []
cakes = []
for i in range(n):
if space[i] == 1:
people.append(i)
elif space[i] == 2:
cakes.append(i)
result = []
for person in people:
min_dist = min(abs(person - cake) for cake in cakes)
result.append(min_dist)
return result
2. 找出距离最近的人-蛋糕对
def find_closest_pair(space):
"""
返回距离最近的人和蛋糕的位置
"""
people = []
cakes = []
for i in range(len(space)):
if space[i] == 1:
people.append(i)
elif space[i] == 2:
cakes.append(i)
min_dist = float('inf')
closest_pair = None
for person in people:
for cake in cakes:
dist = abs(person - cake)
if dist < min_dist:
min_dist = dist
closest_pair = (person, cake)
return closest_pair, min_dist
3. 二维版本
def min_distance_2d(grid):
"""
二维网格中人和蛋糕的最小曼哈顿距离
"""
m, n = len(grid), len(grid[0])
people = []
cakes = []
for i in range(m):
for j in range(n):
if grid[i][j] == 1:
people.append((i, j))
elif grid[i][j] == 2:
cakes.append((i, j))
min_dist = float('inf')
for px, py in people:
for cx, cy in cakes:
dist = abs(px - cx) + abs(py - cy)
min_dist = min(min_dist, dist)
return min_dist
复杂度对比
| 解法 | 时间复杂度 | 空间复杂度 | 优点 | 缺点 |
|---|---|---|---|---|
| 暴力枚举 | O(P × C) | O(P + C) | 简单直观 | 效率低 |
| 双指针 | O(n) | O(P + C) | 较快 | 需要排序 |
| 一次遍历 | O(n) | O(1) | 最优 | 代码稍复杂 |
| 动态规划 | O(n) | O(n) | 易扩展 | 空间开销大 |
优化技巧
- 提前终止:如果找到距离为 0,直接返回
- 缓存结果:如果多次查询,可以预处理
- 二分查找:如果位置已排序,可以用二分查找优化
总结
Snowflake 人-蛋糕最小距离题考察点:
- 数组遍历:基础的数组操作
- 双指针技巧:优化查找过程
- 动态规划:预处理距离信息
- 边界处理:空数组、无人/无蛋糕等情况
oavoservice 专注于 Snowflake / Google / Amazon 等大厂面试辅导,提供 OA 代做、VO 实时辅助等服务。如需帮助,欢迎联系我们。
需要面试真题? 立刻联系微信 Coding0201,获得真题。