1. 布隆过滤器(及其他存储
题目描述
一个网站有 100 亿 url 存在一个黑名单中,每条 url 平均 64 字节。这个黑名单要怎么存?若此时随便输入一个 url,你如何快速判断该 url 是否在这个黑名单中?
解1 散列表
10 亿字节 ≈ 1 G, 共需640G。散列表是会出现散列冲突的。为了让散列表维持较小的装载因子,避免出现过多的散列冲突,需要使用链表法来处理,这里就要存储链表指针。因此最后的内存空间可能超过 1000G 了
解2 位图(BitMap)
比如有 1 千万个整数,并且整数的范围在 1 到 1 亿之间。
数组大小为1亿(最大值),储存状态(true / false),适用于大规模数据,但数据状态又不是很多的情况。
- 缺点:空间复杂度随集合内最大元素增大而线性增大,若最大值为1000亿,会浪费大量空间。
布隆过滤器(Bloom Filter)
优势是只需要占用很小的内存空间以及有着高效的查询效率。本质是一个位数组(0/1)和k个哈希函数。
首先初始化为0,当加入新元素时,进行k次哈希计算,得到的k个哈希值将下标置为1。
- 缺点:误判率。数组大小有限,随着元素增加,数组中的1逐渐增多,经过hash过的值可能已被置1,有可能一个不存在布隆过滤器中的会被误判成在布隆过滤器中。
存在误判不存在漏判,False is always false. True is maybe true。 - 补救办法:白名单。
- 使用场景:网页爬虫对url的去重,垃圾邮件过滤,防止黑客对服务器的大量请求,防止缓存被击穿。
2. 0/1 背包
https://www.cnblogs.com/mfrank/p/10533701.html#autoid-0-0-0
3. TIPS
- 区间返回
if num > INT_MAX: return INT_MAX
if num < INT_MIN: return INT_MIN
return num
改为
return max(min(num, INT_MAX), INT_MIN)
- gcd 辗转相除法
def gcd(self, a, b):
if b == 0:
return a
return self.gcd(b, a % b)
- 对字典的值排序
res = sorted(s.values())
- 对数组元素计数
# 第一种
s = {}
for i in deck:
if i not in s:
s[i] = 1
else:
s[i] += 1
# 第二种
s = collections.Counter(deck)
- api 队列 时间复杂度
from collections import deque
q = deque()
s = []
q.pop() o(1)
q.popleft() o(1)
s.pop() o(1)
s.pop(0) o(n)
s.index(3) o(1)
- 倒序排序
nums.sort(reverse=True)
- candy
相当于if
l == r == n and ans.append(s)
- 队列
T = collections.deque(maxlen=10)
- pip 清华源
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple tensorflow
- 字典key-value对
pos = {}
pos['ideas'] = 'N'
pos['sleep'] = 'V'
pos['furiously'] = 'ADV'
print(list(pos.items()))
for key, val in sorted(pos.items()):
print(key + ":", val)
- 获取字典中值最大的键
max(tokens, key=tokens.get)
max(tokens, key=lambda k: tokens[k])
- notebook
shift + v 黏贴代码块 - Zip all 用法
s = ['123', '124', '999']
for i in s:
for j in s:
# a 每一位都与 b 不同
if all(a != b for a, b in zip(i, j)):
print(i,j)
print('-------')
for i in s:
for j in s:
if j != i:
print(i,j)
- 阶乘
cnt = math.factorial(size)
- 回溯算法 Leetcode 46
result = []
def backtrack(路径, 选择列表):
if 满足结束条件:
result.add(路径)
return
for 选择 in 选择列表:
做选择
backtrack(路径, 选择列表)
撤销选择
- 图片
img = mping.imread('day3.png')
plt.figure(figsize=(15,4))
plt.title("tf-idf",fontdict={"fontsize":30})
plt.imshow(img)
- txt python %
for i in range(1, 5):
f = open('terrorism data/ArticleSet_%d.txt' %i, 'r')
text = f.read()
print(text[:100])
f.close()
-
linux
查看dir :ls
获取root:su
编辑文件:vi xxx打开 i 编辑 :wq保存 -
counter
# nums = [4,1,4,6]
cnt = Counter(nums)
res = []
for val, n in cnt.items():
if n == 1:
res.append(val)
return res
- 异或运算
任何数和本身异或则为0,任何数和 0 异或则为本身
4. 周赛
- 减少bug:
注意跟标准输出对比,如list中题目是[‘2’, ‘3’],自己输出[2, 3]就错了。 - for 循环的化简
n = 25i + 10j + 5*k + L s.t. i,j,k,L 均为非负整数
for i={0,1,...,n/25}
for j={0,1,... (n-i*25)/10}
for k={0,1,...,(n-i*25-j*10)/5}
ans += 1 # 原
化简一下
#for i={0,1,...,n/25}
# for j={0,1,... (n-i*25)/10}
# ans += (n/5-5*i-j*2)+1
for i={0,1,...,n/25}
for j={0,1,... (n-i*25)/10}
kmax = (n-i*25-j*10)/5 = (n/5-5*i-j*2)
ans += (kmax+1)*1 # kmax * 原
再次化简
for i={0,1,...,n/25}
jmax = (n-i*25)/10
ans += (jmax+1)*(n/5-5*i-jmax+1); # jmax * 原,原来的j要改为jmax/2