解题思路:
首先我们要知道如何求两个区间公共部分的数量:
如图
上图公共区间(红色线之间的部分)公共长度为max(0, min(b, d) - max(a, c));
因此这题我们可以将mm:dd的形式转化为从年初到现在经过了多少天,然后求区间的公共点的数量即可
class Solution { public: int months[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int get(string s) {得到从0月0日开始到现在经过了多少天 int res = 0; int m, d; sscanf(s.c_str(), "%d-%d", &m, &d); for (int i = 1; i < m; i ++ ) res += months[i]; return res + d; } int countDaysTogether(string arriveAlice, string leaveAlice, string arriveBob, string leaveBob) { int a = get(arriveAlice), b = get(leaveAlice); int c = get(arriveBob), d = get(leaveBob); return max(0, min(b, d) - max(a, c) + 1);//区间[a, b]包含的天数为b - a + 1所以要加1 } };
解题思路:
可以先players和traners从小到大排序,假设现在枚举的player的值为a, 找到在traners中大于等于a的最小值将其配对。
为什么是大于等于a的最小值??
如上图若我们找的不是在trainer中找大于等于a的最小值的话,则假设a和c匹配,则此时d没有匹配对象,与题目所求的最大匹配数矛盾,但是我们如果按照在trainer中找大于等于a的最小值的话,那么a可以和b匹配,d可以和c匹配
class Solution { public: int matchPlayersAndTrainers(vector<int>& a, vector<int>& b) { sort(a.begin(), a.end()); sort(b.begin(), b.end()); int res = 0; for (int i = 0, j = 0; i < a.size() && j < b.size(); i ++ ) { while (j < b.size() && a[i] > b[j]) j ++ ; if (j < b.size() && a[i] <= b[j]) { res ++ ; j ++ ; } } return res; } };
解题思路:
我们可以从后往前枚举每个数,将这个数看成二进制,枚举每一位,假设当前枚举的是a这个数的第i位,1:若i == 0则找到距离i最近的在i这个位置上异或值为1的数。
2:若i == 1记录a这个数的第i为是1.
class Solution { public: vector<int> smallestSubarrays(vector<int>& nums) { int n = nums.size(); vector<int> p(30, n); vector<int> res(n); for (int i = n - 1; i >= 0; i -- ) {//从后往前枚举 int t = i; for (int j = 0; j < 30; j ++ ) if (nums[i] >> j & 1) p[j] = i;//nums[i]第j位是1,则记录第j位为1的数的下标是i else if (p[j] < n) t = max(t, p[j]);//找出后面离i这个位置最近的第j位是1的位置 res[i] = t - i + 1;//区间[a, b]中共有b - a + 1个数 } return res; } };
解题思路:
假设花费是a 回报是b由题意得:
monkey - (a[1] - b[1]) - (a[2] - b[2]) - .....(a[i - 1] - b[i - 1]) >= a[i](0 <= i <= n - 1)即
monkey >= a[i] + (a[1] - b[1]) + (a[2] - b[2]) + .....(a[i - 1] - b[i - 1])
要使得任意得顺序monkey都满足条件,即monkey >= a[i] + (a[1] - b[1]) + (a[2] - b[2]) + .....(a[i - 1] - b[i - 1])的最大值。
即枚举a[i]然后确定当i取多少时,整个式子可以取得最大值
1:求 a[i] + (a[1] - b[1]) + (a[2] - b[2]) + .....(a[i - 1] - b[i - 1])的最大值,我们可以枚举每个数找出 a > b的数,然后把每个a > b的数相加即sum += a[i] - b[i]
2: 当枚举第i个数时,我们只需要记录sum - (a[i] - b[i])(加上除了i的sum和) + a[i]的最大值即可;
class Solution { public: long long minimumMoney(vector<vector<int>>& transactions) { long long sum = 0; for (auto &p : transactions) if (p[0] > p[1]) sum += p[0] - p[1];//求得sum long long res = 0; for (auto &p : transactions) { long long s = sum; if (p[0] > p[1]) s -= p[0] - p[1];//减去当前枚举的数 res = max(res, s + p[0]);//加上当前枚举的花费求最大值 } return res; } };