Leetcode[121, 122, 123, 188] Best Time to Buy and Sell Stock
08 Nov 2015###Task1 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. ###Python
class Solution(object):
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
if not prices or len(prices) == 0:
return 0
low = prices[0]
profit = 0
for i in range(1, len(prices)):
profit = max(profit, prices[i] - low)
low = min(low, prices[i])
return profit
###Java
public class Solution {
public int maxProfit(int[] prices) {
if (prices == null || prices.length == 0) {
return 0;
}
int min = Integer.MAX_VALUE;
int profit = 0;
for (int i = 0; i < prices.length; i++) {
min = prices[i] < min ? prices[i] : min;
profit = (prices[i] - min) > profit ? (prices[i] - min) : profit;
}
return profit;
}
}
###Task2 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).
###Python
class Solution(object):
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
profit = 0
for i in range(1, len(prices)):
if prices[i] > prices[i - 1]:
profit += prices[i] - prices[i - 1]
return profit
###Java
public class Solution {
public int maxProfit(int[] prices) {
if (prices == null || prices.length == 0) {
return 0;
}
int max = 0;
for (int i = 0; i < prices.length - 1; i++) {
if (i + 1 < prices.length && prices[i + 1] > prices[i]) {
max += prices[i + 1] - prices[i];
}
}
return max;
}
}
###Points
- Buy & sell whenever makes profit
###Task3 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). ###Python
class Solution(object):
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
if not prices or len(prices) == 0:
return 0
left = [0 for i in range(len(prices))]
right = [0 for i in range(len(prices))]
low = prices[0]
left[0] = 0
for i in range(1, len(prices)):
left[i] = max(left[i - 1], prices[i] - low)
low = min(low, prices[i])
hi = prices[-1]
right[-1] = 0
for i in range(len(prices) - 1)[::-1]:
right[i] = max(right[i + 1], hi - prices[i])
hi = max(hi, prices[i])
profit = 0
for i in range(len(prices)):
profit = max(profit, left[i] + right[i])
return profit
###Java
public class Solution {
public int maxProfit(int[] prices) {
if (prices == null || prices.length < 2) {
return 0;
}
int[] left = new int[prices.length];//stand for 0-i max profit
int[] right = new int[prices.length]; //stands for i - length max profit
left[0] = 0;//pay attention to init
int min = prices[0]; //pay attention to init
for (int i = 1; i < prices.length; i++) {
min = Math.min(min, prices[i]);
left[i] = Math.max(left[i - 1], prices[i] - min);
}
right[prices.length - 1] = 0;//pay attention to init
int max = prices[prices.length - 1];//pay attention to init
for (int i = prices.length - 2; i >= 0; i--) {
max = Math.max(max, prices[i]);
right[i] = Math.max(right[i + 1], max - prices[i]);
}
int profit = 0;
for (int i = 0; i < prices.length; i++) {
profit = Math.max(profit, left[i] + right[i]);
}
return profit;
}
}
###Points
- Similar to: Two pointers from both ends
###Task4 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).
###Java
public class Solution {
public int maxProfit(int k, int[] prices) {
if (k < 0 || prices == null || prices.length == 0) {
return 0;
}
//if k is larger, it becomes to infinite buying
if (k > prices.length / 2) {
int profit = 0;
for (int i = 1; i < prices.length; i++) {
if (prices[i] > prices[i - 1]) {
profit += prices[i] - prices[i - 1];
}
}
return profit;
}
int N = prices.length;
int[][] subProfit = new int[N][N];
for (int i = 0; i < N - 1; i++) {
for (int j = i + 1; j < N; j++) {
subProfit[i][j] = prices[j] - prices[i];
}
}
int[][] max = new int[N + 1][k + 1]; //max[i][j] means prev-i day have j transactions
// for (int i = 0; i <= N; i++) {
// max[i][0] = 0;
// }
// for (int i = 0; i <= k; i++) {
// max[0][i] = Integer.MIN_VALUE;
// }
for (int j = 1; j <= k; j++) {
for (int i = 1; i <= N; i++) {
for (int x = 0; x + 1 < i; x++) {
//System.out.println("j = " + j + " i = " + i + " x = " + x + " sub = " + subProfit[x][i - 1]);
max[i][j] = Math.max(max[x][j - 1] + subProfit[x][i - 1], max[i][j]);
}
}
}
return max[N][k];
}
}
###Points
- max[i][j]: 前i天交易j次
- max[x][j - 1]: 前x天交易j - 1次
- subP[x][i - 1]: 第x天到i天收益