前言

背景

自从重新回到编程的职业道路上以来,每天都能切身地感受到每次考虑到职业生涯的前途而带来的压力。与之前的职业不同,这种压力和解决问题的方法我是可以看得见摸得到的,也愿意为之付出时间和精力。然而由于一直以来学习的方式不够高效,导致并没有很好的系统性地提升自己的工作能力并解决问题。目前面临着职业生涯和个人未来和家庭未来的重要关头,为了能够找到心仪的工作,更要努力和高效地把数据结构和算法学好,以便能够顺利通过面试。

目标

  • 学习数据结构和算法的最大目标是为了眼前找到一个心仪的国外工作;
    • 面试时可以对答如流;
    • 能够刷 LeetCode 的题目;
  • 写这篇文章的有两个目标;
    • 总结记录好的学习资料和网站;
    • 按照自己的想法总结,形成自己的知识体系;

确定教程

网上有很多各式各样的关于数据结构和算法的教程,我相信其中任何一个都是通往罗马的大道。但是既然要高效地学习,就要选择最适合自己的。

选择教程的标准

  • 完整。不得不承认,这门课程我从大学以来就没有入过门,所以无法针对性的提高,只能从基础开始学期,因此教程要完整,需要包含算法复杂度的分析、算法由来的背景、算法的逻辑和实现方式、以及该算法的应用场景;
  • 经典。目前的我没有时间和能力去判断哪个教程或者哪本教材更适合我,只能依靠时间和评价来选择一个被大多数人所接受的经久不衰的教程;
  • 生动。随着电脑多媒体的兴起,学习的方式已经发生了翻天覆地的变化,为了更加高效地学习,更加直观的学习方式是必要的,因此该教程最好有视频或者动画;

选择的教程

简单比较了一下,还是比较快速的选择了之前学过的一个在线教程,这门课是普林斯顿大学的公开课,用的[教材][amazon - Algorithms (4th Edition) ]比较经典,课程也比较新,唯一不足的就是实现语言是 Java,不过估计也不会有用 JS 语言来讲这门课的案例吧。

教程辅助参考资料

在按照这门课程的源代码用 JavaScript 实现数据结构和算法的时候,因为 JavaScript 和 Java 语言毕竟是不同的,在设计上和实现上如果完全照搬会有一些不合理的地方,在解决的过程中,参考了用原生 JavaScript 实现的数据结果和算法项目

使用教程的方式

确定语言

数据结构和算法只是一个概念,一个解决方案,可以落到任何实现方式上。但对我目前来说,JavaScript 是最熟悉的、上手最快的,因此默认使用 JS,如果有些算法或者数据结构实在用 JS 无法实现,再考虑其他的语言。

确定的教程是使用 Java 教学的,这也不奇怪,很难想到谁会用 JS 演示数据结构和算法。不过还是要控制自己尽量少地设计 Java 编程的语法和细节,尽量把精力和时间都画在核心上。如果有余力的画,最好还是用 JavaScript 或者更喜欢的 TypeScript 再去实现一遍。

范型

使用范型创建数组

开发和调试常用方法

一般情况下课程的左右在执行的时候都有两个要求:

  • 一是要读取命令行的参数;
  • 二是要从文件重定向输入;

例如如下所示命令。

~/Desktop/queues> cat distinct.txt
A B C D E F G H I

~/Desktop/queues> java Permutation 3 < distinct.txt
C
G
A

~/Desktop/queues> java Permutation 3 < distinct.txt
E
F
G

在 IDEA 中可以使用如下的配置:

idea-debug

调试

算法复杂度

algorithms-notations

分析或者应用算法的重要环节

  • 手写或画图。有直观感受,尤其是多个数组以及多个指针的情况下;
  • 语义化命名。通过变量名一眼就知道用途,避免混淆;
  • 将整体逻辑拆分成独立方法。平时的项目如此,算法的代码也是如此。更需要注意的是,在学习算法的过程中,就要注意把算法的整体逻辑拆分成单独的小业务,每个小业务只关注其自己要实现的功能以及边界条件等问题。学了几个排序算法以后发现其实也是有套路可循的,
  • 注意边界条件;

我的不足

  • 没有将整个的算法逻辑拆分成更细致的功能点,导致思维成本增加。比如快速排序算法,可以拆解成入口方法、总的排序方法、分组方法以及比较方法;
  • 没有将相同类型的算法的规律总结出来。比如排序算法都有的方法,入口方法、总的排序方法、比较方法,然后分治排序独有的递归处理方法;
  • 多指针的情况下非常容易弄混;
  • 注意递归的返回条件;

参考资料