蓝湖一面
7,13,29块鸡块,让你去买n块鸡块,问能不能买到。n%7,n%13,n%29是否为零,如果是返回true,否则枚举abc,看是否存在7a+13b+29c=n,存在返回true,否则返回false。dp[i]为i是否能买到,能买到就为true,否则为false,初始化dp[i]为false,dp[7],dp[13],dp[29]为true。之后进行一次遍历,只要dp[i-7],dp[i-13],dp[i-29]其中之一为真,dp[i]即为真,否则为假。ide写代码。本来想写在main函数里的,过了一秒觉得不妥封装成函数,面试官也提醒封装一下。开始写:bool isCanBuy(int n) {
vector<int> hash = { 7,13,29 };
for (const auto& h : hash) if (n % h == 0) return true;
vector<int> dp(n+1, 0);
dp[7] = 1;
dp[13] = 1;
dp[29] = 1;
for (int i = 7; i <= n; ++i) {
if ((i - 7 >= 0 && dp[i - 7] == 1) ||
(i - 13 >= 0 && dp[i - 13] == 1) ||
(i - 29 >= 0 && dp[i - 29] == 1)) dp[i] == 1;
}
if (dp[n] == 1) return true;
else return false;
}main函数里写测试,面试官说不必了,主要是这个函数的实现。O(n),只需要遍历一次7-n即可。n大于某个k之后,所有的n都能购买到,也即,当大于某个数之后的所有数都可以表示成这三个质数的和emmm,你说的有道理,但是这个数是多少呢,我想想。可以先用现有算法建表,也即,从29开始一直测试n是否满足条件,当出现连续多个,比如一百个n都满足条件时,我们就有理由认为之后的所有数都满足条件,当然100不一定准确。7.7个数都满足条件,那么之后的任意数都可以用这7个数连续加7得到。K,这样大于K的情况都是O(1),我们可以将时间复杂度降为O(K)。int findMinK() {
for (int i = 29; ; ++i) {
if (isCanBuy(i)) {
bool isK = true;
for (int j = i; j < i + 7; ++j) if (!isCanBuy(j)) isK = false;
if (isK) return i + 6;
else i += 6;
}
}
}emm,没用到7,13,29吗?isCanBuy都要重新计算7-i/j,实际上是不是可以保存以前计算的结果,降低时间复杂度os,我真傻比,咋这都忘了),那我写一下O(K)的时间复杂度。行,算法考察先到这里。c++多态override跟final倒是没想起来。c++里有智能指针解决内存泄漏问题,你说一下c++里的两种智能指针unique_ptr,share_ptr,我提了一嘴之前还有auto_ptr,后来弃用了,然后分别说了一下unique_ptr,share_ptr,之后说到share_ptr的循环引用问题,又介绍了用于解决循环引用问题的weak_ptr。c++基础和计算机底层原理,学一下webassembly,还有计算机图形学相关的东西。然后就结束了,十分钟后hr通知一面过了,约了明天下午的二面。