力扣:第 308 场周赛
2389. 和有限的最长子序列
问题解析
对nums升序排序后计算前缀和数组sum,sum[i]表示至少有多少个nums的数字组成,然后对于queries[i],每次二分寻找sum数组中小于等于queries[i]的最大数,用那个数在sum数组中的下标来构造数组。
AC代码
class Solution {
public:
vector<int> answerQueries(vector<int>& nums, vector<int>& queries) {
int n=nums.size(),m=queries.size();
sort(nums.begin(),nums.end());
vector<int>sum(n+1),ans(m);
for(int i=0;i<n;i++)sum[i+1]=sum[i]+nums[i];
for(int i=0;i<m;i++)
{
int l=1,r=n;
while(l<r)
{
int mid=(l+r+1)/2;
if(sum[mid]>queries[i])r=mid-1;
else l=mid;
}
if(sum[l]<=queries[i])ans[i]=l;
else ans[i]=l-1;
}
return ans;
}
};
2390. 从字符串中移除星号
问题解析
用一个字符串str存储答案。遍历字符串s,如果s[i]不是星号,就加在str的最后面,如果s[i]是星号,且str不为空,就把str的最后一个字符去掉(利用pop_back()函数可以O1的复杂度做到)。最后的str就是答案。
AC代码
class Solution {
public:
string removeStars(string s) {
string str;
for(auto i:s)
{
if(i!='*')str+=i;
else if(!str.empty())str.pop_back();
}
return str;
}
};
2391. 收集垃圾的最少总时间
问题解析
先遍历一遍garbage数组,记录哪个位置之后不在有玻璃、纸、金属垃圾,然后遍历三次garbage数组,每次分别去除一种种类的垃圾,对于一种垃圾,当走到记录的最后一个位置之后(这个位置后不再有当前类型的垃圾)就可以结束这次循环(节省了前往之后房子的时间),计算三次清理垃圾的时间,总和就是答案。
AC代码
class Solution {
public:
int garbageCollection(vector<string>& garbage, vector<int>& travel) {
int n=garbage.size(),m=n-1;
int res=0,a=0,b=0,c=0;
for(int i=0;i<n;i++)
{
sort(garbage[i].begin(),garbage[i].end());
for(auto j:garbage[i])
{
if(j=='P')c=i;
if(j=='M')b=i;
if(j=='G')a=i;
}
}
for(int i=0;i<n;i++)
{
if(i>c)break;
else if(i>0)res+=travel[i-1];
while(!garbage[i].empty()&&garbage[i].back()=='P')
{
res++;
garbage[i].pop_back();
}
}
for(int i=0;i<n;i++)
{
if(i>b)break;
else if(i>0)res+=travel[i-1];
while(!garbage[i].empty()&&garbage[i].back()=='M')
{
res++;
garbage[i].pop_back();
}
}
for(int i=0;i<n;i++)
{
if(i>a)break;
else if(i>0)res+=travel[i-1];
while(!garbage[i].empty()&&garbage[i].back()=='G')
{
res++;
garbage[i].pop_back();
}
}
return res;
}
};
2392. 给定条件下构造矩阵
问题解析
利用rowConditions数组建立 abovei指向belowi的边来构造图,记录每个点的入度,然后拓扑排序,记录每个点的入队次序,这个入队次序就是他们将他们放在在答案数组中的第几行(即x坐标)。
再利用colConditions数组建立lefti指向righti的边来构造图,记录每个点的入度,然后拓扑排序,记录每个点的入队次序,这个入队次序就是他们将他们放在在答案数组中的第几列(即y坐标)。
(因为答案数组是k*k的,而一共有k个点,所以每行只放一个点也是可以放得下的,列同理)
AC代码
bool cmp(vector<int>& a, vector<int>& b)
{
if (a[0] != b[0])return a[0] < b[0];
return a[1] < b[1];
}
class Solution {
public:
vector<int>row[450],col[450];
bool topsort(int k, vector<int>&dep, vector<int>&in)
{
queue<int>que;
int res = 0;
for (int i = 1; i <= k; i++)
{
if (in[i] == 0)
{
que.push(i);
dep[i] = res++;
}
}
while (!que.empty())
{
int len = que.size();
for (int i = 0; i < len; i++)
{
int t = que.front();
que.pop();
for (auto j : row[t])
{
in[j]--;
if (in[j] == 0)
{
que.push(j);
dep[j] = res++;
}
}
}
}
for (int i = 1; i <= k; i++)
{
if (in[i] != 0)
{
return false;
}
}
return true;
}
bool topsort2(int k, vector<int>&dep, vector<int>&in)
{
queue<int>que;
int res = 0;
for (int i = 1; i <= k; i++)
{
if (in[i] == 0)
{
que.push(i);
dep[i] = res++;
}
}
while (!que.empty())
{
int len = que.size();
for (int i = 0; i < len; i++)
{
int t = que.front();
que.pop();
for (auto j : col[t])
{
in[j]--;
if (in[j] == 0)
{
que.push(j);
dep[j] = res++;
}
}
}
}
for (int i = 1; i <= k; i++)
{
if (in[i] != 0)
{
return false;
}
}
return true;
}
vector<vector<int>> buildMatrix(int k, vector<vector<int>>& rowConditions, vector<vector<int>>& colConditions) {
vector<vector<int>>res(k, vector<int>(k,0)),err;
vector<int>depx(450), depy(450), stx(450), sty(450), inx(450), iny(450);
sort(rowConditions.begin(), rowConditions.end(),cmp);
sort(colConditions.begin(), colConditions.end(),cmp);
rowConditions.erase(unique(rowConditions.begin(), rowConditions.end()), rowConditions.end());
colConditions.erase(unique(colConditions.begin(), colConditions.end()), colConditions.end());
int n = rowConditions.size(), m = colConditions.size();
for (int i = 0; i < n; i++)
{
row[rowConditions[i][0]].push_back(rowConditions[i][1]);
inx[rowConditions[i][1]]++;
}
if(!topsort(k,depx, inx))return err;
for (int i = 0; i < m; i++)
{
col[colConditions[i][0]].push_back(colConditions[i][1]);
iny[colConditions[i][1]]++;
}
if (!topsort2(k, depy, iny))return err;
for (int i = 1; i <= k; i++)
{
res[depx[i]][depy[i]] = i;
}
return res;
}
};