目录
例1:爬楼梯(easy)
class Solution {
public:
int climbStairs(int n) {
vector<int>dp(n + 3, 0);
dp[1] = 1;
dp[2] = 2;
for (int i = 3; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
};
class Solution:
def climb(self,n):
dp=[0]*(n+1)
dp[1]=1
dp[2]=2
for i in range(3,n+1):
dp[i]=dp[i-1]+dp[i-2]
return dp[n]
例2:打家劫舍(easy)
class Solution {
public:
int rob(vector<int>& nums) {
if (nums.size() == 0) {
return 0;
}
if (nums.size() == 1) {
return nums[0];
}
vector<int> dp(nums.size(), 0);
dp[0] = nums[0];
dp[1] = max(nums[0], nums[1]);
for (int i = 2; i < nums.size(); i++) {
dp[i] = max(dp[i - 1], nums[i] + dp[i - 2]);
}
return dp[nums.size() - 1];
}
};
class Solution:
def rmb(self,nums):
n=len(nums)
if n==0:
return 0
if n==1:
return nums[0]
dp=[0]*(n+1)
dp[0]=nums[0]
dp[1]=max(nums[0],nums[1])
for i in range(2,n):
dp[i]=max(dp[i-2]+nums[i-1],dp[i-1])
return dp[n-1]
例3:最大字段和(easy)
class Solution {
public:
int maxSubArray(vector<int>& nums) {
vector<int>dp(nums.size(), 0);
dp[0] = nums[0];
int max_res = dp[0];
for (int i = 1; i < nums.size(); i++) {
dp[i] = max(dp[i - 1] + nums[i], nums[i]);
if (dp[i] >= max_res) {
max_res = dp[i];
}
}
return max_res;
}
};
class Solution:
def max_sum(self,nums):
n=len(nums)
if n==1:
return nums[0]
if n==0:
return 0
dp=[0]*n
dp[0]=nums[0]
max_result=dp[0]
for i in range(1,n):
dp[i]=max(dp[i-1]+nums[i],nums[i])
if dp[i]>max_result:
max_result=dp[i]
return max_result
例4:找零钱(medium)
class Solution {
public:
int coinChange(std::vector<int>& coins, int amount) {
std::vector<int> dp(amount + 1, -1);
dp[0] = 0;
for (int i = 1; i <= amount; i++) {
for (int j = 0; j < coins.size(); j++) {
if (i - coins[j] >= 0 && dp[i - coins[j]] != -1) {
if (dp[i] == -1 || dp[i] > dp[i - coins[j]] + 1) {
dp[i] = dp[i - coins[j]] + 1;
}
}
}
}
return dp[amount];
}
};
例5:三角形(medium)
class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle) {
vector<vector<int>> dp(triangle);
for (int i = dp.size() - 2; i >= 0; i--) {
for (int j = 0; j < dp[i].size(); j++) {
dp[i][j] = std::min(dp[i + 1][j], dp[i + 1][j + 1]) + triangle[i][j];
}
}
return dp[0][0];
}
};
class Solution6:
def minnums(self,triangle):
dp=triangle
m=len(triangle)
if m==0:
return 0
if m==1:
return dp[0][0]
for i in range(m-2,-1,-1):
for j in range(0,len(dp[i])):
print(i,j)
dp[i][j]=min(dp[i+1][j],dp[i+1][j+1])+triangle[i][j]
return dp[0][0]
例6:最长上升子序列(medium,hard)
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
if (nums.size() == 0) {
return 0;
}
vector<int>stack;
stack.push_back(nums[0]);
for (int i = 1; i < nums.size(); i++) {
if (nums[i] > stack.back()) {
stack.push_back(nums[i]);
}
else {
for (int j = 0; j < stack.size(); j++) {
if (stack[j] >= nums[i]) {
stack[j] = nums[i];
break;
}
}
}
}
return stack.size();
}
};
class Solution:
def max_list(self,nums):
if len(nums)==0:
return 0
temp_llist=[nums[0]]
for i in range(1,len(nums)):
id=len(temp_llist)
if temp_llist[id-1] <nums[i]:
temp_llist.append(nums[i])
else:
for j in range(id):
if temp_llist[j]>=nums[i]:
temp_llist[j]=nums[i]
break
return len(temp_llist)
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
if (nums.size() == 0) {
return 0;
}
vector<int>dp(nums.size(), 0);
dp[0] = 1;
int LIS = 1;
for (int i = 1; i < nums.size(); i++) {
dp[i] = 1;
for (int j = 0; j < i; j++) {
if (nums[i] > nums[j] && dp[i] < dp[j] + 1) {
dp[i] = dp[j] + 1;
}
}
if (LIS < dp[i]) {
LIS = dp[i];
}
}
return LIS;
}
};
例7:最小路径和(medium)
class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
if (grid.size() == 0) {
return 0;
}
int row = grid.size();
int column = grid[0].size();
vector<vector<int>>dp(grid);
dp[0][0] = grid[0][0];
for (int i = 1; i < column; i++) {
dp[0][i] = grid[0][i] + dp[0][i - 1];
}
for (int i = 1; i < row; i++) {
dp[i][0] = grid[i][0] + dp[i - 1][0];
for (int j = 1; j < column; j++) {
dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
}
}
return dp[row - 1][column - 1];
}
};
class Solution:
def min_path(self,grid):
dp=grid
m,n=len(dp),len(dp[0])
for i in range(1,m):
dp[i][0]=dp[i-1][0]+grid[i][0]
for j in range(1,n):
dp[0][j]=dp[0][j-1]+grid[0][j]
for i in range(1,m):
for j in range(1,n):
dp[i][j]=min(dp[i-1][j],dp[i][j-1])+grid[i][j]
return dp[m-1][n-1]
例8:地牢游戏(hard)
class Solution {
public:
int calculateMinimumHP(vector<vector<int>>& dungeon) {
if (dungeon.size() == 0) {
return 0;
}
vector<vector<int>> dp(dungeon);
int row = dungeon.size();
int column = dungeon[0].size();
dp[row - 1][column - 1] = max(1, 1 - dungeon[row - 1][column - 1]);
for (int i = column - 2; i >= 0; i--) {
dp[row - 1][i] = max(1, dp[row - 1][i + 1] - dungeon[row - 1][i]);
}
for (int i = row - 2; i >= 0; i--) {
dp[i][column - 1] = max(1, dp[i + 1][column - 1] - dungeon[i][column - 1]);
}
for (int i = row - 2; i >= 0; i--) {
for (int j = column - 2; j >= 0; j--) {
int dp_min = min(dp[i + 1][j], dp[i][j + 1]);
dp[i][j] = max(1, dp_min - dungeon[i][j]);
}
}
return dp[0][0];
}
};
class Solution():
def calculateMinimumHP(self,dungeon):
if len(dungeon)==0:return 0
dp=dungeon
m,n=len(dungeon),len(dungeon[0])
dp[m-1][n-1]=max(1,1-dungeon[m-1][n-1])
for i in range(m-2,-1,-1):
dp[i][n-1]=max(1,dp[i+1][n-1]-dungeon[i][n-1])
for i in range(n-2,-1,-1):
dp[m-1][i]=max(1,dp[m-1][i+1]-dungeon[m-1][i])
for i in range(m-2,-1,-1):
for j in range(n-2,-1,-1):
dp_min=min(dp[i+1][j],dp[i][j+1])
dp[i][j]=max(1,dp_min-dungeon[i][j])
return dp[0][0]
if __name__=='__main__':
s=Solution()
res=s.calculateMinimumHP([[-2,-3,3],[-5,-10,1],[10,30,-5]])
print(res)
例9:乘积最大子数组(medium)
class Solution(object):
def maxProduct(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if nums is None:return 0
dp=[[0 for _ in range(len(nums))] for _ in range(2)]
dp[0][0],dp[1][0]=nums[0],nums[0]
#[0]为正数最大,[1]负数为最小
max_n=dp[0][0]
for i in range(1,len(nums)):
if nums[i]>=0:
dp[0][i]=max(dp[0][i-1]*nums[i],nums[i])
dp[1][i]=dp[1][i-1]*nums[i]
else:
dp[0][i]=dp[1][i-1]*nums[i]
dp[1][i]=min(dp[0][i-1]*nums[i],nums[i],)
max_n=max(dp[0][i],max_n)
return max_n
class Solution(object):
def maxProduct(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if nums is None:return 0
dp=[[0 for _ in range(2)] for _ in range(2)]
dp[0][1],dp[0][0],res=nums[0],nums[0],nums[0]
for i in range(1,len(nums)):
x,y=i%2,(i-1)%2
dp[x][0]=max(dp[y][0]*nums[i],dp[y][1]*nums[i],nums[i])
dp[x][1]=min(dp[y][0]*nums[i],dp[y][1]*nums[i],nums[i])
res=max(res,dp[x][0])
return res
例10:01 矩阵(medium)
class Solution:
def updateMatrix(self,mat):
m,n=len(mat),len(mat[0])
dp=[[10**9]*n for _ in range(m)]
for i in range(m):
for j in range(n):
if mat[i][j]==0:
dp[i][j]=0
for i in range(m):
for j in range(n):
if i>=1:
dp[i][j]=min(dp[i][j],dp[i-1][j]+1)
if j>=1:
dp[i][j]=min(dp[i][j],dp[i][j-1]+1)
for i in range(m-1,-1,-1):
for j in range(n-1,-1,-1):
if i<m-1:
dp[i][j]=min(dp[i][j],dp[i+1][j]+1)
if j<n-1:
dp[i][j]=min(dp[i][j],dp[i][j+1]+1)
return dp
class Solution:
def updateMatrix(self, matrix) :
m, n = len(matrix), len(matrix[0])
dp = [[0] * n for _ in range(m)]
zeroes_pos = [(i, j) for i in range(m) for j in range(n) if matrix[i][j] == 0]
# 将所有的 0 添加进初始队列中
q = collections.deque(zeroes_pos)
seen = set(zeroes_pos)
# 广度优先搜索
while q:
i, j = q.popleft()
for ni, nj in [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]:
if 0 <= ni < m and 0 <= nj < n and (ni, nj) not in seen:
dp[ni][nj] = dp[i][j] + 1
q.append((ni, nj))
seen.add((ni, nj))
return dp
class Solution {
public:
vector<vector<int>> updateMatrix(vector<vector<int>>& mat) {
int n = mat.size(), m = mat[0].size();
vector<vector<int>> dp(n, vector<int>(m, INT_MAX - 1));
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
if (!mat[i][j]) // 格点为0的位置初始dp状态为0
dp[i][j] = 0;
for (int i = 0; i < n; i++) // 左上到右下更新
for (int j = 0; j < m; j++) {
if (i >= 1) // 上移
dp[i][j] = min(dp[i][j], dp[i - 1][j] + 1);
if (j >= 1) // 左移
dp[i][j] = min(dp[i][j], dp[i][j - 1] + 1);
}
for (int i = n - 1; i >= 0; i--) // 右下到左上更新
for (int j = m - 1; j >= 0; j--) {
if (i < n - 1) // 下移
dp[i][j] = min(dp[i][j], dp[i + 1][j] + 1);
if (j < m - 1) // 右移
dp[i][j] = min(dp[i][j], dp[i][j + 1] + 1);
}
return dp;
}
};