算法系列教程01 - 开篇语和 FizzBuzz 问题

大家好,好久没有写新文章了,对不起大家。今天开始,我要写另一个系列教程:算法。

开篇语

为什么要写算法系列教程呢?因为最近刚看完《Algorithms, 4th Edition》这本经典算法书(电子书,中英版网上都有下载),有了些新收获,觉得那些零散的知识点和经验有必要也值得花时间好好整理一下。另外,我自己的算法知识应该还没有达到去学好“机器学习”这门学科的程度,在写教程的同时我也会不断学习,我想和大家一起用算法这把钥匙开启“机器学习”这扇大门,去探索算法是如何让机器“学习”的。

为什么要学习算法呢?我个人觉得最终目的还是为了提高自己的职场竞争力。算法的本质就是解决问题,所以学习算法本质上是在提高解决问题的能力,这是职场最重要的能力之一。另外,如果你想在面试中表现得更加出色,也要对算法有一定程度的掌握。

写教程是很耗费精力的,而且学习算法是很枯燥的,但如果大家都能参与进来一起交流讨论,那么整个过程就是不断进行头脑风暴、集思广益的过程,这会是我继续写作的动力,这也会使得枯燥的算法学习之路变得有趣,并让每个人收获满满。

为了更方便大家利用碎片化的时间学习,更好的利用空闲时间在手机上阅读,这个系列的每一篇文章我都会精心排版,而且每一篇文章阅读时间都不会太长,会尽量控制在 6 分种以内(不包括思考的时间)。

这个系列会包含三部分内容。第一部分是算法基础,由于算法和数据结构是密切相关的,所以也会讲到一些数据结构的知识,但不会讲太细。第二部分以常见的算法案例解析为主,包括解析一些算法面试题。第三部分是算法在机器学习中的应用,由于我自己也没有学习过机器学习,所以这部分是探索式和交流式的,我会把我学到的用我理解写出来,希望大家能参与进来一起交流。

这个系列的文章代码选择用 JavaScript 语言来编写,程序语言都是相通的,我相信你看了 JavaScript 写的算法实现可以很快用你熟悉的语言写出来。但第三部分的机器学习相关内容,可能选用 Python,现在还不确定。

希望这个算法系列教程能帮助大家在今后的编程道路上得心应手。

开篇算法题:FizzBuzz

好了,我们今天以一个算法问题 FizzBuzz 来开篇吧。FizzBuzz 是一个非常典型的用来面试的算法题。下面是 FizzBuzz 的自然语言描述:

编写一个程序,打印 1 到 100 中的数字,但能被 3 整除的变为“Fizz”,能被 5 整除的变为“Buzz”,既能被 3 整除又能被 5 整除的变为“FizzBuzz”。

一看是不是很简单?确实很简单。看完题,随手就能写出下面的代码:

for (var i = 1; i < 101; i++) {
  if (i % 3 == 0) console.log('Fizz')
  else if (i % 5 == 0) console.log('Buzz')
  else if (i % 3 == 0 && i % 5 == 0) console.log('FizzBuzz')
  else console.log(i)
}

和需求吻合,好像没什么问题。等等,仔细检查,这段代码问题大了,FizzBuzz永远没有输出的机会,例如遇到 i=15 还是会输出Fizz。这是初级程序员很容易犯的一个错误,拿到需求后直接就是一通写,对需求的理解比较生硬,不容易考虑到上下文的关联关系。纠正后的写法是将第 4 行的 if 条件放到最前面:

for (var i = 1; i < 101; i++) {
  if (i % 3 == 0 && i % 5 == 0) console.log('FizzBuzz')
  else if (i % 3 == 0) console.log('Fizz')
  else if (i % 5 == 0) console.log('Buzz')
  else console.log(i)
}

这样写是对的,但如果是面试,这个答案只能算是及格。如何能做到优秀呢?我总结写算法可以分为三个步骤:

第一步是实现,即按照需求把算法写对了,让程序能正确的运行;第二步是优化,即降低复杂度,让程序运算更高效。第三步是美化,即让代码看起来美观简洁,这一步很多时候会灵活运用到程序语言本身的语法糖,但简洁有时候会牺牲代码的易读性,这需要在实际场景中稍作权衡。

做到这三步,我觉得应对面试中的算法题就可以拿优秀了。

前面我们已经完成了写 FizzBuzz 算法的第一步,我们再来做第二步:优化。既能被 3 整除又能被 5 整除,我们很自然会想到 3 和 5 的最小公倍数:15,能被 15 整除的数一定也是既能被 3 整除又能被 5 整除的。也就是说上面的第二行代码可以只对 i 判断一次(而不是两次),下面是优化后的代码:

for (var i = 1; i < 101; i++) {
  if (i % 15 == 0) console.log('FizzBuzz')
  else if (i % 3 == 0) console.log('Fizz')
  else if (i % 5 == 0) console.log('Buzz')
  else console.log(i)
}

我们再来看第三步:美化。上面我们写这个算法用了 6 行代码(包括大括号),如果要减少代码量,能减少到多少行呢?这里给到 2 行的实现方案:

for (let i = 0; i < 100; )
  console.log((++i % 3 ? '' : 'Fizz') + (i % 5 ? '' : 'Buzz') || i)

这个实现来自 Reddit 。当然也可以写成一行,但写成两行阅读体验更好。这段代码很好理解,我就不解读了,有疑问可以在留言区留言提问。

最后,对于 FizzBuzz 算法问题,你有其它的实现方案吗?欢迎在留言区讨论。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,188评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,464评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,562评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,893评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,917评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,708评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,430评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,342评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,801评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,976评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,115评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,804评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,458评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,008评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,135评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,365评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,055评论 2 355

推荐阅读更多精彩内容

  • 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你...
    hw1212阅读 12,732评论 2 59
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,180评论 25 707
  • 凌霜花开了 夜里的时候 你在路的那头 轻弄裙褶 月影斜挂危楼 听风吟阿 靖夜曦笑了 睡醒的时候 我在海的这头 望断...
    茗香酒影阅读 159评论 1 1
  • 今天,开了一个培训会,已是下午四点多钟了。我与同事告别,独自一人走在滨江路上,走着走着,忽然觉得有一种疲惫感从...
    孤独的一片云阅读 227评论 0 1
  • 云雪华裳露影重, 曳隐星辰醉春风。 与君轻诉千千喜, 莫惊枝头云雀声。 花怨琼楼寒霖晚, 岁意淡搏竞九霄。 年年月...
    柒月流年阅读 249评论 0 0