记:应聘一加 C/C++工程师

一轮,笔试加测评

测评还是那个老题库,感觉都做了好几遍了。。
记录一下笔试的知识点。
1.指针步长:这个博客的最后一个知识点
2.边界对齐,前面刚对这个知识进行过记录,但是记的不详细,这里再记录的详细些。
分为两大部分;
1)没有#pragma pack的情况,需要遵循三个原则。
原则1、普通数据成员对齐规则:第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始。
原则2、结构体成员对齐规则:如果一个结构里有某些结构体成员,则该结构体成员要从其内部最大元素大小的整数倍地址开始存储。(struct a里存有struct b,b里有char,int,double等元素,那b应该从8的整数倍开始存储。)
原则3、结构体大小对齐规则:结构体大小也就是sizeof的结果,必须是其内部成员中最大的对齐参数的整数倍,不足的要补齐。
补充:如果数组作为结构体成员,比如:char a[3]。它的对齐方式和分别写3个char是一样的,也就是说它还是按1个字节对齐。
2)有#pragma pack的情况。
#pragma pack(1)意思就是按照1字节对齐。后面是几就是按照几字节对齐。
这篇博客讲的比这里还好。
这篇博客中间对结构体的位域做了详细介绍。
3.是一道算法题。M(M<1000000)个数字中取前N(N<M)个大的数。
我当时用的优先级队列,不知道能不能这么多的数。
利用快排的思想如下:

#include<iostream>
using namespace std;
int a[1000000];

void swap(int& a, int& b)
{
	int temp;
	temp = b;
	b = a;
	a = temp;
}

void QuickSort(int a[], int s, int e, int m)  //a[],0,n-1,m
{
	if (s >= e)
		return;
	int k = a[s];
	int i = s, j = e;
	while (i != j)
	{
		while (j > i&& a[j] > k)
			j--;
		swap(a[i], a[j]);
		while (j > i&& a[i] < k)
			i++;
		swap(a[i], a[j]);
	}
	//快排的思想,走一遍。然后看看右边的较大的数是否是m个。
	int b = e - j; // 判断右边大的数有几个.
	if (m > b)           // 若小于m个,在左边再取m-b个
	{
		QuickSort(a, s, i, m - b); return;
	}
	if (m < b)           // 若大于m个,在右边重新取m个
	{
		QuickSort(a, j + 1, e, m); return;
	}
}

int main()
{
	int m, n;
	cin >> n >> m;
	if (n < 0) { return -1; }
	else if (m > n) { return -2; }
	else {
		for (int i = 0; i < n; i++)
			cin >> a[i];
		QuickSort(a, 0, n - 1, m);
		for (int i = n - 1; i >= n - m; i--)
			cout << a[i] << " ";
		return 0;
	}
}

得牛客网大佬指点:
快排的时间复杂度在 O ( n l o g n ) O(n*log n)
如果使用冒泡排序,部分排序的时间复杂度为 O ( n m ) O(n*m)
如果使用小根堆,时间复杂度是 O ( n l o g m ) O(n*log m)

int main()
{
	int n = 0;
	int m = 0;
	cin >> n >> m;
	vector<int>vec;
	for (unsigned int i = 0; i < n; ++i)
	{
		int n1 = 0;
		cin >> n1;
		vec.push_back(n1);
	}
	priority_queue<int, vector<int>, greater<int>> minHeap; //建立最小堆
	//注意:最小堆要加上greater<int>
	//其实,优先级队列的底层就是堆。
	//greater<int>表示数字大的优先级小。
	for (unsigned int i = 0; i < m; i++)
	{
		minHeap.push(vec[i]); //push的时间复杂度是O(log n)
	}
	for (unsigned int i = m; i < n; ++i)
	{
		//遍历判断容器中剩余的每个数与堆顶元素的大小
		//若大于堆顶元素 则把堆顶元素出堆 把该元素入堆
		if (vec[i] > minHeap.top())
		{
			minHeap.pop();   //push和pop操作的复杂度是O(log n).
			minHeap.push(vec[i]);
		}
	}
	//这个循环的时间复杂度是O(n*log m)
	while (!minHeap.empty())
	{
		//打印小根堆里边的m个最大的数
		cout << minHeap.top() << " ";
		minHeap.pop();
	}
	cout << endl;
	return 0;
}

哎,笔试没过。收到消息了。下次再接再厉。

原创文章 77 获赞 4 访问量 9044

猜你喜欢

转载自blog.csdn.net/weixin_40007143/article/details/104796645