Hirschberg's algorithm returns a longest common subsequence full
This proof shows: correctness.
We use the pseudocode of the page. Write lcs(U,V) for the length of a longest common subsequence of U and V, UR for the reverse of U, X[a…b]=xa⋯xb and Y[a…b]=ya⋯yb, both empty if a>b.
Lemma 1 (LCS-ROW). LCS-ROW(X,Y) returns R with R[j]=lcs(X,Y[1…j]) for 0≤j≤n.
Proof. Let L(i,j)=lcs(X[1…i],Y[1…j]). We show by induction on i that after i rounds of the loop of line L9, R[j]=L(i,j) for all j. For i=0, line L8 sets R[j]=0=L(0,j).
Let i≥1 and assume R[j]=L(i−1,j) for all j before round i. Inside the round we show by induction on j that, before the iteration j of line L11, R[0…j−1] holds L(i,0),…,L(i,j−1), R[j…n] holds L(i−1,j),…,L(i−1,n), and diag=L(i−1,j−1). Before j=1 this holds: R[0]=0=L(i,0) is never written, the rest of R is the old row, and line L10 sets diag=0=L(i−1,0). In iteration j, line L12 sets up=L(i−1,j), and line L13 writes L(i−1,j−1)+1 if xi=yj, and max(L(i−1,j),L(i,j−1)) if not. By the LCS recurrence (the corollary of the optimal substructure theorem) this is L(i,j). Line L14 sets diag=L(i−1,j), which is the value needed for j+1. After j=n the whole row holds L(i,⋅). □
Lemma 2 (reversal). Z is a common subsequence of U and V if and only if ZR is a common subsequence of UR and VR. So lcs(U,V)=lcs(UR,VR).
Proof. If Z=ui1⋯uik with i1<⋯<ik, then ZR is the subsequence of UR at the positions ∣U∣+1−ik<⋯<∣U∣+1−i1. The same holds for V, and the converse is the same statement applied to ZR. □
By Lemmas 1 and 2, after lines L4 and L5 of a call with m≥2,
F[j]=lcs(X[1…h],Y[1…j]),B[n−j]=lcs(X[h+1…m]R,Y[j+1…n]R)=lcs(X[h+1…m],Y[j+1…n]), since the first n−j items of YR are Y[j+1…n]R.
Lemma 3 (split). For each 0≤h≤m,
lcs(X,Y)=0≤j≤nmax(lcs(X[1…h],Y[1…j])+lcs(X[h+1…m],Y[j+1…n])). Proof. (≥) Fix j. Let Z1 be an LCS of X[1…h] and Y[1…j] and Z2 an LCS of X[h+1…m] and Y[j+1…n]. The positions of Z1 in X are at most h and those of Z2 are above h, and the same holds in Y with j. So Z1Z2 is a common subsequence of X and Y, of length ∣Z1∣+∣Z2∣.
(≤) Let Z be an LCS of X and Y, of length ℓ, with positions i1<⋯<iℓ in X and j1<⋯<jℓ in Y, where xit=yjt=zt. Let s be the number of t with it≤h, so i1,…,is≤h<is+1,…,iℓ. Let j=js if s≥1 and j=0 if s=0. Then z1⋯zs is a common subsequence of X[1…h] and Y[1…j], and zs+1⋯zℓ is a common subsequence of X[h+1…m] and Y[j+1…n], since js+1>js=j. So ℓ=s+(ℓ−s) is at most the term of the maximum for this j. □
Theorem. For all X and Y, HIRSCHBERG(X,Y) returns a common subsequence of X and Y of length lcs(X,Y).
Proof. Induction on m.
Base. If m=0 or n=0, the only common subsequence is empty, and line L1 returns it. If m=1 and n≥1, lcs(X,Y) is 1 if x1 occurs in Y and 0 otherwise, and line L2 returns ⟨x1⟩ or the empty sequence, which are common subsequences of these lengths.
Step. Let m≥2, so 1≤h=⌊m/2⌋<m and both halves of X are shorter than X. By Lemmas 1 to 3, line L6 picks k with
F[k]+B[n−k]=jmax(F[j]+B[n−j])=lcs(X,Y). By the induction hypothesis, the first call of line L7 returns a common subsequence Z1 of X[1…h] and Y[1…k] of length F[k], and the second returns a common subsequence Z2 of X[h+1…m] and Y[k+1…n] of length B[n−k]. As in the (≥) part of Lemma 3, Z1Z2 is a common subsequence of X and Y. Its length is F[k]+B[n−k]=lcs(X,Y). □
Termination. Each recursive call has a shorter first sequence (h<m and m−h<m for m≥2), so the recursion ends.
Cost. Let C(m,n) be the number of cells that LCS-ROW fills in a call on lengths m and n, and let c(1)=0 and c(m)=m+c(⌈m/2⌉) for m≥2. Then c is non-decreasing and C(m,n)≤c(m)n. For m≤1, C=0. For m≥2, the call fills hn+(m−h)n=mn cells and
C(m,n)≤mn+c(h)k+c(m−h)(n−k)≤mn+c(⌈m/2⌉)n=c(m)n, because h,m−h≤⌈m/2⌉. Unrolling, c(m)≤m+⌈m/2⌉+⌈m/4⌉+⋯, and since ⌈m/2t⌉<m/2t+1 and the sum has at most ⌈log2m⌉ terms, c(m)<2m+⌈log2m⌉. So the algorithm fills fewer than (2m+⌈log2m⌉)n cells, and at least the mn cells of the top call. ■