8.16字节笔试整理

代码是我现在写的,无法提交验证,欢迎大家指正!
第一题给出二叉树前序和中序求有几个叶子节点,跟重建二叉树差不多,但不需要重建。
#include <iostream>
#include <unordered_map>
using namespace std;

int N, leaf, index;
int pre[30010];
int mid[30010];
unordered_map<int, int> mp;
void build_tree(int L, int R){
	if (L >= R) return;
	if (L == R-1){
		++leaf;
		return;
	}
	int val = pre[index];
	++index;
	build_tree(L, mp[val]);
	build_tree(mp[val]+1, R);
}
int main()
{
	cin >> N;
	for (int i = 0; i < N; ++i) cin >> pre[i];
	for (int i = 0; i < N; ++i){
		cin >> mid[i];
		mp[mid[i]] = i;
	}
	leaf = 0;
	index = 0;
	build_tree(0, N);
	cout << leaf << endl;
	return 0;
}
第二题问一个字符串里至少要删去几个字符可以使该字符串不包含“0010”。
没做出来。。。后来讨论区里说只要找有几个“0010”即可,仔细想想确实是,比如00100010至少删去两个字符,0010010至少删去两个字符,001010至少删去一个字符。
#include <iostream>
#include <string>
using namespace std;

string ss;
string now = "0010";
int main()
{
	int T;
	cin >> T;
	while (T--)
	{
		cin >> ss;
		string::size_type pos = 0;
		int ans = 0;
		while ((pos = ss.find(now, pos)) != string::npos){
			++pos;
			++ans;
		}
		cout << ans << endl;
	}
	return 0;
}
第三题给出n段视频,每段视频的时长是L[i],要在视频里插入广告,如果广告间隔时间是x,则第i段视频可以插入L[i]/x+1个广告,现在一共要插入m个广告,求广告间隔时间的最大值。
二分这个间隔时间,左边界是0,表示不能放视频,只能一直放广告,右边界是max{L[i]},因为如果m = n + 1,广告间隔最长就是max{L[i]},其余m > n的情况间隔肯定小于等于max{L[i]}
这题的代码可以确定能过,笔试也是提交的这个。
#include <iostream>
using namespace std;

int n;
long long m;
long long L[100010];
int main()
{
	cin >> n >> m;
	long long right = 0;
	for (int i = 0; i < n; ++i){
		cin >> L[i];
		right = max(L[i], right);
	}
	long long left = 0;
	++right;
	while (left < right){
		long long mid = 1 + left + (right - left) / 2;
		long long sum = 0;
		for (int i = 0; i < n; ++i)
			sum += L[i] / mid + 1;
		if (sum >= m) left = mid;
		else right = mid - 1;
	}
	cout << left << endl;
	return 0;
}
第四题给出n和m,n个数字a[i],每个数字只能用一次,问能凑出的最大的sum%m,sum是数字取和,其中n最大为35,m最大1e9+7。
因为m太大了,如果用dp[i]表示i能不能凑出来,那要开1e9的数组,所以我一开始就放弃了dp的思路。
n很小,所以暴力dfs,每个数字就只有选/不选,复杂度O(2^n),然后过了0.6。
结束以后跟朋友讨论了一下,想到把n个数字分成两组进行暴力dfs,得到的结果分别存在两个set里,set有排序和去重功能。
然后双指针,第一个指针指向set1的头,第二个指针指向set2的尾,把指向的这两个数加起来,更新ans,如果和等于m-1直接结束,如果大于m-1,第二个指针前移,如果小于,第一个指针后移。
dfs复杂度2 * 2^(n/2),双指针复杂度2 * 2^(n/2),最终O(2^(n/2+2))。
#include <iostream>
#include <set>
using namespace std;

int n;
long long m, ans;
long long a[40];
set<long long> s1, s2;

void dfs1(int index, long long sum)
{
	if (index == n/2){
		s1.insert(sum);
		return;
	}
	dfs1(index+1, (sum+a[index])%m);
	dfs1(index+1, sum);
}

void dfs2(int index, long long sum)
{
	if (index == n){
		s2.insert(sum);
		return;
	}
	dfs2(index+1, (sum+a[index])%m);
	dfs2(index+1, sum);
}

int main()
{
	ans = -1;
	cin >> n >> m;
	for (int i = 0; i < n; ++i) cin >> a[i];
	dfs1(0, 0);
	dfs2(n/2, 0);
	auto p = s1.begin();
	auto q = s2.rbegin();
	while (p!=s1.end() && q!=s2.rend()){
		ans = max(ans, (*p+*q)%m);
		if (*p + *q > m-1) 
			++q;
		else if (*p + *q == m-1){
			ans = m-1;
			break;
		}
		else ++p;
	}
	cout << ans << endl;
	return 0;
}




#字节跳动##笔试题目#
全部评论
第二题为啥我也是直接这么做的,样例能过,但是测试通过0
1
送花
回复 分享
发布于 2020-08-16 19:53
大佬能把第一题思路说一下嘛
点赞
送花
回复 分享
发布于 2020-08-16 14:08
现代汽车中国前瞻数字研发中心
校招火热招聘中
官网直投
大佬
点赞
送花
回复 分享
发布于 2020-08-16 14:32
大佬强无敌
点赞
送花
回复 分享
发布于 2020-08-16 14:52
tql
点赞
送花
回复 分享
发布于 2020-08-16 15:54
第二题可以用一个dp(i,s),s表示最后三位是什么,有000~111八种,然后看当前的是0还是1要不要删就好了
点赞
送花
回复 分享
发布于 2020-08-16 19:47
第四题就算时间复杂度优化了也是0.6  后面都是指数级数据量的测试用例。肯定有别的方法。
点赞
送花
回复 分享
发布于 2020-08-16 22:09
第三题这里 为啥要right++啊 然后mid那里还加1  直接mid=(left+right+1)/2;可行不
点赞
送花
回复 分享
发布于 2020-08-16 22:22
真大佬
点赞
送花
回复 分享
发布于 2020-08-16 22:35
开发的题比测试的难多了😅
点赞
送花
回复 分享
发布于 2020-08-16 23:09
大疆的测试开发也太划水了吧,算法题就是斐波那契数列。。。
点赞
送花
回复 分享
发布于 2020-08-17 09:00
第三题mid = 1+ left + (right-left)/2  多加1 是为了防止出现死循环嘛?
点赞
送花
回复 分享
发布于 2020-08-17 10:02
为什么等于m-1时退出循环?
点赞
送花
回复 分享
发布于 2020-08-17 12:55
第四题的dfs函数中,应该是dfs1(index+1, sum+a[index]%m); 这样写吧,要不然每次都对m多一次取余数操作
点赞
送花
回复 分享
发布于 2020-08-17 12:59
大佬厉害!
点赞
送花
回复 分享
发布于 2020-08-17 14:35
left、right为什么定义成long long 呢
点赞
送花
回复 分享
发布于 2020-08-17 22:53
帖子不要多整洁,起码清晰一点吗?
点赞
送花
回复 分享
发布于 2020-08-18 16:57
请问收到面试了吗
点赞
送花
回复 分享
发布于 2020-08-18 23:50
收到面试通知了吗?
点赞
送花
回复 分享
发布于 2020-08-23 10:44

相关推荐

头像
不愿透露姓名的神秘牛友
06-20 00:21
点赞 评论 收藏
分享
#简历#先说一说我自己的想法,很多人都很排斥苍穹外卖,认为没什么技术点和含金量,但实际上我觉得恰恰相反,苍穹外卖虽然代码本身并不是你自身能力的证明,但是是作为一个新人学习时很好的跳板和原始框架,在这个框架上进行的改进可以很好的辐射到你自己的个人成果上,并作为你和面试官聊天的筹码大多数人的苍穹外卖只写增删改查,千篇一律,吸引不了面试官,所以这才让大家误以为只要是苍穹外卖就不要写进简历里这种误区,但实际上如果你在原有的层面上进行改进,并作为你的项目亮点和面试官介绍,告诉他你的苍穹外卖和别人的有什么不同,增加了哪些技术难点,这才显得你是完全自己理解了这个项目,并且有自己动手实践项目的能力,而不是就看了个课程就以为自己会了,就当成自己的了,如此一来,这反而成为你的加分项苍穹外卖为什么看的人最多,说明它好啊,如果它不好,为什么看的人还这么多,想清楚这个逻辑,我觉得要做的最重要的事,就是如何在原有框架上进行改进提效,比起听其他人的话重新搞一个项目性价比高得多,而且我亲测项目并没有成为我找到工作的阻碍,我投的大厂一大半都给我面试了,而且很多不止一个部门,退一万步说,当你手头没有其他项目的时候,有苍穹外卖总比什么都没有的好很多,不需要因为苍穹外卖有任何心理负担关于简历的任何部分都欢迎大家提意见,十分感谢大家,祝大家找实习+秋招顺利上岸,offer拿到手软#简历中的项目经历要怎么写##我的上岸简历长这样##最后再改一次简历##简历##简历被挂麻了,求建议#
点赞 评论 收藏
分享
22 92 评论
分享
牛客网
牛客企业服务