Analysis of hw written test questions (5.24)

Full analysis of Huawei 5.24 written test questions

1. Huawei written test, continuous free memory merge management;

In fact, it is to find the longest continuous substring and return the smallest subscript value;

enter

Input: 1,3,2,5 means releasing four blocks of memory, the IDs are 1.3.2.5, and the size of each block of memory is 1 unit [prefabricated conditions]

Before the function is executed, all memory has been allocated and there is no idle space. There is no need to consider repeated release of memory [value range]

Memory ID number: 0<ID<2^31-1, number of memories released at a time<10000

output

Output: 1,3 After recycling processing, the currently available maximum continuous memory size is 3, and the starting number of this memory is 1. Description: 1, 3, 2, 5 four blocks of memory, the first three blocks 1, 3, 2 are Continuous memory, the number of contiguous memories after merging is 3 units. The starting number is 1, so 1,3 is returned.

Code analysis:


#include <iostream>
#include <vector>
#include <algorithm>
#include<string>
using namespace std;

int main() {
	vector<int> nums;
	string input;
	getline(cin, input);
//也可以这样去解析字符串
//	for (char a : input)
//	{
//		if (a == ',')
//			continue;
//		else
//		{
//			int num = a - '0';
//			nums.push_back(num);
//		}
//
//	}
	size_t pos = 0;
	string token;

	while ((pos = input.find(",")) != string::npos) {  //找不到返回npos
		token = input.substr(0, pos);
		nums.push_back(stoi(token));
		input.erase(0, pos + 1);  //删除从0开始的pos+1个字符
	}
	nums.push_back(stoi(input));

	sort(nums.begin(), nums.end()); //升序排列

	int st = -1, mxlen = -1;
	int n = nums.size();
	int index = 0;
	while (index < n) {
		int i = index;
		for (int j = index + 1; j < n; j++) {
			if (nums[j] - nums[i] != 1)
				break;
			i++;
		}
		//循环操作完之后更新最大值
		if (mxlen < i - index + 1) {
			mxlen = i - index + 1;
			st = index;
		}
		index = i + 1;  //下一波开始
	}

	cout << nums[st] << ", " << mxlen << endl;

	return 0;
}

2. Huawei written test, massive log suppression

The definition of "massive logs": 2 identical logs are printed within 10ms (<10ms) (including the second one needs to be suppressed), that is: only the first one is retained or 10 similar logs are printed within 100ms (<100ms) (removed Two logs that are exactly the same after the number are considered "similar", including the 10th log, which needs to be suppressed), that is: only the first 9 logs are retained. The understanding of log suppression: suppressed logs are not recorded in the log file

enter

Number of logs for this use case (maximum no more than 1,000) Time cutoff: Log print content

constraint

1、时间戳单位是ms,用32位无符号+进制整数表示
2、用例保证后一条日志时间戳不小于前一条;
3、一条日志打打印只占一行,一条日志内容不超过1024 Bytes;
4、用例保证1s内(<1s),最多100条日志
5、数字均为正整数。

output

Timestamp: Log print content. The output needs to remove suppressed logs.

Code analysis:

#include <iostream>
#include <vector>
#include <unordered_map>
#include <regex>
#include <string>
#include<sstream>
using namespace std;

int main() {
	int n;
	cin >> n;
	cin.ignore(); //清除以回车结束的输入缓冲区的内容,

	vector<pair<int, string>> records;
	unordered_map<string, vector<pair<int, int>>> same;
	unordered_map<string, vector<pair<int, int>>> like;
	vector<bool> vst(n, true);

	for (int i = 0; i < n; i++) {  //i表示行数


		string line;
		getline(cin, line);  //getline会丢弃换行符
		istringstream iss(line); //字符串的输入流
		// 有参构造,输入流 ,默认构造表示输入流的结束位置
		//输入流迭代器,划分成一个个单词 
		//istream_iterator<string>默认以空白字符(包括空格、制表符、换行符等)作为分隔符来提取字符串
		vector<string> lines(istream_iterator<string>{iss}, istream_iterator<string>()); //范围构造函数
		int time = stoi(lines[0]); //哪怕后面有字母 也只会转换数字
		//text是后面的字符串
		string text = "";
		for (int j = 1; j < lines.size(); j++) {
			text += lines[j];
			if (j != lines.size() - 1)
				text += " ";
		}
		same[text].push_back(make_pair(time, i));
		//\\d表示匹配任意数字字符,+表示匹配前面的元素一次或多次。
		//regex_replace(text, regex("\\d+"), ""):这是一个使用正则表达式进行替换的函数调用
		//将所有数字替换为空字符串,删掉数字
		string likeText = regex_replace(text, regex("\\d+"), ""); //不喊时间和数字
		like[likeText].push_back(make_pair(time, i));
		records.push_back(make_pair(time, text)); //用来记录 所有的信息
	}

	//判断相同的日志
	for (auto& d : same) {
		vector<pair<int, int>>& record = d.second;
		for (int i = 0; i < record.size(); i++) {
			int time = record[i].first;
			int index = record[i].second;
			if (i + 1 < record.size() && record[i + 1].first - time < 10)  //满足相同日志条件
				vst[index + 1] = false;
		}
	}
	//判断相似的日志
	for (auto& d : like) {
		vector<pair<int, int>>& record = d.second;
		for (int i = 0; i + 9 < record.size(); i++) {
			int time = record[i].first;
			int index = record[i].second;
			if (record[i + 9].first - time < 100)
				vst[index + 9] = false;
		}
	}

	for (int i = 0; i < records.size(); i++) {
		if (vst[i])
			cout << records[i].first << " : " << records[i].second << endl;
	}

	return 0;
}

3. Huawei written test, network upgrade and transformation

The input network is a full binary tree structure, and each network node is marked with a value indicating the annual maintenance cost of the node. Given each input network, after removing certain nodes as required, find the maximum maintenance cost that can be saved (this question is similar to the robbery problem of a binary tree)

enter

The first line: a positive integer N, indicating that there are N values ​​behind it. 1<=N<= 10000 The second line: N non-negative integers, representing the annual maintenance cost of network nodes, given according to the "breadth-first traversal sequence number" of the full tree. 0 means that the associated node does not exist, and 0 will only exist on leaf nodes. The value range of each number is [0.1000]

Example:

enter

Enter: 7 in the first line, which means there are 7 numbers behind it.

The second line input: 5 3 5 0 6 0 1, which means "Indicates the annual maintenance cost of the network node, which is given according to the "breadth-first traversal sequence number" of the full binary tree. 0 means that the associated node does not exist"

output

The greatest maintenance cost savings possible. 12

Follow the rules of the binary tree:

#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<algorithm>
#include<unordered_map>
using namespace std;
struct TreeNode
{
	int val;
	TreeNode *left;
	TreeNode * right;
	TreeNode():val(0),left(nullptr),right(nullptr){}
	TreeNode(int x) :val(x), left(nullptr), right(nullptr) {}
	TreeNode(int x, TreeNode * left, TreeNode* right) :val(x), left(left), right(right) {}
};

unordered_map<TreeNode*, int>memo;
int rob(TreeNode* root)
{
	if (root == nullptr)
		return 0;
	if (memo.count(root))
		return memo[root];
	int do_it = root->val
		+ (root->left == nullptr ? 0 : rob(root->left->left) + rob(root->left->right))
			+ (root->right == nullptr ? 0 : rob(root->right->left) + rob(root->right->right));
	int not_do = rob(root->left) + rob(root->right);
	int res = max(do_it, not_do);
	memo[root] = res;
	return res;
}
TreeNode* buildtree(vector<int>& input)  //根据层序遍历去构造二叉树
{
	if (input.empty()) return nullptr;

	TreeNode* root = new TreeNode(input[0]);
	queue<TreeNode*>q;
	q.push(root);
	for (int i = 1; i < input.size();)
	{
		TreeNode* next_head = q.front();
		q.pop();
		int left = input[i++];
		if (left != 0)
		{
			next_head->left = new TreeNode(left);
			q.push(next_head->left);
		}
		else
		{
			next_head->left = nullptr;
		}
		int right = input[i++];
		if (right != 0)
		{
			next_head->right = new TreeNode(right);
			q.push(next_head->right);
		}
		else
		{
			next_head->right = nullptr;
		}
	}
	return root;
}
int main()
{
	vector<int>input;
	int num;
	cin >> num;
	for(int i = 0; i < num; i++)
	{
		int a;
		cin >> a;
		input.push_back(a);
	}
	if (num == 1)
	{
		cout << input[0] << endl;
		return 0;
	}
	TreeNode * root = buildtree(input);


	int res = rob(root);
	cout << res << endl;
	system("pause");
	return 0;

}

Do not build a binary tree, directly dfs:

#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;

int n;
vector<int> nums;
unordered_map<int, int> dp;

//node对应索引


int dfs(int node) {
    if (node >= n) return 0;//>= 因为会*2
    if (dp.count(node)) return dp[node];//类似备忘录
  
    // Select
    //在层序遍历的情况下,node*2+1对应这个节点的左子树,node*2+2对应右子树,再套一层*2+1就是左子树的下一个左子树
    // 选择这个节点,这个节点的左子树和右子树不选择
    int cur = dfs((node * 2 + 1) * 2 + 1) + dfs((node * 2 + 1) * 2 + 2) + dfs((node * 2 + 2) * 2 + 1) + dfs((node * 2 + 2) * 2 + 2) + nums[node];
  
    // Don't select
    cur = max(cur, dfs(node * 2 + 1) + dfs(node * 2 + 2));
    dp[node] = cur;
    return cur;
}

int main() {
    cin >> n;
    nums.resize(n);
    for (int i = 0; i < n; i++) {
        cin >> nums[i];
    }

    cout << dfs(0) << endl;

    return 0;
}

Guess you like

Origin blog.csdn.net/qq_43377917/article/details/130883330