mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
538 words
3 minutes
Algorithm Study: Prefix Sum, Difference Array, and Two Pointers
2022-07-16

1. Prefix Sum#

1.1 Algorithm Principle#

The prefix sum is defined as recording the sum of all data to the left; when intermediate data is needed, it can be obtained in O(1) time.

  • One-dimensional prefix sum

The sum of all terms from 1 to i.

Since when processing the i-th position, the first i-1 positions have already been computed, thus a[i] = a[i] + a[i-1].

  1. When the sum of [l,r] is needed, it can be obtained by a[r]-a[l-1]
  • Two-dimensional prefix sum

Find the sum of data within the rectangle whose top-left corner is (1,1) and bottom-right corner is (i,j)

When processing (i,j), the first i-1 rows and the first j-1 elements in row i have been computed, so a[i][j] = a[i][j] + a[i-1][j] + a[i][j-1] - a[i-1][j-1].

  1. When the sum of data inside the rectangle with top-left corner (x1,y1) and bottom-right corner (x2,y2) is needed, it is a[x2][y2]-a[x2][y1-1]-a[x1-1][y2]+a[x1-1][y1-1]

1.2 Examples#

Reference code:

void solve(){
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i],a[i]+=a[i-1];
while(m--){
cin>>l>>r;
cout<<a[r]-a[l-1]<<endl;
}
}

Reference code:

void solve(){
cin>>n>>m>>q;
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)
cin>>a[i][j],a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1];
while(q--){
cin>>x1>>y1>>x2>>y2;
cout<<a[x2][y2]-a[x2][y1-1]-a[x1-1][y2]+a[x1-1][y1-1]<<endl;
}
}

2. Difference#

2.1 Algorithm Principle#

The so-called difference array records the difference between each value and the previous value; when needing to operate on a range, the operation can be completed in O(1) time.

At the same time, we can see that the prefix sum of the difference array is the original array.

  • One-dimensional difference

Compute the difference from the previous term. When needing to add or subtract to numbers in the range [l,r], it can be achieved by b[l]+=c and b[r+1]-=c

  • Two-dimensional difference

The construction of the two-dimensional difference array can be reasoned backwards from its prefix sum.

When all data inside the rectangle defined by (x1,y1) and (x2,y2) is increased by c, i.e., a[x1,y1]~a[x2,y2] are all increased by c. Therefore by doing b[x1,y1]+=c, b[x1,y2+1]-=c, b[x2+1,y1]-=c, b[x2+1,y2+1]+=c, we can achieve adding c only to the region.

20201217171134926.png

When constructing the difference array, one can see that it is adding a rectangle of width and height 1 with a[i,j], thus realizing a two-dimensional difference array.

2.2 Examples#

Reference code:

void solve(){
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) b[i] = a[i]-a[i-1];
while(m--){
cin>>l>>r>>c;
b[l]+=c;b[r+1]-=c;
}for(int i=1,t=0;i<=n;i++) t+=b[i],cout<<t<<' ';
}

Reference code:

void add(){
b[x1][y1] += c;b[x1][y2+1] -=c;
b[x2+1][y1] -= c;b[x2+1][y2+1] +=c;
}
void solve(){
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)
cin>>a[i][j],x1=x2=i,y1=y2=j,c=a[i][j],add();
while(q--){
cin>>x1>>y1>>x2>>y2>>c;
add();
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
a[i][j] = b[i][j] + a[i-1][j]+a[i][j-1]-a[i-1][j-1];
cout<<a[i][j]<<' ';
}cout<<endl;
}
}

3. Two Pointers#

3.1 Algorithm Principle#

Two-pointer problems are mainly based on the properties of the sequence, using pointer j to record the valid query range, thereby reducing the time complexity of computations.

Two-pointer problems are mainly divided into the following two categories:

  1. In a single sequence, two pointers maintain a segment.
  2. In two sequences, maintain some order

Basic template (from AcWing)

void solve(){
for(int i=0,j=0;i<n;i++){
while(j<i && check(i,j)) j++;
// Specific problem logic
}
}

3.2 Examples#

Solution idea: set a cnt array to record the occurrence count of data in the [j,i] interval; when i points to a[i] that has already appeared, move j forward until the count of a[i] in [j,i-1] becomes 0. Track the length along the way.

Reference code:

void solve(){
for(int i=1,j=1;i<=n;i++){
if(cnt[a[i]]){
while(cnt[a[i]]) cnt[a[j++]]--;
}
cnt[a[i]]++;
ans = max(i-j+1,ans);
}cout<<ans<<endl;
}

Solution idea: Since the sequence is sorted in ascending order, you can stop when a[i]+a[j]>x; then a[i+1]+a[j] will also be greater than x. Therefore you can use j to record the boundary that needs to be checked, reducing search time.

Reference code:

void solve(){
for(int i=0,j=m-1;i<n,j>0;i++){
while(a[i]+b[j]>x) j--;
if(a[i]+b[j]==x){
cout<<i<<' '<<j<<endl;
return 0;
}
}
}

Solution idea: Since the substring appears in the source string in order, we can locate each character of the substring in the source string sequentially.

Reference code:

void solve(){
for(int i=0,j=0;i<n && j<m;i++,j++){
while(a[i] != b[j] && j<m) j++;
if(i==n-1 && j < m) {cout<<"Yes"<<endl;return 0;}
}cout<<"No"<<endl;
}
Share

If this article helped you, please share it with others!

Algorithm Study: Prefix Sum, Difference Array, and Two Pointers
https://dreaife.tokyo/en/posts/prefix-sum-difference/
Author
dreaife
Published at
2022-07-16
License
CC BY-NC-SA 4.0

Some information may be outdated

Related Posts Smart
1
Algorithm Study: Bitwise Operations, Discretization, and Interval Merging
algorithm This article introduces algorithms for bitwise operations, discretization, and interval merging. Bitwise operations are used to process binary numbers, discretization is used to optimize storage and queries for sparse data, and interval merging uses sorting and overlap checks to efficiently merge multiple intervals. Related examples and reference code are provided to help understand their applications.
2
Sorting and Binary Search Study Notes
algorithm This article introduces the principles and implementations of quicksort and merge sort, including time complexity and related problems. Quicksort partitions the sequence into two parts around a midpoint, while merge sort merges sorted subarrays. It also discusses binary search algorithms for integers and floating-point numbers and their implementations.
3
High-Precision Arithmetic Study Notes
algorithm High-precision arithmetic includes addition, subtraction, multiplication, and division for large numbers that exceed the range of ordinary data types. Addition and subtraction are implemented by simulating manual calculation, while multiplication and division process digits step by step and pay attention to removing leading zeros. Related examples and reference code are provided to help understand and implement these operations.
4
Interview Algorithm Study 1
algorithm This post contains multiple algorithm interview problems and solutions, including snake matrix filling, quicksort on a singly linked list, finding peaks and local minima, the egg hardness problem, a stack supporting minimum retrieval, and finding the entry node of a cycle in a linked list. Each problem includes a detailed description, input/output format, and sample code.
5
The First Round of Selection in the New Era
life With the development of AI technology, the cost of using advanced models may lead to social stratification, where only those with strong financial means can use these models. Although current prices are still acceptable, future price increases may make them unaffordable for most people, thus forming the first round of selection. The author feels anxious about this phenomenon, while also realizing that AI applications have moved beyond programming and into broader industries. Facing the challenges and opportunities of a new world, individuals continue to explore under the momentum of the times.

Table of Contents