3344. Maximum Sized Array
Problem Description
You are given a positive integer s. You need to create a 3D array A with dimensions n × n × n, where each element is calculated using a specific formula.
For each element in the array, A[i][j][k] is defined as:
A[i][j][k] = i * (j OR k), where0 <= i, j, k < n- The
ORoperation is the bitwise OR operation
Your task is to find the maximum possible value of n such that when you sum up all elements in the entire 3D array A, the total sum does not exceed s.
For example, if n = 2, you would have a 2×2×2 array with 8 elements total:
A[0][0][0] = 0 * (0 OR 0) = 0A[0][0][1] = 0 * (0 OR 1) = 0A[0][1][0] = 0 * (1 OR 0) = 0A[0][1][1] = 0 * (1 OR 1) = 0A[1][0][0] = 1 * (0 OR 0) = 0A[1][0][1] = 1 * (0 OR 1) = 1A[1][1][0] = 1 * (1 OR 0) = 1A[1][1][1] = 1 * (1 OR 1) = 1
The sum would be 3, and if s >= 3, then n = 2 would be valid. You need to find the largest such n where the sum stays within the limit s.
Intuition
Let's think about how to calculate the sum efficiently. If we expand the sum of all elements in the 3D array:
Sum = Σ(i=0 to n-1) Σ(j=0 to n-1) Σ(k=0 to n-1) i * (j OR k)
We can rearrange this as:
Sum = Σ(i=0 to n-1) i * Σ(j=0 to n-1) Σ(k=0 to n-1) (j OR k)
Notice that the inner double summation Σ(j=0 to n-1) Σ(k=0 to n-1) (j OR k) is independent of i. Let's call this value S_or.
The key insight is that for any fixed value of j OR k, we can count how many (j, k) pairs produce that value. Due to symmetry in the OR operation, we can simplify our calculation.
For efficiency, we can precompute f[n] which represents Σ(i=0 to n-1) Σ(j=0 to i) (i OR j). Why up to i instead of n-1? Because (i OR j) where j <= i captures the essential pattern, and we can use symmetry to handle the full range.
The total sum for a given n can then be expressed as:
Total Sum = f[n-1] * (n-1) * n / 2
This formula accounts for the multiplication by each i value and the proper counting of all (j, k) pairs.
Since the sum grows rapidly with n (approximately as n^5), and we want the maximum n where the sum doesn't exceed s, binary search becomes the natural choice. We can estimate that n won't exceed around 1330 based on the growth rate.
By preprocessing the values up to this maximum and then using binary search, we can efficiently find the largest valid n where the total sum stays within the limit s.
Learn more about Binary Search patterns.
Solution Implementation
1# Maximum array size to precompute
2MAX_SIZE = 1330
3
4# Precompute cumulative OR sums for all array sizes
5# cumulative_or_sum[i] = sum of all (j | k) for 0 <= j, k < i
6cumulative_or_sum = [0] * MAX_SIZE
7
8for array_size in range(1, MAX_SIZE):
9 # Start with previous cumulative sum
10 cumulative_or_sum[array_size] = cumulative_or_sum[array_size - 1] + array_size
11
12 # Add contribution of OR operations with the new element (array_size)
13 for element in range(array_size):
14 cumulative_or_sum[array_size] += 2 * (array_size | element)
15
16
17class Solution:
18 def maxSizedArray(self, s: int) -> int:
19 """
20 Find the maximum array size where the total cost doesn't exceed s.
21 Uses standard template: find first n where cost exceeds s.
22
23 The cost for an array of size n is calculated as:
24 cumulative_or_sum[n-1] * (n-1) * n // 2
25
26 Args:
27 s: Maximum allowed cost
28
29 Returns:
30 Maximum array size that satisfies the cost constraint
31 """
32 left, right = 1, MAX_SIZE - 1
33 first_exceed_index = -1 # First n where cost > s
34
35 # Binary search for first size where cost exceeds s
36 while left <= right:
37 mid = (left + right) // 2
38
39 # Check if array of size 'mid' exceeds the cost constraint
40 cost = cumulative_or_sum[mid - 1] * (mid - 1) * mid // 2
41
42 if cost > s:
43 # Feasible: cost exceeds limit
44 first_exceed_index = mid
45 right = mid - 1 # Look for earlier exceed
46 else:
47 # Not feasible: cost still valid
48 left = mid + 1
49
50 # Return one less than first exceed, or max if never exceeded
51 if first_exceed_index == -1:
52 return MAX_SIZE - 1
53 return first_exceed_index - 1
541class Solution {
2 // Maximum array size to precompute
3 private static final int MAX_SIZE = 1330;
4
5 // Precomputed values for each array size
6 // f[i] represents the sum: i + 2 * sum of (i | j) for all j from 0 to i-1
7 private static final long[] precomputedValues = new long[MAX_SIZE];
8
9 // Static initialization block to precompute values
10 static {
11 for (int i = 1; i < MAX_SIZE; ++i) {
12 // Start with the previous computed value plus current index
13 precomputedValues[i] = precomputedValues[i - 1] + i;
14
15 // Add twice the bitwise OR of current index with all previous indices
16 for (int j = 0; j < i; ++j) {
17 precomputedValues[i] += 2 * (i | j);
18 }
19 }
20 }
21
22 public int maxSizedArray(long s) {
23 // Binary search using standard template: find first n where cost > s
24 int left = 1;
25 int right = MAX_SIZE - 1;
26 int firstExceedIndex = -1;
27
28 while (left <= right) {
29 int mid = left + (right - left) / 2;
30
31 // Check if the computed value for size mid exceeds s
32 long cost = precomputedValues[mid - 1] * (mid - 1) * mid / 2;
33
34 if (cost > s) {
35 // Feasible: cost exceeds limit
36 firstExceedIndex = mid;
37 right = mid - 1; // Look for earlier exceed
38 } else {
39 // Not feasible: cost still valid
40 left = mid + 1;
41 }
42 }
43
44 // Return one less than first exceed, or max if never exceeded
45 if (firstExceedIndex == -1) {
46 return MAX_SIZE - 1;
47 }
48 return firstExceedIndex - 1;
49 }
50}
511// Maximum array size constant
2const int MAX_SIZE = 1330;
3
4// Precomputed values for array size calculations
5// f[i] represents the sum of i plus all pairwise OR operations for elements 0 to i-1
6long long cumulativeOrSum[MAX_SIZE];
7
8// Initialize the precomputed values at compile time
9auto initializer = [] {
10 cumulativeOrSum[0] = 0;
11
12 for (int i = 1; i < MAX_SIZE; ++i) {
13 // Start with the sum from previous iteration plus current index
14 cumulativeOrSum[i] = cumulativeOrSum[i - 1] + i;
15
16 // Add twice the bitwise OR of current index with all previous indices
17 // (twice because each pair contributes to both elements)
18 for (int j = 0; j < i; ++j) {
19 cumulativeOrSum[i] += 2 * (i | j);
20 }
21 }
22 return 0;
23}();
24
25class Solution {
26public:
27 /**
28 * Finds the maximum size of an array that satisfies the given constraint.
29 * Uses standard template: find first n where cost > s.
30 *
31 * @param s The upper bound constraint value
32 * @return The maximum size of the array that satisfies the constraint
33 */
34 int maxSizedArray(long long s) {
35 int left = 1;
36 int right = MAX_SIZE - 1;
37 int firstExceedIndex = -1;
38
39 // Binary search for first size where cost exceeds s
40 while (left <= right) {
41 int mid = left + (right - left) / 2;
42
43 // Check if array of size 'mid' exceeds the constraint
44 long long cost = cumulativeOrSum[mid - 1] * (mid - 1) * mid / 2;
45
46 if (cost > s) {
47 // Feasible: cost exceeds limit
48 firstExceedIndex = mid;
49 right = mid - 1; // Look for earlier exceed
50 } else {
51 // Not feasible: cost still valid
52 left = mid + 1;
53 }
54 }
55
56 // Return one less than first exceed, or max if never exceeded
57 if (firstExceedIndex == -1) {
58 return MAX_SIZE - 1;
59 }
60 return firstExceedIndex - 1;
61 }
62};
631// Maximum array size constant
2const MAX_SIZE = 1330;
3
4// Precomputed values array for optimization
5// f[i] represents the cumulative sum for size i
6const precomputedValues: bigint[] = Array(MAX_SIZE).fill(0n);
7
8// Initialize precomputed values using IIFE (Immediately Invoked Function Expression)
9(() => {
10 // Base case: empty array has sum 0
11 precomputedValues[0] = 0n;
12
13 // Calculate cumulative sums for each array size
14 for (let i = 1; i < MAX_SIZE; i++) {
15 // Start with previous sum plus current index
16 precomputedValues[i] = precomputedValues[i - 1] + BigInt(i);
17
18 // Add contribution from bitwise OR operations with all previous indices
19 for (let j = 0; j < i; j++) {
20 // Each OR operation contributes twice (for both i|j and j|i pairs)
21 precomputedValues[i] += BigInt(2) * BigInt(i | j);
22 }
23 }
24})();
25
26/**
27 * Finds the maximum sized array whose total sum does not exceed the given limit.
28 * Uses standard template: find first n where cost > s.
29 *
30 * @param s - The maximum allowed sum
31 * @returns The maximum array size that satisfies the sum constraint
32 */
33function maxSizedArray(s: number): number {
34 let left = 1;
35 let right = MAX_SIZE - 1;
36 let firstExceedIndex = -1;
37 const targetSum = BigInt(s);
38
39 // Binary search for first size where cost exceeds s
40 while (left <= right) {
41 const mid = Math.floor((left + right) / 2);
42
43 // Calculate the total sum for an array of size mid
44 const currentSum = (precomputedValues[mid - 1] * BigInt(mid - 1) * BigInt(mid)) / BigInt(2);
45
46 if (currentSum > targetSum) {
47 // Feasible: cost exceeds limit
48 firstExceedIndex = mid;
49 right = mid - 1; // Look for earlier exceed
50 } else {
51 // Not feasible: cost still valid
52 left = mid + 1;
53 }
54 }
55
56 // Return one less than first exceed, or max if never exceeded
57 if (firstExceedIndex === -1) {
58 return MAX_SIZE - 1;
59 }
60 return firstExceedIndex - 1;
61}
62Solution Approach
The solution consists of two main parts: preprocessing and binary search.
Preprocessing Phase:
First, we establish an upper bound for n. Since the sum grows approximately as (n-1)^5 / 4, and we need (n-1)^5 / 4 ≤ s, we can determine that n won't exceed approximately 1330 for reasonable values of s.
We precompute an array f where f[i] represents the sum Σ(j=0 to i) Σ(k=0 to j) (j OR k). The preprocessing code:
mx = 1330
f = [0] * mx
for i in range(1, mx):
f[i] = f[i - 1] + i # Add the case where j OR k = i (when j = k = i)
for j in range(i):
f[i] += 2 * (i | j) # Count both (i, j) and (j, i) cases
The formula f[i] = f[i-1] + i + 2 * Σ(j=0 to i-1) (i OR j) builds upon the previous value and adds new contributions from index i.
Binary Search Phase:
Once we have the preprocessed values, we use binary search to find the maximum n such that the total sum doesn't exceed s.
For a given n, the total sum of the 3D array is calculated as:
Total Sum = f[n-1] * (n-1) * n / 2
This formula accounts for:
f[n-1]: The sum pattern for OR operations(n-1): Multiplication by each value ofifrom 0 to n-1n / 2: Proper scaling factor for the 3D array structure
The binary search implementation uses the standard template. Since we want the maximum valid n, we find the first n where sum exceeds s:
def maxSizedArray(self, s: int) -> int:
left, right = 1, mx
first_exceed_index = -1 # First n where sum > s
while left <= right:
mid = (left + right) // 2
cost = f[mid - 1] * (mid - 1) * mid // 2
if cost > s: # Feasible: sum exceeds s
first_exceed_index = mid
right = mid - 1 # Look for earlier exceed
else:
left = mid + 1 # Sum still valid, try larger
# If never exceeded, return max; otherwise return one less than first exceed
if first_exceed_index == -1:
return mx
return first_exceed_index - 1
The binary search finds the first n where the sum exceeds s, then returns first_exceed_index - 1 as the maximum valid n.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through finding the maximum n for s = 10.
Step 1: Understanding the 3D Array
For n = 2, we calculate all elements:
- When
i = 0: All elements are 0 (since0 * anything = 0) - When
i = 1:A[1][0][0] = 1 * (0 OR 0) = 1 * 0 = 0A[1][0][1] = 1 * (0 OR 1) = 1 * 1 = 1A[1][1][0] = 1 * (1 OR 0) = 1 * 1 = 1A[1][1][1] = 1 * (1 OR 1) = 1 * 1 = 1
Total sum = 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 = 3
Step 2: Preprocessing Values
We build our f array:
f[0] = 0f[1] = f[0] + 1 + 2*(1 OR 0) = 0 + 1 + 2*1 = 3f[2] = f[1] + 2 + 2*(2 OR 0) + 2*(2 OR 1) = 3 + 2 + 2*2 + 2*3 = 3 + 2 + 4 + 6 = 15
Step 3: Binary Search
Now we search for maximum n where the sum ≤ 10:
Initial range: l = 1, r = 1330
First iteration:
m = (1 + 1330 + 1) / 2 = 666- Calculate sum for
n = 666: This would be enormous, much greater than 10 - Update:
r = 665
After several iterations, we narrow down to:
- When checking
n = 2: Sum =f[1] * 1 * 2 / 2 = 3 * 1 * 1 = 3✓ (≤ 10) - When checking
n = 3: Sum =f[2] * 2 * 3 / 2 = 15 * 2 * 3 / 2 = 45✗ (> 10)
Therefore, the maximum n = 2.
Verification:
For n = 2, the total sum is 3, which is indeed ≤ 10. For n = 3, we would have a 3×3×3 array where the sum would be 45, exceeding our limit. Thus, n = 2 is the correct answer.
Time and Space Complexity
The time complexity consists of two parts:
-
Preprocessing phase: The outer loop runs from
1tomx-1(i.e.,O(mx)iterations). For each iterationi, the inner loop runsitimes, performing a bitwise OR operation and arithmetic operations. This results in1 + 2 + 3 + ... + (mx-1) = (mx-1) * mx / 2operations, giving usO(mx^2)time complexity for preprocessing. -
Binary search phase: The
maxSizedArraymethod performs a binary search between1andmx. Each iteration of the while loop reduces the search space by half, resulting inO(log mx)time complexity.
Therefore, the total time complexity is O(mx^2 + log mx). Since mx = 1330 is a constant, we can also express this as O(n^2 + log n) where n represents the upper bound of the search range.
The space complexity is O(mx) or O(n), as we allocate an array f of size mx to store the precomputed values. No additional space that scales with input is used during the binary search phase.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Using Wrong Binary Search Template Variant
Pitfall: Using while left < right with left = mid for finding the maximum valid n:
# WRONG: Non-standard template for finding maximum while left < right: mid = (left + right + 1) >> 1 # Need ceiling division if cost <= s: left = mid else: right = mid - 1 return left
Solution: Use the standard template by finding the first n where cost exceeds s:
# CORRECT: Standard template first_exceed_index = -1 while left <= right: mid = (left + right) // 2 if cost > s: # Feasible: exceeds limit first_exceed_index = mid right = mid - 1 else: left = mid + 1 return first_exceed_index - 1 if first_exceed_index != -1 else MAX_SIZE - 1
2. Integer Overflow in Cost Calculation
Pitfall: The most critical issue in this solution is potential integer overflow when calculating the cost:
cost = cumulative_or_sum[mid - 1] * (mid - 1) * mid // 2
For large values of mid (approaching 1330), the multiplication cumulative_or_sum[mid - 1] * (mid - 1) * mid can exceed Python's integer limits in other languages or cause performance issues even in Python with very large numbers.
Solution: Rearrange the calculation to perform division earlier or check for overflow:
# Option 1: Divide earlier to reduce intermediate values cost = cumulative_or_sum[mid - 1] * ((mid - 1) * mid // 2) # Option 2: Check if multiplication would exceed s before computing if cumulative_or_sum[mid - 1] > s * 2 // ((mid - 1) * mid): right = mid - 1 continue
3. Incorrect Precomputation Formula
Pitfall: The precomputation loop might be implemented incorrectly:
# Wrong: Missing the factor of 2 for symmetric pairs
for array_size in range(1, MAX_SIZE):
cumulative_or_sum[array_size] = cumulative_or_sum[array_size - 1] + array_size
for element in range(array_size):
cumulative_or_sum[array_size] += (array_size | element) # Missing factor of 2!
This misses that for each unique OR value, we need to count both (j, k) and (k, j) pairs when j ≠ k.
Solution: Ensure the factor of 2 is included for non-diagonal elements:
for array_size in range(1, MAX_SIZE):
cumulative_or_sum[array_size] = cumulative_or_sum[array_size - 1] + array_size
for element in range(array_size):
cumulative_or_sum[array_size] += 2 * (array_size | element) # Correct
4. Hardcoded Maximum Size Without Validation
Pitfall: Using a fixed MAX_SIZE = 1330 without considering the actual input range. If s is extremely large (beyond what 1330 can handle), the solution would return an incorrect answer.
Solution: Dynamically determine the upper bound based on s:
def maxSizedArray(self, s: int) -> int:
# Dynamically calculate upper bound
# Since sum ~ n^5/4, we have n ~ (4*s)^(1/5)
import math
max_possible = min(MAX_SIZE, int((4 * s) ** 0.2) + 10) # Add buffer
left, right = 1, max_possible
# ... rest of binary search
5. Not Handling Edge Cases
Pitfall: Not properly handling small values of s:
- When
s = 0, the answer should be 1 (array of size 1 has sum 0) - When
s < 0, the input is invalid
Solution: Add edge case handling:
def maxSizedArray(self, s: int) -> int:
if s == 0:
return 1
if s < 0:
raise ValueError("s must be non-negative")
# Continue with normal binary search...
Which of the following array represent a max heap?
Recommended Readings
https assets algo monster cover_photos Binary_Search svg Binary Search Intuition Binary search is an efficient array search algorithm It works by narrowing down the search range by half each time If you have looked up a word in a physical dictionary you've already used binary search in real life Let's
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion If you prefer videos here's a video that explains recursion in a fun and easy way Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask him
Want a Structured Path to Master System Design Too? Don’t Miss This!