Strings continued. We reviewed the definitions from last time, then dove in to the algorithm itself.
Step 1 of the Z-algorithm was to explicitly compute Z_2. Then we inductively compute all further Z-values.
To compute Z_k(S) we noticed that if k > r (i.e. we are not currently in a Z-box) we find Z_k by explicit comparisons.
If we were in a Z-box (i.e. k <= r), then we noted that there was a matching position to S(k) at k'=k-l+1. Now two cases: (A) if Z_k' < |BETA| (where BETA was defined as S[k..r]) then we immediately computed Z_k = Z_k' (the arguing for this case was somewhat subtle, but became clear with an example to guide us). Case (B) was when Z_k' >= |BETA| we had to do explicit comparisons again to compute the portion of the Z-box starting at k which continues after r.
Finally we argued that the running time was linear in the size of S.