【位运算】C014_LC_ 可被 5 整除的二进制前缀(暴力大数 / 同余(2转10进制 新发现))

一、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;
    }
}

复杂度分析

  • 时间复杂度:O(n2)O(n^2)
  • 空间复杂度:O()O()

方法二:同余

这题的关键是:知道一个二进制串 s,如何按照从左到右的顺序去算出串对应的十进制呢?(ps:我们 2 转 10 进制,我们一般是从低位到高位进行计算的),直接给出公式把:
x=(x<<1)+s[i]i[0,n1]x = (x << 1) + s[i](i∈[0,n-1])

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;
    }
}

复杂度分析

  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(n)O(n)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章