【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题-2

简介: 【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题

【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题-1

https://developer.aliyun.com/article/1538357


三、空间复杂度的计算

空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度 。空间复杂度不是程序占用了多少Byte的空间,因为这个也没太大意义,所以空间复杂度算的是变量的个数。空间复杂度计算规则基本跟实践复杂度类似,也使用大O渐进表示法。


【示例1】:

// 计算BubbleSort的空间复杂度?
void BubbleSort(int* a, int n)
{
    assert(a);
    for (size_t end = n; end > 0; --end)
    {
        int exchange = 0;
        for (size_t i = 1; i < end; ++i)
        {
            if (a[i-1] > a[i])
            {
                Swap(&a[i-1], &a[i]);
                exchange = 1;
            }
        }
        if (exchange == 0)
            break;
    }
}

7c0b565413daebbd4bb2d23823b51ee1_0e01ce87441847c3ac91e303486b1cf7.png

记住一个点:时间是累计的,空间是不累计的,空间是可以重复利用的,for循环走了N次,重复利用的是一个空间。

即这个算法的空间复杂度为:

O(1)

【示例2】:

// 计算Fibonacci的空间复杂度?
long long* Fibonacci(size_t n)
{
    if(n==0)
        return NULL;
    long long * fibArray = (long long *)malloc((n+1) * sizeof(long long));
    fibArray[0] = 0;
    fibArray[1] = 1;
    for (int i = 2; i <= n ; ++i)
    {
        fibArray[i ] = fibArray[ i - 1] + fibArray [i - 2];
    }
    return fibArray ;
}

6699a2e8f9f376606e8ef7ff7ead1019_dc07eff5d40e40a0a0de923ed860bbc2.png

空间复杂度为:

O(N)

【示例3】:

// 计算阶乘递归Factorial的空间复杂度?
long long Factorial(size_t N)
{
    return N < 2 ? N : Factorial(N-1)*N;
}

每次调用都会创建栈帧,调用了N次,每个栈帧使用了常数个空间O(1),其整体的空间复杂度为:

O(N)

四、Leetcode刷题

1. 消失的数

消失的数

思路一:排序 --> 对于示例输入:0 1 3,后一个数比前一个数大一就说明找到了

这个思路可行,但不符合提议为O(n)

排序 --> 最快排序O(N * logN),不符合。


思路2:把0到n的所有整数加到一起,结果为ret1,把输入示例中数组的数加到一起,结果为ret2,用ret1减去ret2,得到的结果就是所缺失的数。

int missingNumber(int* nums, int numsSize){
    int ret1 = 0;
    // 缺失一个数,那么0到n的所有数的个数就是numsSize的个数加1
    for(int i = 0; i < numsSize + 1; i++)
    {
        ret1 += i;  // 计算0到n之间所有的数的和
    }
    int ret2 = 0;
    for(int j = 0; j < numsSize; j++)
    {
        ret2 += nums[j];  // 计算数组nums中所有数的和
    }
    return ret1 - ret2;
}

思路3:按位异或,两个数按位异或(二进制),相同为0,相异为1,两个相同的数按位异或得到的就是0,另外,异或是支持交换律的,这意味着不需要排序直接依次异或即可。我们把从0到n之间的所有数与数组中的数依次按位异或,相同的数按位异或直接就等于0,最后得到的结果就是缺失的数。

int missingNumber(int* nums, int numsSize){
    int n = 0;
    for(int i = 0; i < numsSize; i++)
    {
      // 先跟数组中的数异或
        n ^= nums[i]; // 0异或任何数还是原来那个数 
    }
    for(int j = 0; j < numsSize + 1; j++)
    {
      // 在跟[0,n]之间所有的数异或
        n ^= j;
    }
    return n;
}

2. 旋转数组

旋转数组

题意:输入一个数k,将数组中的每个元素向右移动k位,数组的最后一个元素向右移动移位后就成了数组的第一个元素。

思路一:旋转k次,给一个变量tmp用于存数组的最后一个元素,从数组的最后一个元素开始,与他的前面一个元素互换,然后将tmp赋值给数组的首元素,这是旋转一次的过程,最后循环k次就可以了。

缺陷:Leetcode中有些测试样例将数组给的特别大,跑不过。

这种算法的时间复杂度为O(N * K)


思路二:以空间换时间,创建一个和nums同样大的数组,将nums数组的后k位元素与前k位元素进行互换,然后在将新数组中的元素拷贝到nums中。

缺陷:时间复杂度为O(N),空间复杂度为O(N),与题意不相符。


思路三:后k个逆置,前n - k个逆置,最后在整体逆置。假设给定一个数组:[1,2,3,4,5,6,7],k = 3,前k个逆置之后变成[1,2,3,4,7,6,5],前n - k个逆置后变成[4,3,2,1,7,6,5],最后在整体逆置后变成[5,6,7,1,2,3,4],最后得到的结果就和测试样例中的一样啦。


样例中可能会出现k大于数组元素的个数,对k取数组大小的余数即可。

// 逆置操作
void Reverse(int *nums, int left, int right)
{
    while(left < right)
    {
        int tmp = nums[left];
        nums[left] = nums[right];
        nums[right] = tmp;
        left++;
        right--;
    }
}
void rotate(int* nums, int numsSize, int k) {
    if(k >= numsSize)
    {
        k %= numsSize;  // 如果k大于数组, 对k进行取模操作
    }
    // 数组后k个逆置
    Reverse(nums, numsSize - k, numsSize - 1);
    // 数组前n - k个逆置
    Reverse(nums, 0, numsSize - k - 1);
    // 数组整体逆置
    Reverse(nums, 0, numsSize - 1);
}

相关文章
|
2月前
|
算法 机器人
基于SOA海鸥优化算法的PID控制器最优控制参数计算matlab仿真
本课题研究基于海鸥优化算法(SOA)优化PID控制器参数的方法,通过MATLAB仿真对比传统PID控制效果。利用SOA算法优化PID的kp、ki、kd参数,以积分绝对误差(IAE)为适应度函数,提升系统响应速度与稳定性。仿真结果表明,SOA优化的PID控制器在阶跃响应和误差控制方面均优于传统方法,具有更快的收敛速度和更强的全局寻优能力,适用于复杂系统的参数整定。
|
6月前
|
存储 监控 算法
基于 C++ 哈希表算法实现局域网监控电脑屏幕的数据加速机制研究
企业网络安全与办公管理需求日益复杂的学术语境下,局域网监控电脑屏幕作为保障信息安全、规范员工操作的重要手段,已然成为网络安全领域的关键研究对象。其作用类似网络空间中的 “电子眼”,实时捕获每台电脑屏幕上的操作动态。然而,面对海量监控数据,实现高效数据存储与快速检索,已成为提升监控系统性能的核心挑战。本文聚焦于 C++ 语言中的哈希表算法,深入探究其如何成为局域网监控电脑屏幕数据处理的 “加速引擎”,并通过详尽的代码示例,展现其强大功能与应用价值。
147 2
|
6月前
|
算法 JavaScript 数据安全/隐私保护
基于GA遗传优化的最优阈值计算认知异构网络(CHN)能量检测算法matlab仿真
本内容介绍了一种基于GA遗传优化的阈值计算方法在认知异构网络(CHN)中的应用。通过Matlab2022a实现算法,完整代码含中文注释与操作视频。能量检测算法用于感知主用户信号,其性能依赖检测阈值。传统固定阈值方法易受噪声影响,而GA算法通过模拟生物进化,在复杂环境中自动优化阈值,提高频谱感知准确性,增强CHN的通信效率与资源利用率。预览效果无水印,核心程序部分展示,适合研究频谱感知与优化算法的学者参考。
|
8月前
|
存储 负载均衡 算法
基于 C++ 语言的迪杰斯特拉算法在局域网计算机管理中的应用剖析
在局域网计算机管理中,迪杰斯特拉算法用于优化网络路径、分配资源和定位故障节点,确保高效稳定的网络环境。该算法通过计算最短路径,提升数据传输速率与稳定性,实现负载均衡并快速排除故障。C++代码示例展示了其在网络模拟中的应用,为企业信息化建设提供有力支持。
221 15
|
8月前
|
存储 算法 数据处理
公司局域网管理中的哈希表查找优化 C++ 算法探究
在数字化办公环境中,公司局域网管理至关重要。哈希表作为一种高效的数据结构,通过哈希函数将关键值(如IP地址、账号)映射到数组索引,实现快速的插入、删除与查找操作。例如,在员工登录验证和设备信息管理中,哈希表能显著提升效率,避免传统线性查找的低效问题。本文以C++为例,展示了哈希表在局域网管理中的具体应用,包括设备MAC地址与IP分配的存储与查询,并探讨了优化哈希函数和扩容策略,确保网络管理高效准确。
|
4月前
|
存储 监控 算法
基于跳表数据结构的企业局域网监控异常连接实时检测 C++ 算法研究
跳表(Skip List)是一种基于概率的数据结构,适用于企业局域网监控中海量连接记录的高效处理。其通过多层索引机制实现快速查找、插入和删除操作,时间复杂度为 $O(\log n)$,优于链表和平衡树。跳表在异常连接识别、黑名单管理和历史记录溯源等场景中表现出色,具备实现简单、支持范围查询等优势,是企业网络监控中动态数据管理的理想选择。
128 0
|
6月前
|
监控 算法 数据处理
基于 C++ 的 KD 树算法在监控局域网屏幕中的理论剖析与工程实践研究
本文探讨了KD树在局域网屏幕监控中的应用,通过C++实现其构建与查询功能,显著提升多维数据处理效率。KD树作为一种二叉空间划分结构,适用于屏幕图像特征匹配、异常画面检测及数据压缩传输优化等场景。相比传统方法,基于KD树的方案检索效率提升2-3个数量级,但高维数据退化和动态更新等问题仍需进一步研究。未来可通过融合其他数据结构、引入深度学习及开发增量式更新算法等方式优化性能。
175 17
|
5月前
|
机器学习/深度学习 存储 算法
基于 C++ 布隆过滤器算法的局域网上网行为控制:URL 访问过滤的高效实现研究
本文探讨了一种基于布隆过滤器的局域网上网行为控制方法,旨在解决传统黑白名单机制在处理海量URL数据时存储与查询效率低的问题。通过C++实现URL访问过滤功能,实验表明该方法可将内存占用降至传统方案的八分之一,查询速度提升约40%,假阳性率可控。研究为优化企业网络管理提供了新思路,并提出结合机器学习、改进哈希函数及分布式协同等未来优化方向。
138 0
|
5月前
|
Java C++
力扣第一道困难题《3. 无重复字符的最长子串》,c++
首先我们看到这个题是肯定有一种暴力的硬解思路的,那就是将两个vector直接链接起来,然后再排序后,直接返回中间值,这个方法实现起来还是非常容易的,
98 0
|
7月前
|
存储 监控 算法
基于 C++ 哈希表算法的局域网如何监控电脑技术解析
当代数字化办公与生活环境中,局域网的广泛应用极大地提升了信息交互的效率与便捷性。然而,出于网络安全管理、资源合理分配以及合规性要求等多方面的考量,对局域网内计算机进行有效监控成为一项至关重要的任务。实现局域网内计算机监控,涉及多种数据结构与算法的运用。本文聚焦于 C++ 编程语言中的哈希表算法,深入探讨其在局域网计算机监控场景中的应用,并通过详尽的代码示例进行阐释。
144 4

热门文章

最新文章