Saturday, February 28, 2015

188. Best Time to Buy and Sell Stock IV !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Q:
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 k transactions.
Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

A:

思路:dp

设dp[t][d]为t次交易,新进d天的最大利润:

  • 每次开始的时候,初始化为不用最新一天,或者少用一次transaction.    
  •  DP[t][d] = max(DP[t-1][d], DP[t][d-1]);
  • 状态转移方程:  DP[t][d] = max(DP[t][d], DP[t-1][j] + prices[d]- prices[j])
  •  j in [0,day-1]  inclusive.
  • 第一项为第i天不进行交易,第二项为枚举j 从0~i-1,第j天买入,第i天卖出

注意当k >= len(prices) / 2的时候,说明相当于无限次交易,和第122题Best Time to Buy and Sell Stock II 一样。

上面的复杂度为O(kn^2)代码如下:


class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {
        int n = prices.size();
        if(n<=1)
            return 0;
        k = min(k, n/2); // in case given k is tooo big, 
        vector<vector<int>> DP(k+1, vector<int>(n,0));
        for(int t = 1; t < k+1; t++){// t -> transaction count
            for(int d =1; d < n; d ++){ // d --> day
                //if not use newly added value
                DP[t][d] = DP[t][d-1];
                for(int j = d-1; j>=0; j--){
                    DP[t][d] = max(DP[t][d], DP[t-1][j] + prices[d]- prices[j]);
                }
            }
        }
        return DP[k][n-1];
    }
};
然而上面的超时了。
仔细看,我们有3层循环。
然后,其实状态转移函数里。  
DP[t-1][j] + prices[d]- prices[j]  ==> (DP[t-1][j] - prices[j]) + price[d] 
而(DP[t-1][j] - prices[j]) 每次只需要记录一个最大就可以了。

class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {
        int n = prices.size();
        if(n<=1)
            return 0;
        k = min(k, n/2); // in case given k is tooo big, 
        vector<vector<int>> DP(k+1, vector<int>(n,0));
        for(int t = 1; t < k+1; t++){// t -> transaction count
            int pre_max_diff = DP[t-1][0] - prices[0];
            for(int d =1; d < n; d ++){ // d --> day
                //if not use newly added value
                DP[t][d] = max(DP[t][d-1], pre_max_diff + prices[d]);
                pre_max_diff = max(pre_max_diff, DP[t-1][d] - prices[d] );
            }
        }
        return DP[k][n-1];
    }
};



Mistakes:

这里不能一行一行地计算DP, 要一列一列地计算。-------这个是我以前没有这样搞过的。
也就是说。 要慎重地考虑DP哪一个 变量





Friday, February 27, 2015

187. Repeated DNA Sequences ----M ~

All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACGAATTCCG". When studying DNA, it is sometimes useful to identify repeated sequences within the DNA.

Write a function to find all the 10-letter-long sequences (substrings) that occur more than once in a DNA molecule.

Example:

Input: s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT"

Output: ["AAAAACCCCC", "CCCCCAAAAA"]
A:
就是像String matching的 Rabin–Karp algorithm。
class Solution {
public:
    vector<string> findRepeatedDnaSequences(string s) {
        vector<string> res;
        unordered_map<string,int> M;
        for(int i =0;i <= int(s.length())-10; i++)
            M[s.substr(i,10)] +=1;
        
        auto iter = M.begin();
        while(iter != M.end()){
            if(iter->second > 1){
                res.push_back(iter->first);
            }
            iter++;
        }
        return res;
    }
};


Mistakes:

auto len = s.length()  return type is size_t, 
which is non-negative, thus len-10 can be negative, but would be treated a huge positive number