阅读目录
- 1. 题目
- 2. 解题思路
- 3. 代码实现
1. 题目
2. 解题思路
首先,我们对人的身高按照从小到大排序,特别注意,对于身高相等的人,要按照体重从高到低排序。这时候,序列已经满足了在上面的人要比下面的人矮一点,然后,我们只需要保证提取到一个最长的体重的上升子序列即可。这一步骤也就是 LeetCode 300——最长上升子序列 的解答思路,贪心+二分查找。
为什么身高相等的情况下,要按照体重从高到低排序呢?因为,如果按照体重从低到高排序的话,第二个步骤身高相等的人就会满足体重的上升子序列,但实际上,题目要求的则是上面的人要比下面的人高一点,所以身高相同的情况下只能保留一个体重最小的。
比如身高是 [ 2 , 3 , 3 , 3 , 5 , 8 ] [2, 3, 3, 3, 5, 8] [2,3,3,3,5,8],体重是 [ 3 , 5 , 5 , 4 , 2 , 6 ] [3, 5, 5, 4, 2, 6] [3,5,5,4,2,6],最终满足要求的其中一个序列是 [ ( 2 , 3 ) , ( 3 , 4 ) , ( 8 , 6 ) ] [(2,3), (3,4), (8,6)] [(2,3),(3,4),(8,6)]。
而如果体重按照升序排列的话,那么身高是 [ 2 , 3 , 3 , 3 , 5 , 8 ] [2, 3, 3, 3, 5, 8] [2,3,3,3,5,8],体重是 [ 3 , 4 , 4 , 5 , 2 , 6 ] [3, 4, 4, 5, 2, 6] [3,4,4,5,2,6],得到的答案则是 [ ( 2 , 3 ) , ( 3 , 4 ) , ( 3 , 5 ) , ( 8 , 6 ) ] [(2,3), (3,4), (3,5), (8,6)] [(2,3),(3,4),(3,5),(8,6)],这是不满足题意要求的。
3. 代码实现
class Solution {
public:
void quickSort(vector<int>& height, vector<int>& weight, int left, int right) {
if (left < right) {
int pivot = height[right];
int i = left;
for (int j = left; j <= right; ++j) {
// 身高从小到大排,身高相等时,体重从大到小
if (height[j] < pivot || (height[j] == pivot && weight[j] >= weight[right]) ) {
int temp = height[i];
height[i] = height[j];
height[j] = temp;
temp = weight[i];
weight[i++] = weight[j];
weight[j] = temp;
}
}
quickSort(height, weight, left, i-2);
quickSort(height, weight, i, right);
}
}
int bestSeqAtIndex(vector<int>& height, vector<int>& weight) {
if (height.empty()) {
return 0;
}
quickSort(height, weight, 0, height.size()-1);
vector<int> new_weight = {weight[0]};
for (int i = 1; i < weight.size(); ++i) {
if (weight[i] > new_weight.back()) {
new_weight.push_back(weight[i]);
} else if (weight[i] < new_weight.back()) {
int l = 0;
int r = new_weight.size()-1;
int pos = -1;
while (l <= r) {
int mid = l + (r - l) / 2;
if (new_weight[mid] == weight[i]) {
break;
// 找到第一个比weight[i]大的位置进行替换
} else if (new_weight[mid] > weight[i]) {
if (mid == 0 || new_weight[mid-1] < weight[i]) {
pos = mid;
break;
} else {
r = mid - 1;
}
} else {
l = mid + 1;
}
}
if (pos != -1) {
new_weight[pos] = weight[i];
}
}
}
return new_weight.size();
}
};