You have n boxes. You are given a binary string boxes of length n, where boxes[i] is '0' if the ith box is empty, and '1' if it contains one ball.
In one operation, you can move one ball from a box to an adjacent box. Box i is adjacent to box j if abs(i - j) == 1. Note that after doing so, there may be more than one ball in some boxes.
Return an array answer of size n, where answer[i] is the minimum number of operations needed to move all the balls to the ith box.
Each answer[i] is calculated considering the initial state of the boxes.
Example 1:
Input: boxes = "110"
Output: [1,1,3]
Explanation: The answer for each box is as follows:
1) First box: you will have to move one ball from the second box to the first box in one operation.
2) Second box: you will have to move one ball from the first box to the second box in one operation.
3) Third box: you will have to move one ball from the first box to the third box in two operations, and move one ball from the second box to the third box in one operation.
Example 2:
Input: boxes = "001011"
Output: [11,8,5,4,3,4]
Constraints:
n == boxes.length
1 <= n <= 2000
boxes[i] is either '0' or '1'.
Solutions
Solution 1: Prefix Sums
Thinking
The cost of gathering every ball at box \(i\) is the sum of index distances. \(n\le 2000\) allows a double loop, but a linear recurrence exists.
The left (right) cost follows from the neighbour: one more ball on that side increases the cost by the ball count. Precompute \(left[i]\) and \(right[i]\) and add them.
Precompute \(\textit{left}[i]\) as the cost of moving all balls on the left of \(i\) to position \(i\), and \(\textit{right}[i]\) as the cost of moving all balls on the right of \(i\) to position \(i\). The answer at \(i\) is \(\textit{left}[i] + \textit{right}[i]\).
The time complexity is \(O(n)\) and the space complexity is \(O(n)\), where \(n\) is the length of \(\textit{boxes}\).
/** * Note: The returned array must be malloced, assume caller calls free(). */int*minOperations(char*boxes,int*returnSize){intn=strlen(boxes);int*left=malloc(sizeof(int)*n);int*right=malloc(sizeof(int)*n);memset(left,0,sizeof(int)*n);memset(right,0,sizeof(int)*n);for(inti=1,count=0;i<n;i++){if(boxes[i-1]=='1'){count++;}left[i]=left[i-1]+count;}for(inti=n-2,count=0;i>=0;i--){if(boxes[i+1]=='1'){count++;}right[i]=right[i+1]+count;}int*ans=malloc(sizeof(int)*n);for(inti=0;i<n;i++){ans[i]=left[i]+right[i];}free(left);free(right);*returnSize=n;returnans;}
Solution 2: Prefix Sums (Space Optimization)
Thinking
The two arrays in Solution 1 depend only on the previous cell. Accumulate the same recurrences into \(ans\) left-to-right and right-to-left, using constant extra space.
\(\textit{left}[i]\) and \(\textit{right}[i]\) in Solution 1 depend only on the previous position, so we can drop those arrays and accumulate into \(\textit{ans}\) with one left-to-right pass and one right-to-left pass.
The time complexity is \(O(n)\). Ignoring the answer array, the extra space complexity is \(O(1)\).
/** * Note: The returned array must be malloced, assume caller calls free(). */int*minOperations(char*boxes,int*returnSize){intn=strlen(boxes);int*ans=malloc(sizeof(int)*n);memset(ans,0,sizeof(int)*n);for(inti=1,count=0;i<n;i++){if(boxes[i-1]=='1'){count++;}ans[i]=ans[i-1]+count;}for(inti=n-2,count=0,sum=0;i>=0;i--){if(boxes[i+1]=='1'){count++;}sum+=count;ans[i]+=sum;}*returnSize=n;returnans;}
Solution 3: Enumeration
Thinking
A direct implementation stores every ball index and, for each box, sums \(|i-j|\). It passes for this \(n\), at a worse constant than the prefix recurrences.
Collect every ball position, then for each box \(i\) add \(|i - j|\) for every ball \(j\).
The time complexity is \(O(n \times m)\) and the space complexity is \(O(m)\), where \(n\) is the length of \(\textit{boxes}\) and \(m\) is the number of balls.