Piccola correzione. Creava un livello più del necessario.

Codice PHP:
$mio_array = array(2,3,4,5,7,9,10,12,14,15,16,17,20,21,24,28,29,30,31);

function 
serie($array) {
    
$range range(    min($array) , max($array) );
    
$interv = array();
    
$i 0;
    foreach(
$range as $valore) {
        if (
in_array($valore,$array)) 
            
$interv[$i][] = $valore;
        else
        
$i++;
    }

    
$finale = array();
    
$k 0;
    foreach(
$interv as $elm) {
        if (
count($elm) < 3) {
            foreach(
$elm as $v)
                
$finale[$k][] = $v;
        }
        else {
            
$finale[$k][] = min($elm);
            
$finale[$k][] = max($elm);
        }
    
$k++;
    }
return 
$finale;
}

echo 
'<pre>';
print_r(serie($mio_array));