开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看活动详情
Codility刷题背景
之前还在上学时期的时候,其实会因为各种地方的推荐注册很多奇奇怪怪网站的账号。
然后这些网站就会隔三岔五给你发邮件,Codility就是其中之一。
前几天看到Codility发送的最新Challenge的通知,于是点进去看了看。
发现其实分类内容不多,是可以抽出时间一道一道刷完的。
至于目的的话,其实也没什么太多目的,就是提高一下算法题能力,回忆回忆各类型算法题的解题思路吧。
我是从Codility的Lessons开始的,预计顺序按 Lessons -> Exercises -> Challenges把所有已有的内容都刷一遍吧。
正文
Lessons部分,第一项是Iterations
每个Lesson里的内容结构,是1个reading material,和1-N个Tasks。
我的想法是,Lessons部分的每篇,我会简单总结下PDF的内容,然后再说下自己做Tasks的历程:
PDF - Iterations:这部分PDF里写的内容大概是三部分:
- For Loops:
- 介绍了Loop就是实现重复操作的一种方式
- Loop的代码实现(for i in range(X)),以及用range实现了一个斐波那契数列的计算
- 接着拓展到了双循环(Two Loops),通过内外循环(Outer Loop, Inner Loop)实现了两种形状的三角形的打星操作
- While Loops:
- 介绍了range之外的while实现的循环,也即我们无法事先确认要循环多少次时的一种实现方法
- 举了两个代码例子,分别实现“计算一个integer的位数”,“无限打印斐波那契数列”
- Looping over collections of values
- 介绍了除了上边介绍的range()实现自然数递增迭代外,for还可以用来循环可迭代对象(如list)中的内容
- 接着展示了用【星期1~星期7的一个list、一个dict】,分别实现循环打印的代码
内容还是比较简单的,有兴趣的可以点开上边的链接来看看
Tasks
- BinaryGap:
题目比较简单:
传入参数是一个自然数,需要的传出参数,是将自然数转为2进制后,两个1间最长的连续0的个数(如果两个1相连,或者只有一个1,那么最长的连续0的个数就按0算)。
比如1041,转为二进制后是10000010001,那么两个1之间的最长连续0个数就是5。
比如32,转为二进制后是100000,因为只有一个1,所以最长连续0个数就是0。
以下是我最后提交的答案:
我的思路是找个变量(str_bin),把自然数对应的二进制字符串保存下来,然后再对二进制字符串进行具体的最长0个数的计算。
在转换得到二进制字符串后,因为二进制第一位一定是1,所以是从二进制字符串末尾开始向前搜索到第一个1,再从这个1开始循环向左,计算1~N组的两个1之间的0个数(len0)。
计算时,我也是干脆直接新建了新的list(len0s)来保留每一组1之间的0个数长度(len0),并在返回时直接返回len0s里的最大值(max(len0s))。
def solution(N):
# Implement your solution here
if N==0: # 为0时直接返回0
return 0
else: # 不为0
# 转为二进制字符串
str_bin = ''
while N > 0:
a, b = N//2, N%2
str_bin = str(b) + str_bin
N = a
# 二进制字符串从右往左,从第一个1开始,计算连续0最大长度
reverse_str_bin = str_bin[::-1]
index_1 = reverse_str_bin.index('1')
# 开始计算len0,可能有多个间隔,所以用len0s进行统一存储,以便最后取最大的结果
len0 = 0
len0s = []
for b in reverse_str_bin[index_1:]:
if b=='1': # 遇到1时,把现在的len0保存在len0s,并重新从0开始计算
len0s.append(len0)
len0 = 0
else: # 遇到0时,把len0+1
len0 += 1
return max(len0s)
提交结果:
最终提交结果,是Correctness 100%,也就是全部Test Case都计算正确了。
不过作为第一道Task,Codility并没有对这道题评估Performance,因此我新增的这些变量也并没有对综合的Task Score造成影响。