给定由若干 0 0 0 和 1 1 1 组成的数组 A A A。我们定义 N i N_i Ni:从 A [ 0 ] A[0] A[0] 到 A [ i ] A[i] A[i] 的第 i i i 个子数组被解释为一个二进制数(从最高有效位到最低有效位)。
返回布尔值列表 a n s w e r answer answer,只有当 N i N_i Ni 可以被 5 5 5 整除时,答案 a n s w e r [ i ] answer[i] answer[i] 为 true,否则为 false。
示例 1:
输入:[0,1,1]
输出:[true,false,false]
解释:
输入数字为
0
0
0,
01
01
01,
011
011
011;也就是十进制中的
0
0
0,
1
1
1,
3
3
3 。只有第一个数可以被
5
5
5 整除,因此
a
n
s
w
e
r
[
0
]
answer[0]
answer[0] 为真。
示例 2:
输入:[1,1,1]
输出:[false,false,false]
示例 3:
输入:[0,1,1,1,1,1]
输出:[true,false,false,false,true,false]
示例 4:
输入:[1,1,1,0,1]
输出:[false,false,false,false,false]
提示:
1
<
=
A
.
l
e
n
g
t
h
<
=
30000
1 <= A.length <= 30000
1<=A.length<=30000
A
[
i
]
A[i]
A[i] 为
0
0
0 或
1
1
1
令 N i N_i Ni为数组 A A A 从下标 0 0 0 到下标 i i i 的前缀表示的二进制数,则有 N 0 = A [ 0 ] N_0=A[0] N0=A[0]当 i > 0 i>0 i>0 时,有 N i = N i − 1 × 2 + A [ i ] N_i=N_{i-1} \times 2+A[i] Ni=Ni−1×2+A[i]。令 n n n 为数组 A A A 的长度,则对于 0 ≤ i < n 0 ≤ i < n 0 \le i<n0≤i<n 0≤i<n0≤i<n,可以依次计算每个 N i N_i Ni的值。对于每个 N i N_i Ni的值,判断其是否可以被 5 5 5 整除,即可得到答案。
考虑到数组 A A A 可能很长,如果每次都保留 N i N_i Ni的值,则可能导致溢出。由于只需要知道每个 N i N_i Ni是否可以被 5 5 5 整除,因此在计算过程中只需要保留余数即可。
令 M i M_i Mi表示计算到下标 i i i 时的除以 5 5 5 的余数,则有 M 0 = A [ 0 ] M_0=A[0] M0=A[0](显然 A [ 0 ] A[0] A[0] 一定小于 5 5 5),当 i > 0 i>0 i>0 时,有 M i = ( M i − 1 × 2 + A [ i ] ) m o d 5 M_i=(M_{i-1} \times 2+A[i])\bmod 5 Mi=(Mi−1×2+A[i])mod5,判断每个 M i M_i Mi是否为 0 0 0 即可。由于 M i M_i Mi一定小于 5 5 5,因此不会溢出。
如何证明判断 M i M_i Mi是否为 0 0 0 可以得到正确的结果?可以通过数学归纳法证明。
当 i = 0 i=0 i=0时,由于 $N_0=A[0]<5,因此 M 0 = N 0 M_0=N_0 M0=N0, M 0 = N 0 m o d 5 M_0=N_0\bmod 5 M0=N0mod5成立。
当
i
>
0
i>0
i>0 时,假设
M
i
−
1
=
N
i
−
1
m
o
d
5
M_{i-1}=N_{i-1}\bmod 5
Mi−1=Ni−1mod5成立,考虑
N
i
m
o
d
5
N_i\bmod 5
Nimod5和
M
i
M_i
Mi
的值:
N
i
m
o
d
5
=
(
N
i
−
1
×
2
+
A
[
i
]
)
m
o
d
5
=
(
N
i
−
1
×
2
)
m
o
d
5
+
A
[
i
]
m
o
d
5
M
i
=
(
M
i
−
1
×
2
+
A
[
i
]
)
m
o
d
5
=
(
N
i
−
1
m
o
d
5
×
2
+
A
[
i
]
)
m
o
d
5
=
(
N
i
−
1
m
o
d
5
×
2
)
m
o
d
5
+
A
[
i
]
m
o
d
5
=
(
N
i
−
1
×
2
)
m
o
d
5
+
A
[
i
]
m
o
d
5
\begin{aligned} N_i\bmod 5=&(N_{i-1} \times 2+A[i])\bmod 5 \\ =&(N_{i-1} \times 2)\bmod 5+A[i]\bmod 5 \\ \\ M_i=&(M_{i-1} \times 2+A[i])\bmod 5 \\ =&(N_{i-1}\bmod 5 \times 2+A[i])\bmod 5 \\ =&(N_{i-1}\bmod 5 \times 2)\bmod 5+A[i]\bmod 5 \\ =&(N_{i-1} \times 2)\bmod 5+A[i]\bmod 5 \end{aligned}
Nimod5==Mi====(Ni−1×2+A[i])mod5(Ni−1×2)mod5+A[i]mod5(Mi−1×2+A[i])mod5(Ni−1mod5×2+A[i])mod5(Ni−1mod5×2)mod5+A[i]mod5(Ni−1×2)mod5+A[i]mod5
即可得到正确的结果。
class Solution {
public:
vector<bool> prefixesDivBy5(vector<int>& A) {
int n=A.size();
vector<bool>res;
int num=0;
for (int i=0;i<n;i++){
num=(num*2+A[i])%5;
if (num==0){
res.push_back(true);
}else res.push_back(false);
}
return res;
}
};