LintCode Best Time to Buy and Sell Stock

149. Best Time to Buy and Sell Stock

方法一:时间复杂度O(n^{2})

  • 两次for循环,第一层循环寻找买入价,第二层循环寻找卖出价;
public class Solution {
    /**
     * @param prices: Given an integer array
     * @return: Maximum profit
     */
    public int maxProfit(int[] prices) {
        int n = prices.length;
        if (0 == n) {
        	return 0;
        }
        int profit = 0;
        for (int i = 0;i < n - 1;i++){
            for (int j = i + 1;j < n;j++) {
                if (prices[j] - prices[i] > profit ){
                    profit = prices[j] - prices[i];
                } 
            }
        } 
        return profit;
    }
}

方法二:时间复杂度O(n) 

  • 一次for循环,min记录当前位置的最小值,profit记录到当前位置的最大获益。
public class Solution {
    /**
     * @param prices: Given an integer array
     * @return: Maximum profit
     */
    public int maxProfit(int[] prices) {
        int n = prices.length;
        if (0 == n) {
        	return 0;
        }
        int profit = 0;
        int min = prices[0];
        for (int i = 1;i < n;i++){
            min = Math.min(min, prices[i]);
            profit = Math.max(profit, prices[i] - min);
        } 
        return profit;
    }
}

150. Best Time to Buy and Sell Stock II

方法:时间复杂度O(n) 

  • 一次for循环,profit累加上相邻两次股票差为正数的收益
public class Solution {
    /**
     * @param prices: Given an integer array
     * @return: Maximum profit
     */
    public int maxProfit(int[] prices) {
        int n = prices.length;
        if (0 == n){
            return 0;
        } 
        int profit = 0;
        for (int i = 0;i < n - 1 ;i++){
            if (prices[i+1] - prices[i] > 0){
                profit += prices[i+1] - prices[i];
            } 
        } 
        return profit;
    }
}

151. Best Time to Buy and Sell Stock III

     方法:时间复杂度O(n)

 

f[i][j]表示前i天在j状态的最大收益(eg:1天的下标为0)

当处于非持股状态时,考虑前一天处于非持股或者持股状态

f[i][j] = max{f[i-1][j], f[i-1][j-1] + Ai-1 – Ai-2}

当处于持股状态时,考虑前一天处于非持股或者持股状态

f[i][j] = max{f[i-1][j-1], f[i-1][j] + Ai-1 – Ai-2, f[i-1][j-2] + Ai-1 – Ai-2}

public class Solution {
	/**
	 * @param prices: Given an integer array
	 * @return: Maximum profit
	 */
	public int maxProfit(int[] A) {
		int n = A.length;
		if (0 == n) {
			return 0;
		}
		int[][] f = new int[n + 1][5 + 1];
		for (int j = 0; j < 6; j++) {
			f[0][j] = 0;
		}
		for (int i = 1; i < n + 1; i++) {
			for (int j = 1; j < 6; j += 2) {
				f[i][j] = f[i - 1][j];
				if (i > 1 && j > 1) {
					f[i][j] = Math.max(f[i][j], f[i-1][j-1] + A[i-1] - A[i-2]);
				}
			}
			for (int j = 2; j < 6; j += 2) {
				f[i][j] = f[i - 1][j - 1];
				if (i > 1) {
					f[i][j] = Math.max(f[i][j], f[i-1][j] + A[i-1] - A[i-2]);
				}
				if (i > 1 && j > 2) {
					f[i][j] = Math.max(f[i][j], f[i-1][j-2] + A[i-1] - A[i-2]);
				}
			}
		}
		int profit = 0;
		for (int j = 1; j < 6; j += 2) {
			if (f[n][j] > profit) {
				profit = f[n][j];
			}
		}
		return profit;
	}
}

对空间进行优化:空间复杂度O(1)

public class Solution {
	/**
	 * @param prices: Given an integer array
	 * @return: Maximum profit
	 */
	public int maxProfit(int[] A) {
		int n = A.length;
		if (0 == n) {
			return 0;
		}
		int[][] f = new int[2][5 + 1];
		for (int j = 0; j < 6; j++) {
			f[0][j] = 0;
		}
		int old = 0;
		int now = 1;
		for (int i = 1; i < n + 1; i++) {
			old = now;
			now = 1 - now;
			for (int j = 1; j < 6; j += 2) {
				f[now][j] = f[old][j];
				if (i > 1 && j > 1) {
					f[now][j] = Math.max(f[now][j], f[old][j-1]+A[i-1]-A[i-2]);
				}
			}
			for (int j = 2; j < 6; j += 2) {
				f[now][j] = f[old][j - 1];
				if (i > 1) {
					f[now][j] = Math.max(f[now][j], f[old][j]+A[i-1]-A[i-2]);
				}
				if (i > 1 && j > 2) {
					f[now][j] = Math.max(f[now][j], f[old][j-2]+A[i-1]-A[i-2]);
				}
			}
		}
		int profit = 0;
		for (int j = 1; j < 6; j += 2) {
			if (f[now][j] > profit) {
				profit = f[now][j];
			}
		}
		return profit;
	}
}

393. Best Time to Buy and Sell Stock IV 

在至多2次买卖的基础上,将2次买卖的5个阶段扩充到k次买卖的2k+1个阶段

package test;

public class Solution {
	/**
	 * @param K: An integer
	 * @param prices: An integer array
	 * @return: Maximum profit
	 */
	public int maxProfit(int K, int[] A) {
		int n = A.length;
		if (0 == n) {
			return 0;
		}
		if (K > n / 2) {
			int res = 0;
			for (int i = 0; i < n - 1; i++) {
				if (A[i + 1] > A[i]) {
					res += A[i + 1] - A[i];
				}
			}
			return res;
		}
		int[][] f = new int[n + 1][2 * K + 1 + 1];
		for (int j = 0; j < 2 * K + 2; j++) {
			f[0][j] = 0;
		}
		for (int i = 1; i < n + 1; i++) {
			for (int j = 1; j < 2 * K + 2; j += 2) {
				f[i][j] = f[i - 1][j];
				if (i > 1 && j > 1) {
					f[i][j] = Math.max(f[i][j], f[i-1][j-1] + A[i-1] - A[i-2]);
				}
			}
			for (int j = 2; j < 2 * K + 2; j += 2) {
				f[i][j] = f[i - 1][j - 1];
				if (i > 1) {
					f[i][j] = Math.max(f[i][j], f[i-1][j] + A[i-1] - A[i-2]);
				}
				if (i > 1 && j > 2) {
					f[i][j] = Math.max(f[i][j], f[i-1][j-2] + A[i-1] - A[i-2]);
				}
			}
		}
		int profit = 0;
		for (int j = 1; j < 2 * K + 2; j += 2) {
			if (f[n][j] > profit) {
				profit = f[n][j];
			}
		}
		return profit;
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值