力扣264周赛题解

题目

5906. 句子中的有效单词数

本题的解决思路就是去遍历该string,同时将判断条件在模拟的过程中进行判断即可,判断条件如下;

1.仅由小写字母、连字符和/或标点(不含数字)。

2.至多一个 连字符 '-' 。如果存在,连字符两侧应当都存在小写字母("a-b" 是一个有效单词,但 "-ab" 和 "ab-" 不是有效单词)。

3.至多一个 标点符号。如果存在,标点符号应当位于 token 的 末尾 。

解决代码

class Solution {

public:

     int countValidWords(string s) {

         int n = s.size(), res = 0;

         for (int i = 0; i < n; i ++){

            if (isalpha(s[i]) || s[i] == '.'  || s[i] == '!' || s[i] == ',') {

                int num = 0;

                while(i < n &&  s[i] != ' '){

                    if (s[i] == '-'  && i < n-1 && isalpha(s[i + 1])) num ++;

                    else if((s[i] == '-'  && i < n-1 && !isalpha(s[i + 1])) || ((s[i] == '.' || s[i]  == '!' || s[i] == ',') && (i < n-1 && s[i + 1] != ' ')) ||  isdigit(s[i])) num = 2;

                    i ++;

                }

                i --;

                if (num <= 1) res ++;

            }

            else if(s[i] != ' '){

                while(i < n &&  s[i] != ' ') i ++;

                i --;

            }

         }

         return res;

     }

};


5907.下一个更大的数值平衡数

读完该题,首先应该注意到该题的数据范围在n <= 1e6; 有了这个条件就可以考虑去枚举所有在n + 1  -  1e7这个范围内满足条件的最小值;该题的题目要求满足条件的值单个位置存在的数字个数等于该数字本身,并且严格大于给出的n;

为什么是1e7呢?因为该题是要求严格大于n的,n能够取到1e6,所以操作时可以向上取到1e7,就一定会存在严格大于n的值。

解决代码

const int N = 10, M = 1e7;

class Solution {

public:

     int snt[N];

     int nextBeautifulNumber(int n) {

         for (int i = n + 1; i <= M; i ++){

            memset(snt, 0, sizeof snt);

            int k = i;

            while(k > 0) {

                snt[k % 10] ++;

                k /= 10;

            }

            bool flag = false;

            for (int j = 0; j <= 9; j ++){

                if (snt[j] > 0 &&  j != snt[j]) {

                    flag = true;

                    break;

                }

            }

            if (!flag) return i;

         }

         return -1;

     }

};

5908. 统计最高分的节点数目

该题题意:给出的是一个二叉树,想要得到的是删除某个节点的分支,所产生的新的分支的乘积的最大值的个数;所以此题可以采用dfs+回溯来解决该问题,在回溯的过程中返回分支所产生的节点,然后求其乘积,得到最大值,同时并记录其个数。解释如下:

83a31fa4749769e457fc9c41d6d6822f.png

对于此案例,若是采用dfs+回溯的方法对于节点2来看;在回溯的过程中2节点的两个子节点3 ,1分别回溯到节点2的节点个数为n1,n2,但对于节点2而言还得计算其父节点部分所产生的个数为p, 整个二叉树的节点个数为n;已知子节点的回溯值n1, n2,如何求出父节点p的值呢?由上图可知:

p  =  n –  n1 – n2

有了此公式对于该问题也就很好解决了。

解决代码

class Solution {

public:

     int root, n, res;

     unordered_map<int, vector<int>> mp;

     typedef long long LL;

     LL kk;

     int dfs(int p){

         LL maxv = 1;

         int nums = 1;

         for (int v: mp[p]) {

            int k = dfs(v);

            maxv = (LL)maxv * k;

            nums += k;

         }

         if(p != root) maxv = (LL)maxv * (n-nums);

         if (maxv > kk) {

            res = 1;

            kk = maxv;

         }

         else if (maxv == kk) {

            res ++;

         }

         return nums;

     }

     int countHighestScoreNodes(vector<int>& ps) {

         n = ps.size();

         for (int i = 0; i < n; i ++){

             if (ps[i] == -1) root = i;

            else {

                mp[ps[i]].push_back(i);

            }

         }

         dfs(root);

         return res;

     }

};

5909. 并行课程 III

该题的题意:完成某一个课程前,必须先完成在它之前的先修课,那么此题就完全符合拓扑结构,故此可以采用拓扑图去解决该问题。如果要进行该点操作,必须首先完成其所有入度点的操作,因为完成每一个该点入度的时间不一样,所以我们取时间最晚的入度为执行该点的起始执行时间(因为最晚的入度时间点必定其他入度已经全部执行完成);写出拓扑图+数组记录每一个点的起始时间就可解决该问题。

 解决代码

const int N = 50010;

class Solution {

public:

     int n, r[N], dist[N];

     vector<int> rlx[N];

     void topu(vector<int> time){

         queue<int> qu;

         int n = time.size();

         for (int i = 1; i <= n; i ++){

            if (r[i] == 0) {

                qu.push(i);

                dist[i] = time[i-1];

            }

         }

         while(qu.size()){

            int v = qu.front();

            qu.pop();

            for (int x: rlx[v]){

                r[x] --;

                dist[x] = max(dist[x],  dist[v] + time[x-1]);

                if (r[x] == 0) qu.push(x);

            }

         }

     }

     int minimumTime(int n, vector<vector<int>>& rx,  vector<int>& time) {

         n = time.size();

         for (int i = 0; i < rx.size(); i ++){

            int a = rx[i][0], b = rx[i][1];

            r[b] ++;

            rlx[a].push_back(b);

         }

         topu(time);

         int res = 0;

         for (int i = 1; i <= n; i ++) res = max(res, dist[i]);

         return res;

     }

};

总结

本博客是力扣264场周赛的题解,如果存在不懂的地方可以在评论区提出,这里会耐心解答!关注公众号:算法与编程之美,我们会不断的更新力扣周赛题解,codeforces题解等比赛题解。

实习编辑:衡辉

稿件来源:深度学习与文旅应用实验室(DLETA)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

算法与编程之美

欢迎关注『算法与编程之美』

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值