剑指offer: 跳台阶、斐波那契、具有min方法的栈

包含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]

猜你喜欢

转载自blog.csdn.net/qq_35279914/article/details/82115509