zoukankan      html  css  js  c++  java
  • 《极客时间--算法面试》--动态规划

    题目:70、爬楼梯

    思路:

      一、采用回溯法,递归+记忆化

      二、采用动态规划,时间复杂度为O(n),采用递推的方式

        要找到DP的状态和DP方程。

      

    代码(动态规划):

    class Solution(object):
        def climbStairs(self, n):
            """
            :type n: int
            :rtype: int
            """
            '''   
            方式一:传统的方式
            if n==0 or n==1 or n==2:                #边界值判定
                return n                            
            men = [1,2]                             #递推初始值
            for i in range(2,n):                    #从第二个开始到最后
                men.append(men[i-1]+men[i-2])       #将前面两个值相加最为后一个值
            return men[n-1]                         #返回最后的一个结果
            '''
            '''方式二:python的编码方式较为简洁,直接赋值的'''
            x,y = 1,1
            for _ in range(1,n):
                x,y = y,x+y
            return y

    题目:120、三角形最小路径和

    思路:

      一、回溯

      二、动态规划

        从底层倒推,明确状态转移方程和初始状态。

        初始状态是最后一层,转移方程是相邻节点的最小值和当前值相加作为下一个状态的值。

    代码:

    class Solution(object):
        def minimumTotal(self, triangle):
            """
            :type triangle: List[List[int]]
            :rtype: int
            """
            if not triangle:                                        #边界判断
                return 0
            res = triangle[-1]                                      #初始状态为最后层
            for i in range(len(triangle)-2,-1,-1):                  #从底层到上层进行遍历
                for j in range(len(triangle[i])):                   #每一层从左往右遍历
                    res[j] = min(res[j],res[j+1])+triangle[i][j]    #当前节点的相邻节点之间最小值加上当前节点
            return res[0]                                           #最终的结果值就是最顶层的数

      需要一个一维的数组进行状态压缩。

    题目:152乘积最大子序列

    思路:

      一、采用递归的思路,暴力解决

        采用递归的思路但采用循环的方式编码。对每一个值进行乘积,将当前最大值进行保存起来,如果与当前的乘积小于前面值就赋值为1.最终返回最大的那个值即可。

      二、采用动态规划,采用递推的方式

        一、状态的定义,一个二维方程,存放正向最大值和负向最小值,两个负数相乘会变正数。

        二、状态方程,最大和最小的值,是比较当前值和当前值和前面乘积的乘积。

    代码:

    class Solution(object):
        def maxProduct(self, nums):
            """
            :type nums: List[int]
            :rtype: int
            """
            if nums is None: return 0                                       #边界判断
            dp = [[0 for _ in range(2)]for _ in range(2)]                   #定义状态,二维数组,存放正向最大和负向最小
            dp[0][1],dp[0][0],res = nums[0],nums[0],nums[0]                 #状态初始值,从第一个值开始
            for i in range(1,len(nums)):                                    #从第二个值开始遍历
                x,y = i%2,(i-1)%2                                           #0,1周期性调控
                dp[x][0] = max(dp[y][0]*nums[i],dp[y][1]*nums[i],nums[i])   #正向最大值
                dp[x][1] = min(dp[y][0]*nums[i],dp[y][1]*nums[i],nums[i])   #负向最小值
                res = max(res,dp[x][0])                                     #每次都保存最大的值,最终返回
            return res

      以下题目买卖股票的最佳时机系列题目均采用动态规划思路去做,明确动态规划的两个基本点:定义状态、状态转移方程和最终的目标结果值。以下思路是通用的泛华思路,定义了三个状态,根据具体的需求再进行细微修改。

      明确状态含义:

        dp[i][j][k]:第i天的最大收益第k次交易的最大收益

        i:第i天【0,n-1】

        j:手上是否持有【0、1】代表手上只能持有一股,可以多股

        k:第k次交易【0,k】

        如果是冷冻时期可以在加状态,比如是否冷冻期,取值范围是0、1等。

      初始状态:

        

      状态转义方程:

        通俗讲:在考虑上次交易的前提下,根据手上是否有股票分别作出行动,由于只有两种情况,即是否持有,后期可以改为

          手上有股票:保持当前的股票和卖掉手上的股票的最大值

          手上没有股票:保持手上没有股票和买入当前饿股票的最大值

      三个循环进行遍历,第一个循环遍历第几天,第二个循环遍历第几次买卖。第三个循环根据手上的股票个数进行操作。针对第一题只有一个股票,后面多个股票,细微修改。

      最终的结果值是最后一天股票操作后在这k次中最大的一个利润值。

    股票买卖题目:121股票买卖的最佳时机I

    只能进行一次交易

    思路:

      

    代码:

    股票买卖题目:122股票买卖的最佳时机II

    无数次交易

    思路:

    代码:

    股票买卖题目:123股票买卖的最佳时机III

    只能两次交易

    思路:

    代码:

    股票买卖题目:188股票买卖的最佳时机IV

    K次交易

    思路:

    代码:

    股票买卖题目:309最佳股票买卖的最佳时机含冷冻期

    两次交易中间会有限制

    思路:

    代码:

    股票买卖题目:714股票买卖的最佳时机含手续费

    思路:

    代码:

  • 相关阅读:
    IBatis学习总结之动态拼sql
    IBatis学习总结
    帝都残暴的.net 之旅 (Martin Fowler 有留言哦)
    简洁实用的WordPress模板
    发现一位同行特牛
    app爬虫--mitmproxy用法梳理
    [转]数据库设计中的14个技巧
    [转] sql数据类型 varchar与nvarchar的区别
    web工作原理
    Xcode6 LaunchImage尺寸
  • 原文地址:https://www.cnblogs.com/missidiot/p/10999081.html
Copyright © 2011-2022 走看看