its doing multiple nested for loop. How to reduce to 1?
I've seen this on SO, but only realised the biggest optimisation today.

The first optimization is to not build the $interval_array array in each iteration.  This code starts with the empty array and then in each loop just adds the next number in sequence to this array.

for ($i=0; $i &lt;$n; $i++) {
    // Reset array in outer loop
    $interval_array = array();
    for($j = $i;$j &lt; $n; $j++){
        // Add in new number to interval array as the key
        $interval_array[$main_array[$j]] = 0;


So the first time round it will add be [1], then on the second loop it add the next number in and will be [1,2] etc. (although they are actually [1=&gt;0], [1=&gt;0, 2=&gt;0] the principle is the same)

The main difference is note that it adds the number as the key of the array and not the value.  This allows the main optimization which is when you are checking if you want to exclude particular combinations in...

        if(in_array($abc[$l], $interval_array) &amp;&amp; 
         in_array($xyz[$l], $interval_array)){ 


it will look through (up to) the entire array twice to check for the values.

If instead you had the values as the key, you could use isset()...

            if(isset($interval_array[$abc[$l]]) &amp;&amp;
                isset($interval_array[$xyz[$l]]))   {


This is much more efficient at just checking a value exists.

The last thing I've added is that I create an array with all of the numbers you are checking against in (use array_flip() to again make these numbers the keys)...

$interest = array_flip(array_merge($abc, $xyz));


This allows me to check if the number is even something I'm interested in before running the more detailed checks...

    if ( isset($interest[$main_array[$j]] )) {


Put all of this together...

$n = 1299;
$start = microtime(true);
$main_array = range(1,$n);
$counter = 0;
$abc = [2,1];
$xyz = [3,4];
$count = sizeof($abc);  // $abc and $xyz size will same always.

// Create a combined array which lists all the numbers interested in
$interest = array_flip(array_merge($abc, $xyz));
for ($i=0; $i &lt;$n; $i++) {
    // Reset array in outer loop
    $interval_array = array();
    for($j = $i;$j &lt; $n; $j++){
        // Add in new number to interval array as the key
        $interval_array[$main_array[$j]] = 0;
        $counter++;
        // Only check for exclusion if interested in the number
        if ( isset($interest[$main_array[$j]] )) {
            for ($l=0; $l &lt; $count ; $l++) {
                // if block here to additional condition using isset()
                if(isset($interval_array[$abc[$l]]) &amp;&amp;
                    isset($interval_array[$xyz[$l]]))   {
                        $counter--;
                        // Exit 2 levels of array as all further combinations will be excluded
                        break 2;
                }
            }
        }
    }
}

echo $counter."=".(microtime(true)-$start);


On my laptop (i7-3632QM, 8GB) the results of running this for 1299 are

original code...

841756=206.25858306885


modified code...

841756=0.34013700485229