一、Problem
给定由若干 0 和 1 组成的数组 A。我们定义 N_i:从 A[0] 到 A[i] 的第 i 个子数组被解释为一个二进制数(从最高有效位到最低有效位)。
返回布尔值列表 answer,只有当 N_i 可以被 5 整除时,答案 answer[i] 为 true,否则为 false。
输入:[0,1,1]
输出:[true,false,false]
解释:
输入数字为 0, 01, 011;也就是十进制中的 0, 1, 3 。只有第一个数可以被 5 整除,因此 answer[0] 为真。
提示:
1 <= A.length <= 30000
A[i] 为 0 或 1
二、Solution
方法一:大数暴力
超时之 23/24
import java.math.*;
class Solution {
public List<Boolean> prefixesDivBy5(int[] A) {
int n = A.length;
StringBuilder[] pre = new StringBuilder[n+1];
pre[0] = new StringBuilder();
List<Boolean> ans = new LinkedList<>();
for (int i = 1; i <= n; i++) {
pre[i] = new StringBuilder(pre[i-1]);
pre[i].append(A[i-1]);
}
BigInteger Five = new BigInteger("5"), zero = BigInteger.ZERO;
for (int i = 1; i <= n; i++) {
BigInteger v = new BigInteger(pre[i].toString(), 2);
ans.add(zero.equals(v.mod(Five)));
}
return ans;
}
}
复杂度分析
- 时间复杂度:,
- 空间复杂度:,
方法二:同余
这题的关键是:知道一个二进制串 s,如何按照从左到右的顺序去算出串对应的十进制呢?(ps:我们 2 转 10 进制,我们一般是从低位到高位进行计算的),直接给出公式把:
class Solution {
public List<Boolean> prefixesDivBy5(int[] A) {
List<Boolean> ans = new LinkedList<>();
int x = 0;
for (int v : A) {
x = ((x << 1) + v) % 5;
ans.add(x % 5 == 0);
}
return ans;
}
}
复杂度分析
- 时间复杂度:,
- 空间复杂度:,