一、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;
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,