leetcode算法刷题(二)——动态规划(一)

上次刷了五六道题,都是关于string处理的,这次想换个知识点刷一下,然后再回头刷string的题,当做复习..
这几天主要会选择动态规划的题目,因为以前从没刷过这方面的东西,很多东西都不是很懂..就当重新学习吧~

第198题 House Robber

题目的意思:一个抢劫者要抢劫一条街上的住户,由于每家都有报警器,连续抢劫2家就会触发报警器。现在给你一个列表,里面的元素是每家可抢劫的金额,要求在不触发报警器的情况下抢劫最多的钱

分析:这是一道典型的动态规划题,我们先分析一下。
对于每一家,抢劫者的选择有两个:抢劫或者不抢劫。根据要求我们可以知道,不能连续抢劫2家。假设d(N)是抢劫犯抢劫到第N家的最大金额。当抢劫者抢劫第N家的时候,有两种情况:

  1. 抢劫第N家,这时候d(N)=nums[N]+d(N-1),而且我们可以知道,第N-1家不能抢劫
  2. 不抢劫第N家,这时候d(N)=d(N-1)
    所以我们可以得到:d(N) = max(nums[N] + d(N-1), d(N-1)). 下面是解法:
class Solution:
    # @param {integer[]} nums
    # @return {integer}
    def rob(self, nums):
        noRobN = 0  (不抢劫第N家)
        robN = 0        (抢劫第N家)
        maxProfix = 0       (最大金额)
        for i in range(len(nums)):
            robN = nums[N] + noRobN
            noRobN = maxProfix
            maxProfix = max(robN, noRobN)
            
        return maxProfix

第70题 Climbing Stairs

题目的意思:上楼要爬n级台阶,每次爬台阶有两种爬法:1. 爬一级台阶 2. 爬二级台阶。现在要求爬n级台阶一共有多少种爬法

分析:假设d(n)是爬第n级台阶的时候的爬法个数。当要爬n级台阶的时候,有两种情况:

  1. 从第n-1级台阶爬一级
  2. 从第n-2级台阶爬两级
    所以我们可以得到:d(n) = d(n-1) + d(n-2),下面是解法:
class Solution:
    # @param {integer[]} nums
    # @return {integer}
    def climbStairs(self, n):
        step = 0
        onestep = 1
        twostep = 0
        
        for i in range(n):
            step = onestep + twostep
            twostep = onestep
            onestep = step
        return step

第120题 Triangle

题目的意思:给予一个由多个数列组成的三角形,找出从顶端到底层的最短路径,上层的数字只能移动到下层中与之相邻的数字上。例如:

[
     [2],
    [3,4],
   [6,5,7],
  [4,1,8,3]
]

最短路径和 = 2+3+5+1 = 11

分析:这道题不能直接找每行数列的最小值然后相加就和. 这道题的思路是把下层的数依次与上层的数相加(取相邻上层的两个数中的较小的那个),然后取最小,直到最底层。

class Solution:
    # @param triangle, a list of lists of integers
    # @return an integer
    def minimumTotal(self, tr):
        #特殊情况,只有一行
        if len(tr) == 1:
            return tr[0][0]
        for i in range(1, len(tr)): #从第二行开始
            for j in range(len(tr[i])):
                if j == 0:      #第一个数
                    tr[i][j] = tr[i-1][j] + tr[i][j]
                elif j == len(tr[i]) -1:    #最后一个数
                    tr[i][j] = tr[i][j] + tr[i-1][j-1]
                else:       #一般情况
                    tr[i][j] = min(tr[i-1][j-1], tr[i-1][j]) + tr[i][j]
        return min(tr[len(tr)-1])

延伸一下,如果需要输出路径,也很简单,最开始我们新建一个列表,比如li = [],然后每当取到每行的最小值的时候,就把这个数推入列表中,最后输出列表即可

第64题 Minimum Path Sum

题目的意思:给予一个m * n 的表格grid,表格里面填充了数字,求从grid[0][0]到grid[m-1][n-1]的最小和路径。每次移动只能向下或向右
分析:这道题和上一道基本一样,思路就是MPS[i][j] = Min(MPS[i-1][j],MPS[i][j-1])+ val[i][j]

class Solution:
    # @param {integer[][]} grid
    # @return {integer}
    def minPathSum(self, grid):
        row = len(grid)     #行
        col = len(grid[0])  #列

        for i in range(row):
            for j in range(col):
                if i == 0 and j ==0:
                    pass
                elif i == 0 and j != 0:      #最上面一行
                    grid[i][j] = grid[i][j] + grid[i][j-1]
                elif j == 0 and i != 0:      #最左边一列
                    grid[i][j] = grid[i][j] + grid[i-1][j]
                else:
                    grid[i][j] = grid[i][j] + min(grid[i][j-1], grid[i-1][j])
        return grid[row-1][col-1]

转载于:https://www.cnblogs.com/eric-nirnava/p/dynamic1.html

你可能感兴趣的:(leetcode算法刷题(二)——动态规划(一))