动态规划在面试中的重要性
动态规划是面试中最常见的面试题型,面试难度相对较高,也能很好的辨认面试者对于数据结构的掌握水准,同时也可以对面试者的思维严谨性、逻辑完备性、算法功底扎实性进行全方位的考察。
动态规划的一些理论知识这里就一笔带过了。比如,动态规划的题目需要满足三大特性:最优子结构、重叠子问题和无后性。这里主要是针对leetcode
实战来进行的,因此,本文主要针对的是解题方向。
动态规划题型分类
动态规划有很多类型,这里按博主的理解,主要分为一维dp和二维dp,一维dp基本是简单问题,二维dp主要有背包问题、区间dp、博弈dp、树形dp等。接下来,博主不定期更新每一个类型的dp问题,旨在和大家一起解决dp问题,碰到dp不再难。
一维dp
该部分dp相对二维dp来说一般题目比较好想,通常的解题思路如下:
1、定义dp数组,明确第i个状态时dp[i]代表的含义是什么。
2、明确i-1、i、i+1等状态之间的状态转移关系式。
3、明确对于dp数组来说,badcase是什么。
经过以上三个步骤,一般情况下,一维dp不是问题了。
下面开始解题:
53、最大子序和
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
思路分析:
我们先看一下当前情况下的子数组的最大和,
子数组 | 最大和 |
---|---|
[-2] | -2 |
[-2, 1] | -2 + 1 = -1 |
[-2, 1, -3] | -2 + 1 = -1 |
[-2, 1, -3, 4] | 4 |
[-2, 1, -3, 4,-1] | 4 |
[-2, 1, -3, 4, -1, 2] | 4+(-1)+2=5 |
[-2, 1, -3, 4, -1, 2, 1] | 4+(-1)+2+1=6 |
[-2, 1, -3, 4, -1, 2, 1, -5] | 4+(-1)+2+1=6 |
[-2, 1, -3, 4, -1, 2, 1, -5, 4] | 4+(-1)+2+1=6 |
假设dp[i]
是以nums[i]
为结尾的子数组的最大和,
dp[i-1]
是以nums[i-1]
为结尾的子数组的最大和,那么dp[i]
和dp[i-1]
的关系是:
dp[i-1] + nums[i]
和 nums[i]
当中取大的。
即:
dp[i] = max(dp[i-1] + nums[i], nums[i])
代码如下:
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
if not nums or len(nums) == 0:
return 0
# 以nums[i]为结尾的最大子序和
dp = [0 for _ in range(len(nums))]
for index in range(len(nums)):
dp[index] = max(dp[index-1] + nums[index], nums[index])
return max(dp)
二维
二维动态规划问题主要有:
背包问题
背包问题系列请参考博主博客:
区间dp
树形dp
博弈dp
两重dp
五个类别问题,接下来,分系列进行介绍。