Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Move from brute-force thinking to an efficient approach using array strategy.
You are given an array nums consisting of non-negative integers.
We define the score of subarray nums[l..r] such that l <= r as nums[l] AND nums[l + 1] AND ... AND nums[r] where AND is the bitwise AND operation.
Consider splitting the array into one or more subarrays such that the following conditions are satisfied:
Return the maximum number of subarrays in a split that satisfies the conditions above.
A subarray is a contiguous part of an array.
Example 1:
Input: nums = [1,0,2,0,1,2] Output: 3 Explanation: We can split the array into the following subarrays: - [1,0]. The score of this subarray is 1 AND 0 = 0. - [2,0]. The score of this subarray is 2 AND 0 = 0. - [1,2]. The score of this subarray is 1 AND 2 = 0. The sum of scores is 0 + 0 + 0 = 0, which is the minimum possible score that we can obtain. It can be shown that we cannot split the array into more than 3 subarrays with a total score of 0. So we return 3.
Example 2:
Input: nums = [5,7,1,3] Output: 1 Explanation: We can split the array into one subarray: [5,7,1,3] with a score of 1, which is the minimum possible score that we can obtain. It can be shown that we cannot split the array into more than 1 subarray with a total score of 1. So we return 1.
Constraints:
1 <= nums.length <= 1050 <= nums[i] <= 106Problem summary: You are given an array nums consisting of non-negative integers. We define the score of subarray nums[l..r] such that l <= r as nums[l] AND nums[l + 1] AND ... AND nums[r] where AND is the bitwise AND operation. Consider splitting the array into one or more subarrays such that the following conditions are satisfied: Each element of the array belongs to exactly one subarray. The sum of scores of the subarrays is the minimum possible. Return the maximum number of subarrays in a split that satisfies the conditions above. A subarray is a contiguous part of an array.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Greedy · Bit Manipulation
[1,0,2,0,1,2]
[5,7,1,3]
Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #2871: Split Array Into Maximum Number of Subarrays
class Solution {
public int maxSubarrays(int[] nums) {
int score = -1;
int ans = 1;
for (int num : nums) {
score &= num;
if (score == 0) {
ans++;
score = -1;
}
}
return ans == 1 ? 1 : ans - 1;
}
}
// Accepted solution for LeetCode #2871: Split Array Into Maximum Number of Subarrays
func maxSubarrays(nums []int) int {
ans, score := 1, -1
for _, num := range nums {
score &= num
if score == 0 {
score--
ans++
}
}
if ans == 1 {
return 1
}
return ans - 1
}
# Accepted solution for LeetCode #2871: Split Array Into Maximum Number of Subarrays
class Solution:
def maxSubarrays(self, nums: List[int]) -> int:
score, ans = -1, 1
for num in nums:
score &= num
if score == 0:
score = -1
ans += 1
return 1 if ans == 1 else ans - 1
// Accepted solution for LeetCode #2871: Split Array Into Maximum Number of Subarrays
// Rust example auto-generated from java reference.
// Replace the signature and local types with the exact LeetCode harness for this problem.
impl Solution {
pub fn rust_example() {
// Port the logic from the reference block below.
}
}
// Reference (java):
// // Accepted solution for LeetCode #2871: Split Array Into Maximum Number of Subarrays
// class Solution {
// public int maxSubarrays(int[] nums) {
// int score = -1;
// int ans = 1;
// for (int num : nums) {
// score &= num;
// if (score == 0) {
// ans++;
// score = -1;
// }
// }
// return ans == 1 ? 1 : ans - 1;
// }
// }
// Accepted solution for LeetCode #2871: Split Array Into Maximum Number of Subarrays
function maxSubarrays(nums: number[]): number {
let [ans, score] = [1, -1];
for (const num of nums) {
score &= num;
if (score === 0) {
--score;
++ans;
}
}
return ans == 1 ? 1 : ans - 1;
}
Use this to step through a reusable interview workflow for this problem.
Try every possible combination of choices. With n items each having two states (include/exclude), the search space is 2ⁿ. Evaluating each combination takes O(n), giving O(n × 2ⁿ). The recursion stack or subset storage uses O(n) space.
Greedy algorithms typically sort the input (O(n log n)) then make a single pass (O(n)). The sort dominates. If the input is already sorted or the greedy choice can be computed without sorting, time drops to O(n). Proving greedy correctness (exchange argument) is harder than the implementation.
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Wrong move: Locally optimal choices may fail globally.
Usually fails on: Counterexamples appear on crafted input orderings.
Fix: Verify with exchange argument or monotonic objective before committing.