分享一个C++骚操作

分享一个C++骚操作

maximum subarray problem

今天在做LeetCode 121时,学习到了一个新的算法,是关于最大子序列问题,这个链接是维基百科总结的最大子序列的3大算法。今天这个算法是kadane Algorithm。

Kadane Algorithm:

A bit of a background: Kadane's algorithm is based on splitting up the set of possible solutions into mutually exclusive (disjoint) sets. We exploit the fact that any solution (i.e., any member of the set of solutions) will always have a last element {\displaystyle i} i (this is what is meant by "sum ending at position {\displaystyle i} i"). Thus, we simply have to examine, one by one, the set of solutions whose last element's index is {\displaystyle 1} 1, the set of solutions whose last element's index is {\displaystyle 2} 2, then {\displaystyle 3} 3, and so forth to {\displaystyle n} n. It turns out that this process can be carried out in linear time.
Kadane's algorithm begins with a simple inductive question: if we know the maximum subarray sum ending at position {\displaystyle i} i (call this {\displaystyle B{i}} B{i}), what is the maximum subarray sum ending at position {\displaystyle i+1} i+1 (equivalently, what is {\displaystyle B{i+1}} B{{i+1}})? The answer turns out to be relatively straightforward: either the maximum subarray sum ending at position {\displaystyle i+1} i+1 includes the maximum subarray sum ending at position {\displaystyle i} i as a prefix, or it doesn't (equivalently, {\displaystyle B{i+1}=max(A{i+1},A{i+1}+B{i})} {\displaystyle B{i+1}=max(A{i+1},A{i+1}+B{i})}, where {\displaystyle A{i+1}} A{i+1} is the element at index {\displaystyle i+1} i+1).
Thus, we can compute the maximum subarray sum ending at position {\displaystyle i} i for all positions {\displaystyle i} i by iterating once over the array. As we go, we simply keep track of the maximum sum we've ever seen. Thus, the problem can be solved with the following code, expressed here in Python:
1 def max_subarray(A):
2    max_ending_here = max_so_far = A[0]
3    for x in A[1:]:
4        max_ending_here = max(x, max_ending_here + x)
5        max_so_far = max(max_so_far, max_ending_here)
6    return max_so_far

但是今天的LeetCode题又不完全与那个算法相同,需要稍微改进一下。


描述:

121. 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.

Example 1:

Input: [7, 1, 5, 3, 6, 4]
Output: 5
max. difference = 6-1 = 5 (not 7-1 = 6, as selling price needs to be larger than buying price)

Example 2:

Input: [7, 6, 4, 3, 1]
Output: 0
In this case, no transaction is done, i.e. max profit = 0.

##不知道为什么我又想放一张图




好,是时候表演真正的技术了
参考程序:

version 1:

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

version 1 plus:

static const auto _____ = []()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    return nullptr;
}();

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


加强版的方法比较秀:

  1. 首先sync_with_stdio(false)是为了打断iostream输入输出到缓存,可以节约很多时间,使之与scanf相差无几。
  2. tie是将两个stream绑定的函数,空参数的话返回当前的输出指针,即tie(0)与tie(nullptr)来解决cin与cout的绑定。



当你分别提交这两个版本的时候,你就会发现.cpp时间直接提升到4ms!!!!!!!!!!


好了,今天的分享就到这里了,欢迎评论和点赞!

发布于 2018-04-13