Leetcode[121, 122, 123, 188] Best Time to Buy and Sell Stock

###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

###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

###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