算法入门之优化枚举(一) 思路介绍和部分工具

        首先呢,博主并不是什么大神。博主觉得在复习和学习的过程中需要给自己留下点知识和财富,所以决定开始总结一些知识点 包括汇编、C、java、web框架、Python等。 这个分类主要记录和总结算法知识

这篇主要介绍暴力枚举的思路及部分工具


上图是一个网上的算法题,值得注意的是数据范围,很多正规的编程比赛都会注明数据范围。

最后一部分是时间和内存限制。现在主流的服务器据说是10^8数量级。


枚举算法:

    设计一个枚举算法的关键    1 关键在于确定枚举的变量

                                              2 确定枚举的范围。

常用思路   


        1 二分法   算法复杂度通常由o(N)----->o(logN)

                2 Hash 空间换时间

                3 前缀和后缀和

                4 双指针                   主要呢都是空间换时间的方法

(1)确定枚举的变量


   这是一道某比赛国赛题目 是一个填空题显然是个水题.........简单的通过暴力就可以得到结果,那么它的枚举该如何设计呢。

  首先枚举【1026753849,9876543210】 不过他的复杂度大概是10^10级以上的。

  这时候稍微优化一下,改成枚举数字的平方根A是多少即可。所以枚举【30000,100000】 计算x=A*A 然后判断x是不是0-9是不是10位数字。 此时枚举算法10^ 5 判断还有一个o(10)所以优化了很多


2 查找一个元素是不是存在

这也是一个常见的问题 要解决这样的问题,哈希表是一个非常好用的工具。而且更方便的是,C++的STL已经帮我们把这些工具都实现好了,提供了非常方便的接口,我们直接用行了。下面我们就介绍一下这些工具。
首先我们要介绍的就是unordered_setunordered_map。unordered_set可以把它想象成一个集合,它提供了几个函数让我们可以增删查:
unordered_set::insert
unordered_set::find
unordered_set::erase



 对于unordered_set,insert/find/erase的平均复杂度是O(1)有两种情况会出现O(N)复杂度。
1是你的哈希函数太烂了,导致很多不同元素的哈希值都相同,全是碰撞,这种情况复杂度会变成O(N)。但是这种情况一般不用担心,
2是如果insert很多数据,会触发rehash。就是整个哈希表重建。这个过程有点类似向vector里不断添加元素,vector会resize。比如你新建一个vector时,它可能只申请了一块最多保存10个元素的内存,当你插入第11个元素的时候,它会自动重新申请一块更大空间,比如能存下20个元素。哈希表也是类似,不过rehash不会频繁发生,均摊复杂度还是O(1)的,也不用太担心。


 unordered_set是一个集合,有的时候我们需要一个字典,就是保存一系列key/value对,并且可以按key来查询。比如我们要保存很多同学的成绩,每位同学有一个学号,也有一个分数,我们想按学号迅速查到成绩。这时候我们就可以用unordered_map。
unordered_map同样也提供了增删查函数:
unordered_map::insert
unordered_map::find
unordered_map::erase
这三个函数的平均时间复杂度也是O(1)的 
 值得一提的是,unordered_map重载了[]运算符,我们可以把key放在中括号里,像操作数组一样操作unordered_map:

这样会使程序的操作更加简单
普通set/map的用法其实和unordered_set/map是一样的 其中set/map不一样的地方是它们内部是用平衡树实现的。所以insert/find/erase操作时间复杂度都是O(logN)的。这里N指容器中有多少个元素。不过O(logN)这个复杂度已经很优秀了



猜你喜欢

转载自blog.csdn.net/weixin_39538977/article/details/80672992