Leetcode Best Time to Buy and Sell Stock III

Leetcode Best Time to Buy and Sell Stock III,本算法的关键为找出其动态子结构。可以发现,序列中的最小值可以做为其的一个分割,令左边序列为left,右边的序列为right,整个串为whole,可以推出当前串的最大值一定是在:a.左序列一次transaction最大值(left_max)与右序列一次transaction最大值(right_max)之和,b.整个序列一次交易最大值;两者之间产生。有一种情况.

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int max = 0;
        findMax(prices, max, 0, prices.size() - 1);
        return max;
    }

    int findMax(vector<int>& prices, int& max, int start, int end) {
        if (start >= end) {
            return 0;
        }
        int begin = start;
        int cur_max = 0;
        int left_max = 0;
        int right_max = 0;
        int min_pos = -1;
        int pre = start;
        int descent_count = 0;
        int backward = 0;
        for (int i = start + 1; i <= end; i ++) {
            // get the consective descent element num
            if (prices[i] <= prices[pre]) {
                descent_count ++;
            } else {
                descent_count = 0;
            }
            // get the minest element
            if ((prices[i] <= prices[min_pos] || min_pos == -1) &&
                    prices[i] < prices[pre]) {
                min_pos = i;
                backward = descent_count;
            }
            // calculate the max profite by one transaction
            if (prices[i] < prices[begin]) {
                begin = i;
            } else {
                int tmp = prices[i] - prices[begin];
                cur_max = tmp > cur_max? tmp : cur_max;
            }
            pre = i;
        }
        // calculate the left and the right
        if (min_pos != -1) {
            left_max = findMax(prices, max, start, min_pos - backward);
            right_max = findMax(prices, max, min_pos, end);
        }
        // get the current max
        if (cur_max > max) {
            max = cur_max;
        }
        if (left_max + right_max > max) {
            max = left_max + right_max;
        }
        return cur_max;
    }
};
test: ./a.out 3 2 4 2 5 7 2 4 9 0
re: 12
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值