程序员代码面试指南题目解析(一)

        题目一:如何仅用递归函数和栈操作逆序一个栈

      题目要求:

    一个栈依次压入 1、2、3、4、5,那么从栈顶到栈底分别为5、4、3、2、1。将这个栈
转置后,从栈顶到栈底为 1、2、3、4、5,也就是实现栈中元素的逆序,但是只能用递归函数来实现,不能用其他数据结构。

      题目解析:

   根据题目要求,我们需要使用递归函数,依次将栈中的元素进行逆置出来。我们可以根据递归函数所可能产生的影响进行问题的解决。

   由于递归函数在递归的结束的时候可以进行返回,所以我们如果拿到一个数据并删除的话,在最后返回的时候会拿到最后一个数据。所进行的操作如下:

  如果想要将数组进行逆序仅仅拿到最后一个数据是完全不够的,我们还需要思考如何将一个数组进行逆序,这个思路其实很简单。我们可以再次使用一次递归操作,每次拿出最下面的数据,并保存,之后我们递归返回的时候就可以拿到最上面的数据了。我们将数据依次压入栈中就会得到一个逆序的栈。

    根据上述思路我们可以设计两个递归函数实现栈的逆序操作,实现代码如下:

#include<iostream>
#include<stack>
using namespace std;int getAndRemoveLastElem(stack<int>& sk)
{int result = sk.top();sk.pop();if (sk.empty()){return result;}else{//继续进行递归删除操作int last = getAndRemoveLastElem(sk);sk.push(result);return last;}
}//最后通过调用递归函数
void StackReverseStack(stack<int>& sk)
{if (sk.empty()){return;}int i = getAndRemoveLastElem(sk);StackReverseStack(sk);sk.push(i);
}int main()
{stack<int> ret;ret.push(1);ret.push(2);ret.push(3);ret.push(4);ret.push(5);StackReverseStack(ret);//之后打印输出栈当中的内容检查逆序的状况while (!ret.empty()){cout << ret.top() << endl;ret.pop();}return 0;
}

        题目二:用栈来求解汉诺塔问题

      题目要求: 
   汉诺塔问题比较经典,这里修改一下游戏规则:现在限制不能从最左侧的塔直接移动
到最右侧,也不能从最右侧直接移动到最左侧,而是必须经过中间。求当塔有 N层的时候,需要最少移动多少步。

    题目解析:

    这道题我们可以将其认为是一个简单的模拟类的题目,首先我们来分析问题:

    题目当中要求我们所进行的移动的步数是最少的,因此不允许由连续的可逆的步骤存在。例如:上一步从左到中间进行移动,下一步就从中间到左进行移动。这样上一步移动的步骤就是完全没有效果的,不可能是最少的移动次数。

   其次,题目当中要求我们在移动的时候必须经过中间,因此我们可以判断,当两个柱子进行移动完成之后(其中一个柱子一定是中间的柱子)一定是中间的柱子和另外一个没有进行移动的柱子进行移动操作,无非就是从中间移动到目标位置,或者从目标位置移动到中间。我们只需要符合汉诺塔的规则即可,也就是小的数据必须在大的数据之上才可以进行移动。所进行的示例如下:

    我们可以设置两个变量用于作为记录两个变化的柱子的情况,之后排除中间的柱子,让另一根柱子跟中间柱子进行数据的移动即可。根据上述思路我们可以写出如下代码:

#include<iostream>
#include<stack>
#include<vector>
#include<string>
using namespace std;
//使用栈进行解决汉诺塔问题
int stackSloveHanio(int data)
{stack<int> left;while (data){left.push(data);data--;}stack<int> mid;stack<int> right;//经过第一次初始化之后进行统一的数据操作int from = 1;int to = 2;     //使用1,2,3表示左中右三个柱子int x = left.top();left.pop();mid.push(x);int count = 1;//之后检查三个柱子的情况得到最终想要的结果while (!left.empty() || !mid.empty()){//当左边跟中间的柱子都不为空的时候就继续循环查找新的初始情况//由判断可知,我们的from和to无论怎么移动一定与中间柱子有关,//因此我们只需要查找中间柱子跟另外一个没有用到的柱子的移动方向即可int tmp = from;if (from == 2){tmp = to;}if (tmp == 1)  //下一次进行的操作就需要是从另外一个柱子跟中间柱子移动数据{//判断3柱子移动到中间,还是从中间移动到3柱子if (!right.empty()&&(mid.empty() || right.top() < mid.top())){//从3移动到2mid.push(right.top());right.pop();from = 3;to = 2;}else{//从2移动到3right.push(mid.top());mid.pop();from = 2;to = 3;}count++;}if (tmp == 3){//同理可得if (!left.empty()&&(mid.empty() || left.top() < mid.top())){mid.push(left.top());left.pop();from = 1;to = 2;}else{left.push(mid.top());mid.pop();from = 2;to = 1;}count++;}}return count;
}
int main()
{cout<<stackSloveHanio(3);return 0;
}

        题目三:生成窗口最大值数组

      题目要求:
  有一个整型数组 arr 和一个大小为 w 的窗口从数组的最左边滑到最右边,窗口每次向
右边滑一个位置。
例如,数组为[4,3,5,4.3,3,6,7],窗口大小为 3 时:
[4 3 5] 4 3 3 6 7          窗口中最大值为 5
4 [3 5 4] 3 3 6 7          窗口中最大值为 5
4 3 [5 4 3] 3 6 7          窗口中最大值为 5
4 3 5 14 3 3] 6 7         窗口中最大值为 4
4 3 5 4 [3 3 6] 7          窗口中最大值为 6
4 3 5 4 3 [3 6 7]          窗口中最大值为 7
如果数组长度为 n,窗口大小为 w,则一共产生 n-w+1 个窗口的最大值。

请实现一个函数。
•输入:整型数组 arr,窗口大小为 w.
•输出:一个长度为 n-W+1 的数组 res,res[i]表示每一种窗口状态下的最大值。
以本题为例,结果应该返回{5,5,5,4,6,7}。

     题目解析:

   这道题目实际上想要让我们进行的操作也就是根据指定的窗口依次选出窗口内元素的最大值。拿到这道题目的时候我们首先会有一个思路:直接进行模拟不久行了嘛,每次有新的数据进入窗口的时候进行一次遍历,得到最大的值,加入到数组当中。但是我们来思考一下时间复杂度:每一次遍历窗口一遍,假设窗口的大小为M,数据总共N个,所以我们总的时间复杂度为O(MN)这并不是一个很好的算法,因此我们需要进行优化。

  书中有一个很奇妙的思想:试想一下,在我们的窗口当中有新加入的元素,当新加入的元素较大的时候前面较小的元素就不可能是最大的元素,我们可以直接前面较小的数据删除。当新加入的数据较小的时候,当前面较大的数据删除之后,那么这个暂时较小的数据就有可能是最大的了。所以我们需要将数据保存。

  借助双端队列进行优化我们的代码。我们可以进行一次数组遍历,当队列为空或者新数据小于队列尾部的数据的时候可以直接将数据的下标加入到队列的尾部,当新数据大于队列尾部的数据的时候,直接将队列尾部的数据进行弹出数据。知道队列当中的数据大于新数据或者队列为空为止。所要进行的操作如下:

    需要注意的是:由于为了方便我们判断数据的加入以及输出的边界条件,因此我们需要将数组的下标作为加入队列的元素。当我们的队头元素小于我们窗口最左侧元素的下标的时候就说明数据已经失效,需要将队头数据删除,获得下一个窗口当中最大的元素。根据上述思路我们可以编写出如下的代码:

#include<iostream>
#include<vector>
#include<queue>
using namespace std;//编写一个函数,用于查找生成窗口最大值的数组
vector<int> createMaxWindow(vector<int> ret, int windows)
{//我们需要借助一个栈进行解决这个问题deque<int> dq;vector<int> finEnd;int count = windows;//进行数据的遍历操作,将我们数组当中的内容的下标依次放到栈当中,如果之后进入的数据大于之前的数据//就直接进行入栈操作,否则需要先执行出栈操作,等到满足小于之前的元素的时候就可以执行入栈操作了for (int i=0;i<ret.size();i++){while (!dq.empty()&&ret[i]>ret[dq.front()]){dq.pop_back();}dq.push_back(i);//之前向栈当中插入的元素还不满,不能直接进行记录最大值if ( count== 1){//进行检查并返回最大值,检查栈顶的最大值是否过期while (i - windows >= dq.front()){dq.pop_front();    //删除过期的最大值}//找到不过期的数据直接进行记录队头元素finEnd.push_back(ret[dq.front()]);}else{count--;}}return finEnd;
}int main()
{//进行测试最大生成窗口代码vector<int> ret({ 1,2,3,4,5,6,7,8,9 });vector<int> tmp=createMaxWindow(ret, 5);for (auto e : tmp){cout << e << " ";}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/689590.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Python系列】字节串与字典字节串

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

在Linux上安装并运行RabbitMQ

目录 准备CentOS服务器 下载rabbit-server和erlang文件 启动RabbitMQ服务 准备CentOS服务器 两个命令&#xff0c;选一个能用的&#xff0c;查看CentOS服务器的版本 lsb_release -a下载rabbit-server和erlang文件 参考文章&#xff1a;http://t.csdnimg.cn/t8BbM 1、创建新…

MySQL innodb_buffer_pool_size 相关常用语句

对于MySQL速度慢的问题&#xff0c;除了优化 SQL 以外&#xff0c;应该必须优先想到的即使 MySQL 数据库的 innodb_buffer_pool_size 配置问题。 一般来说&#xff0c;innodb_buffer_pool_size 的默认大小都是很小的&#xff0c;尤其是 win 下其默认大小更是只有离谱的 8M。Li…

【C/C++笔试练习】DNS设置文件、应用层、Dos攻击、DNS服务、DNS、子网划分、http状态、路由设置、TCP连接、HTTP状态码、剪花布条、客似云来

文章目录 C/C笔试练习选择部分&#xff08;1&#xff09;DNS设置文件&#xff08;2&#xff09;应用层&#xff08;3&#xff09;Dos攻击&#xff08;4&#xff09;DNS服务&#xff08;5&#xff09;DNS&#xff08;6&#xff09;子网划分&#xff08;7&#xff09;http状态&am…

ios 开发如何给项目安装第三方库,以websocket库 SocketRocket 为例

1.brew 安装 cococapods $ brew install cocoapods 2、找到xcode项目 的根目录&#xff0c;如图&#xff0c;在根目录下创建Podfile 文件 3、在Podfile文件中写入 platform :ios, 13.0 use_frameworks! target chat_app do pod SocketRocket end project ../chat_app.x…

Flink DataSink介绍

介绍 Flink DataSink是Apache Flink框架中的一个重要组件&#xff0c;它定义了数据流经过一系列处理后最终的输出位置。以下是关于Flink DataSink的详细介绍&#xff1a; 概念&#xff1a;DataSink主要负责对经过Flink处理后的流进行一系列操作&#xff0c;并将计算后的数据结…

GPT-SoVits:语音克隆,语音融合

首发网站 https://tianfeng.space 前言 零样本文本到语音&#xff08;TTS&#xff09;&#xff1a; 输入 5 秒的声音样本&#xff0c;即刻体验文本到语音转换。少样本 TTS&#xff1a; 仅需 1 分钟的训练数据即可微调模型&#xff0c;提升声音相似度和真实感。跨语言支持&…

去哪里找高清视频素材?推荐几个短视频素材免费网站

在数字时代&#xff0c;视频内容的质量直接影响观众的吸引力和留存率。尤其是高清、4K视频素材和可商用素材&#xff0c;它们在提升视觉质量和叙事深度方面起到了至关重要的作用。以下是一些国内外的顶级视频素材网站&#xff0c;它们提供的资源将为您的创作提供极大的支持和灵…

OGG几何内核开发-BRepAlgoAPI_Fuse与BRep_Builder.MakeCompound比较

最近在与同事讨论BRepAlgoAPI_Fuse与BRep_Builder.MakeCompound有什么区别。 一、从直觉上来说&#xff0c;BRepAlgoAPI_Fuse会对两个实体相交处理&#xff0c;相交的部分会重新的生成相关的曲面。而BRep_Builder.MakeCompound仅仅是把两个实体组合成一个新的实体&#xff0c;…

VTK官方示例

VTK官方示例 -vtk字體 #!/usr/bin/env python# noinspection PyUnresolvedReferences import vtkmodules.vtkInteractionStyle # noinspection PyUnresolvedReferences import vtkmodules.vtkRenderingFreeType # noinspection PyUnresolvedReferences import vtkmodules.vtk…

matlab的imclose()详解

J imclose(I,SE) J imclose(I,nhood) 说明 J imclose(I,SE) 使用结构元素 SE 对灰度或二值图像 I 执行形态学闭运算。形态学闭运算是先膨胀后腐蚀&#xff0c;这两种运算使用相同的结构元素。 J imclose(I,nhood) 对图像 I 执行闭运算&#xff0c;其中 nhood 是由指定结…

配置Docker对象与管理守护进程

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 本章节的快速目录导航&#xff1a; 一、配置Docker对象 1.1、Docker对象的标记 1.2、格式化命令和日志的输出 二、示例&#xff1a; 2.1、管理…