3个月用python刷完leetcode600题!-动态规划简单题

十五天的时间,刷完了所有的简单题,避免遗忘,所以开始简单题的二刷,第一遍刷题的时候过得速度比较快,因为我觉得基础不好的我,不要硬着头皮去想最优的方法,而是应该尽量去学一些算法思想,所以每道题只给自己5-10分钟的时间想,想不出来的就去找相关的答案,所以刷的比较快。二刷的时候按照leetcode官方给出的题目分类展开,同时,将解题思路记录于简书加深印象。
想要一起刷题的小伙伴,我们一起加油吧!
我的github连接:https://github.com/princewen/leetcode_python

关于动态规划,在微信公众号看到了一篇不错的入门文章,分享给大家:https://mp.weixin.qq.com/s?src=3&timestamp=1498535774&ver=1&signature=wlhff7Gzbelps0O191bGYx8ILrglCMn7B7rLeedEneRIOcWsKyfWqD1Sz7YJrX4bY-kNUSKFQIY7piIt2oTd777tpeNmkxvNAhikk93UrBEKevDyI6B-HwjRDFxiuvmgEPzX1bh3UxhzY1j5sLLtqMdDdcAGpV6SX5ZlV*VAU=

53. Maximum Subarray

参见数组简单题(一)

62. Unique Paths

《3个月用python刷完leetcode600题!-动态规划简单题》 62. Unique Paths

这道题乍一看是挺简单的,从左上角走到右下角需要t=(m-1)+(n-1)步,这t步中有n-1步是往下走,所以是一个简单的组合题:

class Solution(object):
    def uniquePaths(self, m, n):
        """
        :type m: int
        :type n: int
        :rtype: int
        """
        if m > n:
            m, n = m - 1, n - 1
        else:
            m, n = n - 1, m - 1
        if m <= 0 or n <= 0:
            return 1
        t = m + n
        sub = 1
        for i in range(1, n):
            t = t * (m + n - i)
            sub = sub * (i + 1)
        return t / sub

这是很简单的想法,但并不是动态规划的思想,我们可以定义一个F函数表示走到每一个的走法数,想要走到最后一格(m,n),可以先走到(m-1,n),也可以先走到(m,n-1),那么F(m,n)=F(m-1,n)+F(m,n-1),我们按照反向的思维去求解这个问题,可以写成如下的递归代码:

class Solution(object):
    def uniquePaths(self, m, n):
        """
        :type m: int
        :type n: int
        :rtype: int
        """
        if m<1 or n<1:
            return 0
        elif m==1 and n==1:
            return 1
        elif m==1:
            return self.uniquePaths(m,n-1)
        elif n==1:
            return self.uniquePaths(m-1,n)
        else:
            return self.uniquePaths(m-1,n) + self.uniquePaths(m,n-1)

但上述的递归代码报错了,因为递归导致时间复杂度很大,我们相当于建立了一个二叉树,时间复杂度是指数级的,所以我们不妨按照正向的思维,建立一个m*n的矩阵,从第一行开始,循环数组,不断计算走到该位置的总共的走法:

class Solution(object):
    def uniquePaths(self, m, n):
        """
        :type m: int
        :type n: int
        :rtype: int
        """
        count = [[0 for t in range(n)] for x in range(m)]
        count[0][0] = 1
        for i in range(m):
            for j in range(n):
                if i == 0 and j == 0:
                    count[i][j] = 1
                elif i == 0:
                    count[i][j] = count[i][j - 1]
                elif j == 0:
                    count[i][j] = count[i - 1][j]
                else:
                    count[i][j] = count[i - 1][j] + count[i][j - 1]
        return count[m - 1][n - 1]

63. Unique Paths II

《3个月用python刷完leetcode600题!-动态规划简单题》 63. Unique Paths II

这道题和62题思路一致,只不过增加了一些障碍,我们只需要把这些障碍的位置其路径矩阵赋值为0即可:

class Solution(object):
    def uniquePathsWithObstacles(self, obstacleGrid):
        """
        :type obstacleGrid: List[List[int]]
        :rtype: int
        """
        if not obstacleGrid:
            return 0
        for i in range(len(obstacleGrid)):
            for j in range(len(obstacleGrid[0])):
                if obstacleGrid[i][j] == 1:
                    obstacleGrid[i][j] = 0
                elif i == 0 and j == 0:
                    obstacleGrid[i][j] = 1
                elif i == 0:
                    obstacleGrid[i][j] = obstacleGrid[i][j - 1]
                elif j == 0:
                    obstacleGrid[i][j] = obstacleGrid[i - 1][j]
                else:
                    obstacleGrid[i][j] = obstacleGrid[i - 1][j] + obstacleGrid[i][j - 1]
        return obstacleGrid[i][j]

64. Minimum Path Sum

《3个月用python刷完leetcode600题!-动态规划简单题》 64. Minimum Path Sum

仍然是和62题一样的思路。

class Solution(object):
    def minPathSum(self, grid):
        """
        :type grid: List[List[int]]
        :rtype: int
        """
        for i in range(len(grid)-1,-1,-1):
            for j in range(len(grid[0])-1,-1,-1):
                if j == len(grid[0])-1 and i== len(grid)-1:
                    continue
                elif j == len(grid[0])-1:
                    grid[i][j] = grid[i+1][j] + grid[i][j]
                elif i == len(grid)-1:
                    grid[i][j] = grid[i][j] + grid[i][j+1]
                else:
                    grid[i][j] = grid[i][j] + min(grid[i+1][j],grid[i][j+1])
        return grid[0][0]

70. Climbing Stairs

《3个月用python刷完leetcode600题!-动态规划简单题》 70. Climbing Stairs

逆向思维,正向求解,详细解释参照文章开头给出的公众号帖子。

class Solution(object):
    def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """
        a = 1
        b = 1
        for i in range(2,n+1):
            a,b = b,a+b
        return b

121. Best Time to Buy and Sell Stock

参照数组简单题

303. Range Sum Query – Immutable

《3个月用python刷完leetcode600题!-动态规划简单题》 303. Range Sum Query – Immutable

class NumArray(object):
    def __init__(self, nums):
        """
        :type nums: List[int]
        """
        self.dp = nums
        for i in range(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)

如果你喜欢我写的文章,可以帮忙给小编点个赞或者加个关注,我一定会互粉的!
如果大家对leetcode感兴趣,欢迎跟小编进行交流,小编微信为sxw2251,加我要写好备注哟!:

《3个月用python刷完leetcode600题!-动态规划简单题》 我的微信

    原文作者:石晓文的学习日记
    原文地址: https://www.jianshu.com/p/03ce80f5d953
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞