Codility刷题之旅 - Iterations

1,318 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看活动详情

Codility刷题背景

之前还在上学时期的时候,其实会因为各种地方的推荐注册很多奇奇怪怪网站的账号。
然后这些网站就会隔三岔五给你发邮件,Codility就是其中之一。

前几天看到Codility发送的最新Challenge的通知,于是点进去看了看。
发现其实分类内容不多,是可以抽出时间一道一道刷完的。

至于目的的话,其实也没什么太多目的,就是提高一下算法题能力,回忆回忆各类型算法题的解题思路吧。

我是从Codility的Lessons开始的,预计顺序按 Lessons -> Exercises -> Challenges把所有已有的内容都刷一遍吧。

正文

Lessons部分,第一项是Iterations

每个Lesson里的内容结构,是1个reading material,和1-N个Tasks。

image.png

我的想法是,Lessons部分的每篇,我会简单总结下PDF的内容,然后再说下自己做Tasks的历程:

PDF

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:

image.png

题目比较简单:
传入参数是一个自然数,需要的传出参数,是将自然数转为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造成影响。

测评报告 image.png