7.20 牛客左程云老师第一题(个人学习笔记)

给定一个 N*2 的二维数组,看作是一个个二元组,例如[[a1,b1],[a2,b2],[a3,b3]],规定:一个如果想把二元组甲放在二元组乙上,甲中的 a 值必须大于乙中的 a 值,甲中的 b

 值必须大于乙中的 b 值。如果在二维数组中随意选择二元组,请问二元组最多可以往上摞几个?

 例如:[[5,4],[6,4],[6,7],[2,3]], 最大数量可以摞 3 个,[2,3] => [5,4] => [6,7]

 要求:实现时间复杂度 O(N*logN)的解法


C++实现代码

#include
#include
using namespace std;
class Dot
{
public:
	int w;
	int h;

};
int cmp(Dot &a, Dot &b){
	if (a.w < b.w)//w的值从小到大排列
		return 1;
	else
	if (a.w == b.w){
		if (a.h > b.h)//h的值从大到小排列
			return 1;
		else
			return 0;
	}
	else
		return 0;
}
 int maxEnvelopes(int (*es)[2],int length) 
 {
	if (es ==NULL || length <= 0 || es[0] == NULL) {
		return 0;
	}
	Dot* dots = new Dot [length];
	for (int i = 0; i < length; i++) 
	{
		dots[i].w = es[i][0];
		dots[i].h = es[i][1];
	}
	sort(dots,dots+length,cmp);//此处为 w升序 h降序排列,辅助数组对h进行处理;若 h升序 w降序排列,则辅助数组应对w进行处理
	int*ends = new int[length];
	ends[0] = dots[0].h;
	int right = 0;
	int l = 0;
	int r = 0;
	int m = 0;
	for (int i = 1; i < length; i++) {
		l = 0;
		r = right;
		while (l <= r) {
			m = (l + r) / 2;
			if (dots[i].h > ends[m]) {
				l = m + 1;
			}
			else {
				r = m - 1;
			}
		}
		right = right>l?right:l;
		ends[l] = dots[i].h;
	}
	return right + 1;
}
//此处为函数原型主要是二分查找,外圈算法复杂度O(n),内圈为O(logn)故整个复杂度为O(nlogn)
int ER(int *a,int length)
{
	if (a == NULL || length < 0)return 0;
	int *end = new int[length];
	int l, r = 0, m = 0;
	int right = 0;
	end[0] = a[0];
	for (int i = 1; i < length; i++)
	{
		l = 0;
		r = right;
		while (l <= r)
		{
			m = (r + l) / 2;
			if (a[i]>end[m])
				l = m + 1;
			else
				r = m - 1;
		}
		end[l] = a[i];
		right = l > right ? l : right;
	}
	return right + 1;
}
int main()
{
	//int a[] = {2,1,6,4,5,2,7,4};
	//cout << ER(a, 8);
	int test[7][2] = { { 4, 3 }, { 1, 2 }, { 5, 7 }, { 5, 3 }, { 1, 1 }, { 4, 9 }, {6,8} };
	cout << maxEnvelopes(test,7);
		return 0;
}


函数原型 ER()

 可用于查找整数序列的最长递增子序列例如{2,-2,6,-1,5,2,7,4},调用ER()得到4。

过程:

同等长度辅助数组

(1)2

辅助数组    2

(2)-2  (-2比2小替换掉2)

辅助数组 -2

(3)6(6比-2大,扩大辅助数组)

辅助数组 -2 ,6

(4)-1(-1比6小,替换6)

辅助数组  -2,-1

(5)5 (5大于-1,扩大数组)

辅助数组   -2,-1, 5

(6)2 (2小于5)

辅助数组 -2,-1, 2

(7)7  (7大于2,扩大数组)

辅助数组    -2,-1 ,2, 7

(8)4  (4小于7,替换)

辅助数组   -2,-1, 2, 4

最后得到最长递增子序列的即为辅助数组的长度(设置以全局变量来记录辅助数组的长),

上述过程即为函数原型ER()的过程

你可能感兴趣的:(7.20 牛客左程云老师第一题(个人学习笔记))