题意
给两个字符串表示时间段,问两个时间段是否有交集
思路
计算两个时间段中的最早开始时间到最晚结束时间之间的差值,并将其和两个时间段的时间跨度之和比较。
事实上,直接比较字符串的大小即可。
代码
方法1:
class Solution {
public:
bool haveConflict(vector& event1, vector& event2) {
int all=0;
//开始的时间
int sh1=(event1[0][0]-'0')*10+(event1[0][1]-'0'),sh2=(event2[0][0]-'0')*10+(event2[0][1]-'0');
int sm1=(event1[0][3]-'0')*10+(event1[0][4]-'0'),sm2=(event2[0][3]-'0')*10+(event2[0][4]-'0');
//结束的时间
int eh1=(event1[1][0]-'0')*10+(event1[1][1]-'0'),eh2=(event2[1][0]-'0')*10+(event2[1][1]-'0');
int em1=(event1[1][3]-'0')*10+(event1[1][4]-'0'),em2=(event2[1][3]-'0')*10+(event2[1][4]-'0');
if((sh2sm1)){
swap(sh1,sh2);
swap(sm1,sm2);
swap(eh1,eh2);
swap(em1,em2);
}
long long int t1=(eh1-sh1)*60+(em1-sm1),t2=(eh2-sh2)*60+(em2-sm2);
long long int t=abs((eh2-sh1)*60+(em2-sm1));
if(t1+t2>=t) return true;
return false;
}
};
方法2:
class Solution {
public:
bool haveConflict(vector& event1, vector& event2) {
return !(event1[0] > event2[1] || event2[0] > event1[1]);
}
};
题意
给定一个数组和正整数k,统计子数组中元素的最大公因数等于k的子数组数目。
思路
数组长度只有1000,直接 O ( n 2 ) O(n^2) O(n2)做法,双重循环暴力。
代码
#define ll long long
class Solution {
public:
int subarrayGCD(vector<int>& nums, int k) {
int ans=0,n=nums.size();
for(int i=0;i<n;i++){
int gc=nums[i];
for(int j=i;j<n;j++){
gc=__gcd(gc,nums[j]);
if(gc==k) ans++;
}
}
return ans;
}
};
题意
给定数组 nums 和 cost
你可以执行下面操作任意次:
求使得数组元素全部相等的最小代价
思路
看到这个问题可以想到这个问题的简化版本,就是当cost都是1时,使得数组元素全部相等的最小代价就是将数组元素全部变成中位数。
那么将本问题转化为上面这个基础问题的方法就是**“将cost看作cnt”**。
以第一个数组为例,可以看作:求将数组[1,1,3,3,3,5,2,2,2,…,2]的元素全部变成相等的最小代价(所有元素+1和-1的代价均为1)。
所以我们就把这个问题变成了找中位数的问题,将数组按照nums的升序排列后找中位数即可。
代码
#define ll long long
class Solution {
public:
ll minCost(vector<int>& nums, vector<int>& cost) {
int n=nums.size();
vector<pair<ll,ll> > p;
ll sum=0;
for(int i=0;i<n;i++)
p.push_back(pair<int,int>{nums[i],cost[i]}),sum+=(ll)cost[i];
sort(p.begin(),p.end());
ll m=0,idx=0;
for(int i=0;i<n;i++) {
m+=p[i].second;
if(m+m>=sum){
idx=i;
break;
}
}
ll ans=0;
for(int i=0;i<n;i++)
ans+=abs(nums[i]-p[idx].first)*cost[i];
return ans;
}
};
题意
给定原数组和目标数组,每次操作可以选择两个下标不同的元素,一个+2,一个-2,问把原数组变得与目标数组相似的最小操作次数。
如果两个数组中每个元素出现的频率相等,我们称两个数组是相似的。
思路
注意到,奇数只能变成奇数,偶数只能变成偶数。
分别考虑奇数数组和目标的奇数数组以及偶数数组和目标的偶数数组,一定是维持当前的顺序找目标更优。(否则总距离会更长)
而每一次进行操作都可以同时使得两个数更接近与自身的目标,因此,距离目标的总差值每次会减少 4,所以我们只需要计算总差值除以 4 的结果即可。
代码
class Solution {
public:
long long makeSimilar(vector<int>& nums, vector<int>& target) {
sort(nums.begin(),nums.end(),[](int a,int b){
if(a%2 == b%2) return a<b;
return a%2 < b%2;
});
sort(target.begin(),target.end(),[](int a,int b){
if(a%2 == b%2) return a<b;
return a%2 < b%2;
});
long long ans=0,n=nums.size();
for(int i=0;i<n;i++)
ans+=abs(nums[i]-target[i]);
return ans/4;
}
};