$pileTops = array(); // sort into piles foreach ($n as $x) { // binary search $low = 0; $high = count($pileTops) - 1; while ($low <= $high) { $mid = (int) (($low + $high) / 2); if ($pileTops[$mid]->val >= $x) { $high = $mid - 1; } else { $low = $mid + 1; } } $i = $low; $node = new Node(); $node->val = $x; if ($i != 0) { $node->back = $pileTops[$i - 1]; } $pileTops[$i] = $node; } $result = array(); for ($node = count($pileTops) ? $pileTops[count($pileTops) - 1] : NULL; $node != NULL; $node = $node->back) { $result[] = $node->val; } return array_reverse($result); } print_r(lis(array(3, 2, 6, 4, 5, 1))); print_r(lis(array(0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15)));
$P = [0]; $L = 0; for ($i = 0; $i < $N; $i++) { $j = 0; for ($pos = $L; $pos >= 1; $pos--) { if ($X[$M[$pos]] < $X[$i]) { $j = $pos; break; } } $P[$i] = $M[$j]; if ($j === $L || $X[$i] < $X[$M[$j + 1]]) { $M[$j + 1] = $i; $L = max($L, $j + 1); } } $result = []; $pos = $M[$L]; for ($i = $L - 1; $i >= 0; $i--) { $result[$i] = $X[$pos]; $pos = $P[$pos]; } return $result; } // Test cases var_dump(lis([0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15])); // array -> 0, 2, 6, 9, 11, 15 var_dump(lis([0, 1, 2, 3, 4, 5, 1, 3, 8])); // array -> 0, 1, 2, 3, 4, 5, 8 var_dump(lis([0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 3, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 3])); // array -> 0, 1, 2, 3