https://leetcode.com/problems/number-of-longest-increasing-subsequence/
Given an unsorted array of integers, find the number of longest increasing subsequence.
Example 1:
Input: [1,3,5,4,7] Output: 2 Explanation: The two longest increasing subsequence are [1, 3, 4, 7] and [1, 3, 5, 7].Example 2:
Input: [2,2,2,2,2] Output: 5 Explanation: The length of longest continuous increasing subsequence is 1, and there are 5 subsequences' length is 1, so output 5.Note: Length of the given array will be not exceed 2000 and the answer is guaranteed to be fit in 32-bit signed int.
二分搜索插入點,再二分搜索累加值,注意邊界情況。
class Solution {
public:
int findNumberOfLIS(vector<int>& nums) {
if(nums.empty()) return 0;
vector<vector<pair<int, int>>> arr;
int idx;
int pre_num, pre_idx;
for(int cur : nums){
// cout << cur << ' ';
idx = binary_search(arr, cur);
// cout << idx << ' ';
if(idx == arr.size()) arr.push_back(vector<pair<int, int>>());
if(idx == 0){
// if(arr[idx].size() != 0) arr[idx].push_back(pair<int, int>(cur, arr[idx].back().second+1));
// else arr[idx].push_back(pair<int, int>(cur, 1));
if(arr[idx].size() != 0) arr[idx].emplace_back(cur, arr[idx].back().second+1);
else arr[idx].emplace_back(cur, 1);
}else{
pre_idx = binary_search_sec(arr[idx-1], cur);
// cout << pre_idx << ' ';
if(pre_idx == -1){
pre_num = arr[idx-1].back().second;
}else{
pre_num = arr[idx-1].back().second - arr[idx-1][pre_idx].second;
}
// if(arr[idx].size() != 0) arr[idx].push_back(pair<int, int>(cur, pre_num+arr[idx].back().second));
// else arr[idx].push_back(pair<int, int>(cur, pre_num));
if(arr[idx].size() != 0) arr[idx].emplace_back(cur, pre_num+arr[idx].back().second);
else arr[idx].emplace_back(cur, pre_num);
}
// cout << endl;
}
return arr.back().back().second;
}
int binary_search(vector<vector<pair<int, int>>> &arr, int target){
int lo = -1, hi = arr.size()-1;
int mid;
while(lo < hi){
mid = (lo+hi+1)/2;
if(target > arr[mid].back().first) lo = mid;
else hi = mid-1;
}
return hi+1;
}
int binary_search_sec(vector<pair<int, int>> &arr, int target){
int lo = 0, hi = arr.size();
int mid;
while(lo < hi){
mid = (lo+hi)/2;
if(target > arr[mid].first) hi = mid;
else lo = mid+1;
}
return hi-1;
}
};