Algorithm Search⌘K

Proofs: SMAWK algorithm

These are the human proofs of SMAWK algorithm, at full length.

SMAWK reads O(n + m) entries and takes O(n + m) time full

This proof shows: time.worst, space.extra.

We count the entries of AA that SMAWK reads. Each other step is charged to a read or to a row or column, so the time is of the same order.

REDUCE on pp rows and cc columns reads at most 4c4c entries. Each test of line L13 reads two entries. A test that is true pops a column. A column is pushed at most once, so it is popped at most once, and there are at most cc true tests. A test that is false, or a loop that stops because the stack is empty, ends the loop for the current column, which happens at most once per column. So there are at most 2c2c tests and 4c4c reads.

Lines L5 to L9 on pp rows and dd reduced columns read at most d+⌈p/2⌉d + \lceil p/2 \rceil entries. Let k0=0,k1,k2,…k_0 = 0, k_1, k_2, \ldots be the values of kk at the passes for the even positions 0,2,4,…0, 2, 4, \ldots, and let stopt=kt+1stop_t = k_{t+1} be the stop of pass tt, with the last stop at most d−1d - 1. Pass tt reads stopt−kt+1stop_t - k_t + 1 entries. The sum telescopes to at most (d−1)−0+⌈p/2⌉(d - 1) - 0 + \lceil p/2 \rceil.

The recurrence. Let T(p,c)T(p, c) be the largest number of reads of SMAWK on p≥1p \ge 1 rows and c≥1c \ge 1 columns, and T(0,c)=0T(0, c) = 0. After line L2, the call works on d≤min⁡(c,p)d \le \min(c, p) columns, so

T(p,c)≤4c+T(⌊p/2⌋,min⁡(c,p))+min⁡(c,p)+⌈p/2⌉≤4c+2p+T(⌊p/2⌋,p).T(p, c) \le 4c + T(\lfloor p/2 \rfloor, \min(c, p)) + \min(c, p) + \lceil p/2 \rceil \le 4c + 2p + T(\lfloor p/2 \rfloor, p).

Let p0=np_0 = n and pℓ=⌊pℓ−1/2⌋p_\ell = \lfloor p_{\ell - 1}/2 \rfloor, so pℓ≤n/2ℓp_\ell \le n / 2^\ell. At the top level the cost outside the recursion is at most 4m+2n4m + 2n. At level ℓ≥1\ell \ge 1, the call has pℓp_\ell rows and at most pℓ−1p_{\ell - 1} columns, so its cost outside the recursion is at most 4pℓ−1+2pℓ≤4n/2ℓ−1+2n/2ℓ=5n/2ℓ−14p_{\ell - 1} + 2p_\ell \le 4n/2^{\ell - 1} + 2n/2^\ell = 5n / 2^{\ell - 1}. Summing,

T(n,m)≤4m+2n+∑ℓ≥15n2ℓ−1=4m+12n.T(n, m) \le 4m + 2n + \sum_{\ell \ge 1} \frac{5n}{2^{\ell - 1}} = 4m + 12n.

So SMAWK reads O(n+m)O(n + m) entries. The rest of the work is O(1)O(1) per read, plus O(p)O(p) per call to build R′R' in line L3 and O(d)O(d) to find the positions of line L7 (with an array from columns to positions, or by walking DD forward together with kk). These are bounded by the same geometric sum, so the time is O(n+m)O(n + m).

Lower bound. Let n≥1n \ge 1 and m≥2m \ge 2. Fix any matrix whose rows 1,…,n−11, \ldots, n-1 are strictly decreasing from left to right, for example A[i][j]=−jA[i][j] = -j, and let row 0 be arbitrary. For i<i′i < i' and j<j′j < j' with i′≥1i' \ge 1 we have A[i′][j]>A[i′][j′]A[i'][j] > A[i'][j'], so the implication of total monotonicity holds, and the matrix is totally monotone for every choice of row 0. An algorithm that does not read some entry A[0][j]A[0][j] cannot tell row 0 with that entry as its only minimum from the same row with that entry larger than all others, and the two answers differ. So every correct algorithm reads all mm entries of row 0 on some input. It also writes nn answers. The worst-case time is therefore Ω(n+m)\Omega(n + m), and SMAWK is optimal up to a constant factor.

Space. The recursion has depth at most ⌊lg⁡n⌋+1\lfloor \lg n \rfloor + 1. The lists at level ℓ\ell have O(n/2ℓ)O(n / 2^\ell) rows and columns, except the mm columns at the top, so all lists alive at one time have O(n+m)O(n + m) entries, and the map MM has nn entries. ■\blacksquare

SMAWK returns the leftmost minimum of each row full

This proof shows: correctness, termination.

We use the pseudocode of the page. AA is totally monotone: for rows i<i′i < i' and columns j<j′j < j', A[i][j]>A[i][j′]  ⟹  A[i′][j]>A[i′][j′]A[i][j] > A[i][j'] \implies A[i'][j] > A[i'][j']. The contrapositive is: A[i′][j]≤A[i′][j′]  ⟹  A[i][j]≤A[i][j′]A[i'][j] \le A[i'][j'] \implies A[i][j] \le A[i][j']. For a list of rows RR and a list of columns CC, both in increasing order and with CC not empty, let λC(r)\lambda_C(r) be the leftmost column c∈Cc \in C with the least value A[r][c]A[r][c] among the columns of CC.

Fact 1 (monotone minima). If r<r′r < r' are rows, then λC(r)≤λC(r′)\lambda_C(r) \le \lambda_C(r').

Proof. Let j=λC(r)j = \lambda_C(r) and suppose j′=λC(r′)<jj' = \lambda_C(r') < j. Since jj is the leftmost minimum of row rr in CC and j′∈Cj' \in C is to its left, A[r][j′]>A[r][j]A[r][j'] > A[r][j]. Total monotonicity with r<r′r < r' and j′<jj' < j gives A[r′][j′]>A[r′][j]A[r'][j'] > A[r'][j], so j′j' is not a minimum of row r′r' in CC, a contradiction. □\square

Fact 2 (removing losers). Let D⊆CD \subseteq C with λC(r)∈D\lambda_C(r) \in D. Then λD(r)=λC(r)\lambda_D(r) = \lambda_C(r).

Proof. Let j=λC(r)j = \lambda_C(r). Each column of DD is in CC, so A[r][j]≤A[r][c]A[r][j] \le A[r][c] for c∈Dc \in D, and each c∈Dc \in D with c<jc < j has A[r][c]>A[r][j]A[r][c] > A[r][j]. So jj is the leftmost minimum of row rr in DD. □\square

Lemma 3 (REDUCE). Let R=(r0,…,rp−1)R = (r_0, \ldots, r_{p-1}) with p≥1p \ge 1, and let CC be nonempty. REDUCE(A,R,C)(A, R, C) stops and returns a list SS of columns of CC, in increasing order, with 1≤∣S∣≤p1 \le |S| \le p, such that λC(r)∈S\lambda_C(r) \in S for each r∈Rr \in R.

Proof. The stack only receives columns in the order of CC, so it is increasing from bottom to top. Line L14 pushes only when ∣S∣<p|S| < p, so ∣S∣≤p|S| \le p always. Each pass of the loop of line L13 pops one column, and each column is pushed at most once, so the loop stops. After the first column, the stack is never empty at the end of an iteration of line L12: if line L13 empties it, line L14 pushes cc because 0<p0 < p.

Write S=(s0,…,sq−1)S = (s_0, \ldots, s_{q-1}) from the bottom. We show this invariant, which holds after each iteration of line L12:

(I) For each position tt with 1≤t<q1 \le t < q and each u<tu < t, the column sts_t is not λC(ru)\lambda_C(r_u). More exactly, A[ru][st−1]≤A[ru][st]A[r_u][s_{t-1}] \le A[r_u][s_t] and st−1<sts_{t-1} < s_t.

It holds for the empty stack. A pop removes the top and leaves the rest of the stack, with the same positions, so (I) stays true. A push of cc at position qq happens after the loop of line L13 ended. If q=0q = 0, there is nothing to show. If q≥1q \ge 1, the loop ended because A[rq−1][sq−1]≤A[rq−1][c]A[r_{q-1}][s_{q-1}] \le A[r_{q-1}][c]. Since sq−1<cs_{q-1} < c, the contrapositive of total monotonicity gives A[ru][sq−1]≤A[ru][c]A[r_u][s_{q-1}] \le A[r_u][c] for each u≤q−1u \le q - 1. So cc has a column to its left with a value at most as large on each of these rows, and it is not their leftmost minimum. This is (I) for position qq.

Now take a column cc that is not in the final SS. Then either it was popped or it was never pushed. We show that c≠λC(ru)c \ne \lambda_C(r_u) for each uu.

  • Popped. Some later column c′>cc' > c arrived when cc was at position tt, and line L13 found A[rt][c]>A[rt][c′]A[r_t][c] > A[r_t][c']. Total monotonicity gives A[ru][c]>A[ru][c′]A[r_u][c] > A[r_u][c'] for each u≥tu \ge t, so cc is not a minimum of these rows. For u<tu < t, (I) at the time of the pop says that cc is not λC(ru)\lambda_C(r_u).
  • Not pushed. Then the loop of line L13 ended with ∣S∣=p|S| = p and A[rp−1][sp−1]≤A[rp−1][c]A[r_{p-1}][s_{p-1}] \le A[r_{p-1}][c], with sp−1<cs_{p-1} < c. The contrapositive gives A[ru][sp−1]≤A[ru][c]A[r_u][s_{p-1}] \le A[r_u][c] for each u≤p−1u \le p - 1, so cc is not the leftmost minimum of any row.

So every λC(ru)\lambda_C(r_u) stays in SS. □\square

Theorem. For RR nonempty or empty and CC nonempty, SMAWK(A,R,C)(A, R, C) stops and returns MM with M[r]=λC(r)M[r] = \lambda_C(r) for each r∈Rr \in R.

Proof. By induction on ∣R∣|R|. If ∣R∣=0|R| = 0, line L1 returns the empty map, which is correct. Let ∣R∣=p≥1|R| = p \ge 1 and assume the claim for all shorter row lists.

Line L2 replaces CC by $D = $ REDUCE(A,R,C)(A, R, C). By Lemma 3, DD is nonempty and holds λC(r)\lambda_C(r) for each r∈Rr \in R, so by Fact 2, λD(r)=λC(r)\lambda_D(r) = \lambda_C(r). It remains to compute λD\lambda_D.

The list R′R' of line L3 has ⌊p/2⌋<p\lfloor p/2 \rfloor < p rows, so by the hypothesis line L4 stops and gives M[r]=λD(r)M[r] = \lambda_D(r) for r∈R′r \in R'. The submatrix on the rows R′R' and the columns DD is totally monotone, since each of its 2×22 \times 2 submatrices is one of AA.

Lines L5 to L9 treat the rows R[0],R[2],…R[0], R[2], \ldots in order. We claim that before the pass for the even position ii, D[k]=λD(R[i−1])D[k] = \lambda_D(R[i-1]) if i≥2i \ge 2, and k=0k = 0 if i=0i = 0. Line L5 makes this true for i=0i = 0, and line L9 sets kk to the position of M[R[i+1]]=λD(R[i+1])M[R[i+1]] = \lambda_D(R[i+1]), which is the claim for i+2i + 2. In the pass for ii, let j=λD(R[i])j = \lambda_D(R[i]). By Fact 1, λD(R[i−1])≤j\lambda_D(R[i-1]) \le j when i≥2i \ge 2, and j≤λD(R[i+1])j \le \lambda_D(R[i+1]) when i+1<pi + 1 < p. So jj lies in D[k],…,D[stop]D[k], \ldots, D[stop], with stop=∣D∣−1stop = |D| - 1 when i+1=pi + 1 = p. Each column of DD left of D[k]D[k] is not jj, and each column right of D[stop]D[stop] is not jj. Line L8 returns the leftmost column of least value in this range, and since jj is in the range and is the leftmost minimum of the whole row in DD, line L8 returns jj. Line L8 also never reads outside DD, because 0≤k≤stop≤∣D∣−10 \le k \le stop \le |D| - 1, where k≤stopk \le stop follows from Fact 1.

So line L10 returns λD(r)=λC(r)\lambda_D(r) = \lambda_C(r) for every r∈Rr \in R. Each loop runs over a finite list, so the call stops. ■\blacksquare

Back to SMAWK algorithm