包含min函数的栈
- 问题描述:定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。
- 解题思路:正常的min实现需要O(n)复杂度,利用辅助栈实现空间换时间的策略,可以将其复杂度降至O(1);另一思路,记录最小元素索引并在pop时更新,使pop复杂度为O(n),min复杂度为O(1)。
# -*- coding:utf-8 -*-
class Solution:
def __init__(self):
self.__stack = []
self.__min = []
def push(self, node):
if not self.__min or node < self.__min[-1]:
self.__min.append(node)
self.__stack.append(node)
def pop(self):
if not self.__stack:
return False
if self.__min[-1] == self.__stack[-1]:
self.__min.pop()
self.__stack.pop()
return True
def top(self):
if not self.__stack:
return None
return self.__stack[-1]
def min(self):
if not self.__min:
return None
return self.__min[-1]
斐波那契数列
- 问题描述:大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。n<=39
- 解题思路:已知斐波那契数列的递推公式,求解该问题转变为实现该递推公式,有六种实现思路,一是树形递归;二是尾递归;三是迭代。四是通项公式。五是利用矩阵形式的斐波那契递推,此时可以应用快速幂。
# 尾递归
# -*- coding:utf-8 -*-
class Magic:
def __init__(self,args,kwargs):
self.args = args
self.kwargs = kwargs
def tail_rec(func):
import sys
def wrapper(*args,**kwargs):
f = sys._getframe()
if f.f_back and f.f_back.f_back
and f.f_back.f_back.f_code == f.f_code:
raise Magic(args,kwargs)
while True:
try:
return func(*args,**kwargs)
except Magic as ex:
args = ex.args
kwargs = ex.kwargs
return wrapper
class Solution:
def Fibonacci(self, n):
@tail_rec
def fib_iter(a,b,n):
if n <= 0:
return a
return fib_iter(b,a+b,n-1)
return fib_iter(0,1,n)
# 递推矩阵+快速幂
# -*- coding:utf-8 -*-
def multi2_2(a,b):
c = [0,0,0,0]
c[0] = a[0]*b[0] + a[1]*b[2]
c[1] = a[0]*b[1] + a[1]*b[3]
c[2] = a[2]*b[0] + a[3]*b[2]
c[3] = a[2]*b[1] + a[3]*b[3]
return c
class Solution:
def Fibonacci(self, n):
if n<=1:
return n
Q = [1,1,1,0]
Fib = [1,0,0,1]
while n:
if n&1:
Fib = multi2_2(Fib,Q)
n -= 1
Q = multi2_2(Q,Q)
n >>= 1
return Fib[1]
跳台阶
· 问题描述:一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
· 解题思路:动态规划使用一维dp即可解决,策略是自底向上,状态转移为:n阶台阶由n-1阶台阶跨一步和n-2跨两步两种唯一策略得到,只要n-1阶和n-2阶均为最优,n阶即为所求最优
# -*- coding:utf-8 -*-
class Solution:
def __init__(self):
self.__n = 50
self.__dp = []
for i in range(self.__n):
if i <= 1:
self.__dp.append(i+1)
else:
self.__dp.append(self.__dp[i-1]+self.__dp[i-2])
def jumpFloor(self, number):
if number > self.__n:
for i in range(self.__n,number):
self.__dp.append(self.__dp[i-1]+self.__dp[i-2])
return self.__dp[number-1]