Algorithm Search⌘K

Proofs: Prefix sum hash counting

These are the human proofs of Prefix sum hash counting, at full length.

Prefix sum hash counting counts the subarrays with sum k full

This proof shows: correctness.

We use the pseudocode of the page on A[0..n−1]A[0..n-1] and a target kk. Let P0=0P_0 = 0 and Pm=A[0]+⋯+A[m−1]P_m = A[0] + \dots + A[m-1] for 1≤m≤n1 \le m \le n, so that the subarray A[i..j]A[i..j] has sum Pj+1−PiP_{j+1} - P_i. Treat the hash table CC as a map from values to counts, where an absent key has count 00. For 0≤j≤n0 \le j \le n let NjN_j be the number of pairs (i,l)(i, l) with 0≤i≤l<j0 \le i \le l < j and Pl+1−Pi=kP_{l+1} - P_i = k.

Claim. At the start of step jj (and, for j=nj = n, when the loop ends):

  1. p=Pjp = P_j;
  2. for every value vv, C[v]=#{m:0≤m≤j, Pm=v}C[v] = \#\{m : 0 \le m \le j,\ P_m = v\};
  3. count=Njcount = N_j.

Proof. By induction on jj.

Base, j=0j = 0. Line L1 sets p=0=P0p = 0 = P_0, C[0]=1C[0] = 1 and every other count to 00, which matches the one value P0=0P_0 = 0, and count=0=N0count = 0 = N_0, because there is no pair with l<0l < 0.

Step. Assume the claim at the start of step j<nj < n. Line L3 sets p=Pj+A[j]=Pj+1p = P_j + A[j] = P_{j+1}. The pairs counted by Nj+1N_{j+1} but not by NjN_j are those with l=jl = j, that is, the starts ii with 0≤i≤j0 \le i \le j and Pi=Pj+1−kP_i = P_{j+1} - k. By part 2, line L4 adds exactly their number, C[Pj+1−k]C[P_{j+1} - k], so count=Nj+1count = N_{j+1}. Line L5 then adds one to C[Pj+1]C[P_{j+1}], so part 2 holds with j+1j + 1 in place of jj. ■\blacksquare

Theorem. COUNT-SUM-K returns the number of subarrays of AA with sum kk.

Proof. By the claim with j=nj = n, line L6 returns NnN_n, the number of pairs 0≤i≤l≤n−10 \le i \le l \le n - 1 with A[i]+⋯+A[l]=kA[i] + \dots + A[l] = k. The loop runs nn times with one lookup and one update of CC, so the algorithm stops. ■\blacksquare

Remark (order of lines L4 and L5). If line L5 came before line L4, part 2 would include m=j+1m = j + 1 at the lookup, and for k=0k = 0 line L4 would also count the pair i=j+1i = j + 1, which is the empty subarray A[j+1..j]A[j+1..j]. So the order of the two lines is needed for k=0k = 0, and does no harm for k≠0k \ne 0.

Back to Prefix sum hash counting