C++-时间复杂度

前言

        OJ测试中最烦人的结果莫过于TLE(Time Limit Exceed 超时)MLE(Mempry Limit Exceed超内存)了,在递归和搜索题里面看见这两货就烦。

目录

前言

时间复杂度 

        时间复杂度概念

时间复杂度的表示法

        时间复杂度OJ测试要求

         时间复杂度例举

剪枝

                  1.可行性剪枝

2.最优性剪枝

3.记忆化搜索

4.搜索顺序剪枝


时间复杂度 

        时间复杂度概念

        C++时间复杂度是指算法在处理数据时所需要的计算时间。在C++中,常见的时间复杂度包括常数级别、对数级别、线性级别、平方级别、立方级别等。其中,常数级别是最快的,而立方级别是最慢的。具体来说:
常数级别:只需要一次计算即可完成,如赋值操作等。
对数级别:需要不断缩小问题规模,通常用于二分查找等算法。
线性级别:随着问题规模增加,所需计算时间也呈线性增长,如遍历一个数组等。
平方级别:通常是嵌套循环的形式,所需计算时间随着问题规模的增加呈平方级别增长。
立方级别:通常是三层嵌套循环的形式,所需计算时间随着问题规模的增加呈立方级别增长。
当然,在实际应用中,我们需要选择合适的算法来降低时间复杂度。例如,可以使用哈希表来加速查找操作,或者使用动态规划来减少重复计算等。在竞赛中,一般算机一秒能执行5x10^8次汁算。

时间复杂度的表示法

对于表示时间复杂度,我们可以使用O()表示法来表示时间复杂度,O(n)表示程序运行n次汁算。判断时,只关注最高次项。但执行的数量不是不确定的都填1
比如下面的例子:

O(c) = O(1)     (c表示常数)
O(2n+1) = O(n)
O(+n+1) = O(n²)
O(3+1) = O(n³)


注意:符号 O(c)表示算法或函数具有恒定的时间复杂度,这意味着无论输入大小如何,它都需要固定的时间来执行。 

        时间复杂度OJ测试要求

        为了避免TLE,OJ中要减少时间复杂度,一般来讲(1000ms) n的数据范围大致如下

            时间复杂度                             n算
### C++算法时间复杂度计算分析与示例 #### 时间复杂度的概念 时间复杂度是用来衡量算法运行时间随着输入数据规模变化的趋势。在C++中,时间复杂度通过大O表示法来描述算法的效率[^1]。 #### 大O表示法的意义 大O表示法用于描述算法最坏情况下的运行时间上界。例如,如果一个算法的时间复杂度为 \( O(n) \),则意味着当输入规模增大时,其运行时间线性增加[^2]。 #### 常见的时间复杂度及其对应代码示例 以下是几种常见的算法时间复杂度以及它们在C++中的实现: ##### 1. 常数时间复杂度 \( O(1) \) 常数时间复杂度表示无论输入数据规模如何变化,算法的执行时间始终不变。 ```cpp int getFirstElement(int array[], int size) { if (size > 0) { return array[0]; // 返回数组的第一个元素 } return -1; // 如果数组为空,则返回默认值 } ``` 上述函数仅访问数组的一个固定位置,因此具有 \( O(1) \) 的时间复杂度。 ##### 2. 线性时间复杂度 \( O(n) \) 线性时间复杂度表示算法的运行时间与输入数据规模呈线性关系。 ```cpp void printArray(int array[], int n) { for (int i = 0; i < n; ++i) { // 遍历整个数组并打印每个元素 std::cout << array[i] << " "; } } ``` 此函数遍历一次数组,每次迭代处理单个元素,故时间为 \( O(n) \)。 ##### 3. 平方级时间复杂度 \( O(n^2) \) 平方级时间复杂度通常出现在嵌套循环的情况下,其中外层和内层循环均依赖于输入规模。 ```cpp void bubbleSort(int array[], int n) { for (int i = 0; i < n - 1; ++i) { // 外层循环控制比较轮次 for (int j = 0; j < n - i - 1; ++j) { // 内层循环完成每一轮相邻元素交换 if (array[j] > array[j + 1]) { std::swap(array[j], array[j + 1]); } } } } ``` 冒泡排序包含两重嵌套循环,总操作次数接近 \( n^2/2 \),简化后得到 \( O(n^2) \)。 ##### 4. 对数时间复杂度 \( O(\log n) \) 对数时间复杂度常见于分治策略的应用场景,比如二分查找。 ```cpp bool binarySearch(int array[], int target, int low, int high) { while (low <= high) { int mid = low + (high - low) / 2; if (array[mid] == target) { return true; // 找到目标值 } else if (array[mid] < target) { low = mid + 1; // 调整下限继续搜索右半部分 } else { high = mid - 1; // 调整上限继续搜索左半部分 } } return false; // 若未找到目标值 } ``` 由于每次迭代都将问题范围缩小一半,最终达到 \( O(\log n) \) 的时间复杂度。 ##### 5. 指数时间复杂度 \( O(2^n) \) 指数时间复杂度通常出现在穷举或回溯类算法中,这类算法会尝试所有可能解。 ```cpp long long fibonacciRecursive(int n) { if (n <= 1) { return n; // 基础情形 } return fibonacciRecursive(n - 1) + fibonacciRecursive(n - 2); // 递归调用 } ``` 该斐波那契序列递归版本因重复子问题而呈现指数增长特性,即 \( O(2^n) \)[^1]。 --- ### 总结 以上展示了不同级别时间复杂度的具体含义及其实现方式。理解这些概念有助于优化程序性能,在实际开发过程中合理选择高效的数据结构和算法至关重要。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值