第二章

面试题9:用两个栈实现队列

题目:如面试题,给你两个栈, 实现队列的先进先出,即在队列头删除一个元素以及在队列的尾部添加一个元素

思路:这个题的分析感觉很巧妙,从一个具体的例子入手,找出其中的规律,进而得到一种解决方法。解决方法几句话就能说完,但是这种思维很重要,放个图留着自己以后体会吧。

图好大。。

代码如下:

stack1 = []
stack2 = []
# 尾部添加一个节点
def appendTail(val):
stack1.append(val) # 头部删除一个元素
def deleteHead():
if stack2.__len__() == 0 and stack1.__len__() == 0:
return "error"
if stack2.__len__() == 0:
while stack1.__len__() != 0:
stack2.append(stack1.pop())
return stack2.pop()

测试代码:

appendTail(1)
appendTail(2)
appendTail(3)
print(deleteHead())
print(deleteHead())

代码用Python写还是比较简洁的,java要多写挺多的,python牛逼

类似题目:两个队列实现一个栈。

自己画一下就知道了,加的时候往有元素的队列加,当然一开始直接往1队列加。出的时候,把有元素的队列其中的n-1个元素都取出来,放到另一个队列之中,剩下最后一个元素,即为目标元素,其它同理。

面试题10:斐波那切数列

做过很多次了。记住一点,对于这类问题,先假设n很小的时候,求出n==1,2....或者其它一般情况之下的值,然后规模为的问题进行分解,想办法分解为n-1和规模的问题,最终就可以缩小成1,2.....的问题,进而求解出N问题。难点还是在分解问题上,看自己能不能想到。

非递归的写法:

def solution(n):
result = [0,1]
if n < 2:
return result[n]
x = 1
y = 0
target = None
for i in range(1,n):
target = x + y
y = x
x = target
return target

代码不多说了,一看就会。

面试题11:求旋转数组之中的最小值

题目:旋转数组是指将一个有序的数组前面的x个数移动到最后面,类似于,原数组【1,2,3,4,5】,旋转过后的数组:【3,4,5,1,2】,当然这个x也可以是0,就是不移动,但是它本身也是一个旋转数组。如题,求该数组之中的最小值。

思路分析:首先能想到的肯定是O(N)的方法,遍历数组然后找出最小值,但是这肯定是不行的,需要找到一个O(logn)复杂度的方法,一般来讲,这种查找数字的,而且是部分有序,都可以用二分查找的思想进行。可以看到了这个旋转数组,它仍然可以划分为两个有序的子数组,一个是【3,4,5】,一个是【1,2】,前面数组的值都大于等于后面数组之中的值, 我们需要找的数字是1,二分查找,自然是需要两个边界指针,和一个中间指针,比较中间和两边的值,进而一步步缩小目标值的范围,从而达到O(logn)复杂度的查找方法。对于【3,4,5,1,2】,设有指针left,right,middle,初始时,分别指向3,2,5,比较5>3,说明left到middle之间的数字,都是处于第一个数组之中的,所以最小值肯定是在midlle~right之间,同理,如果旋转数组为【4,5,1,2,3】,1<3,说明midlle~right之间都是后面那个子数组的元素,所以最小值肯定是位于middle~left之间的,之后的都同理。总体上说,就是通过比较middle和两边的值,不断缩小最小值的区间,当最小值区间大小为2时,nums[right]的值就是最小值。

但是需要注意两个特殊情况:

一,就是刚开始说得,旋转了0个或者n个数字的情况,此时第一个数字就是最小数字,没有必要再进行查找了,所以,如果第一个数小于最后一个数字,说明旋转了n个或者0个数字,直接返回第一个数字就可以了。

二,如果midlle,left,right这三个数字都相等的话,那么就无法继续缩小区间,比如这个数组【0,1,1,1,1】,旋转之后可以是【1,0,1,1,1】,【1,1,1,0,1】,可以看到,按照之前的规则是有可能得出错误的结果的,所以如果这种情况,那么就只能采用顺序查找的方法了。

个人认为这题需要考虑的很多,现阶段我肯定是考虑不到这么周全的,继续加油。

代码如下:

def min(nums):
if len(nums) == 0 or nums == None:
return False
left = 0
right = len(nums)-1
# 旋转了0或者n
if nums[left] < nums[right]:
return nums[0]
# 正常旋转
while nums[left] >= nums[right]:
# 查找到了最小值
if right - left == 1:
return nums[right]
middle = int((right+left)/2) if nums[middle] == nums[left] == nums[right]:
# 顺序查找
return orderSearch(nums, left, end)
# 正常缩小区间
if nums[middle] >= nums[left]:
left = middle
elif nums[middle] <= nums[right]:
right = middle # 顺序查找
def orderSearch(nums, start, end):
result = nums[start]
for i in range(start, end+1):
if nums[i] < result:
result = nums[i]
return result

面试题12:矩阵之中的路径

题目:给定一个字符矩阵以及一个字符串,寻找在该字符矩阵之中是否有一条路径,连起来的顺序刚好是给定的字符串,只能上下左右相连,不能斜着相连,并且一个字符格走过之后就不能再走这个了,相当于不能重复走过同一个矩阵之中的格子。

思路:这个问题相当于从一个点开始,下一步可以有好几种走法,每次判断一下是否达到了目标,以及能够达到目标,达到目标了直接结束,没有达到的话说明当前步骤行不通,回溯到上一步,尝试其他路径是否可行。这种问题一般都是用回溯法来解决。

具体到这个问题:以矩阵之中任何一个字符格为起点进行考察,判断当前字符是否等于字符串第一个字符,等于了进行下步,以该字符的上下左右四个字符作为下一个考察点(有的话),看看是否等于字符串的第二个字符,等于的话,重复上一次的步骤,不等于则停止以当前字符为基准的判断,回溯到上一个格子,尝试其它可行的路径,以此类推。

思路还是比较容易理解的,代码虽然很长,但是其中的思路很明了。

代码如下:

def hasPath(matrix, rows, cols, word):
if matrix == None or rows < 1 or cols <1 or word == None:
return False
visited = []
for i in range(rows):
visited.append([])
for j in range(cols):
visited[i].append(False)
pathLength = 0
for i in range(rows):
for j in range(cols):
# 以每一个矩阵格子为起点进行考察
if hasPathCore(matrix, rows, cols, i, j, word, pathLength, visited):
return True
return False def hasPathCore(matrix, rows, cols, row, col, word, pathLength, visited):
# 判断是否到了字符串结尾
if word[pathLength] == '#':
return True
hasPath = False
# 判断当前字符是否在矩阵之中并且需要等于第pathLength个字符
# 而且不能已经访问过了
if row < rows and row >= 0 and col < cols and col >= 0 and \
word[pathLength] == matrix[row][col] and visited[row][col] == False:
# 进行下一个字符的查找
pathLength += 1
visited[row][col] = True
# 对上下左右四条路径进行查找
hasPath = hasPathCore(matrix, rows, cols, row+1, col, word, pathLength, visited) or \
hasPathCore(matrix, rows, cols, row-1, col, word, pathLength, visited) or \
hasPathCore(matrix, rows, cols, row, col+1, word, pathLength, visited) or \
hasPathCore(matrix, rows, cols, row, col-1, word, pathLength, visited)
if hasPath: # 没有找到,回溯到上一个字符
visited[row][col] = False
pathLength -= 1
return hasPath

 测试代码如下:

nums = [
['a', 'b', 't', 'g'],
['c', 'f', 'c', 's'],
['j', 'd', 'e', 'h'],
] print(hasPath(nums, 3, 4, 'cehsg#'))

《剑指Offer》第二章(一)题 9 -12的更多相关文章

  1. 剑指offer第二章

    剑指offer第二章 1.二维数组中的查找 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含 ...

  2. 剑指offer—第二章算法之二分查找(旋转数组的最小值)

    旋转数组的最小数字 题目:把一个数组最开始的若干元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如:数组{3,4,5,1,2}为{1,2,3,4, ...

  3. 剑指offer—第二章算法之快速排序

    算法:排序和查找(二分查找,归并排序,快速排序),位运算等. 查找:顺序查找,哈希查找,二叉排序树查找,哈希表. 二分查找可以解决:"旋转数组中的最小数字","数字在排序 ...

  4. 《剑指offer(第二版)》面试题55——判断是否为平衡二叉树

    一.题目大意 输入一颗二叉树,判断该二叉树是否为平衡二叉树(AVL树). 二.题解 <剑指offer>上给出了两种解决方式: 1.第一种是从根节点开始,从上往下遍历每个子节点并计算以子节点 ...

  5. 《剑指offer 第二版》题解

    剑指Offer 按题号排序 面试题 3:数组中重复的数字 面试题 4:二维数组中的查找 面试题 5:替换空格 面试题 6:从头到尾打印链表 面试题 7:重建二叉树 面试题 8:二叉树的下一个节点 面试 ...

  6. 经典面试题目——找到第n个丑数(参考《剑指offer(第二版)》面试题49)

    一.题目大意 给你一个数n,要求返回第n个丑数.其中,丑数的定义如下: 丑数是指只包含因子2.3和5的数.(数字1也是丑数,不过是个特例)引用<剑指offer>上的话来说,对于一个数M,如 ...

  7. 《剑指offer(第二版)》——面试题36:二叉搜索树与双向链表

    具体的题目大意和参考思路在此处不详述(见<剑指offer>),实质就是在中序遍历的过程中调整指针的指向,关于中序遍历有递归和非递归两种操作,所以此处也用了两种方法. 方法1(递归法): 代 ...

  8. 《剑指offer(第二版)》面试题60——n个骰子的点数

    一.题目描述 把n个骰子仍在地上,所有的骰子朝上的一面的点数之和为s,输入n,打印出s所有可能的值出现的概率. 二.题解 <剑指offer>上给出的两种方法,尤其是代码,晦涩难懂且没有注释 ...

  9. 《剑指offer(第二版)》面试题64——求1+2+...+n

    一.题目描述 求1+2+3+...+n,要求不能使用乘除法.for.while.if.else.switch.case等关键字以及条件判断语句 (即三元运算符,A? B : C) 二.题解 虽然求和问 ...

  10. 结合《剑指offer(第二版)》面试题51来谈谈归并排序

    一.题目大意 给定一个数组A,对于数组A中的两个数字,如果排在前面的一个数字大于(必须大于,等于不算)后面的数字,则这两个数字组成一个逆序对.要求输出数组A中的逆序对的总数.例如,对于数组{7,5,6 ...

随机推荐

  1. 【FAR 方云研发绩效】助力于解决管理难题

    方云研发绩效(farcloud.com)自发布以来,助力多家企业完成研发管理数字化转型,并有效解决产研绩效这一普遍存在的管理难题. 研发管理是许多企业面临的管理难题,首先,技术构成的信息壁垒,让内部沟 ...

  2. 用Django自动生成表遇到问题

    因为以前在数据库中已经生成过Django 叫App01下的表,所以无法生成,在数据库中执行这个命令 DELETE FROM django_migrations WHERE app='App01';然后 ...

  3. 7月17日刷题记录 分治Getting!循环比赛日程表

    通过数:1 ┭┮﹏┭┮ qdoj.xyz 1053 分治-循环比赛日程表 其实今天晚上留给编程的时间并不多,做出一道... 不过收获还是非常大的 毕竟本人从来没有学习过分治算法,今天竟然攻克了我人生中 ...

  4. Oracle安装连接常见错误

    oracle安装注意:安装路径url不能带中文C:\app\59428\product\11.2.0\dbhome_1\sqldeveloper打开sqldeveloper的时候,需要输入java.e ...

  5. 打包一份py给大家用!!!

    好不容易写完了代码,却发现对面无法使用自己的python代码,其无奈可想而知 在这里就给大家介绍一下pyinstaller的简单用法 你所需要的就是在电脑上安装好 https://blog.csdn. ...

  6. 全网最详细!Centos7.X 搭建Grafana+Jmeter+Influxdb 性能实时监控平台

    背景 日常工作中,经常会用到Jmeter去压测,毕竟LR还要钱(@¥&*...),而最常用的接口压力测试,我们都是通过聚合报告去查看压测结果的,然鹅聚合报告的真的是丑到家了,作为程序猿这当然不 ...

  7. 真机调试报The executable was signed with invalid entitlements.错误

    真机运行时,提示The executable was signed with invalid entitlements.(The entitlements specified in your appl ...

  8. MySQL:如何查询出每个分组中的 top n 条记录?

    问题描述 需求: 查询出每月 order_amount(订单金额) 排行前3的记录. 例如对于2019-02,查询结果中就应该是这3条: 解决方法 MySQL 5.7 和 MySQL 8.0 有不同的 ...

  9. noip2018 考前提醒!

    适应Noilinux 1.终端操作 打开终端 \(Ctrl+Alt+T\) 打开文件夹 \(cd\) +名称 新建文件夹 \(mkdir\) +名称 打开 \(vim\) 配置 \(vim ~/.vi ...

  10. [bzoj2326] [洛谷P3216] [HNOI2011] 数学作业

    想法 最初的想法就是记录当前 \(%m\) 值为cur,到下一个数时 \(cur=cur \times 10^x + i\) n这么大,那就矩阵乘法呗. 矩阵乘法使用的要点就是有一个转移矩阵会不停的用 ...