记清华LabmU校园极客社面试

OpenCV实现图像搜索引擎(Image Search Engine) OpenCV(Open Source Computer Vision Library)的计算效率很高且能够完成实时任务。OpenCV库由优化的C/C++代码编写而成,能够充分发挥多核处理和硬件加速的优势。OpenCV有大量技术社区和超过900万的下载量,它的使用范围极为广泛,如人机互动、资源检查、拼接地图等。 阅读详情

今天参加了清华LabmU校园极客社的面试。面试时间不长,主要问了掌握哪些技术以及参与项目的意向。但问了几个有关数据结构的问题还算有趣。和大家分享一下。

问题一:如何用两个栈实现一个队列,要求均摊O(1)时间复杂度。

问题二:如何实时获得一个栈中元素的最小(大)值。注意不取出,只需知道最值。也就是实现一个随时都能知道栈中最小值的特殊栈。

问题三:如何实时获得一个队列中元素的最小(大)值。注意不取出,只需知道最值。也就是实现一个随时都能知道栈中最小值的特殊队列。


分析:

(1)问题一:

这个问题比较简单。假设栈A和栈B,容量分别为m和n(要求m<=n)。

入队操作:将元素压入栈A。

出队操作:如栈B非空,则弹栈,弹出元素为出队元素;如栈B为空,则将栈A中所有元素弹出并压入栈B,同时将B中栈顶元素弹出。

应注意2点:

a) 栈A和栈B实现的队列容量为m+1。可以这样考虑,当栈A中有2个元素而栈B为空时,做出队操作。此后,B中有1个元素,A为空。此时入队m个元素。此时无法再入队。所以认为极限情况下保证安全的队列容量为m+1。

b) m<=n。如m>n,当栈A满时,无法将所有栈A中元素弹栈并压入栈B。

具体实现:

<span style="font-size:14px;">#include <iostream>
#include <stack>
using namespace std;

template <typename type>
class twoStacksQueue {
public:
	void push(type item) {
		stka.push(item);	
	}
	type pop() {//简化实现, 没有考虑队空的情况
		type item;
		if (stkb.empty()) {
			while (!stka.empty()) {
				item = stka.top(); stka.pop();
				stkb.push(item);
			}
		}
		item = stkb.top(); stkb.pop();
		return item;
	}
private:
	stack<type> stka, stkb;
};
int main() {
	twoStacksQueue<int> que;
	int item;
	que.push(1); que.push(2);que.push(6);
	for (int i = 0; i != 3; ++i) {
		cout << que.pop() << " ";
	}
	return 0;
}</span>

(2)问题二:

这个问题并不难,考虑最小值,只需维护一个最小值栈minstack即可。设辅助栈minstk。

入栈操作:

当主栈有元素E入栈时,比较minstk栈顶元素A与元素E,如A>=E,则主栈和辅助栈minstk都压入元素E。如A<E,则只在主栈中压入元素E。

出栈操作:

当主栈需要出栈时,将主栈栈顶元素E弹出,同时比较minstk栈顶元素A与元素E。如A=E,那么minstk也弹栈;如E>A,则minstk不做任何操作。

取最小值操作:栈顶元素就是最小值。

上述三个操作就实现了一个随时都能知道栈中最小值的特殊栈。

注意:

如果对辅助栈的深度有要求且相同元素较多的情况,可以采用设置一个最小值计数栈的方法优化。

此题与leetcode的minstack相同,直接放上leetcode的实现代码:

struct minStkNode {
    int count, curmin;//记录当前最小值和出现的次数
    minStkNode(int min): count(1), curmin(min) {}
};
class MinStack {
public:
    void push(int x) {
        stk.push(x);
        if (minstk.empty())
            minstk.push(minStkNode(x));
        else {
            auto &minval = minstk.top();
            if (minval.curmin > x)
                minstk.push(minStkNode(x));
            else if (minval.curmin == x)
                ++minval.count;
        }
    }

    void pop() {
        int cur = stk.top(); stk.pop();
        auto &minval = minstk.top();//此处使用引用, 直接修改minstk的栈顶元素, 而非创建其副本
        if (cur == minval.curmin && --minval.count == 0)
            minstk.pop();
    }

    int top() {
        return stk.top();
    }

    int getMin() {
        return minstk.top().curmin;
    }
private:
    stack<int> stk;
    stack<minStkNode> minstk;
};

(3)问题三:

这题应该是三道题中最难的一道。这个问题需要一种特殊的数据结构:单调队列。单调队列能够维护一个下界不减的一个数据区间内的最值。

这里先解释一下什么叫做下界不减。假设一个数组arr[10] = {1, 4, 2, 7, 8, 6, 5, 4, 3, 9};

INDEX

0

1

2

3

4

5

6

7

8

9

VALUE

1

4

2

7

8

6

5

4

3

9

这里下界不减表示,在一个动态求某个范围内最小值的过程中,范围的下界不会减小。比如这样一个过程,我需要知道(0,1)->(0, 3)->(2, 4)->(2,7)->(3, 8)->(7, 9)。格式(BOTTOM, TOP)表示从index=BOTTOM到index=TOP范围内的最小值。我们可以发现下界是这样增长的0->0->2->2->3->7。

当然,高中信息竞赛中有一道题也是用单调队列完成。要求求出一个数组中范围宽度为d的最小值集合。

单调队列的出入队操作:

需要维护一个下标队列和单调递增队列。

入队操作:

比较入队元素A与队尾元素B,如A>=B,则将A送入单调队列,同时将元素A的下标送入下标队列;如A<B,则将队尾B出队,同时B的下标也要从下标队列的队尾出队(普通队列不支持队尾出队操作,因此使用vector实现),继续比较A与新的队尾元素,重复步骤直到A>=B时将A入队,同时注意将A的下标送入下标队列。

出队操作:

比较所需范围的下界bottom和当前下标队列的队头元素值head,如head<bottom则将下标队列队头元素出队,对应单调队列中的队头也出队,重复上述步骤直到bottom<=head,此时单调队列中的队头元素即为所求范围内的最小值。

根据出队的操作,我们可以发现,下标队列的队头元素出队会导致下标队列的队头元素不断增大(下标队列中的下标值也是递增的),这就是为什么我们要求下界不减的原因。

注意:

a) 单调队列和下标队列中,单调队列中的元素值和下标队列中对应位置的下标是一一对应的。

b) 另外我们应该确认一点,任一一个时刻单调队列的队头元素是当前范围内的最小值。

 

科普完单调队列,现在我们来看一看问题三。只要我们在对队列进行入队出队操作时,同样对这样一个单调递增队列也做相应操作就可以了。

具体步骤:

假设原队列叫A,单调队列称为B,这题不需要下标队列。

入队操作:队A入队,同时队B也入队(不是普通的入队操作,而是单调队列的入队,具体看上面);

出队操作:队A出队,出队元素为item,比较item和队B队头元素head,如item=head,队B也出队,如item>head,队B不做任何操作。

取最小值操作:队B的队头元素值就是最小值。

上述三个操作就实现了一个随时可以知道队列中最小值的特殊队列。

具体实现:

 

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

template <typename type>
class minQueue {
public:
	void push(const type&);
	type front();
	void pop();
	type extractMin();
	bool empty() {
		return que.empty();
	}
private:
	queue<type> que;
	vector<type> minque;
};
template <typename type>
void minQueue<type>::push(const type& item) {
	que.push(item);
	while (!minque.empty() && minque.back() > item) {
		minque.pop_back();
	}
	minque.push_back(item);
}
template <typename type>
type minQueue<type>::front() {
	return que.front();
}
template <typename type>
void minQueue<type>::pop() {
	type item = que.front(); que.pop();
	if (item == minque.front()) {
		minque.erase(minque.begin());
	}
}
template <typename type>
type minQueue<type>::extractMin() {
	return minque.front();
}

int main() {
	minQueue<int> minq;
	int item;
	for (int i = 0; i != 10; ++i) {
		cin >> item;
		minq.push(item);
	}
	while (!minq.empty()) {
		cout << "current minval: " << minq.extractMin() << endl;
		minq.pop();
	}
	return 0;
}
如有错误,请批评指正,谢谢!
使用 Cynthion 与 Packetry 进行 USB 抓包与协议分析 Cynthion 是 Great Scott Gadgets 推出的USB 流量分析与注入设备。它具备以下特点:通过 FPGA 实现高速 USB 流量捕获;能够同时作为 USB Host 和 Device,进行调试和测试;支持输出 pcap 文件,可直接用 Wireshark 分析;提供 Python API,方便与上层软件联动。简单来说,Cynthion 是一个USB 协议分析仪 + 注入工具。硬件层捕获:实时拦截 USB 总线上的数据包;软件层解析。 阅读详情

相关推荐

如何快速学习 PHP 编程:从入门到实战的高效路径

PHP高效学习路线摘要:4-8周掌握Web开发核心技能。阶段1(1周)搭建XAMPP/MAMP环境,掌握基础语法和变量处理;阶段2(2周)重点学习表单处理、会话管理和PDO数据库操作(防SQL注入);阶段3(2-3周)实战开发个人博客等小项目。关键原则:边学边练(每个知识点配3-5个案例)、优先掌握Web刚需技能(HTTP请求、数据库、动态页面)、善用官方手册。避坑点:密码必须加密、SQL使用预处理、统一UTF-8编码。建议每天2-3小时实操,通过项目驱动学习,快速形成开发能力。

2501_94233638的博客 1387

Windows 8 应用开发实践——labmu版Tunet(一):功能设计

基本功能如同Android上的labmu版Tunet: 首次启动:输入账号、密码界面 验证失败:提示 验证成功:进入主界面 之后启动均进入主界面: 主界面包含流量、费用等账户信息,连接管理 连接管理是一个设备列表,包含了已连接设备和已经记忆的未连接设备 点击连接可以查看连接信息 后台运行: 开机自动启动(可设置) 启动后连接到校内

cgcgbcbc的专栏 753

CarPlay无线连接开发实战:从蓝牙EIR查询到iAP2认证的完整代码逻辑梳理

本文详细解析了无线CarPlay连接开发的完整流程,从蓝牙EIR查询到iAP2认证的代码实现。重点介绍了蓝牙握手、WiFi Beacon帧配置、热点信息准备等关键环节的实战技巧,帮助开发者快速搭建稳定可靠的无线CarPlay连接系统。

weixin_31534091的博客 318

聚类算法概述(k-Means++/FCM/凝聚层次聚类/DBSCAN)

欢迎光临我的博客:HaoyuHu’s Blog 近期做完了labmu的tunet3.0,总算有时间学习一些东西了。目前想学的有聚类分析、图像识别算法和计算机网络方面的知识。在暑假实习期间,开始着手游戏编程。聚类的目的将数据划分为若干个簇,簇内相似性大,簇间相似性小,聚类效果好。用于从数据中提取信息和规律。

coderhuhy的专栏 1万+

STM32鱼塘水质监测系统设计与实现

物联网技术在农业领域的应用正逐步深入,其中传感器网络作为关键基础设施,通过实时数据采集与传输实现环境监测。基于STM32微控制器的嵌入式系统因其高性能和低功耗特性,成为物联网终端设备的理想选择。该系统通过DS18B20水温传感器、PH传感器和浊度传感器组成的多参数检测网络,配合4G通信模块实现水质数据的远程监控。在农业物联网场景中,这种解决方案不仅大幅降低了传统人工检测的成本,更能通过实时预警有效预防养殖损失。本文介绍的鱼塘水质监测系统正是这一技术的典型应用,展示了如何通过STM32和常见传感器构建高性价比

weixin_42173218的博客 620

Flowable第一篇、快速上手(Flowable安装、配置、集成)

Flowable是一个轻量级、高效可扩展的工作流和业务流程管理(BPM)引擎,支持在Java应用程序中实现复杂的工作流自动化。Flowable最初是作为Activiti项目的一个分支发展而来的,但它现在已经成为一个独立的开源项目,并在企业级应用中得到了广泛使用

Du_XiaoNan的博客 1万+

Leetcode Repeated DNA Sequences

Leetcode Repeated DNA Sequences

coderhuhy的专栏 4012

用Isaac Sim复现经典案例:手把手教你写Python脚本控制机械臂抓取(附避障算法调试心得)

本文详细介绍了如何使用NVIDIA Isaac Sim仿真系统复现机械臂抓取经典案例,包括Python脚本编写、避障算法调试等关键步骤。通过URDF模型导入、关节控制逻辑实现和RMPFlow避障配置等实战演示,帮助开发者快速掌握机器人仿真技术,特别分享了官方文档未提及的实用调试技巧和性能优化策略。

weixin_30632089的博客 406

A-star算法概述及其在游戏开发中的应用分析

回想起曾学习A*寻径算法时,难以透彻理解其原理和机制,但随着对图和搜索算法的理解愈发深入,近期重拾A-star时发现并没有那么困难。因此对A*算法和A*变种算法进行系统地学习,同时对其在游戏开发中的应用做了更深层次上的了解。 A*算法很巧妙地结合了Dijkstra算法和Best-fit算法的优点,一方面通过设定代价函数g(x)来考虑从起始点到当前点的实际代价,另一方面通过设定启发式函数h(x)来考虑从当前点到目的地的估计代价,f(x) = g(x) + h(x)。它是从当前点击中取出f值最小的节点并进行拓展

coderhuhy的专栏 2860

【Simscape】用Simscape实现三维物理仿真(三)——创建一个滑块单摆系统

1 首先创建一个Simscape Multibody 模型 (方法见 【Simscape】用Simscape实现三维物理仿真(一)——创建一个自由落体小球) 2 创建四个Solid模块 (1)摆杆 Shape : Brick Dimensions : [0.1 0.05 1] m (2)摆杆轴 Shape : Cylinder Radius : 0.02 m Le...

ReadAir的专栏 9036

MySQL常见面试题汇总(建议收藏!!!)

目录一、索引相关(1)什么是索引?(2)索引是个什么样的数据结构呢?(3)为什么使用索引?(4)Innodb为什么要用自增id作为主键?(5)Hash 索引和 B+ 树索引有什么区别或者说优劣呢?(6)什么是聚簇索引(6)非聚簇索引一定会回表查询吗?(6)聚簇索引和非聚簇索引的区别(6)MyISAM和InnoDB实现B+树索引方式的区别是什么?(6)MySQL中有四种索引类型,可以简单说说吗?(6)覆盖索引是什么?(6)联合索引是什么?为什么需要注意联合索引中的顺序?(6)创建的索引有没有被使用到?或者说怎

蔡政洁的博客 7万+

python实现清华大学联网助手(三)——linux下带参数的自定义命令/import机制

上两篇已经大致满足了我起初设计的需求。 最后,对代码进行了一些优化,并且修改代码使一些函数方法可以重用。最终实现了如下功能:登录校园网、登出校园网、查询当前网络状态、查询流量、帐户余额、当前用户组等基本信息、查询本账号当前在线IP信息、查询每日流量使用明细并生成直方图。 本篇主要探讨两个问题: 1 如何将.py脚本制作成linux下带参数的自定义命令; 2 import机制及使用。

coderhuhy的专栏 2763

台球 PCOL:极致物理还原的网页斯诺克引擎(附源码深度解析)

*完整源码地址**:[https://github.com/billiards/pcol-core](https://github.com/billiards/pcol-core)(包含详细文档与示例)通过这个项目,我们不仅创建了一个游戏,更构建了一个**可扩展的物理引擎框架**,为网页端复杂物理模拟开辟了新的可能性。**在线体验**:[https://pcol.billiards](https://pcol.billiards)(支持移动端触控操作)clone.velocity.x *= -0.92;

Loving_enjoy的博客 2797

左偏树leftistTree和斜堆skewHeap的分析和实现

今天主要分析一下左偏树和斜堆, 这两个数据结构是二叉堆的进化版, 一方面能够实现与二叉堆相同的功能, 代码结构也比较简单; 另一方面它们的合并操作的时间复杂度为O(logn), 而普通二叉堆实现合并操作的时间复杂度为O(n);

coderhuhy的专栏 2576

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

python实现清华大学联网助手(一)——urllib/hashlib/getopt/time/codecs的使用

python版清华大学联网助手 github:https://github.com/HaoyuHu/python urllib/hashlib/getopt/getpass/time/codecs的使用分析和实例代码。 学习完python之后,能够明白它的语法和特性,感觉这是一种与C/C++和java截然不同的语言,它更高级,更接近自然语言。所以能通过极少的代码完成其他语言需要几百行代码才能完成的任务。前些阵子曾经用python从各大网站上抓取信息用作分析数据,觉得挺过瘾。因此为了满足在linux下快速连接

coderhuhy的专栏 2384

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

建堆O(n)时间复杂度证明

建堆复杂度先考虑满二叉树,计算完全二叉树建堆复杂度基本相同。对满二叉树而言,第i层(根为第0层)有2^i个节点。由于建堆过程自底向上,以交换作为主要操作,因此第i层任意节点在最不利情况下,需要经过(n-i)次交换操作才能完成以该节点为堆根节点的建堆过程。

coderhuhy的专栏 2144

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

python实现清华大学联网助手(二)——正则表达式re/网页跳转/cookiejar

本篇是第二篇。正则表达式re/网页跳转/cookiejar的使用。 本篇要实现python实现清华大学联网助手(一)——urllib/hashlib/getopt/time/codecs的使用中提到的大部分功能。主要新增的功能是:查询流量、帐户余额、当前用户组等基本信息;查询本账号当前在线IP信息;查询每日流量使用明细,并生成直方图。而且需要访问的url不在是之前登录校园网的url。

coderhuhy的专栏 1629

大数乘法(Multiply Strings)

大数乘法的算法大数乘法的关键在于如何用字符串来模拟大数乘法。方法有如下几种:模拟普通的手算乘法、利用代数方法优化的乘法、快速傅立叶变换FFT。

coderhuhy的专栏 1255

Leetcode214-Shortest Palindrome

我的新博客地址:HuHaoyu’s Blog,欢迎参观。 Find and return the shortest palindrome you can find by performing this transformation.

coderhuhy的专栏 952

Leetcode204-Count Primes

这个题相当于求小于n的所有质数,曾在编程之美中看到过一个求一组质数的算法,叫厄拉多塞筛法,时间复杂度仅有O(nloglogn),这是一个相当好的算法(如果从1到n-1分别判断质数,时间复杂度为O(n*sqrt(n)))。 厄拉多塞筛法的步骤:建立从2到n的集合G={2, 3, 4, ..., n},每次从集合中取出最小的数A,这个数就是质数;然后将数A * times从集合中删除,其中1<=times<=n/A。得到一个新的集合G',重复上述步骤直到集合为空,就取出了所有质数。

coderhuhy的专栏 918

Leetcode212-Word Search II

Each word must be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once in a word.

coderhuhy的专栏 906

Leetcode233-Number of Digit One

欢迎参观我的博客:Huhaoyu’s Blog。 Given an integer n, count the total number of digit 1 appearing in all non-negative integers less than or equal to n.

coderhuhy的专栏 854

【数据结构】基于比较的排序算法 - 交换排序

本文介绍交换排序中的冒泡排序与快速排序。冒泡排序通过相邻元素比较交换,实现升序,时间复杂度最坏为O(N²),空间复杂度O(1),稳定且适合小规模有序数据。快速排序采用分治思想,以基准值划分区间,平均时间复杂度O(N log N),空间复杂度O(log N),但不稳定,实际应用中性能优异,可通过随机基准、小区间优化等提升效率。

careathers的博客 331

【数据结构-5】单链表的实现

单链表,具体来说是单向的、不带头的、不循环的链表。链表由一个一个节点组成,每个节点分为数据域和指针域,数据域存放数据,指针域存放下一节点的地址。这样,就可以根据指针域中的地址找到下一个节点,节点就串起来了构成了单链表。

weixin_44218929的博客 164

pandas 深度入门:从数据结构到一份真实销售报表

本文系统讲解Pandas核心应用,从三分钟安装到完整月度报表生成,涵盖数据读取、清洗、筛选、分组聚合、表连接、透视表与时间序列等13个关键环节。强调“先看数据再动手”,掌握Series/DataFrame/Index结构本质,熟练运用loc/iloc、merge校验、agg/transform区别,通过真实案例实现高效报表自动化,告别手动Excel操作。最后提供性能优化与高频报错解决方案,助力读者快速上手,真正实现“写二十行代码,跑三秒出结果”。

信息安全领域优质创作者|操作系统领域专家 267

C# 数据结构和特殊类型

.NET Core(现称.NET)提供丰富数据结构,优化性能与开发效率。日常开发首选List<T>和Dictionary<TKey,TValue>;高性能场景推荐Span<T>与Memory<T>减少内存分配;并发环境使用ConcurrentDictionary等线程安全集合;避免非泛型集合如ArrayList。

cccloveforever的博客 667
上一篇: C++贪吃蛇的简单实现版
下一篇: A-star算法概述及其在游戏开发中的应用分析
coderhuhy
博客等级 码龄12年 24粉丝 40原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值