算法学习(二)

  最近开始看一些简单的算法书,之前大一上学期学Python的时候,其实就有想写一些笔记的想法,但是之前一直太懒,没有实现。最近老师要求我们每个星期看一些算法书,并做一些笔记,希望这个习惯能够坚持下来吧。编程小白,错误之处请大佬们指正,也希望和大佬萌新们一起加油学习。
 
一.链表(list
STL 中的 list 是双向链表,它的特点是内存空间不连续,可以通 过指针来进行数据的访问,可以很快地在任意处插入和删除(这个操
作只需要常数时间。) list 适用于插入和删除频繁,而随机访问较少。
vector 则相反。下面是 list 的一个实例:
1 hdu1276 士兵报数问题

注意,在这里使用了迭代器。
( 迭代器:要访问顺序容器和关联容器中的元素,需要通过“迭代器
  1. iterator)”进行。迭代器是一个变量,相当于容器和操纵容器的算
法之间的中介。迭代器可以指向容器中的某个元素,通过迭代器就可
以读写它指向的元素。从这一点上看,迭代器和指针类似。注意 list 不支持“ < ”,因为双向迭代器不支持这种运算 )
 
二.集合( set
集合具有元素自动去重的特点,并且 STL 中的 set 使用二叉搜索树
实现,访问元素的时间复杂度是 O log n )。
集合的大部分操作与 vector 等类似,但是多了:
A. lower_ /( upper_) bound(k)
// 返回一个迭代器,指向键值
不小于 /( 不大于 )k 的的第一个元素
下面是一个例子:
(2) hdu2094 冠军问题
注意这里 set 会自动去重,胜利者不会在 B 中, A 中包含了所有的选
手,并且如果存在冠军,即胜利者唯一,故两集合的基的差值为 1
这就是这个算法的核心。
 

三.map

map 容器可以建立把不同类型的数据串接起来,它是关联容器,

可以实现键到值的映射。比如查找学生的姓名和学号。当然,c++

的结构体( struct )也可以实现这一操作,但它需要遍历所有的 n
学生,是复杂度 O(n) 的算法。而 map 是通过平衡二叉搜索树来存储
和访问,因此它是 O(log n ) 的算法。这里补充说明一下平衡二叉树
(AVL)
平衡二叉树满足:
1. 是「二叉排序树」 ( 即所有左子树的值小于根节点,右子树的
值大于根节点 )
2. 任何一个节点的左子树或者右子树都是「平衡二叉树」(左
右高度差小于等于 1
这样就避免了二叉树成为一个链表一样的排列,这个时候查找的
效率是最差情况 (the worst case) ,它是 O(n) 的复杂度。
下面是一个实例:
(3) hdu2648 购物问题
注意代码的最后一行的迭代器使用了 ”it->second”, 这相当于 (*it).second,会得到值 (value) ,相对的 it->first 得到键 (key)
 
四. Sort( ) 函数
Sort( ) 函数可以自定义排序,也可以使用系统自带的 4 种排序。其
中,最常用的有: sort(a.begin(),a.end()); 从小到大排序。当然也可以
有从大到小,大于等于等排序方法。
 
五. next_permutation( ) 函数
这个函数是 STL 中用来生成下一个组合的函数。它是 bool 形式的
函数,若存在下一个排列组合,则返回 true ,反之返回 false 。每执行
一次这个函数,就会把新的排列放到原来的空间里。算法的复杂度为
O(n) ,特别需要注意的是它排列的范围是左闭右开区间的。
下面是运用此函数实现找到下一个字典序更大的序列:
这个问题使用 next_permutation() 函数非常简单,当然我们也可以
自己编写一个函数实现 next_permutation() 的功能。这个算法的原理
是:从右向左遍历,从这个序列中从右至左找第一个左邻小于右邻的
数,如果找不到,则所有排列求解完成,如果找得到则说明排列未完
成。将这个左侧的数记为 i ,在从右往左找到第一个大于 i 的数,记
j ,把 i 换成 j ,这个左侧数后面所有的数从小到大排序即可以得到
下一个更大的字典序。 ( 因为字典序实际上是只比较到某一个位数上
的数的不等关系即可,若前几位数相同,则继续往后比较。 )
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值