斐波拉契数列
面试题007 斐波拉契数列
题目描述:大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0,第1项是1)。n<=39
解题思路:利用dp[i]=dp[i-1]+dp[i-2]
代码
class Solution:
def Fibonacci(self, n):
# write code here
f1 = 0
f2 = 1
if n== 0:
return f1
elif n==1:
return f2
for _ in range(n-1):
f2, f1 = f1+f2, f2
return f2
面试题008 跳台阶
题目描述:一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
解题思路:假设第n节台阶有f(n)种跳法。f(1)=1,f(2)=2,f(n)=f(n-1)+f(n-2)
代码
class Solution:
def jumpFloor(self, number):
# write code here
f0 = 0
f1 = 1
f2 = 2
if number == 0:
return f0
if number == 1:
return f1
if number == 2:
return f2
for _ in range(number-2):
f2, f1 = f1+f2, f2
return f2%1000000007
面试题009 变态跳台阶
题目描述:一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
解题思路:f(1)=1 f(2)=2 f(3)=4 f(4) = 8 ... 得到f(n+2)=2f(n+1)
代码
class Solution:
def jumpFloorII(self, number):
# write code here
f1 = 1
if number == 1:
return f1
for _ in range(number-1):
f1 = 2*f1
return f1
面试题010 矩形覆盖
题目描述:我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
解题思路:f(1)=1 f(2)=2 f(n)=f(n-1)+f(n-2)
代码
class Solution:
def rectCover(self, number):
# write code here
if number == 0:
return 0
f1 = 1
f2 = 2
if number == 1:
return f1
if number == 2:
return f2
for _ in range(number-2):
f2, f1 = f1+f2, f2
return f2
搜索算法
面试题001 二维数组查找
题目描述:在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
解题思路:分治解题 从右上角(或左下角)开始查找,target更大 指针下移 target更小 指针左移
代码
function Find(target, array)
{
// write code here
if(array.length != 0) {
var row=0;
var col=array[0].length - 1;
while(row<array.length&&col>=0) {
if(array[row][col]==target) {
return true;
}else if(array[row][col]<target) {
++row;
}else {
--col;
}
}
return false;
}
}
面试题006 旋转数组的最小数字
题目描述:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
解题思路:From 牛客剑指offer
二分查找变形
二分查找分为三种情况讨论:
1.如果mid > high那么mid一定不是最小的,所以low = mid + 1
2.如果mid < high那么mid可能是最小的,也可能不是,所以high = mid
3.如果mid == high,情况比较特殊例如[0, 1, 1, 1]和[1, 1, 0, 1],这种只能一个个试high = high -1
题目中给的旋转数组是非递减而不是递增,所以一定要考虑第三种情况
代码
class Solution:
def minNumberInRotateArray(self, rotateArray):
# write code here
if not rotateArray:
return 0
lowp = 0
highp = len(rotateArray) - 1
while lowp < highp:
mid = (lowp + highp) // 2
if rotateArray[mid] < rotateArray[highp]:
highp = mid
continue
if rotateArray[mid] > rotateArray[highp]:
lowp = mid + 1
continue
if rotateArray[mid] == rotateArray[highp]:
highp = highp - 1
return rotateArray[lowp]
解题思路:From 牛客剑指offer
非递减是指列表list[i]<=list[i+1],list[2:]中存在一个最小数
代码
class Solution:
def minNumberInRotateArray(self, rotateArray):
# write code here
for i in range(len(rotateArray)-1):
if(rotateArray[i+1]<rotateArray[i]):
return rotateArray[i+1]
return -1
面试题037 数字在排序数组中出现的次数
题目描述:统计一个数字在排序数组中出现的次数。
解题思路:通过两次二分查找,递归中直接计算k的个数
代码
class Solution:
def GetNumberOfK(self, data, k):
if not data:
return 0
return self.helper(data,k)
def helper(self,data,k):
if not data:
return 0
left, right = 0, len(data) - 1
mid = (left + right) // 2
if data[mid] > k:
return self.helper(data[:mid], k)
elif data[mid] < k:
return self.helper(data[mid + 1:], k)
else:
return 1 + self.helper(data[:mid], k) + self.helper(data[mid + 1:], k)
解题思路:双指针
代码
class Solution:
def GetNumberOfK(self, data, k):
# write code here
if len(data)==1:
return 1 if k in data else 0
left=0
right=len(data)-1
while left<right:
if data[left]!=k:
left+=1
if data[right]!=k:
right-=1
if data[left]==k and data[right]==k:
return right-left+1
return 0
全排序
面试题027 字符串的排序
题目描述:输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
解题思路:From 剑指Offer 全排列
代码
class Solution:
def Permutation(self, ss):
if len(ss) <= 1:
return ss
res = set()
# 遍历字符串,固定第一个元素,第一个元素可以取a,b,c...,然后递归求解
for i in range(len(ss)):
for j in self.Permutation(ss[:i] + ss[i+1:]): # 依次固定了元素,其他的全排列(递归求解)
res.add(ss[i] + j) # 集合添加元素的方法add(),集合添加去重(若存在重复字符,排列后会存在相同,如baa,baa)
return sorted(res) # sorted()能对可迭代对象进行排序,结果返回一个新的list
解题思路:Frome leetcode
回溯法
第一步,求所有可能出现在第一个位置的字符,即把第一个字符和后面所有的字符进行交换
第二步,固定住第一个字符,求后面字符的全排列.这时候我们仍把后面的字符分成两部分: 后面字符的第一个字符以及这个字符后面的所有字符.
然后把第一个字符逐一和它后面的字符交换.
算法最后的结果可能会有重复的情况出现,我们使用python自带的set()函数来去重
代码
class Solution(object):
def permutation(self, s):
"""
:type s: str
:rtype: List[str]
"""
result = []
if not s:
return []
s = list(s)
temp = []
self.stringSort(s, temp, result)
return list(set(result))
def stringSort(self, s, temp, result):
if len(s) == 1:
temp.append(s[0])
result.append(''.join(temp))
temp.pop()
return
for i in range(0,len(s)):
if i!= 0 and s[i] == s[0]:
continue
s[0],s[i] = s[i],s[0]
temp.append(s[0])
self.stringSort(s[1:], temp, result)
temp.pop()
s[i], s[0], = s[0], s[i]
动态规划
面试题030 连续数组的最大和
题目描述:HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)
解题思路:动态规划
代码
class Solution:
def FindGreatestSumOfSubArray(self, array):
# write code here
n = len(array)
dp = [ i for i in array]
for i in range(1,n):
dp[i] = max(dp[i-1]+array[i],array[i])
return max(dp)
面试题012 数值的整数次方
解题思路1 考虑所有情况,循环连乘
代码:
def power(base, exponent):
if (base==0):
return 0
if (exponent == 0):
return 1
res = 1
for i in range(abs(exponent)): #i只是循环变量,不起作用
res *= base
return 1/res if exponent < 0 else res
解题思路2 快速幂快速幂详解
代码
def fast_power(self, base, exponent):
if base == 0:
return 0
if exponent == 0:
return 1
e = abs(exponent)
tmp = base
res = 1
while(e > 0):
#如果最后一位为1,那么给res乘上这一位的结果
if (e & 1 == 1):
res =res * tmp
e = e >> 1
tmp = tmp * tmp
return res if exponent > 0 else 1/res
面试题 顺时针打印矩阵
题目描述:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
解题思路:打印第一行 然后删除第一行 剩余部分逆时针转动90度。重复以上步骤,直到矩阵为空
代码
# -*- coding:utf-8 -*-
class Solution:
def printMatrix(self, matrix):
# write code here
s=[]
while matrix:
s+=matrix[0]
del matrix[0]
matrix=zip(*matrix)[::-1]
return s