对于该题,我们应该用回溯算法进行求解。
我们可以用dp数组来进行动态规划,用dp[ii]来记录以nums[ii]结尾的最长递增子序列,因此,最后我们返回dp数组的最大值即可。
动态规划四部曲。
1.dp数组的含义为以nums[ii]结尾的最长递增子序列长度。
2.dp数组的推导公式。
我们定义一个临时变量用于遍历并记录以nums[ii]结尾的可能最长子序列长度,如果当前数字nums[ii]大于遍历的nums[jj],此时就可以将nums[ii]加到nums[jj]后面,形成更长的子序列长度,因此,如果temp比dp[jj]+1(dp[jj]表示截止到nums[jj]最长的子序列长度)小的话,我们就令temp更新为dp[jj]+1。
int temp = 1;
for(int jj = 0;jj<ii;jj++)
{
if(nums[ii]>nums[jj]) temp = max(dp[jj]+1,temp);
}
dp[ii] = temp;
3.dp数组的初始化,初始情况,任何一个数字都可以构成一个子序列,因此,我们令dp数组的所有元素都为1。
4.遍历顺序,从前向后进行遍历。
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
int len = nums.size();
vector<int> dp(len,1);
for(int ii =1;ii<len;ii++)
{
int temp = 1;
for(int jj = 0;jj<ii;jj++)
{
if(nums[ii]>nums[jj]) temp = max(dp[jj]+1,temp);
}
dp[ii] = temp;
}
int result = dp[0];
for(int ii =1;ii<len;ii++)
result = max(result,dp[ii]);
return result;
}
};
首先,我们可以利用双指针的思想,利用快慢指针,我们定义一个结果量result,一个临时量temp,快指针遍历一次数组,如果快指针大于快指针前一个元素,就让temp++,如果此时temp大于了result,就跟新result。如果快指针小于等于前一个元素,我们就让慢指针low指向fast所指位置。
最后返回result即可。
class Solution {
public:
int findLengthOfLCIS(vector<int>& nums) {
int result = 1;
if(nums.size()==1) return 1;
int low = 0,fast = 1;
for(;fast<nums.size();fast++)
if(nums[fast]>nums[fast-1])
result = max(result,fast-low+1);
else
low=fast;
return result;
}
};
我们用dp数组来记录当前最长子序列长度,如果当前遍历的数字比前一个大,则我们更新dp[ii]让其等于dp[ii-1]+1,表示该元素可以增长这个连续递增序列。
动态规划四部曲。
1.dp数组的含义,包含当前元素的最长子序列长度。
2.dp数组的推导公式,if(nums[ii]>nums[ii-1])dp[ii] = dp[ii-1]+1;
3.dp数组的初始化,我们令dp数组最初都为1,这样访问时,即使连续子序列断掉,我们也可以继续访问。
4.遍历顺序,从前往后进行遍历。
class Solution {
public:
int findLengthOfLCIS(vector<int>& nums) {
vector<int>dp(nums.size(),1);
int result = 1;
for(int ii =1;ii<nums.size();ii++)
{
if(nums[ii]>nums[ii-1])dp[ii] = dp[ii-1]+1;
result = max(result,dp[ii]);
}
return result;
}
};
我们可以用动态规划的思路。
我们用dp数组来解决。dp[ii][jj]表示以nums2[ii-1]、nums1[jj-1]结尾的最长重复子数组。如果nums2[ii-1]=nums1[jj-1],那么我们让dp[ii][jj]进行更新,因为其含义,所以更新的话,需要dp[ii-1][jj-1],即在dp[ii-1][jj-1]的基础上进行+1;
对此,动态规划四部曲。
1.dp数组含义,dp数组用于记录以nums2[ii-1]、nums1[jj-1]结尾的最长重复子数组的长度。
2.dp数组的推导公式。
if(nums2[ii-1]==nums1[jj-1])
{
dp[ii][jj] = dp[ii-1][jj-1]+1;
}
3.dp数组的初始化。我们令dp数组初始全为零,表示遍历之前没有相同的元素。
4.遍历顺序。我们用两层for循环,分别循环两个数组,表示两个数组每个元素都进行一次比较。
class Solution {
public:
int findLength(vector<int>& nums1, vector<int>& nums2) {
vector<vector<int>>dp(nums2.size()+1,vector<int>(nums1.size()+1,0));
int result = 0;
for(int ii =1;ii<nums2.size()+1;ii++)
{
for(int jj =1;jj<nums1.size()+1;jj++)
if(nums2[ii-1]==nums1[jj-1])
{
dp[ii][jj] = dp[ii-1][jj-1]+1;
result=max(result,dp[ii][jj]);
}
}
return result;
}
};