lettcode 动态规划 easy

  • House Robber
    一个数组中找出子数组和最大的和,要求数组中的数字不能连续出现。例如 [1, 2, 3, 1] 和最大为 4 ,是 1 和 3 的和;[2, 7, 9, 3, 1],和为 12,是 2,9,1 的和。
def rob1(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    if not nums:
        return 0
    a,b=0,0
    for i in range(len(nums)):
        if i%2==0:
            a=max(a+nums[i],b)
        else:
            b=max(b+nums[i],a)
    return max(a,b)
  • Paint House
    染房子,只有三种颜色,相邻房子不能同色,求最小花费。
    思路来源于网络
    思路: 每个房子有三种方案, 那么如果当前房子染一个色的话, 最小代价将是上一个房子的另两种颜色的最小代价+当前房子染色的代价。所以
dp[i][0] = min(dp[i-1][1], dp[i-1][2]) + costs[i-1][0];
dp[i][1] = min(dp[i-1][0], dp[i-1][2]) + costs[i-1][1];
dp[i][2] = min(dp[i-1][0], dp[i-1][1]) + costs[i-1][2];
# 代码来源于网络
class Solution {  
public:  
    int minCost(vector<vector<int>>& costs) {  
        if(costs.size()==0) return 0;  
        int len = costs.size();  
        vector<vector<int>> dp(len+1, vector<int>(3, 0));  
        for(int i = 1; i <= len; i++)  
        {  
            dp[i][0] = min(dp[i-1][1], dp[i-1][2]) + costs[i-1][0];  
            dp[i][1] = min(dp[i-1][0], dp[i-1][2]) + costs[i-1][1];  
            dp[i][2] = min(dp[i-1][0], dp[i-1][1]) + costs[i-1][2];  
        }  
        return min(dp[len][0], min(dp[len][1], dp[len][2]));  
    }  
}; 
  • Paint Fence
    涂栅栏,n 个栅栏 k 种颜色
    任意两个栅栏不能同色
def numWays(n, k):
    dp = [0, k, k*k, 0]
    if n <= 2 :
        return dp[n]
    for i in range(2, n):
        dp[3] = (k-1) * (dp[1] + dp[2])
        dp[1] = dp[2]
        dp[2] = dp[3]
    return dp[3]
  • Range Sum Query - Immutable
    求取一个数组区间的和
    题目给出很明确的要求, 对这个函数会有很多次调用,数组不会改变
    思路:如果是直接求取区间内的和,那么肯定会超时。换一个思路,如果能知道 i -1 位置之前的和,j 位置之前的和,那么 i 到 j 位置的和就显而易见了。j 位置的和 - i-1 位置的和即可。
    例如 [-2, 0, 3, -5, 2, -1],求取2,5 之间的和。
    那么知道 2-1=1 位置的和为 -2,5位置的和为 -3
    那么 2 - 5 之间的和为 -3 - (-2) = -1。注意 2 和 5 是数组的下标。
class NumArray(object):
    def __init__(self, nums):
        """
        :type nums: List[int]
        """
        # 这是一个数组,保存到当前位置的和
        self.dp = nums
        for i in xrange(1, len(nums)):
            self.dp[i] += self.dp[i-1]
        
    def sumRange(self, i, j):
        """
        :type i: int
        :type j: int
        :rtype: int
        """
        return self.dp[j] - (self.dp[i-1] if i > 0 else 0)
Input: [7,1,5,3,6,4]
Output: 5
# 在 1 的时候购入,在 6 的时候卖出。得到最大利润 5
def maxProfit(prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        length = len(prices)
        if length < 2:
            return 0
        min = prices[0]
        maxdiff = prices[1] - min
        for i in range(2,length):
            if prices[i-1] < min:
                min = prices[i-1]
            curdiff = prices[i] - min
            maxdiff = max(maxdiff, curdiff)
        if maxdiff <= 0:
            return 0
        return maxdiff
Input: [-2,1,-3,4,-1,2,1,-5,4],
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.

如果当前和为负数,那么根本没有加的必要,直接从当前位置开始累加即可,然后与当前的最大值进行比较即可。

def maxSubArray(nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if not nums:
            return
        cur_sum = 0
        max_sum = nums[0]
        for i in nums:
            if cur_sum < 0:
                cur_sum = i
            else:
                cur_sum += i
            #if cur_sum > max_sum:
                #max_sum = cur_sum
            max_sum = max(cur_sum, max_sum)
        return max_sum
  • Climbing Stairs
    爬楼梯,一次可以爬一个台阶,也可以爬两个台阶,对于一个有 n 个台阶的楼梯,有对少种爬法?
def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """
        if n <= 1:
            return 1
        dp = [i for i in range(n)]
        dp[0], dp[1] = 1, 2
        for i in range(2, n):
            dp[i] = dp[i-1] + dp[i-2]
        
        return dp[-1]
  • Min Cost Climbing Stairs
    数组的每个索引做为一个阶梯,第 i个阶梯对应着一个非负数的体力花费值 cost[i] (索引从0开始)。
    每当你爬上一个阶梯你都要花费对应的体力花费值,然后你可以选择继续爬一个阶梯或者爬两个阶梯。您需要找到达到楼层顶部的最低花费。在开始时,你可以选择从索引为 0 或 1 的元素作为初始阶梯。
Input: cost = [10, 15, 20]
Output: 15
Input: cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1]
Output: 6

注意,最终目的是跳上这个楼梯,意味着最后一个楼梯也要计算在内。
思路:当前楼梯的最小花费取决于前两个楼梯的花费,意味着第 i 层楼梯的花费是当前花费 + min(第 i-1 层楼梯的花费,第 i-2 层楼梯的花费),得到递推关系式就比较好解决了。

def minCostClimbingStairs(self, cost):
        """
        :type cost: List[int]
        :rtype: int
        """
        n = len(cost)
        if n == 0:
            return 0
        dp = [0 for _ in range(n)]
        dp[0], dp[1] = cost[0], cost[1]
        
        for i in range(2, n):
            dp[i] = min(dp[i-1], dp[i-2]) + cost[i]
        return min(dp[-1], dp[-2])
# O(1) 空间
def test(cost):
    dp0, dp1, dp2 = 0, 0, 0
    for i in range(2, len(cost) + 1):
        dp2 = min(dp0 + cost[i - 2], dp1 + cost[i - 1])
        dp0,dp1 = dp1,dp2
    return dp2
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容