【LeetCode周赛】第 385 场周赛

目录

  • [3042. 统计前后缀下标对 I 简单](#3042. 统计前后缀下标对 I 简单)
  • [3043. 最长公共前缀的长度 中等](#3043. 最长公共前缀的长度 中等)
  • [3044. 出现频率最高的质数 中等](#3044. 出现频率最高的质数 中等)
  • [3045. 统计前后缀下标对 II 困难](#3045. 统计前后缀下标对 II 困难)

3042. 统计前后缀下标对 I 简单

3042. 统计前后缀下标对 I

分析:

数据量较少,直接暴力即可,也可以采用 构建前后缀字典树(3045. 统计前后缀下标对 II)。
代码:

cpp 复制代码
class Solution {
public:
    int countPrefixSuffixPairs(vector<string>& words) {
        int n=words.size(), ans=0;
        for(int i=0;i<n;i++){
            int l = words[i].length();
            for(int j=i+1;j<n;j++){
                int le = words[j].length();
                if(l>le) continue;
                if(words[i]==words[j].substr(0,l) && words[i]==words[j].substr(le-l,l)) ans++;
            }
        }
        return ans;
    }
};

3043. 最长公共前缀的长度 中等

3043. 最长公共前缀的长度

分析:

arr1 构建字典树,在遍历 arr2 进行比较即可。
代码:

cpp 复制代码
class Node{
public:
    int val;
    vector<Node*> ne;
    Node() : val(0), ne(10, nullptr) {}
    Node(int v) : val(v), ne(10, nullptr) {}
};

class Solution {
public:
    void buildTree(Node* root, string& s, int i){
        if(i>= s.length()) return;
        int k = s[i] - '0';
        if(root->ne[k] == nullptr){
            Node *node = new Node(s[i]-'0');
            root->ne[k] = node;
        }
        
        buildTree(root->ne[k], s, i+1);
    }

    int longestCommonPrefix(vector<int>& arr1, vector<int>& arr2) {
        Node* root = new Node();
        for(int& a : arr1){
            string s = to_string(a);
            buildTree(root, s, 0);
        }
        int ans=0;
        for(int& a : arr2){
            string s = to_string(a);
            int i=0;
            Node* p=root;
            for(;i<s.length();i++){
                int k = s[i]-'0';
                if(p->ne[k]==nullptr) break;
                p=p->ne[k];
            }
            ans=max(i,ans);
        }
        return ans;
    }
};

3044. 出现频率最高的质数 中等

3044. 出现频率最高的质数

分析:

选择合适的判断质数的算法,按照题意模拟即可。

注意: 如果对数据范围内的质数进行打表,需要注意调用方式,否则会出现多次计算,最终超时。

代码:

对质数打表,再判断。

cpp 复制代码
const int ma = 1e7+5;
vector<int> prime(ma,1);

void getPrimes(){
    prime[0]=prime[1]=0;
    for(int i=2;i<ma;i++){
        if(prime[i]==0) continue;
        for(int j=2;j*i<ma;j++) prime[j*i]=0;
    }
    for(int i=2;i<10;i++) prime[i]=0;
}

void init(){
    static bool ini = false;
    if(!ini){
        ini = true;
        getPrimes();
    }
}

class Solution {
public:

    int mostFrequentPrime(vector<vector<int>>& mat) {
        init();
        int n=mat.size(), m=mat[0].size(), ans=-1, mm=0;
        unordered_map<int,int> mp;
        int move_x[] = {0,1,1,1,0,-1,-1,-1}, move_y[] = {1,1,0,-1,-1,-1,0,1};
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                for(int k=0;k<8;k++){
                    int x=i,y=j;
                    int m_x=move_x[k], m_y=move_y[k], t=mat[i][j];
                    x+=m_x;y+=m_y;
                    while(x>=0&&y>=0&&x<n&&y<m){
                        t=t*10+mat[x][y];
                        if(prime[t]){
                            mp[t]++;
                            if(mm<mp[t]){
                                ans=t;
                                mm=mp[t];
                            }else if(mm==mp[t]){
                                ans=max(ans,t);
                            }
                        }
                        x+=m_x;y+=m_y;
                    }
                }
            }
        }
        return ans;
    }
};

对每一个出现的数进行质数的判断。

cpp 复制代码
class Solution {
public:
    bool isPrime(int n){
        if(n<10) return false;
        for(int i=2;i*i<=n;i++){
            if(n%i==0) return false;
        }
        return true;
    }

    int mostFrequentPrime(vector<vector<int>>& mat) {
        int n=mat.size(), m=mat[0].size(), ans=-1, mm=0;
        unordered_map<int,int> mp;
        int move_x[] = {0,1,1,1,0,-1,-1,-1}, move_y[] = {1,1,0,-1,-1,-1,0,1};
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                for(int k=0;k<8;k++){
                    int x=i,y=j;
                    int m_x=move_x[k], m_y=move_y[k], t=mat[i][j];
                    x+=m_x;y+=m_y;
                    while(x>=0&&y>=0&&x<n&&y<m){
                        t=t*10+mat[x][y];
                        if(isPrime(t)){
                            mp[t]++;
                            if(mm<mp[t]){
                                ans=t;
                                mm=mp[t];
                            }else if(mm==mp[t]){
                                ans=max(ans,t);
                            }
                        }
                        x+=m_x;y+=m_y;
                    }
                }
            }
        }
        return ans;
    }
};

3045. 统计前后缀下标对 II 困难

3045. 统计前后缀下标对 II

分析:

对于前缀,可以通过构建 字典树Trie ,进行判断。

而后缀,观察字符串 S = "abcabc"s1 = "abc"的前后缀情况:

S的前后缀与s1一致,即S[0...2]S[3...5] 均与s1相等。

  • S[0], S[5] = a, c , s1[0], s1[2] = a, c
  • S[1], S[4] = b, b , s1[1], s1[1] = b, b
  • S[2], S[3] = c, a , s1[2], s1[0] = c, a

易得若S(长度为L)的前后缀与s1(长度为l)完全一致则有:

  • S[0], S[L-1] == s1[0], s1[l-1]
  • S[1], S[L-2] == s1[1], s1[l-2]
  • ...
  • S[l-1], S[L-l+1] == s1[l-1], s1[0]

根据得到的性质,在构建字典树时,同时记录前缀与后缀的字符,再进行对比即可。

注意: i < j,因此不需要根据字符串长度进行排序。

也可以正常构建字典树来对比前缀,同时使用 **Z函数(拓展KMP)**来对比后缀。

代码:

cpp 复制代码
struct Node {
    unordered_map<int, Node*> son;
    int cnt=0;
};

class Solution {
public:
    long long countPrefixSuffixPairs(vector<string>& words) {
        long long ans=0;
        Node *root = new Node();
        for(string& s : words){
            int n = s.length();
            Node *cur = root;
            for(int i=0;i<n;i++){
                int p = (int) ((s[i] - 'a') << 5) | (s[n - i - 1] - 'a'); // 仅26个字母,五位二进制即可完全表示,使用十位二进制数来表示(前五位表示前缀,后五位表示后缀)
                if(cur->son[p] == nullptr){
                    cur->son[p] = new Node();
                }
                cur = cur->son[p];
                ans += cur->cnt;
            }
            cur->cnt++;
        }
        return ans;
    }
};
相关推荐
江畔柳前堤3 分钟前
大语言模型分布式训练:从并行策略到万卡工程的系统梳理
人工智能·分布式·深度学习·算法·目标检测·机器学习·语言模型
Forever Nore1 小时前
LeetCode 4 寻找两个正序数组的中位数 - 二分
算法·leetcode
罗西的思考3 小时前
【OpenClaw具身硬件】MiniClaw 阅读笔记---(1)基础
人工智能·算法·机器学习
蛋先生DX4 小时前
大模型参数存储格式揭秘:BF不是男朋友
深度学习·算法·llm
爱跳舞的烤冷面4 小时前
自学嵌入式第22天(数据结构——哈希)
数据结构·算法·哈希算法
猎嘤一号4 小时前
博弈论(Game Theory)的理论、算法与工程
人工智能·算法·安全·博弈论
月光船幽幽5 小时前
影子模式下保护 logits 不被修改
人工智能·python·算法
马拉AI5 小时前
腾讯开源 Agent 记忆系统,AI“换对话就忘”的问题有了新解法(附安装使用教程)
人工智能·算法·开源·科研
地平线开发者6 小时前
征程6工具链模型X86推理方式说明
算法
地平线开发者6 小时前
【征程6】校准量化中HistogramObserver解析
算法