题目一
测试链接:LCR 132. 砍竹子 II - 力扣(LeetCode)
分析:对于特殊情况2和3直接返回1和2。观察到大于等于4时,如果长度模3等于0,则答案全部是由3相乘;如果长度模3等于1,则答案最后会有两个2相乘;如果长度模3等于2,则答案最后会有一个2相乘。且长度模3等于0时,3的个数是长度除以3;长度模3等于1时,3的个数是长度除以3-1;长度模3等于2时,3的个数是长度除以3。然后相乘即可得到答案。代码如下。
class Solution {
public:int MOD = 1000000007;int power(int number, int num){int ans = 1;int temp = number;for(int i = 0;i < 32;++i){if((num & (1 << i)) != 0){ans = (int)(((long long)ans * temp) % MOD);}temp = (int)(((long long)temp * temp) % MOD);}return ans;}int cuttingBamboo(int bamboo_len) {if(bamboo_len == 2){return 1;}if(bamboo_len == 3){return 2;}int tail = bamboo_len % 3 == 0 ? 1 : (bamboo_len % 3 == 1 ? 4 : 2);int num = tail == 1 ? bamboo_len / 3 : (tail == 4 ? bamboo_len / 3 - 1 : bamboo_len / 3);return (int)(((long long)power(3, num) * tail) % MOD);}
};
题目二
分成k份的最大乘积
一个数字n一定要分成k份,得到的乘积尽量大是多少。数字n和k,可能非常大,到达10^12规模。结果可能更大,所以返回结果对1000000007取模。
来自真实大厂笔试,没有在线测试。
分析:乘积尽量大即k份尽可能相等,所以先将n除以k得到每一份的基础值,然后得到n模k的值即有多少基础值再加上1,相乘即可得到答案。代码如下。
class Solution {
public:int MOD = 1000000007;long long power(long long number, long long num){long long ans = 1;long long temp = number;for(int i = 0;i < 64;++i){if((num & (1 << i)) != 0){ans = (ans * temp) % MOD;}temp = (temp * temp) % MOD;}return ans;}int maxValue(long long n, long long k) {long long a = n / k;long long b = n % k;return (int)((power(a, k-b) * power(a+1, b)) % MOD);}
};
题目三
会议必须独占时间段的最大会议数量
给定若干会议的开始、结束时间。你参加某个会议的期间,不能参加其他会议。返回你能参加的最大会议数量。
来自真实大厂笔试,没有在线测试。
分析:以会议的结束时间从小到大进行排序,对于当前时间如果小于等于当前会议的开始时间则代表可以参加,时间更新为当前会议的结束时间,遍历所有会议即可得到答案。代码如下。
class Solution {
public:int maxMeetingNum(vector<vector<int>>& meeting){int ans = 0;int length = meeting.size();sort(meeting.begin(), meeting.end(), [](vector<int>& v1, vector<int>& v2){return v1[1] < v2[1];});int cur = -1;for(int i = 0;i < length;++i){if(cur <= meeting[i][0]){++ans;cur = meeting[i][1];}}return ans;}
};
题目四
测试链接:1353. 最多可以参加的会议数目 - 力扣(LeetCode)
分析:首先按照开始时间进行排序,然后用一个小根堆维护结束时间,遍历会议的时候,对于当前时间可以解锁的会议的结束时间进入小根堆,选择可以解锁的会议中结束时间最小的会议进行参加。遍历所有天数即可得到答案。代码如下。
class Solution {
public:int maxEvents(vector<vector<int>>& events) {int length = events.size();sort(events.begin(), events.end(), [](vector<int>& v1, vector<int>& v2){return v1[0] < v2[0];});auto cmp = [](int& a, int& b){return a > b;};priority_queue<int, vector<int>, decltype(cmp)> p(cmp);int ans = 0;int index = 0;for(int day = 1;day <= 100000;++day){while (!p.empty() && day > p.top()){p.pop();}while (index < length && day >= events[index][0] && day <= events[index][1]){p.push(events[index][1]);++index;}if(!p.empty()){++ans;p.pop();}}return ans;}
};
题目五
测试链接:502. IPO - 力扣(LeetCode)
分析:对最小资本从小到大进行排序,用一个大根堆维护纯利润。遍历每一次选择项目的机会,对于当前资本可以解锁的项目的纯利润进入大根堆,选择当前纯利润最大的项目进行投资,将纯利润加入当前资本进行下一次的选择。遍历完即可得到答案。代码如下。
class Solution {
public:struct project{int profit;int capital;};int findMaximizedCapital(int k, int w, vector<int>& profits, vector<int>& capital) {int length = profits.size();vector<project> pro;pro.reserve(length);for(int i = 0;i < length;++i){project temp;temp.profit = profits[i];temp.capital = capital[i];pro.push_back(temp);}sort(pro.begin(), pro.end(), [](project& p1, project& p2){return p1.capital < p2.capital;});auto cmp = [](int& a, int& b){return a < b;};priority_queue<int, vector<int>, decltype(cmp)> p(cmp);for(int i = 0, index = 0;i < k;++i){while (index < length && pro[index].capital <= w){p.push(pro[index].profit);++index;}if(!p.empty()){w += p.top();p.pop();}}return w;}
};
题目六
加入差值绝对值直到长度固定
给定一个非负数组arr,计算任何两个数差值的绝对值。如果arr中没有,都要加入到arr里,但是只加一份。然后新的arr,继续计算任何两个数差值的绝对值,如果arr中没有,都要加入到arr里,但是只加一份。一直到arr大小固定,返回arr最终的长度。
来自真实大厂笔试,没有在线测试。
分析:观察可得这个数组中的所有数字是原数组除0之外所有数的最大公约数到原数组中的最大值,每一个数都是最大公约数的倍数。所以思路是求得最大公约数,得到基础个数,然后加上词频统计中个数不为1的数的剩余个数。对于是否有0的情况,如果原数组中有0,则加上原数组中0的个数;如果原数组中没0则取决于最大词频数,如果最大词频数不超过1,则没有零,超过1则加上一个0。代码如下。
class Solution {
public:int get_gcd(int a, int b){return b == 0 ? a : get_gcd(b, a % b);}int getLen(vector<int> arr){int gcd = 0;int maxValue = 0;int length = arr.size();for(int i = 0;i < length;++i){if(arr[i] != 0){gcd = arr[i];}maxValue = max(maxValue, arr[i]);}if(gcd == 0){return length;}map<int, int> table;map<int, int>::iterator pos;int maxCnt = 1;for(int i = 0;i < length;++i){if(arr[i] != 0){gcd = get_gcd(gcd, arr[i]);}pos = table.find(arr[i]);if(pos != table.end()){++((*pos).second);maxCnt = max(maxCnt, (*pos).second);}else{table.insert(pair<int, int>(arr[i], 1));}}int ans = maxValue / gcd;for(int i = 0;i < length;++i){if(arr[i] != 0){pos = table.find(arr[i]);ans += ((*pos).second - 1);}}pos = table.find(0);ans += (pos == table.end() ? (maxCnt > 1 ? 1 : 0) : (*pos).second);return ans;}
};