• 第 300 场周赛 - 力扣(LeetCode)


    第 300 场周赛 - 力扣(LeetCode)

    2325. 解密消息

    给你字符串 key 和 message ,分别表示一个加密密钥和一段加密消息。解密 message 的步骤如下:

    使用 key 中 26 个英文小写字母第一次出现的顺序作为替换表中的字母 顺序 。
    将替换表与普通英文字母表对齐,形成对照表。
    按照对照表 替换 message 中的每个字母。
    空格 ’ ’ 保持不变。
    例如,key = “happy boy”(实际的加密密钥会包含字母表中每个字母 至少一次),据此,可以得到部分对照表(‘h’ -> ‘a’、‘a’ -> ‘b’、‘p’ -> ‘c’、‘y’ -> ‘d’、‘b’ -> ‘e’、‘o’ -> ‘f’)。
    返回解密后的消息。

    img

    样例1:
    输入:key = "the quick brown fox jumps over the lazy dog", message = "vkbs bs t suepuv"
    输出:"this is a secret"
    解释:对照表如上图所示。
    提取 "the quick brown fox jumps over the lazy dog" 中每个字母的首次出现可以得到替换表。
    
    • 1
    • 2
    • 3
    • 4
    • 5

    问题解析

    直接遍历key字符串,把这些字符和26个字母的映射用数组或哈希表存起来,只要遍历到一个字符的时候这个字符还没有映射,就按照26字母的顺序给他一个映射。

    再遍历字符串message,按照记录的映射把字符转化后返回即可。

    AC代码

    class Solution {
    public:
        string decodeMessage(string key, string message) {
            int n=key.size();
            char c='a';
            unordered_map<char,char>mymap;
            for(int i=0;i<n;i++)
            {
                if (key[i] == ' ')continue;
                if(c>'z')break;
                if(mymap[key[i]]==0)
                {
                    mymap[key[i]]=c++;
                }
            }
            string s;
            for(auto i:message)
            {
                if(i==' ')s+=i;
                else s+=mymap[i];
            }
            return s;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    2326. 螺旋矩阵 IV

    给你两个整数:m 和 n ,表示矩阵的维数。

    另给你一个整数链表的头节点 head 。

    请你生成一个大小为 m x n 的螺旋矩阵,矩阵包含链表中的所有整数。链表中的整数从矩阵 左上角 开始、顺时针 按 螺旋 顺序填充。如果还存在剩余的空格,则用 -1 填充。

    返回生成的矩阵。

    img

    示例 1:
    输入:m = 3, n = 5, head = [3,0,2,6,8,1,7,9,4,2,5,5,0]
    输出:[[3,0,2,6,8],[5,0,-1,-1,1],[5,2,4,9,7]]
    解释:上图展示了链表中的整数在矩阵中是如何排布的。
    注意,矩阵中剩下的空格用 -1 填充。
    
    • 1
    • 2
    • 3
    • 4
    • 5

    问题解析

    难度主要在螺旋遍历数组,我们可以先准备一个方向数组,按照右(0,1)下(1,0)左(0,-1)上(-1,0),这样我们先按照右方向遍历数组,当移动到边界或移动到之前遍历过的格子时便改变方向。

    至于剩余的位置都设为-1,我们可以先把所有的矩阵都设为-1,当遍历完后也不用管剩下的格子了。

    AC代码

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode() : val(0), next(nullptr) {}
     *     ListNode(int x) : val(x), next(nullptr) {}
     *     ListNode(int x, ListNode *next) : val(x), next(next) {}
     * };
     */
    class Solution {
    public:
        int dx[4]={0,1,0,-1},dy[4]={1,0,-1,0};
        vector<vector<int>> spiralMatrix(int m, int n, ListNode* head) {
            vector<vector<int>>v(m,vector<int>(n,-1));
            int d=0,x=0,y=0;
            while(head)
            {
                v[x][y]=head->val;
                head=head->next;
                int a=x+dx[d],b=y+dy[d];
                if(a>=m||a<0||b<0||b>=n||v[a][b]!=-1)
                {
                    d=(d+1)%4;
                    a=x+dx[d],b=y+dy[d];
                }
                x=a,y=b;
                
            }
            return v;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    2327. 知道秘密的人数

    在第 1 天,有一个人发现了一个秘密。

    给你一个整数 delay ,表示每个人会在发现秘密后的 delay 天之后,每天 给一个新的人 分享 秘密。同时给你一个整数 forget ,表示每个人在发现秘密 forget 天之后会 忘记 这个秘密。一个人 不能 在忘记秘密那一天及之后的日子里分享秘密。

    给你一个整数 n ,请你返回在第 n 天结束时,知道秘密的人数。由于答案可能会很大,请你将结果对 109 + 7 取余 后返回。

    示例 1:
    
    输入:n = 6, delay = 2, forget = 4
    输出:5
    解释:
    第 1 天:假设第一个人叫 A 。(一个人知道秘密)
    第 2 天:A 是唯一一个知道秘密的人。(一个人知道秘密)
    第 3 天:A 把秘密分享给 B 。(两个人知道秘密)
    第 4 天:A 把秘密分享给一个新的人 C 。(三个人知道秘密)
    第 5 天:A 忘记了秘密,B 把秘密分享给一个新的人 D 。(三个人知道秘密)
    第 6 天:B 把秘密分享给 E,C 把秘密分享给 F 。(五个人知道秘密)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    问题解析

    设动态规划数组f,f[i]的意思为:第i天新增的知道秘密的人数为f[i]。

    第i天新增的人数,就是第i天的前forge天到delay天的知道人数的总和。

    第n天知道秘密的总人数,就是第n天的前forge天到delay天的f[i]的总和。

    AC代码

    class Solution {
    public:
        int MOD=1e9+7;
        typedef long long ll;
        int peopleAwareOfSecret(int n, int delay, int forget) {
            vector<ll>f(n + 1);
            f[1] = 1;
            for (int i = 2; i <= n; i++)
            {
                int j = i - delay;
                while (j > 0 && i - j < forget)
                {
                    f[i] = (f[i] + f[j]) % MOD;
                    j--;
                }
            }
            ll res = 0;
            for (int i = 0; i < forget; i++)
            {
                res = (res + f[n - i]) % MOD;
            }
            return res;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    2328. 网格图中递增路径的数目

    给你一个 m x n 的整数网格图 grid ,你可以从一个格子移动到 4 个方向相邻的任意一个格子。

    请你返回在网格图中从 任意 格子出发,达到 任意 格子,且路径中的数字是 严格递增 的路径数目。由于答案可能会很大,请将结果对 109 + 7 取余 后返回。

    如果两条路径中访问过的格子不是完全相同的,那么它们视为两条不同的路径。

    img

    示例 1:
    
    输入:grid = [[1,1],[3,4]]
    输出:8
    解释:严格递增路径包括:
    
    - 长度为 1 的路径:[1],[1],[3],[4] 。
    - 长度为 2 的路径:[1 -> 3],[1 -> 4],[3 -> 4] 。
    - 长度为 3 的路径:[1 -> 3 -> 4] 。
      路径数目为 4 + 3 + 1 = 8 。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    问题解析

    记忆化搜索。

    以每一个点为起点进行dfs,看以一个点为起点能延申出多少条不同的路径出来,记录在二维数组f中,f[i] [j]表示以(i,j)为起点的路径有f[i] [j]条。

    dfs的时候,如果下一个格子(x,y)的值大于当前格子(i,j),说明当前格子可以延申到那个格子,那么f[i] [j]就能多出f[x] [y]条路径出来,再以[x] [y]为起点继续dfs。最后的结果就是二维数组f的全部的和。

    AC代码

    class Solution {
    public:
        typedef long long ll;
        int MOD=1e9+7;
        int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1},n,m;
        ll f[1050][1050];
        vector<vector<int>>v;
        ll dp(int x,int y)
        {
            if(f[x][y]!=0)return f[x][y];
            f[x][y]=1;
            for(int i=0;i<4;i++)
            {
                int a=x+dx[i],b=y+dy[i];
                if(a>=0&&a<n&&b>=0&&b<m&&v[a][b]>v[x][y])
                {
                    f[x][y]=(f[x][y]+dp(a,b))%MOD;
                }
            }
            return f[x][y];
        }
        int countPaths(vector<vector<int>>& grid) {
            v=grid;
            n=grid.size(),m=grid[0].size();
            ll res=0;
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<m;j++)
                {
                    res=(res+dp(i,j))%MOD;
                }
            }
            return res;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
  • 相关阅读:
    4年博主写博客的折腾之路
    Spring Boot Actuator 漏洞复现合集
    设计模式学习笔记 - 组合模式
    2022-08-16
    【面试题精讲】如何将二进制转为十六进制
    让 GPT-4 来修复 Golang “数据竞争”问题(续) - 每天5分钟玩转 GPT 编程系列(7)
    高性能系统架构设计之:多级缓存
    探索学习新时代,江苏开放大学与电大搜题带您飞!
    NAT技术---网络地址转换
    threeJS 踩坑
  • 原文地址:https://blog.csdn.net/fnmdpnmsl/article/details/125608763