最长递增子序列(dp动态规划,贪心,最大增长子序列技巧,leetcode300)-------------------c++实现
题目表述
给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。
子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。
样例
输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。
条件
1 <= nums.length <= 2500
-104 <= nums[i] <= 104
思路
1.dp暴力思想,申请一个int数组位数和原数组一一对应,每一位都遍历之前位数的值以及最长子序列个数,对比得出最大值保存在此位。
2.贪心,保存最长递增序列子串x,每一位依次判断,如果该位比x的最后一位大,则直接保存,否则,把该值替换掉x里大于该值的最小值。
注意点
注意边界值
ac代码
c++:
dp暴力算法
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
vector<int> remember = vector<int>(nums.size());
if(nums.size()<=1)
return nums.size();
else
remember[0]=1;
for(int i = 1;i<nums.size();i++) //remember[i]==1则表示0-(i-1)的字符串可以被表示
{ int max = 0;
for(int j=0;j<i;j++)
if(nums[j]<nums[i]&&remember[j]>=max)
max=remember[j];
remember[i]=max+1;
}
int result=0;
for(auto i:remember)
if(i>result)result=i;
return result;
}
};
贪心巧妙替换算法
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
vector<int> data;
data.push_back(nums[0]);
if(!nums.size())
return 0;
int max = 1;
for(int i=1;i<nums.size();i++)
{
if(nums[i]>data[max-1])
{max++;data.push_back(nums[i]);}
else
{
int front = 0,rear = max-1;
int middle;
while(front<=rear)
{
middle=(front+rear)>>1;
if(data[middle]==nums[i])
break;
if(data[middle]>nums[i])
rear=middle-1;
else
front=middle+1;
}
if(data[middle]!=nums[i])
data[front]=nums[i];
}
}
return max;
}
};
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/squares-of-a-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。