动态规划总结(一)

动态规划在算法中属于难的问题了,在leetcode中属于中等偏上难度,但是动规是面试容易问到的,因此掌握基本的动规题目很有必要。下面列举leetcode中用DP处理的题目,其中有些用到贪心算法,就不单列出来了,本质上贪心也是动态规划的一个特例。动态规划重要的是能找出递推式,这需要我们多加练习,需要有一个过程。

有关买卖股票的题目有几道,这里列举前两道题。
1,Best Time to Buy and Sell Stock
给定一个整形数组,第i个元素代表第i天股票的价格。如果我们只能做一次交易,也就是只能买卖一次,如何能得到最大的利益。

我们把它抽象一下,就是从一个数组中找到两个元素,使他们的差最大,但是有一个限定,要考虑顺序,因为必须先买了才可以卖。我们设定一个全局的变量max用来保存最大值,用一个变量profit记录每次比较时的利润,然后与max比较,每次都取最大值。时间复杂度为O(n)。
代码如下:
public class Solution {
    public int maxProfit(int[] prices) {
        int profit = 0;
        int max = 0;
        for(int i = 1; i < prices.length; i++) {
            profit += prices[i] - prices[i - 1];
            if(profit < 0) profit = 0;
            if(profit > max) max = profit;
        }
        return max;
    }
}


2,Best Time to Buy and Sell Stock II
给定一个整形数组,第i个元素代表第i天股票的价格。如果我们可以做多次交易,也就是我们可以买卖多次,如何能得到最大的利益。

与上面的题目相比,不同的是可以买卖多次,当仅可以买卖一次的时候,我们每次保留一个最大值;既然可以买卖多次,那么只要是profit大于零,我们都要把它算到最后的利润里。所以我们只要在profit大于0的时候,将它加入max中就可以了。代码如下:
public class Solution {
    public int maxProfit(int[] prices) {
        int profit = 0;
	int max = 0;
	for (int i = 1; i < prices.length; i++) {
		profit = prices[i] - prices[i-1];
		if(profit > 0) {
			max += profit;
		} else {
			profit = 0;
		}
	}
	return max;
    }
}


3,Triangle
给定一个三角形,找出从top到bottom的最小带权路径,每个元素只能移动到下面与它们相邻的元素。
例如:
[
     [ 2],
    [ 3,4],
   [6, 5,7],
  [4, 1,8,3]
]
输出:11    (2 + 3 + 5 + 1 = 11)

三角形计算属于动态规划的经典题目,对于这道题,我们可以采用一个滚动数组,从下往上开始计算,每次保留最小的值,这样一直到三角形的顶点,我们就得到一个最小带权路径了。时间复杂度为O(n^2);
代码如下:
public class Solution {
    public int minimumTotal(List<List<Integer>> triangle) {
        int[] result = new int[triangle.size() + 1];
        for(int i = triangle.size()-1; i >= 0; i--) {
            List<Integer> list = triangle.get(i);
            for(int j = 0; j < triangle.get(i).size(); j++) {
                result[j] = Math.min(result[j], result[j + 1]) + triangle.get(i).get(j);
            }
        }
        return result[0];
    }
}

猜你喜欢

转载自kickcode.iteye.com/blog/2264673