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

  • 相关阅读:
    CSS中position小解
    position
    mac默认安装postgresql, 如何让postgresql可以远程访问
    The data directory was initialized by PostgreSQL version 9.6, which is not compatible with this version 10.0.
    active admin gem error
    psql 无法添加超级用户
    ubuntu 15.04 安装Balsamiq Mockups 3
    Rails html 写public里图片的路径
    rails c 历史命令
    undefined local variable or method `per' for []:ActiveRecord::Relation
  • 原文地址:https://www.cnblogs.com/Nicholas0707/p/12716512.html
Copyright © 2011-2022 走看看