zoukankan      html  css  js  c++  java
  • 算法漫游指北(第一篇):什么是数据结构与算法?为什么要学习数据结构与算法?怎么学习数据结构与算法?

    一、什么是数据结构?什么是算法?

    什么是数据结构?

    Sartaj Sahni在他的《数据结构、算法与应用》一书中称:“数据结构是数据对象,以及存在于该对象的实例合组成实例的数据元素之间的各种联系。这些联系可以通过定义相关的函数来给出。”他将数据对象(data object)定义为“一个数据对象是实例或值的集合”。

    Clifford A.Shaffer在《数据结构与算法分析》一书中的定义是:“数据结构是 ADT(抽象数据类型Abstract Data Type) 的物理实现。”

    大话数据结构:数据结构是相互之间存在一种或多种特定关系的数据元素的集合。

    mooc-陈越:数据结构包括数据对象集以及它们在计算机中的组织方式,即它们的逻辑结构和物理存储结构,同时还包括与数据对象集相关的操作集,以及实现这些操作的最高效的算法。

    个人:就是把图书馆中的书转化为一些字符数据存入电脑中,以及对这些数据对象集的操作。如找书,摆放放书等。

    什么是算法?

    还是图书馆的例子,如果一本一本找累死人,要是有个索引,先找哪一类这样会快很多。如何查找其实就是算法。

    算法是解决问题步骤的有限集合,通常用某一种计算机语言进行伪码描述。通常用时间复杂度和空间复杂度来衡量算法的优劣。

    算法的五大特征:输入、输出、有穷性、确定性、可行性。

    输入:零个或多个输入。

    输出:一个或多个输出。

    有穷性:有限步骤后在可接受时间内完成。

    确定性:每个步骤都有确定含义,无二义性。

    可行性:每一步都是可行的。

    算法设计要求:正确性、可读性、健壮性、时间效率高和存储低。

    正确性:有输入输出,无二义性,有正确答案。

    可读性:方便阅读。

    健壮性:输入不合法能处理

    时间效率高和存储低:时间空间复杂度越低越好。

    这就是数据结构和算法。

    数据结构有哪些?

     

    数据结构可以简单分为:排序、链表、列表、生成树、树、图、栈、哈希

     

    抽象数据类型可以分为:栈、队列、集合、映射

    数据结构中英文对照

    Data Structure
    ​
    Array                      数组
    Stack / Queue              栈/队列
    PriorityQueue              优先队列     
    LinkedList                 链表
    Tree / Binary Search Tree  树/二叉搜索树
    HashTable                  哈希表
    Disjoint Set               并查集 
    Trie                       字典树(单词查找树)
    BloomFilter                布隆过滤器
    LRU Cache                  LRU缓存
    ​
    

      

     

    算法有哪些?

    1、十大排序算法

    • 简单排序:插入排序、选择排序、冒泡排序(必学)

    • 分治排序:快速排序、归并排序(必学,快速排序还要关注中轴的选取方式)

    • 分配排序:桶排序、基数排序

    • 树状排序:堆排序(必学)

    • 其他:计数排序(必学)、希尔排序

    2、图论算法

    • 图的表示:邻接矩阵和邻接表

    • 遍历算法:深度搜索和广度搜索(必学)

    • 最短路径算法:Floyd,Dijkstra(必学)

    • 最小生成树算法:Prim,Kruskal(必学)

    • 实际常用算法:关键路径、拓扑排序(原理与应用)

    • 二分图匹配:配对、匈牙利算法(原理与应用)

    • 拓展:中心性算法、社区发现算法(原理与应用)

     

    3、搜索与回溯算法

    • 贪心算法(必学)

    • 启发式搜索算法:A*寻路算法(了解)

    • 地图着色算法、N 皇后问题、最优加工顺序

    • 旅行商问题

     

    4、动态规划

    • 树形DP:01背包问题

    • 线性DP:最长公共子序列、最长公共子串

    • 区间DP:矩阵最大值(和以及积)

    • 数位DP:数字游戏

    • 状态压缩DP:旅行商

     

    5、字符匹配算法

    • 正则表达式

    • 模式匹配:KMP、Boyer-Moore

     

    6、流相关算法

    • 最大流:最短增广路、Dinic 算法

    • 最大流最小割:最大收益问题、方格取数问题

    • 最小费用最大流:最小费用路、消遣

     

    部分算法中英文对照


    Greedy                            贪心算法
    Recursion/Backtrace               递归算法/回溯算法
    Traversal                         遍历算法
    Breadth-first/Depth-first search  广度优先搜索/深度优先搜索
    Divide and Conquer                分而治之法简称分治法
    Dynamic Programming               动态规划
    Graph                             图
    Pre-order/In-order/Post-order traversal   前序/中序/后序遍历
    Binary Search                     二分查找
     
    

      

     

     

    二、为什么要学习数据结构与算法?

    此处省略一万字...

     

    三、怎么学数据结构与算法?

     

    1、刻意练习:

    指的是针对一个模块的知识点,刻意的进行练习,并且要练习自己有缺陷跟弱点的地方,特别是让自己有不舒服、不爽、枯燥的感觉。比如生活中的例子:乒乓球、台球、游戏等等。

     

    2、反馈:

    • 反馈要即时,分如下两种:

    • 主动型反馈:指的是找比自己做得更好的人,他们是如何做的。编程的话,就是阅读大牛的源代码:github, leetcode;还有第一视角的直播。

    • 被动型反馈:指的是高手给你的指点。比如:code review

     

    核心概括一下:

    • 把学习算法和数据结构这个整体进行切分,可以看到是上面这么多种类,根据这些种类来进行学习。

    • 刻意的练习自己的薄弱环节。

    • 看大量的高手代码,刷大量的leetcode题目。

    • 解题的时候要实现所有的方法,比较算法时间和空间复杂度。

     

    3、算法面试面试时的切题四件套

    • Clarification(明确)

    先把题目弄明白,看看有没有什么比较阴险的地方,边界啊范围啊之类的

    • Possible solutions (可能的解决方案)

      • compare(time/space)(比较时间复杂度和空间复杂度)

      • optimal(加强)

      找到尽可能多的解,找到最佳解,多问,多思考

       

    • Coding (多写)

      边学边练,适度刷题,用编辑器或者IDE在本地敲代码

    • Test cases (测试案例)

    看Solutions和Discussions板块学习别人的代码

     

    知识需要沉淀,不要想试图一下子掌握所有,不要一下子学习太多,然后还学的不咋地,最后放弃了。

     

    总结一下就是:我们遇到什么困难,也不要怕,微笑着面对它,消除恐惧的最好办法就是面对恐惧,坚持,才是胜利!加油,奥利给!

    没毛病,干就完了,奥利给!

     

     

     

     

     

    然并卵,哈哈哈。

     

    四、 如何通过LeetCode来进行算法题目练习

    常见练习场景

    场景1

    拿到题目后就开始想着怎么写代码,结果写了大半天,试着做了半天,不对,再继续写,还是不对,f**k,这么难,大sb,不做了

    场景2

    看完题目,这是要干啥,完全不知道怎么下手。

     

    一些微小的算法学习经验

    其实,学算法,刷题蛮干是不行的,需要遵循科学的方法。

    算法不是拼智商

    算法不是纯粹拼智商的,智商高,就一定很厉害,不够聪明,就一定不行。算法是一种技能,是可以通过科学合理的方式训练出来的能力。

    智商的高低,当然会有影响,但这个先天因素无法改变,而科学合理的方法是大家都可以掌握的。

    所以,首要的一点,是要意识到,算法不是只拼智商的,也是可以经由后天训练习得的。

     

    难度要循序渐进

    有些同学喜欢上来就是干,上来就是终极难度的题目,觉得自己只要做出最难的,其它的就迎刃而解了。这种急于求成的思想要不得。

    算法训练是一个系统工程,需要循序渐进,太过于急功近利,反而容易因做不出难题而产生挫败感,带来反效果。

     

    选择题目不要看标签

    不要看标签,不要看标签,不要看标签。标签相当于问题的分类,看了标签就会往那个方向去想,不利于自主思考。

     

    练习时使用番茄时钟

    番茄时钟是啥?百度一下

    分配时间大概如下

     

    第一阶段:

    分析阶段:读完题目,分析大概的要点,可能需要的知识点,此阶段不动手,仅仅动脑。

    在分析推导题目解法的时候,不要去想任何实现相关地事情,不用去想代码怎么写,不用去想要用什么库,定义什么变量,用多少层循环,都不要想,就想着在逻辑上,这道题目要怎么解。

    这样做可以极大地降低你的心智负担,使你高效地想出题目的解法。对于如何将想法变成代码,可以留在下一个步骤,单独来进行。

     

    用时:1个番茄钟,最多2个番茄钟

    重要的一点:如果最多2个番茄钟过完,还是没有任何思路,直接看解法,各种别人的解法,这不是抄答案!

    然后背诵并默写好的解法。直接应用五步刷题法。

    第二阶段:

    验证分析阶段:

    代码写起来,注意一些常见的小错误有:

    • 拼写错误。变量命名要足够清楚,不要用单个字母或者语意不明的单词。

    • 数组边界未考虑。

    • 空值未考虑。

     

    用时:1个番茄钟,最多2个番茄钟。

    注意:

    如果中间发现了分析阶段的错误或者疏漏。应该立即结束编码,休息。

    并且重新开启分析阶段的时钟。

    如果是重新开始分析再次进入代码验证分析阶段,还是做的不对,用时超过3个番茄钟,直接看讨论或者答案。

     

    切忌边写边改方案。如果发现编码过程状态不够好,应该加长休息时间,或者干脆结束掉。不要给自己留下低效的映像。

    去开开心心的玩游戏,看电影吧,哔哩哔哩刷起来,别练习了。

     

     

    第三阶段:

    进行解题分享阶段:

     

    分享时,建议大家就把自己番茄时钟的执行记录进行分享。最后标准的解法以及思路其实在 discussion 中都有。对他人有用的分享不是结果,而是:

    • 你在番茄时钟中是如何规划的,也就是番茄时钟的目标。

    • 你是如何分析,也就是思路。

    • 你的结论是什么,或者是你在执行时除了什么问题。

    • 你所总结出的题目的关键部分。也就是对问题域进行探索的经验。

     

    五步刷题法

    刷题第一遍:

    • 5~10分钟:读题思考

    • 直接看解法,去国际站看最高票的回答

    • 背诵、默写好的解法

    • 多解法,比较解法优劣

    刷题第二遍:

    • 马上自己打开浏览器写->leetcode提交

    • 多种解法比较、体会->优化

    刷题第三遍:

    • 一天后,再重复刷题

    • 不同解法的熟练程度->专项练习 刷题第四遍:

    • 一周后:反复回来练习相同题 刷题第五遍:

    • 面试前一周恢复性训练

       

    认真学习,坚持训练。

     

    最大的误区

    做算法题只做一遍!!!

     

     

    关键的关键

    • 现在就动手

    • 注册LeetCode

    • 练习-坚持-机会给予有准备的人

     

    参考资料

    [1]https://blog.csdn.net/u013164931/article/details/80189351

    [2]https://www.cnblogs.com/kubidemanong/p/11847944.html

    [3]https://blog.csdn.net/weixin_41278720/article/details/90268965

  • 相关阅读:
    .Net常见笔试题
    冒泡排序算法 C#版
    Bundle捆绑压缩技术
    异步Ajax
    HtmlHelper总结
    HtmlHelper的扩展分页方法
    WCF
    程序猿值得看的几个技术网站(记录)
    Struts2和SpringMVC的区别
    nginx配置文件作用介绍
  • 原文地址:https://www.cnblogs.com/Nicholas0707/p/12716512.html
Copyright © 2011-2022 走看看