前言
怎么说呢,第一是深刻地理解怎么使用机会。机会就是会先浪费前一半,后一半才能抓住。我因为觉得自己太菜,所以没去参加春招和秋招。等五月份决定去参加面试的时候,到现在只面试了一家。其实本来以为很有机会,但是最终被短信拒绝了,理由是名额有限,其实在参观的时候,就听到他们的负责人说之前该招的都招满了,我觉得多半这次是招实习生。再加上第一次在一些地方废话太多,展现力不足。也是很正常的。
这个星期四要去无锡参加面试,感觉他们更想招混合开发的前端而不是Android前端。感觉很渺茫。不过前面走得不踏实,现在感觉渺茫也是很正常的。现在踏实了,后面才不会感觉虚无。
如果再被拒的话,去投一投
也不知道准备点什么,我推测他会比较考虑基础知识,我优先准备数据结构与算法。
参考资料:
面试中需要掌握的 8 种数据结构知识
最常见的面试算法题
时间是明后两天时间,明天还要去找荣国平改论文。今天先复习数据结构。
数据结构
首先,什么是数据结构?简单说,数据结构就是一个容器,以某种特定的布局存储数据。这个“布局”使得数据结构在某些操作上非常高效,在另一些操作上则不那么高效。你的目标就是理解数据结构,这样就能为手头的问题选择最优的数据结构。
常用的数据结构
数组、堆栈、队列、链表、树、图、字典树(Tries,这是一种高效的树,有必要单独列出来)、哈希表
数组(Array)
数组是一种最简单和最广泛使用的数据结构,其它数据结构比如堆栈和队列都源自数组。
- 这句话怎么解释?其实疑惑的点在于堆栈中的这个“堆”。
其实这篇文章的堆栈指一般意义上的“栈-stack”。所以栈是先入后出,列表是先入先出。
而且数据结构中的栈和内存中的堆栈又不同。内存中的堆栈是一块物理存储区。
数组的基本操作:
Insert——在给定索引位置插入一个元素
Get——返回给定索引位置的元素
Delete——删除给定索引位置的元素
Size——获取数组内所有元素的总数
- 实现访问操作?
数据按顺序存储在连续位置的存储器中,由于它们存储在连续的位置,因此可以使用它们的索引来计算内存地址,以便随机访问数据。 - 实现添加Insert和删除remove操作?
与列表(即链表)相比,特定位置添加或删除数据的成本很高。
例如添加insert操作。如果要将数据添加到位置position处
首先:保证数组的末尾有足够的额外空间
然后:当前的数组,从位置position开始,逐个移动数据
最后:完成添加
而删除remove操作,先删除元素,然后逐个移动数据填补空白区域
常问的数组面试问题:
1.找到数组中第二小的元素
2.找到数组中第一个没有重复的整数
3.合并两个分类数组
4.重新排列数组中的正值和负值
- 找到数组中第二小的元素。参考文章
我的直觉解法是排序算法,用选择排序(或者冒泡排序),外循环循环两次。但是如果不能改变数据位置呢?同时,如果考虑数字会重复呢?
不能改变数据位置的话就要申请两个空间来存放临时数据了,int a,b; 然后遍历一遍,每次比较。这样的时间复杂度是最低的
std::pair<int,int> secondSmallest(std::vector<int> arrays)
{
//INT_MAX 这个操作,解决了我的困扰。就是因为int默认为0,所以必须先在头两个循环中进行赋值行为,多写了很多判断语句
int firstmin = INT_MAX;
int secondmin = INT_MAX;
for (auto value : arrays)
{
if (value < firstmin) //小于最小的元素 更新1和2
{
secondmin = firstmin;
firstmin = value;
}
else if (value < secondmin && value != firstmin) //小于倒数二的 更新2
{
secondmin = value;
}
}
return std::make_pair(firstmin, secondmin);
}
- 找到数组中第一个没有重复的整数。参考文章
意思是 [1,2,1,2,3]要返回3。直觉上是只用双重循环了。但是参考文章上介绍了一个方法,就是使用hashmap。将数组内的值作为map的key,然后循环遍历数组,依据key将hashmap取到的value+1。最后再循环一次,根据key取hashmap,得到的值为1的话,就是第一个没有重复的整数。(题目限制中全为整数,哇,厉害了。)
std::unordered_map<int, int> tempmap;
for (auto value : arrays)
{
tempmap[value]++;
}
for (auto value : arrays)
{
if (tempmap[value] == 1)
{
return value;
}
}
- 合并两个分类数组
?啥叫分类数组,就是两个有序数组合并了还得有序吗。我觉得这个用插入排序做很妥嘛!
堆栈(Stack)
内存中的堆栈和数据结构堆栈区别
感觉参考的这个教程的翻译应该是和平常的使用习惯有所不同的,它这里是单指“栈”数据结构。堆和栈是两种不同的数据结构,它似乎在翻译的时候将栈翻译为堆栈了。
堆 - heap
栈 - stack
内存中的堆栈和数据结构堆栈不是一个概念,可以说内存中的堆栈是真实存在的物理区,数据结构中的堆栈是抽象的数据存储结构。
- 内存中的堆栈
内存空间在逻辑上分为三部分:代码区、静态数据区和动态数据区,动态数据区又分为栈区和堆区。
代码区:存储方法体的二进制代码。高级调度(作业调度)、中级调度(内存调度)、低级调度(进程调度)控制代码区执行代码的切换。
静态数据区:存储全局变量、静态变量、常量,常量包括final修饰的常量和String常量。系统自动分配和回收。
栈区:存储运行方法的形参、局部变量、返回值。由系统自动分配和回收。
例如 int method(int a){int b;}栈中存储参数a、局部变量b、返回值temp。它是先看看栈里面有没有,有的话就先对现有的数据进行绑定
堆区:new一个对象的引用或地址存储在栈区,指向该对象存储在堆区中的真实数据。由程序员分配和回收(Java中由JVM虚拟机的垃圾回收机制自动回收)。
例如 Class Student{int num; int age;} main方法中Student stu = new Student();分配堆区空间中存储的该对象的num、age,变量stu存储在栈中,里面的值是对应堆区空间的引用或地址。
参考:HEAP和STACK的区别
- 数据结构中的堆栈
栈:是一种连续存储的数据结构,特点是存储的数据先进后出。
堆:是一棵完全二叉树结构,特点是父节点的值大于(小于)两个子节点的值(分别称为大顶堆和小顶堆)。它常用于管理算法执行过程中的信息,应用场景包括堆排序,优先队列等。
疑惑
?时间复杂度,比较行为赋值行为不算时间复杂度吗?复杂度到底怎么算的?