[leetcode] Best Time to Buy and Sell Stock Ⅰ Ⅱ Ⅲ

三道题目都是比较基础的dp或者贪心的题目,除了第三个需要想一会,仔细分析题干才能发现玄机,其他的都是算法的基本应用。下面具体分析

 

Best Time to Buy and Sell Stock

Say you have an array for which the ith element is the price of a given stock on day i.

If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.

思路:

题目的大意是买卖股票,求最大收益,只能进行一次买卖。

典型的一维动态规划,由于卖出一定不能超前于买入(废话),所以遍历一遍价格数组,如果在第i天卖出,这一天的收益就是prices[i]-min,找出最大的这个收益即可。min是到第i天为止出现的最低价格。

题解:

class Solution {
public:
    int maxProfit(vector<int> &prices) {
        if(!prices.size())
            return 0;
        int profit = 0;
        int min = prices[0];
        for(int i=0;i<prices.size();i++)
        {
            if(prices[i]<min)
                min = prices[i];
            int tmp = prices[i]-min;
            if(tmp>profit)
                profit = tmp;
        }
        return profit;
    }
};

Best Time to Buy and Sell Stock II

Say you have an array for which the ith element is the price of a given stock on day i.

Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times). However, you may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

思路:

与第一题区别是可以进行任意次数的买卖。

尽然可以进行任意次数的买卖,那就可以用贪心算法了。举个例子:1,2,3。收益是3-1=2。但也可以1的时候买进,2的时候卖出,收益1;2的时候买进,3的时候卖出,收益1,此时总的收益也是2,整体最优等于两次最优之和。所以,只要明天的价格比今天高,那就今天买进,明天卖出,遍历一遍价格数组,一定可以得出最佳收益。

题解:

class Solution {
public:
    int maxProfit(vector<int> &prices) {
        if(!prices.size())
            return 0;
        int profit = 0;
        for(int i=0;i<prices.size()-1;i++)
        {
            if(prices[i]<prices[i+1])
                profit += prices[i+1]-prices[i];
        }
        return profit;
    }
};

Best Time to Buy and Sell Stock III

 Say you have an array for which the ith element is the price of a given stock on day i.

Design an algorithm to find the maximum profit. You may complete at most two transactions.

Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

思路:

这次能进行两次交易了。开始蒙了,认为只有暴力法才行,不过leetcode对暴力法一定是超时的,就没进行实践了。仔细想想,肯定还是与动态规划有关,如果第i天完成了第1次交易,那么第2次交易一定发生在第i天至最后一天之间,关键在于i的确定,如果i确定了i,一切就解决了。其实这个题目解决有一定运气成分,因为第一题是顺序遍历,这题当时没做出来,所以就像练习一下与第一题一样倒序遍历一遍,看自己能不能一遍就过,还没写完思路就来了。

第一次遍历用一个数组dp[]确定第j天进行一次买卖的最佳收益,第二次遍历那就倒着来,从最后一天开始遍历至第j天(j以前是第一次买卖的区间),寻找总的最佳收益。

题解:

class Solution {
public:
    int maxProfit(vector<int> &prices) {
        if(prices.size()==0)
            return 0;
            int n=prices.size();
        int profit = 0;
        int min = prices[0];
        int *dp = new int [n];
        //第一遍循环,正序遍历
        for(int i=0;i<n;i++)
        {
            if(prices[i]<min)
                min = prices[i];
            int tmp = prices[i]-min;
            if(tmp>profit)
                profit = tmp;
            dp[i] = profit;
        }
        profit = 0;
        int max = prices[n-1];
        //第二遍,逆序遍历
        for(int i=n-1;i>=0;i--)
        {
            if(prices[i]>max)
                max = prices[i];
            int tmp = dp[i]+max-prices[i];
            if(tmp>profit)
                profit = tmp;
        }
        return profit;
    }
};

 

posted on 2014-12-01 15:34  cha1992  阅读(133)  评论(0编辑  收藏  举报

导航