数据结构的时间复杂度问题

for(i=1;i<=n;i++)
    for(j=1;j<=i;j++)
        for(k=1;k<=j;k++)
            x++;

请问这个代码的时间复杂度n^3是如何计算的

i执行次数是n
j<i,那么其实就是个三角形,执行次数n^2/2
k<j,那么就是个三棱锥,执行次数n^3/6
这里的1/6是系数,在问复杂度问题的时候系数和常数项都被忽略,只保留n的最高次幂
所以就是O(n^3)

这个嵌套循环的代码段可以通过遵循以下步骤来计算其时间复杂度:

  1. 每个循环的迭代次数:

    • 外部循环 for(i=1;i<=n;i++) 执行了 n 次。
    • 第一个内部循环 for(j=1;j<=i;j++) 执行了 i 次,其中 i 的值在每次外部循环迭代中不同,从 1 到 n。
    • 第二个内部循环 for(k=1;k<=j;k++) 执行了 j 次,其中 j 的值在每次第一个内部循环迭代中不同,从 1 到 i。
  2. 计算总迭代次数:

    • 外部循环迭代次数为 n。
    • 第一个内部循环的迭代次数取决于外部循环的迭代次数和内部循环的变量 i,即 1 + 2 + 3 + ... + n = n * (n + 1) / 2。
    • 第二个内部循环的迭代次数取决于第一个内部循环的迭代次数和内部循环的变量 j,即 1 + 2 + 3 + ... + n * (n + 1) / 2 = n * (n + 1) * (n + 2) / 6。
  3. 总的时间复杂度:
    由于每个循环的迭代次数相乘,因此时间复杂度为 n * (n + 1) / 2 * n * (n + 1) * (n + 2) / 6 = O(n^3)。

因此,该代码段的时间复杂度是 O(n^3)。

第一个循环:外层循环使用变量i,从1迭代到n。因此,这个循环的时间复杂度是O(n)。
第二个循环:嵌套在第一个循环内部,使用变量j,从1迭代到i。该循环平均的迭代次数为i/2。但是时间复杂度一般只写次数不写系数,因此,它的时间复杂度可以近似为O(n)。
第三个循环:嵌套在第二个循环内部,使用变量k,从1迭代到j。该循环平均的迭代次数为j/2。就像刚才提到的,因此,时间复杂度一般只写次数不写系数。所以它的时间复杂度可以近似为O(n)。
由于每个循环是相互嵌套的,所以我们将它们的时间复杂度相乘:
总体时间复杂度 = n×n×n。

  • 你可以看下这个问题的回答https://ask.csdn.net/questions/7784296
  • 你也可以参考下这篇文章:通过一趟遍历找出长度为n的单链表中值最大的节点.【数据结构】【单链表】
  • 除此之外, 这篇博客: 使数组的左下三角元素中的值乘以n中的 3 代码 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • # include <stdio.h> 
    # include <stdlib.h>
    # define N 3
    
    /**
    函数:fun(int a[][N], int n)
    功能:使数组的左下三角元素中的值乘以n
    描述:程序定义了 N*N 的二维数组,并在主函数中自动赋值。
    举例:
    若 n 的值为3,a数组中的值为 
    1  9  7
    3  9  7
    2  3  8
    则返回主程序后 a 数组中的值应该为
    3  9  7
    9  27 7
    6  9  24
    */
     
    void fun(int a[][N], int n) {
    	for (int i = 0; i < N; ++i) {
    		for (int j = 0; j <= i; ++j) {
    			a[i][j] = a[i][j] * n;
    		}
    	}
    }
    
    int main(int argc, char const *argv[]) { 
    	int a[N][N] = {{1,9,7}, {3,9,7}, {2,3,8}};
    	int n = 3; 
    
    	printf("原数组为:\n");
    	for (int i = 0; i < N; ++i) {
    		for (int j = 0; j < N; ++j) {
    			printf("%d\t", a[i][j]);
    		}
    		printf("\n");
    	}
    
    	fun(a, n);
    	printf("计算后数组:\n");
    	for (int i = 0; i < N; ++i) {
    		for (int j = 0; j < N; ++j) {
    			printf("%d\t", a[i][j]);
    		}
    		printf("\n");
    	}
    }
    

    示例结果:

    $ gcc ex008.c -o demo
    $ ./demo
    原数组为:
    1	9	7
    3	9	7
    2	3	8
    计算后数组:
    3	9	7
    9	27	7
    6	9	24
    
  • 以下回答由chatgpt基于相关博客总结生成:

    首先,时间复杂度(n^3)表示代码的运行时间与输入规模n的立方成正比。为了计算代码的时间复杂度,我们可以按照以下步骤进行:

    1. 确定代码的主要操作:首先,我们需要确定代码中执行次数最多的操作。在给定的代码片段中,可以看到最嵌套的循环是两层循环,其中第一层循环从0到n-1,第二层循环从i到n-1。因此,这两个循环是执行次数最多的操作。

    2. 计算每个操作的执行次数:根据代码中的循环结构,我们可以确定这两个循环的执行次数。第一个循环的执行次数是n-1,第二个循环的执行次数是(n-1)-i。为了计算所有操作的执行次数,我们需要计算第二个循环的执行次数的总和。

    3. 计算时间复杂度:根据第二步的计算结果,我们可以得到代码的执行次数。由于时间复杂度表示代码运行时间与输入规模n的关系,因此我们需要将上述结果表示为关于n的函数。在这种情况下,第二步计算的结果是两个循环执行次数的总和,即∑(n-1)-i。根据公式的推导,这个总和可以表示为(n-1)+(n-2)+...+2+1,即等差数列的求和。根据等差数列求和公式,这个总和可以简化为(n-1)*n/2。因此,代码的时间复杂度为O(n^2)。

    由于给出的参考代码片段是一个最大子数组问题的解决方法,它的时间复杂度实际上是O(n^2),而不是n^3。因此,以上的解释和计算步骤仅适用于时间复杂度为O(n^2)的代码。如果确实需要计算时间复杂度为n^3的代码,请提供该代码片段以便进一步分析和计算。