【位運算】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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章