タイトル
アレイ整数所与の疾患、最長の長さは、立ち上がりシーケンスを発見しました。
例
输入: [10,9,2,5,3,7,101,18]
输出: 4
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。
思考
- アレイの上昇に最も長いサブシーケンスの各々の最後のシーケンス番号のレコード長。
- 現在の位置のために、トラバースの数の各々の前に、それぞれが、その数は、最長系列長の増加の終わりとして現在位置に最も長いを取るために、立ち上がりのサブシーケンスを取得し、より小さい見つけます。
コード1
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
if ( nums.size() == 0 ) return 0;
int res = 1;
vector<int> dp( nums.size(), 1 );
for ( int i = 1; i < nums.size(); ++i ) {
for ( int j = 0; j < i; ++j ) {
if ( nums[i] > nums[j] ) {
dp[i] = max( dp[i], dp[j] + 1);
}
}
res = max( dp[i], res );
}
return res;
}
};
アイデア2
- Oの複雑さ(nlgn)
- 配列Sを維持します。アレイを介して、充填された第1の値Sの第1のアレイは空です。
- アレイを介して、アレイは、現在NUMの数であり、
- 数がsにsのテールNUM、NUMよりも大きい場合。
- sが少ないnum個の尾数を超える場合、最初のものよりとs NUM numと引き換えに、ちょうどより多くを見つけます。
- このステップは、バイナリを使用して検索することができます。
- Sは最長の上昇シーケンスの最後の長さの長さです。
コード2
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
if ( nums.size() < 2 ) return nums.size();
vector<int> tail; // 以i为结尾的最长子序列。
tail.reserve( nums.size() );
tail.push_back( nums[0] );
int end = 0;
for ( int i = 1; i < nums.size(); ++i ) {
if ( nums[i] > tail[end] ) {
tail.push_back( nums[i] );
++end;
}
else {
// i前面找到第一个大于nums[i]的数并替换
int index = getFirst( tail, end, nums[i] );
tail[index] = nums[i];
}
}
return end + 1;
}
int getFirst( vector<int>& tail, int end, int target ) {
int start = 0;
while ( start < end ) {
int mid = ( start + end ) >> 1;
if ( tail[mid] >= target )
end = mid;
else
start = mid + 1;
}
return start;
}
};