zoukankan      html  css  js  c++  java
  • LeetCode OJ--Best Time to Buy and Sell Stock III

    http://oj.leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/

    这三道题,很好的进阶。1题简单处理,2题使用贪心,3题使用动态规划。

    话说这叫一维动态规划,嗯。又复习了《算法导论》中和贪心以及动态规划有关的知识,记录如下:

    动态规划的标志:最优子结构、子问题重叠。

          1.找最优子结构

          2.定义递归公示(列一个式子出来,并定义好这个式子到底是什么意思)。

          3.写自底向上或递归备忘录法。

    比如本问题:f(i,j) = max{f(i,k)+f(k,j)}           其中:f(i,j)表示从i到j的所有数,进行一次交易能获得的最多的钱数。最终要求的是f(0,n-1),k从1到n-2.

    再深化一下:

          fp(i,j)表示从i 到 j 进行最多进行 p 次交易可以获得的钱数,则:

          fp(i,j) = max {fp-1(i,j), fp-p'(i,k)+fp'(k,j)}     其中:p'从1到p-1,k从i+1到j-1.

    这大概叫二维动态规划(或许)。

    贪心算法是从局部最优,能够做到全局最优。可分成一步步的,当前的选择受之前做过的选择的影响。而动态规划,是受后面要做的选择的影响。

    于是有了下面代码,复杂度O(n2)然后超时了。

    class Solution {
    public:
        //start 第一个元素,end 最后一个元素的下标
        int onceBuyAndSell(vector<int> &prices,int start,int end)
        {
            int ans = 0;
            int max = prices[end];
            for(int i = end - 1;i>=start;i--)
            {
                if(max - prices[i]>ans)
                    ans = max - prices[i];
                if(prices[i]>max)
                    max = prices[i];
            }
            return ans;  
        }
    
        int maxProfit(vector<int> &prices) {
            if(prices.empty())
                return NULL;
            if(prices.size()==1)
                return 0;
    
            int ans = onceBuyAndSell(prices,0,prices.size()-1);
    
            if(prices.size()<4 || ans == 0)
                return ans;
    
            int temp = 0;
            for(int itor = 2;itor<prices.size()-2;itor++)
            {
                temp = onceBuyAndSell(prices,0,itor) + onceBuyAndSell(prices,itor+1,prices.size()-1);
                if(temp> ans)
                    ans = temp;
            }
            return ans;
        }
    };

    在网上找资料,参考了http://blog.unieagle.net/2012/12/05/leetcode%E9%A2%98%E7%9B%AE%EF%BC%9Abest-time-to-buy-and-sell-stock-iii%EF%BC%8C%E4%B8%80%E7%BB%B4%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92/

    使用了动态规划中打表的方法,降低了复杂度O(n).代码如下:

    class Solution {
    public:
            vector<int> ansN;
        
    //ansN[i]表示,从i到最后的所有元素,只进行一次交易的话,可以得到的最多值。
    void onceBuyAndSell(vector<int> &prices,int start,int end) { int ans = 0; int max = prices[end]; ansN[end] = 0; for(int i = end - 1;i>=start;i--) { if(max - prices[i]>ans) ans = max - prices[i]; if(prices[i]>max) max = prices[i]; ansN[i] = ans; } } int maxProfit(vector<int> &prices) { if(prices.empty()) return NULL; if(prices.size()==1) return 0; ansN.resize(prices.size()); //先来一遍从后面计算的。 onceBuyAndSell(prices,0,prices.size()-1); if(prices.size()<4 ) return ansN[0]; int min = prices[0]; int ans2 = 0; int ans = ansN[0]; for(int itor = 1;itor<prices.size()-2;itor++) { if(prices[itor] - min>ans2) ans2 = prices[itor] - min; if(prices[itor]<min) min = prices[itor]; if(ans2 + ansN[itor+1]> ans) ans = ans2 + ansN[itor+1]; } return ans; } };
  • 相关阅读:
    如何让touchmove之后不触发touchend的事件
    解决alert在ios版微信中显示url的问题(重写alert)
    meta常用标签总结
    HTTP状态码
    前端用到的一些功能
    判断鼠标从哪个方向进入--jQuery
    jsonp是什么
    数据结构与算法之链表-javascript实现
    数据结构之栈-JavaScript实现栈的功能
    数据结构之列表-javascript实现
  • 原文地址:https://www.cnblogs.com/qingcheng/p/3502382.html
Copyright © 2011-2022 走看看