• 数据结构与算法(Java版) | 几个经典的算法面试题(上)


    大家好啊,我是你们的李阿昀,好久不见了,甚是想念大家!这不,从今儿个开始,我又要给大家开个坑了,从本文的标题大家就能看出来,这次我要给大家讲的就是数据结构与算法(Java版),而且我还特地汇总成了一套系列教程,我有理由相信,本套讲述有关数据结构与算法的教程将有可能会是东半球最系统全面的一套教程,所含文章至少不会少于200篇,如若不信,则就请大家拭目以待吧!

    关于本套系列教程,有三点我需要向大家说明一下,第一点就是本套系列教程主要讲解的是有关数据结构与算法方面的内容,而且还是基于Java语言来进行讲解的,这一点相信我不说,大家也应该都知道了。之所以要向大家说清楚这一点,是因为在大学里面数据结构与算法这门课大多是采用C/C++语言来讲的,想必大家对此应该都有所体会,而本套系列教程则不同,它采用的是目前最流行的编程语言之一,即我们都熟悉的Java语言,这便是我要向大家说明的第一点。

    至于第二点嘛,就是在讲解过程中,我会以图解的形式来帮助大家更好地理解数据结构与算法。

    最后,还有第三点,就是我在向大家讲解数据结构与算法这门课时,不可避免地会用到很多资料,例如Google算法编程大赛里面的一些题,有:

    • 磁盘问题
    • 公交车
    • 画图
    • ······

    另外,就是一些数据结构的经典应用案例了,例如:

    • 银行排队叫号(队列)
    • 汉诺塔
    • 迷宫案例
    • 坦克游戏
    • 小球找家
    • 丢手帕问题
    • ······

    以上这些题或者应用案例,等需要用到的时候,我再来给大家一一进行介绍啊!

    为了勾起大家对数据结构与算法这门课学习的一个兴趣和欲望,下面我会以几个经典的算法面试题作为引子来进行一个暖场。

    字符串匹配问题

    首先,我们来看看第一个经典算法面试题,即字符串匹配问题。

    说有这样一个字符串,即str1 = "阿阿昀 李阿昀你李阿 李阿昀你李阿昀你李阿你好",和另外一个子串,即str2="李阿昀你李阿你",现在要判断str1是否含有str2,如果判断存在,那么就返回str2子串在str1字符串中第一次出现的位置,如果没有,那么则返回-1,并且要求用最快的速度来完成匹配。

    大家好好想一想,如果这道题给到你,你会怎么做呢?

    如果你没有学过算法,例如KMP算法,那么一般来说你是会采用暴力匹配这种方式来进行解决的。大家好好看一下,你是不是会像下面这样来进行暴力匹配?

    先用str2子串中的来匹配str1字符串中的第一个字符,看看能不能匹配成功,结果发现匹配不成功。

    在这里插入图片描述

    于是,继续往下匹配,这时匹配的是str1字符串中的第二个字符,结果发现还是匹配不到。

    在这里插入图片描述

    既然匹配不到,那就只好继续匹配了,这时匹配的便是str1字符串中的第三个字符了,结果发现还是匹配不到。

    在这里插入图片描述

    没办法,那就只好继续再往下匹配了,这时匹配的便是str1字符串中的第四个字符了,发现是一个空格,不用说,还是没匹配到。

    在这里插入图片描述

    啥也别说了,继续往下匹配,这时匹配的是str1字符串中的第五个字符,你会发现终于终于在这儿匹配成功了,可真是不容易啊!

    在这里插入图片描述

    匹配成功之后,再用str2子串中的往后继续匹配str1字符串,结果发现一下子就匹配成功了。

    在这里插入图片描述

    然后,依次使用str2子串中的后续字符往后继续匹配str1字符串,直至最后这个字符为止,你会发现这之前的所有字符都匹配成功了,唯独到最后这个字符去匹配时,匹配就不成功,因为这时它匹配的是一个空格。

    在这里插入图片描述

    这不是完犊子了嘛!是的,情况确实很糟糕,但大家也不要气馁,接下来大家就要好好想一想该怎么去匹配了。

    如果你不曾学过算法的话,那么你肯定是要像下面这样去匹配的,即让str2子串中的各个字符依次去匹配str1字符串中从如下开始的字符,简而言之,就是进行一个回溯。

    在这里插入图片描述

    以上便是一个最简单、最直接的暴力匹配算法,这也是大家最容易想到的一种算法,只不过这种算法有一个巨大的缺陷,那就是由于回溯的次数太多,会导致速度特别的慢。

    痛心的是,如果面试时别人给你一道这样的算法题,你要是使用暴力匹配这种算法去做的话,那么可能你直接就会失去一个工作的机会,因为你给别人的印象就是你压根就不会算法。

    但是,你要是学过KMP算法的话,那么相对来讲事情就会变得简单许多,因为这时你会创建一个部分匹配表,然后通过这个部分匹配表里面的搜索词再去进行一个匹配,如此一来,效率就将会得到大幅度提升。

    至此,关于这个字符串匹配问题,我就先讲到这里,之所以讲这个算法面试题,是因为我想引起大家对算法的高度重视与思考,具体来说,就是你在做算法面试题的时候,会考虑采用什么样的算法去进行解决,当然,速度也要兼顾到。

    汉诺塔游戏

    这里,我们再来看一个经典的算法面试题,即汉诺塔游戏。

    汉诺塔游戏,我相信很多童鞋应该都多多少少听说过,要是没听说过,那也没关系,因为下面我会来简单概述一下该游戏。

    关于汉诺塔游戏,下图应该可以大致描述出来。

    在这里插入图片描述

    总体来说,它的要求还是很简单的,如下:

    1. 将A塔的所有圆盘移动到C塔。可以看到,上图中A塔一共有5个圆盘,其实,圆盘的个数不止这么少,最多的时候有64个这么多。
    2. 并且规定小圆盘上不能放大圆盘。也就是说,在移动的整个过程中,大圆盘是不可以放在小圆盘上的。
    3. 此外,还规定在三根柱子之间一次只能移动一个圆盘。

    童鞋们,试想一下,如果是你,那么你会怎么把A塔的所有圆盘移动到C塔呢?说说你的思路。

    要不下面我们来玩一把这个汉诺塔游戏吧!不过,为了图方便,这里我会先给大家演示一个A塔上有3个圆盘的汉诺塔游戏,如下。

    在这里插入图片描述

    这时,大家不妨开动脑筋想一下,如果想把A塔上的3个圆盘全部移动到C塔,那么具体思路应该是什么样子的呢?

    我想大部分同学的思路应该很简单,无非就是下面这样子的。

    • 第一步:先想办法把A塔最上面的两个圆盘移动到B塔。
    • 第二步:然后再把A塔最底层的那个圆盘移动到C塔。
    • 第三步:接着再想办法把B塔上的两个圆盘移动到C塔。

    知晓思路之后,接下来我们就来玩一把吧!

    首先,把A塔最上面的两个圆盘移动到B塔,分三步完成。

    1. 先把A塔最上面的那个圆盘移动到C塔。

      在这里插入图片描述

    2. 再把A塔中间的那个圆盘移动到B塔。

      在这里插入图片描述

    3. 最后再把C塔上的圆盘移动到B塔。

      在这里插入图片描述

    注意,之所以要这么移动,是因为我们得遵循一个规定,即在圆盘移动的整个过程中,小圆盘上不得放大圆盘。

    然后,再把A塔最底层的那个圆盘移动到C塔。

    在这里插入图片描述

    最后,再把B塔上的两个圆盘移动到C塔,同样也是分三步完成。

    1. 先把B塔最上面的那个圆盘移动到A塔。

      在这里插入图片描述

    2. 再把B塔上的圆盘移动到C塔。

      在这里插入图片描述

    3. 最后再把A塔上的圆盘移动到C塔。

      在这里插入图片描述

    是不是还是挺简单的啊!各位,只要你智商正常,移动3个圆盘还是毫无压力的!

    但是,问题来了,如果A塔上有4个圆盘或者5个圆盘需要你来移动,那么这时你又该怎么办呢?不妨接下来我再来给大家演示一个A塔上有4个圆盘的汉诺塔游戏吧!

    在这里插入图片描述

    不过,由于这时圆盘较多,所以圆盘移动的步骤还是比较繁琐的,嘻嘻😂!

    大家现在思索一下,如果想把A塔上的4个圆盘全部移动到C塔,那么具体思路又该是什么样子的呢?是不是和上面的思路一样啊!就是你得先想办法把A塔最上面的三个圆盘移动到B塔,然后再把A塔最底层的那个圆盘移动到C塔,最后再想办法把B塔的三个圆盘移动到C塔,这不就完事了嘛!其实,你只要会移动三个圆盘,那么照理来说四个圆盘你也应该也是会移动的。

    于是,大家可能就要问了,如果把A塔上的4个圆盘全部移动到C塔,那么这一共得经历多少步啊?这里我提前告诉大家,一共得经历15步,是不是特别繁琐,哈哈哈😄,虽然听起来有点吓人,但是对于我们人来说还是勉强能接受的。下面,我就要正式地来玩一把了,大家可千万一定要跟上我的思路哟!

    第一步,把A塔最上面的那个圆盘移动到B塔。

    在这里插入图片描述

    第二步,再把A塔最上面的那个圆盘移动到C塔。

    在这里插入图片描述

    第三步,把B塔上的那个圆盘移动到C塔。

    在这里插入图片描述

    第四步,再把A塔最上面的那个圆盘移动到B塔。

    在这里插入图片描述

    第五步,把C塔最上面的那个圆盘移动到A塔。

    在这里插入图片描述

    第六步,再把C塔上的那个圆盘移动到B塔。

    在这里插入图片描述

    第七步,把A塔最上面的那个圆盘移动到B塔。

    在这里插入图片描述

    至此,我们就把A塔最上面的那三个圆盘移动到了B塔。

    第八步,把A塔上的那个圆盘移动到C塔。

    在这里插入图片描述

    第九步,把B塔最上面的那个圆盘移动到C塔。

    在这里插入图片描述

    第十步,再把B塔最上面的那个圆盘移动到A塔。

    在这里插入图片描述

    第十一步,把C塔最上面的那个圆盘移动到A塔。

    在这里插入图片描述

    第十二步,把B塔上的那个圆盘移动到C塔。

    在这里插入图片描述

    第十三步,把A塔最上面的那个圆盘移动到B塔。

    在这里插入图片描述

    第十四步,再把A塔上的那个圆盘移动到C塔。

    在这里插入图片描述

    第十五步,把B塔上的那个圆盘移动到C塔。

    在这里插入图片描述

    至此,圆盘移动完毕,一共移动了15步。

    移动4个圆盘你是搞定了,但是别人要是给你出个题,让你移动5个圆盘,甚至更多,比如20个圆盘,你还搞得定嘛?5个圆盘多少还说得过去,但是要移动20个圆盘那就很麻烦了,因为对于咱们人来讲,大脑可能都反应不过来,所以这个时候算法的重要性就凸显出来了,也就是说,我们得需要使用算法来编程解决汉诺塔游戏问题。

    那么,有童鞋可能就要问了,具体应该使用什么算法呢?应该使用分治算法,也就是说,汉诺塔游戏这个经典算法面试题需要使用分治算法来进行解决。总之,算法无处不在!

  • 相关阅读:
    JavaScript - async 和 await 修饰符的基本使用方法
    《六》BFC
    Linux多线程C++版(七) 线程互斥方式-----读写锁
    MySQL高级SQL语句
    Java 全新生态的框架,Solon v1.10.12 发布
    vue3 script setup 使用tinymce富文本编辑器-f
    MyBatisPlus实现分页和查询操作就这么简单
    ES8(Java API Client)查询详解
    springmvc视图格式——模板引擎freemarker输出HTML文本
    CUMT-----Java课后第七章编程作业
  • 原文地址:https://blog.csdn.net/yerenyuan_pku/article/details/128190852