这次挑选了2道与动态规划有关的问题。
64. Minimum Path Sum.
Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.
Note: You can only move either down or right at any point in time.
难度为Medium。题意很明确,就是给定m*n的正整数矩阵。从左上角开始,只允许向右或向下走,走到右下角停止。找到所有数值和最小的路径。我的解题思路是:首先第一行和第一列的最短路径由于只能向右或向下走,所以他们最短路径paths[i][0] = paths[i - 1][0] + grid[i][0];以及paths[0][j] = paths[0][j - 1] + grid[0][j]; 然后根据动态规划的思想,逐行从左到右的根据下面公式进行最短路径计算: paths[i][j] = min(paths[i - 1][j], paths[i][j - 1]) + grid[i][j];代码如下:
<span style="font-family:Helvetica Neue, Helvetica, Arial, sans-serif;color:#333333;">class Solution {
public:
int minPathSum(vector<vector<int> > &grid) {
int m = grid.size();
int n = grid[0].size();
int paths[m][n];
paths[0][0] = grid[0][0];
for(int i = 1; i < m; ++i)
{
paths[i][0] = paths[i - 1][0] + grid[i][0];
}
for(int j = 1; j < n; ++j)
{
paths[0][j] = paths[0][j - 1] + grid[0][j];
}
for(int i = 1; i < m; ++i)
for(int j = 1; j < n; ++j)
{
paths[i][j] = std::min(paths[i - 1][j], paths[i][j - 1])
+ grid[i][j];
}
return paths[m - 1][n - 1];
}
};</span>
300. Longest Increasing Subsequence.
Given an unsorted array of integers, find the length of longest increasing subsequence.
For example,
Given [10, 9, 2, 5, 3, 7, 101, 18]
,
The longest increasing subsequence is [2, 3, 7, 101]
, therefore the length is 4
. Note that there may be more than one LIS combination, it is only necessary for you to return the length.
Your algorithm should run in O(n2) complexity.
本题难度也为Medium。题意就是找出最大的子数列。要注意的是子数列不需要连续,但顺序依然不变。这题也可以利用动态规划的思想,用length[i]来表示数组中从0到i的最大子数列,然后因为length[j]其实就是0~j-1中所有数值比j小的位置中最大的lenth+1,这样从头到尾进行一次计算再找出最大的lenth[j]便是最终要输出的答案,所以公式为:
length[j]=max(length[j],length[i]+1);
详细代码如下:
<span style="font-family:Helvetica Neue, Helvetica, Arial, sans-serif;color:#333333;"><span style="font-size:24px;">class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
if(nums.size()==0)
return 0;
vector<int> length(nums.size(),1);
int ret=1;
for(int i=0;i<nums.size();i++)
for(int j=i+1;j<nums.size();j++)
if(nums[i]<nums[j]){
length[j]=max(length[j],length[i]+1);
if(length[j]>ret)
ret=length[j];
}
return ret;
}
};</span></span>