面试技巧

关注公众号 jb51net

关闭
IT专业知识 > IT职场规划 > 面试技巧 >

腾讯游戏客户端开发面试经历记录

Reeker丶

简历是去年在腾讯招聘官网投的,都快忘记这事了,前一周突然来了面试邀请。一共面了两轮,都是电面,现在在等结果。这算是我人生第一次面试工作,还是蛮有意义的,趁着还有印象+录了一部分音,赶紧过来记录一下。

初面

二面

typedef struct {
	int id;
	//other data...
	vector<Node*> children; //the order of the sub nodes is exactly the shown order in picture
} Node;

class Tree {
private:
	Node* root;
	void format();
	//other functions...
};

/*
* this implementation can only find local optimal solutions, assuming each step has no aftereffect (actually not)
* format the tree from the lowest level
* for each node, mapping to a deque,  which stores a pair of displacements relative to the node for the most left and right sub nodes for each sub level
* after formating all sub nodes of a node, use brutal force to compute the possible minimal gap with the deques of the sub nodes
* during the process, maintain the optimal permutation, after enumerate all the cases, compute the deque of the current node
* suppose :
* 1. nodes with the same depth must have the same y
* 2. the sub nodes of different nodes cannot be interlaced 
* 3. the distance of every two sub nodes  of a single node must be the same
*/
void Tree::format()
{
	if (root == nullptr)
		return;

	//post order traversal of the tree
	stack< pair<Node*, int> > stackOfNodes; //int element is used to record the times of encountering the node
	unordered_map<Node*, deque<pair<int, int>>> subLevelDis; //the pair of two ints records the left and the right displacement * 2 of the level relative to its parent
	stackOfNodes.push(make_pair(root, 1));
	while (!stackOfNodes.empty())
	{
		Node* curNode = stackOfNodes.top().first;
		int cnt = stackOfNodes.top().second;
		switch (cnt)
		{
		case 1:
			//the sub nodes of the current node havent been formatted yet
			stackOfNodes.top().second = 2;
			//push the sub nodes to stack in the reverse node such that the first child is on the top
			for (auto it = curNode->children.rbegin(); it != curNode->children.rend(); ++it)
			{
				stackOfNodes.push(make_pair(*it, 1));
			}
			break; //end case1
		case 2:
			//the sub nodes of the current node have been formatted
			stackOfNodes.pop();
			//format the order of sub nodes of the current node
			vector<Node*>& childrens = curNode->children;
			if (!childrens.empty())
			{
				int cntOfChildren = childrens.size();
				vector<int> permutation(cntOfChildren); //the permutation of the index of the sub nodes
				for (int i = 0; i < cntOfChildren; ++i)
					permutation[i] = i;
				int minMaxGap = INT_MAX;
				vector<int> minMaxPermutation(cntOfChildren);
				//use brutal force to check each permutation
				//for each permutation, find the max gap
				do
				{
					int maxGap = 0;
					//compute the gap between each two adjacent node
					for (int i = 0; i < cntOfChildren - 1; ++i)
					{
						int tempMaxGap = 0;
						auto& deque1 = subLevelDis[childrens[permutation[i]]];
						auto& deque2 = subLevelDis[childrens[permutation[i+1]]];
						int minLen = min(deque1.size(), deque2.size());
						auto it1 = deque1.begin(), it2 = deque2.begin();
						for (int i = 0; i < minLen; ++i, ++it1, ++it2)
						{
							tempMaxGap = it1->second - it2->first;
							maxGap = max(maxGap, tempMaxGap);
						}
					}

					if (maxGap < minMaxGap)
					{
						minMaxGap = maxGap;
						minMaxPermutation.assign(permutation.begin(), permutation.end());
					}

				} while (next_permutation(permutation.begin(), permutation.end()));

				//reorder the subnodes according to the indice in minMaxPermutation
				vector<Node*> tempChildrens(childrens.begin(), childrens.end());
				for (int i = 0; i < cntOfChildren; ++i)
				{
					childrens[i] = tempChildrens[minMaxPermutation[i]];
				}

				//compute the level displacements of the current node and bind to the node
				vector<int> maxLens(cntOfChildren);
				int maxLen = 0;
				for (int i = 0; i < cntOfChildren; ++i)
				{
					maxLens[i] = subLevelDis[childrens[i]].size();
					maxLen = max(maxLen, maxLens[i]);
				}
				//for each level, find the index of the most left and right node, then compute the displacement
				deque<pair<int, int>> dis;
				//if all the sub nodes of current node 
				if (dis.empty())
					dis.push_back(make_pair(-cntOfChildren * minMaxGap, cntOfChildren * minMaxGap));
				//otherwise
				for (int i = 0; i < maxLen; ++i)
				{
					int left = 0, right = cntOfChildren;
					while (maxLens[left] < i)
						++left;
					while (maxLens[right] < i)
						--right;
					int leftDis = subLevelDis[childrens[left]][i].first * 2 + (left * 2 - cntOfChildren) * minMaxGap;
					int rightDis = subLevelDis[childrens[right]][i].second * 2 + (right * 2 - cntOfChildren) * minMaxGap;
					dis.push_back(make_pair(leftDis, rightDis));
				}
				subLevelDis[curNode] = dis;

				//free the memory space for level displacements of the sub nodes
				for (int i = 0; i < cntOfChildren; ++i)
					subLevelDis.erase(childrens[i]);
			}
			break; //end case2
		} //end switch
	}
}

后记

2019.3.28

Reeker