力扣:第 308 场周赛

力扣:第 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;
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值