Week15
Problem–Medium–646. Maximum Length of Pair Chain
You are given n
pairs of numbers. In every pair, the first number is always smaller than the second number.
Now, we define a pair (c, d)
can follow another pair (a, b)
if and only if b < c
. Chain of pairs can be formed in this fashion.
Given a set of pairs, find the length longest chain which can be formed. You needn’t use up all the given pairs. You can select pairs in any order.
Example 1:
Input: [[1,2], [2,3], [3,4]] Output: 2 Explanation: The longest chain is [1,2] -> [3,4]
Note:
- The number of given pairs will be in the range [1, 1000].
题目解析:
这道题类似于最长递增子序列问题,但是判定标准变了一下,这一次一个结点不再是一个数,而是一对数,只需在判定的时候判断前节点的第二个数与后节点的第一个数的大小关系即可,与判定一个数类似。这道题还有一个麻烦的地方就是寻找子序列不一定是严格从头到尾的一个序列,这个序列严格上在这里是一个集合,无先后之分,我们只需在里面找到最多的元素构成一个最长的递增子序列,与普通的最长递归子序列又不同。
无顺序的一个影响就是,前面出现的比较大的数,以其为结尾的序列的长度还未更新为最长的,因此,我们需要在寻找前做一个排序的预处理,即较大的数永远在序列的后面更新最长长度,而不是一开始就更新长度,因为较小的数还未更新其最长长度。举个例子,10,5,4,1,如果我们按原始的方法从头向后检索,状态len[0]永远为2,因为较小的数的最长长度len[i]还未更新为最长的。但是,假设将序列排序,1,4,5,10,那么,结果就正确了,因为较小的数的最长序列已经提前得到更新,因此正确。类似的,对于这道题也是如此,将节点按第一个数进行升序排序,然后直接查找即可。
状态定义:
len[i]: 以节点i为终点的最长递增序列
状态初始化:
len[i] = 1
状态转移方程:
if pairs[i][0] > pairs[j][1]: len[i] = max(len[i], len[j] + 1)
代码:
class Solution {
public:
int findLongestChain(vector<vector<int>>& pairs) {
int n = pairs.size();
mySort(pairs);
cout << "ok" << endl;
vector<int> len(n, 1);
int max_len = 1;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
len[i] = max(len[i], pairs[i][0] > pairs[j][1] ? len[j] + 1 : 1);
}
if (max_len < len[i])
max_len = len[i];
}
return max_len;
}
void mySort(vector<vector<int>>& pairs) {
for (int i = 0; i < pairs.size(); i++) {
for (int j = i + 1; j < pairs.size(); j++) {
if (pairs[i][0] > pairs[j][0]) {
vector<int> temp = pairs[i];
pairs[i] = pairs[j];
pairs[j] = temp;
} else if (pairs[i][0] == pairs[j][0] && pairs[i][1] > pairs[j][1]) {
vector<int> temp = pairs[i];
pairs[i] = pairs[j];
pairs[j] = temp;
}
}
}
}
};