This is a learning note related to the prefix sum (cumulative sum) and difference array algorithm. It contains the basic ideas of them and some practice examples.
Prefix Sum
The prefix sum refers to the sum of all array elements (including itself) before a subscript of an array. The prefix sum is divided into one-dimensional prefix sum and two-dimensional prefix sum. Prefix sum is an important preprocessing, which can reduce the time complexity of the algorithm.
Practice
- New a array
preSumwherepreSum [I]records the cumulative sum ofnums[0 .. i-1]or other kind of sum - Use the
preSumto reach the answer.
-
303 Range Sum Query - Immutable
-
Question: Given an integer array
nums, handle multiple queries of the following type:- Calculate the sum of the elements of
numsbetween indicesleftandrightinclusive whereleft <= right.
Implement the
NumArrayclass:NumArray(int[] nums)Initializes the object with the integer arraynums.int sumRange(int left, int right)Returns the sum of the elements ofnumsbetween indicesleftandrightinclusive (i.e.nums[left] + nums[left + 1] + ... + nums[right]).
- Calculate the sum of the elements of
-
Solution: As basic idea suggested, we need a
preSumlist to help to compute the cumulative sum. -
Code:
```java class NumArray { // prefix sum list private int[] preSum; // construct prefix sum list public NumArray(int[] nums) { // preSum[0] = 0 preSum = new int[nums.length+1]; for(int i = 1; i < preSum.length; i++){ preSum[i] = preSum[i-1] + nums[i-1]; } } // compute the cumulative sum between [left, right] public int sumRange(int left, int right) { return preSum[right+1] - preSum[left]; } }
-
-
875 Koko Eating Bananas
-
Questions: Given a 2D matrix
matrix, handle multiple queries of the following type:- Calculate the sum of the elements of
matrixinside the rectangle defined by its upper left corner(row1, col1)and lower right corner(row2, col2).
Implement the
NumMatrixclass:NumMatrix(int[][] matrix)Initializes the object with the integer matrixmatrix.int sumRegion(int row1, int col1, int row2, int col2)Returns the sum of the elements ofmatrixinside the rectangle defined by its upper left corner(row1, col1)and lower right corner(row2, col2).
You must design an algorithm where
sumRegionworks onO(1)time complexity. - Calculate the sum of the elements of
-
Solution: Same as previous one, but we need to extend it to 2D matrix. The sum of the elements of the matrix can be converted into the sum of the elements of the matrix around it.
-
Code:
class Solution { public int minEatingSpeed(int[] piles, int h) { // left and right boundary, left closed right open // left boundary means the minimum amount Koko can eat // right boundary is one more than the amount of bananas that may in a pile int left = 1; int right = 1000000000+1; while(left < right){ int mid = left + (right - left) / 2; if(f(piles, mid) <= h) right = mid; else left = mid + 1; } return left; } // auxiliary function // where x is k, f(x) is the number of hours, target is h public int f(int[] piles, int k){ int h = 0; for(int i = 0; i < piles.length; i++){ // compute how long it will take Koko to finish eating thi pile // be careful, if Koko eats all bananas in a pile, // she will not eat any more bananas during this hour h += piles[i] / k; if(piles[i] % k != 0) h++; } return h; } }
-
Difference Array
The prefix sum mainly applicates in such scenario that the cumulative sum of a certain interval is frequently queried when the original array is not modified. While the main application scenario of difference array is to frequently increase or decrease the elements of a certain interval of the original array.
Practice
- New a array
diffwherediff [I]records the difference betweennum[i]andnum[i-1] - Use the
diffto reach the answer.
-
1094 Car Pooling
-
Question: There is a car with
capacityempty seats. The vehicle only drives east (i.e., it cannot turn around and drive west).You are given the integer
capacityand an arraytripswheretrips[i] = [numPassengersi, fromi, toi]indicates that theithtrip hasnumPassengersipassengers and the locations to pick them up and drop them off arefromiandtoirespectively. The locations are given as the number of kilometers due east from the car’s initial location.Return
trueif it is possible to pick up and drop off all passengers for all the given trips, orfalseotherwise. -
Solution: Assume we have an array
numswhich records the number of passengers for each stop. Then thetripsindicates the elements innumsis frequently increased or decreased, so we can use difference array to solve this problem. Usediffrecord the difference of the number of passengers for each stop. -
Code:
class Solution { public boolean carPooling(int[][] trips, int capacity) { // define the difference array int[] diff = new int[1001]; for(int i = 0; i<trips.length; i++){ int[] trip = trips[i]; int n = trip[0]; int start = trip[1]; int end = trip[2]; diff[start] += n; if(end < diff.length) diff[end] -= n; } // build the ressult list by difference array int[] res = new int[1001]; for(int j = 0; j < res.length; j++){ if(j==0) res[0]=diff[0]; else res[j] = res[j-1] + diff[j]; if(res[j]>capacity) return false; } return true; } }
-
-
1109 Corporate Flight Bookings
-
Question: There are
nflights that are labeled from1ton.You are given an array of flight bookings
bookings, wherebookings[i] = [firsti, lasti, seatsi]represents a booking for flightsfirstithroughlasti(inclusive) withseatsiseats reserved for each flight in the range.Return an array
answerof lengthn, whereanswer[i]is the total number of seats reserved for flighti. -
Solution: Same as previous one but return the result list.
-
Code:
class Solution { public int[] corpFlightBookings(int[][] bookings, int n) { int[] diff = new int[n+1]; for(int[] booking : bookings){ int start = booking[0]; int end = booking[1]; int seat = booking[2]; diff[start] += seat; if(end+1<diff.length) diff[end+1] -= seat; } int[] answer = new int[n]; for(int i = 0; i<answer.length; i++){ if(i==0) answer[i] = diff[1]; else answer[i] = answer[i-1] + diff[i+1]; } return answer; } }
-