《剑指offer》-第2章(2)
来源:互联网 发布:java中的类命名规范 编辑:程序博客网 时间:2024/05/22 15:51
2.3.5 栈和队列
栈:后进先出,不考虑排序的数据结构,要找到最大最小元素需要O(n)时间,若要在O(1)时间内找到最大最小值,需要对栈做特殊的设计。
队列:先进先出。在树的宽度优先遍历中,遍历某一层数的队列里,以便下一层节点的遍历(面试题32)。
面试题9:用两个栈实现队列
实现两个函数appendTail和deleteHead
测试用例:
1. 往空队列里添加元素、删除元素;
2. 往非空队列里添加元素、删除元素;
3. 连续删除元素直到队列为空;
思路:
1. 题目意图是用两个先进后出的栈stack1、stack2,实现一个先进先出的队列
2. 插入的元素压入stack1,不管stack2
3. 删除元素deleteHead:如果stack2为空,则从stack1依次弹出元素并压入stack2,操作完后stack1是空,弹出stack2顶部元素;如果是stack2不为空,则直接弹出stack2顶部元素;
4. 插入元素appendTail:压入stack1;
5. 考虑是否有问题,如果此时stack2有元素,要弹出元素,则弹出stack2顶部元素,stack2中的元素总是比stack1中的元素先到;因此删除元素时考查stack2,插入元素时直接压入stack1
相关题目:用两个队列实现一个栈
思路:
1. queue1中依次是插入的元素,queue2是空;
2. 删除元素(删除最后插入的元素):找到不为空的队列(queue1或queue2),依次从队列头弹出元素并压入另一个队列,直到剩下最后一个元素,直接弹出不压入另一个队列;
3. 插入元素:找到不为空的队列(queue1或queue2),将新元素压入队列尾;
2.4 算法和数据操作
重点掌握二分查找、归并排序、快速排序,能够随时正确、完整地写出代码;
如果要在二维数组上搜索路径,可尝试回溯法,考虑用递归、用栈模拟递归;
求某个问题的最优解,且问题可分为多个子问题,尝试动态规划;如果面试官提示在分解子问题的时候是不是存在某个特殊的选择,采用这个特殊选择将一定能得到最优解,考虑贪婪算法;
2.4.1 递归和循环
递归:代码简洁,但函数调用有时间和空间的消耗,且可能发生调用栈溢出,可能很多计算是重复的;性能比循环差。
循环:设置循环的初始值和终止条件即可。
面试题10:斐波那契数列
输入n,求斐波那契数列的第n项。
解法一:递归,挑剔的面试官会提示有效率问题
分析:用树的结构分析递归过程,发现很多节点是重复的,n很大时重复量也很大
解法二:循环,从下往上计算,根据f(0) f(1)计算f(2),依次计算f(3),f(4)……f(n),
分析:复杂度是O(n)
解法三:时间复杂度O(logn)的解法,代码复杂,一般不用
斐波那契数列的应用:
青蛙跳台阶问题:一直青蛙依次可以跳上1级台阶,也可以跳上2级台阶,求该青蛙跳上衣蛾n级台阶总共有多少种跳法
1级台阶f(1) = 1,2级台阶f(2) = 2,n级台阶;如果第一次跳1级,后面的n-1级台阶的跳法是f(n-1),如果第二次跳2级,后面n-2级台阶的跳法是f(n-2),即f(n) = f(n-1) + f(n-2)
2.4.2 查找和排序
顺序查找、二分查找、哈希表查找、二叉排序树查找,要能够随时正确写出
哈希表:能够在O(1)时间内查找到某一元素,但需要额外的空间来实现
要对各种排序算法的特点烂熟于胸:插入排序、冒泡排序、归并排序、快速排序,能从额外空间消耗、平均时间复杂度、最差时间复杂度等方面比较
面试题11:旋转数组的最小数字
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转({3,4,5,1,2}是{1,2,3,4,5}的一个旋转,数组的最小值为1)。输入一个数组的旋转,输出该数组的最小值。
测试用例:
1. 输入数组中有重复数字、没有重复数字
2. 输入数组是一个升序序列(升序序列本身也是一个旋转)、只有一个元素的数组
3. 输入null
分析:
1. 从头到尾遍历可以找到最小值,算法复杂度是O(n),这不是想要的解答
2. 旋转后的数组可以分为两个排序子序列,最小的元素是两个序列的分界线
3. 用二分查找的思路,两个指针P1、P2分别指向数组第一个元素和最后一个元素
4. 对于一般的旋转数组*p1>=*p2,找数组中间元素
5. 如果*p1<中间元素,说明中间元素属于第一个子数组,将p1指向中间元素
6. 如果中间元素<*p2,说明中间元素属于第二个子数组,将p2指向中间元素
7. 循环4,5,6,直到p1与p2相邻,则p2所指的元素是最小的元素
8. 对于边界情况即升序序列本身,*p1<*p2时,则p1所值的数组是最小的元素
9. 如果*p1==中间元素==*p2,则无法判断中间元素属于哪个子数组(如10111与11101),此时采用顺序查找
- 《剑指offer》-第2章(2)
- 《剑指offer》读书笔记(第2章)
- 《剑指offer》-第2章(1)
- 《剑指offer》第2章总结
- 《剑指offer》笔记-第2章(3)
- 《剑指offer》笔记-第4章(2)
- 《剑指offer》笔记-第5章(2)
- 剑指Offer第2题
- 剑指Offer-第2章 面试需要的基础知识
- [剑指Offer] 第2章课后题详解
- 替换空格 (剑指Offer 第 2 题)
- 《剑指offer》读书笔记(第1章)
- 剑指offer-(第一天)
- 剑指offer第2题 单件模式
- 《剑指offer》笔记-第3章(1)
- 《剑指offer》笔记-第4章(1)
- 《剑指offer》笔记-第4章(3)
- 《剑指offer》笔记-第4章(4)
- FPGA编程注意事项
- char与signed char, unsigned char的区别
- 415Add Strings
- 6.列表
- 学生、成绩、课程表,要求查询001课程比002课程成绩高的所有学生的学号解决办法
- 《剑指offer》-第2章(2)
- MySQL重建或修复表或索引
- 在windows上安装和启动Elasticseach
- 树的非递归遍历
- 在 Ubuntu 11.10 上安装 Sun Grid Engine
- C++入门基本知识
- Java常见的几种排序方法
- 函数式接口和lambda表达式
- C++map如何按值排序