跳转至

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

题目描述

给定一个二进制数组 nums索引从0开始 )。

我们将xi 定义为其二进制表示形式为子数组 nums[0..i] (从最高有效位到最低有效位)。

  • 例如,如果 nums =[1,0,1] ,那么 x0 = 1x1 = 2, 和 x2 = 5

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

 

示例 1:

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

示例 2:

输入:nums = [1,1,1]
输出:[false,false,false]

 

提示:

  • 1 <= nums.length <= 105 
  • nums[i] 仅为 0 或 1

解法

方法一:模拟

我们用一个变量 $x$ 来表示当前的二进制前缀,然后遍历数组 $nums$,对于每个元素 $v$,我们将 $x$ 左移一位,然后加上 $v$,再对 $5$ 取模,判断是否等于 $0$,如果等于 $0$,则说明当前的二进制前缀可以被 $5$ 整除,我们将 $\textit{true}$ 加入答案数组,否则将 $\textit{false}$ 加入答案数组。

时间复杂度 $O(n)$,忽略答案数组的空间消耗,空间复杂度 $O(1)$。

1
2
3
4
5
6
7
8
class Solution:
    def prefixesDivBy5(self, nums: List[int]) -> List[bool]:
        ans = []
        x = 0
        for v in nums:
            x = (x << 1 | v) % 5
            ans.append(x == 0)
        return ans
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class Solution {
    public List<Boolean> prefixesDivBy5(int[] nums) {
        List<Boolean> ans = new ArrayList<>();
        int x = 0;
        for (int v : nums) {
            x = (x << 1 | v) % 5;
            ans.add(x == 0);
        }
        return ans;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Solution {
public:
    vector<bool> prefixesDivBy5(vector<int>& nums) {
        vector<bool> ans;
        int x = 0;
        for (int v : nums) {
            x = (x << 1 | v) % 5;
            ans.push_back(x == 0);
        }
        return ans;
    }
};
1
2
3
4
5
6
7
8
func prefixesDivBy5(nums []int) (ans []bool) {
    x := 0
    for _, v := range nums {
        x = (x<<1 | v) % 5
        ans = append(ans, x == 0)
    }
    return
}
1
2
3
4
5
6
7
8
9
function prefixesDivBy5(nums: number[]): boolean[] {
    const ans: boolean[] = [];
    let x = 0;
    for (const v of nums) {
        x = ((x << 1) | v) % 5;
        ans.push(x === 0);
    }
    return ans;
}

评论