1.算法的常见复杂度
a.(
) :枚举集合的子集个数
来源:关于“枚举{0,1,...,n-1}所包含的所有大小为k的子集”的理解 - pjhui - 博客园 (cnblogs.com)
“枚举{0,1,…,n-1}所包含的所有大小为k的子集”与二进制状态压缩关系密切,其本质为利用二进制与位元算表示和操作集合,举个例子:
含有n个元素的集合{0,1,…,n-1},就有n个二进制位,第i
个二进制位代表第i
个元素,第i
个二进制位为1代表第i
个元素存在于集合,第i
位二进制位为0代表第i
个元素不存在于集合。(i
<=n)
含有3个元素的集合{0,1,2}
,全部子集有0000
、0001
、0010
、0011
、0100
、0101
、0110
、0111
,其中0000
代表空集∅
。
二进制数与集合对应关系如下:
我们可以:
(1)取出字典序最小的1的连续区间,1100 1100 → 0000 1100
(2)找到字典序最小的1的位置,1100 1100 → 0000 0100
(3)将字典序最小的1的连续区间置为0,并将区间左侧第一个0置为1,1100 1100 → 1101 0000
(4)将 (1) 取出的区间右移,直至区间中1的个数减少一个,0000 1100 → 0000 0001
(5)将 (4) 的结果与 (3) 的结果取并集,0000 0001 | 1101 0000 → 1101 0001
按照这种方法,我们不难找出后续的子集。
代码如下:
int comb = (1 << k) - 1;
int comb = (1 << k) - 1;
while (comb < 1 << n) {
//进行针对组合的处理
int x = comb & -comb, y = comb + x;
comb = ((comb&~y) / x >> 1) | y;
}
b.(
) :多见于暴力求解
c.(
) :一般与二分、倍增等方法相关,每次计算后问题的规模会缩小一半。
d.平均算法复杂度:
在某些算法中,实际算法复杂度可能被平均分配过,如在,最小圆覆盖算法,表面上为(
),但在随机数据下均摊时间复杂度只是
(
)。
2.小寄巧
PI的引入
#python
import math
print(math.pi)
//c++
const double PI = acos(-1.0);
二分数组
#法一
mid=(l+r)//2
#法二
mid=(l+r)>>1
取最大值/最小值
list=[1,2,3,4,5]
maxval=max(list)
print(maxval)