在嵌套嵌套的PHP中将O(n4)复杂度优化为O(n)

时间:2019-11-25 10:21:57

标签: php for-loop time-complexity

我正在编写一种逻辑,以便首先对数字进行迭代,然后再进行其他逻辑,以将数字放入数组的特定子集中。

此代码的作用:

  1. 代码接受第一个$ n
  2. 它创建从1到$ n的$ n个数字的数组
  3. 然后开始将$ main_array的子​​集转换为可能的 ['1'] [1,2] [1,2,3] [2] [2,3] [3]等。same like this
  4. 创建子集后,我要计算那些满足条件的子集
  5. 条件是xyz [0]不应与abc [0]一起出现在子集中,反之亦然xyz [i]不应与abc [i]一起出现在子集中。示例2和3是子集,然后不计算该子集,相同的1和4子集,然后不计算

这是我嵌套的for循环:

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

for ($i=0; $i <$n; $i++) {  
         for($j = $i;$j < $n; $j++){  
            $interval_array = array();
          for ($k = $i; $k <= $j; $k++){
                array_push($interval_array,$main_array[$k]);
          }
           $counter++;
           for ($l=0; $l < $count ; $l++) {
                //if block here to additional condition using in_array() php function. which do $counter--
                if(in_array($abc[$l], $interval_array) && 
                 in_array($xyz[$l], $interval_array)){ 
                     $counter--;
                     break;
                 } 
             } 
         }
    }

$main_array我必须在收到$n值后立即创建。

以下是情况:

  1. 运行$n = 4只需4秒
  2. 在运行$n = 1200 or 1299 or more than 1000时在60s-123s中运行

预期执行时间为9s。通过删除在for循环内调用的函数,我将其从124s减少到65s,但并没有指出。

代码的期望是,如果我有像

这样的数组
$array = [1,2,3];

然后

子集需要生成:

[1],[1,2],[1,2,3],[2],[2,3],[3]

对此有任何帮助吗?

2 个答案:

答案 0 :(得分:1)

很难根据您的经验来测试性能,但是此解决方案消除了其中一个循环。

不需要重复构建$interval_array的方式,此代码的作用是仅在每个$j循环中从主数组添加新值。然后,仅在外部循环中重置此数组,因此它仅保留最后一个值,并且每次都添加1个额外的值...

for ($i=0; $i <$n; $i++) {
    $interval_array = array();
    for($j = $i;$j < $n; $j++){
        array_push($interval_array,$main_array[$j]);
        // Check output
        echo implode(",", $interval_array)."\n";

        $counter++;
        for ($l=0; $l < $count ; $l++) {
            if(in_array($abc[$l], $interval_array) && 
             in_array($xyz[$l], $interval_array)){ 
                 $counter--;
                 break 2;
             } 
        }
    }
}

添加“ \ n”以更好地了解子集流。

答案 1 :(得分:1)

import datetime


N = list(range(1, int(input("N:")) + 1))

affected_list = list(map(int, input("affected_list").split()))

poisoned_list = list(map(int, input("poisoned_list").split()))

start_time = datetime.datetime.now()

exclude_list = list(map(list, list(zip(affected_list, poisoned_list))))

final_list = []

for i in range(0, len(N)):
    for j in range(i + 1, len(N) + 1):
        if N[i:j] not in exclude_list:
            final_list.append(N[i:j])

print(final_list)
end_time = datetime.datetime.now()
print("Total Time: ", (end_time - start_time).seconds)