04 – 时间复杂度相关的题

一、常见题型

题目1、在数组A[0….n-1]中,查找给定值k的算法

// 题目1 在数组A中查找给定值k的算法
int main()
{
	int A[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int k = 11;
	int i = sizeof(A) / sizeof(A[0]) - 1; //数组最后一个元素下标
	int count = 0; 

	while (i >= 0 && (A[i] != k))
	{
		count++;
		
		printf("i = %d , count = %d\n", i, count);

		i--;
	}
}

以下是代码运行结果

  • A中没有元素与k相等的元素,i– 运行的频度是f(n) = n
04 - 时间复杂度相关的题
  • A中最后一个元素与k相等,i– 运行的频度是f(n) = 0

题目2:计算下列代码的时间复杂度

void fun(int n)
{
	int i = 0;
	int count = 0;
	while (i * i * i <= n)
	{
		i++;
		count++;
		printf("i=%d ", i);
	}
	printf("\ncount=%d ", count);
}
int main()
{
	int n = 10;
	fun(n);
}

时间复杂度计算

  1. 关键操作:在while循环里,i进行自增操作,同时count也进行自增,并且执行printf函数。
  2. 循环终止条件:当i * i * i > n时,循环就会停止。
  3. 循环次数:假设循环执行的次数是k,那么i的值会从 0 开始,逐步增加到k。此时,k要满足k³ > n,而(k-1)³ ≤ n。由此可知,k的大小和 n 的立方根是同一个数量级,即k ≈ ∛n
  4. 时间复杂度:由于循环执行的次数和 n 的立方根成正比,所以该算法的时间复杂度为 O (∛n)。

结论

此算法的时间复杂度是O(n^(1/3))

以下是代码运行结果:

04 - 时间复杂度相关的题

题目3:冒泡排序 – 计算下列代码的最坏时间复杂度

#include <stdio.h>

int main()
{
    int i, j, temp;
    int A[] = {9,8,7,6,5,4,3,2,1,0};
    int count = 0;
    int sz = sizeof(A) / sizeof(A[0]);

    // 标准冒泡排序实现
    for (i = 0; i < sz - 1; i++) {
        for (j = 0; j < sz - i - 1; j++) {
            if (A[j] > A[j + 1]) {
                // 添加元素交换逻辑
                temp = A[j];
                A[j] = A[j + 1];
                A[j + 1] = temp;
                count++;
            }
        }
    }

    printf("count=%d\n", count);
    
    // 打印所有元素
    for (i = 0; i < sz; i++) {
        printf("%d ", A[i]);
    }
    printf("\n");

    return 0;
}

时间复杂度推导

  1. 外层循环次数: 变量 isz-1 递减到 2,共执行 n-2 次(假设 sz = n)。
  2. 内层循环次数: 对于每个 i,内层循环的次数为 i-1 次。具体来说:
    • i = n-1 时,内层循环执行 n-2 次;
    • i = n-2 时,内层循环执行 n-3 次;
    • i = 2 时,内层循环执行 1 次。
  3. 总执行次数: 内层循环的总次数为等差数列求和: 1 + 2 + 3 + … + (n-2) = (n-2)(n-1)/2展开后为 (n² – 3n + 2)/2,忽略低阶项和系数,时间复杂度为 O(n²)

关键结论

  • 无论输入如何,嵌套循环的结构决定了代码的执行次数始终是二次函数,因此最坏、平均和最好时间复杂度均为 O(n²)
  • 排序逻辑缺陷:尽管代码中的赋值操作(A[j] = A[j+1])无法正确排序数组,但时间复杂度仍由循环次数决定,与实际排序效果无关。

补充说明

  • 若要实现正确的冒泡排序,需在交换元素时同时更新 A[j+1](例如使用临时变量),但这不会改变时间复杂度。
  • 打印数组的循环(for (i = 0; i < sz - 1; i++))仅执行 n-1 次,时间复杂度为 O(n),但整体复杂度仍由嵌套循环主导(O (n²))。

题目4:另一种形式的冒泡排序

#include <stdio.h>

int main()
{
    int i, j, temp;
    int A[] = {9,8,7,6,5,4,3,2,1,0};
    int count = 0;
    int sz = sizeof(A) / sizeof(A[0]);

    // 修改:外层循环从 i=sz-1 开始递减到 1
    for (i = sz-1; i > 0; i--) {
        for (j = 0; j < i; j++) {
            if (A[j] > A[j + 1]) {
                temp = A[j];
                A[j] = A[j + 1];
                A[j + 1] = temp;
                count++;
            }
        }
    }

    printf("count=%d\n", count);
    
    // 打印所有元素
    for (i = 0; i < sz; i++) {
        printf("%d ", A[i]);
    }
    printf("\n");

    return 0;
}

1. 外层循环次数

  • 循环条件isz-1(数组末尾索引)递减到 1,共执行 n-1n 为数组长度,sz = n)。
  • 示例:当 n=10 时,i 取值为 9, 8, ..., 1,共循环 9 次。

2. 内层循环次数

  • 对于每个外层循环的 i,内层循环 j0 遍历到 i-1,执行 i
  • 次数规律:
    • i = n-1 时,内层循环执行 n-1 次;
    • i = n-2 时,内层循环执行 n-2 次;
    • ……
    • i = 1 时,内层循环执行 1 次。

3. 总操作次数(数学推导)

  • 内层循环总次数为等差数列求和:
04 - 时间复杂度相关的题
  • 最高阶项,忽略低阶项和系数后,时间复杂度为 O(n²)

4. 关键结论

场景时间复杂度说明
最坏情况O(n²)数组完全逆序(如示例输入),每轮均需完整比较和交换。
平均情况O(n²)随机无序数组,比较和交换次数接近最坏情况的一半。
最好情况O(n²)未优化时,即使数组有序,仍需执行所有比较(优化后可降至 O (n))。

最终结论

该冒泡排序代码的 最坏时间复杂度为 O (n²),由嵌套循环的二次方级操作次数决定。

实战题目

04 - 时间复杂度相关的题
04 - 时间复杂度相关的题
解析
04 - 时间复杂度相关的题

数学解析
04 - 时间复杂度相关的题

题目5:计算下列m++代码执行次数

int main()
{
	int i = 0;
	int j = 0;
	int n = 10;
	int m = 0;

	for (i = 0;i <= n; i++)
	{
		for (j = 1;j <= 2 * i; j++)
		{
			m++;
		}
	}
	printf("m = %d\n", m);
}

以下是n=10计算结果:

04 - 时间复杂度相关的题
04 - 时间复杂度相关的题

题目6:计算下列m++代码执行次数(对比题目5)

int main()
{
	int i = 0;
	int j = 0;
	int n = 10;
	int m = 0;

	for (i = 0;i < n;i++)
	{
		for (j = 1;j < 2 * i;j++)
		{
			m++;
		}
	}
	printf("m = %d\n", m);
}

以下是运行结果:

04 - 时间复杂度相关的题
04 - 时间复杂度相关的题

(重要)总结以上该题型:

04 - 时间复杂度相关的题
04 - 时间复杂度相关的题

题目7:计算递归函数的时间复杂度

// 题目 11:递归函数的时间复杂度
int Func(int n)
{
	if (n == 1)
		return 1;
	else
		return 2 * Func(n / 2) + n;
}

int main()
{
	int i = 4;
	int ret = Func(i);
	printf("%d\n", ret);
	return 0;
}

以下是运行结果:

04 - 时间复杂度相关的题
解析
04 - 时间复杂度相关的题
04 - 时间复杂度相关的题

数学表达

04 - 时间复杂度相关的题

二、408真题

题目1

04 - 时间复杂度相关的题
解析
04 - 时间复杂度相关的题

题目2

04 - 时间复杂度相关的题
解析
04 - 时间复杂度相关的题
04 - 时间复杂度相关的题

关键分析步骤:

  1. 递归调用次数:计算 fact(n) 时,会依次调用 fact(n-1)fact(n-2)、… 直到 fact(1)。总共有 n 次递归调用(从 n 递减到 1,共 n 层)。
  2. 每次调用的操作量:每次递归调用仅执行一次乘法运算(n * fact(n-1))和条件判断(n <= 1),均为常数时间 O(1)

结论

总时间复杂度为递归调用次数与单次操作时间的乘积,即:
时间复杂度 = O (n)(线性时间复杂度)。

题目3

04 - 时间复杂度相关的题
04 - 时间复杂度相关的题
解析
04 - 时间复杂度相关的题

题目4

题目4

04 - 时间复杂度相关的题
解析
04 - 时间复杂度相关的题
int Func(int n)
{
	int i = 0; 
	int sum = 0;
	while (sum < n)
	{
		sum += ++i;
	}
	return sum;
}

int main()
{
	int n = 4;
	int ret = Func(n);
	printf("%d\n", ret);
	return 0;
}

要计算该代码的时间复杂度,我们需要分析Func函数中循环的执行次数与输入规模n的关系。

关键分析步骤:

  1. 循环逻辑while (sum < n) 循环中,sum 累加的是 ++i(即 i 先自增 1,再累加到 sum)。因此,循环的实际行为是计算从 1 开始的连续整数的累加和,直到累加和大于等于n
  2. 累加和公式:假设循环执行了k次,则累加和为 sum = 1 + 2 + 3 + ... + k = k(k+1)/2(等差数列求和公式)。
  3. 循环终止条件:循环终止时满足 sum >= n,即 k(k+1)/2 >= n。当n较大时,近似有 k² ≈ 2n,因此 k ≈ √(2n)kn的平方根成正比)。

时间复杂度结论:

循环的执行次数kn的平方根成正比,因此时间复杂度为 O(√n)(根号 n 阶)。

题目5

04 - 时间复杂度相关的题
解析
04 - 时间复杂度相关的题

题目6

04 - 时间复杂度相关的题
解析
04 - 时间复杂度相关的题
04 - 时间复杂度相关的题

题目7

04 - 时间复杂度相关的题
解析
04 - 时间复杂度相关的题

三、总结

04 - 时间复杂度相关的题

本网站原创文章版权归何大锤的狂飙日记所有。发布者:何大锤,转转请注明出处:何大锤的博客

(1)
何大锤的头像何大锤管理团队

相关推荐

  • 第二章数据结构线性表 – 带头结点的单链表

    一、单链表的定义和表示 – 带头结点的单链表 1、定义 单链表是由表头唯一确定,因此单链表可以用头指针的名字来命名 若头指针名是L,则把链表称为表L 2、单链表的存储结构 二、单链表基本操作的算法实现 – 带头结点的单链表 2.1 单链表的初始化 2.2 判断一个链表是否为空 一、带头结点的单链表代码实现 共6种函数代码 三、头插法创…

    3小时前
    200
  • 第二章数据结构线性表 – 单链表定义

    一、引言 1.1 知识框架 1.2 有了数组为什么还要链表? 在前面我们介绍过数组,数组中元素是存储在连续的内存位置在声明数组时,我们可以指定数组的大小,但这将限制数组可以存储的元素数量 例如我们声明的是 int arr[10],那么arr数组最多可以存储10个数据元素 但是我们事先不知道元素的大小呢? 我们该如何去做? 当然首先想到的是申请一个足够大的数组…

    6小时前
    200
  • 04 程序流程结构

    C/C++支持最基本的三种程序运行结构:顺序结构、选择结构、循环结构 循环结构:依据条件是否满足,循环多次执行某段代码 顺序结构:程序按顺序执行,不发生跳转 选择结构:依据条件是否满足,有选择的执行相应功能 4.1 选择结构 4.1.1 if语句 作用:执行满足条件的语句 if语句的三种形式 示例: 注意:if条件表达式后不要加分号 示例: 示例: 嵌套if…

    3天前
    300
  • 初始C语言01

    0、什么是C语言? C语言是一门通用计算机编程语言,广泛应用于底层开发。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。尽管C语言提供了许多低级处理的功能,但仍然保持着良好跨平台的特性,以一个标准规格写出的C语言程序可在许多电脑平台上进行编译,甚至包含一些嵌入式处理器(单片机或称MC…

    4天前
    000
  • 01 你好Python

    一、课件

    4天前
    000

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

2211932694

在线咨询: QQ交谈

邮件:hdcblog1999@163.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信
网站建设中ing......