1018. 可被 5 整除的二进制前缀『简单』

题目来源于力扣(LeetCode

一、题目

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

题目相关标签:数组

提示:

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

二、解题思路

  1. 遍历数组,对数组上的元素进行二进制数字的计算操作

  2. 定义变量 j,j 初始值为 0,用于存储当前遍历元素及其索引之前的全部元素组成的二进制数字

    使初始值为 0,可以防止元素首位元素为 0 的情况

  3. 计算方式:j 左移一位加上当前遍历的元素

    元素只为 0 或 1

  4. 考虑到数组 A 的长度取值范围是 1 到 30000,则需要处理数值溢出的情况

    long 类型也不够用

  5. 处理数值溢出:每次都对 j 进行取余 5 的操作,使 j 的值控制在较小的数值内

三、代码实现

public static List<Boolean> prefixesDivBy5(int[] A) {
    List<Boolean> list = new ArrayList<>(A.length);
    // 变量 j 记录数组前 i 项组成的二进制数字的十进制形式
    int j = 0;  // 初始和声明为 0
    for (int i = 0; i < A.length; i++) {
        // 当前遍历元素与之前元素所能组成的二进制数字,用十进制表示
        // 每次遍历都左移 1 位,即乘 2,加上当前遍历元素的值,为 0 或为 1
        j = (j << 1) + A[i];
        // 对 5 取余并赋值取余的结果,因数组长度过大,有溢出风险
        // 对 j 赋值 j 取余 5 的结果,该操作并不会影响判断的结果
        j %= 5;
        // j == 0 时,说明当前遍历元素与前面全部的元素组成的二进制数字能够被 5 整除
        list.add(j == 0 ? Boolean.TRUE : Boolean.FALSE);
    }
    return list;
}

四、执行用时

五、部分测试用例

public static void main(String[] args) {
    int[] arr = {0, 1, 1};  // output:{true, false, false}
//    int[] arr = {1, 1, 1};  // output:{false, false, false}
//    int[] arr = {0, 1, 1, 1, 1, 1};  // output:{true, false, false, false, true, false}
//    int[] arr = {1, 1, 1, 0, 1};  // output:{fasle, false, false, false, false}
    List<Boolean> result = prefixesDivBy5(arr);
    System.out.println(result);
}
posted @ 2020-05-14 21:34  知音12138  阅读(246)  评论(0编辑  收藏  举报