LeetCode1029. Binary Prefix Divisible By 5(DFA)自动机

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

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

示例 1:

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

输入:[1,1,1]
输出:[false,false,false]
示例 3:

输入:[0,1,1,1,1,1]
输出:[true,false,false,false,true,false]
示例 4:

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

提示:

1 <= A.length <= 30000
A[i] 为 0 或 1

思路:一个数除以5,其余数(十进制)只能是0,1,2,3,4五种,因此我们以0,1,2,3,4分别表示这五种状态。因为要求得能被5整除的数,0 mod 5=0满足要求,故状态0既为初始状态,又为终结状态。

接着,考虑二进制数在其串后增添0或1时,状态的转化情况。在二进制串后添1位,即可理解为将先前的串值乘以二再加上所添的数值。那么,串尾添数后新的数值模5的余数便可以计算出来。即可以得到添0或1后的新的状态。
在这里插入图片描述
也就是可以定义一个三维数组来记录所有的情况

class Solution {
       public List<Boolean> prefixesDivBy5(int[] A) {
        List<Boolean> res = new ArrayList<>();
        if (A.length < 1) return res;
        int StateSet[][] = new int[][]{
                {0, 1},
                {2, 3},
                {4, 0},
                {1, 2},
                {3, 4}
        };
        int state = 0;
        for (int i = 0; i < A.length; i++) {
            state = StateSet[state][A[i]];  //转换后的状态
            if (state == 0) {
                res.add(Boolean.TRUE);
            } else {
                res.add(Boolean.FALSE);
            }
        }
        return res;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_43274298/article/details/88927741