力扣 1018. 可被 5 整除的二进制前缀

题目说明

给定由若干 0 和 1 组成的数组 A。我们定义 N_i:从 A[0] 到 A[i] 的第 i 个子数组被解释为一个二进制数(从最高有效位到最低有效位)。

返回布尔值列表 answer,只有当 N_i 可以被 5 整除时,答案 answer[i] 为 true,否则为 false。

  • 1 <= A.length <= 30000
  • A[i]01

示例

例1

1
2
3
4
输入:[0,1,1]
输出:[true,false,false]
解释:
输入数字为 0, 01, 011;也就是十进制中的 0, 1, 3 。只有第一个数可以被 5 整除,因此 answer[0] 为真。

例2

1
2
输入:[1,1,1]
输出:[false,false,false]

例3

1
2
输入:[1,1,1,0,1]
输出:[false,false,false,false,false]

笔者理解

此题是一道位运算判定算法问题,在力扣题库中被定义为简单题。

解法

当笔者阅读完此题后,发现此题就是在计算各位置二进制累积所得数的个位数对5取余是否等于0,所以我们只需要保存每次计算完的个位数即可,就让我们看看位运算以及具体如何实现吧。

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
public List<Boolean> prefixesDivBy5(int[] A) {
List<Boolean> result = new ArrayList<Boolean>();
//创建result结果集用以存储结果
int temp = 0;
//创建temp用以暂存当前次数结果的个位结果
for(int i=0;i<A.length;i++){
temp<<=1;//左移一位即乘以2
temp+=A[i];//加上当前次数值
temp%=10;//取余
result.add(temp%5==0);//判断存入
}
return result;
}

时间和空间效率都较高,可见此解法比较适合此题;

image.png

总结

本题是今天的每日一题,难度达到了简单,感兴趣的朋友都可以去尝试一下,此题还有其他更多的解法,朋友们可以自己逐一尝试。