Se capisco correttamente il problema (e forse no, sentiti libero di dirmi se non lo faccio) vuoi trasformare una griglia 2D in un array 1D ordinato, mentre ogni riga e colonna è già ordinata nella griglia 2D?
Il primo elemento nell'elenco in questo caso deve essere l'angolo in alto a sinistra ((0,0), per definizione del problema). Dopodiché deve essere l'elemento (1,0) o (0,1), poiché tutti gli altri saranno più grandi di questi per definizione.
Puoi generalizzare dicendo che il prossimo elemento più piccolo nella griglia è sempre direttamente sotto un elemento già usato (o il bordo della griglia), e anche a destra di un elemento già usato (o il bordo della griglia), poiché entrambi sono definito per essere più piccolo di esso. Quindi ad ogni iterazione devi considerare solo il valore più piccolo che soddisfa questo requisito.
È possibile mantenere i possibili candidati in modo ordinato come li si trova (non più di due saranno mai resi disponibili in una iterazione) e ad ogni iterazione controllare i nuovi valori resi disponibili (se presenti). Se sono inferiori al più basso dei precedenti candidati, aggiungili immediatamente all'elenco e ripeti, altrimenti aggiungi il precedente candidato più basso e confronta con il successivo più basso, ecc.
Sfortunatamente non pretendo di essere in grado di fornire un'esatta complessità di questo, né pretendo che sia il più efficiente possibile, sembra certamente migliore di un approccio ingenuo e spero di averlo spiegato abbastanza bene da capirlo.
EDIT: per nd griglie come questa credo che si applichi lo stesso principio di base, ma ogni iterazione rende disponibili fino a n nuovi candidati e questi candidati devono essere gli elementi inutilizzati più piccoli in ciascuna delle n dimensioni a questo punto.