{x}
blog image

Binary Prefix Divisible By 5

You are given a binary array nums (0-indexed).

We define xi as the number whose binary representation is the subarray nums[0..i] (from most-significant-bit to least-significant-bit).

  • For example, if nums = [1,0,1], then x0 = 1, x1 = 2, and x2 = 5.

Return an array of booleans answer where answer[i] is true if xi is divisible by 5.

 

Example 1:

Input: nums = [0,1,1]
Output: [true,false,false]
Explanation: The input numbers in binary are 0, 01, 011; which are 0, 1, and 3 in base-10.
Only the first number is divisible by 5, so answer[0] is true.

Example 2:

Input: nums = [1,1,1]
Output: [false,false,false]

 

Constraints:

  • 1 <= nums.length <= 105
  • nums[i] is either 0 or 1.

Solution Explanation:

This problem asks to determine if the binary representation of prefixes of a given binary array are divisible by 5. The solution utilizes bit manipulation for efficient computation.

Approach:

The core idea is to iteratively build the binary number represented by each prefix and check for divisibility by 5. Instead of converting the binary representation to an integer each time (which can be inefficient for large inputs), we use modular arithmetic.

  1. Initialization: We start with x = 0, representing the initial binary prefix (empty, which is divisible by 5).
  2. Iteration: We iterate through the input array nums. For each digit v:
    • We perform a left bit shift on x (x << 1). This effectively multiplies the current binary number by 2.
    • We then add the current digit v to x. This appends the digit to the binary number.
    • We take the modulo 5 of the result (% 5). This ensures that x always holds the remainder when the binary number is divided by 5. This prevents the numbers from becoming excessively large.
  3. Divisibility Check: If the resulting x is 0, it means the current binary prefix is divisible by 5; we append true to the result array. Otherwise, we append false.

Time Complexity: O(n), where n is the length of the input array nums. We iterate through the array once.

Space Complexity: O(n), where n is the length of the input array. This is due to the storage of the ans array (the result). If we ignore the output array, the space complexity is O(1), as we only use a few constant-sized variables.

Code in Different Languages:

The provided code snippets in Python, Java, C++, Go, and TypeScript all implement this approach. They are functionally equivalent, differing only in syntax.

Python3:

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

Java:

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

C++:

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

Go:

func prefixesDivBy5(nums []int) (ans []bool) {
	x := 0
	for _, v := range nums {
		x = (x<<1 | v) % 5
		ans = append(ans, x == 0)
	}
	return
}

TypeScript:

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

All these solutions efficiently solve the problem using bit manipulation and modular arithmetic, achieving a linear time complexity. The choice of language depends on personal preference and the project's requirements.