1. 问题描述:
给定一个长度为 n 的整数数组 a1,a2,…,an,对于每个整数 i(1 ≤ i ≤ n),请你找到一个整数 j,要求:
- 1 ≤ j ≤ n
- aj = 0
在满足以上两个条件的情况下,|i − j| 应尽可能小,|i−j| 的最小可能值不妨用 bi 来表示
请你计算并输出 b1,b2,…,bn,保证给定数组中一定存在 0
输入格式
第一行包含整数 n,第二行包含 n 个整数 a1,a2,…,an。
输出格式
一行,n 个整数 b1,b2,…,bn。
数据范围
前 4 个测试点满足 1 ≤ n ≤ 10
所有测试点满足 1 ≤ n ≤ 2 × 10 ^ 5,−10 ^ 9 ≤ ai ≤ 10 ^ 9
输入样例1:
9
2 1 0 3 0 0 3 2 4
输出样例1:
2 1 0 1 0 0 1 2 3
输入样例2:
5
0 1 2 3 4
输出样例2:
0 1 2 3 4
输入样例3:
7
5 6 0 1 -2 3 4
输出样例3:
2 1 0 1 2 3 4
来源:https://www.acwing.com/problem/content/description/4426/
2. 思路分析:
分析题目可以知道我们需要找到每一个元素 a[i] 距离最近的 0 的位置 j,而 b[i] = |i - j|,可以发现第一个 0 与最后一个 0 两边的元素的最短距离是唯一确定的,而对于中间相邻两个 0 之间的元素 a[i],b[i] 的值为与最靠近的 0 之间的距离,我们可以枚举所有的 a[i],记录下 a[i] = 0 的位置 i 到 q 中,对于第一个 0 和最后一个 0 两边的元素由于 |i - j| 是确定的,所以直接计算 |i - j| 即可,而对于相邻两个 0 之间的元素 b[i] 的 |i - j| 则需要分情况讨论,若相邻两个 0 的位置分别为 x,y,则中间位置为 (x + y ) / 2,[x + 1,mid] 的元素的最短距离为 i - x,[mid + 1,y) 的元素的最短距离为 y - i:
3. 代码如下:
python:
class Solution:
def process(self):
n = int(input())
a = list(map(int, input().split()))
q = list()
for i in range(n):
if a[i] == 0:
q.append(i)
b = [0] * n
x0, x1 = q[0], q[-1]
# 特殊处理开头与结尾的0的两边的元素
for i in range(x0):
b[i] = x0 - i
for i in range(x1 + 1, n):
b[i] = i - x1
# 只有当0的个数大于等于2的时候两个0之间才有元素
for i in range(1, len(q)):
# 计算相邻两个0之间的中间位置
mid = q[i] + q[i - 1] >> 1
for j in range(q[i - 1] + 1, mid + 1):
b[j] = j - q[i - 1]
for j in range(mid + 1, q[i]):
b[j] = q[i] - j
print(*b)
if __name__ == '__main__':
Solution().process()
go:
package main
import (
"bufio"
"fmt"
"io"
"os"
)
func run(r io.Reader, w io.Writer) {
in := bufio.NewReader(r)
out := bufio.NewWriter(w)
// 将缓存数据写入到标准输出中
defer out.Flush()
var (
n, x int
// q记录0的位置
q []int
)
fmt.Fscan(in, &n)
for i := 0; i < n; i++ {
fmt.Fscan(in, &x)
if x == 0 {
q = append(q, i)
}
}
x0 := q[0]
x1 := q[len(q)-1]
b := make([]int, n)
// 特殊开头与结尾的0两边的元素
for i := 0; i < x0; i++ {
b[i] = x0 - i
}
for i := x1 + 1; i < n; i++ {
b[i] = i - x1
}
for i := 1; i < len(q); i++ {
mid := (q[i] + q[i-1]) / 2
for j := q[i-1] + 1; j <= mid; j++ {
b[j] = j - q[i-1]
}
for j := mid + 1; j < q[i]; j++ {
b[j] = q[i] - j
}
}
for i := 0; i < n; i++ {
fmt.Fprint(out, b[i], " ")
}
}
func main() {
run(os.Stdin, os.Stdout)
}