【力扣周赛】第394场周赛

1.统计特殊字母的数量

题目链接
在这里插入图片描述

  • 🍎该题涉及的小技巧:🐥
    🐧①大写字母和对应的小写字母低5位都是相等的;
    🐧②大写字母ASCII二进制第 6 位是0,对应的小写字母第 6 位是1;
    在这里插入图片描述

🐧③位运算小技巧:🐥
在这里插入图片描述

  • 解题思路:
    🐧①将 word 中的字母都取出来各自放入一个大写🔠字母的集合,和一个小写🔡字母的集合;

    🐧②再对两个集合求交集就可以求出同时出现大小写字母的个数;

    🐧③用到的位运算小技巧:
    (ch >> 5) & 1,表示取出该字母的ASCII第6位,如果是 0 表示大写字母,1 表示小写字母;

    1<<(ch&31);,可以将该字母转换成为得到一个唯一的 8个字节32个 比特位数中的一位数字 1,其他的31位都是 0,这样 26个字母每个字母对应的映射都不一样;(例如: 假如 ch 字符是小写字母 c的话,此时1<<(ch&31) )的结果为十进制 8(0000 0000 0000 1000),所以这样看每个字母都有自己对应不同的二进制表示

    🐧④mask[0] & mask[1]表示求交集;

    🐧⑤集合的大小:__builtin_popcount(s)
  • 代码实现
class Solution {
public:
    int numberOfSpecialChars(string word) {

        int mask[2] = {0};

        // 注意:大写字母的ASCII二进制第 6 位是 0,小写字母第 6 位是 1
        for(auto ch : word)
        {
            mask[(ch >> 5) & 1] |= 1<<(ch&31);
        }


        // 求集合的大小:__builtin_popcount(s)

        return __builtin_popcount(mask[0] & mask[1]);
    }
};

2.使矩阵满足条件的最少操作次数

题目链接

在这里插入图片描述

  • 解题思路:
    🐧①逆向思维:求最少操作的次数,那我们可以反过来取求最多保留多少个数字🔢;🎈

    🐧②我们从后往前来求每一列最多保留多少个数字🔢;

    🐧③必须记录前一列填的数字(要保证相邻列数字不同

    🐧④注意❗:必须用一个数组记录每一列用某一个数字的时候的结果,并且及时更新;
  • 解题代码
class Solution {

int n, m;
int cnt[1010][15] = {0};
int vis[1010][15] = {0};
int ans = 0;

public:
    int minimumOperations(vector<vector<int>>& grid) {

        n = grid.size(), m = grid[0].size();
        memset(vis, -1, sizeof(vis));

        for (int i = 0; i < m; i ++)
        {
            for (int j = 0; j < n; j ++)
            {
                int x = grid[j][i];
                cnt[i][x] ++;   // 第 i 列中,0 ~ 9 的个数
            }
        }

        //从最后一列开始往前搜索
        int res = dfs(m - 1, 10);

        // 注意:我们用了逆向思维,求的是最多保留数据的个数
        return n * m - res;
    }
    // 表示搜索第 i 列中,最多保留的个数,前一列为 j
    int dfs(int i, int j)
    {
        // 递归出口
        if (i < 0)
            return 0;
        
        auto& ans = vis[i][j]; // 注意这里是引用
        if (ans != -1)
            return ans;

        ans = 0;
        for (int k = 0; k <= 9; k ++)
        {
            if (k != j)
            {
                ans = max(ans, dfs(i - 1, k) + cnt[i][k]);
            }
        }
        return ans;
    }
};
  • 32
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

未来可期LJ

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值